.:: Bots United ::.

.:: Bots United ::. (http://forums.bots-united.com/index.php)
-   General Bot Coding (http://forums.bots-united.com/forumdisplay.php?f=24)
-   -   code to get the illumination at any point on the map (http://forums.bots-united.com/showthread.php?t=9005)

Immortal_BLG 03-02-2012 06:05

code to get the illumination at any point on the map
 
Here a code which will help to receive value of illumination of any point on the map.
Also you will open for yourselves some changes in such structures as 'texture_t', 'mleaf_t', 'msurface_t' and 'mnode_t' which Valve hasn't found time to update in HLSDK....

NOTE: The code is working, but in that kind in which it is placed here wasn't checked.
NOTE2: Engine functions (GiveFnptrsToDll, StartFrame, LightStyle and PM_Move) in a code are placed simply for descriptive reasons.

Code:

#undef texture_t
#undef mleaf_t
#undef msurface_t
#undef mnode_t

struct texture_t        // NOT USED BY LIGHTING CODE, BUT STILL AS BONUS
{
/*! Off=0(0)*/        char                name[16];
/*! Off=16(4)*/        unsigned int        width, height;
/*! Off=24(6)*/        unsigned int UNKNOWN[2u];
/*! Off=32(8)*/        int                        anim_total;                                // total tenths in sequence (0 = no)
/*! Off=36(9)*/        int                        anim_min, anim_max;                // time for this frame min <=time< max
/*! Off=44(11)*/        texture_t *anim_next;                // in the animation sequence
/*! Off=48(12)*/        texture_t *alternate_anims;        // bmodels in frame 1 use these
/*! Off=52(13)*/        unsigned int        offsets[MIPLEVELS];                // four mip maps stored
/*! Off=68(17)*/        unsigned int        paloffset;
};        // sizeof (texture_t) == 72 (18)
struct mleaf_t        // NOT USED BY LIGHTING CODE, BUT STILL HERE AS A BONUS
{
// common with node
/*! Off=0(0)*/        int                        contents;                // wil be a negative contents number
/*! 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;

// leaf specific
/*! Off=36(9)*/        unsigned char                *compressed_vis;
/*! Off=40(10)*/        efrag_t        *efrags;

/*! Off=44(11)*/        msurface_t        **firstmarksurface;
/*! Off=48(12)*/        int                        nummarksurfaces;
/*! Off=52(13)*/        int                        key;                        // BSP sequence number for leaf's contents
/*! Off=56(14)*/        unsigned char                ambient_sound_level[NUM_AMBIENTS];
};        // sizeof (mleaf_t) == 60 (15)
struct msurface_t
{
/*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)*/        BOOL        cached_dlight;                                // true if dynamic light in cache

/*off=84(21)*/        color24                *samples;        // [numstyles*surfsize]

/*off=88(22)*/        decal_t                *pdecals;
};        // sizeof (msurface_t) == 92 (23)
struct 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=52(13)*/        unsigned short                numsurfaces;
};        // sizeof (mnode_t) == 52 (13)

#define        MAX_LIGHTSTYLES        64
#define        MAX_LIGHTSTYLEVALUE        256

struct lightstyle_t
{
        int  length;
        char map[MAX_LIGHTSTYLES];
};

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.

static inline void SetupLightStyles (void)
{
        // Setup lighting information....

        // reset all light styles
        for (unsigned char index (0u); index < MAX_LIGHTSTYLES; ++index)
        {
                cl_lightstyle.length = 0u;
                cl_lightstyle.map[0u] = '\0';
        }

        for (unsigned short index (0u); index < MAX_LIGHTSTYLEVALUE; ++index)
                d_lightstylevalue[index] = 264;        // normal light value
}

static inline void R_AnimateLight (void)
{
        // light animations
        // 'm' is normal light, 'a' is no light, 'z' is double bright
        const int i (static_cast <int> (gpGlobals->time * 10.0f));
        int k;

        for (unsigned char j (0u); j < MAX_LIGHTSTYLES; ++j)
        {
                if (cl_lightstyle[j].length == 0u)
                {
                        d_lightstylevalue[j] = 256;

                        continue;
                }

                k = cl_lightstyle[j].map[i % cl_lightstyle[j].length] - 'a';
                k *= 22;

                d_lightstylevalue[j] = k;
        }       
}

static inline void CallbackLightStyle (const unsigned char style, char *const value)
{
        if (style >= MAX_LIGHTSTYLES)
        {
                g_engfuncs.ServerPrintf ("SVC_LIGHTSTYLE > MAX_LIGHTSTYLES\n");

                return;
        }

        // OCCURS!
        if (value == NULL)
        {
                cl_lightstyle[style].length = 0u;
                cl_lightstyle[style].map[0u] = '\0';

                return;
        }

        const unsigned short maximumCopyAmount (sizeof (cl_lightstyle[style].map) - sizeof ('\0'));

        strncpy (cl_lightstyle[style].map, value, maximumCopyAmount);

        cl_lightstyle[style].map[maximumCopyAmount] = '\0';

        cl_lightstyle[style].length = strlen (cl_lightstyle[style].map);
}
static inline void CallbackStartFrame (void)
{
        R_AnimateLight ();

        inline void ShowMagic (void);

        ShowMagic ();
}
static inline void CallbackPM_Move (playermove_t *const playerMove, const bool server)
{
        // Reliability checks.
        assert (playerMove != NULL);
        assert (server == true);        // ALWAYS SHOULD BE TRUE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

        // Honestly this is need only once per changelevel, but....
        sv_worldmodel = playerMove->physents[0u].model;        // Always point at sv.worldmodel!

        // Reliability check.
        assert (sv_worldmodel != NULL);
}

static WINAPI GiveFnptrsToDll (enginefuncs_t *pengfuncsFromEngine, globalvars_t *pGlobals)
{
        // get the engine functions from the engine...
        memcpy (&g_engfuncs, pengfuncsFromEngine, sizeof (g_engfuncs));
        gpGlobals = pGlobals;
 
        SetupLightStyles ();
}
static void pfnLightStyle (int style, char *value)
{
        LIGHT_STYLE (style, value);
        or ->>---------->>------------->>---------------------->>-------------------|
                                                                                                                                                                |
        // Update light style for fake clients....                                                                        |
        CallbackLightStyle (static_cast <const unsigned char> (style), value);                |
                                                                                                                                                                |
        RETURN_META (MRES_IGNORED);        <------------------<<------------<<-------------|
}
static void pfnStartFrame (void)
{
        // this function starts a video frame. It is called once per video frame by the engine. If
        // you run Half-Life at 90 fps, this function will then be called 90 times per second. By
        // placing a hook on it, we have a good place to do things that should be done continuously
        // during the game, for example making the bots think (yes, because no Think() function exists
        // for the bots by the MOD side, remember). Also here we have control on the bot population,
        // for example if a new player joins the server, we should disconnect a bot, and if the
        // player population decreases, we should fill the server with other bots.

        CallbackStartFrame ();

        (*g_engfuncs.pfnStartFrame) ();
        or
        RETURN_META (MRES_IGNORED);
}
static void PM_Move (playermove_t *playerMove, BOOL server)
{
        // this is the player movement code clients run to predict things when the server can't update
        // them often enough (or doesn't want to). The server runs exactly the same function for
        // moving players. There is normally no distinction between them, else client-side prediction
        // wouldn't work properly (and it doesn't work that well, already...)

        CallbackPM_Move (playerMove, server == TRUE);

        (*g_engfuncs.pfnPM_Move) (playerMove, server);
        or
        RETURN_META (MRES_IGNORED);
}

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
{
//static const mplane_t *lightplane (NULL);
//static Vector lightspot;
static Color g_pointColor;

static const bool RecursiveLightPoint (const mnode_t *const node, const Vector &start, const Vector &end)
{
        float front, back, frac;
        int side;
        mplane_t *plane;
        Vector mid;
        msurface_t *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 = (start | plane->normal) - plane->dist;
        back = (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 (node->children[side], start, end);

        // calculate mid point
        frac = front / (front - back);
        mid = start + (end - start) * frac;

        // go down front side       
        if (RecursiveLightPoint (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 = 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> ((mid | Vector (tex->vecs[0])) + tex->vecs[0][3]);
                t = static_cast <int> ((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 (node->children[!side], mid, end);
}

static inline const unsigned char R_LightPoint (const Vector &p)
{
        // Reliability check.
        assert (sv_worldmodel != NULL);

        if (sv_worldmodel->lightdata == NULL)
                return 255u;

        Vector end (p);

        end.z -= 2048.0f;

        return RecursiveLightPoint (sv_worldmodel->nodes, p, end) == false ? 0u : static_cast <unsigned char> (g_pointColor.GetAvg ());
}
}

static inline const char *const FormatBuffer (const char *const format, ...)
{
        static char string[4096u];

        va_list argumentPointer;

        // Concatenate all the arguments in one string....
        va_start (argumentPointer, format);
                vsnprintf (string, sizeof (string), format, argumentPointer);
        va_end (argumentPointer);

        return string;
}

inline void ShowMagic (void)
{
        const edict_t *const hostPlayerEdict (INDEXENT (1u));

        if (hostPlayerEdict == NULL || hostPlayerEdict->free)
                return;

        CLIENT_PRINTF (hostPlayerEdict, print_chat, FormatBuffer ("ShowMagic(): \"%s\"->v.light_level=%i, R_LightPoint(hostOrg)=%i\n", STRING (hostPlayerEdict->v.netname), hostPlayerEdict->v.light_level, Light::R_LightPoint (hostPlayerEdict->v.origin)));
}

Now bots don't need to create fakeIlluminationEntity for illumination reception!!!!!!!!!!!!!!!!!

The Storm 04-02-2012 12:52

Re: code to get the illumination at any point on the map
 
Thank you again for your time in discovering/reversing what Valve should give us by default.

I didn't look at the code very deeply, so sorry if my question is obvious.
Is it PM_Move requred? Because actually this is only valid in Listen server mode.

Immortal_BLG 04-02-2012 13:50

Re: code to get the illumination at any point on the map
 
Quote:

Originally Posted by The Storm
Is it PM_Move requred? Because actually this is only valid in Listen server mode.

You're 100 percent right, but I started from the fact that the server will be present, or the person editing the waypoints (for example exposing the illumination for waypoints), or bots, for which in fact I posted the code because I wanted to have it replaced illuminationEntity for bots.

IMPORTANT NOTE that I forgot to write in the first post: The code will work if at least one client will be present on the server!!!

P.S. Why I have made reception 'sv.worldmodel' of structure 'playermove_t'? Because this is probably the only way without the use of wild hooks.....

The Storm 05-02-2012 13:39

Re: code to get the illumination at any point on the map
 
Ok, but I think there is anoder fall. It is bad ides to save illumination in waypoits, because of the many mods that exists( like AMXX ) that depending on some condition can change the light level in some area. Then if the waypoits are holding such data it will become invalid.

Immortal_BLG 06-02-2012 03:21

Re: code to get the illumination at any point on the map
 
It was a simple example.

And now about the actual fall :)
Now I have understood, why the Valve haven't changed structure which I posted.
The reason is that the structures which are currently in HLSDK intended for a dedicated server (swds.dll), and those structures that I have posted are used in the listen server (hw.dll) to work with openGL.

Well now that in this situation will have to take into account the type of server (listen/dedicated) and on the basis of it to choose structure.... :(

So modified code is here (The prefix "GL_" for names of structures is added, has replaced 'GL_texture_t::UNKNOWN[2u]' to original members, fixed offset for 'GL_mnode_t::numsurfaces', function RecursiveLightPoint() now a template, added function ActualRecursiveLightPoint(), the call in function 'R_LightPoint' of function 'RecursiveLightPoint' has been changed to a call 'ActualRecursiveLightPoint')

Code:

struct GL_texture_t        // NOT USED BY LIGHTING CODE, BUT STILL AS BONUS
{
/*! Off=0(0)*/        char                name[16];
/*! Off=16(4)*/        unsigned int        width, height;
/*! Off=24(6)*/        int                        gl_texturenum;
/*! Off=28(7)*/        msurface_t        *texturechain;        // for gl_texsort drawing
/*! Off=32(8)*/        int                        anim_total;                                // total tenths in sequence (0 = no)
/*! Off=36(9)*/        int                        anim_min, anim_max;                // time for this frame min <=time< max
/*! Off=44(11)*/        texture_t *anim_next;                // in the animation sequence
/*! Off=48(12)*/        texture_t *alternate_anims;        // bmodels in frame 1 use these
/*! Off=52(13)*/        unsigned int        offsets[MIPLEVELS];                // four mip maps stored
/*! Off=68(17)*/        unsigned int        paloffset;
};        // sizeof (GL_texture_t) == 72 (18)
struct GL_mleaf_t        // NOT USED BY LIGHTING CODE, BUT STILL HERE AS A BONUS
{
// common with node
/*! Off=0(0)*/        int                        contents;                // wil be a negative contents number
/*! 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;

// leaf specific
/*! Off=36(9)*/        unsigned char                *compressed_vis;
/*! Off=40(10)*/        efrag_t        *efrags;

/*! Off=44(11)*/        msurface_t        **firstmarksurface;
/*! Off=48(12)*/        int                        nummarksurfaces;
/*! Off=52(13)*/        int                        key;                        // BSP sequence number for leaf's contents
/*! Off=56(14)*/        unsigned char                ambient_sound_level[NUM_AMBIENTS];
};        // sizeof (GL_mleaf_t) == 60 (15)
struct GL_msurface_t
{
/*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)*/        BOOL        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];
};

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.

static inline void SetupLightStyles (void)
{
        // Setup lighting information....

        // reset all light styles
        for (unsigned char index (0u); index < MAX_LIGHTSTYLES; ++index)
        {
                cl_lightstyle.length = 0u;
                cl_lightstyle.map[0u] = '\0';
        }

        for (unsigned short index (0u); index < MAX_LIGHTSTYLEVALUE; ++index)
                d_lightstylevalue[index] = 264;        // normal light value
}

static inline void R_AnimateLight (void)
{
        // light animations
        // 'm' is normal light, 'a' is no light, 'z' is double bright
        const int i (static_cast <int> (gpGlobals->time * 10.0f));
        int k;

        for (unsigned char j (0u); j < MAX_LIGHTSTYLES; ++j)
        {
                if (cl_lightstyle[j].length == 0u)
                {
                        d_lightstylevalue[j] = 256;

                        continue;
                }

                k = cl_lightstyle[j].map[i % cl_lightstyle[j].length] - 'a';
                k *= 22;

                d_lightstylevalue[j] = k;
        }       
}

static inline void CallbackLightStyle (const unsigned char style, char *const value)
{
        if (style >= MAX_LIGHTSTYLES)
        {
                g_engfuncs.ServerPrintf ("SVC_LIGHTSTYLE > MAX_LIGHTSTYLES\n");

                return;
        }

        // OCCURS!
        if (value == NULL)
        {
                cl_lightstyle[style].length = 0u;
                cl_lightstyle[style].map[0u] = '\0';

                return;
        }

        const unsigned short maximumCopyAmount (sizeof (cl_lightstyle[style].map) - sizeof ('\0'));

        strncpy (cl_lightstyle[style].map, value, maximumCopyAmount);

        cl_lightstyle[style].map[maximumCopyAmount] = '\0';

        cl_lightstyle[style].length = strlen (cl_lightstyle[style].map);
}
static inline void CallbackStartFrame (void)
{
        R_AnimateLight ();

        inline void ShowMagic (void);

        ShowMagic ();
}
static inline void CallbackPM_Move (playermove_t *const playerMove, const bool server)
{
        // Reliability checks.
        assert (playerMove != NULL);
        assert (server == true);        // ALWAYS SHOULD BE TRUE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

        // Honestly this is need only once per changelevel, but....
        sv_worldmodel = playerMove->physents[0u].model;        // Always point at sv.worldmodel!

        // Reliability check.
        assert (sv_worldmodel != NULL);
}

static WINAPI GiveFnptrsToDll (enginefuncs_t *pengfuncsFromEngine, globalvars_t *pGlobals)
{
        // get the engine functions from the engine...
        memcpy (&g_engfuncs, pengfuncsFromEngine, sizeof (g_engfuncs));
        gpGlobals = pGlobals;
 
        SetupLightStyles ();
}
static void pfnLightStyle (int style, char *value)
{
        LIGHT_STYLE (style, value);
        or ->>---------->>------------->>---------------------->>-------------------|
                                                                                                                                                                |
        // Update light style for fake clients....                                                                        |
        CallbackLightStyle (static_cast <const unsigned char> (style), value);                |
                                                                                                                                                                |
        RETURN_META (MRES_IGNORED);        <------------------<<------------<<-------------|
}
static void pfnStartFrame (void)
{
        // this function starts a video frame. It is called once per video frame by the engine. If
        // you run Half-Life at 90 fps, this function will then be called 90 times per second. By
        // placing a hook on it, we have a good place to do things that should be done continuously
        // during the game, for example making the bots think (yes, because no Think() function exists
        // for the bots by the MOD side, remember). Also here we have control on the bot population,
        // for example if a new player joins the server, we should disconnect a bot, and if the
        // player population decreases, we should fill the server with other bots.

        CallbackStartFrame ();

        (*g_engfuncs.pfnStartFrame) ();
        or
        RETURN_META (MRES_IGNORED);
}
static void PM_Move (playermove_t *playerMove, BOOL server)
{
        // this is the player movement code clients run to predict things when the server can't update
        // them often enough (or doesn't want to). The server runs exactly the same function for
        // moving players. There is normally no distinction between them, else client-side prediction
        // wouldn't work properly (and it doesn't work that well, already...)

        CallbackPM_Move (playerMove, server == TRUE);

        (*g_engfuncs.pfnPM_Move) (playerMove, server);
        or
        RETURN_META (MRES_IGNORED);
}

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
{
//static const mplane_t *lightplane (NULL);
//static Vector lightspot;
static Color g_pointColor;

template <typename nodeType, typename surfaceType> static 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 = (start | plane->normal) - plane->dist;
        back = (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> ((mid | Vector (tex->vecs[0])) + tex->vecs[0][3]);
                t = static_cast <int> ((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);
}
const bool ActualRecursiveLightPoint (const Math::Vector3D &start, const Math::Vector3D &end)
{
        return IS_DEDICATED_SERVER () ?
                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);
}

static inline const unsigned char R_LightPoint (const Vector &p)
{
        // Reliability check.
        assert (sv_worldmodel != NULL);

        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 ());
}
}

static inline const char *const FormatBuffer (const char *const format, ...)
{
        static char string[4096u];

        va_list argumentPointer;

        // Concatenate all the arguments in one string....
        va_start (argumentPointer, format);
                vsnprintf (string, sizeof (string), format, argumentPointer);
        va_end (argumentPointer);

        return string;
}

inline void ShowMagic (void)
{
        const edict_t *const hostPlayerEdict (INDEXENT (1u));

        if (hostPlayerEdict == NULL || hostPlayerEdict->free)
                return;

        CLIENT_PRINTF (hostPlayerEdict, print_chat, FormatBuffer ("ShowMagic(): \"%s\"->v.light_level=%i, R_LightPoint(hostOrg)=%i\n", STRING (hostPlayerEdict->v.netname), hostPlayerEdict->v.light_level, Light::R_LightPoint (hostPlayerEdict->v.origin)));
}

P.S. Excuse if that and also sorry for bad english

SamPlay 12-02-2012 13:19

Re: code to get the illumination at any point on the map
 
Hi,
I think that looking at the modified common/com_model.h file in the hlsdk23_msvc2008.zip downloadable from
http://www.moddb.com/games/half-life/downloads/half-life-sdk-v23-for-visual-studio-2008
will provide you with useful information on data structure you addressed.
regards.

Immortal_BLG 13-02-2012 04:54

Re: code to get the illumination at any point on the map
 
It seems that Mr. "Gary_McTaggart" has already made it long before me. :) I on the computer had this archive, however I have missed these changes. Thanks!

KWo 25-02-2012 20:43

Re: code to get the illumination at any point on the map
 
After very fast look at Your code (of course without understanding it) I haven't seen the call for this function:
#define GETENTITYILLUM (*g_engfuncs.pfnGetEntityIllum)
I don't know it this is no longer needed or what. But I had troubles with that function - it works perfectly on a windows server, but it always gives 0 as a return value on a linux server. So - did You check if Your code is working on both - linux and windows server?

Immortal_BLG 27-02-2012 02:28

Re: code to get the illumination at any point on the map
 
Hello KWo!

Quote:

Originally Posted by KWo
I had troubles with that function - it works perfectly on a windows server, but it always gives 0 as a return value on a linux server.

Fairly I admit - I don't know why on LINUX function GetEntityIllum always returns 0 and also how to solve this problem, all that I can is to show code of function GetEntityIllum to you:
Code:

//----- (01D82AE0) --------------------------------------------------------
int GetEntityIllum (edict_t *const edict)
{
        if (edict == NULL)
                return -1;

        const unsigned int edictIndex (NUM_FOR_EDICT (edict));

        if (edictIndex <= svs.maxclients)
                return edict->v.light_level;        // player has more precision light level that come from client-side

        if (cls.state == 3/*! MAYBE 'ca_connected', BUT NOT SHURE!!! */ || cls.state == 4/*! MAYBE 'ca_active', BUT NOT SHURE!!! */ || cls.state == 5/*! @warning DON'T KNOW!!! */)
        {
                const colorVec &cvFloorColor (cl_entities[edictIndex].cvFloorColor);

                return (cvFloorColor.r + cvFloorColor.g + cvFloorColor.b) / 3u;
        }

        return 128;
}

And 'edict->v.light_level' is assigned approximately so:
edict->v.light_level = R_LightPoint (edict->v.origin);

Quote:

Originally Posted by KWo
did You check if Your code is working on both - linux and windows server?

The answer is no, because I do not have LINUX. However, I think that everything should work. The only thing I want to recommend - is to change line
Code:

assert (sv_worldmodel != NULL);
to
Code:

if (sv_worldmodel == NULL)
        return 0u;

in the beginning of function R_LightPoint() just in case.

And one more: it is necessary to replace in function "ActualRecursiveLightPoint()" call "IsSoftwareDrawingMode()" instead of a call of function "IS_DEDICATED_SERVER()" and to define this function so:
Code:

inline const bool IsSoftwareDrawingMode (void)
{
        static const bool isSoftwareDrawingMode (IS_DEDICATED_SERVER () || GetModuleHandle ("sw.dll") != NULL);

        return isSoftwareDrawingMode;
}

It is made that the client could play without crashing on software mode. Sorry forgot about it....

KWo 12-03-2012 21:20

Re: code to get the illumination at any point on the map
 
OK - I'm getting confused after reading that. What should I do in HLSDK files, and what in bot code files? I mean which changes should be applied to HLSDK files and which should be applied to bot cpp/h files?

Immortal_BLG 13-03-2012 03:34

Re: code to get the illumination at any point on the map
 
You should add or in HLSDK, or somewhere in the header file of the bot of structures with a prefix "GL_".
Generally, for your bot it is necessary to add simply all code, from my fifth post and if it is concrete:
Code:

// "bot_globals.h"
//{
#include <com_model.h>        // WARNING: Probably it is necessary to add any additional includes....

struct GL_msurface_t
{
/*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)*/        BOOL        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;

template <typename nodeType, typename surfaceType> extern const bool RecursiveLightPoint (const nodeType *const node, const Vector &start, const Vector &end);

inline const bool IsSoftwareDrawingMode (void)
{
        static const bool isSoftwareDrawingMode (IS_DEDICATED_SERVER () || GetModuleHandle ("sw.dll") != NULL);

        return isSoftwareDrawingMode;
}
inline const bool ActualRecursiveLightPoint (const Math::Vector3D &start, const Math::Vector3D &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"
//{
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.
//}

// "dll.cpp"
//{
static inline const char *const FormatBuffer (const char *const format, ...)
{
        /// @todo REMOVE THIS SHIT

        static char string[4096u];

        va_list argumentPointer;

        // Concatenate all the arguments in one string....
        va_start (argumentPointer, format);
                vsnprintf (string, sizeof (string), format, argumentPointer);
        va_end (argumentPointer);

        return string;
}
inline void ShowMagic (void)
{
        /// @todo REMOVE THIS SHIT

        const edict_t *const hostPlayerEdict (INDEXENT (1u));

        if (hostPlayerEdict == NULL || hostPlayerEdict->free || (hostPlayerEdict->v.flags & FL_FAKECLIENT))
                return;

        CLIENT_PRINTF (hostPlayerEdict, print_chat, FormatBuffer ("ShowMagic(): \"%s\"->v.light_level=%i, R_LightPoint(hostOrg)=%i\n", STRING (hostPlayerEdict->v.netname), hostPlayerEdict->v.light_level, Light::R_LightPoint (hostPlayerEdict->v.origin)));
}

static inline void SetupLightStyles (void)
{
        // Setup lighting information....

        // reset all light styles
        for (unsigned char index (0u); index < MAX_LIGHTSTYLES; ++index)
        {
                cl_lightstyle.length = 0u;
                cl_lightstyle.map[0u] = '\0';
        }

        for (unsigned short index (0u); index < MAX_LIGHTSTYLEVALUE; ++index)
                d_lightstylevalue[index] = 264;        // normal light value
}

static inline void R_AnimateLight (void)
{
        // light animations
        // 'm' is normal light, 'a' is no light, 'z' is double bright
        const int i (static_cast <int> (gpGlobals->time * 10.0f));
        int k;

        for (unsigned char j (0u); j < MAX_LIGHTSTYLES; ++j)
        {
                if (cl_lightstyle[j].length == 0u)
                {
                        d_lightstylevalue[j] = 256;

                        continue;
                }

                k = cl_lightstyle[j].map[i % cl_lightstyle[j].length] - 'a';
                k *= 22;

                d_lightstylevalue[j] = k;
        }       
}

static inline void CallbackStartFrame (void)
{
        R_AnimateLight ();

        /// @todo REMOVE THIS SHIT
        {
        inline void ShowMagic (void);

        ShowMagic ();
        }
}
static inline void CallbackPM_Move (playermove_t *const playerMove, const bool server)
{
        // Reliability checks.
        assert (playerMove != NULL);
        assert (server == true);        // ALWAYS SHOULD BE TRUE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

        // Honestly this is need only once per changelevel, but....
        sv_worldmodel = playerMove->physents[0u].model;        // Always point at sv.worldmodel!

        // Reliability check.
        assert (sv_worldmodel != NULL);
}

/////////////////////////////////// BEGIN OF DLL API FORWARDS ///////////////////////////////////
WINAPI GiveFnptrsToDll (enginefuncs_t *pengfuncsFromEngine, globalvars_t *pGlobals)
{
        // get the engine functions from the engine...

        memcpy (&g_engfuncs, pengfuncsFromEngine, sizeof (enginefuncs_t));
        gpGlobals = pGlobals;

        SetupLightStyles ();
}
// Called each Server frame at the very beginning
void StartFrame (void)
{
        CallbackStartFrame ();

        /// ... PART OF YOUR CODE HERE

        RETURN_META (MRES_IGNORED);
}
static void PM_Move (playermove_t *playerMove, BOOL server)        // NEW FORWARD FOR YOUR BOT!!!
{
        // this is the player movement code clients run to predict things when the server can't update
        // them often enough (or doesn't want to). The server runs exactly the same function for
        // moving players. There is normally no distinction between them, else client-side prediction
        // wouldn't work properly (and it doesn't work that well, already...)

        CallbackPM_Move (playerMove, server == TRUE);

        RETURN_META (MRES_IGNORED);
}
/////////////////////////////////// END OF DLL API FORWARDS ///////////////////////////////////

C_DLLEXPORT int GetEntityAPI2 (DLL_FUNCTIONS *pFunctionTable, int *interfaceVersion)
{
  gFunctionTable.pfnGameInit = GameDLLInit;
  gFunctionTable.pfnSpawn = Spawn;
  gFunctionTable.pfnClientConnect = ClientConnect;
  gFunctionTable.pfnClientDisconnect = ClientDisconnect;
  gFunctionTable.pfnClientPutInServer = ClientPutInServer;
  gFunctionTable.pfnClientCommand = ClientCommand;
  gFunctionTable.pfnServerActivate = ServerActivate;
  gFunctionTable.pfnServerDeactivate = ServerDeactivate;
  gFunctionTable.pfnStartFrame = StartFrame;
  gFunctionTable.pfnKeyValue = Pfn_KeyValue;                  // KWo - 06.03.2006
  gFunctionTable.pfnPM_Move = PM_Move;        // NEW FORWARD FOR YOUR BOT!!!
  gFunctionTable.pfnUpdateClientData = Pfn_UpdateClientData;  // KWo - 02.03.2010

  memcpy (pFunctionTable, &gFunctionTable, sizeof (DLL_FUNCTIONS));
  return (TRUE);
}
//}

// "engine.cpp"
//{
static inline void CallbackLightStyle (const unsigned char style, char *const value)
{
        if (style >= MAX_LIGHTSTYLES)
        {
                g_engfuncs.ServerPrintf ("SVC_LIGHTSTYLE > MAX_LIGHTSTYLES\n");

                return;
        }

        // OCCURS!
        if (value == NULL)
        {
                cl_lightstyle[style].length = 0u;
                cl_lightstyle[style].map[0u] = '\0';

                return;
        }

        const unsigned short maximumCopyAmount (sizeof (cl_lightstyle[style].map) - sizeof ('\0'));

        strncpy (cl_lightstyle[style].map, value, maximumCopyAmount);

        cl_lightstyle[style].map[maximumCopyAmount] = '\0';

        cl_lightstyle[style].length = strlen (cl_lightstyle[style].map);
}

/////////////////////////////////// BEGIN OF ENGINE API FORWARDS ///////////////////////////////////
static void pfnLightStyle (int style, char *value)        // NEW FORWARD FOR YOUR BOT!!!
{
        // Update light style for fake clients....
        CallbackLightStyle (static_cast <const unsigned char> (style), value);

        RETURN_META (MRES_IGNORED);
}

C_DLLEXPORT int GetEngineFunctions (enginefuncs_t *pengfuncsFromEngine, int *interfaceVersion)
{
  meta_engfuncs.pfnChangeLevel = pfnChangeLevel;
  meta_engfuncs.pfnEmitSound = pfnEmitSound;
  meta_engfuncs.pfnFindEntityByString = pfnFindEntityByString;
  meta_engfuncs.pfnClientCommand = pfnClientCommand;
  meta_engfuncs.pfnLightStyle = pfnLightStyle;        // NEW FORWARD FOR YOUR BOT!!!
  meta_engfuncs.pfnMessageBegin = pfnMessageBegin;
  meta_engfuncs.pfnMessageEnd = pfnMessageEnd;
  meta_engfuncs.pfnWriteByte = pfnWriteByte;
  meta_engfuncs.pfnWriteChar = pfnWriteChar;
  meta_engfuncs.pfnWriteShort = pfnWriteShort;
  meta_engfuncs.pfnWriteLong = pfnWriteLong;
  meta_engfuncs.pfnWriteAngle = pfnWriteAngle;
  meta_engfuncs.pfnWriteCoord = pfnWriteCoord;
  meta_engfuncs.pfnWriteString = pfnWriteString;
  meta_engfuncs.pfnWriteEntity = pfnWriteEntity;
  meta_engfuncs.pfnClientPrintf = pfnClientPrintf;
  meta_engfuncs.pfnCmd_Args = pfnCmd_Args;
  meta_engfuncs.pfnCmd_Argv = pfnCmd_Argv;
  meta_engfuncs.pfnCmd_Argc = pfnCmd_Argc;
  meta_engfuncs.pfnSetClientMaxspeed = pfnSetClientMaxspeed;
  meta_engfuncs.pfnGetPlayerWONId = pfnGetPlayerWONId;
  meta_engfuncs.pfnGetPlayerAuthId = pfnGetPlayerAuthId;

  memcpy (pengfuncsFromEngine, &meta_engfuncs, sizeof (enginefuncs_t));
  return (TRUE);
}
/////////////////////////////////// END OF ENGINE API FORWARDS ///////////////////////////////////
//}

// "util.cpp"
//{
/*
=============================================================================

LIGHT SAMPLING

=============================================================================
*/
namespace Light
{
//const mplane_t *lightplane (NULL);
//Vector lightspot;
Color g_pointColor;

template <typename nodeType, typename surfaceType> 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 = (start | plane->normal) - plane->dist;
        back = (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> ((mid | Vector (tex->vecs[0])) + tex->vecs[0][3]);
                t = static_cast <int> ((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);
}
}
//}

Well everything seems to be....

KWo 15-03-2012 20:59

Re: code to get the illumination at any point on the map
 
Quote:

Originally Posted by ERROR_LOG
>d:\tools\compile\mingw\proj\podbot\bot_globals.h( 442) : error C2653: 'Math' : is not a class or namespace name
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (442) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (442) : error C2143: syntax error : missing ',' before '&'
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (445) : error C2065: 'start' : undeclared identifier
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (445) : error C2065: 'end' : undeclared identifier
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (446) : error C2065: 'start' : undeclared identifier
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (446) : error C2065: 'end' : undeclared identifier
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (462) : error C2660: 'Light::ActualRecursiveLightPoint' : function does not take 2 arguments
1>waypoint.cpp
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (442) : error C2653: 'Math' : is not a class or namespace name
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (442) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (442) : error C2143: syntax error : missing ',' before '&'
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (445) : error C2065: 'start' : undeclared identifier
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (445) : error C2065: 'end' : undeclared identifier
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (446) : error C2065: 'start' : undeclared identifier
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (446) : error C2065: 'end' : undeclared identifier
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (462) : error C2660: 'Light::ActualRecursiveLightPoint' : function does not take 2 arguments
1>util.cpp
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (442) : error C2653: 'Math' : is not a class or namespace name
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (442) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (442) : error C2143: syntax error : missing ',' before '&'
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (445) : error C2065: 'start' : undeclared identifier
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (445) : error C2065: 'end' : undeclared identifier
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (446) : error C2065: 'start' : undeclared identifier
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (446) : error C2065: 'end' : undeclared identifier
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (462) : error C2660: 'Light::ActualRecursiveLightPoint' : function does not take 2 arguments
1>engine.cpp
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (442) : error C2653: 'Math' : is not a class or namespace name
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (442) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (442) : error C2143: syntax error : missing ',' before '&'
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (445) : error C2065: 'start' : undeclared identifier
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (445) : error C2065: 'end' : undeclared identifier
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (446) : error C2065: 'start' : undeclared identifier
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (446) : error C2065: 'end' : undeclared identifier
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (462) : error C2660: 'Light::ActualRecursiveLightPoint' : function does not take 2 arguments
1>.\engine.cpp(592) : error C2039: 'ServerPrintf' : is not a member of 'enginefuncs_s'
1> ../hlsdk\multiplayer\engine\eiface.h(106) : see declaration of 'enginefuncs_s'
1>dll.cpp
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (442) : error C2653: 'Math' : is not a class or namespace name
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (442) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (442) : error C2143: syntax error : missing ',' before '&'
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (445) : error C2065: 'start' : undeclared identifier
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (445) : error C2065: 'end' : undeclared identifier
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (446) : error C2065: 'start' : undeclared identifier
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (446) : error C2065: 'end' : undeclared identifier
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (462) : error C2660: 'Light::ActualRecursiveLightPoint' : function does not take 2 arguments
1>.\dll.cpp(238 ) : error C3861: 'SetupLightStyles': identifier not found
1>.\dll.cpp(1902) : error C3861: 'CallbackStartFrame': identifier not found
1>.\dll.cpp(2368 ) : error C2065: 'playermove_t' : undeclared identifier
1>.\dll.cpp(2368 ) : error C2065: 'playerMove' : undeclared identifier
1>.\dll.cpp(2368 ) : error C2275: 'BOOL' : illegal use of this type as an expression
1> C:\Program Files\Microsoft SDKs\Windows\v6.0A\\include\windef.h(153) : see declaration of 'BOOL'
1>.\dll.cpp(2368 ) : error C2146: syntax error : missing ')' before identifier 'server'
1>.\dll.cpp(2368 ) : error C2182: 'PM_Move' : illegal use of type 'void'
1>.\dll.cpp(2368 ) : error C2078: too many initializers
1>.\dll.cpp(2368 ) : error C2275: 'BOOL' : illegal use of this type as an expression
1> C:\Program Files\Microsoft SDKs\Windows\v6.0A\\include\windef.h(153) : see declaration of 'BOOL'
1>.\dll.cpp(2368 ) : error C2059: syntax error : ')'
1>.\dll.cpp(2369) : error C2143: syntax error : missing ';' before '{'
1>.\dll.cpp(2369) : error C2447: '{' : missing function header (old-style formal list?)
1>.\dll.cpp(3708 ) : error C2664: 'void (edict_t *,PRINT_TYPE,const char *)' : cannot convert parameter 1 from 'const edict_t *const ' to 'edict_t *'
1> Conversion loses qualifiers
1>.\dll.cpp(3718 ) : error C2228: left of '.length' must have class/struct/union
1> type is 'lightstyle_t [64]'
1>.\dll.cpp(3719) : error C2228: left of '.map' must have class/struct/union
1> type is 'lightstyle_t [64]'
1>.\dll.cpp(3760) : error C2065: 'playermove_t' : undeclared identifier
1>.\dll.cpp(3760) : error C2059: syntax error : 'const'
1>.\dll.cpp(3761) : error C2143: syntax error : missing ';' before '{'
1>.\dll.cpp(3761) : error C2447: '{' : missing function header (old-style formal list?)
1>.\dll.cpp(3785) : error C2440: '=' : cannot convert from 'int' to 'void (__cdecl *)(playermove_s *,qboolean)'
1> Conversion from integral type to pointer type requires reinterpret_cast, C-style cast or function-style cast
1>bot_sounds.cpp
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (442) : error C2653: 'Math' : is not a class or namespace name
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (442) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (442) : error C2143: syntax error : missing ',' before '&'
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (445) : error C2065: 'start' : undeclared identifier
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (445) : error C2065: 'end' : undeclared identifier
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (446) : error C2065: 'start' : undeclared identifier
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (446) : error C2065: 'end' : undeclared identifier
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (462) : error C2660: 'Light::ActualRecursiveLightPoint' : function does not take 2 arguments
1>bot_navigate.cpp
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (442) : error C2653: 'Math' : is not a class or namespace name
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (442) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (442) : error C2143: syntax error : missing ',' before '&'
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (445) : error C2065: 'start' : undeclared identifier
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (445) : error C2065: 'end' : undeclared identifier
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (446) : error C2065: 'start' : undeclared identifier
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (446) : error C2065: 'end' : undeclared identifier
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (462) : error C2660: 'Light::ActualRecursiveLightPoint' : function does not take 2 arguments
1>bot_globals.cpp
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (442) : error C2653: 'Math' : is not a class or namespace name
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (442) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (442) : error C2143: syntax error : missing ',' before '&'
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (445) : error C2065: 'start' : undeclared identifier
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (445) : error C2065: 'end' : undeclared identifier
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (446) : error C2065: 'start' : undeclared identifier
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (446) : error C2065: 'end' : undeclared identifier
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (462) : error C2660: 'Light::ActualRecursiveLightPoint' : function does not take 2 arguments
1>bot_combat.cpp
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (442) : error C2653: 'Math' : is not a class or namespace name
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (442) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (442) : error C2143: syntax error : missing ',' before '&'
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (445) : error C2065: 'start' : undeclared identifier
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (445) : error C2065: 'end' : undeclared identifier
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (446) : error C2065: 'start' : undeclared identifier
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (446) : error C2065: 'end' : undeclared identifier
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (462) : error C2660: 'Light::ActualRecursiveLightPoint' : function does not take 2 arguments
1>bot_client.cpp
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (442) : error C2653: 'Math' : is not a class or namespace name
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (442) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (442) : error C2143: syntax error : missing ',' before '&'
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (445) : error C2065: 'start' : undeclared identifier
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (445) : error C2065: 'end' : undeclared identifier
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (446) : error C2065: 'start' : undeclared identifier
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (446) : error C2065: 'end' : undeclared identifier
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (462) : error C2660: 'Light::ActualRecursiveLightPoint' : function does not take 2 arguments
1>bot_chat.cpp
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (442) : error C2653: 'Math' : is not a class or namespace name
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (442) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (442) : error C2143: syntax error : missing ',' before '&'
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (445) : error C2065: 'start' : undeclared identifier
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (445) : error C2065: 'end' : undeclared identifier
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (446) : error C2065: 'start' : undeclared identifier
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (446) : error C2065: 'end' : undeclared identifier
1>d:\tools\compile\mingw\proj\podbot\bot_globals.h (462) : error C2660: 'Light::ActualRecursiveLightPoint' : function does not take 2 arguments
1>Generating Code...
1>Build log was saved at "file://d:\TOOLS\Compile\MinGW\PROJ\podbot\Release\BuildLo g.htm"
1>PodBot_mm - 109 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

It would be much more easy if You could post a working code instead just examples... :)

[EDIT]
If You want to see my code - send me a pm with Your email address, I can send it You that way. I wanted to upload it at the mirror of the filebase (CFE server), but it looks like Ancient has changed some access rights and nobody can browse my files there. :(
[/EDIT]

Immortal_BLG 16-03-2012 02:33

Re: code to get the illumination at any point on the map
 
Quote:

Originally Posted by KWo (Post 64319)
It would be much more easy if You could post a working code instead just examples... :)

[EDIT]
If You want to see my code - send me a pm with Your email address, I can send it You that way. I wanted to upload it at the mirror of the filebase (CFE server), but it looks like Ancient has changed some access rights and nobody can browse my files there. :(
[/EDIT]

Eventually I decided to compile the project podbot_mm (in MSVC 2010) yourself, pre-inserting my code in order to eliminate all errors at the building.
So KWo HERE you can take the project (the source code and DLL), and below I present the corrected code:
Code:

#include <com_model.h>
#include <pm_defs.h>

#define        SURF_PLANEBACK                2
#define        SURF_DRAWSKY                4
#define SURF_DRAWSPRITE                8
#define SURF_DRAWTURB                0x10
#define SURF_DRAWTILED                0x20
#define SURF_DRAWBACKGROUND        0x40

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];
};

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.

static inline void SetupLightStyles (void)
{
        // Setup lighting information....

        // reset all light styles
        for (unsigned char index (0u); index < MAX_LIGHTSTYLES; ++index)
        {
                cl_lightstyle[index].length = 0u;
                cl_lightstyle[index].map[0u] = '\0';
        }

        for (unsigned short index (0u); index < MAX_LIGHTSTYLEVALUE; ++index)
                d_lightstylevalue[index] = 264;        // normal light value
}

static inline void R_AnimateLight (void)
{
        // light animations
        // 'm' is normal light, 'a' is no light, 'z' is double bright
        const int i (static_cast <int> (gpGlobals->time * 10.0f));
        int k;

        for (unsigned char j (0u); j < MAX_LIGHTSTYLES; ++j)
        {
                if (cl_lightstyle[j].length == 0u)
                {
                        d_lightstylevalue[j] = 256;

                        continue;
                }

                k = cl_lightstyle[j].map[i % cl_lightstyle[j].length] - 'a';
                k *= 22;

                d_lightstylevalue[j] = k;
        }       
}

static inline void CallbackLightStyle (const unsigned char style, char *const value)
{
        if (style >= MAX_LIGHTSTYLES)
        {
                g_engfuncs.pfnServerPrint ("SVC_LIGHTSTYLE > MAX_LIGHTSTYLES\n");

                return;
        }

        // OCCURS!
        if (value == NULL)
        {
                cl_lightstyle[style].length = 0u;
                cl_lightstyle[style].map[0u] = '\0';

                return;
        }

        const unsigned short maximumCopyAmount (sizeof (cl_lightstyle[style].map) - sizeof ('\0'));

        strncpy (cl_lightstyle[style].map, value, maximumCopyAmount);

        cl_lightstyle[style].map[maximumCopyAmount] = '\0';

        cl_lightstyle[style].length = strlen (cl_lightstyle[style].map);
}
static inline void CallbackStartFrame (void)
{
        R_AnimateLight ();

        inline void ShowMagic (void);

        ShowMagic ();
}
static inline void CallbackPM_Move (playermove_t *const playerMove, const bool server)
{
        // Reliability checks.
        assert (playerMove != NULL);
        assert (server == true);        // ALWAYS SHOULD BE TRUE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

        // Honestly this is need only once per changelevel, but....
        sv_worldmodel = playerMove->physents[0u].model;        // Always point at sv.worldmodel!

        // Reliability check.
        assert (sv_worldmodel != NULL);
}

static WINAPI GiveFnptrsToDll (enginefuncs_t *pengfuncsFromEngine, globalvars_t *pGlobals)
{
        // get the engine functions from the engine...
        memcpy (&g_engfuncs, pengfuncsFromEngine, sizeof (g_engfuncs));
        gpGlobals = pGlobals;
 
        SetupLightStyles ();
}
static void pfnLightStyle (int style, char *value)
{
        LIGHT_STYLE (style, value);
        or ->>---------->>------------->>---------------------->>-------------------|
                                                                                                                                                                |
        // Update light style for fake clients....                                                                        |
        CallbackLightStyle (static_cast <const unsigned char> (style), value);                |
                                                                                                                                                                |
        RETURN_META (MRES_IGNORED);        <------------------<<------------<<-------------|
}
static void pfnStartFrame (void)
{
        // this function starts a video frame. It is called once per video frame by the engine. If
        // you run Half-Life at 90 fps, this function will then be called 90 times per second. By
        // placing a hook on it, we have a good place to do things that should be done continuously
        // during the game, for example making the bots think (yes, because no Think() function exists
        // for the bots by the MOD side, remember). Also here we have control on the bot population,
        // for example if a new player joins the server, we should disconnect a bot, and if the
        // player population decreases, we should fill the server with other bots.

        CallbackStartFrame ();

        (*g_engfuncs.pfnStartFrame) ();
        or
        RETURN_META (MRES_IGNORED);
}
static void PM_Move (playermove_t *playerMove, qboolean server)
{
        // this is the player movement code clients run to predict things when the server can't update
        // them often enough (or doesn't want to). The server runs exactly the same function for
        // moving players. There is normally no distinction between them, else client-side prediction
        // wouldn't work properly (and it doesn't work that well, already...)

        CallbackPM_Move (playerMove, server == TRUE);

        (*g_engfuncs.pfnPM_Move) (playerMove, server);
        or
        RETURN_META (MRES_IGNORED);
}

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
{
//static const mplane_t *lightplane (NULL);
//static Vector lightspot;
static Color g_pointColor;

template <typename nodeType, typename surfaceType> static 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;
}
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);
}

static 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 ());
}
}

inline void ShowMagic (void)
{
        edict_t *const hostPlayerEdict (INDEXENT (1u));

        if (hostPlayerEdict == NULL || hostPlayerEdict->free || hostPlayerEdict->pvPrivateData == NULL || (hostPlayerEdict->v.flags & FL_FAKECLIENT))
                return;

        char message[192];
        _snprintf (message, sizeof (message), "ShowMagic(): \"%s\"->v.light_level=%i, R_LightPoint(hostOrg)=%i\n", STRING (hostPlayerEdict->v.netname), hostPlayerEdict->v.light_level, Light::R_LightPoint (hostPlayerEdict->v.origin));
        CLIENT_PRINTF (hostPlayerEdict, print_chat, message);
}

Changes:
1) add the required headers from HLSDK;
2) added definitions of 'SURF_*' constants;
3) type 'BOOL' is changed to 'qboolean';
4) type 'Math::Vector3D' is changed to HLSDK 'Vector';
5) added check "hostPlayerEdict->pvPrivateData == NULL" in a function 'ShowMagic';
6) in a function 'SetupLightStyles' fixed bug related to 'cl_lightstyle' array.
7) changed the name of the function 'g_engfuncs.ServerPrintf' to 'g_engfuncs.pfnServerPrint'
8) function 'DotProduct' is used instead of the overloaded operator logical OR for calculation of scalar product of vectors.

Excuse me. It all is simply a consequence of the porting of code from my bot, and also because of that that I this code up until that time didn't compile/not checked properly....

KWo 16-03-2012 21:45

Re: code to get the illumination at any point on the map
 
Thanks. :)
I have added all things into my current code and I've got it finally compiling correctly (no errors and no warnings).
It was calling the function Show_Magic() for me as a Host (on my listenserver) to show me my light level (something about 178 on de_dust2). After that I have commented out the call of that function, because I couldn't use the console. Then I've checked bots light_level and it was still 0. I was using PMTOOLS from the filebase.
pEntity->v.light_level = 0
I believe Your code is to make the light_level of bots alive, but - at least on the listenserver CS1.6 steam - it doesn't do the job. Or maybe I misunderstood the point of this code?
[EDIT]
Just checked - on the dedicated server bots light_level is also still 0.
[/EDIT]

Immortal_BLG 17-03-2012 04:15

Re: code to get the illumination at any point on the map
 
Quote:

I've checked bots light_level and it was still 0. I was using PMTOOLS from the filebase.
pEntity->v.light_level = 0
I believe Your code is to make the light_level of bots alive, but - at least on the listenserver CS1.6 steam - it doesn't do the job. Or maybe I misunderstood the point of this code?
[EDIT]
Just checked - on the dedicated server bots light_level is also still 0.
[/EDIT]
Of course all that will be as you describe :D
Because you do not assign a value of illumination received after the call of "Light::R_LightPoint" to variable "bot->v.light_level"!!
To get everything working as it should you just have to after each function call "pfnRunPlayerMove" to add the code:
Code:

if (!pBot->bDead)
  pEdict->v.light_level = Light::R_LightPoint (pEdict->v.origin);

and that's all!!!

as a result the code should look like:
Code:

g_engfuncs.pfnRunPlayerMove (pEdict, vecMoveAngles, pBot->f_move_speed, pBot->f_sidemove_speed, 0, pEdict->v.button, 0, (unsigned char) i_msecval);        // KWo - 25.09.2006 - thanks to THE_STORM

if (!pBot->bDead)
  pEdict->v.light_level = Light::R_LightPoint (pEdict->v.origin);

Why after calling of function "pfnRunPlayerMove"?
Because this function resets back to zero value of bot light_level and we just restores it to normal....

KWo 17-03-2012 22:18

Re: code to get the illumination at any point on the map
 
Thanks. It works now. I have rewritten the UTIL_IlluminationOf function. I cannot remove the Illumination entity (that one based on mechgibs.mdl) because there might be still other bots on the server (like CZERO bots other podbot clone and so on) and their light_level still would be 0. :)
Or maybe there is a way to run Your function for all users/bots from my dll?

[EDIT]
I cannot compile it for linux, because of the function GetModuleHandle (coming from WinBase.h - not existing for linux). I need a replacement for linux. Whistler would help with it. :)
[/EDIT]

Immortal_BLG 18-03-2012 07:15

Re: code to get the illumination at any point on the map
 
Quote:

Originally Posted by KWo
I cannot remove the Illumination entity (that one based on mechgibs.mdl) because there might be still other bots on the server (like CZERO bots other podbot clone and so on) and their light_level still would be 0.
Or maybe there is a way to run Your function for all users/bots from my dll?

Of course you can do it!
Way 1, inaccurate:
Code:

///........................
  // Record some Stats of all Players on the Server
  g_iNum_players = 0;
  g_iNum_humans = 0;
  g_iNum_hum_tm = 0;  // KWo - 08.03.2010
  bAliveHumans = false;
  g_iAliveCTs = 0;  // KWo - 19.01.2008
  g_iAliveTs = 0;  // KWo - 19.01.2008
  for (player_index = 0; player_index < gpGlobals->maxClients; player_index++)
  {
      pPlayer = INDEXENT (player_index + 1);

      if (!FNullEnt (pPlayer) && (pPlayer->v.flags & FL_CLIENT))
      {
        g_iNum_players++;
        clients[player_index].pEdict = pPlayer;
        clients[player_index].iFlags |= CLIENT_USED;
        IsAlive (pPlayer) ? clients[player_index].iFlags |= CLIENT_ALIVE : clients[player_index].iFlags &= ~CLIENT_ALIVE;

//////////// BEGINNING OF NEW CODE \\\\\\\\\\\\\\\\\\\\\\\\
        if ((pPlayer->v.flags & FL_FAKECLIENT) && (clients[player_index].iFlags & CLIENT_ALIVE))
            pPlayer->v.light_level = Light::R_LightPoint (pPlayer->v.origin);
//////////// END OF NEW CODE \\\\\\\\\\\\\\\\\\\\\\\\
        if ((clients[player_index].iTeam == TEAM_CS_TERRORIST) && (clients[player_index].iFlags & CLIENT_ALIVE)) // KWo - 19.01.2008
            g_iAliveTs++;
        if ((clients[player_index].iTeam == TEAM_CS_COUNTER) && (clients[player_index].iFlags & CLIENT_ALIVE))    // KWo - 19.01.2008
            g_iAliveCTs++;
/// ...................................

Or a way 2, more correct:
Code:

static void RunPlayerMove_Post (edict_t *fakeclient, const float *viewangles, float forwardmove, float sidemove, float upmove, unsigned short buttons, byte impulse, byte msec)
{
  if (IsAlive (fakeclient))
      fakeclient->v.light_level = Light::R_LightPoint (fakeclient->v.origin);

  RETURN_META (MRES_IGNORED);
}
C_DLLEXPORT int GetEngineFunctions_Post (enginefuncs_t *pengfuncsFromEngine, int *interfaceVersion)
{
  // ....
  meta_engfuncs_post.pfnRunPlayerMove = RunPlayerMove_Post;
  // ....
}

But of course for both methods you need to remove code, which you have added earlier from my previous post.

BTW.
Taken from Source SDK interface.cpp:
Code:

#ifdef _LINUX
// Linux doesn't have this function so this emulates its functionality
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


KWo 18-03-2012 22:40

Re: code to get the illumination at any point on the map
 
I'm having troubles with compiling under cygwin with that function
void *GetModuleHandle(const char *name)
After adding it to botglobals.h the compiler says it is defined twice (which really isn't). When I'm compiling it under mingw it also says about some problems:
obj.win32/bot.o:bot.cpp:(.text+0x1a822): undefined reference to `bool const Light::RecursiveLightPoint<mnode_s, msurface_s>(mnode_s const*, Vector const&, Vector const&)'
obj.win32/bot.o:bot.cpp:(.text+0x1b08b): undefined reference to `bool const Light::RecursiveLightPoint<GL_mnode_t, GL_msurface_t>(GL_mnode_t const*, Vector const&, Vector const&)'
collect2: ld returned 1 exit status
make: *** [obj.win32/podbot_mm.dll] Error 1

What does it mean that kind of messages like (.text+0x1a822)?

About GetModuleHandle ("sw.dll") - what exactly is this check for?

Isn't just the same as a check (!FNullEnt (pHostEdict))?
Another thing - there is no listenserver for a linux...

Immortal_BLG 18-03-2012 22:54

Re: code to get the illumination at any point on the map
 
First of all, I want to refute my previous post a little.
The second way is incorrect, as metamod doesn't do callbacks for its plug-ins, I have forgotten about it, forgive me again :( So use the first method....

About your last post:
Change:
Code:

void *GetModuleHandle(const char *name)
to:
Code:

inline void *GetModuleHandle(const char *name)
or:
Code:

extern inline void *GetModuleHandle(const char *name)

KWo 19-03-2012 08:12

Re: code to get the illumination at any point on the map
 
How about that below?
Quote:

Originally Posted by KWo (Post 64327)
What does it mean that kind of messages like (.text+0x1a822)?

About GetModuleHandle ("sw.dll") - what exactly is this check for?

Isn't just the same as a check (!FNullEnt (pHostEdict))?
Another thing - there is no listenserver for a linux...


Immortal_BLG 19-03-2012 09:05

Re: code to get the illumination at any point on the map
 
oh, missed it....

Quote:

Originally Posted by KWo
About GetModuleHandle ("sw.dll") - what exactly is this check for?

It is associated with specificity of display for different renderers....
I use it to determine which structure to use:
1) swds.DLL - used only for dedicated server - has no render interface (structures withOUT "GL_" prefix)
2) sw.DLL - used in software rendering mode (Options->Video->Renderer->Software) (structures withOUT "GL_" prefix)
3) hw.DLL - used in hardware rendering mode (OpenGL: Options->Video->Renderer->Software, Direct 3D: Options->Video->Renderer->D3D) (structures with "GL_" prefix)
Quote:

Originally Posted by KWo
Isn't just the same as a check (!FNullEnt (pHostEdict))?

NO.
Quote:

Originally Posted by KWo
Another thing - there is no listenserver for a linux...

It turns out that the function "IS_DEDICATED_SERVER" always returns true on LINUX?, if so, try this:
Code:

inline const bool IsSoftwareDrawingMode (void)
{
        #ifdef _LINUX
                return true;        // Always software rendering mode....
        #else        // ifdef _LINUX
                static const bool isSoftwareDrawingMode (IS_DEDICATED_SERVER () || GetModuleHandle ("sw.dll") != NULL);

                return isSoftwareDrawingMode;
        #endif        // ifndef _LINUX
}


KWo 19-03-2012 09:58

Re: code to get the illumination at any point on the map
 
Adding "inline" helped for cygwin (so the binary has been finally created and I'll be able to test Your function on a linux server - to see if it works - GETENTITYILLUM wasn't working on linux, so my bots wouldn use i.e. flashlights). But that one seems to be still unsolved:
Quote:

Originally Posted by KWo (Post 64327)
When I'm compiling it under mingw it also says about some problems:
obj.win32/bot.o:bot.cpp (.text+0x1a822): undefined reference to `bool const Light::RecursiveLightPoint<mnode_s, msurface_s>(mnode_s const*, Vector const&, Vector const&)'
obj.win32/bot.o:bot.cpp (.text+0x1b08b): undefined reference to `bool const Light::RecursiveLightPoint<GL_mnode_t, GL_msurface_t>(GL_mnode_t const*, Vector const&, Vector const&)'
collect2: ld returned 1 exit status
make: *** [obj.win32/podbot_mm.dll] Error 1

What does it mean that kind of messages like (.text+0x1a822)?

I don't understand that at all - cygwin and mingw are compiling binaries the same gcc way (I mean with the same rules and the same makefile), so why exactly cygwin cannot see any problem, but mingw still says something stupid?

About linux - from that what I know - there is no client and no listenserver available for CS for linux. VALVE has released only a dedicated server version of CS. So IS_DEDICATED_SERVER () SHOULD return always true (expect the situation VALVE has there a bug in the code).
About that GL thing - what if the user selects D3D instead OpenGL (in Video preferences) on a listenserver? Does that mean Your code wouldn't work then?

Immortal_BLG 19-03-2012 11:51

Re: code to get the illumination at any point on the map
 
Quote:

Originally Posted by KWo
GETENTITYILLUM wasn't working on linux, so my bots wouldn use i.e. flashlights).

I don't know in what a problem, try to involve again function ShowMagic and to look at result. If the function "Light::R_LightPoint" returns 0 (or some inappropriate value), it means that an error somewhere in my code, but I do not know how to solve it for LINUX, otherwise an error apparently in function "GETENTITYILLUM".
So, my council: use instead of function "GETENTITYILLUM" directly variable "bot->v.light_level" - for bots and players it is the same.

And about the compilation error, I do not know what help you :(

Quote:

Originally Posted by KWo
About that GL thing - what if the user selects D3D instead OpenGL (in Video preferences) on a listenserver? Does that mean Your code wouldn't work then?

No, it means nothing also nothing will change.

KWo 19-03-2012 12:10

Re: code to get the illumination at any point on the map
 
Quote:

Originally Posted by Immortal_BLG (Post 64332)
So, my council: use instead of function "GETENTITYILLUM" directly variable "bot->v.light_level" - for bots and players it is the same.

The council is:
1. a group of people who are elected to govern an area such as a town, city, etc.
2. a group of people chosen to give advice, manage affairs, etc. for a particular organization or activity
In our Slovian languages we have one the same word for "council" and for "advice" (in Polish it's "Rada" - in Russian it may sound similar). :)

That's exacty what I have done. I have to look at Your another advice about other bots (not podbot mm) to run Your function at them, too. Your function doesn't return 0 on bots on a Windows server, but now it's time for me to test it on a linux server, too. I'm going to test it today evening.

Quote:

Originally Posted by Immortal_BLG (Post 64332)
And about the compilation error, I do not know what help you :(

OK - i'll try to ask Whistler or somebody with gcc compilation knowledge.
Thanks for all Your help so far. :)

Immortal_BLG 19-03-2012 12:37

Re: code to get the illumination at any point on the map
 
Thanks for the lesson :)
I mean advice, F*CKING translator....
Good Luck!

Whistler 19-03-2012 16:03

Re: code to get the illumination at any point on the map
 
'hack' way - add something like this to util.cpp (so that the symbols for the 2 types actually exist in the compiled .o file):

Code:

void myhack()
{
 Vector v;
 Light::RecursiveLightPoint<mnode_s, msurface_s>(NULL, v, v);
 Light::RecursiveLightPoint<GL_mnode_t, GL_msurface_t>(NULL, v, v);
}

or move the templated function to .h file instead.

KWo 19-03-2012 20:49

Re: code to get the illumination at any point on the map
 
The templated function is already placed in .h (bot_globals.h):
Code:

namespace Light
{
//extern const mplane_t *lightplane (NULL);
//extern Vector lightspot;
  extern Color g_pointColor;

  template <typename nodeType, typename surfaceType> extern const bool RecursiveLightPoint (const nodeType *const node, const Vector &start, const Vector &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 ());
  }
}

I don't understand the hack. Rather I would like to understand somehow the problem (why mingw doesn't see the function) and solve it the way mingw can see it (without workarounds). Can You help again?

[EDIT]
The cygwin file - even if it's compiled - it is not loading on my mandriva 2011 linux test server. :big_crying:
The problem reported by MinGW has to be definitely somehow resolved.

Immortal_BLG 20-03-2012 04:08

Re: code to get the illumination at any point on the map
 
Whistler has in mind that you must put the body of a function "RecursiveLightPoint" in the header file bot_globals.h instead of util.cpp

KWo 20-03-2012 08:15

Re: code to get the illumination at any point on the map
 
From that what I've seen in the code, all extern variables they are placed in bot_gloabals.h, they have to be placed also in bot_globals.cpp. Isn't here the same situation - if extern const bool RecursiveLightPoint exists in bot_globals.h, maybe it shoud be also defined in bot_globals.cpp? The only difference is - in this case it is a const (not a variable). I don't have such case in the rest of code, so I cannot compare it with anything. :(
Another thing - I don't have other clasess in podbot mm code, so I'm completly lost with Your function. :) I have completly no idea how classes variables should be declared to be seen from other *.cpp files and their functions. If i.e. there is a function FVisible in util.cpp, it's just enough to add this decalration below in bot.h:
bool FVisible (const Vector &vecOrigin, edict_t *pEdict);

But how it should be made for functions they are some members of a class?

Immortal_BLG 20-03-2012 09:15

Re: code to get the illumination at any point on the map
 
Quote:

Originally Posted by KWo
From that what I've seen in the code, all extern variables they are placed in bot_gloabals.h, they have to be placed also in bot_globals.cpp. Isn't here the same situation - if extern const bool RecursiveLightPoint exists in bot_globals.h, maybe it shoud be also defined in bot_globals.cpp? The only difference is - in this case it is a const (not a variable). I don't have such case in the rest of code, so I cannot compare it with anything.

About it I don't know, try to declare this function in bot_globals.cpp, but why you do not accept the declaration in a header file, how has offered Whistler?

And into the account of classes and namespaces - you are free to make with a code all that you want, so you can simply remove this namespace....

KWo 20-03-2012 09:49

Re: code to get the illumination at any point on the map
 
Quote:

Originally Posted by Immortal_BLG (Post 64339)
About it I don't know, try to declare this function in bot_globals.cpp, but why you do not accept the declaration in a header file, how has offered Whistler?

Because I just don't know how to do it with a member of a class/namespace. :D

Quote:

Originally Posted by Immortal_BLG (Post 64339)
And into the account of classes and namespaces - you are free to make with a code all that you want, so you can simply remove this namespace....

If You can re-write that function so it doesn't need to be a member of namespace/class, it would be moreeasy for me to handle it. :)
Another thing I'm thinking of is - how much Your function consume the CPU power since it is a recursive function, which needs to be called for every 30 bots on the server (if there are 30 bots)?

Immortal_BLG 20-03-2012 10:56

Re: code to get the illumination at any point on the map
 
Quote:

Originally Posted by KWo (Post 64340)
Because I just don't know how to do it with a member of a class/namespace. :D

There is no difficult. Just cut code from utils.cpp and paste it to bot_globals.cpp.... :)

Quote:

Originally Posted by KWo (Post 64340)
If You can re-write that function so it doesn't need to be a member of namespace/class, it would be moreeasy for me to handle it. :)

Just remove:
Code:

namespace Light
{

// ...
}
And also "Light::" prefixes.

Quote:

Originally Posted by KWo (Post 64340)
Another thing I'm thinking of is - how much Your function consume the CPU power since it is a recursive function, which needs to be called for every 30 bots on the server (if there are 30 bots)?

Not cheked, but I think it is more faster then 30 fake illumination entities....

KWo 20-03-2012 11:01

Re: code to get the illumination at any point on the map
 
Quote:

Originally Posted by Immortal_BLG (Post 64341)
There is no difficult. Just cut code from utils.cpp and paste it to bot_globals.cpp.... :)

I believe You meant bot_globals.h (as Whistler wrote).

Immortal_BLG 20-03-2012 11:28

Re: code to get the illumination at any point on the map
 
Why? You said yourself that the functions that are defined in bot_globals.h, must be declared in the same file - bot_globals.cpp. But instead of it you can declare function "RecursiveLightPoint" in a header file bot_globals.h and ofcourse remove declaration from utils.cpp

KWo 20-03-2012 12:07

Re: code to get the illumination at any point on the map
 
I said - it is so for variables and functions, but I haven't had that case for a const (so I don't know if it needs or not to be done exactly the same way). My doubts are coming from lack of basic C++ knowledge. :)
Anyway I'll try to do something with it today evening.
Thanks again for all Your help.
Спасибо за совет! :)

KWo 20-03-2012 21:07

Re: code to get the illumination at any point on the map
 
OK. Still no luck. One thing I'm sure now. I have commented out in bot_globals.cpp this line:
const char *g_sz_cv_WPT_Folder;
and I've got similar error messages about text (0xaaaa), so that really means I do need somehow the declaration of the function RecursiveLightPoint.
I have checked and there are also other const (not only variables) - first added in bot_globals.h with "extern" prefix, then - without this prefix - in bot_globals.cpp. The problem for me is that template. I don't know how to correctly declare the function RecursiveLightPoint to pevent i.e. such error messages:

bot_globals.cpp|235|error: expected `,' or `...' before '*' token|
bot_globals.cpp|235|error: ISO C++ forbids declaration of `nodeType' with no type|
bot_globals.cpp|235|error: `const bool Light::RecursiveLightPoint(int)' should have been declared inside `Light'|
||=== Build finished: 3 errors, 0 warnings ===|


Currently in my code I've removed the function from util.cpp and in bot_globals.h it looks so:
Code:

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 ());
  }
}

#endif

The line 235 from bot_globals.cpp looks so:
Code:

235: const bool Light::RecursiveLightPoint (const nodeType *const node, const Vector &start, const Vector &end);
236: Color Light::g_pointColor;

I need still some help with this. :(

Immortal_BLG 21-03-2012 03:25

Re: code to get the illumination at any point on the map
 
try:
in bot_globals.h:
Code:

#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
/*
=============================================================================

LIGHT SAMPLING

=============================================================================
*/
namespace Light
{
//extern const mplane_t *lightplane (NULL);
//extern Vector lightspot;
extern Color g_pointColor;

template <typename nodeType, typename surfaceType> static 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)
{
        #ifdef _LINUX
                return true;        // Always software rendering mode....
        #else        // ifdef _LINUX
                static const bool isSoftwareDrawingMode (IS_DEDICATED_SERVER () || GetModuleHandle ("sw.dll") != NULL);

                return isSoftwareDrawingMode;
        #endif        // ifndef _LINUX
}
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 ());
}
}

or even use the method of an "axe", as we in Russia love.... (without templates)
Code:

static const bool RecursiveLightPoint (const mnode_t *const node, const Vector &start, const Vector &end)
{
        float front, back, frac;
        int side;
        mplane_t *plane;
        Vector mid;
        msurface_t *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 (node->children[side], start, end);

        // calculate mid point
        frac = front / (front - back);
        mid = start + (end - start) * frac;

        // go down front side       
        if (RecursiveLightPoint (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 = 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 (node->children[!side], mid, end);
}
static const bool GL_RecursiveLightPoint (const GL_mnode_t *const node, const Vector &start, const Vector &end)
{
        float front, back, frac;
        int side;
        mplane_t *plane;
        Vector mid;
        GL_msurface_t *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 GL_RecursiveLightPoint (reinterpret_cast <GL_mnode_t *> (node->children[side]), start, end);

        // calculate mid point
        frac = front / (front - back);
        mid = start + (end - start) * frac;

        // go down front side       
        if (GL_RecursiveLightPoint (reinterpret_cast <GL_mnode_t *> (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 <GL_msurface_t *> (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 GL_RecursiveLightPoint (reinterpret_cast <GL_mnode_t *> (node->children[!side]), mid, end);
}
inline const bool ActualRecursiveLightPoint (const Vector &start, const Vector &end)
{
        return IsSoftwareDrawingMode () ?
                RecursiveLightPoint (sv_worldmodel->nodes, start, end) :
                GL_RecursiveLightPoint (reinterpret_cast <GL_mnode_t *> (sv_worldmodel->nodes), start, end);
}

But don't forget to remove all definitions of function RecursiveLightPoint from .cpp files FOR BOTH CASES....
Finally in bot_globals.cpp everything should be as so:
Code:

/*
=============================================================================

LIGHT SAMPLING

=============================================================================
*/
namespace Light
{
//const mplane_t *lightplane (NULL);
//Vector lightspot;
Color g_pointColor;
}


KWo 21-03-2012 22:10

Re: code to get the illumination at any point on the map
 
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 2008). 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. :)

Immortal_BLG 22-03-2012 00:55

Re: code to get the illumination at any point on the map
 
Good news :)

just a question: have you tried to compile the function "RecursiveLightPoint" with the keyword "static" instead of "extern"? I'm just wondering whether the code from my last post is working or not.

BTW at the expense of function "GetModuleHandle". Once again I was wrong in my last post, because if there is no listen servers for LINUX, then the function "GetModuleHandle" for LINUX does not need, in addition, ".DLL" extension on LINUX, it does not exist, there ".SO".

So you should use: (without GetModuleHandle for LINUX)
Code:

inline const bool IsSoftwareDrawingMode (void)
{
        #ifdef _LINUX
                return true;        // Always software rendering mode....
        #else        // ifdef _LINUX
                static const bool isSoftwareDrawingMode (IS_DEDICATED_SERVER () || GetModuleHandle ("sw.dll") != NULL);

                return isSoftwareDrawingMode;
        #endif        // ifndef _LINUX
}


KWo 22-03-2012 08:06

Re: code to get the illumination at any point on the map
 
Quote:

Originally Posted by Immortal_BLG (Post 64348)
just a question: have you tried to compile the function "RecursiveLightPoint" with the keyword "static" instead of "extern"? I'm just wondering whether the code from my last post is working or not.

I was trying it when the code didn't want to compile. Later on - when I got it finally compiling - I was compiling it with that Your beloved method without templates. After that I went back to template and after compilation and successful loading dll (and working on windows) I didn't try again with static instead extern. I have focused to run my linux vmware test server, but yesterday that machine got crashed and I had to restore it from some my backup (11.2011). :D So finally I haven't had time yet to test if the cygwin compiled .so is loading and working or not. I'll try this today evening.


All times are GMT +2. The time now is 16:34.

Powered by vBulletin® Version 3.8.2
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.