X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fdarkplaces.git;a=blobdiff_plain;f=cl_parse.c;h=dcde8eb1607e060f1bd748eb06eb6076f8c71152;hp=a0d340b276b2634cc03816ec48ef15dca9673d49;hb=e267b18ea5e1e6ab71b14db5a12a803cd0554421;hpb=810077aff6c99517dbd4e112d1f5f184745d1a33 diff --git a/cl_parse.c b/cl_parse.c index a0d340b2..dcde8eb1 100644 --- a/cl_parse.c +++ b/cl_parse.c @@ -25,8 +25,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "csprogs.h" #include "libcurl.h" #include "utf8lib.h" +#include "menu.h" +#include "cl_video.h" -char *svc_strings[128] = +const char *svc_strings[128] = { "svc_bad", "svc_nop", @@ -100,7 +102,7 @@ char *svc_strings[128] = "svc_pointparticles1", // 62 // [short] effectnum [vector] start, same as svc_pointparticles except velocity is zero and count is 1 }; -char *qw_svc_strings[128] = +const char *qw_svc_strings[128] = { "qw_svc_bad", // 0 "qw_svc_nop", // 1 @@ -165,7 +167,6 @@ cvar_t cl_worldname = {CVAR_READONLY, "cl_worldname", "", "name of current world cvar_t cl_worldnamenoextension = {CVAR_READONLY, "cl_worldnamenoextension", "", "name of current worldmodel without extension"}; cvar_t cl_worldbasename = {CVAR_READONLY, "cl_worldbasename", "", "name of current worldmodel without maps/ prefix or extension"}; -cvar_t demo_nehahra = {0, "demo_nehahra", "0", "reads all quake demos as nehahra movie protocol"}; cvar_t developer_networkentities = {0, "developer_networkentities", "0", "prints received entities, value is 0-4 (higher for more info)"}; cvar_t cl_gameplayfix_soundsmovewithentities = {0, "cl_gameplayfix_soundsmovewithentities", "1", "causes sounds made by lifts, players, projectiles, and any other entities, to move with the entity, so for example a rocket noise follows the rocket rather than staying at the starting position"}; cvar_t cl_sound_wizardhit = {0, "cl_sound_wizardhit", "wizard/hit.wav", "sound to play during TE_WIZSPIKE (empty cvar disables sound)"}; @@ -193,8 +194,8 @@ static void QW_CL_NextUpload(void); void QW_CL_StartUpload(unsigned char *data, int size); //static qboolean QW_CL_IsUploading(void); static void QW_CL_StopUpload(void); -void CL_VM_UpdateIntermissionState(int intermission); -qboolean CL_VM_Event_Sound(int sound_num, float volume, int channel, float attenuation, int ent, vec3_t pos); +extern void CL_VM_UpdateIntermissionState(int intermission); +extern qboolean CL_VM_Event_Sound(int sound_num, float volume, int channel, float attenuation, int ent, vec3_t pos, int flags, float speed); /* ================== @@ -209,6 +210,8 @@ void CL_ParseStartSoundPacket(int largesoundindex) int volume; int field_mask; float attenuation; + float speed; + int fflags = CHANNELFLAG_NONE; if (cls.protocol == PROTOCOL_QUAKEWORLD) { @@ -223,6 +226,8 @@ void CL_ParseStartSoundPacket(int largesoundindex) attenuation = MSG_ReadByte () / 64.0; else attenuation = DEFAULT_SOUND_PACKET_ATTENUATION; + + speed = 1.0f; ent = (channel>>3)&1023; channel &= 7; @@ -243,10 +248,15 @@ void CL_ParseStartSoundPacket(int largesoundindex) else attenuation = DEFAULT_SOUND_PACKET_ATTENUATION; + if (field_mask & SND_SPEEDUSHORT4000) + speed = ((unsigned short)MSG_ReadShort ()) / 4000.0f; + else + speed = 1.0f; + if (field_mask & SND_LARGEENTITY) { ent = (unsigned short) MSG_ReadShort (); - channel = MSG_ReadByte (); + channel = MSG_ReadChar (); } else { @@ -261,6 +271,8 @@ void CL_ParseStartSoundPacket(int largesoundindex) sound_num = MSG_ReadByte (); } + channel = CHAN_NET2ENGINE(channel); + MSG_ReadVector(pos, cls.protocol); if (sound_num >= MAX_SOUNDS) @@ -278,8 +290,8 @@ void CL_ParseStartSoundPacket(int largesoundindex) if (ent >= cl.max_entities) CL_ExpandEntities(ent); - if( !CL_VM_Event_Sound(sound_num, volume / 255.0f, channel, attenuation, ent, pos) ) - S_StartSound (ent, channel, cl.sound_precache[sound_num], pos, volume/255.0f, attenuation); + if( !CL_VM_Event_Sound(sound_num, volume / 255.0f, channel, attenuation, ent, pos, fflags, speed) ) + S_StartSound_StartPosition_Flags (ent, channel, cl.sound_precache[sound_num], pos, volume/255.0f, attenuation, 0, fflags, speed); } /* @@ -294,6 +306,7 @@ so the server doesn't disconnect. static unsigned char olddata[NET_MAXMESSAGE]; void CL_KeepaliveMessage (qboolean readmessages) { + static qboolean recursive = false; float time; static double nextmsg = -1; static double nextupdate = -1; @@ -304,18 +317,29 @@ void CL_KeepaliveMessage (qboolean readmessages) qboolean oldbadread; sizebuf_t old; - if(cls.state != ca_dedicated) + qboolean thisrecursive; + + thisrecursive = recursive; + recursive = true; + + if(!thisrecursive) { - if((time = Sys_DoubleTime()) >= nextupdate) + if(cls.state != ca_dedicated) { - SCR_UpdateLoadingScreenIfShown(); - nextupdate = time + 2; + if((time = Sys_DoubleTime()) >= nextupdate) + { + SCR_UpdateLoadingScreenIfShown(); + nextupdate = time + 2; + } } } // no need if server is local and definitely not if this is a demo if (!cls.netcon || cls.protocol == PROTOCOL_QUAKEWORLD || cls.signon >= SIGNONS) + { + recursive = thisrecursive; return; + } if (readmessages) { @@ -355,6 +379,8 @@ void CL_KeepaliveMessage (qboolean readmessages) MSG_WriteChar(&msg, clc_nop); NetConn_SendUnreliableMessage(cls.netcon, &msg, cls.protocol, 10000, false); } + + recursive = thisrecursive; } void CL_ParseEntityLump(char *entdata) @@ -452,7 +478,7 @@ static void CL_SetupWorldModel(void) { strlcpy(cl.worldname, cl.worldmodel->name, sizeof(cl.worldname)); FS_StripExtension(cl.worldname, cl.worldnamenoextension, sizeof(cl.worldnamenoextension)); - strlcpy(cl.worldbasename, !strncmp(cl.worldnamenoextension, "maps/", 5) ? cl.worldnamenoextension + 4 : cl.worldnamenoextension, sizeof(cl.worldbasename)); + strlcpy(cl.worldbasename, !strncmp(cl.worldnamenoextension, "maps/", 5) ? cl.worldnamenoextension + 5 : cl.worldnamenoextension, sizeof(cl.worldbasename)); Cvar_SetQuick(&cl_worldmessage, cl.worldmessage); Cvar_SetQuick(&cl_worldname, cl.worldname); Cvar_SetQuick(&cl_worldnamenoextension, cl.worldnamenoextension); @@ -486,6 +512,9 @@ static void CL_SetupWorldModel(void) // check memory integrity Mem_CheckSentinelsGlobal(); + // make menu know + MR_NewMap(); + // load the csqc now if (cl.loadcsqc) { @@ -1190,13 +1219,13 @@ void CL_BeginDownloads(qboolean aborteddownload) // finished loading sounds } - if(gamemode == GAME_NEXUIZ) + if(gamemode == GAME_NEXUIZ || gamemode == GAME_XONOTIC) Cvar_SetValueQuick(&cl_serverextension_download, false); - // in Nexuiz, the built in download protocol is kinda broken (misses lots + // in Nexuiz/Xonotic, the built in download protocol is kinda broken (misses lots // of dependencies) anyway, and can mess around with the game directory; // until this is fixed, only support pk3 downloads via curl, and turn off // individual file downloads other than for CSQC - // on the other end of the download protocol, GAME_NEXUIZ enforces writing + // on the other end of the download protocol, GAME_NEXUIZ/GAME_XONOTIC enforces writing // to dlcache only // idea: support download of pk3 files using this protocol later @@ -1252,7 +1281,7 @@ void CL_BeginDownloads(qboolean aborteddownload) Mod_FreeQ3Shaders(); } - cl.model_precache[cl.downloadmodel_current] = Mod_ForName(cl.model_name[cl.downloadmodel_current], false, false, cl.model_name[cl.downloadmodel_current][0] == '*' ? cl.model_name[1] : NULL); + cl.model_precache[cl.downloadmodel_current] = Mod_ForName(cl.model_name[cl.downloadmodel_current], false, true, cl.model_name[cl.downloadmodel_current][0] == '*' ? cl.model_name[1] : NULL); if (cl.downloadmodel_current == 1) { // we now have the worldmodel so we can set up the game world @@ -1369,8 +1398,8 @@ void CL_StopDownload(int size, int crc) // save to disk only if we don't already have it // (this is mainly for playing back demos) existingcrc = FS_CRCFile(cls.qw_downloadname, &existingsize); - if (existingsize || gamemode == GAME_NEXUIZ || !strcmp(cls.qw_downloadname, csqc_progname.string)) - // let csprogs ALWAYS go to dlcache, to prevent "viral csprogs"; also, never put files outside dlcache for Nexuiz + if (existingsize || gamemode == GAME_NEXUIZ || gamemode == GAME_XONOTIC || !strcmp(cls.qw_downloadname, csqc_progname.string)) + // let csprogs ALWAYS go to dlcache, to prevent "viral csprogs"; also, never put files outside dlcache for Nexuiz/Xonotic { if ((int)existingsize != size || existingcrc != crc) { @@ -1616,7 +1645,11 @@ void CL_ParseServerInfo (void) protocolversion_t protocol; int nummodels, numsounds; + // if we start loading a level and a video is still playing, stop it + CL_VideoStop(); + Con_DPrint("Serverinfo packet received.\n"); + Collision_Cache_Reset(true); // if server is active, we already began a loading plaque if (!sv.active) @@ -1647,7 +1680,7 @@ void CL_ParseServerInfo (void) return; } // hack for unmarked Nehahra movie demos which had a custom protocol - if (protocol == PROTOCOL_QUAKEDP && cls.demoplayback && demo_nehahra.integer) + if (protocol == PROTOCOL_QUAKEDP && cls.demoplayback && gamemode == GAME_NEHAHRA) protocol = PROTOCOL_NEHAHRAMOVIE; cls.protocol = protocol; Con_DPrintf("Server protocol is %s\n", Protocol_NameForEnum(cls.protocol)); @@ -1794,7 +1827,7 @@ void CL_ParseServerInfo (void) // set the base name for level-specific things... this gets updated again by CL_SetupWorldModel later strlcpy(cl.worldname, cl.model_name[1], sizeof(cl.worldname)); FS_StripExtension(cl.worldname, cl.worldnamenoextension, sizeof(cl.worldnamenoextension)); - strlcpy(cl.worldbasename, FS_FileWithoutPath(cl.worldnamenoextension), sizeof(cl.worldbasename)); + strlcpy(cl.worldbasename, !strncmp(cl.worldnamenoextension, "maps/", 5) ? cl.worldnamenoextension + 5 : cl.worldnamenoextension, sizeof(cl.worldbasename)); Cvar_SetQuick(&cl_worldmessage, cl.worldmessage); Cvar_SetQuick(&cl_worldname, cl.worldname); Cvar_SetQuick(&cl_worldnamenoextension, cl.worldnamenoextension); @@ -1905,11 +1938,14 @@ 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_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)) - Con_DPrintf("CL_ValidateState: no such skin %i in \"%s\" (which has %i skins)\n", s->skin, model->name, model->numskins); + if (developer_extra.integer) + { + 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)) + Con_DPrintf("CL_ValidateState: no such skin %i in \"%s\" (which has %i skins)\n", s->skin, model->name, model->numskins); + } } void CL_MoveLerpEntityStates(entity_t *ent) @@ -2012,6 +2048,16 @@ void CL_MoveLerpEntityStates(entity_t *ent) // trigger muzzleflash effect if necessary if (ent->state_current.effects & EF_MUZZLEFLASH) ent->persistent.muzzleflash = 1; + + // restart animation bit + 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; + } } /* @@ -2864,7 +2910,7 @@ void CL_ParseTrailParticles(void) effectindex = (unsigned short)MSG_ReadShort(); MSG_ReadVector(start, cls.protocol); MSG_ReadVector(end, cls.protocol); - CL_ParticleEffect(effectindex, VectorDistance(start, end), start, end, vec3_origin, vec3_origin, entityindex > 0 ? cl.entities + entityindex : NULL, 0); + CL_ParticleEffect(effectindex, 1, start, end, vec3_origin, vec3_origin, entityindex > 0 ? cl.entities + entityindex : NULL, 0); } void CL_ParsePointParticles(void) @@ -3181,6 +3227,7 @@ qboolean CL_ExaminePrintString(const char *text) } extern cvar_t slowmo; +extern cvar_t cl_lerpexcess; extern void CSQC_UpdateNetworkTimes(double newtime, double oldtime); static void CL_NetworkTimeReceived(double newtime) { @@ -3264,6 +3311,20 @@ static void CL_NetworkTimeReceived(double newtime) if (cl.mtime[0] > cl.mtime[1]) World_Physics_Frame(&cl.world, cl.mtime[0] - cl.mtime[1], cl.movevars_gravity); + + // only lerp entities that also get an update in this frame, when lerp excess is used + if(cl_lerpexcess.value > 0) + { + int i; + for (i = 1;i < cl.num_entities;i++) + { + if (cl.entities_active[i]) + { + entity_t *ent = cl.entities + i; + ent->persistent.lerpdeltatime = 0; + } + } + } } #define SHOWNET(x) if(cl_shownet.integer==2)Con_Printf("%3i:%s(%i)\n", msg_readcount-1, x, cmd); @@ -3288,7 +3349,7 @@ void CL_ParseServerMessage(void) int i; protocolversion_t protocol; unsigned char cmdlog[32]; - char *cmdlogname[32], *temp; + const char *cmdlogname[32], *temp; int cmdindex, cmdcount = 0; qboolean qwplayerupdatereceived; qboolean strip_pqc; @@ -3557,7 +3618,7 @@ void CL_ParseServerMessage(void) break; case qw_svc_sellscreen: - Cmd_ExecuteString ("help", src_command); + Cmd_ExecuteString ("help", src_command, true); break; case qw_svc_smallkick: @@ -3765,7 +3826,7 @@ void CL_ParseServerMessage(void) if (protocol == PROTOCOL_UNKNOWN) Host_Error("CL_ParseServerMessage: Server is unrecognized protocol number (%i)", i); // hack for unmarked Nehahra movie demos which had a custom protocol - if (protocol == PROTOCOL_QUAKEDP && cls.demoplayback && demo_nehahra.integer) + if (protocol == PROTOCOL_QUAKEDP && cls.demoplayback && gamemode == GAME_NEHAHRA) protocol = PROTOCOL_NEHAHRAMOVIE; cls.protocol = protocol; break; @@ -4063,7 +4124,7 @@ void CL_ParseServerMessage(void) break; case svc_sellscreen: - Cmd_ExecuteString ("help", src_command); + Cmd_ExecuteString ("help", src_command, true); break; case svc_hidelmp: if (gamemode == GAME_TENEBRAE) @@ -4075,7 +4136,7 @@ void CL_ParseServerMessage(void) MSG_ReadCoord(cls.protocol); MSG_ReadCoord(cls.protocol); MSG_ReadCoord(cls.protocol); - MSG_ReadByte(); + (void) MSG_ReadByte(); MSG_ReadLong(); MSG_ReadLong(); MSG_ReadString(); @@ -4090,7 +4151,7 @@ void CL_ParseServerMessage(void) MSG_ReadCoord(cls.protocol); MSG_ReadCoord(cls.protocol); MSG_ReadCoord(cls.protocol); - MSG_ReadByte(); + (void) MSG_ReadByte(); MSG_ReadString(); } else @@ -4176,10 +4237,6 @@ void CL_Parse_Init(void) Cvar_RegisterVariable(&cl_worldnamenoextension); Cvar_RegisterVariable(&cl_worldbasename); - // LordHavoc: added demo_nehahra cvar - Cvar_RegisterVariable (&demo_nehahra); - if (gamemode == GAME_NEHAHRA) - Cvar_SetValue("demo_nehahra", 1); Cvar_RegisterVariable(&developer_networkentities); Cvar_RegisterVariable(&cl_gameplayfix_soundsmovewithentities);