]> git.xonotic.org Git - xonotic/darkplaces.git/commitdiff
you can now (try to) play in maps you don't have, and models you don't have are shown...
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Thu, 5 Sep 2002 10:10:47 +0000 (10:10 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Thu, 5 Sep 2002 10:10:47 +0000 (10:10 +0000)
added CL_BoundingBoxForEntity to clean up the various mins/maxs calculations in the engine
no longer spews clc_nops to server past the first signon stage
the clc_nops sent to the server are now sent using unreliable packets (because queuing them up as reliable made no sense and spewed warnings when developer was on)
failed client to server reliable messages now print a hexdump of the message contents when developer is on
there is now Mod_PointContents (this is different than Mod_PointInLeaf because a lot of calls to Mod_PointInLeaf were just wanting the contents, and it's not convenient to check for NULL (no world model) in the caller
r_speeds no longer reports a "walls" count, as it was often nearly identical to faces and simplified the code to remove it
r_speeds faces count may count bmodels twice if some contain sky polygons (this is less technically correct, but more performance correct - it is processing the faces twice)
DrawQ_Pic won't crash if given a NULL picname now (won't draw it either)
r_cullsurfaces cvar added
r_surfacesworldnode cvar added
surface backface culling moved to PrepareSurfaces
simplified a lot of worldnode related stuff
surf->pvsframe and node->pvsframe and leaf->pvsframe simplified worldnode code, and only needs updating when leaf changes (this is partly how quake did things)
leaf->visframe no longer exists, this meant changing/cleaning a lot of code
leaf->dlightbits and leaf->dlightframe no longer exist, this meant doing TraceLine's to see if dlights should shine on models and such (but only if within radius of them)
console is forced if there's nothing else to look at, this is tracked separately from whether the user wants a console (key_consoleactive is now bits, but most code should just check if it is non-zero)
RecursiveHullCheckPoint has been enabled again, only invoked if trace length is exactly 0
SZ_GetSpace overflow warnings/errors have newlines at the end now
R_VisibleCullBox is gone (it relied on leaf->visframe), uses R_CullBox instead
move around some R_NewMap code into more suitable modules
rearranged R_RenderView code a lot, to group things more appropriately
dlights work correctly on bmodels now
PR_Crash function added, to properly shutdown progs interpreter (reset it's stack) and print out a crash report
PR_RunError went away, it has been replaced by Host_Error (which now calls PR_Crash incase it happend during progs execution)
R_ResetQuakeSky and R_ResetSkyBox added, to clean up some sky related hacks in model loading
various QC builtins added for getting info on surfaces from the engine

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

35 files changed:
cl_demo.c
cl_main.c
cl_parse.c
cl_particles.c
cl_screen.c
client.h
collision.c
common.c
common.h
console.c
gl_backend.c
gl_backend.h
gl_rmain.c
gl_rsurf.c
host.c
keys.c
keys.h
makefile
model_brush.c
model_brush.h
model_shared.c
model_shared.h
portals.c
pr_cmds.c
pr_exec.c
pr_execprogram.h
progs.h
r_lerpanim.c
r_light.c
r_sky.c
render.h
sv_move.c
sv_phys.c
view.c
world.c

index c0af97923772c2480c59533da6867907b65911b6..b38a2db5d9f18a70aac5bf01e6c7381b6b2e2464 100644 (file)
--- a/cl_demo.c
+++ b/cl_demo.c
@@ -399,7 +399,7 @@ void CL_TimeDemo_f (void)
 
        // instantly hide console and deactivate it
        key_dest = key_game;
-       key_consoleactive = false;
+       key_consoleactive = 0;
        scr_conlines = 0;
        scr_con_current = 0;
 
index ae47246bc675ad569a5297eea043428532fedcbf..c4d450a94ef6769dd7782e6e542bd51ec5f9b59c 100644 (file)
--- a/cl_main.c
+++ b/cl_main.c
@@ -259,6 +259,37 @@ static void CL_PrintEntities_f (void)
        }
 }
 
+static const vec3_t nomodelmins = {-16, -16, -16};
+static const vec3_t nomodelmaxs = {16, 16, 16};
+void CL_BoundingBoxForEntity(entity_render_t *ent)
+{
+       if (ent->model)
+       {
+               if (ent->angles[0] || ent->angles[2])
+               {
+                       // pitch or roll
+                       VectorAdd(ent->origin, ent->model->rotatedmins, ent->mins);
+                       VectorAdd(ent->origin, ent->model->rotatedmaxs, ent->maxs);
+               }
+               else if (ent->angles[1])
+               {
+                       // yaw
+                       VectorAdd(ent->origin, ent->model->yawmins, ent->mins);
+                       VectorAdd(ent->origin, ent->model->yawmaxs, ent->maxs);
+               }
+               else
+               {
+                       VectorAdd(ent->origin, ent->model->normalmins, ent->mins);
+                       VectorAdd(ent->origin, ent->model->normalmaxs, ent->maxs);
+               }
+       }
+       else
+       {
+               VectorAdd(ent->origin, nomodelmins, ent->mins);
+               VectorAdd(ent->origin, nomodelmaxs, ent->maxs);
+       }
+}
+
 void CL_LerpUpdate(entity_t *e)
 {
        entity_persistent_t *p;
@@ -605,35 +636,20 @@ static void CL_RelinkNetworkEntities()
                                continue;
                }
 
-               if (ent->render.model == NULL)
+               // don't show entities with no modelindex (note: this still shows
+               // entities which have a modelindex that resolved to a NULL model)
+               if (!ent->state_current.modelindex)
                        continue;
                if (effects & EF_NODRAW)
                        continue;
 
-               if (ent->render.angles[0] || ent->render.angles[2])
-               {
-                       // pitch or roll
-                       VectorAdd(ent->render.origin, ent->render.model->rotatedmins, ent->render.mins);
-                       VectorAdd(ent->render.origin, ent->render.model->rotatedmaxs, ent->render.maxs);
-               }
-               else if (ent->render.angles[1])
-               {
-                       // yaw
-                       VectorAdd(ent->render.origin, ent->render.model->yawmins, ent->render.mins);
-                       VectorAdd(ent->render.origin, ent->render.model->yawmaxs, ent->render.maxs);
-               }
-               else
-               {
-                       VectorAdd(ent->render.origin, ent->render.model->normalmins, ent->render.mins);
-                       VectorAdd(ent->render.origin, ent->render.model->normalmaxs, ent->render.maxs);
-               }
+               CL_BoundingBoxForEntity(&ent->render);
+               if (ent->render.model && ent->render.model->name[0] == '*' && ent->render.model->type == mod_brush)
+                       cl_brushmodel_entities[cl_num_brushmodel_entities++] = &ent->render;
 
                if (r_refdef.numentities < r_refdef.maxentities)
                        r_refdef.entities[r_refdef.numentities++] = &ent->render;
 
-               if (ent->render.model->name[0] == '*' && ent->render.model->type == mod_brush)
-                       cl_brushmodel_entities[cl_num_brushmodel_entities++] = &ent->render;
-
                if (cl_num_entities < i + 1)
                        cl_num_entities = i + 1;
        }
@@ -746,23 +762,7 @@ static void CL_RelinkEffects()
                                ent->render.scale = 1;
                                ent->render.alpha = 1;
 
-                               if (ent->render.angles[0] || ent->render.angles[2])
-                               {
-                                       // pitch or roll
-                                       VectorAdd(ent->render.origin, ent->render.model->rotatedmins, ent->render.mins);
-                                       VectorAdd(ent->render.origin, ent->render.model->rotatedmaxs, ent->render.maxs);
-                               }
-                               else if (ent->render.angles[1])
-                               {
-                                       // yaw
-                                       VectorAdd(ent->render.origin, ent->render.model->yawmins, ent->render.mins);
-                                       VectorAdd(ent->render.origin, ent->render.model->yawmaxs, ent->render.maxs);
-                               }
-                               else
-                               {
-                                       VectorAdd(ent->render.origin, ent->render.model->normalmins, ent->render.mins);
-                                       VectorAdd(ent->render.origin, ent->render.model->normalmaxs, ent->render.maxs);
-                               }
+                               CL_BoundingBoxForEntity(&ent->render);
                        }
                }
        }
@@ -773,6 +773,7 @@ void CL_RelinkWorld (void)
        if (cl_num_entities < 1)
                cl_num_entities = 1;
        cl_brushmodel_entities[cl_num_brushmodel_entities++] = &cl_entities[0].render;
+       CL_BoundingBoxForEntity(&cl_entities[0].render);
 }
 
 void CL_RelinkEntities (void)
@@ -834,7 +835,7 @@ int CL_ReadFromServer (void)
        cl_num_entities = 0;
        cl_num_brushmodel_entities = 0;
 
-       if (cls.state == ca_connected && cl.worldmodel)
+       if (cls.state == ca_connected && cls.signon == SIGNONS)
        {
                CL_RelinkEntities ();
 
@@ -876,7 +877,7 @@ void CL_SendCmd (void)
                CL_SendMove (&cmd);
        }
 #ifndef NOROUTINGFIX
-       else
+       else if (cls.signon == 0 && !cls.demoplayback)
        {
                // LordHavoc: fix for NAT routing of netquake:
                // bounce back a clc_nop message to the newly allocated server port,
@@ -884,9 +885,21 @@ void CL_SendCmd (void)
                // the server waits for this before sending anything
                if (realtime > cl.sendnoptime)
                {
-                       Con_DPrintf("sending clc_nop to get server's attention\n");
                        cl.sendnoptime = realtime + 3;
-                       MSG_WriteByte(&cls.message, clc_nop);
+                       Con_DPrintf("sending clc_nop to get server's attention\n");
+                       {
+                               sizebuf_t buf;
+                               qbyte data[128];
+                               buf.maxsize = 128;
+                               buf.cursize = 0;
+                               buf.data = data;
+                               MSG_WriteByte(&buf, clc_nop);
+                               if (NET_SendUnreliableMessage (cls.netcon, &buf) == -1)
+                               {
+                                       Con_Printf ("CL_SendCmd: lost server connection\n");
+                                       CL_Disconnect ();
+                               }
+                       }
                }
        }
 #endif
@@ -904,6 +917,8 @@ void CL_SendCmd (void)
        if (!NET_CanSendMessage (cls.netcon))
        {
                Con_DPrintf ("CL_WriteToServer: can't send\n");
+               if (developer.integer)
+                       SZ_HexDumpToConsole(&cls.message);
                return;
        }
 
index b33a23d79294976accaed6ede7ca3dcd15ad43d9..0bb92223c3b7f8908f1648b5c6a69e3a4af6dabb 100644 (file)
@@ -388,6 +388,9 @@ void CL_ParseServerInfo (void)
 
        Mod_ClearUsed();
 
+       // disable until we get textures for it
+       R_ResetSkyBox();
+
 // precache models
        memset (cl.model_precache, 0, sizeof(cl.model_precache));
        for (nummodels=1 ; ; nummodels++)
@@ -434,11 +437,10 @@ void CL_ParseServerInfo (void)
        {
                // LordHavoc: i == 1 means the first model is the world model
                cl.model_precache[i] = Mod_ForName (model_precache[i], false, false, i == 1);
-
                if (cl.model_precache[i] == NULL)
                {
-                       Host_Error("Model %s not found\n", model_precache[i]);
-                       return;
+                       Con_Printf("Model %s not found\n", model_precache[i]);
+                       //return;
                }
                CL_KeepaliveMessage ();
        }
@@ -458,20 +460,19 @@ void CL_ParseServerInfo (void)
        ent->render.model = cl.worldmodel = cl.model_precache[1];
        ent->render.scale = 1;
        ent->render.alpha = 1;
-       VectorAdd(ent->render.origin, ent->render.model->normalmins, ent->render.mins);
-       VectorAdd(ent->render.origin, ent->render.model->normalmaxs, ent->render.maxs);
+       CL_BoundingBoxForEntity(&ent->render);
        // clear entlife array
        memset(entlife, 0, MAX_EDICTS);
 
        cl_num_entities = 1;
 
        R_NewMap ();
-
        CL_CGVM_Start();
 
+       noclip_anglehack = false;               // noclip is turned off at start
+
        Mem_CheckSentinelsGlobal();
 
-       noclip_anglehack = false;               // noclip is turned off at start
 }
 
 void CL_ValidateState(entity_state_t *s)
@@ -916,23 +917,7 @@ void CL_ParseStatic (int large)
        VectorCopy (ent->state_baseline.origin, ent->render.origin);
        VectorCopy (ent->state_baseline.angles, ent->render.angles);
 
-       if (ent->render.angles[0] || ent->render.angles[2])
-       {
-               // pitch or roll
-               VectorAdd(ent->render.origin, ent->render.model->rotatedmins, ent->render.mins);
-               VectorAdd(ent->render.origin, ent->render.model->rotatedmaxs, ent->render.maxs);
-       }
-       else if (ent->render.angles[1])
-       {
-               // yaw
-               VectorAdd(ent->render.origin, ent->render.model->yawmins, ent->render.mins);
-               VectorAdd(ent->render.origin, ent->render.model->yawmaxs, ent->render.maxs);
-       }
-       else
-       {
-               VectorAdd(ent->render.origin, ent->render.model->normalmins, ent->render.mins);
-               VectorAdd(ent->render.origin, ent->render.model->normalmaxs, ent->render.maxs);
-       }
+       CL_BoundingBoxForEntity(&ent->render);
 
        // This is definitely cheating...
        if (ent->render.model == NULL)
index 9a0655491227626329973afbbce97c8383c9b32d..11ed29f60a8e5a93bd58fee2b113dfc7a1937076 100644 (file)
@@ -351,7 +351,7 @@ void CL_ParticleExplosion (vec3_t org, int smoke)
        if (cl_stainmaps.integer)
                R_Stain(org, 96, 80, 80, 80, 64, 176, 176, 176, 64);
 
-       i = Mod_PointInLeaf(org, cl.worldmodel)->contents;
+       i = Mod_PointContents(org, cl.worldmodel);
        if ((i == CONTENTS_SLIME || i == CONTENTS_WATER) && cl_particles.integer && cl_particles_bubbles.integer)
        {
                for (i = 0;i < 128;i++)
@@ -717,7 +717,7 @@ void CL_RocketTrail (vec3_t start, vec3_t end, int type, entity_t *ent)
        // if we skip out, leave it reset
        ent->persistent.trail_time = 0.0f;
 
-       contents = Mod_PointInLeaf(pos, cl.worldmodel)->contents;
+       contents = Mod_PointContents(pos, cl.worldmodel);
        if (contents == CONTENTS_SKY || contents == CONTENTS_LAVA)
                return;
 
@@ -880,7 +880,7 @@ void CL_MoveParticles (void)
                {
                        f = p->friction * frametime;
                        if (!content)
-                               content = Mod_PointInLeaf(p->org, cl.worldmodel)->contents;
+                               content = Mod_PointContents(p->org, cl.worldmodel);
                        if (content != CONTENTS_EMPTY)
                                f *= 4;
                        f = 1.0f - f;
@@ -893,7 +893,7 @@ void CL_MoveParticles (void)
                        {
                        case pt_blood:
                                if (!content)
-                                       content = Mod_PointInLeaf(p->org, cl.worldmodel)->contents;
+                                       content = Mod_PointContents(p->org, cl.worldmodel);
                                a = content;
                                if (a != CONTENTS_EMPTY)
                                {
@@ -911,7 +911,7 @@ void CL_MoveParticles (void)
                                break;
                        case pt_bubble:
                                if (!content)
-                                       content = Mod_PointInLeaf(p->org, cl.worldmodel)->contents;
+                                       content = Mod_PointContents(p->org, cl.worldmodel);
                                if (content != CONTENTS_WATER && content != CONTENTS_SLIME)
                                {
                                        p->die = -1;
@@ -928,7 +928,7 @@ void CL_MoveParticles (void)
                                        p->vel[2] = /*lhrandom(-32, 32) +*/ p->vel2[2];
                                }
                                if (!content)
-                                       content = Mod_PointInLeaf(p->org, cl.worldmodel)->contents;
+                                       content = Mod_PointContents(p->org, cl.worldmodel);
                                a = content;
                                if (a != CONTENTS_EMPTY && a != CONTENTS_SKY)
                                        p->die = -1;
@@ -1305,17 +1305,9 @@ void R_DrawParticles (void)
 
        minparticledist = DotProduct(r_origin, vpn) + 16.0f;
 
+       // LordHavoc: only render if not too close
        for (i = 0, p = particles;i < cl_numparticles;i++, p++)
-       {
-               // LordHavoc: only render if not too close
-               if (DotProduct(p->org, vpn) < minparticledist)
-                       continue;
-
-               // LordHavoc: check if it's in a visible leaf
-               //if (Mod_PointInLeaf(p->org, cl.worldmodel)->visframe != r_framecount)
-               //      continue;
-
-               R_MeshQueue_AddTransparent(p->org, R_DrawParticleCallback, p, 0);
-       }
+               if (DotProduct(p->org, vpn) >= minparticledist)
+                       R_MeshQueue_AddTransparent(p->org, R_DrawParticleCallback, p, 0);
 }
 
index deceed22740dc192e092866de0b755d0f78fe08d..16166631aeb3cccd59d4404fe5cba5295753c751 100644 (file)
@@ -237,11 +237,15 @@ void SCR_SetUpToDrawConsole (void)
 {
        Con_CheckResize ();
 
-       //if (key_dest == key_game && (!cl.worldmodel || cls.signon != SIGNONS))
-       //      key_dest = key_console;
+       if (key_dest == key_game && cls.signon != SIGNONS)
+               key_consoleactive |= KEY_CONSOLEACTIVE_FORCED;
+       else
+               key_consoleactive &= ~KEY_CONSOLEACTIVE_FORCED;
 
 // decide on the height of the console
-       if (key_consoleactive)
+       if (key_consoleactive & KEY_CONSOLEACTIVE_FORCED)
+               scr_conlines = vid.conheight; // full screen
+       else if (key_consoleactive & KEY_CONSOLEACTIVE_USER)
                scr_conlines = vid.conheight/2; // half screen
        else
                scr_conlines = 0;                               // none visible
@@ -348,7 +352,7 @@ void R_TimeReport(char *desc)
 
 void R_TimeReport_Start(void)
 {
-       r_timereport_active = r_speeds.integer && cl.worldmodel && cls.state == ca_connected;
+       r_timereport_active = r_speeds.integer && cls.signon == SIGNONS && cls.state == ca_connected;
        r_speeds_string[0] = 0;
        if (r_timereport_active)
        {
@@ -356,15 +360,14 @@ void R_TimeReport_Start(void)
                AngleVectors (r_refdef.viewangles, vpn, NULL, NULL);
                sprintf(r_speeds_string,
                        "org:'%+8.2f %+8.2f %+8.2f' ang:'%+4.0f %+4.0f %+4.0f' dir:'%+2.3f %+2.3f %+2.3f'\n"
-                       "world:%6i faces%6i nodes%6i leafs%6i walls%6i dlitwalls\n"
+                       "world:%6i faces%6i nodes%6i leafs%6i dlitwalls\n"
                        "%5i models%5i bmodels%5i sprites%6i particles%4i dlights\n"
                        "%6i modeltris%6i meshs%6i meshtris\n",
                        r_refdef.vieworg[0], r_refdef.vieworg[1], r_refdef.vieworg[2], r_refdef.viewangles[0], r_refdef.viewangles[1], r_refdef.viewangles[2], vpn[0], vpn[1], vpn[2],
-                       c_faces, c_nodes, c_leafs, c_brush_polys, c_light_polys,
+                       c_faces, c_nodes, c_leafs, c_light_polys,
                        c_models, c_bmodels, c_sprites, c_particles, c_dlights,
                        c_alias_polys, c_meshs, c_meshtris);
 
-               c_brush_polys = 0;
                c_alias_polys = 0;
                c_light_polys = 0;
                c_faces = 0;
@@ -478,7 +481,7 @@ void DrawQ_Pic(float x, float y, char *picname, float width, float height, float
 {
        int size;
        drawqueue_t *dq;
-       if (alpha < (1.0f / 255.0f))
+       if (alpha < (1.0f / 255.0f) || !picname || !picname[0])
                return;
        size = sizeof(*dq) + ((strlen(picname) + 1 + 3) & ~3);
        if (r_refdef.drawqueuesize + size > r_refdef.maxdrawqueuesize)
@@ -684,7 +687,7 @@ static void SCR_CalcRefdef (void)
        if (cl.worldmodel)
        {
                Mod_CheckLoaded(cl.worldmodel);
-               contents = Mod_PointInLeaf(r_refdef.vieworg, cl.worldmodel)->contents;
+               contents = Mod_PointContents(r_refdef.vieworg, cl.worldmodel);
                if (contents != CONTENTS_EMPTY && contents != CONTENTS_SOLID)
                {
                        r_refdef.fov_x *= (sin(cl.time * 4.7) * 0.015 + 0.985);
@@ -880,10 +883,9 @@ void SHOWLMP_decodeshow(void)
 void SHOWLMP_drawall(void)
 {
        int i;
-       if (cl.worldmodel)
-               for (i = 0;i < SHOWLMP_MAXLABELS;i++)
-                       if (showlmp[i].isactive)
-                               DrawQ_Pic(showlmp[i].x, showlmp[i].y, showlmp[i].pic, 0, 0, 1, 1, 1, 1, 0);
+       for (i = 0;i < SHOWLMP_MAXLABELS;i++)
+               if (showlmp[i].isactive)
+                       DrawQ_Pic(showlmp[i].x, showlmp[i].y, showlmp[i].pic, 0, 0, 1, 1, 1, 1, 0);
 }
 
 void SHOWLMP_clear(void)
@@ -939,7 +941,7 @@ void CL_UpdateScreen(void)
        else
                cl_avidemo_frame = 0;
 
-       if (cl.worldmodel)
+       if (cls.signon == SIGNONS)
                R_TimeReport("other");
 
        CL_SetupScreenSize();
@@ -949,11 +951,11 @@ void CL_UpdateScreen(void)
        V_UpdateBlends();
        V_CalcRefdef ();
 
-       if (cl.worldmodel)
+       if (cls.signon == SIGNONS)
                R_TimeReport("setup");
 
        //FIXME: force menu if nothing else to look at?
-       //if (key_dest == key_game && !cl.worldmodel && cls.state == ca_disconnected)
+       //if (key_dest == key_game && cls.signon != SIGNONS && cls.state == ca_disconnected)
 
        if (scr_drawloading)
        {
@@ -962,19 +964,19 @@ void CL_UpdateScreen(void)
        }
        else
        {
-               if (cl.worldmodel)
+               if (cls.signon == SIGNONS)
                {
                        SCR_DrawNet ();
                        SCR_DrawTurtle ();
                        SCR_DrawPause ();
                        Sbar_Draw();
+                       SHOWLMP_drawall();
+                       SCR_CheckDrawCenterString();
                }
-               SCR_CheckDrawCenterString();
-               SHOWLMP_drawall();
                ui_draw();
                CL_DrawVideo();
                M_Draw();
-               if (cl.worldmodel)
+               if (cls.signon == SIGNONS)
                {
                        R_TimeReport("2d");
                        R_TimeReport_End();
index 02a6c558f7666b52bbbee9fdcd5190389759073b..cdd525566aef9c984bd353fe5f7257443c58d628 100644 (file)
--- a/client.h
+++ b/client.h
@@ -483,7 +483,7 @@ extern cvar_t r_draweffects;
 extern cvar_t cl_explosions;
 extern cvar_t cl_stainmaps;
 
-// these are updated by
+// these are updated by CL_ClearState
 extern int cl_num_entities;
 extern int cl_num_static_entities;
 extern int cl_num_temp_entities;
@@ -518,6 +518,8 @@ void CL_EstablishConnection (char *host);
 void CL_Disconnect (void);
 void CL_Disconnect_f (void);
 
+void CL_BoundingBoxForEntity(entity_render_t *ent);
+
 //
 // cl_input
 //
index a22c8fb9a988487542ee9053e29b1907499e463f..01904128dcdead51fa278538459cf78dbac82bb6 100644 (file)
@@ -165,7 +165,6 @@ loc0:
        return HULLCHECKSTATE_DONE;
 }
 
-/*
 // used if start and end are the same
 static void RecursiveHullCheckPoint (RecursiveHullCheckTraceInfo_t *t, int num)
 {
@@ -204,7 +203,6 @@ static void RecursiveHullCheckPoint (RecursiveHullCheckTraceInfo_t *t, int num)
                }
        }
 }
-*/
 
 void Collision_RoundUpToHullSize(const model_t *cmodel, const vec3_t inmins, const vec3_t inmaxs, vec3_t outmins, vec3_t outmaxs)
 {
@@ -378,10 +376,10 @@ void Collision_ClipTrace (trace_t *trace, const void *cent, const model_t *cmode
                VectorCopy(endd, rhc.end);
                VectorCopy(rhc.end, rhc.trace->endpos);
                VectorSubtract(rhc.end, rhc.start, rhc.dist);
-               //if (DotProduct(rhc.dist, rhc.dist) > 0.00001)
+               if (rhc.dist[0] || rhc.dist[1] || rhc.dist[2])
                        RecursiveHullCheck (&rhc, rhc.hull->firstclipnode, 0, 1, rhc.start, rhc.end);
-               //else
-               //      RecursiveHullCheckPoint (&rhc, rhc.hull->firstclipnode);
+               else
+                       RecursiveHullCheckPoint (&rhc, rhc.hull->firstclipnode);
 
                // if we hit, unrotate endpos and normal, and store the entity we hit
                if (rhc.trace->fraction != 1)
@@ -420,10 +418,10 @@ void Collision_ClipTrace (trace_t *trace, const void *cent, const model_t *cmode
                VectorSubtract(end, offset, rhc.end);
                VectorCopy(rhc.end, rhc.trace->endpos);
                VectorSubtract(rhc.end, rhc.start, rhc.dist);
-               //if (DotProduct(rhc.dist, rhc.dist) > 0.00001)
+               if (rhc.dist[0] || rhc.dist[1] || rhc.dist[2])
                        RecursiveHullCheck (&rhc, rhc.hull->firstclipnode, 0, 1, rhc.start, rhc.end);
-               //else
-               //      RecursiveHullCheckPoint (&rhc, rhc.hull->firstclipnode);
+               else
+                       RecursiveHullCheckPoint (&rhc, rhc.hull->firstclipnode);
 
                // if we hit, store the entity we hit
                if (rhc.trace->fraction != 1)
index cbe05713b993015aec14d8e25ba2efbae69ebd9f..3dfcf6d51577d324702fcf62083d03de5cf9edee 100644 (file)
--- a/common.c
+++ b/common.c
@@ -434,13 +434,13 @@ void *SZ_GetSpace (sizebuf_t *buf, int length)
        if (buf->cursize + length > buf->maxsize)
        {
                if (!buf->allowoverflow)
-                       Host_Error ("SZ_GetSpace: overflow without allowoverflow set");
+                       Host_Error ("SZ_GetSpace: overflow without allowoverflow set\n");
 
                if (length > buf->maxsize)
-                       Host_Error ("SZ_GetSpace: %i is > full buffer size", length);
+                       Host_Error ("SZ_GetSpace: %i is > full buffer size\n", length);
 
                buf->overflowed = true;
-               Con_Printf ("SZ_GetSpace: overflow");
+               Con_Printf ("SZ_GetSpace: overflow\n");
                SZ_Clear (buf);
        }
 
@@ -458,7 +458,7 @@ void SZ_Write (sizebuf_t *buf, void *data, int length)
 void SZ_Print (sizebuf_t *buf, char *data)
 {
        int             len;
-       
+
        len = strlen(data)+1;
 
 // byte * cast to keep VC++ happy
@@ -468,6 +468,55 @@ void SZ_Print (sizebuf_t *buf, char *data)
                memcpy ((qbyte *)SZ_GetSpace(buf, len-1)-1,data,len); // write over trailing 0
 }
 
+static char *hexchar = "0123456789ABCDEF";
+void SZ_HexDumpToConsole(sizebuf_t *buf)
+{
+       int i;
+       char text[1024];
+       char *cur, *flushpointer;
+       cur = text;
+       flushpointer = text + 512;
+       for (i = 0;i < buf->cursize;i++)
+       {
+               if ((i & 15) == 0)
+               {
+                       *cur++ = hexchar[(i >> 12) & 15];
+                       *cur++ = hexchar[(i >>  8) & 15];
+                       *cur++ = hexchar[(i >>  4) & 15];
+                       *cur++ = hexchar[(i >>  0) & 15];
+                       *cur++ = ':';
+                       *cur++ = ' ';
+               }
+               else if ((i & 15) == 15)
+                       *cur++ = '\n';
+               else
+                       *cur++ = ' ';
+               if (i & 1)
+               {
+                       *cur++ = hexchar[(buf->data[i] >> 4) & 15] | 0x80;
+                       *cur++ = hexchar[(buf->data[i] >> 0) & 15] | 0x80;
+               }
+               else
+               {
+                       *cur++ = hexchar[(buf->data[i] >> 4) & 15];
+                       *cur++ = hexchar[(buf->data[i] >> 0) & 15];
+               }
+               if (cur >= flushpointer)
+               {
+                       *cur++ = 0;
+                       Con_Printf("%s", text);
+                       cur = text;
+               }
+       }
+       if ((i & 15) != 0)
+               *cur++ = '\n';
+       if (cur > text)
+       {
+               *cur++ = 0;
+               Con_Printf("%s", text);
+       }
+}
+
 
 //============================================================================
 
index 3d2275f422a08e7f74b6cec4643516d3dd28d2f7..7ad25529cfc0e9afccb7e44e08511452983f94bf 100644 (file)
--- a/common.h
+++ b/common.h
@@ -44,6 +44,7 @@ void SZ_Clear (sizebuf_t *buf);
 void *SZ_GetSpace (sizebuf_t *buf, int length);
 void SZ_Write (sizebuf_t *buf, void *data, int length);
 void SZ_Print (sizebuf_t *buf, char *data);    // strcats onto the sizebuf
+void SZ_HexDumpToConsole(sizebuf_t *buf);
 
 //============================================================================
 #if !defined(ENDIAN_LITTLE) && !defined(ENDIAN_BIG)
index 6600491196b29dd49a8733f6691d43812643fd25..93840d6d1396216b5ae31de7508ddd039714e8c3 100644 (file)
--- a/console.c
+++ b/console.c
@@ -78,7 +78,8 @@ Con_ToggleConsole_f
 */
 void Con_ToggleConsole_f (void)
 {
-       key_consoleactive = !key_consoleactive;
+       // toggle the 'user wants console' bit
+       key_consoleactive ^= KEY_CONSOLEACTIVE_USER;
        memset (con_times, 0, sizeof(con_times));
 }
 
index 05ebc12bbcdca189ea05cdd3986ea86de3ead593..4b8c0343d05b3044baccf00d8475584be2478338 100644 (file)
@@ -1044,7 +1044,7 @@ void SCR_UpdateScreen (void)
 
        R_TimeReport("clear");
 
-       if (scr_conlines < vid.conheight)
+       if (scr_conlines < vid.conheight && cls.signon == SIGNONS)
                R_RenderView();
 
        // draw 2D stuff
index 3cbb69946905f80d1268af65301092309b64de12..eac1e6d7a6237baf5bfc8965f7e794c351cf68df 100644 (file)
@@ -17,8 +17,7 @@ typedef struct
        int numverts;
        int tex[MAX_TEXTUREUNITS];
        int texrgbscale[MAX_TEXTUREUNITS]; // used only if COMBINE is present
-       // model to world transform matrix
-       matrix4x4_t matrix;
+       matrix4x4_t matrix; // model to world transform matrix
 
        // output
        int *index;
index 82162e540f8adf2387a2008c24866b66c8a4f8bf..b16a2bda9d66f3d0f51518fa74c030e928e3b219 100644 (file)
@@ -26,7 +26,7 @@ int r_framecount;
 
 mplane_t frustum[4];
 
-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;
+int c_alias_polys, c_light_polys, c_faces, c_nodes, c_leafs, c_models, c_bmodels, c_sprites, c_particles, c_dlights;
 
 // true during envmap command capture
 qboolean envmap;
@@ -44,8 +44,6 @@ vec3_t vup;
 //
 refdef_t r_refdef;
 
-mleaf_t *r_viewleaf, *r_oldviewleaf;
-
 // 8.8 fraction of base light value
 unsigned short d_lightstylevalue[256];
 
@@ -125,50 +123,6 @@ static void R_TimeRefresh_f (void)
 
 extern cvar_t r_drawportals;
 
-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)
-                       return false;
-               if (!stack)
-                       return true;
-               node = nodestack[--stack];
-               goto loc0;
-       }
-
-       sides = BOX_ON_PLANE_SIDE(mins, maxs, node->plane);
-
-// recurse down the contacted sides
-       if (sides & 1)
-       {
-               if (sides & 2) // 3
-               {
-                       // put second child on the stack for later examination
-                       nodestack[stack++] = node->children[1];
-                       node = node->children[0];
-                       goto loc0;
-               }
-               else // 1
-               {
-                       node = node->children[0];
-                       goto loc0;
-               }
-       }
-       // 2
-       node = node->children[1];
-       goto loc0;
-}
-
 vec3_t fogcolor;
 vec_t fogdensity;
 float fog_density, fog_red, fog_green, fog_blue;
@@ -248,8 +202,11 @@ void gl_main_shutdown(void)
 {
 }
 
+extern void CL_ParseEntityLump(char *entitystring);
 void gl_main_newmap(void)
 {
+       if (cl.worldmodel && cl.worldmodel->entities)
+               CL_ParseEntityLump(cl.worldmodel->entities);
        r_framecount = 1;
 }
 
@@ -313,20 +270,9 @@ float R_FarClip_Finish(void)
 R_NewMap
 ===============
 */
-void CL_ParseEntityLump(char *entitystring);
 void R_NewMap (void)
 {
-       int i;
-
-       for (i = 0;i < 256;i++)
-               d_lightstylevalue[i] = 264;             // normal light value
-
-       r_viewleaf = NULL;
-       if (cl.worldmodel->entities)
-               CL_ParseEntityLump(cl.worldmodel->entities);
        R_Modules_NewMap();
-
-       r_farclip = 64.0f;
 }
 
 extern void R_Textures_Init(void);
@@ -393,7 +339,8 @@ static void R_MarkEntities (void)
        Matrix4x4_CreateIdentity(&ent->matrix);
        Matrix4x4_CreateIdentity(&ent->inversematrix);
 
-       R_FarClip_Box(cl.worldmodel->normalmins, cl.worldmodel->normalmaxs);
+       if (cl.worldmodel)
+               R_FarClip_Box(cl.worldmodel->normalmins, cl.worldmodel->normalmaxs);
 
        if (!r_drawentities.integer)
                return;
@@ -417,40 +364,23 @@ static void R_MarkEntities (void)
                        VectorAdd(ent->angles, r_refdef.viewangles, ent->angles);
                }
 
-               if (ent->angles[0] || ent->angles[2])
-               {
-                       VectorMA(ent->origin, ent->scale, ent->model->rotatedmins, ent->mins);
-                       VectorMA(ent->origin, ent->scale, ent->model->rotatedmaxs, ent->maxs);
-               }
-               else if (ent->angles[1])
-               {
-                       VectorMA(ent->origin, ent->scale, ent->model->yawmins, ent->mins);
-                       VectorMA(ent->origin, ent->scale, ent->model->yawmaxs, ent->maxs);
-               }
-               else
-               {
-                       VectorMA(ent->origin, ent->scale, ent->model->normalmins, ent->mins);
-                       VectorMA(ent->origin, ent->scale, ent->model->normalmaxs, ent->maxs);
-               }
-               if (R_VisibleCullBox(ent->mins, ent->maxs))
+               if (R_CullBox(ent->mins, ent->maxs))
                        continue;
 
+               ent->visframe = r_framecount;
                VectorCopy(ent->angles, v);
-               if (ent->model->type != mod_brush)
+               if (!ent->model || ent->model->type != mod_brush)
                        v[0] = -v[0];
                Matrix4x4_CreateFromQuakeEntity(&ent->matrix, ent->origin[0], ent->origin[1], ent->origin[2], v[0], v[1], v[2], ent->scale);
                Matrix4x4_Invert_Simple(&ent->inversematrix, &ent->matrix);
                R_LerpAnimation(ent);
-               ent->visframe = r_framecount;
-
-               R_FarClip_Box(ent->mins, ent->maxs);
-
                R_UpdateEntLights(ent);
+               R_FarClip_Box(ent->mins, ent->maxs);
        }
 }
 
 // only used if skyrendermasked, and normally returns false
-int R_DrawBModelSky (void)
+int R_DrawBrushModelsSky (void)
 {
        int i, sky;
        entity_render_t *ent;
@@ -462,7 +392,7 @@ int R_DrawBModelSky (void)
        for (i = 0;i < r_refdef.numentities;i++)
        {
                ent = r_refdef.entities[i];
-               if (ent->visframe == r_framecount && ent->model->DrawSky)
+               if (ent->visframe == r_framecount && ent->model && ent->model->DrawSky)
                {
                        ent->model->DrawSky(ent);
                        sky = true;
@@ -471,6 +401,7 @@ int R_DrawBModelSky (void)
        return sky;
 }
 
+void R_DrawNoModel(entity_render_t *ent);
 void R_DrawModels (void)
 {
        int i;
@@ -482,8 +413,16 @@ void R_DrawModels (void)
        for (i = 0;i < r_refdef.numentities;i++)
        {
                ent = r_refdef.entities[i];
-               if (ent->visframe == r_framecount && ent->model->Draw)
-                       ent->model->Draw(ent);
+               if (ent->visframe == r_framecount)
+               {
+                       if (ent->model)
+                       {
+                               if (ent->model->Draw)
+                                       ent->model->Draw(ent);
+                       }
+                       else
+                               R_DrawNoModel(ent);
+               }
        }
 }
 
@@ -556,10 +495,6 @@ static void R_SetupFrame (void)
 
        AngleVectors (r_refdef.viewangles, vpn, vright, vup);
 
-// current viewleaf
-       r_oldviewleaf = r_viewleaf;
-       r_viewleaf = Mod_PointInLeaf (r_origin, cl.worldmodel);
-
        R_AnimateLight ();
 }
 
@@ -612,75 +547,63 @@ r_refdef must be set before the first call
 */
 void R_RenderView (void)
 {
-       entity_render_t *world = &cl_entities[0].render;
-       if (!cl.worldmodel)
+       entity_render_t *world;
+       if (!r_refdef.entities/* || !cl.worldmodel*/)
                return; //Host_Error ("R_RenderView: NULL worldmodel");
 
+       world = &cl_entities[0].render;
+
        // FIXME: move to client
        R_MoveExplosions();
        R_TimeReport("mexplosion");
 
        R_Textures_Frame();
-
        R_SetupFrame();
        R_SetFrustum();
        R_SetupFog();
        R_SkyStartFrame();
        R_BuildLightList();
-
-       R_FarClip_Start(r_origin, vpn, 768.0f);
-
        R_TimeReport("setup");
 
-       R_DrawWorld(world);
-       R_TimeReport("worldnode");
-
+       R_FarClip_Start(r_origin, vpn, 768.0f);
        R_MarkEntities();
-       R_TimeReport("markentity");
-
-       R_SurfMarkLights(world);
-       R_TimeReport("marklights");
-
        r_farclip = R_FarClip_Finish() + 256.0f;
+       R_TimeReport("markentity");
 
        R_Mesh_Start(r_farclip);
-
        R_MeshQueue_BeginScene();
 
+       if (R_DrawBrushModelsSky())
+               R_TimeReport("bmodelsky");
 
-       if (skyrendermasked)
+       if (world->model)
        {
-               if (R_DrawBModelSky())
-                       R_TimeReport("bmodelsky");
-       }
-       else
-       {
-               R_DrawViewModel();
-               R_TimeReport("viewmodel");
-       }
+               R_DrawWorld(world);
+               R_TimeReport("worldnode");
 
-       R_PrepareSurfaces(world);
-       R_TimeReport("surfprep");
+               R_SurfMarkLights(world);
+               R_TimeReport("marklights");
 
-       R_DrawSurfaces(world, SHADERSTAGE_SKY);
-       R_DrawSurfaces(world, SHADERSTAGE_NORMAL);
-       R_TimeReport("surfdraw");
+               R_PrepareSurfaces(world);
+               R_TimeReport("surfprep");
 
-       if (r_drawportals.integer)
-       {
-               R_DrawPortals(world);
-               R_TimeReport("portals");
+               R_DrawSurfaces(world, SHADERSTAGE_SKY);
+               R_DrawSurfaces(world, SHADERSTAGE_NORMAL);
+               R_TimeReport("surfdraw");
+
+               if (r_drawportals.integer)
+               {
+                       R_DrawPortals(world);
+                       R_TimeReport("portals");
+               }
        }
 
        // don't let sound skip if going slow
        if (!intimerefresh && !r_speeds.integer)
                S_ExtraUpdate ();
 
-       if (skyrendermasked)
-       {
-               R_DrawViewModel();
-               R_TimeReport("viewmodel");
-       }
+       R_DrawViewModel();
+       R_TimeReport("viewmodel");
 
        R_DrawModels();
        R_TimeReport("models");
@@ -704,10 +627,129 @@ void R_RenderView (void)
        R_TimeReport("blendview");
 
        R_MeshQueue_Render();
-
        R_MeshQueue_EndScene();
-
        R_Mesh_Finish();
        R_TimeReport("meshfinish");
 }
 
+void R_DrawBBoxMesh(vec3_t mins, vec3_t maxs, float cr, float cg, float cb, float ca)
+{
+       int i;
+       float *v, *c, f1, f2, diff[3];
+       rmeshbufferinfo_t m;
+       m.numtriangles = 12;
+       m.numverts = 8;
+       m.blendfunc1 = GL_SRC_ALPHA;
+       m.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
+       Matrix4x4_CreateIdentity(&m.matrix);
+       if (R_Mesh_Draw_GetBuffer(&m, false))
+       {
+               m.vertex[ 0] = mins[0];m.vertex[ 1] = mins[1];m.vertex[ 2] = mins[2];
+               m.vertex[ 4] = maxs[0];m.vertex[ 5] = mins[1];m.vertex[ 6] = mins[2];
+               m.vertex[ 8] = mins[0];m.vertex[ 9] = maxs[1];m.vertex[10] = mins[2];
+               m.vertex[12] = maxs[0];m.vertex[13] = maxs[1];m.vertex[14] = mins[2];
+               m.vertex[16] = mins[0];m.vertex[17] = mins[1];m.vertex[18] = maxs[2];
+               m.vertex[20] = maxs[0];m.vertex[21] = mins[1];m.vertex[22] = maxs[2];
+               m.vertex[24] = mins[0];m.vertex[25] = maxs[1];m.vertex[26] = maxs[2];
+               m.vertex[28] = maxs[0];m.vertex[29] = maxs[1];m.vertex[30] = maxs[2];
+               m.color[ 0] = m.color[ 4] = m.color[ 8] = m.color[12] = m.color[16] = m.color[20] = m.color[24] = m.color[28] = cr * m.colorscale;
+               m.color[ 1] = m.color[ 5] = m.color[ 9] = m.color[13] = m.color[17] = m.color[21] = m.color[25] = m.color[29] = cg * m.colorscale;
+               m.color[ 2] = m.color[ 6] = m.color[10] = m.color[14] = m.color[18] = m.color[22] = m.color[26] = m.color[30] = cb * m.colorscale;
+               m.color[ 3] = m.color[ 7] = m.color[11] = m.color[15] = m.color[19] = m.color[23] = m.color[27] = m.color[31] = ca;
+               if (fogenabled)
+               {
+                       for (i = 0, v = m.vertex, c = m.color;i < m.numverts;i++, v += 4, c += 4)
+                       {
+                               VectorSubtract(v, r_origin, diff);
+                               f2 = exp(fogdensity/DotProduct(diff, diff));
+                               f1 = 1 - f2;
+                               f2 *= m.colorscale;
+                               c[0] = c[0] * f1 + fogcolor[0] * f2;
+                               c[1] = c[1] * f1 + fogcolor[1] * f2;
+                               c[2] = c[2] * f1 + fogcolor[2] * f2;
+                       }
+               }
+               R_Mesh_Render();
+       }
+}
+
+void R_DrawNoModelCallback(const void *calldata1, int calldata2)
+{
+       const entity_render_t *ent = calldata1;
+       int i;
+       float f1, f2, *c, diff[3];
+       rmeshbufferinfo_t m;
+       memset(&m, 0, sizeof(m));
+       if (ent->flags & EF_ADDITIVE)
+       {
+               m.blendfunc1 = GL_SRC_ALPHA;
+               m.blendfunc2 = GL_ONE;
+       }
+       else if (ent->alpha < 1)
+       {
+               m.blendfunc1 = GL_SRC_ALPHA;
+               m.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
+       }
+       else
+       {
+               m.blendfunc1 = GL_ONE;
+               m.blendfunc2 = GL_ZERO;
+       }
+       m.numtriangles = 8;
+       m.numverts = 6;
+       m.matrix = ent->matrix;
+       if (R_Mesh_Draw_GetBuffer(&m, false))
+       {
+               m.index[ 0] = 5;m.index[ 1] = 2;m.index[ 2] = 0;
+               m.index[ 3] = 5;m.index[ 4] = 1;m.index[ 5] = 2;
+               m.index[ 6] = 5;m.index[ 7] = 0;m.index[ 8] = 3;
+               m.index[ 9] = 5;m.index[10] = 3;m.index[11] = 1;
+               m.index[12] = 0;m.index[13] = 2;m.index[14] = 4;
+               m.index[15] = 2;m.index[16] = 1;m.index[17] = 4;
+               m.index[18] = 3;m.index[19] = 0;m.index[20] = 4;
+               m.index[21] = 1;m.index[22] = 3;m.index[23] = 4;
+               m.vertex[ 0] = -16;m.vertex[ 1] =   0;m.vertex[ 2] =   0;
+               m.vertex[ 4] =  16;m.vertex[ 5] =   0;m.vertex[ 6] =   0;
+               m.vertex[ 8] =   0;m.vertex[ 9] = -16;m.vertex[10] =   0;
+               m.vertex[12] =   0;m.vertex[13] =  16;m.vertex[14] =   0;
+               m.vertex[16] =   0;m.vertex[17] =   0;m.vertex[18] = -16;
+               m.vertex[20] =   0;m.vertex[21] =   0;m.vertex[22] =  16;
+               m.color[ 0] = 0.00f;m.color[ 1] = 0.00f;m.color[ 2] = 0.50f;m.color[ 3] = ent->alpha;
+               m.color[ 4] = 0.00f;m.color[ 5] = 0.00f;m.color[ 6] = 0.50f;m.color[ 7] = ent->alpha;
+               m.color[ 8] = 0.00f;m.color[ 9] = 0.50f;m.color[10] = 0.00f;m.color[11] = ent->alpha;
+               m.color[12] = 0.00f;m.color[13] = 0.50f;m.color[14] = 0.00f;m.color[15] = ent->alpha;
+               m.color[16] = 0.50f;m.color[17] = 0.00f;m.color[18] = 0.00f;m.color[19] = ent->alpha;
+               m.color[20] = 0.50f;m.color[21] = 0.00f;m.color[22] = 0.00f;m.color[23] = ent->alpha;
+               if (fogenabled)
+               {
+                       VectorSubtract(ent->origin, r_origin, diff);
+                       f2 = exp(fogdensity/DotProduct(diff, diff));
+                       f1 = 1 - f2;
+                       for (i = 0, c = m.color;i < m.numverts;i++, c += 4)
+                       {
+                               c[0] = (c[0] * f1 + fogcolor[0] * f2) * m.colorscale;
+                               c[1] = (c[1] * f1 + fogcolor[1] * f2) * m.colorscale;
+                               c[2] = (c[2] * f1 + fogcolor[2] * f2) * m.colorscale;
+                       }
+               }
+               else
+               {
+                       for (i = 0, c = m.color;i < m.numverts;i++, c += 4)
+                       {
+                               c[0] *= m.colorscale;
+                               c[1] *= m.colorscale;
+                               c[2] *= m.colorscale;
+                       }
+               }
+               R_Mesh_Render();
+       }
+}
+
+void R_DrawNoModel(entity_render_t *ent)
+{
+       //if ((ent->effects & EF_ADDITIVE) || (ent->alpha < 1))
+               R_MeshQueue_AddTransparent(ent->origin, R_DrawNoModelCallback, ent, 0);
+       //else
+       //      R_DrawNoModelCallback(ent, 0);
+}
+
index 86502d13469676c2c0604a7077f607cbb778c582..35701067e92e21f0d423918ce887552cdcbc565c 100644 (file)
@@ -35,10 +35,17 @@ cvar_t r_drawportals = {0, "r_drawportals", "0"};
 cvar_t r_testvis = {0, "r_testvis", "0"};
 cvar_t r_floatbuildlightmap = {0, "r_floatbuildlightmap", "0"};
 cvar_t r_detailtextures = {CVAR_SAVE, "r_detailtextures", "1"};
+cvar_t r_surfaceworldnode = {0, "r_surfaceworldnode", "0"};
+cvar_t r_cullsurface = {0, "r_cullsurface", "0"};
 
 static int dlightdivtable[32768];
 
-static int R_IntAddDynamicLights (msurface_t *surf)
+// variables used by R_PVSUpdate
+int r_pvsframecount = 0;
+mleaf_t *r_viewleaf = NULL;
+int r_viewleafnovis = 0;
+
+static int R_IntAddDynamicLights (const matrix4x4_t *matrix, msurface_t *surf)
 {
        int sdtable[256], lnum, td, maxdist, maxdist2, maxdist3, i, s, t, smax, tmax, smax3, red, green, blue, lit, dist2, impacts, impactt, subtract;
        unsigned int *bl;
@@ -62,7 +69,7 @@ static int R_IntAddDynamicLights (msurface_t *surf)
                if (!(surf->dlightbits[lnum >> 5] & (1 << (lnum & 31))))
                        continue;                                       // not lit by this light
 
-               softwareuntransform(r_dlight[lnum].origin, local);
+               Matrix4x4_Transform(matrix, r_dlight[lnum].origin, local);
                dist = DotProduct (local, surf->plane->normal) - surf->plane->dist;
 
                // for comparisons to minimum acceptable light
@@ -139,7 +146,7 @@ static int R_IntAddDynamicLights (msurface_t *surf)
        return lit;
 }
 
-static int R_FloatAddDynamicLights (msurface_t *surf)
+static int R_FloatAddDynamicLights (const matrix4x4_t *matrix, msurface_t *surf)
 {
        int lnum, s, t, smax, tmax, smax3, lit, impacts, impactt;
        float sdtable[256], *bl, k, dist, dist2, maxdist, maxdist2, maxdist3, td1, td, red, green, blue, impact[3], local[3], subtract;
@@ -155,7 +162,7 @@ static int R_FloatAddDynamicLights (msurface_t *surf)
                if (!(surf->dlightbits[lnum >> 5] & (1 << (lnum & 31))))
                        continue;                                       // not lit by this light
 
-               softwareuntransform(r_dlight[lnum].origin, local);
+               Matrix4x4_Transform(matrix, r_dlight[lnum].origin, local);
                dist = DotProduct (local, surf->plane->normal) - surf->plane->dist;
 
                // for comparisons to minimum acceptable light
@@ -280,7 +287,7 @@ static void R_BuildLightMap (const entity_render_t *ent, msurface_t *surf, int d
 
                        if (surf->dlightframe == r_framecount && r_dlightmap.integer)
                        {
-                               surf->cached_dlight = R_IntAddDynamicLights(surf);
+                               surf->cached_dlight = R_IntAddDynamicLights(&ent->inversematrix, surf);
                                if (surf->cached_dlight)
                                        c_light_polys++;
                                else if (dlightchanged)
@@ -371,7 +378,7 @@ static void R_BuildLightMap (const entity_render_t *ent, msurface_t *surf, int d
 
                if (surf->dlightframe == r_framecount && r_dlightmap.integer)
                {
-                       surf->cached_dlight = R_FloatAddDynamicLights(surf);
+                       surf->cached_dlight = R_FloatAddDynamicLights(&ent->inversematrix, surf);
                        if (surf->cached_dlight)
                                c_light_polys++;
                        else if (dlightchanged)
@@ -587,7 +594,8 @@ void R_Stain (vec3_t origin, float radius, int cr1, int cg1, int cb1, int ca1, i
        icolor[7] = ca2;
 
        model = cl.worldmodel;
-       R_StainNode(model->nodes + model->hulls[0].firstclipnode, model, origin, radius, icolor);
+       if (model)
+               R_StainNode(model->nodes + model->hulls[0].firstclipnode, model, origin, radius, icolor);
 
        // look for embedded bmodels
        for (n = 0;n < cl_num_brushmodel_entities;n++)
@@ -795,7 +803,7 @@ static int RSurf_LightSeparate(const matrix4x4_t *matrix, const int *dlightbits,
 
 // note: this untransforms lights to do the checking,
 // and takes surf->mesh->vertex data
-static int RSurf_LightCheck(const int *dlightbits, surfmesh_t *mesh)
+static int RSurf_LightCheck(const matrix4x4_t *matrix, const int *dlightbits, surfmesh_t *mesh)
 {
        int i, l;
        rdlight_t *rd;
@@ -806,7 +814,7 @@ static int RSurf_LightCheck(const int *dlightbits, surfmesh_t *mesh)
                if (dlightbits[l >> 5] & (1 << (l & 31)))
                {
                        rd = &r_dlight[l];
-                       softwareuntransform(rd->origin, lightorigin);
+                       Matrix4x4_Transform(matrix, rd->origin, lightorigin);
                        for (i = 0, sv = mesh->vertex;i < mesh->numverts;i++, sv++)
                                if (VectorDistance2(sv->v, lightorigin) < rd->cullradius2)
                                        return true;
@@ -1230,7 +1238,7 @@ static void RSurfShader_OpaqueWall_Pass_Light(const entity_render_t *ent, const
        m.matrix = ent->matrix;
        for (mesh = surf->mesh;mesh;mesh = mesh->chain)
        {
-               if (RSurf_LightCheck(surf->dlightbits, mesh))
+               if (RSurf_LightCheck(&ent->inversematrix, surf->dlightbits, mesh))
                {
                        m.numtriangles = mesh->numtriangles;
                        m.numverts = mesh->numverts;
@@ -1342,7 +1350,6 @@ static void RSurfShader_Wall_Fullbright(const entity_render_t *ent, const msurfa
        {
                for (surf = firstsurf;surf;surf = surf->chain)
                {
-                       c_brush_polys++;
                        Matrix4x4_Transform(&ent->matrix, surf->poly_center, center);
                        R_MeshQueue_AddTransparent(center, RSurfShader_Wall_Fullbright_Callback, ent, surf - ent->model->surfaces);
                }
@@ -1351,7 +1358,6 @@ static void RSurfShader_Wall_Fullbright(const entity_render_t *ent, const msurfa
        {
                for (surf = firstsurf;surf;surf = surf->chain)
                {
-                       c_brush_polys++;
                        if (surf->currenttexture->fogtexture != NULL)
                        {
                                Matrix4x4_Transform(&ent->matrix, surf->poly_center, center);
@@ -1390,7 +1396,6 @@ static void RSurfShader_Wall_Vertex(const entity_render_t *ent, const msurface_t
        {
                for (surf = firstsurf;surf;surf = surf->chain)
                {
-                       c_brush_polys++;
                        Matrix4x4_Transform(&ent->matrix, surf->poly_center, center);
                        R_MeshQueue_AddTransparent(center, RSurfShader_Wall_Vertex_Callback, ent, surf - ent->model->surfaces);
                }
@@ -1399,7 +1404,6 @@ static void RSurfShader_Wall_Vertex(const entity_render_t *ent, const msurface_t
        {
                for (surf = firstsurf;surf;surf = surf->chain)
                {
-                       c_brush_polys++;
                        if (surf->currenttexture->fogtexture != NULL)
                        {
                                Matrix4x4_Transform(&ent->matrix, surf->poly_center, center);
@@ -1427,7 +1431,6 @@ static void RSurfShader_Wall_Lightmap(const entity_render_t *ent, const msurface
        {
                for (surf = firstsurf;surf;surf = surf->chain)
                {
-                       c_brush_polys++;
                        Matrix4x4_Transform(&ent->matrix, surf->poly_center, center);
                        R_MeshQueue_AddTransparent(center, RSurfShader_Wall_Vertex_Callback, ent, surf - ent->model->surfaces);
                }
@@ -1436,7 +1439,6 @@ static void RSurfShader_Wall_Lightmap(const entity_render_t *ent, const msurface
        {
                for (surf = firstsurf;surf;surf = surf->chain)
                {
-                       c_brush_polys++;
                        if (surf->currenttexture->fogtexture != NULL)
                        {
                                Matrix4x4_Transform(&ent->matrix, surf->poly_center, center);
@@ -1462,7 +1464,6 @@ static void RSurfShader_Wall_Lightmap(const entity_render_t *ent, const msurface
                        {
                                for (surf = firstsurf;surf;surf = surf->chain)
                                {
-                                       c_brush_polys++;
                                        if (surf->currenttexture->fogtexture != NULL)
                                        {
                                                Matrix4x4_Transform(&ent->matrix, surf->poly_center, center);
@@ -1476,7 +1477,6 @@ static void RSurfShader_Wall_Lightmap(const entity_render_t *ent, const msurface
                        {
                                for (surf = firstsurf;surf;surf = surf->chain)
                                {
-                                       c_brush_polys++;
                                        if (surf->currenttexture->fogtexture != NULL)
                                        {
                                                Matrix4x4_Transform(&ent->matrix, surf->poly_center, center);
@@ -1495,7 +1495,6 @@ static void RSurfShader_Wall_Lightmap(const entity_render_t *ent, const msurface
                {
                        for (surf = firstsurf;surf;surf = surf->chain)
                        {
-                               c_brush_polys++;
                                if (surf->currenttexture->fogtexture != NULL)
                                {
                                        Matrix4x4_Transform(&ent->matrix, surf->poly_center, center);
@@ -1528,236 +1527,6 @@ static void RSurfShader_Wall_Lightmap(const entity_render_t *ent, const msurface
        }
 }
 
-/*
-=============================================================
-
-       WORLD MODEL
-
-=============================================================
-*/
-
-static void R_SolidWorldNode (entity_render_t *ent)
-{
-       if (r_viewleaf->contents != CONTENTS_SOLID)
-       {
-               int portalstack;
-               mportal_t *p, *pstack[8192];
-               msurface_t *surf, **mark, **endmark;
-               mleaf_t *leaf;
-               // 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;
-               portalstack = 0;
-       loc0:
-               c_leafs++;
-
-               leaf->visframe = r_framecount;
-
-               if (leaf->nummarksurfaces)
-               {
-                       mark = leaf->firstmarksurface;
-                       endmark = mark + leaf->nummarksurfaces;
-                       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);
-               }
-
-               // follow portals into other leafs
-               p = leaf->portals;
-               for (;p;p = p->next)
-               {
-                       if (DotProduct(r_origin, p->plane.normal) < p->plane.dist)
-                       {
-                               leaf = p->past;
-                               if (leaf->worldnodeframe != r_framecount)
-                               {
-                                       leaf->worldnodeframe = r_framecount;
-                                       if (leaf->contents != CONTENTS_SOLID)
-                                       {
-                                               if (R_NotCulledBox(leaf->mins, leaf->maxs))
-                                               {
-                                                       p->visframe = r_framecount;
-                                                       pstack[portalstack++] = p;
-                                                       goto loc0;
-
-       loc1:
-                                                       p = pstack[--portalstack];
-                                               }
-                                       }
-                               }
-                       }
-               }
-
-               if (portalstack)
-                       goto loc1;
-       }
-       else
-       {
-               mnode_t *nodestack[8192], *node = cl.worldmodel->nodes;
-               int nodestackpos = 0;
-               // 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 (node->numsurfaces)
-                       {
-                               msurface_t *surf = cl.worldmodel->surfaces + node->firstsurface, *surfend = surf + node->numsurfaces;
-                               if (PlaneDiff (r_origin, node->plane) < 0)
-                               {
-                                       for (;surf < surfend;surf++)
-                                       {
-                                               if (surf->flags & SURF_PLANEBACK)
-                                                       surf->visframe = r_framecount;
-                                       }
-                               }
-                               else
-                               {
-                                       for (;surf < surfend;surf++)
-                                       {
-                                               if (!(surf->flags & SURF_PLANEBACK))
-                                                       surf->visframe = r_framecount;
-                                       }
-                               }
-                       }
-
-                       // recurse down the children
-                       if (node->children[0]->contents >= 0)
-                       {
-                               if (node->children[1]->contents >= 0)
-                               {
-                                       if (nodestackpos < 8192)
-                                               nodestack[nodestackpos++] = node->children[1];
-                                       node = node->children[0];
-                                       goto loc2;
-                               }
-                               else
-                                       ((mleaf_t *)node->children[1])->visframe = r_framecount;
-                               node = node->children[0];
-                               goto loc2;
-                       }
-                       else
-                       {
-                               ((mleaf_t *)node->children[0])->visframe = r_framecount;
-                               if (node->children[1]->contents >= 0)
-                               {
-                                       node = node->children[1];
-                                       goto loc2;
-                               }
-                               else if (nodestackpos > 0)
-                               {
-                                       ((mleaf_t *)node->children[1])->visframe = r_framecount;
-                                       node = nodestack[--nodestackpos];
-                                       goto loc2;
-                               }
-                       }
-               }
-               else if (nodestackpos > 0)
-               {
-                       node = nodestack[--nodestackpos];
-                       goto loc2;
-               }
-       }
-}
-
-static void R_PVSWorldNode()
-{
-       int portalstack, i;
-       mportal_t *p, *pstack[8192];
-       msurface_t *surf, **mark, **endmark;
-       mleaf_t *leaf;
-       qbyte *worldvis;
-
-       worldvis = Mod_LeafPVS (r_viewleaf, cl.worldmodel);
-
-       leaf = r_viewleaf;
-       leaf->worldnodeframe = r_framecount;
-       portalstack = 0;
-loc0:
-       c_leafs++;
-
-       leaf->visframe = r_framecount;
-
-       if (leaf->nummarksurfaces)
-       {
-               mark = leaf->firstmarksurface;
-               endmark = mark + leaf->nummarksurfaces;
-               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);
-       }
-
-       // follow portals into other leafs
-       for (p = leaf->portals;p;p = p->next)
-       {
-               if (DotProduct(r_origin, p->plane.normal) < p->plane.dist)
-               {
-                       leaf = p->past;
-                       if (leaf->worldnodeframe != r_framecount)
-                       {
-                               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 (portalstack)
-               goto loc1;
-}
-
 Cshader_t Cshader_wall_vertex = {{NULL, RSurfShader_Wall_Vertex}, NULL};
 Cshader_t Cshader_wall_lightmap = {{NULL, RSurfShader_Wall_Lightmap}, NULL};
 Cshader_t Cshader_wall_fullbright = {{NULL, RSurfShader_Wall_Fullbright}, NULL};
@@ -1780,6 +1549,7 @@ void R_PrepareSurfaces(entity_render_t *ent)
        texture_t *t;
        model_t *model;
        msurface_t *surf;
+       vec3_t modelorg;
 
        for (i = 0;i < Cshader_count;i++)
                Cshaders[i]->chain = NULL;
@@ -1788,14 +1558,25 @@ void R_PrepareSurfaces(entity_render_t *ent)
        alttextures = ent->frame != 0;
        texframe = (int)(cl.time * 5.0f);
 
+       Matrix4x4_Transform(&ent->inversematrix, r_origin, modelorg);
        for (i = 0;i < model->nummodelsurfaces;i++)
        {
                surf = model->modelsortedsurfaces[i];
                if (surf->visframe == r_framecount)
                {
-                       if (surf->insertframe != r_framecount)
+                       // mark any backface surfaces as not visible
+                       if (PlaneDist(modelorg, surf->plane) < surf->plane->dist)
+                       {
+                               if (!(surf->flags & SURF_PLANEBACK))
+                                       surf->visframe = -1;
+                       }
+                       else
+                       {
+                               if (surf->flags & SURF_PLANEBACK)
+                                       surf->visframe = -1;
+                       }
+                       if (surf->visframe == r_framecount)
                        {
-                               surf->insertframe = r_framecount;
                                c_faces++;
                                t = surf->texinfo->texture;
                                if (t->animated)
@@ -1808,18 +1589,18 @@ void R_PrepareSurfaces(entity_render_t *ent)
                                }
                                else
                                        surf->currenttexture = t;
-                       }
 
-                       surf->chain = surf->shader->chain;
-                       surf->shader->chain = surf;
+                               surf->chain = surf->shader->chain;
+                               surf->shader->chain = surf;
+                       }
                }
        }
 }
 
 void R_DrawSurfaces (entity_render_t *ent, int type)
 {
-       int                     i;
-       Cshader_t       *shader;
+       int i;
+       Cshader_t *shader;
 
        for (i = 0;i < Cshader_count;i++)
        {
@@ -1892,37 +1673,36 @@ void R_DrawPortals(entity_render_t *ent)
        }
 }
 
-void R_SetupForBModelRendering(entity_render_t *ent)
+void R_SetupForBrushModelRendering(entity_render_t *ent)
 {
-       int                     i;
-       msurface_t      *surf;
-       model_t         *model;
-       vec3_t          modelorg;
+       int i;
+       msurface_t *surf;
+       model_t *model;
+       vec3_t modelorg;
 
        // because bmodels can be reused, we have to decide which things to render
        // from scratch every time
-
        model = ent->model;
-
        Matrix4x4_Transform(&ent->inversematrix, r_origin, modelorg);
        for (i = 0;i < model->nummodelsurfaces;i++)
        {
-               surf = model->modelsortedsurfaces[i];
-               if (((surf->flags & SURF_PLANEBACK) == 0) == (PlaneDiff(modelorg, surf->plane) >= 0))
-                       surf->visframe = r_framecount;
-               else
-                       surf->visframe = -1;
+               surf = model->surfaces + model->firstmodelsurface + i;
+               surf->visframe = r_framecount;
+               surf->pvsframe = -1;
                surf->worldnodeframe = -1;
                surf->lightframe = -1;
                surf->dlightframe = -1;
-               surf->insertframe = -1;
        }
+       R_PrepareSurfaces(ent);
 }
 
 void R_SurfMarkLights (entity_render_t *ent)
 {
-       int                     i;
-       msurface_t      *surf;
+       int i;
+       msurface_t *surf;
+
+       if (!ent->model)
+               return;
 
        if (r_dynamic.integer)
                R_MarkLights(ent);
@@ -1952,6 +1732,171 @@ void R_SurfMarkLights (entity_render_t *ent)
        }
 }
 
+void R_SurfaceWorldNode (entity_render_t *ent)
+{
+       int i;
+       msurface_t *surf;
+       model_t *model;
+       model = ent->model;
+       // FIXME: R_NotCulledBox is absolute, should be done relative
+       for (i = 0, surf = model->surfaces + model->firstmodelsurface;i < model->nummodelsurfaces;i++, surf++)
+               if (surf->pvsframe == r_pvsframecount && (!r_cullsurface.integer || R_NotCulledBox (surf->poly_mins, surf->poly_maxs)))
+                       surf->visframe = r_framecount;
+}
+
+/*
+static void R_PortalWorldNode(entity_render_t *ent, mleaf_t *viewleaf)
+{
+       int portalstack, i;
+       mportal_t *p, *pstack[8192];
+       msurface_t *surf, **mark, **endmark;
+       mleaf_t *leaf;
+       // LordHavoc: portal-passage worldnode with PVS;
+       // follows portals leading outward from viewleaf, does not venture
+       // offscreen or into leafs that are not visible, faster than Quake's
+       // RecursiveWorldNode
+       leaf = viewleaf;
+       leaf->worldnodeframe = r_framecount;
+       portalstack = 0;
+loc0:
+       c_leafs++;
+       if (leaf->nummarksurfaces)
+       {
+               for (c = leaf->nummarksurfaces, mark = leaf->firstmarksurface;c;c--)
+               {
+                       surf = *mark++;
+                       // make sure surfaces are only processed once
+                       if (surf->worldnodeframe != r_framecount)
+                       {
+                               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;
+                               }
+                       }
+               }
+       }
+       // follow portals into other leafs
+       for (p = leaf->portals;p;p = p->next)
+       {
+               leaf = p->past;
+               if (leaf->worldnodeframe != r_framecount)
+               {
+                       leaf->worldnodeframe = r_framecount;
+                       // FIXME: R_NotCulledBox is absolute, should be done relative
+                       if (leaf->pvsframe == r_pvsframecount && R_NotCulledBox(leaf->mins, leaf->maxs))
+                       {
+                               p->visframe = r_framecount;
+                               pstack[portalstack++] = p;
+                               goto loc0;
+loc1:
+                               p = pstack[--portalstack];
+                       }
+               }
+       }
+       if (portalstack)
+               goto loc1;
+}
+*/
+
+static void R_PortalWorldNode(entity_render_t *ent, mleaf_t *viewleaf)
+{
+       int c, leafstackpos;
+       mleaf_t *leaf, *leafstack[8192];
+       mportal_t *p;
+       msurface_t *surf, **mark;
+       vec3_t modelorg;
+       // LordHavoc: portal-passage worldnode with PVS;
+       // follows portals leading outward from viewleaf, does not venture
+       // offscreen or into leafs that are not visible, faster than Quake's
+       // RecursiveWorldNode
+       Matrix4x4_Transform(&ent->inversematrix, r_origin, modelorg);
+       viewleaf->worldnodeframe = r_framecount;
+       leafstack[0] = viewleaf;
+       leafstackpos = 1;
+       while (leafstackpos)
+       {
+               c_leafs++;
+               leaf = leafstack[--leafstackpos];
+               // only useful for drawing portals
+               //leaf->visframe = r_framecount;
+               // draw any surfaces bounding this leaf
+               if (leaf->nummarksurfaces)
+               {
+                       for (c = leaf->nummarksurfaces, mark = leaf->firstmarksurface;c;c--)
+                       {
+                               surf = *mark++;
+                               if (!r_cullsurface.integer || R_NotCulledBox (surf->poly_mins, surf->poly_maxs))
+                                       surf->visframe = r_framecount;
+                       }
+               }
+               // follow portals into other leafs
+               for (p = leaf->portals;p;p = p->next)
+               {
+                       leaf = p->past;
+                       if (leaf->worldnodeframe != r_framecount)
+                       {
+                               leaf->worldnodeframe = r_framecount;
+                               // FIXME: R_NotCulledBox is absolute, should be done relative
+                               if (leaf->pvsframe == r_pvsframecount && R_NotCulledBox(leaf->mins, leaf->maxs))
+                                       leafstack[leafstackpos++] = leaf;
+                       }
+               }
+       }
+}
+
+
+void R_PVSUpdate (mleaf_t *viewleaf)
+{
+       int i, j, l, c, bits;
+       mnode_t *node;
+       mleaf_t *leaf;
+       qbyte *vis;
+       msurface_t **mark;
+
+       if (r_viewleaf == viewleaf && r_viewleafnovis == r_novis.integer)
+               return;
+
+       r_pvsframecount++;
+       r_viewleaf = viewleaf;
+       r_viewleafnovis = r_novis.integer;
+
+       if (viewleaf)
+       {
+               vis = Mod_LeafPVS (viewleaf, cl.worldmodel);
+               for (j = 0;j < cl.worldmodel->numleafs;j += 8)
+               {
+                       bits = *vis++;
+                       if (bits)
+                       {
+                               l = cl.worldmodel->numleafs - j;
+                               if (l > 8)
+                                       l = 8;
+                               for (i = 0;i < l;i++)
+                               {
+                                       if (bits & (1 << i))
+                                       {
+                                               leaf = &cl.worldmodel->leafs[j + i + 1];
+                                               // mark surfaces bounding this leaf as visible
+                                               for (c = leaf->nummarksurfaces, mark = leaf->firstmarksurface;c;c--)
+                                                       (*mark++)->pvsframe = r_pvsframecount;
+                                               // mark parents as visible until we hit an already
+                                               // marked parent (which is usually very soon)
+                                               for (node = (mnode_t *)leaf;node && node->pvsframe != r_pvsframecount;node = node->parent)
+                                                       node->pvsframe = r_pvsframecount;
+                                       }
+                               }
+                       }
+               }
+       }
+}
+
 /*
 =============
 R_DrawWorld
@@ -1961,10 +1906,15 @@ void R_DrawWorld (entity_render_t *ent)
 {
        // there is only one instance of the world, but it can be rendered in
        // multiple stages
-       if (r_viewleaf->contents == CONTENTS_SOLID || r_novis.integer || r_viewleaf->compressed_vis == NULL)
-               R_SolidWorldNode (ent);
+       mleaf_t *viewleaf;
+       viewleaf = Mod_PointInLeaf (r_origin, cl.worldmodel);
+       R_PVSUpdate(viewleaf);
+       if (!viewleaf)
+               return;
+       if (r_surfaceworldnode.integer || viewleaf->contents == CONTENTS_SOLID)
+               R_SurfaceWorldNode (ent);
        else
-               R_PVSWorldNode (ent);
+               R_PortalWorldNode (ent, viewleaf);
 }
 
 /*
@@ -1974,27 +1924,17 @@ R_DrawBrushModel
 */
 void R_DrawBrushModelSky (entity_render_t *ent)
 {
-       R_SetupForBModelRendering(ent);
-
-       R_PrepareSurfaces(ent);
+       R_SetupForBrushModelRendering(ent);
        R_DrawSurfaces(ent, SHADERSTAGE_SKY);
 }
 
 void R_DrawBrushModelNormal (entity_render_t *ent)
 {
        c_bmodels++;
-
        // have to flush queue because of possible lightmap reuse
        R_Mesh_Render();
-
-       R_SetupForBModelRendering(ent);
-
+       R_SetupForBrushModelRendering(ent);
        R_SurfMarkLights(ent);
-
-       R_PrepareSurfaces(ent);
-
-       if (!skyrendermasked)
-               R_DrawSurfaces(ent, SHADERSTAGE_SKY);
        R_DrawSurfaces(ent, SHADERSTAGE_NORMAL);
 }
 
@@ -2008,6 +1948,10 @@ static void gl_surf_shutdown(void)
 
 static void gl_surf_newmap(void)
 {
+       // reset pvs visibility variables so it will update on first frame
+       r_pvsframecount = 1;
+       r_viewleaf = NULL;
+       r_viewleafnovis = false;
 }
 
 void GL_Surf_Init(void)
@@ -2024,6 +1968,8 @@ void GL_Surf_Init(void)
        Cvar_RegisterVariable(&r_testvis);
        Cvar_RegisterVariable(&r_floatbuildlightmap);
        Cvar_RegisterVariable(&r_detailtextures);
+       Cvar_RegisterVariable(&r_surfaceworldnode);
+       Cvar_RegisterVariable(&r_cullsurface);
 
        R_RegisterModule("GL_Surf", gl_surf_start, gl_surf_shutdown, gl_surf_newmap);
 }
diff --git a/host.c b/host.c
index ef402120afe67d95101df13e8d8ddec236590512..2816a121cf18b9039defe75d8b7dabda50eec4c8 100644 (file)
--- a/host.c
+++ b/host.c
@@ -143,12 +143,14 @@ void Host_Error (char *error, ...)
                Sys_Error ("Host_Error: recursively entered (original error was: %s    new error is: %s)", hosterrorstring, string);
        }
        inerror = true;
-       
+
        va_start (argptr,error);
        vsprintf (hosterrorstring,error,argptr);
        va_end (argptr);
        Con_Printf ("Host_Error: %s\n",hosterrorstring);
-       
+
+       PR_Crash();
+
        if (sv.active)
                Host_ShutdownServer (false);
 
@@ -449,6 +451,9 @@ void Host_ShutdownServer(qboolean crash)
        if (!sv.active)
                return;
 
+       // print out where the crash happened, if it was caused by QC
+       PR_Crash();
+
        sv.active = false;
 
 // stop all client sounds immediately
diff --git a/keys.c b/keys.c
index ff098d5f1fcfe04b5f3e30fbeafccc1f8e107c69..9b4380a9788edfed646805fd8d60c9f03856dba2 100644 (file)
--- a/keys.c
+++ b/keys.c
@@ -703,25 +703,19 @@ void Key_Event (int key, qboolean down)
        {
                if (!down)
                        return;
-               if (key_consoleactive)
-                       M_ToggleMenu_f ();
-               else
+               switch (key_dest)
                {
-                       switch (key_dest)
-                       {
-                       case key_message:
-                               Key_Message (key);
-                               break;
-                       case key_menu:
-                               M_Keydown (key);
-                               break;
-                       case key_game:
-                       //case key_console:
-                               M_ToggleMenu_f ();
-                               break;
-                       default:
-                               Sys_Error ("Bad key_dest");
-                       }
+               case key_message:
+                       Key_Message (key);
+                       break;
+               case key_menu:
+                       M_Keydown (key);
+                       break;
+               case key_game:
+                       M_ToggleMenu_f ();
+                       break;
+               default:
+                       Sys_Error ("Bad key_dest");
                }
                return;
        }
diff --git a/keys.h b/keys.h
index 4447faf4729af3451f20f7a04f366fa4aa75a71d..57d32eedf8df84df3d25a42d33b113c29213e79d 100644 (file)
--- a/keys.h
+++ b/keys.h
@@ -149,6 +149,11 @@ typedef enum {
 
 typedef enum {key_game, key_message, key_menu} keydest_t;
 
+// key_consoleactive bits
+// user wants console (halfscreen)
+#define KEY_CONSOLEACTIVE_USER 1
+// console forced because there's nothing else active (fullscreen)
+#define KEY_CONSOLEACTIVE_FORCED 2
 extern int key_consoleactive;
 extern keydest_t key_dest;
 extern char *keybindings[256];
index fff672e45fb2990f6a1881991216f76c63979afc..ec3105c2766eaf735a2cbb09f1487f16e6176242 100644 (file)
--- a/makefile
+++ b/makefile
@@ -50,11 +50,11 @@ NOPROFILEOPTIMIZATIONS=
 #this is used to ensure that all released versions are free of warnings.
 
 #normal compile
-OPTIMIZATIONS= -O6 -fno-strict-aliasing -ffast-math -funroll-loops $(NOPROFILEOPTIMIZATIONS) -fexpensive-optimizations $(CPUOPTIMIZATIONS)
-CFLAGS= -MD -Wall -Werror -I/usr/X11R6/include $(OPTIMIZATIONS) $(PROFILEOPTION)
+#OPTIMIZATIONS= -O6 -fno-strict-aliasing -ffast-math -funroll-loops $(NOPROFILEOPTIMIZATIONS) -fexpensive-optimizations $(CPUOPTIMIZATIONS)
+#CFLAGS= -MD -Wall -Werror -I/usr/X11R6/include $(OPTIMIZATIONS) $(PROFILEOPTION)
 #debug compile
-#OPTIMIZATIONS=
-#CFLAGS= -MD -Wall -Werror -I/usr/X11R6/include -ggdb $(OPTIMIZATIONS) $(PROFILEOPTION)
+OPTIMIZATIONS=
+CFLAGS= -MD -Wall -Werror -I/usr/X11R6/include -ggdb $(OPTIMIZATIONS) $(PROFILEOPTION)
 
 LDFLAGS= -L/usr/X11R6/lib -lm -lX11 -lXext -lXxf86dga -lXxf86vm -ldl $(SOUNDLIB) $(PROFILEOPTION)
 
index 92244c451766043a293caeeef637f281afffb23c..4eec6da8844b4f92136f0e9a8b4831fee000eadb 100644 (file)
@@ -111,7 +111,10 @@ Mod_PointInLeaf
 */
 mleaf_t *Mod_PointInLeaf (const vec3_t p, model_t *model)
 {
-       mnode_t         *node;
+       mnode_t *node;
+
+       if (model == NULL)
+               return NULL;
 
        Mod_CheckLoaded(model);
 
@@ -124,17 +127,35 @@ mleaf_t *Mod_PointInLeaf (const vec3_t p, model_t *model)
        return (mleaf_t *)node;
 }
 
+int Mod_PointContents (const vec3_t p, model_t *model)
+{
+       mnode_t *node;
+
+       if (model == NULL)
+               return CONTENTS_EMPTY;
+
+       Mod_CheckLoaded(model);
+
+       // LordHavoc: modified to start at first clip node,
+       // in other words: first node of the (sub)model
+       node = model->nodes + model->hulls[0].firstclipnode;
+       while (node->contents == 0)
+               node = node->children[(node->plane->type < 3 ? p[node->plane->type] : DotProduct (p,node->plane->normal)) < node->plane->dist];
+
+       return ((mleaf_t *)node)->contents;
+}
+
 void Mod_FindNonSolidLocation(vec3_t pos, model_t *mod)
 {
-       if (Mod_PointInLeaf(pos, mod)->contents != CONTENTS_SOLID) return;
-       pos[0]-=1;if (Mod_PointInLeaf(pos, mod)->contents != CONTENTS_SOLID) return;
-       pos[0]+=2;if (Mod_PointInLeaf(pos, mod)->contents != CONTENTS_SOLID) return;
+       if (Mod_PointContents(pos, mod) != CONTENTS_SOLID) return;
+       pos[0]-=1;if (Mod_PointContents(pos, mod) != CONTENTS_SOLID) return;
+       pos[0]+=2;if (Mod_PointContents(pos, mod) != CONTENTS_SOLID) return;
        pos[0]-=1;
-       pos[1]-=1;if (Mod_PointInLeaf(pos, mod)->contents != CONTENTS_SOLID) return;
-       pos[1]+=2;if (Mod_PointInLeaf(pos, mod)->contents != CONTENTS_SOLID) return;
+       pos[1]-=1;if (Mod_PointContents(pos, mod) != CONTENTS_SOLID) return;
+       pos[1]+=2;if (Mod_PointContents(pos, mod) != CONTENTS_SOLID) return;
        pos[1]-=1;
-       pos[2]-=1;if (Mod_PointInLeaf(pos, mod)->contents != CONTENTS_SOLID) return;
-       pos[2]+=2;if (Mod_PointInLeaf(pos, mod)->contents != CONTENTS_SOLID) return;
+       pos[2]-=1;if (Mod_PointContents(pos, mod) != CONTENTS_SOLID) return;
+       pos[2]+=2;if (Mod_PointContents(pos, mod) != CONTENTS_SOLID) return;
        pos[2]-=1;
 }
 
@@ -1275,6 +1296,8 @@ void Mod_GenerateSurfacePolygon (msurface_t *surf)
                if (mins[2] > vert[2]) mins[2] = vert[2];if (maxs[2] < vert[2]) maxs[2] = vert[2];
                vert += 3;
        }
+       VectorCopy(mins, surf->poly_mins);
+       VectorCopy(maxs, surf->poly_maxs);
        surf->poly_center[0] = (mins[0] + maxs[0]) * 0.5f;
        surf->poly_center[1] = (mins[1] + maxs[1]) * 0.5f;
        surf->poly_center[2] = (mins[2] + maxs[2]) * 0.5f;
@@ -2485,7 +2508,11 @@ void Mod_LoadBrushModel (model_t *mod, void *buffer)
                Host_Error ("Mod_LoadBrushModel: %s has wrong version number (%i should be %i (Quake) or 30 (HalfLife))", mod->name, i, BSPVERSION);
        mod->ishlbsp = i == 30;
        if (loadmodel->isworldmodel)
+       {
                Cvar_SetValue("halflifebsp", mod->ishlbsp);
+               // until we get a texture for it...
+               R_ResetQuakeSky();
+       }
 
 // swap all the lumps
        mod_base = (qbyte *)header;
index fdc69165e7ec50614a0c04f36a331799318ad88f..6f24b259ee5dba7e6e71e4dd34f27f929cdd246f 100644 (file)
@@ -139,6 +139,8 @@ typedef struct msurface_s
 {
        // should be drawn if visframe == r_framecount (set by WorldNode functions)
        int                     visframe;
+       // should be drawn if onscreen and not a backface (used for setting visframe)
+       int                     pvsframe;
 
        // the node plane this is on, backwards if SURF_PLANEBACK flag set
        mplane_t        *plane;
@@ -176,8 +178,8 @@ typedef struct msurface_s
        // no texcoord info (that can be generated from these)
        int                     poly_numverts;
        float           *poly_verts;
-       // the center is useful for sorting
-       float           poly_center[3];
+       // bounding box for onscreen checks, and center for sorting
+       vec3_t          poly_mins, poly_maxs, poly_center;
 
        // these are regenerated every frame
        // lighting info
@@ -187,8 +189,6 @@ typedef struct msurface_s
        int                     lightframe;
        // only render each surface once
        int                     worldnodeframe;
-       // marked when surface is prepared for the frame
-       int                     insertframe;
 
        // these cause lightmap updates if regenerated
        // values currently used in lightmap
@@ -235,6 +235,8 @@ typedef struct mnode_s
        vec3_t                          mins;
        vec3_t                          maxs;
 
+       int                                     pvsframe;               // potentially visible if current (r_pvsframecount)
+
 // node specific
        mplane_t                        *plane;
        struct mnode_s          *children[2];
@@ -256,15 +258,13 @@ typedef struct mleaf_s
        vec3_t                          mins;
        vec3_t                          maxs;
 
+       int                                     pvsframe;               // potentially visible if current (r_pvsframecount)
+
 // leaf specific
        int                                     visframe;               // visible if current (r_framecount)
        int                                     worldnodeframe; // used by certain worldnode variants to avoid processing the same leaf twice in a frame
        int                                     portalmarkid;   // used by polygon-through-portals visibility checker
 
-       // LordHavoc: leaf based dynamic lighting
-       int                                     dlightbits[8];
-       int                                     dlightframe;
-
        qbyte                           *compressed_vis;
 
        msurface_t                      **firstmarksurface;
@@ -317,7 +317,11 @@ extern texture_t r_notexture_mip;
 struct model_s;
 void Mod_LoadBrushModel (struct model_s *mod, void *buffer);
 void Mod_BrushInit(void);
+
 void Mod_FindNonSolidLocation(vec3_t pos, struct model_s *mod);
+mleaf_t *Mod_PointInLeaf (const float *p, struct model_s *model);
+int Mod_PointContents (const float *p, struct model_s *model);
+qbyte *Mod_LeafPVS (mleaf_t *leaf, struct model_s *model);
 
 #endif
 
index adbe9348adaaa8f4360df748a39f8ccb58beb301..4ece6a32638274b704f3848d68996b66b5077fcd 100644 (file)
@@ -251,8 +251,8 @@ void Mod_ClearAll (void)
 
 void Mod_ClearUsed(void)
 {
-       int             i;
-       model_t *mod;
+       int i;
+       model_t *mod;
 
        for (i = 0, mod = mod_known;i < MAX_MOD_KNOWN;i++, mod++)
                if (mod->name[0])
@@ -261,8 +261,8 @@ void Mod_ClearUsed(void)
 
 void Mod_PurgeUnused(void)
 {
-       int             i;
-       model_t *mod;
+       int i;
+       model_t *mod;
 
        for (i = 0, mod = mod_known;i < MAX_MOD_KNOWN;i++, mod++)
                if (mod->name[0])
@@ -278,8 +278,8 @@ Mod_FindName
 */
 model_t *Mod_FindName (char *name)
 {
-       int             i;
-       model_t *mod, *freemod;
+       int i;
+       model_t *mod, *freemod;
 
        if (!name[0])
                Host_Error ("Mod_ForName: NULL name");
@@ -369,4 +369,3 @@ static void Mod_Flush (void)
                if (mod_known[i].name[0])
                        Mod_UnloadModel(&mod_known[i]);
 }
-
index f6a6bdc9f6d7dc40c942b8d6e4e8bb2d267c637e..d970b84f07e4813da1b138f9b63c2b3230ee8397 100644 (file)
@@ -226,9 +226,6 @@ model_t *Mod_ForName (char *name, qboolean crash, qboolean checkdisk, qboolean i
 void Mod_TouchModel (char *name);
 void Mod_UnloadModel (model_t *mod);
 
-mleaf_t *Mod_PointInLeaf (const float *p, model_t *model);
-qbyte *Mod_LeafPVS (mleaf_t *leaf, model_t *model);
-
 void Mod_ClearUsed(void);
 void Mod_PurgeUnused(void);
 
index 0343e9de2955f80094b70a8faaa82cb390a0e3ef..554177ad849ea74da3c9c77049fe259f71831ff8 100644 (file)
--- a/portals.c
+++ b/portals.c
@@ -187,6 +187,10 @@ int Portal_CheckPolygon(model_t *model, vec3_t eye, float *polypoints, int numpo
        mleaf_t *eyeleaf;
        vec3_t center, v1, v2;
 
+       // if there is no model, it can not block visibility
+       if (model == NULL)
+               return true;
+
        portal_markid++;
 
        Mod_CheckLoaded(model);
index 14cc29349246755887b6ce0ca27c0b1589198cb1..2c1c8ce600e6b97fb58c27893dbe549162d755f3 100644 (file)
--- a/pr_cmds.c
+++ b/pr_cmds.c
@@ -166,7 +166,7 @@ void PF_objerror (void)
 {
        char    *s;
        edict_t *ed;
-       
+
        s = PF_VarString(0);
        Con_Printf ("======OBJECT ERROR in %s:\n%s\n", pr_strings + pr_xfunction->s_name, s);
        ed = PROG_TO_EDICT(pr_global_struct->self);
@@ -229,7 +229,7 @@ void SetMinMaxSize (edict_t *e, float *min, float *max, qboolean rotate)
        
        for (i=0 ; i<3 ; i++)
                if (min[i] > max[i])
-                       PR_RunError ("backwards mins/maxs");
+                       Host_Error ("backwards mins/maxs");
 
 // set derived values
        VectorCopy (min, e->v.mins);
@@ -284,7 +284,7 @@ void PF_setmodel (void)
                        break;
 
        if (!*check)
-               PR_RunError ("no precache: %s\n", m);
+               Host_Error ("no precache: %s\n", m);
 
 
        e->v.model = m - pr_strings;
@@ -646,7 +646,7 @@ break()
 */
 void PF_break (void)
 {
-       PR_RunError ("break statement");
+       Host_Error ("break statement");
 }
 
 /*
@@ -849,15 +849,15 @@ void PF_checkclient (void)
        mleaf_t *leaf;
        int             l;
        vec3_t  view;
-       
-// find a new check if on a new frame
+
+       // find a new check if on a new frame
        if (sv.time - sv.lastchecktime >= 0.1)
        {
                sv.lastcheck = PF_newcheckclient (sv.lastcheck);
                sv.lastchecktime = sv.time;
        }
 
-// return check if it might be visible 
+       // return check if it might be visible
        ent = EDICT_NUM(sv.lastcheck);
        if (ent->free || ent->v.health <= 0)
        {
@@ -865,20 +865,23 @@ void PF_checkclient (void)
                return;
        }
 
-// if current entity can't possibly see the check entity, return 0
+       // if current entity can't possibly see the check entity, return 0
        self = PROG_TO_EDICT(pr_global_struct->self);
        VectorAdd (self->v.origin, self->v.view_ofs, view);
        leaf = Mod_PointInLeaf (view, sv.worldmodel);
-       l = (leaf - sv.worldmodel->leafs) - 1;
-       if ( (l<0) || !(checkpvs[l>>3] & (1<<(l&7)) ) )
+       if (leaf)
        {
-c_notvis++;
-               RETURN_EDICT(sv.edicts);
-               return;
+               l = (leaf - sv.worldmodel->leafs) - 1;
+               if ( (l<0) || !(checkpvs[l>>3] & (1<<(l&7)) ) )
+               {
+                       c_notvis++;
+                       RETURN_EDICT(sv.edicts);
+                       return;
+               }
        }
 
-// might be able to see it
-c_invis++;
+       // might be able to see it
+       c_invis++;
        RETURN_EDICT(ent);
 }
 
@@ -902,7 +905,7 @@ void PF_stuffcmd (void)
        
        entnum = G_EDICTNUM(OFS_PARM0);
        if (entnum < 1 || entnum > svs.maxclients)
-               PR_RunError ("Parm 0 not a client");
+               Host_Error ("Parm 0 not a client");
        str = G_STRING(OFS_PARM1);      
        
        old = host_client;
@@ -1081,9 +1084,9 @@ void PF_Remove (void)
 
        ed = G_EDICT(OFS_PARM0);
        if (ed == sv.edicts)
-               PR_RunError("remove: tried to remove world\n");
+               Host_Error("remove: tried to remove world\n");
        if (NUM_FOR_EDICT(ed) <= svs.maxclients)
-               PR_RunError("remove: tried to remove a client\n");
+               Host_Error("remove: tried to remove a client\n");
        ED_Free (ed);
 }
 
@@ -1219,7 +1222,7 @@ void PF_findchainfloat (void)
 void PR_CheckEmptyString (char *s)
 {
        if (s[0] <= ' ')
-               PR_RunError ("Bad string");
+               Host_Error ("Bad string");
 }
 
 void PF_precache_file (void)
@@ -1233,7 +1236,7 @@ void PF_precache_sound (void)
        int             i;
 
        if (sv.state != ss_loading)
-               PR_RunError ("PF_Precache_*: Precache can only be done in spawn functions");
+               Host_Error ("PF_Precache_*: Precache can only be done in spawn functions");
 
        s = G_STRING(OFS_PARM0);
        G_INT(OFS_RETURN) = G_INT(OFS_PARM0);
@@ -1249,7 +1252,7 @@ void PF_precache_sound (void)
                if (!strcmp(sv.sound_precache[i], s))
                        return;
        }
-       PR_RunError ("PF_precache_sound: overflow");
+       Host_Error ("PF_precache_sound: overflow");
 }
 
 void PF_precache_model (void)
@@ -1258,7 +1261,7 @@ void PF_precache_model (void)
        int             i;
        
        if (sv.state != ss_loading)
-               PR_RunError ("PF_Precache_*: Precache can only be done in spawn functions");
+               Host_Error ("PF_Precache_*: Precache can only be done in spawn functions");
 
        s = G_STRING(OFS_PARM0);
        if (sv.worldmodel->ishlbsp && ((!s) || (!s[0])))
@@ -1277,7 +1280,7 @@ void PF_precache_model (void)
                if (!strcmp(sv.model_precache[i], s))
                        return;
        }
-       PR_RunError ("PF_precache_model: overflow");
+       Host_Error ("PF_precache_model: overflow");
 }
 
 
@@ -1447,7 +1450,7 @@ PF_pointcontents
 */
 void PF_pointcontents (void)
 {
-       G_FLOAT(OFS_RETURN) = Mod_PointInLeaf(G_VECTOR(OFS_PARM0), sv.worldmodel)->contents;
+       G_FLOAT(OFS_RETURN) = Mod_PointContents(G_VECTOR(OFS_PARM0), sv.worldmodel);
 }
 
 /*
@@ -1621,14 +1624,14 @@ void PF_changepitch (void)
                ideal = val->_float;
        else
        {
-               PR_RunError ("PF_changepitch: .float idealpitch and .float pitch_speed must be defined to use changepitch");
+               Host_Error ("PF_changepitch: .float idealpitch and .float pitch_speed must be defined to use changepitch");
                return;
        }
        if ((val = GETEDICTFIELDVALUE(ent, eval_pitch_speed)))
                speed = val->_float;
        else
        {
-               PR_RunError ("PF_changepitch: .float idealpitch and .float pitch_speed must be defined to use changepitch");
+               Host_Error ("PF_changepitch: .float idealpitch and .float pitch_speed must be defined to use changepitch");
                return;
        }
 
@@ -1688,7 +1691,7 @@ sizebuf_t *WriteDest (void)
                ent = PROG_TO_EDICT(pr_global_struct->msg_entity);
                entnum = NUM_FOR_EDICT(ent);
                if (entnum < 1 || entnum > svs.maxclients)
-                       PR_RunError ("WriteDest: not a client");
+                       Host_Error ("WriteDest: not a client");
                return &svs.clients[entnum-1].message;
 
        case MSG_ALL:
@@ -1698,7 +1701,7 @@ sizebuf_t *WriteDest (void)
                return &sv.signon;
 
        default:
-               PR_RunError ("WriteDest: bad destination");
+               Host_Error ("WriteDest: bad destination");
                break;
        }
 
@@ -1802,7 +1805,7 @@ void PF_setspawnparms (void)
        ent = G_EDICT(OFS_PARM0);
        i = NUM_FOR_EDICT(ent);
        if (i < 1 || i > svs.maxclients)
-               PR_RunError ("Entity is not a client");
+               Host_Error ("Entity is not a client");
 
        // copy spawn parms out of the client_t
        client = svs.clients + (i-1);
@@ -1911,7 +1914,7 @@ void PF_registercvar (void)
        }
 
        if (currentqc_cvar >= MAX_QC_CVARS)
-               PR_RunError ("PF_registercvar: ran out of cvar slots (%i)\n", MAX_QC_CVARS);
+               Host_Error ("PF_registercvar: ran out of cvar slots (%i)\n", MAX_QC_CVARS);
 
 // copy the name and value
        variable = &qc_cvar[currentqc_cvar++];
@@ -1949,7 +1952,7 @@ void PF_min (void)
                G_FLOAT(OFS_RETURN) = f;
        }
        else
-               PR_RunError("min: must supply at least 2 floats\n");
+               Host_Error("min: must supply at least 2 floats\n");
 }
 
 /*
@@ -1976,7 +1979,7 @@ void PF_max (void)
                G_FLOAT(OFS_RETURN) = f;
        }
        else
-               PR_RunError("max: must supply at least 2 floats\n");
+               Host_Error("max: must supply at least 2 floats\n");
 }
 
 /*
@@ -2068,7 +2071,7 @@ void PF_effect (void)
        char *s;
        s = G_STRING(OFS_PARM1);
        if (!s || !s[0])
-               PR_RunError("effect: no model specified\n");
+               Host_Error("effect: no model specified\n");
 
        SV_StartEffect(G_VECTOR(OFS_PARM0), SV_ModelIndex(s), G_FLOAT(OFS_PARM2), G_FLOAT(OFS_PARM3), G_FLOAT(OFS_PARM4));
 }
@@ -2464,9 +2467,152 @@ void PF_te_plasmaburn (void)
        MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
 }
 
+static void clippointtosurface(msurface_t *surf, vec3_t p, vec3_t out)
+{
+       int i, j;
+       vec3_t v1, clipplanenormal, normal;
+       vec_t clipplanedist, clipdist;
+       VectorCopy(p, out);
+       if (surf->flags & SURF_PLANEBACK)
+               VectorNegate(surf->plane->normal, normal);
+       else
+               VectorCopy(surf->plane->normal, normal);
+       for (i = 0, j = surf->poly_numverts - 1;i < surf->poly_numverts;j = i, i++)
+       {
+               VectorSubtract(&surf->poly_verts[j * 3], &surf->poly_verts[i * 3], v1);
+               VectorNormalizeFast(v1);
+               CrossProduct(v1, normal, clipplanenormal);
+               clipplanedist = DotProduct(&surf->poly_verts[i * 3], clipplanenormal);
+               clipdist = DotProduct(out, clipplanenormal) - clipplanedist;
+               if (clipdist > 0)
+               {
+                       clipdist = -clipdist;
+                       VectorMA(out, clipdist, clipplanenormal, out);
+               }
+       }
+}
+
+static msurface_t *getsurface(edict_t *ed, int surfnum)
+{
+       int modelindex;
+       model_t *model;
+       if (!ed || ed->free)
+               return NULL;
+       modelindex = ed->v.modelindex;
+       if (modelindex < 1 || modelindex >= MAX_MODELS)
+               return NULL;
+       model = sv.models[modelindex];
+       if (model->type != mod_brush)
+               return NULL;
+       if (surfnum < 0 || surfnum >= model->nummodelsurfaces)
+               return NULL;
+       return model->surfaces + surfnum + model->firstmodelsurface;
+}
+
+
+//PF_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints = #434;
+void PF_getsurfacenumpoints(void)
+{
+       msurface_t *surf;
+       // return 0 if no such surface
+       if (!(surf = getsurface(G_EDICT(OFS_PARM0), G_FLOAT(OFS_PARM1))))
+       {
+               G_FLOAT(OFS_RETURN) = 0;
+               return;
+       }
+
+       G_FLOAT(OFS_RETURN) = surf->poly_numverts;
+}
+//PF_getsurfacepoint,     // #435 vector(entity e, float s, float n) getsurfacepoint = #435;
+void PF_getsurfacepoint(void)
+{
+       edict_t *ed;
+       msurface_t *surf;
+       int pointnum;
+       VectorClear(G_VECTOR(OFS_RETURN));
+       ed = G_EDICT(OFS_PARM0);
+       if (!ed || ed->free)
+               return;
+       if (!(surf = getsurface(ed, G_FLOAT(OFS_PARM1))))
+               return;
+       pointnum = G_FLOAT(OFS_PARM2);
+       if (pointnum < 0 || pointnum >= surf->poly_numverts)
+               return;
+       // FIXME: implement rotation/scaling
+       VectorAdd(&surf->poly_verts[pointnum * 3], ed->v.origin, G_VECTOR(OFS_RETURN));
+}
+//PF_getsurfacenormal,    // #436 vector(entity e, float s) getsurfacenormal = #436;
+void PF_getsurfacenormal(void)
+{
+       msurface_t *surf;
+       VectorClear(G_VECTOR(OFS_RETURN));
+       if (!(surf = getsurface(G_EDICT(OFS_PARM0), G_FLOAT(OFS_PARM1))))
+               return;
+       // FIXME: implement rotation/scaling
+       if (surf->flags & SURF_PLANEBACK)
+               VectorNegate(surf->plane->normal, G_VECTOR(OFS_RETURN));
+       else
+               VectorCopy(surf->plane->normal, G_VECTOR(OFS_RETURN));
+}
+//PF_getsurfacetexture,   // #437 string(entity e, float s) getsurfacetexture = #437;
+void PF_getsurfacetexture(void)
+{
+       msurface_t *surf;
+       G_INT(OFS_RETURN) = 0;
+       if (!(surf = getsurface(G_EDICT(OFS_PARM0), G_FLOAT(OFS_PARM1))))
+               return;
+       G_INT(OFS_RETURN) = surf->texinfo->texture->name - pr_strings;
+}
+//PF_getsurfacenearpoint, // #438 void(entity e, vector p) getsurfacenearpoint = #438;
+void PF_getsurfacenearpoint(void)
+{
+       int surfnum, best, modelindex;
+       vec3_t clipped, p;
+       vec_t dist, bestdist;
+       edict_t *ed;
+       model_t *model;
+       msurface_t *surf;
+       vec_t *point;
+       G_FLOAT(OFS_RETURN) = -1;
+       ed = G_EDICT(OFS_PARM0);
+       point = G_VECTOR(OFS_PARM1);
+
+       if (!ed || ed->free)
+               return;
+       modelindex = ed->v.modelindex;
+       if (modelindex < 1 || modelindex >= MAX_MODELS)
+               return;
+       model = sv.models[modelindex];
+       if (model->type != mod_brush)
+               return;
+
+       // FIXME: implement rotation/scaling
+       VectorSubtract(point, ed->v.origin, p);
+       best = -1;
+       bestdist = 1000000000;
+       for (surfnum = 0;surfnum < model->nummodelsurfaces;surfnum++)
+       {
+               surf = model->surfaces + surfnum + model->firstmodelsurface;
+               dist = PlaneDiff(p, surf->plane);
+               dist = dist * dist;
+               if (dist < bestdist)
+               {
+                       clippointtosurface(surf, p, clipped);
+                       VectorSubtract(clipped, p, clipped);
+                       dist += DotProduct(clipped, clipped);
+                       if (dist < bestdist)
+                       {
+                               best = surfnum;
+                               bestdist = dist;
+                       }
+               }
+       }
+       G_FLOAT(OFS_RETURN) = best;
+}
+
 void PF_Fixme (void)
 {
-       PR_RunError ("unimplemented builtin"); // LordHavoc: was misspelled (bulitin)
+       Host_Error ("unimplemented QC builtin"); // LordHavoc: was misspelled (bulitin)
 }
 
 
@@ -2622,6 +2768,11 @@ PF_te_lightning3,                // #430
 PF_te_beam,                            // #431
 PF_vectorvectors,              // #432
 PF_te_plasmaburn,              // #433
+PF_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints = #434;
+PF_getsurfacepoint,     // #435 vector(entity e, float s, float n) getsurfacepoint = #435;
+PF_getsurfacenormal,    // #436 vector(entity e, float s) getsurfacenormal = #436;
+PF_getsurfacetexture,   // #437 string(entity e, float s) getsurfacetexture = #437;
+PF_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint = #438;
 };
 
 builtin_t *pr_builtins = pr_builtin;
index eda7404f8d03efa01e17d1db6de90f8b0cc42d98..368f485bd358015fc592c0985413c72cfd4e66ff 100644 (file)
--- a/pr_exec.c
+++ b/pr_exec.c
@@ -240,23 +240,18 @@ void PR_Profile_f (void)
 }
 
 
-/*
-============
-PR_RunError
-
-Aborts the currently executing function
-============
-*/
-void PR_RunError (char *error, ...)
+void PR_Crash(void)
 {
-       int                     i;
-       va_list         argptr;
-       char            string[1024];
-
-       va_start (argptr,error);
-       vsprintf (string,error,argptr);
-       va_end (argptr);
+       int i;
+       if (!pr_depth)
+       {
+               // kill the stack just to be sure
+               pr_depth = 0;
+               localstack_used = 0;
+               return;
+       }
 
+       Con_Printf("QuakeC crash report:\n");
        if (pr_xfunction)
        {
                for (i = -4;i <= 0;i++)
@@ -266,13 +261,10 @@ void PR_RunError (char *error, ...)
        else
                Con_Printf("null function executing??\n");
        PR_StackTrace ();
-       Con_Printf ("%s\n", string);
 
        // dump the stack so host_error can shutdown functions
        pr_depth = 0;
        localstack_used = 0;
-
-       Host_Error ("Program error");
 }
 
 /*
@@ -295,18 +287,18 @@ int PR_EnterFunction (dfunction_t *f)
        int             i, j, c, o;
 
        if (!f)
-               PR_RunError ("PR_EnterFunction: NULL function\n");
+               Host_Error ("PR_EnterFunction: NULL function\n");
 
        pr_stack[pr_depth].s = pr_xstatement;
        pr_stack[pr_depth].f = pr_xfunction;
        pr_depth++;
        if (pr_depth >= MAX_STACK_DEPTH)
-               PR_RunError ("stack overflow");
+               Host_Error ("stack overflow");
 
 // save off any locals that the new function steps on
        c = f->locals;
        if (localstack_used + c > LOCALSTACK_SIZE)
-               PR_RunError ("PR_ExecuteProgram: locals stack overflow\n");
+               Host_Error ("PR_ExecuteProgram: locals stack overflow\n");
 
        for (i=0 ; i < c ; i++)
                localstack[localstack_used+i] = ((int *)pr_globals)[f->parm_start + i];
@@ -340,12 +332,12 @@ int PR_LeaveFunction (void)
                Host_Error ("prog stack underflow");
 
        if (!pr_xfunction)
-               PR_RunError ("PR_LeaveFunction: NULL function\n");
+               Host_Error ("PR_LeaveFunction: NULL function\n");
 // restore locals from the stack
        c = pr_xfunction->locals;
        localstack_used -= c;
        if (localstack_used < 0)
-               PR_RunError ("PR_ExecuteProgram: locals stack underflow\n");
+               Host_Error ("PR_ExecuteProgram: locals stack underflow\n");
 
        for (i=0 ; i < c ; i++)
                ((int *)pr_globals)[pr_xfunction->parm_start + i] = localstack[localstack_used+i];
index fd306cf2154a0fc1bcbb1a0c2f1963374369be22..05e861030470c53474e20006edc8ba6073a47963 100644 (file)
@@ -7,7 +7,7 @@
                        if (++profile > 1000000) // LordHavoc: increased runaway loop limit 10x
                        {
                                pr_xstatement = st - pr_statements;
-                               PR_RunError ("runaway loop error");
+                               Host_Error ("runaway loop error");
                        }
 
 #if PRTRACE
                                if (OPB->_int < 0 || OPB->_int + 4 > pr_edictareasize)
                                {
                                        pr_xstatement = st - pr_statements;
-                                       PR_RunError("Progs attempted to write to an out of bounds edict\n");
+                                       Host_Error("Progs attempted to write to an out of bounds edict\n");
                                        return;
                                }
                                if (OPB->_int % pr_edict_size < ((qbyte *)&sv.edicts->v - (qbyte *)sv.edicts))
                                {
                                        pr_xstatement = st - pr_statements;
-                                       PR_RunError("Progs attempted to write to an engine edict field\n");
+                                       Host_Error("Progs attempted to write to an engine edict field\n");
                                        return;
                                }
 #endif
                                if (OPB->_int < 0 || OPB->_int + 12 > pr_edictareasize)
                                {
                                        pr_xstatement = st - pr_statements;
-                                       PR_RunError("Progs attempted to write to an out of bounds edict\n");
+                                       Host_Error("Progs attempted to write to an out of bounds edict\n");
                                        return;
                                }
 #endif
                                        if (OPA->edict == 0 && sv.state == ss_active)
                                        {
                                                pr_xstatement = st - pr_statements;
-                                               PR_RunError ("assignment to world entity");
+                                               Host_Error ("assignment to world entity");
                                                return;
                                        }
                                        else
                                        {
                                                pr_xstatement = st - pr_statements;
-                                               PR_RunError("Progs attempted to address an out of bounds edict\n");
+                                               Host_Error("Progs attempted to address an out of bounds edict\n");
                                                return;
                                        }
                                }
                                else if (OPA->edict >= pr_edictareasize)
                                {
                                        pr_xstatement = st - pr_statements;
-                                       PR_RunError("Progs attempted to address an out of bounds edict\n");
+                                       Host_Error("Progs attempted to address an out of bounds edict\n");
                                        return;
                                }
                                if (OPB->_int < 0 || OPB->_int >= progs->entityfields)
                                {
                                        pr_xstatement = st - pr_statements;
-                                       PR_RunError("Progs attempted to address an invalid field in an edict\n");
+                                       Host_Error("Progs attempted to address an invalid field in an edict\n");
                                        return;
                                }
 #else
                                if (OPA->edict == 0 && sv.state == ss_active)
                                {
                                        pr_xstatement = st - pr_statements;
-                                       PR_RunError ("assignment to world entity");
+                                       Host_Error ("assignment to world entity");
                                        return;
                                }
 #endif
                                if (OPA->edict < 0 || OPA->edict >= pr_edictareasize)
                                {
                                        pr_xstatement = st - pr_statements;
-                                       PR_RunError("Progs attempted to read an out of bounds edict number\n");
+                                       Host_Error("Progs attempted to read an out of bounds edict number\n");
                                        return;
                                }
                                if (OPB->_int < 0 || OPB->_int >= progs->entityfields)
                                {
                                        pr_xstatement = st - pr_statements;
-                                       PR_RunError("Progs attempted to read an invalid field in an edict\n");
+                                       Host_Error("Progs attempted to read an invalid field in an edict\n");
                                        return;
                                }
 #endif
                                if (OPA->edict < 0 || OPA->edict >= pr_edictareasize)
                                {
                                        pr_xstatement = st - pr_statements;
-                                       PR_RunError("Progs attempted to read an out of bounds edict number\n");
+                                       Host_Error("Progs attempted to read an out of bounds edict number\n");
                                        return;
                                }
                                if (OPB->_int < 0 || OPB->_int + 2 >= progs->entityfields)
                                {
                                        pr_xstatement = st - pr_statements;
-                                       PR_RunError("Progs attempted to read an invalid field in an edict\n");
+                                       Host_Error("Progs attempted to read an invalid field in an edict\n");
                                        return;
                                }
 #endif
                                pr_xstatement = st - pr_statements;
                                pr_argc = st->op - OP_CALL0;
                                if (!OPA->function)
-                                       PR_RunError ("NULL function");
+                                       Host_Error ("NULL function");
 
                                newf = &pr_functions[OPA->function];
 
                                {
                                        // negative statements are built in functions
                                        if ((-newf->first_statement) >= pr_numbuiltins)
-                                               PR_RunError ("Bad builtin call number");
+                                               Host_Error ("Bad builtin call number");
                                        pr_builtins[-newf->first_statement] ();
                                }
                                else
                                if (OPB->_int < 0 || OPB->_int + 4 > pr_edictareasize)
                                {
                                        pr_xstatement = st - pr_statements;
-                                       PR_RunError("Progs attempted to write to an out of bounds edict\n");
+                                       Host_Error("Progs attempted to write to an out of bounds edict\n");
                                        return;
                                }
                                if (OPB->_int % pr_edict_size < ((qbyte *)&sv.edicts->v - (qbyte *)sv.edicts))
                                {
                                        pr_xstatement = st - pr_statements;
-                                       PR_RunError("Progs attempted to write to an engine edict field\n");
+                                       Host_Error("Progs attempted to write to an engine edict field\n");
                                        return;
                                }
 #endif
                                if (OPA->edict < 0 || OPA->edict >= pr_edictareasize)
                                {
                                        pr_xstatement = st - pr_statements;
-                                       PR_RunError("Progs attempted to read an out of bounds edict number\n");
+                                       Host_Error("Progs attempted to read an out of bounds edict number\n");
                                        return;
                                }
                                if (OPB->_int < 0 || OPB->_int >= progs->entityfields)
                                {
                                        pr_xstatement = st - pr_statements;
-                                       PR_RunError("Progs attempted to read an invalid field in an edict\n");
+                                       Host_Error("Progs attempted to read an invalid field in an edict\n");
                                        return;
                                }
 #endif
                                if (OPB->_int < 0 || OPB->_int >= pr_globaldefs)
                                {
                                        pr_xstatement = st - pr_statements;
-                                       PR_RunError("Progs attempted to write to an invalid indexed global\n");
+                                       Host_Error("Progs attempted to write to an invalid indexed global\n");
                                        return;
                                }
 #endif
                                if (OPB->_int < 0 || OPB->_int + 2 >= pr_globaldefs)
                                {
                                        pr_xstatement = st - pr_statements;
-                                       PR_RunError("Progs attempted to write to an invalid indexed global\n");
+                                       Host_Error("Progs attempted to write to an invalid indexed global\n");
                                        return;
                                }
 #endif
                                if (i < 0 || i >= pr_globaldefs)
                                {
                                        pr_xstatement = st - pr_statements;
-                                       PR_RunError("Progs attempted to address an out of bounds global\n");
+                                       Host_Error("Progs attempted to address an out of bounds global\n");
                                        return;
                                }
 #endif
                                if (OPA->_int < 0 || OPA->_int >= pr_globaldefs)
                                {
                                        pr_xstatement = st - pr_statements;
-                                       PR_RunError("Progs attempted to read an invalid indexed global\n");
+                                       Host_Error("Progs attempted to read an invalid indexed global\n");
                                        return;
                                }
 #endif
                                if (OPA->_int < 0 || OPA->_int + 2 >= pr_globaldefs)
                                {
                                        pr_xstatement = st - pr_statements;
-                                       PR_RunError("Progs attempted to read an invalid indexed global\n");
+                                       Host_Error("Progs attempted to read an invalid indexed global\n");
                                        return;
                                }
 #endif
                                if (OPA->_int < 0 || OPA->_int >= st->b)
                                {
                                        pr_xstatement = st - pr_statements;
-                                       PR_RunError("Progs boundcheck failed at line number %d, value is < 0 or >= %d\n", st->b, st->c);
+                                       Host_Error("Progs boundcheck failed at line number %d, value is < 0 or >= %d\n", st->b, st->c);
                                        return;
                                }
                                break;
 
                        default:
                                pr_xstatement = st - pr_statements;
-                               PR_RunError ("Bad opcode %i", st->op);
+                               Host_Error ("Bad opcode %i", st->op);
                        }
                }
 
diff --git a/progs.h b/progs.h
index c456c8943bd3ba3a51e42122ec6a95edf16b92c7..874ba9f93ab0ed89102f198d44ae96d15defe326 100644 (file)
--- a/progs.h
+++ b/progs.h
@@ -122,6 +122,8 @@ void PR_LoadProgs (void);
 
 void PR_Profile_f (void);
 
+void PR_Crash (void);
+
 edict_t *ED_Alloc (void);
 void ED_Free (edict_t *ed);
 
@@ -176,7 +178,6 @@ extern      int                     pr_xstatement;
 
 extern unsigned short          pr_crc;
 
-void PR_RunError (char *error, ...);
 void PR_Execute_ProgsLoaded(void);
 
 void ED_PrintEdicts (void);
index fe8f2495f90a21b03e3e1cc69cb7b1ec5afde077..753e4af25fe51c7269174cb1d30cad83af92fd73 100644 (file)
@@ -10,6 +10,10 @@ void R_LerpAnimation(entity_render_t *r)
        double sublerp, lerp, d;
        animscene_t *scene;
        frameblend_t *blend;
+
+       if (!r->model)
+               return;
+
        blend = r->frameblend;
 
        numframes = r->model->numframes;
index f6b8d4803ca86e0238dd314122e1a9e688255251..754685ae7394306ac68afa04dd24863976bf7784 100644 (file)
--- a/r_light.c
+++ b/r_light.c
@@ -64,6 +64,9 @@ void r_light_shutdown(void)
 
 void r_light_newmap(void)
 {
+       int i;
+       for (i = 0;i < 256;i++)
+               d_lightstylevalue[i] = 264;             // normal light value
 }
 
 void R_Light_Init(void)
@@ -90,7 +93,7 @@ void R_AnimateLight (void)
        i = (int)(cl.time * 10);
        for (j = 0;j < MAX_LIGHTSTYLES;j++)
        {
-               if (!cl_lightstyle[j].length)
+               if (!cl_lightstyle || !cl_lightstyle[j].length)
                {
                        d_lightstylevalue[j] = 256;
                        continue;
@@ -112,7 +115,7 @@ void R_BuildLightList(void)
        r_numdlights = 0;
        c_dlights = 0;
 
-       if (!r_dynamic.integer)
+       if (!r_dynamic.integer || !cl_dlights)
                return;
 
        for (i = 0;i < MAX_DLIGHTS;i++)
@@ -226,8 +229,9 @@ static void R_OldMarkLights (entity_render_t *ent, vec3_t lightorigin, rdlight_t
 {
        float ndist, maxdist;
        msurface_t *surf;
-       mleaf_t *leaf;
        int i;
+       int d, impacts, impactt;
+       float dist, dist2, impact[3];
 
        if (!r_dynamic.integer)
                return;
@@ -237,19 +241,7 @@ static void R_OldMarkLights (entity_render_t *ent, vec3_t lightorigin, rdlight_t
 
 loc0:
        if (node->contents < 0)
-       {
-               if (node->contents != CONTENTS_SOLID)
-               {
-                       leaf = (mleaf_t *)node;
-                       if (leaf->dlightframe != r_framecount) // not dynamic until now
-                       {
-                               leaf->dlightbits[0] = leaf->dlightbits[1] = leaf->dlightbits[2] = leaf->dlightbits[3] = leaf->dlightbits[4] = leaf->dlightbits[5] = leaf->dlightbits[6] = leaf->dlightbits[7] = 0;
-                               leaf->dlightframe = r_framecount;
-                       }
-                       leaf->dlightbits[bitindex] |= bit;
-               }
                return;
-       }
 
        ndist = PlaneDiff(lightorigin, node->plane);
 
@@ -266,10 +258,8 @@ loc0:
 
 // mark the polygons
        surf = ent->model->surfaces + node->firstsurface;
-       for (i=0 ; i<node->numsurfaces ; i++, surf++)
+       for (i = 0;i < node->numsurfaces;i++, surf++)
        {
-               int d, impacts, impactt;
-               float dist, dist2, impact[3];
                if (surf->visframe != r_framecount)
                        continue;
                dist = ndist;
@@ -285,14 +275,14 @@ loc0:
 
                if (node->plane->type < 3)
                {
-                       VectorCopy(rd->origin, impact);
+                       VectorCopy(lightorigin, impact);
                        impact[node->plane->type] -= dist;
                }
                else
                {
-                       impact[0] = rd->origin[0] - surf->plane->normal[0] * dist;
-                       impact[1] = rd->origin[1] - surf->plane->normal[1] * dist;
-                       impact[2] = rd->origin[2] - surf->plane->normal[2] * dist;
+                       impact[0] = lightorigin[0] - surf->plane->normal[0] * dist;
+                       impact[1] = lightorigin[1] - surf->plane->normal[1] * dist;
+                       impact[2] = lightorigin[2] - surf->plane->normal[2] * dist;
                }
 
                impacts = DotProduct (impact, surf->texinfo->vecs[0]) + surf->texinfo->vecs[0][3] - surf->texturemins[0];
@@ -355,28 +345,17 @@ static void R_VisMarkLights (entity_render_t *ent, rdlight_t *rd, int bit, int b
        if (!r_dynamic.integer)
                return;
 
-       model = ent->model;
-       //softwareuntransform(rd->origin, lightorigin);
        Matrix4x4_Transform(&ent->inversematrix, rd->origin, lightorigin);
 
-       if (!r_vismarklights.integer)
-       {
-               R_OldMarkLights(ent, lightorigin, rd, bit, bitindex, model->nodes + model->hulls[0].firstclipnode);
-               return;
-       }
-
+       model = ent->model;
        pvsleaf = Mod_PointInLeaf (lightorigin, model);
        if (pvsleaf == NULL)
-       {
-               Con_Printf("R_VisMarkLights: NULL leaf??\n");
-               R_OldMarkLights(ent, lightorigin, rd, bit, bitindex, model->nodes + model->hulls[0].firstclipnode);
                return;
-       }
 
        in = pvsleaf->compressed_vis;
-       if (!in)
+       if (!r_vismarklights.integer || !in)
        {
-               // no vis info, so make all visible
+               // told not to use pvs, or there's no pvs to use
                R_OldMarkLights(ent, lightorigin, rd, bit, bitindex, model->nodes + model->hulls[0].firstclipnode);
                return;
        }
@@ -406,19 +385,10 @@ static void R_VisMarkLights (entity_render_t *ent, rdlight_t *rd, int bit, int b
                                        if (leafnum > model->numleafs)
                                                return;
                                        leaf = &model->leafs[leafnum];
-                                       if (leaf->visframe != r_framecount
-                                        || leaf->contents == CONTENTS_SOLID
-                                        || leaf->mins[0] > high[0] || leaf->maxs[0] < low[0]
+                                       if (leaf->mins[0] > high[0] || leaf->maxs[0] < low[0]
                                         || leaf->mins[1] > high[1] || leaf->maxs[1] < low[1]
                                         || leaf->mins[2] > high[2] || leaf->maxs[2] < low[2])
                                                continue;
-                                       if (leaf->dlightframe != r_framecount)
-                                       {
-                                               // not dynamic until now
-                                               leaf->dlightbits[0] = leaf->dlightbits[1] = leaf->dlightbits[2] = leaf->dlightbits[3] = leaf->dlightbits[4] = leaf->dlightbits[5] = leaf->dlightbits[6] = leaf->dlightbits[7] = 0;
-                                               leaf->dlightframe = r_framecount;
-                                       }
-                                       leaf->dlightbits[bitindex] |= bit;
                                        if ((m = leaf->nummarksurfaces))
                                        {
                                                mark = leaf->firstmarksurface;
@@ -445,14 +415,14 @@ static void R_VisMarkLights (entity_render_t *ent, rdlight_t *rd, int bit, int b
 
                                                                if (surf->plane->type < 3)
                                                                {
-                                                                       VectorCopy(rd->origin, impact);
+                                                                       VectorCopy(lightorigin, impact);
                                                                        impact[surf->plane->type] -= dist;
                                                                }
                                                                else
                                                                {
-                                                                       impact[0] = rd->origin[0] - surf->plane->normal[0] * dist;
-                                                                       impact[1] = rd->origin[1] - surf->plane->normal[1] * dist;
-                                                                       impact[2] = rd->origin[2] - surf->plane->normal[2] * dist;
+                                                                       impact[0] = lightorigin[0] - surf->plane->normal[0] * dist;
+                                                                       impact[1] = lightorigin[1] - surf->plane->normal[1] * dist;
+                                                                       impact[2] = lightorigin[2] - surf->plane->normal[2] * dist;
                                                                }
 
                                                                impacts = DotProduct (impact, surf->texinfo->vecs[0]) + surf->texinfo->vecs[0][3] - surf->texturemins[0];
@@ -646,23 +616,15 @@ middle sample (the one which was requested)
 void R_CompleteLightPoint (vec3_t color, const vec3_t p, int dynamic, const mleaf_t *leaf)
 {
        int i;
-       const int *dlightbits;
        vec3_t v;
        float f;
        rdlight_t *rd;
        mlight_t *sl;
        if (leaf == NULL)
                leaf = Mod_PointInLeaf(p, cl.worldmodel);
-
-       if (leaf->contents == CONTENTS_SOLID)
+       if (!leaf || leaf->contents == CONTENTS_SOLID || r_fullbright.integer || !cl.worldmodel->lightdata)
        {
-               color[0] = color[1] = color[2] = 0;
-               return;
-       }
-
-       if (r_fullbright.integer || !cl.worldmodel->lightdata)
-       {
-               color[0] = color[1] = color[2] = 2;
+               color[0] = color[1] = color[2] = 1;
                return;
        }
 
@@ -687,17 +649,14 @@ void R_CompleteLightPoint (vec3_t color, const vec3_t p, int dynamic, const mlea
        else
                RecursiveLightPoint (color, cl.worldmodel->nodes, p[0], p[1], p[2], p[2] - 65536);
 
-       if (dynamic && leaf->dlightframe == r_framecount)
+       if (dynamic)
        {
-               dlightbits = leaf->dlightbits;
                for (i = 0;i < r_numdlights;i++)
                {
-                       if (!(dlightbits[i >> 5] & (1 << (i & 31))))
-                               continue;
                        rd = r_dlight + i;
                        VectorSubtract (p, rd->origin, v);
                        f = DotProduct(v, v);
-                       if (f < rd->cullradius2)
+                       if (f < rd->cullradius2 && CL_TraceLine(p, rd->origin, NULL, NULL, 0, false) == 1)
                        {
                                f = (1.0f / (f + LIGHTOFFSET)) - rd->subtract;
                                VectorMA(color, f, rd->light, color);
@@ -706,41 +665,19 @@ void R_CompleteLightPoint (vec3_t color, const vec3_t p, int dynamic, const mlea
        }
 }
 
-void R_ModelLightPoint (const entity_render_t *ent, vec3_t color, const vec3_t p, int *dlightbits)
+void R_ModelLightPoint (const entity_render_t *ent, vec3_t color, const vec3_t p)
 {
        mleaf_t *leaf;
        leaf = Mod_PointInLeaf(p, cl.worldmodel);
-       if (leaf->contents == CONTENTS_SOLID)
+       if (!leaf || leaf->contents == CONTENTS_SOLID || r_fullbright.integer || !cl.worldmodel->lightdata || ent->effects & EF_FULLBRIGHT)
        {
-               color[0] = color[1] = color[2] = 0;
-               dlightbits[0] = dlightbits[1] = dlightbits[2] = dlightbits[3] = dlightbits[4] = dlightbits[5] = dlightbits[6] = dlightbits[7] = 0;
-               return;
-       }
-
-       if (r_fullbright.integer || !cl.worldmodel->lightdata || ent->effects & EF_FULLBRIGHT)
-       {
-               color[0] = color[1] = color[2] = 2;
-               dlightbits[0] = dlightbits[1] = dlightbits[2] = dlightbits[3] = dlightbits[4] = dlightbits[5] = dlightbits[6] = dlightbits[7] = 0;
+               color[0] = color[1] = color[2] = 1;
                return;
        }
 
        color[0] = color[1] = color[2] = r_ambient.value * (2.0f / 128.0f);
        if (!cl.worldmodel->numlights)
                RecursiveLightPoint (color, cl.worldmodel->nodes, p[0], p[1], p[2], p[2] - 65536);
-
-       if (leaf->dlightframe == r_framecount)
-       {
-               dlightbits[0] = leaf->dlightbits[0];
-               dlightbits[1] = leaf->dlightbits[1];
-               dlightbits[2] = leaf->dlightbits[2];
-               dlightbits[3] = leaf->dlightbits[3];
-               dlightbits[4] = leaf->dlightbits[4];
-               dlightbits[5] = leaf->dlightbits[5];
-               dlightbits[6] = leaf->dlightbits[6];
-               dlightbits[7] = leaf->dlightbits[7];
-       }
-       else
-               dlightbits[0] = dlightbits[1] = dlightbits[2] = dlightbits[3] = dlightbits[4] = dlightbits[5] = dlightbits[6] = dlightbits[7] = 0;
 }
 
 void R_LightModel(const entity_render_t *ent, int numverts, float colorr, float colorg, float colorb, int worldcoords)
@@ -761,7 +698,6 @@ void R_LightModel(const entity_render_t *ent, int numverts, float colorr, float
                vec_t intensity;
        }
        nearlight[MAX_DLIGHTS], *nl;
-       int modeldlightbits[8];
        mlight_t *sl;
        rdlight_t *rd;
        a = ent->alpha;
@@ -770,7 +706,7 @@ void R_LightModel(const entity_render_t *ent, int numverts, float colorr, float
        mscale = ent->scale * ent->scale;
        if ((maxnearlights != 0) && !r_fullbright.integer && !(ent->effects & EF_FULLBRIGHT))
        {
-               R_ModelLightPoint(ent, basecolor, ent->origin, modeldlightbits);
+               R_ModelLightPoint(ent, basecolor, ent->origin);
 
                nl = &nearlight[0];
                for (i = 0;i < ent->numentlights;i++)
@@ -812,7 +748,6 @@ void R_LightModel(const entity_render_t *ent, int numverts, float colorr, float
                                if (worldcoords)
                                        VectorCopy(sl->origin, nl->origin);
                                else
-                                       //softwareuntransform(sl->origin, nl->origin);
                                        Matrix4x4_Transform(&ent->inversematrix, sl->origin, nl->origin);
                                // integrate mscale into falloff, for maximum speed
                                nl->falloff = sl->falloff * mscale;
@@ -826,66 +761,73 @@ void R_LightModel(const entity_render_t *ent, int numverts, float colorr, float
                }
                for (i = 0;i < r_numdlights;i++)
                {
-                       if (!(modeldlightbits[i >> 5] & (1 << (i & 31))))
-                               continue;
                        rd = r_dlight + i;
-                       VectorSubtract (ent->origin, rd->origin, v);
-                       f = ((1.0f / (DotProduct(v, v) + LIGHTOFFSET)) - rd->subtract);
-                       VectorScale(rd->light, f, ambientcolor);
-                       intensity = DotProduct(ambientcolor, ambientcolor);
-                       if (f < 0)
-                               intensity *= -1.0f;
-                       if (nearlights < maxnearlights)
-                               j = nearlights++;
-                       else
+                       VectorCopy(rd->origin, v);
+                       if (v[0] < ent->mins[0]) v[0] = ent->mins[0];if (v[0] > ent->maxs[0]) v[0] = ent->maxs[0];
+                       if (v[1] < ent->mins[1]) v[1] = ent->mins[1];if (v[1] > ent->maxs[1]) v[1] = ent->maxs[1];
+                       if (v[2] < ent->mins[2]) v[2] = ent->mins[2];if (v[2] > ent->maxs[2]) v[2] = ent->maxs[2];
+                       VectorSubtract (v, rd->origin, v);
+                       if (DotProduct(v, v) < rd->cullradius2)
                        {
-                               for (j = 0;j < maxnearlights;j++)
+                               if (CL_TraceLine(ent->origin, rd->origin, NULL, NULL, 0, false) != 1)
+                                       continue;
+                               VectorSubtract (ent->origin, rd->origin, v);
+                               f = ((1.0f / (DotProduct(v, v) + LIGHTOFFSET)) - rd->subtract);
+                               VectorScale(rd->light, f, ambientcolor);
+                               intensity = DotProduct(ambientcolor, ambientcolor);
+                               if (f < 0)
+                                       intensity *= -1.0f;
+                               if (nearlights < maxnearlights)
+                                       j = nearlights++;
+                               else
                                {
-                                       if (nearlight[j].intensity < intensity)
+                                       for (j = 0;j < maxnearlights;j++)
                                        {
-                                               if (nearlight[j].intensity > 0)
-                                                       VectorAdd(basecolor, nearlight[j].ambientlight, basecolor);
-                                               break;
+                                               if (nearlight[j].intensity < intensity)
+                                               {
+                                                       if (nearlight[j].intensity > 0)
+                                                               VectorAdd(basecolor, nearlight[j].ambientlight, basecolor);
+                                                       break;
+                                               }
                                        }
                                }
-                       }
-                       if (j >= maxnearlights)
-                       {
-                               // this light is less significant than all others,
-                               // add it to ambient
-                               if (intensity > 0)
-                                       VectorAdd(basecolor, ambientcolor, basecolor);
-                       }
-                       else
-                       {
-                               nl = nearlight + j;
-                               nl->intensity = intensity;
-                               // transform the light into the model's coordinate system
-                               if (worldcoords)
-                                       VectorCopy(rd->origin, nl->origin);
+                               if (j >= maxnearlights)
+                               {
+                                       // this light is less significant than all others,
+                                       // add it to ambient
+                                       if (intensity > 0)
+                                               VectorAdd(basecolor, ambientcolor, basecolor);
+                               }
                                else
                                {
-                                       //softwareuntransform(rd->origin, nl->origin);
-                                       Matrix4x4_Transform(&ent->inversematrix, rd->origin, nl->origin);
-                                       /*
-                                       Con_Printf("%i %s : %f %f %f : %f %f %f\n%f %f %f %f\n%f %f %f %f\n%f %f %f %f\n%f %f %f %f\n"
-                                       , rd - r_dlight, ent->model->name
-                                       , rd->origin[0], rd->origin[1], rd->origin[2]
-                                       , nl->origin[0], nl->origin[1], nl->origin[2]
-                                       , ent->inversematrix.m[0][0], ent->inversematrix.m[0][1], ent->inversematrix.m[0][2], ent->inversematrix.m[0][3]
-                                       , ent->inversematrix.m[1][0], ent->inversematrix.m[1][1], ent->inversematrix.m[1][2], ent->inversematrix.m[1][3]
-                                       , ent->inversematrix.m[2][0], ent->inversematrix.m[2][1], ent->inversematrix.m[2][2], ent->inversematrix.m[2][3]
-                                       , ent->inversematrix.m[3][0], ent->inversematrix.m[3][1], ent->inversematrix.m[3][2], ent->inversematrix.m[3][3]);
-                                       */
+                                       nl = nearlight + j;
+                                       nl->intensity = intensity;
+                                       // transform the light into the model's coordinate system
+                                       if (worldcoords)
+                                               VectorCopy(rd->origin, nl->origin);
+                                       else
+                                       {
+                                               Matrix4x4_Transform(&ent->inversematrix, rd->origin, nl->origin);
+                                               /*
+                                               Con_Printf("%i %s : %f %f %f : %f %f %f\n%f %f %f %f\n%f %f %f %f\n%f %f %f %f\n%f %f %f %f\n"
+                                               , rd - r_dlight, ent->model->name
+                                               , rd->origin[0], rd->origin[1], rd->origin[2]
+                                               , nl->origin[0], nl->origin[1], nl->origin[2]
+                                               , ent->inversematrix.m[0][0], ent->inversematrix.m[0][1], ent->inversematrix.m[0][2], ent->inversematrix.m[0][3]
+                                               , ent->inversematrix.m[1][0], ent->inversematrix.m[1][1], ent->inversematrix.m[1][2], ent->inversematrix.m[1][3]
+                                               , ent->inversematrix.m[2][0], ent->inversematrix.m[2][1], ent->inversematrix.m[2][2], ent->inversematrix.m[2][3]
+                                               , ent->inversematrix.m[3][0], ent->inversematrix.m[3][1], ent->inversematrix.m[3][2], ent->inversematrix.m[3][3]);
+                                               */
+                                       }
+                                       // integrate mscale into falloff, for maximum speed
+                                       nl->falloff = mscale;
+                                       VectorCopy(ambientcolor, nl->ambientlight);
+                                       nl->light[0] = rd->light[0] * colorr * 4.0f;
+                                       nl->light[1] = rd->light[1] * colorg * 4.0f;
+                                       nl->light[2] = rd->light[2] * colorb * 4.0f;
+                                       nl->subtract = rd->subtract;
+                                       nl->offset = LIGHTOFFSET;
                                }
-                               // integrate mscale into falloff, for maximum speed
-                               nl->falloff = mscale;
-                               VectorCopy(ambientcolor, nl->ambientlight);
-                               nl->light[0] = rd->light[0] * colorr * 4.0f;
-                               nl->light[1] = rd->light[1] * colorg * 4.0f;
-                               nl->light[2] = rd->light[2] * colorb * 4.0f;
-                               nl->subtract = rd->subtract;
-                               nl->offset = LIGHTOFFSET;
                        }
                }
        }
@@ -967,9 +909,10 @@ void R_UpdateEntLights(entity_render_t *ent)
                ent->entlightstime = realtime + 0.1;
                VectorCopy(ent->origin, ent->entlightsorigin);
                ent->numentlights = 0;
-               for (i = 0, sl = cl.worldmodel->lights;i < cl.worldmodel->numlights && ent->numentlights < MAXENTLIGHTS;i++, sl++)
-                       if (CL_TraceLine(ent->origin, sl->origin, NULL, NULL, 0, false) == 1)
-                               ent->entlights[ent->numentlights++] = i;
+               if (cl.worldmodel)
+                       for (i = 0, sl = cl.worldmodel->lights;i < cl.worldmodel->numlights && ent->numentlights < MAXENTLIGHTS;i++, sl++)
+                               if (CL_TraceLine(ent->origin, sl->origin, NULL, NULL, 0, false) == 1)
+                                       ent->entlights[ent->numentlights++] = i;
        }
        ent->entlightsframe = r_framecount;
 }
diff --git a/r_sky.c b/r_sky.c
index 364818a888f3a45e241ac52c009c67bf04eed2c7..8b3d697a230eb380a1d7c786f2222ac131d73d80 100644 (file)
--- a/r_sky.c
+++ b/r_sky.c
@@ -1,52 +1,21 @@
 
 #include "quakedef.h"
 
-void LoadSky_f(void);
-
 cvar_t r_sky = {CVAR_SAVE, "r_sky", "1"};
-
-static char skyworldname[1024];
-rtexture_t *solidskytexture;
-rtexture_t *alphaskytexture;
-static qboolean skyavailable_quake;
-static qboolean skyavailable_box;
-static rtexturepool_t *skytexturepool;
-
+qboolean skyavailable_quake;
+qboolean skyavailable_box;
 int skyrendernow;
 int skyrendermasked;
 
-static void r_sky_start(void)
-{
-       skytexturepool = R_AllocTexturePool();
-       solidskytexture = NULL;
-       alphaskytexture = NULL;
-}
-
-static void r_sky_shutdown(void)
-{
-       R_FreeTexturePool(&skytexturepool);
-       solidskytexture = NULL;
-       alphaskytexture = NULL;
-}
-
-int R_SetSkyBox(char *sky);
-
-static void r_sky_newmap(void)
-{
-       skyavailable_quake = false;
-       if (!strcmp(skyworldname, cl.worldmodel->name))
-               skyavailable_quake = true;
-}
-
-void R_Sky_Init(void)
-{
-       Cmd_AddCommand ("loadsky", &LoadSky_f);
-       Cvar_RegisterVariable (&r_sky);
-       R_RegisterModule("R_Sky", r_sky_start, r_sky_shutdown, r_sky_newmap);
-}
-
+static rtexture_t *solidskytexture;
+static rtexture_t *alphaskytexture;
 static int skyrendersphere;
 static int skyrenderbox;
+static rtexturepool_t *skytexturepool;
+static char skyname[256];
+static char *suf[6] = {"rt", "bk", "lf", "ft", "up", "dn"};
+static rtexture_t *skyboxside[6];
+int R_SetSkyBox(char *sky);
 
 void R_SkyStartFrame(void)
 {
@@ -66,15 +35,11 @@ void R_SkyStartFrame(void)
        }
 }
 
-static char skyname[256];
-
 /*
 ==================
 R_SetSkyBox
 ==================
 */
-static char *suf[6] = {"rt", "bk", "lf", "ft", "up", "dn"};
-static rtexture_t *skyboxside[6];
 int R_SetSkyBox(char *sky)
 {
        int i;
@@ -405,7 +370,7 @@ void R_InitSky (qbyte *src, int bytesperpixel)
        qbyte skyupperlayerpixels[128*128*4], skylowerlayerpixels[128*128*4];
        unsigned trans[128*128], transpix, *rgba;
 
-       strcpy(skyworldname, loadmodel->name);
+       skyavailable_quake = true;
 
        // flush skytexturepool so we won't build up a leak from uploading textures multiple times
        R_FreeTexturePool(&skytexturepool);
@@ -473,3 +438,39 @@ void R_InitSky (qbyte *src, int bytesperpixel)
        alphaskytexture = R_LoadTexture (skytexturepool, "sky_alphatexture", 128, 128, (qbyte *) trans, TEXTYPE_RGBA, TEXF_ALPHA | TEXF_PRECACHE);
 }
 
+void R_ResetQuakeSky(void)
+{
+       skyavailable_quake = false;
+}
+
+void R_ResetSkyBox(void)
+{
+       skyboxside[0] = skyboxside[1] = skyboxside[2] = skyboxside[3] = skyboxside[4] = skyboxside[5] = NULL;
+       skyname[0] = 0;
+       skyavailable_box = false;
+}
+
+static void r_sky_start(void)
+{
+       skytexturepool = R_AllocTexturePool();
+       solidskytexture = NULL;
+       alphaskytexture = NULL;
+}
+
+static void r_sky_shutdown(void)
+{
+       R_FreeTexturePool(&skytexturepool);
+       solidskytexture = NULL;
+       alphaskytexture = NULL;
+}
+
+static void r_sky_newmap(void)
+{
+}
+
+void R_Sky_Init(void)
+{
+       Cmd_AddCommand ("loadsky", &LoadSky_f);
+       Cvar_RegisterVariable (&r_sky);
+       R_RegisterModule("R_Sky", r_sky_start, r_sky_shutdown, r_sky_newmap);
+}
index a22cad766adfd82bff3131bf08f86c3cea318247..195c0cac93d194cfb0bab25ed295d56bccf790a6 100644 (file)
--- a/render.h
+++ b/render.h
@@ -32,14 +32,13 @@ extern void FOG_clear(void);
 extern float fog_density, fog_red, fog_green, fog_blue;
 
 // sky stuff
-extern int R_SetSkyBox(char* sky);
 extern cvar_t r_sky;
-// these are exposed because surface rendering uses them
-extern rtexture_t *solidskytexture;
-extern rtexture_t *alphaskytexture;
 extern int skyrendernow, skyrendermasked;
+extern int R_SetSkyBox(char* sky);
 extern void R_SkyStartFrame(void);
 extern void R_Sky(void);
+extern void R_ResetQuakeSky(void);
+extern void R_ResetSkyBox(void);
 
 // SHOWLMP stuff (Nehahra)
 extern void SHOWLMP_decodehide(void);
@@ -79,7 +78,7 @@ void R_FillColors(float *out, int verts, float r, float g, float b, float a);
 
 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;
+extern int             c_alias_polys, c_light_polys, c_faces, c_nodes, c_leafs, c_models, c_bmodels, c_sprites, c_particles, c_dlights;
 
 
 //
index dd71097051c91d188ac44f3a00c23dcb63569e4f..5645c54078b051adcd1cd4b489db1ffafd5e2c57 100644 (file)
--- a/sv_move.c
+++ b/sv_move.c
@@ -51,7 +51,7 @@ qboolean SV_CheckBottom (edict_t *ent)
                {
                        start[0] = x ? maxs[0] : mins[0];
                        start[1] = y ? maxs[1] : mins[1];
-                       if (Mod_PointInLeaf(start, sv.worldmodel)->contents != CONTENTS_SOLID)
+                       if (Mod_PointContents(start, sv.worldmodel) != CONTENTS_SOLID)
                                goto realcheck;
                }
 
@@ -138,7 +138,7 @@ qboolean SV_movestep (edict_t *ent, vec3_t move, qboolean relink)
                        if (trace.fraction == 1)
                        {
                                VectorCopy(trace.endpos, traceendpos);
-                               if ( ((int)ent->v.flags & FL_SWIM) && Mod_PointInLeaf(traceendpos, sv.worldmodel)->contents == CONTENTS_EMPTY )
+                               if ( ((int)ent->v.flags & FL_SWIM) && Mod_PointContents(traceendpos, sv.worldmodel) == CONTENTS_EMPTY )
                                        return false;   // swim monster left water
 
                                VectorCopy (traceendpos, ent->v.origin);
index 94f2bdf0fa4f44f27a5333f2c88203d3ddbadfdb..b89e114dfe21ef2cd8f4c145e069f9e2e4326df1 100644 (file)
--- a/sv_phys.c
+++ b/sv_phys.c
@@ -771,18 +771,18 @@ qboolean SV_CheckWater (edict_t *ent)
 
        ent->v.waterlevel = 0;
        ent->v.watertype = CONTENTS_EMPTY;
-       cont = Mod_PointInLeaf(point, sv.worldmodel)->contents;
+       cont = Mod_PointContents(point, sv.worldmodel);
        if (cont <= CONTENTS_WATER)
        {
                ent->v.watertype = cont;
                ent->v.waterlevel = 1;
                point[2] = ent->v.origin[2] + (ent->v.mins[2] + ent->v.maxs[2])*0.5;
-               cont = Mod_PointInLeaf(point, sv.worldmodel)->contents;
+               cont = Mod_PointContents(point, sv.worldmodel);
                if (cont <= CONTENTS_WATER)
                {
                        ent->v.waterlevel = 2;
                        point[2] = ent->v.origin[2] + ent->v.view_ofs[2];
-                       cont = Mod_PointInLeaf(point, sv.worldmodel)->contents;
+                       cont = Mod_PointContents(point, sv.worldmodel);
                        if (cont <= CONTENTS_WATER)
                                ent->v.waterlevel = 3;
                }
@@ -1135,8 +1135,8 @@ SV_CheckWaterTransition
 */
 void SV_CheckWaterTransition (edict_t *ent)
 {
-       int             cont;
-       cont = Mod_PointInLeaf(ent->v.origin, sv.worldmodel)->contents;
+       int cont;
+       cont = Mod_PointContents(ent->v.origin, sv.worldmodel);
        if (!ent->v.watertype)
        {
                // just spawned here
@@ -1291,7 +1291,7 @@ void SV_Physics_Step (edict_t *ent)
        {
                if (flags & FL_FLY)
                        fall = false;
-               else if ((flags & FL_SWIM) && Mod_PointInLeaf(ent->v.origin, sv.worldmodel)->contents != CONTENTS_EMPTY)
+               else if ((flags & FL_SWIM) && Mod_PointContents(ent->v.origin, sv.worldmodel) != CONTENTS_EMPTY)
                        fall = false;
        }
        if (fall && (flags & FL_ONGROUND) && ent->v.groundentity == 0)
diff --git a/view.c b/view.c
index 4839e64ef1357a55e054ad29fbc5a9108160c907..e50d4ce7519a842acced322b2ad4c57edd12beae 100644 (file)
--- a/view.c
+++ b/view.c
@@ -324,7 +324,7 @@ void V_UpdateBlends (void)
        float   r, g, b, a, a2;
        int             j;
 
-       if (cl.worldmodel == NULL)
+       if (cls.signon != SIGNONS)
        {
                cl.cshifts[CSHIFT_DAMAGE].percent = 0;
                cl.cshifts[CSHIFT_BONUS].percent = 0;
@@ -348,7 +348,7 @@ void V_UpdateBlends (void)
                cl.cshifts[CSHIFT_BONUS].percent = 0;
 
        // set contents color
-       switch (Mod_PointInLeaf (r_refdef.vieworg, cl.worldmodel)->contents)
+       switch (Mod_PointContents (r_refdef.vieworg, cl.worldmodel))
        {
        case CONTENTS_EMPTY:
        case CONTENTS_SOLID:
@@ -478,7 +478,7 @@ void V_CalcRefdef (void)
        float           bob;
        float           side;
 
-       if (cls.state != ca_connected || !cl.worldmodel)
+       if (cls.state != ca_connected || cls.signon != SIGNONS)
                return;
 
        // ent is the player model (visible when out of body)
diff --git a/world.c b/world.c
index a970bdd07975406a8ae80f20f8927bc55b423ade..0dbcb29feee5e2646f8f9a3a07b79e0910aa1962 100644 (file)
--- a/world.c
+++ b/world.c
@@ -34,6 +34,7 @@ cvar_t sv_useareanodes = {CVAR_NOTIFY, "sv_useareanodes", "1"};
 void SV_World_Init(void)
 {
        Cvar_RegisterVariable(&sv_useareanodes);
+       Collision_Init ();
 }
 
 
@@ -179,8 +180,6 @@ SV_ClearWorld
 */
 void SV_ClearWorld (void)
 {
-       Collision_Init ();
-
        memset (sv_areanodes, 0, sizeof(sv_areanodes));
        sv_numareanodes = 0;
        Mod_CheckLoaded(sv.worldmodel);
@@ -290,12 +289,12 @@ void SV_LinkEdict (edict_t *ent, qboolean touch_triggers)
        if (ent->v.solid == SOLID_BSP)
        {
                if (ent->v.modelindex < 0 || ent->v.modelindex > MAX_MODELS)
-                       PR_RunError("SOLID_BSP with invalid modelindex!\n");
+                       Host_Error("SOLID_BSP with invalid modelindex!\n");
                model = sv.models[(int) ent->v.modelindex];
                if (model != NULL)
                {
                        if (model->type != mod_brush)
-                               PR_RunError("SOLID_BSP with non-BSP model\n");
+                               Host_Error("SOLID_BSP with non-BSP model\n");
 
                        if (ent->v.angles[0] || ent->v.angles[2] || ent->v.avelocity[0] || ent->v.avelocity[2])
                        {
@@ -427,10 +426,10 @@ trace_t SV_ClipMoveToEntity (edict_t *ent, vec3_t start, vec3_t mins, vec3_t max
 
        i = ent->v.modelindex;
        if ((unsigned int) i >= MAX_MODELS)
-               PR_RunError("SV_ClipMoveToEntity: invalid modelindex\n");
+               Host_Error("SV_ClipMoveToEntity: invalid modelindex\n");
        model = sv.models[i];
        if (i != 0 && model == NULL)
-               PR_RunError("SV_ClipMoveToEntity: invalid modelindex\n");
+               Host_Error("SV_ClipMoveToEntity: invalid modelindex\n");
 
        if ((int) ent->v.solid == SOLID_BSP)
        {