moved light matrix generation out of the render code and into the light creation...
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Sat, 21 Feb 2004 07:37:36 +0000 (07:37 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Sat, 21 Feb 2004 07:37:36 +0000 (07:37 +0000)
rtlights and dlights now have an orientation matrix (this allows cubemaps to be rotated)
rtlights can now have corona flares, and it is adjustable per light (also on dlights)
r_coronas cvar now controls corona intensity, and menu now has r_coronas slider instead of checkbox
dlights now have color[]/radius settings instead of just colored intensity, so the radius can be independently controlled again (this mainly improves realtime dlight behaviors)
dlights can now have cubemaps, light styles, optional shadows (rather than always on), and better color/radius settings (and all this is tenebrae compatible) using the light_lev, color, style, skin (cubemap number, only available if modelindex is 0), and pflags (1 is no shadow, 2 is draw corona which is ignored by darkplaces because it always draws a corona) fields in the quakec entities
now supports tenebrae dlight fields (light_lev, color, style, pflags), this means dlights can now have cubemaps (skin, only used if modelindex is 0), light style (style), color (color) and radius (light_lev) with more precision than glow_ fields, and pflags (flag 1 is no shadow, flag 2 is corona which is ignored because dlights always have a corona in darkplaces), also loads tenebrae mods
added TENEBRAE_GFX_DLIGHTS extension

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@3913 d7cf8633-e32d-0410-b094-e92efae38249

27 files changed:
cgame_api.h
cgamevm.c
cl_main.c
cl_parse.c
client.h
common.c
common.h
gl_models.c
gl_rmain.c
gl_rsurf.c
menu.c
model_alias.c
model_brush.c
model_shared.h
pr_cmds.c
pr_edict.c
progs.h
protocol.c
protocol.h
r_light.c
r_light.h
r_shadow.c
r_shadow.h
server.h
sv_main.c
sv_phys.c
todo

index 8e7c4a5..01eb847 100644 (file)
@@ -24,7 +24,8 @@ cgdrawentity_t;
 typedef struct cgdrawlight_s
 {
        float origin[3];
-       float light[3];
+       float color[3];
+       float radius;
 }
 cgdrawlight_t;
 
index a2dc929..721c339 100644 (file)
--- a/cgamevm.c
+++ b/cgamevm.c
@@ -167,7 +167,9 @@ void CGVM_Draw_Entity(const cgdrawentity_t *e)
 
 void CGVM_Draw_Light(const cgdrawlight_t *l)
 {
-       CL_AllocDlight(NULL, (float *) l->origin, 1, l->light[0], l->light[1], l->light[2], 0, 0);
+       matrix4x4_t matrix;
+       Matrix4x4_CreateTranslate(&matrix, l->origin[0], l->origin[1], l->origin[2]);
+       CL_AllocDlight(NULL, &matrix, l->radius, l->color[0], l->color[1], l->color[2], 0, 0, 0, 0, true, 1);
 }
 
 void *CGVM_Malloc(const int size)
index 2ea477a..42b01de 100644 (file)
--- a/cl_main.c
+++ b/cl_main.c
@@ -414,7 +414,7 @@ void CL_Effect(vec3_t org, int modelindex, int startframe, int framecount, float
        }
 }
 
-void CL_AllocDlight(entity_render_t *ent, vec3_t org, float radius, float red, float green, float blue, float decay, float lifetime)
+void CL_AllocDlight(entity_render_t *ent, matrix4x4_t *matrix, float radius, float red, float green, float blue, float decay, float lifetime, int cubemapnum, int style, int shadowenable, vec_t corona)
 {
        int i;
        dlight_t *dl;
@@ -442,9 +442,15 @@ void CL_AllocDlight(entity_render_t *ent, vec3_t org, float radius, float red, f
 dlightsetup:
        //Con_Printf("dlight %i : %f %f %f : %f %f %f\n", i, org[0], org[1], org[2], red * radius, green * radius, blue * radius);
        memset (dl, 0, sizeof(*dl));
+       dl->matrix = *matrix;
        dl->ent = ent;
-       CL_FindNonSolidLocation(org, dl->origin, 6);
-       //VectorCopy(org, dl->origin);
+       dl->origin[0] = dl->matrix.m[0][3];
+       dl->origin[1] = dl->matrix.m[1][3];
+       dl->origin[2] = dl->matrix.m[2][3];
+       CL_FindNonSolidLocation(dl->origin, dl->origin, 6);
+       dl->matrix.m[0][3] = dl->origin[0];
+       dl->matrix.m[1][3] = dl->origin[1];
+       dl->matrix.m[2][3] = dl->origin[2];
        dl->radius = radius;
        dl->color[0] = red;
        dl->color[1] = green;
@@ -454,6 +460,10 @@ dlightsetup:
                dl->die = cl.time + lifetime;
        else
                dl->die = 0;
+       dl->cubemapnum = cubemapnum;
+       dl->style = style;
+       dl->shadow = shadowenable;
+       dl->corona = corona;
 }
 
 void CL_DecayLights(void)
@@ -486,9 +496,9 @@ extern void V_CalcRefdef(void);
 // note this is a recursive function, but it can never get in a runaway loop (because of the delayedlink flags)
 void CL_LinkNetworkEntity(entity_t *e)
 {
-       matrix4x4_t *matrix, blendmatrix, tempmatrix, matrix2;
+       matrix4x4_t *matrix, blendmatrix, tempmatrix, matrix2, dlightmatrix;
        int j, k, l, trailtype, temp;
-       float origin[3], angles[3], delta[3], lerp, dlightcolor[3], mins[3], maxs[3], v[3], v2[3], d;
+       float origin[3], angles[3], delta[3], lerp, dlightcolor[3], dlightradius, mins[3], maxs[3], v[3], v2[3], d;
        entity_t *t;
        model_t *model;
        //entity_persistent_t *p = &e->persistent;
@@ -637,6 +647,7 @@ void CL_LinkNetworkEntity(entity_t *e)
                origin[1] = e->render.matrix.m[1][3];
                origin[2] = e->render.matrix.m[2][3];
                trailtype = -1;
+               dlightradius = 0;
                dlightcolor[0] = 0;
                dlightcolor[1] = 0;
                dlightcolor[2] = 0;
@@ -647,9 +658,10 @@ void CL_LinkNetworkEntity(entity_t *e)
                        {
                                if (gamemode == GAME_NEXUIZ)
                                {
-                                       dlightcolor[0] += 100.0f;
-                                       dlightcolor[1] += 200.0f;
-                                       dlightcolor[2] += 400.0f;
+                                       dlightradius = max(dlightradius, 200);
+                                       dlightcolor[0] += 0.390625f;
+                                       dlightcolor[1] += 0.781250f;
+                                       dlightcolor[2] += 1.562500f;
                                        trailtype = 8;
                                }
                                else
@@ -659,28 +671,32 @@ void CL_LinkNetworkEntity(entity_t *e)
                                e->persistent.muzzleflash = 100.0f;
                        if (e->render.effects & EF_DIMLIGHT)
                        {
-                               dlightcolor[0] += 200.0f;
-                               dlightcolor[1] += 200.0f;
-                               dlightcolor[2] += 200.0f;
+                               dlightradius = max(dlightradius, 200);
+                               dlightcolor[0] += 0.781250f;
+                               dlightcolor[1] += 0.781250f;
+                               dlightcolor[2] += 0.781250f;
                        }
                        if (e->render.effects & EF_BRIGHTLIGHT)
                        {
-                               dlightcolor[0] += 400.0f;
-                               dlightcolor[1] += 400.0f;
-                               dlightcolor[2] += 400.0f;
+                               dlightradius = max(dlightradius, 400);
+                               dlightcolor[0] += 1.562500f;
+                               dlightcolor[1] += 1.562500f;
+                               dlightcolor[2] += 1.562500f;
                        }
                        // LordHavoc: more effects
                        if (e->render.effects & EF_RED) // red
                        {
-                               dlightcolor[0] += 200.0f;
-                               dlightcolor[1] +=  20.0f;
-                               dlightcolor[2] +=  20.0f;
+                               dlightradius = max(dlightradius, 200);
+                               dlightcolor[0] += 0.781250f;
+                               dlightcolor[1] += 0.078125f;
+                               dlightcolor[2] += 0.078125f;
                        }
                        if (e->render.effects & EF_BLUE) // blue
                        {
-                               dlightcolor[0] +=  20.0f;
-                               dlightcolor[1] +=  20.0f;
-                               dlightcolor[2] += 200.0f;
+                               dlightradius = max(dlightradius, 200);
+                               dlightcolor[0] += 0.078125f;
+                               dlightcolor[1] += 0.078125f;
+                               dlightcolor[2] += 0.781250f;
                        }
                        if (e->render.effects & EF_FLAME)
                        {
@@ -693,7 +709,8 @@ void CL_LinkNetworkEntity(entity_t *e)
                                // how many flames to make
                                temp = (int) (cl.time * 300) - (int) (cl.oldtime * 300);
                                CL_FlameCube(mins, maxs, temp);
-                               d = lhrandom(200, 250);
+                               d = lhrandom(0.75f, 1);
+                               dlightradius = max(dlightradius, 200);
                                dlightcolor[0] += d * 1.0f;
                                dlightcolor[1] += d * 0.7f;
                                dlightcolor[2] += d * 0.3f;
@@ -709,7 +726,8 @@ void CL_LinkNetworkEntity(entity_t *e)
                                // how many particles to make
                                temp = (int) (cl.time * 200) - (int) (cl.oldtime * 200);
                                CL_Stardust(mins, maxs, temp);
-                               d = 100;
+                               d = 0.390625f;
+                               dlightradius = max(dlightradius, 200);
                                dlightcolor[0] += d * 1.0f;
                                dlightcolor[1] += d * 0.7f;
                                dlightcolor[2] += d * 0.3f;
@@ -720,7 +738,11 @@ void CL_LinkNetworkEntity(entity_t *e)
                {
                        Matrix4x4_Transform(&e->render.matrix, muzzleflashorigin, v2);
                        CL_TraceLine(origin, v2, v, NULL, true, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_SKY);
-                       CL_AllocDlight(NULL, v, e->persistent.muzzleflash, 1, 1, 1, 0, 0);
+                       tempmatrix = e->render.matrix;
+                       tempmatrix.m[0][3] = v[0];
+                       tempmatrix.m[1][3] = v[1];
+                       tempmatrix.m[2][3] = v[2];
+                       CL_AllocDlight(NULL, &tempmatrix, e->persistent.muzzleflash, 1, 1, 1, 0, 0, 0, 0, true, 1);
                        e->persistent.muzzleflash -= cl.frametime * 1000;
                }
                // LordHavoc: if the model has no flags, don't check each
@@ -733,23 +755,26 @@ void CL_LinkNetworkEntity(entity_t *e)
                        else if (e->render.model->flags & EF_TRACER)
                        {
                                trailtype = 3;
-                               dlightcolor[0] += 0x10;
-                               dlightcolor[1] += 0x40;
-                               dlightcolor[2] += 0x10;
+                               dlightradius = max(dlightradius, 100);
+                               dlightcolor[0] += 0.060000f;
+                               dlightcolor[1] += 0.250000f;
+                               dlightcolor[2] += 0.062500f;
                        }
                        else if (e->render.model->flags & EF_TRACER2)
                        {
                                trailtype = 5;
-                               dlightcolor[0] += 0x50;
-                               dlightcolor[1] += 0x30;
-                               dlightcolor[2] += 0x10;
+                               dlightradius = max(dlightradius, 100);
+                               dlightcolor[0] += 0.312500f;
+                               dlightcolor[1] += 0.187500f;
+                               dlightcolor[2] += 0.062500f;
                        }
                        else if (e->render.model->flags & EF_ROCKET)
                        {
                                trailtype = 0;
-                               dlightcolor[0] += 200.0f;
-                               dlightcolor[1] += 160.0f;
-                               dlightcolor[2] +=  80.0f;
+                               dlightradius = max(dlightradius, 200);
+                               dlightcolor[0] += 0.781250f;
+                               dlightcolor[1] += 0.625000f;
+                               dlightcolor[2] += 0.312500f;
                        }
                        else if (e->render.model->flags & EF_GRENADE)
                        {
@@ -759,9 +784,10 @@ void CL_LinkNetworkEntity(entity_t *e)
                        else if (e->render.model->flags & EF_TRACER3)
                        {
                                trailtype = 6;
-                               dlightcolor[0] += 0x50;
-                               dlightcolor[1] += 0x20;
-                               dlightcolor[2] += 0x40;
+                               dlightradius = max(dlightradius, 200);
+                               dlightcolor[0] += 0.312500f;
+                               dlightcolor[1] += 0.125000f;
+                               dlightcolor[2] += 0.250000f;
                        }
                }
                // LordHavoc: customizable glow
@@ -769,16 +795,25 @@ void CL_LinkNetworkEntity(entity_t *e)
                {
                        // * 4 for the expansion from 0-255 to 0-1023 range,
                        // / 255 to scale down byte colors
-                       VectorMA(dlightcolor, e->state_current.glowsize * (4.0f / 255.0f), (qbyte *)&palette_complete[e->state_current.glowcolor], dlightcolor);
+                       dlightradius = max(dlightradius, e->state_current.glowsize * 4);
+                       VectorMA(dlightcolor, (1.0f / 255.0f), (qbyte *)&palette_complete[e->state_current.glowcolor], dlightcolor);
+               }
+               if (e->state_current.light[3])
+               {
+                       dlightradius = max(dlightradius, e->state_current.light[3]);
+                       if (VectorLength2(dlightcolor) == 0)
+                               (dlightcolor[0] += 1, dlightcolor[1] += 1, dlightcolor[2] += 1);
+                       else
+                               VectorMA(dlightcolor, (1.0f/256.0f), e->state_current.light, dlightcolor);
                }
                // make the dlight
-               if ((dlightcolor[0] || dlightcolor[1] || dlightcolor[2]) && !(e->render.flags & RENDER_VIEWMODEL) && !e->state_current.tagentity)
+               if (dlightradius > 0 && (dlightcolor[0] || dlightcolor[1] || dlightcolor[2]) && !(e->render.flags & RENDER_VIEWMODEL))
                {
-                       VectorCopy(origin, v);
+                       dlightmatrix = e->render.matrix;
                        // hack to make glowing player light shine on their gun
                        if ((e - cl_entities) == cl.viewentity/* && !chase_active.integer*/)
-                               v[2] += 30;
-                       CL_AllocDlight(&e->render, v, 1, dlightcolor[0], dlightcolor[1], dlightcolor[2], 0, 0);
+                               dlightmatrix.m[2][3] += 30;
+                       CL_AllocDlight(&e->render, &dlightmatrix, dlightradius, dlightcolor[0], dlightcolor[1], dlightcolor[2], 0, 0, e->state_current.skin >= 16 ? e->state_current.skin : 0, e->state_current.lightstyle, !(e->state_current.lightpflags & 1), 1);
                }
                // trails need the previous frame
                if (e->state_previous.active && e->state_previous.modelindex == e->state_current.modelindex)
@@ -808,6 +843,8 @@ void CL_LinkNetworkEntity(entity_t *e)
                        r_refdef.entities[r_refdef.numentities++] = &e->render;
                if (cl_num_entities < e->state_current.number + 1)
                        cl_num_entities = e->state_current.number + 1;
+               //if (cl.viewentity && e - cl_entities == cl.viewentity)
+               //      Matrix4x4_Print(&e->render.matrix);
        }
 }
 
@@ -939,6 +976,7 @@ void CL_RelinkBeams(void)
        entity_t *ent;
        float yaw, pitch;
        float forward;
+       matrix4x4_t tempmatrix;
 
        for (i = 0, b = cl_beams;i < cl_max_beams;i++, b++)
        {
@@ -986,7 +1024,11 @@ void CL_RelinkBeams(void)
                if (b->lightning)
                {
                        if (cl_beams_lightatend.integer)
-                               CL_AllocDlight (NULL, b->end, 200, 0.3, 0.7, 1, 0, 0);
+                       {
+                               // FIXME: create a matrix from the beam start/end orientation
+                               Matrix4x4_CreateTranslate(&tempmatrix, b->end[0], b->end[1], b->end[2]);
+                               CL_AllocDlight (NULL, &tempmatrix, 200, 0.3, 0.7, 1, 0, 0, 0, 0, true, 1);
+                       }
                        if (cl_beams_polygons.integer)
                                continue;
                }
index 45a8587..43cb2c2 100644 (file)
@@ -1007,6 +1007,7 @@ void CL_ParseTempEntity(void)
        int colorStart, colorLength, count;
        float velspeed, radius;
        qbyte *tempcolor;
+       matrix4x4_t tempmatrix;
 
        type = MSG_ReadByte();
        switch (type)
@@ -1015,7 +1016,8 @@ void CL_ParseTempEntity(void)
                // spike hitting wall
                MSG_ReadVector(pos);
                CL_FindNonSolidLocation(pos, pos, 4);
-               CL_AllocDlight(NULL, pos, 50, 0.25f, 1.00f, 0.25f, 250, 0.2);
+               Matrix4x4_CreateTranslate(&tempmatrix, pos[0], pos[1], pos[2]);
+               CL_AllocDlight(NULL, &tempmatrix, 150, 0.25f, 1.00f, 0.25f, 250, 0.2, 0, 0, false, 1);
                CL_RunParticleEffect(pos, vec3_origin, 20, 30);
                S_StartSound(-1, 0, cl_sfx_wizhit, pos, 1, 1);
                break;
@@ -1024,7 +1026,8 @@ void CL_ParseTempEntity(void)
                // spike hitting wall
                MSG_ReadVector(pos);
                CL_FindNonSolidLocation(pos, pos, 4);
-               CL_AllocDlight(NULL, pos, 50, 1.0f, 0.60f, 0.20f, 250, 0.2);
+               Matrix4x4_CreateTranslate(&tempmatrix, pos[0], pos[1], pos[2]);
+               CL_AllocDlight(NULL, &tempmatrix, 150, 1.0f, 0.60f, 0.20f, 250, 0.2, 0, 0, false, 1);
                CL_RunParticleEffect(pos, vec3_origin, 226, 20);
                S_StartSound(-1, 0, cl_sfx_knighthit, pos, 1, 1);
                break;
@@ -1054,7 +1057,8 @@ void CL_ParseTempEntity(void)
                CL_FindNonSolidLocation(pos, pos, 4);
                // LordHavoc: changed to spark shower
                CL_SparkShower(pos, vec3_origin, 15);
-               CL_AllocDlight(NULL, pos, 200, 0.1f, 0.1f, 1.0f, 1000, 0.2);
+               Matrix4x4_CreateTranslate(&tempmatrix, pos[0], pos[1], pos[2]);
+               CL_AllocDlight(NULL, &tempmatrix, 200, 0.1f, 0.1f, 1.0f, 1000, 0.2, 0, 0, true, 1);
                S_StartSound(-1, 0, cl_sfx_r_exp3, pos, 1, 1);
                if (rand() % 5)
                        S_StartSound(-1, 0, cl_sfx_tink1, pos, 1, 1);
@@ -1094,7 +1098,8 @@ void CL_ParseTempEntity(void)
                CL_FindNonSolidLocation(pos, pos, 4);
                // LordHavoc: changed to dust shower
                CL_SparkShower(pos, vec3_origin, 30);
-               CL_AllocDlight(NULL, pos, 200, 0.1f, 0.1f, 1.0f, 1000, 0.2);
+               Matrix4x4_CreateTranslate(&tempmatrix, pos[0], pos[1], pos[2]);
+               CL_AllocDlight(NULL, &tempmatrix, 200, 0.1f, 0.1f, 1.0f, 1000, 0.2, 0, 0, true, 1);
                if (rand() % 5)
                        S_StartSound(-1, 0, cl_sfx_tink1, pos, 1, 1);
                else
@@ -1132,7 +1137,8 @@ void CL_ParseTempEntity(void)
        case TE_PLASMABURN:
                MSG_ReadVector(pos);
                CL_FindNonSolidLocation(pos, pos, 4);
-               CL_AllocDlight(NULL, pos, 200, 1, 1, 1, 1000, 0.2);
+               Matrix4x4_CreateTranslate(&tempmatrix, pos[0], pos[1], pos[2]);
+               CL_AllocDlight(NULL, &tempmatrix, 200, 1, 1, 1, 1000, 0.2, 0, 0, true, 1);
                CL_PlasmaBurn(pos);
                break;
                // LordHavoc: added for improved gore
@@ -1189,7 +1195,8 @@ void CL_ParseTempEntity(void)
                MSG_ReadVector(pos);
                CL_FindNonSolidLocation(pos, pos, 4);
                CL_SparkShower(pos, vec3_origin, 15);
-               CL_AllocDlight(NULL, pos, 200, 0.1f, 0.1f, 1.0f, 1000, 0.2);
+               Matrix4x4_CreateTranslate(&tempmatrix, pos[0], pos[1], pos[2]);
+               CL_AllocDlight(NULL, &tempmatrix, 200, 0.1f, 0.1f, 1.0f, 1000, 0.2, 0, 0, true, 1);
                break;
 
        case TE_EXPLOSION:
@@ -1198,7 +1205,8 @@ void CL_ParseTempEntity(void)
                CL_FindNonSolidLocation(pos, pos, 10);
                CL_ParticleExplosion(pos);
                // LordHavoc: boosted color from 1.0, 0.8, 0.4 to 1.25, 1.0, 0.5
-               CL_AllocDlight(NULL, pos, 350, 1.25f, 1.0f, 0.5f, 700, 0.5);
+               Matrix4x4_CreateTranslate(&tempmatrix, pos[0], pos[1], pos[2]);
+               CL_AllocDlight(NULL, &tempmatrix, 350, 1.25f, 1.0f, 0.5f, 700, 0.5, 0, 0, true, 1);
                S_StartSound(-1, 0, cl_sfx_r_exp3, pos, 1, 1);
                break;
 
@@ -1207,7 +1215,8 @@ void CL_ParseTempEntity(void)
                MSG_ReadVector(pos);
                CL_FindNonSolidLocation(pos, pos, 10);
                CL_ParticleExplosion(pos);
-               CL_AllocDlight(NULL, pos, 600, 0.5f, 0.4f, 1.0f, 1200, 0.5);
+               Matrix4x4_CreateTranslate(&tempmatrix, pos[0], pos[1], pos[2]);
+               CL_AllocDlight(NULL, &tempmatrix, 600, 0.5f, 0.4f, 1.0f, 1200, 0.5, 0, 0, true, 1);
                S_StartSound(-1, 0, cl_sfx_r_exp3, pos, 1, 1);
                break;
 
@@ -1216,7 +1225,8 @@ void CL_ParseTempEntity(void)
                MSG_ReadVector(pos);
                CL_FindNonSolidLocation(pos, pos, 10);
                CL_ParticleExplosion(pos);
-               CL_AllocDlight(NULL, pos, 350, MSG_ReadCoord(), MSG_ReadCoord(), MSG_ReadCoord(), 700, 0.5);
+               Matrix4x4_CreateTranslate(&tempmatrix, pos[0], pos[1], pos[2]);
+               CL_AllocDlight(NULL, &tempmatrix, 350, MSG_ReadCoord(), MSG_ReadCoord(), MSG_ReadCoord(), 700, 0.5, 0, 0, true, 1);
                S_StartSound(-1, 0, cl_sfx_r_exp3, pos, 1, 1);
                break;
 
@@ -1228,7 +1238,8 @@ void CL_ParseTempEntity(void)
                color[0] = MSG_ReadByte() * (1.0 / 255.0);
                color[1] = MSG_ReadByte() * (1.0 / 255.0);
                color[2] = MSG_ReadByte() * (1.0 / 255.0);
-               CL_AllocDlight(NULL, pos, 350, color[0], color[1], color[2], 700, 0.5);
+               Matrix4x4_CreateTranslate(&tempmatrix, pos[0], pos[1], pos[2]);
+               CL_AllocDlight(NULL, &tempmatrix, 350, color[0], color[1], color[2], 700, 0.5, 0, 0, true, 1);
                S_StartSound(-1, 0, cl_sfx_r_exp3, pos, 1, 1);
                break;
 
@@ -1240,13 +1251,15 @@ void CL_ParseTempEntity(void)
 
                S_StartSound(-1, 0, cl_sfx_r_exp3, pos, 1, 1);
                S_StartSound(-1, 0, cl_sfx_r_exp3, pos, 1, 1);
-               CL_AllocDlight(NULL, pos, 600, 0.8f, 0.4f, 1.0f, 1200, 0.5);
+               Matrix4x4_CreateTranslate(&tempmatrix, pos[0], pos[1], pos[2]);
+               CL_AllocDlight(NULL, &tempmatrix, 600, 0.8f, 0.4f, 1.0f, 1200, 0.5, 0, 0, true, 1);
                break;
 
        case TE_SMALLFLASH:
                MSG_ReadVector(pos);
                CL_FindNonSolidLocation(pos, pos, 10);
-               CL_AllocDlight(NULL, pos, 200, 1, 1, 1, 1000, 0.2);
+               Matrix4x4_CreateTranslate(&tempmatrix, pos[0], pos[1], pos[2]);
+               CL_AllocDlight(NULL, &tempmatrix, 200, 1, 1, 1, 1000, 0.2, 0, 0, true, 1);
                break;
 
        case TE_CUSTOMFLASH:
@@ -1257,7 +1270,8 @@ void CL_ParseTempEntity(void)
                color[0] = MSG_ReadByte() * (1.0 / 255.0);
                color[1] = MSG_ReadByte() * (1.0 / 255.0);
                color[2] = MSG_ReadByte() * (1.0 / 255.0);
-               CL_AllocDlight(NULL, pos, radius, color[0], color[1], color[2], radius / velspeed, velspeed);
+               Matrix4x4_CreateTranslate(&tempmatrix, pos[0], pos[1], pos[2]);
+               CL_AllocDlight(NULL, &tempmatrix, radius, color[0], color[1], color[2], radius / velspeed, velspeed, 0, 0, true, 1);
                break;
 
        case TE_FLAMEJET:
@@ -1313,7 +1327,8 @@ void CL_ParseTempEntity(void)
                pos[0] = MSG_ReadCoord();
                pos[1] = MSG_ReadCoord();
                pos[2] = MSG_ReadCoord();
-               CL_AllocDlight(NULL, pos, 500, 1.0f, 1.0f, 1.0f, 1500, 99.0f);
+               Matrix4x4_CreateTranslate(&tempmatrix, pos[0], pos[1], pos[2]);
+               CL_AllocDlight(NULL, &tempmatrix, 500, 1.0f, 1.0f, 1.0f, 1500, 99.0f, 0, 0, true, 1);
 //             CL_TeleportSplash(pos);
                break;
 
@@ -1325,7 +1340,8 @@ void CL_ParseTempEntity(void)
                colorLength = MSG_ReadByte();
                CL_ParticleExplosion2(pos, colorStart, colorLength);
                tempcolor = (qbyte *)&palette_complete[(rand()%colorLength) + colorStart];
-               CL_AllocDlight(NULL, pos, 350, tempcolor[0] * (1.0f / 255.0f), tempcolor[1] * (1.0f / 255.0f), tempcolor[2] * (1.0f / 255.0f), 700, 0.5);
+               Matrix4x4_CreateTranslate(&tempmatrix, pos[0], pos[1], pos[2]);
+               CL_AllocDlight(NULL, &tempmatrix, 350, tempcolor[0] * (1.0f / 255.0f), tempcolor[1] * (1.0f / 255.0f), tempcolor[2] * (1.0f / 255.0f), 700, 0.5, 0, 0, true, 1);
                S_StartSound(-1, 0, cl_sfx_r_exp3, pos, 1, 1);
                break;
 
@@ -1349,7 +1365,8 @@ void CL_ParseTempEntity(void)
                MSG_ReadVector(pos);
                CL_FindNonSolidLocation(pos, pos, 10);
                CL_ParticleExplosion(pos);
-               CL_AllocDlight(NULL, pos, 500, 1.25f, 1.0f, 0.5f, 500, 9999);
+               Matrix4x4_CreateTranslate(&tempmatrix, pos[0], pos[1], pos[2]);
+               CL_AllocDlight(NULL, &tempmatrix, 500, 1.25f, 1.0f, 0.5f, 500, 9999, 0, 0, true, 1);
                S_StartSound(-1, 0, cl_sfx_r_exp3, pos, 1, 1);
                break;
 
@@ -1359,7 +1376,8 @@ void CL_ParseTempEntity(void)
                count = MSG_ReadByte();
                CL_FindNonSolidLocation(pos, pos, 5);
                CL_Tei_PlasmaHit(pos, dir, count);
-               CL_AllocDlight(NULL, pos, 500, 0.3, 0.6, 1.0f, 2000, 9999);
+               Matrix4x4_CreateTranslate(&tempmatrix, pos[0], pos[1], pos[2]);
+               CL_AllocDlight(NULL, &tempmatrix, 500, 0.3, 0.6, 1.0f, 2000, 9999, 0, 0, true, 1);
                break;
 
        default:
@@ -1693,10 +1711,35 @@ void CL_ParseServerMessage(void)
                        Cmd_ExecuteString ("help", src_command);
                        break;
                case svc_hidelmp:
-                       SHOWLMP_decodehide();
+                       if (gamemode == GAME_TENEBRAE)
+                       {
+                               // repeating particle effect
+                               MSG_ReadCoord();
+                               MSG_ReadCoord();
+                               MSG_ReadCoord();
+                               MSG_ReadCoord();
+                               MSG_ReadCoord();
+                               MSG_ReadCoord();
+                               MSG_ReadByte();
+                               MSG_ReadLong();
+                               MSG_ReadLong();
+                               MSG_ReadString();
+                       }
+                       else
+                               SHOWLMP_decodehide();
                        break;
                case svc_showlmp:
-                       SHOWLMP_decodeshow();
+                       if (gamemode == GAME_TENEBRAE)
+                       {
+                               // particle effect
+                               MSG_ReadCoord();
+                               MSG_ReadCoord();
+                               MSG_ReadCoord();
+                               MSG_ReadByte();
+                               MSG_ReadString();
+                       }
+                       else
+                               SHOWLMP_decodeshow();
                        break;
                case svc_skybox:
                        R_SetSkyBox(MSG_ReadString());
index 468c8e1..692b0e5 100644 (file)
--- a/client.h
+++ b/client.h
@@ -75,15 +75,25 @@ typedef struct
        // location
        vec3_t  origin;
        // stop lighting after this time
-       float   die;
+       vec_t   die;
        // color of light
        vec3_t  color;
        // brightness (not really radius anymore)
-       float   radius;
+       vec_t   radius;
        // drop this each second
-       float   decay;
+       vec_t   decay;
        // the entity that owns this light (can be NULL)
        struct entity_render_s *ent;
+       // orientation/scaling/location
+       matrix4x4_t matrix;
+       // cubemap number to use on this light
+       int cubemapnum;
+       // light style which controls intensity of this light
+       int style;
+       // cast shadows
+       int shadow;
+       // corona intensity
+       vec_t corona;
 }
 dlight_t;
 
@@ -499,7 +509,7 @@ extern lightstyle_t *cl_lightstyle;
 
 extern client_state_t cl;
 
-extern void CL_AllocDlight (entity_render_t *ent, vec3_t org, float radius, float red, float green, float blue, float decay, float lifetime);
+extern void CL_AllocDlight (entity_render_t *ent, matrix4x4_t *matrix, float radius, float red, float green, float blue, float decay, float lifetime, int cubemapnum, int style, int shadowenable, vec_t corona);
 extern void CL_DecayLights (void);
 
 //=============================================================================
index 8af5518..43db21a 100644 (file)
--- a/common.c
+++ b/common.c
@@ -765,6 +765,8 @@ void COM_InitGameType (void)
                gamemode = GAME_SETHERAL;
        else if (strstr(name, "som"))
                gamemode = GAME_SOM;
+       else if (strstr(name, "tenebrae"))
+               gamemode = GAME_TENEBRAE;
        else
                gamemode = GAME_NORMAL;
 
@@ -794,6 +796,8 @@ void COM_InitGameType (void)
                gamemode = GAME_SETHERAL;
        else if (COM_CheckParm ("-som"))
                gamemode = GAME_SOM;
+       else if (COM_CheckParm ("-tenebrae"))
+               gamemode = GAME_TENEBRAE;
 
        switch(gamemode)
        {
@@ -849,6 +853,10 @@ void COM_InitGameType (void)
                gamename = "Son of Man";
                gamedirname = "data";
                break;
+       case GAME_TENEBRAE:
+               gamename = "DarkPlaces-Tenebrae";
+               gamedirname = "tenebrae";
+               break;
        default:
                Sys_Error("COM_InitGameType: unknown gamemode %i\n", gamemode);
                break;
index 837b01c..62796b3 100644 (file)
--- a/common.h
+++ b/common.h
@@ -174,6 +174,7 @@ extern      struct cvar_s   registered;
 #define GAME_FNIGGIUM 10
 #define GAME_SETHERAL 11
 #define GAME_SOM 12
+#define GAME_TENEBRAE 13 // full of evil hackery
 
 extern int gamemode;
 extern char *gamename;
index 1f6fc96..46e1397 100644 (file)
@@ -328,7 +328,7 @@ void R_Model_Alias_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightor
        }
 }
 
-void R_Model_Alias_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltofilter, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap)
+void R_Model_Alias_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltolight, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap)
 {
        int c, meshnum, layernum;
        float fog, ifog, lightcolor2[3];
@@ -383,7 +383,7 @@ void R_Model_Alias_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, v
                        if (layer->flags & ALIASLAYER_SPECULAR)
                        {
                                c_alias_polys += mesh->num_triangles;
-                               R_Shadow_SpecularLighting(mesh->num_vertices, mesh->num_triangles, mesh->data_element3i, aliasvert_vertex3f, aliasvert_svector3f, aliasvert_tvector3f, aliasvert_normal3f, mesh->data_texcoord2f, relativelightorigin, relativeeyeorigin, lightradius, lightcolor2, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, layer->texture, layer->nmap, lightcubemap);
+                               R_Shadow_SpecularLighting(mesh->num_vertices, mesh->num_triangles, mesh->data_element3i, aliasvert_vertex3f, aliasvert_svector3f, aliasvert_tvector3f, aliasvert_normal3f, mesh->data_texcoord2f, relativelightorigin, relativeeyeorigin, lightradius, lightcolor2, matrix_modeltolight, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, layer->texture, layer->nmap, lightcubemap);
                        }
                        else if (layer->flags & ALIASLAYER_DIFFUSE)
                        {
@@ -412,7 +412,7 @@ void R_Model_Alias_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, v
                                        lightcolor2[2] *= bcolor[2] * (1.0f / 255.0f);
                                }
                                c_alias_polys += mesh->num_triangles;
-                               R_Shadow_DiffuseLighting(mesh->num_vertices, mesh->num_triangles, mesh->data_element3i, aliasvert_vertex3f, aliasvert_svector3f, aliasvert_tvector3f, aliasvert_normal3f, mesh->data_texcoord2f, relativelightorigin, lightradius, lightcolor2, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, layer->texture, layer->nmap, lightcubemap);
+                               R_Shadow_DiffuseLighting(mesh->num_vertices, mesh->num_triangles, mesh->data_element3i, aliasvert_vertex3f, aliasvert_svector3f, aliasvert_tvector3f, aliasvert_normal3f, mesh->data_texcoord2f, relativelightorigin, lightradius, lightcolor2, matrix_modeltolight, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, layer->texture, layer->nmap, lightcubemap);
                        }
                }
        }
@@ -807,7 +807,7 @@ void R_Model_Zymotic_DrawShadowVolume(entity_render_t *ent, vec3_t relativelight
        // FIXME
 }
 
-void R_Model_Zymotic_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltofilter, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap)
+void R_Model_Zymotic_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltolight, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap)
 {
        // FIXME
 }
index c0d23b1..375f4d5 100644 (file)
@@ -538,9 +538,8 @@ void R_ShadowVolumeLighting(int visiblevolumes)
        worldlight_t *wl;
        rdlight_t *rd;
        rmeshstate_t m;
-       matrix4x4_t matrix;
-       matrix4x4_t matrix_worldtofilter, matrix_worldtoattenuationxyz, matrix_worldtoattenuationz;
-       matrix4x4_t matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz;
+       rtexture_t *cubemaptexture;
+       matrix4x4_t matrix_modeltolight, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz;
 
        if (visiblevolumes)
        {
@@ -571,19 +570,19 @@ void R_ShadowVolumeLighting(int visiblevolumes)
                                continue;
 
                        cullradius = wl->cullradius;
-                       lightradius = wl->lightradius;
+                       lightradius = wl->radius;
                        VectorCopy(wl->mins, clipmins);
                        VectorCopy(wl->maxs, clipmaxs);
 
                        f = d_lightstylevalue[wl->style] * (1.0f / 256.0f);
-                       VectorScale(wl->light, f, lightcolor);
+                       VectorScale(wl->color, f, lightcolor);
                        if (wl->selected)
                        {
                                f = 2 + sin(realtime * M_PI * 4.0);
                                VectorScale(lightcolor, f, lightcolor);
                        }
 
-                       if (r_shadow_worldshadows.integer && wl->castshadows && (gl_stencil || visiblevolumes))
+                       if (r_shadow_worldshadows.integer && wl->drawshadows && (gl_stencil || visiblevolumes))
                        {
                                if (!visiblevolumes)
                                        R_Shadow_Stage_ShadowVolumes();
@@ -599,37 +598,23 @@ void R_ShadowVolumeLighting(int visiblevolumes)
 
                        if (!visiblevolumes)
                        {
-                               if (r_shadow_worldshadows.integer && wl->castshadows && gl_stencil)
+                               if (r_shadow_worldshadows.integer && wl->drawshadows && gl_stencil)
                                        R_Shadow_Stage_LightWithShadows();
                                else
                                        R_Shadow_Stage_LightWithoutShadows();
 
-                               // calculate world to filter matrix
-                               //Matrix4x4_CreateFromQuakeEntity(&matrix, wl->origin[0], wl->origin[1], wl->origin[2], wl->angles[0] + cl.time * 12, wl->angles[1] + cl.time * 45, wl->angles[2], lightradius);
-                               Matrix4x4_CreateFromQuakeEntity(&matrix, wl->origin[0], wl->origin[1], wl->origin[2], wl->angles[0], wl->angles[1], wl->angles[2], lightradius);
-                               Matrix4x4_Invert_Simple(&matrix_worldtofilter, &matrix);
-                               // calculate world to attenuationxyz/xy matrix
-                               Matrix4x4_CreateFromQuakeEntity(&matrix, 0.5, 0.5, 0.5, 0, 0, 0, 0.5);
-                               Matrix4x4_Concat(&matrix_worldtoattenuationxyz, &matrix, &matrix_worldtofilter);
-                               // calculate world to attenuationz matrix
-                               matrix.m[0][0] = 0;matrix.m[0][1] = 0;matrix.m[0][2] = 0.5;matrix.m[0][3] = 0.5;
-                               matrix.m[1][0] = 0;matrix.m[1][1] = 0;matrix.m[1][2] = 0  ;matrix.m[1][3] = 0.5;
-                               matrix.m[2][0] = 0;matrix.m[2][1] = 0;matrix.m[2][2] = 0  ;matrix.m[2][3] = 0.5;
-                               matrix.m[3][0] = 0;matrix.m[3][1] = 0;matrix.m[3][2] = 0  ;matrix.m[3][3] = 1;
-                               Matrix4x4_Concat(&matrix_worldtoattenuationz, &matrix, &matrix_worldtofilter);
-
                                ent = &cl_entities[0].render;
                                if (ent->model && ent->model->DrawLight)
                                {
                                        Matrix4x4_Transform(&ent->inversematrix, wl->origin, relativelightorigin);
                                        Matrix4x4_Transform(&ent->inversematrix, r_vieworigin, relativeeyeorigin);
-                                       Matrix4x4_Concat(&matrix_modeltofilter, &matrix_worldtofilter, &ent->matrix);
-                                       Matrix4x4_Concat(&matrix_modeltoattenuationxyz, &matrix_worldtoattenuationxyz, &ent->matrix);
-                                       Matrix4x4_Concat(&matrix_modeltoattenuationz, &matrix_worldtoattenuationz, &ent->matrix);
+                                       Matrix4x4_Concat(&matrix_modeltolight, &wl->matrix_worldtolight, &ent->matrix);
+                                       Matrix4x4_Concat(&matrix_modeltoattenuationxyz, &wl->matrix_worldtoattenuationxyz, &ent->matrix);
+                                       Matrix4x4_Concat(&matrix_modeltoattenuationz, &wl->matrix_worldtoattenuationz, &ent->matrix);
                                        if (r_shadow_staticworldlights.integer)
-                                               R_Shadow_DrawStaticWorldLight_Light(wl, &ent->matrix, relativelightorigin, relativeeyeorigin, lightradius, lightcolor, &matrix_modeltofilter, &matrix_modeltoattenuationxyz, &matrix_modeltoattenuationz);
+                                               R_Shadow_DrawStaticWorldLight_Light(wl, &ent->matrix, relativelightorigin, relativeeyeorigin, lightradius, lightcolor, &matrix_modeltolight, &matrix_modeltoattenuationxyz, &matrix_modeltoattenuationz);
                                        else
-                                               ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, lightradius / ent->scale, lightcolor, &matrix_modeltofilter, &matrix_modeltoattenuationxyz, &matrix_modeltoattenuationz, wl->cubemap);
+                                               ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, lightradius / ent->scale, lightcolor, &matrix_modeltolight, &matrix_modeltoattenuationxyz, &matrix_modeltoattenuationz, wl->cubemap);
                                }
                                if (r_drawentities.integer)
                                {
@@ -642,10 +627,10 @@ void R_ShadowVolumeLighting(int visiblevolumes)
                                                {
                                                        Matrix4x4_Transform(&ent->inversematrix, wl->origin, relativelightorigin);
                                                        Matrix4x4_Transform(&ent->inversematrix, r_vieworigin, relativeeyeorigin);
-                                                       Matrix4x4_Concat(&matrix_modeltofilter, &matrix_worldtofilter, &ent->matrix);
-                                                       Matrix4x4_Concat(&matrix_modeltoattenuationxyz, &matrix_worldtoattenuationxyz, &ent->matrix);
-                                                       Matrix4x4_Concat(&matrix_modeltoattenuationz, &matrix_worldtoattenuationz, &ent->matrix);
-                                                       ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, lightradius / ent->scale, lightcolor, &matrix_modeltofilter, &matrix_modeltoattenuationxyz, &matrix_modeltoattenuationz, wl->cubemap);
+                                                       Matrix4x4_Concat(&matrix_modeltolight, &wl->matrix_worldtolight, &ent->matrix);
+                                                       Matrix4x4_Concat(&matrix_modeltoattenuationxyz, &wl->matrix_worldtoattenuationxyz, &ent->matrix);
+                                                       Matrix4x4_Concat(&matrix_modeltoattenuationz, &wl->matrix_worldtoattenuationz, &ent->matrix);
+                                                       ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, lightradius / ent->scale, lightcolor, &matrix_modeltolight, &matrix_modeltoattenuationxyz, &matrix_modeltoattenuationz, wl->cubemap);
                                                }
                                        }
                                }
@@ -656,7 +641,7 @@ void R_ShadowVolumeLighting(int visiblevolumes)
        {
                for (lnum = 0, rd = r_dlight;lnum < r_numdlights;lnum++, rd++)
                {
-                       lightradius = rd->cullradius;
+                       lightradius = rd->radius;
                        clipmins[0] = rd->origin[0] - lightradius;
                        clipmins[1] = rd->origin[1] - lightradius;
                        clipmins[2] = rd->origin[2] - lightradius;
@@ -667,9 +652,14 @@ void R_ShadowVolumeLighting(int visiblevolumes)
                                continue;
 
                        cullradius = RadiusFromBoundsAndOrigin(clipmins, clipmaxs, rd->origin);
-                       VectorScale(rd->light, (1.0f / 4096.0f), lightcolor);
+                       VectorCopy(rd->color, lightcolor);
+
+                       if (rd->cubemapnum > 0)
+                               cubemaptexture = R_Shadow_Cubemap(va("cubemaps/%i", rd->cubemapnum));
+                       else
+                               cubemaptexture = NULL;
 
-                       if (r_shadow_dlightshadows.integer && (gl_stencil || visiblevolumes))
+                       if (r_shadow_dlightshadows.integer && rd->shadow && (gl_stencil || visiblevolumes))
                        {
                                if (!visiblevolumes)
                                        R_Shadow_Stage_ShadowVolumes();
@@ -688,33 +678,20 @@ void R_ShadowVolumeLighting(int visiblevolumes)
 
                        if (!visiblevolumes)
                        {
-                               if (r_shadow_dlightshadows.integer && gl_stencil)
+                               if (r_shadow_dlightshadows.integer && gl_stencil && rd->shadow)
                                        R_Shadow_Stage_LightWithShadows();
                                else
                                        R_Shadow_Stage_LightWithoutShadows();
 
-                               // calculate world to filter matrix
-                               Matrix4x4_CreateFromQuakeEntity(&matrix, rd->origin[0], rd->origin[1], rd->origin[2], 0, 0, 0, lightradius);
-                               Matrix4x4_Invert_Simple(&matrix_worldtofilter, &matrix);
-                               // calculate world to attenuationxyz/xy matrix
-                               Matrix4x4_CreateFromQuakeEntity(&matrix, 0.5, 0.5, 0.5, 0, 0, 0, 0.5);
-                               Matrix4x4_Concat(&matrix_worldtoattenuationxyz, &matrix, &matrix_worldtofilter);
-                               // calculate world to attenuationz matrix
-                               matrix.m[0][0] = 0;matrix.m[0][1] = 0;matrix.m[0][2] = 0.5;matrix.m[0][3] = 0.5;
-                               matrix.m[1][0] = 0;matrix.m[1][1] = 0;matrix.m[1][2] = 0  ;matrix.m[1][3] = 0.5;
-                               matrix.m[2][0] = 0;matrix.m[2][1] = 0;matrix.m[2][2] = 0  ;matrix.m[2][3] = 0.5;
-                               matrix.m[3][0] = 0;matrix.m[3][1] = 0;matrix.m[3][2] = 0  ;matrix.m[3][3] = 1;
-                               Matrix4x4_Concat(&matrix_worldtoattenuationz, &matrix, &matrix_worldtofilter);
-
                                ent = &cl_entities[0].render;
                                if (ent->model && ent->model->DrawLight)
                                {
                                        Matrix4x4_Transform(&ent->inversematrix, rd->origin, relativelightorigin);
                                        Matrix4x4_Transform(&ent->inversematrix, r_vieworigin, relativeeyeorigin);
-                                       Matrix4x4_Concat(&matrix_modeltofilter, &matrix_worldtofilter, &ent->matrix);
-                                       Matrix4x4_Concat(&matrix_modeltoattenuationxyz, &matrix_worldtoattenuationxyz, &ent->matrix);
-                                       Matrix4x4_Concat(&matrix_modeltoattenuationz, &matrix_worldtoattenuationz, &ent->matrix);
-                                       ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, lightradius / ent->scale, lightcolor, &matrix_modeltofilter, &matrix_modeltoattenuationxyz, &matrix_modeltoattenuationz, NULL);
+                                       Matrix4x4_Concat(&matrix_modeltolight, &rd->matrix_worldtolight, &ent->matrix);
+                                       Matrix4x4_Concat(&matrix_modeltoattenuationxyz, &rd->matrix_worldtoattenuationxyz, &ent->matrix);
+                                       Matrix4x4_Concat(&matrix_modeltoattenuationz, &rd->matrix_worldtoattenuationz, &ent->matrix);
+                                       ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, lightradius / ent->scale, lightcolor, &matrix_modeltolight, &matrix_modeltoattenuationxyz, &matrix_modeltoattenuationz, cubemaptexture);
                                }
                                if (r_drawentities.integer)
                                {
@@ -727,10 +704,10 @@ void R_ShadowVolumeLighting(int visiblevolumes)
                                                {
                                                        Matrix4x4_Transform(&ent->inversematrix, rd->origin, relativelightorigin);
                                                        Matrix4x4_Transform(&ent->inversematrix, r_vieworigin, relativeeyeorigin);
-                                                       Matrix4x4_Concat(&matrix_modeltofilter, &matrix_worldtofilter, &ent->matrix);
-                                                       Matrix4x4_Concat(&matrix_modeltoattenuationxyz, &matrix_worldtoattenuationxyz, &ent->matrix);
-                                                       Matrix4x4_Concat(&matrix_modeltoattenuationz, &matrix_worldtoattenuationz, &ent->matrix);
-                                                       ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, lightradius / ent->scale, lightcolor, &matrix_modeltofilter, &matrix_modeltoattenuationxyz, &matrix_modeltoattenuationz, NULL);
+                                                       Matrix4x4_Concat(&matrix_modeltolight, &rd->matrix_worldtolight, &ent->matrix);
+                                                       Matrix4x4_Concat(&matrix_modeltoattenuationxyz, &rd->matrix_worldtoattenuationxyz, &ent->matrix);
+                                                       Matrix4x4_Concat(&matrix_modeltoattenuationz, &rd->matrix_worldtoattenuationz, &ent->matrix);
+                                                       ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, lightradius / ent->scale, lightcolor, &matrix_modeltolight, &matrix_modeltoattenuationxyz, &matrix_modeltoattenuationz, cubemaptexture);
                                                }
                                        }
                                }
index 253444e..a3ddc49 100644 (file)
@@ -1851,7 +1851,7 @@ void R_Model_Brush_DrawShadowVolume (entity_render_t *ent, vec3_t relativelighto
        }
 }
 
-void R_Model_Brush_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltofilter, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap)
+void R_Model_Brush_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltolight, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap)
 {
        int surfnum;
        msurface_t *surf;
@@ -1879,8 +1879,8 @@ void R_Model_Brush_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, v
                                t = surf->texinfo->texture->currentframe;
                                if (t->rendertype == SURFRENDER_OPAQUE && t->flags & SURF_SHADOWLIGHT)
                                {
-                                       R_Shadow_DiffuseLighting(surf->mesh.num_vertices, surf->mesh.num_triangles, surf->mesh.data_element3i, surf->mesh.data_vertex3f, surf->mesh.data_svector3f, surf->mesh.data_tvector3f, surf->mesh.data_normal3f, surf->mesh.data_texcoordtexture2f, relativelightorigin, lightradius, lightcolor, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, t->skin.base, t->skin.nmap, lightcubemap);
-                                       R_Shadow_SpecularLighting(surf->mesh.num_vertices, surf->mesh.num_triangles, surf->mesh.data_element3i, surf->mesh.data_vertex3f, surf->mesh.data_svector3f, surf->mesh.data_tvector3f, surf->mesh.data_normal3f, surf->mesh.data_texcoordtexture2f, relativelightorigin, relativeeyeorigin, lightradius, lightcolor, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, t->skin.gloss, t->skin.nmap, lightcubemap);
+                                       R_Shadow_DiffuseLighting(surf->mesh.num_vertices, surf->mesh.num_triangles, surf->mesh.data_element3i, surf->mesh.data_vertex3f, surf->mesh.data_svector3f, surf->mesh.data_tvector3f, surf->mesh.data_normal3f, surf->mesh.data_texcoordtexture2f, relativelightorigin, lightradius, lightcolor, matrix_modeltolight, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, t->skin.base, t->skin.nmap, lightcubemap);
+                                       R_Shadow_SpecularLighting(surf->mesh.num_vertices, surf->mesh.num_triangles, surf->mesh.data_element3i, surf->mesh.data_vertex3f, surf->mesh.data_svector3f, surf->mesh.data_tvector3f, surf->mesh.data_normal3f, surf->mesh.data_texcoordtexture2f, relativelightorigin, relativeeyeorigin, lightradius, lightcolor, matrix_modeltolight, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, t->skin.gloss, t->skin.nmap, lightcubemap);
                                }
                        }
                }
@@ -2395,15 +2395,15 @@ void R_Q3BSP_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin,
        }
 }
 
-void R_Q3BSP_DrawFaceLight(entity_render_t *ent, q3mface_t *face, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltofilter, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap)
+void R_Q3BSP_DrawFaceLight(entity_render_t *ent, q3mface_t *face, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltolight, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap)
 {
        if ((face->texture->surfaceflags & Q3SURFACEFLAG_NODRAW) || !face->num_triangles)
                return;
-       R_Shadow_DiffuseLighting(face->num_vertices, face->num_triangles, face->data_element3i, face->data_vertex3f, face->data_svector3f, face->data_tvector3f, face->data_normal3f, face->data_texcoordtexture2f, relativelightorigin, lightradius, lightcolor, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, face->texture->skin.base, face->texture->skin.nmap, lightcubemap);
-       R_Shadow_SpecularLighting(face->num_vertices, face->num_triangles, face->data_element3i, face->data_vertex3f, face->data_svector3f, face->data_tvector3f, face->data_normal3f, face->data_texcoordtexture2f, relativelightorigin, relativeeyeorigin, lightradius, lightcolor, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, face->texture->skin.gloss, face->texture->skin.nmap, lightcubemap);
+       R_Shadow_DiffuseLighting(face->num_vertices, face->num_triangles, face->data_element3i, face->data_vertex3f, face->data_svector3f, face->data_tvector3f, face->data_normal3f, face->data_texcoordtexture2f, relativelightorigin, lightradius, lightcolor, matrix_modeltolight, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, face->texture->skin.base, face->texture->skin.nmap, lightcubemap);
+       R_Shadow_SpecularLighting(face->num_vertices, face->num_triangles, face->data_element3i, face->data_vertex3f, face->data_svector3f, face->data_tvector3f, face->data_normal3f, face->data_texcoordtexture2f, relativelightorigin, relativeeyeorigin, lightradius, lightcolor, matrix_modeltolight, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, face->texture->skin.gloss, face->texture->skin.nmap, lightcubemap);
 }
 
-void R_Q3BSP_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltofilter, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap)
+void R_Q3BSP_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltolight, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap)
 {
        int i;
        q3mface_t *face;
@@ -2427,7 +2427,7 @@ void R_Q3BSP_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t
                //else
                        for (i = 0, face = model->brushq3.data_thismodel->firstface;i < model->brushq3.data_thismodel->numfaces;i++, face++)
                                if ((ent != &cl_entities[0].render || face->visframe == r_framecount) && BoxesOverlap(lightmins, lightmaxs, face->mins, face->maxs))
-                                       R_Q3BSP_DrawFaceLight(ent, face, relativelightorigin, relativeeyeorigin, lightradius, lightcolor, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, lightcubemap);
+                                       R_Q3BSP_DrawFaceLight(ent, face, relativelightorigin, relativeeyeorigin, lightradius, lightcolor, matrix_modeltolight, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, lightcubemap);
        }
 }
 
diff --git a/menu.c b/menu.c
index 456d3aa..4c772ec 100644 (file)
--- a/menu.c
+++ b/menu.c
@@ -1398,50 +1398,28 @@ void M_Menu_Options_Effects_AdjustSliders (int dir)
        S_LocalSound ("misc/menu3.wav");
 
        optnum = 0;
-       if (options_effects_cursor == optnum++)
-               Cvar_SetValueQuick (&r_modellights, bound(0, r_modellights.value + dir, 8));
-       else if (options_effects_cursor == optnum++)
-               Cvar_SetValueQuick (&r_coronas, !r_coronas.integer);
-       else if (options_effects_cursor == optnum++)
-               Cvar_SetValueQuick (&gl_flashblend, !gl_flashblend.integer);
-       else if (options_effects_cursor == optnum++)
-               Cvar_SetValueQuick (&cl_particles, !cl_particles.integer);
-       else if (options_effects_cursor == optnum++)
-               Cvar_SetValueQuick (&cl_particles_quality, bound(1, cl_particles_quality.value + dir * 0.5, 4));
-       else if (options_effects_cursor == optnum++)
-               Cvar_SetValueQuick (&cl_explosions, !cl_explosions.integer);
-       else if (options_effects_cursor == optnum++)
-               Cvar_SetValueQuick (&r_explosionclip, !r_explosionclip.integer);
-       else if (options_effects_cursor == optnum++)
-               Cvar_SetValueQuick (&cl_stainmaps, !cl_stainmaps.integer);
-       else if (options_effects_cursor == optnum++)
-               Cvar_SetValueQuick (&cl_decals, !cl_decals.integer);
-       else if (options_effects_cursor == optnum++)
-               Cvar_SetValueQuick (&r_detailtextures, !r_detailtextures.integer);
-       else if (options_effects_cursor == optnum++)
-               Cvar_SetValueQuick (&cl_particles_bulletimpacts, !cl_particles_bulletimpacts.integer);
-       else if (options_effects_cursor == optnum++)
-               Cvar_SetValueQuick (&cl_particles_smoke, !cl_particles_smoke.integer);
-       else if (options_effects_cursor == optnum++)
-               Cvar_SetValueQuick (&cl_particles_sparks, !cl_particles_sparks.integer);
-       else if (options_effects_cursor == optnum++)
-               Cvar_SetValueQuick (&cl_particles_bubbles, !cl_particles_bubbles.integer);
-       else if (options_effects_cursor == optnum++)
-               Cvar_SetValueQuick (&cl_particles_blood, !cl_particles_blood.integer);
-       else if (options_effects_cursor == optnum++)
-               Cvar_SetValueQuick (&cl_particles_blood_alpha, bound(0.2, cl_particles_blood_alpha.value + dir * 0.1, 1));
-       else if (options_effects_cursor == optnum++)
-               Cvar_SetValueQuick (&cl_particles_blood_bloodhack, !cl_particles_blood_bloodhack.integer);
-       else if (options_effects_cursor == optnum++)
-               Cvar_SetValueQuick (&r_lerpmodels, !r_lerpmodels.integer);
-       else if (options_effects_cursor == optnum++)
-               Cvar_SetValueQuick (&r_lerpsprites, !r_lerpsprites.integer);
-       else if (options_effects_cursor == optnum++)
-               Cvar_SetValueQuick (&r_wateralpha, bound(0, r_wateralpha.value + dir * 0.1, 1));
-       else if (options_effects_cursor == optnum++)
-               Cvar_SetValueQuick (&r_waterscroll, bound(0, r_waterscroll.value + dir * 0.5, 10));
-       else if (options_effects_cursor == optnum++)
-               Cvar_SetValueQuick (&r_watershader, bound(0, r_watershader.value + dir * 0.25, 10));
+            if (options_effects_cursor == optnum++) Cvar_SetValueQuick (&r_modellights, bound(0, r_modellights.value + dir, 8));
+       else if (options_effects_cursor == optnum++) Cvar_SetValueQuick (&r_coronas, bound(0, r_coronas.value + dir * 0.125, 4));
+       else if (options_effects_cursor == optnum++) Cvar_SetValueQuick (&gl_flashblend, !gl_flashblend.integer);
+       else if (options_effects_cursor == optnum++) Cvar_SetValueQuick (&cl_particles, !cl_particles.integer);
+       else if (options_effects_cursor == optnum++) Cvar_SetValueQuick (&cl_particles_quality, bound(1, cl_particles_quality.value + dir * 0.5, 4));
+       else if (options_effects_cursor == optnum++) Cvar_SetValueQuick (&cl_explosions, !cl_explosions.integer);
+       else if (options_effects_cursor == optnum++) Cvar_SetValueQuick (&r_explosionclip, !r_explosionclip.integer);
+       else if (options_effects_cursor == optnum++) Cvar_SetValueQuick (&cl_stainmaps, !cl_stainmaps.integer);
+       else if (options_effects_cursor == optnum++) Cvar_SetValueQuick (&cl_decals, !cl_decals.integer);
+       else if (options_effects_cursor == optnum++) Cvar_SetValueQuick (&r_detailtextures, !r_detailtextures.integer);
+       else if (options_effects_cursor == optnum++) Cvar_SetValueQuick (&cl_particles_bulletimpacts, !cl_particles_bulletimpacts.integer);
+       else if (options_effects_cursor == optnum++) Cvar_SetValueQuick (&cl_particles_smoke, !cl_particles_smoke.integer);
+       else if (options_effects_cursor == optnum++) Cvar_SetValueQuick (&cl_particles_sparks, !cl_particles_sparks.integer);
+       else if (options_effects_cursor == optnum++) Cvar_SetValueQuick (&cl_particles_bubbles, !cl_particles_bubbles.integer);
+       else if (options_effects_cursor == optnum++) Cvar_SetValueQuick (&cl_particles_blood, !cl_particles_blood.integer);
+       else if (options_effects_cursor == optnum++) Cvar_SetValueQuick (&cl_particles_blood_alpha, bound(0.2, cl_particles_blood_alpha.value + dir * 0.1, 1));
+       else if (options_effects_cursor == optnum++) Cvar_SetValueQuick (&cl_particles_blood_bloodhack, !cl_particles_blood_bloodhack.integer);
+       else if (options_effects_cursor == optnum++) Cvar_SetValueQuick (&r_lerpmodels, !r_lerpmodels.integer);
+       else if (options_effects_cursor == optnum++) Cvar_SetValueQuick (&r_lerpsprites, !r_lerpsprites.integer);
+       else if (options_effects_cursor == optnum++) Cvar_SetValueQuick (&r_wateralpha, bound(0, r_wateralpha.value + dir * 0.1, 1));
+       else if (options_effects_cursor == optnum++) Cvar_SetValueQuick (&r_waterscroll, bound(0, r_waterscroll.value + dir * 0.5, 10));
+       else if (options_effects_cursor == optnum++) Cvar_SetValueQuick (&r_watershader, bound(0, r_watershader.value + dir * 0.25, 10));
 }
 
 void M_Options_Effects_Draw (void)
@@ -1461,7 +1439,7 @@ void M_Options_Effects_Draw (void)
        opty = 32 - bound(0, optcursor - (visible >> 1), max(0, OPTIONS_EFFECTS_ITEMS - visible)) * 8;
 
        M_Options_PrintSlider(  "      Lights Per Model", true, r_modellights.value, 0, 8);
-       M_Options_PrintCheckbox("               Coronas", true, r_coronas.integer);
+       M_Options_PrintSlider(  "      Corona Intensity", true, r_coronas.value, 0, 4);
        M_Options_PrintCheckbox("      Use Only Coronas", true, gl_flashblend.integer);
        M_Options_PrintCheckbox("             Particles", true, cl_particles.integer);
        M_Options_PrintSlider(  "     Particles Quality", true, cl_particles_quality.value, 1, 4);
index d91ef81..f8625a8 100644 (file)
@@ -312,7 +312,7 @@ void Mod_BuildAliasSkinsFromSkinFiles(aliasskin_t *skin, skinfile_t *skinfile, c
 #define BOUNDF(VALUE,MIN,MAX) if (VALUE < MIN || VALUE >= MAX) Host_Error("model %s has an invalid ##VALUE (%f exceeds %f - %f)\n", loadmodel->name, VALUE, MIN, MAX);
 extern void R_Model_Alias_Draw(entity_render_t *ent);
 extern void R_Model_Alias_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin, float lightradius);
-extern void R_Model_Alias_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltofilter, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap);
+extern void R_Model_Alias_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltolight, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap);
 void Mod_IDP0_Load(model_t *mod, void *buffer)
 {
        int i, j, version, totalskins, skinwidth, skinheight, groupframes, groupskins, numverts;
@@ -970,7 +970,7 @@ void Mod_IDP3_Load(model_t *mod, void *buffer)
 extern void R_Model_Zymotic_DrawSky(entity_render_t *ent);
 extern void R_Model_Zymotic_Draw(entity_render_t *ent);
 extern void R_Model_Zymotic_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin, float lightradius);
-extern void R_Model_Zymotic_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltofilter, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap);
+extern void R_Model_Zymotic_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltolight, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap);
 void Mod_ZYMOTICMODEL_Load(model_t *mod, void *buffer)
 {
        zymtype1header_t *pinmodel, *pheader;
index 2209463..cea8a34 100644 (file)
@@ -2819,7 +2819,7 @@ static void Mod_Q1BSP_RoundUpToHullSize(model_t *cmodel, const vec3_t inmins, co
 extern void R_Model_Brush_DrawSky(entity_render_t *ent);
 extern void R_Model_Brush_Draw(entity_render_t *ent);
 extern void R_Model_Brush_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin, float lightradius);
-extern void R_Model_Brush_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltofilter, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap);
+extern void R_Model_Brush_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltolight, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap);
 void Mod_Q1BSP_Load(model_t *mod, void *buffer)
 {
        int i, j, k;
@@ -5259,7 +5259,7 @@ static int Mod_Q3BSP_NativeContentsFromSuperContents(model_t *model, int superco
 extern void R_Q3BSP_DrawSky(struct entity_render_s *ent);
 extern void R_Q3BSP_Draw(struct entity_render_s *ent);
 extern void R_Q3BSP_DrawShadowVolume(struct entity_render_s *ent, vec3_t relativelightorigin, float lightradius);
-extern void R_Q3BSP_DrawLight(struct entity_render_s *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltofilter, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap);
+extern void R_Q3BSP_DrawLight(struct entity_render_s *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltolight, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap);
 void Mod_Q3BSP_Load(model_t *mod, void *buffer)
 {
        int i, j;
index 0aafccc..1846298 100644 (file)
@@ -576,7 +576,7 @@ typedef struct model_s
        // draw a shadow volume for the model based on light source
        void(*DrawShadowVolume)(struct entity_render_s *ent, vec3_t relativelightorigin, float lightradius);
        // draw the lighting on a model (through stencil)
-       void(*DrawLight)(struct entity_render_s *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltofilter, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap);
+       void(*DrawLight)(struct entity_render_s *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltolight, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap);
        // trace a box against this model
        void (*TraceBox)(struct model_s *model, int frame, struct trace_s *trace, const vec3_t boxstartmins, const vec3_t boxstartmaxs, const vec3_t boxendmins, const vec3_t boxendmaxs, int hitsupercontentsmask);
        // fields belonging to each type of model
index 3a0c9d0..9d9571a 100644 (file)
--- a/pr_cmds.c
+++ b/pr_cmds.c
@@ -145,6 +145,7 @@ char *ENGINE_EXTENSIONS =
 "KRIMZON_SV_PARSECLIENTCOMMAND "
 "NEH_CMD_PLAY2 "
 "NEH_RESTOREGAME "
+"TENEBRAE_GFX_DLIGHTS "
 "TW_SV_STEPCONTROL "
 ;
 
index 2a77bac..c447eae 100644 (file)
@@ -122,6 +122,10 @@ int eval_viewzoom;
 int eval_clientcolors;
 int eval_tag_entity;
 int eval_tag_index;
+int eval_light_lev;
+int eval_color;
+int eval_style;
+int eval_pflags;
 
 mfunction_t *SV_PlayerPhysicsQC;
 mfunction_t *EndFrameQC;
@@ -176,6 +180,10 @@ void FindEdictFieldOffsets(void)
        eval_clientcolors = FindFieldOffset("clientcolors");
        eval_tag_entity = FindFieldOffset("tag_entity");
        eval_tag_index = FindFieldOffset("tag_index");
+       eval_light_lev = FindFieldOffset("light_lev");
+       eval_color = FindFieldOffset("color");
+       eval_style = FindFieldOffset("style");
+       eval_pflags = FindFieldOffset("pflags");
 
        // LordHavoc: allowing QuakeC to override the player movement code
        SV_PlayerPhysicsQC = ED_FindFunction ("SV_PlayerPhysics");
@@ -1225,7 +1233,11 @@ dpfield_t dpfields[] =
        {ev_vector, "punchvector"},
        {ev_float, "clientcolors"},
        {ev_entity, "tag_entity"},
-       {ev_float, "tag_index"}
+       {ev_float, "tag_index"},
+       {ev_float, "light_lev"},
+       {ev_float, "color"},
+       {ev_float, "style"},
+       {ev_float, "pflags"}
 };
 
 /*
@@ -1268,7 +1280,7 @@ void PR_LoadProgs (void)
 
        if (progs->version != PROG_VERSION)
                Host_Error ("progs.dat has wrong version number (%i should be %i)", progs->version, PROG_VERSION);
-       if (progs->crc != PROGHEADER_CRC)
+       if (progs->crc != PROGHEADER_CRC && progs->crc != 32401) // tenebrae crc also allowed
                Host_Error ("progs.dat system vars have been modified, progdefs.h is out of date");
 
        //pr_functions = (dfunction_t *)((qbyte *)progs + progs->ofs_functions);
diff --git a/progs.h b/progs.h
index 1483c3b..e1e365c 100644 (file)
--- a/progs.h
+++ b/progs.h
@@ -123,6 +123,10 @@ extern int eval_viewzoom;
 extern int eval_clientcolors;
 extern int eval_tag_entity;
 extern int eval_tag_index;
+extern int eval_light_lev;
+extern int eval_color;
+extern int eval_style;
+extern int eval_pflags;
 
 #define GETEDICTFIELDVALUE(ed, fieldoffset) (fieldoffset ? (eval_t *)((qbyte *)ed->v + fieldoffset) : NULL)
 
index 86e760a..0ded4ed 100644 (file)
@@ -17,6 +17,9 @@ entity_state_t defaultstate =
        0,//unsigned short exteriormodelforclient;
        0,//unsigned short nodrawtoclient;
        0,//unsigned short drawonlytoclient;
+       {0,0,0,0},//short light[4];
+       0,//qbyte lightstyle;
+       0,//qbyte lightpflags;
        0,//qbyte colormap;
        0,//qbyte skin;
        255,//qbyte alpha;
@@ -25,6 +28,7 @@ entity_state_t defaultstate =
        254,//qbyte glowcolor;
        0,//qbyte flags;
        0,//qbyte tagindex;
+       {0,0,0,0,0,0}//qbyte unused[6];
 };
 
 void ClearStateToDefault(entity_state_t *s)
@@ -120,6 +124,12 @@ void EntityState_Write(entity_state_t *ent, sizebuf_t *msg, entity_state_t *delt
                        bits |= E_FLAGS;
                if (ent->tagindex != delta->tagindex || ent->tagentity != delta->tagentity)
                        bits |= E_TAGATTACHMENT;
+               if (ent->light[0] != delta->light[0] || ent->light[1] != delta->light[1] || ent->light[2] != delta->light[2] || ent->light[3] != delta->light[3])
+                       bits |= E_LIGHT;
+               if (ent->lightstyle != delta->lightstyle)
+                       bits |= E_LIGHTSTYLE;
+               if (ent->lightpflags != delta->lightpflags)
+                       bits |= E_LIGHTPFLAGS;
 
                if (bits) // don't send anything if it hasn't changed
                {
@@ -198,6 +208,17 @@ void EntityState_Write(entity_state_t *ent, sizebuf_t *msg, entity_state_t *delt
                                MSG_WriteShort(msg, ent->tagentity);
                                MSG_WriteByte(msg, ent->tagindex);
                        }
+                       if (bits & E_LIGHT)
+                       {
+                               MSG_WriteShort(msg, ent->light[0]);
+                               MSG_WriteShort(msg, ent->light[1]);
+                               MSG_WriteShort(msg, ent->light[2]);
+                               MSG_WriteShort(msg, ent->light[3]);
+                       }
+                       if (bits & E_LIGHTSTYLE)
+                               MSG_WriteByte(msg, ent->lightstyle);
+                       if (bits & E_LIGHTPFLAGS)
+                               MSG_WriteByte(msg, ent->lightpflags);
                }
        }
        else if (delta->active)
@@ -294,6 +315,17 @@ void EntityState_ReadUpdate(entity_state_t *e, int number)
                e->tagentity = MSG_ReadShort();
                e->tagindex = MSG_ReadByte();
        }
+       if (bits & E_LIGHT)
+       {
+               e->light[0] = MSG_ReadShort();
+               e->light[1] = MSG_ReadShort();
+               e->light[2] = MSG_ReadShort();
+               e->light[3] = MSG_ReadShort();
+       }
+       if (bits & E_LIGHTSTYLE)
+               e->lightstyle = MSG_ReadByte();
+       if (bits & E_LIGHTPFLAGS)
+               e->lightpflags = MSG_ReadByte();
 
        if (developer_networkentities.integer >= 2)
        {
@@ -328,12 +360,19 @@ void EntityState_ReadUpdate(entity_state_t *e, int number)
                        Con_Printf(" E_SKIN %i", e->skin);
 
                if (bits & E_GLOWSIZE)
-                       Con_Printf(" E_GLOWSIZE %i", e->glowsize * 8);
+                       Con_Printf(" E_GLOWSIZE %i", e->glowsize * 4);
                if (bits & E_GLOWCOLOR)
                        Con_Printf(" E_GLOWCOLOR %i", e->glowcolor);
+               
+               if (bits & E_LIGHT)
+                       Con_Printf(" E_LIGHT %i:%i:%i:%i", e->light[0], e->light[1], e->light[2], e->light[3]);
+               if (bits & E_LIGHTPFLAGS)                       
+                       Con_Printf(" E_LIGHTPFLAGS %i", e->lightpflags);
 
                if (bits & E_TAGATTACHMENT)
                        Con_Printf(" E_TAGATTACHMENT e%i:%i", e->tagentity, e->tagindex);
+               if (bits & E_LIGHTSTYLE)
+                       Con_Printf(" E_LIGHTSTYLE %i", e->lightstyle);
                Con_Printf("\n");
        }
 }
index 67417b3..b57e4e6 100644 (file)
@@ -87,7 +87,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 #define U_ALPHA                        (1<<17) // 1 byte, 0.0-1.0 maps to 0-255, not sent if exactly 1, and the entity is not sent if <=0 unless it has effects (model effects are checked as well)
 #define U_SCALE                        (1<<18) // 1 byte, scale / 16 positive, not sent if 1.0
 #define U_EFFECTS2             (1<<19) // 1 byte, this is .effects & 0xFF00 (second byte)
-#define U_GLOWSIZE             (1<<20) // 1 byte, encoding is float/8.0, signed (negative is darklight), not sent if 0
+#define U_GLOWSIZE             (1<<20) // 1 byte, encoding is float/4.0, unsigned, not sent if 0
 #define U_GLOWCOLOR            (1<<21) // 1 byte, palette index, default is 254 (white), this IS used for darklight (allowing colored darklight), however the particles from a darklight are always black, not sent if default value (even if glowsize or glowtrail is set)
 // LordHavoc: colormod feature has been removed, because no one used it
 #define U_COLORMOD             (1<<22) // 1 byte, 3 bit red, 3 bit green, 2 bit blue, this lets you tint an object artifically, so you could make a red rocket, or a blue fiend...
@@ -319,19 +319,24 @@ typedef struct
        unsigned short frame;
        unsigned short effects;
        unsigned short tagentity;
-       unsigned short specialvisibilityradius;
+       unsigned short specialvisibilityradius; // larger if it has effects/light
        unsigned short viewmodelforclient;
        unsigned short exteriormodelforclient;
        unsigned short nodrawtoclient;
        unsigned short drawonlytoclient;
+       unsigned short light[4]; // color*256 (0.00 to almost 64.00), and radius*1
+       qbyte lightstyle;
+       qbyte lightpflags;
        qbyte colormap;
-       qbyte skin;
+       qbyte skin; // also chooses cubemap for rtlights if there is no model
        qbyte alpha;
        qbyte scale;
        qbyte glowsize;
        qbyte glowcolor;
        qbyte flags;
        qbyte tagindex;
+       // padding to a multiple of 8 bytes (to align the double time)
+       qbyte unused[6];
 }
 entity_state_t;
 
@@ -471,15 +476,15 @@ entity_frame_t;
 #define E_EFFECTS2             (1<<18)
 #define E_GLOWSIZE             (1<<19)
 #define E_GLOWCOLOR            (1<<20)
-#define E_UNUSED1              (1<<21)
-#define E_UNUSED2              (1<<22)
+#define E_LIGHT                        (1<<21)
+#define E_LIGHTPFLAGS  (1<<22)
 #define E_EXTEND3              (1<<23)
 
 #define E_SOUND1               (1<<24)
 #define E_SOUNDVOL             (1<<25)
 #define E_SOUNDATTEN   (1<<26)
 #define E_TAGATTACHMENT        (1<<27)
-#define E_UNUSED5              (1<<28)
+#define E_LIGHTSTYLE   (1<<28)
 #define E_UNUSED6              (1<<29)
 #define E_UNUSED7              (1<<30)
 #define E_EXTEND4              (1<<31)
index 364e456..2facc1f 100644 (file)
--- a/r_light.c
+++ b/r_light.c
@@ -126,41 +126,69 @@ void R_BuildLightList(void)
                        continue;
                rd = &r_dlight[r_numdlights++];
                VectorCopy(cd->origin, rd->origin);
-               VectorScale(cd->color, cd->radius * 64.0f, rd->light);
+               VectorScale(cd->color, d_lightstylevalue[cd->style] * (1.0f / 256.0f), rd->color);
+               rd->radius = bound(0, cd->radius, 2048.0f);
+               VectorScale(rd->color, rd->radius * 64.0f, rd->light);
+#if 0
                rd->cullradius2 = DotProduct(rd->light, rd->light) * (0.25f / (64.0f * 64.0f)) + 4096.0f;
                // clamp radius to avoid overflowing division table in lightmap code
-               if (rd->cullradius2 > (2048.0f * 2048.0f))
-                       rd->cullradius2 = (2048.0f * 2048.0f);
+               rd->cullradius2 = bound(0, rd->cullradius2, 2048.0f*2048.0f);
                rd->cullradius = sqrt(rd->cullradius2);
+#else
+               rd->cullradius = rd->radius;
+               rd->cullradius2 = rd->cullradius * rd->cullradius;
+#endif
                rd->subtract = 1.0f / rd->cullradius2;
                rd->ent = cd->ent;
+               rd->cubemapnum = cd->cubemapnum;
+               rd->shadow = cd->shadow;
+               rd->corona = cd->corona;
+
+               rd->matrix_lighttoworld = cd->matrix;
+               Matrix4x4_ConcatScale(&rd->matrix_lighttoworld, rd->cullradius);
+               Matrix4x4_Invert_Simple(&rd->matrix_worldtolight, &rd->matrix_lighttoworld);
+               Matrix4x4_Concat(&rd->matrix_worldtoattenuationxyz, &matrix_attenuationxyz, &rd->matrix_worldtolight);
+               Matrix4x4_Concat(&rd->matrix_worldtoattenuationz, &matrix_attenuationz, &rd->matrix_worldtolight);
+
                c_dlights++; // count every dlight in use
        }
 }
 
 void R_DrawCoronas(void)
 {
-       int i;
+       int i, lnum;
        float cscale, scale, viewdist, dist;
        rdlight_t *rd;
+       worldlight_t *wl;
        if (!r_coronas.integer)
                return;
        R_Mesh_Matrix(&r_identitymatrix);
        viewdist = DotProduct(r_vieworigin, r_viewforward);
+       if (r_shadow_realtime_world.integer)
+       {
+               for (lnum = 0, wl = r_shadow_worldlightchain;wl;wl = wl->next, lnum++)
+               {
+                       if (wl->corona * r_coronas.value > 0 && (r_shadow_debuglight.integer < 0 || r_shadow_debuglight.integer == lnum) && (dist = (DotProduct(wl->origin, r_viewforward) - viewdist)) >= 24.0f && CL_TraceLine(wl->origin, r_vieworigin, NULL, NULL, true, NULL, SUPERCONTENTS_SOLID) == 1)
+                       {
+                               cscale = wl->corona * r_coronas.value * 0.25f;
+                               scale = wl->radius * 0.25f;
+                               R_DrawSprite(GL_ONE, GL_ONE, lightcorona, true, rd->origin, r_viewright, r_viewup, scale, -scale, -scale, scale, wl->color[0] * cscale, wl->color[1] * cscale, wl->color[2] * cscale, 1);
+                       }
+               }
+       }
        for (i = 0;i < r_numdlights;i++)
        {
                rd = r_dlight + i;
-               dist = (DotProduct(rd->origin, r_viewforward) - viewdist);
-               if (dist >= 24.0f && CL_TraceLine(rd->origin, r_vieworigin, NULL, NULL, true, NULL, SUPERCONTENTS_SOLID) == 1)
+               if (rd->corona * r_coronas.value > 0 && (dist = (DotProduct(rd->origin, r_viewforward) - viewdist)) >= 24.0f && CL_TraceLine(rd->origin, r_vieworigin, NULL, NULL, true, NULL, SUPERCONTENTS_SOLID) == 1)
                {
-                       cscale = (1.0f / 131072.0f);
-                       scale = rd->cullradius * 0.25f;
+                       cscale = rd->corona * r_coronas.value * 0.25f;
+                       scale = rd->radius * 0.25f;
                        if (gl_flashblend.integer)
                        {
                                cscale *= 4.0f;
                                scale *= 2.0f;
                        }
-                       R_DrawSprite(GL_ONE, GL_ONE, lightcorona, true, rd->origin, r_viewright, r_viewup, scale, -scale, -scale, scale, rd->light[0] * cscale, rd->light[1] * cscale, rd->light[2] * cscale, 1);
+                       R_DrawSprite(GL_ONE, GL_ONE, lightcorona, true, rd->origin, r_viewright, r_viewup, scale, -scale, -scale, scale, rd->color[0] * cscale, rd->color[1] * cscale, rd->color[2] * cscale, 1);
                }
        }
 }
index 379c1b8..a3c7066 100644 (file)
--- a/r_light.h
+++ b/r_light.h
@@ -10,6 +10,17 @@ typedef struct
        vec_t cullradius; // only for culling comparisons
        vec_t subtract; // to avoid sudden brightness change at cullradius, subtract this
        entity_render_t *ent; // owner of this light
+
+       matrix4x4_t matrix_lighttoworld;
+       matrix4x4_t matrix_worldtolight;
+       matrix4x4_t matrix_worldtoattenuationxyz;
+       matrix4x4_t matrix_worldtoattenuationz;
+
+       vec3_t color;
+       vec_t radius;
+       int cubemapnum;
+       int shadow;
+       vec_t corona;
 }
 rdlight_t;
 
index e57f851..060ab75 100644 (file)
@@ -302,6 +302,26 @@ void R_Shadow_Init(void)
        R_RegisterModule("R_Shadow", r_shadow_start, r_shadow_shutdown, r_shadow_newmap);
 }
 
+matrix4x4_t matrix_attenuationxyz =
+{
+       {
+               {0.5, 0.0, 0.0, 0.5},
+               {0.0, 0.5, 0.0, 0.5},
+               {0.0, 0.0, 0.5, 0.5},
+               {0.0, 0.0, 0.0, 1.0}
+       }
+};
+
+matrix4x4_t matrix_attenuationz =
+{
+       {
+               {0.0, 0.0, 0.5, 0.5},
+               {0.0, 0.0, 0.0, 0.0},
+               {0.0, 0.0, 0.0, 0.0},
+               {0.0, 0.0, 0.0, 1.0}
+       }
+};
+
 void R_Shadow_ResizeTriangleFacingLight(int numtris)
 {
        // make sure trianglefacinglight is big enough for this volume
@@ -1259,7 +1279,7 @@ void R_Shadow_GenTexCoords_Specular_NormalCubeMap(float *out3f, int numverts, co
        }
 }
 
-void R_Shadow_DiffuseLighting(int numverts, int numtriangles, const int *elements, const float *vertex3f, const float *svector3f, const float *tvector3f, const float *normal3f, const float *texcoord2f, const float *relativelightorigin, float lightradius, const float *lightcolor, const matrix4x4_t *matrix_modeltofilter, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *basetexture, rtexture_t *bumptexture, rtexture_t *lightcubemap)
+void R_Shadow_DiffuseLighting(int numverts, int numtriangles, const int *elements, const float *vertex3f, const float *svector3f, const float *tvector3f, const float *normal3f, const float *texcoord2f, const float *relativelightorigin, float lightradius, const float *lightcolor, const matrix4x4_t *matrix_modeltolight, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *basetexture, rtexture_t *bumptexture, rtexture_t *lightcubemap)
 {
        int renders;
        float color[3], color2[3];
@@ -1302,7 +1322,7 @@ void R_Shadow_DiffuseLighting(int numverts, int numtriangles, const int *element
                        {
                                m.texcubemap[1] = R_GetTexture(lightcubemap);
                                m.pointer_texcoord[1] = varray_texcoord3f[1];
-                               R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1], numverts, vertex3f, matrix_modeltofilter);
+                               R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1], numverts, vertex3f, matrix_modeltolight);
                        }
                        R_Mesh_State_Texture(&m);
                        qglColorMask(1,1,1,0);
@@ -1354,7 +1374,7 @@ void R_Shadow_DiffuseLighting(int numverts, int numtriangles, const int *element
                        {
                                m.texcubemap[1] = R_GetTexture(lightcubemap);
                                m.pointer_texcoord[1] = varray_texcoord3f[1];
-                               R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1], numverts, vertex3f, matrix_modeltofilter);
+                               R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1], numverts, vertex3f, matrix_modeltolight);
                        }
                        R_Mesh_State_Texture(&m);
                        qglColorMask(1,1,1,0);
@@ -1441,7 +1461,7 @@ void R_Shadow_DiffuseLighting(int numverts, int numtriangles, const int *element
                        {
                                m.texcubemap[1] = R_GetTexture(lightcubemap);
                                m.pointer_texcoord[1] = varray_texcoord3f[1];
-                               R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1], numverts, vertex3f, matrix_modeltofilter);
+                               R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1], numverts, vertex3f, matrix_modeltolight);
                        }
                        R_Mesh_State_Texture(&m);
                        qglColorMask(1,1,1,0);
@@ -1496,7 +1516,7 @@ void R_Shadow_DiffuseLighting(int numverts, int numtriangles, const int *element
                        {
                                m.texcubemap[1] = R_GetTexture(lightcubemap);
                                m.pointer_texcoord[1] = varray_texcoord3f[1];
-                               R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1], numverts, vertex3f, matrix_modeltofilter);
+                               R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1], numverts, vertex3f, matrix_modeltolight);
                        }
                        R_Mesh_State_Texture(&m);
                        qglColorMask(1,1,1,0);
@@ -1538,9 +1558,9 @@ void R_Shadow_DiffuseLighting(int numverts, int numtriangles, const int *element
                        color[1] = bound(0, color2[1], 1);
                        color[2] = bound(0, color2[2], 1);
                        if (r_textureunits.integer >= 2)
-                               R_Shadow_VertexLightingWithXYAttenuationTexture(numverts, vertex3f, normal3f, color, matrix_modeltofilter);
+                               R_Shadow_VertexLightingWithXYAttenuationTexture(numverts, vertex3f, normal3f, color, matrix_modeltolight);
                        else
-                               R_Shadow_VertexLighting(numverts, vertex3f, normal3f, color, matrix_modeltofilter);
+                               R_Shadow_VertexLighting(numverts, vertex3f, normal3f, color, matrix_modeltolight);
                        R_Mesh_Draw(numverts, numtriangles, elements);
                        c_rt_lightmeshes++;
                        c_rt_lighttris += numtriangles;
@@ -1548,7 +1568,7 @@ void R_Shadow_DiffuseLighting(int numverts, int numtriangles, const int *element
        }
 }
 
-void R_Shadow_SpecularLighting(int numverts, int numtriangles, const int *elements, const float *vertex3f, const float *svector3f, const float *tvector3f, const float *normal3f, const float *texcoord2f, const float *relativelightorigin, const float *relativeeyeorigin, float lightradius, const float *lightcolor, const matrix4x4_t *matrix_modeltofilter, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *glosstexture, rtexture_t *bumptexture, rtexture_t *lightcubemap)
+void R_Shadow_SpecularLighting(int numverts, int numtriangles, const int *elements, const float *vertex3f, const float *svector3f, const float *tvector3f, const float *normal3f, const float *texcoord2f, const float *relativelightorigin, const float *relativeeyeorigin, float lightradius, const float *lightcolor, const matrix4x4_t *matrix_modeltolight, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *glosstexture, rtexture_t *bumptexture, rtexture_t *lightcubemap)
 {
        int renders;
        float color[3], color2[3], colorscale;
@@ -1615,7 +1635,7 @@ void R_Shadow_SpecularLighting(int numverts, int numtriangles, const int *elemen
                        {
                                m.texcubemap[1] = R_GetTexture(lightcubemap);
                                m.pointer_texcoord[1] = varray_texcoord3f[1];
-                               R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1], numverts, vertex3f, matrix_modeltofilter);
+                               R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1], numverts, vertex3f, matrix_modeltolight);
                        }
                        m.pointer_texcoord[0] = texcoord2f;
                        R_Mesh_State_Texture(&m);
@@ -1739,7 +1759,7 @@ void R_Shadow_SpecularLighting(int numverts, int numtriangles, const int *elemen
                        {
                                m.texcubemap[1] = R_GetTexture(lightcubemap);
                                m.pointer_texcoord[1] = varray_texcoord3f[1];
-                               R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1], numverts, vertex3f, matrix_modeltofilter);
+                               R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1], numverts, vertex3f, matrix_modeltolight);
                        }
                        m.pointer_texcoord[0] = texcoord2f;
                        R_Mesh_State_Texture(&m);
@@ -1794,7 +1814,7 @@ void R_Shadow_DrawStaticWorldLight_Shadow(worldlight_t *light, matrix4x4_t *matr
        R_Shadow_RenderShadowMeshVolume(light->meshchain_shadow);
 }
 
-void R_Shadow_DrawStaticWorldLight_Light(worldlight_t *light, matrix4x4_t *matrix, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltofilter, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz)
+void R_Shadow_DrawStaticWorldLight_Light(worldlight_t *light, matrix4x4_t *matrix, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltolight, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz)
 {
        shadowmesh_t *mesh;
        R_Mesh_Matrix(matrix);
@@ -1823,8 +1843,8 @@ void R_Shadow_DrawStaticWorldLight_Light(worldlight_t *light, matrix4x4_t *matri
        }
        for (mesh = light->meshchain_light;mesh;mesh = mesh->next)
        {
-               R_Shadow_DiffuseLighting(mesh->numverts, mesh->numtriangles, mesh->element3i, mesh->vertex3f, mesh->svector3f, mesh->tvector3f, mesh->normal3f, mesh->texcoord2f, relativelightorigin, lightradius, lightcolor, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, mesh->map_diffuse, mesh->map_normal, light->cubemap);
-               R_Shadow_SpecularLighting(mesh->numverts, mesh->numtriangles, mesh->element3i, mesh->vertex3f, mesh->svector3f, mesh->tvector3f, mesh->normal3f, mesh->texcoord2f, relativelightorigin, relativeeyeorigin, lightradius, lightcolor, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, mesh->map_specular, mesh->map_normal, light->cubemap);
+               R_Shadow_DiffuseLighting(mesh->numverts, mesh->numtriangles, mesh->element3i, mesh->vertex3f, mesh->svector3f, mesh->tvector3f, mesh->normal3f, mesh->texcoord2f, relativelightorigin, lightradius, lightcolor, matrix_modeltolight, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, mesh->map_diffuse, mesh->map_normal, light->cubemap);
+               R_Shadow_SpecularLighting(mesh->numverts, mesh->numtriangles, mesh->element3i, mesh->vertex3f, mesh->svector3f, mesh->tvector3f, mesh->normal3f, mesh->texcoord2f, relativelightorigin, relativeeyeorigin, lightradius, lightcolor, matrix_modeltolight, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, mesh->map_specular, mesh->map_normal, light->cubemap);
        }
 }
 
@@ -1963,7 +1983,7 @@ void R_Shadow_FreeCubemaps(void)
        R_FreeTexturePool(&r_shadow_filters_texturepool);
 }
 
-void R_Shadow_NewWorldLight(vec3_t origin, float radius, vec3_t color, int style, const char *cubemapname, int castshadow)
+void R_Shadow_NewWorldLight(vec3_t origin, vec3_t angles, vec3_t color, vec_t radius, vec_t corona, int style, int shadowenable, const char *cubemapname)
 {
        int i, j, k, l, maxverts = 256, tris;
        float *vertex3f = NULL, mins[3], maxs[3];
@@ -1978,21 +1998,28 @@ void R_Shadow_NewWorldLight(vec3_t origin, float radius, vec3_t color, int style
 
        e = Mem_Alloc(r_shadow_mempool, sizeof(worldlight_t));
        VectorCopy(origin, e->origin);
-       VectorCopy(color, e->light);
-       e->lightradius = radius;
+       VectorCopy(angles, e->angles);
+       VectorCopy(color, e->color);
+       e->radius = radius;
        e->style = style;
        if (e->style < 0 || e->style >= MAX_LIGHTSTYLES)
        {
                Con_Printf("R_Shadow_NewWorldLight: invalid light style number %i, must be >= 0 and < %i\n", e->style, MAX_LIGHTSTYLES);
                e->style = 0;
        }
-       e->castshadows = castshadow;
+       e->drawshadows = shadowenable;
+       e->corona = corona;
 
-       e->cullradius = e->lightradius;
+       Matrix4x4_CreateFromQuakeEntity(&e->matrix_lighttoworld, e->origin[0], e->origin[1], e->origin[2], e->angles[0], e->angles[1], e->angles[2], e->radius);
+       Matrix4x4_Invert_Simple(&e->matrix_worldtolight, &e->matrix_lighttoworld);
+       Matrix4x4_Concat(&e->matrix_worldtoattenuationxyz, &matrix_attenuationxyz, &e->matrix_worldtolight);
+       Matrix4x4_Concat(&e->matrix_worldtoattenuationz, &matrix_attenuationz, &e->matrix_worldtolight);
+
+       e->cullradius = e->radius;
        for (k = 0;k < 3;k++)
        {
-               mins[k] = e->origin[k] - e->lightradius;
-               maxs[k] = e->origin[k] + e->lightradius;
+               mins[k] = e->origin[k] - e->radius;
+               maxs[k] = e->origin[k] + e->radius;
        }
 
        e->next = r_shadow_worldlightchain;
@@ -2004,7 +2031,7 @@ void R_Shadow_NewWorldLight(vec3_t origin, float radius, vec3_t color, int style
                e->cubemap = R_Shadow_Cubemap(e->cubemapname);
        }
        // FIXME: rewrite this to store ALL geometry into a cache in the light
-       if (e->castshadows)
+       if (e->drawshadows)
                castmesh = Mod_ShadowMesh_Begin(r_shadow_mempool, 32768, 32768, NULL, NULL, NULL, false, false, true);
        e->meshchain_light = Mod_ShadowMesh_Begin(r_shadow_mempool, 32768, 32768, NULL, NULL, NULL, true, false, true);
        if (cl.worldmodel)
@@ -2044,7 +2071,7 @@ void R_Shadow_NewWorldLight(vec3_t origin, float radius, vec3_t color, int style
                                        face->lighttemp_castshadow = false;
                                        if (!(face->texture->surfaceflags & (Q3SURFACEFLAG_NODRAW | Q3SURFACEFLAG_SKY)))
                                        {
-                                               if (e->castshadows)
+                                               if (e->drawshadows)
                                                        if (!(face->texture->nativecontents & CONTENTSQ3_TRANSLUCENT))
                                                                Mod_ShadowMesh_AddMesh(r_shadow_mempool, castmesh, NULL, NULL, NULL, face->data_vertex3f, NULL, NULL, NULL, NULL, face->num_triangles, face->data_element3i);
                                                if (!(face->texture->surfaceflags & Q3SURFACEFLAG_SKY))
@@ -2121,7 +2148,7 @@ void R_Shadow_NewWorldLight(vec3_t origin, float radius, vec3_t color, int style
                                if (surf->lighttemp_castshadow)
                                {
                                        surf->lighttemp_castshadow = false;
-                                       if (e->castshadows && (surf->flags & SURF_SHADOWCAST))
+                                       if (e->drawshadows && (surf->flags & SURF_SHADOWCAST))
                                                Mod_ShadowMesh_AddMesh(r_shadow_mempool, castmesh, NULL, NULL, NULL, surf->mesh.data_vertex3f, NULL, NULL, NULL, NULL, surf->mesh.num_triangles, surf->mesh.data_element3i);
                                        if (!(surf->flags & SURF_DRAWSKY))
                                                Mod_ShadowMesh_AddMesh(r_shadow_mempool, e->meshchain_light, surf->texinfo->texture->skin.base, surf->texinfo->texture->skin.gloss, surf->texinfo->texture->skin.nmap, surf->mesh.data_vertex3f, surf->mesh.data_svector3f, surf->mesh.data_tvector3f, surf->mesh.data_normal3f, surf->mesh.data_texcoordtexture2f, surf->mesh.num_triangles, surf->mesh.data_element3i);
@@ -2133,8 +2160,8 @@ void R_Shadow_NewWorldLight(vec3_t origin, float radius, vec3_t color, int style
        // limit box to light bounds (in case it grew larger)
        for (k = 0;k < 3;k++)
        {
-               if (e->mins[k] < e->origin[k] - e->lightradius) e->mins[k] = e->origin[k] - e->lightradius;
-               if (e->maxs[k] > e->origin[k] + e->lightradius) e->maxs[k] = e->origin[k] + e->lightradius;
+               if (e->mins[k] < e->origin[k] - e->radius) e->mins[k] = e->origin[k] - e->radius;
+               if (e->maxs[k] > e->origin[k] + e->radius) e->maxs[k] = e->origin[k] + e->radius;
        }
        e->cullradius = RadiusFromBoundsAndOrigin(e->mins, e->maxs, e->origin);
 
@@ -2154,7 +2181,7 @@ void R_Shadow_NewWorldLight(vec3_t origin, float radius, vec3_t color, int style
                        vertex3f = Mem_Alloc(r_shadow_mempool, maxverts * sizeof(float[3]));
                        // now that we have the buffers big enough, construct and add
                        // the shadow volume mesh
-                       if (e->castshadows)
+                       if (e->drawshadows)
                                e->meshchain_shadow = Mod_ShadowMesh_Begin(r_shadow_mempool, 32768, 32768, NULL, NULL, NULL, false, false, true);
                        for (mesh = castmesh;mesh;mesh = mesh->next)
                        {
@@ -2282,7 +2309,7 @@ void R_Shadow_LoadWorldLights(void)
 {
        int n, a, style, shadow;
        char name[MAX_QPATH], cubemapname[MAX_QPATH], *lightsstring, *s, *t;
-       float origin[3], radius, color[3];
+       float origin[3], radius, color[3], angles[3], corona;
        if (cl.worldmodel == NULL)
        {
                Con_Printf("No map loaded.\n");
@@ -2310,7 +2337,12 @@ void R_Shadow_LoadWorldLights(void)
                                shadow = false;
                                t++;
                        }
-                       a = sscanf(t, "%f %f %f %f %f %f %f %d %s", &origin[0], &origin[1], &origin[2], &radius, &color[0], &color[1], &color[2], &style, cubemapname);
+                       a = sscanf(t, "%f %f %f %f %f %f %f %d %s %f %f %f %f", &origin[0], &origin[1], &origin[2], &radius, &color[0], &color[1], &color[2], &style, cubemapname, &corona, &angles[0], &angles[1], &angles[2]);
+                       if (a < 13)
+                       {
+                               corona = 0;
+                               VectorClear(angles);
+                       }
                        if (a < 9)
                                cubemapname[0] = 0;
                        *s = '\n';
@@ -2321,7 +2353,7 @@ void R_Shadow_LoadWorldLights(void)
                        }
                        VectorScale(color, r_editlights_rtlightscolorscale.value, color);
                        radius *= r_editlights_rtlightssizescale.value;
-                       R_Shadow_NewWorldLight(origin, radius, color, style, cubemapname, shadow);
+                       R_Shadow_NewWorldLight(origin, angles, color, radius, corona, style, shadow, cubemapname);
                        s++;
                        n++;
                }
@@ -2351,7 +2383,7 @@ void R_Shadow_SaveWorldLights(void)
        buf = NULL;
        for (light = r_shadow_worldlightchain;light;light = light->next)
        {
-               sprintf(line, "%s%f %f %f %f %f %f %f %d %s\n", light->castshadows ? "" : "!", light->origin[0], light->origin[1], light->origin[2], light->lightradius / r_editlights_rtlightssizescale.value, light->light[0] / r_editlights_rtlightscolorscale.value, light->light[1] / r_editlights_rtlightscolorscale.value, light->light[2] / r_editlights_rtlightscolorscale.value, light->style, light->cubemapname ? light->cubemapname : "");
+               sprintf(line, "%s%f %f %f %f %f %f %f %d %s\n", light->drawshadows ? "" : "!", light->origin[0], light->origin[1], light->origin[2], light->radius / r_editlights_rtlightssizescale.value, light->color[0] / r_editlights_rtlightscolorscale.value, light->color[1] / r_editlights_rtlightscolorscale.value, light->color[2] / r_editlights_rtlightscolorscale.value, light->style, light->cubemapname ? light->cubemapname : "");
                if (bufchars + (int) strlen(line) > bufmaxchars)
                {
                        bufmaxchars = bufchars + strlen(line) + 2048;
@@ -2411,7 +2443,7 @@ void R_Shadow_LoadLightsFile(void)
                        radius = sqrt(DotProduct(color, color) / (falloff * falloff * 8192.0f * 8192.0f));
                        radius = bound(15, radius, 4096);
                        VectorScale(color, (2.0f / (8388608.0f)), color);
-                       R_Shadow_NewWorldLight(origin, radius, color, style, NULL, true);
+                       R_Shadow_NewWorldLight(origin, vec3_origin, color, radius, 0, style, true, NULL);
                        s++;
                        n++;
                }
@@ -2565,7 +2597,7 @@ void R_Shadow_LoadWorldLightsFromMap_LightArghliteTyrlite(void)
                VectorScale(color, light, color);
                VectorAdd(origin, originhack, origin);
                if (radius >= 15)
-                       R_Shadow_NewWorldLight(origin, radius, color, style, NULL, true);
+                       R_Shadow_NewWorldLight(origin, vec3_origin, color, radius, 0, style, true, NULL);
        }
 }
 
@@ -2645,13 +2677,13 @@ void R_Shadow_EditLights_Spawn_f(void)
                return;
        }
        color[0] = color[1] = color[2] = 1;
-       R_Shadow_NewWorldLight(r_editlights_cursorlocation, 200, color, 0, NULL, true);
+       R_Shadow_NewWorldLight(r_editlights_cursorlocation, vec3_origin, color, 200, 0, 0, true, NULL);
 }
 
 void R_Shadow_EditLights_Edit_f(void)
 {
-       vec3_t origin, color;
-       vec_t radius;
+       vec3_t origin, angles, color;
+       vec_t radius, corona;
        int style, shadows;
        char cubemapname[1024];
        if (!r_editlights.integer)
@@ -2665,19 +2697,21 @@ void R_Shadow_EditLights_Edit_f(void)
                return;
        }
        VectorCopy(r_shadow_selectedlight->origin, origin);
-       radius = r_shadow_selectedlight->lightradius;
-       VectorCopy(r_shadow_selectedlight->light, color);
+       VectorCopy(r_shadow_selectedlight->angles, angles);
+       VectorCopy(r_shadow_selectedlight->color, color);
+       radius = r_shadow_selectedlight->radius;
        style = r_shadow_selectedlight->style;
        if (r_shadow_selectedlight->cubemapname)
                strcpy(cubemapname, r_shadow_selectedlight->cubemapname);
        else
                cubemapname[0] = 0;
-       shadows = r_shadow_selectedlight->castshadows;
+       shadows = r_shadow_selectedlight->drawshadows;
+       corona = r_shadow_selectedlight->corona;
        if (!strcmp(Cmd_Argv(1), "origin"))
        {
                if (Cmd_Argc() != 5)
                {
-                       Con_Printf("usage: r_editlights_edit %s x y z\n", Cmd_Argv(0));
+                       Con_Printf("usage: r_editlights_edit %s x y z\n", Cmd_Argv(1));
                        return;
                }
                origin[0] = atof(Cmd_Argv(2));
@@ -2688,7 +2722,7 @@ void R_Shadow_EditLights_Edit_f(void)
        {
                if (Cmd_Argc() != 3)
                {
-                       Con_Printf("usage: r_editlights_edit %s value\n", Cmd_Argv(0));
+                       Con_Printf("usage: r_editlights_edit %s value\n", Cmd_Argv(1));
                        return;
                }
                origin[0] = atof(Cmd_Argv(2));
@@ -2697,7 +2731,7 @@ void R_Shadow_EditLights_Edit_f(void)
        {
                if (Cmd_Argc() != 3)
                {
-                       Con_Printf("usage: r_editlights_edit %s value\n", Cmd_Argv(0));
+                       Con_Printf("usage: r_editlights_edit %s value\n", Cmd_Argv(1));
                        return;
                }
                origin[1] = atof(Cmd_Argv(2));
@@ -2706,7 +2740,7 @@ void R_Shadow_EditLights_Edit_f(void)
        {
                if (Cmd_Argc() != 3)
                {
-                       Con_Printf("usage: r_editlights_edit %s value\n", Cmd_Argv(0));
+                       Con_Printf("usage: r_editlights_edit %s value\n", Cmd_Argv(1));
                        return;
                }
                origin[2] = atof(Cmd_Argv(2));
@@ -2715,7 +2749,7 @@ void R_Shadow_EditLights_Edit_f(void)
        {
                if (Cmd_Argc() != 5)
                {
-                       Con_Printf("usage: r_editlights_edit %s x y z\n", Cmd_Argv(0));
+                       Con_Printf("usage: r_editlights_edit %s x y z\n", Cmd_Argv(1));
                        return;
                }
                origin[0] += atof(Cmd_Argv(2));
@@ -2726,7 +2760,7 @@ void R_Shadow_EditLights_Edit_f(void)
        {
                if (Cmd_Argc() != 3)
                {
-                       Con_Printf("usage: r_editlights_edit %s value\n", Cmd_Argv(0));
+                       Con_Printf("usage: r_editlights_edit %s value\n", Cmd_Argv(1));
                        return;
                }
                origin[0] += atof(Cmd_Argv(2));
@@ -2735,7 +2769,7 @@ void R_Shadow_EditLights_Edit_f(void)
        {
                if (Cmd_Argc() != 3)
                {
-                       Con_Printf("usage: r_editlights_edit %s value\n", Cmd_Argv(0));
+                       Con_Printf("usage: r_editlights_edit %s value\n", Cmd_Argv(1));
                        return;
                }
                origin[1] += atof(Cmd_Argv(2));
@@ -2744,16 +2778,54 @@ void R_Shadow_EditLights_Edit_f(void)
        {
                if (Cmd_Argc() != 3)
                {
-                       Con_Printf("usage: r_editlights_edit %s value\n", Cmd_Argv(0));
+                       Con_Printf("usage: r_editlights_edit %s value\n", Cmd_Argv(1));
                        return;
                }
                origin[2] += atof(Cmd_Argv(2));
        }
+       if (!strcmp(Cmd_Argv(1), "angles"))
+       {
+               if (Cmd_Argc() != 5)
+               {
+                       Con_Printf("usage: r_editlights_edit %s x y z\n", Cmd_Argv(1));
+                       return;
+               }
+               angles[0] = atof(Cmd_Argv(2));
+               angles[1] = atof(Cmd_Argv(3));
+               angles[2] = atof(Cmd_Argv(4));
+       }
+       else if (!strcmp(Cmd_Argv(1), "anglesx"))
+       {
+               if (Cmd_Argc() != 3)
+               {
+                       Con_Printf("usage: r_editlights_edit %s value\n", Cmd_Argv(1));
+                       return;
+               }
+               angles[0] = atof(Cmd_Argv(2));
+       }
+       else if (!strcmp(Cmd_Argv(1), "anglesy"))
+       {
+               if (Cmd_Argc() != 3)
+               {
+                       Con_Printf("usage: r_editlights_edit %s value\n", Cmd_Argv(1));
+                       return;
+               }
+               angles[1] = atof(Cmd_Argv(2));
+       }
+       else if (!strcmp(Cmd_Argv(1), "anglesz"))
+       {
+               if (Cmd_Argc() != 3)
+               {
+                       Con_Printf("usage: r_editlights_edit %s value\n", Cmd_Argv(1));
+                       return;
+               }
+               angles[2] = atof(Cmd_Argv(2));
+       }
        else if (!strcmp(Cmd_Argv(1), "color"))
        {
                if (Cmd_Argc() != 5)
                {
-                       Con_Printf("usage: r_editlights_edit %s red green blue\n", Cmd_Argv(0));
+                       Con_Printf("usage: r_editlights_edit %s red green blue\n", Cmd_Argv(1));
                        return;
                }
                color[0] = atof(Cmd_Argv(2));
@@ -2764,7 +2836,7 @@ void R_Shadow_EditLights_Edit_f(void)
        {
                if (Cmd_Argc() != 3)
                {
-                       Con_Printf("usage: r_editlights_edit %s value\n", Cmd_Argv(0));
+                       Con_Printf("usage: r_editlights_edit %s value\n", Cmd_Argv(1));
                        return;
                }
                radius = atof(Cmd_Argv(2));
@@ -2773,7 +2845,7 @@ void R_Shadow_EditLights_Edit_f(void)
        {
                if (Cmd_Argc() != 3)
                {
-                       Con_Printf("usage: r_editlights_edit %s value\n", Cmd_Argv(0));
+                       Con_Printf("usage: r_editlights_edit %s value\n", Cmd_Argv(1));
                        return;
                }
                style = atoi(Cmd_Argv(2));
@@ -2782,7 +2854,7 @@ void R_Shadow_EditLights_Edit_f(void)
        {
                if (Cmd_Argc() > 3)
                {
-                       Con_Printf("usage: r_editlights_edit %s value\n", Cmd_Argv(0));
+                       Con_Printf("usage: r_editlights_edit %s value\n", Cmd_Argv(1));
                        return;
                }
                if (Cmd_Argc() == 3)
@@ -2794,26 +2866,37 @@ void R_Shadow_EditLights_Edit_f(void)
        {
                if (Cmd_Argc() != 3)
                {
-                       Con_Printf("usage: r_editlights_edit %s value\n", Cmd_Argv(0));
+                       Con_Printf("usage: r_editlights_edit %s value\n", Cmd_Argv(1));
                        return;
                }
                shadows = Cmd_Argv(2)[0] == 'y' || Cmd_Argv(2)[0] == 'Y' || Cmd_Argv(2)[0] == 't' || atoi(Cmd_Argv(2));
        }
+       else if (!strcmp(Cmd_Argv(1), "corona"))
+       {
+               if (Cmd_Argc() != 3)
+               {
+                       Con_Printf("usage: r_editlights_edit %s value\n", Cmd_Argv(1));
+                       return;
+               }
+               corona = atof(Cmd_Argv(2));
+       }
        else
        {
                Con_Printf("usage: r_editlights_edit [property] [value]\n");
                Con_Printf("Selected light's properties:\n");
-               Con_Printf("Origin: %f %f %f\n", r_shadow_selectedlight->origin[0], r_shadow_selectedlight->origin[1], r_shadow_selectedlight->origin[2]);
-               Con_Printf("Radius: %f\n", r_shadow_selectedlight->lightradius);
-               Con_Printf("Color: %f %f %f\n", r_shadow_selectedlight->light[0], r_shadow_selectedlight->light[1], r_shadow_selectedlight->light[2]);
-               Con_Printf("Style: %i\n", r_shadow_selectedlight->style);
+               Con_Printf("Origin : %f %f %f\n", r_shadow_selectedlight->origin[0], r_shadow_selectedlight->origin[1], r_shadow_selectedlight->origin[2]);
+               Con_Printf("Angles : %f %f %f\n", r_shadow_selectedlight->angles[0], r_shadow_selectedlight->angles[1], r_shadow_selectedlight->angles[2]);
+               Con_Printf("Color  : %f %f %f\n", r_shadow_selectedlight->color[0], r_shadow_selectedlight->color[1], r_shadow_selectedlight->color[2]);
+               Con_Printf("Radius : %f\n", r_shadow_selectedlight->radius);
+               Con_Printf("Corona : %f\n", r_shadow_selectedlight->corona);
+               Con_Printf("Style  : %i\n", r_shadow_selectedlight->style);
+               Con_Printf("Shadows: %s\n", r_shadow_selectedlight->drawshadows ? "yes" : "no");
                Con_Printf("Cubemap: %s\n", r_shadow_selectedlight->cubemapname);
-               Con_Printf("Shadows: %s\n", r_shadow_selectedlight->castshadows ? "yes" : "no");
                return;
        }
        R_Shadow_FreeWorldLight(r_shadow_selectedlight);
        r_shadow_selectedlight = NULL;
-       R_Shadow_NewWorldLight(origin, radius, color, style, cubemapname, shadows);
+       R_Shadow_NewWorldLight(origin, angles, color, radius, corona, style, shadows, cubemapname);
 }
 
 extern int con_vislines;
@@ -2826,12 +2909,14 @@ void R_Shadow_EditLights_DrawSelectedLightProperties(void)
        x = 0;
        y = con_vislines;
        sprintf(temp, "Light properties");DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0);y += 8;
-       sprintf(temp, "Origin %f %f %f", r_shadow_selectedlight->origin[0], r_shadow_selectedlight->origin[1], r_shadow_selectedlight->origin[2]);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0);y += 8;
-       sprintf(temp, "Radius %f", r_shadow_selectedlight->lightradius);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0);y += 8;
-       sprintf(temp, "Color %f %f %f", r_shadow_selectedlight->light[0], r_shadow_selectedlight->light[1], r_shadow_selectedlight->light[2]);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0);y += 8;
-       sprintf(temp, "Style %i", r_shadow_selectedlight->style);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0);y += 8;
+       sprintf(temp, "Origin  %f %f %f", r_shadow_selectedlight->origin[0], r_shadow_selectedlight->origin[1], r_shadow_selectedlight->origin[2]);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0);y += 8;
+       sprintf(temp, "Angles  %f %f %f", r_shadow_selectedlight->angles[0], r_shadow_selectedlight->angles[1], r_shadow_selectedlight->angles[2]);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0);y += 8;
+       sprintf(temp, "Color   %f %f %f", r_shadow_selectedlight->color[0], r_shadow_selectedlight->color[1], r_shadow_selectedlight->color[2]);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0);y += 8;
+       sprintf(temp, "Radius  %f", r_shadow_selectedlight->radius);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0);y += 8;
+       sprintf(temp, "Corona  %f", r_shadow_selectedlight->corona);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0);y += 8;
+       sprintf(temp, "Style   %i", r_shadow_selectedlight->style);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0);y += 8;
+       sprintf(temp, "Shadows %s", r_shadow_selectedlight->drawshadows ? "yes" : "no");DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0);y += 8;
        sprintf(temp, "Cubemap %s", r_shadow_selectedlight->cubemapname);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0);y += 8;
-       sprintf(temp, "Shadows %s", r_shadow_selectedlight->castshadows ? "yes" : "no");DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0);y += 8;
 }
 
 void R_Shadow_EditLights_ToggleShadow_f(void)
@@ -2846,7 +2931,24 @@ void R_Shadow_EditLights_ToggleShadow_f(void)
                Con_Printf("No selected light.\n");
                return;
        }
-       R_Shadow_NewWorldLight(r_shadow_selectedlight->origin, r_shadow_selectedlight->lightradius, r_shadow_selectedlight->light, r_shadow_selectedlight->style, r_shadow_selectedlight->cubemapname, !r_shadow_selectedlight->castshadows);
+       R_Shadow_NewWorldLight(r_shadow_selectedlight->origin, r_shadow_selectedlight->angles, r_shadow_selectedlight->color, r_shadow_selectedlight->radius, r_shadow_selectedlight->corona, r_shadow_selectedlight->style, !r_shadow_selectedlight->drawshadows, r_shadow_selectedlight->cubemapname);
+       R_Shadow_FreeWorldLight(r_shadow_selectedlight);
+       r_shadow_selectedlight = NULL;
+}
+
+void R_Shadow_EditLights_ToggleCorona_f(void)
+{
+       if (!r_editlights.integer)
+       {
+               Con_Printf("Cannot spawn light when not in editing mode.  Set r_editlights to 1.\n");
+               return;
+       }
+       if (!r_shadow_selectedlight)
+       {
+               Con_Printf("No selected light.\n");
+               return;
+       }
+       R_Shadow_NewWorldLight(r_shadow_selectedlight->origin, r_shadow_selectedlight->angles, r_shadow_selectedlight->color, r_shadow_selectedlight->radius, !r_shadow_selectedlight->corona, r_shadow_selectedlight->style, r_shadow_selectedlight->drawshadows, r_shadow_selectedlight->cubemapname);
        R_Shadow_FreeWorldLight(r_shadow_selectedlight);
        r_shadow_selectedlight = NULL;
 }
@@ -2900,11 +3002,16 @@ void R_Shadow_EditLights_Help_f(void)
 "movex x: adjust x component of light location\n"
 "movey y: adjust y component of light location\n"
 "movez z: adjust z component of light location\n"
+"angles x y z : set light angles\n"
+"anglesx x: set x component of light angles\n"
+"anglesy y: set y component of light angles\n"
+"anglesz z: set z component of light angles\n"
 "color r g b : set color of light (can be brighter than 1 1 1)\n"
 "radius radius : set radius (size) of light\n"
 "style style : set lightstyle of light (flickering patterns, switches, etc)\n"
 "cubemap basename : set filter cubemap of light (not yet supported)\n"
 "shadows 1/0 : turn on/off shadows\n"
+"corona n : set corona intensity\n"
 "<nothing> : print light properties to console\n"
        );
 }
@@ -2927,6 +3034,8 @@ void R_Shadow_EditLights_Init(void)
        Cmd_AddCommand("r_editlights_edit", R_Shadow_EditLights_Edit_f);
        Cmd_AddCommand("r_editlights_remove", R_Shadow_EditLights_Remove_f);
        Cmd_AddCommand("r_editlights_toggleshadow", R_Shadow_EditLights_ToggleShadow_f);
+       Cmd_AddCommand("r_editlights_togglecorona", R_Shadow_EditLights_ToggleCorona_f);
        Cmd_AddCommand("r_editlights_importlightentitiesfrommap", R_Shadow_EditLights_ImportLightEntitiesFromMap_f);
        Cmd_AddCommand("r_editlights_importlightsfile", R_Shadow_EditLights_ImportLightsFile_f);
 }
+
index 7a2da06..953c883 100644 (file)
@@ -17,8 +17,8 @@ extern cvar_t r_shadow_dlightshadows;
 
 void R_Shadow_Init(void);
 void R_Shadow_Volume(int numverts, int numtris, const float *invertex3f, int *elements, int *neighbors, vec3_t relativelightorigin, float lightradius, float projectdistance);
-void R_Shadow_DiffuseLighting(int numverts, int numtriangles, const int *elements, const float *vertices, const float *svectors, const float *tvectors, const float *normals, const float *texcoords, const float *relativelightorigin, float lightradius, const float *lightcolor, const matrix4x4_t *matrix_worldtofilter, const matrix4x4_t *matrix_worldtoattenuationxyz, const matrix4x4_t *matrix_worldtoattenuationz, rtexture_t *basetexture, rtexture_t *bumptexture, rtexture_t *lightcubemap);
-void R_Shadow_SpecularLighting(int numverts, int numtriangles, const int *elements, const float *vertices, const float *svectors, const float *tvectors, const float *normals, const float *texcoords, const float *relativelightorigin, const float *relativeeyeorigin, float lightradius, const float *lightcolor, const matrix4x4_t *matrix_worldtofilter, const matrix4x4_t *matrix_worldtoattenuationxyz, const matrix4x4_t *matrix_worldtoattenuationz, rtexture_t *glosstexture, rtexture_t *bumptexture, rtexture_t *lightcubemap);
+void R_Shadow_DiffuseLighting(int numverts, int numtriangles, const int *elements, const float *vertices, const float *svectors, const float *tvectors, const float *normals, const float *texcoords, const float *relativelightorigin, float lightradius, const float *lightcolor, const matrix4x4_t *matrix_worldtolight, const matrix4x4_t *matrix_worldtoattenuationxyz, const matrix4x4_t *matrix_worldtoattenuationz, rtexture_t *basetexture, rtexture_t *bumptexture, rtexture_t *lightcubemap);
+void R_Shadow_SpecularLighting(int numverts, int numtriangles, const int *elements, const float *vertices, const float *svectors, const float *tvectors, const float *normals, const float *texcoords, const float *relativelightorigin, const float *relativeeyeorigin, float lightradius, const float *lightcolor, const matrix4x4_t *matrix_worldtolight, const matrix4x4_t *matrix_worldtoattenuationxyz, const matrix4x4_t *matrix_worldtoattenuationz, rtexture_t *glosstexture, rtexture_t *bumptexture, rtexture_t *lightcubemap);
 void R_Shadow_ClearStencil(void);
 
 void R_Shadow_RenderShadowMeshVolume(shadowmesh_t *mesh);
@@ -30,14 +30,21 @@ void R_Shadow_Stage_LightWithoutShadows(void);
 void R_Shadow_Stage_End(void);
 int R_Shadow_ScissorForBBox(const float *mins, const float *maxs);
 
+// these never change, they are used to create attenuation matrices
+extern matrix4x4_t matrix_attenuationxyz;
+extern matrix4x4_t matrix_attenuationz;
+
+rtexture_t *R_Shadow_Cubemap(const char *basename);
+
 typedef struct worldlight_s
 {
        // saved properties
        vec3_t origin;
-       vec_t lightradius;
-       vec3_t light;
        vec3_t angles;
-       int castshadows;
+       vec3_t color;
+       vec_t radius;
+       vec_t corona;
+       int drawshadows;
        char *cubemapname;
 
        // shadow volumes are done entirely in model space, so there are no matrices for dealing with them...
@@ -45,8 +52,8 @@ typedef struct worldlight_s
        // note that the world to light matrices are inversely scaled (divided) by lightradius
 
        // matrix for transforming world coordinates to light filter coordinates
-       //matrix4x4_t matrix_worldtofilter;
-       // based on worldtofilter this transforms -1 to +1 to 0 to 1 for purposes
+       //matrix4x4_t matrix_worldtolight;
+       // based on worldtolight this transforms -1 to +1 to 0 to 1 for purposes
        // of attenuation texturing in full 3D (z result often ignored)
        //matrix4x4_t matrix_worldtoattenuationxyz;
        // this transforms only the Z to S, and T is always 0.5
@@ -61,6 +68,11 @@ typedef struct worldlight_s
        int style;
        int selected;
 
+       matrix4x4_t matrix_lighttoworld;
+       matrix4x4_t matrix_worldtolight;
+       matrix4x4_t matrix_worldtoattenuationxyz;
+       matrix4x4_t matrix_worldtoattenuationz;
+
        // premade shadow volumes and lit surfaces to render
        shadowmesh_t *meshchain_shadow;
        shadowmesh_t *meshchain_light;
@@ -72,6 +84,6 @@ extern worldlight_t *r_shadow_worldlightchain;
 void R_Shadow_UpdateWorldLightSelection(void);
 
 void R_Shadow_DrawStaticWorldLight_Shadow(worldlight_t *light, matrix4x4_t *matrix);
-void R_Shadow_DrawStaticWorldLight_Light(worldlight_t *light, matrix4x4_t *matrix, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltofilter, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz);
+void R_Shadow_DrawStaticWorldLight_Light(worldlight_t *light, matrix4x4_t *matrix, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltolight, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz);
 
 #endif
index fdc94cd..de23230 100644 (file)
--- a/server.h
+++ b/server.h
@@ -178,6 +178,7 @@ typedef struct client_s
 #define        MOVETYPE_BOUNCE                 10
 #define MOVETYPE_BOUNCEMISSILE 11              // bounce w/o gravity
 #define MOVETYPE_FOLLOW                        12              // track movement of aiment
+#define MOVETYPE_FAKEPUSH              13              // tenebrae's push that doesn't push
 
 // edict->solid values
 #define        SOLID_NOT                               0               // no interaction with other objects
index afc29be..9893dc3 100644 (file)
--- a/sv_main.c
+++ b/sv_main.c
@@ -805,7 +805,18 @@ void SV_PrepareEntitiesForSending(void)
                if (cs.viewmodelforclient)
                        cs.flags |= RENDER_VIEWMODEL; // show relative to the view
 
-               cs.specialvisibilityradius = 0;
+               f = GETEDICTFIELDVALUE(ent, eval_color)->vector[0]*256;
+               cs.light[0] = (unsigned short)bound(0, f, 65535);
+               f = GETEDICTFIELDVALUE(ent, eval_color)->vector[1]*256;
+               cs.light[1] = (unsigned short)bound(0, f, 65535);
+               f = GETEDICTFIELDVALUE(ent, eval_color)->vector[2]*256;
+               cs.light[2] = (unsigned short)bound(0, f, 65535);
+               f = GETEDICTFIELDVALUE(ent, eval_light_lev)->_float;
+               cs.light[3] = (unsigned short)bound(0, f, 65535);
+               cs.lightstyle = (qbyte)GETEDICTFIELDVALUE(ent, eval_style)->_float;
+               cs.lightpflags = (qbyte)GETEDICTFIELDVALUE(ent, eval_pflags)->_float;
+
+               cs.specialvisibilityradius = cs.light[3];
                if (cs.glowsize)
                        cs.specialvisibilityradius = max(cs.specialvisibilityradius, cs.glowsize * 4);
                if (cs.flags & RENDER_GLOWTRAIL)
index 82b7488..62b1ff6 100644 (file)
--- a/sv_phys.c
+++ b/sv_phys.c
@@ -703,7 +703,8 @@ void SV_PushMove (edict_t *pusher, float movetime)
                if (check->v->movetype == MOVETYPE_PUSH
                 || check->v->movetype == MOVETYPE_NONE
                 || check->v->movetype == MOVETYPE_FOLLOW
-                || check->v->movetype == MOVETYPE_NOCLIP)
+                || check->v->movetype == MOVETYPE_NOCLIP
+                || check->v->movetype == MOVETYPE_FAKEPUSH)
                        continue;
 
                // if the entity is standing on the pusher, it will definitely be moved
@@ -1413,6 +1414,7 @@ void SV_Physics (void)
                switch ((int) ent->v->movetype)
                {
                case MOVETYPE_PUSH:
+               case MOVETYPE_FAKEPUSH:
                        SV_Physics_Pusher (ent);
                        break;
                case MOVETYPE_NONE:
diff --git a/todo b/todo
index fd77b16..2b2c5e0 100644 (file)
--- a/todo
+++ b/todo
 -n darkplaces: server is starting before the "port" cvar is set by commandline and scripts? (yummyluv)
 -n darkplaces: typing ip in join game menu should show 'trying' and 'no response' after a while, or 'no network' if networking is not initialized (yummyluv)
 -n dpmod: make grapple off-hand (joe hill)
+0 darkplaces: change cl_fakelocalping_min and _max to only lag by half each way, as currently it results in 2x ping
+0 darkplaces: make MAX_PACKETFRAGMENT a property of each net connection, so memory loopbacks could use huge limits (Sajt)
+d darkplaces: add extension for tenebrae dlight entities
+0 darkplaces: fix broken mouse button display in key binding menu, it shows ??? for mouse buttons (Mercury, Tomaz)
+0 darkplaces: fix broken key repeat on backspace key in console (Mercury)
+d darkplaces: add constant insertion capabilities to Image_CopyMux
+1 darkplaces: add palette conversion capabilities to Image_CopyMux
+0 darkplaces: add scaling capabilities to Image_CopyMux
+4 dpmod: figure out why intermission camera pitch changes after a moment (Tomaz)
+0 darkplaces: add -benchmark commandline option which plays a demo, appends the resulting min/max/avg fps to gamedir/benchmark.log with commandline so people know what settings were used, like +exec realtimelow.cfg, +exec realtimemed.cfg, etc (romi)
+0 darkplaces: keep track of min and max fps (based on single frame frametime) during timedemo and print these stats (romi)
+d darkplaces: add tenebrae light entity properties, like cubemap and style and such
 -n darkplaces: implement cubemap support on rtlights (romi, Vermeulen, Mitchell)
 d darkplaces: add r_shadow_realtime_world_lightmaps cvar to control lightmap brightness (Mitchell)
 -n darkplaces: add gl_lightmaps cvar to disable texturing except lightmaps for testing (Vic)