]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - cl_parse.c
fixed BIH line clipping and enabled it, BIH is now faster than BSP
[xonotic/darkplaces.git] / cl_parse.c
index bee2cb533c4d08efcbca02f4ce858b439c79dcb7..d5c66b79daebcab9bbb1b3559e1ccb03574cb378 100644 (file)
@@ -24,6 +24,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 #include "cl_collision.h"
 #include "csprogs.h"
 #include "libcurl.h"
+#include "utf8lib.h"
 
 char *svc_strings[128] =
 {
@@ -391,10 +392,12 @@ void CL_ParseEntityLump(char *entdata)
                        r_refdef.fog_start = 0;
                        r_refdef.fog_alpha = 1;
                        r_refdef.fog_end = 16384;
+                       r_refdef.fog_height = 1<<30;
+                       r_refdef.fog_fadedepth = 128;
 #if _MSC_VER >= 1400
 #define sscanf sscanf_s
 #endif
-                       sscanf(value, "%f %f %f %f %f %f %f", &r_refdef.fog_density, &r_refdef.fog_red, &r_refdef.fog_green, &r_refdef.fog_blue, &r_refdef.fog_alpha, &r_refdef.fog_start, &r_refdef.fog_end);
+                       sscanf(value, "%f %f %f %f %f %f %f %f %f", &r_refdef.fog_density, &r_refdef.fog_red, &r_refdef.fog_green, &r_refdef.fog_blue, &r_refdef.fog_alpha, &r_refdef.fog_start, &r_refdef.fog_end, &r_refdef.fog_height, &r_refdef.fog_fadedepth);
                }
                else if (!strcmp("fog_density", key))
                        r_refdef.fog_density = atof(value);
@@ -410,6 +413,10 @@ void CL_ParseEntityLump(char *entdata)
                        r_refdef.fog_start = atof(value);
                else if (!strcmp("fog_end", key))
                        r_refdef.fog_end = atof(value);
+               else if (!strcmp("fog_height", key))
+                       r_refdef.fog_height = atof(value);
+               else if (!strcmp("fog_fadedepth", key))
+                       r_refdef.fog_fadedepth = atof(value);
        }
 }
 
@@ -420,7 +427,7 @@ static const vec3_t defaultmaxs = {4096, 4096, 4096};
 static void CL_SetupWorldModel(void)
 {
        // update the world model
-       cl.entities[0].render.model = cl.worldmodel = cl.model_precache[1];
+       cl.entities[0].render.model = cl.worldmodel = CL_GetModelByIndex(1);
        CL_UpdateRenderEntity(&cl.entities[0].render);
 
        // set up csqc world for collision culling
@@ -428,6 +435,7 @@ static void CL_SetupWorldModel(void)
                World_SetSize(&cl.world, cl.worldmodel->name, cl.worldmodel->normalmins, cl.worldmodel->normalmaxs);
        else
                World_SetSize(&cl.world, "", defaultmins, defaultmaxs);
+       World_Start(&cl.world);
 
        // load or reload .loc file for team chat messages
        CL_Locs_Reload_f();
@@ -1299,9 +1307,18 @@ void CL_StopDownload(int size, int crc)
                        size_t inflated_size;
                        out = FS_Inflate(cls.qw_downloadmemory, cls.qw_downloadmemorycursize, &inflated_size, tempmempool);
                        Mem_Free(cls.qw_downloadmemory);
-                       Con_Printf("Inflated download: new size: %u (%g%%)\n", (unsigned)inflated_size, 100.0 - 100.0*(cls.qw_downloadmemorycursize / (float)inflated_size));
-                       cls.qw_downloadmemory = out;
-                       cls.qw_downloadmemorycursize = inflated_size;
+                       if(out)
+                       {
+                               Con_Printf("Inflated download: new size: %u (%g%%)\n", (unsigned)inflated_size, 100.0 - 100.0*(cls.qw_downloadmemorycursize / (float)inflated_size));
+                               cls.qw_downloadmemory = out;
+                               cls.qw_downloadmemorycursize = inflated_size;
+                       }
+                       else
+                       {
+                               cls.qw_downloadmemory = NULL;
+                               cls.qw_downloadmemorycursize = 0;
+                               Con_Printf("Cannot inflate download, possibly corrupt or zlib not present\n");
+                       }
                }
 
                if(!cls.qw_downloadmemory)
@@ -1364,7 +1381,7 @@ void CL_StopDownload(int size, int crc)
 void CL_ParseDownload(void)
 {
        int i, start, size;
-       unsigned char data[65536];
+       static unsigned char data[NET_MAXMESSAGE];
        start = MSG_ReadLong();
        size = (unsigned short)MSG_ReadShort();
 
@@ -1492,8 +1509,7 @@ An svc_signonnum has been received, perform a client side setup
 */
 static void CL_SignonReply (void)
 {
-       if (developer.integer >= 100)
-               Con_Printf("CL_SignonReply: %i\n", cls.signon);
+       Con_DPrintf("CL_SignonReply: %i\n", cls.signon);
 
        switch (cls.signon)
        {
@@ -1653,7 +1669,7 @@ void CL_ParseServerInfo (void)
                cl.movevars_airaccel_sideways_friction = 0;
 
                // seperate the printfs so the server message can have a color
-               Con_Printf("\n\n\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\37\n\n\2%s\n", str);
+               Con_Printf("\n\n<===================================>\n\n\2%s\n", str);
 
                // check memory integrity
                Mem_CheckSentinelsGlobal();
@@ -1698,7 +1714,7 @@ void CL_ParseServerInfo (void)
 
        // seperate the printfs so the server message can have a color
                if (cls.protocol != PROTOCOL_NEHAHRAMOVIE) // no messages when playing the Nehahra movie
-                       Con_Printf("\n\n\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\37\n\n\2%s\n", str);
+                       Con_Printf("\n<===================================>\n\n\2%s\n", str);
 
                // check memory integrity
                Mem_CheckSentinelsGlobal();
@@ -1830,7 +1846,7 @@ void CL_ValidateState(entity_state_t *s)
        if (!(s->flags & RENDER_COLORMAPPED) && s->colormap > cl.maxclients)
                Con_DPrintf("CL_ValidateState: colormap (%i) > cl.maxclients (%i)\n", s->colormap, cl.maxclients);
 
-       model = cl.model_precache[s->modelindex];
+       model = CL_GetModelByIndex(s->modelindex);
        if (model && model->type && s->frame >= model->numframes)
                Con_DPrintf("CL_ValidateState: no such frame %i in \"%s\" (which has %i frames)\n", s->frame, model->name, model->numframes);
        if (model && model->type && s->skin > 0 && s->skin >= model->numskins && !(s->lightpflags & PFLAGS_FULLDYNAMIC))
@@ -1883,6 +1899,14 @@ void CL_MoveLerpEntityStates(entity_t *ent)
 
                // note that this case must do everything the following case does too
        }
+       else if ((ent->state_previous.effects & EF_RESTARTANIM_BIT) != (ent->state_current.effects & EF_RESTARTANIM_BIT))
+       {
+               ent->render.framegroupblend[1] = ent->render.framegroupblend[0];
+               ent->render.framegroupblend[1].lerp = 1;
+               ent->render.framegroupblend[0].frame = ent->state_current.frame;
+               ent->render.framegroupblend[0].start = cl.time;
+               ent->render.framegroupblend[0].lerp = 0;
+       }
        else if (DotProduct(odelta, odelta) > 1000*1000
                || (cl.fixangle[0] && !cl.fixangle[1])
                || (ent->state_previous.tagindex != ent->state_current.tagindex)
@@ -2115,7 +2139,7 @@ void CL_ParseStatic (int large)
        }
 
 // copy it to the current state
-       ent->render.model = cl.model_precache[ent->state_baseline.modelindex];
+       ent->render.model = CL_GetModelByIndex(ent->state_baseline.modelindex);
        ent->render.framegroupblend[0].frame = ent->state_baseline.frame;
        ent->render.framegroupblend[0].lerp = 1;
        // make torchs play out of sync
@@ -2128,6 +2152,7 @@ void CL_ParseStatic (int large)
        //VectorCopy (ent->state_baseline.angles, ent->render.angles);
 
        Matrix4x4_CreateFromQuakeEntity(&ent->render.matrix, ent->state_baseline.origin[0], ent->state_baseline.origin[1], ent->state_baseline.origin[2], ent->state_baseline.angles[0], ent->state_baseline.angles[1], ent->state_baseline.angles[2], 1);
+       ent->render.allowdecals = true;
        CL_UpdateRenderEntity(&ent->render);
 }
 
@@ -2823,8 +2848,8 @@ static void CL_IPLog_Add(const char *address, const char *name, qboolean checkex
                return;
        if (!cl_iplog_loaded)
                CL_IPLog_Load();
-       if (developer.integer >= 100)
-               Con_Printf("CL_IPLog_Add(\"%s\", \"%s\", %i, %i);\n", address, name, checkexisting, addtofile);
+       if (developer_extra.integer)
+               Con_DPrintf("CL_IPLog_Add(\"%s\", \"%s\", %i, %i);\n", address, name, checkexisting, addtofile);
        // see if it already exists
        if (checkexisting)
        {
@@ -2832,8 +2857,8 @@ static void CL_IPLog_Add(const char *address, const char *name, qboolean checkex
                {
                        if (!strcmp(cl_iplog_items[i].address, address) && !strcmp(cl_iplog_items[i].name, name))
                        {
-                               if (developer.integer >= 100)
-                                       Con_Printf("... found existing \"%s\" \"%s\"\n", cl_iplog_items[i].address, cl_iplog_items[i].name);
+                               if (developer_extra.integer)
+                                       Con_DPrintf("... found existing \"%s\" \"%s\"\n", cl_iplog_items[i].address, cl_iplog_items[i].name);
                                return;
                        }
                }
@@ -2864,8 +2889,8 @@ static void CL_IPLog_Add(const char *address, const char *name, qboolean checkex
                // TODO: this ought to open the one in the userpath version of the base
                // gamedir, not the current gamedir
                Log_Printf(cl_iplog_name.string, "%s %s\n", address, name);
-               if (developer.integer >= 100)
-                       Con_Printf("CL_IPLog_Add: appending this line to %s: %s %s\n", cl_iplog_name.string, address, name);
+               if (developer_extra.integer)
+                       Con_DPrintf("CL_IPLog_Add: appending this line to %s: %s %s\n", cl_iplog_name.string, address, name);
        }
 }
 
@@ -2985,7 +3010,7 @@ qboolean CL_ExaminePrintString(const char *text)
        if (cl.parsingtextmode == CL_PARSETEXTMODE_PING)
        {
                // if anything goes wrong, we'll assume this is not a ping report
-               qboolean expected = cl.parsingtextexpectingpingforscores;
+               qboolean expected = cl.parsingtextexpectingpingforscores != 0;
                cl.parsingtextexpectingpingforscores = 0;
                cl.parsingtextmode = CL_PARSETEXTMODE_NONE;
                t = text;
@@ -3103,7 +3128,7 @@ static void CL_NetworkTimeReceived(double newtime)
        double timehigh;
        cl.mtime[1] = cl.mtime[0];
        cl.mtime[0] = newtime;
-       if (cls.timedemo || (cl.islocalgame && !sv_fixedframeratesingleplayer.integer) || cl.mtime[1] == cl.mtime[0] || cls.signon < SIGNONS)
+       if (cl_nolerp.integer || cls.timedemo || (cl.islocalgame && !sv_fixedframeratesingleplayer.integer) || cl.mtime[1] == cl.mtime[0] || cls.signon < SIGNONS)
                cl.time = cl.mtime[1] = newtime;
        else if (cls.demoplayback)
        {
@@ -3116,12 +3141,12 @@ static void CL_NetworkTimeReceived(double newtime)
        else if (cls.protocol != PROTOCOL_QUAKEWORLD)
        {
                cl.mtime[1] = max(cl.mtime[1], cl.mtime[0] - 0.1);
-               if (developer.integer >= 100 && vid_activewindow)
+               if (developer_extra.integer && vid_activewindow)
                {
                        if (cl.time < cl.mtime[1] - (cl.mtime[0] - cl.mtime[1]))
-                               Con_Printf("--- cl.time < cl.mtime[1] (%f < %f ... %f)\n", cl.time, cl.mtime[1], cl.mtime[0]);
+                               Con_DPrintf("--- cl.time < cl.mtime[1] (%f < %f ... %f)\n", cl.time, cl.mtime[1], cl.mtime[0]);
                        else if (cl.time > cl.mtime[0] + (cl.mtime[0] - cl.mtime[1]))
-                               Con_Printf("--- cl.time > cl.mtime[0] (%f > %f ... %f)\n", cl.time, cl.mtime[1], cl.mtime[0]);
+                               Con_DPrintf("--- cl.time > cl.mtime[0] (%f > %f ... %f)\n", cl.time, cl.mtime[1], cl.mtime[0]);
                }
                cl.time += (cl.mtime[1] - cl.time) * bound(0, cl_nettimesyncfactor.value, 1);
                timehigh = cl.mtime[1] + (cl.mtime[0] - cl.mtime[1]) * cl_nettimesyncboundtolerance.value;
@@ -3177,6 +3202,9 @@ static void CL_NetworkTimeReceived(double newtime)
                VectorCopy(cl.mviewangles[0], cl.mviewangles[1]);
        // update the csqc's server timestamps, critical for proper sync
        CSQC_UpdateNetworkTimes(cl.mtime[0], cl.mtime[1]);
+
+       if (cl.mtime[0] > cl.mtime[1])
+               World_Physics_Frame(&cl.world, cl.mtime[0] - cl.mtime[1], cl.movevars_gravity);
 }
 
 #define SHOWNET(x) if(cl_shownet.integer==2)Con_Printf("%3i:%s(%i)\n", msg_readcount-1, x, cmd);
@@ -3204,6 +3232,7 @@ void CL_ParseServerMessage(void)
        char            *cmdlogname[32], *temp;
        int                     cmdindex, cmdcount = 0;
        qboolean        qwplayerupdatereceived;
+       qboolean        strip_pqc;
 
        // LordHavoc: moved demo message writing from before the packet parse to
        // after the packet parse so that CL_Stop_f can be called by cl_autodemo
@@ -3567,7 +3596,7 @@ void CL_ParseServerMessage(void)
                                break;
 
                        case qw_svc_setpause:
-                               cl.paused = MSG_ReadByte ();
+                               cl.paused = MSG_ReadByte () != 0;
                                if (cl.paused)
                                        CDAudio_Pause ();
                                else
@@ -3700,7 +3729,42 @@ void CL_ParseServerMessage(void)
                                break;
 
                        case svc_stufftext:
-                               CL_VM_Parse_StuffCmd(MSG_ReadString ());        //[515]: csqc
+                               temp = MSG_ReadString();
+                               /* if(utf8_enable.integer)
+                               {
+                                       strip_pqc = true;
+                                       // we can safely strip and even
+                                       // interpret these in utf8 mode
+                               }
+                               else */ switch(cls.protocol)
+                               {
+                                       case PROTOCOL_QUAKE:
+                                       case PROTOCOL_QUAKEDP:
+                                               // maybe add other protocols if
+                                               // so desired, but not DP7
+                                               strip_pqc = true;
+                                               break;
+                                       case PROTOCOL_DARKPLACES7:
+                                       default:
+                                               // ProQuake does not support
+                                               // these protocols
+                                               strip_pqc = false;
+                                               break;
+                               }
+                               if(strip_pqc)
+                               {
+                                       // skip over ProQuake messages,
+                                       // TODO actually interpret them
+                                       // (they are sbar team score
+                                       // updates), see proquake cl_parse.c
+                                       if(*temp == 0x01)
+                                       {
+                                               ++temp;
+                                               while(*temp >= 0x01 && *temp <= 0x1F)
+                                                       ++temp;
+                                       }
+                               }
+                               CL_VM_Parse_StuffCmd(temp);     //[515]: csqc
                                break;
 
                        case svc_damage:
@@ -3858,7 +3922,7 @@ void CL_ParseServerMessage(void)
                                break;
 
                        case svc_setpause:
-                               cl.paused = MSG_ReadByte ();
+                               cl.paused = MSG_ReadByte () != 0;
                                if (cl.paused)
                                        CDAudio_Pause ();
                                else