Getting ready for qexpo. CSQC is in final dev stages. Everything else should be working well enough too, hopefully.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@1217 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2005-08-11 04:14:33 +00:00
parent 0a96f18230
commit 83a2f3aa06
26 changed files with 681 additions and 212 deletions

View File

@ -1444,7 +1444,7 @@ void CL_LinkPacketEntities (void)
{ {
entity_t *ent; entity_t *ent;
packet_entities_t *pack; packet_entities_t *pack;
entity_state_t *s1, *s2; entity_state_t *s1;
float f; float f;
model_t *model; model_t *model;
vec3_t old_origin; vec3_t old_origin;

View File

@ -37,6 +37,7 @@ cvar_t cl_netfps = {"cl_netfps", "0"};
cvar_t cl_smartjump = {"cl_smartjump", "1"}; cvar_t cl_smartjump = {"cl_smartjump", "1"};
cvar_t cl_prydoncursor = {"cl_prydoncursor", "0"}; //for dp protocol cvar_t cl_prydoncursor = {"cl_prydoncursor", "0"}; //for dp protocol
cvar_t cl_instantrotate = {"cl_instantrotate", "1", NULL, CVAR_SEMICHEAT};
usercmd_t independantphysics[MAX_SPLITS]; usercmd_t independantphysics[MAX_SPLITS];
@ -422,7 +423,8 @@ void CL_AdjustAngles (int pnum)
// quant = -800; // quant = -800;
// else if (quant > 800) // else if (quant > 800)
// quant = 800; // quant = 800;
quant *= speed; if (!cl_instantrotate.value)
quant *= speed;
in_rotate -= quant; in_rotate -= quant;
cl.viewangles[pnum][YAW] += quant; cl.viewangles[pnum][YAW] += quant;
} }
@ -1547,6 +1549,7 @@ void CL_InitInput (void)
Cvar_Register (&cl_smartjump, inputnetworkcvargroup); Cvar_Register (&cl_smartjump, inputnetworkcvargroup);
Cvar_Register (&cl_prydoncursor, inputnetworkcvargroup); Cvar_Register (&cl_prydoncursor, inputnetworkcvargroup);
Cvar_Register (&cl_instantrotate, inputnetworkcvargroup);
} }
/* /*

View File

@ -108,6 +108,8 @@ cvar_t v_powerupshell = {"v_powerupshell", "0"};
cvar_t cl_gibfilter = {"cl_gibfilter", "0"}; cvar_t cl_gibfilter = {"cl_gibfilter", "0"};
cvar_t cl_deadbodyfilter = {"cl_deadbodyfilter", "0"}; cvar_t cl_deadbodyfilter = {"cl_deadbodyfilter", "0"};
cvar_t allow_download_csprogs = {"allow_download_csprogs", "0"};
cvar_t cl_muzzleflash = {"cl_muzzleflash", "1"}; cvar_t cl_muzzleflash = {"cl_muzzleflash", "1"};
cvar_t cl_item_bobbing = {"cl_model_bobbing", "0"}; cvar_t cl_item_bobbing = {"cl_model_bobbing", "0"};
@ -1314,16 +1316,6 @@ void CL_FullServerinfo_f (void)
cl.gamespeed = 1; cl.gamespeed = 1;
cl.csqcdebug = atoi(Info_ValueForKey(cl.serverinfo, "*csqcdebug")); cl.csqcdebug = atoi(Info_ValueForKey(cl.serverinfo, "*csqcdebug"));
#ifdef CSQC_DAT
p = Info_ValueForKey(cl.serverinfo, "*csprogs");
if (*p || cls.demoplayback) //only allow csqc if the server says so, and the 'checksum' matches.
{
unsigned int chksum = strtoul(p, NULL, 0);
if (CSQC_Init(chksum))
CL_SendClientCommand(true, "enablecsqc");
}
#endif
} }
/* /*
@ -2197,7 +2189,7 @@ void CL_Download_f (void)
cls.downloadtype = dl_singlestuffed; cls.downloadtype = dl_singlestuffed;
CL_CheckOrDownloadFile(url, false); CL_CheckOrDownloadFile(url, url, false);
return; return;
} }
else else
@ -2205,7 +2197,7 @@ void CL_Download_f (void)
cls.downloadtype = dl_single; cls.downloadtype = dl_single;
} }
CL_EnqueDownload(url, true, false); CL_EnqueDownload(url, url, true, false);
/* /*
strcpy(cls.downloadname, url); strcpy(cls.downloadname, url);
@ -2382,6 +2374,8 @@ void CL_Init (void)
Cvar_Register (&cl_nolerp, "Item effects"); Cvar_Register (&cl_nolerp, "Item effects");
Cvar_Register (&allow_download_csprogs, cl_controlgroup);
// //
// info mirrors // info mirrors
// //
@ -2815,10 +2809,10 @@ void Host_Frame (double time)
time2 = Sys_DoubleTime (); time2 = Sys_DoubleTime ();
// update audio // update audio
if (cls.state == ca_active) if (CSQC_SettingListener())
{ S_ExtraUpdate();
else if (cls.state == ca_active)
S_Update (r_origin, vpn, vright, vup); S_Update (r_origin, vpn, vright, vup);
}
else else
S_Update (vec3_origin, vec3_origin, vec3_origin, vec3_origin); S_Update (vec3_origin, vec3_origin, vec3_origin, vec3_origin);

View File

@ -224,10 +224,13 @@ int CL_CalcNet (void)
//note: this will overwrite existing files. //note: this will overwrite existing files.
//returns true if the download is going to be downloaded after the call. //returns true if the download is going to be downloaded after the call.
qboolean CL_EnqueDownload(char *filename, qboolean verbose, qboolean ignorefailedlist) qboolean CL_EnqueDownload(char *filename, char *localname, qboolean verbose, qboolean ignorefailedlist)
{ {
downloadlist_t *dl; downloadlist_t *dl;
if (strchr(filename, '\\') || strchr(filename, ':') || strstr(filename, "..")) if (!localname)
localname = filename;
if (strchr(localname, '\\') || strchr(localname, ':') || strstr(localname, ".."))
{ {
Con_Printf("Denying download of \"%s\"\n", filename); Con_Printf("Denying download of \"%s\"\n", filename);
return false; return false;
@ -267,7 +270,8 @@ qboolean CL_EnqueDownload(char *filename, qboolean verbose, qboolean ignorefaile
} }
dl = Z_Malloc(sizeof(downloadlist_t)); dl = Z_Malloc(sizeof(downloadlist_t));
strcpy(dl->name, filename); Q_strncpyz(dl->name, filename, sizeof(dl->name));
Q_strncpyz(dl->localname, localname, sizeof(dl->localname));
dl->next = cl.downloadlist; dl->next = cl.downloadlist;
cl.downloadlist = dl; cl.downloadlist = dl;
@ -304,18 +308,18 @@ void CL_DisenqueDownload(char *filename)
} }
} }
void CL_SendDownloadRequest(char *filename) void CL_SendDownloadRequest(char *filename, char *localname)
{ {
strcpy (cls.downloadname, filename); strcpy (cls.downloadname, localname);
Con_TPrintf (TL_DOWNLOADINGFILE, cls.downloadname); Con_TPrintf (TL_DOWNLOADINGFILE, cls.downloadname);
// download to a temp name, and only rename // download to a temp name, and only rename
// to the real name when done, so if interrupted // to the real name when done, so if interrupted
// a runt file wont be left // a runt file wont be left
COM_StripExtension (cls.downloadname, cls.downloadtempname); COM_StripExtension (localname, cls.downloadtempname);
strcat (cls.downloadtempname, ".tmp"); strcat (cls.downloadtempname, ".tmp");
CL_SendClientCommand(true, "download %s", cls.downloadname); CL_SendClientCommand(true, "download %s", filename);
//prevent ftp/http from changing stuff //prevent ftp/http from changing stuff
cls.downloadmethod = DL_QWPENDING; cls.downloadmethod = DL_QWPENDING;
@ -391,15 +395,17 @@ Returns true if the file exists, otherwise it attempts
to start a download from the server. to start a download from the server.
=============== ===============
*/ */
qboolean CL_CheckOrDownloadFile (char *filename, int nodelay) qboolean CL_CheckOrDownloadFile (char *filename, char *localname, int nodelay)
{ {
if (strstr (filename, "..")) if (!localname)
localname = filename;
if (strstr (localname, ".."))
{ {
Con_TPrintf (TL_NORELATIVEPATHS); Con_TPrintf (TL_NORELATIVEPATHS);
return true; return true;
} }
if (COM_FCheckExists (filename)) if (COM_FCheckExists (localname))
{ // it exists, no need to download { // it exists, no need to download
return true; return true;
} }
@ -425,7 +431,7 @@ qboolean CL_CheckOrDownloadFile (char *filename, int nodelay)
HTTP_CL_Get(va("http://maps.quakeworld.nu/%s/download/", base), filename, MapDownload); HTTP_CL_Get(va("http://maps.quakeworld.nu/%s/download/", base), filename, MapDownload);
} }
*/ */
if (CL_EnqueDownload(filename, false, false)) if (CL_EnqueDownload(filename, localname, false, false))
return !nodelay; return !nodelay;
else else
return true; return true;
@ -467,7 +473,7 @@ qboolean CL_CheckMD2Skins (char *name)
LittleLong(pheader->ofs_skins) + LittleLong(pheader->ofs_skins) +
(precache_model_skin - 1)*MD2MAX_SKINNAME; (precache_model_skin - 1)*MD2MAX_SKINNAME;
COM_CleanUpPath(str); COM_CleanUpPath(str);
if (!CL_CheckOrDownloadFile(str, false)) if (!CL_CheckOrDownloadFile(str, str, false))
{ {
precache_model_skin++; precache_model_skin++;
@ -515,7 +521,7 @@ void Model_NextDownload (void)
if (!*cl.image_name[i]) if (!*cl.image_name[i])
continue; continue;
sprintf(picname, "pics/%s.pcx", cl.image_name[i]); sprintf(picname, "pics/%s.pcx", cl.image_name[i]);
if (!CL_CheckOrDownloadFile(picname, false)) if (!CL_CheckOrDownloadFile(picname, picname, false))
return; return;
} }
if (!CLQ2_RegisterTEntModels()) if (!CLQ2_RegisterTEntModels())
@ -541,7 +547,7 @@ void Model_NextDownload (void)
continue; continue;
#endif #endif
if (!CL_CheckOrDownloadFile(s, cls.downloadnumber==1)) //world is required to be loaded. if (!CL_CheckOrDownloadFile(s, s, cls.downloadnumber==1)) //world is required to be loaded.
return; // started a download return; // started a download
if (strstr(s, ".md2")) if (strstr(s, ".md2"))
@ -630,13 +636,48 @@ void Sound_NextDownload (void)
char *s; char *s;
int i; int i;
cls.downloadtype = dl_sound;
if (cls.downloadnumber == 0) if (cls.downloadnumber == 0)
{ {
Con_TPrintf (TLC_CHECKINGSOUNDS); Con_TPrintf (TLC_CHECKINGSOUNDS);
#ifdef CSQC_DAT
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);
if (!CL_CheckOrDownloadFile("csprogs.dat", str, true))
{
cls.downloadnumber = 1;
return;
}
}
else
{
Con_Printf("Not downloading csprogs.dat\n");
}
}
cls.downloadnumber = 1; cls.downloadnumber = 1;
#endif
} }
cls.downloadtype = dl_sound; #ifdef CSQC_DAT
if (cls.downloadnumber == 1)
{
s = Info_ValueForKey(cl.serverinfo, "*csprogs");
if (*s || cls.demoplayback) //only allow csqc if the server says so, and the 'checksum' matches.
{
unsigned int chksum = strtoul(s, NULL, 0);
if (CSQC_Init(chksum))
CL_SendClientCommand(true, "enablecsqc");
}
}
#endif
for ( for (
; cl.sound_name[cls.downloadnumber][0] ; cl.sound_name[cls.downloadnumber][0]
; cls.downloadnumber++) ; cls.downloadnumber++)
@ -644,7 +685,7 @@ void Sound_NextDownload (void)
s = cl.sound_name[cls.downloadnumber]; s = cl.sound_name[cls.downloadnumber];
if (*s == '*') if (*s == '*')
continue; continue;
if (!CL_CheckOrDownloadFile(va("sound/%s",s), false)) if (!CL_CheckOrDownloadFile(va("sound/%s",s), NULL, false))
return; // started a download return; // started a download
} }
@ -698,7 +739,7 @@ void CL_RequestNextDownload (void)
if (cl.downloadlist) if (cl.downloadlist)
{ {
if (!COM_FCheckExists (cl.downloadlist->name)) if (!COM_FCheckExists (cl.downloadlist->name))
CL_SendDownloadRequest(cl.downloadlist->name); CL_SendDownloadRequest(cl.downloadlist->name, cl.downloadlist->localname);
else else
{ {
Con_Printf("Already have %s\n", cl.downloadlist->name); Con_Printf("Already have %s\n", cl.downloadlist->name);
@ -2213,7 +2254,7 @@ void CL_ParseStartSoundPacket(void)
Host_EndGame ("CL_ParseStartSoundPacket: ent = %i", ent); Host_EndGame ("CL_ParseStartSoundPacket: ent = %i", ent);
#ifdef PEXT_CSQC #ifdef PEXT_CSQC
if (!CSQC_StartSound(ent, channel, cl.sound_precache[sound_num], pos, volume/255.0, attenuation)) if (!CSQC_StartSound(ent, channel, cl.sound_name[sound_num], pos, volume/255.0, attenuation))
#endif #endif
S_StartSound (ent, channel, cl.sound_precache[sound_num], pos, volume/255.0, attenuation); S_StartSound (ent, channel, cl.sound_precache[sound_num], pos, volume/255.0, attenuation);
@ -3128,7 +3169,7 @@ void CL_ParsePrecache(void)
if (i >= 1 && i < MAX_MODELS) if (i >= 1 && i < MAX_MODELS)
{ {
model_t *model; model_t *model;
CL_CheckOrDownloadFile(s, true); CL_CheckOrDownloadFile(s, s, true);
model = Mod_ForName(s, i == 1); model = Mod_ForName(s, i == 1);
if (!model) if (!model)
Con_Printf("svc_precache: Mod_ForName(\"%s\") failed\n", s); Con_Printf("svc_precache: Mod_ForName(\"%s\") failed\n", s);
@ -3144,7 +3185,7 @@ void CL_ParsePrecache(void)
if (i >= 1 && i < MAX_SOUNDS) if (i >= 1 && i < MAX_SOUNDS)
{ {
sfx_t *sfx; sfx_t *sfx;
CL_CheckOrDownloadFile(va("sounds/%s", s), true); CL_CheckOrDownloadFile(va("sounds/%s", s), NULL, true);
sfx = S_PrecacheSound (s); sfx = S_PrecacheSound (s);
if (!sfx) if (!sfx)
Con_Printf("svc_precache: S_PrecacheSound(\"%s\") failed\n", s); Con_Printf("svc_precache: S_PrecacheSound(\"%s\") failed\n", s);

View File

@ -557,7 +557,7 @@ void SCR_ShowPic_Create(void)
sp->x = MSG_ReadShort(); sp->x = MSG_ReadShort();
sp->y = MSG_ReadShort(); sp->y = MSG_ReadShort();
CL_CheckOrDownloadFile(sp->picname, -1); CL_CheckOrDownloadFile(sp->picname, sp->picname, -1);
} }
void SCR_ShowPic_Hide(void) void SCR_ShowPic_Hide(void)
@ -605,7 +605,7 @@ void SCR_ShowPic_Update(void)
sp->picname = Z_Malloc(strlen(s)+1); sp->picname = Z_Malloc(strlen(s)+1);
strcpy(sp->picname, s); strcpy(sp->picname, s);
CL_CheckOrDownloadFile(sp->picname, false); CL_CheckOrDownloadFile(sp->picname, sp->picname, false);
} }
void SCR_ShowPic_Script_f(void) void SCR_ShowPic_Script_f(void)

View File

@ -358,7 +358,9 @@ void VQ3_AddEntity(const q3refEntity_t *q3)
Con_Printf("Beam\n"); Con_Printf("Beam\n");
break; break;
case RT_RAIL_CORE: case RT_RAIL_CORE:
Con_Printf("RailCore\n"); VectorCopy(q3->oldorigin, ent.oldorigin);
ent.flags |= Q2RF_BEAM;
ent.scale = q3->radius;
break; break;
case RT_RAIL_RINGS: case RT_RAIL_RINGS:
Con_Printf("RailRings\n"); Con_Printf("RailRings\n");

View File

@ -178,6 +178,10 @@ typedef struct
// the usercmd // the usercmd
packet_entities_t packet_entities; packet_entities_t packet_entities;
qboolean invalid; // true if the packet_entities delta was invalid qboolean invalid; // true if the packet_entities delta was invalid
int server_time;
int client_time;
int server_message_num;
} frame_t; } frame_t;
#ifdef Q2CLIENT #ifdef Q2CLIENT
@ -379,6 +383,7 @@ extern int nq_dp_protocol;
typedef struct downloadlist_s { typedef struct downloadlist_s {
char name[128]; char name[128];
char localname[128];
struct downloadlist_s *next; struct downloadlist_s *next;
} downloadlist_t; } downloadlist_t;
@ -708,7 +713,7 @@ void CLNQ_ParseServerMessage (void);
void CLQ2_ParseServerMessage (void); void CLQ2_ParseServerMessage (void);
#endif #endif
void CL_NewTranslation (int slot); void CL_NewTranslation (int slot);
qboolean CL_CheckOrDownloadFile (char *filename, int nodelay); qboolean CL_CheckOrDownloadFile (char *filename, char *localname, int nodelay);
qboolean CL_IsUploading(void); qboolean CL_IsUploading(void);
void CL_NextUpload(void); void CL_NextUpload(void);
void CL_StartUpload (qbyte *data, int size); void CL_StartUpload (qbyte *data, int size);

View File

@ -1441,8 +1441,8 @@ static void ProcessMouse(mouse_t *mouse, usercmd_t *cmd, int pnum)
cmd->sidemove += m_side.value * mouse_x; cmd->sidemove += m_side.value * mouse_x;
else else
{ {
if ((int)((cl.viewangles[pnum][PITCH]+89.99)/180) & 1) // if ((int)((cl.viewangles[pnum][PITCH]+89.99)/180) & 1)
mouse_x *= -1; // mouse_x *= -1;
cl.viewangles[pnum][YAW] -= m_yaw.value * mouse_x; cl.viewangles[pnum][YAW] -= m_yaw.value * mouse_x;
} }

View File

@ -18,7 +18,6 @@ typedef struct csqctreadstate_s {
} csqctreadstate_t; } csqctreadstate_t;
static unsigned int csqcchecksum; static unsigned int csqcchecksum;
static qboolean csqcwantskeys;
static csqctreadstate_t *csqcthreads; static csqctreadstate_t *csqcthreads;
qboolean csqc_resortfrags; qboolean csqc_resortfrags;
qboolean csqc_drawsbar; qboolean csqc_drawsbar;
@ -68,6 +67,7 @@ cvar_t cl_csqcdebug = {"cl_csqcdebug", "0"}; //prints entity numbers which arriv
globalfloat(servercommandframe, "servercommandframe"); \ globalfloat(servercommandframe, "servercommandframe"); \
\ \
globalfloat(player_localentnum, "player_localentnum"); /*float the entity number of the local player*/ \ 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(pmove_org, "pmove_org"); \ globalvector(pmove_org, "pmove_org"); \
globalvector(pmove_vel, "pmove_vel"); \ globalvector(pmove_vel, "pmove_vel"); \
@ -175,6 +175,7 @@ static void CSQC_FindGlobals(void)
fieldfloat(pitch_speed);\ fieldfloat(pitch_speed);\
\ \
fieldentity(chain); \ fieldentity(chain); \
fieldentity(enemy); \
fieldentity(groundentity); \ fieldentity(groundentity); \
fieldentity(owner); \ fieldentity(owner); \
\ \
@ -935,6 +936,72 @@ static void PF_R_AddEntityMask(progfuncs_t *prinst, struct globalvars_s *pr_glob
} }
} }
qboolean csqc_rebuildmatricies;
float mvp[12];
float mvpi[12];
static void buildmatricies(void)
{
float modelview[16];
float proj[16];
ML_ModelViewMatrix(modelview, r_refdef.viewangles, r_refdef.vieworg);
ML_ProjectionMatrix2(proj, r_refdef.fov_x, r_refdef.fov_y);
Matrix4_Multiply(proj, modelview, mvp);
Matrix4x4_Invert_Simple(mvpi, mvp); //not actually used in this function.
csqc_rebuildmatricies = false;
}
static void PF_cs_project (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
if (csqc_rebuildmatricies)
buildmatricies();
{
float *in = G_VECTOR(OFS_PARM0);
float *out = G_VECTOR(OFS_RETURN);
float v[4], tempv[4];
v[0] = in[0];
v[1] = in[1];
v[2] = in[2];
v[3] = 1;
Matrix4_Transform4(mvp, v, tempv);
tempv[0] /= tempv[3];
tempv[1] /= tempv[3];
tempv[2] /= tempv[3];
out[0] = (1+tempv[0])/2;
out[1] = (1+tempv[1])/2;
out[2] = (1+tempv[2])/2;
}
}
static void PF_cs_unproject (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
if (csqc_rebuildmatricies)
buildmatricies();
{
float *in = G_VECTOR(OFS_PARM0);
float *out = G_VECTOR(OFS_RETURN);
float v[4], tempv[4];
v[0] = in[0]*2-1;
v[1] = in[1]*2-1;
v[2] = in[2]*2-1;
v[3] = 1;
Matrix4_Transform4(mvpi, v, tempv);
out[0] = tempv[0];
out[1] = tempv[1];
out[2] = tempv[2];
}
}
//float CalcFov (float fov_x, float width, float height); //float CalcFov (float fov_x, float width, float height);
//clear scene, and set up the default stuff. //clear scene, and set up the default stuff.
static void PF_R_ClearScene (progfuncs_t *prinst, struct globalvars_s *pr_globals) static void PF_R_ClearScene (progfuncs_t *prinst, struct globalvars_s *pr_globals)
@ -942,6 +1009,8 @@ static void PF_R_ClearScene (progfuncs_t *prinst, struct globalvars_s *pr_global
extern frame_t *view_frame; extern frame_t *view_frame;
extern player_state_t *view_message; extern player_state_t *view_message;
csqc_rebuildmatricies = true;
CL_DecayLights (); CL_DecayLights ();
if (cl.worldmodel) if (cl.worldmodel)
@ -1013,6 +1082,8 @@ static void PF_R_SetViewFlag(progfuncs_t *prinst, struct globalvars_s *pr_global
viewflags parametertype = G_FLOAT(OFS_PARM0); viewflags parametertype = G_FLOAT(OFS_PARM0);
float *p = G_VECTOR(OFS_PARM1); float *p = G_VECTOR(OFS_PARM1);
csqc_rebuildmatricies = true;
G_FLOAT(OFS_RETURN) = 1; G_FLOAT(OFS_RETURN) = 1;
switch(parametertype) switch(parametertype)
{ {
@ -1210,6 +1281,22 @@ static void PF_cs_SetSize(progfuncs_t *prinst, struct globalvars_s *pr_globals)
CS_LinkEdict(ent, false); CS_LinkEdict(ent, false);
} }
static void cs_settracevars(trace_t *tr)
{
*csqcg.trace_allsolid = tr->allsolid;
*csqcg.trace_startsolid = tr->startsolid;
*csqcg.trace_fraction = tr->fraction;
*csqcg.trace_inwater = tr->inwater;
*csqcg.trace_inopen = tr->inopen;
VectorCopy (tr->endpos, csqcg.trace_endpos);
VectorCopy (tr->plane.normal, csqcg.trace_plane_normal);
*csqcg.trace_plane_dist = tr->plane.dist;
if (tr->ent)
*csqcg.trace_ent = EDICT_TO_PROG(csqcprogs, (void*)tr->ent);
else
*csqcg.trace_ent = EDICT_TO_PROG(csqcprogs, (void*)csqc_edicts);
}
static void PF_cs_traceline(progfuncs_t *prinst, struct globalvars_s *pr_globals) static void PF_cs_traceline(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{ {
float *v1, *v2, *mins, *maxs; float *v1, *v2, *mins, *maxs;
@ -1238,19 +1325,8 @@ static void PF_cs_traceline(progfuncs_t *prinst, struct globalvars_s *pr_globals
ent->v->hull = 0; ent->v->hull = 0;
trace = CS_Move (v1, mins, maxs, v2, nomonsters, ent); trace = CS_Move (v1, mins, maxs, v2, nomonsters, ent);
ent->v->hull = savedhull; ent->v->hull = savedhull;
*csqcg.trace_allsolid = trace.allsolid; cs_settracevars(&trace);
*csqcg.trace_startsolid = trace.startsolid;
*csqcg.trace_fraction = trace.fraction;
*csqcg.trace_inwater = trace.inwater;
*csqcg.trace_inopen = trace.inopen;
VectorCopy (trace.endpos, csqcg.trace_endpos);
VectorCopy (trace.plane.normal, csqcg.trace_plane_normal);
*csqcg.trace_plane_dist = trace.plane.dist;
if (trace.ent)
*csqcg.trace_ent = EDICT_TO_PROG(prinst, (void*)trace.ent);
else
*csqcg.trace_ent = EDICT_TO_PROG(prinst, (void*)csqc_edicts);
} }
static void PF_cs_tracebox(progfuncs_t *prinst, struct globalvars_s *pr_globals) static void PF_cs_tracebox(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{ {
@ -1810,21 +1886,6 @@ static void PF_cs_getplayerkey (progfuncs_t *prinst, struct globalvars_s *pr_glo
G_INT(OFS_RETURN) = 0; G_INT(OFS_RETURN) = 0;
} }
extern int mouseusedforgui, mousecursor_x, mousecursor_y;
static void PF_cs_setwantskeys (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
qboolean wants = G_FLOAT(OFS_PARM0);
csqcwantskeys = wants;
mouseusedforgui = wants;
}
static void PF_cs_getmousepos (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
G_FLOAT(OFS_RETURN+0) = mousecursor_x;
G_FLOAT(OFS_RETURN+1) = mousecursor_y;
G_FLOAT(OFS_RETURN+2) = 0;
}
#define lh_extension_t void #define lh_extension_t void
lh_extension_t *checkfteextensionsv(char *name); lh_extension_t *checkfteextensionsv(char *name);
lh_extension_t *checkextension(char *name); lh_extension_t *checkextension(char *name);
@ -2447,10 +2508,6 @@ void PF_rotatevectorsbytag (progfuncs_t *prinst, struct globalvars_s *pr_globals
if (Mod_GetTag) if (Mod_GetTag)
if (Mod_GetTag(mod, tagnum, frame1, frame2, lerp, frame1time, frame2time, transforms)) if (Mod_GetTag(mod, tagnum, frame1, frame2, lerp, frame1time, frame2time, transforms))
{ {
// VectorNegate(transforms+0, transforms+0);
// VectorNegate(transforms+4, transforms+4);
// VectorNegate(transforms+8, transforms+8);
VectorCopy(csqcg.forward, src+0); VectorCopy(csqcg.forward, src+0);
VectorNegate(csqcg.right, src+4); VectorNegate(csqcg.right, src+4);
VectorCopy(csqcg.up, src+8); VectorCopy(csqcg.up, src+8);
@ -2628,8 +2685,193 @@ static void PF_cs_break (progfuncs_t *prinst, struct globalvars_s *pr_globals)
#endif #endif
} }
qboolean CS_movestep (csqcedict_t *ent, vec3_t move, qboolean relink, qboolean noenemy, qboolean set_trace)
{
float dz;
vec3_t oldorg, neworg, end;
trace_t trace;
int i;
csqcedict_t *enemy = csqc_edicts;
// try the move
VectorCopy (ent->v->origin, oldorg);
VectorAdd (ent->v->origin, move, neworg);
// flying monsters don't step up
if ( (int)ent->v->flags & (FL_SWIM | FL_FLY) )
{
// try one move with vertical motion, then one without
for (i=0 ; i<2 ; i++)
{
VectorAdd (ent->v->origin, move, neworg);
if (!noenemy)
{
enemy = (csqcedict_t*)PROG_TO_EDICT(csqcprogs, ent->v->enemy);
if (i == 0 && enemy != csqc_edicts)
{
dz = ent->v->origin[2] - ((csqcedict_t*)PROG_TO_EDICT(csqcprogs, ent->v->enemy))->v->origin[2];
if (dz > 40)
neworg[2] -= 8;
if (dz < 30)
neworg[2] += 8;
}
}
trace = CS_Move (ent->v->origin, ent->v->mins, ent->v->maxs, neworg, false, ent);
if (set_trace)
cs_settracevars(&trace);
if (trace.fraction == 1)
{
if ( ((int)ent->v->flags & FL_SWIM) && !(CS_PointContents(trace.endpos) & FTECONTENTS_FLUID))
return false; // swim monster left water
VectorCopy (trace.endpos, ent->v->origin);
if (relink)
CS_LinkEdict (ent, true);
return true;
}
if (noenemy || enemy == csqc_edicts)
break;
}
return false;
}
// push down from a step height above the wished position
neworg[2] += pm_stepheight;
VectorCopy (neworg, end);
end[2] -= pm_stepheight*2;
trace = CS_Move (neworg, ent->v->mins, ent->v->maxs, end, false, ent);
if (set_trace)
cs_settracevars(&trace);
if (trace.allsolid)
return false;
if (trace.startsolid)
{
neworg[2] -= pm_stepheight;
trace = CS_Move (neworg, ent->v->mins, ent->v->maxs, end, false, ent);
if (set_trace)
cs_settracevars(&trace);
if (trace.allsolid || trace.startsolid)
return false;
}
if (trace.fraction == 1)
{
// if monster had the ground pulled out, go ahead and fall
if ( (int)ent->v->flags & FL_PARTIALGROUND )
{
VectorAdd (ent->v->origin, move, ent->v->origin);
if (relink)
CS_LinkEdict (ent, true);
ent->v->flags = (int)ent->v->flags & ~FL_ONGROUND;
// Con_Printf ("fall down\n");
return true;
}
return false; // walked off an edge
}
// check point traces down for dangling corners
VectorCopy (trace.endpos, ent->v->origin);
if (!CS_CheckBottom (ent))
{
if ( (int)ent->v->flags & FL_PARTIALGROUND )
{ // entity had floor mostly pulled out from underneath it
// and is trying to correct
if (relink)
CS_LinkEdict (ent, true);
return true;
}
VectorCopy (oldorg, ent->v->origin);
return false;
}
if ( (int)ent->v->flags & FL_PARTIALGROUND )
{
// Con_Printf ("back on ground\n");
ent->v->flags = (int)ent->v->flags & ~FL_PARTIALGROUND;
}
ent->v->groundentity = EDICT_TO_PROG(csqcprogs, trace.ent);
// the move is ok
if (relink)
CS_LinkEdict (ent, true);
return true;
}
static void PF_cs_walkmove (progfuncs_t *prinst, struct globalvars_s *pr_globals) static void PF_cs_walkmove (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{ {
csqcedict_t *ent;
float yaw, dist;
vec3_t move;
// dfunction_t *oldf;
int oldself;
qboolean settrace;
ent = (csqcedict_t*)PROG_TO_EDICT(prinst, *csqcg.self);
yaw = G_FLOAT(OFS_PARM0);
dist = G_FLOAT(OFS_PARM1);
if (*prinst->callargc >= 3 && G_FLOAT(OFS_PARM2))
settrace = true;
else
settrace = false;
if ( !( (int)ent->v->flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
{
G_FLOAT(OFS_RETURN) = 0;
return;
}
yaw = yaw*M_PI*2 / 360;
move[0] = cos(yaw)*dist;
move[1] = sin(yaw)*dist;
move[2] = 0;
// save program state, because CS_movestep may call other progs
oldself = *csqcg.self;
G_FLOAT(OFS_RETURN) = CS_movestep(ent, move, true, false, settrace);
// restore program state
*csqcg.self = oldself;
}
static void CS_ConsoleCommand_f(void)
{ //FIXME: unregister them.
char cmd[2048];
sprintf(cmd, "%s %s", Cmd_Argv(0), Cmd_Args());
CSQC_ConsoleCommand(cmd);
}
static void PF_cs_registercommand (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *str = PF_VarString(prinst, 0, pr_globals);
Cmd_AddRemCommand(str, CS_ConsoleCommand_f);
}
static qboolean csqc_usinglistener;
qboolean CSQC_SettingListener(void)
{ //stops the engine from setting the listener positions.
if (csqc_usinglistener)
{
csqc_usinglistener = false;
return true;
}
return false;
}
static void PF_cs_setlistener (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
float *origin = G_VECTOR(OFS_PARM0);
float *forward = G_VECTOR(OFS_PARM1);
float *right = G_VECTOR(OFS_PARM2);
float *up = G_VECTOR(OFS_PARM3);
csqc_usinglistener = true;
S_Update(origin, forward, right, up);
} }
#define PF_FixTen PF_Fixme,PF_Fixme,PF_Fixme,PF_Fixme,PF_Fixme,PF_Fixme,PF_Fixme,PF_Fixme,PF_Fixme,PF_Fixme #define PF_FixTen PF_Fixme,PF_Fixme,PF_Fixme,PF_Fixme,PF_Fixme,PF_Fixme,PF_Fixme,PF_Fixme,PF_Fixme,PF_Fixme
@ -2643,6 +2885,10 @@ static void PF_cs_walkmove (progfuncs_t *prinst, struct globalvars_s *pr_globals
#define PF_cs_gettaginfo PF_Fixme #define PF_cs_gettaginfo PF_Fixme
#define PS_cs_setattachment PF_Fixme #define PS_cs_setattachment PF_Fixme
#define PF_R_PolygonBegin PF_Fixme // #306 void(string texturename) R_BeginPolygon (EXT_CSQC_???)
#define PF_R_PolygonVertex PF_Fixme // #307 void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex (EXT_CSQC_???)
#define PF_R_PolygonEnd PF_Fixme // #308 void() R_EndPolygon (EXT_CSQC_???)
//warning: functions that depend on globals are bad, mkay? //warning: functions that depend on globals are bad, mkay?
static builtin_t csqc_builtins[] = { static builtin_t csqc_builtins[] = {
//0 //0
@ -2804,69 +3050,19 @@ PF_Fixme,
PF_Fixme, PF_Fixme,
//130 //130
PF_R_ClearScene, // #??? PF_FixTen,
PF_R_AddEntityMask, // #???
PF_R_AddEntity, // #???
PF_R_SetViewFlag, // #???
PF_R_RenderScene, // #???
PF_R_AddDynamicLight, // #???
PF_Stub,
PF_Fixme,
PF_Fixme,
PF_CL_drawline, // #???
//140 //140
PF_CL_is_cached_pic, // #??? PF_FixTen,
PF_CL_precache_pic, // #???
PF_CL_free_pic, // #???
PF_CL_drawcharacter, // #???
PF_CL_drawstring, // #???
PF_CL_drawpic, // #???
PF_CL_drawfill, // #???
PF_CL_drawsetcliparea, // #???
PF_CL_drawresetcliparea, // #???
PF_CL_drawgetimagesize, // #??? vector(string picname) draw_getimagesize (EXT_CSQC)
//150 //150
PF_cs_getstatf, // #??? float(float stnum) getstatf (EXT_CSQC) PF_FixTen,
PF_cs_getstati, // #??? float(float stnum) getstati (EXT_CSQC)
PF_cs_getstats, // #??? string(float firststnum) getstats (EXT_CSQC)
PF_cs_SetModelIndex, // #??? void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
PF_cs_ModelnameForIndex, // #??? string(float mdlindex) modelnameforindex (EXT_CSQC)
PF_cs_setsensativityscaler, // #??? void(float sens) setsensitivityscaler (EXT_CSQC)
PF_cl_cprint, // #??? void(string s) cprint (EXT_CSQC)
PF_print, // #??? void(string s) print (EXT_CSQC)
PF_cs_pointparticles, // #??? void(float effectnum, vector origin [, vector dir, float count]) pointparticles (EXT_CSQC)
PF_cs_particlesloaded, // #??? float(string effectname) particleeffectnum (EXT_CSQC)
//160 //160
PF_cs_getinputstate, // #??? float(float framenum) getinputstate (EXT_CSQC) PF_FixTen,
PF_cs_runplayerphysics, // #??? void() runstandardplayerphysics (EXT_CSQC)
PF_cs_getplayerkey, // #??? string(float playernum, string keyname) getplayerkeyvalue (EXT_CSQC)
PF_cs_setwantskeys, // #??? void(float wants) setwantskeys (EXT_CSQC)
PF_cs_getmousepos, // #??? vector() getmousepos (EXT_CSQC)
PF_cl_playingdemo, // #??? float() isdemo
PF_cl_runningserver, // #??? float() isserver
PF_cl_keynumtostring, // #??? string(float keynum) keynumtostring (EXT_CSQC)
PF_cl_stringtokeynum, // #??? float(string keyname) stringtokeynum (EXT_CSQC)
PF_cl_getkeybind, // #??? string(float keynum) getkeybind (EXT_CSQC)
//170 //170
//note that 'ReadEntity' is pretty hard to implement reliably. Modders should use a combination of ReadShort, and findfloat, and remember that it might not be known clientside (pvs culled or other reason) PF_FixTen,
PF_ReadByte, // #??? float() readbyte (EXT_CSQC)
PF_ReadChar, // #??? float() readchar (EXT_CSQC)
PF_ReadShort, // #??? float() readshort (EXT_CSQC)
PF_ReadLong, // #??? float() readlong (EXT_CSQC)
PF_ReadCoord, // #??? float() readcoord (EXT_CSQC)
PF_ReadAngle, // #??? float() readangle (EXT_CSQC)
PF_ReadString, // #??? string() readstring (EXT_CSQC)
PF_ReadFloat, // #??? string() readfloat (EXT_CSQC)
PF_WasFreed, // #??? float(entity) wasfreed (EXT_CSQC) (should be availabe on server too)
PF_cs_trailparticles, // #??? void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC),
//180 //180
PF_FixTen, PF_FixTen,
@ -2947,25 +3143,106 @@ PF_FixTen,
PF_FixTen, PF_FixTen,
//300 //300
PF_FixTen, PF_R_ClearScene, // #300 void() clearscene (EXT_CSQC)
PF_R_AddEntityMask, // #301 void(float mask) addentities (EXT_CSQC)
PF_R_AddEntity, // #302 void(entity ent) addentity (EXT_CSQC)
PF_R_SetViewFlag, // #303 float(float property, ...) setproperty (EXT_CSQC)
PF_R_RenderScene, // #304 void() renderscene (EXT_CSQC)
PF_R_AddDynamicLight, // #305 void(vector org, float radius, vector lightcolours) adddynamiclight (EXT_CSQC)
PF_R_PolygonBegin, // #306 void(string texturename) R_BeginPolygon (EXT_CSQC_???)
PF_R_PolygonVertex, // #307 void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex (EXT_CSQC_???)
PF_R_PolygonEnd, // #308 void() R_EndPolygon (EXT_CSQC_???)
PF_Fixme, // #309
//310 //310
PF_FixTen, //maths stuff that uses the current view settings.
PF_cs_unproject, // #310 vector (vector v) unproject (EXT_CSQC)
PF_cs_project, // #311 vector (vector v) project (EXT_CSQC)
PF_Fixme, // #312
PF_Fixme, // #313
PF_Fixme, // #314
//2d (immediate) operations
PF_CL_drawline, // #315 void(float width, vector pos1, vector pos2) drawline (EXT_CSQC)
PF_CL_is_cached_pic, // #316 float(string name) iscachedpic (EXT_CSQC)
PF_CL_precache_pic, // #317 string(string name, float trywad) precache_pic (EXT_CSQC)
PF_CL_drawgetimagesize, // #318 vector(string picname) draw_getimagesize (EXT_CSQC)
PF_CL_free_pic, // #319 void(string name) freepic (EXT_CSQC)
//320 //320
PF_FixTen, PF_CL_drawcharacter, // #320 float(vector position, float character, vector scale, vector rgb, float alpha [, float flag]) drawcharacter (EXT_CSQC, [EXT_CSQC_???])
PF_CL_drawstring, // #321 float(vector position, string text, vector scale, vector rgb, float alpha [, float flag]) drawstring (EXT_CSQC, [EXT_CSQC_???])
PF_CL_drawpic, // #322 float(vector position, string pic, vector size, vector rgb, float alpha [, float flag]) drawpic (EXT_CSQC, [EXT_CSQC_???])
PF_CL_drawfill, // #323 float(vector position, vector size, vector rgb, float alpha [, float flag]) drawfill (EXT_CSQC, [EXT_CSQC_???])
PF_CL_drawsetcliparea, // #324 void(float x, float y, float width, float height) drawsetcliparea (EXT_CSQC_???)
PF_CL_drawresetcliparea, // #325 void(void) drawresetcliparea (EXT_CSQC_???)
PF_Fixme, // #326
PF_Fixme, // #327
PF_Fixme, // #328
PF_Fixme, // #329
//330 //330
PF_FixTen, PF_cs_getstatf, // #330 float(float stnum) getstatf (EXT_CSQC)
PF_cs_getstati, // #331 float(float stnum) getstati (EXT_CSQC)
PF_cs_getstats, // #332 string(float firststnum) getstats (EXT_CSQC)
PF_cs_SetModelIndex, // #333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
PF_cs_ModelnameForIndex, // #334 string(float mdlindex) modelnameforindex (EXT_CSQC)
PF_cs_particlesloaded, // #335 float(string effectname) particleeffectnum (EXT_CSQC)
PF_cs_trailparticles, // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC),
PF_cs_pointparticles, // #337 void(float effectnum, vector origin [, vector dir, float count]) pointparticles (EXT_CSQC)
PF_cl_cprint, // #338 void(string s) cprint (EXT_CSQC)
PF_print, // #339 void(string s) print (EXT_CSQC)
//340 //340
PF_FixTen, PF_cl_keynumtostring, // #340 string(float keynum) keynumtostring (EXT_CSQC)
PF_cl_stringtokeynum, // #341 float(string keyname) stringtokeynum (EXT_CSQC)
PF_cl_getkeybind, // #342 string(float keynum) getkeybind (EXT_CSQC)
PF_Fixme, // #343
PF_Fixme, // #344
PF_cs_getinputstate, // #345 float(float framenum) getinputstate (EXT_CSQC)
PF_cs_setsensativityscaler, // #346 void(float sens) setsensitivityscaler (EXT_CSQC)
PF_cs_runplayerphysics, // #347 void() runstandardplayerphysics (EXT_CSQC)
PF_cs_getplayerkey, // #348 string(float playernum, string keyname) getplayerkeyvalue (EXT_CSQC)
PF_cl_playingdemo, // #349 float() isdemo (EXT_CSQC)
//350 //350
PF_FixTen, PF_cl_runningserver, // #350 float() isserver (EXT_CSQC)
PF_cs_setlistener, // #351 void(vector origin, vector forward, vector right, vector up) SetListener (EXT_CSQC)
PF_cs_registercommand, // #352 void(string cmdname) registercommand (EXT_CSQC)
PF_WasFreed, // #353 float(entity ent) wasfreed (EXT_CSQC) (should be availabe on server too)
PF_Fixme, // #354
PF_Fixme, // #355
PF_Fixme, // #356
PF_Fixme, // #357
PF_Fixme, // #358
PF_Fixme, // #359
//360 //360
PF_FixTen, //note that 'ReadEntity' is pretty hard to implement reliably. Modders should use a combination of ReadShort, and findfloat, and remember that it might not be known clientside (pvs culled or other reason)
PF_ReadByte, // #360 float() readbyte (EXT_CSQC)
PF_ReadChar, // #361 float() readchar (EXT_CSQC)
PF_ReadShort, // #362 float() readshort (EXT_CSQC)
PF_ReadLong, // #363 float() readlong (EXT_CSQC)
PF_ReadCoord, // #364 float() readcoord (EXT_CSQC)
PF_ReadAngle, // #365 float() readangle (EXT_CSQC)
PF_ReadString, // #366 string() readstring (EXT_CSQC)
PF_ReadFloat, // #367 string() readfloat (EXT_CSQC)
PF_Fixme, // #368
PF_Fixme, // #369
//370 //370
PF_FixTen, PF_FixTen,
@ -3146,7 +3423,7 @@ qbyte *CSQC_PRLoadFile (char *path, void *buffer, int bufsize)
return file; return file;
file = COM_LoadStackFile(path, buffer, bufsize); file = COM_LoadStackFile(path, buffer, bufsize);
if (!cls.demoplayback) //allow them to use csprogs.dat if playing a demo, and don't care about the checksum if (file && !cls.demoplayback) //allow them to use csprogs.dat if playing a demo, and don't care about the checksum
{ {
if (Com_BlockChecksum(file, com_filesize) != csqcchecksum) if (Com_BlockChecksum(file, com_filesize) != csqcchecksum)
return NULL; //not valid return NULL; //not valid
@ -3162,6 +3439,34 @@ qbyte *CSQC_PRLoadFile (char *path, void *buffer, int bufsize)
return COM_LoadStackFile(path, buffer, bufsize);; return COM_LoadStackFile(path, buffer, bufsize);;
} }
int CSQC_PRFileSize (char *path)
{
qbyte *file;
if (!strcmp(path, "csprogs.dat"))
{
char newname[MAX_QPATH];
_snprintf(newname, MAX_PATH, "csprogsvers/%x.dat", csqcchecksum);
file = COM_LoadTempFile (newname);
if (file)
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 (Com_BlockChecksum(file, com_filesize) != csqcchecksum)
return -1; //not valid
}
return com_filesize;
}
return COM_FileSize(path);
}
double csqctime; double csqctime;
qboolean CSQC_Init (unsigned int checksum) qboolean CSQC_Init (unsigned int checksum)
{ {
@ -3179,7 +3484,7 @@ qboolean CSQC_Init (unsigned int checksum)
csqcprogparms.progsversion = PROGSTRUCT_VERSION; csqcprogparms.progsversion = PROGSTRUCT_VERSION;
csqcprogparms.ReadFile = CSQC_PRLoadFile;//char *(*ReadFile) (char *fname, void *buffer, int *len); csqcprogparms.ReadFile = CSQC_PRLoadFile;//char *(*ReadFile) (char *fname, void *buffer, int *len);
csqcprogparms.FileSize = COM_FileSize;//int (*FileSize) (char *fname); //-1 if file does not exist csqcprogparms.FileSize = CSQC_PRFileSize;//int (*FileSize) (char *fname); //-1 if file does not exist
csqcprogparms.WriteFile = QC_WriteFile;//bool (*WriteFile) (char *name, void *data, int len); csqcprogparms.WriteFile = QC_WriteFile;//bool (*WriteFile) (char *name, void *data, int len);
csqcprogparms.printf = (void *)Con_Printf;//Con_Printf;//void (*printf) (char *, ...); csqcprogparms.printf = (void *)Con_Printf;//Con_Printf;//void (*printf) (char *, ...);
csqcprogparms.Sys_Error = Sys_Error; csqcprogparms.Sys_Error = Sys_Error;
@ -3282,6 +3587,8 @@ qboolean CSQC_DrawView(void)
*csqcg.clientcommandframe = cls.netchan.outgoing_sequence; *csqcg.clientcommandframe = cls.netchan.outgoing_sequence;
if (csqcg.servercommandframe) if (csqcg.servercommandframe)
*csqcg.servercommandframe = cls.netchan.incoming_sequence; *csqcg.servercommandframe = cls.netchan.incoming_sequence;
if (csqcg.intermission)
*csqcg.intermission = cl.intermission;
if (csqcg.time) if (csqcg.time)
*csqcg.time = Sys_DoubleTime(); *csqcg.time = Sys_DoubleTime();
@ -3297,7 +3604,7 @@ qboolean CSQC_KeyPress(int key, qboolean down)
{ {
void *pr_globals; void *pr_globals;
if (!csqcprogs || !csqcwantskeys) if (!csqcprogs || !csqcg.input_event)
return false; return false;
pr_globals = PR_globals(csqcprogs, PR_CURRENT); pr_globals = PR_globals(csqcprogs, PR_CURRENT);
@ -3307,7 +3614,23 @@ qboolean CSQC_KeyPress(int key, qboolean down)
PR_ExecuteProgram (csqcprogs, csqcg.input_event); PR_ExecuteProgram (csqcprogs, csqcg.input_event);
return true; return G_FLOAT(OFS_RETURN);
}
qboolean CSQC_MouseMove(float xdelta, float ydelta)
{
void *pr_globals;
if (!csqcprogs || !csqcg.input_event)
return false;
pr_globals = PR_globals(csqcprogs, PR_CURRENT);
G_FLOAT(OFS_PARM0) = 2;
G_FLOAT(OFS_PARM1) = xdelta;
G_FLOAT(OFS_PARM2) = ydelta;
PR_ExecuteProgram (csqcprogs, csqcg.input_event);
return G_FLOAT(OFS_RETURN);
} }
qboolean CSQC_ConsoleCommand(char *cmd) qboolean CSQC_ConsoleCommand(char *cmd)

View File

@ -3768,6 +3768,7 @@ void DrawParticleTypes (void texturedparticles(particle_t *,part_type_t*), void
else if (r_part_beams.value > 0) else if (r_part_beams.value > 0)
bdraw = beamparticlesut; bdraw = beamparticlesut;
} }
break;
case PT_TEXTUREDSPARK: case PT_TEXTUREDSPARK:
if (r_part_sparks.value) if (r_part_sparks.value)
{ {

View File

@ -490,7 +490,7 @@ void Skin_NextDownload (void)
if (strchr(sc->skin->name, ' ')) //skip over skins using a space if (strchr(sc->skin->name, ' ')) //skip over skins using a space
continue; continue;
if (!CL_CheckOrDownloadFile(va("skins/%s.pcx", sc->skin->name), false)) if (!CL_CheckOrDownloadFile(va("skins/%s.pcx", sc->skin->name), NULL, false))
return; // started a download return; // started a download
} }

View File

@ -547,7 +547,7 @@ qboolean Wad_NextDownload (void)
if (wadname[9]) if (wadname[9])
{ {
if (COM_FCheckExists(wadname+9)) //wad is in root dir, so we don't need to try textures. if (COM_FCheckExists(wadname+9)) //wad is in root dir, so we don't need to try textures.
if (!CL_CheckOrDownloadFile(wadname, true)) if (!CL_CheckOrDownloadFile(wadname, wadname, true))
return false; return false;
} }
wads[i] = k; wads[i] = k;

View File

@ -918,6 +918,38 @@ void ML_ProjectionMatrix(float *proj, float wdivh, float fovy)
proj[11] = -1; proj[11] = -1;
proj[15] = 0; proj[15] = 0;
} }
void ML_ProjectionMatrix2(float *proj, float fovx, float fovy)
{
float xmin, xmax, ymin, ymax;
float nudge = 1;
//proj
ymax = 4 * tan( fovy * M_PI / 360.0 );
ymin = -ymax;
xmax = 4 * tan( fovx * M_PI / 360.0 );
xmin = -xmax;
proj[0] = (2*4) / (xmax - xmin);
proj[4] = 0;
proj[8] = (xmax + xmin) / (xmax - xmin);
proj[12] = 0;
proj[1] = 0;
proj[5] = (2*4) / (ymax - ymin);
proj[9] = (ymax + ymin) / (ymax - ymin);
proj[13] = 0;
proj[2] = 0;
proj[6] = 0;
proj[10] = -1 * nudge;
proj[14] = -2*4 * nudge;
proj[3] = 0;
proj[7] = 0;
proj[11] = -1;
proj[15] = 0;
}
typedef struct { typedef struct {
float m[4][4]; float m[4][4];

View File

@ -107,7 +107,8 @@ void RotatePointAroundVector( vec3_t dst, const vec3_t dir, const vec3_t point,
void ML_Project (vec3_t in, vec3_t out, vec3_t viewangles, vec3_t vieworg, float wdivh, float fovy); void ML_Project (vec3_t in, vec3_t out, vec3_t viewangles, vec3_t vieworg, float wdivh, float fovy);
void Matrix3_Multiply (vec3_t *in1, vec3_t *in2, vec3_t *out); void Matrix3_Multiply (vec3_t *in1, vec3_t *in2, vec3_t *out);
void Matrix4_Transform3(float *matrix, float *vector, float *product); void Matrix4_Transform3(float *matrix, float *vector, float *product);
void ML_ModelViewMatrix(vec3_t modelview, vec3_t viewangles, vec3_t vieworg); void ML_ModelViewMatrix(float *modelview, vec3_t viewangles, vec3_t vieworg);
void ML_ProjectionMatrix2(float *proj, float fovx, float fovy);
void ML_ModelViewMatrixFromAxis(float *modelview, vec3_t pn, vec3_t right, vec3_t up, vec3_t vieworg); void ML_ModelViewMatrixFromAxis(float *modelview, vec3_t pn, vec3_t right, vec3_t up, vec3_t vieworg);

View File

@ -1180,5 +1180,7 @@ typedef struct q1usercmd_s
#define DRF_TRANSLUCENT 128 #define DRF_TRANSLUCENT 128
//TENEBRAE_GFX_DLIGHTS
#define PFLAGS_NOSHADOW 1
#define PFLAGS_CORONA 2
#define PFLAGS_FULLDYNAMIC 128

View File

@ -625,7 +625,7 @@ int QVM_Exec(register qvm_t *qvm, int command, int arg0, int arg1, int arg2, int
static int recurse = 0; static int recurse = 0;
if (recurse++) if (recurse++)
Host_EndGame("QVM recursivly entered\n"); Sys_Error("QVM recursivly entered\n");
stackstart = (unsigned long*)(qvm->ss+qvm->len_ss); stackstart = (unsigned long*)(qvm->ss+qvm->len_ss);
stackend = (unsigned long*)(qvm->ss); stackend = (unsigned long*)(qvm->ss);

View File

@ -20,7 +20,7 @@ ObjectOutput=../../build
OverrideOutput=0 OverrideOutput=0
OverrideOutputName=FTEQuake.exe OverrideOutputName=FTEQuake.exe
HostApplication= HostApplication=
Folders=Client,Common,gl,inet,nq,qclib,server Folders=Client,Common,gl,inet,qclib,server
CommandLine=-basedir d:\quake\ CommandLine=-basedir d:\quake\
IncludeVersionInfo=1 IncludeVersionInfo=1
SupportXPThemes=0 SupportXPThemes=0
@ -211,7 +211,7 @@ BuildCmd=
Major=2 Major=2
Minor=5 Minor=5
Release=5 Release=5
Build=46 Build=47
LanguageID=2057 LanguageID=2057
CharsetID=1252 CharsetID=1252
CompanyName= CompanyName=

View File

@ -269,13 +269,12 @@ LINK32=link.exe
# PROP BASE Target_Dir "" # PROP BASE Target_Dir ""
# PROP Use_MFC 0 # PROP Use_MFC 0
# PROP Use_Debug_Libraries 1 # PROP Use_Debug_Libraries 1
# PROP Output_Dir "ftequake___Win32_Debug_Dedicated_Server" # PROP Output_Dir "DebugServer"
# PROP Intermediate_Dir "ftequake___Win32_Debug_Dedicated_Server" # PROP Intermediate_Dir "DebugServer"
# PROP Ignore_Export_Lib 0 # PROP Ignore_Export_Lib 0
# PROP Target_Dir "" # PROP Target_Dir ""
# ADD BASE CPP /nologo /G5 /ML /W3 /GX /ZI /Od /I "..\client" /I "../common" /I "../server" /I "../gl" /I "../sw" /I "../qclib" /I "../libs" /D "MINIMAL" /D "_DEBUG" /D "GLQUAKE" /D "WIN32" /D "_WINDOWS" /FR".\GLDebug/" /Fp".\GLDebug/qwcl.pch" /YX /Fo".\GLDebug/" /Fd".\GLDebug/" /FD /c # ADD BASE CPP /nologo /G5 /ML /W3 /GX /ZI /Od /I "..\client" /I "../common" /I "../server" /I "../gl" /I "../sw" /I "../qclib" /I "../libs" /D "MINIMAL" /D "_DEBUG" /D "GLQUAKE" /D "WIN32" /D "_WINDOWS" /FR".\GLDebug/" /Fp".\GLDebug/qwcl.pch" /YX /Fo".\GLDebug/" /Fd".\GLDebug/" /FD /c
# ADD CPP /nologo /G6 /ML /W3 /Gm /Gi /GX /ZI /Od /I "..\client" /I "../common" /I "../server" /I "../gl" /I "../sw" /I "../qclib" /I "../libs" /I "../libs/dxsdk7/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "SERVERONLY" /FR".\GLDebug/" /Fp".\GLDebug/qwcl.pch" /Yu"quakedef.h" /Fo".\GLDebug/" /Fd".\GLDebug/" /FD /c # ADD CPP /nologo /G6 /ML /W3 /Gm /Gi /GX /ZI /Od /I "..\client" /I "../common" /I "../server" /I "../gl" /I "../sw" /I "../qclib" /I "../libs" /I "../libs/dxsdk7/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "SERVERONLY" /FR".\DebugServer/" /Fp".\DebugServer/qwcl.pch" /Yu"quakedef.h" /Fo".\DebugServer/" /Fd".\DebugServer/" /FD /c
# SUBTRACT CPP /WX
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x809 /d "_DEBUG" # ADD BASE RSC /l 0x809 /d "_DEBUG"
@ -6262,7 +6261,7 @@ InputName=math
!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server" !ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server"
# Begin Custom Build # Begin Custom Build
OutDir=.\ftequake___Win32_Debug_Dedicated_Server OutDir=.\DebugServer
InputPath=..\common\math.s InputPath=..\common\math.s
InputName=math InputName=math
@ -7610,7 +7609,7 @@ InputName=worlda
!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server" !ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server"
# Begin Custom Build # Begin Custom Build
OutDir=.\ftequake___Win32_Debug_Dedicated_Server OutDir=.\DebugServer
InputPath=..\server\worlda.s InputPath=..\server\worlda.s
InputName=worlda InputName=worlda

View File

@ -1761,7 +1761,7 @@ void R_DrawBeam( entity_t *e )
vec3_t perpvec; vec3_t perpvec;
vec3_t direction, normalized_direction; vec3_t direction, normalized_direction;
vec3_t start_points[NUM_BEAM_SEGS], end_points[NUM_BEAM_SEGS]; vec3_t points[NUM_BEAM_SEGS*2];
vec3_t oldorigin, origin; vec3_t oldorigin, origin;
oldorigin[0] = e->oldorigin[0]; oldorigin[0] = e->oldorigin[0];
@ -1780,43 +1780,97 @@ void R_DrawBeam( entity_t *e )
return; return;
PerpendicularVector( perpvec, normalized_direction ); PerpendicularVector( perpvec, normalized_direction );
VectorScale( perpvec, e->frame / 2, perpvec ); if (!e->frame)
VectorScale( perpvec, e->scale / 2, perpvec );
else
VectorScale( perpvec, e->frame / 2, perpvec );
for ( i = 0; i < 6; i++ ) for ( i = 0; i < 6; i++ )
{ {
RotatePointAroundVector( start_points[i], normalized_direction, perpvec, (360.0/NUM_BEAM_SEGS)*i ); RotatePointAroundVector( points[i], normalized_direction, perpvec, (360.0/NUM_BEAM_SEGS)*i );
VectorAdd( start_points[i], origin, start_points[i] ); VectorAdd( points[i], origin, points[i] );
VectorAdd( start_points[i], direction, end_points[i] ); VectorAdd( points[i], direction, points[i+NUM_BEAM_SEGS] );
} }
qglDisable( GL_TEXTURE_2D ); #ifdef Q3SHADERS
qglEnable( GL_BLEND ); if (e->forcedshader)
qglDepthMask( GL_FALSE );
qglDisable(GL_ALPHA_TEST);
r = ( d_8to24rgbtable[e->skinnum & 0xFF] ) & 0xFF;
g = ( d_8to24rgbtable[e->skinnum & 0xFF] >> 8 ) & 0xFF;
b = ( d_8to24rgbtable[e->skinnum & 0xFF] >> 16 ) & 0xFF;
r *= 1/255.0F;
g *= 1/255.0F;
b *= 1/255.0F;
qglColor4f( r, g, b, e->alpha );
qglBegin( GL_TRIANGLE_STRIP );
for ( i = 0; i < NUM_BEAM_SEGS; i++ )
{ {
qglVertex3fv( start_points[i] ); int indexarray[NUM_BEAM_SEGS*6];
qglVertex3fv( end_points[i] ); vec2_t texcoords[NUM_BEAM_SEGS*2];
qglVertex3fv( start_points[(i+1)%NUM_BEAM_SEGS] ); mesh_t mesh;
qglVertex3fv( end_points[(i+1)%NUM_BEAM_SEGS] ); meshbuffer_t mb;
}
qglEnd();
qglEnable( GL_TEXTURE_2D ); mesh.xyz_array = points;
qglDisable( GL_BLEND ); mesh.indexes = indexarray;
qglDepthMask( GL_TRUE ); mesh.numindexes = sizeof(indexarray)/sizeof(indexarray[0]);
mesh.colors_array = NULL;
mesh.lmst_array = NULL;
mesh.normals_array = NULL;
mesh.numvertexes = NUM_BEAM_SEGS*2;
mesh.st_array = texcoords;
mb.entity = e;
mb.mesh = &mesh;
mb.shader = e->forcedshader;
mb.infokey = 0;
mb.fog = NULL;
mb.infokey = currententity->keynum;
mb.dlightbits = 0;
for (i = 0; i < NUM_BEAM_SEGS; i++)
{
indexarray[i*6+0] = i+0;
indexarray[i*6+1] = (i+1)%NUM_BEAM_SEGS;
indexarray[i*6+2] = indexarray[i*6+1]+NUM_BEAM_SEGS;
indexarray[i*6+3] = indexarray[i*6+0];
indexarray[i*6+4] = indexarray[i*6+2];
indexarray[i*6+5] = i+0+NUM_BEAM_SEGS;
texcoords[i][1] = (float)i/NUM_BEAM_SEGS;
texcoords[i][0] = 0;
texcoords[i+NUM_BEAM_SEGS][1] = (float)i/NUM_BEAM_SEGS;
texcoords[i+NUM_BEAM_SEGS][0] = 1;
}
R_IBrokeTheArrays();
R_PushMesh(&mesh, mb.shader->features | MF_NONBATCHED);
R_RenderMeshBuffer ( &mb, false );
}
else
#endif
{
qglDisable( GL_TEXTURE_2D );
qglEnable( GL_BLEND );
qglDepthMask( GL_FALSE );
qglDisable(GL_ALPHA_TEST);
r = ( d_8to24rgbtable[e->skinnum & 0xFF] ) & 0xFF;
g = ( d_8to24rgbtable[e->skinnum & 0xFF] >> 8 ) & 0xFF;
b = ( d_8to24rgbtable[e->skinnum & 0xFF] >> 16 ) & 0xFF;
r *= 1/255.0F;
g *= 1/255.0F;
b *= 1/255.0F;
qglColor4f( r, g, b, e->alpha );
qglBegin( GL_TRIANGLE_STRIP );
for ( i = 0; i < NUM_BEAM_SEGS; i++ )
{
qglVertex3fv( points[i] );
qglVertex3fv( points[i+NUM_BEAM_SEGS] );
qglVertex3fv( points[((i+1)%NUM_BEAM_SEGS)] );
qglVertex3fv( points[((i+1)%NUM_BEAM_SEGS)+NUM_BEAM_SEGS] );
}
qglEnd();
qglEnable( GL_TEXTURE_2D );
qglDisable( GL_BLEND );
qglDepthMask( GL_TRUE );
}
} }
void PPL_DrawEnt(entity_t *e, void *parm) void PPL_DrawEnt(entity_t *e, void *parm)
@ -1873,11 +1927,11 @@ void PPL_BaseEntTextures(void)
//FIXME: We want to depth sort with particles, but we also want depth. :( //FIXME: We want to depth sort with particles, but we also want depth. :(
//Until then, we have broken model lighting. //Until then, we have broken model lighting.
case mod_alias: case mod_alias:
// R_DrawGAliasModel (currententity); R_DrawGAliasModel (currententity);
if (currententity->flags & Q2RF_WEAPONMODEL) // if (currententity->flags & Q2RF_WEAPONMODEL)
RQ_AddDistReorder(PPL_DrawEnt, currententity, NULL, r_refdef.vieworg); // RQ_AddDistReorder(PPL_DrawEnt, currententity, NULL, r_refdef.vieworg);
else // else
RQ_AddDistReorder(PPL_DrawEnt, currententity, NULL, currententity->origin); // RQ_AddDistReorder(PPL_DrawEnt, currententity, NULL, currententity->origin);
break; break;
case mod_brush: case mod_brush:

View File

@ -133,7 +133,10 @@ void LightLoadEntities(char *entstring)
if (!entstring || !*com_token) if (!entstring || !*com_token)
break; break;
if (strcmp(com_token, "{")) if (strcmp(com_token, "{"))
Host_Error("token wasn't an open brace\n"); { //someone messed up. Stop parsing.
Con_Printf("token wasn't an open brace\n");
break;
}
mapent = &entities[num_entities]; mapent = &entities[num_entities];
memset(mapent, 0, sizeof(*mapent)); memset(mapent, 0, sizeof(*mapent));

View File

@ -3109,14 +3109,17 @@ static void PF_cvar (progfuncs_t *prinst, struct globalvars_s *pr_globals)
else if (!strcmp(str, "halflifebsp")) else if (!strcmp(str, "halflifebsp"))
G_FLOAT(OFS_RETURN) = sv.worldmodel->fromgame == fg_halflife; G_FLOAT(OFS_RETURN) = sv.worldmodel->fromgame == fg_halflife;
else else
G_FLOAT(OFS_RETURN) = Cvar_VariableValue (str); {
cvar_t *cv = Cvar_Get(str, "", 0, "QC variables");
G_FLOAT(OFS_RETURN) = cv->value;
}
} }
void PF_cvar_string (progfuncs_t *prinst, struct globalvars_s *pr_globals) void PF_cvar_string (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{ {
char *str; char *str = PR_GetStringOfs(prinst, OFS_PARM0);
str = PR_GetStringOfs(prinst, OFS_PARM0); cvar_t *cv = Cvar_Get(str, "", 0, "QC variables");
RETURN_CSTRING(Cvar_VariableString (str)); RETURN_CSTRING(cv->string);
} }
/* /*
@ -3134,11 +3137,8 @@ void PF_cvar_set (progfuncs_t *prinst, struct globalvars_s *pr_globals)
var_name = PR_GetStringOfs(prinst, OFS_PARM0); var_name = PR_GetStringOfs(prinst, OFS_PARM0);
val = PR_GetStringOfs(prinst, OFS_PARM1); val = PR_GetStringOfs(prinst, OFS_PARM1);
var = Cvar_FindVar(var_name); var = Cvar_Get(var_name, val, 0, "QC variables");
if (!var) Cvar_Set (var, val);
Con_Printf("PF_cvar_set: variable %s not found\n", var_name);
else
Cvar_Set (var, val);
} }
void PF_cvar_setf (progfuncs_t *prinst, struct globalvars_s *pr_globals) void PF_cvar_setf (progfuncs_t *prinst, struct globalvars_s *pr_globals)
@ -6113,6 +6113,7 @@ lh_extension_t QSG_Extensions[] = {
{"FRIK_FILE", 11, NULL, {"stof", "fopen","fclose","fgets","fputs","strlen","strcat","substring","stov","strzone","strunzone"}}, {"FRIK_FILE", 11, NULL, {"stof", "fopen","fclose","fgets","fputs","strlen","strcat","substring","stov","strzone","strunzone"}},
{"FTE_CALLTIMEOFDAY", 1, NULL, {"calltimeofday"}}, {"FTE_CALLTIMEOFDAY", 1, NULL, {"calltimeofday"}},
{"FTE_FORCEINFOKEY", 1, NULL, {"forceinfokey"}}, {"FTE_FORCEINFOKEY", 1, NULL, {"forceinfokey"}},
{"FTE_GFX_QUAKE3SHADERS"},
{"FTE_ISBACKBUFFERED", 1, NULL, {"isbackbuffered"}}, {"FTE_ISBACKBUFFERED", 1, NULL, {"isbackbuffered"}},
#ifndef NOMEDIA #ifndef NOMEDIA
{"FTE_MEDIA_AVI"}, //playfilm supports avi files. {"FTE_MEDIA_AVI"}, //playfilm supports avi files.
@ -6136,7 +6137,7 @@ lh_extension_t QSG_Extensions[] = {
{"KRIMZON_SV_PARSECLIENTCOMMAND", 3, NULL, {"clientcommand", "tokenize", "argv"}}, //very very similar to the mvdsv system. {"KRIMZON_SV_PARSECLIENTCOMMAND", 3, NULL, {"clientcommand", "tokenize", "argv"}}, //very very similar to the mvdsv system.
{"QSG_CVARSTRING", 1, NULL, {"cvar_string"}}, {"QSG_CVARSTRING", 1, NULL, {"cvar_string"}},
{"QW_ENGINE"}, //warning: interpretation of .skin on players can be dodgy, as can some other QW features that differ from NQ. {"QW_ENGINE", 1, NULL, {"infokey", "stof", "logfrag"}}, //warning: interpretation of .skin on players can be dodgy, as can some other QW features that differ from NQ.
{"QWE_MVD_RECORD"}, //Quakeworld extended get the credit for this one. (mvdsv) {"QWE_MVD_RECORD"}, //Quakeworld extended get the credit for this one. (mvdsv)
{"TEI_MD3_MODEL"}, {"TEI_MD3_MODEL"},
// {"TQ_RAILTRAIL"}, //treat this as the ZQ style railtrails which the client already supports, okay so the preparse stuff needs strengthening. // {"TQ_RAILTRAIL"}, //treat this as the ZQ style railtrails which the client already supports, okay so the preparse stuff needs strengthening.

View File

@ -2460,7 +2460,7 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore
ent = EDICT_NUM(svprogfuncs, e); ent = EDICT_NUM(svprogfuncs, e);
// ignore ents without visible models // ignore ents without visible models
if (!ent->v->SendEntity && (!ent->v->modelindex || !*PR_GetString(svprogfuncs, ent->v->model))) if (!ent->v->SendEntity && (!ent->v->modelindex || !*PR_GetString(svprogfuncs, ent->v->model)) && !((int)ent->v->pflags & PFLAGS_FULLDYNAMIC))
continue; continue;
if (progstype != PROG_QW) if (progstype != PROG_QW)

View File

@ -387,7 +387,7 @@ void SV_DropClient (client_t *drop)
SV_WipeChat(drop); SV_WipeChat(drop);
#endif #endif
#ifdef Q2SERVER #ifdef Q2SERVER
if (ge) if (ge && drop->protocol == SCP_QUAKE2)
ge->ClientDisconnect(drop->q2edict); ge->ClientDisconnect(drop->q2edict);
#endif #endif
if (svprogfuncs) if (svprogfuncs)

View File

@ -1872,19 +1872,24 @@ qboolean SV_Physics (void)
if (svs.gametype != GT_PROGS) //make tics multiples of sv_maxtic (defaults to 0.1) if (svs.gametype != GT_PROGS) //make tics multiples of sv_maxtic (defaults to 0.1)
{ {
host_frametime = realtime - old_time; host_frametime = sv.time - old_time;
if (host_frametime<0)
{
if (host_frametime < -1)
old_time = sv.time;
host_frametime = 0;
}
if (host_frametime < sv_maxtic.value && realtime) if (host_frametime < sv_maxtic.value && realtime)
{ {
sv.time+=host_frametime; // sv.time+=host_frametime;
return true; //don't bother with the whole server thing for a bit longer return true; //don't bother with the whole server thing for a bit longer
} }
if (host_frametime > sv_maxtic.value) if (host_frametime > sv_maxtic.value)
host_frametime = sv_maxtic.value; host_frametime = sv_maxtic.value;
old_time = realtime; old_time = sv.time;
sv.framenum++; sv.framenum++;
sv.time = sv.framenum*100;
switch(svs.gametype) switch(svs.gametype)
{ {
#ifdef Q2SERVER #ifdef Q2SERVER

View File

@ -660,7 +660,7 @@ void StartQuakeServer(void)
SV_Init (&parms); SV_Init (&parms);
// run one frame immediately for first heartbeat // run one frame immediately for first heartbeat
SV_Frame (0.1); SV_Frame ();
} }
@ -682,7 +682,7 @@ void ServerMainLoop(void)
newtime = Sys_DoubleTime (); newtime = Sys_DoubleTime ();
time = newtime - oldtime; time = newtime - oldtime;
oldtime = newtime; oldtime = newtime;
SV_Frame (time); SV_Frame ();
#ifdef USESERVICE #ifdef USESERVICE

View File

@ -1613,7 +1613,10 @@ qboolean SV_AllowDownload (char *name)
//root of gamedir //root of gamedir
if (!strchr(name, '/') && !allow_download_root.value) if (!strchr(name, '/') && !allow_download_root.value)
return false; {
if (strcmp(name, "csprogs.dat")) //we always allow csprogs.dat to be downloaded.
return false;
}
//any other subdirs are allowed //any other subdirs are allowed
return true; return true;