From 261b104c0947e735b741e4ed480276d3d11fdbce Mon Sep 17 00:00:00 2001 From: Spoike Date: Tue, 16 Aug 2011 04:12:15 +0000 Subject: [PATCH] Added a cvar to enable recording mvd files containing 'unsafe' extensions, so CSQC ents can now be recorded. This defaults to off, and is expected to be enabled for mods that are truely FTE only. Recording qwd files works again. Not all extensions are fully implemented, when recording both mvds and qwds, particularly the initial connection info (including model list length). Ezquake's invalid chunk requests generate no protocol response. Ezquake should no longer kick itself after every download. Couple of other bugs fixed. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@3893 fc73d0e0-1445-4013-8a0c-d673dee63da5 --- engine/client/cl_demo.c | 19 +++- engine/client/cl_ents.c | 16 +-- engine/client/cl_parse.c | 2 +- engine/client/pr_csqc.c | 16 ++- engine/client/pr_menu.c | 5 +- engine/common/com_mesh.c | 17 ++- engine/common/fs.c | 2 +- engine/common/fs_zip.c | 9 +- engine/common/pr_bgcmd.c | 74 +++++++++++-- engine/d3d/vid_d3d.c | 13 +++ engine/dotnet2005/ftequake.sln | 168 ++++++++++++++++++++++-------- engine/dotnet2005/ftequake.vcproj | 9 +- engine/qclib/execloop.h | 2 +- engine/qclib/initlib.c | 9 +- engine/qclib/progslib.h | 5 +- engine/qclib/qcc_pr_comp.c | 71 ++++++++++--- engine/qclib/qcc_pr_lex.c | 12 +++ engine/qclib/qccgui.c | 2 +- engine/qclib/qccmain.c | 2 + engine/server/pr_cmds.c | 9 -- engine/server/server.h | 5 +- engine/server/sv_ents.c | 11 +- engine/server/sv_init.c | 3 + engine/server/sv_main.c | 2 +- engine/server/sv_mvd.c | 147 +++++++++++++++++--------- engine/server/sv_send.c | 160 ++++++++++++++++------------ engine/server/sv_user.c | 15 +-- 27 files changed, 566 insertions(+), 239 deletions(-) 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;