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;