Finally I've got it compiling even with such code:
bot_globals.h
Code:
#include <com_model.h>
#include <pm_defs.h>
// KWo - 13.03.2012 - Thanks to Immortal_BLG for light code
#define SURF_PLANEBACK 2
#define SURF_DRAWSKY 4
#define SURF_DRAWSPRITE 8
#define SURF_DRAWTURB 0x10
#define SURF_DRAWTILED 0x20
#define SURF_DRAWBACKGROUND 0x40
#ifdef __linux__
// Linux doesn't have this function so this emulates its functionality
inline void *GetModuleHandle(const char *name)
{
void *handle;
if( name == NULL )
{
// hmm, how can this be handled under linux....
// is it even needed?
return NULL;
}
if( (handle=dlopen(name, RTLD_NOW))==NULL)
{
// couldn't open this file
return NULL;
}
// read "man dlopen" for details
// in short dlopen() inc a ref count
// so dec the ref count by performing the close
dlclose(handle);
return handle;
}
#endif
struct GL_msurface_t
{
#define SURF_UNDERWATER 0x80 // ONLY FOR OpenGL!!!
//#define SURF_DONTWARP 0x100 // ONLY FOR OpenGL!!! (EXISTS?!?!?!?!?!??!?!?!?!?!?!??!)
/*off=0(0)*/ int visframe; // should be drawn when node is crossed
/*off=4(1)*/ mplane_t *plane; // pointer to shared plane
/*off=8(2)*/ int flags; // see SURF_* #defines
/*off=12(3)*/ int firstedge; // look up in model->surfedges[], negative numbers are backwards edges
/*off=16(4)*/ int numedges;
/*off=20(5)*/ short texturemins[2]; // smallest s/t position on the surface.
/*off=24(6)*/ short extents[2]; // ?? s/t texture size, 1..256 for all non-sky surfaces
/*off=28(7)*/ int light_s, light_t; // gl lightmap coordinates
/*off=36(9)*/ struct glpoly_t *polys; // multiple if warped
/*off=40(10)*/ msurface_t *texturechain;
/*off=44(11)*/ mtexinfo_t *texinfo;
// lighting info
/*off=48(12)*/ int dlightframe; // last frame the surface was checked by an animated light
/*off=52(13)*/ int dlightbits; // dynamically generated. Indicates if the surface illumination
// is modified by an animated light.
/*off=56(14)*/ int lightmaptexturenum;
/*off=60(15)*/ unsigned char styles[MAXLIGHTMAPS]; // index into d_lightstylevalue[] for animated lights
// no one surface can be effected by more than 4
// animated lights.
/*off=64(16)*/ int cached_light[MAXLIGHTMAPS]; // values currently used in lightmap
/*off=80(20)*/ qboolean cached_dlight; // true if dynamic light in cache
/*off=84(21)*/ color24 *samples; // [numstyles*surfsize]
/*off=88(22)*/ decal_t *pdecals;
}; // sizeof (GL_msurface_t) == 92 (23)
struct GL_mnode_t
{
enum ChildrenType_t
{
ChildrenType_Front,
ChildrenType_Back,
ChildrenType_Total
};
// common with leaf
/*! Off=0(0)*/ int contents; // 0, to differentiate from leafs
/*! Off=4(1)*/ int visframe; // node needs to be traversed if current
/*! Off=8(2)*/ Vector mins, maxs; // for bounding box culling
/*! Off=32(8)*/ mnode_t *parent;
// node specific
/*! Off=36(9)*/ mplane_t *plane;
/*! Off=40(10)*/ mnode_t *children[ChildrenType_Total];
/*! Off=48(12)*/ unsigned short firstsurface;
/*! Off=50(12.5)*/ unsigned short numsurfaces;
}; // sizeof (GL_mnode_t) == 52 (13)
#define MAX_LIGHTSTYLES 64
#define MAX_LIGHTSTYLEVALUE 256
struct lightstyle_t
{
int length;
char map[MAX_LIGHTSTYLES];
};
extern lightstyle_t cl_lightstyle[MAX_LIGHTSTYLES];
extern int d_lightstylevalue[MAX_LIGHTSTYLEVALUE]; // 8.8 fraction of base light value
extern model_t *sv_worldmodel; // Analog of sv.worldmodel.
struct Color
{
int red;
int green;
int blue;
inline void Reset (void) { red = green = blue = 0; }
inline const unsigned int GetAvg (void) const { return (red + green + blue) / (sizeof (Color) / sizeof (int)); }
};
/*
=============================================================================
LIGHT SAMPLING
=============================================================================
*/
namespace Light
{
//extern const mplane_t *lightplane (NULL);
//extern Vector lightspot;
extern Color g_pointColor;
// extern const bool RecursiveLightPoint (const nodeType *const node, const Vector &start, const Vector &end);
// Color g_pointColor;
//
template <typename nodeType, typename surfaceType> extern const bool RecursiveLightPoint (const nodeType *const node, const Vector &start, const Vector &end)
{
float front, back, frac;
int side;
mplane_t *plane;
Vector mid;
surfaceType *surf;
int s, t, ds, dt;
int i;
mtexinfo_t *tex;
color24 *lightmap;
unsigned int scale;
unsigned char maps;
// Reliability check.
assert (node != NULL);
if (node->contents < 0)
return false; // didn't hit anything
// Determine which side of the node plane our points are on
// FIXME: optimize for axial
plane = node->plane;
front = DotProduct (start, plane->normal) - plane->dist;
back = DotProduct (end, plane->normal) - plane->dist;
side = front < 0.0f;
// If they're both on the same side of the plane, don't bother to split just check the appropriate child
if ((back < 0.0f) == side)
return RecursiveLightPoint <nodeType, surfaceType> (reinterpret_cast <nodeType *> (node->children[side]), start, end);
// calculate mid point
frac = front / (front - back);
mid = start + (end - start) * frac;
// go down front side
if (RecursiveLightPoint <nodeType, surfaceType> (reinterpret_cast <nodeType *> (node->children[side]), start, mid))
return true; // hit something
// Blow it off if it doesn't split the plane...
if ((back < 0.0f) == side)
return false; // didn't hit anything
// check for impact on this node
// lightspot = mid;
// lightplane = plane;
surf = reinterpret_cast <surfaceType *> (sv_worldmodel->surfaces) + node->firstsurface;
for (i = 0; i < node->numsurfaces; ++i, ++surf)
{
if (surf->flags & SURF_DRAWTILED)
continue; // no lightmaps
tex = surf->texinfo;
// See where in lightmap space our intersection point is
s = static_cast <int> (DotProduct (mid, Vector (tex->vecs[0])) + tex->vecs[0][3]);
t = static_cast <int> (DotProduct (mid, Vector (tex->vecs[1])) + tex->vecs[1][3]);
// Not in the bounds of our lightmap? punt...
if (s < surf->texturemins[0] || t < surf->texturemins[1])
continue;
// assuming a square lightmap (FIXME: which ain't always the case),
// lets see if it lies in that rectangle. If not, punt...
ds = s - surf->texturemins[0];
dt = t - surf->texturemins[1];
if (ds > surf->extents[0] || dt > surf->extents[1])
continue;
if (surf->samples == NULL)
return true;
ds >>= 4;
dt >>= 4;
g_pointColor.Reset (); // Reset point color.
const int smax ((surf->extents[0] >> 4) + 1);
const int tmax ((surf->extents[1] >> 4) + 1);
const int size (smax * tmax);
lightmap = surf->samples + dt * smax + ds;
// Compute the lightmap color at a particular point
for (maps = 0u; maps < MAXLIGHTMAPS && surf->styles[maps] != 255u; ++maps)
{
scale = d_lightstylevalue[surf->styles[maps]];
g_pointColor.red += lightmap->r * scale;
g_pointColor.green += lightmap->g * scale;
g_pointColor.blue += lightmap->b * scale;
lightmap += size; // skip to next lightmap
}
g_pointColor.red >>= 8u;
g_pointColor.green >>= 8u;
g_pointColor.blue >>= 8u;
return true;
}
// go down back side
return RecursiveLightPoint <nodeType, surfaceType> (reinterpret_cast <nodeType *> (node->children[!side]), mid, end);
}
inline const bool IsSoftwareDrawingMode (void)
{
static const bool isSoftwareDrawingMode (IS_DEDICATED_SERVER () || GetModuleHandle ("sw.dll") != NULL);
return isSoftwareDrawingMode;
}
inline const bool ActualRecursiveLightPoint (const Vector &start, const Vector &end)
{
return IsSoftwareDrawingMode () ?
RecursiveLightPoint <mnode_t, msurface_t> (sv_worldmodel->nodes, start, end) :
RecursiveLightPoint <GL_mnode_t, GL_msurface_t> (reinterpret_cast <GL_mnode_t *> (sv_worldmodel->nodes), start, end);
}
inline const unsigned char R_LightPoint (const Vector &p)
{
// Reliability check.
if (sv_worldmodel == NULL)
return 0u;
if (sv_worldmodel->lightdata == NULL)
return 255u;
Vector end (p);
end.z -= 2048.0f;
return ActualRecursiveLightPoint (p, end) == false ? 0u : static_cast <unsigned char> (g_pointColor.GetAvg ());
}
}
bot_globals.cpp
Code:
lightstyle_t cl_lightstyle[MAX_LIGHTSTYLES];
int d_lightstylevalue[MAX_LIGHTSTYLEVALUE]; // 8.8 fraction of base light value
model_t *sv_worldmodel (NULL); // Analog of sv.worldmodel.
namespace Light
{
Color g_pointColor;
template <typename nodeType, typename surfaceType> const bool RecursiveLightPoint (const nodeType *const node, const Vector &start, const Vector &end);
}
The stupid message about wrong reference was coming from old compiled bot.cpp.obj, which wasn't changed by me long time, but it had already linked some references to the function defined first way (when it was compiling correctly for MS C++ Visual Express 200
. After that I was using all the time the "Rebuild" function (as usually), which should compile newer files only. If headers file were changed, all cpp should be compiled again, but it looks it didn't work correctly for MinGW. The "Clean" command helped. After that I did "Build" and it compiled the dll correctly (it is loading and light code is working for windows). I have to check how about cygwin and linux.
Thanks again for the patience for me.