rewrote RecursiveHullCheck, no longer gets stuck on angle changes, and is generally...
authorlordhavoc <lordhavoc@d7cf8633-e32d-0410-b094-e92efae38249>
Tue, 4 Dec 2001 13:28:29 +0000 (13:28 +0000)
committerlordhavoc <lordhavoc@d7cf8633-e32d-0410-b094-e92efae38249>
Tue, 4 Dec 2001 13:28:29 +0000 (13:28 +0000)
added content value to RecursiveHullCheck and TraceLine, they can now treat any content change as an impact
TraceLine now can take NULL impact and normal if they are not desired
TraceLine now sets trace_endcontents to the impacted content value
rewrote nehahra/rogue/hipnotic/standard_quake variables to be gamemode (GAME_NORMAL, GAME_HIPNOTIC, GAME_ROGUE, GAME_NEHAHRA, etc)
unfinished code for directional static lighting on models (CL_ParseEntityLump)
game now uses current mode as title everywhere (window title, server title, etc), so it would say 'DarkPlaces-Hipnotic' for example
added Draw_AdditiveString variant of Draw_String, switchs to additive blending and back to alpha afterward
engineversion string is now generated in sys_shared
major rewrite of transpolyrender, now uses glDrawElements (with batching of same texture/mode) and array locking
transpolyparticle added to quickly add particles to transpoly list (30% or so savings)
split wallpolyrender into two pieces, first renders walls, second renders fog over them, decals are rendered between the two, so decals are now fogged
added field of vision distortion when underwater (in MYgluPerspective)
changed gl_lightmapalign to align to the specified byte boundary instead of pixel boundary, and removed NVIDIA mentions (it is not their problem, it is a matter of the texture unpack alignment, but I stuck with 4 byte alignment because it is likely faster for most people)
fixed animating textures
rearranged a little bmodel code (probably no effect)
got rid of r_solidworldnode and r_pvsworldnode cvars (only the fastest choices are available now)
screenshots are now corrected to match lighthalf if it is being done using hardware gamma
removed some old unused cruft from host.c
added RGB gamma correction code to image.c
added VectorRandom to mathlib.h
model skins are no longer mipmapped by default (r_mipskins 0, but this is saved in configs so most people might not notice) because quake skins were not designed for it, and it is a 25% texture memory use increase on model skins
removed old unused Mod_FloodFillSkin code
transparent textures no longer clip other geometry in the hidden surface removal (ouch this was a bug)
maps should be able to use engine fields without the mod knowing about them now (alpha, etc), engine fields are appended to the list of progs fields
particle and decal textures are now all stored in one 'particle font' texture, for a rather hefty speed gain (no texture switchs)
all particles are now alpha blended (additive wasn't necessary on them, but is still available), to kill off state changes
new splash effect from raindrops
added a few bithacking float optimizations here and there (most with alternates if you define SLOWMATH)
new explosion effect (on by default, but a major speed drain, turn off with r_particles_explosions 0)
particle textures are now all in one image (a 'particle font'), massive speed gains with mixed particle types
all particles are alpha blend now (additive still supported, just not used), for more speed gains
particles now use 24bit RGB colors, rather than palette colors (the quake palette has been included however, because many particles still use it)
a lot of old cruft has been removed from r_part
ui items can now be strings rather than pics (actually they can be both, but I have not found a real use for this, perhaps a second draw location needs to be added for the string, so a button could have a label centered on it)
unfinished X11 gamma ramp support (need to allocate colors before setting them, haven't figured this out yet)
changed pitch range in GLX to let you look straight up and down, like in wgl version
mostly redesigned animation interpolation management code (R_LerpUpdate is now CL_LerpUpdate and performed on all network entities, R_LerpAnimation has been tweaked to not crash on bmodels and is now automatically used on all visible entities in the renderer, lerping info has has been split out of entity_render_t into entity_persistent_t so that entity_render_t contains no persistent data)
renderer now only uses entity_render_t structures
renderer now uses only currentrenderentity, and rarely passes individual properties around
cleaned out some old global variables relating to rendering
moved most of glquake.h to render.h
envmap is now actually a vaguely useful command (renders cubic environment map images of the current scene, changed to write tga images rather than raw rgba, and take a basename to use, and name them like skyboxes expect, and place them in the env directory)
many things that should be private to a particular file have been marked static
models now contain a SERAddEntity function (to add themselves to the SER clipping list to verify visibility)
models now contain DrawEarly and DrawLate functions (to render before and after wallpoly/decals/skypoly/etc, respectively)
dlight management functions moved out of cl_main and into cl_light
rewrote RelinkStaticEntities (does the same, just cleaner)
renamed RelinkEntities to RelinkNetworkEntities, split out LerpPlayerVelocity, and made a RelinkEntities function which calls the various functions
rewrote or altered portions of RelinkNetworkEntities relating to origin
muzzleflash lights are now clipped to keep them out of walls
fixed up code relating to vid.conwidth/height and vid.width/height (which is now gone, converted to vid.conwidth/height) and renamed glx/gly/glwidth/glheight to vid.realx/y/width/height (updated each frame using GL_BeginRendering)
rewrote most (all?) code relating to r_refdef, it is now always recalculated as well
dynamic lights will only update a lightmap if they actually alter it (optimization)
models now have 3 bounding boxes, used depending on angles (normal, yaw rotation only, and full rotation)
bmodel bounding boxes are recalculated from vertices
server now uses model bounding box instead of entity bounding box for visibility testing (since entity bounding box is often smaller)
server no longer portal-visibility checks entities because it was FAR too slow (sv_vischeckentities is still available though)
gl_rsurf code now relies on there being a currentrenderentity (even if it is cl.worldent.render), R_SetupWorldEnt added to avoid duplicate code for this
engine no longer has a version number, only build number
makefile now uses buildnum (as was originally intended) to increment build number every time it is compiled, build numbers will be rising rapidly from now on
timedemos will now force up console instantly
rocket trails are more dense
renamed VectorMA (function) to VectorMASlow, renamed VectorMAQuick (#define) to VectorMA, don't know why I had changed it before, had already cleaned up the parameter issues where it is used
converted most of lighting in decal code to integer
added support for all sprite types (untested)

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

73 files changed:
buildnumber.c
chase.c
cl_demo.c
cl_effects.c
cl_light.c [new file with mode: 0644]
cl_light.h [new file with mode: 0644]
cl_main.c
cl_parse.c
cl_tent.c
client.h
common.c
common.h
console.c
draw.h
gl_draw.c
gl_models.c
gl_poly.c
gl_poly.h
gl_rmain.c
gl_rmisc.c
gl_rsurf.c
gl_screen.c
glquake.h
host.c
host_cmd.c
image.c
image.h
keys.c
makefile
mathlib.c
mathlib.h
menu.c
model_alias.c
model_brush.c
model_brush.h
model_shared.h
model_sprite.c
portals.c
pr_cmds.c
pr_edict.c
quakedef.h
r_clip.c
r_crosshairs.c
r_decals.c
r_decals.h
r_explosion.c
r_lerpanim.c
r_lerpanim.h
r_light.c
r_light.h
r_part.c
r_sprites.c
render.h
sbar.c
sv_main.c
sv_phys.c
sv_user.c
sys.h
sys_linux.c
sys_shared.c
sys_win.c
transform.c
transform.h
ui.c
ui.h
vid.h
vid_3dfxsvga.c
vid_glx.c
vid_wgl.c
view.c
view.h
world.c
world.h

index 93dd2d4..9bbf28a 100644 (file)
@@ -1,4 +1,4 @@
 
-#define BUILDNUMBER 105
+#define BUILDNUMBER 253
 
 int buildnumber = BUILDNUMBER;
diff --git a/chase.c b/chase.c
index 4633565..f4ee5b9 100644 (file)
--- a/chase.c
+++ b/chase.c
@@ -8,7 +8,7 @@ of the License, or (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
 See the GNU General Public License for more details.
 
@@ -38,16 +38,26 @@ void Chase_Reset (void)
 //     start position 12 units behind head
 }
 
-float TraceLine (vec3_t start, vec3_t end, vec3_t impact, vec3_t normal)
+int traceline_endcontents;
+
+float TraceLine (vec3_t start, vec3_t end, vec3_t impact, vec3_t normal, int contents)
 {
-       trace_t trace;
+       trace_t trace;
 
        memset (&trace, 0, sizeof(trace));
        VectorCopy (end, trace.endpos);
        trace.fraction = 1;
-       SV_RecursiveHullCheck (cl.worldmodel->hulls, 0, 0, 1, start, end, &trace);
-       VectorCopy (trace.endpos, impact);
-       VectorCopy (trace.plane.normal, normal);
+       trace.startcontents = contents;
+       VectorCopy(start, RecursiveHullCheckInfo.start);
+       VectorSubtract(end, start, RecursiveHullCheckInfo.dist);
+       RecursiveHullCheckInfo.hull = cl.worldmodel->hulls;
+       RecursiveHullCheckInfo.trace = &trace;
+       SV_RecursiveHullCheck (0, 0, 1, start, end);
+       if (impact)
+               VectorCopy (trace.endpos, impact);
+       if (normal)
+               VectorCopy (trace.plane.normal, normal);
+       traceline_endcontents = trace.endcontents;
        return trace.fraction;
 }
 
@@ -66,7 +76,7 @@ void Chase_Update (void)
        chase_dest[1] = r_refdef.vieworg[1] + forward[1] * dist;
        chase_dest[2] = r_refdef.vieworg[2] + forward[2] * dist + chase_up.value;
 
-       TraceLine (r_refdef.vieworg, chase_dest, stop, normal);
+       TraceLine (r_refdef.vieworg, chase_dest, stop, normal, 0);
        chase_dest[0] = stop[0] + forward[0] * 8 + normal[0] * 4;
        chase_dest[1] = stop[1] + forward[1] * 8 + normal[1] * 4;
        chase_dest[2] = stop[2] + forward[2] * 8 + normal[2] * 4;
index 34c875e..ee61e50 100644 (file)
--- a/cl_demo.c
+++ b/cl_demo.c
@@ -365,10 +365,15 @@ void CL_TimeDemo_f (void)
        }
 
        CL_PlayDemo_f ();
-       
+
 // cls.td_starttime will be grabbed at the second frame of the demo, so
 // all the loading time doesn't get counted
-       
+
+       // instantly hide console and deactivate it
+       key_dest = key_game;
+       scr_conlines = 0;
+       scr_con_current = 0;
+
        cls.timedemo = true;
        cls.td_startframe = host_framecount;
        cls.td_lastframe = -1;          // get a new message this frame
index 42341f0..5020aaa 100644 (file)
@@ -33,25 +33,25 @@ typedef struct effect_s
        int endframe;
        // these are for interpolation
        int frame;
-       double frame1start;
-       double frame2start;
+       double frame1time;
+       double frame2time;
 }
 effect_t;
 
-effect_t effect[MAX_EFFECTS];
+static effect_t effect[MAX_EFFECTS];
 
-cvar_t r_draweffects = {0, "r_draweffects", "1"};
+static cvar_t r_draweffects = {0, "r_draweffects", "1"};
 
-void r_effects_start(void)
+static void r_effects_start(void)
 {
        memset(effect, 0, sizeof(effect));
 }
 
-void r_effects_shutdown(void)
+static void r_effects_shutdown(void)
 {
 }
 
-void r_effects_newmap(void)
+static void r_effects_newmap(void)
 {
        memset(effect, 0, sizeof(effect));
 }
@@ -82,12 +82,14 @@ void CL_Effect(vec3_t org, int modelindex, int startframe, int framecount, float
                e->framerate = framerate;
 
                e->frame = 0;
-               e->frame1start = cl.time;
-               e->frame2start = cl.time;
+               e->frame1time = cl.time;
+               e->frame2time = cl.time;
                break;
        }
 }
 
+extern void CL_LerpAnimation(entity_t *e);
+
 void CL_DoEffects()
 {
        int i, intframe;
@@ -111,28 +113,30 @@ void CL_DoEffects()
                        if (intframe != e->frame)
                        {
                                e->frame = intframe;
-                               e->frame1start = e->frame2start;
-                               e->frame2start = cl.time;
+                               e->frame1time = e->frame2time;
+                               e->frame2time = cl.time;
                        }
 
-                       vis = CL_NewTempEntity();
-                       if (!vis)
-                               continue;
-                       VectorCopy(e->origin, vis->render.origin);
-                       vis->render.lerp_model = vis->render.model = cl.model_precache[e->modelindex];
-                       vis->render.frame1 = e->frame;
-                       vis->render.frame2 = e->frame + 1;
-                       if (vis->render.frame2 >= e->endframe)
-                               vis->render.frame2 = -1; // disappear
-                       vis->render.frame = vis->render.frame2;
-                       vis->render.framelerp = frame - vis->render.frame1;
-                       vis->render.frame1start = e->frame1start;
-                       vis->render.frame2start = e->frame2start;
-                       vis->render.lerp_starttime = -1;
-                       vis->render.colormap = -1; // no special coloring
-                       vis->render.scale = 1;
-                       vis->render.alpha = 1;
-                       vis->render.colormod[0] = vis->render.colormod[1] = vis->render.colormod[2] = 1;
+                       if ((vis = CL_NewTempEntity()))
+                       {
+                               // interpolation stuff
+                               vis->render.frame1 = intframe;
+                               vis->render.frame2 = intframe + 1;
+                               if (vis->render.frame2 >= e->endframe)
+                                       vis->render.frame2 = -1; // disappear
+                               vis->render.framelerp = frame - intframe;
+                               vis->render.frame1time = e->frame1time;
+                               vis->render.frame2time = e->frame2time;
+
+                               // normal stuff
+                               VectorCopy(e->origin, vis->render.origin);
+                               vis->render.model = cl.model_precache[e->modelindex];
+                               vis->render.frame = vis->render.frame2;
+                               vis->render.colormap = -1; // no special coloring
+                               vis->render.scale = 1;
+                               vis->render.alpha = 1;
+                               vis->render.colormod[0] = vis->render.colormod[1] = vis->render.colormod[2] = 1;
+                       }
                }
        }
 }
diff --git a/cl_light.c b/cl_light.c
new file mode 100644 (file)
index 0000000..e4b9d4b
--- /dev/null
@@ -0,0 +1,99 @@
+#include "quakedef.h"
+
+dlight_t cl_dlights[MAX_DLIGHTS];
+
+void cl_light_start(void)
+{
+}
+
+void cl_light_shutdown(void)
+{
+}
+
+void cl_light_newmap(void)
+{
+       memset (cl_dlights, 0, sizeof(cl_dlights));
+}
+
+void CL_Light_Init(void)
+{
+       R_RegisterModule("CL_Light", cl_light_start, cl_light_shutdown, cl_light_newmap);
+}
+
+/*
+===============
+CL_AllocDlight
+
+===============
+*/
+void CL_AllocDlight (entity_render_t *ent, vec3_t org, float radius, float red, float green, float blue, float decay, float lifetime)
+{
+       int             i;
+       dlight_t        *dl;
+
+// first look for an exact key match
+       if (ent)
+       {
+               dl = cl_dlights;
+               for (i = 0;i < MAX_DLIGHTS;i++, dl++)
+                       if (dl->ent == ent)
+                               goto dlightsetup;
+       }
+
+// then look for anything else
+       dl = cl_dlights;
+       for (i = 0;i < MAX_DLIGHTS;i++, dl++)
+               if (!dl->radius)
+                       goto dlightsetup;
+
+       // unable to find one
+       return;
+
+dlightsetup:
+       memset (dl, 0, sizeof(*dl));
+       dl->ent = ent;
+       VectorCopy(org, dl->origin);
+       dl->radius = radius;
+       dl->color[0] = red;
+       dl->color[1] = green;
+       dl->color[2] = blue;
+       dl->decay = decay;
+       dl->die = cl.time + lifetime;
+}
+
+
+/*
+===============
+CL_DecayLights
+
+===============
+*/
+void CL_DecayLights (void)
+{
+       int                     i;
+       dlight_t        *dl;
+       float           time;
+
+       time = cl.time - cl.oldtime;
+
+       c_dlights = 0;
+       dl = cl_dlights;
+       for (i=0 ; i<MAX_DLIGHTS ; i++, dl++)
+       {
+               if (!dl->radius)
+                       continue;
+               if (dl->die < cl.time)
+               {
+                       dl->radius = 0;
+                       continue;
+               }
+
+               c_dlights++; // count every dlight in use
+
+               dl->radius -= time*dl->decay;
+               if (dl->radius < 0)
+                       dl->radius = 0;
+       }
+}
+
+
diff --git a/cl_light.h b/cl_light.h
new file mode 100644 (file)
index 0000000..3843065
--- /dev/null
@@ -0,0 +1,21 @@
+
+// LordHavoc: 256 dynamic lights
+#define        MAX_DLIGHTS             256
+typedef struct
+{
+       vec3_t  origin;
+       float   radius;
+       float   die;                    // stop lighting after this time
+       float   decay;                  // drop this each second
+       entity_render_t *ent;   // the entity that spawned this light (can be NULL if it will never be replaced)
+       vec3_t  color;                  // LordHavoc: colored lighting
+} dlight_t;
+
+// LordHavoc: this affects the lighting scale of the whole game
+#define LIGHTOFFSET 4096.0f
+
+extern dlight_t                cl_dlights[MAX_DLIGHTS];
+
+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_DecayLights (void);
+
index a938d12..26b78cf 100644 (file)
--- a/cl_main.c
+++ b/cl_main.c
@@ -49,7 +49,6 @@ client_state_t        cl;
 entity_t               cl_entities[MAX_EDICTS];
 entity_t               cl_static_entities[MAX_STATIC_ENTITIES];
 lightstyle_t   cl_lightstyle[MAX_LIGHTSTYLES];
-dlight_t               cl_dlights[MAX_DLIGHTS];
 
 int                            cl_numvisedicts;
 entity_t               *cl_visedicts[MAX_VISEDICTS];
@@ -72,9 +71,8 @@ void CL_ClearState (void)
 
        SZ_Clear (&cls.message);
 
-// clear other arrays  
+// clear other arrays
        memset (cl_entities, 0, sizeof(cl_entities));
-       memset (cl_dlights, 0, sizeof(cl_dlights));
        memset (cl_lightstyle, 0, sizeof(cl_lightstyle));
        memset (cl_temp_entities, 0, sizeof(cl_temp_entities));
        memset (cl_beams, 0, sizeof(cl_beams));
@@ -87,6 +85,44 @@ void CL_ClearState (void)
        }
 }
 
+void CL_LerpUpdate(entity_t *e, int frame, int modelindex)
+{
+       entity_persistent_t *p;
+       entity_render_t *r;
+       p = &e->persistent;
+       r = &e->render;
+
+       if (p->modelindex != modelindex)
+       {
+               // reset all interpolation information
+               p->modelindex = modelindex;
+               p->frame1 = p->frame2 = frame;
+               p->frame1time = p->frame2time = cl.time;
+               p->framelerp = 1;
+       }
+       else if (p->frame2 != frame)
+       {
+               // transition to new frame
+               p->frame1 = p->frame2;
+               p->frame1time = p->frame2time;
+               p->frame2 = frame;
+               p->frame2time = cl.time;
+               p->framelerp = 0;
+       }
+       else
+       {
+               // update transition
+               p->framelerp = (cl.time - p->frame2time) * 10;
+               p->framelerp = bound(0, p->framelerp, 1);
+       }
+
+       r->frame1 = p->frame1;
+       r->frame2 = p->frame2;
+       r->framelerp = p->framelerp;
+       r->frame1time = p->frame1time;
+       r->frame2time = p->frame2time;
+}
+
 /*
 =====================
 CL_Disconnect
@@ -186,7 +222,7 @@ Con_DPrintf ("CL_SignonReply: %i\n", cls.signon);
                MSG_WriteByte (&cls.message, clc_stringcmd);
                MSG_WriteString (&cls.message, "prespawn");
                break;
-               
+
        case 2:
                MSG_WriteByte (&cls.message, clc_stringcmd);
                MSG_WriteString (&cls.message, va("name \"%s\"\n", cl_name.string));
@@ -285,83 +321,6 @@ void CL_PrintEntities_f (void)
 
 /*
 ===============
-CL_AllocDlight
-
-===============
-*/
-void CL_AllocDlight (entity_t *ent, vec3_t org, float radius, float red, float green, float blue, float decay, float lifetime)
-{
-       int             i;
-       dlight_t        *dl;
-
-// first look for an exact key match
-       if (ent)
-       {
-               dl = cl_dlights;
-               for (i = 0;i < MAX_DLIGHTS;i++, dl++)
-                       if (dl->ent == ent)
-                               goto dlightsetup;
-       }
-
-// then look for anything else
-       dl = cl_dlights;
-       for (i = 0;i < MAX_DLIGHTS;i++, dl++)
-               if (!dl->radius)
-                       goto dlightsetup;
-
-       // unable to find one
-       return;
-
-dlightsetup:
-       memset (dl, 0, sizeof(*dl));
-       dl->ent = ent;
-       VectorCopy(org, dl->origin);
-       dl->radius = radius;
-       dl->color[0] = red;
-       dl->color[1] = green;
-       dl->color[2] = blue;
-       dl->decay = decay;
-       dl->die = cl.time + lifetime;
-}
-
-
-/*
-===============
-CL_DecayLights
-
-===============
-*/
-void CL_DecayLights (void)
-{
-       int                     i;
-       dlight_t        *dl;
-       float           time;
-       
-       time = cl.time - cl.oldtime;
-
-       c_dlights = 0;
-       dl = cl_dlights;
-       for (i=0 ; i<MAX_DLIGHTS ; i++, dl++)
-       {
-               if (!dl->radius)
-                       continue;
-               if (dl->die < cl.time)
-               {
-                       dl->radius = 0;
-                       continue;
-               }
-
-               c_dlights++; // count every dlight in use
-
-               dl->radius -= time*dl->decay;
-               if (dl->radius < 0)
-                       dl->radius = 0;
-       }
-}
-
-
-/*
-===============
 CL_LerpPoint
 
 Determines the fraction between the last two messages that the objects
@@ -432,14 +391,9 @@ float CL_EntityLerpPoint (entity_t *ent)
 
 void CL_RelinkStaticEntities(void)
 {
-       entity_t *ent, *endent;
-       if (cl.num_statics > MAX_VISEDICTS)
-               Host_Error("CL_RelinkStaticEntities: cl.num_statics > MAX_VISEDICTS??\n");
-
-       ent = cl_static_entities;
-       endent = ent + cl.num_statics;
-       for (;ent < endent;ent++)
-               cl_visedicts[cl_numvisedicts++] = ent;
+       int i;
+       for (i = 0;i < cl.num_statics && cl_numvisedicts < MAX_VISEDICTS;i++)
+               cl_visedicts[cl_numvisedicts++] = &cl_static_entities[i];
 }
 
 /*
@@ -448,43 +402,18 @@ CL_RelinkEntities
 ===============
 */
 void R_RocketTrail2 (vec3_t start, vec3_t end, int color, entity_t *ent);
-void CL_RelinkEntities (void)
+void CL_RelinkNetworkEntities()
 {
        entity_t        *ent;
        int                     i, j, glowcolor, effects;
-       float           frac, f, d, bobjrotate/*, bobjoffset*/, dlightradius, glowsize;
-       vec3_t          oldorg, delta, dlightcolor;
-
-// determine partial update time       
-       frac = CL_LerpPoint ();
+       float           f, d, bobjrotate/*, bobjoffset*/, dlightradius, glowsize;
+       vec3_t          oldorg, neworg, delta, dlightcolor;
 
-       cl_numvisedicts = 0;
+       bobjrotate = ANGLEMOD(100*cl.time);
+//     bobjoffset = cos(180 * cl.time * M_PI / 180) * 4.0f + 4.0f;
 
        CL_RelinkStaticEntities();
 
-//
-// interpolate player info
-//
-       for (i = 0;i < 3;i++)
-               cl.velocity[i] = cl.mvelocity[1][i] + frac * (cl.mvelocity[0][i] - cl.mvelocity[1][i]);
-
-       if (cls.demoplayback)
-       {
-       // interpolate the angles
-               for (j = 0;j < 3;j++)
-               {
-                       d = cl.mviewangles[0][j] - cl.mviewangles[1][j];
-                       if (d > 180)
-                               d -= 360;
-                       else if (d < -180)
-                               d += 360;
-                       cl.viewangles[j] = cl.mviewangles[1][j] + frac*d;
-               }
-       }
-       
-       bobjrotate = ANGLEMOD(100*cl.time);
-//     bobjoffset = cos(180 * cl.time * M_PI / 180) * 4.0f + 4.0f;
-       
 // start on the entity after the world
        for (i = 1, ent = cl_entities + 1;i < MAX_EDICTS /*cl.num_entities*/;i++, ent++)
        {
@@ -492,33 +421,27 @@ void CL_RelinkEntities (void)
                if (!ent->state_current.active)
                        continue;
 
-               VectorCopy (ent->render.origin, oldorg);
+               VectorCopy(ent->persistent.trail_origin, oldorg);
 
                if (!ent->state_previous.active)
                {
                        // only one state available
-                       VectorCopy (ent->state_current.origin, ent->render.origin);
+                       VectorCopy (ent->state_current.origin, neworg);
                        VectorCopy (ent->state_current.angles, ent->render.angles);
-//                     Con_Printf(" %i", i);
                }
                else
                {
                        // if the delta is large, assume a teleport and don't lerp
-                       f = CL_EntityLerpPoint(ent);
-                       if (f < 1)
-                       {
-                               for (j = 0;j < 3;j++)
-                               {
-                                       delta[j] = ent->state_current.origin[j] - ent->state_previous.origin[j];
-                                       // LordHavoc: increased lerp tolerance from 100 to 200
-                                       if (delta[j] > 200 || delta[j] < -200)
-                                               f = 1;
-                               }
-                       }
+                       VectorSubtract(ent->state_current.origin, ent->state_previous.origin, delta);
+                       // LordHavoc: increased tolerance from 100 to 200
+                       if (DotProduct(delta, delta) > 200*200)
+                               f = 1;
+                       else
+                               f = CL_EntityLerpPoint(ent);
                        if (f >= 1)
                        {
                                // no interpolation
-                               VectorCopy (ent->state_current.origin, ent->render.origin);
+                               VectorCopy (ent->state_current.origin, neworg);
                                VectorCopy (ent->state_current.angles, ent->render.angles);
                        }
                        else
@@ -526,7 +449,7 @@ void CL_RelinkEntities (void)
                                // interpolate the origin and angles
                                for (j = 0;j < 3;j++)
                                {
-                                       ent->render.origin[j] = ent->state_previous.origin[j] + f*delta[j];
+                                       neworg[j] = ent->state_previous.origin[j] + f*delta[j];
 
                                        d = ent->state_current.angles[j] - ent->state_previous.angles[j];
                                        if (d > 180)
@@ -538,6 +461,12 @@ void CL_RelinkEntities (void)
                        }
                }
 
+               VectorCopy (neworg, ent->persistent.trail_origin);
+               // persistent.modelindex will be updated by CL_LerpUpdate
+               if (ent->state_current.modelindex != ent->persistent.modelindex)
+                       VectorCopy(neworg, oldorg);
+
+               VectorCopy (neworg, ent->render.origin);
                ent->render.flags = ent->state_current.flags;
                ent->render.effects = effects = ent->state_current.effects;
                ent->render.model = cl.model_precache[ent->state_current.modelindex];
@@ -555,6 +484,10 @@ void CL_RelinkEntities (void)
                ent->render.colormod[1] = (float) ((ent->state_current.colormod >> 2) & 7) * (1.0f / 7.0f);
                ent->render.colormod[2] = (float) (ent->state_current.colormod & 3) * (1.0f / 3.0f);
 
+               // update interpolation info
+               CL_LerpUpdate(ent, ent->state_current.frame, ent->state_current.modelindex);
+
+               // handle effects now...
                dlightradius = 0;
                dlightcolor[0] = 0;
                dlightcolor[1] = 0;
@@ -567,13 +500,14 @@ void CL_RelinkEntities (void)
                                R_EntityParticles (ent);
                        if (effects & EF_MUZZLEFLASH)
                        {
-                               vec3_t v;
+                               vec3_t v, v2;
 
                                AngleVectors (ent->render.angles, v, NULL, NULL);
 
-                               v[0] = v[0] * 18 + ent->render.origin[0];
-                               v[1] = v[1] * 18 + ent->render.origin[1];
-                               v[2] = v[2] * 18 + ent->render.origin[2] + 16;
+                               v2[0] = v[0] * 18 + neworg[0];
+                               v2[1] = v[1] * 18 + neworg[1];
+                               v2[2] = v[2] * 18 + neworg[2] + 16;
+                               TraceLine(neworg, v2, v, NULL, 0);
 
                                CL_AllocDlight (NULL, v, 100, 1, 1, 1, 0, 0.1);
                        }
@@ -602,14 +536,27 @@ void CL_RelinkEntities (void)
                                dlightcolor[1] +=  20.0f;
                                dlightcolor[2] += 200.0f;
                        }
-                       else if (effects & EF_FLAME)
+                       if (effects & EF_FLAME)
                        {
                                if (ent->render.model)
                                {
                                        vec3_t mins, maxs;
                                        int temp;
-                                       VectorAdd(ent->render.origin, ent->render.model->mins, mins);
-                                       VectorAdd(ent->render.origin, ent->render.model->maxs, maxs);
+                                       if (ent->render.angles[0] || ent->render.angles[2])
+                                       {
+                                               VectorAdd(neworg, ent->render.model->rotatedmins, mins);
+                                               VectorAdd(neworg, ent->render.model->rotatedmaxs, maxs);
+                                       }
+                                       else if (ent->render.angles[1])
+                                       {
+                                               VectorAdd(neworg, ent->render.model->yawmins, mins);
+                                               VectorAdd(neworg, ent->render.model->yawmaxs, maxs);
+                                       }
+                                       else
+                                       {
+                                               VectorAdd(neworg, ent->render.model->normalmins, mins);
+                                               VectorAdd(neworg, ent->render.model->normalmaxs, maxs);
+                                       }
                                        // how many flames to make
                                        temp = (int) (cl.time * 300) - (int) (cl.oldtime * 300);
                                        R_FlameCube(mins, maxs, temp);
@@ -633,13 +580,13 @@ void CL_RelinkEntities (void)
                        if (ent->state_previous.active)
                        {
                                if (ent->render.model->flags & EF_GIB)
-                                       R_RocketTrail (oldorg, ent->render.origin, 2, ent);
+                                       R_RocketTrail (oldorg, neworg, 2, ent);
                                else if (ent->render.model->flags & EF_ZOMGIB)
-                                       R_RocketTrail (oldorg, ent->render.origin, 4, ent);
+                                       R_RocketTrail (oldorg, neworg, 4, ent);
                                else if (ent->render.model->flags & EF_TRACER)
-                                       R_RocketTrail (oldorg, ent->render.origin, 3, ent);
+                                       R_RocketTrail (oldorg, neworg, 3, ent);
                                else if (ent->render.model->flags & EF_TRACER2)
-                                       R_RocketTrail (oldorg, ent->render.origin, 5, ent);
+                                       R_RocketTrail (oldorg, neworg, 5, ent);
                                else if (ent->render.model->flags & EF_ROCKET)
                                {
                                        R_RocketTrail (oldorg, ent->render.origin, 0, ent);
@@ -650,12 +597,12 @@ void CL_RelinkEntities (void)
                                else if (ent->render.model->flags & EF_GRENADE)
                                {
                                        if (ent->render.alpha == -1) // LordHavoc: Nehahra dem compatibility
-                                               R_RocketTrail (oldorg, ent->render.origin, 7, ent);
+                                               R_RocketTrail (oldorg, neworg, 7, ent);
                                        else
-                                               R_RocketTrail (oldorg, ent->render.origin, 1, ent);
+                                               R_RocketTrail (oldorg, neworg, 1, ent);
                                }
                                else if (ent->render.model->flags & EF_TRACER3)
-                                       R_RocketTrail (oldorg, ent->render.origin, 6, ent);
+                                       R_RocketTrail (oldorg, neworg, 6, ent);
                        }
                }
                // LordHavoc: customizable glow
@@ -668,17 +615,18 @@ void CL_RelinkEntities (void)
                }
                // LordHavoc: customizable trail
                if (ent->render.flags & RENDER_GLOWTRAIL)
-                       R_RocketTrail2 (oldorg, ent->render.origin, glowcolor, ent);
+                       R_RocketTrail2 (oldorg, neworg, glowcolor, ent);
 
                if (dlightcolor[0] || dlightcolor[1] || dlightcolor[2])
                {
                        vec3_t vec;
                        dlightradius = VectorLength(dlightcolor);
                        d = 1.0f / dlightradius;
-                       VectorCopy(ent->render.origin, vec);
+                       VectorCopy(neworg, vec);
+                       // hack to make glowing player light shine on their gun
                        if (i == cl.viewentity && !chase_active.value)
                                vec[2] += 30;
-                       CL_AllocDlight (ent, vec, dlightradius, dlightcolor[0] * d, dlightcolor[1] * d, dlightcolor[2] * d, 0, 0);
+                       CL_AllocDlight (&ent->render, vec, dlightradius, dlightcolor[0] * d, dlightcolor[1] * d, dlightcolor[2] * d, 0, 0);
                }
 
                if (chase_active.value)
@@ -699,7 +647,40 @@ void CL_RelinkEntities (void)
                if (cl_numvisedicts < MAX_VISEDICTS)
                        cl_visedicts[cl_numvisedicts++] = ent;
        }
-//     Con_Printf("\n");
+}
+
+void CL_LerpPlayerVelocity (void)
+{
+       int i;
+       float frac, d;
+
+       // fraction from previous network update to current
+       frac = CL_LerpPoint ();
+
+       for (i = 0;i < 3;i++)
+               cl.velocity[i] = cl.mvelocity[1][i] + frac * (cl.mvelocity[0][i] - cl.mvelocity[1][i]);
+
+       if (cls.demoplayback)
+       {
+               // interpolate the angles
+               for (i = 0;i < 3;i++)
+               {
+                       d = cl.mviewangles[0][i] - cl.mviewangles[1][i];
+                       if (d > 180)
+                               d -= 360;
+                       else if (d < -180)
+                               d += 360;
+                       cl.viewangles[i] = cl.mviewangles[1][i] + frac*d;
+               }
+       }
+}
+
+void CL_RelinkEntities (void)
+{
+       cl_numvisedicts = 0;
+
+       CL_LerpPlayerVelocity();
+       CL_RelinkNetworkEntities();
 }
 
 
index f2c704f..ec3d3d5 100644 (file)
@@ -35,7 +35,7 @@ char *svc_strings[128] =
        "svc_stufftext",                // [string] stuffed into client's console buffer
                                                // the string should be \n terminated
        "svc_setangle",         // [vec3] set the view angle to this absolute value
-       
+
        "svc_serverinfo",               // [long] version
                                                // [string] signon string
                                                // [string]..[0]model cache [string]...[0]sounds cache
@@ -94,7 +94,7 @@ void CL_Parse_Init(void)
 {
        // LordHavoc: added demo_nehahra cvar
        Cvar_RegisterVariable (&demo_nehahra);
-       if (nehahra)
+       if (gamemode == GAME_NEHAHRA)
                Cvar_SetValue("demo_nehahra", 1);
 }
 
@@ -174,7 +174,7 @@ void CL_ParseStartSoundPacket(int largesoundindex)
        
        for (i=0 ; i<3 ; i++)
                pos[i] = MSG_ReadCoord ();
+
     S_StartSound (ent, channel, cl.sound_precache[sound_num], pos, volume/255.0, attenuation);
 }       
 
@@ -239,31 +239,90 @@ void CL_KeepaliveMessage (void)
        SZ_Clear (&cls.message);
 }
 
+//FIXME finish this code!
+#define MAX_STATICLIGHTS 2048
+// tyrlite types
+#define LIGHTFADE_LMINUSX 0 // light, arghlite, others?
+#define LIGHTFADE_LDIVX 1
+#define LIGHTFADE_LDIVX2 2 // hlight
+#define LIGHTFADE_L 3
+#define LIGHTFADE_DEFAULT 999999 // light util not yet identified, switched later
+
+typedef struct
+{
+       int fadetype; // one of the LIGHTFADE_ values
+       int style;
+       vec3_t origin;
+       vec_t radius; // the point at which lighting stops
+       vec3_t direction;
+       vec_t cone; // if non-zero, it is a spot light
+       vec3_t color;
+       vec_t distancescale; // attenuation
+       vec_t lightsubtract; // biasing lighting toward black (hlight feature)
+}
+staticlight_t;
+
+staticlight_t staticlight[MAX_STATICLIGHTS];
+int staticlights;
+
+int r_sunlightenabled;
+vec3_t r_sunlightdirection, r_sunlightcolor;
+vec3_t r_light_ambientcolor;
+
 void CL_ParseEntityLump(char *entdata)
 {
        char *data;
        char key[128], value[4096];
        char wadname[128];
-       int i, j, k;
+       char targetnamebuffer[65536];
+       char *targetname[8192], *target[MAX_STATICLIGHTS], light_target[256];
+       vec3_t targetnameorigin[8192], targetnametemporigin, v;
+       int targets, targetnames, targetnamebufferpos, targetnameorigintofillin;
+       int i, j, k, n;
+       float f1, f2, f3, f4;
+       float ambientlight, ambientcolor[3], sunlight, sunlightdirection[3], sunlightcolor[3];
+       int light_fadetype, light_style, hlight, tyrlite, light_enable;
+       float light_origin[3], light_light, light_distancescale, light_lightcolor[3], light_color[3], light_direction[3], light_cone, light_lightradius;
        FOG_clear(); // LordHavoc: no fog until set
        R_SetSkyBox(""); // LordHavoc: no environment mapped sky until set
        r_farclip.value = 6144; // LordHavoc: default farclip distance
+       r_sunlightenabled = false;
+       staticlights = 0;
        data = entdata;
        if (!data)
                return;
        data = COM_Parse(data);
        if (!data)
-               return; // valid exit
+               return; // error
        if (com_token[0] != '{')
                return; // error
+       hlight = false;
+       tyrlite = false;
+       ambientlight = 0;
+       ambientcolor[0] = ambientcolor[1] = ambientcolor[2] = 1;
+       sunlight = 0;
+       sunlightcolor[0] = sunlightcolor[1] = sunlightcolor[2] = 1;
+       sunlightdirection[0] = 0;
+       sunlightdirection[1] = 0;
+       sunlightdirection[2] = -1;
+       targets = 0;
+       targetnames = 0;
+       targetnamebufferpos = 0;
+       targetnameorigintofillin = -1;
+       targetnametemporigin[0] = 0;
+       targetnametemporigin[1] = 0;
+       targetnametemporigin[2] = 0;
        while (1)
        {
                data = COM_Parse(data);
                if (!data)
                        return; // error
                if (com_token[0] == '}')
-                       return; // since we're just parsing the first ent (worldspawn), exit
-               strcpy(key, com_token);
+                       break; // end of worldspawn
+               if (com_token[0] == '_')
+                       strcpy(key, com_token + 1);
+               else
+                       strcpy(key, com_token);
                while (key[strlen(key)-1] == ' ') // remove trailing spaces
                        key[strlen(key)-1] = 0;
                data = COM_Parse(data);
@@ -283,10 +342,7 @@ void CL_ParseEntityLump(char *entdata)
                                r_farclip.value = 64;
                }
                else if (!strcmp("fog", key))
-               {
                        scanf(value, "%f %f %f %f", &fog_density, &fog_red, &fog_green, &fog_blue);
-                       j = 0;
-               }
                else if (!strcmp("fog_density", key))
                        fog_density = atof(value);
                else if (!strcmp("fog_red", key))
@@ -325,6 +381,242 @@ void CL_ParseEntityLump(char *entdata)
                                }
                        }
                }
+               else if (!strcmp("light", key))
+                       ambientlight = atof(value);
+               else if (!strcmp("sunlight", key))
+               {
+                       sunlight = atof(value);
+                       tyrlite = true;
+               }
+               else if (!strcmp("sun_color", key))
+               {
+                       if (scanf(value, "%f %f %f", &v[0], &v[1], &v[2]) == 3)
+                               VectorCopy(v, sunlightcolor);
+                       tyrlite = true;
+               }
+               else if (!strcmp("sun_mangle", key))
+               {
+                       if (scanf(value, "%f %f %f", &v[0], &v[1], &v[2]) == 3)
+                               AngleVectors(v, sunlightdirection, NULL, NULL);
+                       tyrlite = true;
+               }
+               else if (!strcmp("origin", key))
+               {
+                       if (scanf(value, "%f %f %f", &v[0], &v[1], &v[2]) == 3)
+                       {
+                               VectorCopy(v, targetnametemporigin);
+                               VectorCopy(v, light_origin);
+                       }
+               }
+               else if (!strcmp("targetname", key))
+               {
+                       if ((targetnames < 8192) && (strlen(value) + 1 + targetnamebufferpos <= 65536))
+                       {
+                               targetname[targetnames] = targetnamebuffer + targetnamebufferpos;
+                               strcpy(targetnamebuffer + targetnamebufferpos, value);
+                               targetnamebufferpos += strlen(value) + 1;
+                               targetnameorigintofillin = targetnames++;
+                       }
+               }
+       }
+       if (targetnameorigintofillin >= 0)
+               VectorCopy(targetnametemporigin, targetnameorigin[targetnameorigintofillin]);
+
+       if (sunlight)
+       {
+               r_sunlightenabled = true;
+               VectorScale(sunlightcolor, sunlight, r_sunlightcolor);
+               VectorCopy(sunlightdirection, r_sunlightdirection);
+       }
+       VectorScale(ambientcolor, ambientlight, r_light_ambientcolor);
+
+       while(1)
+       {
+               data = COM_Parse(data);
+               if (!data)
+                       break; // done
+               if (com_token[0] != '{')
+                       break; // error
+               light_light = 0;
+               light_lightcolor[0] = light_lightcolor[1] = light_lightcolor[2] = 1.0f;
+               light_color[0] = light_color[1] = light_color[2] = 1.0f;
+               light_direction[0] = light_direction[1] = light_direction[2] = 0.0f;
+               light_cone = -cos(20*M_PI/180);
+               light_distancescale = 1.0f;
+               light_fadetype = LIGHTFADE_DEFAULT; // replaced later when light util is identified
+               light_style = 0;
+               light_lightradius = 0;
+               light_enable = false;
+               targetnameorigintofillin = -1;
+               targetnametemporigin[0] = 0;
+               targetnametemporigin[1] = 0;
+               targetnametemporigin[2] = 0;
+               while (1)
+               {
+                       data = COM_Parse(data);
+                       if (!data)
+                               return; // error
+                       if (com_token[0] == '}')
+                               break;
+                       if (com_token[0] == '_')
+                               strcpy(key, com_token + 1);
+                       else
+                               strcpy(key, com_token);
+                       while (key[strlen(key)-1] == ' ') // remove trailing spaces
+                               key[strlen(key)-1] = 0;
+                       data = COM_Parse(data);
+                       if (!data)
+                               return; // error
+                       strcpy(value, com_token);
+                       if (!strcmp("light", key))
+                       {
+                               n = scanf(value, "%f %f %f %f", &f1, &f2, &f3, &f4);
+                               switch(n)
+                               {
+                               case 1:
+                                       // id light, arghlite, tyrlite, others
+                                       light_light = f1;
+                                       light_lightcolor[0] = light_lightcolor[1] = light_lightcolor[2] = 1.0f;
+                                       break;
+                               case 3:
+                                       // hlight specific (supports all 3 light formats, but this one is unique to it)
+                                       hlight = true;
+                                       light_light = max(f1, max(f2, f3));
+                                       light_lightcolor[0] = f1 / light_light;
+                                       light_lightcolor[1] = f2 / light_light;
+                                       light_lightcolor[2] = f3 / light_light;
+                                       break;
+                               case 4:
+                                       // halflife
+                                       hlight = true; // unless this is a halflife map, probably hlight
+                                       light_light = f4;
+                                       light_lightcolor[0] = f1 * (1.0f / 255.0f);
+                                       light_lightcolor[1] = f1 * (1.0f / 255.0f);
+                                       light_lightcolor[2] = f1 * (1.0f / 255.0f);
+                                       break;
+                               default:
+                                       // error
+                                       break;
+                               }
+                       }
+                       else if (!strcmp("color", key))
+                       {
+                               n = scanf(value, "%f %f %f", &f1, &f2, &f3);
+                               if (n == 3)
+                               {
+                                       light_color[0] = f1;
+                                       light_color[1] = f2;
+                                       light_color[2] = f3;
+                               }
+                               // n != 3 is an error
+                       }
+                       else if (!strcmp("wait", key))
+                               light_distancescale = atof(value);
+                       else if (!strcmp("delay", key))
+                       {
+                               light_fadetype = atoi(value);
+                               tyrlite = true;
+                       }
+                       else if (!strcmp("angle", key))
+                               light_cone = -cos(atof(value) * M_PI / 360);
+                       else if (!strcmp("mangle", key))
+                       {
+                               n = scanf(value, "%f %f %f", &v[0], &v[1], &v[2]);
+                               if (n == 3)
+                                       AngleVectors(v, light_direction, NULL, NULL);
+                               // n != 3 is an error
+                               tyrlite = true;
+                       }
+                       else if (!strcmp("style", key))
+                       {
+                               n = atoi(value);
+                               if (n >= 0 && n < MAX_LIGHTSTYLES)
+                                       light_style = n;
+                       }
+                       else if (!strcmp("lightradius", key))
+                       {
+                               hlight = true;
+                               light_lightradius = atof(value);
+                       }
+                       else if (!strcmp("classname", key))
+                               if (!strncmp(value, "light", 5))
+                                       light_enable = true;
+                       else if (!strcmp("origin", key))
+                       {
+                               if (scanf(value, "%f %f %f", &v[0], &v[1], &v[2]) == 3)
+                                       VectorCopy(v, targetnametemporigin);
+                       }
+                       else if (!strcmp("targetname", key))
+                       {
+                               if ((targetnames < 8192) && (strlen(value) + 1 + targetnamebufferpos <= 65536))
+                               {
+                                       targetname[targetnames] = targetnamebuffer + targetnamebufferpos;
+                                       strcpy(targetnamebuffer + targetnamebufferpos, value);
+                                       targetnamebufferpos += strlen(value) + 1;
+                                       targetnameorigintofillin = targetnames++;
+                               }
+                       }
+                       else if (!strcmp("target", key))
+                               if (strlen(value) < sizeof(light_target))
+                                       strcpy(light_target, value);
+               }
+               if (targetnameorigintofillin >= 0)
+                       VectorCopy(targetnametemporigin, targetnameorigin[targetnameorigintofillin]);
+               if (light_enable && staticlights < MAX_STATICLIGHTS && light_light != 0)
+               {
+                       VectorCopy(light_origin, staticlight[staticlights].origin);
+                       staticlight[staticlights].color[0] = light_light * light_lightcolor[0] * light_color[0];
+                       staticlight[staticlights].color[1] = light_light * light_lightcolor[1] * light_color[1];
+                       staticlight[staticlights].color[2] = light_light * light_lightcolor[2] * light_color[2];
+                       VectorCopy(light_direction, staticlight[staticlights].direction);
+                       staticlight[staticlights].cone = light_cone;
+                       staticlight[staticlights].distancescale = light_distancescale;
+                       staticlight[staticlights].fadetype = light_fadetype;
+                       staticlight[staticlights].style = light_style;
+                       if (light_target && (targets < 8192) && (strlen(value) + 1 + targetnamebufferpos <= 65536))
+                       {
+                               target[staticlights] = targetnamebuffer + targetnamebufferpos;
+                               strcpy(targetnamebuffer + targetnamebufferpos, value);
+                               targetnamebufferpos += strlen(value) + 1;
+                       }
+                       else
+                               target[staticlights] = NULL;
+                       staticlight[staticlights].lightsubtract = 0;
+                       if (light_lightradius)
+                       {
+                               staticlight[staticlights].fadetype = LIGHTFADE_LDIVX2;
+                               staticlight[staticlights].lightsubtract = max(staticlight[staticlights].color[0], max(staticlight[staticlights].color[1], staticlight[staticlights].color[2])) * 0.5f / (light_lightradius * light_distancescale * light_lightradius * light_distancescale * (1.0f / 65536.0f) + 1.0f);
+                       }
+                       staticlights++;
+               }
+       }
+       if (hlbsp)
+               n = LIGHTFADE_LDIVX2;
+       else if (tyrlite)
+               n = LIGHTFADE_LMINUSX;
+       else if (hlight)
+               n = LIGHTFADE_LDIVX2;
+       else
+               n = LIGHTFADE_LMINUSX;
+       for (i = 0;i < staticlights;i++)
+       {
+               if (staticlight[i].fadetype == LIGHTFADE_DEFAULT)
+                       staticlight[i].fadetype = n;
+               if (target[i])
+               {
+                       for (j = 0;j < targetnames;j++)
+                       {
+                               if (!strcmp(target[i], targetname[j]))
+                               {
+                                       VectorSubtract(targetnameorigin[j], staticlight[i].origin, v);
+                                       VectorNormalize(v);
+                                       VectorCopy(v, staticlight[i].direction);
+                                       break;
+                               }
+                       }
+               }
+               if (staticlight[i].direction[0] == 0 && staticlight[i].direction[1] == 0 && staticlight[i].direction[2] == 0)
+                       staticlight[i].cone = 0;
        }
 }
 
@@ -340,7 +632,7 @@ void CL_ParseServerInfo (void)
        int             nummodels, numsounds;
        char    model_precache[MAX_MODELS][MAX_QPATH];
        char    sound_precache[MAX_SOUNDS][MAX_QPATH];
-       
+
        Con_DPrintf ("Serverinfo packet received.\n");
 //
 // wipe the client_state_t struct
@@ -495,6 +787,11 @@ void CL_ValidateState(entity_state_t *s)
                Con_DPrintf("CL_ValidateState: no such frame %i in \"%s\"\n", s->frame, model->name);
                s->frame = 0;
        }
+       if (model && s->skin >= model->numskins)
+       {
+               Con_DPrintf("CL_ValidateState: no such skin %i in \"%s\"\n", s->skin, model->name);
+               s->skin = 0;
+       }
 }
 
 /*
@@ -812,10 +1109,10 @@ void CL_ParseClientdata (int bits)
 
        i = MSG_ReadByte ();
 
-       if (standard_quake)
-               cl.stats[STAT_ACTIVEWEAPON] = i;
-       else
+       if (gamemode == GAME_HIPNOTIC || gamemode == GAME_ROGUE)
                cl.stats[STAT_ACTIVEWEAPON] = (1<<i);
+       else
+               cl.stats[STAT_ACTIVEWEAPON] = i;
 }
 
 /*
@@ -826,7 +1123,7 @@ CL_ParseStatic
 void CL_ParseStatic (int large)
 {
        entity_t *ent;
-               
+
        if (cl.num_statics >= MAX_STATIC_ENTITIES)
                Host_Error ("Too many static entities");
        ent = &cl_static_entities[cl.num_statics++];
@@ -836,9 +1133,8 @@ void CL_ParseStatic (int large)
        ent->render.model = cl.model_precache[ent->state_baseline.modelindex];
        ent->render.frame = ent->render.frame1 = ent->render.frame2 = ent->state_baseline.frame;
        ent->render.framelerp = 0;
-       ent->render.lerp_starttime = -1;
        // make torchs play out of sync
-       ent->render.frame1start = ent->render.frame2start = -(rand() & 32767);
+       ent->render.frame1time = ent->render.frame2time = lhrandom(-10, -1);
        ent->render.colormap = -1; // no special coloring
        ent->render.skinnum = ent->state_baseline.skin;
        ent->render.effects = ent->state_baseline.effects;
@@ -1046,7 +1342,7 @@ void CL_ParseServerMessage (void)
                        
                case svc_serverinfo:
                        CL_ParseServerInfo ();
-                       vid.recalc_refdef = true;       // leave intermission full screen
+//                     vid.recalc_refdef = true;       // leave intermission full screen
                        break;
                        
                case svc_setangle:
@@ -1184,20 +1480,20 @@ void CL_ParseServerMessage (void)
                case svc_intermission:
                        cl.intermission = 1;
                        cl.completed_time = cl.time;
-                       vid.recalc_refdef = true;       // go to full screen
+//                     vid.recalc_refdef = true;       // go to full screen
                        break;
 
                case svc_finale:
                        cl.intermission = 2;
                        cl.completed_time = cl.time;
-                       vid.recalc_refdef = true;       // go to full screen
+//                     vid.recalc_refdef = true;       // go to full screen
                        SCR_CenterPrint (MSG_ReadString ());                    
                        break;
 
                case svc_cutscene:
                        cl.intermission = 3;
                        cl.completed_time = cl.time;
-                       vid.recalc_refdef = true;       // go to full screen
+//                     vid.recalc_refdef = true;       // go to full screen
                        SCR_CenterPrint (MSG_ReadString ());                    
                        break;
 
index 1c921fe..d441a61 100644 (file)
--- a/cl_tent.c
+++ b/cl_tent.c
@@ -524,7 +524,7 @@ void CL_UpdateTEnts (void)
                        ent->render.angles[2] = rand()%360;
 
                        if (r_glowinglightning.value > 0)
-                               CL_AllocDlight(ent, ent->render.origin, lhrandom(100, 120), r_glowinglightning.value * 0.25f, r_glowinglightning.value * 0.25f, r_glowinglightning.value * 0.25f, 0, 0);
+                               CL_AllocDlight(&ent->render, ent->render.origin, lhrandom(100, 120), r_glowinglightning.value * 0.25f, r_glowinglightning.value * 0.25f, r_glowinglightning.value * 0.25f, 0, 0);
 
                        VectorMA(org, 30, dist, org);
                        d -= 30;
index a690fdc..4b469bb 100644 (file)
--- a/client.h
+++ b/client.h
@@ -263,17 +263,16 @@ extern client_state_t cl;
 extern entity_t                cl_entities[MAX_EDICTS];
 extern entity_t                cl_static_entities[MAX_STATIC_ENTITIES];
 extern lightstyle_t    cl_lightstyle[MAX_LIGHTSTYLES];
-extern dlight_t                cl_dlights[MAX_DLIGHTS];
 extern entity_t                cl_temp_entities[MAX_TEMP_ENTITIES];
 extern beam_t                  cl_beams[MAX_BEAMS];
 
 //=============================================================================
 
+#include "cl_light.h"
+
 //
 // cl_main
 //
-extern void CL_AllocDlight (entity_t *ent, vec3_t org, float radius, float red, float green, float blue, float decay, float lifetime);
-extern void CL_DecayLights (void);
 
 extern void CL_Init (void);
 
index 4258945..7a04287 100644 (file)
--- a/common.c
+++ b/common.c
@@ -58,7 +58,8 @@ char  **com_argv;
 #define CMDLINE_LENGTH 1024
 char   com_cmdline[CMDLINE_LENGTH];
 
-qboolean               standard_quake = true, rogue = false, hipnotic = false, nehahra = false;
+int gamemode;
+char *gamename;
 
 /*
 
@@ -1120,28 +1121,48 @@ void COM_InitArgv (int argc, char **argv)
        largv[com_argc] = argvdummy;
        com_argv = largv;
 
-#ifdef NEHAHRA
-       nehahra = true;
-       standard_quake = false;
+#if ZYMOTIC
+       gamemode = GAME_ZYMOTIC;
+#elif FIENDARENA
+       gamemode = GAME_FIENDARENA;
+#elif NEHAHRA
+       gamemode = GAME_NEHAHRA;
 #else
-       if (COM_CheckParm ("-rogue"))
-       {
-               rogue = true;
-               standard_quake = false;
-       }
-
-       if (COM_CheckParm ("-hipnotic"))
-       {
-               hipnotic = true;
-               standard_quake = false;
-       }
-
-       if (COM_CheckParm ("-nehahra"))
+       if (COM_CheckParm ("-zymotic"))
+               gamemode = GAME_ZYMOTIC;
+       else if (COM_CheckParm ("-fiendarena"))
+               gamemode = GAME_FIENDARENA;
+       else if (COM_CheckParm ("-nehahra"))
+               gamemode = GAME_NEHAHRA;
+       else if (COM_CheckParm ("-hipnotic"))
+               gamemode = GAME_HIPNOTIC;
+       else if (COM_CheckParm ("-rogue"))
+               gamemode = GAME_ROGUE;
+#endif
+       switch(gamemode)
        {
-               nehahra = true;
-               standard_quake = false;
+       case GAME_NORMAL:
+               gamename = "DarkPlaces";
+               break;
+       case GAME_HIPNOTIC:
+               gamename = "Darkplaces-Hipnotic";
+               break;
+       case GAME_ROGUE:
+               gamename = "Darkplaces-Rogue";
+               break;
+       case GAME_NEHAHRA:
+               gamename = "DarkPlaces-Nehahra";
+               break;
+       case GAME_FIENDARENA:
+               gamename = "FiendArena";
+               break;
+       case GAME_ZYMOTIC:
+               gamename = "Zymotic";
+               break;
+       default:
+               Sys_Error("COM_InitArgv: unknown gamemode %i\n", gamemode);
+               break;
        }
-#endif
 }
 
 
@@ -1378,7 +1399,7 @@ void COM_WriteFile (char *filename, void *data, int len)
 {
        int             handle;
        char    name[MAX_OSPATH];
-       
+
        sprintf (name, "%s/%s", com_gamedir, filename);
 
        // LordHavoc: added this
@@ -1390,8 +1411,8 @@ void COM_WriteFile (char *filename, void *data, int len)
                Sys_Printf ("COM_WriteFile: failed on %s\n", name);
                return;
        }
-       
-       Sys_Printf ("COM_WriteFile: %s\n", name);
+
+       Con_Printf ("COM_WriteFile: %s\n", name);
        Sys_FileWrite (handle, data, len);
        Sys_FileClose (handle);
 }
@@ -1846,21 +1867,32 @@ void COM_InitFilesystem (void)
                com_cachedir[0] = 0;
 #endif
 
-//
 // start up with GAMENAME by default (id1)
-//
        COM_AddGameDirectory (va("%s/"GAMENAME, basedir) );
 
-#ifdef NEHAHRA
-       COM_AddGameDirectory (va("%s/nehahra", basedir) );
-#else
-       if (COM_CheckParm ("-rogue"))
-               COM_AddGameDirectory (va("%s/rogue", basedir) );
-       if (COM_CheckParm ("-hipnotic"))
+       switch(gamemode)
+       {
+       case GAME_NORMAL:
+               break;
+       case GAME_HIPNOTIC:
                COM_AddGameDirectory (va("%s/hipnotic", basedir) );
-       if (COM_CheckParm ("-nehahra"))
+               break;
+       case GAME_ROGUE:
+               COM_AddGameDirectory (va("%s/rogue", basedir) );
+               break;
+       case GAME_NEHAHRA:
                COM_AddGameDirectory (va("%s/nehahra", basedir) );
-#endif
+               break;
+       case GAME_FIENDARENA:
+               COM_AddGameDirectory (va("%s/fiendarena", basedir) );
+               break;
+       case GAME_ZYMOTIC:
+               COM_AddGameDirectory (va("%s/zymotic", basedir) );
+               break;
+       default:
+               Sys_Error("COM_InitFilesystem: unknown gamemode %i\n", gamemode);
+               break;
+       }
 
 //
 // -game <gamedir>
@@ -1886,7 +1918,7 @@ void COM_InitFilesystem (void)
                {
                        if (!com_argv[i] || com_argv[i][0] == '+' || com_argv[i][0] == '-')
                                break;
-                       
+
                        search = Hunk_AllocName (sizeof(searchpath_t), "pack info");
                        if ( !strcmp(COM_FileExtension(com_argv[i]), "pak") )
                        {
@@ -1924,7 +1956,7 @@ int COM_FileExists(char *filename)
                }
                else
                {
-                       sprintf (netpath, "%s/%s",search->filename, filename);               
+                       sprintf (netpath, "%s/%s",search->filename, filename);
                        findtime = Sys_FileTime (netpath);
                        if (findtime != -1)
                                return true;
index 98467fd..c7a0be3 100644 (file)
--- a/common.h
+++ b/common.h
@@ -213,7 +213,15 @@ int COM_FileExists(char *filename);
 
 extern struct cvar_s   registered;
 
-extern qboolean                standard_quake, rogue, hipnotic, nehahra;
+#define GAME_NORMAL 0
+#define GAME_HIPNOTIC 1
+#define GAME_ROGUE 2
+#define GAME_NEHAHRA 3
+#define GAME_FIENDARENA 4
+#define GAME_ZYMOTIC 5
+
+extern int gamemode;
+extern char *gamename;
 
 // LordHavoc: useful...
 extern void COM_ToLowerString(char *in, char *out);
index 218ea63..2fe6eea 100644 (file)
--- a/console.c
+++ b/console.c
@@ -160,7 +160,7 @@ void Con_CheckResize (void)
        int             i, j, width, oldwidth, oldtotallines, numlines, numchars;
        char    tbuf[CON_TEXTSIZE];
 
-       width = (vid.width >> 3) - 2;
+       width = (vid.conwidth >> 3) - 2;
 
        if (width == con_linewidth)
                return;
diff --git a/draw.h b/draw.h
index 58efe1b..80ba2d1 100644 (file)
--- a/draw.h
+++ b/draw.h
@@ -32,5 +32,6 @@ void Draw_PicTranslate (int x, int y, qpic_t *pic, byte *translation);
 void Draw_ConsoleBackground (int lines);
 void Draw_Fill (int x, int y, int w, int h, int c);
 void Draw_String (int x, int y, char *str, int maxlen); // LordHavoc: added maxlen
+void Draw_AdditiveString (int x, int y, char *str, int maxlen);
 qpic_t *Draw_PicFromWad (char *name);
 qpic_t *Draw_CachePic (char *path);
index 8e0b3dc..bf3de8f 100644 (file)
--- a/gl_draw.c
+++ b/gl_draw.c
@@ -154,7 +154,7 @@ void gl_draw_newmap(void)
 {
 }
 
-char engineversion[40];
+extern char engineversion[40];
 int engineversionx, engineversiony;
 
 extern void R_Textures_Init();
@@ -163,17 +163,10 @@ void GL_Draw_Init (void)
        int i;
        Cvar_RegisterVariable (&scr_conalpha);
 
-#if defined(__linux__)
-       sprintf (engineversion, "DarkPlaces Linux   GL %.2f build %3i", (float) VERSION, buildnumber);
-#elif defined(WIN32)
-       sprintf (engineversion, "DarkPlaces Windows GL %.2f build %3i", (float) VERSION, buildnumber);
-#else
-       sprintf (engineversion, "DarkPlaces Unknown GL %.2f build %3i", (float) VERSION, buildnumber);
-#endif
        for (i = 0;i < 40 && engineversion[i];i++)
                engineversion[i] += 0x80; // shift to orange
-       engineversionx = vid.width - strlen(engineversion) * 8 - 8;
-       engineversiony = vid.height - 8;
+       engineversionx = vid.conwidth - strlen(engineversion) * 8 - 8;
+       engineversiony = vid.conheight - 8;
 
        R_Textures_Init();
        R_RegisterModule("GL_Draw", gl_draw_start, gl_draw_shutdown, gl_draw_newmap);
@@ -212,7 +205,7 @@ void Draw_Character (int x, int y, int num)
                return;
        glBindTexture(GL_TEXTURE_2D, R_GetTexture(char_texture));
        // LordHavoc: NEAREST mode on text if not scaling up
-       if (glwidth <= (int) vid.width)
+       if (vid.realwidth <= (int) vid.conwidth)
        {
                glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
                glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
@@ -239,7 +232,7 @@ void Draw_Character (int x, int y, int num)
        glEnd ();
 
        // LordHavoc: revert to LINEAR mode
-//     if (glwidth < (int) vid.width)
+//     if (vid.realwidth <= (int) vid.conwidth)
 //     {
 //             glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 //             glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
@@ -258,7 +251,7 @@ void Draw_String (int x, int y, char *str, int maxlen)
        float frow, fcol;
        if (!r_render.value)
                return;
-       if (y <= -8 || y >= (int) vid.height || x >= (int) vid.width || *str == 0) // completely offscreen or no text to print
+       if (y <= -8 || y >= (int) vid.conheight || x >= (int) vid.conwidth || *str == 0) // completely offscreen or no text to print
                return;
        if (maxlen < 1)
                maxlen = strlen(str);
@@ -267,7 +260,7 @@ void Draw_String (int x, int y, char *str, int maxlen)
        glBindTexture(GL_TEXTURE_2D, R_GetTexture(char_texture));
 
        // LordHavoc: NEAREST mode on text if not scaling up
-       if (glwidth <= (int) vid.width)
+       if (vid.realwidth <= (int) vid.conwidth)
        {
                glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
                glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
@@ -283,7 +276,7 @@ void Draw_String (int x, int y, char *str, int maxlen)
        else
                glColor3f(1.0f,1.0f,1.0f);
        glBegin (GL_QUADS);
-       while (maxlen-- && x < (int) vid.width) // stop rendering when out of characters or room
+       while (maxlen-- && x < (int) vid.conwidth) // stop rendering when out of characters or room
        {
                if ((num = *str++) != 32) // skip spaces
                {
@@ -299,13 +292,22 @@ void Draw_String (int x, int y, char *str, int maxlen)
        glEnd ();
 
        // LordHavoc: revert to LINEAR mode
-//     if (glwidth < (int) vid.width)
+//     if (vid.realwidth < (int) vid.conwidth)
 //     {
 //             glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 //             glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 //     }
 }
 
+void Draw_AdditiveString (int x, int y, char *str, int maxlen)
+{
+       if (!r_render.value)
+               return;
+       glBlendFunc(GL_SRC_ALPHA, GL_ONE);
+       Draw_String(x, y, str, maxlen);
+       glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+}
+
 void Draw_GenericPic (rtexture_t *tex, float red, float green, float blue, float alpha, int x, int y, int width, int height)
 {
        if (!r_render.value)
@@ -397,9 +399,9 @@ Draw_ConsoleBackground
 */
 void Draw_ConsoleBackground (int lines)
 {
-       Draw_GenericPic (conbacktex, 1,1,1,scr_conalpha.value*lines/vid.height, 0, lines - vid.height, vid.width, vid.height);
+       Draw_GenericPic (conbacktex, 1,1,1,scr_conalpha.value * lines / vid.conheight, 0, lines - vid.conheight, vid.conwidth, vid.conheight);
        // LordHavoc: draw version
-       Draw_String(engineversionx, lines - vid.height + engineversiony, engineversion, 9999);
+       Draw_String(engineversionx, lines - vid.conheight + engineversiony, engineversion, 9999);
 }
 
 /*
@@ -448,11 +450,11 @@ void GL_Set2D (void)
 {
        if (!r_render.value)
                return;
-       glViewport (glx, gly, glwidth, glheight);
+       glViewport (vid.realx, vid.realy, vid.realwidth, vid.realheight);
 
        glMatrixMode(GL_PROJECTION);
     glLoadIdentity ();
-       glOrtho  (0, vid.width, vid.height, 0, -99999, 99999);
+       glOrtho  (0, vid.conwidth, vid.conheight, 0, -99999, 99999);
 
        glMatrixMode(GL_MODELVIEW);
     glLoadIdentity ();
@@ -503,7 +505,7 @@ void SHOWLMP_decodeshow(void)
        float x, y;
        strcpy(lmplabel,MSG_ReadString());
        strcpy(picname, MSG_ReadString());
-       if (nehahra) // LordHavoc: nasty old legacy junk
+       if (gamemode == GAME_NEHAHRA) // LordHavoc: nasty old legacy junk
        {
                x = MSG_ReadByte();
                y = MSG_ReadByte();
index 035e5b0..1a18c95 100644 (file)
@@ -266,7 +266,7 @@ void R_AliasLerpVerts(int vertcount,
        }
 }
 
-void GL_DrawModelMesh(rtexture_t *skin, byte *colors, maliashdr_t *maliashdr)
+void GL_DrawModelMesh(rtexture_t *skin, byte *colors, maliashdr_t *m)
 {
        if (!r_render.value)
                return;
@@ -284,7 +284,7 @@ void GL_DrawModelMesh(rtexture_t *skin, byte *colors, maliashdr_t *maliashdr)
                glEnableClientState(GL_COLOR_ARRAY);
        }
 
-       glDrawElements(GL_TRIANGLES, maliashdr->numtris * 3, GL_UNSIGNED_SHORT, (void *)((int) maliashdr + maliashdr->tridata));
+       glDrawElements(GL_TRIANGLES, m->numtris * 3, GL_UNSIGNED_SHORT, (void *)((int) m + m->tridata));
 
        if (colors)
                glDisableClientState(GL_COLOR_ARRAY);
@@ -317,51 +317,65 @@ R_DrawAliasFrame
 
 =================
 */
-void R_LightModel(entity_t *ent, int numverts, vec3_t center, vec3_t basecolor);
-void R_DrawAliasFrame (model_t *model, maliashdr_t *maliashdr, float alpha, vec3_t color, entity_t *ent, int shadow, vec3_t org, vec3_t angles, vec_t scale, frameblend_t *blend, rtexture_t **skin, int colormap, int effects, int flags)
+void R_DrawAliasFrame (void)
 {
+       maliashdr_t *m = Mod_Extradata(currentrenderentity->model);
+//     int *skinanimrange = (int *) (currentrenderentity->model->skinanimrange + (int) modelheader) + skin * 2;
+//     int *skinanim = (int *) (currentrenderentity->model->skinanim + (int) modelheader);
+       int *skinanimrange = currentrenderentity->model->skinanimrange;
+       int skin;
+       rtexture_t **skinanim = currentrenderentity->model->skinanim;
+       rtexture_t **skinset;
+
+       skinanimrange += currentrenderentity->skinnum * 2;
+       skin = skinanimrange[0];
+       if (skinanimrange[1] > 1) // animated
+               skin += (int) (cl.time * 10) % skinanimrange[1];
+       skinset = skinanim + skin * 5;
+
        if (gl_transform.value)
        {
                if (r_render.value)
                {
                        glPushMatrix();
-                       GL_SetupModelTransform(org, angles, scale);
+                       GL_SetupModelTransform(currentrenderentity->origin, currentrenderentity->angles, currentrenderentity->scale);
                }
        }
        // always needed, for model lighting
-       softwaretransformforentity(ent);
+       softwaretransformforentity(currentrenderentity);
+
+       R_AliasLerpVerts(m->numverts,
+               currentrenderentity->frameblend[0].lerp, ((trivertx_t *)((int) m + m->posedata)) + currentrenderentity->frameblend[0].frame * m->numverts, m->scale, m->scale_origin,
+               currentrenderentity->frameblend[1].lerp, ((trivertx_t *)((int) m + m->posedata)) + currentrenderentity->frameblend[1].frame * m->numverts, m->scale, m->scale_origin,
+               currentrenderentity->frameblend[2].lerp, ((trivertx_t *)((int) m + m->posedata)) + currentrenderentity->frameblend[2].frame * m->numverts, m->scale, m->scale_origin,
+               currentrenderentity->frameblend[3].lerp, ((trivertx_t *)((int) m + m->posedata)) + currentrenderentity->frameblend[3].frame * m->numverts, m->scale, m->scale_origin);
 
-       R_AliasLerpVerts(maliashdr->numverts,
-               blend[0].lerp, ((trivertx_t *)((int) maliashdr + maliashdr->posedata)) + blend[0].frame * maliashdr->numverts, maliashdr->scale, maliashdr->scale_origin,
-               blend[1].lerp, ((trivertx_t *)((int) maliashdr + maliashdr->posedata)) + blend[1].frame * maliashdr->numverts, maliashdr->scale, maliashdr->scale_origin,
-               blend[2].lerp, ((trivertx_t *)((int) maliashdr + maliashdr->posedata)) + blend[2].frame * maliashdr->numverts, maliashdr->scale, maliashdr->scale_origin,
-               blend[3].lerp, ((trivertx_t *)((int) maliashdr + maliashdr->posedata)) + blend[3].frame * maliashdr->numverts, maliashdr->scale, maliashdr->scale_origin);
        if (!gl_transform.value)
-               R_AliasTransformVerts(maliashdr->numverts);
+               R_AliasTransformVerts(m->numverts);
 
        // prep the vertex array as early as possible
        if (r_render.value)
        {
                glVertexPointer(3, GL_FLOAT, sizeof(float[3]), aliasvert);
                glEnableClientState(GL_VERTEX_ARRAY);
-               glTexCoordPointer(2, GL_FLOAT, sizeof(float[2]), (void *)((int) maliashdr->texdata + (int) maliashdr));
+               glTexCoordPointer(2, GL_FLOAT, sizeof(float[2]), (void *)((int) m->texdata + (int) m));
                glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-               GL_LockArray(0, maliashdr->numverts);
+               GL_LockArray(0, m->numverts);
        }
 
-       R_LightModel(ent, maliashdr->numverts, org, color);
+       R_LightModel(m->numverts);
 
        if (!r_render.value)
                return;
        glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
-       glShadeModel(GL_SMOOTH);
-       if (effects & EF_ADDITIVE)
+//     glShadeModel(GL_SMOOTH);
+       if (currentrenderentity->effects & EF_ADDITIVE)
        {
                glBlendFunc(GL_SRC_ALPHA, GL_ONE); // additive rendering
                glEnable(GL_BLEND);
                glDepthMask(0);
        }
-       else if (alpha != 1.0 || (model->flags2 & MODF_TRANSPARENT))
+       else if (currentrenderentity->alpha != 1.0 || (currentrenderentity->model->flags2 & MODF_TRANSPARENT))
        {
                glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
                glEnable(GL_BLEND);
@@ -373,40 +387,41 @@ void R_DrawAliasFrame (model_t *model, maliashdr_t *maliashdr, float alpha, vec3
                glDepthMask(1);
        }
 
-       if (skin[0] || skin[1] || skin[2] || skin[3] || skin[4])
+       if (skinset[0] || skinset[1] || skinset[2] || skinset[3] || skinset[4])
        {
-               if (colormap >= 0 && (skin[0] || skin[1] || skin[2]))
+               if (currentrenderentity->colormap >= 0 && (skinset[0] || skinset[1] || skinset[2]))
                {
                        int c;
-                       if (skin[0])
-                               GL_DrawModelMesh(skin[0], aliasvertcolor, maliashdr);
-                       if (skin[1])
+                       if (skinset[0])
+                               GL_DrawModelMesh(skinset[0], aliasvertcolor, m);
+                       if (skinset[1])
                        {
-                               c = (colormap & 0xF) << 4;c += (c >= 128 && c < 224) ? 4 : 12; // 128-224 are backwards ranges
-                               R_TintModel(aliasvertcolor, aliasvertcolor2, maliashdr->numverts, (byte *) (&d_8to24table[c]));
-                               GL_DrawModelMesh(skin[1], aliasvertcolor2, maliashdr);
+                               c = (currentrenderentity->colormap & 0xF) << 4;c += (c >= 128 && c < 224) ? 4 : 12; // 128-224 are backwards ranges
+                               R_TintModel(aliasvertcolor, aliasvertcolor2, m->numverts, (byte *) (&d_8to24table[c]));
+                               GL_DrawModelMesh(skinset[1], aliasvertcolor2, m);
                        }
-                       if (skin[2])
+                       if (skinset[2])
                        {
-                               c = colormap & 0xF0      ;c += (c >= 128 && c < 224) ? 4 : 12; // 128-224 are backwards ranges
-                               R_TintModel(aliasvertcolor, aliasvertcolor2, maliashdr->numverts, (byte *) (&d_8to24table[c]));
-                               GL_DrawModelMesh(skin[2], aliasvertcolor2, maliashdr);
+                               c = currentrenderentity->colormap & 0xF0      ;c += (c >= 128 && c < 224) ? 4 : 12; // 128-224 are backwards ranges
+                               R_TintModel(aliasvertcolor, aliasvertcolor2, m->numverts, (byte *) (&d_8to24table[c]));
+                               GL_DrawModelMesh(skinset[2], aliasvertcolor2, m);
                        }
                }
                else
                {
-                       if (skin[4]) GL_DrawModelMesh(skin[4], aliasvertcolor, maliashdr);
+                       if (skinset[4])
+                               GL_DrawModelMesh(skinset[4], aliasvertcolor, m);
                        else
                        {
-                               if (skin[0]) GL_DrawModelMesh(skin[0], aliasvertcolor, maliashdr);
-                               if (skin[1]) GL_DrawModelMesh(skin[1], aliasvertcolor, maliashdr);
-                               if (skin[2]) GL_DrawModelMesh(skin[2], aliasvertcolor, maliashdr);
+                               if (skinset[0]) GL_DrawModelMesh(skinset[0], aliasvertcolor, m);
+                               if (skinset[1]) GL_DrawModelMesh(skinset[1], aliasvertcolor, m);
+                               if (skinset[2]) GL_DrawModelMesh(skinset[2], aliasvertcolor, m);
                        }
                }
-               if (skin[3]) GL_DrawModelMesh(skin[3], NULL, maliashdr);
+               if (skinset[3]) GL_DrawModelMesh(skinset[3], NULL, m);
        }
        else
-               GL_DrawModelMesh(0, NULL, maliashdr);
+               GL_DrawModelMesh(0, NULL, m);
 
        if (fogenabled)
        {
@@ -416,14 +431,15 @@ void R_DrawAliasFrame (model_t *model, maliashdr_t *maliashdr, float alpha, vec3
                glEnable (GL_BLEND);
                glDepthMask(0); // disable zbuffer updates
 
-               VectorSubtract(org, r_origin, diff);
+               VectorSubtract(currentrenderentity->origin, r_origin, diff);
                glColor4f(fogcolor[0], fogcolor[1], fogcolor[2], exp(fogdensity/DotProduct(diff,diff)));
 
-               glDrawElements(GL_TRIANGLES, maliashdr->numtris * 3, GL_UNSIGNED_SHORT, (void *)((int) maliashdr + maliashdr->tridata));
+               glDrawElements(GL_TRIANGLES, m->numtris * 3, GL_UNSIGNED_SHORT, (void *)((int) m + m->tridata));
 
                glEnable (GL_TEXTURE_2D);
                glColor3f (1,1,1);
        }
+
        GL_UnlockArray();
        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
        glDisableClientState(GL_VERTEX_ARRAY);
@@ -441,41 +457,74 @@ R_DrawQ2AliasFrame
 
 =================
 */
-void R_DrawQ2AliasFrame (model_t *model, md2mem_t *pheader, float alpha, vec3_t color, entity_t *ent, int shadow, vec3_t org, vec3_t angles, vec_t scale, frameblend_t *blend, rtexture_t *skin, int effects, int flags)
+void R_DrawQ2AliasFrame (void)
 {
        int *order, count;
        md2frame_t *frame1, *frame2, *frame3, *frame4;
+       vec3_t diff;
+       md2mem_t *m = Mod_Extradata(currentrenderentity->model);
+//     int *skinanimrange = (int *) (currentrenderentity->model->skinanimrange + (int) modelheader) + skin * 2;
+//     int *skinanim = (int *) (currentrenderentity->model->skinanim + (int) modelheader);
+       int *skinanimrange = currentrenderentity->model->skinanimrange;
+       int skin;
+       rtexture_t **skinanim = currentrenderentity->model->skinanim;
+       rtexture_t **skinset;
+
+       skinanimrange += currentrenderentity->skinnum * 2;
+       skin = skinanimrange[0];
+       if (skinanimrange[1] > 1) // animated
+               skin += (int) (cl.time * 10) % skinanimrange[1];
+       skinset = skinanim + skin * 5;
 
        if (r_render.value)
-               glBindTexture(GL_TEXTURE_2D, R_GetTexture(skin));
+               glBindTexture(GL_TEXTURE_2D, R_GetTexture(skinset[0]));
 
        if (gl_transform.value)
        {
                if (r_render.value)
                {
                        glPushMatrix();
-                       GL_SetupModelTransform(org, angles, scale);
+                       GL_SetupModelTransform(currentrenderentity->origin, currentrenderentity->angles, currentrenderentity->scale);
                }
        }
        // always needed, for model lighting
-       softwaretransformforentity(ent);
-
-       frame1 = (void *)((int) pheader + pheader->ofs_frames + (pheader->framesize * blend[0].frame));
-       frame2 = (void *)((int) pheader + pheader->ofs_frames + (pheader->framesize * blend[1].frame));
-       frame3 = (void *)((int) pheader + pheader->ofs_frames + (pheader->framesize * blend[2].frame));
-       frame4 = (void *)((int) pheader + pheader->ofs_frames + (pheader->framesize * blend[3].frame));
-       R_AliasLerpVerts(pheader->num_xyz,
-               blend[0].lerp, frame1->verts, frame1->scale, frame1->translate,
-               blend[1].lerp, frame2->verts, frame2->scale, frame2->translate,
-               blend[2].lerp, frame3->verts, frame3->scale, frame3->translate,
-               blend[3].lerp, frame4->verts, frame4->scale, frame4->translate);
+       softwaretransformforentity(currentrenderentity);
+
+       frame1 = (void *)((int) m + m->ofs_frames + (m->framesize * currentrenderentity->frameblend[0].frame));
+       frame2 = (void *)((int) m + m->ofs_frames + (m->framesize * currentrenderentity->frameblend[1].frame));
+       frame3 = (void *)((int) m + m->ofs_frames + (m->framesize * currentrenderentity->frameblend[2].frame));
+       frame4 = (void *)((int) m + m->ofs_frames + (m->framesize * currentrenderentity->frameblend[3].frame));
+       R_AliasLerpVerts(m->num_xyz,
+               currentrenderentity->frameblend[0].lerp, frame1->verts, frame1->scale, frame1->translate,
+               currentrenderentity->frameblend[1].lerp, frame2->verts, frame2->scale, frame2->translate,
+               currentrenderentity->frameblend[2].lerp, frame3->verts, frame3->scale, frame3->translate,
+               currentrenderentity->frameblend[3].lerp, frame4->verts, frame4->scale, frame4->translate);
        if (!gl_transform.value)
-               R_AliasTransformVerts(pheader->num_xyz);
+               R_AliasTransformVerts(m->num_xyz);
 
-       R_LightModel(ent, pheader->num_xyz, org, color);
+       R_LightModel(m->num_xyz);
 
        if (!r_render.value)
                return;
+
+       if (currentrenderentity->effects & EF_ADDITIVE)
+       {
+               glBlendFunc(GL_SRC_ALPHA, GL_ONE); // additive rendering
+               glEnable(GL_BLEND);
+               glDepthMask(0);
+       }
+       else if (currentrenderentity->alpha != 1.0 || (currentrenderentity->model->flags2 & MODF_TRANSPARENT))
+       {
+               glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+               glEnable(GL_BLEND);
+               glDepthMask(0);
+       }
+       else
+       {
+               glDisable(GL_BLEND);
+               glDepthMask(1);
+       }
+
        // LordHavoc: big mess...
        // using vertex arrays only slightly, although it is enough to prevent duplicates
        // (saving half the transforms)
@@ -484,7 +533,7 @@ void R_DrawQ2AliasFrame (model_t *model, md2mem_t *pheader, float alpha, vec3_t
        glEnableClientState(GL_VERTEX_ARRAY);
        glEnableClientState(GL_COLOR_ARRAY);
 
-       order = (int *)((int)pheader + pheader->ofs_glcmds);
+       order = (int *)((int)m + m->ofs_glcmds);
        while(1)
        {
                if (!(count = *order++))
@@ -514,11 +563,9 @@ void R_DrawQ2AliasFrame (model_t *model, md2mem_t *pheader, float alpha, vec3_t
                glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
                glEnable (GL_BLEND);
                glDepthMask(0); // disable zbuffer updates
-               {
-                       vec3_t diff;
-                       VectorSubtract(org, r_origin, diff);
-                       glColor4f(fogcolor[0], fogcolor[1], fogcolor[2], exp(fogdensity/DotProduct(diff,diff)));
-               }
+
+               VectorSubtract(currentrenderentity->origin, r_origin, diff);
+               glColor4f(fogcolor[0], fogcolor[1], fogcolor[2], exp(fogdensity/DotProduct(diff,diff)));
 
                // LordHavoc: big mess...
                // using vertex arrays only slightly, although it is enough to prevent duplicates
@@ -526,7 +573,7 @@ void R_DrawQ2AliasFrame (model_t *model, md2mem_t *pheader, float alpha, vec3_t
                glVertexPointer(3, GL_FLOAT, sizeof(float[3]), aliasvert);
                glEnableClientState(GL_VERTEX_ARRAY);
 
-               order = (int *)((int)pheader + pheader->ofs_glcmds);
+               order = (int *)((int)m + m->ofs_glcmds);
                while(1)
                {
                        if (!(count = *order++))
@@ -880,25 +927,26 @@ void GL_DrawZymoticModelMeshFog(vec3_t org, zymtype1header_t *m)
 R_DrawZymoticFrame
 =================
 */
-void R_DrawZymoticFrame (model_t *model, zymtype1header_t *m, float alpha, vec3_t color, entity_t *ent, int shadow, vec3_t org, vec3_t angles, vec_t scale, frameblend_t *blend, int skinblah, int effects, int flags)
+void R_DrawZymoticFrame (void)
 {
-       ZymoticLerpBones(m->numbones, (zymbonematrix *)(m->lump_poses.start + (int) m), blend, (zymbone_t *)(m->lump_bones.start + (int) m), org, angles, scale);
+       zymtype1header_t *m = Mod_Extradata(currentrenderentity->model);
+       ZymoticLerpBones(m->numbones, (zymbonematrix *)(m->lump_poses.start + (int) m), currentrenderentity->frameblend, (zymbone_t *)(m->lump_bones.start + (int) m), currentrenderentity->origin, currentrenderentity->angles, currentrenderentity->scale);
        ZymoticTransformVerts(m->numverts, (int *)(m->lump_vertbonecounts.start + (int) m), (zymvertex_t *)(m->lump_verts.start + (int) m));
        ZymoticCalcNormals(m->numverts, m->numshaders, (int *)(m->lump_render.start + (int) m));
 
-       R_LightModel(ent, m->numverts, org, color);
+       R_LightModel(m->numverts);
 
        if (!r_render.value)
                return;
        glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
-       glShadeModel(GL_SMOOTH);
-       if (effects & EF_ADDITIVE)
+//     glShadeModel(GL_SMOOTH);
+       if (currentrenderentity->effects & EF_ADDITIVE)
        {
                glBlendFunc(GL_SRC_ALPHA, GL_ONE); // additive rendering
                glEnable(GL_BLEND);
                glDepthMask(0);
        }
-       else if (alpha != 1.0)
+       else if (currentrenderentity->alpha != 1.0)
        {
                glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
                glEnable(GL_BLEND);
@@ -913,7 +961,7 @@ void R_DrawZymoticFrame (model_t *model, zymtype1header_t *m, float alpha, vec3_
        GL_DrawZymoticModelMesh(aliasvertcolor, m);
 
        if (fogenabled)
-               GL_DrawZymoticModelMeshFog(org, m);
+               GL_DrawZymoticModelMeshFog(currentrenderentity->origin, m);
 
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        glEnable (GL_BLEND);
@@ -926,51 +974,21 @@ R_DrawAliasModel
 
 =================
 */
-void R_DrawAliasModel (entity_t *ent, int cull, float alpha, model_t *clmodel, frameblend_t *blend, int skin, vec3_t org, vec3_t angles, vec_t scale, int effects, int flags, int colormap)
+void R_DrawAliasModel (void)
 {
-       int                     i;
-       vec3_t          mins, maxs, color;
-       void            *modelheader;
-       rtexture_t      **skinset;
-
-       if (alpha < (1.0 / 64.0))
+       if (currentrenderentity->alpha < (1.0 / 64.0))
                return; // basically completely transparent
 
-       VectorAdd (org, clmodel->mins, mins);
-       VectorAdd (org, clmodel->maxs, maxs);
-
-//     if (cull && R_CullBox (mins, maxs))
-//             return;
-
        c_models++;
 
-       if (skin < 0 || skin >= clmodel->numskins)
-       {
-               skin = 0;
-               Con_DPrintf("invalid skin number %d for model %s\n", skin, clmodel->name);
-       }
-
-       modelheader = Mod_Extradata (clmodel);
-
-       {
-//             int *skinanimrange = (int *) (clmodel->skinanimrange + (int) modelheader) + skin * 2;
-//             int *skinanim = (int *) (clmodel->skinanim + (int) modelheader);
-               int *skinanimrange = clmodel->skinanimrange + skin * 2;
-               rtexture_t **skinanim = clmodel->skinanim;
-               i = skinanimrange[0];
-               if (skinanimrange[1] > 1) // animated
-                       i += ((int) (cl.time * 10) % skinanimrange[1]);
-               skinset = skinanim + i*5;
-       }
-
        if (r_render.value)
                glEnable (GL_TEXTURE_2D);
 
-       c_alias_polys += clmodel->numtris;
-       if (clmodel->aliastype == ALIASTYPE_ZYM)
-               R_DrawZymoticFrame (clmodel, modelheader, alpha, color, ent, ent != &cl.viewent, org, angles, scale, blend, 0                   , effects, flags);
-       else if (clmodel->aliastype == ALIASTYPE_MD2)
-               R_DrawQ2AliasFrame (clmodel, modelheader, alpha, color, ent, ent != &cl.viewent, org, angles, scale, blend, skinset[0]          , effects, flags);
+       c_alias_polys += currentrenderentity->model->numtris;
+       if (currentrenderentity->model->aliastype == ALIASTYPE_ZYM)
+               R_DrawZymoticFrame ();
+       else if (currentrenderentity->model->aliastype == ALIASTYPE_MD2)
+               R_DrawQ2AliasFrame ();
        else
-               R_DrawAliasFrame   (clmodel, modelheader, alpha, color, ent, ent != &cl.viewent, org, angles, scale, blend, skinset   , colormap, effects, flags);
+               R_DrawAliasFrame   ();
 }
index 0f35ab8..8750595 100644 (file)
--- a/gl_poly.c
+++ b/gl_poly.c
@@ -1,8 +1,18 @@
 #include "quakedef.h"
 
+typedef struct
+{
+       unsigned short tex;
+       unsigned short type;
+       int indices;
+}
+rendertranspoly_t;
+
 transvert_t *transvert;
 transpoly_t *transpoly;
-unsigned short *transpolyindex;
+rendertranspoly_t *rendertranspoly;
+int *transpolyindex;
+int *transvertindex;
 wallvert_t *wallvert;
 wallvertcolor_t *wallvertcolor;
 wallpoly_t *wallpoly;
@@ -16,11 +26,13 @@ int currentwallvert;
 int currentskypoly;
 int currentskyvert;
 
+
 void LoadSky_f(void);
 
 cvar_t r_multitexture = {0, "r_multitexture", "1"};
 cvar_t r_skyquality = {CVAR_SAVE, "r_skyquality", "2"};
 cvar_t r_mergesky = {CVAR_SAVE, "r_mergesky", "0"};
+cvar_t gl_transpolytris = {0, "gl_transpolytris", "0"};
 
 static char skyworldname[1024];
 static rtexture_t *mergeskytexture;
@@ -29,7 +41,7 @@ static rtexture_t *alphaskytexture, *alphaskytexture_half;
 static qboolean skyavailable_quake;
 static qboolean skyavailable_box;
 
-void R_BuildSky (int scrollupper, int scrolllower);
+static void R_BuildSky (int scrollupper, int scrolllower);
 
 typedef struct translistitem_s
 {
@@ -47,12 +59,14 @@ float transviewdist; // distance of view origin along the view normal
 
 float transreciptable[256];
 
-void gl_poly_start(void)
+static void gl_poly_start(void)
 {
        int i;
        transvert = qmalloc(MAX_TRANSVERTS * sizeof(transvert_t));
        transpoly = qmalloc(MAX_TRANSPOLYS * sizeof(transpoly_t));
-       transpolyindex = qmalloc(MAX_TRANSPOLYS * sizeof(unsigned short));
+       rendertranspoly = qmalloc(MAX_TRANSPOLYS * sizeof(rendertranspoly_t));
+       transpolyindex = qmalloc(MAX_TRANSPOLYS * sizeof(int));
+       transvertindex = qmalloc(MAX_TRANSVERTS * sizeof(int));
        wallvert = qmalloc(MAX_WALLVERTS * sizeof(wallvert_t));
        wallvertcolor = qmalloc(MAX_WALLVERTS * sizeof(wallvertcolor_t));
        wallpoly = qmalloc(MAX_WALLPOLYS * sizeof(wallpoly_t));
@@ -63,11 +77,13 @@ void gl_poly_start(void)
                transreciptable[i] = 1.0f / i;
 }
 
-void gl_poly_shutdown(void)
+static void gl_poly_shutdown(void)
 {
        qfree(transvert);
        qfree(transpoly);
+       qfree(rendertranspoly);
        qfree(transpolyindex);
+       qfree(transvertindex);
        qfree(wallvert);
        qfree(wallvertcolor);
        qfree(wallpoly);
@@ -75,7 +91,7 @@ void gl_poly_shutdown(void)
        qfree(skypoly);
 }
 
-void gl_poly_newmap(void)
+static void gl_poly_newmap(void)
 {
        skyavailable_box = false;
        skyavailable_quake = false;
@@ -89,6 +105,7 @@ void GL_Poly_Init(void)
        Cvar_RegisterVariable (&r_multitexture);
        Cvar_RegisterVariable (&r_skyquality);
        Cvar_RegisterVariable (&r_mergesky);
+       Cvar_RegisterVariable (&gl_transpolytris);
        R_RegisterModule("GL_Poly", gl_poly_start, gl_poly_shutdown, gl_poly_newmap);
 }
 
@@ -100,42 +117,7 @@ void transpolyclear(void)
        transviewdist = DotProduct(r_origin, vpn);
 }
 
-// turned into a #define
-/*
-void transpolybegin(int texnum, int glowtexnum, int fogtexnum, int transpolytype)
-{
-       if (currenttranspoly >= MAX_TRANSPOLYS || currenttransvert >= MAX_TRANSVERTS)
-               return;
-       transpoly[currenttranspoly].texnum = (unsigned short) texnum;
-       transpoly[currenttranspoly].glowtexnum = (unsigned short) glowtexnum;
-       transpoly[currenttranspoly].fogtexnum = (unsigned short) fogtexnum;
-       transpoly[currenttranspoly].transpolytype = (unsigned short) transpolytype;
-       transpoly[currenttranspoly].firstvert = currenttransvert;
-       transpoly[currenttranspoly].verts = 0;
-//     transpoly[currenttranspoly].ndist = 0; // clear the normal
-}
-*/
-
-// turned into a #define
-/*
-void transpolyvert(float x, float y, float z, float s, float t, int r, int g, int b, int a)
-{
-       int i;
-       if (currenttranspoly >= MAX_TRANSPOLYS || currenttransvert >= MAX_TRANSVERTS)
-               return;
-       transvert[currenttransvert].s = s;
-       transvert[currenttransvert].t = t;
-       transvert[currenttransvert].r = bound(0, r, 255);
-       transvert[currenttransvert].g = bound(0, g, 255);
-       transvert[currenttransvert].b = bound(0, b, 255);
-       transvert[currenttransvert].a = bound(0, a, 255);
-       transvert[currenttransvert].v[0] = x;
-       transvert[currenttransvert].v[1] = y;
-       transvert[currenttransvert].v[2] = z;
-       currenttransvert++;
-       transpoly[currenttranspoly].verts++;
-}
-*/
+// transpolybegin and transpolyvert are #define macros
 
 void transpolyend(void)
 {
@@ -174,207 +156,367 @@ void transpolyend(void)
        currenttranspoly++;
 }
 
-int transpolyindices;
+void transpolyparticle(vec3_t org, vec3_t right, vec3_t up, vec_t scale, unsigned short texnum, unsigned short transpolytype, int ir, int ig, int ib, float alphaf, float s1, float t1, float s2, float t2)
+{
+       float center, scale2;
+       int i;
+       vec3_t corner;
+       byte br, bg, bb, ba;
+       transpoly_t *p;
+       transvert_t *v;
+       center = DotProduct(org, vpn) - transviewdist;
+       if (center < 4.0f || currenttranspoly >= MAX_TRANSPOLYS || (currenttransvert + 4) > MAX_TRANSVERTS)
+               return;
+
+       p = transpoly + (currenttranspoly++);
+       v = transvert + currenttransvert;
+
+       if (lighthalf)
+       {
+               ir >>= 1;
+               ig >>= 1;
+               ib >>= 1;
+       }
+       ir = bound(0, ir, 255);
+       ig = bound(0, ig, 255);
+       ib = bound(0, ib, 255);
+       br = (byte) ir;
+       bg = (byte) ig;
+       bb = (byte) ib;
+
+#if SLOWMATH
+       i = (int) alphaf;
+       if (i > 255)
+               i = 255;
+       ba = (byte) i;
+
+       i = (int) center;
+#else
+       alphaf += 8388608.0f;
+       i = *((long *)&alphaf) & 0x007FFFFF;
+       if (i > 255)
+               i = 255;
+       ba = (byte) i;
+
+       center += 8388608.0f;
+       i = *((long *)&center) & 0x007FFFFF;
+#endif
+       i = bound(0, i, 4095);
+       currenttranslist->next = translisthash[i];
+       currenttranslist->poly = p;
+       translisthash[i] = currenttranslist++;
+
+       p->texnum = p->fogtexnum = texnum;
+       p->glowtexnum = 0;
+       p->transpolytype = transpolytype;
+       p->firstvert = currenttransvert;
+       p->verts = 4;
+       currenttransvert += 4;
+
+       scale2 = scale * -0.5f;
+       corner[0] = org[0] + (up[0] + right[0]) * scale2;
+       corner[1] = org[1] + (up[1] + right[1]) * scale2;
+       corner[2] = org[2] + (up[2] + right[2]) * scale2;
+       v->s = s1;
+       v->t = t1;
+       v->r = br;
+       v->g = bg;
+       v->b = bb;
+       v->a = ba;
+       v->v[0] = corner[0];
+       v->v[1] = corner[1];
+       v->v[2] = corner[2];
+       v++;
+       v->s = s1;
+       v->t = t2;
+       v->r = br;
+       v->g = bg;
+       v->b = bb;
+       v->a = ba;
+       v->v[0] = corner[0] + up[0] * scale;
+       v->v[1] = corner[1] + up[1] * scale;
+       v->v[2] = corner[2] + up[2] * scale;
+       v++;
+       v->s = s2;
+       v->t = t2;
+       v->r = br;
+       v->g = bg;
+       v->b = bb;
+       v->a = ba;
+       v->v[0] = corner[0] + (up[0] + right[0]) * scale;
+       v->v[1] = corner[1] + (up[1] + right[1]) * scale;
+       v->v[2] = corner[2] + (up[2] + right[2]) * scale;
+       v++;
+       v->s = s2;
+       v->t = t1;
+       v->r = br;
+       v->g = bg;
+       v->b = bb;
+       v->a = ba;
+       v->v[0] = corner[0] + right[0] * scale;
+       v->v[1] = corner[1] + right[1] * scale;
+       v->v[2] = corner[2] + right[2] * scale;
+       v++;
+}
 
 void transpolyrender(void)
 {
-       int i, j, tpolytype, texnum;
-       transpoly_t *p;
+       int                             i, j, k, l, tpolytype, texnum, transvertindices, alpha, currentrendertranspoly;
+       byte                    fogr, fogg, fogb;
+       vec3_t                  diff;
+       transpoly_t             *p;
+       rendertranspoly_t *r, *rend;
+       translistitem   *item;
+
        if (!r_render.value)
                return;
        if (currenttranspoly < 1)
                return;
-//     transpolyrenderminmax();
-//     if (transpolyindices < 1)
-//             return;
-       // testing
-//     Con_DPrintf("transpolyrender: %i polys %i infront %i vertices\n", currenttranspoly, transpolyindices, currenttransvert);
-//     if (transpolyindices >= 2)
-//             transpolysort();
+
        glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
        glEnable(GL_BLEND);
-       glShadeModel(GL_SMOOTH);
+//     glShadeModel(GL_SMOOTH);
        glDepthMask(0); // disable zbuffer updates
-       glDisable(GL_ALPHA_TEST);
-       glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-       tpolytype = TPOLYTYPE_ALPHA;
-       texnum = -1;
-       /*
-       if (gl_vertexarrays.value)
+
+       // set up the vertex array
+       glInterleavedArrays(GL_T2F_C4UB_V3F, sizeof(transvert[0]), transvert);
+
+       currentrendertranspoly = 0;
+       transvertindices = 0;
+       fogr = (byte) bound(0, (int) (fogcolor[0] * 255.0f), 255);
+       fogg = (byte) bound(0, (int) (fogcolor[1] * 255.0f), 255);
+       fogb = (byte) bound(0, (int) (fogcolor[2] * 255.0f), 255);
+       if (gl_transpolytris.value)
        {
-               // set up the vertex array
-               glInterleavedArrays(GL_T2F_C4UB_V3F, 0, transvert);
-               for (i = 0;i < transpolyindices;i++)
+               int glowtexnum, fogtexnum;
+               for (i = 4095;i >= 0;i--)
                {
-                       p = &transpoly[transpolyindex[i]];
-                       if (p->texnum != texnum || p->transpolytype != tpolytype)
+                       item = translisthash[i];
+                       while(item)
                        {
-                               if (p->texnum != texnum)
+                               p = item->poly;
+                               item = item->next;
+                               glowtexnum = p->glowtexnum;
+                               fogtexnum = p->fogtexnum;
+
+#define POLYTOTRI(pfirstvert, ptexnum, ptranspolytype) \
+                               l = pfirstvert;\
+                               r = &rendertranspoly[currentrendertranspoly++];\
+                               r->tex = ptexnum;\
+                               r->type = ptranspolytype;\
+                               if (p->verts == 4)\
+                               {\
+                                       transvertindex[transvertindices] = l;\
+                                       transvertindex[transvertindices + 1] = l + 1;\
+                                       transvertindex[transvertindices + 2] = l + 2;\
+                                       transvertindex[transvertindices + 3] = l;\
+                                       transvertindex[transvertindices + 4] = l + 2;\
+                                       transvertindex[transvertindices + 5] = l + 3;\
+                                       transvertindices += 6;\
+                                       r->indices = 6;\
+                               }\
+                               else if (p->verts == 3)\
+                               {\
+                                       transvertindex[transvertindices] = l;\
+                                       transvertindex[transvertindices + 1] = l + 1;\
+                                       transvertindex[transvertindices + 2] = l + 2;\
+                                       transvertindices += 3;\
+                                       r->indices = 3;\
+                               }\
+                               else\
+                               {\
+                                       for (j = l + p->verts, k = l + 2;k < j;k++)\
+                                       {\
+                                               transvertindex[transvertindices] = l;\
+                                               transvertindex[transvertindices + 1] = k - 1;\
+                                               transvertindex[transvertindices + 2] = k;\
+                                               transvertindices += 3;\
+                                       }\
+                                       r->indices = (p->verts - 2) * 3;\
+                               }
+
+                               POLYTOTRI(p->firstvert, p->texnum, p->transpolytype)
+
+                               if (p->glowtexnum)
                                {
-                                       texnum = p->texnum;
-                                       glBindTexture(GL_TEXTURE_2D, texnum);
+                                       // make another poly for glow effect
+                                       if (currenttranspoly < MAX_TRANSPOLYS && currenttransvert + p->verts <= MAX_TRANSVERTS)
+                                       {
+                                               memcpy(&transvert[currenttransvert], &transvert[p->firstvert], sizeof(transvert_t) * p->verts);
+                                               POLYTOTRI(currenttransvert, p->glowtexnum, TPOLYTYPE_ADD)
+                                               for (j = 0;j < p->verts;j++)
+                                               {
+                                                       transvert[currenttransvert].r = transvert[currenttransvert].g = transvert[currenttransvert].b = 255;
+                                                       currenttransvert++;
+                                               }
+                                       }
                                }
-                               if (p->transpolytype != tpolytype)
+
+                               if (fogenabled)
                                {
-                                       tpolytype = p->transpolytype;
-                                       if (tpolytype == TPOLYTYPE_ADD) // additive
-                                               glBlendFunc(GL_SRC_ALPHA, GL_ONE);
-                                       else // alpha
-                                               glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+                                       // make another poly for fog
+                                       if (currenttranspoly < MAX_TRANSPOLYS && currenttransvert + p->verts <= MAX_TRANSVERTS)
+                                       {
+                                               memcpy(&transvert[currenttransvert], &transvert[p->firstvert], sizeof(transvert_t) * p->verts);
+                                               POLYTOTRI(currenttransvert, p->fogtexnum, TPOLYTYPE_ALPHA)
+                                               for (j = 0, k = p->firstvert;j < p->verts;j++, k++)
+                                               {
+                                                       transvert[currenttransvert].r = fogr;
+                                                       transvert[currenttransvert].g = fogg;
+                                                       transvert[currenttransvert].b = fogb;
+                                                       VectorSubtract(transvert[currenttransvert].v, r_origin, diff);
+                                                       alpha = transvert[currenttransvert].a * exp(fogdensity / DotProduct(diff, diff));
+                                                       transvert[currenttransvert].a = (byte) bound(0, alpha, 255);
+                                                       currenttransvert++;
+                                               }
+                                       }
                                }
                        }
-                       glDrawArrays(GL_POLYGON, p->firstvert, p->verts);
-                       if (p->glowtexnum)
-                       {
-                               texnum = p->glowtexnum; // highly unlikely to match next poly, but...
-                               glBindTexture(GL_TEXTURE_2D, texnum);
-                               tpolytype = TPOLYTYPE_ADD; // might match next poly
-                               glBlendFunc(GL_SRC_ALPHA, GL_ONE);
-                               glDrawArrays(GL_POLYGON, p->firstvert, p->verts);
-                       }
                }
-               glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-               glDisableClientState(GL_COLOR_ARRAY);
-               glDisableClientState(GL_VERTEX_ARRAY);
        }
        else
-       */
        {
-               int points = -1;
-               translistitem *item;
-               transvert_t *vert;
                for (i = 4095;i >= 0;i--)
                {
                        item = translisthash[i];
-                       while (item)
+                       while(item)
                        {
                                p = item->poly;
                                item = item->next;
-                               if (p->texnum != texnum || p->verts != points || p->transpolytype != tpolytype)
-                               {
-                                       glEnd();
-                                       if (isG200)
-                                       {
-                                               // LordHavoc: Matrox G200 cards can't handle per pixel alpha
-                                               if (p->fogtexnum)
-                                                       glEnable(GL_ALPHA_TEST);
-                                               else
-                                                       glDisable(GL_ALPHA_TEST);
-                                       }
-                                       if (p->texnum != texnum)
-                                       {
-                                               texnum = p->texnum;
-                                               glBindTexture(GL_TEXTURE_2D, texnum);
-                                       }
-                                       if (p->transpolytype != tpolytype)
-                                       {
-                                               tpolytype = p->transpolytype;
-                                               if (tpolytype == TPOLYTYPE_ADD) // additive
-                                                       glBlendFunc(GL_SRC_ALPHA, GL_ONE);
-                                               else // alpha
-                                                       glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-                                       }
-                                       points = p->verts;
-                                       switch (points)
-                                       {
-                                       case 3:
-                                               glBegin(GL_TRIANGLES);
-                                               break;
-                                       case 4:
-                                               glBegin(GL_QUADS);
-                                               break;
-                                       default:
-                                               glBegin(GL_POLYGON);
-                                               points = -1; // to force a reinit on the next poly
-                                               break;
-                                       }
-                               }
-                               for (j = 0,vert = &transvert[p->firstvert];j < p->verts;j++, vert++)
-                               {
-                                       // would be 2fv, but windoze Matrox G200 and probably G400 drivers don't support that (dumb...)
-                                       glTexCoord2f(vert->s, vert->t);
-                                       // again, vector version isn't supported I think
-                                       glColor4ub(vert->r, vert->g, vert->b, vert->a);
-                                       glVertex3fv(vert->v);
-                               }
+
+                               l = p->firstvert;
+                               r = &rendertranspoly[currentrendertranspoly++];
+                               r->tex = p->texnum;
+                               r->type = p->transpolytype;
+                               r->indices = p->verts;
+
+                               for (j = l + p->verts, k = l;k < j;k++)
+                                       transvertindex[transvertindices++] = k;
+
                                if (p->glowtexnum)
                                {
-                                       glEnd();
-                                       texnum = p->glowtexnum; // highly unlikely to match next poly, but...
-                                       glBindTexture(GL_TEXTURE_2D, texnum);
-                                       if (tpolytype != TPOLYTYPE_ADD)
-                                       {
-                                               tpolytype = TPOLYTYPE_ADD; // might match next poly
-                                               glBlendFunc(GL_SRC_ALPHA, GL_ONE);
-                                       }
-                                       points = -1;
-                                       glBegin(GL_POLYGON);
-                                       for (j = 0,vert = &transvert[p->firstvert];j < p->verts;j++, vert++)
-                                       {
-                                               glColor4ub(255,255,255,vert->a);
-                                               // would be 2fv, but windoze Matrox G200 and probably G400 drivers don't support that (dumb...)
-                                               glTexCoord2f(vert->s, vert->t);
-                                               glVertex3fv(vert->v);
-                                       }
-                                       glEnd();
-                               }
-                               if (fogenabled && p->transpolytype == TPOLYTYPE_ALPHA)
-                               {
-                                       vec3_t diff;
-                                       glEnd();
-                                       points = -1; // to force a reinit on the next poly
-                                       if (tpolytype != TPOLYTYPE_ALPHA)
+                                       // make another poly for glow effect
+                                       if (currentrendertranspoly < MAX_TRANSPOLYS && currenttransvert + p->verts <= MAX_TRANSVERTS)
                                        {
-                                               tpolytype = TPOLYTYPE_ALPHA; // probably matchs next poly
-                                               glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-                                       }
-                                       if (p->fogtexnum)
-                                       {
-                                               if (texnum != p->fogtexnum) // highly unlikely to match next poly, but...
-                                               {
-                                                       texnum = p->fogtexnum;
-                                                       glBindTexture(GL_TEXTURE_2D, texnum);
-                                               }
-                                               glBegin(GL_POLYGON);
-                                               for (j = 0,vert = &transvert[p->firstvert];j < p->verts;j++, vert++)
+                                               l = currenttransvert;
+                                               r = &rendertranspoly[currentrendertranspoly++];
+                                               r->tex = p->glowtexnum;
+                                               r->type = TPOLYTYPE_ADD;
+                                               r->indices = p->verts;
+
+                                               memcpy(&transvert[currenttransvert], &transvert[p->firstvert], sizeof(transvert_t) * p->verts);
+                                               for (j = 0;j < p->verts;j++)
                                                {
-                                                       VectorSubtract(vert->v, r_origin, diff);
-                                                       glTexCoord2f(vert->s, vert->t);
-                                                       glColor4f(fogcolor[0], fogcolor[1], fogcolor[2], vert->a*(1.0f/255.0f)*exp(fogdensity/DotProduct(diff,diff)));
-                                                       glVertex3fv(vert->v);
+                                                       transvert[currenttransvert].r = transvert[currenttransvert].g = transvert[currenttransvert].b = 255;
+                                                       transvertindex[transvertindices++] = currenttransvert++;
                                                }
-                                               glEnd ();
                                        }
-                                       else
+                               }
+                               if (fogenabled)
+                               {
+                                       // make another poly for fog
+                                       if (currentrendertranspoly < MAX_TRANSPOLYS && currenttransvert + p->verts <= MAX_TRANSVERTS)
                                        {
-                                               glDisable(GL_TEXTURE_2D);
-                                               glBegin(GL_POLYGON);
-                                               for (j = 0,vert = &transvert[p->firstvert];j < p->verts;j++, vert++)
+                                               l = currenttransvert;
+                                               r = &rendertranspoly[currentrendertranspoly++];
+                                               r->tex = p->fogtexnum;
+                                               r->type = TPOLYTYPE_ALPHA;
+                                               r->indices = p->verts;
+
+                                               memcpy(&transvert[currenttransvert], &transvert[p->firstvert], sizeof(transvert_t) * p->verts);
+                                               for (j = 0;j < p->verts;j++)
                                                {
-                                                       VectorSubtract(vert->v, r_origin, diff);
-                                                       glColor4f(fogcolor[0], fogcolor[1], fogcolor[2], vert->a*(1.0f/255.0f)*exp(fogdensity/DotProduct(diff,diff)));
-                                                       glVertex3fv(vert->v);
+                                                       transvert[currenttransvert].r = fogr;
+                                                       transvert[currenttransvert].g = fogg;
+                                                       transvert[currenttransvert].b = fogb;
+                                                       VectorSubtract(transvert[currenttransvert].v, r_origin, diff);
+                                                       alpha = transvert[currenttransvert].a * exp(fogdensity / DotProduct(diff, diff));
+                                                       transvert[currenttransvert].a = (byte) bound(0, alpha, 255);
+                                                       transvertindex[transvertindices++] = currenttransvert++;
                                                }
-                                               glEnd ();
-                                               glEnable(GL_TEXTURE_2D);
                                        }
                                }
                        }
                }
-               glEnd();
        }
 
+       GL_LockArray(0, currenttransvert);
+
+       glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+       tpolytype = TPOLYTYPE_ALPHA;
+       texnum = -1;
+       transvertindices = 0;
+       r = rendertranspoly;
+       rend = r + currentrendertranspoly;
+       while(r < rend)
+       {
+               if (texnum != r->tex)
+               {
+                       texnum = r->tex;
+                       glBindTexture(GL_TEXTURE_2D, texnum);
+               }
+               if (tpolytype != r->type)
+               {
+                       tpolytype = r->type;
+                       if (tpolytype == TPOLYTYPE_ADD) // additive
+                               glBlendFunc(GL_SRC_ALPHA, GL_ONE);
+                       else // alpha
+                               glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+               }
+               k = transvertindices;
+               if (gl_transpolytris.value)
+               {
+                       do
+                               transvertindices += r->indices, r++;
+                       while (r < rend && r->tex == texnum && r->type == tpolytype);
+                       glDrawElements(GL_TRIANGLES, transvertindices - k, GL_UNSIGNED_INT, &transvertindex[k]);
+               }
+               else
+               {
+                       if (r->indices == 4)
+                       {
+                               do
+                                       transvertindices += 4, r++;
+                               while (r < rend && r->indices == 4 && r->tex == texnum && r->type == tpolytype);
+                               glDrawElements(GL_QUADS, transvertindices - k, GL_UNSIGNED_INT, &transvertindex[k]);
+                       }
+                       else if (r->indices == 3)
+                       {
+                               do
+                                       transvertindices += 3, r++;
+                               while (r < rend && r->indices == 3 && r->tex == texnum && r->type == tpolytype);
+                               glDrawElements(GL_TRIANGLES, transvertindices - k, GL_UNSIGNED_INT, &transvertindex[k]);
+                       }
+                       else
+                       {
+                               transvertindices += r->indices, r++;
+                               glDrawElements(GL_POLYGON, transvertindices - k, GL_UNSIGNED_INT, &transvertindex[k]);
+                       }
+               }
+       }
+
+       GL_UnlockArray();
+
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        glDepthMask(1); // enable zbuffer updates
-       glDisable(GL_ALPHA_TEST);
+       glDisable(GL_BLEND);
+       glColor3f(1,1,1);
+
+       glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+       glDisableClientState(GL_COLOR_ARRAY);
+       glDisableClientState(GL_VERTEX_ARRAY);
+
 }
 
 void wallpolyclear(void)
 {
+       if (!gl_mtexable)
+               r_multitexture.value = 0;
        currentwallpoly = currentwallvert = 0;
 }
 
-void wallpolyrender(void)
+// render walls and fullbrights, but not fog
+void wallpolyrender1(void)
 {
        int i, j, texnum, lighttexnum;
        wallpoly_t *p;
@@ -387,11 +529,9 @@ void wallpolyrender(void)
        c_brush_polys += currentwallpoly;
        // testing
        //Con_DPrintf("wallpolyrender: %i polys %i vertices\n", currentwallpoly, currentwallvert);
-       if (!gl_mtexable)
-               r_multitexture.value = 0;
        glDisable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-       glShadeModel(GL_FLAT);
+//     glShadeModel(GL_FLAT);
        // make sure zbuffer is enabled
        glEnable(GL_DEPTH_TEST);
 //     glDisable(GL_ALPHA_TEST);
@@ -401,7 +541,7 @@ void wallpolyrender(void)
        {
                glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
                texnum = -1;
-               for (i = 0,p = wallpoly;i < currentwallpoly;i++, p++)
+               for (i = 0, p = wallpoly;i < currentwallpoly;i++, p++)
                {
                        if (p->texnum != texnum)
                        {
@@ -472,7 +612,7 @@ void wallpolyrender(void)
                }
                texnum = -1;
                lighttexnum = -1;
-               for (i = 0,p = wallpoly;i < currentwallpoly;i++, p++)
+               for (i = 0, p = wallpoly;i < currentwallpoly;i++, p++)
                {
                        if (p->texnum != texnum)
                        {
@@ -508,7 +648,7 @@ void wallpolyrender(void)
                // first do the textures
                glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
                texnum = -1;
-               for (i = 0,p = wallpoly;i < currentwallpoly;i++, p++)
+               for (i = 0, p = wallpoly;i < currentwallpoly;i++, p++)
                {
                        if (p->texnum != texnum)
                        {
@@ -549,10 +689,10 @@ void wallpolyrender(void)
        // switch to additive mode settings
        glDepthMask(0);
        glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
-       glBlendFunc(GL_SRC_ALPHA, GL_ONE);
+       glBlendFunc(GL_ONE, GL_ONE);
        glEnable(GL_BLEND);
 //     glDisable(GL_ALPHA_TEST);
-       glShadeModel(GL_SMOOTH);
+//     glShadeModel(GL_SMOOTH);
        // render vertex lit overlays ontop
        texnum = -1;
        for (i = 0, p = wallpoly;i < currentwallpoly;i++, p++)
@@ -582,14 +722,13 @@ lit:
                glEnd();
        }
        // render glow textures
-       glShadeModel(GL_FLAT);
-       glBlendFunc(GL_ONE, GL_ONE);
+//     glShadeModel(GL_FLAT);
        if (lighthalf)
                glColor3f(0.5,0.5,0.5);
        else
                glColor3f(1,1,1);
        texnum = -1;
-       for (i = 0,p = wallpoly;i < currentwallpoly;i++, p++)
+       for (i = 0, p = wallpoly;i < currentwallpoly;i++, p++)
        {
                if (!p->glowtexnum)
                        continue;
@@ -609,31 +748,54 @@ lit:
        }
        glColor3f(1,1,1);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-       glShadeModel(GL_SMOOTH);
+//     glDisable(GL_ALPHA_TEST);
+//     glShadeModel(GL_SMOOTH);
+       glDisable(GL_BLEND);
+       glDepthMask(1);
+}
+
+// render fog
+void wallpolyrender2(void)
+{
+       if (!r_render.value)
+               return;
+       if (currentwallpoly < 1)
+               return;
        if (fogenabled)
        {
+               int i, j, alpha, fogr, fogg, fogb;
+               wallpoly_t *p;
+               wallvert_t *vert;
                vec3_t diff;
+               glEnable(GL_DEPTH_TEST);
+               glDepthMask(0);
+               glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+               glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+               glEnable(GL_BLEND);
+//             glShadeModel(GL_SMOOTH);
                glDisable(GL_TEXTURE_2D);
-               for (i = 0,p = &wallpoly[0];i < currentwallpoly;i++, p++)
+               fogr = (byte) bound(0, (int) (fogcolor[0] * 255.0f), 255);
+               fogg = (byte) bound(0, (int) (fogcolor[1] * 255.0f), 255);
+               fogb = (byte) bound(0, (int) (fogcolor[2] * 255.0f), 255);
+               for (i = 0, p = wallpoly;i < currentwallpoly;i++, p++)
                {
                        vert = &wallvert[p->firstvert];
                        glBegin(GL_POLYGON);
                        for (j=0 ; j<p->numverts ; j++, vert++)
                        {
                                VectorSubtract(vert->vert, r_origin, diff);
-                               glColor4f(fogcolor[0], fogcolor[1], fogcolor[2], exp(fogdensity/DotProduct(diff,diff)));
+                               alpha = 255.0f * exp(fogdensity/DotProduct(diff,diff));
+                               alpha = bound(0, alpha, 255);
+                               glColor4ub(fogr, fogg, fogb, (byte) alpha);
                                glVertex3fv (vert->vert);
                        }
                        glEnd ();
                }
                glEnable(GL_TEXTURE_2D);
+               glColor3f(1,1,1);
+               glDisable(GL_BLEND);
+               glDepthMask(1);
        }
-       glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
-       glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-//     glDisable(GL_ALPHA_TEST);
-       glShadeModel(GL_SMOOTH);
-       glDisable(GL_BLEND);
-       glDepthMask(1);
 }
 
 static int skyrendersphere;
@@ -691,6 +853,8 @@ void skypolyclear(void)
 
 }
 
+static void R_Sky(void);
+
 void skypolyrender(void)
 {
        int i, j;
@@ -859,6 +1023,8 @@ void skypolyrender(void)
        }
        GL_UnlockArray();
        glDisableClientState(GL_VERTEX_ARRAY);
+
+       R_Sky();
 }
 
 static char skyname[256];
@@ -868,8 +1034,8 @@ static char skyname[256];
 R_SetSkyBox
 ==================
 */
-char   *suf[6] = {"rt", "bk", "lf", "ft", "up", "dn"};
-rtexture_t *skyboxside[6];
+static char *suf[6] = {"rt", "bk", "lf", "ft", "up", "dn"};
+static rtexture_t *skyboxside[6];
 int R_SetSkyBox(char *sky)
 {
        int             i;
@@ -900,7 +1066,7 @@ int R_SetSkyBox(char *sky)
                        sprintf (name, "gfx/env/%s%s", sky, suf[i]);
                        if (!(image_rgba = loadimagepixels(name, false, 0, 0)))
                        {
-                               Con_Printf ("Couldn't load %s\n", name);
+                               Con_Printf ("Couldn't load env/%s%s or gfx/env/%s%s\n", sky, suf[i], sky, suf[i]);
                                continue;
                        }
                }
@@ -949,7 +1115,7 @@ void LoadSky_f (void)
        glTexCoord2f((s) * (254.0f/256.0f) + (1.0f/256.0f), (t) * (254.0f/256.0f) + (1.0f/256.0f));\
        glVertex3f((x) * 1024.0 + r_origin[0], (y) * 1024.0 + r_origin[1], (z) * 1024.0 + r_origin[2]);
 
-void R_SkyBox(void)
+static void R_SkyBox(void)
 {
        glDisable(GL_DEPTH_TEST);
        glDepthMask(0);
@@ -1006,9 +1172,9 @@ void R_SkyBox(void)
        glColor3f (1,1,1);
 }
 
-float skysphere[33*33*5];
-int skysphereindices[32*32*6];
-void skyspherecalc(float *sphere, float dx, float dy, float dz)
+static float skysphere[33*33*5];
+static int skysphereindices[32*32*6];
+static void skyspherecalc(float *sphere, float dx, float dy, float dz)
 {
        float a, b, x, ax, ay, v[3], length;
        int i, j, *index;
@@ -1047,7 +1213,7 @@ void skyspherecalc(float *sphere, float dx, float dy, float dz)
        }
 }
 
-void skyspherearrays(float *vert, float *tex, float *tex2, float *source, float s, float s2)
+static void skyspherearrays(float *vert, float *tex, float *tex2, float *source, float s, float s2)
 {
        float *v, *t, *t2;
        int i;
@@ -1068,7 +1234,7 @@ void skyspherearrays(float *vert, float *tex, float *tex2, float *source, float
        }
 }
 
-void R_SkySphere(void)
+static void R_SkySphere(void)
 {
        float speedscale, speedscale2;
        float vert[33*33*4], tex[33*33*2], tex2[33*33*2];
@@ -1207,7 +1373,7 @@ void R_SkySphere(void)
        glColor3f (1,1,1);
 }
 
-void R_Sky(void)
+static void R_Sky(void)
 {
        if (!r_render.value)
                return;
@@ -1219,11 +1385,11 @@ void R_Sky(void)
 
 //===============================================================
 
-byte skyupperlayerpixels[128*128*4];
-byte skylowerlayerpixels[128*128*4];
-byte skymergedpixels[128*128*4];
+static byte skyupperlayerpixels[128*128*4];
+static byte skylowerlayerpixels[128*128*4];
+static byte skymergedpixels[128*128*4];
 
-void R_BuildSky (int scrollupper, int scrolllower)
+static void R_BuildSky (int scrollupper, int scrolllower)
 {
        int x, y, ux, uy, lx, ly;
        byte *m, *u, *l;
index 21665d7..6db5741 100644 (file)
--- a/gl_poly.h
+++ b/gl_poly.h
@@ -9,9 +9,11 @@ extern void transpolyclear(void);
 extern void transpolyrender(void);
 extern void transpolybegin(int texnum, int glowtexnum, int fogtexnum, int transpolytype);
 extern void transpolyend(void);
+extern void transpolyparticle(vec3_t org, vec3_t right, vec3_t up, vec_t scale, unsigned short texnum, unsigned short transpolytype, int ir, int ig, int ib, float alphaf, float s1, float t1, float s2, float t2);
 
 extern void wallpolyclear(void);
-extern void wallpolyrender(void);
+extern void wallpolyrender1(void);
+extern void wallpolyrender2(void);
 
 extern void skypolyclear(void);
 extern void skypolyrender(void);
@@ -88,7 +90,9 @@ skypoly_t;
 
 extern transvert_t *transvert;
 extern transpoly_t *transpoly;
-extern unsigned short *transpolyindex;
+extern int *transpolyindex;
+extern int *transvertindex;
+extern transpoly_t **transpolylist;
 extern wallvert_t *wallvert;
 extern wallvertcolor_t *wallvertcolor;
 extern wallpoly_t *wallpoly;
index ffa9226..f848def 100644 (file)
@@ -8,7 +8,7 @@ of the License, or (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
 See the GNU General Public License for more details.
 
@@ -21,10 +21,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 #include "quakedef.h"
 
-qboolean       r_cache_thrash;         // compatability
+//static qboolean      r_cache_thrash;         // compatability
 
-vec3_t         modelorg, r_entorigin;
-entity_t       *currententity;
+vec3_t         modelorg;
+entity_render_t        *currentrenderentity;
 
 int                    r_framecount;           // used for dlight push checking
 
@@ -46,8 +46,8 @@ vec3_t        vpn;
 vec3_t vright;
 vec3_t r_origin;
 
-float  r_world_matrix[16];
-float  r_base_world_matrix[16];
+//float        r_world_matrix[16];
+//float        r_base_world_matrix[16];
 
 //
 // screen size info
@@ -58,8 +58,6 @@ mleaf_t               *r_viewleaf, *r_oldviewleaf;
 
 unsigned short d_lightstylevalue[256]; // 8.8 fraction of base light value
 
-void R_MarkLeaves (void);
-
 //cvar_t       r_norefresh = {0, "r_norefresh","0"};
 cvar_t r_drawentities = {0, "r_drawentities","1"};
 cvar_t r_drawviewmodel = {0, "r_drawviewmodel","1"};
@@ -86,24 +84,23 @@ cvar_t      gl_fogend = {0, "gl_fogend","0"};
 cvar_t glfog = {0, "glfog", "0"};
 
 cvar_t r_ser = {CVAR_SAVE, "r_ser", "1"};
+cvar_t gl_viewmodeldepthhack = {0, "gl_viewmodeldepthhack", "1"};
 
-/*
 int R_VisibleCullBox (vec3_t mins, vec3_t maxs)
 {
        int sides;
        mnode_t *nodestack[8192], *node;
        int stack = 0;
 
+       if (R_CullBox(mins, maxs))
+               return true;
+
        node = cl.worldmodel->nodes;
 loc0:
        if (node->contents < 0)
        {
                if (((mleaf_t *)node)->visframe == r_framecount)
-               {
-                       if (R_CullBox(mins, maxs))
-                               return true;
                        return false;
-               }
                if (!stack)
                        return true;
                node = nodestack[--stack];
@@ -132,7 +129,6 @@ loc0:
        node = node->children[1];
        goto loc0;
 }
-*/
 
 qboolean lighthalf;
 
@@ -143,10 +139,8 @@ qboolean fogenabled;
 qboolean oldgl_fogenable;
 void FOG_framebegin(void)
 {
-       if (nehahra)
+       if (gamemode == GAME_NEHAHRA)
        {
-//             if (!Nehahrademcompatibility)
-//                     gl_fogenable.value = 0;
                if (gl_fogenable.value)
                {
                        oldgl_fogenable = true;
@@ -182,7 +176,7 @@ void FOG_framebegin(void)
                        return;
                if(fog_density)
                {
-                       // LordHavoc: Borland C++ 5.0 was choking on this line, stupid compiler...
+                       // LordHavoc: Borland C++ 5.0 was choking on this line...
                        //GLfloat colors[4] = {(GLfloat) gl_fogred.value, (GLfloat) gl_foggreen.value, (GLfloat) gl_fogblue.value, (GLfloat) 1};
                        GLfloat colors[4];
                        colors[0] = fog_red;
@@ -197,7 +191,7 @@ void FOG_framebegin(void)
                        }
 
                        glFogi (GL_FOG_MODE, GL_EXP2);
-                       glFogf (GL_FOG_DENSITY, (GLfloat) fog_density / 100); 
+                       glFogf (GL_FOG_DENSITY, (GLfloat) fog_density / 100);
                        glFogfv (GL_FOG_COLOR, colors);
                        glEnable (GL_FOG);
                }
@@ -225,7 +219,7 @@ void FOG_frameend(void)
 
 void FOG_clear(void)
 {
-       if (nehahra)
+       if (gamemode == GAME_NEHAHRA)
        {
                Cvar_Set("gl_fogenable", "0");
                Cvar_Set("gl_fogdensity", "0.2");
@@ -239,7 +233,7 @@ void FOG_clear(void)
 void FOG_registercvars(void)
 {
        Cvar_RegisterVariable (&glfog);
-       if (nehahra)
+       if (gamemode == GAME_NEHAHRA)
        {
                Cvar_RegisterVariable (&gl_fogenable);
                Cvar_RegisterVariable (&gl_fogdensity);
@@ -278,12 +272,11 @@ void GL_Main_Init(void)
        Cvar_RegisterVariable (&r_dynamic);
        Cvar_RegisterVariable (&r_waterripple);
        Cvar_RegisterVariable (&r_farclip);
-       if (nehahra)
-               Cvar_SetValue("r_fullbrights", 0);
-//     if (gl_vendor && strstr(gl_vendor, "3Dfx"))
-//             gl_lightmode.value = 0;
        Cvar_RegisterVariable (&r_fullbright);
        Cvar_RegisterVariable (&r_ser);
+       Cvar_RegisterVariable (&gl_viewmodeldepthhack);
+       if (gamemode == GAME_NEHAHRA)
+               Cvar_SetValue("r_fullbrights", 0);
        R_RegisterModule("GL_Main", gl_main_start, gl_main_shutdown, gl_main_newmap);
 }
 
@@ -360,151 +353,66 @@ void GL_Init (void)
 }
 
 
-/*
-void R_RotateForEntity (entity_t *e)
-{
-       glTranslatef (e->origin[0],  e->origin[1],  e->origin[2]);
-
-       glRotatef (e->angles[1],  0, 0, 1);
-       glRotatef (-e->angles[0],  0, 1, 0);
-       glRotatef (e->angles[2],  1, 0, 0);
-
-       glScalef (e->scale, e->scale, e->scale); // LordHavoc: model scale
-}
-*/
-
-// LordHavoc: shading stuff
-vec3_t shadevector;
-vec3_t shadecolor;
-
-float  modelalpha;
-
 //==================================================================================
 
-void R_LerpUpdate(entity_t *ent)
+void R_Entity_Callback(void *data, void *junk)
 {
-       int frame;
-       frame = ent->render.frame;
-       if (ent->render.model && ent->render.frame >= ent->render.model->numframes)
-       {
-               Con_Printf("R_LerpUpdate: no such frame%6i in \"%s\"\n", ent->render.frame, ent->render.model->name);
-               frame = 0;
-       }
-
-       if (ent->render.lerp_model != ent->render.model)
-       {
-               // reset all interpolation information
-               ent->render.lerp_model = ent->render.model;
-               ent->render.frame1 = ent->render.frame2 = frame;
-               ent->render.frame1start = ent->render.frame2start = cl.time;
-               ent->render.framelerp = 1;
-               ent->render.lerp_starttime = 0;
-       }
-       else if (ent->render.frame2 != frame)
-       {
-               // transition to new frame
-               ent->render.frame1 = ent->render.frame2;
-               ent->render.frame1start = ent->render.frame2start;
-               ent->render.frame2 = frame;
-               ent->render.frame2start = cl.time;
-               ent->render.framelerp = 0;
-               ent->render.lerp_starttime = cl.time;
-       }
-       else
-       {
-               // lerp_starttime < 0 is used to prevent changing of framelerp
-               if (ent->render.lerp_starttime >= 0)
-               {
-                       // update transition
-                       ent->render.framelerp = (cl.time - ent->render.lerp_starttime) * 10;
-                       ent->render.framelerp = bound(0, ent->render.framelerp, 1);
-               }
-       }
+       ((entity_render_t *)data)->visframe = r_framecount;
 }
 
-
-void R_PrepareEntities (void)
+static void R_AddModelEntities (void)
 {
-       int i;
-       entity_t *ent;
-       vec3_t v;
-       // this updates entities that are supposed to be view relative
+       int             i;
+       vec3_t  v;
+
+       if (!r_drawentities.value)
+               return;
+
        for (i = 0;i < cl_numvisedicts;i++)
        {
-               ent = cl_visedicts[i];
+               currentrenderentity = &cl_visedicts[i]->render;
 
-               if (ent->render.flags & RENDER_VIEWMODEL)
+               // move view-relative models to where they should be
+               if (currentrenderentity->flags & RENDER_VIEWMODEL)
                {
                        // remove flag so it will not be repeated incase RelinkEntities is not called again for a while
-                       ent->render.flags -= RENDER_VIEWMODEL;
+                       currentrenderentity->flags -= RENDER_VIEWMODEL;
                        // transform origin
-                       VectorCopy(ent->render.origin, v);
-                       ent->render.origin[0] = v[0] * vpn[0] + v[1] * vright[0] + v[2] * vup[0] + r_origin[0];
-                       ent->render.origin[1] = v[0] * vpn[1] + v[1] * vright[1] + v[2] * vup[1] + r_origin[1];
-                       ent->render.origin[2] = v[0] * vpn[2] + v[1] * vright[2] + v[2] * vup[2] + r_origin[2];
+                       VectorCopy(currentrenderentity->origin, v);
+                       currentrenderentity->origin[0] = v[0] * vpn[0] + v[1] * vright[0] + v[2] * vup[0] + r_origin[0];
+                       currentrenderentity->origin[1] = v[0] * vpn[1] + v[1] * vright[1] + v[2] * vup[1] + r_origin[1];
+                       currentrenderentity->origin[2] = v[0] * vpn[2] + v[1] * vright[2] + v[2] * vup[2] + r_origin[2];
                        // adjust angles
-                       VectorAdd(ent->render.angles, r_refdef.viewangles, ent->render.angles);
+                       VectorAdd(currentrenderentity->angles, r_refdef.viewangles, currentrenderentity->angles);
                }
-       }
-}
-
-void R_Entity_Callback(void *data, void *junk)
-{
-       ((entity_t *)data)->render.visframe = r_framecount;
-}
-
-void R_AddModelEntities (void)
-{
-       int             i;
-       vec3_t  mins, maxs;
-       frameblend_t blend[4];
-
-       if (!r_drawentities.value)
-               return;
 
-       for (i = 0;i < cl_numvisedicts;i++)
-       {
-               currententity = cl_visedicts[i];
-               if (currententity->render.model->type == mod_brush)
+               if (currentrenderentity->angles[0] || currentrenderentity->angles[2])
                {
-                       modelalpha = currententity->render.alpha;
-                       R_DrawBrushModel (currententity);
+                       VectorMA(currentrenderentity->origin, currentrenderentity->scale, currentrenderentity->model->rotatedmins, currentrenderentity->mins);
+                       VectorMA(currentrenderentity->origin, currentrenderentity->scale, currentrenderentity->model->rotatedmaxs, currentrenderentity->maxs);
                }
-               else if (currententity->render.model->type == mod_alias)
+               else if (currentrenderentity->angles[1])
                {
-                       VectorAdd(currententity->render.origin, currententity->render.model->mins, mins);
-                       VectorAdd(currententity->render.origin, currententity->render.model->maxs, maxs);
-                       if (r_ser.value)
-                               R_Clip_AddBox(mins, maxs, R_Entity_Callback, currententity, NULL);
-                       else if (R_NotCulledBox(mins, maxs))
-                               currententity->render.visframe = r_framecount;
+                       VectorMA(currentrenderentity->origin, currentrenderentity->scale, currentrenderentity->model->yawmins, currentrenderentity->mins);
+                       VectorMA(currentrenderentity->origin, currentrenderentity->scale, currentrenderentity->model->yawmaxs, currentrenderentity->maxs);
                }
-               else if (currententity->render.model->type == mod_sprite)
+               else
                {
-                       R_LerpUpdate(currententity);
-                       if (r_ser.value)
-                       {
-                               R_LerpAnimation(currententity->render.model, currententity->render.frame1, currententity->render.frame2, currententity->render.frame1start, currententity->render.frame2start, currententity->render.framelerp, blend);
-                               R_ClipSprite(currententity, blend);
-                       }
-                       else
-                       {
-                               VectorAdd(currententity->render.origin, currententity->render.model->mins, mins);
-                               VectorAdd(currententity->render.origin, currententity->render.model->maxs, maxs);
-                               if (R_NotCulledBox(mins, maxs))
-                                       currententity->render.visframe = r_framecount;
-                       }
+                       VectorMA(currentrenderentity->origin, currentrenderentity->scale, currentrenderentity->model->normalmins, currentrenderentity->mins);
+                       VectorMA(currentrenderentity->origin, currentrenderentity->scale, currentrenderentity->model->normalmaxs, currentrenderentity->maxs);
                }
+               if (R_VisibleCullBox(currentrenderentity->mins, currentrenderentity->maxs))
+                       continue;
+
+               R_LerpAnimation(currentrenderentity);
+               if (r_ser.value)
+                       currentrenderentity->model->SERAddEntity();
+               else
+                       currentrenderentity->visframe = r_framecount;
        }
 }
 
-/*
-=============
-R_DrawEntitiesOnList
-=============
-*/
-/*
-void R_DrawEntitiesOnList1 (void)
+void R_DrawModels1 (void)
 {
        int             i;
 
@@ -513,65 +421,24 @@ void R_DrawEntitiesOnList1 (void)
 
        for (i = 0;i < cl_numvisedicts;i++)
        {
-               if (cl_visedicts[i]->render.visframe != r_framecount)
-                       continue;
-               if (cl_visedicts[i]->render.model->type != mod_brush)
-                       continue;
-               currententity = cl_visedicts[i];
-               modelalpha = currententity->render.alpha;
-
-               R_DrawBrushModel (currententity);
+               currentrenderentity = &cl_visedicts[i]->render;
+               if (currentrenderentity->visframe == r_framecount && currentrenderentity->model->DrawEarly)
+                       currentrenderentity->model->DrawEarly();
        }
 }
-*/
 
-void R_DrawModels (void)
+void R_DrawModels2 (void)
 {
        int             i;
-       frameblend_t blend[4];
-//     vec3_t  mins, maxs;
 
        if (!r_drawentities.value)
                return;
 
        for (i = 0;i < cl_numvisedicts;i++)
        {
-               if (cl_visedicts[i]->render.visframe != r_framecount)
-                       continue;
-               currententity = cl_visedicts[i];
-               if (currententity->render.model->type != mod_alias && currententity->render.model->type != mod_sprite)
-                       continue;
-
-               modelalpha = currententity->render.alpha;
-
-               if (currententity->render.model->type == mod_alias)
-               {
-                       // only lerp models here because sprites were already lerped for their clip polygon
-                       R_LerpUpdate(currententity);
-                       R_LerpAnimation(currententity->render.model, currententity->render.frame1, currententity->render.frame2, currententity->render.frame1start, currententity->render.frame2start, currententity->render.framelerp, blend);
-                       R_DrawAliasModel (currententity, true, modelalpha, currententity->render.model, blend, currententity->render.skinnum, currententity->render.origin, currententity->render.angles, currententity->render.scale, currententity->render.effects, currententity->render.model->flags, currententity->render.colormap);
-               }
-               else //if (currententity->render.model->type == mod_sprite)
-               {
-                       // build blend array
-                       R_LerpAnimation(currententity->render.model, currententity->render.frame1, currententity->render.frame2, currententity->render.frame1start, currententity->render.frame2start, currententity->render.framelerp, blend);
-                       R_DrawSpriteModel (currententity, blend);
-               }
-
-               /*
-               VectorAdd(cl_visedicts[i]->render.origin, cl_visedicts[i]->render.model->mins, mins);
-               VectorAdd(cl_visedicts[i]->render.origin, cl_visedicts[i]->render.model->maxs, maxs);
-
-               switch (cl_visedicts[i]->render.model->type)
-               {
-               case mod_alias:
-                       R_Clip_AddBox(mins, maxs, R_DrawModelCallback, cl_visedicts[i], NULL);
-                       break;
-               case mod_sprite:
-                       R_Clip_AddBox(mins, maxs, R_DrawSpriteCallback, cl_visedicts[i], NULL);
-                       break;
-               }
-               */
+               currentrenderentity = &cl_visedicts[i]->render;
+               if (currentrenderentity->visframe == r_framecount && currentrenderentity->model->DrawLate)
+                       currentrenderentity->model->DrawLate();
        }
 }
 
@@ -582,31 +449,22 @@ R_DrawViewModel
 */
 void R_DrawViewModel (void)
 {
-       frameblend_t blend[4];
-
        if (!r_drawviewmodel.value || chase_active.value || envmap || !r_drawentities.value || cl.items & IT_INVISIBILITY || cl.stats[STAT_HEALTH] <= 0 || !cl.viewent.render.model)
                return;
 
-       currententity = &cl.viewent;
-       currententity->render.alpha = modelalpha = cl_entities[cl.viewentity].render.alpha; // LordHavoc: if the player is transparent, so is the gun
-       currententity->render.effects = cl_entities[cl.viewentity].render.effects;
-       currententity->render.scale = 1;
-       VectorCopy(cl_entities[cl.viewentity].render.colormod, currententity->render.colormod);
+       currentrenderentity = &cl.viewent.render;
 
-       R_LerpUpdate(currententity);
-       R_LerpAnimation(currententity->render.model, currententity->render.frame1, currententity->render.frame2, currententity->render.frame1start, currententity->render.frame2start, currententity->render.framelerp, blend);
+       R_LerpAnimation(currentrenderentity);
 
        // hack the depth range to prevent view model from poking into walls
-       glDepthRange (gldepthmin, gldepthmin + 0.3*(gldepthmax-gldepthmin));
-       R_DrawAliasModel (currententity, false, modelalpha, currententity->render.model, blend, currententity->render.skinnum, currententity->render.origin, currententity->render.angles, currententity->render.scale, currententity->render.effects, currententity->render.model->flags, currententity->render.colormap);
-       glDepthRange (gldepthmin, gldepthmax);
+       if (gl_viewmodeldepthhack.value)
+               glDepthRange (gldepthmin, gldepthmin + 0.3*(gldepthmax-gldepthmin));
+       currentrenderentity->model->DrawLate();
+       if (gl_viewmodeldepthhack.value)
+               glDepthRange (gldepthmin, gldepthmax);
 }
 
-void R_DrawBrushModel (entity_t *e);
-
-void RotatePointAroundVector( vec3_t dst, const vec3_t dir, const vec3_t point, float degrees );
-
-void R_SetFrustum (void)
+static void R_SetFrustum (void)
 {
        int             i;
 
@@ -646,21 +504,20 @@ void R_SetFrustum (void)
        }
 }
 
-void R_AnimateLight (void);
-void V_CalcBlend (void);
-
 /*
 ===============
 R_SetupFrame
 ===============
 */
-void R_SetupFrame (void)
+static void R_SetupFrame (void)
 {
 // don't allow cheats in multiplayer
        if (cl.maxclients > 1)
        {
-               Cvar_Set ("r_fullbright", "0");
-               Cvar_Set ("r_ambient", "0");
+               if (r_fullbright.value != 0)
+                       Cvar_Set ("r_fullbright", "0");
+               if (r_ambient.value != 0)
+                       Cvar_Set ("r_ambient", "0");
        }
 
        r_framecount++;
@@ -677,7 +534,7 @@ void R_SetupFrame (void)
        V_SetContentsColor (r_viewleaf->contents);
        V_CalcBlend ();
 
-       r_cache_thrash = false;
+//     r_cache_thrash = false;
 
        c_brush_polys = 0;
        c_alias_polys = 0;
@@ -695,17 +552,20 @@ void R_SetupFrame (void)
 }
 
 
-void MYgluPerspective( GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar )
+static void MYgluPerspective(GLdouble fovx, GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar )
 {
-   GLdouble xmin, xmax, ymin, ymax;
+       GLdouble xmax, ymax;
 
-   ymax = zNear * tan( fovy * M_PI / 360.0 );
-   ymin = -ymax;
+       xmax = zNear * tan( fovx * M_PI / 360.0 ) * aspect;
+       ymax = zNear * tan( fovy * M_PI / 360.0 );
 
-   xmin = ymin * aspect;
-   xmax = ymax * aspect;
+       if (r_viewleaf->contents != CONTENTS_EMPTY && r_viewleaf->contents != CONTENTS_SOLID)
+       {
+               xmax *= (sin(cl.time * 4.7) * 0.03 + 0.97);
+               ymax *= (sin(cl.time * 3) * 0.03 + 0.97);
+       }
 
-   glFrustum( xmin, xmax, ymin, ymax, zNear, zFar );
+       glFrustum(-xmax, xmax, -ymax, ymax, zNear, zFar );
 }
 
 
@@ -714,60 +574,33 @@ void MYgluPerspective( GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble
 R_SetupGL
 =============
 */
-void R_SetupGL (void)
+static void R_SetupGL (void)
 {
-       float   screenaspect;
-       int             x, x2, y2, y, w, h;
-
        if (!r_render.value)
                return;
-       //
+
        // set up viewpoint
-       //
        glMatrixMode(GL_PROJECTION);
-    glLoadIdentity ();
-       x = r_refdef.vrect.x * glwidth/vid.width;
-       x2 = (r_refdef.vrect.x + r_refdef.vrect.width) * glwidth/vid.width;
-       y = (vid.height-r_refdef.vrect.y) * glheight/vid.height;
-       y2 = (vid.height - (r_refdef.vrect.y + r_refdef.vrect.height)) * glheight/vid.height;
-
-       // fudge around because of frac screen scale
-       if (x > 0)
-               x--;
-       if (x2 < glwidth)
-               x2++;
-       if (y2 < 0)
-               y2--;
-       if (y < glheight)
-               y++;
-
-       w = x2 - x;
-       h = y - y2;
-
-       if (envmap)
-       {
-               x = y2 = 0;
-               w = h = 256;
-       }
+       glLoadIdentity ();
 
-       glViewport (glx + x, gly + y2, w, h);
-    screenaspect = (float)r_refdef.vrect.width/r_refdef.vrect.height;
-//     yfov = 2*atan((float)r_refdef.vrect.height/r_refdef.vrect.width)*180/M_PI;
-       MYgluPerspective (r_refdef.fov_y,  screenaspect,  4,  r_farclip.value);
+       // y is weird beause OpenGL is bottom to top, we use top to bottom
+       glViewport(r_refdef.x, vid.realheight - (r_refdef.y + r_refdef.height), r_refdef.width, r_refdef.height);
+//     yfov = 2*atan((float)r_refdef.height/r_refdef.width)*180/M_PI;
+       MYgluPerspective (r_refdef.fov_x, r_refdef.fov_y, r_refdef.width/r_refdef.height, 4, r_farclip.value);
 
        glCullFace(GL_FRONT);
 
        glMatrixMode(GL_MODELVIEW);
-    glLoadIdentity ();
+       glLoadIdentity ();
 
-    glRotatef (-90,  1, 0, 0);     // put Z going up
-    glRotatef (90,  0, 0, 1);      // put Z going up
-    glRotatef (-r_refdef.viewangles[2],  1, 0, 0);
-    glRotatef (-r_refdef.viewangles[0],  0, 1, 0);
-    glRotatef (-r_refdef.viewangles[1],  0, 0, 1);
-    glTranslatef (-r_refdef.vieworg[0],  -r_refdef.vieworg[1],  -r_refdef.vieworg[2]);
+       glRotatef (-90,  1, 0, 0);          // put Z going up
+       glRotatef (90,  0, 0, 1);           // put Z going up
+       glRotatef (-r_refdef.viewangles[2],  1, 0, 0);
+       glRotatef (-r_refdef.viewangles[0],  0, 1, 0);
+       glRotatef (-r_refdef.viewangles[1],  0, 0, 1);
+       glTranslatef (-r_refdef.vieworg[0],  -r_refdef.vieworg[1],  -r_refdef.vieworg[2]);
 
-       glGetFloatv (GL_MODELVIEW_MATRIX, r_world_matrix);
+//     glGetFloatv (GL_MODELVIEW_MATRIX, r_world_matrix);
 
        //
        // set drawing parms
@@ -790,7 +623,7 @@ void R_SetupGL (void)
 R_Clear
 =============
 */
-void R_Clear (void)
+static void R_Clear (void)
 {
        if (!r_render.value)
                return;
@@ -802,35 +635,7 @@ void R_Clear (void)
        glDepthRange (gldepthmin, gldepthmax);
 }
 
-// LordHavoc: my trick to *FIX* GLQuake lighting once and for all :)
-void GL_Brighten(void)
-{
-       if (!r_render.value)
-               return;
-       glMatrixMode(GL_PROJECTION);
-    glLoadIdentity ();
-       glOrtho  (0, vid.width, vid.height, 0, -99999, 99999);
-       glMatrixMode(GL_MODELVIEW);
-    glLoadIdentity ();
-       glDisable (GL_DEPTH_TEST);
-       glDisable (GL_CULL_FACE);
-       glDisable(GL_TEXTURE_2D);
-       glEnable(GL_BLEND);
-       glBlendFunc (GL_DST_COLOR, GL_ONE);
-       glBegin (GL_TRIANGLES);
-       glColor3f (1, 1, 1);
-       glVertex2f (-5000, -5000);
-       glVertex2f (10000, -5000);
-       glVertex2f (-5000, 10000);
-       glEnd ();
-       glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-       glDisable(GL_BLEND);
-       glEnable(GL_TEXTURE_2D);
-       glEnable (GL_DEPTH_TEST);
-       glEnable (GL_CULL_FACE);
-}
-
-void GL_BlendView(void)
+static void GL_BlendView(void)
 {
        if (!r_render.value)
                return;
@@ -840,7 +645,7 @@ void GL_BlendView(void)
 
        glMatrixMode(GL_PROJECTION);
     glLoadIdentity ();
-       glOrtho  (0, vid.width, vid.height, 0, -99999, 99999);
+       glOrtho  (0, 256, 256, 0, -99999, 99999);
        glMatrixMode(GL_MODELVIEW);
     glLoadIdentity ();
        glDisable (GL_DEPTH_TEST);
@@ -871,7 +676,6 @@ R_RenderView
 r_refdef must be set before the first call
 ================
 */
-extern void R_Sky(void);
 extern void UploadLightmaps(void);
 extern void R_DrawSurfaces(void);
 extern void R_DrawPortals(void);
@@ -919,28 +723,28 @@ void timestring(int t, char *desc)
 void R_RenderView (void)
 {
        double starttime, currtime, temptime;
-//     if (r_norefresh.value)
-//             return;
 
        if (!cl.worldmodel)
                Host_Error ("R_RenderView: NULL worldmodel");
 
        if (r_speeds2.value)
        {
-               starttime = currtime = Sys_DoubleTime();
-
                speedstringcount = 0;
                sprintf(r_speeds2_string, "org:'%c%6.2f %c%6.2f %c%6.2f' ang:'%c%3.0f %c%3.0f %c%3.0f' dir:'%c%2.3f %c%2.3f %c%2.3f'\n%6i walls %6i dlitwalls %7i modeltris %7i transpoly\nBSP: %6i faces %6i nodes %6i leafs\n%4i models %4i bmodels %4i sprites %5i particles %3i dlights\n",
                        r_origin[0] < 0 ? '-' : ' ', fabs(r_origin[0]), r_origin[1] < 0 ? '-' : ' ', fabs(r_origin[1]), r_origin[2] < 0 ? '-' : ' ', fabs(r_origin[2]), r_refdef.viewangles[0] < 0 ? '-' : ' ', fabs(r_refdef.viewangles[0]), r_refdef.viewangles[1] < 0 ? '-' : ' ', fabs(r_refdef.viewangles[1]), r_refdef.viewangles[2] < 0 ? '-' : ' ', fabs(r_refdef.viewangles[2]), vpn[0] < 0 ? '-' : ' ', fabs(vpn[0]), vpn[1] < 0 ? '-' : ' ', fabs(vpn[1]), vpn[2] < 0 ? '-' : ' ', fabs(vpn[2]),
                        c_brush_polys, c_light_polys, c_alias_polys, currenttranspoly,
                        c_faces, c_nodes, c_leafs,
                        c_models, c_bmodels, c_sprites, c_particles, c_dlights);
+
+               starttime = currtime = Sys_DoubleTime();
        }
        else
                starttime = currtime = 0;
 
        R_MoveParticles ();
+       TIMEREPORT("mparticles")
        R_MoveExplosions();
+       TIMEREPORT("mexplosion")
 
        FOG_framebegin();
 
@@ -954,8 +758,6 @@ void R_RenderView (void)
        R_SetupGL ();
        R_Clip_StartFrame();
 
-       R_PrepareEntities();
-
        skypolyclear();
        wallpolyclear();
        transpolyclear();
@@ -963,17 +765,21 @@ void R_RenderView (void)
        TIMEREPORT("setup     ")
 
        R_DrawWorld ();
-       TIMEREPORT("world     ")
+       TIMEREPORT("addworld  ")
 
        R_AddModelEntities();
-       TIMEREPORT("addmodels")
+       TIMEREPORT("addmodels ")
 
        R_Clip_EndFrame();
        TIMEREPORT("scanedge  ")
 
        // now mark the lit surfaces
        R_PushDlights ();
-       // yes this does add the world surfaces after the brush models
+       TIMEREPORT("marklights")
+
+       R_DrawModels1 ();
+
+       // yes this does add the world after the brush models when using the SER
        R_DrawSurfaces ();
        R_DrawPortals ();
        TIMEREPORT("surfaces  ");
@@ -981,30 +787,29 @@ void R_RenderView (void)
        UploadLightmaps();
        TIMEREPORT("uploadlmap")
 
-       // fogged sky polys, affects depth
        skypolyrender();
-
-       // does not affect depth, draws over the sky polys
-       if (currentskypoly)
-               R_Sky();
        TIMEREPORT("skypoly   ")
 
-       wallpolyrender();
-       TIMEREPORT("wallpoly  ")
+       wallpolyrender1();
+       TIMEREPORT("wallpoly1 ")
 
        GL_DrawDecals();
        TIMEREPORT("ddecal    ")
 
+       wallpolyrender2();
+       TIMEREPORT("wallpoly2 ")
+
        // don't let sound skip if going slow
        if (!intimerefresh && !r_speeds2.value)
                S_ExtraUpdate ();
 
        R_DrawViewModel ();
-       R_DrawModels ();
+       R_DrawModels2 ();
        TIMEREPORT("models    ")
 
        R_DrawParticles ();
        TIMEREPORT("dparticles")
+
        R_DrawExplosions();
        TIMEREPORT("dexplosion")
 
index 5a8a874..5cf5612 100644 (file)
@@ -8,7 +8,7 @@ of the License, or (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
 See the GNU General Public License for more details.
 
@@ -29,74 +29,104 @@ R_Envmap_f
 Grab six views for environment mapping tests
 ===============
 */
+float CalcFov (float fov_x, float width, float height);
+struct
+{
+       float angles[3];
+       char *name;
+}
+envmapinfo[6] =
+{
+       {{  0,   0, 0}, "ft"},
+       {{  0,  90, 0}, "rt"},
+       {{  0, 180, 0}, "bk"},
+       {{  0, 270, 0}, "lf"},
+       {{-90,  90, 0}, "up"},
+       {{ 90,  90, 0}, "dn"}
+};
 void R_Envmap_f (void)
 {
-       byte    buffer[256*256*4];
+       int             i, size;
+       char    filename[256];
+       char    basename[256];
+       byte    *buffer, gamma[256];
+
+       if (Cmd_Argc() != 3)
+       {
+               Con_Printf ("envmap <basename> <size>: save out 6 cubic environment map images, usable with loadsky, note that size must one of 128, 256, 512, or 1024 and can't be bigger than your current resolution\n");
+               return;
+       }
 
        if (!r_render.value)
                return;
 
-       glDrawBuffer  (GL_FRONT);
-       glReadBuffer  (GL_FRONT);
+       strcpy(basename, Cmd_Argv(1));
+       size = atoi(Cmd_Argv(2));
+       if (size != 128 && size != 256 && size != 512 && size != 1024)
+       {
+               Con_Printf("envmap: size must be one of 128, 256, 512, or 1024\n");
+               return;
+       }
+       if (size > vid.realwidth || size > vid.realheight)
+       {
+               Con_Printf("envmap: your resolution is not big enough to render that size\n");
+               return;
+       }
+
+       buffer = malloc(size*size*3);
+       if (buffer == NULL)
+       {
+               Con_Printf("envmap: unable to allocate memory for image\n");
+               return;
+       }
+
+       BuildGammaTable8((lighthalf && hardwaregammasupported) ? 2.0f : 1.0f, 1, 1, 0, gamma);
+
+//     glDrawBuffer  (GL_FRONT);
+//     glReadBuffer  (GL_FRONT);
+       glDrawBuffer  (GL_BACK);
+       glReadBuffer  (GL_BACK);
        envmap = true;
 
-       r_refdef.vrect.x = 0;
-       r_refdef.vrect.y = 0;
-       r_refdef.vrect.width = 256;
-       r_refdef.vrect.height = 256;
-
-       r_refdef.viewangles[0] = 0;
-       r_refdef.viewangles[1] = 0;
-       r_refdef.viewangles[2] = 0;
-       R_RenderView ();
-       glReadPixels (0, 0, 256, 256, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
-       COM_WriteFile ("env0.rgb", buffer, sizeof(buffer));             
-
-       r_refdef.viewangles[1] = 90;
-       R_RenderView ();
-       glReadPixels (0, 0, 256, 256, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
-       COM_WriteFile ("env1.rgb", buffer, sizeof(buffer));             
-
-       r_refdef.viewangles[1] = 180;
-       R_RenderView ();
-       glReadPixels (0, 0, 256, 256, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
-       COM_WriteFile ("env2.rgb", buffer, sizeof(buffer));             
-
-       r_refdef.viewangles[1] = 270;
-       GL_BeginRendering (&glx, &gly, &glwidth, &glheight);
-       R_RenderView ();
-       glReadPixels (0, 0, 256, 256, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
-       COM_WriteFile ("env3.rgb", buffer, sizeof(buffer));             
-
-       r_refdef.viewangles[0] = -90;
-       r_refdef.viewangles[1] = 0;
-       R_RenderView ();
-       glReadPixels (0, 0, 256, 256, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
-       COM_WriteFile ("env4.rgb", buffer, sizeof(buffer));             
-
-       r_refdef.viewangles[0] = 90;
-       r_refdef.viewangles[1] = 0;
-       R_RenderView ();
-       glReadPixels (0, 0, 256, 256, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
-       COM_WriteFile ("env5.rgb", buffer, sizeof(buffer));             
+       r_refdef.x = 0;
+       r_refdef.y = 0;
+       r_refdef.width = size;
+       r_refdef.height = size;
+
+       r_refdef.fov_x = 90;
+       r_refdef.fov_y = 90;
+
+       for (i = 0;i < 6;i++)
+       {
+               VectorCopy(envmapinfo[i].angles, r_refdef.viewangles);
+               glClearColor(0,0,0,0);
+               glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // LordHavoc: clear the screen (around the view as well)
+               R_RenderView ();
+               glReadPixels (0, 0, size, size, GL_RGB, GL_UNSIGNED_BYTE, buffer);
+               sprintf(filename, "env/%s%s.tga", basename, envmapinfo[i].name);
+               Image_GammaRemapRGB(buffer, buffer, size * size, gamma, gamma, gamma);
+               Image_WriteTGARGB_preflipped(filename, size, size, buffer);
+       }
 
        envmap = false;
        glDrawBuffer  (GL_BACK);
        glReadBuffer  (GL_BACK);
-       GL_EndRendering ();
-}
 
-void R_InitParticles (void);
+       free(buffer);
+
+       // cause refdef to be fixed
+//     vid.recalc_refdef = 1;
+}
 
-void gl_misc_start(void)
+static void gl_misc_start(void)
 {
 }
 
-void gl_misc_shutdown(void)
+static void gl_misc_shutdown(void)
 {
 }
 
-void gl_misc_newmap(void)
+static void gl_misc_newmap(void)
 {
 }
 
@@ -105,15 +135,15 @@ void gl_misc_newmap(void)
 R_Init
 ===============
 */
+static void R_TimeRefresh_f (void);
 void GL_Misc_Init (void)
-{      
-       Cmd_AddCommand ("envmap", R_Envmap_f);  
-       Cmd_AddCommand ("timerefresh", R_TimeRefresh_f);        
+{
+       Cmd_AddCommand ("envmap", R_Envmap_f);
+       Cmd_AddCommand ("timerefresh", R_TimeRefresh_f);
 
        R_RegisterModule("GL_Misc", gl_misc_start, gl_misc_shutdown, gl_misc_newmap);
 }
 
-extern void R_ClearParticles (void);
 extern void GL_BuildLightmaps (void);
 
 /*
@@ -124,7 +154,7 @@ R_NewMap
 void R_NewMap (void)
 {
        int             i;
-       
+
        for (i=0 ; i<256 ; i++)
                d_lightstylevalue[i] = 264;             // normal light value
 
@@ -145,20 +175,22 @@ For program optimization
 ====================
 */
 qboolean intimerefresh = 0;
-void R_TimeRefresh_f (void)
+static void R_TimeRefresh_f (void)
 {
        int                     i;
        float           start, stop, time;
 
        intimerefresh = 1;
        start = Sys_DoubleTime ();
+       glDrawBuffer (GL_FRONT);
        for (i = 0;i < 128;i++)
        {
                r_refdef.viewangles[0] = 0;
                r_refdef.viewangles[1] = i/128.0*360.0;
                r_refdef.viewangles[2] = 0;
-               SCR_UpdateScreen();
+               R_RenderView();
        }
+       glDrawBuffer  (GL_BACK);
 
        stop = Sys_DoubleTime ();
        intimerefresh = 0;
index 3085168..0b9f07f 100644 (file)
@@ -38,8 +38,10 @@ short lightmapupdate[MAX_LIGHTMAPS][2];
 
 signed int blocklights[BLOCK_WIDTH*BLOCK_HEIGHT*3]; // LordHavoc: *3 for colored lighting
 
-int lightmapalign, lightmapalignmask; // LordHavoc: NVIDIA's broken subimage fix, see BuildLightmaps for notes
-cvar_t gl_lightmapalign = {0, "gl_lightmapalign", "4"};
+byte templight[BLOCK_WIDTH*BLOCK_HEIGHT*4];
+
+int lightmapalign, lightmapalignmask; // LordHavoc: align texsubimage updates on 4 byte boundaries
+cvar_t gl_lightmapalign = {0, "gl_lightmapalign", "4"}; // align texsubimage updates on 4 byte boundaries
 cvar_t gl_lightmaprgba = {0, "gl_lightmaprgba", "1"};
 cvar_t gl_nosubimagefragments = {0, "gl_nosubimagefragments", "0"};
 cvar_t gl_nosubimage = {0, "gl_nosubimage", "0"};
@@ -48,8 +50,6 @@ cvar_t gl_vertex = {0, "gl_vertex", "0"};
 cvar_t r_dlightmap = {CVAR_SAVE, "r_dlightmap", "1"};
 cvar_t r_drawportals = {0, "r_drawportals", "0"};
 cvar_t r_testvis = {0, "r_testvis", "0"};
-cvar_t r_solidworldnode = {0, "r_solidworldnode", "3"};
-cvar_t r_pvsworldnode = {0, "r_pvsworldnode", "1"};
 
 qboolean lightmaprgba, nosubimagefragments, nosubimage;
 int lightmapbytes;
@@ -82,8 +82,6 @@ void GL_Surf_Init(void)
        Cvar_RegisterVariable(&r_dlightmap);
        Cvar_RegisterVariable(&r_drawportals);
        Cvar_RegisterVariable(&r_testvis);
-       Cvar_RegisterVariable(&r_solidworldnode);
-       Cvar_RegisterVariable(&r_pvsworldnode);
 
        R_RegisterModule("GL_Surf", gl_surf_start, gl_surf_shutdown, gl_surf_newmap);
 }
@@ -124,7 +122,7 @@ int R_AddDynamicLights (msurface_t *surf)
                if (!(surf->dlightbits[lnum >> 5] & (1 << (lnum & 31))))
                        continue;                                       // not lit by this light
 
-               VectorSubtract (cl_dlights[lnum].origin, currententity->render.origin, local);
+               VectorSubtract (cl_dlights[lnum].origin, currentrenderentity->origin, local);
                dist = DotProduct (local, surf->plane->normal) - surf->plane->dist;
 
                // for comparisons to minimum acceptable light
@@ -232,7 +230,7 @@ R_BuildLightMap
 Combine and scale multiple lightmaps into the 8.8 format in blocklights
 ===============
 */
-void R_BuildLightMap (msurface_t *surf, byte *dest, int stride)
+void R_BuildLightMap (msurface_t *surf, byte *dest, int stride, int dlightchanged)
 {
        int             smax, tmax;
        int             i, j, size, size3;
@@ -241,9 +239,14 @@ void R_BuildLightMap (msurface_t *surf, byte *dest, int stride)
        int             maps;
        int             *bl;
 
+       // update cached lighting info
        surf->cached_dlight = 0;
        surf->cached_lightscalebit = lightscalebit;
        surf->cached_ambient = r_ambient.value;
+       surf->cached_light[0] = d_lightstylevalue[surf->styles[0]];
+       surf->cached_light[1] = d_lightstylevalue[surf->styles[1]];
+       surf->cached_light[2] = d_lightstylevalue[surf->styles[2]];
+       surf->cached_light[3] = d_lightstylevalue[surf->styles[3]];
 
        smax = (surf->extents[0]>>4)+1;
        tmax = (surf->extents[1]>>4)+1;
@@ -252,10 +255,10 @@ void R_BuildLightMap (msurface_t *surf, byte *dest, int stride)
        lightmap = surf->samples;
 
 // set to full bright if no light data
-       if ((currententity && (currententity->render.effects & EF_FULLBRIGHT)) || !cl.worldmodel->lightdata)
+       if ((currentrenderentity->effects & EF_FULLBRIGHT) || !cl.worldmodel->lightdata)
        {
                bl = blocklights;
-               for (i=0 ; i<size ; i++)
+               for (i = 0;i < size;i++)
                {
                        *bl++ = 255*256;
                        *bl++ = 255*256;
@@ -275,28 +278,25 @@ void R_BuildLightMap (msurface_t *surf, byte *dest, int stride)
                else
                        memset(&blocklights[0], 0, size*3*sizeof(int));
 
+               if (r_dlightmap.value && surf->dlightframe == r_framecount)
+               {
+                       if ((surf->cached_dlight = R_AddDynamicLights(surf)))
+                               c_light_polys++;
+                       else if (dlightchanged)
+                               return; // don't upload if only updating dlights and none mattered
+               }
+
 // add all the lightmaps
                if (lightmap)
-               {
                        for (maps = 0;maps < MAXLIGHTMAPS && surf->styles[maps] != 255;maps++)
-                       {
-                               scale = d_lightstylevalue[surf->styles[maps]];
-                               surf->cached_light[maps] = scale;       // 8.8 fraction
-                               bl = blocklights;
-                               for (i = 0;i < size3;i++)
+                               for (scale = d_lightstylevalue[surf->styles[maps]], bl = blocklights, i = 0;i < size3;i++)
                                        *bl++ += *lightmap++ * scale;
-                       }
-               }
-               if (r_dlightmap.value && surf->dlightframe == r_framecount)
-                       if ((surf->cached_dlight = R_AddDynamicLights(surf)))
-                               c_light_polys++;
        }
+
        R_ConvertLightmap(blocklights, dest, smax, tmax, stride);
 }
 
-byte templight[BLOCK_WIDTH*BLOCK_HEIGHT*4];
-
-void R_UpdateLightmap(msurface_t *s, int lnum)
+void R_UpdateLightmap(msurface_t *s, int lnum, int dlightschanged)
 {
        int smax, tmax;
        // upload the new lightmap texture fragment
@@ -309,9 +309,9 @@ void R_UpdateLightmap(msurface_t *s, int lnum)
                if (lightmapupdate[lnum][1] < (s->light_t + ((s->extents[1]>>4)+1)))
                        lightmapupdate[lnum][1] = (s->light_t + ((s->extents[1]>>4)+1));
                if (lightmaprgba)
-                       R_BuildLightMap (s, lightmaps[s->lightmaptexturenum] + (s->light_t * BLOCK_WIDTH + s->light_s) * 4, BLOCK_WIDTH * 4);
+                       R_BuildLightMap (s, lightmaps[s->lightmaptexturenum] + (s->light_t * BLOCK_WIDTH + s->light_s) * 4, BLOCK_WIDTH * 4, false);
                else
-                       R_BuildLightMap (s, lightmaps[s->lightmaptexturenum] + (s->light_t * BLOCK_WIDTH + s->light_s) * 3, BLOCK_WIDTH * 3);
+                       R_BuildLightMap (s, lightmaps[s->lightmaptexturenum] + (s->light_t * BLOCK_WIDTH + s->light_s) * 3, BLOCK_WIDTH * 3, false);
        }
        else
        {
@@ -319,13 +319,13 @@ void R_UpdateLightmap(msurface_t *s, int lnum)
                tmax = (s->extents[1]>>4)+1;
                if (lightmaprgba)
                {
-                       R_BuildLightMap (s, templight, smax * 4);
+                       R_BuildLightMap (s, templight, smax * 4, false);
                        if(r_upload.value)
                                glTexSubImage2D(GL_TEXTURE_2D, 0, s->light_s, s->light_t, smax, tmax, GL_RGBA, GL_UNSIGNED_BYTE, templight);
                }
                else
                {
-                       R_BuildLightMap (s, templight, smax * 3);
+                       R_BuildLightMap (s, templight, smax * 3, false);
                        if(r_upload.value)
                                glTexSubImage2D(GL_TEXTURE_2D, 0, s->light_s, s->light_t, smax, tmax, GL_RGB , GL_UNSIGNED_BYTE, templight);
                }
@@ -342,44 +342,13 @@ Returns the proper texture for a given time and base texture
 */
 texture_t *R_TextureAnimation (texture_t *base)
 {
-//     texture_t *original;
-//     int             relative;
-//     int             count;
+       if (currentrenderentity->frame && base->alternate_anims != NULL)
+               base = base->alternate_anims;
 
-       if (currententity->render.frame)
-       {
-               if (base->alternate_anims)
-                       base = base->alternate_anims;
-       }
-       
-       if (!base->anim_total)
+       if (base->anim_total < 2)
                return base;
 
-       return base->anim_frames[(int)(cl.time*5) % base->anim_total];
-
-       /*
-       original = base;
-
-       relative = (int)(cl.time*5) % base->anim_total;
-
-       count = 0;      
-       while (base->anim_min > relative || base->anim_max <= relative)
-       {
-               base = base->anim_next;
-               if (!base)
-               {
-                       Con_Printf("R_TextureAnimation: broken cycle");
-                       return original;
-               }
-               if (++count > 100)
-               {
-                       Con_Printf("R_TextureAnimation: infinite cycle");
-                       return original;
-               }
-       }
-
-       return base;
-       */
+       return base->anim_frames[(int)(cl.time * 5.0f) % base->anim_total];
 }
 
 
@@ -625,24 +594,26 @@ void RSurf_DrawWall(msurface_t *s, texture_t *t, int transform)
        wallvertcolor_t *outcolor;
        // check for lightmap modification
        if (s->cached_dlight
-        || (r_dynamic.value && r_dlightmap.value && s->dlightframe == r_framecount)
         || r_ambient.value != s->cached_ambient
         || lightscalebit != s->cached_lightscalebit
         || (r_dynamic.value
-        && ((s->styles[0] != 255 && d_lightstylevalue[s->styles[0]] != s->cached_light[0])
-        || (s->styles[1] != 255 && d_lightstylevalue[s->styles[1]] != s->cached_light[1])
-        || (s->styles[2] != 255 && d_lightstylevalue[s->styles[2]] != s->cached_light[2])
-        || (s->styles[3] != 255 && d_lightstylevalue[s->styles[3]] != s->cached_light[3]))))
-               R_UpdateLightmap(s, s->lightmaptexturenum);
+        && (d_lightstylevalue[s->styles[0]] != s->cached_light[0]
+        ||  d_lightstylevalue[s->styles[1]] != s->cached_light[1]
+        ||  d_lightstylevalue[s->styles[2]] != s->cached_light[2]
+        ||  d_lightstylevalue[s->styles[3]] != s->cached_light[3])))
+               R_UpdateLightmap(s, s->lightmaptexturenum, false); // base lighting changed
+       else if (r_dynamic.value && r_dlightmap.value && s->dlightframe == r_framecount)
+               R_UpdateLightmap(s, s->lightmaptexturenum, true); // only dlights
+
        if (s->dlightframe != r_framecount || r_dlightmap.value)
        {
                // LordHavoc: fast path version for no vertex lighting cases
-               wp = &wallpoly[currentwallpoly];
                out = &wallvert[currentwallvert];
                for (p = s->polys;p;p = p->next)
                {
                        if ((currentwallpoly >= MAX_WALLPOLYS) || (currentwallvert+p->numverts > MAX_WALLVERTS))
                                return;
+                       wp = &wallpoly[currentwallpoly++];
                        wp->texnum = (unsigned short) R_GetTexture(t->texture);
                        wp->lighttexnum = (unsigned short) (lightmap_textures + s->lightmaptexturenum);
                        wp->glowtexnum = (unsigned short) R_GetTexture(t->glowtexture);
@@ -650,7 +621,6 @@ void RSurf_DrawWall(msurface_t *s, texture_t *t, int transform)
                        wp->numverts = p->numverts;
                        wp->lit = false;
                        wp++;
-                       currentwallpoly++;
                        currentwallvert += p->numverts;
                        v = p->verts[0];
                        if (transform)
@@ -757,7 +727,7 @@ void RSurf_DrawWallVertex(msurface_t *s, texture_t *t, int transform, int isbmod
        float *v, *wv, scale;
        glpoly_t *p;
        byte *lm;
-       alpha = (int) (modelalpha * 255.0f);
+       alpha = (int) (currentrenderentity->alpha * 255.0f);
        size3 = ((s->extents[0]>>4)+1)*((s->extents[1]>>4)+1)*3; // *3 for colored lighting
        wv = wvert;
        for (p = s->polys;p;p = p->next)
@@ -792,14 +762,14 @@ void RSurf_DrawWallVertex(msurface_t *s, texture_t *t, int transform, int isbmod
        if (s->dlightframe == r_framecount)
                RSurf_Light(s->dlightbits, s->polys);
        wv = wvert;
-       if (isbmodel && (currententity->render.colormod[0] != 1 || currententity->render.colormod[1] != 1 || currententity->render.colormod[2] != 1))
+       if (alpha != 255 || currentrenderentity->colormod[0] != 1 || currentrenderentity->colormod[1] != 1 || currentrenderentity->colormod[2] != 1)
        {
                for (p = s->polys;p;p = p->next)
                {
                        v = p->verts[0];
-                       transpolybegin(R_GetTexture(t->texture), R_GetTexture(t->glowtexture), 0, currententity->render.effects & EF_ADDITIVE ? TPOLYTYPE_ADD : TPOLYTYPE_ALPHA);
+                       transpolybegin(R_GetTexture(t->texture), R_GetTexture(t->glowtexture), 0, currentrenderentity->effects & EF_ADDITIVE ? TPOLYTYPE_ADD : TPOLYTYPE_ALPHA);
                        for (i = 0,v = p->verts[0];i < p->numverts;i++, v += VERTEXSIZE, wv += 6)
-                               transpolyvert(wv[0], wv[1], wv[2], v[3], v[4], wv[3] * currententity->render.colormod[0], wv[4] * currententity->render.colormod[1], wv[5] * currententity->render.colormod[2], alpha);
+                               transpolyvert(wv[0], wv[1], wv[2], v[3], v[4], wv[3] * currentrenderentity->colormod[0], wv[4] * currentrenderentity->colormod[1], wv[5] * currentrenderentity->colormod[2], alpha);
                        transpolyend();
                }
        }
@@ -808,7 +778,7 @@ void RSurf_DrawWallVertex(msurface_t *s, texture_t *t, int transform, int isbmod
                for (p = s->polys;p;p = p->next)
                {
                        v = p->verts[0];
-                       transpolybegin(R_GetTexture(t->texture), R_GetTexture(t->glowtexture), 0, currententity->render.effects & EF_ADDITIVE ? TPOLYTYPE_ADD : TPOLYTYPE_ALPHA);
+                       transpolybegin(R_GetTexture(t->texture), R_GetTexture(t->glowtexture), 0, currentrenderentity->effects & EF_ADDITIVE ? TPOLYTYPE_ADD : TPOLYTYPE_ALPHA);
                        for (i = 0,v = p->verts[0];i < p->numverts;i++, v += VERTEXSIZE, wv += 6)
                                transpolyvert(wv[0], wv[1], wv[2], v[3], v[4], wv[3], wv[4], wv[5], alpha);
                        transpolyend();
@@ -822,6 +792,7 @@ float bmverts[256*3];
 
 int vertexworld;
 
+// LordHavoc: disabled clipping on bmodels because they tend to intersect things sometimes
 /*
 void RBrushModelSurf_DoVisible(msurface_t *surf)
 {
@@ -837,12 +808,14 @@ void RBrushModelSurf_DoVisible(msurface_t *surf)
 }
 */
 
+/*
 void RBrushModelSurf_Callback(void *data, void *data2)
 {
-       entity_t *ent = data2;
        msurface_t *surf = data;
        texture_t *t;
 
+       currentrenderentity = data2;
+*/
        /*
        // FIXME: implement better dupe prevention in AddPolygon callback code
        if (ent->render.model->firstmodelsurface != 0)
@@ -852,14 +825,12 @@ void RBrushModelSurf_Callback(void *data, void *data2)
                        return;
        }
        */
+/*
        surf->visframe = r_framecount;
 
        c_faces++;
 
-       currententity = ent;
-       modelalpha = ent->render.alpha;
-
-       softwaretransformforbrushentity (ent);
+       softwaretransformforbrushentity (currentrenderentity);
 
        if (surf->flags & (SURF_DRAWSKY | SURF_DRAWTURB))
        {
@@ -872,69 +843,52 @@ void RBrushModelSurf_Callback(void *data, void *data2)
        else
        {
                t = R_TextureAnimation(surf->texinfo->texture);
-               if (surf->texinfo->texture->transparent || vertexworld || ent->render.alpha != 1 || ent->render.model->firstmodelsurface == 0 || (ent->render.effects & EF_FULLBRIGHT) || ent->render.colormod[0] != 1 || ent->render.colormod[2] != 1 || ent->render.colormod[2] != 1)
+               if (t->transparent || vertexworld || ent->render.alpha != 1 || ent->render.model->firstmodelsurface == 0 || (ent->render.effects & EF_FULLBRIGHT) || ent->render.colormod[0] != 1 || ent->render.colormod[2] != 1 || ent->render.colormod[2] != 1)
                        RSurf_DrawWallVertex(surf, t, true, true);
                else
                        RSurf_DrawWall(surf, t, true);
        }
 }
+*/
 
 /*
 =================
 R_DrawBrushModel
 =================
 */
-void R_DrawBrushModel (entity_t *e)
+void R_DrawBrushModel (void)
 {
-       int                     i, j, vertexlit;
-       vec3_t          mins, maxs;
+       int                     i/*, j*/, vertexlit, rotated, transform;
        msurface_t      *s;
-       model_t         *clmodel;
-       int                     rotated;
-       vec3_t          org;
-       glpoly_t        *p;
-
-       currententity = e;
-
-       clmodel = e->render.model;
-
-       if (e->render.angles[0] || e->render.angles[1] || e->render.angles[2])
-       {
-               rotated = true;
-               for (i=0 ; i<3 ; i++)
-               {
-                       mins[i] = e->render.origin[i] - clmodel->radius;
-                       maxs[i] = e->render.origin[i] + clmodel->radius;
-               }
-       }
-       else
-       {
-               rotated = false;
-               VectorAdd (e->render.origin, clmodel->mins, mins);
-               VectorAdd (e->render.origin, clmodel->maxs, maxs);
-       }
+       model_t         *model;
+       vec3_t          org, temp, forward, right, up;
+//     glpoly_t        *p;
+       texture_t       *t;
 
-       if (R_CullBox (mins, maxs))
-               return;
+       model = currentrenderentity->model;
 
        c_bmodels++;
 
-       VectorSubtract (r_origin, e->render.origin, modelorg);
-       if (rotated)
+       VectorSubtract (r_origin, currentrenderentity->origin, modelorg);
+       rotated = false;
+       transform = false;
+       if (currentrenderentity->angles[0] || currentrenderentity->angles[1] || currentrenderentity->angles[2])
        {
-               vec3_t  temp;
-               vec3_t  forward, right, up;
-
+               transform = true;
+               rotated = true;
                VectorCopy (modelorg, temp);
-               AngleVectors (e->render.angles, forward, right, up);
+               AngleVectors (currentrenderentity->angles, forward, right, up);
                modelorg[0] = DotProduct (temp, forward);
                modelorg[1] = -DotProduct (temp, right);
                modelorg[2] = DotProduct (temp, up);
        }
+       else if (currentrenderentity->origin[0] || currentrenderentity->origin[1] || currentrenderentity->origin[2] || currentrenderentity->scale)
+               transform = true;
 
-       softwaretransformforbrushentity (e);
+       if (transform)
+               softwaretransformforbrushentity (currentrenderentity);
 
-       for (i = 0, s = &clmodel->surfaces[clmodel->firstmodelsurface];i < clmodel->nummodelsurfaces;i++, s++)
+       for (i = 0, s = &model->surfaces[model->firstmodelsurface];i < model->nummodelsurfaces;i++, s++)
        {
                s->visframe = -1;
                if (((s->flags & SURF_PLANEBACK) == 0) == (PlaneDiff(modelorg, s->plane) >= 0))
@@ -947,45 +901,56 @@ void R_DrawBrushModel (entity_t *e)
                if (!cl_dlights[i].radius)
                        continue;
 
-               VectorSubtract(cl_dlights[i].origin, currententity->render.origin, org);
-               R_NoVisMarkLights (org, &cl_dlights[i], 1<<(i&31), i >> 5, clmodel);
+               if (rotated)
+               {
+                       VectorSubtract(cl_dlights[i].origin, currentrenderentity->origin, temp);
+                       org[0] = DotProduct (temp, forward);
+                       org[1] = -DotProduct (temp, right);
+                       org[2] = DotProduct (temp, up);
+               }
+               else
+                       VectorSubtract(cl_dlights[i].origin, currentrenderentity->origin, org);
+               R_NoVisMarkLights (org, &cl_dlights[i], 1<<(i&31), i >> 5, model);
        }
-       vertexlit = modelalpha != 1 || clmodel->firstmodelsurface == 0 || (currententity->render.effects & EF_FULLBRIGHT) || currententity->render.colormod[0] != 1 || currententity->render.colormod[2] != 1 || currententity->render.colormod[2] != 1;
+       vertexlit = vertexworld || currentrenderentity->alpha != 1 || model->firstmodelsurface == 0 || (currentrenderentity->effects & EF_FULLBRIGHT) || currentrenderentity->colormod[0] != 1 || currentrenderentity->colormod[2] != 1 || currentrenderentity->colormod[2] != 1;
 
        // draw texture
-       for (i = 0, s = &clmodel->surfaces[clmodel->firstmodelsurface];i < clmodel->nummodelsurfaces;i++, s++)
+       for (i = 0, s = &model->surfaces[model->firstmodelsurface];i < model->nummodelsurfaces;i++, s++)
        {
                if (s->visframe == r_framecount)
                {
 //                     R_DrawSurf(s, true, vertexlit || s->texinfo->texture->transparent);
+                       /*
                        if (r_ser.value)
                        {
                                for (p = s->polys;p;p = p->next)
                                {
                                        for (j = 0;j < p->numverts;j++)
                                                softwaretransform(&p->verts[j][0], bmverts + j * 3);
-                                       R_Clip_AddPolygon(bmverts, p->numverts, 3 * sizeof(float), (s->flags & SURF_CLIPSOLID) != 0 && modelalpha == 1, RBrushModelSurf_Callback, s, e, NULL);
+                                       R_Clip_AddPolygon(bmverts, p->numverts, 3 * sizeof(float), (s->flags & SURF_CLIPSOLID) != 0 && currentrenderentity->alpha == 1, RBrushModelSurf_Callback, s, e, NULL);
                                }
                        }
                        else
                        {
+                       */
+                               c_faces++;
+                               t = R_TextureAnimation(s->texinfo->texture);
                                if (s->flags & (SURF_DRAWSKY | SURF_DRAWTURB))
                                {
                                        // sky and liquid don't need sorting (skypoly/transpoly)
                                        if (s->flags & SURF_DRAWSKY)
-                                               RSurf_DrawSky(s, true);
+                                               RSurf_DrawSky(s, transform);
                                        else
-                                               RSurf_DrawWater(s, R_TextureAnimation(s->texinfo->texture), true, s->flags & SURF_DRAWNOALPHA ? 255 : wateralpha);
+                                               RSurf_DrawWater(s, t, transform, s->flags & SURF_DRAWNOALPHA ? 255 : wateralpha);
                                }
                                else
                                {
-                                       texture_t *t = R_TextureAnimation(s->texinfo->texture);
-                                       if (vertexlit || s->texinfo->texture->transparent)
-                                               RSurf_DrawWallVertex(s, t, true, true);
+                                       if (t->transparent || vertexlit)
+                                               RSurf_DrawWallVertex(s, t, transform, true);
                                        else
-                                               RSurf_DrawWall(s, t, true);
+                                               RSurf_DrawWall(s, t, transform);
                                }
-                       }
+                       //}
                }
        }
        UploadLightmaps();
@@ -1138,7 +1103,7 @@ void R_MarkLeaves (void)
 
 void R_SolidWorldNode (void)
 {
-       if ((int) r_solidworldnode.value == 3)
+       if (r_viewleaf->contents != CONTENTS_SOLID)
        {
                int portalstack;
                mportal_t *p, *pstack[8192];
@@ -1146,6 +1111,10 @@ void R_SolidWorldNode (void)
                mleaf_t *leaf;
                glpoly_t *poly;
                tinyplane_t plane;
+               // LordHavoc: portal-passage worldnode; follows portals leading
+               // outward from viewleaf, if a portal leads offscreen it is not
+               // followed, in indoor maps this can often cull a great deal of
+               // geometry away when pvs data is not present (useful with pvs as well)
 
                leaf = r_viewleaf;
                leaf->worldnodeframe = r_framecount;
@@ -1239,18 +1208,22 @@ void R_SolidWorldNode (void)
                if (portalstack)
                        goto loc1;
        }
-       else if ((int) r_solidworldnode.value == 2)
+       else
        {
                mnode_t *nodestack[8192], *node = cl.worldmodel->nodes;
                int nodestackpos = 0;
                glpoly_t *poly;
+               // LordHavoc: recursive descending worldnode; if portals are not
+               // available, this is a good last resort, can cull large amounts of
+               // geometry, but is more time consuming than portal-passage and renders
+               // things behind walls
 
 loc2:
                if (R_NotCulledBox(node->mins, node->maxs))
                {
-                       if (r_ser.value)
+                       if (node->numsurfaces)
                        {
-                               if (node->numsurfaces)
+                               if (r_ser.value)
                                {
                                        msurface_t *surf = cl.worldmodel->surfaces + node->firstsurface, *surfend = surf + node->numsurfaces;
                                        tinyplane_t plane;
@@ -1277,10 +1250,7 @@ loc2:
                                                }
                                        }
                                }
-                       }
-                       else
-                       {
-                               if (node->numsurfaces)
+                               else
                                {
                                        msurface_t *surf = cl.worldmodel->surfaces + node->firstsurface, *surfend = surf + node->numsurfaces;
                                        if (PlaneDiff (r_origin, node->plane) < 0)
@@ -1339,111 +1309,6 @@ loc2:
                        goto loc2;
                }
        }
-       else if ((int) r_solidworldnode.value == 1 && r_ser.value)
-       {
-               glpoly_t *poly;
-               msurface_t *surf, *endsurf;
-               tinyplane_t plane;
-
-               surf = &cl.worldmodel->surfaces[cl.worldmodel->firstmodelsurface];
-               endsurf = surf + cl.worldmodel->nummodelsurfaces;
-               for (;surf < endsurf;surf++)
-               {
-                       if (PlaneDiff(r_origin, surf->plane) < 0)
-                       {
-                               if (surf->flags & SURF_PLANEBACK)
-                               {
-                                       VectorNegate(surf->plane->normal, plane.normal);
-                                       plane.dist = -surf->plane->dist;
-                                       for (poly = surf->polys;poly;poly = poly->next)
-                                               R_Clip_AddPolygon((float *)poly->verts, poly->numverts, VERTEXSIZE * sizeof(float), (surf->flags & SURF_CLIPSOLID) != 0, RSurf_Callback, surf, NULL, &plane);
-                               }
-                       }
-                       else
-                       {
-                               if (!(surf->flags & SURF_PLANEBACK))
-                                       for (poly = surf->polys;poly;poly = poly->next)
-                                               R_Clip_AddPolygon((float *)poly->verts, poly->numverts, VERTEXSIZE * sizeof(float), (surf->flags & SURF_CLIPSOLID) != 0, RSurf_Callback, surf, NULL, (tinyplane_t *)&surf->plane);
-                       }
-               }
-       }
-       else
-       {
-               int l;
-               mleaf_t *leaf;
-               msurface_t *surf, **mark, **endmark;
-               glpoly_t *poly;
-               tinyplane_t plane;
-
-               for (l = 0, leaf = cl.worldmodel->leafs;l < cl.worldmodel->numleafs;l++, leaf++)
-               {
-                       if (R_CullBox(leaf->mins, leaf->maxs))
-                               continue;
-                       leaf->visframe = r_framecount;
-                       c_leafs++;
-                       if (leaf->nummarksurfaces)
-                       {
-//                             if (R_CullBox(leaf->mins, leaf->maxs))
-//                                     continue;
-
-                               if (leaf->nummarksurfaces)
-                               {
-                                       mark = leaf->firstmarksurface;
-                                       endmark = mark + leaf->nummarksurfaces;
-                                       if (r_ser.value)
-                                       {
-                                               do
-                                               {
-                                                       surf = *mark++;
-                                                       // make sure surfaces are only processed once
-                                                       if (surf->worldnodeframe == r_framecount)
-                                                               continue;
-                                                       surf->worldnodeframe = r_framecount;
-                                                       if (PlaneDist(r_origin, surf->plane) < surf->plane->dist)
-                                                       {
-                                                               if (surf->flags & SURF_PLANEBACK)
-                                                               {
-                                                                       VectorNegate(surf->plane->normal, plane.normal);
-                                                                       plane.dist = -surf->plane->dist;
-                                                                       for (poly = surf->polys;poly;poly = poly->next)
-                                                                               R_Clip_AddPolygon((float *)poly->verts, poly->numverts, VERTEXSIZE * sizeof(float), (surf->flags & SURF_CLIPSOLID) != 0, RSurf_Callback, surf, NULL, &plane);
-                                                               }
-                                                       }
-                                                       else
-                                                       {
-                                                               if (!(surf->flags & SURF_PLANEBACK))
-                                                                       for (poly = surf->polys;poly;poly = poly->next)
-                                                                               R_Clip_AddPolygon((float *)poly->verts, poly->numverts, VERTEXSIZE * sizeof(float), (surf->flags & SURF_CLIPSOLID) != 0, RSurf_Callback, surf, NULL, (tinyplane_t *)surf->plane);
-                                                       }
-                                               }
-                                               while (mark < endmark);
-                                       }
-                                       else
-                                       {
-                                               do
-                                               {
-                                                       surf = *mark++;
-                                                       // make sure surfaces are only processed once
-                                                       if (surf->worldnodeframe == r_framecount)
-                                                               continue;
-                                                       surf->worldnodeframe = r_framecount;
-                                                       if (PlaneDist(r_origin, surf->plane) < surf->plane->dist)
-                                                       {
-                                                               if (surf->flags & SURF_PLANEBACK)
-                                                                       surf->visframe = r_framecount;
-                                                       }
-                                                       else
-                                                       {
-                                                               if (!(surf->flags & SURF_PLANEBACK))
-                                                                       surf->visframe = r_framecount;
-                                                       }
-                                               }
-                                               while (mark < endmark);
-                                       }
-                               }
-                       }
-               }
-       }
 }
 
 /*
@@ -1629,220 +1494,111 @@ void R_Portal_Callback(void *data, void *data2)
 
 void R_PVSWorldNode()
 {
-       if (r_pvsworldnode.value == 1)
-       {
-               int portalstack, i;
-               mportal_t *p, *pstack[8192];
-               msurface_t *surf, **mark, **endmark;
-               mleaf_t *leaf;
-               tinyplane_t plane;
-               glpoly_t *poly;
-               byte *worldvis;
+       int portalstack, i;
+       mportal_t *p, *pstack[8192];
+       msurface_t *surf, **mark, **endmark;
+       mleaf_t *leaf;
+       tinyplane_t plane;
+       glpoly_t *poly;
+       byte *worldvis;
 
-               worldvis = Mod_LeafPVS (r_viewleaf, cl.worldmodel);
+       worldvis = Mod_LeafPVS (r_viewleaf, cl.worldmodel);
 
-               leaf = r_viewleaf;
-               leaf->worldnodeframe = r_framecount;
-               portalstack = 0;
-       loc0:
-               c_leafs++;
+       leaf = r_viewleaf;
+       leaf->worldnodeframe = r_framecount;
+       portalstack = 0;
+loc0:
+       c_leafs++;
 
-               leaf->visframe = r_framecount;
+       leaf->visframe = r_framecount;
 
-               if (leaf->nummarksurfaces)
+       if (leaf->nummarksurfaces)
+       {
+               mark = leaf->firstmarksurface;
+               endmark = mark + leaf->nummarksurfaces;
+               if (r_ser.value)
                {
-                       mark = leaf->firstmarksurface;
-                       endmark = mark + leaf->nummarksurfaces;
-                       if (r_ser.value)
+                       do
                        {
-                               do
+                               surf = *mark++;
+                               // make sure surfaces are only processed once
+                               if (surf->worldnodeframe == r_framecount)
+                                       continue;
+                               surf->worldnodeframe = r_framecount;
+                               if (PlaneDist(modelorg, surf->plane) < surf->plane->dist)
                                {
-                                       surf = *mark++;
-                                       // make sure surfaces are only processed once
-                                       if (surf->worldnodeframe == r_framecount)
-                                               continue;
-                                       surf->worldnodeframe = r_framecount;
-                                       if (PlaneDist(modelorg, surf->plane) < surf->plane->dist)
-                                       {
-                                               if (surf->flags & SURF_PLANEBACK)
-                                               {
-                                                       VectorNegate(surf->plane->normal, plane.normal);
-                                                       plane.dist = -surf->plane->dist;
-                                                       for (poly = surf->polys;poly;poly = poly->next)
-                                                               R_Clip_AddPolygon((float *)poly->verts, poly->numverts, VERTEXSIZE * sizeof(float), (surf->flags & SURF_CLIPSOLID) != 0, RSurf_Callback, surf, NULL, &plane);
-                                               }
-                                       }
-                                       else
+                                       if (surf->flags & SURF_PLANEBACK)
                                        {
-                                               if (!(surf->flags & SURF_PLANEBACK))
-                                                       for (poly = surf->polys;poly;poly = poly->next)
-                                                               R_Clip_AddPolygon((float *)poly->verts, poly->numverts, VERTEXSIZE * sizeof(float), (surf->flags & SURF_CLIPSOLID) != 0, RSurf_Callback, surf, NULL, (tinyplane_t *)surf->plane);
+                                               VectorNegate(surf->plane->normal, plane.normal);
+                                               plane.dist = -surf->plane->dist;
+                                               for (poly = surf->polys;poly;poly = poly->next)
+                                                       R_Clip_AddPolygon((float *)poly->verts, poly->numverts, VERTEXSIZE * sizeof(float), (surf->flags & SURF_CLIPSOLID) != 0, RSurf_Callback, surf, NULL, &plane);
                                        }
                                }
-                               while (mark < endmark);
-                       }
-                       else
-                       {
-                               do
+                               else
                                {
-                                       surf = *mark++;
-                                       // make sure surfaces are only processed once
-                                       if (surf->worldnodeframe == r_framecount)
-                                               continue;
-                                       surf->worldnodeframe = r_framecount;
-                                       if (PlaneDist(modelorg, surf->plane) < surf->plane->dist)
-                                       {
-                                               if (surf->flags & SURF_PLANEBACK)
-                                                       surf->visframe = r_framecount;
-                                       }
-                                       else
-                                       {
-                                               if (!(surf->flags & SURF_PLANEBACK))
-                                                       surf->visframe = r_framecount;
-                                       }
+                                       if (!(surf->flags & SURF_PLANEBACK))
+                                               for (poly = surf->polys;poly;poly = poly->next)
+                                                       R_Clip_AddPolygon((float *)poly->verts, poly->numverts, VERTEXSIZE * sizeof(float), (surf->flags & SURF_CLIPSOLID) != 0, RSurf_Callback, surf, NULL, (tinyplane_t *)surf->plane);
                                }
-                               while (mark < endmark);
                        }
+                       while (mark < endmark);
                }
-
-               // follow portals into other leafs
-               p = leaf->portals;
-               for (;p;p = p->next)
+               else
                {
-                       if (DotProduct(r_origin, p->plane.normal) < p->plane.dist)
+                       do
                        {
-                               leaf = p->past;
-                               if (leaf->worldnodeframe != r_framecount)
+                               surf = *mark++;
+                               // make sure surfaces are only processed once
+                               if (surf->worldnodeframe == r_framecount)
+                                       continue;
+                               surf->worldnodeframe = r_framecount;
+                               if (PlaneDist(modelorg, surf->plane) < surf->plane->dist)
                                {
-                                       leaf->worldnodeframe = r_framecount;
-                                       if (leaf->contents != CONTENTS_SOLID)
-                                       {
-                                               i = (leaf - cl.worldmodel->leafs) - 1;
-                                               if (worldvis[i>>3] & (1<<(i&7)))
-                                               {
-                                                       if (R_NotCulledBox(leaf->mins, leaf->maxs))
-                                                       {
-                                                               pstack[portalstack++] = p;
-                                                               goto loc0;
-
-       loc1:
-                                                               p = pstack[--portalstack];
-                                                       }
-                                               }
-                                       }
+                                       if (surf->flags & SURF_PLANEBACK)
+                                               surf->visframe = r_framecount;
+                               }
+                               else
+                               {
+                                       if (!(surf->flags & SURF_PLANEBACK))
+                                               surf->visframe = r_framecount;
                                }
                        }
+                       while (mark < endmark);
                }
-
-               if (portalstack)
-                       goto loc1;
        }
-       else
-       {
-               int i/*, l*/, k, c, row, numbits, bit, leafnum, numleafs;
-               mleaf_t *leaf;
-               msurface_t *surf, **mark, **endmark;
-               model_t *model = cl.worldmodel;
-               byte *in;
-       //      mportal_t *portal;
-               glpoly_t *poly;
-               tinyplane_t plane;
-
-       //      c_leafs++;
-       //      r_viewleaf->visframe = r_framecount;
-               if (!r_testvis.value)
-                       r_portalframecount++;
 
-               numleafs = model->numleafs;
-               numbits = numleafs;
-               k = 0;
-               in = r_viewleaf->compressed_vis;
-               row = (numbits + 7) >> 3;
-               while (k < row)
+       // follow portals into other leafs
+       p = leaf->portals;
+       for (;p;p = p->next)
+       {
+               if (DotProduct(r_origin, p->plane.normal) < p->plane.dist)
                {
-                       c = *in++;
-                       if (c)
+                       leaf = p->past;
+                       if (leaf->worldnodeframe != r_framecount)
                        {
-                               for (i = 0, bit = 1;c;i++, bit <<= 1)
+                               leaf->worldnodeframe = r_framecount;
+                               if (leaf->contents != CONTENTS_SOLID)
                                {
-                                       if (c & bit)
+                                       i = (leaf - cl.worldmodel->leafs) - 1;
+                                       if (worldvis[i>>3] & (1<<(i&7)))
                                        {
-                                               leafnum = (k << 3)+i+1;
-                                               if (leafnum > numleafs)
-                                                       return;
-                                               c -= bit;
-                                               leaf = &model->leafs[leafnum];
                                                if (R_NotCulledBox(leaf->mins, leaf->maxs))
                                                {
-                                                       //for (portal = leaf->portals;portal;portal = portal->next)
-                                                       //      if (DotProduct(r_origin, portal->plane.normal) > portal->plane.dist)
-                                                       //              R_Clip_AddPolygon((float *)portal->points, portal->numpoints, sizeof(mvertex_t), false, R_Portal_Callback, leaf, portal, portal->plane);
-                                                       //leaf->visframe = r_framecount;
-                                                       c_leafs++;
-                                                       if (leaf->nummarksurfaces)
-                                                       {
-                                                               mark = leaf->firstmarksurface;
-                                                               endmark = mark + leaf->nummarksurfaces;
-                                                               if (r_ser.value)
-                                                               {
-                                                                       do
-                                                                       {
-                                                                               surf = *mark++;
-                                                                               // make sure surfaces are only processed once
-                                                                               if (surf->worldnodeframe == r_framecount)
-                                                                                       continue;
-                                                                               surf->worldnodeframe = r_framecount;
-                                                                               if (PlaneDist(r_origin, surf->plane) < surf->plane->dist)
-                                                                               {
-                                                                                       if (surf->flags & SURF_PLANEBACK)
-                                                                                       {
-                                                                                               VectorNegate(surf->plane->normal, plane.normal);
-                                                                                               plane.dist = -surf->plane->dist;
-                                                                                               for (poly = surf->polys;poly;poly = poly->next)
-                                                                                                       R_Clip_AddPolygon((float *)poly->verts, poly->numverts, VERTEXSIZE * sizeof(float), (surf->flags & SURF_CLIPSOLID) != 0, RSurf_Callback, surf, NULL, &plane);
-                                                                                       }
-                                                                               }
-                                                                               else
-                                                                               {
-                                                                                       if (!(surf->flags & SURF_PLANEBACK))
-                                                                                               for (poly = surf->polys;poly;poly = poly->next)
-                                                                                                       R_Clip_AddPolygon((float *)poly->verts, poly->numverts, VERTEXSIZE * sizeof(float), (surf->flags & SURF_CLIPSOLID) != 0, RSurf_Callback, surf, NULL, (tinyplane_t *)surf->plane);
-                                                                               }
-                                                                       }
-                                                                       while (mark < endmark);
-                                                               }
-                                                               else
-                                                               {
-                                                                       do
-                                                                       {
-                                                                               surf = *mark++;
-                                                                               // make sure surfaces are only processed once
-                                                                               if (surf->worldnodeframe == r_framecount)
-                                                                                       continue;
-                                                                               surf->worldnodeframe = r_framecount;
-                                                                               if (PlaneDist(r_origin, surf->plane) < surf->plane->dist)
-                                                                               {
-                                                                                       if (surf->flags & SURF_PLANEBACK)
-                                                                                               surf->visframe = r_framecount;
-                                                                               }
-                                                                               else
-                                                                               {
-                                                                                       if (!(surf->flags & SURF_PLANEBACK))
-                                                                                               surf->visframe = r_framecount;
-                                                                               }
-                                                                       }
-                                                                       while (mark < endmark);
-                                                               }
-                                                       }
+                                                       pstack[portalstack++] = p;
+                                                       goto loc0;
+
+loc1:
+                                                       p = pstack[--portalstack];
                                                }
                                        }
                                }
-                               k++;
                        }
-                       else
-                               k += *in++;
                }
        }
+
+       if (portalstack)
+               goto loc1;
 }
 
 entity_t clworldent;
@@ -1853,8 +1609,7 @@ void R_DrawSurfaces (void)
        texture_t       *t, *currentt;
        int vertex = gl_vertex.value;
 
-       currententity = &clworldent;
-       modelalpha = 1;
+       currentrenderentity = &clworldent.render;
        softwaretransformidentity();
        surf = &cl.worldmodel->surfaces[cl.worldmodel->firstmodelsurface];
        endsurf = surf + cl.worldmodel->nummodelsurfaces;
@@ -1955,6 +1710,19 @@ void R_DrawPortals(void)
        }
 }
 
+void R_SetupWorldEnt(void)
+{
+       memset (&clworldent, 0, sizeof(clworldent));
+       clworldent.render.model = cl.worldmodel;
+       clworldent.render.colormod[0] = clworldent.render.colormod[1] = clworldent.render.colormod[2] = 1;
+       clworldent.render.alpha = 1;
+       clworldent.render.scale = 1;
+
+       VectorCopy (r_origin, modelorg);
+
+       currentrenderentity = &clworldent.render;
+}
+
 /*
 =============
 R_DrawWorld
@@ -1965,28 +1733,14 @@ void R_DrawWorld (void)
        wateralpha = bound(0, r_wateralpha.value*255.0f, 255);
        vertexworld = gl_vertex.value;
 
-       memset (&clworldent, 0, sizeof(clworldent));
-       clworldent.render.model = cl.worldmodel;
-       clworldent.render.colormod[0] = clworldent.render.colormod[1] = clworldent.render.colormod[2] = 1;
-       modelalpha = clworldent.render.alpha = 1;
-       clworldent.render.scale = 1;
-
-       VectorCopy (r_origin, modelorg);
-
-       currententity = &clworldent;
+       R_SetupWorldEnt();
 
        softwaretransformidentity(); // LordHavoc: clear transform
 
-       if (cl.worldmodel)
-       {
-               if (r_novis.value || r_viewleaf->compressed_vis == NULL)
-                       R_SolidWorldNode ();
-               else
-               {
-//                     R_MarkLeaves ();
-                       R_PVSWorldNode ();
-               }
-       }
+       if (r_viewleaf->contents == CONTENTS_SOLID || r_novis.value || r_viewleaf->compressed_vis == NULL)
+               R_SolidWorldNode ();
+       else
+               R_PVSWorldNode ();
 }
 
 /*
@@ -2008,7 +1762,7 @@ int AllocBlock (int w, int h, short *x, short *y)
        {
                best = BLOCK_HEIGHT;
 
-               for (i = 0;i < BLOCK_WIDTH - w;i += lightmapalign) // LordHavoc: NVIDIA has broken subimage, so align the lightmaps
+               for (i = 0;i < BLOCK_WIDTH - w;i += lightmapalign) // LordHavoc: align updates on 4 byte boundaries
                {
                        best2 = 0;
 
@@ -2040,17 +1794,16 @@ int AllocBlock (int w, int h, short *x, short *y)
                // LordHavoc: clear texture to blank image, fragments are uploaded using subimage
                else if (!allocated[texnum][0])
                {
-                       byte blank[BLOCK_WIDTH*BLOCK_HEIGHT*4];
-                       memset(blank, 0, sizeof(blank));
+                       memset(templight, 0, sizeof(templight));
                        if(r_upload.value)
                        {
                                glBindTexture(GL_TEXTURE_2D, lightmap_textures + texnum);
                                glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
                                glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
                                if (lightmaprgba)
-                                       glTexImage2D (GL_TEXTURE_2D, 0, 3, BLOCK_WIDTH, BLOCK_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, blank);
+                                       glTexImage2D (GL_TEXTURE_2D, 0, 3, BLOCK_WIDTH, BLOCK_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, templight);
                                else
-                                       glTexImage2D (GL_TEXTURE_2D, 0, 3, BLOCK_WIDTH, BLOCK_HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, blank);
+                                       glTexImage2D (GL_TEXTURE_2D, 0, 3, BLOCK_WIDTH, BLOCK_HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, templight);
                        }
                }
 
@@ -2195,13 +1948,13 @@ void GL_CreateSurfaceLightmap (msurface_t *surf)
        smax = ((surf->extents[0]>>4)+lightmapalign) & lightmapalignmask;
        if (lightmaprgba)
        {
-               R_BuildLightMap (surf, templight, smax * 4);
+               R_BuildLightMap (surf, templight, smax * 4, false);
                if(r_upload.value)
                        glTexSubImage2D(GL_TEXTURE_2D, 0, surf->light_s, surf->light_t, smax, tmax, GL_RGBA, GL_UNSIGNED_BYTE, templight);
        }
        else
        {
-               R_BuildLightMap (surf, templight, smax * 3);
+               R_BuildLightMap (surf, templight, smax * 3, false);
                if(r_upload.value)
                        glTexSubImage2D(GL_TEXTURE_2D, 0, surf->light_s, surf->light_t, smax, tmax, GL_RGB , GL_UNSIGNED_BYTE, templight);
        }
@@ -2246,18 +1999,24 @@ void GL_BuildLightmaps (void)
                lightmapbytes = 3;
        }
 
-       // LordHavoc: NVIDIA seems to have a broken glTexSubImage2D,
-       //            it needs to be aligned on 4 pixel boundaries...
-       //            so I implemented an adjustable lightmap alignment
-       if (gl_lightmapalign.value < 1)
-               gl_lightmapalign.value = 1;
-       if (gl_lightmapalign.value > 16)
-               gl_lightmapalign.value = 16;
+       // LordHavoc: TexSubImage2D needs data aligned on 4 byte boundaries unless
+       // I specify glPixelStorei(GL_UNPACK_ALIGNMENT, 1), I suspect 4 byte may be
+       // faster anyway, so I implemented an adjustable lightmap alignment...
+
+       // validate the lightmap alignment
+       i = 1;
+       while (i < 16 && i < gl_lightmapalign.value)
+               i <<= 1;
+       Cvar_SetValue("gl_lightmapalign", i);
+
+       // find the lowest pixel count which satisfies the byte alignment
        lightmapalign = 1;
-       while (lightmapalign < gl_lightmapalign.value)
+       j = lightmaprgba ? 4 : 3; // bytes per pixel
+       while ((lightmapalign * j) & (i - 1))
                lightmapalign <<= 1;
-       gl_lightmapalign.value = lightmapalign;
        lightmapalignmask = ~(lightmapalign - 1);
+
+       // alignment is irrelevant if using fallback modes
        if (nosubimagefragments || nosubimage)
        {
                lightmapalign = 1;
@@ -2267,6 +2026,9 @@ void GL_BuildLightmaps (void)
        if (!lightmap_textures)
                lightmap_textures = R_GetTextureSlots(MAX_LIGHTMAPS);
 
+       // need a world entity for lightmap code
+       R_SetupWorldEnt();
+
        for (j=1 ; j<MAX_MODELS ; j++)
        {
                m = cl.model_precache[j];
index 729e292..0cfd6ac 100644 (file)
@@ -70,8 +70,6 @@ console is:
 */
 
 
-int            glx, gly, glwidth, glheight;
-
 float  scr_con_current;
 float  scr_conlines;           // lines of console to display
 
@@ -164,7 +162,7 @@ void SCR_DrawCenterString (void)
        start = scr_centerstring;
 
        if (scr_center_lines <= 4)
-               y = vid.height*0.35;
+               y = vid.conheight*0.35;
        else
                y = 48;
 
@@ -174,7 +172,7 @@ void SCR_DrawCenterString (void)
                for (l=0 ; l<40 ; l++)
                        if (start[l] == '\n' || !start[l])
                                break;
-               x = (vid.width - l*8)/2;
+               x = (vid.conwidth - l*8)/2;
                // LordHavoc: speedup
                if (l > 0)
                {
@@ -229,19 +227,8 @@ CalcFov
 */
 float CalcFov (float fov_x, float width, float height)
 {
-       float   a;
-       float   x;
-
-       if (fov_x < 1 || fov_x > 179)
-               Sys_Error ("Bad fov: %f", fov_x);
-
-       x = width/tan(fov_x/360*M_PI);
-
-       a = atan (height/x);
-
-       a = a*360/M_PI;
-
-       return a;
+       // calculate vision size and alter by aspect, then convert back to angle
+       return atan (height / (width / tan(fov_x/360*M_PI))) * 360 / M_PI;
 }
 
 /*
@@ -254,15 +241,12 @@ Internal use only
 */
 static void SCR_CalcRefdef (void)
 {
-       float           size;
-       int             h;
-       qboolean                full = false;
-
+       float size;
 
-       vid.recalc_refdef = 0;
+//     vid.recalc_refdef = 0;
 
 //========================================
-       
+
 // bound viewsize
        if (scr_viewsize.value < 30)
                Cvar_Set ("viewsize","30");
@@ -278,7 +262,6 @@ static void SCR_CalcRefdef (void)
 // intermission is always full screen
        if (cl.intermission)
        {
-               full = true;
                size = 1;
                sb_lines = 0;
        }
@@ -290,39 +273,31 @@ static void SCR_CalcRefdef (void)
                        sb_lines = 24;          // no inventory
                else
                        sb_lines = 24+16+8;
-
-               if (scr_viewsize.value >= 100.0)
-               {
-                       full = true;
-                       size = 1.0f;
-               }
-               else
-                       size = scr_viewsize.value * (1.0f / 100.0f);
+               size = scr_viewsize.value * (1.0 / 100.0);
        }
 
-       // LordHavoc: always fullscreen rendering
-       h = vid.height/* - sb_lines*/;
-
-       r_refdef.vrect.width = vid.width * size;
-       if (r_refdef.vrect.width < 96)
+       if (size >= 1)
        {
-               size = 96.0 / r_refdef.vrect.width;
-               r_refdef.vrect.width = 96;      // min for icons
+               r_refdef.width = vid.realwidth;
+               r_refdef.height = vid.realheight;
+               r_refdef.x = 0;
+               r_refdef.y = 0;
        }
-
-       r_refdef.vrect.height = vid.height * size;
-       //if (r_refdef.vrect.height > vid.height - sb_lines)
-       //      r_refdef.vrect.height = vid.height - sb_lines;
-       if (r_refdef.vrect.height > (int) vid.height)
-                       r_refdef.vrect.height = vid.height;
-       r_refdef.vrect.x = (vid.width - r_refdef.vrect.width)/2;
-       if (full)
-               r_refdef.vrect.y = 0;
        else
-               r_refdef.vrect.y = (h - r_refdef.vrect.height)/2;
+       {
+               r_refdef.width = vid.realwidth * size;
+               r_refdef.height = vid.realheight * size;
+               r_refdef.x = (vid.realwidth - r_refdef.width)/2;
+               r_refdef.y = (vid.realheight - r_refdef.height)/2;
+       }
 
        r_refdef.fov_x = scr_fov.value;
-       r_refdef.fov_y = CalcFov (r_refdef.fov_x, r_refdef.vrect.width, r_refdef.vrect.height);
+       r_refdef.fov_y = CalcFov (r_refdef.fov_x, r_refdef.width, r_refdef.height);
+
+       r_refdef.width = bound(0, r_refdef.width, vid.realwidth);
+       r_refdef.height = bound(0, r_refdef.height, vid.realheight);
+       r_refdef.x = bound(0, r_refdef.x, vid.realwidth) + vid.realx;
+       r_refdef.y = bound(0, r_refdef.y, vid.realheight) + vid.realy;
 }
 
 
@@ -336,7 +311,7 @@ Keybinding command
 void SCR_SizeUp_f (void)
 {
        Cvar_SetValue ("viewsize",scr_viewsize.value+10);
-       vid.recalc_refdef = 1;
+//     vid.recalc_refdef = 1;
 }
 
 
@@ -350,7 +325,7 @@ Keybinding command
 void SCR_SizeDown_f (void)
 {
        Cvar_SetValue ("viewsize",scr_viewsize.value-10);
-       vid.recalc_refdef = 1;
+//     vid.recalc_refdef = 1;
 }
 
 //============================================================================
@@ -415,13 +390,9 @@ SCR_DrawRam
 */
 void SCR_DrawRam (void)
 {
-       if (!scr_showram.value)
-               return;
-
-       if (!r_cache_thrash)
-               return;
-
-       Draw_Pic (32, 0, scr_ram);
+//     if (!scr_showram.value)
+//             return;
+//     Draw_Pic (32, 0, scr_ram);
 }
 
 /*
@@ -480,8 +451,7 @@ void SCR_DrawPause (void)
                return;
 
        pic = Draw_CachePic ("gfx/pause.lmp");
-       Draw_Pic ( (vid.width - pic->width)/2, 
-               (vid.height - 48 - pic->height)/2, pic);
+       Draw_Pic ((vid.conwidth - pic->width)/2, (vid.conheight - pic->height)/2, pic);
 }
 
 
@@ -500,8 +470,7 @@ void SCR_DrawLoading (void)
                return;
                
        pic = Draw_CachePic ("gfx/loading.lmp");
-       Draw_Pic ( (vid.width - pic->width)/2, 
-               (vid.height - 48 - pic->height)/2, pic);
+       Draw_Pic ((vid.conwidth - pic->width)/2, (vid.conheight - pic->height)/2, pic);
 }
 */
 
@@ -527,14 +496,14 @@ void SCR_SetUpToDrawConsole (void)
 
        if (con_forcedup)
        {
-               scr_conlines = vid.height;              // full screen
+               scr_conlines = vid.conheight;           // full screen
                scr_con_current = scr_conlines;
        }
        else if (key_dest == key_console)
-               scr_conlines = vid.height/2;    // half screen
+               scr_conlines = vid.conheight/2; // half screen
        else
                scr_conlines = 0;                               // none visible
-       
+
        if (scr_conlines < scr_con_current)
        {
                scr_con_current -= scr_conspeed.value*host_realframetime;
@@ -549,7 +518,7 @@ void SCR_SetUpToDrawConsole (void)
                        scr_con_current = scr_conlines;
        }
 }
-       
+
 /*
 ==================
 SCR_DrawConsole
@@ -572,33 +541,33 @@ void SCR_DrawConsole (void)
 
 /*
 ============================================================================== 
+
                                                SCREEN SHOTS 
  
 ============================================================================== 
 */ 
 
 /*
-================== 
+==================
 SCR_ScreenShot_f
-================== 
+==================
 */
-void SCR_ScreenShot_f (void) 
+void SCR_ScreenShot_f (void)
 {
-       byte            *buffer;
-       char            filename[80]; 
+       byte            *buffer, gamma[256];
+       char            filename[80];
        char            checkname[MAX_OSPATH];
        int                     i;
 //
-// find a file name to save it to 
-// 
+// find a file name to save it to
+//
        strcpy(filename,"dp0000.tga");
-               
-       for (i=0 ; i<=9999 ; i++) 
-       { 
-               filename[2] = (i/1000)%10 + '0'; 
-               filename[3] = (i/ 100)%10 + '0'; 
-               filename[4] = (i/  10)%10 + '0'; 
+
+       for (i=0 ; i<=9999 ; i++)
+       {
+               filename[2] = (i/1000)%10 + '0';
+               filename[3] = (i/ 100)%10 + '0';
+               filename[4] = (i/  10)%10 + '0';
                filename[5] = (i/   1)%10 + '0';
                sprintf (checkname, "%s/%s", com_gamedir, filename);
                if (Sys_FileTime(checkname) == -1)
@@ -606,13 +575,18 @@ void SCR_ScreenShot_f (void)
        }
        if (i==10000)
        {
-               Con_Printf ("SCR_ScreenShot_f: Couldn't create a TGA file\n"); 
+               Con_Printf ("SCR_ScreenShot_f: Couldn't create a TGA file\n");
                return;
        }
 
-       buffer = qmalloc(glwidth*glheight*3);
-       glReadPixels (glx, gly, glwidth, glheight, GL_RGB, GL_UNSIGNED_BYTE, buffer);
-       Image_WriteTGARGB_preflipped(filename, glwidth, glheight, buffer);
+       buffer = qmalloc(vid.realwidth*vid.realheight*3);
+       glReadPixels (vid.realx, vid.realy, vid.realwidth, vid.realheight, GL_RGB, GL_UNSIGNED_BYTE, buffer);
+
+       // apply hardware gamma to the image
+       BuildGammaTable8((lighthalf && hardwaregammasupported) ? 2.0f : 1.0f, 1, 1, 0, gamma);
+       Image_GammaRemapRGB(buffer, buffer, vid.realwidth*vid.realheight, gamma, gamma, gamma);
+
+       Image_WriteTGARGB_preflipped(filename, vid.realwidth, vid.realheight, buffer);
 
        qfree(buffer);
        Con_Printf ("Wrote %s\n", filename);
@@ -637,7 +611,7 @@ void SCR_BeginLoadingPlaque (void)
 //             return;
 //     if (cls.signon != SIGNONS)
 //             return;
-       
+
 // redraw with no console and the loading plaque
 //     Con_ClearNotify ();
 //     scr_centertime_off = 0;
@@ -678,7 +652,7 @@ void SCR_DrawNotifyString (void)
 
        start = scr_notifystring;
 
-       y = vid.height*0.35;
+       y = vid.conheight*0.35;
 
        do      
        {
@@ -686,7 +660,7 @@ void SCR_DrawNotifyString (void)
                for (l=0 ; l<40 ; l++)
                        if (start[l] == '\n' || !start[l])
                                break;
-               x = (vid.width - l*8)/2;
+               x = (vid.conwidth - l*8)/2;
                // LordHavoc: speedup
 //             for (j=0 ; j<l ; j++, x+=8)
 //                     Draw_Character (x, y, start[j]);
@@ -810,7 +784,7 @@ void SCR_UpdateScreen (void)
                return;                         // not initialized yet
 
 
-       GL_BeginRendering (&glx, &gly, &glwidth, &glheight);
+       GL_BeginRendering (&vid.realx, &vid.realy, &vid.realwidth, &vid.realheight);
 
        if (gl_combine.value && !gl_combine_extension)
                Cvar_SetValue("gl_combine", false);
@@ -832,16 +806,16 @@ void SCR_UpdateScreen (void)
        if (oldfov != scr_fov.value)
        {
                oldfov = scr_fov.value;
-               vid.recalc_refdef = true;
+//             vid.recalc_refdef = true;
        }
 
        if (oldscreensize != scr_viewsize.value)
        {
                oldscreensize = scr_viewsize.value;
-               vid.recalc_refdef = true;
+//             vid.recalc_refdef = true;
        }
 
-       if (vid.recalc_refdef)
+//     if (vid.recalc_refdef)
                SCR_CalcRefdef();
 
        if (r_render.value)
@@ -895,18 +869,17 @@ void SCR_UpdateScreen (void)
                calc = (int) ((1.0 / (newtime - currtime)) + 0.5);
                sprintf(temp, "%4i fps", calc);
                currtime = newtime;
-               Draw_String(vid.width - (8*8), vid.height - sb_lines - 8, temp, 9999);
+               Draw_String(vid.conwidth - (8*8), vid.conheight - sb_lines - 8, temp, 9999);
        }
 
-       // LordHavoc: only print info if renderer is being used
-       if (r_speeds2.value && !con_forcedup)
+       if (r_speeds2.value && r_speeds2_string[0])
        {
                int i, j, lines, y;
                lines = 1;
                for (i = 0;r_speeds2_string[i];i++)
                        if (r_speeds2_string[i] == '\n')
                                lines++;
-               y = vid.height - sb_lines - lines * 8 - 8;
+               y = vid.conheight - sb_lines - lines * 8 - 8;
                i = j = 0;
                while (r_speeds2_string[i])
                {
@@ -919,6 +892,8 @@ void SCR_UpdateScreen (void)
                                i++;
                        y += 8;
                }
+               // clear so it won't reprint without renderer being called again
+               r_speeds2_string[0] = 0;
        }
 
        V_UpdateBlends();
index d1f65a1..be41491 100644 (file)
--- a/glquake.h
+++ b/glquake.h
@@ -54,58 +54,8 @@ typedef struct
 
 extern glvert_t glv;
 
-extern int glx, gly, glwidth, glheight;
-
-// r_local.h -- private refresh defs
-
-#define ALIAS_BASE_SIZE_RATIO          (1.0 / 11.0)
-                                       // normalizing factor so player model works out to about
-                                       //  1 pixel per triangle
-#define        MAX_LBM_HEIGHT          480
-
-#define BACKFACE_EPSILON       0.01
-
-
-extern void R_TimeRefresh_f (void);
-
 //====================================================
 
-
-extern qboolean        r_cache_thrash;         // compatability
-extern vec3_t          modelorg, r_entorigin;
-extern entity_t        *currententity;
-extern int                     r_framecount;
-extern mplane_t        frustum[4];
-extern int             c_brush_polys, c_alias_polys, c_light_polys, c_faces, c_nodes, c_leafs, c_models, c_bmodels, c_sprites, c_particles, c_dlights;
-
-
-//
-// view origin
-//
-extern vec3_t  vup;
-extern vec3_t  vpn;
-extern vec3_t  vright;
-extern vec3_t  r_origin;
-
-//
-// screen size info
-//
-extern refdef_t        r_refdef;
-extern mleaf_t         *r_viewleaf, *r_oldviewleaf;
-extern unsigned short  d_lightstylevalue[256]; // 8.8 fraction of base light value
-
-extern qboolean        envmap;
-
-extern cvar_t  r_drawentities;
-extern cvar_t  r_drawviewmodel;
-extern cvar_t  r_speeds;
-extern cvar_t  r_fullbright;
-extern cvar_t  r_wateralpha;
-extern cvar_t  r_dynamic;
-extern cvar_t  r_waterripple;
-
-extern float   r_world_matrix[16];
-
 extern const char *gl_vendor;
 extern const char *gl_renderer;
 extern const char *gl_version;
diff --git a/host.c b/host.c
index 4d272b9..38ef523 100644 (file)
--- a/host.c
+++ b/host.c
@@ -778,18 +778,6 @@ Host_Init
 void Host_Init (void)
 {
        int i;
-       /*
-       if (standard_quake)
-               minimum_memory = MINIMUM_MEMORY;
-       else
-               minimum_memory = MINIMUM_MEMORY_LEVELPAK;
-
-       if (COM_CheckParm ("-minmemory"))
-               host_parms.memsize = minimum_memory;
-
-       if (host_parms.memsize < minimum_memory)
-               Sys_Error ("Only %4.1f megs of memory available, can't execute game", host_parms.memsize / (float)0x100000);
-       */
 
        host_parms.memsize = DEFAULTMEM * 1024 * 1024;
 
index 7455032..780abee 100644 (file)
@@ -45,7 +45,7 @@ void Host_Quit_f (void)
        }
        */
        CL_Disconnect ();
-       Host_ShutdownServer(false);             
+       Host_ShutdownServer(false);
 
        Sys_Quit ();
 }
@@ -64,7 +64,7 @@ void Host_Status_f (void)
        int                     hours = 0;
        int                     j;
        void            (*print) (char *fmt, ...);
-       
+
        if (cmd_source == src_command)
        {
                if (!sv.active)
@@ -78,7 +78,7 @@ void Host_Status_f (void)
                print = SV_ClientPrintf;
 
        print ("host:    %s\n", Cvar_VariableString ("hostname"));
-       print ("version: %4.2f (build %i)\n", VERSION, buildnumber);
+       print ("version: %s build %i\n", gamename, buildnumber);
        if (tcpipAvailable)
                print ("tcp/ip:  %s\n", my_tcpip_address);
        if (ipxAvailable)
@@ -715,7 +715,7 @@ void Host_Name_f (void)
        
 void Host_Version_f (void)
 {
-       Con_Printf ("Version %4.2f (build %i)\n", VERSION, buildnumber);
+       Con_Printf ("Version: %s build %i\n", gamename, buildnumber);
        Con_Printf ("Exe: "__TIME__" "__DATE__"\n");
 }
 
@@ -1275,58 +1275,58 @@ void Host_Give_f (void)
 
        t = Cmd_Argv(1);
        v = atoi (Cmd_Argv(2));
-       
+
        switch (t[0])
        {
-   case '0':
-   case '1':
-   case '2':
-   case '3':
-   case '4':
-   case '5':
-   case '6':
-   case '7':
-   case '8':
-   case '9':
-      // MED 01/04/97 added hipnotic give stuff
-      if (hipnotic)
-      {
-         if (t[0] == '6')
-         {
-            if (t[1] == 'a')
-               sv_player->v.items = (int)sv_player->v.items | HIT_PROXIMITY_GUN;
-            else
-               sv_player->v.items = (int)sv_player->v.items | IT_GRENADE_LAUNCHER;
-         }
-         else if (t[0] == '9')
-            sv_player->v.items = (int)sv_player->v.items | HIT_LASER_CANNON;
-         else if (t[0] == '0')
-            sv_player->v.items = (int)sv_player->v.items | HIT_MJOLNIR;
-         else if (t[0] >= '2')
-            sv_player->v.items = (int)sv_player->v.items | (IT_SHOTGUN << (t[0] - '2'));
-      }
-      else
-      {
-         if (t[0] >= '2')
-            sv_player->v.items = (int)sv_player->v.items | (IT_SHOTGUN << (t[0] - '2'));
-      }
+       case '0':
+       case '1':
+       case '2':
+       case '3':
+       case '4':
+       case '5':
+       case '6':
+       case '7':
+       case '8':
+       case '9':
+               // MED 01/04/97 added hipnotic give stuff
+               if (gamemode == GAME_HIPNOTIC)
+               {
+                       if (t[0] == '6')
+                       {
+                               if (t[1] == 'a')
+                               sv_player->v.items = (int)sv_player->v.items | HIT_PROXIMITY_GUN;
+                               else
+                               sv_player->v.items = (int)sv_player->v.items | IT_GRENADE_LAUNCHER;
+                       }
+                       else if (t[0] == '9')
+                               sv_player->v.items = (int)sv_player->v.items | HIT_LASER_CANNON;
+                       else if (t[0] == '0')
+                               sv_player->v.items = (int)sv_player->v.items | HIT_MJOLNIR;
+                       else if (t[0] >= '2')
+                               sv_player->v.items = (int)sv_player->v.items | (IT_SHOTGUN << (t[0] - '2'));
+               }
+               else
+               {
+                       if (t[0] >= '2')
+                               sv_player->v.items = (int)sv_player->v.items | (IT_SHOTGUN << (t[0] - '2'));
+               }
                break;
-       
-    case 's':
-               if (rogue)
+
+       case 's':
+               if (gamemode == GAME_ROGUE)
                {
-                   if ((val = GETEDICTFIELDVALUE(sv_player, eval_ammo_shells1)))
-                           val->_float = v;
+                       if ((val = GETEDICTFIELDVALUE(sv_player, eval_ammo_shells1)))
+                               val->_float = v;
                }
 
-        sv_player->v.ammo_shells = v;
-        break;         
-    case 'n':
-               if (rogue)
+               sv_player->v.ammo_shells = v;
+               break;
+       case 'n':
+               if (gamemode == GAME_ROGUE)
                {
-                   if ((val = GETEDICTFIELDVALUE(sv_player, eval_ammo_nails1)))
+                       if ((val = GETEDICTFIELDVALUE(sv_player, eval_ammo_nails1)))
                        {
-                           val->_float = v;
+                               val->_float = v;
                                if (sv_player->v.weapon <= IT_LIGHTNING)
                                        sv_player->v.ammo_nails = v;
                        }
@@ -1335,9 +1335,9 @@ void Host_Give_f (void)
                {
                        sv_player->v.ammo_nails = v;
                }
-        break;         
-    case 'l':
-               if (rogue)
+               break;
+       case 'l':
+               if (gamemode == GAME_ROGUE)
                {
                        val = GETEDICTFIELDVALUE(sv_player, eval_ammo_lava_nails);
                        if (val)
@@ -1347,9 +1347,9 @@ void Host_Give_f (void)
                                        sv_player->v.ammo_nails = v;
                        }
                }
-        break;
-    case 'r':
-               if (rogue)
+               break;
+       case 'r':
+               if (gamemode == GAME_ROGUE)
                {
                        val = GETEDICTFIELDVALUE(sv_player, eval_ammo_rockets1);
                        if (val)
@@ -1363,9 +1363,9 @@ void Host_Give_f (void)
                {
                        sv_player->v.ammo_rockets = v;
                }
-        break;         
-    case 'm':
-               if (rogue)
+               break;
+       case 'm':
+               if (gamemode == GAME_ROGUE)
                {
                        val = GETEDICTFIELDVALUE(sv_player, eval_ammo_multi_rockets);
                        if (val)
@@ -1375,12 +1375,12 @@ void Host_Give_f (void)
                                        sv_player->v.ammo_rockets = v;
                        }
                }
-        break;         
-    case 'h':
-        sv_player->v.health = v;
-        break;         
-    case 'c':
-               if (rogue)
+               break;
+       case 'h':
+               sv_player->v.health = v;
+               break;
+       case 'c':
+               if (gamemode == GAME_ROGUE)
                {
                        val = GETEDICTFIELDVALUE(sv_player, eval_ammo_cells1);
                        if (val)
@@ -1394,9 +1394,9 @@ void Host_Give_f (void)
                {
                        sv_player->v.ammo_cells = v;
                }
-        break;         
-    case 'p':
-               if (rogue)
+               break;
+       case 'p':
+               if (gamemode == GAME_ROGUE)
                {
                        val = GETEDICTFIELDVALUE(sv_player, eval_ammo_plasma);
                        if (val)
@@ -1406,15 +1406,15 @@ void Host_Give_f (void)
                                        sv_player->v.ammo_cells = v;
                        }
                }
-        break;         
-    }
+               break;
+       }
 }
 
 edict_t        *FindViewthing (void)
 {
        int             i;
        edict_t *e;
-       
+
        for (i=0 ; i<sv.num_edicts ; i++)
        {
                e = EDICT_NUM(i);
@@ -1477,8 +1477,7 @@ void Host_Viewframe_f (void)
 void PrintFrameName (model_t *m, int frame)
 {
        int data;
-       data = (int) Mod_Extradata(m);
-       if (m->ofs_scenes && data)
+       if (m->ofs_scenes && (data = (int) Mod_Extradata(m)))
                Con_Printf("frame %i: %s\n", frame, ((animscene_t *) (m->ofs_scenes + data))[frame].name);
        else
                Con_Printf("frame %i\n", frame);
@@ -1620,7 +1619,7 @@ void Host_InitCommands (void)
 {
        Cmd_AddCommand ("status", Host_Status_f);
        Cmd_AddCommand ("quit", Host_Quit_f);
-       if (nehahra)
+       if (gamemode == GAME_NEHAHRA)
        {
                Cmd_AddCommand ("max", Host_God_f);
                Cmd_AddCommand ("monster", Host_Notarget_f);
diff --git a/image.c b/image.c
index acfdf77..6023e91 100644 (file)
--- a/image.c
+++ b/image.c
@@ -4,6 +4,18 @@
 int            image_width;
 int            image_height;
 
+void Image_GammaRemapRGB(byte *in, byte *out, int pixels, byte *gammar, byte *gammag, byte *gammab)
+{
+       while (pixels--)
+       {
+               out[0] = gammar[in[0]];
+               out[1] = gammag[in[1]];
+               out[2] = gammab[in[2]];
+               in += 3;
+               out += 3;
+       }
+}
+
 // note: pal must be 32bit color
 void Image_Copy8bitRGBA(byte *in, byte *out, int pixels, int *pal)
 {
diff --git a/image.h b/image.h
index 9fc65f0..0a1d73f 100644 (file)
--- a/image.h
+++ b/image.h
@@ -1,4 +1,5 @@
 
+void Image_GammaRemapRGB(byte *in, byte *out, int pixels, byte *gammar, byte *gammag, byte *gammab);
 void Image_Copy8bitRGBA(byte *in, byte *out, int pixels, int *pal);
 void Image_CopyRGBAGamma(byte *in, byte *out, int pixels);
 int image_makemask (byte *in, byte *out, int size);
diff --git a/keys.c b/keys.c
index 9632ed6..6fe4a86 100644 (file)
--- a/keys.c
+++ b/keys.c
@@ -279,8 +279,8 @@ void Key_Console (int key)
        if (key == K_PGUP || key==K_MWHEELUP)
        {
                con_backscroll += 2;
-               if (con_backscroll > con_totallines - (vid.height>>3) - 1)
-                       con_backscroll = con_totallines - (vid.height>>3) - 1;
+               if (con_backscroll > con_totallines - (vid.conheight>>3) - 1)
+                       con_backscroll = con_totallines - (vid.conheight>>3) - 1;
                return;
        }
 
@@ -294,7 +294,7 @@ void Key_Console (int key)
 
        if (key == K_HOME)
        {
-               con_backscroll = con_totallines - (vid.height>>3) - 1;
+               con_backscroll = con_totallines - (vid.conheight>>3) - 1;
                return;
        }
 
index f30f40a..a6f6e42 100644 (file)
--- a/makefile
+++ b/makefile
@@ -9,7 +9,7 @@ SOUNDLIB=-lasound
 #SND=snd_oss.o
 #SOUNDLIB=
 
-OBJECTS= buildnumber.o cd_linux.o chase.o cl_demo.o cl_input.o cl_main.o cl_parse.o cl_tent.o cmd.o common.o console.o crc.o cvar.o fractalnoise.o gl_draw.o gl_poly.o gl_rmain.o gl_rmisc.o gl_rsurf.o gl_screen.o gl_warp.o host.o host_cmd.o image.o keys.o mathlib.o menu.o model_alias.o model_brush.o model_shared.o model_sprite.o net_bsd.o net_udp.o net_dgrm.o net_loop.o net_main.o pr_cmds.o pr_edict.o pr_exec.o r_light.o r_part.o r_explosion.o sbar.o snd_dma.o snd_mem.o snd_mix.o $(SND) sv_main.o sv_move.o sv_phys.o sv_user.o sv_light.o sys_linux.o transform.o view.o wad.o world.o zone.o vid_shared.o palette.o r_crosshairs.o gl_textures.o gl_models.o r_sprites.o r_modules.o r_explosion.o r_lerpanim.o cl_effects.o r_decals.o protocol.o quakeio.o r_clip.o ui.o portals.o sys_shared.o
+OBJECTS= buildnumber.o cd_linux.o chase.o cl_demo.o cl_input.o cl_main.o cl_parse.o cl_tent.o cmd.o common.o console.o crc.o cvar.o fractalnoise.o gl_draw.o gl_poly.o gl_rmain.o gl_rmisc.o gl_rsurf.o gl_screen.o gl_warp.o host.o host_cmd.o image.o keys.o mathlib.o menu.o model_alias.o model_brush.o model_shared.o model_sprite.o net_bsd.o net_udp.o net_dgrm.o net_loop.o net_main.o pr_cmds.o pr_edict.o pr_exec.o r_light.o r_part.o r_explosion.o sbar.o snd_dma.o snd_mem.o snd_mix.o $(SND) sv_main.o sv_move.o sv_phys.o sv_user.o sv_light.o sys_linux.o transform.o&n