Fixed Ogg support a bit. Enhanced DarkPlaces/Nuxuiz compatability. Fixed a couple other minor bugs.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@2519 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2007-06-20 00:02:54 +00:00
parent 7ea15cfdc1
commit dcec305bd9
38 changed files with 1013 additions and 252 deletions

View file

@ -68,8 +68,9 @@ static int CDAudio_GetAudioDiskInfo(void)
DWORD dwReturn;
MCI_STATUS_PARMS mciStatusParms;
cdValid = false;
if (!initialized)
return -1;
mciStatusParms.dwItem = MCI_STATUS_READY;
dwReturn = mciSendCommand(wDeviceID, MCI_STATUS, MCI_STATUS_ITEM | MCI_WAIT, (DWORD_PTR) (LPVOID) &mciStatusParms);
@ -133,6 +134,9 @@ void CDAudio_Play(int track, qboolean looping)
}
}
if (!initialized)
return;
track = remap[track];
if (track < 1 || track > maxTrack)
@ -278,6 +282,26 @@ static void CD_f (void)
command = Cmd_Argv (1);
if (Q_strcasecmp(command, "play") == 0)
{
CDAudio_Play((qbyte)Q_atoi(Cmd_Argv (2)), false);
return;
}
if (Q_strcasecmp(command, "loop") == 0)
{
CDAudio_Play((qbyte)Q_atoi(Cmd_Argv (2)), true);
return;
}
if (!initialized)
{
Con_Printf("No cd drive detected\n");
return;
}
if (Q_strcasecmp(command, "on") == 0)
{
enabled = true;
@ -324,18 +348,6 @@ static void CD_f (void)
return;
}
if (Q_strcasecmp(command, "play") == 0)
{
CDAudio_Play((qbyte)Q_atoi(Cmd_Argv (2)), false);
return;
}
if (Q_strcasecmp(command, "loop") == 0)
{
CDAudio_Play((qbyte)Q_atoi(Cmd_Argv (2)), true);
return;
}
if (!cdValid)
{
CDAudio_GetAudioDiskInfo();
@ -446,6 +458,8 @@ int CDAudio_Init(void)
MCI_SET_PARMS mciSetParms;
int n;
Cmd_AddCommand ("cd", CD_f);
#if 0 // QW
if (cls.state == ca_dedicated)
return -1;
@ -484,8 +498,6 @@ int CDAudio_Init(void)
enabled = false;
}
Cmd_AddCommand ("cd", CD_f);
Cvar_Hook(&bgmvolume, BGMVolume_Callback);
// Con_Printf("CD Audio Initialized\n");

View file

@ -893,7 +893,7 @@ void CLNQ_ParseDarkPlaces5Entities(void) //the things I do.. :o(
cl_latestframenum = MSG_ReadLong();
if (nq_dp_protocol >=7)
/*cl.servermovesequence =*/ MSG_ReadLong();
cl.ackedinputsequence = MSG_ReadLong();
pack = &cl.frames[(cls.netchan.incoming_sequence)&UPDATE_MASK].packet_entities;
pack->servertime = cl.gametime;

View file

@ -739,7 +739,7 @@ void CLNQ_SendMove (usercmd_t *cmd, int pnum, sizebuf_t *buf)
MSG_WriteByte (buf, clc_move);
if (nq_dp_protocol>=7)
MSG_WriteLong(buf, 0);
MSG_WriteLong(buf, cls.netchan.outgoing_sequence);
MSG_WriteFloat (buf, cl.gametime); // so server can get ping times
@ -1254,13 +1254,13 @@ void CL_SendCmd (double frametime)
msecs -= msecstouse;
i = cls.netchan.outgoing_sequence & UPDATE_MASK;
cmd = &cl.frames[i].cmd[plnum];
*cmd = independantphysics[plnum];
cmd = &cl.frames[i].cmd[0];
*cmd = independantphysics[0];
cl.frames[i].senttime = realtime;
cl.frames[i].receivedtime = 0; // nq doesn't allow us to find our own packetloss
memset(&independantphysics[plnum], 0, sizeof(independantphysics[plnum]));
CLNQ_SendCmd ();
memset(&independantphysics[0], 0, sizeof(independantphysics[plnum]));
return;
}
#endif
@ -1609,6 +1609,22 @@ void CL_RegisterSplitCommands(void)
}
}
void CL_SendCvar_f (void)
{
cvar_t *var;
char *val;
char *name = Cmd_Argv(1);
var = Cvar_FindVar(name);
if (!var)
val = "";
else if (var->flags & CVAR_NOUNSAFEEXPAND)
val = "";
else
val = var->string;
CL_SendClientCommand(true, "sentcvar %s \"%s\"", name, val);
}
/*
============
CL_InitInput
@ -1622,6 +1638,7 @@ void CL_InitInput (void)
Cmd_AddCommand("rotate", IN_Rotate_f);
Cmd_AddCommand("in_restart", IN_Restart);
Cmd_AddCommand("sendcvar", CL_SendCvar_f);
Cvar_Register (&cl_nodelta, inputnetworkcvargroup);

View file

@ -1412,6 +1412,11 @@ void CL_CheckServerInfo(void)
movevars.airstep = (Q_atof(Info_ValueForKey(cl.serverinfo, "pm_airstep")) != 0);
movevars.walljump = (Q_atof(Info_ValueForKey(cl.serverinfo, "pm_walljump")));
movevars.ktjump = Q_atof(Info_ValueForKey(cl.serverinfo, "pm_ktjump"));
s = Info_ValueForKey(cl.serverinfo, "pm_stepheight");
if (*s)
movevars.stepheight = Q_atof(s);
else
movevars.stepheight = PM_DEFAULTSTEPHEIGHT;
// Initialize cl.maxpitch & cl.minpitch
s = (cls.z_ext & Z_EXT_PITCHLIMITS) ? Info_ValueForKey (cl.serverinfo, "maxpitch") : "";
@ -3345,6 +3350,8 @@ void Host_Init (quakeparms_t *parms)
Memory_Init (parms->membase, parms->memsize);
Sys_Init();
COM_ParsePlusSets();
Cbuf_Init ();
Cmd_Init ();

View file

@ -29,6 +29,9 @@ void CL_SetStat (int pnum, int stat, int value);
int nq_dp_protocol;
int msgflags;
int cl_dp_csqc_progssize;
int cl_dp_csqc_progscrc;
char *svc_strings[] =
{
@ -181,7 +184,7 @@ char *svc_nqstrings[] =
"NEW PROTOCOL",
"NEW PROTOCOL",
"NEW PROTOCOL",
"dpsvc_cgame", //50
"dpsvc_downloaddata", //50
"dpsvc_updatestatubyte",
"dpsvc_effect",
"dpsvc_effect2",
@ -399,10 +402,12 @@ void CL_FinishDownload(char *filename, char *tempname)
{
if (strncmp(tempname,"skins/",6))
{
FS_CreatePath(filename, FS_GAME);
FS_Rename(tempname, filename, FS_GAME);
}
else
{
FS_CreatePath(filename+6, FS_SKINS);
FS_Rename(tempname+6, filename+6, FS_SKINS);
}
}
@ -448,6 +453,21 @@ void MapDownload(char *name, qboolean gotornot)
CL_EnqueDownload(filename, false, false);
}
*/
qboolean CL_CheckFile(char *filename)
{
if (strstr (filename, ".."))
{
Con_TPrintf (TL_NORELATIVEPATHS);
return true;
}
if (COM_FCheckExists (filename))
{ // it exists, no need to download
return true;
}
return false;
}
/*
===============
CL_CheckOrEnqueDownloadFile
@ -456,20 +476,14 @@ Returns true if the file exists, otherwise it attempts
to start a download from the server.
===============
*/
qboolean CL_CheckOrEnqueDownloadFile (char *filename, char *localname)
{ //returns false if we don't have the file yet.
if (!localname)
localname = filename;
if (strstr (localname, ".."))
{
Con_TPrintf (TL_NORELATIVEPATHS);
return true;
}
if (COM_FCheckExists (localname))
{ // it exists, no need to download
if (CL_CheckFile(localname))
return true;
}
//ZOID - can't download when recording
if (cls.demorecording)
@ -624,6 +638,32 @@ int CL_LoadModels(int stage)
pmove.numphysent = 0;
#ifdef PEXT_CSQC
if (atstage())
{
if (cls.protocol == CP_NETQUAKE)
{
char *s;
s = Info_ValueForKey(cl.serverinfo, "*csprogs");
if (*s || cls.demoplayback) //only allow csqc if the server says so, and the 'checksum' matches.
{
extern cvar_t allow_download_csprogs;
unsigned int chksum = strtoul(s, NULL, 0);
if (allow_download_csprogs.value)
{
char *str = va("csprogsvers/%x.dat", chksum);
CL_CheckOrEnqueDownloadFile("csprogs.dat", str);
}
else
{
Con_Printf("Not downloading csprogs.dat due to allow_download_csprogs\n");
}
}
}
endstage();
}
#endif
#ifdef PEXT_CSQC
if (atstage())
{
@ -752,6 +792,7 @@ Sound_NextDownload
*/
void Sound_NextDownload (void)
{
char mangled[512];
char *s;
int i;
@ -785,7 +826,19 @@ void Sound_NextDownload (void)
s = cl.sound_name[i];
if (*s == '*')
continue;
CL_CheckOrEnqueDownloadFile(va("sound/%s",s), NULL);
s = va("sound/%s",s);
if (CL_CheckFile(s))
continue; //we have it already
//the things I do for nexuiz... *sigh*
COM_StripExtension(s, mangled, sizeof(mangled));
COM_DefaultExtension(mangled, ".ogg", sizeof(mangled));
if (CL_CheckFile(mangled))
continue;
//download the one the server said.
CL_CheckOrEnqueDownloadFile(s, NULL);
}
for (i=1 ; i<MAX_SOUNDS ; i++)
@ -1134,6 +1187,7 @@ int CL_RequestADownloadChunk(void)
// Con_Printf("^1 EOF?\n");
VFS_CLOSE(cls.downloadqw);
CL_SendClientCommand(true, "stopdownload");
CL_FinishDownload(cls.downloadname, cls.downloadtempname);
Con_Printf("Download took %i seconds (%i more)\n", (int)(Sys_DoubleTime() - downloadstarttime), CL_CountQueuedDownloads());
@ -1288,6 +1342,118 @@ void CL_ParseDownload (void)
}
}
void CLDP_ParseDownloadData(void)
{
unsigned char buffer[1<<16];
int start;
int size;
start = MSG_ReadLong();
size = (unsigned short)MSG_ReadShort();
MSG_ReadData(buffer, size);
VFS_SEEK(cls.downloadqw, start);
VFS_WRITE(cls.downloadqw, buffer, size);
//this is only reliable because I'm lazy
MSG_WriteByte(&cls.netchan.message, clcdp_ackdownloaddata);
MSG_WriteLong(&cls.netchan.message, start);
MSG_WriteShort(&cls.netchan.message, size);
cls.downloadpercent = start / (float)VFS_GETLEN(cls.downloadqw) * 100;
}
void CLDP_ParseDownloadBegin(char *s)
{
char buffer[8192];
unsigned int size, pos, chunk;
char *fname;
Cmd_TokenizeString(s+1, false, false);
size = (unsigned int)atoi(Cmd_Argv(1));
fname = Cmd_Argv(2);
COM_StripExtension (fname, cls.downloadtempname, sizeof(cls.downloadtempname)-5);
strcat (cls.downloadtempname, ".tmp");
CL_SendClientCommand(true, "sv_startdownload");
if (cls.downloadqw)
{
Con_Printf("Warning: cl_begindownload while already downloading\n");
VFS_CLOSE(cls.downloadqw);
}
FS_CreatePath (cls.downloadtempname, FS_GAME);
cls.downloadqw = FS_OpenVFS (cls.downloadtempname, "wb", FS_GAME);
cls.downloadmethod = DL_DARKPLACES;
//fill the file with 0 bytes
memset(buffer, 0, sizeof(buffer));
for (pos = 0, chunk = 1; chunk; pos += chunk)
{
chunk = size - pos;
if (chunk > sizeof(buffer))
chunk = sizeof(buffer);
VFS_WRITE(cls.downloadqw, buffer, chunk);
}
downloadstarttime = Sys_DoubleTime();
}
void CLDP_ParseDownloadFinished(char *s)
{
unsigned short runningcrc;
char buffer[8192];
int size, pos, chunk;
if (!cls.downloadqw)
return;
Cmd_TokenizeString(s+1, false, false);
VFS_CLOSE (cls.downloadqw);
cls.downloadqw = FS_OpenVFS (cls.downloadtempname, "rb", FS_GAME);
if (cls.downloadqw)
{
size = VFS_GETLEN(cls.downloadqw);
QCRC_Init(&runningcrc);
for (pos = 0, chunk = 1; chunk; pos += chunk)
{
chunk = size - pos;
if (chunk > sizeof(buffer))
chunk = sizeof(buffer);
VFS_READ(cls.downloadqw, buffer, chunk);
QCRC_AddBlock(&runningcrc, buffer, chunk);
}
VFS_CLOSE (cls.downloadqw);
}
Cmd_TokenizeString(s+1, false, false);
if (size != atoi(Cmd_Argv(1)))
{
Con_Printf("Download failed: wrong file size\n");
CL_DownloadFailed(cls.downloadname);
return;
}
if (runningcrc != atoi(Cmd_Argv(2)))
{
Con_Printf("Download failed: wrong crc\n");
CL_DownloadFailed(cls.downloadname);
return;
}
CL_FinishDownload(cls.downloadname, cls.downloadtempname);
*cls.downloadname = '\0';
cls.downloadqw = NULL;
cls.downloadpercent = 0;
Con_Printf("Download took %i seconds\n", (int)(Sys_DoubleTime() - downloadstarttime));
// get another file if needed
CL_RequestNextDownload ();
}
static vfsfile_t *upload_file;
static qbyte *upload_data;
static int upload_pos;
@ -1718,6 +1884,8 @@ void CLNQ_ParseServerData(void) //Doesn't change gamedir - use with caution.
Stats_NewMap();
Cvar_ForceCallback(&r_particlesdesc);
Info_SetValueForStarKey(cl.serverinfo, "*csprogs", va("%i", cl_dp_csqc_progscrc), sizeof(cl.serverinfo));
protover = MSG_ReadLong ();
sizeofcoord = 2;
@ -1875,7 +2043,8 @@ Con_DPrintf ("CL_SignonReply: %i\n", cls.signon);
switch (cls.signon)
{
case 1:
CL_SendClientCommand(true, "prespawn");
cl.sendprespawn = true;
// CL_SendClientCommand(true, "prespawn");
break;
case 2:
@ -1891,6 +2060,15 @@ Con_DPrintf ("CL_SignonReply: %i\n", cls.signon);
CL_SendClientCommand(true, "playermodel %s", model.string);
CL_SendClientCommand(true, "playerskin %s", skin.string);
{
char *s;
s = Info_ValueForKey(cl.serverinfo, "*csprogs");
if (*s)
CSQC_Init(atoi(s));
else
CSQC_Shutdown();
}
}
break;
@ -4211,10 +4389,12 @@ void CL_ParseServerMessage (void)
case svc_packetentities:
CL_ParsePacketEntities (false);
cl.ackedinputsequence = cl.validsequence;
break;
case svc_deltapacketentities:
CL_ParsePacketEntities (true);
cl.ackedinputsequence = cl.validsequence;
break;
case svc_maxspeed :
@ -4673,8 +4853,26 @@ void CLNQ_ParseServerMessage (void)
else
{
Con_DPrintf ("stufftext: %s\n", s);
if (!strncmp(s, "cl_serverextension_download ", 14))
{
}
else if (!strncmp(s, "\ncl_downloadbegin ", 17))
CLDP_ParseDownloadBegin(s);
else if (!strncmp(s, "\ncl_downloadfinished ", 17))
CLDP_ParseDownloadFinished(s);
else if (!strncmp(s, "csqc_progname ", 14))
{
// Info_SetValueForStarKey(cl.serverinfo, "*cspname", s+14, sizeof(cl.serverinfo));
}
else if (!strncmp(s, "csqc_progsize ", 14))
cl_dp_csqc_progssize = atoi(s+14);
else if (!strncmp(s, "csqc_progcrc ", 13))
cl_dp_csqc_progscrc = atoi(s+13);
else
{
Cbuf_AddText (s, RESTRICT_SERVER); //no cheating here...
}
}
break;
case svc_serverdata:
@ -4890,7 +5088,7 @@ void CLNQ_ParseServerMessage (void)
CL_ParseEffect(true);
break;
case 57://svc_entities
case svcdp_entities:
if (cls.signon == 4 - 1)
{ // first update is the final signon stage
cls.signon = 4;
@ -4899,7 +5097,16 @@ void CLNQ_ParseServerMessage (void)
//well, it's really any protocol, but we're only going to support version 5.
CLNQ_ParseDarkPlaces5Entities();
break;
case svcdp_csqcentities:
CSQC_ParseEntities();
break;
case svcdp_downloaddata:
CLDP_ParseDownloadData();
break;
}
}
}
#endif

View file

@ -474,7 +474,7 @@ void CL_CalcCrouch (int pnum)
if (cl.onground[pnum] && cl.simorg[pnum][2] - oldz[pnum] > 0)
{
if (cl.simorg[pnum][2] - oldz[pnum] > 20)
if (cl.simorg[pnum][2] - oldz[pnum] > movevars.stepheight+2)
{
// if on steep stairs, increase speed
if (crouchspeed[pnum] < 160)
@ -717,12 +717,12 @@ void CL_PredictMovePNum (int pnum)
return;
}
if (!cl.validsequence)
if (!cl.ackedinputsequence)
{
return;
}
if (cls.netchan.outgoing_sequence - cl.validsequence >= UPDATE_BACKUP-1)
if (cls.netchan.outgoing_sequence - cl.ackedinputsequence >= UPDATE_BACKUP-1)
{ //lagging like poo.
if (!cl.intermission) //keep the angles working though.
VectorCopy (cl.viewangles[pnum], cl.simangles[pnum]);
@ -730,7 +730,7 @@ void CL_PredictMovePNum (int pnum)
}
// this is the last frame received from the server
from = &cl.frames[cl.validsequence & UPDATE_MASK];
from = &cl.frames[cl.ackedinputsequence & UPDATE_MASK];
if (!cl.intermission)
{
@ -793,7 +793,7 @@ fixedorg:
VectorCopy (vel, cl.simvel[pnum]);
VectorCopy (org, cl.simorg[pnum]);
to = &cl.frames[cl.validsequence & UPDATE_MASK];
to = &cl.frames[cl.ackedinputsequence & UPDATE_MASK];
@ -805,13 +805,13 @@ fixedorg:
oldphysent = pmove.numphysent;
CL_SetSolidPlayers (cl.playernum[pnum]);
to = &cl.frames[cl.validsequence & UPDATE_MASK];
to = &cl.frames[cl.ackedinputsequence & UPDATE_MASK];
if (Cam_TrackNum(pnum)>=0 && !cl_nolerp.value && cls.demoplayback != DPB_MVD)
{
float f;
to = &cl.frames[cl.validsequence & UPDATE_MASK];
to = &cl.frames[cl.ackedinputsequence & UPDATE_MASK];
from = &cl.frames[cl.oldvalidsequence & UPDATE_MASK];
//figure out the lerp factor
@ -838,10 +838,10 @@ fixedorg:
}
else
{
for (i=1 ; i<UPDATE_BACKUP-1 && cl.validsequence+i <
for (i=1 ; i<UPDATE_BACKUP-1 && cl.ackedinputsequence+i <
cls.netchan.outgoing_sequence; i++)
{
to = &cl.frames[(cl.validsequence+i) & UPDATE_MASK];
to = &cl.frames[(cl.ackedinputsequence+i) & UPDATE_MASK];
if (cl.intermission)
to->playerstate->pm_type = PM_FLY;
CL_PredictUsercmd (pnum, &from->playerstate[cl.playernum[pnum]]

View file

@ -2301,6 +2301,7 @@ void SCR_DrawTwoDimensional(int uimenu, qboolean nohud)
{
Sbar_IntermissionOverlay ();
M_Draw (uimenu);
MP_Draw();
}
else if (cl.intermission == 2 && key_dest == key_game)
{
@ -2349,6 +2350,7 @@ void SCR_DrawTwoDimensional(int uimenu, qboolean nohud)
Editor_Draw();
#endif
M_Draw (uimenu);
MP_Draw();
SCR_DrawConsole (false);
}

View file

@ -329,7 +329,7 @@ typedef struct
int tcpinlen;
#endif
enum {DL_NONE, DL_QW, DL_QWCHUNKS, DL_Q3, DL_QWPENDING, DL_HTTP, DL_FTP} downloadmethod;
enum {DL_NONE, DL_QW, DL_QWCHUNKS, DL_Q3, DL_DARKPLACES, DL_QWPENDING, DL_HTTP, DL_FTP} downloadmethod;
vfsfile_t *downloadqw; // file transfer from server
char downloadtempname[MAX_OSPATH];
char downloadname[MAX_OSPATH];
@ -429,6 +429,7 @@ typedef struct
int parsecount; // server message counter
int oldparsecount;
int oldvalidsequence;
int ackedinputsequence; //in quakeworld/q2 this is always equal to validsequence. dp can differ.
int validsequence; // this is the sequence number of the last good
// packetentity_t we got. If this is 0, we can't
// render a frame yet

View file

@ -1065,7 +1065,7 @@ void M_Draw (int uimenu)
#endif
#ifdef MENU_DAT
case m_menu_dat:
MP_Draw();
// MP_Draw();
return;
#endif
}

View file

@ -1246,7 +1246,7 @@ void MasterInfo_Begin(void)
Master_AddMaster("62.112.145.129:27000", MT_MASTERQW, "Ocrana master server.");
// Master_AddMaster("master.edome.net", MT_MASTERQW, "edome master server.");
Master_AddMaster("qwmaster.barrysworld.com", MT_MASTERQW, "barrysworld master server.");
//down Master_AddMaster("qwmaster.barrysworld.com", MT_MASTERQW, "barrysworld master server.");
Master_AddMaster("qwmaster.ocrana.de:27000", MT_MASTERQW, "Ocrana2 master server.");
Master_AddMaster("213.221.174.165:27000", MT_MASTERQW, "unknown1 master server.");
Master_AddMaster("195.74.0.8", MT_MASTERQW, "unknown2 master server.");

View file

@ -86,6 +86,7 @@ extern sfx_t *cl_sfx_r_exp3;
\
globalfloat(player_localentnum, "player_localentnum"); /*float the entity number of the local player*/ \
globalfloat(intermission, "intermission"); /*float the entity number of the local player*/ \
globalvector(view_angles, "view_angles"); \
\
globalvector(pmove_org, "pmove_org"); \
globalvector(pmove_vel, "pmove_vel"); \
@ -2699,11 +2700,11 @@ static void PF_shaderforname (progfuncs_t *prinst, struct globalvars_s *pr_globa
shader_t *shad;
shad = R_RegisterSkin(str);
if (shad)
G_INT(OFS_RETURN) = shad-r_shaders + 1;
G_FLOAT(OFS_RETURN) = shad-r_shaders + 1;
else
G_INT(OFS_RETURN) = 0;
G_FLOAT(OFS_RETURN) = 0;
#else
G_INT(OFS_RETURN) = 0;
G_FLOAT(OFS_RETURN) = 0;
#endif
}
@ -2747,7 +2748,7 @@ realcheck:
// the midpoint must be within 16 of the bottom
start[0] = stop[0] = (mins[0] + maxs[0])*0.5;
start[1] = stop[1] = (mins[1] + maxs[1])*0.5;
stop[2] = start[2] - 2*pm_stepheight;
stop[2] = start[2] - 2*movevars.stepheight;
trace = CS_Move (start, vec3_origin, vec3_origin, stop, true, ent);
if (trace.fraction == 1.0)
@ -2768,7 +2769,7 @@ realcheck:
if (trace.fraction != 1.0 && trace.endpos[2] > bottom)
bottom = trace.endpos[2];
if (trace.fraction == 1.0 || mid - trace.endpos[2] > pm_stepheight)
if (trace.fraction == 1.0 || mid - trace.endpos[2] > movevars.stepheight)
return false;
}
@ -2846,9 +2847,9 @@ qboolean CS_movestep (csqcedict_t *ent, vec3_t move, qboolean relink, qboolean n
}
// push down from a step height above the wished position
neworg[2] += pm_stepheight;
neworg[2] += movevars.stepheight;
VectorCopy (neworg, end);
end[2] -= pm_stepheight*2;
end[2] -= movevars.stepheight*2;
trace = CS_Move (neworg, ent->v->mins, ent->v->maxs, end, false, ent);
if (set_trace)
@ -2859,7 +2860,7 @@ qboolean CS_movestep (csqcedict_t *ent, vec3_t move, qboolean relink, qboolean n
if (trace.startsolid)
{
neworg[2] -= pm_stepheight;
neworg[2] -= movevars.stepheight;
trace = CS_Move (neworg, ent->v->mins, ent->v->maxs, end, false, ent);
if (set_trace)
cs_settracevars(&trace);
@ -3211,7 +3212,7 @@ PF_str2chr, // #222 float(string str, float index) str2chr (FTE_STRINGS)
PF_chr2str, // #223 string(float chr, ...) chr2str (FTE_STRINGS)
PF_strconv, // #224 string(float ccase, float redalpha, float redchars, string str, ...) strconv (FTE_STRINGS)
PF_strpad, // #225 string(float ccase, float redalpha, float redchars, string str, ...) strconv (FTE_STRINGS)
PF_strpad, // #225 string strpad(float pad, string str1, ...) strpad (FTE_STRINGS)
PF_infoadd, // #226 string(string old, string key, string value) infoadd
PF_infoget, // #227 string(string info, string key) infoget
PF_strncmp, // #228 float(string s1, string s2, float len) strncmp (FTE_STRINGS)
@ -3525,14 +3526,32 @@ qbyte *CSQC_PRLoadFile (char *path, void *buffer, int bufsize)
file = COM_LoadStackFile(newname, buffer, bufsize);
if (file)
{
if (cls.protocol == CP_NETQUAKE)
{
if (QCRC_Block(file, com_filesize) == csqcchecksum)
return file;
}
else
{
if (Com_BlockChecksum(file, com_filesize) == csqcchecksum) //and the user wasn't trying to be cunning.
return file;
}
}
file = COM_LoadStackFile(path, buffer, bufsize);
if (file && !cls.demoplayback) //allow them to use csprogs.dat if playing a demo, and don't care about the checksum
{
if (cls.protocol == CP_NETQUAKE)
{
if (QCRC_Block(file, com_filesize) != csqcchecksum)
return NULL;
}
else
{
if (Com_BlockChecksum(file, com_filesize) != csqcchecksum)
return NULL; //not valid
}
//back it up
COM_WriteFile(newname, file, com_filesize);
@ -3556,15 +3575,35 @@ int CSQC_PRFileSize (char *path)
file = COM_LoadTempFile (newname);
if (file)
{
if (cls.protocol == CP_NETQUAKE)
{
if (QCRC_Block(file, com_filesize) == csqcchecksum)
return com_filesize+1;
}
else
{
if (Com_BlockChecksum(file, com_filesize) == csqcchecksum) //and the user wasn't trying to be cunning.
return com_filesize+1;
}
}
file = COM_LoadTempFile(path);
if (file && !cls.demoplayback) //allow them to use csprogs.dat if playing a demo, and don't care about the checksum
{
if (cls.protocol == CP_NETQUAKE)
{
if (QCRC_Block(file, com_filesize) != csqcchecksum)
return -1; //not valid
}
else
{
if (Com_BlockChecksum(file, com_filesize) != csqcchecksum)
return -1; //not valid
}
}
if (!file)
return -1;
return com_filesize;
}
@ -3718,10 +3757,17 @@ qboolean CSQC_DrawView(void)
if (csqcg.clientcommandframe)
*csqcg.clientcommandframe = cls.netchan.outgoing_sequence;
if (csqcg.servercommandframe)
*csqcg.servercommandframe = cls.netchan.incoming_sequence;
*csqcg.servercommandframe = cl.ackedinputsequence;
if (csqcg.intermission)
*csqcg.intermission = cl.intermission;
if (csqcg.view_angles)
{
csqcg.view_angles[0] = cl.viewangles[0][0];
csqcg.view_angles[1] = cl.viewangles[0][1];
csqcg.view_angles[2] = cl.viewangles[0][2];
}
if (csqcg.time)
*csqcg.time = Sys_DoubleTime();
@ -3858,7 +3904,7 @@ void CSQC_ParseEntities(void)
if (csqcg.clientcommandframe)
*csqcg.clientcommandframe = cls.netchan.outgoing_sequence;
if (csqcg.servercommandframe)
*csqcg.servercommandframe = cls.netchan.incoming_sequence;
*csqcg.servercommandframe = cl.ackedinputsequence;
for(;;)
{

View file

@ -23,6 +23,8 @@ typedef struct menuedict_s
evalc_t menuc_eval_chain;
int menuentsize;
// cvars
@ -830,6 +832,12 @@ void PF_M_addwantedhostcachekey(progfuncs_t *prinst, struct globalvars_s *pr_glo
{
PF_M_gethostcacheindexforkey(prinst, pr_globals);
}
void PF_M_getextresponse(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
//this does something weird
G_INT(OFS_RETURN) = 0;
}
#else
void PF_gethostcachevalue (progfuncs_t *prinst, struct globalvars_s *pr_globals){G_FLOAT(OFS_RETURN) = 0;}
@ -887,7 +895,8 @@ void PF_CL_precache_file (progfuncs_t *prinst, struct globalvars_s *pr_globals)
void PF_menu_findchain (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int i, f;
char *s, *t;
char *s;
string_t t;
menuedict_t *ent, *chain; //note, all edicts share the common header, but don't use it's fields!
eval_t *val;
@ -901,13 +910,13 @@ void PF_menu_findchain (progfuncs_t *prinst, struct globalvars_s *pr_globals)
ent = (menuedict_t *)EDICT_NUM(prinst, i);
if (ent->isfree)
continue;
t = *(string_t *)&((float*)ent->fields)[f] + prinst->stringtable;
t = *(string_t *)&((float*)ent->fields)[f];
if (!t)
continue;
if (strcmp(t, s))
if (strcmp(PR_GetString(prinst, t), s))
continue;
val = prinst->GetEdictFieldValue(prinst, (void*)ent, "chain", NULL);
val = prinst->GetEdictFieldValue(prinst, (void*)ent, "chain", &menuc_eval_chain);
if (val)
val->edict = EDICT_TO_PROG(prinst, (void*)chain);
chain = ent;
@ -1295,7 +1304,8 @@ builtin_t menu_builtins[] = {
PF_M_refreshhostcache,
PF_M_gethostcachenumber,
PF_M_gethostcacheindexforkey,
PF_M_addwantedhostcachekey
PF_M_addwantedhostcachekey,
PF_M_getextresponse // #624
};
int menu_numbuiltins = sizeof(menu_builtins)/sizeof(menu_builtins[0]);
@ -1407,6 +1417,8 @@ void MP_Init (void)
M_DeInit_Internal();
memset(&menuc_eval_chain, 0, sizeof(menuc_eval_chain));
menuprogparms.progsversion = PROGSTRUCT_VERSION;
menuprogparms.ReadFile = COM_LoadStackFile;//char *(*ReadFile) (char *fname, void *buffer, int *len);
@ -1521,7 +1533,7 @@ void MP_Reload_f(void)
void MP_RegisterCvarsAndCmds(void)
{
Cmd_AddCommand("coredump_menuqc", MP_CoreDump_f);
Cmd_AddCommand("menuqc_reload", MP_Reload_f);
Cmd_AddCommand("menu_restart", MP_Reload_f);
Cvar_Register(&forceqmenu, MENUPROGSGROUP);
Cvar_Register(&pr_menuqc_coreonerror, MENUPROGSGROUP);
@ -1532,6 +1544,8 @@ void MP_RegisterCvarsAndCmds(void)
void MP_Draw(void)
{
if (!menuprogs)
return;
if (setjmp(mp_abort))
return;

View file

@ -1783,6 +1783,9 @@ void Sbar_Draw (void)
if (sbarfailed) //files failed to load.
{
if (cl.stats[pnum][STAT_HEALTH] <= 0) //when dead, show nothing
continue;
if (scr_viewsize.value != 120)
Cvar_Set(&scr_viewsize, "120");

View file

@ -709,9 +709,13 @@ sfxcache_t *S_LoadWavSound (sfx_t *s, qbyte *data, int datalen, int sndspeed)
int len;
sfxcache_t *sc;
if (datalen < 4 || strncmp(data, "RIFF", 4))
return NULL;
info = GetWavinfo (s->name, data, datalen);
if (info.numchannels < 1 || info.numchannels > 2)
{
s->failedload = true;
Con_Printf ("%s has an unsupported quantity of channels.\n",s->name);
return NULL;
}
@ -851,6 +855,15 @@ sfxcache_t *S_LoadSound (sfx_t *s)
if (!data)
data = COM_LoadStackFile(namebuffer, stackbuf, sizeof(stackbuf));
if (!data)
{
char altname[sizeof(namebuffer)];
COM_StripExtension(namebuffer, altname, sizeof(altname));
COM_DefaultExtension(altname, ".ogg", sizeof(altname));
data = COM_LoadStackFile(altname, stackbuf, sizeof(stackbuf));
if (data)
Con_DPrintf("found a mangled name\n");
}
}
if (!data)
@ -861,6 +874,8 @@ sfxcache_t *S_LoadSound (sfx_t *s)
return NULL;
}
s->failedload = false;
for (i = sizeof(AudioInputPlugins)/sizeof(AudioInputPlugins[0])-1; i >= 0; i--)
{
if (AudioInputPlugins[i])
@ -871,6 +886,9 @@ sfxcache_t *S_LoadSound (sfx_t *s)
}
}
if (!s->failedload)
Con_Printf ("Format not recognised: %s\n", namebuffer);
s->failedload = true;
return NULL;
}

View file

@ -84,6 +84,9 @@ sfxcache_t *S_LoadOVSound (sfx_t *s, qbyte *data, int datalen, int sndspeed)
//qboolean telluser; //unreferenced
//int len; //unreferenced
if (datalen < 4 || strncmp(data, "OggS", 4))
return NULL;
name = s->name;
if (!s->decoder)
@ -107,6 +110,7 @@ sfxcache_t *S_LoadOVSound (sfx_t *s, qbyte *data, int datalen, int sndspeed)
}
Z_Free(s->decoder);
s->decoder=NULL;
s->failedload = true;
return NULL;
}
@ -131,6 +135,8 @@ int OV_DecodeSome(sfx_t *s, int minlength)
// Con_Printf("Minlength = %03i ", minlength);
for (;;)
{
if (dec->mediaaswavbuflen < dec->mediaaswavpos+minlength+11050) //expand if needed.
{
// Con_Printf("Expand buffer\n");
@ -153,12 +159,14 @@ int OV_DecodeSome(sfx_t *s, int minlength)
return 0;
}
for (;;)
{
bytesread = p_ov_read(&dec->vf, dec->mediaaswavdata+dec->mediaaswavpos, dec->mediaaswavbuflen-dec->mediaaswavpos, bigendianp, 2, 1, &current_section);
if (bytesread <= 0)
{
if (bytesread != 0) //0==eof
{
Con_Printf("ogg decoding failed\n");
return 1;
}
return 0;
}
@ -275,6 +283,8 @@ qboolean OV_StartDecode(unsigned char *start, unsigned long length, ovdecoderbuf
#elif defined(WINDOWSDYNAMICLINK)
{
oggvorbislibrary = LoadLibrary("vorbisfile.dll");
if (!oggvorbislibrary)
oggvorbislibrary = LoadLibrary("libvorbisfile.dll");
if (!oggvorbislibrary)
{
Con_Printf("Couldn't load DLL: \"vorbisfile.dll\".\n");
@ -311,14 +321,17 @@ qboolean OV_StartDecode(unsigned char *start, unsigned long length, ovdecoderbuf
tried = true;
if (!oggvorbislibrary)
{
Con_Printf("ogg vorbis library is not loaded.\n");
return false;
}
buffer->start = start;
buffer->length = length;
buffer->pos = 0;
if (p_ov_open_callbacks(buffer, &buffer->vf, NULL, 0, callbacks))
{
// Con_Printf("Input does not appear to be an Ogg bitstream.\n");
Con_Printf("Input does not appear to be an Ogg bitstream.\n");
return false;
}

View file

@ -473,8 +473,6 @@ int main (int c, char **v)
if (COM_CheckParm("-nostdout"))
nostdout = 1;
Sys_Init();
Host_Init(&parms);
oldtime = Sys_DoubleTime ();

View file

@ -259,7 +259,6 @@ int main(int argc, char **argv)
#else
parms.membase = malloc (parms.memsize);
#endif
Sys_Init ();
Sys_Printf ("Host_Init\n");
Host_Init (&parms);

View file

@ -462,6 +462,9 @@ void Sys_Init (void)
// unsigned int lowpart, highpart;
OSVERSIONINFO vinfo;
Cvar_Register(&sys_disableWinKeys, "System vars");
Cvar_Register(&sys_disableTaskSwitch, "System vars");
#ifndef SERVERONLY
#ifndef CLIENTONLY
if (!isDedicated && !COM_CheckParm("-nomutex"))
@ -1232,14 +1235,9 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin
if (!tevent)
Sys_Error ("Couldn't create event");
Sys_Init ();
Sys_Printf ("Host_Init\n");
Host_Init (&parms);
Cvar_Register(&sys_disableWinKeys, "System vars");
Cvar_Register(&sys_disableTaskSwitch, "System vars");
oldtime = Sys_DoubleTime ();

View file

@ -1168,7 +1168,7 @@ void V_CalcRefdef (int pnum)
else if (scr_viewsize.value == 80)
view->origin[2] += 0.5;
if (!view_message || view_message->flags & (PF_GIB|PF_DEAD) )
if (!view_message || view_message->flags & (PF_GIB|PF_DEAD) || (unsigned int)cl.stats[pnum][STAT_WEAPON] >= MAX_MODELS)
view->model = NULL;
else
view->model = cl.model_precache[cl.stats[pnum][STAT_WEAPON]];

View file

@ -530,7 +530,7 @@ MAX_CL_STATS = 256
#define SAVEGAME_VERSION 667
#define PM_DEFAULTSTEPHEIGHT 18
#define dem_cmd 0

View file

@ -1602,6 +1602,247 @@ void COM_DefaultExtension (char *path, char *extension, int maxlen)
Q_strncatz (path, extension, maxlen);
}
///=====================================
//Strips out the flags
void COM_DeFunString(unsigned long *str, char *out, int outsize, qboolean ignoreflags)
{
if (ignoreflags)
{
while(*str)
{
if (!--outsize)
break;
*out++ = (unsigned char)(*str++&255);
}
*out++ = 0;
}
else
{
int fl, d;
//FIXME: TEST!
fl = CON_WHITEMASK;
while(*str)
{
if (!--outsize)
break;
if ((*str & CON_FLAGSMASK) != fl)
{
d = fl^(*str & CON_FLAGSMASK);
// if (fl & CON_NONCLEARBG) //not represented.
if (d & CON_BLINKTEXT)
{
if (outsize<=2)
break;
outsize -= 2;
*out++ = '^';
*out++ = 'b';
}
if (d & CON_2NDCHARSETTEXT)
{
if (outsize<=2)
break;
outsize -= 2;
*out++ = '^';
*out++ = 'a';
}
if (d & CON_HALFALPHA)
{
if (outsize<=2)
break;
outsize -= 2;
*out++ = '^';
*out++ = 'h';
}
if (d & (CON_FGMASK | CON_BGMASK | CON_NONCLEARBG))
{
if (outsize<=4)
break;
outsize -= 4;
d = (*str & CON_FLAGSMASK);
*out++ = '^';
*out++ = '&';
if ((d & CON_FGMASK) == CON_WHITEMASK)
*out++ = '-';
else
sprintf(out, "%X", d>>24);
if (d & CON_NONCLEARBG)
{
sprintf(out, "%X", d>>28);
}
else
*out++ = '-';
}
fl = (*str & CON_FLAGSMASK);
}
*out++ = (unsigned char)(*str++&255);
}
*out++ = 0;
}
}
//Takes a q3-style fun string, and returns an expanded string-with-flags
void COM_ParseFunString(char *str, unsigned long *out, int outsize)
{
int ext = CON_WHITEMASK;
int extstack[4];
int extstackdepth = 0;
while(*str)
{
if (*str == '^')
{
str++;
if (*str >= '0' && *str <= '9')
{
ext = q3codemasks[*str++-'0'] | (ext&~CON_Q3MASK); //change colour only.
continue;
}
else if (*str == '&') // extended code
{
if (isextendedcode(str[1]) && isextendedcode(str[2]))
{
str++;// foreground char
if (*str == '-') // default for FG
ext = (COLOR_WHITE << CON_FGSHIFT) | (ext&~CON_FGMASK);
else if (*str >= 'A')
ext = ((*str - ('A' - 10)) << CON_FGSHIFT) | (ext&~CON_FGMASK);
else
ext = ((*str - '0') << CON_FGSHIFT) | (ext&~CON_FGMASK);
str++; // background char
if (*str == '-') // default (clear) for BG
ext &= ~CON_BGMASK & ~CON_NONCLEARBG;
else if (*str >= 'A')
ext = ((*str - ('A' - 10)) << CON_BGSHIFT) | (ext&~CON_BGMASK) | CON_NONCLEARBG;
else
ext = ((*str - '0') << CON_BGSHIFT) | (ext&~CON_BGMASK) | CON_NONCLEARBG;
str++;
continue;
}
// else invalid code
goto messedup;
}
else if (*str == 'a')
{
str++;
ext ^= CON_2NDCHARSETTEXT;
continue;
}
else if (*str == 'b')
{
str++;
ext ^= CON_BLINKTEXT;
continue;
}
else if (*str == 'h')
{
str++;
ext ^= CON_HALFALPHA;
continue;
}
else if (*str == 's') //store on stack (it's great for names)
{
str++;
if (extstackdepth < sizeof(extstack)/sizeof(extstack[0]))
{
extstack[extstackdepth] = ext;
extstackdepth++;
}
continue;
}
else if (*str == 'r') //restore from stack (it's great for names)
{
str++;
if (extstackdepth)
{
extstackdepth--;
ext = extstack[extstackdepth];
}
continue;
}
else if (*str == '^')
{
if (!--outsize)
break;
*out++ = '^' | ext;
str++;
}
else
{
if (!--outsize)
break;
*out++ = '^' | ext;
if (!--outsize)
break;
*out++ = (*str++) | ext;
}
continue;
}
messedup:
if (!--outsize)
break;
*out++ = (*str++) | ext;
}
*out = 0;
}
int COM_FunStringLength(unsigned char *str)
{
int len;
while(*str)
{
if (*str == '^')
{
str++;
if (*str >= '0' && *str <= '9')
str++; //invisible
else if (*str == '&') // extended code
{
if (isextendedcode(str[1]) && isextendedcode(str[2]))
{
str++;// foreground char
str++; // background char
str++;
continue;
}
// else invalid code
goto messedup;
}
else if (*str == 'a' || *str == 'b' || *str == 'h' || *str == 's' || *str == 'r')
str++; //invisible
else if (*str == '^')
{
len++; //double-code single-output
str++;
}
else
{
len++; //not recognised
len++;
str++;
}
continue;
}
messedup:
len++;
str++;
}
return len;
}
//============================================================================
#define TOKENSIZE sizeof(com_token)

View file

@ -2788,6 +2788,7 @@ void COM_Gamedir (char *dir)
#endif
}
/*
typedef struct {
char *file;
char *path;
@ -2801,7 +2802,9 @@ potentialgamepath_t pgp[] = {
{"%s/baseq3/pak0.pk3", "%s/baseq3"}, //quake3
{"%s/base/assets0.pk3", "%s/base"} //jk2
};
*/
#define NEXCFG "set sv_maxairspeed \"400\"\nset sv_mintic \"0.01\"\ncl_nolerp 0\n"
typedef struct {
char *gamename; //sent to the master server when this is the current gamemode.
@ -2809,6 +2812,8 @@ typedef struct {
char *argname; //used if this was used as a parameter.
char *auniquefile; //used if this file is relative from the gamedir
char *customexec;
char *dir1;
char *dir2;
char *dir3;
@ -2817,17 +2822,19 @@ typedef struct {
gamemode_info_t gamemode_info[] = {
//note that there is no basic 'fte' gamemode, this is because we aim for network compatability. Darkplaces-Quake is the closest we get.
//this is to avoid having too many gamemodes anyway.
{"Darkplaces-Quake", "darkplaces", "-quake", "id1/pak0.pak", "id1", "qw", "fte"},
{"Darkplaces-Hipnotic", "hipnotic", "-hipnotic", NULL/*"hipnotic/pak0.pak"*/,"id1", "qw", "hipnotic", "fte"},
{"Darkplaces-Rogue", "rogue", "-rogue", NULL/*"rogue/pak0.pak", "id1"*/, "qw", "rogue", "fte"},
{"Nexuiz", "nexuiz", "-nexuiz", "data/cvars.txt", "id1", "qw", "data", "fte"},
//rogue/hipnotic have no special files - the detection conflicts and stops us from running regular quake
{"Darkplaces-Quake", "darkplaces", "-quake", "id1/pak0.pak", NULL, "id1", "qw", "fte"},
{"Darkplaces-Hipnotic", "hipnotic", "-hipnotic", NULL, NULL, "id1", "qw", "hipnotic", "fte"},
{"Darkplaces-Rogue", "rogue", "-rogue", NULL, NULL, "id1", "qw", "rogue", "fte"},
{"Nexuiz", "nexuiz", "-nexuiz", "nexuiz.exe", NEXCFG, "id1", "qw", "data", "fte"},
//supported commercial mods (some are currently only partially supported)
{"FTE-Hexen2", "hexen", "-hexen2", "data1/pak0.pak", "data1", "fte"},
{"FTE-Quake2", "q2", "-q2", "baseq2/pak0.pak", "baseq2", "fte"},
{"FTE-Quake3", "q3", "-q3", "baseq3/pak0.pk3", "baseq3", "fte"},
{"FTE-Hexen2", "hexen", "-hexen2", "data1/pak0.pak", NULL, "data1", "fte"},
{"FTE-Quake2", "q2", "-q2", "baseq2/pak0.pak", NULL, "baseq2", "fte"},
{"FTE-Quake3", "q3", "-q3", "baseq3/pak0.pk3", NULL, "baseq3", "fte"},
{"FTE-JK2", "jk2", "-jk2", "base/assets0.pk3", "base", "fte"},
{"FTE-JK2", "jk2", "-jk2", "base/assets0.pk3", NULL, "base", "fte"},
{NULL}
};
@ -3095,6 +3102,9 @@ void COM_InitFilesystem (void)
}
Cvar_Set(&com_gamename, gamemode_info[gamenum].gamename);
if (gamemode_info[gamenum].customexec)
Cbuf_AddText(gamemode_info[gamenum].customexec, RESTRICT_LOCAL);
#ifdef _WIN32
{ //win32 sucks.

View file

@ -271,17 +271,17 @@ int PM_StepSlideMove (qboolean in_air)
org = (originalvel[2] < 0) ? pmove.origin : original;
VectorCopy (org, dest);
dest[2] -= pm_stepheight;
dest[2] -= movevars.stepheight;
trace = PM_PlayerTrace (org, dest);
if (trace.fraction == 1 || trace.plane.normal[2] < MIN_STEP_NORMAL)
return blocked;
// adjust stepsize, otherwise it would be possible to walk up a
// a step higher than STEPSIZE
stepsize = pm_stepheight - (org[2] - trace.endpos[2]);
stepsize = movevars.stepheight - (org[2] - trace.endpos[2]);
}
else
stepsize = pm_stepheight;
stepsize = movevars.stepheight;
VectorCopy (pmove.origin, down);
VectorCopy (pmove.velocity, downvel);
@ -600,7 +600,7 @@ void PM_LadderMove (void)
// assume it is a stair or a slope, so press down from stepheight above
VectorMA (pmove.origin, frametime, pmove.velocity, dest);
VectorCopy (dest, start);
start[2] += pm_stepheight + 1;
start[2] += movevars.stepheight + 1;
trace = PM_PlayerTrace (start, dest);
if (!trace.startsolid && !trace.allsolid) // FIXME: check steep slope?
{ // walked up the step

View file

@ -93,6 +93,7 @@ typedef struct {
qboolean slidefix;
qboolean airstep;
qboolean slidyslopes;
int stepheight;
} movevars_t;

View file

@ -19,7 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "quakedef.h"
float pm_stepheight = 18;
float pm_q2stepheight = PM_DEFAULTSTEPHEIGHT;
#if defined(Q2CLIENT) || defined(Q2SERVER)
#define Q2PMF_DUCKED 1
@ -293,7 +293,7 @@ void PMQ2_StepSlideMove (void)
VectorCopy (q2pml.velocity, down_v);
VectorCopy (start_o, up);
up[2] += pm_stepheight;
up[2] += pm_q2stepheight;
trace = q2pm->trace (up, q2pm->mins, q2pm->maxs, up);
if (trace.allsolid)
@ -307,7 +307,7 @@ void PMQ2_StepSlideMove (void)
// push down the final amount
VectorCopy (q2pml.origin, down);
down[2] -= pm_stepheight;
down[2] -= pm_q2stepheight;
trace = q2pm->trace (q2pml.origin, q2pm->mins, q2pm->maxs, down);
if (!trace.allsolid)
{

View file

@ -1319,7 +1319,7 @@ void R_ModifyTextureCoords ( shaderpass_t *pass, int unit )
int i, j;
float *table;
float t1, t2, sint, cost;
float *tcArray;
float *tcArray, *buffer;
tcmod_t *tcmod;
r_texNums[unit] = R_ShaderpassTex ( pass );
@ -1336,11 +1336,12 @@ void R_ModifyTextureCoords ( shaderpass_t *pass, int unit )
return;
}
R_VertexTCBase ( pass->tcgen, unit );
buffer = R_VertexTCBase (pass->tcgen, unit);
qglTexCoordPointer(2, GL_FLOAT, 0, buffer);
for (i = 0, tcmod = pass->tcmods; i < pass->numtcmods; i++, tcmod++)
{
tcArray = tUnitCoordsArray[unit][0];
tcArray = buffer;
switch (tcmod->type)
{

View file

@ -241,6 +241,9 @@ qboolean Draw_RealPicFromWad (mpic_t *out, char *name)
int texnum;
char name2[256];
if (!strncmp(name, "gfx/", 4))
in = W_SafeGetLumpName (name+4);
else
in = W_SafeGetLumpName (name);
gl = (glpic_t *)out->data;
@ -513,8 +516,6 @@ mpic_t *GLDraw_SafeCachePic (char *path)
{
mpic_t *m;
m = GLDraw_SafePicFromWad(path);
if (!m && !strncmp(path, "gfx/", 4))
return GLDraw_SafePicFromWad(path+4);
return m;
}
}

View file

@ -1107,6 +1107,8 @@ TRACE(("dbg: GLR_NewMap: tp\n"));
void GLR_PreNewMap(void)
{
extern int solidskytexture;
solidskytexture = 0;
}

View file

@ -3269,7 +3269,7 @@ void PF_clienttype (progfuncs_t *prinst, struct globalvars_s *pr_globals)
return;
}
if (svs.clients[entnum].protocol == SCP_BAD)
G_FLOAT(OFS_RETURN) = 2; //an active, not-bot client.
G_FLOAT(OFS_RETURN) = 2; //an active, bot client.
else
G_FLOAT(OFS_RETURN) = 1; //an active, not-bot client.
}
@ -3287,7 +3287,7 @@ void PF_localcmd (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *str;
str = PR_GetStringOfs(prinst, OFS_PARM0);
str = PF_VarString(prinst, 0, pr_globals);
if (!strcmp(str, "host_framerate 0\n"))
Cbuf_AddText ("sv_mintic 0\n", RESTRICT_INSECURE); //hmm... do this better...
else
@ -3317,7 +3317,12 @@ static void PF_cvar (progfuncs_t *prinst, struct globalvars_s *pr_globals)
G_FLOAT(OFS_RETURN) = sv.worldmodel->fromgame == fg_halflife;
else
{
cvar_t *cv = Cvar_Get(str, "", 0, "QC variables");
cvar_t *cv = Cvar_FindVar(str);
if (!cv)
{
cv = Cvar_Get(str, "", 0, "QC variables");
Con_Printf("Creating cvar %s\n", str);
}
G_FLOAT(OFS_RETURN) = cv->value;
}
}
@ -5690,7 +5695,7 @@ void PF_strconv (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int ccase = G_FLOAT(OFS_PARM0); //0 same, 1 lower, 2 upper
int redalpha = G_FLOAT(OFS_PARM1); //0 same, 1 white, 2 red, 5 alternate, 6 alternate-alternate
int redchars = G_FLOAT(OFS_PARM2); //0 same, 1 white, 2 red, 3 redspecial, 4 whitespecial, 5 alternate, 6 alternate-alternate
int rednum = G_FLOAT(OFS_PARM2); //0 same, 1 white, 2 red, 3 redspecial, 4 whitespecial, 5 alternate, 6 alternate-alternate
unsigned char *string = PF_VarString(prinst, 3, pr_globals);
int len = strlen(string);
int i;
@ -5703,22 +5708,22 @@ void PF_strconv (progfuncs_t *prinst, struct globalvars_s *pr_globals)
for (i = 0; i < len; i++, string++, result++) //should this be done backwards?
{
if (*string >= '0' && *string <= '9') //normal numbers...
*result = chrconv_number(*string, '0', redchars);
*result = chrconv_number(*string, '0', rednum);
else if (*string >= '0'+128 && *string <= '9'+128)
*result = chrconv_number(*string, '0'+128, redchars);
*result = chrconv_number(*string, '0'+128, rednum);
else if (*string >= '0'+128-30 && *string <= '9'+128-30)
*result = chrconv_number(*string, '0'+128-30, redchars);
*result = chrconv_number(*string, '0'+128-30, rednum);
else if (*string >= '0'-30 && *string <= '9'-30)
*result = chrconv_number(*string, '0'-30, redchars);
*result = chrconv_number(*string, '0'-30, rednum);
else if (*string >= 'a' && *string <= 'z') //normal numbers...
*result = chrchar_alpha(*string, 'a', 0, ccase, redchars, i);
*result = chrchar_alpha(*string, 'a', 0, ccase, redalpha, i);
else if (*string >= 'A' && *string <= 'Z') //normal numbers...
*result = chrchar_alpha(*string, 'A', 0, ccase, redchars, i);
*result = chrchar_alpha(*string, 'A', 0, ccase, redalpha, i);
else if (*string >= 'a'+128 && *string <= 'z'+128) //normal numbers...
*result = chrchar_alpha(*string, 'a', 128, ccase, redchars, i);
*result = chrchar_alpha(*string, 'a', 128, ccase, redalpha, i);
else if (*string >= 'A'+128 && *string <= 'Z'+128) //normal numbers...
*result = chrchar_alpha(*string, 'A', 128, ccase, redchars, i);
*result = chrchar_alpha(*string, 'A', 128, ccase, redalpha, i);
else if ((*string & 127) < 16 || !redalpha) //special chars..
*result = *string;
@ -5790,6 +5795,28 @@ void PF_infoget (progfuncs_t *prinst, struct globalvars_s *pr_globals)
RETURN_TSTRING(key);
}
//DP_QC_STRINGCOLORFUNCTIONS
// #476 float(string s) strlennocol - returns how many characters are in a string, minus color codes
void PF_strlennocol (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *in = PR_GetStringOfs(prinst, OFS_PARM0);
G_FLOAT(OFS_RETURN) = COM_FunStringLength(in);
}
//DP_QC_STRINGCOLORFUNCTIONS
// string (string s) strdecolorize - returns the passed in string with color codes stripped
void PF_strdecolorize (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *in = PR_GetStringOfs(prinst, OFS_PARM0);
char result[8192];
unsigned long flagged[8192];
COM_ParseFunString(in, flagged, sizeof(flagged)/sizeof(flagged[0]));
COM_DeFunString(flagged, result, sizeof(result), true);
RETURN_TSTRING(result);
}
//back to frik_file support.
@ -5881,9 +5908,8 @@ void PF_fopen (progfuncs_t *prinst, struct globalvars_s *pr_globals)
}
}
void PF_fclose (progfuncs_t *prinst, struct globalvars_s *pr_globals)
void PF_fclose_i (int fnum)
{
int fnum = G_FLOAT(OFS_PARM0)-FIRST_QC_FILE_INDEX;
if (fnum < 0 || fnum >= MAX_QC_FILES)
{
Con_Printf("PF_fclose: File out of range\n");
@ -5896,12 +5922,6 @@ void PF_fclose (progfuncs_t *prinst, struct globalvars_s *pr_globals)
return; //not open
}
if (pf_fopen_files[fnum].prinst != prinst)
{
Con_Printf("PF_fclose: File is from wrong instance\n");
return; //this just isn't ours.
}
switch(pf_fopen_files[fnum].accessmode)
{
case 0:
@ -5917,6 +5937,25 @@ void PF_fclose (progfuncs_t *prinst, struct globalvars_s *pr_globals)
pf_fopen_files[fnum].prinst = NULL;
}
void PF_fclose (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int fnum = G_FLOAT(OFS_PARM0)-FIRST_QC_FILE_INDEX;
if (fnum < 0 || fnum >= MAX_QC_FILES)
{
Con_Printf("PF_fclose: File out of range\n");
return; //out of range
}
if (pf_fopen_files[fnum].prinst != prinst)
{
Con_Printf("PF_fclose: File is from wrong instance\n");
return; //this just isn't ours.
}
PF_fclose_i(fnum);
}
void PF_fgets (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char c, *s, *o, *max;
@ -6008,15 +6047,14 @@ void PF_fputs (progfuncs_t *prinst, struct globalvars_s *pr_globals)
pf_fopen_files[fnum].ofs+=len;
}
void PF_fcloseall (progfuncs_t *prinst, struct globalvars_s *pr_globals)
void PF_fcloseall (progfuncs_t *prinst)
{
int i;
for (i = 0; i < MAX_QC_FILES; i++)
{
if (pf_fopen_files[i].prinst != prinst)
continue;
G_FLOAT(OFS_PARM0) = i+FIRST_QC_FILE_INDEX;
PF_fclose(prinst, pr_globals);
PF_fclose_i(i);
}
}
@ -6274,6 +6312,7 @@ lh_extension_t QSG_Extensions[] = {
{"DP_QC_MULTIPLETEMPSTRINGS"},
{"DP_QC_RANDOMVEC", 1, NULL, {"randomvec"}},
{"DP_QC_SINCOSSQRTPOW", 4, NULL, {"sin", "cos", "sqrt", "pow"}},
{"DP_QC_STRINGCOLORFUNCTIONS", 2, NULL, {"strlennocol", "strdecolorize"}},
{"DP_QC_UNLIMITEDTEMPSTRINGS"},
{"DP_QC_TRACEBOX", 1, NULL, {"tracebox"}},
{"DP_QC_TRACETOSS"},
@ -6663,7 +6702,7 @@ void PF_strcat (progfuncs_t *prinst, struct globalvars_s *pr_globals)
=================
PF_strpad
string strcat(float pad, string str1, ...)
string strpad(float pad, string str1, ...)
=================
*/
@ -7048,7 +7087,8 @@ void PF_etos (progfuncs_t *prinst, struct globalvars_s *pr_globals)
void PF_findchain (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int i, f;
char *s, *t;
char *s;
string_t t;
edict_t *ent, *chain;
chain = (edict_t *) *prinst->parms->sv_edicts;
@ -7061,10 +7101,10 @@ void PF_findchain (progfuncs_t *prinst, struct globalvars_s *pr_globals)
ent = EDICT_NUM(prinst, i);
if (ent->isfree)
continue;
t = *(string_t *)&((float*)ent->v)[f] + prinst->stringtable;
t = *(string_t *)&((float*)ent->v)[f];
if (!t)
continue;
if (strcmp(t, s))
if (strcmp(PR_GetString(prinst, t), s))
continue;
ent->v->chain = EDICT_TO_PROG(prinst, chain);
@ -9687,6 +9727,9 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
{"WriteUnterminatedString",PF_WriteString2,0, 0, 0, 456}, //writestring but without the null terminator. makes things a little nicer.
{"strlennocol", PF_strlennocol, 0, 0, 0, 476}, // #476 float(string s) strlennocol
{"strdecolorize", PF_strdecolorize, 0, 0, 0, 477}, // #477 string(string s) strdecolorize
//end other peoples extras
//don't exceed sizeof(pr_builtin)/sizeof(pr_builtin[0]) (currently 1024) without modifing the size of pr_builtin

View file

@ -30,7 +30,7 @@ typedef enum multicast_e
MULTICAST_PVS_R
} multicast_t;
extern float pm_stepheight;
extern float pm_q2stepheight;
#ifdef Q2SERVER

View file

@ -409,10 +409,14 @@ typedef struct client_s
q3client_frame_t *q3frames;
#endif
} frameunion;
vfsfile_t *download; // file being downloaded
int downloadsize; // total bytes
int downloadcount; // bytes sent
int downloadacked; //DP-specific
int downloadstarted; //DP-specific
int spec_track; // entnum of player tracking
#ifdef Q3SERVER

View file

@ -613,7 +613,20 @@ void SV_Map_f (void)
SV_SpawnServer (level, startspot, false, cinematic);
}
SV_BroadcastCommand ("cmd new\n");
//SV_BroadcastCommand ("cmd new\n");
for (i=0, host_client = svs.clients ; i<MAX_CLIENTS ; i++, host_client++)
{ //this expanded code cuts out a packet when changing maps...
//but more usefully, it stops dp(and probably nq too) from timing out.
if (host_client->controller)
continue;
if (host_client->state>=cs_connected)
{
if (ISNQCLIENT(host_client))
SVNQ_New_f();
else
SV_New_f();
}
}
if (!issamelevel)
{

View file

@ -1719,7 +1719,7 @@ void SV_WritePlayersToClient (client_t *client, edict_t *clent, qbyte *pvs, size
clst.zext = client->zquake_extensions;
clst.cl = cl;
if (ent != vent)
if (ent != vent || host_client->viewent == j+1)
clst.modelindex = 0;
if (sv.demostatevalid)
@ -2293,6 +2293,8 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore
state->fatness = clent->v->fatness*2;
#endif
if (progstype == PROG_QW)
{
if (state->effects & QWEF_FLAG1)
{
memcpy(&pack->entities[pack->num_entities], state, sizeof(*state));
@ -2313,6 +2315,7 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore
state->number++;
state->skinnum = 1;
}
}
state->effects &= ~(QWEF_FLAG1 | QWEF_FLAG2);
}
@ -2558,6 +2561,9 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore
if (state->effects & 0x32)
state->effects |= 0;
if (state->effects & 0x00400000)
state->effects &= ~0x00400000;
if (state->effects & EF_FULLBRIGHT)
{
state->hexen2flags |= MLS_FULLBRIGHT;

View file

@ -1535,7 +1535,7 @@ client_t *SVC_DirectConnect(void)
if (!sv_listen_qw.value && net_from.type != NA_LOOPBACK)
{
SV_RejectMessage (SCP_BAD, "QuakeWorld protocols are not permitted on this server.\n");
Con_Printf ("* rejected connect from quakeworld\n", version);
Con_Printf ("* rejected connect from quakeworld\n");
return NULL;
}
@ -3018,6 +3018,7 @@ void SV_InitLocal (void)
extern cvar_t pm_airstep;
extern cvar_t pm_walljump;
extern cvar_t pm_slidyslopes;
extern cvar_t pm_stepheight;
SV_InitOperatorCommands ();
SV_UserInit ();
@ -3085,6 +3086,7 @@ void SV_InitLocal (void)
Cvar_Register (&pm_slidyslopes, cvargroup_serverphysics);
Cvar_Register (&pm_airstep, cvargroup_serverphysics);
Cvar_Register (&pm_walljump, cvargroup_serverphysics);
Cvar_Register (&pm_stepheight, cvargroup_serverphysics);
Cvar_Register (&sv_compatablehulls, cvargroup_serverphysics);
@ -3490,7 +3492,8 @@ void SV_FixupName(char *in, char *out)
}
*s = '\0';
if (!*out) { //reached end and it was all whitespace
if (!*out)
{ //reached end and it was all whitespace
//white space only
strcpy(out, "unnamed");
p = out;
@ -3585,9 +3588,12 @@ void SV_ExtractFromUserinfo (client_t *cl)
val = Info_ValueForKey (cl->userinfo, "name");
val[40] = 0; //trim to smallish length now (to allow for adding more.
if (cl->protocol != SCP_BAD || *val)
SV_FixupName(val, newname);
else
newname[0] = 0;
if (!val[0])
if (!val[0] && cl->protocol != SCP_BAD)
strcpy(newname, "Hidden");
else if (!stricmp(val, "console"))
{
@ -3778,6 +3784,8 @@ void SV_Init (quakeparms_t *parms)
Memory_Init (parms->membase, parms->memsize);
Sys_Init();
COM_ParsePlusSets();
Cbuf_Init ();
@ -3810,7 +3818,6 @@ void SV_Init (quakeparms_t *parms)
if (isDedicated)
#endif
{
Sys_Init ();
PM_Init ();
#ifdef PLUGINS

View file

@ -71,7 +71,7 @@ realcheck:
// the midpoint must be within 16 of the bottom
start[0] = stop[0] = (mins[0] + maxs[0])*0.5;
start[1] = stop[1] = (mins[1] + maxs[1])*0.5;
stop[2] = start[2] - 2*pm_stepheight;
stop[2] = start[2] - 2*movevars.stepheight;
savedhull = ent->v->hull;
ent->v->hull = 0;
trace = SV_Move (start, vec3_origin, vec3_origin, stop, true, ent);
@ -95,7 +95,7 @@ realcheck:
if (trace.fraction != 1.0 && trace.endpos[2] > bottom)
bottom = trace.endpos[2];
if (trace.fraction == 1.0 || mid - trace.endpos[2] > pm_stepheight)
if (trace.fraction == 1.0 || mid - trace.endpos[2] > movevars.stepheight)
return false;
}
@ -184,9 +184,9 @@ qboolean SV_movestep (edict_t *ent, vec3_t move, qboolean relink, qboolean noene
}
// push down from a step height above the wished position
neworg[2] += pm_stepheight;
neworg[2] += movevars.stepheight;
VectorCopy (neworg, end);
end[2] -= pm_stepheight*2;
end[2] -= movevars.stepheight*2;
trace = SV_Move (neworg, ent->v->mins, ent->v->maxs, end, false, ent);
if (set_trace)
@ -197,7 +197,7 @@ qboolean SV_movestep (edict_t *ent, vec3_t move, qboolean relink, qboolean noene
if (trace.startsolid)
{
neworg[2] -= pm_stepheight;
neworg[2] -= movevars.stepheight;
trace = SV_Move (neworg, ent->v->mins, ent->v->maxs, end, false, ent);
if (set_trace)
set_move_trace(&trace, set_trace);

View file

@ -60,6 +60,7 @@ cvar_t pm_slidefix = SCVARF("pm_slidefix", "0", CVAR_SERVERINFO);
cvar_t pm_slidyslopes = SCVARF("pm_slidyslopes", "0", CVAR_SERVERINFO);
cvar_t pm_airstep = SCVARF("pm_airstep", "0", CVAR_SERVERINFO);
cvar_t pm_walljump = SCVARF("pm_walljump", "0", CVAR_SERVERINFO);
cvar_t pm_stepheight = FCVAR("pm_stepheight", "sv_stepheight", "0", CVAR_SERVERINFO);
extern cvar_t sv_nomsec;
@ -1213,7 +1214,7 @@ void SV_CheckStuck (edict_t *ent)
return;
}
for (z=0 ; z < pm_stepheight ; z++)
for (z=0 ; z < movevars.stepheight ; z++)
for (i=-1 ; i <= 1 ; i++)
for (j=-1 ; j <= 1 ; j++)
{
@ -1419,8 +1420,8 @@ void SV_WalkMove (edict_t *ent)
VectorCopy (vec3_origin, upmove);
VectorCopy (vec3_origin, downmove);
upmove[2] = pm_stepheight;
downmove[2] = -pm_stepheight + oldvel[2]*host_frametime;
upmove[2] = movevars.stepheight;
downmove[2] = -movevars.stepheight + oldvel[2]*host_frametime;
// move up
SV_PushEntity (ent, upmove); // FIXME: don't link?
@ -1609,7 +1610,7 @@ void SV_WalkMove (edict_t *ent)
// move up
VectorClear (upmove);
upmove[2] = pm_stepheight;
upmove[2] = movevars.stepheight;
// FIXME: don't link?
SV_PushEntity(ent, upmove);
@ -1652,7 +1653,7 @@ void SV_WalkMove (edict_t *ent)
// move down
VectorClear (downmove);
downmove[2] = -pm_stepheight + start_velocity[2]*host_frametime;
downmove[2] = -movevars.stepheight + start_velocity[2]*host_frametime;
// FIXME: don't link?
downtrace = SV_PushEntity (ent, downmove);
@ -2030,5 +2031,6 @@ void SV_SetMoveVars(void)
movevars.friction = sv_friction.value;
movevars.waterfriction = sv_waterfriction.value;
movevars.entgravity = 1.0;
movevars.stepheight = pm_stepheight.value;
}
#endif

View file

@ -1477,6 +1477,8 @@ qboolean SV_SendClientDatagram (client_t *client)
SZ_Clear (&msg);
}
SV_DarkPlacesDownloadChunk(client, &msg);
// send the datagram
Netchan_Transmit (&client->netchan, msg.cursize, buf, SV_RateForClient(client));
@ -1563,7 +1565,7 @@ void SV_UpdateToReliableMessages (void)
MSG_WriteString (&sv.reliable_datagram, host_client->name);
}
}
host_client->edict->v->netname = host_client->name - svprogfuncs->stringtable;
host_client->edict->v->netname = PR_SetString(svprogfuncs, host_client->name);
}
}
@ -1910,7 +1912,22 @@ void SV_SendClientMessages (void)
{ //nq clients get artificial choke too
c->send_message = false;
if (c->nextservertimeupdate != sv.physicstime && c->state != cs_zombie)
{
c->send_message = true;
if (c->state == cs_connected && !c->datagram.cursize && !c->netchan.message.cursize)
{
if (c->nextservertimeupdate < sv.physicstime)
{ //part of the nq protocols allowed downloading content over isdn
//the nop requirement of the protocol persisted to prevent timeouts when content loading is otherwise slow..
//aditionally we might need this for lost packets, not sure
//but the client isn't able to respond unless we send an occasional datagram
if (c->nextservertimeupdate)
MSG_WriteByte(&c->datagram, svc_nop);
c->nextservertimeupdate = sv.physicstime+5;
}
}
}
}
if (!c->send_message)
continue;
@ -1925,6 +1942,7 @@ void SV_SendClientMessages (void)
SV_SendClientDatagram (c);
else
{
SV_DarkPlacesDownloadChunk(c, &c->datagram);
Netchan_Transmit (&c->netchan, c->datagram.cursize, c->datagram.data, SV_RateForClient(c)); // just update reliable
c->datagram.cursize = 0;
}

View file

@ -345,10 +345,14 @@ void SVNQ_New_f (void)
if (host_client->protocol == SCP_DARKPLACES7)
{
extern cvar_t allow_download;
char *f;
if (allow_download.value)
{
MSG_WriteByte (&host_client->netchan.message, svc_stufftext);
MSG_WriteString (&host_client->netchan.message, "cl_serverextension_download 1\n");
}
f = COM_LoadTempFile("csprogs.dat");
if (f)
@ -1504,17 +1508,37 @@ void SV_Begin_f (void)
//=============================================================================
void SV_DarkPlacesDownloadChunk(client_t *cl)
//dp downloads are a 2-stream system
//the server->client stream is as you'd expect. except that its unreliable rather than reliable
//the client->server stream contains no actual data.
//when c2s has a hole, the s2c stream is reset to the last-known 'good' position.
//eventually the client is left acking packets with no data in them, the server then tells the client that the download is complete.
//the client does no checks to see if there's a hole, other than the crc
//so any single lost packet (even client->server) means that the entire stream will be set back by your ping time
void SV_DarkPlacesDownloadChunk(client_t *cl, sizebuf_t *msg)
{
#define MAXDPDOWNLOADCHUNK 1024
char buffer[MAXDPDOWNLOADCHUNK];
int size, start;
if (!ISNQCLIENT(cl))
return;
if (!cl->download)
return;
if (!cl->downloadstarted)
return;
if (cl->num_backbuf)
size = 16;
else
size = 512;
return;
size = 1024; //fixme
if (size > cl->datagram.maxsize - cl->datagram.cursize)
size = cl->datagram.maxsize - cl->datagram.cursize - 16;
if (size > MAXDPDOWNLOADCHUNK) //don't clog it too much
size = MAXDPDOWNLOADCHUNK;
@ -1522,20 +1546,23 @@ void SV_DarkPlacesDownloadChunk(client_t *cl)
if (start+size > cl->downloadsize) //clamp to the size of the file.
size = cl->downloadsize - start;
VFS_READ(cl->download, buffer, size);
size = VFS_READ(cl->download, buffer, size);
if (size < 0)
size = 0;
//reliable? I don't care, this works.
ClientReliableWrite_Begin (cl, svcdp_downloaddata, 7+size);
ClientReliableWrite_Long (cl, start);
ClientReliableWrite_Short (cl, size);
ClientReliableWrite_SZ (cl, buffer, size);
MSG_WriteByte(msg, svcdp_downloaddata);
MSG_WriteLong (msg, start);
MSG_WriteShort (msg, size);
SZ_Write(msg, buffer, size);
}
void SVDP_ForceDownloadChunk_f(void)
void SVDP_StartDownload_f(void)
{
if (host_client->protocol != SCP_DARKPLACES7)
return;
SV_DarkPlacesDownloadChunk(host_client);
if (!host_client->download)
return;
host_client->downloadstarted = true;
}
void SV_DarkPlacesDownloadAck(client_t *cl)
@ -1543,7 +1570,20 @@ void SV_DarkPlacesDownloadAck(client_t *cl)
int start = MSG_ReadLong();
int size = (unsigned short)MSG_ReadShort();
if (size == 0)
if (!cl->download)
return;
if (start != cl->downloadacked)
{
//packetloss
VFS_SEEK(cl->download, cl->downloadacked);
}
else if (size != 0)
{
cl->downloadacked += size; //successful packet
cl->downloadcount = cl->downloadacked;
}
else
{
char *s;
unsigned short crc;
@ -1564,9 +1604,11 @@ void SV_DarkPlacesDownloadAck(client_t *cl)
s = va("\ncl_downloadfinished %i %i \"\"\n", host_client->downloadsize, crc);
ClientReliableWrite_Begin (cl, svc_stufftext, 2+strlen(s));
ClientReliableWrite_String(cl, s);
VFS_CLOSE(host_client->download);
host_client->download = NULL;
host_client->downloadsize = 0;
}
else
SV_DarkPlacesDownloadChunk(cl);
}
void SV_NextChunkedDownload(int chunknum)
@ -1860,6 +1902,8 @@ void SV_BeginDownload_f(void)
{ // don't allow anything with .. path
if (ISNQCLIENT(host_client))
{
SV_PrintToClient(host_client, PRINT_HIGH, "Download rejected by server settings\n");
ClientReliableWrite_Begin (host_client, svc_stufftext, 2+strlen(name));
ClientReliableWrite_String (host_client, "\nstopdownload\n");
}
@ -1981,6 +2025,20 @@ void SV_BeginDownload_f(void)
Con_Printf ("Downloading %s to %s\n", name, host_client->name);
}
void SV_StopDownload_f(void)
{
//this doesn't mean the download failed or was canceled.
if (host_client->download)
{
VFS_CLOSE (host_client->download);
host_client->download = NULL;
}
else
Con_Printf ("But you're not downloading anything\n");
host_client->downloadstarted = false;
}
//=============================================================================
@ -2312,6 +2370,22 @@ void SV_Pings_f (void)
return;
}
if (ISNQCLIENT(host_client))
{
char *s;
ClientReliableWrite_Begin(host_client, svc_stufftext, 15+10*MAX_CLIENTS);
ClientReliableWrite_SZ(host_client, "pingplreport", 12);
for (j = 0, client = svs.clients; j < MAX_CLIENTS; j++, client++)
{
s = va(" %i %i", SV_CalcPing(client), client->lossage);
ClientReliableWrite_SZ(host_client, s, strlen(s));
}
ClientReliableWrite_Byte (host_client, '\n');
ClientReliableWrite_Byte (host_client, '\0');
}
else
{
for (j = 0, client = svs.clients; j < MAX_CLIENTS; j++, client++)
{
if (client->state != cs_spawned)
@ -2325,6 +2399,7 @@ void SV_Pings_f (void)
ClientReliableWrite_Byte (host_client, client->lossage);
}
}
}
@ -3216,16 +3291,15 @@ void Cmd_Observe_f (void)
void SV_EnableClientsCSQC(void)
{
#ifdef PEXT_CSQC
if (host_client->fteprotocolextensions & PEXT_CSQC)
if (host_client->fteprotocolextensions & PEXT_CSQC || atoi(Cmd_Argv(1)))
host_client->csqcactive = true;
else
Con_DPrintf("CSQC enabled without protocol extensions\n");
Con_Printf("CSQC entities not enabled - no support from network protocol\n");
#endif
}
void SV_DisableClientsCSQC(void)
{
#ifdef PEXT_CSQC
if (host_client->fteprotocolextensions & PEXT_CSQC)
host_client->csqcactive = false;
#endif
}
@ -3291,7 +3365,7 @@ ucmd_t ucmds[] =
{"notarget", Cmd_Notarget_f},
{"setpos", Cmd_SetPos_f},
// {"stopdownload", SV_StopDownload_f},
{"stopdownload", SV_StopDownload_f},
{"demolist", SV_MVDList_f},
{"demoinfo", SV_MVDInfo_f},
@ -3811,6 +3885,8 @@ void SVNQ_Ping_f(void)
ucmd_t nqucmds[] =
{
{"new", SVNQ_New_f, true},
{"status", NULL},
{"god", Cmd_God_f},
@ -3818,6 +3894,7 @@ ucmd_t nqucmds[] =
{"notarget", Cmd_Notarget_f},
{"fly", NULL},
{"noclip", Cmd_Noclip_f},
{"pings", SV_Pings_f},
{"name", SVNQ_NQInfo_f},
@ -3836,7 +3913,7 @@ ucmd_t nqucmds[] =
{"vote", SV_Vote_f},
{"download", SV_BeginDownload_f},
{"sv_startdownload", SVDP_ForceDownloadChunk_f},
{"sv_startdownload", SVDP_StartDownload_f},
{"setinfo", SV_SetInfo_f},
{"playermodel", NULL},
@ -5195,7 +5272,7 @@ void SVNQ_ExecuteClientMessage (client_t *cl)
// calc ping time
frame = &cl->frameunion.frames[cl->netchan.incoming_acknowledged & UPDATE_MASK];
frame->ping_time = 999;
frame->ping_time = -1;
// make sure the reply sequence number matches the incoming
// sequence number