diff --git a/engine/client/cl_demo.c b/engine/client/cl_demo.c index 27e07f815..d9e9c9eda 100644 --- a/engine/client/cl_demo.c +++ b/engine/client/cl_demo.c @@ -1054,6 +1054,7 @@ void CL_Record_f (void) memset(&buf, 0, sizeof(buf)); buf.data = buf_data; buf.maxsize = sizeof(buf_data); + buf.prim = cls.netchan.netprim; // send the serverdata MSG_WriteByte (&buf, svc_serverdata); @@ -1289,9 +1290,21 @@ void CL_Record_f (void) if (!*cl_lightstyle[i].map) continue; - MSG_WriteByte (&buf, svc_lightstyle); - MSG_WriteByte (&buf, (char)i); - MSG_WriteString (&buf, cl_lightstyle[i].map); +#ifdef PEXT_LIGHTSTYLECOL + if ((cls.fteprotocolextensions & PEXT_LIGHTSTYLECOL) && cl_lightstyle[i].colour!=7) + { + MSG_WriteByte (&buf, svcfte_lightstylecol); + MSG_WriteByte (&buf, (unsigned char)i); + MSG_WriteByte (&buf, cl_lightstyle[i].colour); + MSG_WriteString (&buf, cl_lightstyle[i].map); + } + else +#endif + { + MSG_WriteByte (&buf, svc_lightstyle); + MSG_WriteByte (&buf, (unsigned char)i); + MSG_WriteString (&buf, cl_lightstyle[i].map); + } } for (i = ((cls.fteprotocolextensions&PEXT_HEXEN2)?MAX_QW_STATS:MAX_CL_STATS); i >= 0; i--) diff --git a/engine/client/cl_ents.c b/engine/client/cl_ents.c index 9fa0538b8..8f3c936b7 100644 --- a/engine/client/cl_ents.c +++ b/engine/client/cl_ents.c @@ -382,33 +382,33 @@ void CL_ParseDelta (entity_state_t *from, entity_state_t *to, int bits, qboolean } #ifdef PEXT_SCALE - if (morebits & U_SCALE && cls.fteprotocolextensions & PEXT_SCALE) + if ((morebits & U_SCALE) && (cls.fteprotocolextensions & PEXT_SCALE)) to->scale = MSG_ReadByte(); #endif #ifdef PEXT_TRANS - if (morebits & U_TRANS && cls.fteprotocolextensions & PEXT_TRANS) + if ((morebits & U_TRANS) && (cls.fteprotocolextensions & PEXT_TRANS)) to->trans = MSG_ReadByte(); #endif #ifdef PEXT_FATNESS - if (morebits & U_FATNESS && cls.fteprotocolextensions & PEXT_FATNESS) + if ((morebits & U_FATNESS) && (cls.fteprotocolextensions & PEXT_FATNESS)) to->fatness = MSG_ReadChar(); #endif - if (morebits & U_DRAWFLAGS && cls.fteprotocolextensions & PEXT_HEXEN2) + if ((morebits & U_DRAWFLAGS) && (cls.fteprotocolextensions & PEXT_HEXEN2)) to->hexen2flags = MSG_ReadByte(); - if (morebits & U_ABSLIGHT && cls.fteprotocolextensions & PEXT_HEXEN2) + if ((morebits & U_ABSLIGHT) && (cls.fteprotocolextensions & PEXT_HEXEN2)) to->abslight = MSG_ReadByte(); - if (morebits & U_COLOURMOD && cls.fteprotocolextensions & PEXT_COLOURMOD) + if ((morebits & U_COLOURMOD) && (cls.fteprotocolextensions & PEXT_COLOURMOD)) { to->colormod[0] = MSG_ReadByte(); to->colormod[1] = MSG_ReadByte(); to->colormod[2] = MSG_ReadByte(); } - if (morebits & U_ENTITYDBL && cls.fteprotocolextensions & PEXT_ENTITYDBL) + if ((morebits & U_ENTITYDBL) && (cls.fteprotocolextensions & PEXT_ENTITYDBL)) to->number += 512; - if (morebits & U_ENTITYDBL2 && cls.fteprotocolextensions & PEXT_ENTITYDBL2) + if ((morebits & U_ENTITYDBL2) && (cls.fteprotocolextensions & PEXT_ENTITYDBL2)) to->number += 1024; if (morebits & U_DPFLAGS)// && cls.fteprotocolextensions & PEXT_DPFLAGS) diff --git a/engine/client/cl_parse.c b/engine/client/cl_parse.c index 6d29dc5b6..52a995aec 100644 --- a/engine/client/cl_parse.c +++ b/engine/client/cl_parse.c @@ -3200,7 +3200,7 @@ void CL_ParseBaseline2 (void) { entity_state_t es; - CL_ParseDelta(&nullentitystate, &es, MSG_ReadShort(), true); + CL_ParseDelta(&nullentitystate, &es, (unsigned short)MSG_ReadShort(), true); if (!CL_CheckBaselines(es.number)) Host_EndGame("CL_ParseBaseline2: check baselines failed with size %i", es.number); memcpy(cl_baselines + es.number, &es, sizeof(es)); diff --git a/engine/client/pr_csqc.c b/engine/client/pr_csqc.c index 4ba8584af..f63ce8953 100644 --- a/engine/client/pr_csqc.c +++ b/engine/client/pr_csqc.c @@ -180,8 +180,9 @@ typedef enum globalfloat(clientcommandframe, "clientcommandframe"); /*float the next frame that will be sent*/ \ globalfloat(servercommandframe, "servercommandframe"); /*float the most recent frame received from the server*/ \ \ + globalfloat(player_tracknum, "player_trackentnum"); /*float the player number of the player being tracked*/ \ globalfloat(player_localentnum, "player_localentnum"); /*float the entity number of the local player*/ \ - globalfloat(player_localnum, "player_localnum"); /*float the entity number of the local player*/ \ + globalfloat(player_localnum, "player_localnum"); /*float the player number of the local player*/ \ globalfloat(intermission, "intermission"); /*float set when the client receives svc_intermission*/ \ globalvector(view_angles, "view_angles"); /*float set to the view angles at the start of each new frame (EXT_CSQC_1)*/ \ \ @@ -224,8 +225,19 @@ static csqcglobals_t csqcg; static void CSQC_ChangeLocalPlayer(int lplayernum) { csqc_lplayernum = lplayernum; + if (csqcg.player_tracknum) + { + *csqcg.player_tracknum = Cam_TrackNum(csqc_lplayernum); + } if (csqcg.player_localentnum) - *csqcg.player_localentnum = cl.playernum[lplayernum]+1; + { + if (cl.viewentity[lplayernum]) + *csqcg.player_localentnum = cl.viewentity[lplayernum]; + else if (cl.spectator && Cam_TrackNum(csqc_lplayernum) >= 0) + *csqcg.player_localentnum = Cam_TrackNum(csqc_lplayernum) + 1; + else + *csqcg.player_localentnum = cl.playernum[lplayernum]+1; + } if (csqcg.player_localnum) *csqcg.player_localnum = cl.playernum[lplayernum]; diff --git a/engine/client/pr_menu.c b/engine/client/pr_menu.c index 21f655213..e7992db77 100644 --- a/engine/client/pr_menu.c +++ b/engine/client/pr_menu.c @@ -956,12 +956,11 @@ void QCBUILTIN PF_cl_setkeydest (progfuncs_t *prinst, struct globalvars_s *pr_gl { case 0: // key_game - key_dest = key_game; + key_dest = ((cls.state == ca_active)?key_game:key_console); break; case 2: // key_menu - if (key_dest != key_console) - key_dest = key_menu; + key_dest = key_menu; m_state = m_menu_dat; break; case 1: diff --git a/engine/common/com_mesh.c b/engine/common/com_mesh.c index b0a04467f..26e51290a 100644 --- a/engine/common/com_mesh.c +++ b/engine/common/com_mesh.c @@ -5528,7 +5528,9 @@ galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, char *buffer) galiasinfo_t *gai; +#ifndef SERVERONLY galiasskin_t *skin; +#endif galiasgroup_t *fgroup; galiasbone_t *bones; texnums_t *texnum; @@ -5594,18 +5596,23 @@ galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, char *buffer) mesh = (struct iqmmesh*)(buffer + h->ofs_meshes); /*allocate a nice big block of memory and figure out where stuff is*/ - gai = Hunk_Alloc(sizeof(*gai)*h->num_meshes + sizeof(*skin)*h->num_meshes + sizeof(*texnum)*h->num_meshes + + gai = Hunk_Alloc(sizeof(*gai)*h->num_meshes + +#ifndef SERVERONLY + sizeof(*skin)*h->num_meshes + sizeof(*texnum)*h->num_meshes + +#endif sizeof(*fgroup)*h->num_anims + sizeof(float)*12*h->num_poses*h->num_frames + sizeof(*bones)*h->num_joints + (sizeof(*opos) + sizeof(*onorm) + sizeof(*oweight) + sizeof(*oindex)) * h->num_vertexes); bones = (galiasbone_t*)(gai + h->num_meshes); - skin = (galiasskin_t*)(bones + h->num_joints); - texnum = (texnums_t*)(skin + h->num_meshes); - opos = (vecV_t*)(texnum + h->num_meshes); + opos = (vecV_t*)(bones + h->num_joints); onorm = (vec3_t*)(opos + h->num_vertexes); oindex = (byte_vec4_t*)(onorm + h->num_vertexes); oweight = (vec4_t*)(oindex + h->num_vertexes); fgroup = (galiasgroup_t*)(oweight + h->num_vertexes); opose = (float*)(fgroup + h->num_anims); +#ifndef SERVERONLY + skin = (galiasskin_t*)(opose + 12*h->num_poses*h->num_frames); + texnum = (texnums_t*)(skin + h->num_meshes); +#endif //no code to load animations or bones framedata = (unsigned short*)(buffer + h->ofs_frames); @@ -5711,6 +5718,7 @@ galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, char *buffer) gai[i].groups = h->num_frames; gai[i].groupofs = (char*)fgroup - (char*)&gai[i]; +#ifndef SERVERONLY /*skins*/ gai[i].numskins = 1; gai[i].ofsskins = (char*)&skin[i] - (char*)&gai[i]; @@ -5722,6 +5730,7 @@ galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, char *buffer) skin[i].texnums = 1; skin[i].ofstexnums = (char*)&texnum[i] - (char*)&skin[i]; texnum[i].shader = R_RegisterSkin(skin[i].name, mod->name); +#endif offset = LittleLong(mesh[i].first_vertex); diff --git a/engine/common/fs.c b/engine/common/fs.c index 811cc1ffc..d9ae42961 100644 --- a/engine/common/fs.c +++ b/engine/common/fs.c @@ -1637,7 +1637,7 @@ void COM_Gamedir (const char *dir) /*nexuiz/xonotic has a few quirks...*/ #define NEXCFG DPCOMPAT "set r_particlesdesc effectinfo\nset sv_maxairspeed \"400\"\nset sv_jumpvelocity 270\nset sv_mintic \"0.01\"\ncl_nolerp 0\n" /*some modern non-compat settings*/ -#define DMFCFG "set com_parseutf8 1\npm_airstep 1\n" +#define DMFCFG "set com_parseutf8 1\npm_airstep 1\nsv_demoExtensions 1\n" /*set some stuff so our regular qw client appears more like hexen2*/ #define HEX2CFG "set r_particlesdesc \"spikeset tsshaft h2part\"\nset sv_maxspeed 640\nset watervis 1\nset r_wateralpha 0.5\nset sv_pupglow 1\nset cl_model_bobbing 1\n" /*Q3's ui doesn't like empty model/headmodel/handicap cvars, even if the gamecode copes*/ diff --git a/engine/common/fs_zip.c b/engine/common/fs_zip.c index faf35990b..3bd71fcaa 100644 --- a/engine/common/fs_zip.c +++ b/engine/common/fs_zip.c @@ -86,6 +86,11 @@ vfsfile_t *FS_DecompressGZip(vfsfile_t *infile) return infile; } } + else + { + VFS_SEEK(infile, 0); + return infile; + } if (header.flags & GZ_FEXTRA) { VFS_READ(infile, &inshort, sizeof(inshort)); @@ -169,6 +174,8 @@ vfsfile_t *FS_DecompressGZip(vfsfile_t *infile) { strm.avail_in = VFS_READ(infile, inbuffer, sizeof(inbuffer)); strm.next_in = inbuffer; + if (!strm.avail_in) + break; } if (strm.avail_out == 0) @@ -182,9 +189,9 @@ vfsfile_t *FS_DecompressGZip(vfsfile_t *infile) } //doh, it terminated for no reason - qinflateEnd(&strm); if (ret != Z_STREAM_END) { + qinflateEnd(&strm); Con_Printf("Couldn't decompress gz file\n"); VFS_CLOSE(temp); VFS_CLOSE(infile); diff --git a/engine/common/pr_bgcmd.c b/engine/common/pr_bgcmd.c index 3f2abc111..e10351006 100644 --- a/engine/common/pr_bgcmd.c +++ b/engine/common/pr_bgcmd.c @@ -494,10 +494,20 @@ typedef struct { } pf_fopen_files_t; pf_fopen_files_t pf_fopen_files[MAX_QC_FILES]; +/*only read+append+write are standard frik_file*/ +#define FRIK_FILE_READ 0 /*read-only*/ +#define FRIK_FILE_APPEND 1 /*append (write-only, but offset begins at end of previous file)*/ +#define FRIK_FILE_WRITE 2 /*write-only*/ +#define FRIK_FILE_INVALID 3 /*no idea what this is for, presume placeholder*/ +#define FRIK_FILE_READNL 4 /*fgets ignores newline chars, returning the entire thing in one lump*/ +#define FRIK_FILE_MMAP_READ 5 /*fgets returns a pointer. memory is not guarenteed to be released.*/ +#define FRIK_FILE_MMAP_RW 6 /*fgets returns a pointer. file is written upon close. memory is not guarenteed to be released.*/ + void QCBUILTIN PF_fopen (progfuncs_t *prinst, struct globalvars_s *pr_globals) { char *name = PR_GetStringOfs(prinst, OFS_PARM0); int fmode = G_FLOAT(OFS_PARM1); + int fsize = G_FLOAT(OFS_PARM2); int i; for (i = 0; i < MAX_QC_FILES; i++) @@ -524,8 +534,39 @@ void QCBUILTIN PF_fopen (progfuncs_t *prinst, struct globalvars_s *pr_globals) pf_fopen_files[i].accessmode = fmode; switch (fmode) { - case 0: //read - case 4: //read whole file + case FRIK_FILE_MMAP_READ: + case FRIK_FILE_MMAP_RW: + { + vfsfile_t *f = FS_OpenVFS(pf_fopen_files[i].name, "rb", FS_GAME); + if (f) + { + pf_fopen_files[i].bufferlen = pf_fopen_files[i].len = VFS_GETLEN(f); + if (pf_fopen_files[i].bufferlen < fsize) + pf_fopen_files[i].bufferlen = fsize; + pf_fopen_files[i].data = PR_AddressableAlloc(prinst, pf_fopen_files[i].bufferlen); + VFS_READ(f, pf_fopen_files[i].data, pf_fopen_files[i].len); + VFS_CLOSE(f); + } + else + { + pf_fopen_files[i].bufferlen = fsize; + pf_fopen_files[i].data = PR_AddressableAlloc(prinst, pf_fopen_files[i].bufferlen); + } + + if (!pf_fopen_files[i].data) + { + G_FLOAT(OFS_RETURN) = -1; + break; + } + + pf_fopen_files[i].len = pf_fopen_files[i].bufferlen; + pf_fopen_files[i].ofs = 0; + G_FLOAT(OFS_RETURN) = i + FIRST_QC_FILE_INDEX; + pf_fopen_files[i].prinst = prinst; + } + break; + case FRIK_FILE_READ: //read + case FRIK_FILE_READNL: //read whole file pf_fopen_files[i].data = FS_LoadMallocFile(pf_fopen_files[i].name); if (!pf_fopen_files[i].data) { @@ -544,7 +585,7 @@ void QCBUILTIN PF_fopen (progfuncs_t *prinst, struct globalvars_s *pr_globals) pf_fopen_files[i].bufferlen = pf_fopen_files[i].len = com_filesize; pf_fopen_files[i].ofs = 0; break; - case 1: //append + case FRIK_FILE_APPEND: //append pf_fopen_files[i].data = FS_LoadMallocFile(pf_fopen_files[i].name); pf_fopen_files[i].ofs = pf_fopen_files[i].bufferlen = pf_fopen_files[i].len = com_filesize; if (pf_fopen_files[i].data) @@ -554,7 +595,7 @@ void QCBUILTIN PF_fopen (progfuncs_t *prinst, struct globalvars_s *pr_globals) break; } //file didn't exist - fall through - case 2: //write + case FRIK_FILE_WRITE: //write pf_fopen_files[i].bufferlen = 8192; pf_fopen_files[i].data = BZ_Malloc(pf_fopen_files[i].bufferlen); pf_fopen_files[i].len = 0; @@ -562,7 +603,7 @@ void QCBUILTIN PF_fopen (progfuncs_t *prinst, struct globalvars_s *pr_globals) G_FLOAT(OFS_RETURN) = i + FIRST_QC_FILE_INDEX; pf_fopen_files[i].prinst = prinst; break; - case 3: + case FRIK_FILE_INVALID: pf_fopen_files[i].bufferlen = 0; pf_fopen_files[i].data = ""; pf_fopen_files[i].len = 0; @@ -592,7 +633,14 @@ void PF_fclose_i (int fnum) switch(pf_fopen_files[fnum].accessmode) { - case 0: + case FRIK_FILE_MMAP_RW: + COM_WriteFile(pf_fopen_files[fnum].name, pf_fopen_files[fnum].data, pf_fopen_files[fnum].len); + /*fall through*/ + case FRIK_FILE_MMAP_READ: + /*cannot free accessible mem*/ + break; + + case FRIK_FILE_READ: case 4: BZ_Free(pf_fopen_files[fnum].data); break; @@ -653,6 +701,12 @@ void QCBUILTIN PF_fgets (progfuncs_t *prinst, struct globalvars_s *pr_globals) return; //this just isn't ours. } + if (pf_fopen_files[fnum].accessmode == FRIK_FILE_MMAP_READ || pf_fopen_files[fnum].accessmode == FRIK_FILE_MMAP_RW) + { + G_INT(OFS_RETURN) = PR_SetString(prinst, pf_fopen_files[fnum].data); + return; + } + //read up to the next \n, ignoring any \rs. o = pr_string_temp; max = o + sizeof(pr_string_temp)-1; @@ -661,9 +715,9 @@ void QCBUILTIN PF_fgets (progfuncs_t *prinst, struct globalvars_s *pr_globals) while(s < eof) { c = *s++; - if (c == '\n' && pf_fopen_files[fnum].accessmode != 4) + if (c == '\n' && pf_fopen_files[fnum].accessmode != FRIK_FILE_READNL) break; - if (c == '\r' && pf_fopen_files[fnum].accessmode != 4) + if (c == '\r' && pf_fopen_files[fnum].accessmode != FRIK_FILE_READNL) continue; if (o == max) @@ -707,8 +761,8 @@ void QCBUILTIN PF_fputs (progfuncs_t *prinst, struct globalvars_s *pr_globals) { default: break; - case 1: - case 2: + case FRIK_FILE_APPEND: + case FRIK_FILE_WRITE: if (pf_fopen_files[fnum].bufferlen < pf_fopen_files[fnum].ofs + len) { char *newbuf; diff --git a/engine/d3d/vid_d3d.c b/engine/d3d/vid_d3d.c index 263296d19..007549c2d 100644 --- a/engine/d3d/vid_d3d.c +++ b/engine/d3d/vid_d3d.c @@ -619,6 +619,16 @@ static void initD3D9(HWND hWnd, rendererstate_t *info) if (initD3D9Device(hWnd, info, i, D3DDEVTYPE_HAL)) return; } + for (i = 0; i < numadaptors; i++) + { //try each adaptor in turn until we get one that actually works + if (initD3D9Device(hWnd, info, i, D3DDEVTYPE_SW)) + return; + } + for (i = 0; i < numadaptors; i++) + { //try each adaptor in turn until we get one that actually works + if (initD3D9Device(hWnd, info, i, D3DDEVTYPE_REF)) + return; + } } static qboolean D3D9_VID_Init(rendererstate_t *info, unsigned char *palette) @@ -673,7 +683,10 @@ static qboolean D3D9_VID_Init(rendererstate_t *info, unsigned char *palette) initD3D9(mainwindow, info); if (!pD3DDev9) + { + Con_Printf("No suitable D3D device found\n"); return false; + } diff --git a/engine/dotnet2005/ftequake.sln b/engine/dotnet2005/ftequake.sln index 30179959c..46faa4b76 100644 --- a/engine/dotnet2005/ftequake.sln +++ b/engine/dotnet2005/ftequake.sln @@ -14,13 +14,14 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "npfte", "npfte.vcproj", "{8 EndProject Project("{54435603-DBB4-11D2-8724-00A0C9A8B90C}") = "FTEQuake", "..\setup\setup.vdproj", "{E0EE8B50-3A75-42A9-B80A-787675979B0C}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qtvprox", "..\..\fteqtv\qtvprox.vcproj", "{1A353DA0-F351-4C0D-A21D-E2B460600B20}" - ProjectSection(ProjectDependencies) = postProject - {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365} = {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365} - EndProjectSection -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "botlib", "botlib.vcproj", "{0018E098-B12A-4E4D-9B22-6772DA287080}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fteqcc", "..\qclib\dotnet2005\qcc.vcproj", "{2866F783-6B44-4655-A38D-D53874037454}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "axfte", "axfte.vcproj", "{E27271B3-4E6F-4F53-86FF-2BCBB6BA4D01}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qtvprox", "..\..\fteqtv\dotnet2005\qtvprox.vcproj", "{62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution D3DDebug|Win32 = D3DDebug|Win32 @@ -92,8 +93,8 @@ Global {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.Release Dedicated Server|Win32.Build.0 = Release Dedicated Server|Win32 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.Release Dedicated Server|x64.ActiveCfg = Release Dedicated Server|x64 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.Release Dedicated Server|x64.Build.0 = Release Dedicated Server|x64 - {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.Release|Win32.ActiveCfg = GLRelease|Win32 - {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.Release|Win32.Build.0 = GLRelease|Win32 + {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.Release|Win32.ActiveCfg = MRelease|Win32 + {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.Release|Win32.Build.0 = MRelease|Win32 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.Release|x64.ActiveCfg = GLRelease|x64 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.Release|x64.Build.0 = GLRelease|x64 {F384725A-62D4-4063-9941-6D8D2D6C2A47}.D3DDebug|Win32.ActiveCfg = D3DDebug_SDL|x64 @@ -187,41 +188,6 @@ Global {E0EE8B50-3A75-42A9-B80A-787675979B0C}.Release Dedicated Server|x64.ActiveCfg = Release {E0EE8B50-3A75-42A9-B80A-787675979B0C}.Release|Win32.ActiveCfg = Release {E0EE8B50-3A75-42A9-B80A-787675979B0C}.Release|x64.ActiveCfg = Release - {1A353DA0-F351-4C0D-A21D-E2B460600B20}.D3DDebug|Win32.ActiveCfg = Debug|Win32 - {1A353DA0-F351-4C0D-A21D-E2B460600B20}.D3DDebug|Win32.Build.0 = Debug|Win32 - {1A353DA0-F351-4C0D-A21D-E2B460600B20}.D3DDebug|x64.ActiveCfg = Debug|Win32 - {1A353DA0-F351-4C0D-A21D-E2B460600B20}.D3DRelease|Win32.ActiveCfg = Release|Win32 - {1A353DA0-F351-4C0D-A21D-E2B460600B20}.D3DRelease|x64.ActiveCfg = Release|Win32 - {1A353DA0-F351-4C0D-A21D-E2B460600B20}.Debug Dedicated Server|Win32.ActiveCfg = Debug|Win32 - {1A353DA0-F351-4C0D-A21D-E2B460600B20}.Debug Dedicated Server|Win32.Build.0 = Debug|Win32 - {1A353DA0-F351-4C0D-A21D-E2B460600B20}.Debug Dedicated Server|x64.ActiveCfg = Debug|Win32 - {1A353DA0-F351-4C0D-A21D-E2B460600B20}.Debug|Win32.ActiveCfg = Debug|Win32 - {1A353DA0-F351-4C0D-A21D-E2B460600B20}.Debug|Win32.Build.0 = Debug|Win32 - {1A353DA0-F351-4C0D-A21D-E2B460600B20}.Debug|x64.ActiveCfg = Debug|Win32 - {1A353DA0-F351-4C0D-A21D-E2B460600B20}.GLDebug|Win32.ActiveCfg = Debug|Win32 - {1A353DA0-F351-4C0D-A21D-E2B460600B20}.GLDebug|Win32.Build.0 = Debug|Win32 - {1A353DA0-F351-4C0D-A21D-E2B460600B20}.GLDebug|x64.ActiveCfg = Debug|Win32 - {1A353DA0-F351-4C0D-A21D-E2B460600B20}.GLRelease|Win32.ActiveCfg = Release|Win32 - {1A353DA0-F351-4C0D-A21D-E2B460600B20}.GLRelease|Win32.Build.0 = Release|Win32 - {1A353DA0-F351-4C0D-A21D-E2B460600B20}.GLRelease|x64.ActiveCfg = Release|Win32 - {1A353DA0-F351-4C0D-A21D-E2B460600B20}.MDebug|Win32.ActiveCfg = Debug|Win32 - {1A353DA0-F351-4C0D-A21D-E2B460600B20}.MDebug|Win32.Build.0 = Debug|Win32 - {1A353DA0-F351-4C0D-A21D-E2B460600B20}.MDebug|x64.ActiveCfg = Debug|Win32 - {1A353DA0-F351-4C0D-A21D-E2B460600B20}.MinGLDebug|Win32.ActiveCfg = Debug|Win32 - {1A353DA0-F351-4C0D-A21D-E2B460600B20}.MinGLDebug|Win32.Build.0 = Debug|Win32 - {1A353DA0-F351-4C0D-A21D-E2B460600B20}.MinGLDebug|x64.ActiveCfg = Debug|Win32 - {1A353DA0-F351-4C0D-A21D-E2B460600B20}.MinGLRelease|Win32.ActiveCfg = Release|Win32 - {1A353DA0-F351-4C0D-A21D-E2B460600B20}.MinGLRelease|Win32.Build.0 = Release|Win32 - {1A353DA0-F351-4C0D-A21D-E2B460600B20}.MinGLRelease|x64.ActiveCfg = Release|Win32 - {1A353DA0-F351-4C0D-A21D-E2B460600B20}.MRelease|Win32.ActiveCfg = Release|Win32 - {1A353DA0-F351-4C0D-A21D-E2B460600B20}.MRelease|Win32.Build.0 = Release|Win32 - {1A353DA0-F351-4C0D-A21D-E2B460600B20}.MRelease|x64.ActiveCfg = Release|Win32 - {1A353DA0-F351-4C0D-A21D-E2B460600B20}.Release Dedicated Server|Win32.ActiveCfg = Release|Win32 - {1A353DA0-F351-4C0D-A21D-E2B460600B20}.Release Dedicated Server|Win32.Build.0 = Release|Win32 - {1A353DA0-F351-4C0D-A21D-E2B460600B20}.Release Dedicated Server|x64.ActiveCfg = Release|Win32 - {1A353DA0-F351-4C0D-A21D-E2B460600B20}.Release|Win32.ActiveCfg = Release|Win32 - {1A353DA0-F351-4C0D-A21D-E2B460600B20}.Release|Win32.Build.0 = Release|Win32 - {1A353DA0-F351-4C0D-A21D-E2B460600B20}.Release|x64.ActiveCfg = Release|Win32 {0018E098-B12A-4E4D-9B22-6772DA287080}.D3DDebug|Win32.ActiveCfg = Debug|Win32 {0018E098-B12A-4E4D-9B22-6772DA287080}.D3DDebug|Win32.Build.0 = Debug|Win32 {0018E098-B12A-4E4D-9B22-6772DA287080}.D3DDebug|x64.ActiveCfg = Debug|Win32 @@ -256,6 +222,124 @@ Global {0018E098-B12A-4E4D-9B22-6772DA287080}.Release|Win32.ActiveCfg = Release|Win32 {0018E098-B12A-4E4D-9B22-6772DA287080}.Release|Win32.Build.0 = Release|Win32 {0018E098-B12A-4E4D-9B22-6772DA287080}.Release|x64.ActiveCfg = Release|Win32 + {2866F783-6B44-4655-A38D-D53874037454}.D3DDebug|Win32.ActiveCfg = Debug|Win32 + {2866F783-6B44-4655-A38D-D53874037454}.D3DDebug|Win32.Build.0 = Debug|Win32 + {2866F783-6B44-4655-A38D-D53874037454}.D3DDebug|x64.ActiveCfg = Debug|Win32 + {2866F783-6B44-4655-A38D-D53874037454}.D3DRelease|Win32.ActiveCfg = Release|Win32 + {2866F783-6B44-4655-A38D-D53874037454}.D3DRelease|Win32.Build.0 = Release|Win32 + {2866F783-6B44-4655-A38D-D53874037454}.D3DRelease|x64.ActiveCfg = Release|Win32 + {2866F783-6B44-4655-A38D-D53874037454}.Debug Dedicated Server|Win32.ActiveCfg = Debug|Win32 + {2866F783-6B44-4655-A38D-D53874037454}.Debug Dedicated Server|Win32.Build.0 = Debug|Win32 + {2866F783-6B44-4655-A38D-D53874037454}.Debug Dedicated Server|x64.ActiveCfg = Debug|Win32 + {2866F783-6B44-4655-A38D-D53874037454}.Debug|Win32.ActiveCfg = Debug|Win32 + {2866F783-6B44-4655-A38D-D53874037454}.Debug|Win32.Build.0 = Debug|Win32 + {2866F783-6B44-4655-A38D-D53874037454}.Debug|x64.ActiveCfg = Debug|Win32 + {2866F783-6B44-4655-A38D-D53874037454}.GLDebug|Win32.ActiveCfg = Debug|Win32 + {2866F783-6B44-4655-A38D-D53874037454}.GLDebug|Win32.Build.0 = Debug|Win32 + {2866F783-6B44-4655-A38D-D53874037454}.GLDebug|x64.ActiveCfg = Debug|Win32 + {2866F783-6B44-4655-A38D-D53874037454}.GLRelease|Win32.ActiveCfg = Release|Win32 + {2866F783-6B44-4655-A38D-D53874037454}.GLRelease|Win32.Build.0 = Release|Win32 + {2866F783-6B44-4655-A38D-D53874037454}.GLRelease|x64.ActiveCfg = Release|Win32 + {2866F783-6B44-4655-A38D-D53874037454}.MDebug|Win32.ActiveCfg = Debug|Win32 + {2866F783-6B44-4655-A38D-D53874037454}.MDebug|Win32.Build.0 = Debug|Win32 + {2866F783-6B44-4655-A38D-D53874037454}.MDebug|x64.ActiveCfg = Debug|Win32 + {2866F783-6B44-4655-A38D-D53874037454}.MinGLDebug|Win32.ActiveCfg = Debug|Win32 + {2866F783-6B44-4655-A38D-D53874037454}.MinGLDebug|Win32.Build.0 = Debug|Win32 + {2866F783-6B44-4655-A38D-D53874037454}.MinGLDebug|x64.ActiveCfg = Debug|Win32 + {2866F783-6B44-4655-A38D-D53874037454}.MinGLRelease|Win32.ActiveCfg = Release|Win32 + {2866F783-6B44-4655-A38D-D53874037454}.MinGLRelease|Win32.Build.0 = Release|Win32 + {2866F783-6B44-4655-A38D-D53874037454}.MinGLRelease|x64.ActiveCfg = Release|Win32 + {2866F783-6B44-4655-A38D-D53874037454}.MRelease|Win32.ActiveCfg = Release|Win32 + {2866F783-6B44-4655-A38D-D53874037454}.MRelease|Win32.Build.0 = Release|Win32 + {2866F783-6B44-4655-A38D-D53874037454}.MRelease|x64.ActiveCfg = Release|Win32 + {2866F783-6B44-4655-A38D-D53874037454}.Release Dedicated Server|Win32.ActiveCfg = Release|Win32 + {2866F783-6B44-4655-A38D-D53874037454}.Release Dedicated Server|Win32.Build.0 = Release|Win32 + {2866F783-6B44-4655-A38D-D53874037454}.Release Dedicated Server|x64.ActiveCfg = Release|Win32 + {2866F783-6B44-4655-A38D-D53874037454}.Release|Win32.ActiveCfg = Release|Win32 + {2866F783-6B44-4655-A38D-D53874037454}.Release|Win32.Build.0 = Release|Win32 + {2866F783-6B44-4655-A38D-D53874037454}.Release|x64.ActiveCfg = Release|Win32 + {E27271B3-4E6F-4F53-86FF-2BCBB6BA4D01}.D3DDebug|Win32.ActiveCfg = Debug|Win32 + {E27271B3-4E6F-4F53-86FF-2BCBB6BA4D01}.D3DDebug|Win32.Build.0 = Debug|Win32 + {E27271B3-4E6F-4F53-86FF-2BCBB6BA4D01}.D3DDebug|x64.ActiveCfg = Debug|x64 + {E27271B3-4E6F-4F53-86FF-2BCBB6BA4D01}.D3DDebug|x64.Build.0 = Debug|x64 + {E27271B3-4E6F-4F53-86FF-2BCBB6BA4D01}.D3DRelease|Win32.ActiveCfg = Release|Win32 + {E27271B3-4E6F-4F53-86FF-2BCBB6BA4D01}.D3DRelease|Win32.Build.0 = Release|Win32 + {E27271B3-4E6F-4F53-86FF-2BCBB6BA4D01}.D3DRelease|x64.ActiveCfg = Release|x64 + {E27271B3-4E6F-4F53-86FF-2BCBB6BA4D01}.D3DRelease|x64.Build.0 = Release|x64 + {E27271B3-4E6F-4F53-86FF-2BCBB6BA4D01}.Debug Dedicated Server|Win32.ActiveCfg = Debug|Win32 + {E27271B3-4E6F-4F53-86FF-2BCBB6BA4D01}.Debug Dedicated Server|x64.ActiveCfg = Debug|x64 + {E27271B3-4E6F-4F53-86FF-2BCBB6BA4D01}.Debug Dedicated Server|x64.Build.0 = Debug|x64 + {E27271B3-4E6F-4F53-86FF-2BCBB6BA4D01}.Debug|Win32.ActiveCfg = Debug|Win32 + {E27271B3-4E6F-4F53-86FF-2BCBB6BA4D01}.Debug|Win32.Build.0 = Debug|Win32 + {E27271B3-4E6F-4F53-86FF-2BCBB6BA4D01}.Debug|x64.ActiveCfg = Debug|x64 + {E27271B3-4E6F-4F53-86FF-2BCBB6BA4D01}.Debug|x64.Build.0 = Debug|x64 + {E27271B3-4E6F-4F53-86FF-2BCBB6BA4D01}.GLDebug|Win32.ActiveCfg = Debug|Win32 + {E27271B3-4E6F-4F53-86FF-2BCBB6BA4D01}.GLDebug|Win32.Build.0 = Debug|Win32 + {E27271B3-4E6F-4F53-86FF-2BCBB6BA4D01}.GLDebug|x64.ActiveCfg = Debug|x64 + {E27271B3-4E6F-4F53-86FF-2BCBB6BA4D01}.GLDebug|x64.Build.0 = Debug|x64 + {E27271B3-4E6F-4F53-86FF-2BCBB6BA4D01}.GLRelease|Win32.ActiveCfg = Release|Win32 + {E27271B3-4E6F-4F53-86FF-2BCBB6BA4D01}.GLRelease|Win32.Build.0 = Release|Win32 + {E27271B3-4E6F-4F53-86FF-2BCBB6BA4D01}.GLRelease|x64.ActiveCfg = Release|x64 + {E27271B3-4E6F-4F53-86FF-2BCBB6BA4D01}.GLRelease|x64.Build.0 = Release|x64 + {E27271B3-4E6F-4F53-86FF-2BCBB6BA4D01}.MDebug|Win32.ActiveCfg = Debug|Win32 + {E27271B3-4E6F-4F53-86FF-2BCBB6BA4D01}.MDebug|Win32.Build.0 = Debug|Win32 + {E27271B3-4E6F-4F53-86FF-2BCBB6BA4D01}.MDebug|x64.ActiveCfg = Debug|x64 + {E27271B3-4E6F-4F53-86FF-2BCBB6BA4D01}.MDebug|x64.Build.0 = Debug|x64 + {E27271B3-4E6F-4F53-86FF-2BCBB6BA4D01}.MinGLDebug|Win32.ActiveCfg = Debug|Win32 + {E27271B3-4E6F-4F53-86FF-2BCBB6BA4D01}.MinGLDebug|Win32.Build.0 = Debug|Win32 + {E27271B3-4E6F-4F53-86FF-2BCBB6BA4D01}.MinGLDebug|x64.ActiveCfg = Debug|x64 + {E27271B3-4E6F-4F53-86FF-2BCBB6BA4D01}.MinGLDebug|x64.Build.0 = Debug|x64 + {E27271B3-4E6F-4F53-86FF-2BCBB6BA4D01}.MinGLRelease|Win32.ActiveCfg = Release|Win32 + {E27271B3-4E6F-4F53-86FF-2BCBB6BA4D01}.MinGLRelease|Win32.Build.0 = Release|Win32 + {E27271B3-4E6F-4F53-86FF-2BCBB6BA4D01}.MinGLRelease|x64.ActiveCfg = Release|x64 + {E27271B3-4E6F-4F53-86FF-2BCBB6BA4D01}.MinGLRelease|x64.Build.0 = Release|x64 + {E27271B3-4E6F-4F53-86FF-2BCBB6BA4D01}.MRelease|Win32.ActiveCfg = Release|Win32 + {E27271B3-4E6F-4F53-86FF-2BCBB6BA4D01}.MRelease|Win32.Build.0 = Release|Win32 + {E27271B3-4E6F-4F53-86FF-2BCBB6BA4D01}.MRelease|x64.ActiveCfg = Release|x64 + {E27271B3-4E6F-4F53-86FF-2BCBB6BA4D01}.MRelease|x64.Build.0 = Release|x64 + {E27271B3-4E6F-4F53-86FF-2BCBB6BA4D01}.Release Dedicated Server|Win32.ActiveCfg = Release|Win32 + {E27271B3-4E6F-4F53-86FF-2BCBB6BA4D01}.Release Dedicated Server|x64.ActiveCfg = Release|x64 + {E27271B3-4E6F-4F53-86FF-2BCBB6BA4D01}.Release Dedicated Server|x64.Build.0 = Release|x64 + {E27271B3-4E6F-4F53-86FF-2BCBB6BA4D01}.Release|Win32.ActiveCfg = Release|Win32 + {E27271B3-4E6F-4F53-86FF-2BCBB6BA4D01}.Release|Win32.Build.0 = Release|Win32 + {E27271B3-4E6F-4F53-86FF-2BCBB6BA4D01}.Release|x64.ActiveCfg = Release|x64 + {E27271B3-4E6F-4F53-86FF-2BCBB6BA4D01}.Release|x64.Build.0 = Release|x64 + {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.D3DDebug|Win32.ActiveCfg = Debug|Win32 + {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.D3DDebug|Win32.Build.0 = Debug|Win32 + {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.D3DDebug|x64.ActiveCfg = Debug|Win32 + {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.D3DRelease|Win32.ActiveCfg = Release|Win32 + {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.D3DRelease|Win32.Build.0 = Release|Win32 + {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.D3DRelease|x64.ActiveCfg = Release|Win32 + {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.Debug Dedicated Server|Win32.ActiveCfg = Debug|Win32 + {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.Debug Dedicated Server|Win32.Build.0 = Debug|Win32 + {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.Debug Dedicated Server|x64.ActiveCfg = Debug|Win32 + {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.Debug|Win32.ActiveCfg = Debug|Win32 + {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.Debug|Win32.Build.0 = Debug|Win32 + {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.Debug|x64.ActiveCfg = Debug|Win32 + {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.GLDebug|Win32.ActiveCfg = Debug|Win32 + {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.GLDebug|Win32.Build.0 = Debug|Win32 + {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.GLDebug|x64.ActiveCfg = Debug|Win32 + {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.GLRelease|Win32.ActiveCfg = Release|Win32 + {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.GLRelease|Win32.Build.0 = Release|Win32 + {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.GLRelease|x64.ActiveCfg = Release|Win32 + {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.MDebug|Win32.ActiveCfg = Debug|Win32 + {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.MDebug|Win32.Build.0 = Debug|Win32 + {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.MDebug|x64.ActiveCfg = Debug|Win32 + {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.MinGLDebug|Win32.ActiveCfg = Debug|Win32 + {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.MinGLDebug|Win32.Build.0 = Debug|Win32 + {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.MinGLDebug|x64.ActiveCfg = Debug|Win32 + {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.MinGLRelease|Win32.ActiveCfg = Release|Win32 + {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.MinGLRelease|Win32.Build.0 = Release|Win32 + {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.MinGLRelease|x64.ActiveCfg = Release|Win32 + {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.MRelease|Win32.ActiveCfg = Release|Win32 + {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.MRelease|Win32.Build.0 = Release|Win32 + {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.MRelease|x64.ActiveCfg = Release|Win32 + {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.Release Dedicated Server|Win32.ActiveCfg = Release|Win32 + {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.Release Dedicated Server|Win32.Build.0 = Release|Win32 + {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.Release Dedicated Server|x64.ActiveCfg = Release|Win32 + {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.Release|Win32.ActiveCfg = Release|Win32 + {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.Release|Win32.Build.0 = Release|Win32 + {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.Release|x64.ActiveCfg = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/engine/dotnet2005/ftequake.vcproj b/engine/dotnet2005/ftequake.vcproj index 080a51ac3..ef7e12f73 100644 --- a/engine/dotnet2005/ftequake.vcproj +++ b/engine/dotnet2005/ftequake.vcproj @@ -303,7 +303,6 @@ _int >= addressableused) { pr_xstatement = st-pr_statements; - PR_RunError (progfuncs, "bad pointer write in %s", progfuncs->stringtable + pr_xfunction->s_name); + PR_RunError (progfuncs, "bad pointer write in %s (%x >= %x)", progfuncs->stringtable + pr_xfunction->s_name, OPB->_int, addressableused); } ptr = QCPOINTER(OPB); ptr->_int = OPA->_int; diff --git a/engine/qclib/initlib.c b/engine/qclib/initlib.c index 4115a066f..167cd7871 100644 --- a/engine/qclib/initlib.c +++ b/engine/qclib/initlib.c @@ -430,8 +430,8 @@ string_t PR_StringToProgs (progfuncs_t *progfuncs, char *str) if (!str) return 0; -// if (str-progfuncs->stringtable < progfuncs->stringtablesize) -// return str - progfuncs->stringtable; + if (str-progfuncs->stringtable < addressableused) + return str - progfuncs->stringtable; for (i = prinst->numallocedstrings-1; i >= 0; i--) { @@ -537,7 +537,7 @@ char *ASMCALL PR_StringToNative (progfuncs_t *progfuncs, string_t str) } } - if (str >= progfuncs->stringtablesize) + if (str >= addressableused) { printf("invalid string offset %x\n", str); pr_trace = 1; @@ -691,7 +691,8 @@ progfuncs_t deffuncs = { 0, PR_QueryField, QC_ClearEdict, - QC_FindPrefixedGlobals + QC_FindPrefixedGlobals, + PRAddressableAlloc }; #undef printf diff --git a/engine/qclib/progslib.h b/engine/qclib/progslib.h index 1e9b61255..4df5574fb 100644 --- a/engine/qclib/progslib.h +++ b/engine/qclib/progslib.h @@ -138,6 +138,8 @@ struct progfuncs_s { void (*EntClear) (progfuncs_t *progfuncs, struct edict_s *e); void (*FindPrefixGlobals) (progfuncs_t *progfuncs, char *prefix, void (*found) (progfuncs_t *progfuncs, char *name, union eval_s *val, etype_t type) ); + + void *(*AddressableAlloc) (progfuncs_t *progfuncs, int ammount); /*returns memory within the qc block, use stringtoprogs to get a usable qc pointer/string*/ }; typedef struct progexterns_s { @@ -252,7 +254,8 @@ typedef union eval_s #define PR_FindFunction(pf, name, num) (*pf->FindFunction) (pf, name, num) #define PR_FindGlobal(pf, name, progs, type) (*pf->FindGlobal) (pf, name, progs, type) #define PR_AddString(pf, ed, len) (*pf->AddString) (pf, ed, len) -#define PR_Alloc(pf,size) (*pf->Tempmem) (pf, size) +#define PR_Alloc(pf,size,whatfor) (*pf->Tempmem) (pf, size, whatfor) +#define PR_AddressableAlloc(pf,size) (*pf->AddressableAlloc) (pf, size) #define PROG_TO_EDICT(pf, ed) (*pf->ProgsToEdict) (pf, ed) #define EDICT_TO_PROG(pf, ed) (*pf->EdictToProgs) (pf, (struct edict_s*)ed) diff --git a/engine/qclib/qcc_pr_comp.c b/engine/qclib/qcc_pr_comp.c index f1993eb85..daafed1eb 100644 --- a/engine/qclib/qcc_pr_comp.c +++ b/engine/qclib/qcc_pr_comp.c @@ -189,7 +189,7 @@ int num_labels; QCC_def_t *extra_parms[MAX_EXTRA_PARMS]; -#define ASSOC_RIGHT_RESULT ASSOC_RIGHT +//#define ASSOC_RIGHT_RESULT ASSOC_RIGHT //======================================== @@ -1750,6 +1750,12 @@ QCC_def_t *QCC_PR_Statement ( QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var //a is const, b is not switch (op - pr_opcodes) { + case OP_CONV_FTOI: + optres_constantarithmatic++; + return QCC_MakeIntDef(G_FLOAT(var_a->ofs)); + case OP_CONV_ITOF: + optres_constantarithmatic++; + return QCC_MakeFloatDef(G_INT(var_a->ofs)); case OP_BITOR_F: case OP_OR_F: case OP_ADD_F: @@ -3709,10 +3715,15 @@ QCC_def_t *QCC_MakeIntDef(int value) cn->scope = NULL; // always share immediates cn->arraysize = 1; -// copy the immediate to the global area - cn->ofs = QCC_GetFreeOffsetSpace (type_size[type_integer->type]); + if (!value) + G_INT(cn->ofs) = 0; + else + { + // copy the immediate to the global area + cn->ofs = QCC_GetFreeOffsetSpace (type_size[type_integer->type]); - G_INT(cn->ofs) = value; + G_INT(cn->ofs) = value; + } return cn; @@ -4019,6 +4030,8 @@ void QCC_PR_EmitClassFromFunction(QCC_def_t *scope, char *tname) if (!basetype) QCC_PR_ParseError(ERR_INTERNAL, "Type %s was not defined...", tname); + if (numfunctions >= MAX_FUNCTIONS) + QCC_Error(ERR_INTERNAL, "Too many function defs"); pr_scope = NULL; memset(basictypefield, 0, sizeof(basictypefield)); @@ -4279,27 +4292,28 @@ reloop: if (d->arraysize>1) //use the array { nd = QCC_PR_Statement(&pr_opcodes[OP_LOADA_I], d, ao, NULL); //get pointer to precise def. - nd->type = d->type->aux_type; + newtype = d->type->aux_type; } else { //dereference the pointer. + ao = QCC_PR_Statement(&pr_opcodes[OP_MUL_I], ao, QCC_MakeIntDef(4), NULL); switch(newtype->aux_type->type) { case ev_pointer: nd = QCC_PR_Statement(&pr_opcodes[OP_LOADP_I], d, ao, NULL); //get pointer to precise def. - nd->type = d->type->aux_type; + newtype = d->type->aux_type; break; case ev_float: nd = QCC_PR_Statement(&pr_opcodes[OP_LOADP_F], d, ao, NULL); //get pointer to precise def. - nd->type = d->type->aux_type; + newtype = d->type->aux_type; break; case ev_vector: nd = QCC_PR_Statement(&pr_opcodes[OP_LOADP_V], d, ao, NULL); //get pointer to precise def. - nd->type = d->type->aux_type; + newtype = d->type->aux_type; break; case ev_integer: nd = QCC_PR_Statement(&pr_opcodes[OP_LOADP_I], d, ao, NULL); //get pointer to precise def. - nd->type = d->type->aux_type; + newtype = d->type->aux_type; break; default: QCC_PR_ParseError(ERR_NOVALIDOPCODES, "No op available. Try assembler"); @@ -4429,19 +4443,19 @@ reloop: { case ev_pointer: nd = QCC_PR_Statement(&pr_opcodes[OP_LOADP_I], d, QCC_PR_Statement (&pr_opcodes[OP_CONV_FTOI], ao, 0, NULL), NULL); //get pointer to precise def. - nd->type = d->type->aux_type; + newtype = d->type->aux_type; break; case ev_float: nd = QCC_PR_Statement(&pr_opcodes[OP_LOADP_F], d, QCC_PR_Statement (&pr_opcodes[OP_CONV_FTOI], ao, 0, NULL), NULL); //get pointer to precise def. - nd->type = d->type->aux_type; + newtype = d->type->aux_type; break; case ev_vector: nd = QCC_PR_Statement(&pr_opcodes[OP_LOADP_V], d, QCC_PR_Statement (&pr_opcodes[OP_CONV_FTOI], ao, 0, NULL), NULL); //get pointer to precise def. - nd->type = d->type->aux_type; + newtype = d->type->aux_type; break; case ev_integer: nd = QCC_PR_Statement(&pr_opcodes[OP_LOADP_I], d, QCC_PR_Statement (&pr_opcodes[OP_CONV_FTOI], ao, 0, NULL), NULL); //get pointer to precise def. - nd->type = d->type->aux_type; + newtype = d->type->aux_type; break; default: QCC_PR_ParseError(ERR_NOVALIDOPCODES, "No op available. Try assembler"); @@ -4858,6 +4872,8 @@ QCC_def_t *QCC_PR_Term (void) if (t != ev_pointer) QCC_PR_ParseError (ERR_BADNOTTYPE, "type mismatch for *"); + + switch(e->type->aux_type->type) { case ev_float: @@ -4941,7 +4957,19 @@ QCC_def_t *QCC_PR_Term (void) if (QCC_PR_CheckToken ("(")) { - if (QCC_PR_CheckKeyword(keyword_float, "float")) //check for type casts + if (QCC_PR_CheckToken("*")) + { + QCC_PR_Expect (")"); + e = QCC_PR_Term(); + e2 = (void *)qccHunkAlloc (sizeof(QCC_def_t)); + memset (e2, 0, sizeof(QCC_def_t)); + e2->type = type_pointer; + e2->ofs = e->ofs; + e2->constant = true; + e2->temp = e->temp; + return e2; + } + else if (QCC_PR_CheckKeyword(keyword_float, "float")) //check for type casts { QCC_PR_Expect (")"); e = QCC_PR_Term(); @@ -7557,6 +7585,9 @@ QCC_def_t *QCC_PR_EmitArrayGetVector(QCC_def_t *array) pr_scope = func; + if (numfunctions >= MAX_FUNCTIONS) + QCC_Error(ERR_INTERNAL, "Too many function defs"); + df = &functions[numfunctions]; numfunctions++; @@ -7611,6 +7642,9 @@ void QCC_PR_EmitArrayGetFunction(QCC_def_t *scope, char *arrayname) pr_scope = scope; + if (numfunctions >= MAX_FUNCTIONS) + QCC_Error(ERR_INTERNAL, "Too many function defs"); + df = &functions[numfunctions]; numfunctions++; @@ -7764,6 +7798,9 @@ void QCC_PR_EmitArraySetFunction(QCC_def_t *scope, char *arrayname) def = QCC_PR_GetDef(NULL, arrayname, NULL, false, 0, false); pr_scope = scope; + if (numfunctions >= MAX_FUNCTIONS) + QCC_Error(ERR_INTERNAL, "Too many function defs"); + df = &functions[numfunctions]; numfunctions++; @@ -8816,6 +8853,9 @@ void QCC_PR_ParseDefs (char *classname) // if (pr_dumpasm) // PR_PrintFunction (def); + if (numfunctions >= MAX_FUNCTIONS) + QCC_Error(ERR_INTERNAL, "Too many function defs"); + // fill in the dfunction df = &functions[numfunctions]; numfunctions++; @@ -9226,6 +9266,9 @@ void QCC_PR_ParseDefs (char *classname) // if (pr_dumpasm) // PR_PrintFunction (def); + if (numfunctions >= MAX_FUNCTIONS) + QCC_Error(ERR_INTERNAL, "Too many function defs"); + // fill in the dfunction df = &functions[numfunctions]; numfunctions++; diff --git a/engine/qclib/qcc_pr_lex.c b/engine/qclib/qcc_pr_lex.c index 9bdd11c42..e42afff79 100644 --- a/engine/qclib/qcc_pr_lex.c +++ b/engine/qclib/qcc_pr_lex.c @@ -831,6 +831,18 @@ pbool QCC_PR_Precompiler(void) { defaultstatic = atoi(msg); } + else if (!strncmp(qcc_token, "wrasm", 5)) + { + pbool on = atoi(msg); + + if (asmfile && !on) + { + fclose(asmfile); + asmfile = NULL; + } + if (!asmfile && on) + asmfile = fopen("qc.asm", "wb"); + } else if (!strncmp(qcc_token, "sourcefile", 10)) { #define MAXSOURCEFILESLIST 8 diff --git a/engine/qclib/qccgui.c b/engine/qclib/qccgui.c index e6fb7bd02..ac805648a 100644 --- a/engine/qclib/qccgui.c +++ b/engine/qclib/qccgui.c @@ -1893,7 +1893,7 @@ int GUIprintf(const char *msg, ...) void Sys_Error(const char *text, ...); void RunCompiler(char *args) { - char *argv[64]; + char *argv[128]; int argc; progexterns_t ext; progfuncs_t funcs; diff --git a/engine/qclib/qccmain.c b/engine/qclib/qccmain.c index 5fb287257..1e22aadce 100644 --- a/engine/qclib/qccmain.c +++ b/engine/qclib/qccmain.c @@ -767,6 +767,8 @@ pbool QCC_WriteData (int crc) } else if (def->type->type == ev_field && def->constant) { + if (numfielddefs >= MAX_FIELDS) + QCC_PR_ParseError(0, "Too many fields. Limit is %u\n", MAX_FIELDS); dd = &fields[numfielddefs]; numfielddefs++; dd->type = def->type->aux_type->type; diff --git a/engine/server/pr_cmds.c b/engine/server/pr_cmds.c index 686c0b760..f5f299b87 100644 --- a/engine/server/pr_cmds.c +++ b/engine/server/pr_cmds.c @@ -126,8 +126,6 @@ struct { func_t ClassChangeWeapon;//hexen2 support } gfuncs; -func_t getplayerstat[MAX_CL_STATS]; //unnamed FTE extension -func_t getplayerstati[MAX_CL_STATS];//unnamed FTE extension func_t SpectatorConnect; //QW func_t SpectatorThink; //QW func_t SpectatorDisconnect; //QW @@ -505,8 +503,6 @@ void PR_Deinit(void) //clear out function pointers (so changing game modes cannot lead to confusions) memset(&gfuncs, 0, sizeof(gfuncs)); - memset(&getplayerstat, 0, sizeof(getplayerstat)); - memset(&getplayerstati, 0, sizeof(getplayerstati)); SpectatorConnect = 0; SpectatorThink = 0; SpectatorDisconnect = 0; @@ -652,11 +648,6 @@ void PR_LoadGlabalStruct(void) SpectatorConnect = PR_FindFunction(svprogfuncs, "SpectatorConnect", PR_ANY); SpectatorDisconnect = PR_FindFunction(svprogfuncs, "SpectatorDisconnect", PR_ANY); SpectatorThink = PR_FindFunction(svprogfuncs, "SpectatorThink", PR_ANY); - for (i = 0; i < MAX_CL_STATS; i++) - { - getplayerstat[i] = PR_FindFunction(svprogfuncs, va("SetPlayerStat%i", i), PR_ANY); - getplayerstati[i] = PR_FindFunction(svprogfuncs, va("SetPlayerStat%ii", i), PR_ANY); - } gfuncs.ParseClientCommand = PR_FindFunction(svprogfuncs, "SV_ParseClientCommand", PR_ANY); gfuncs.ParseConnectionlessPacket = PR_FindFunction(svprogfuncs, "SV_ParseConnectionlessPacket", PR_ANY); diff --git a/engine/server/server.h b/engine/server/server.h index ec6e999f6..a3c387fbe 100644 --- a/engine/server/server.h +++ b/engine/server/server.h @@ -639,7 +639,9 @@ typedef struct int lastto; int lasttype; double time, pingtime; - int stats[MAX_CLIENTS][MAX_CL_STATS]; // ouch! + int statsi[MAX_CLIENTS][MAX_CL_STATS]; // ouch! + float statsf[MAX_CLIENTS][MAX_CL_STATS]; // ouch! + char *statss[MAX_CLIENTS][MAX_CL_STATS]; // ouch! client_t recorder; qboolean fixangle[MAX_CLIENTS]; float fixangletime[MAX_CLIENTS]; @@ -1286,7 +1288,6 @@ extern demo_t demo; // server demo struct extern cvar_t sv_demofps; extern cvar_t sv_demoPings; -extern cvar_t sv_demoNoVis; extern cvar_t sv_demoUseCache; extern cvar_t sv_demoMaxSize; extern cvar_t sv_demoMaxDirSize; diff --git a/engine/server/sv_ents.c b/engine/server/sv_ents.c index 10a224f0a..e13a098cc 100644 --- a/engine/server/sv_ents.c +++ b/engine/server/sv_ents.c @@ -262,6 +262,7 @@ void SV_EmitCSQCUpdate(client_t *client, sizebuf_t *msg) globalvars_t *pr_globals; edict_t *ent; qboolean writtenheader = false; + int viewerent; //we don't check that we got some already - because this is delta compressed! @@ -270,6 +271,11 @@ void SV_EmitCSQCUpdate(client_t *client, sizebuf_t *msg) pr_globals = PR_globals(svprogfuncs, PR_CURRENT); + if (client->edict) + viewerent = EDICT_TO_PROG(svprogfuncs, client->edict); + else + viewerent = 0; /*for mvds, its as if world is looking*/ + //FIXME: prioritise the list of csqc ents somehow csqcmsgbuffer.data = messagebuffer; @@ -300,7 +306,7 @@ void SV_EmitCSQCUpdate(client_t *client, sizebuf_t *msg) csqcmsgbuffer.cursize = 0; csqcmsgbuffer.currentbit = 0; //Ask CSQC to write a buffer for it. - G_INT(OFS_PARM0) = EDICT_TO_PROG(svprogfuncs, client->edict); + G_INT(OFS_PARM0) = viewerent; G_FLOAT(OFS_PARM1) = 0xffffff; //psudo compatibility with SendFlags (fte doesn't support properly) pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, ent); PR_ExecuteProgram(svprogfuncs, ent->xv->SendEntity); @@ -1477,6 +1483,9 @@ void SV_WritePlayersToClient (client_t *client, client_frame_t *frame, edict_t * } } + if (SV_AddCSQCUpdate(client, ent)) + continue; + if (cl->spectator) continue; diff --git a/engine/server/sv_init.c b/engine/server/sv_init.c index 26e644793..bb82fb906 100644 --- a/engine/server/sv_init.c +++ b/engine/server/sv_init.c @@ -572,6 +572,9 @@ void SV_UnspawnServer (void) //terminate the running server. Con_TPrintf(STL_SERVERUNSPAWNED); SV_FinalMessage("Server unspawned\n"); + if (sv.mvdrecording) + SV_MVDStop (0, false); + for (i = 0; i < sv.allocated_client_slots; i++) { if (svs.clients[i].state) diff --git a/engine/server/sv_main.c b/engine/server/sv_main.c index 5347b399f..d7eb0cc09 100644 --- a/engine/server/sv_main.c +++ b/engine/server/sv_main.c @@ -260,7 +260,7 @@ void SV_Shutdown (void) #endif if (sv.mvdrecording) - SV_MVDStop_f(); + SV_MVDStop (0, false); NET_Shutdown (); #ifdef WEBSERVER diff --git a/engine/server/sv_mvd.c b/engine/server/sv_mvd.c index 266461146..855b77874 100644 --- a/engine/server/sv_mvd.c +++ b/engine/server/sv_mvd.c @@ -30,6 +30,43 @@ void SV_MVDStop_f (void); #define demo_size_padding 0x1000 + +#define MIN_MVD_MEMORY 0x100000 +#define MAXSIZE (demobuffer->end < demobuffer->last ? \ + demobuffer->start - demobuffer->end : \ + demobuffer->maxsize - demobuffer->end) + +static void SV_DemoDir_Callback(struct cvar_s *var, char *oldvalue); + +cvar_t sv_demoUseCache = CVARD("sv_demoUseCache", "0", "If set, demo data will be flushed only periodically"); +cvar_t sv_demoCacheSize = CVAR("sv_demoCacheSize", "0x80000"); //half a meg +cvar_t sv_demoMaxDirSize = CVAR("sv_demoMaxDirSize", "102400"); //so ktpro autorecords. +cvar_t sv_demoDir = CVARC("sv_demoDir", "demos", SV_DemoDir_Callback); +cvar_t sv_demofps = CVAR("sv_demofps", "30"); +cvar_t sv_demoPings = CVARD("sv_demoPings", "10", "Interval between ping updates in mvds"); +cvar_t sv_demoMaxSize = CVARD("sv_demoMaxSize", "", "Demos will be truncated to be no larger than this size."); +cvar_t sv_demoExtraNames = CVAR("sv_demoExtraNames", ""); +cvar_t sv_demoExtensions = CVARD("sv_demoExtensions", "0", "Enables protocol extensions within MVDs. This will cause older/non-fte clients to error upon playback"); + +cvar_t qtv_password = CVAR( "qtv_password", ""); +cvar_t qtv_streamport = CVARAF( "qtv_streamport", "0", + "mvd_streamport", 0); +cvar_t qtv_maxstreams = CVARAF( "qtv_maxstreams", "1", + "mvd_maxstreams", 0); + +cvar_t sv_demoPrefix = CVAR("sv_demoPrefix", ""); +cvar_t sv_demoSuffix = CVAR("sv_demoSuffix", ""); +cvar_t sv_demotxt = CVAR("sv_demotxt", "1"); + +void SV_WriteMVDMessage (sizebuf_t *msg, int type, int to, float time); + +demo_t demo; +static dbuffer_t *demobuffer; +static int header = (char *)&((header_t*)0)->data - (char *)NULL; + +entity_state_t demo_entities[UPDATE_MASK+1][MAX_MVDPACKET_ENTITIES]; +client_frame_t demo_frames[UPDATE_MASK+1]; + mvddest_t *singledest; mvddest_t *SV_InitStream(int socket); @@ -699,42 +736,6 @@ void Sys_freedir(dir_t *dir) -#define MIN_MVD_MEMORY 0x100000 -#define MAXSIZE (demobuffer->end < demobuffer->last ? \ - demobuffer->start - demobuffer->end : \ - demobuffer->maxsize - demobuffer->end) - -static void SV_DemoDir_Callback(struct cvar_s *var, char *oldvalue); - -cvar_t sv_demoUseCache = CVAR("sv_demoUseCache", ""); -cvar_t sv_demoCacheSize = CVAR("sv_demoCacheSize", ""); -cvar_t sv_demoMaxDirSize = CVAR("sv_demoMaxDirSize", "102400"); //so ktpro autorecords. -cvar_t sv_demoDir = CVARC("sv_demoDir", "demos", SV_DemoDir_Callback); -cvar_t sv_demofps = CVAR("sv_demofps", ""); -cvar_t sv_demoPings = CVAR("sv_demoPings", ""); -cvar_t sv_demoNoVis = CVAR("sv_demoNoVis", ""); -cvar_t sv_demoMaxSize = CVAR("sv_demoMaxSize", ""); -cvar_t sv_demoExtraNames = CVAR("sv_demoExtraNames", ""); - -cvar_t qtv_password = CVAR( "qtv_password", ""); -cvar_t qtv_streamport = CVARAF( "qtv_streamport", "0", - "mvd_streamport", 0); -cvar_t qtv_maxstreams = CVARAF( "qtv_maxstreams", "1", - "mvd_maxstreams", 0); - -cvar_t sv_demoPrefix = CVAR("sv_demoPrefix", ""); -cvar_t sv_demoSuffix = CVAR("sv_demoSuffix", ""); -cvar_t sv_demotxt = CVAR("sv_demotxt", "1"); - -void SV_WriteMVDMessage (sizebuf_t *msg, int type, int to, float time); - -demo_t demo; -static dbuffer_t *demobuffer; -static int header = (char *)&((header_t*)0)->data - (char *)NULL; - -entity_state_t demo_entities[UPDATE_MASK+1][MAX_MVDPACKET_ENTITIES]; -client_frame_t demo_frames[UPDATE_MASK+1]; - // only one .. is allowed (so we can get to the same dir as the quake exe) static void SV_DemoDir_Callback(struct cvar_s *var, char *oldvalue) { @@ -1296,7 +1297,6 @@ void MVD_Init (void) Cvar_Register (&sv_demofps, MVDVARGROUP); Cvar_Register (&sv_demoPings, MVDVARGROUP); - Cvar_Register (&sv_demoNoVis, MVDVARGROUP); Cvar_Register (&sv_demoUseCache, MVDVARGROUP); Cvar_Register (&sv_demoCacheSize, MVDVARGROUP); Cvar_Register (&sv_demoMaxSize, MVDVARGROUP); @@ -1306,6 +1306,7 @@ void MVD_Init (void) Cvar_Register (&sv_demoSuffix, MVDVARGROUP); Cvar_Register (&sv_demotxt, MVDVARGROUP); Cvar_Register (&sv_demoExtraNames, MVDVARGROUP); + Cvar_Register (&sv_demoExtensions, MVDVARGROUP); } static char *SV_PrintTeams(void) @@ -1398,7 +1399,10 @@ mvddest_t *SV_InitRecordFile (char *name) { dst->desttype = DEST_BUFFEREDFILE; dst->file = file; - dst->maxcachesize = 0x81000; + if (sv_demoCacheSize.ival < 0x8000) + dst->maxcachesize = 0x8000; + else + dst->maxcachesize = sv_demoCacheSize.ival; dst->cache = BZ_Malloc(dst->maxcachesize); } dst->droponmapchange = true; @@ -1656,6 +1660,16 @@ static qboolean SV_MVD_Record (mvddest_t *dest) demo.datagram.maxsize = sizeof(demo.datagram_data); demo.datagram.data = demo.datagram_data; demo.datagram.prim = demo.recorder.netchan.netprim; + + if (sv_demoExtensions.ival) + { + demo.recorder.fteprotocolextensions = PEXT_CSQC | PEXT_COLOURMOD | PEXT_DPFLAGS | PEXT_CUSTOMTEMPEFFECTS | PEXT_ENTITYDBL | PEXT_ENTITYDBL2 | PEXT_FATNESS | PEXT_HEXEN2 | PEXT_HULLSIZE | PEXT_LIGHTSTYLECOL | PEXT_MODELDBL | PEXT_SCALE | PEXT_SETATTACHMENT | PEXT_SETVIEW | PEXT_SOUNDDBL | PEXT_SPAWNSTATIC2 | PEXT_TRANS | PEXT_VIEW2; + demo.recorder.fteprotocolextensions2 = PEXT2_VOICECHAT | PEXT2_SETANGLEDELTA | PEXT2_PRYDONCURSOR; + /*assume that all playback will be done with a valid csprogs that can correctly decode*/ + demo.recorder.csqcactive = true; + /*enable these, because we might as well (stat ones are always useful)*/ + demo.recorder.zquake_extensions = Z_EXT_PM_TYPE | Z_EXT_PM_TYPE_NEW | Z_EXT_VIEWHEIGHT | Z_EXT_SERVERTIME | Z_EXT_PITCHLIMITS | Z_EXT_JOIN_OBSERVE | Z_EXT_VWEP; + } } // else // SV_WriteRecordMVDMessage(&buf, dem_read); @@ -1701,13 +1715,29 @@ void SV_MVD_SendInitialGamestate(mvddest_t *dest) gamedir = Info_ValueForKey (svs.info, "*gamedir"); if (!gamedir[0]) + gamedir = FS_GetGamedir(); + + /*the gamedir shouldn't be fte - that should be hidden from clients*/ + if (!strncmp(gamedir, "fte", 3)) gamedir = "qw"; MSG_WriteByte (&buf, svc_serverdata); - if (buf.prim.coordsize == 4) //sorry. + + //fix up extensions to match sv_bigcoords correctly. sorry for old clients not working. + if (buf.prim.coordsize == 4) + demo.recorder.fteprotocolextensions |= PEXT_FLOATCOORDS; + else + demo.recorder.fteprotocolextensions &= ~PEXT_FLOATCOORDS; + + if (demo.recorder.fteprotocolextensions) { - MSG_WriteLong (&buf, PROTOCOL_VERSION_FTE); - MSG_WriteLong (&buf, PEXT_FLOATCOORDS); + MSG_WriteLong(&buf, PROTOCOL_VERSION_FTE); + MSG_WriteLong(&buf, demo.recorder.fteprotocolextensions); + } + if (demo.recorder.fteprotocolextensions2) + { + MSG_WriteLong(&buf, PROTOCOL_VERSION_FTE2); + MSG_WriteLong(&buf, demo.recorder.fteprotocolextensions2); } MSG_WriteLong (&buf, PROTOCOL_VERSION_QW); MSG_WriteLong (&buf, svs.spawncount); @@ -1744,7 +1774,7 @@ void SV_MVD_SendInitialGamestate(mvddest_t *dest) SZ_Clear (&buf); // soundlist - MSG_WriteByte (&buf, svc_soundlist); + MSG_WriteByte (&buf, svc_soundlist); /*FIXME: soundlist2*/ MSG_WriteByte (&buf, 0); n = 0; @@ -1774,7 +1804,7 @@ void SV_MVD_SendInitialGamestate(mvddest_t *dest) } // modellist - MSG_WriteByte (&buf, svc_modellist); + MSG_WriteByte (&buf, svc_modellist); /*FIXME: modellist2*/ MSG_WriteByte (&buf, 0); n = 0; @@ -1837,11 +1867,11 @@ void SV_MVD_SendInitialGamestate(mvddest_t *dest) MSG_WriteAngle(&buf, 0); } } - /* else if (host_client->fteprotocolextensions & PEXT_SPAWNSTATIC2) + else if (demo.recorder.fteprotocolextensions & PEXT_SPAWNSTATIC2) { - MSG_WriteByte(&buf, svc_spawnbaseline2); - SV_WriteDelta(&from, state, &buf, true, host_client->fteprotocolextensions); - }*/ + MSG_WriteByte(&buf, svcfte_spawnbaseline2); + SV_WriteDelta(&from, state, &buf, true, demo.recorder.fteprotocolextensions); + } else { MSG_WriteByte(&buf, svc_spawnbaseline); @@ -1912,11 +1942,26 @@ void SV_MVD_SendInitialGamestate(mvddest_t *dest) } // send all current light styles - for (i=0 ; i= MAX_STANDARDLIGHTSTYLES) + if (!sv.strings.lightstyles[i]) + continue; +#ifdef PEXT_LIGHTSTYLECOL + if ((demo.recorder.fteprotocolextensions & PEXT_LIGHTSTYLECOL) && sv.strings.lightstylecolours[i]!=7) + { + MSG_WriteByte (&buf, svcfte_lightstylecol); + MSG_WriteByte (&buf, (unsigned char)i); + MSG_WriteByte (&buf, sv.strings.lightstylecolours[i]); + MSG_WriteString (&buf, sv.strings.lightstyles[i]); + } + else +#endif + { + MSG_WriteByte (&buf, svc_lightstyle); + MSG_WriteByte (&buf, (unsigned char)i); + MSG_WriteString (&buf, sv.strings.lightstyles[i]); + } } // get the client to check and download skins diff --git a/engine/server/sv_send.c b/engine/server/sv_send.c index 9c5e3ee6e..fc053f26a 100644 --- a/engine/server/sv_send.c +++ b/engine/server/sv_send.c @@ -44,9 +44,6 @@ char outputbuf[8000]; redirect_t sv_redirected; int sv_redirectedlang; -extern func_t getplayerstat[MAX_CL_STATS]; -extern func_t getplayerstati[MAX_CL_STATS]; - extern cvar_t sv_phs; /* @@ -1450,28 +1447,15 @@ void SV_UpdateQCStats(edict_t *ent, int *statsi, char **statss, float *statsf) } } -/* -======================= -SV_UpdateClientStats - -Performs a delta update of the stats array. This should only be performed -when a reliable message can be delivered this frame. -======================= -*/ -void SV_UpdateClientStats (client_t *client, int pnum) +/*this function calculates the current stat values for the given client*/ +void SV_CalcClientStats(client_t *client, int statsi[MAX_CL_STATS], float statsf[MAX_CL_STATS], char *statss[MAX_CL_STATS]) { - edict_t *ent; - int statsi[MAX_CL_STATS]; - float statsf[MAX_CL_STATS]; - char *statss[MAX_CL_STATS]; - int i, m; - globalvars_t *pr_globals; extern qboolean pr_items2; - + edict_t *ent; ent = client->edict; - memset (statsi, 0, sizeof(statsi)); - memset (statsf, 0, sizeof(statsf)); - memset (statss, 0, sizeof(statss)); + memset (statsi, 0, sizeof(int)*MAX_CL_STATS); + memset (statsf, 0, sizeof(float)*MAX_CL_STATS); + memset (statss, 0, sizeof(char*)*MAX_CL_STATS); // if we are a spectator and we are tracking a player, we get his stats // so our status bar reflects his @@ -1482,15 +1466,13 @@ void SV_UpdateClientStats (client_t *client, int pnum) if (svs.gametype == GT_HALFLIFE) { SVHL_BuildStats(client, statsi, statsf, statss); - - pr_globals = NULL; } else #endif { statsf[STAT_HEALTH] = ent->v->health; //sorry, but mneh statsi[STAT_WEAPON] = SV_ModelIndex(PR_GetString(svprogfuncs, ent->v->weaponmodel)); - if (host_client->fteprotocolextensions & PEXT_MODELDBL) + if (client->fteprotocolextensions & PEXT_MODELDBL) { if ((unsigned)statsi[STAT_WEAPON] >= MAX_MODELS) statsi[STAT_WEAPON] = 0; @@ -1532,7 +1514,7 @@ void SV_UpdateClientStats (client_t *client, int pnum) else statsi[STAT_VIEWZOOM] = ent->xv->viewzoom*255; - if (host_client->protocol == SCP_DARKPLACES7) + if (client->protocol == SCP_DARKPLACES7) { float *statsfi = (float*)statsi; // statsfi[STAT_MOVEVARS_WALLFRICTION] = sv_wall @@ -1557,30 +1539,33 @@ void SV_UpdateClientStats (client_t *client, int pnum) } SV_UpdateQCStats(ent, statsi, statss, statsf); - - //dmw tweek for stats - pr_globals = PR_globals(svprogfuncs, PR_CURRENT); - pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, ent); } +} + +/* +======================= +SV_UpdateClientStats + +Performs a delta update of the stats array. This should only be performed +when a reliable message can be delivered this frame. +======================= +*/ +void SV_UpdateClientStats (client_t *client, int pnum) +{ + int statsi[MAX_CL_STATS]; + float statsf[MAX_CL_STATS]; + char *statss[MAX_CL_STATS]; + int i, m; + + /*figure out what the stat values should be*/ + SV_CalcClientStats(client, statsi, statsf, statss); + m = MAX_QW_STATS; if (client->fteprotocolextensions & PEXT_HEXEN2) m = MAX_CL_STATS; for (i=0 ; ib)?a:b) void SV_SendMVDMessage(void) { - int i, j, cls = 0; + int i, j, m, cls = 0; client_t *c; qbyte buf[MAX_DATAGRAM]; sizebuf_t msg; - edict_t *ent; - int stats[MAX_QW_STATS]; + int statsi[MAX_CL_STATS]; + float statsf[MAX_CL_STATS]; + char *statss[MAX_CL_STATS]; float min_fps; extern cvar_t sv_demofps; extern cvar_t sv_demoPings; @@ -2355,7 +2341,7 @@ void SV_SendMVDMessage(void) } - if (!sv_demofps.value) + if (sv_demofps.value <= 1) min_fps = 30.0; else min_fps = sv_demofps.value; @@ -2387,6 +2373,10 @@ void SV_SendMVDMessage(void) msg.allowoverflow = true; msg.overflowed = false; + m = MAX_QW_STATS; + if (demo.recorder.fteprotocolextensions & PEXT_HEXEN2) + m = MAX_CL_STATS; + for (i=0, c = svs.clients ; istate != cs_spawned) @@ -2395,42 +2385,74 @@ void SV_SendMVDMessage(void) if (c->spectator) continue; - ent = c->edict; - memset (stats, 0, sizeof(stats)); + /*figure out what the stat values should be*/ + SV_CalcClientStats(c, statsi, statsf, statss); - stats[STAT_HEALTH] = ent->v->health; - stats[STAT_WEAPON] = SV_ModelIndex(PR_GetString(svprogfuncs, ent->v->weaponmodel)); - stats[STAT_AMMO] = ent->v->currentammo; - stats[STAT_ARMOR] = ent->v->armorvalue; - stats[STAT_SHELLS] = ent->v->ammo_shells; - stats[STAT_NAILS] = ent->v->ammo_nails; - stats[STAT_ROCKETS] = ent->v->ammo_rockets; - stats[STAT_CELLS] = ent->v->ammo_cells; - stats[STAT_ACTIVEWEAPON] = ent->v->weapon; - - - // stuff the sigil bits into the high bits of items for sbar - stats[STAT_ITEMS] = (int)ent->v->items | ((int)pr_global_struct->serverflags << 28); - - for (j=0 ; j=0 && stats[j] <= 255) + if (statss[j] || demo.statss[i][j]) + if (strcmp(statss[j]?statss[j]:"", demo.statss[i][j]?demo.statss[i][j]:"")) + { + MVDWrite_Begin(dem_stats, i, 3+strlen(statss[j])); + demo.statss[i][j] = statss[j]; + MSG_WriteByte(&demo.dbuf->sb, svcfte_updatestatstring); + MSG_WriteByte(&demo.dbuf->sb, j); + MSG_WriteString(&demo.dbuf->sb, statss[j]); + } + } + + if (statsf[j]) + { + if (demo.recorder.fteprotocolextensions & PEXT_CSQC) + { + if (statsf[j] != demo.statsf[i][j]) + { + if (statsf[j] - (float)(int)statsf[j] == 0 && statsf[j] >= 0 && statsf[j] <= 255) + { + MVDWrite_Begin(dem_stats, i, 3); + MSG_WriteByte(&demo.dbuf->sb, svc_updatestat); + MSG_WriteByte(&demo.dbuf->sb, j); + MSG_WriteByte(&demo.dbuf->sb, statsf[j]); + } + else + { + MVDWrite_Begin(dem_stats, i, 6); + MSG_WriteByte(&demo.dbuf->sb, svcfte_updatestatfloat); + MSG_WriteByte(&demo.dbuf->sb, j); + MSG_WriteFloat(&demo.dbuf->sb, statsf[j]); + } + demo.statsf[i][j] = statsf[j]; + /*make sure statsf is correct*/ + demo.statsi[i][j] = statsf[j]; + } + continue; + } + else + statsi[j] = statsf[j]; + } + + if (statsi[j] != demo.statsi[i][j]) + { + demo.statsi[i][j] = statsi[j]; + demo.statsf[i][j] = statsi[j]; + if (statsi[j] >=0 && statsi[j] <= 255) { MVDWrite_Begin(dem_stats, i, 3); MSG_WriteByte(&demo.dbuf->sb, svc_updatestat); MSG_WriteByte(&demo.dbuf->sb, j); - MSG_WriteByte(&demo.dbuf->sb, stats[j]); + MSG_WriteByte(&demo.dbuf->sb, statsi[j]); } else { MVDWrite_Begin(dem_stats, i, 6); MSG_WriteByte(&demo.dbuf->sb, svc_updatestatlong); MSG_WriteByte(&demo.dbuf->sb, j); - MSG_WriteLong(&demo.dbuf->sb, stats[j]); + MSG_WriteLong(&demo.dbuf->sb, statsi[j]); } } + } } // send over all the objects that are in the PVS diff --git a/engine/server/sv_user.c b/engine/server/sv_user.c index 8641e2b3b..ab92e8cff 100644 --- a/engine/server/sv_user.c +++ b/engine/server/sv_user.c @@ -1870,14 +1870,14 @@ void SV_NextChunkedDownload(unsigned int chunknum, int ezpercent, int ezfilenum) qbyte oobdata[1+ (sizeof("\\chunk")-1) + 4 + 1 + 4 + CHUNKSIZE]; sizebuf_t *msg, msg_oob; int i; - qboolean error = false; + int error = false; msg = &host_client->datagram; if (chunknum*CHUNKSIZE > host_client->downloadsize) { SV_ClientPrintf (host_client, PRINT_HIGH, "Invalid file chunk requested %u to %u of %u.\n", chunknum*CHUNKSIZE, (chunknum+1)*CHUNKSIZE, host_client->downloadsize); - error = true; + error = 2; } if (!error && VFS_SEEK (host_client->download, chunknum*CHUNKSIZE) == false) @@ -1946,10 +1946,13 @@ void SV_NextChunkedDownload(unsigned int chunknum, int ezpercent, int ezfilenum) VFS_CLOSE (host_client->download); host_client->download = NULL; - ClientReliableWrite_Begin (host_client, svc_download, 10+strlen(host_client->downloadfn)); - ClientReliableWrite_Long (host_client, -1); - ClientReliableWrite_Long (host_client, -3); - ClientReliableWrite_String (host_client, host_client->downloadfn); + if (error != 2) + {/*work around for ezquake*/ + ClientReliableWrite_Begin (host_client, svc_download, 10+strlen(host_client->downloadfn)); + ClientReliableWrite_Long (host_client, -1); + ClientReliableWrite_Long (host_client, -3); + ClientReliableWrite_String (host_client, host_client->downloadfn); + } host_client->downloadstarted = false;