mirror of
https://github.com/nzp-team/fteqw.git
synced 2024-11-22 12:01:25 +00:00
remove the old SCVAR macro
server: my attempt at mvd recording fixes. there's a couple of other issues, at least with nq mods. client: properly support recording .dems mid-map for 15+666 client: server browser now queries nq servers for players+rules. renderer: add support for single-image dual-layer skies that some other engines use. qcc: add #merge, along with __wrap + __weak keywords. fix a symboldata issue revealed by this. qcc: added a flag to write the sourcecode into the .dat (zip format compatible with any zip program that can deal with 'self extractors'). qccgui: can be told to open a .dat file instead of .src, showing/using any embedded sourcecode. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5017 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
57dfaea5fd
commit
b749d8356a
62 changed files with 2359 additions and 1306 deletions
|
@ -51,14 +51,14 @@ static void QDECL CL_AutoTrackChanged(cvar_t *v, char *oldval)
|
||||||
Cam_AutoTrack_Update(v->string);
|
Cam_AutoTrack_Update(v->string);
|
||||||
}
|
}
|
||||||
// track high fragger
|
// track high fragger
|
||||||
cvar_t cl_autotrack_team = CVARD("cl_autotrack_team", "", "Specifies a team name that should be auto-tracked (players on other teams will not be candidates for autotracking). Accepts * and ? wildcards for awkward chars.");
|
cvar_t cl_autotrack_team = CVARD("cl_autotrack_team", "", "Specifies a team name that should be auto-tracked (players on other teams will not be candidates for autotracking). Accepts * and ? wildcards for awkward chars.");
|
||||||
cvar_t cl_autotrack = CVARCD("cl_autotrack", "auto", CL_AutoTrackChanged, "Specifies the default tracking mode at the start of the map. Use the 'autotrack' command to reset/apply an auto-tracking mode without changing the default.\nValid values are: high, ^hkiller^h, mod, user. Other values are treated as weighting scripts for mvd playback, where available.");
|
cvar_t cl_autotrack = CVARCD("cl_autotrack", "auto", CL_AutoTrackChanged, "Specifies the default tracking mode at the start of the map. Use the 'autotrack' command to reset/apply an auto-tracking mode without changing the default.\nValid values are: high, ^hkiller^h, mod, user. Other values are treated as weighting scripts for mvd playback, where available.");
|
||||||
cvar_t cl_hightrack = CVARD("cl_hightrack", "0", "Obsolete. If you want hightrack, use '[cl_]autotrack high' instead.");
|
cvar_t cl_hightrack = CVARD("cl_hightrack", "0", "Obsolete. If you want hightrack, use '[cl_]autotrack high' instead.");
|
||||||
|
|
||||||
//cvar_t cl_camera_maxpitch = {"cl_camera_maxpitch", "10" };
|
//cvar_t cl_camera_maxpitch = {"cl_camera_maxpitch", "10" };
|
||||||
//cvar_t cl_camera_maxyaw = {"cl_camera_maxyaw", "30" };
|
//cvar_t cl_camera_maxyaw = {"cl_camera_maxyaw", "30" };
|
||||||
cvar_t cl_chasecam = SCVAR("cl_chasecam", "1");
|
cvar_t cl_chasecam = CVAR("cl_chasecam", "1");
|
||||||
cvar_t cl_selfcam = SCVAR("cl_selfcam", "1");
|
cvar_t cl_selfcam = CVAR("cl_selfcam", "1");
|
||||||
|
|
||||||
void Cam_AutoTrack_Update(const char *mode)
|
void Cam_AutoTrack_Update(const char *mode)
|
||||||
{
|
{
|
||||||
|
|
|
@ -585,7 +585,7 @@ qboolean CL_GetDemoMessage (void)
|
||||||
|
|
||||||
olddemotime = demtime;
|
olddemotime = demtime;
|
||||||
|
|
||||||
if (msglength > MAX_NQMSGLEN)
|
if (msglength > net_message.maxsize)
|
||||||
{
|
{
|
||||||
Con_Printf ("Demo message > MAX_MSGLEN");
|
Con_Printf ("Demo message > MAX_MSGLEN");
|
||||||
CL_StopPlayback ();
|
CL_StopPlayback ();
|
||||||
|
@ -684,7 +684,7 @@ readnext:
|
||||||
cls.td_starttime = Sys_DoubleTime();
|
cls.td_starttime = Sys_DoubleTime();
|
||||||
demtime = demotime; // warp
|
demtime = demotime; // warp
|
||||||
}
|
}
|
||||||
else if (!cl.paused && cls.state >= ca_onserver)
|
else if (!(cl.paused&~4) && cls.state >= ca_onserver)
|
||||||
{ // always grab until fully connected
|
{ // always grab until fully connected
|
||||||
if (demtime + 1.0 < demotime)
|
if (demtime + 1.0 < demotime)
|
||||||
{
|
{
|
||||||
|
@ -993,7 +993,7 @@ void CL_WriteRecordQ2DemoMessage(sizebuf_t *msg)
|
||||||
====================
|
====================
|
||||||
CL_WriteDemoMessage
|
CL_WriteDemoMessage
|
||||||
|
|
||||||
Dumps the current net message, prefixed by the length and view angles
|
Dumps the specified net message as part of initial mid-map demo writing.
|
||||||
====================
|
====================
|
||||||
*/
|
*/
|
||||||
void CL_WriteRecordDemoMessage (sizebuf_t *msg, int seq)
|
void CL_WriteRecordDemoMessage (sizebuf_t *msg, int seq)
|
||||||
|
@ -1008,21 +1008,35 @@ void CL_WriteRecordDemoMessage (sizebuf_t *msg, int seq)
|
||||||
if (!cls.demorecording)
|
if (!cls.demorecording)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
fl = LittleFloat(Sys_DoubleTime()-recdemostart);
|
if (cls.demorecording == DPB_NETQUAKE)
|
||||||
VFS_WRITE (cls.demooutfile, &fl, sizeof(fl));
|
{
|
||||||
|
len = LittleLong (msg->cursize);
|
||||||
|
VFS_WRITE(cls.demooutfile, &len, sizeof(len));
|
||||||
|
for (i=0 ; i<3 ; i++)
|
||||||
|
{
|
||||||
|
float f = LittleFloat (cl.playerview[0].viewangles[i]);
|
||||||
|
VFS_WRITE(cls.demooutfile, &f, sizeof(f));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fl = LittleFloat(Sys_DoubleTime()-recdemostart);
|
||||||
|
VFS_WRITE (cls.demooutfile, &fl, sizeof(fl));
|
||||||
|
|
||||||
c = dem_read;
|
c = dem_read;
|
||||||
VFS_WRITE (cls.demooutfile, &c, sizeof(c));
|
VFS_WRITE (cls.demooutfile, &c, sizeof(c));
|
||||||
|
|
||||||
len = LittleLong (msg->cursize + 8);
|
len = LittleLong (msg->cursize + 8);
|
||||||
VFS_WRITE (cls.demooutfile, &len, 4);
|
VFS_WRITE (cls.demooutfile, &len, 4);
|
||||||
|
|
||||||
i = LittleLong(seq);
|
|
||||||
VFS_WRITE (cls.demooutfile, &i, 4);
|
|
||||||
VFS_WRITE (cls.demooutfile, &i, 4);
|
|
||||||
|
|
||||||
|
i = LittleLong(seq);
|
||||||
|
VFS_WRITE (cls.demooutfile, &i, 4);
|
||||||
|
VFS_WRITE (cls.demooutfile, &i, 4);
|
||||||
|
}
|
||||||
VFS_WRITE (cls.demooutfile, msg->data, msg->cursize);
|
VFS_WRITE (cls.demooutfile, msg->data, msg->cursize);
|
||||||
|
|
||||||
|
SZ_Clear(msg);
|
||||||
|
|
||||||
if (record_flush.ival)
|
if (record_flush.ival)
|
||||||
VFS_FLUSH (cls.demooutfile);
|
VFS_FLUSH (cls.demooutfile);
|
||||||
}
|
}
|
||||||
|
@ -1110,6 +1124,353 @@ void CL_RecordMap_f (void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
//qw-specific serverdata
|
||||||
|
static void CLQW_RecordServerData(sizebuf_t *buf)
|
||||||
|
{
|
||||||
|
extern char gamedirfile[];
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
// send the serverdata
|
||||||
|
MSG_WriteByte (buf, svc_serverdata);
|
||||||
|
#ifdef PROTOCOL_VERSION_FTE
|
||||||
|
if (cls.fteprotocolextensions) //maintain demo compatability
|
||||||
|
{
|
||||||
|
MSG_WriteLong (buf, PROTOCOL_VERSION_FTE);
|
||||||
|
MSG_WriteLong (buf, cls.fteprotocolextensions);
|
||||||
|
}
|
||||||
|
if (cls.fteprotocolextensions2) //maintain demo compatability
|
||||||
|
{
|
||||||
|
MSG_WriteLong (buf, PROTOCOL_VERSION_FTE2);
|
||||||
|
MSG_WriteLong (buf, cls.fteprotocolextensions2);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
MSG_WriteLong (buf, PROTOCOL_VERSION_QW);
|
||||||
|
MSG_WriteLong (buf, cl.servercount);
|
||||||
|
MSG_WriteString (buf, gamedirfile);
|
||||||
|
|
||||||
|
if (cls.fteprotocolextensions2 & PEXT2_MAXPLAYERS)
|
||||||
|
{
|
||||||
|
MSG_WriteByte (buf, cl.allocated_client_slots);
|
||||||
|
MSG_WriteByte (buf, cl.splitclients | (cl.spectator?128:0));
|
||||||
|
for (i = 0; i < cl.splitclients; i++)
|
||||||
|
MSG_WriteByte (buf, cl.playerview[i].playernum);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i = 0; i < cl.splitclients; i++)
|
||||||
|
{
|
||||||
|
if (cl.spectator)
|
||||||
|
MSG_WriteByte (buf, cl.playerview[i].playernum | 128);
|
||||||
|
else
|
||||||
|
MSG_WriteByte (buf, cl.playerview[i].playernum);
|
||||||
|
}
|
||||||
|
if (cls.fteprotocolextensions & PEXT_SPLITSCREEN)
|
||||||
|
MSG_WriteByte (buf, 128);
|
||||||
|
}
|
||||||
|
|
||||||
|
// send full levelname
|
||||||
|
MSG_WriteString (buf, cl.levelname);
|
||||||
|
|
||||||
|
// send the movevars
|
||||||
|
MSG_WriteFloat(buf, movevars.gravity);
|
||||||
|
MSG_WriteFloat(buf, movevars.stopspeed);
|
||||||
|
MSG_WriteFloat(buf, movevars.maxspeed);
|
||||||
|
MSG_WriteFloat(buf, movevars.spectatormaxspeed);
|
||||||
|
MSG_WriteFloat(buf, movevars.accelerate);
|
||||||
|
MSG_WriteFloat(buf, movevars.airaccelerate);
|
||||||
|
MSG_WriteFloat(buf, movevars.wateraccelerate);
|
||||||
|
MSG_WriteFloat(buf, movevars.friction);
|
||||||
|
MSG_WriteFloat(buf, movevars.waterfriction);
|
||||||
|
MSG_WriteFloat(buf, movevars.entgravity);
|
||||||
|
|
||||||
|
// send server info string
|
||||||
|
MSG_WriteByte (buf, svc_stufftext);
|
||||||
|
MSG_WriteString (buf, va("fullserverinfo \"%s\"\n", cl.serverinfo) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void CLNQ_WriteServerData(sizebuf_t *buf)
|
||||||
|
{
|
||||||
|
unsigned int protmain;
|
||||||
|
unsigned int protfl = 0;
|
||||||
|
unsigned int i;
|
||||||
|
const char *val;
|
||||||
|
|
||||||
|
val = Info_ValueForKey(cl.serverinfo, "*csprogs");
|
||||||
|
if (*val)
|
||||||
|
{
|
||||||
|
MSG_WriteByte(buf, svc_stufftext);
|
||||||
|
MSG_WriteString(buf, va("csqc_progcrc \"%s\"\n", val));
|
||||||
|
}
|
||||||
|
val = Info_ValueForKey(cl.serverinfo, "*csprogssize");
|
||||||
|
if (*val)
|
||||||
|
{
|
||||||
|
MSG_WriteByte(buf, svc_stufftext);
|
||||||
|
MSG_WriteString(buf, va("csqc_progsize \"%s\"\n", val));
|
||||||
|
}
|
||||||
|
val = Info_ValueForKey(cl.serverinfo, "*csprogsname");
|
||||||
|
if (*val)
|
||||||
|
{
|
||||||
|
MSG_WriteByte(buf, svc_stufftext);
|
||||||
|
MSG_WriteString(buf, va("csqc_progname \"%s\"\n", val));
|
||||||
|
}
|
||||||
|
|
||||||
|
MSG_WriteByte(buf, svc_serverdata);
|
||||||
|
if (cls.fteprotocolextensions)
|
||||||
|
{
|
||||||
|
MSG_WriteLong (buf, PROTOCOL_VERSION_FTE);
|
||||||
|
MSG_WriteLong (buf, cls.fteprotocolextensions);
|
||||||
|
}
|
||||||
|
if (cls.fteprotocolextensions2)
|
||||||
|
{
|
||||||
|
MSG_WriteLong (buf, PROTOCOL_VERSION_FTE2);
|
||||||
|
MSG_WriteLong (buf, cls.fteprotocolextensions2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cls.netchan.message.prim.anglesize == 2)
|
||||||
|
protfl |= RMQFL_SHORTANGLE;
|
||||||
|
if (cls.netchan.message.prim.anglesize == 4)
|
||||||
|
protfl |= RMQFL_FLOATANGLE;
|
||||||
|
if (cls.netchan.message.prim.coordsize == 3)
|
||||||
|
protfl |= RMQFL_24BITCOORD;
|
||||||
|
if (cls.netchan.message.prim.coordsize == 4)
|
||||||
|
protfl |= RMQFL_FLOATCOORD;
|
||||||
|
switch(cls.protocol_nq)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case CPNQ_ID: protmain = PROTOCOL_VERSION_NQ; break;
|
||||||
|
case CPNQ_BJP1: protmain = PROTOCOL_VERSION_BJP1; break;
|
||||||
|
case CPNQ_BJP2: protmain = PROTOCOL_VERSION_BJP2; break;
|
||||||
|
case CPNQ_BJP3: protmain = PROTOCOL_VERSION_BJP3; break;
|
||||||
|
case CPNQ_FITZ666: protmain = protfl?PROTOCOL_VERSION_RMQ:PROTOCOL_VERSION_FITZ; break; //this might break .scale, fte doesn't care, other engines might.
|
||||||
|
case CPNQ_DP5: protmain = PROTOCOL_VERSION_DP5; break;
|
||||||
|
case CPNQ_DP6: protmain = PROTOCOL_VERSION_DP6; break;
|
||||||
|
case CPNQ_DP7: protmain = PROTOCOL_VERSION_DP7; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
MSG_WriteLong (buf, protmain);
|
||||||
|
if (protmain == PROTOCOL_VERSION_RMQ)
|
||||||
|
MSG_WriteLong (buf, protfl);
|
||||||
|
|
||||||
|
MSG_WriteByte (buf, cl.allocated_client_slots);
|
||||||
|
MSG_WriteByte (buf, cl.deathmatch?GAME_DEATHMATCH:GAME_COOP);
|
||||||
|
MSG_WriteString (buf, cl.levelname);
|
||||||
|
|
||||||
|
for (i = 1; *cl.model_name[i] && i < MAX_PRECACHE_MODELS; i++)
|
||||||
|
MSG_WriteString (buf, cl.model_name[i]);
|
||||||
|
MSG_WriteByte (buf, 0);
|
||||||
|
|
||||||
|
for (i = 1; *cl.sound_name[i] && i < MAX_PRECACHE_SOUNDS ; i++)
|
||||||
|
MSG_WriteString (buf, cl.sound_name[i]);
|
||||||
|
MSG_WriteByte (buf, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CL_Record_Baseline(sizebuf_t *buf, entity_state_t *state, unsigned int bits)
|
||||||
|
{
|
||||||
|
unsigned int j;
|
||||||
|
if (bits & FITZ_B_LARGEMODEL)
|
||||||
|
MSG_WriteShort (buf, state->modelindex);
|
||||||
|
else
|
||||||
|
MSG_WriteByte (buf, state->modelindex);
|
||||||
|
if (bits & FITZ_B_LARGEFRAME)
|
||||||
|
MSG_WriteShort (buf, state->frame);
|
||||||
|
else
|
||||||
|
MSG_WriteByte (buf, state->frame);
|
||||||
|
MSG_WriteByte (buf, state->colormap);
|
||||||
|
MSG_WriteByte (buf, state->skinnum);
|
||||||
|
for (j=0 ; j<3 ; j++)
|
||||||
|
{
|
||||||
|
MSG_WriteCoord (buf, state->origin[j]);
|
||||||
|
MSG_WriteAngle (buf, state->angles[j]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bits & FITZ_B_ALPHA)
|
||||||
|
MSG_WriteByte(buf, state->trans);
|
||||||
|
if (bits & RMQFITZ_B_SCALE)
|
||||||
|
MSG_WriteByte(buf, state->scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
//nq+qw generic stuff.
|
||||||
|
static int CL_Record_ParticlesStaticsBaselines(sizebuf_t *buf, int seq)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
entity_state_t *es;
|
||||||
|
|
||||||
|
//particleeffectnum stuff
|
||||||
|
for (i = 1; i < MAX_SSPARTICLESPRE; i++)
|
||||||
|
{
|
||||||
|
if (!cl.particle_ssname[i])
|
||||||
|
break;
|
||||||
|
MSG_WriteByte(buf, svcfte_precache);
|
||||||
|
MSG_WriteShort(buf, PC_PARTICLE | i);
|
||||||
|
MSG_WriteString(buf, cl.particle_ssname[i]);
|
||||||
|
|
||||||
|
if (buf->cursize > buf->maxsize/2)
|
||||||
|
CL_WriteRecordDemoMessage (buf, seq++);
|
||||||
|
}
|
||||||
|
|
||||||
|
//custom tents (needed for hexen2, if nothing else)
|
||||||
|
for (i = 0; ; i++)
|
||||||
|
{
|
||||||
|
if (!CL_WriteCustomTEnt(buf, i))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (buf->cursize > buf->maxsize/2)
|
||||||
|
CL_WriteRecordDemoMessage (buf, seq++);
|
||||||
|
}
|
||||||
|
|
||||||
|
// spawnstatic
|
||||||
|
|
||||||
|
for (i = 0; i < cl.num_statics; i++)
|
||||||
|
{
|
||||||
|
es = &cl_static_entities[i].state;
|
||||||
|
|
||||||
|
#ifndef CLIENTONLY //FIXME
|
||||||
|
if (cls.fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS)
|
||||||
|
{
|
||||||
|
MSG_WriteByte(buf, svcfte_spawnstatic2);
|
||||||
|
SVFTE_EmitBaseline(es, false, buf, cls.fteprotocolextensions2);
|
||||||
|
}
|
||||||
|
//else if (cls.fteprotocolextensions & PEXT_SPAWNSTATIC2) //qw deltas
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
unsigned int bits = 0;
|
||||||
|
#ifdef NQPROT
|
||||||
|
if (es->modelindex > 255)
|
||||||
|
bits |= FITZ_B_LARGEMODEL;
|
||||||
|
if (es->frame > 255)
|
||||||
|
bits |= FITZ_B_LARGEFRAME;
|
||||||
|
if (es->trans != 255)
|
||||||
|
bits |= FITZ_B_ALPHA;
|
||||||
|
if (es->scale != 16)
|
||||||
|
bits |= RMQFITZ_B_SCALE;
|
||||||
|
if (cls.protocol == CP_NETQUAKE && CPNQ_IS_BJP)
|
||||||
|
{
|
||||||
|
MSG_WriteByte (buf, svc_spawnstatic);
|
||||||
|
bits = FITZ_B_LARGEMODEL; //bjp always uses shorts for models.
|
||||||
|
}
|
||||||
|
else if (cls.protocol == CP_NETQUAKE && cls.protocol_nq == CPNQ_FITZ666 && bits)
|
||||||
|
{
|
||||||
|
MSG_WriteByte (buf, svcfitz_spawnstatic2);
|
||||||
|
MSG_WriteByte (buf, bits);
|
||||||
|
}
|
||||||
|
// else if (baselinetype2 >= CPNQ_DP5 && baselinetype2 <= CPNQ_DP7 && (bits & (FITZ_B_LARGEMODEL|FITZ_B_LARGEFRAME)))
|
||||||
|
// {
|
||||||
|
// MSG_WriteByte (buf, svcdp_spawnstatic2);
|
||||||
|
// bits = FITZ_B_LARGEMODEL|FITZ_B_LARGEFRAME; //dp's baseline2 always has these (regular baseline is unmodified)
|
||||||
|
// }
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
//classic protocol
|
||||||
|
MSG_WriteByte (buf, svc_spawnstatic);
|
||||||
|
bits = 0;
|
||||||
|
}
|
||||||
|
CL_Record_Baseline(buf, es, bits);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buf->cursize > buf->maxsize/2)
|
||||||
|
CL_WriteRecordDemoMessage (buf, seq++);
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: static sounds
|
||||||
|
// static sounds are skipped in demos, life is hard
|
||||||
|
|
||||||
|
// baselines
|
||||||
|
|
||||||
|
for (i = 0; i < cl_baselines_count; i++)
|
||||||
|
{
|
||||||
|
es = cl_baselines + i;
|
||||||
|
|
||||||
|
if (memcmp(es, &nullentitystate, sizeof(nullentitystate)))
|
||||||
|
{
|
||||||
|
#ifndef CLIENTONLY //FIXME
|
||||||
|
if (cls.fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS)
|
||||||
|
{
|
||||||
|
MSG_WriteByte(buf, svcfte_spawnbaseline2);
|
||||||
|
SVFTE_EmitBaseline(es, true, buf, cls.fteprotocolextensions2);
|
||||||
|
}
|
||||||
|
//else if (cls.fteprotocolextensions & PEXT_SPAWNSTATIC2) //qw deltas
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
unsigned int bits = 0;
|
||||||
|
#ifdef NQPROT
|
||||||
|
if (es->modelindex > 255)
|
||||||
|
bits |= FITZ_B_LARGEMODEL;
|
||||||
|
if (es->frame > 255)
|
||||||
|
bits |= FITZ_B_LARGEFRAME;
|
||||||
|
if (es->trans != 255)
|
||||||
|
bits |= FITZ_B_ALPHA;
|
||||||
|
if (es->scale != 16)
|
||||||
|
bits |= RMQFITZ_B_SCALE;
|
||||||
|
if (cls.protocol == CP_NETQUAKE && CPNQ_IS_BJP)
|
||||||
|
{
|
||||||
|
MSG_WriteByte (buf, svc_spawnbaseline);
|
||||||
|
bits = FITZ_B_LARGEMODEL; //bjp always uses shorts for models.
|
||||||
|
}
|
||||||
|
else if (cls.protocol == CP_NETQUAKE && cls.protocol_nq == CPNQ_FITZ666 && bits)
|
||||||
|
{
|
||||||
|
MSG_WriteByte (buf, svcfitz_spawnbaseline2);
|
||||||
|
MSG_WriteByte (buf, bits);
|
||||||
|
}
|
||||||
|
else if (cls.protocol == CP_NETQUAKE && CPNQ_IS_DP && (bits & (FITZ_B_LARGEMODEL|FITZ_B_LARGEFRAME)))
|
||||||
|
{
|
||||||
|
MSG_WriteByte (buf, svcdp_spawnbaseline2);
|
||||||
|
bits = FITZ_B_LARGEMODEL|FITZ_B_LARGEFRAME; //dp's baseline2 always has these (regular baseline is unmodified)
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
MSG_WriteByte (buf,svc_spawnbaseline);
|
||||||
|
bits = 0;
|
||||||
|
}
|
||||||
|
MSG_WriteEntity (buf, i);
|
||||||
|
|
||||||
|
CL_Record_Baseline(buf, es, bits);
|
||||||
|
}
|
||||||
|
if (buf->cursize > buf->maxsize/2)
|
||||||
|
CL_WriteRecordDemoMessage (buf, seq++);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return seq;
|
||||||
|
}
|
||||||
|
static int CL_Record_Lightstyles(sizebuf_t *buf, int seq)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
// send all current light styles
|
||||||
|
for (i=0 ; i<MAX_LIGHTSTYLES ; i++)
|
||||||
|
{
|
||||||
|
if (i >= MAX_STANDARDLIGHTSTYLES)
|
||||||
|
if (!*cl_lightstyle[i].map)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
#ifdef PEXT_LIGHTSTYLECOL
|
||||||
|
if ((cls.fteprotocolextensions & PEXT_LIGHTSTYLECOL) && (cl_lightstyle[i].colours[0]!=1||cl_lightstyle[i].colours[1]!=1||cl_lightstyle[i].colours[2]!=1) && *cl_lightstyle[i].map)
|
||||||
|
{
|
||||||
|
MSG_WriteByte (buf, svcfte_lightstylecol);
|
||||||
|
MSG_WriteByte (buf, (unsigned char)i);
|
||||||
|
MSG_WriteByte (buf, 0x87);
|
||||||
|
MSG_WriteShort (buf, cl_lightstyle[i].colours[0]*1024);
|
||||||
|
MSG_WriteShort (buf, cl_lightstyle[i].colours[1]*1024);
|
||||||
|
MSG_WriteShort (buf, cl_lightstyle[i].colours[2]*1024);
|
||||||
|
MSG_WriteString (buf, cl_lightstyle[i].map);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
MSG_WriteByte (buf, svc_lightstyle);
|
||||||
|
MSG_WriteByte (buf, (unsigned char)i);
|
||||||
|
MSG_WriteString (buf, cl_lightstyle[i].map);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buf->cursize > buf->maxsize/2)
|
||||||
|
CL_WriteRecordDemoMessage (buf, seq++);
|
||||||
|
}
|
||||||
|
return seq;
|
||||||
|
}
|
||||||
|
|
||||||
const char *Get_Q2ConfigString(int i);
|
const char *Get_Q2ConfigString(int i);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1124,11 +1485,9 @@ void CL_Record_f (void)
|
||||||
int c;
|
int c;
|
||||||
char name[MAX_OSPATH];
|
char name[MAX_OSPATH];
|
||||||
sizebuf_t buf;
|
sizebuf_t buf;
|
||||||
char buf_data[MAX_QWMSGLEN];
|
char buf_data[MAX_OVERALLMSGLEN];
|
||||||
int n, i, j, seat;
|
int n, i, seat;
|
||||||
char *s, *p, *fname;
|
char *s, *p, *fname;
|
||||||
entity_t *ent;
|
|
||||||
entity_state_t *es;
|
|
||||||
player_info_t *player;
|
player_info_t *player;
|
||||||
extern char gamedirfile[];
|
extern char gamedirfile[];
|
||||||
int seq = 1;
|
int seq = 1;
|
||||||
|
@ -1153,8 +1512,8 @@ void CL_Record_f (void)
|
||||||
|
|
||||||
if (cls.protocol == CP_QUAKE2)
|
if (cls.protocol == CP_QUAKE2)
|
||||||
defaultext = ".dm2";
|
defaultext = ".dm2";
|
||||||
// else if (cls.protocol == CP_NETQUAKE)
|
else if (cls.protocol == CP_NETQUAKE && !CPNQ_IS_DP)
|
||||||
// defaultext = ".dem";
|
defaultext = ".dem";
|
||||||
else if (cls.protocol == CP_QUAKEWORLD)
|
else if (cls.protocol == CP_QUAKEWORLD)
|
||||||
defaultext = ".qwd";
|
defaultext = ".qwd";
|
||||||
else
|
else
|
||||||
|
@ -1169,6 +1528,9 @@ void CL_Record_f (void)
|
||||||
if (c == 2) //user supplied a name
|
if (c == 2) //user supplied a name
|
||||||
{
|
{
|
||||||
fname = Cmd_Argv(1);
|
fname = Cmd_Argv(1);
|
||||||
|
s = strrchr(fname, '.');
|
||||||
|
if (!Q_strcasecmp(s, defaultext))
|
||||||
|
*s = 0; //hack away that extension that they added.
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ //automagically generate a name
|
{ //automagically generate a name
|
||||||
|
@ -1230,8 +1592,7 @@ void CL_Record_f (void)
|
||||||
|| c=='<' || c=='>' || c=='"' || c=='.')
|
|| c=='<' || c=='>' || c=='"' || c=='.')
|
||||||
*p = '_';
|
*p = '_';
|
||||||
}
|
}
|
||||||
strncpy(name, fname, sizeof(name)-1-8);
|
Q_strncpyz(name, fname, sizeof(name)-8);
|
||||||
name[sizeof(name)-1-8] = '\0';
|
|
||||||
|
|
||||||
//make a unique name (unless the user specified it).
|
//make a unique name (unless the user specified it).
|
||||||
strcat (name, defaultext); //we have the space
|
strcat (name, defaultext); //we have the space
|
||||||
|
@ -1242,9 +1603,11 @@ void CL_Record_f (void)
|
||||||
f = FS_OpenVFS (name, "rb", FS_GAME);
|
f = FS_OpenVFS (name, "rb", FS_GAME);
|
||||||
if (f)
|
if (f)
|
||||||
{
|
{
|
||||||
COM_StripExtension(name, name, sizeof(name));
|
//remove the extension again
|
||||||
|
Q_strncpyz(name, fname, sizeof(name)-8);
|
||||||
p = name + strlen(name);
|
p = name + strlen(name);
|
||||||
strcat(p, "_XX.qwd");
|
strcat(p, "_XX");
|
||||||
|
strcat(p, defaultext);
|
||||||
p++;
|
p++;
|
||||||
i = 0;
|
i = 0;
|
||||||
do
|
do
|
||||||
|
@ -1282,67 +1645,12 @@ void CL_Record_f (void)
|
||||||
switch(cls.protocol)
|
switch(cls.protocol)
|
||||||
{
|
{
|
||||||
case CP_QUAKEWORLD:
|
case CP_QUAKEWORLD:
|
||||||
|
if (!cls.fteprotocolextensions && !cls.fteprotocolextensions2)
|
||||||
|
buf.maxsize = MAX_QWMSGLEN; //poo compatibility... :P
|
||||||
|
|
||||||
cls.demorecording = DPB_QUAKEWORLD;
|
cls.demorecording = DPB_QUAKEWORLD;
|
||||||
|
|
||||||
// serverdata
|
CLQW_RecordServerData(&buf);
|
||||||
// send the info about the new client to all connected clients
|
|
||||||
|
|
||||||
// send the serverdata
|
|
||||||
MSG_WriteByte (&buf, svc_serverdata);
|
|
||||||
#ifdef PROTOCOL_VERSION_FTE
|
|
||||||
if (cls.fteprotocolextensions) //maintain demo compatability
|
|
||||||
{
|
|
||||||
MSG_WriteLong (&buf, PROTOCOL_VERSION_FTE);
|
|
||||||
MSG_WriteLong (&buf, cls.fteprotocolextensions);
|
|
||||||
}
|
|
||||||
if (cls.fteprotocolextensions2) //maintain demo compatability
|
|
||||||
{
|
|
||||||
MSG_WriteLong (&buf, PROTOCOL_VERSION_FTE2);
|
|
||||||
MSG_WriteLong (&buf, cls.fteprotocolextensions2);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
MSG_WriteLong (&buf, PROTOCOL_VERSION_QW);
|
|
||||||
MSG_WriteLong (&buf, cl.servercount);
|
|
||||||
MSG_WriteString (&buf, gamedirfile);
|
|
||||||
|
|
||||||
if (cls.fteprotocolextensions2 & PEXT2_MAXPLAYERS)
|
|
||||||
{
|
|
||||||
MSG_WriteByte (&buf, cl.allocated_client_slots);
|
|
||||||
MSG_WriteByte (&buf, cl.splitclients | (cl.spectator?128:0));
|
|
||||||
for (i = 0; i < cl.splitclients; i++)
|
|
||||||
MSG_WriteByte (&buf, cl.playerview[i].playernum);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (i = 0; i < cl.splitclients; i++)
|
|
||||||
{
|
|
||||||
if (cl.spectator)
|
|
||||||
MSG_WriteByte (&buf, cl.playerview[i].playernum | 128);
|
|
||||||
else
|
|
||||||
MSG_WriteByte (&buf, cl.playerview[i].playernum);
|
|
||||||
}
|
|
||||||
if (cls.fteprotocolextensions & PEXT_SPLITSCREEN)
|
|
||||||
MSG_WriteByte (&buf, 128);
|
|
||||||
}
|
|
||||||
|
|
||||||
// send full levelname
|
|
||||||
MSG_WriteString (&buf, cl.levelname);
|
|
||||||
|
|
||||||
// send the movevars
|
|
||||||
MSG_WriteFloat(&buf, movevars.gravity);
|
|
||||||
MSG_WriteFloat(&buf, movevars.stopspeed);
|
|
||||||
MSG_WriteFloat(&buf, movevars.maxspeed);
|
|
||||||
MSG_WriteFloat(&buf, movevars.spectatormaxspeed);
|
|
||||||
MSG_WriteFloat(&buf, movevars.accelerate);
|
|
||||||
MSG_WriteFloat(&buf, movevars.airaccelerate);
|
|
||||||
MSG_WriteFloat(&buf, movevars.wateraccelerate);
|
|
||||||
MSG_WriteFloat(&buf, movevars.friction);
|
|
||||||
MSG_WriteFloat(&buf, movevars.waterfriction);
|
|
||||||
MSG_WriteFloat(&buf, movevars.entgravity);
|
|
||||||
|
|
||||||
// send server info string
|
|
||||||
MSG_WriteByte (&buf, svc_stufftext);
|
|
||||||
MSG_WriteString (&buf, va("fullserverinfo \"%s\"\n", cl.serverinfo) );
|
|
||||||
|
|
||||||
// send music
|
// send music
|
||||||
Media_WriteCurrentTrack(&buf);
|
Media_WriteCurrentTrack(&buf);
|
||||||
|
@ -1378,7 +1686,7 @@ void CL_Record_f (void)
|
||||||
|
|
||||||
|
|
||||||
MSG_WriteByte (&buf, svc_setpause);
|
MSG_WriteByte (&buf, svc_setpause);
|
||||||
MSG_WriteByte (&buf, cl.paused);
|
MSG_WriteByte (&buf, !!cl.paused);
|
||||||
|
|
||||||
#ifdef PEXT_SETVIEW
|
#ifdef PEXT_SETVIEW
|
||||||
if (cl.playerview[0].viewentity != cl.playerview[0].playernum+1) //tell the player if we have a different view entity
|
if (cl.playerview[0].viewentity != cl.playerview[0].playernum+1) //tell the player if we have a different view entity
|
||||||
|
@ -1389,7 +1697,6 @@ void CL_Record_f (void)
|
||||||
#endif
|
#endif
|
||||||
// flush packet
|
// flush packet
|
||||||
CL_WriteRecordDemoMessage (&buf, seq++);
|
CL_WriteRecordDemoMessage (&buf, seq++);
|
||||||
SZ_Clear (&buf);
|
|
||||||
|
|
||||||
// soundlist
|
// soundlist
|
||||||
MSG_WriteByte (&buf, svc_soundlist);
|
MSG_WriteByte (&buf, svc_soundlist);
|
||||||
|
@ -1405,7 +1712,7 @@ void CL_Record_f (void)
|
||||||
MSG_WriteByte (&buf, 0);
|
MSG_WriteByte (&buf, 0);
|
||||||
MSG_WriteByte (&buf, n);
|
MSG_WriteByte (&buf, n);
|
||||||
CL_WriteRecordDemoMessage (&buf, seq++);
|
CL_WriteRecordDemoMessage (&buf, seq++);
|
||||||
SZ_Clear (&buf);
|
|
||||||
if (n + 1 > 0xff)
|
if (n + 1 > 0xff)
|
||||||
{
|
{
|
||||||
MSG_WriteByte (&buf, svcfte_soundlistshort);
|
MSG_WriteByte (&buf, svcfte_soundlistshort);
|
||||||
|
@ -1425,7 +1732,6 @@ void CL_Record_f (void)
|
||||||
MSG_WriteByte (&buf, 0);
|
MSG_WriteByte (&buf, 0);
|
||||||
MSG_WriteByte (&buf, 0);
|
MSG_WriteByte (&buf, 0);
|
||||||
CL_WriteRecordDemoMessage (&buf, seq++);
|
CL_WriteRecordDemoMessage (&buf, seq++);
|
||||||
SZ_Clear (&buf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//FIXME: vweps
|
//FIXME: vweps
|
||||||
|
@ -1444,7 +1750,7 @@ void CL_Record_f (void)
|
||||||
MSG_WriteByte (&buf, 0);
|
MSG_WriteByte (&buf, 0);
|
||||||
MSG_WriteByte (&buf, n);
|
MSG_WriteByte (&buf, n);
|
||||||
CL_WriteRecordDemoMessage (&buf, seq++);
|
CL_WriteRecordDemoMessage (&buf, seq++);
|
||||||
SZ_Clear (&buf);
|
|
||||||
if (n + 1 > 0xff)
|
if (n + 1 > 0xff)
|
||||||
{
|
{
|
||||||
MSG_WriteByte (&buf, svcfte_modellistshort);
|
MSG_WriteByte (&buf, svcfte_modellistshort);
|
||||||
|
@ -1464,131 +1770,15 @@ void CL_Record_f (void)
|
||||||
MSG_WriteByte (&buf, 0);
|
MSG_WriteByte (&buf, 0);
|
||||||
MSG_WriteByte (&buf, 0);
|
MSG_WriteByte (&buf, 0);
|
||||||
CL_WriteRecordDemoMessage (&buf, seq++);
|
CL_WriteRecordDemoMessage (&buf, seq++);
|
||||||
SZ_Clear (&buf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//particleeffectnum stuff
|
seq = CL_Record_ParticlesStaticsBaselines(&buf, seq);
|
||||||
for (i = 1; i < MAX_SSPARTICLESPRE; i++)
|
|
||||||
{
|
|
||||||
if (!cl.particle_ssname[i])
|
|
||||||
break;
|
|
||||||
MSG_WriteByte(&buf, svcfte_precache);
|
|
||||||
MSG_WriteShort(&buf, PC_PARTICLE | i);
|
|
||||||
MSG_WriteString(&buf, cl.particle_ssname[i]);
|
|
||||||
|
|
||||||
if (buf.cursize > buf.maxsize/2)
|
|
||||||
{
|
|
||||||
CL_WriteRecordDemoMessage (&buf, seq++);
|
|
||||||
SZ_Clear (&buf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//custom tents (needed for hexen2, if nothing else)
|
|
||||||
for (i = 0; ; i++)
|
|
||||||
{
|
|
||||||
if (!CL_WriteCustomTEnt(&buf, i))
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (buf.cursize > buf.maxsize/2)
|
|
||||||
{
|
|
||||||
CL_WriteRecordDemoMessage (&buf, seq++);
|
|
||||||
SZ_Clear (&buf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// spawnstatic
|
|
||||||
|
|
||||||
for (i = 0; i < cl.num_statics; i++)
|
|
||||||
{
|
|
||||||
ent = &cl_static_entities[i].ent;
|
|
||||||
|
|
||||||
#ifndef CLIENTONLY //FIXME
|
|
||||||
if (cls.fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS)
|
|
||||||
{
|
|
||||||
MSG_WriteByte(&buf, svcfte_spawnstatic2);
|
|
||||||
SVFTE_EmitBaseline(&cl_static_entities[i].state, false, &buf, cls.fteprotocolextensions2);
|
|
||||||
}
|
|
||||||
//else if (cls.fteprotocolextensions & PEXT_SPAWNSTATIC2) //qw deltas
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
MSG_WriteByte (&buf, svc_spawnstatic);
|
|
||||||
|
|
||||||
for (j = 1; j < MAX_PRECACHE_MODELS; j++)
|
|
||||||
if (ent->model == cl.model_precache[j])
|
|
||||||
break;
|
|
||||||
if (j == MAX_PRECACHE_MODELS)
|
|
||||||
MSG_WriteByte (&buf, 0);
|
|
||||||
else
|
|
||||||
MSG_WriteByte (&buf, j);
|
|
||||||
|
|
||||||
MSG_WriteByte (&buf, ent->framestate.g[FS_REG].frame[0]);
|
|
||||||
MSG_WriteByte (&buf, 0);
|
|
||||||
MSG_WriteByte (&buf, ent->skinnum);
|
|
||||||
for (j=0 ; j<3 ; j++)
|
|
||||||
{
|
|
||||||
MSG_WriteCoord (&buf, ent->origin[j]);
|
|
||||||
MSG_WriteAngle (&buf, ent->angles[j]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (buf.cursize > buf.maxsize/2)
|
|
||||||
{
|
|
||||||
CL_WriteRecordDemoMessage (&buf, seq++);
|
|
||||||
SZ_Clear (&buf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: static sounds
|
|
||||||
// static sounds are skipped in demos, life is hard
|
|
||||||
|
|
||||||
// baselines
|
|
||||||
|
|
||||||
for (i = 0; i < cl_baselines_count; i++)
|
|
||||||
{
|
|
||||||
es = cl_baselines + i;
|
|
||||||
|
|
||||||
if (memcmp(es, &nullentitystate, sizeof(nullentitystate)))
|
|
||||||
{
|
|
||||||
#ifndef CLIENTONLY //FIXME
|
|
||||||
if (cls.fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS)
|
|
||||||
{
|
|
||||||
MSG_WriteByte(&buf, svcfte_spawnbaseline2);
|
|
||||||
SVFTE_EmitBaseline(es, true, &buf, cls.fteprotocolextensions2);
|
|
||||||
}
|
|
||||||
//else if (cls.fteprotocolextensions & PEXT_SPAWNSTATIC2) //qw deltas
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
MSG_WriteByte (&buf,svc_spawnbaseline);
|
|
||||||
MSG_WriteEntity (&buf, i);
|
|
||||||
|
|
||||||
MSG_WriteByte (&buf, es->modelindex);
|
|
||||||
MSG_WriteByte (&buf, es->frame);
|
|
||||||
MSG_WriteByte (&buf, es->colormap);
|
|
||||||
MSG_WriteByte (&buf, es->skinnum);
|
|
||||||
for (j=0 ; j<3 ; j++)
|
|
||||||
{
|
|
||||||
MSG_WriteCoord(&buf, es->origin[j]);
|
|
||||||
MSG_WriteAngle(&buf, es->angles[j]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (buf.cursize > buf.maxsize/2)
|
|
||||||
{
|
|
||||||
CL_WriteRecordDemoMessage (&buf, seq++);
|
|
||||||
SZ_Clear (&buf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MSG_WriteByte (&buf, svc_stufftext);
|
MSG_WriteByte (&buf, svc_stufftext);
|
||||||
MSG_WriteString (&buf, va("cmd spawn %i\n", cl.servercount) );
|
MSG_WriteString (&buf, va("cmd spawn %i\n", cl.servercount) );
|
||||||
|
|
||||||
if (buf.cursize)
|
if (buf.cursize)
|
||||||
{
|
|
||||||
CL_WriteRecordDemoMessage (&buf, seq++);
|
CL_WriteRecordDemoMessage (&buf, seq++);
|
||||||
SZ_Clear (&buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
// send current status of all other players
|
// send current status of all other players
|
||||||
|
|
||||||
|
@ -1633,44 +1823,10 @@ void CL_Record_f (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (buf.cursize > buf.maxsize/2)
|
if (buf.cursize > buf.maxsize/2)
|
||||||
{
|
|
||||||
CL_WriteRecordDemoMessage (&buf, seq++);
|
CL_WriteRecordDemoMessage (&buf, seq++);
|
||||||
SZ_Clear (&buf);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// send all current light styles
|
seq = CL_Record_Lightstyles(&buf, seq);
|
||||||
for (i=0 ; i<MAX_LIGHTSTYLES ; i++)
|
|
||||||
{
|
|
||||||
if (i >= MAX_STANDARDLIGHTSTYLES)
|
|
||||||
if (!*cl_lightstyle[i].map)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
#ifdef PEXT_LIGHTSTYLECOL
|
|
||||||
if ((cls.fteprotocolextensions & PEXT_LIGHTSTYLECOL) && (cl_lightstyle[i].colours[0]!=1||cl_lightstyle[i].colours[1]!=1||cl_lightstyle[i].colours[2]!=1) && *cl_lightstyle[i].map)
|
|
||||||
{
|
|
||||||
MSG_WriteByte (&buf, svcfte_lightstylecol);
|
|
||||||
MSG_WriteByte (&buf, (unsigned char)i);
|
|
||||||
MSG_WriteByte (&buf, 0x87);
|
|
||||||
MSG_WriteShort (&buf, cl_lightstyle[i].colours[0]*1024);
|
|
||||||
MSG_WriteShort (&buf, cl_lightstyle[i].colours[1]*1024);
|
|
||||||
MSG_WriteShort (&buf, cl_lightstyle[i].colours[2]*1024);
|
|
||||||
MSG_WriteString (&buf, cl_lightstyle[i].map);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
MSG_WriteByte (&buf, svc_lightstyle);
|
|
||||||
MSG_WriteByte (&buf, (unsigned char)i);
|
|
||||||
MSG_WriteString (&buf, cl_lightstyle[i].map);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (buf.cursize > buf.maxsize/2)
|
|
||||||
{
|
|
||||||
CL_WriteRecordDemoMessage (&buf, seq++);
|
|
||||||
SZ_Clear (&buf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (seat = 0; seat < cl.splitclients; seat++)
|
for (seat = 0; seat < cl.splitclients; seat++)
|
||||||
{
|
{
|
||||||
|
@ -1712,10 +1868,7 @@ void CL_Record_f (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (buf.cursize > buf.maxsize/2)
|
if (buf.cursize > buf.maxsize/2)
|
||||||
{
|
|
||||||
CL_WriteRecordDemoMessage (&buf, seq++);
|
CL_WriteRecordDemoMessage (&buf, seq++);
|
||||||
SZ_Clear (&buf);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1775,8 +1928,37 @@ void CL_Record_f (void)
|
||||||
CL_WriteRecordQ2DemoMessage (&buf);
|
CL_WriteRecordQ2DemoMessage (&buf);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
case CP_NETQUAKE: //FIXME
|
#ifdef NQPROT
|
||||||
|
case CP_NETQUAKE:
|
||||||
|
//csqc stuff
|
||||||
|
cls.demorecording = DPB_NETQUAKE;
|
||||||
|
VFS_WRITE(cls.demooutfile, "-1\n", 3); //stupid lame header thing.
|
||||||
|
|
||||||
|
CLNQ_WriteServerData(&buf);
|
||||||
|
MSG_WriteByte (&buf, svc_setpause);
|
||||||
|
MSG_WriteByte (&buf, !!cl.paused);
|
||||||
|
MSG_WriteByte (&buf, svc_setview);
|
||||||
|
MSG_WriteEntity (&buf, cl.playerview[0].viewentity);
|
||||||
|
|
||||||
|
MSG_WriteByte (&buf, svc_signonnum);
|
||||||
|
MSG_WriteByte (&buf, 1);
|
||||||
|
CL_WriteRecordDemoMessage (&buf, seq++);
|
||||||
|
|
||||||
|
seq = CL_Record_ParticlesStaticsBaselines(&buf, seq);
|
||||||
|
//fixme: brushes...
|
||||||
|
MSG_WriteByte (&buf, svc_signonnum);
|
||||||
|
MSG_WriteByte (&buf, 2);
|
||||||
|
CL_WriteRecordDemoMessage (&buf, seq++);
|
||||||
|
//fixme: clients
|
||||||
|
seq = CL_Record_Lightstyles(&buf, seq);
|
||||||
|
//fixme: stats
|
||||||
|
MSG_WriteByte (&buf, svc_signonnum);
|
||||||
|
MSG_WriteByte (&buf, 3);
|
||||||
|
CL_WriteRecordDemoMessage (&buf, seq++);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
|
//this should have been caught earlier
|
||||||
Con_Printf("Unable to begin demo recording with this network protocol\n");
|
Con_Printf("Unable to begin demo recording with this network protocol\n");
|
||||||
CL_Stop_f();
|
CL_Stop_f();
|
||||||
break;
|
break;
|
||||||
|
@ -1820,6 +2002,8 @@ void CL_ReRecord_f (void)
|
||||||
|
|
||||||
Q_snprintfz (name, sizeof(name), "%s", s);
|
Q_snprintfz (name, sizeof(name), "%s", s);
|
||||||
|
|
||||||
|
CL_Disconnect();
|
||||||
|
|
||||||
//
|
//
|
||||||
// open the demo file
|
// open the demo file
|
||||||
//
|
//
|
||||||
|
@ -1854,7 +2038,9 @@ void CL_ReRecord_f (void)
|
||||||
|
|
||||||
Con_Printf ("recording to %s.\n", name);
|
Con_Printf ("recording to %s.\n", name);
|
||||||
|
|
||||||
CL_Disconnect();
|
if (cls.demorecording == DPB_NETQUAKE) //nq demos have some silly header.
|
||||||
|
VFS_WRITE(cls.demooutfile, "-1\n", 3);
|
||||||
|
|
||||||
CL_BeginServerReconnect();
|
CL_BeginServerReconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ cvar_t cl_nodelta = CVAR("cl_nodelta","0");
|
||||||
|
|
||||||
cvar_t cl_c2sdupe = CVAR("cl_c2sdupe", "0");
|
cvar_t cl_c2sdupe = CVAR("cl_c2sdupe", "0");
|
||||||
cvar_t cl_c2spps = CVAR("cl_c2spps", "0");
|
cvar_t cl_c2spps = CVAR("cl_c2spps", "0");
|
||||||
cvar_t cl_c2sImpulseBackup = SCVAR("cl_c2sImpulseBackup","3");
|
cvar_t cl_c2sImpulseBackup = CVAR("cl_c2sImpulseBackup","3");
|
||||||
cvar_t cl_netfps = CVAR("cl_netfps", "150");
|
cvar_t cl_netfps = CVAR("cl_netfps", "150");
|
||||||
cvar_t cl_sparemsec = CVARC("cl_sparemsec", "10", CL_SpareMsec_Callback);
|
cvar_t cl_sparemsec = CVARC("cl_sparemsec", "10", CL_SpareMsec_Callback);
|
||||||
cvar_t cl_queueimpulses = CVAR("cl_queueimpulses", "0");
|
cvar_t cl_queueimpulses = CVAR("cl_queueimpulses", "0");
|
||||||
|
@ -555,17 +555,17 @@ void CL_ProxyMenuHooks(void)
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
cvar_t cl_upspeed = SCVARF("cl_upspeed","400", CVAR_ARCHIVE);
|
cvar_t cl_upspeed = CVARF("cl_upspeed","400", CVAR_ARCHIVE);
|
||||||
cvar_t cl_forwardspeed = SCVARF("cl_forwardspeed","400", CVAR_ARCHIVE);
|
cvar_t cl_forwardspeed = CVARF("cl_forwardspeed","400", CVAR_ARCHIVE);
|
||||||
cvar_t cl_backspeed = CVARFD("cl_backspeed","", CVAR_ARCHIVE, "The base speed that you move backwards at. If empty, uses the value of cl_forwardspeed instead.");
|
cvar_t cl_backspeed = CVARFD("cl_backspeed","", CVAR_ARCHIVE, "The base speed that you move backwards at. If empty, uses the value of cl_forwardspeed instead.");
|
||||||
cvar_t cl_sidespeed = SCVARF("cl_sidespeed","400", CVAR_ARCHIVE);
|
cvar_t cl_sidespeed = CVARF("cl_sidespeed","400", CVAR_ARCHIVE);
|
||||||
|
|
||||||
cvar_t cl_movespeedkey = SCVAR("cl_movespeedkey","2.0");
|
cvar_t cl_movespeedkey = CVAR("cl_movespeedkey","2.0");
|
||||||
|
|
||||||
cvar_t cl_yawspeed = SCVAR("cl_yawspeed","140");
|
cvar_t cl_yawspeed = CVAR("cl_yawspeed","140");
|
||||||
cvar_t cl_pitchspeed = SCVAR("cl_pitchspeed","150");
|
cvar_t cl_pitchspeed = CVAR("cl_pitchspeed","150");
|
||||||
|
|
||||||
cvar_t cl_anglespeedkey = SCVAR("cl_anglespeedkey","1.5");
|
cvar_t cl_anglespeedkey = CVAR("cl_anglespeedkey","1.5");
|
||||||
|
|
||||||
|
|
||||||
void CL_GatherButtons (usercmd_t *cmd, int pnum)
|
void CL_GatherButtons (usercmd_t *cmd, int pnum)
|
||||||
|
|
|
@ -45,11 +45,11 @@ qboolean noclip_anglehack; // remnant from old quake
|
||||||
void Host_FinishLoading(void);
|
void Host_FinishLoading(void);
|
||||||
|
|
||||||
|
|
||||||
cvar_t rcon_password = SCVARF("rcon_password", "", CVAR_NOUNSAFEEXPAND);
|
cvar_t rcon_password = CVARF("rcon_password", "", CVAR_NOUNSAFEEXPAND);
|
||||||
|
|
||||||
cvar_t rcon_address = SCVARF("rcon_address", "", CVAR_NOUNSAFEEXPAND);
|
cvar_t rcon_address = CVARF("rcon_address", "", CVAR_NOUNSAFEEXPAND);
|
||||||
|
|
||||||
cvar_t cl_timeout = SCVAR("cl_timeout", "60");
|
cvar_t cl_timeout = CVAR("cl_timeout", "60");
|
||||||
|
|
||||||
cvar_t cl_shownet = CVARD("cl_shownet","0", "Debugging var. 0 shows nothing. 1 shows incoming packet sizes. 2 shows individual messages. 3 shows entities too."); // can be 0, 1, or 2
|
cvar_t cl_shownet = CVARD("cl_shownet","0", "Debugging var. 0 shows nothing. 1 shows incoming packet sizes. 2 shows individual messages. 3 shows entities too."); // can be 0, 1, or 2
|
||||||
|
|
||||||
|
@ -271,11 +271,11 @@ int host_framecount;
|
||||||
qbyte *host_basepal;
|
qbyte *host_basepal;
|
||||||
qbyte *h2playertranslations;
|
qbyte *h2playertranslations;
|
||||||
|
|
||||||
cvar_t host_speeds = SCVAR("host_speeds","0"); // set for running times
|
cvar_t host_speeds = CVAR("host_speeds","0"); // set for running times
|
||||||
#ifdef CRAZYDEBUGGING
|
#ifdef CRAZYDEBUGGING
|
||||||
cvar_t developer = SCVAR("developer","1");
|
cvar_t developer = CVAR("developer","1");
|
||||||
#else
|
#else
|
||||||
cvar_t developer = SCVAR("developer","0");
|
cvar_t developer = CVAR("developer","0");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int fps_count;
|
int fps_count;
|
||||||
|
@ -5824,6 +5824,7 @@ void Host_Shutdown(void)
|
||||||
|
|
||||||
COM_DestroyWorkerThread();
|
COM_DestroyWorkerThread();
|
||||||
|
|
||||||
|
P_ShutdownParticleSystem();
|
||||||
Cvar_Shutdown();
|
Cvar_Shutdown();
|
||||||
Validation_FlushFileList();
|
Validation_FlushFileList();
|
||||||
|
|
||||||
|
|
|
@ -173,6 +173,8 @@ extern struct selectedserver_s
|
||||||
qboolean inuse;
|
qboolean inuse;
|
||||||
netadr_t adr;
|
netadr_t adr;
|
||||||
float refreshtime;
|
float refreshtime;
|
||||||
|
int lastplayer;
|
||||||
|
char lastrule[64];
|
||||||
|
|
||||||
serverdetailedinfo_t *detail;
|
serverdetailedinfo_t *detail;
|
||||||
|
|
||||||
|
|
|
@ -2842,7 +2842,7 @@ void CLQW_ParseServerData (void)
|
||||||
CL_DownloadFailed(cls.download->remotename, cls.download);
|
CL_DownloadFailed(cls.download->remotename, cls.download);
|
||||||
}
|
}
|
||||||
|
|
||||||
Con_DPrintf ("Serverdata packet received.\n");
|
Con_DPrintf ("Serverdata packet %s.\n", cls.demoplayback?"read":"received");
|
||||||
//
|
//
|
||||||
// wipe the client_state_t struct
|
// wipe the client_state_t struct
|
||||||
//
|
//
|
||||||
|
@ -3132,7 +3132,7 @@ void CLQ2_ParseServerData (void)
|
||||||
cls.fteprotocolextensions2 = 0;
|
cls.fteprotocolextensions2 = 0;
|
||||||
cls.demohadkeyframe = true; //assume that it did, so this stuff all gets recorded.
|
cls.demohadkeyframe = true; //assume that it did, so this stuff all gets recorded.
|
||||||
|
|
||||||
Con_DPrintf ("Serverdata packet received.\n");
|
Con_DPrintf ("Serverdata packet %s.\n", cls.demoplayback?"read":"received");
|
||||||
//
|
//
|
||||||
// wipe the client_state_t struct
|
// wipe the client_state_t struct
|
||||||
//
|
//
|
||||||
|
@ -3427,8 +3427,7 @@ void CLNQ_ParseServerData(void) //Doesn't change gamedir - use with caution.
|
||||||
int nummodels, numsounds;
|
int nummodels, numsounds;
|
||||||
char *str;
|
char *str;
|
||||||
int gametype;
|
int gametype;
|
||||||
if (developer.ival)
|
Con_DPrintf ("Serverdata packet %s.\n", cls.demoplayback?"read":"received");
|
||||||
Con_TPrintf ("Serverdata packet received.\n");
|
|
||||||
SCR_SetLoadingStage(LS_CLIENT);
|
SCR_SetLoadingStage(LS_CLIENT);
|
||||||
CL_ClearState ();
|
CL_ClearState ();
|
||||||
Stats_NewMap();
|
Stats_NewMap();
|
||||||
|
@ -3436,8 +3435,10 @@ void CLNQ_ParseServerData(void) //Doesn't change gamedir - use with caution.
|
||||||
|
|
||||||
CLNQ_ParseProtoVersion();
|
CLNQ_ParseProtoVersion();
|
||||||
|
|
||||||
if (MSG_ReadByte() > MAX_CLIENTS)
|
cl.allocated_client_slots = MSG_ReadByte();
|
||||||
|
if (cl.allocated_client_slots > MAX_CLIENTS)
|
||||||
{
|
{
|
||||||
|
cl.allocated_client_slots = MAX_CLIENTS;
|
||||||
Con_Printf ("\nWarning, this server supports more than %i clients, additional clients will do bad things\n", MAX_CLIENTS);
|
Con_Printf ("\nWarning, this server supports more than %i clients, additional clients will do bad things\n", MAX_CLIENTS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,8 +23,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
cvar_t cl_predict_extrapolate = CVARD("cl_predict_extrapolate", "", "If 1, enables prediction based upon partial input frames which can change over time resulting in a swimmy feel but does not need to interpolate. If 0, prediction will stay in the past and thus use only completed frames. Interpolation will then be used to smooth movement.\nThis cvar only applies when video and input frames are independant (ie: cl_netfps is set).");
|
cvar_t cl_predict_extrapolate = CVARD("cl_predict_extrapolate", "", "If 1, enables prediction based upon partial input frames which can change over time resulting in a swimmy feel but does not need to interpolate. If 0, prediction will stay in the past and thus use only completed frames. Interpolation will then be used to smooth movement.\nThis cvar only applies when video and input frames are independant (ie: cl_netfps is set).");
|
||||||
cvar_t cl_predict_timenudge = CVARD("cl_predict_timenudge", "0", "A debug feature. You should normally leave this as 0. Nudges local player prediction into the future if positive (resulting in extrapolation), or into the past if negative (resulting in laggy interpolation). Value is in seconds, so small decimals are required. This cvar applies even if input frames are tied to video frames.");
|
cvar_t cl_predict_timenudge = CVARD("cl_predict_timenudge", "0", "A debug feature. You should normally leave this as 0. Nudges local player prediction into the future if positive (resulting in extrapolation), or into the past if negative (resulting in laggy interpolation). Value is in seconds, so small decimals are required. This cvar applies even if input frames are tied to video frames.");
|
||||||
cvar_t cl_predict_smooth = CVARD("cl_lerp_smooth", "2", "If 2, will act as 1 when playing demos and otherwise act as if set to 0.\nIf 1, interpolation will run in the past, resulting in really smooth movement at the cost of latency (even on bunchy german ISDNs).\nIf 0, interpolation will be based upon packet arrival times and may judder due to packet loss.");
|
cvar_t cl_predict_smooth = CVARD("cl_lerp_smooth", "2", "If 2, will act as 1 when playing demos and otherwise act as if set to 0.\nIf 1, interpolation will run in the past, resulting in really smooth movement at the cost of latency (even on bunchy german ISDNs).\nIf 0, interpolation will be based upon packet arrival times and may judder due to packet loss.");
|
||||||
cvar_t cl_nopred = SCVAR("cl_nopred","0");
|
cvar_t cl_nopred = CVAR("cl_nopred","0");
|
||||||
cvar_t cl_pushlatency = SCVAR("pushlatency","-999");
|
cvar_t cl_pushlatency = CVAR("pushlatency","-999");
|
||||||
|
|
||||||
extern float pm_airaccelerate;
|
extern float pm_airaccelerate;
|
||||||
|
|
||||||
|
|
|
@ -224,19 +224,19 @@ float scr_disabled_time;
|
||||||
float oldsbar = 0;
|
float oldsbar = 0;
|
||||||
|
|
||||||
cvar_t con_stayhidden = CVARFD("con_stayhidden", "0", CVAR_NOTFROMSERVER, "0: allow console to pounce on the user\n1: console stays hidden unless explicitly invoked\n2:toggleconsole command no longer works\n3: shift+escape key no longer works");
|
cvar_t con_stayhidden = CVARFD("con_stayhidden", "0", CVAR_NOTFROMSERVER, "0: allow console to pounce on the user\n1: console stays hidden unless explicitly invoked\n2:toggleconsole command no longer works\n3: shift+escape key no longer works");
|
||||||
cvar_t show_fps = SCVARF("show_fps", "0", CVAR_ARCHIVE);
|
cvar_t show_fps = CVARF("show_fps", "0", CVAR_ARCHIVE);
|
||||||
cvar_t show_fps_x = SCVAR("show_fps_x", "-1");
|
cvar_t show_fps_x = CVAR("show_fps_x", "-1");
|
||||||
cvar_t show_fps_y = SCVAR("show_fps_y", "-1");
|
cvar_t show_fps_y = CVAR("show_fps_y", "-1");
|
||||||
cvar_t show_clock = SCVAR("cl_clock", "0");
|
cvar_t show_clock = CVAR("cl_clock", "0");
|
||||||
cvar_t show_clock_x = SCVAR("cl_clock_x", "0");
|
cvar_t show_clock_x = CVAR("cl_clock_x", "0");
|
||||||
cvar_t show_clock_y = SCVAR("cl_clock_y", "-1");
|
cvar_t show_clock_y = CVAR("cl_clock_y", "-1");
|
||||||
cvar_t show_gameclock = SCVAR("cl_gameclock", "0");
|
cvar_t show_gameclock = CVAR("cl_gameclock", "0");
|
||||||
cvar_t show_gameclock_x = SCVAR("cl_gameclock_x", "0");
|
cvar_t show_gameclock_x = CVAR("cl_gameclock_x", "0");
|
||||||
cvar_t show_gameclock_y = SCVAR("cl_gameclock_y", "-1");
|
cvar_t show_gameclock_y = CVAR("cl_gameclock_y", "-1");
|
||||||
cvar_t show_speed = SCVAR("show_speed", "0");
|
cvar_t show_speed = CVAR("show_speed", "0");
|
||||||
cvar_t show_speed_x = SCVAR("show_speed_x", "-1");
|
cvar_t show_speed_x = CVAR("show_speed_x", "-1");
|
||||||
cvar_t show_speed_y = SCVAR("show_speed_y", "-9");
|
cvar_t show_speed_y = CVAR("show_speed_y", "-9");
|
||||||
cvar_t scr_loadingrefresh = SCVAR("scr_loadingrefresh", "0");
|
cvar_t scr_loadingrefresh = CVAR("scr_loadingrefresh", "0");
|
||||||
cvar_t scr_showloading = CVAR("scr_showloading", "1");
|
cvar_t scr_showloading = CVAR("scr_showloading", "1");
|
||||||
cvar_t scr_showobituaries = CVAR("scr_showobituaries", "0");
|
cvar_t scr_showobituaries = CVAR("scr_showobituaries", "0");
|
||||||
|
|
||||||
|
|
|
@ -58,14 +58,14 @@ qterm_t *activeqterm;
|
||||||
float con_cursorspeed = 4;
|
float con_cursorspeed = 4;
|
||||||
|
|
||||||
|
|
||||||
cvar_t con_numnotifylines = SCVAR("con_notifylines","4"); //max lines to show
|
cvar_t con_numnotifylines = CVAR("con_notifylines","4"); //max lines to show
|
||||||
cvar_t con_notifytime = SCVAR("con_notifytime","3"); //seconds
|
cvar_t con_notifytime = CVAR("con_notifytime","3"); //seconds
|
||||||
cvar_t con_notify_x = SCVAR("con_notify_x","0");
|
cvar_t con_notify_x = CVAR("con_notify_x","0");
|
||||||
cvar_t con_notify_y = SCVAR("con_notify_y","0");
|
cvar_t con_notify_y = CVAR("con_notify_y","0");
|
||||||
cvar_t con_notify_w = SCVAR("con_notify_w","1");
|
cvar_t con_notify_w = CVAR("con_notify_w","1");
|
||||||
cvar_t con_centernotify = SCVAR("con_centernotify", "0");
|
cvar_t con_centernotify = CVAR("con_centernotify", "0");
|
||||||
cvar_t con_displaypossibilities = SCVAR("con_displaypossibilities", "1");
|
cvar_t con_displaypossibilities = CVAR("con_displaypossibilities", "1");
|
||||||
cvar_t con_maxlines = SCVAR("con_maxlines", "1024");
|
cvar_t con_maxlines = CVAR("con_maxlines", "1024");
|
||||||
cvar_t cl_chatmode = CVARD("cl_chatmode", "2", "0(nq) - everything is assumed to be a console command. prefix with 'say', or just use a messagemode bind\n1(q3) - everything is assumed to be chat, unless its prefixed with a /\n2(qw) - anything explicitly recognised as a command will be used as a command, anything unrecognised will be a chat message.\n/ prefix is supported in all cases.\nctrl held when pressing enter always makes any implicit chat into team chat instead.");
|
cvar_t cl_chatmode = CVARD("cl_chatmode", "2", "0(nq) - everything is assumed to be a console command. prefix with 'say', or just use a messagemode bind\n1(q3) - everything is assumed to be chat, unless its prefixed with a /\n2(qw) - anything explicitly recognised as a command will be used as a command, anything unrecognised will be a chat message.\n/ prefix is supported in all cases.\nctrl held when pressing enter always makes any implicit chat into team chat instead.");
|
||||||
cvar_t con_numnotifylines_chat = CVAR("con_numnotifylines_chat", "8");
|
cvar_t con_numnotifylines_chat = CVAR("con_numnotifylines_chat", "8");
|
||||||
cvar_t con_notifytime_chat = CVAR("con_notifytime_chat", "8");
|
cvar_t con_notifytime_chat = CVAR("con_notifytime_chat", "8");
|
||||||
|
|
|
@ -213,6 +213,10 @@ static void PM_FreePackage(package_t *p)
|
||||||
for (i = 0; i < countof(p->mirror); i++)
|
for (i = 0; i < countof(p->mirror); i++)
|
||||||
Z_Free(p->mirror[i]);
|
Z_Free(p->mirror[i]);
|
||||||
|
|
||||||
|
Z_Free(p->description);
|
||||||
|
Z_Free(p->author);
|
||||||
|
Z_Free(p->license);
|
||||||
|
Z_Free(p->previewimage);
|
||||||
Z_Free(p->qhash);
|
Z_Free(p->qhash);
|
||||||
Z_Free(p->arch);
|
Z_Free(p->arch);
|
||||||
Z_Free(p);
|
Z_Free(p);
|
||||||
|
|
|
@ -407,6 +407,7 @@ static void SL_PreDraw (menu_t *menu)
|
||||||
info->numslots = Master_NumSorted();
|
info->numslots = Master_NumSorted();
|
||||||
snprintf(info->refreshtext, sizeof(info->refreshtext), "Refresh - %u/%u/%u\n", info->numslots, Master_NumAlive(), Master_TotalCount());
|
snprintf(info->refreshtext, sizeof(info->refreshtext), "Refresh - %u/%u/%u\n", info->numslots, Master_NumAlive(), Master_TotalCount());
|
||||||
}
|
}
|
||||||
|
void NET_SendPollPacket(int len, void *data, netadr_t to);
|
||||||
static void SL_PostDraw (menu_t *menu)
|
static void SL_PostDraw (menu_t *menu)
|
||||||
{
|
{
|
||||||
static char *helpstrings[] =
|
static char *helpstrings[] =
|
||||||
|
@ -436,7 +437,32 @@ static void SL_PostDraw (menu_t *menu)
|
||||||
{
|
{
|
||||||
selectedserver.refreshtime = realtime + 4;
|
selectedserver.refreshtime = realtime + 4;
|
||||||
server->sends++;
|
server->sends++;
|
||||||
Master_QueryServer(server);
|
#ifdef NQPROT
|
||||||
|
//we might have gotten stuck. reset the poll
|
||||||
|
if ((server->special&SS_PROTOCOLMASK) == SS_NETQUAKE)
|
||||||
|
{ //start spamming the server to get all of its details. silly protocols.
|
||||||
|
selectedserver.lastplayer = 0;
|
||||||
|
*selectedserver.lastrule = 0;
|
||||||
|
|
||||||
|
SZ_Clear(&net_message);
|
||||||
|
net_message.packing = SZ_RAWBYTES;
|
||||||
|
net_message.currentbit = 0;
|
||||||
|
MSG_WriteLong(&net_message, 0);// save space for the header, filled in later
|
||||||
|
MSG_WriteByte(&net_message, CCREQ_PLAYER_INFO);
|
||||||
|
MSG_WriteByte(&net_message, selectedserver.lastplayer);
|
||||||
|
*((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
|
||||||
|
NET_SendPollPacket(net_message.cursize, net_message.data, server->adr);
|
||||||
|
SZ_Clear(&net_message);
|
||||||
|
MSG_WriteLong(&net_message, 0);// save space for the header, filled in later
|
||||||
|
MSG_WriteByte(&net_message, CCREQ_RULE_INFO);
|
||||||
|
MSG_WriteString(&net_message, selectedserver.lastrule);
|
||||||
|
*((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
|
||||||
|
NET_SendPollPacket(net_message.cursize, net_message.data, server->adr);
|
||||||
|
SZ_Clear(&net_message);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
Master_QueryServer(server);
|
||||||
}
|
}
|
||||||
R2D_ImageColours(1,1,1,1);
|
R2D_ImageColours(1,1,1,1);
|
||||||
if (server && server->moreinfo)
|
if (server && server->moreinfo)
|
||||||
|
|
|
@ -256,10 +256,10 @@ qboolean Media_EvaluateNextTrack(void);
|
||||||
|
|
||||||
int lasttrackplayed;
|
int lasttrackplayed;
|
||||||
|
|
||||||
cvar_t media_shuffle = SCVAR("media_shuffle", "1");
|
cvar_t media_shuffle = CVAR("media_shuffle", "1");
|
||||||
cvar_t media_repeat = SCVAR("media_repeat", "1");
|
cvar_t media_repeat = CVAR("media_repeat", "1");
|
||||||
#ifdef WINAMP
|
#ifdef WINAMP
|
||||||
cvar_t media_hijackwinamp = SCVAR("media_hijackwinamp", "0");
|
cvar_t media_hijackwinamp = CVAR("media_hijackwinamp", "0");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int selectedoption=-1;
|
int selectedoption=-1;
|
||||||
|
|
|
@ -756,6 +756,7 @@ const char *presetexec[] =
|
||||||
"seta r_part_classic_opaque 0;"
|
"seta r_part_classic_opaque 0;"
|
||||||
"seta r_stains 0;"
|
"seta r_stains 0;"
|
||||||
"seta r_drawflat 1;"
|
"seta r_drawflat 1;"
|
||||||
|
"seta r_lightmap 0;"
|
||||||
"seta r_nolerp 1;"
|
"seta r_nolerp 1;"
|
||||||
"seta r_nolightdir 1;"
|
"seta r_nolightdir 1;"
|
||||||
"seta r_dynamic 0;"
|
"seta r_dynamic 0;"
|
||||||
|
|
|
@ -209,7 +209,7 @@ qboolean m_recursiveDraw;
|
||||||
|
|
||||||
void M_ConfigureNetSubsystem(void);
|
void M_ConfigureNetSubsystem(void);
|
||||||
|
|
||||||
cvar_t m_helpismedia = SCVAR("m_helpismedia", "0");
|
cvar_t m_helpismedia = CVAR("m_helpismedia", "0");
|
||||||
cvar_t m_preset_chosen = CVARF("m_preset_chosen", "0", CVAR_ARCHIVE);
|
cvar_t m_preset_chosen = CVARF("m_preset_chosen", "0", CVAR_ARCHIVE);
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
|
@ -123,7 +123,7 @@ net_masterlist_t net_masterlist[] = {
|
||||||
// {MP_QUAKEWORLD, CVARFC("net_qwmasterextraHistoric", "telefrag.me:27000", CVAR_NOSAVE, Net_Masterlist_Callback), "telefrag.me"},
|
// {MP_QUAKEWORLD, CVARFC("net_qwmasterextraHistoric", "telefrag.me:27000", CVAR_NOSAVE, Net_Masterlist_Callback), "telefrag.me"},
|
||||||
// {MP_QUAKEWORLD, CVARFC("net_qwmasterextraHistoric", "master.teamdamage.com:27000", CVAR_NOSAVE, Net_Masterlist_Callback), "master.teamdamage.com"},
|
// {MP_QUAKEWORLD, CVARFC("net_qwmasterextraHistoric", "master.teamdamage.com:27000", CVAR_NOSAVE, Net_Masterlist_Callback), "master.teamdamage.com"},
|
||||||
|
|
||||||
{MP_DPMASTER, CVARFC("net_masterextra1", "ghdigital.com:27950 69.59.212.88:27950", CVAR_NOSAVE, Net_Masterlist_Callback)}, //69.59.212.88 (admin: LordHavoc)
|
{MP_DPMASTER, CVARFC("net_masterextra1", "ghdigital.com:27950 207.55.114.154:27950", CVAR_NOSAVE, Net_Masterlist_Callback)}, //207.55.114.154 (was 69.59.212.88 (admin: LordHavoc)
|
||||||
{MP_DPMASTER, CVARFC("net_masterextra2", "dpmaster.deathmask.net:27950 107.161.23.68:27950 [2604:180::4ac:98c1]:27950", CVAR_NOSAVE, Net_Masterlist_Callback)}, //107.161.23.68 (admin: Willis)
|
{MP_DPMASTER, CVARFC("net_masterextra2", "dpmaster.deathmask.net:27950 107.161.23.68:27950 [2604:180::4ac:98c1]:27950", CVAR_NOSAVE, Net_Masterlist_Callback)}, //107.161.23.68 (admin: Willis)
|
||||||
{MP_DPMASTER, CVARFC("net_masterextra3", "dpmaster.tchr.no:27950 92.62.40.73:27950", CVAR_NOSAVE, Net_Masterlist_Callback)}, //92.62.40.73 (admin: tChr)
|
{MP_DPMASTER, CVARFC("net_masterextra3", "dpmaster.tchr.no:27950 92.62.40.73:27950", CVAR_NOSAVE, Net_Masterlist_Callback)}, //92.62.40.73 (admin: tChr)
|
||||||
|
|
||||||
|
@ -560,8 +560,8 @@ typedef int SOCKET;
|
||||||
|
|
||||||
//the number of servers should be limited only by memory.
|
//the number of servers should be limited only by memory.
|
||||||
|
|
||||||
cvar_t slist_cacheinfo = SCVAR("slist_cacheinfo", "0"); //this proves dangerous, memory wise.
|
cvar_t slist_cacheinfo = CVAR("slist_cacheinfo", "0"); //this proves dangerous, memory wise.
|
||||||
cvar_t slist_writeserverstxt = SCVAR("slist_writeservers", "0");
|
cvar_t slist_writeserverstxt = CVAR("slist_writeservers", "0");
|
||||||
|
|
||||||
void CL_MasterListParse(netadrtype_t adrtype, int type, qboolean slashpad);
|
void CL_MasterListParse(netadrtype_t adrtype, int type, qboolean slashpad);
|
||||||
int CL_ReadServerInfo(char *msg, enum masterprotocol_e prototype, qboolean favorite);
|
int CL_ReadServerInfo(char *msg, enum masterprotocol_e prototype, qboolean favorite);
|
||||||
|
@ -1904,6 +1904,7 @@ int Master_CheckPollSockets(void)
|
||||||
int users, maxusers;
|
int users, maxusers;
|
||||||
|
|
||||||
int control;
|
int control;
|
||||||
|
int ccrep;
|
||||||
|
|
||||||
MSG_BeginReading (msg_nullnetprim);
|
MSG_BeginReading (msg_nullnetprim);
|
||||||
control = BigLong(*((int *)net_message.data));
|
control = BigLong(*((int *)net_message.data));
|
||||||
|
@ -1915,23 +1916,94 @@ int Master_CheckPollSockets(void)
|
||||||
if ((control & NETFLAG_LENGTH_MASK) != ret)
|
if ((control & NETFLAG_LENGTH_MASK) != ret)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (MSG_ReadByte() != CCREP_SERVER_INFO)
|
ccrep = MSG_ReadByte();
|
||||||
continue;
|
|
||||||
|
|
||||||
/*this is an address string sent from the server. its not usable. if its replying to serverinfos, its possible to send it connect requests, while the address that it claims is 50% bugged*/
|
if (ccrep == CCREP_PLAYER_INFO)
|
||||||
MSG_ReadString();
|
|
||||||
|
|
||||||
Q_strncpyz(name, MSG_ReadString(), sizeof(name));
|
|
||||||
Q_strncpyz(map, MSG_ReadString(), sizeof(map));
|
|
||||||
users = MSG_ReadByte();
|
|
||||||
maxusers = MSG_ReadByte();
|
|
||||||
if (MSG_ReadByte() != NQ_NETCHAN_VERSION)
|
|
||||||
{
|
{
|
||||||
// Q_strcpy(name, "*");
|
serverinfo_t *selserver = selectedserver.inuse?Master_InfoForServer(&selectedserver.adr):NULL;
|
||||||
// Q_strcat(name, name);
|
serverinfo_t *info = Master_InfoForServer(&net_from);
|
||||||
}
|
info = Master_InfoForServer(&net_from);
|
||||||
|
if (selserver == info)
|
||||||
|
{
|
||||||
|
int playernum = MSG_ReadByte();
|
||||||
|
char *playername = MSG_ReadString();
|
||||||
|
int playercolor = MSG_ReadLong();
|
||||||
|
int playerfrags = MSG_ReadLong();
|
||||||
|
int secsonserver = MSG_ReadLong();
|
||||||
|
//char *playeraddr = MSG_ReadString();
|
||||||
|
if (msg_badread)
|
||||||
|
continue;
|
||||||
|
|
||||||
CL_ReadServerInfo(va("\\hostname\\%s\\map\\%s\\maxclients\\%i\\clients\\%i", name, map, maxusers, users), MP_NETQUAKE, false);
|
selectedserver.lastplayer = playernum+1;
|
||||||
|
|
||||||
|
memset(&info->moreinfo->players[playernum], 0, sizeof(info->moreinfo->players[playernum]));
|
||||||
|
info->moreinfo->players[playernum].userid = 0;
|
||||||
|
info->moreinfo->players[playernum].frags = playerfrags;
|
||||||
|
info->moreinfo->players[playernum].time = secsonserver;
|
||||||
|
info->moreinfo->players[playernum].ping = 0; //*sigh*
|
||||||
|
Q_strncpyz(info->moreinfo->players[playernum].name, playername, sizeof(info->moreinfo->players[playernum].name));
|
||||||
|
Q_strncpyz(info->moreinfo->players[playernum].skin, "", sizeof(info->moreinfo->players[playernum].skin));
|
||||||
|
Q_strncpyz(info->moreinfo->players[playernum].team, "", sizeof(info->moreinfo->players[playernum].team));
|
||||||
|
info->moreinfo->players[playernum].topc = playercolor>>4;
|
||||||
|
info->moreinfo->players[playernum].botc = playercolor&15;
|
||||||
|
info->moreinfo->players[playernum].isspec = false;
|
||||||
|
info->moreinfo->numplayers = max(info->moreinfo->numplayers, playernum+1);
|
||||||
|
|
||||||
|
//... and now try to query the next one... because everyone gives up after the first, right?... dude... I hate this shit.
|
||||||
|
SZ_Clear(&net_message);
|
||||||
|
MSG_WriteLong(&net_message, 0);// save space for the header, filled in later
|
||||||
|
MSG_WriteByte(&net_message, CCREQ_PLAYER_INFO);
|
||||||
|
MSG_WriteByte(&net_message, selectedserver.lastplayer);
|
||||||
|
*((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
|
||||||
|
NET_SendPollPacket(net_message.cursize, net_message.data, info->adr);
|
||||||
|
SZ_Clear(&net_message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (ccrep == CCREP_RULE_INFO)
|
||||||
|
{
|
||||||
|
serverinfo_t *selserver = selectedserver.inuse?Master_InfoForServer(&selectedserver.adr):NULL;
|
||||||
|
serverinfo_t *info = Master_InfoForServer(&net_from);
|
||||||
|
char *s, *old;
|
||||||
|
info = Master_InfoForServer(&net_from);
|
||||||
|
if (selserver == info)
|
||||||
|
{
|
||||||
|
s = MSG_ReadString();
|
||||||
|
if (msg_badread)
|
||||||
|
continue;
|
||||||
|
Q_strncpyz(selectedserver.lastrule, s, sizeof(selectedserver.lastrule));
|
||||||
|
s = MSG_ReadString();
|
||||||
|
|
||||||
|
old = Info_ValueForKey(info->moreinfo->info, selectedserver.lastrule);
|
||||||
|
if (strcmp(s, old))
|
||||||
|
Info_SetValueForStarKey(info->moreinfo->info, selectedserver.lastrule, s, sizeof(info->moreinfo->info));
|
||||||
|
|
||||||
|
//... and now try to query the next one... because everyone gives up after the first, right?... dude... I hate this shit.
|
||||||
|
SZ_Clear(&net_message);
|
||||||
|
MSG_WriteLong(&net_message, 0);// save space for the header, filled in later
|
||||||
|
MSG_WriteByte(&net_message, CCREQ_RULE_INFO);
|
||||||
|
MSG_WriteString(&net_message, selectedserver.lastrule);
|
||||||
|
*((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
|
||||||
|
NET_SendPollPacket(net_message.cursize, net_message.data, info->adr);
|
||||||
|
SZ_Clear(&net_message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (ccrep == CCREP_SERVER_INFO)
|
||||||
|
{
|
||||||
|
/*this is an address string sent from the server. its not usable. if its replying to serverinfos, its possible to send it connect requests, while the address that it claims is 50% bugged*/
|
||||||
|
MSG_ReadString();
|
||||||
|
|
||||||
|
Q_strncpyz(name, MSG_ReadString(), sizeof(name));
|
||||||
|
Q_strncpyz(map, MSG_ReadString(), sizeof(map));
|
||||||
|
users = MSG_ReadByte();
|
||||||
|
maxusers = MSG_ReadByte();
|
||||||
|
if (MSG_ReadByte() != NQ_NETCHAN_VERSION)
|
||||||
|
{
|
||||||
|
// Q_strcpy(name, "*");
|
||||||
|
// Q_strcat(name, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
CL_ReadServerInfo(va("\\hostname\\%s\\map\\%s\\maxclients\\%i\\clients\\%i", name, map, maxusers, users), MP_NETQUAKE, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
continue;
|
continue;
|
||||||
|
@ -1994,6 +2066,29 @@ void SListOptionChanged(serverinfo_t *newserver)
|
||||||
selectedserver.refreshtime = realtime+4;
|
selectedserver.refreshtime = realtime+4;
|
||||||
newserver->sends++;
|
newserver->sends++;
|
||||||
Master_QueryServer(newserver);
|
Master_QueryServer(newserver);
|
||||||
|
|
||||||
|
#ifdef NQPROT
|
||||||
|
selectedserver.lastplayer = 0;
|
||||||
|
*selectedserver.lastrule = 0;
|
||||||
|
if ((newserver->special&SS_PROTOCOLMASK) == SS_NETQUAKE)
|
||||||
|
{ //start spamming the server to get all of its details. silly protocols.
|
||||||
|
SZ_Clear(&net_message);
|
||||||
|
net_message.packing = SZ_RAWBYTES;
|
||||||
|
net_message.currentbit = 0;
|
||||||
|
MSG_WriteLong(&net_message, 0);// save space for the header, filled in later
|
||||||
|
MSG_WriteByte(&net_message, CCREQ_PLAYER_INFO);
|
||||||
|
MSG_WriteByte(&net_message, selectedserver.lastplayer);
|
||||||
|
*((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
|
||||||
|
NET_SendPollPacket(net_message.cursize, net_message.data, newserver->adr);
|
||||||
|
SZ_Clear(&net_message);
|
||||||
|
MSG_WriteLong(&net_message, 0);// save space for the header, filled in later
|
||||||
|
MSG_WriteByte(&net_message, CCREQ_RULE_INFO);
|
||||||
|
MSG_WriteString(&net_message, selectedserver.lastrule);
|
||||||
|
*((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
|
||||||
|
NET_SendPollPacket(net_message.cursize, net_message.data, newserver->adr);
|
||||||
|
SZ_Clear(&net_message);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2475,7 +2570,10 @@ void Master_QueryServer(serverinfo_t *server)
|
||||||
Q_snprintfz(data, sizeof(data), "%c%c%c%cgetstatus", 255, 255, 255, 255);
|
Q_snprintfz(data, sizeof(data), "%c%c%c%cgetstatus", 255, 255, 255, 255);
|
||||||
break;
|
break;
|
||||||
case SS_DARKPLACES:
|
case SS_DARKPLACES:
|
||||||
Q_snprintfz(data, sizeof(data), "%c%c%c%cgetinfo", 255, 255, 255, 255);
|
if (server->moreinfo)
|
||||||
|
Q_snprintfz(data, sizeof(data), "%c%c%c%cgetstatus", 255, 255, 255, 255);
|
||||||
|
else
|
||||||
|
Q_snprintfz(data, sizeof(data), "%c%c%c%cgetinfo", 255, 255, 255, 255);
|
||||||
break;
|
break;
|
||||||
#ifdef NQPROT
|
#ifdef NQPROT
|
||||||
case SS_NETQUAKE:
|
case SS_NETQUAKE:
|
||||||
|
@ -2841,8 +2939,6 @@ int CL_ReadServerInfo(char *msg, enum masterprotocol_e prototype, qboolean favor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MasterInfo_RemovePlayers(&info->adr);
|
|
||||||
|
|
||||||
name = Info_ValueForKey(msg, "hostname");
|
name = Info_ValueForKey(msg, "hostname");
|
||||||
if (!*name)
|
if (!*name)
|
||||||
name = Info_ValueForKey(msg, "sv_hostname");
|
name = Info_ValueForKey(msg, "sv_hostname");
|
||||||
|
@ -2939,178 +3035,189 @@ int CL_ReadServerInfo(char *msg, enum masterprotocol_e prototype, qboolean favor
|
||||||
strcpy(details.info, msg);
|
strcpy(details.info, msg);
|
||||||
msg = msg+strlen(msg)+1;
|
msg = msg+strlen(msg)+1;
|
||||||
|
|
||||||
info->players=details.numplayers = 0;
|
//clear player info. unless its an NQ server, which have some really annoying protocol to find out the players.
|
||||||
if (!strchr(msg, '\n'))
|
if ((info->special & SS_PROTOCOLMASK) == SS_NETQUAKE)
|
||||||
|
{
|
||||||
|
if (!info->moreinfo && ((slist_cacheinfo.value == 2 || NET_CompareAdr(&info->adr, &selectedserver.adr)) || (info->special & SS_KEEPINFO)))
|
||||||
|
info->moreinfo = Z_Malloc(sizeof(serverdetailedinfo_t));
|
||||||
info->numhumans = info->players = atoi(Info_ValueForKey(details.info, "clients"));
|
info->numhumans = info->players = atoi(Info_ValueForKey(details.info, "clients"));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int clnum;
|
MasterInfo_RemovePlayers(&info->adr);
|
||||||
|
info->players=details.numplayers = 0;
|
||||||
for (clnum=0; clnum < MAX_CLIENTS; clnum++)
|
if (!strchr(msg, '\n'))
|
||||||
|
info->numhumans = info->players = atoi(Info_ValueForKey(details.info, "clients"));
|
||||||
|
else
|
||||||
{
|
{
|
||||||
nl = strchr(msg, '\n');
|
int clnum;
|
||||||
if (!nl)
|
|
||||||
break;
|
|
||||||
*nl = '\0';
|
|
||||||
|
|
||||||
details.players[clnum].isspec = 0;
|
for (clnum=0; clnum < MAX_CLIENTS; clnum++)
|
||||||
details.players[clnum].team[0] = 0;
|
|
||||||
details.players[clnum].skin[0] = 0;
|
|
||||||
|
|
||||||
token = msg;
|
|
||||||
if (!token)
|
|
||||||
break;
|
|
||||||
details.players[clnum].userid = atoi(token);
|
|
||||||
token = strchr(token+1, ' ');
|
|
||||||
if (!token)
|
|
||||||
break;
|
|
||||||
details.players[clnum].frags = atoi(token);
|
|
||||||
token = strchr(token+1, ' ');
|
|
||||||
if (!token)
|
|
||||||
break;
|
|
||||||
details.players[clnum].time = atoi(token);
|
|
||||||
msg = token;
|
|
||||||
token = strchr(msg+1, ' ');
|
|
||||||
if (!token) //probably q2 response
|
|
||||||
{
|
{
|
||||||
//see if this is actually a Quake2 server.
|
nl = strchr(msg, '\n');
|
||||||
token = strchr(msg+1, '\"');
|
if (!nl)
|
||||||
if (!token) //it wasn't.
|
|
||||||
break;
|
break;
|
||||||
|
*nl = '\0';
|
||||||
|
|
||||||
details.players[clnum].ping = details.players[clnum].frags;
|
details.players[clnum].isspec = 0;
|
||||||
details.players[clnum].frags = details.players[clnum].userid;
|
details.players[clnum].team[0] = 0;
|
||||||
|
details.players[clnum].skin[0] = 0;
|
||||||
|
|
||||||
msg = strchr(token+1, '\"');
|
token = msg;
|
||||||
if (!msg)
|
|
||||||
break;
|
|
||||||
len = msg - token;
|
|
||||||
if (len >= sizeof(details.players[clnum].name))
|
|
||||||
len = sizeof(details.players[clnum].name);
|
|
||||||
Q_strncpyz(details.players[clnum].name, token+1, len);
|
|
||||||
|
|
||||||
details.players[clnum].skin[0] = '\0';
|
|
||||||
|
|
||||||
details.players[clnum].topc = 0;
|
|
||||||
details.players[clnum].botc = 0;
|
|
||||||
details.players[clnum].time = 0;
|
|
||||||
}
|
|
||||||
else //qw response
|
|
||||||
{
|
|
||||||
details.players[clnum].ping = atoi(token);
|
|
||||||
msg = token;
|
|
||||||
token = strchr(msg+1, ' ');
|
|
||||||
if (!token)
|
if (!token)
|
||||||
break;
|
break;
|
||||||
|
details.players[clnum].userid = atoi(token);
|
||||||
token = strchr(token+1, '\"');
|
|
||||||
if (!token)
|
|
||||||
break;
|
|
||||||
msg = strchr(token+1, '\"');
|
|
||||||
if (!msg)
|
|
||||||
break;
|
|
||||||
len = msg - token;
|
|
||||||
if (len >= sizeof(details.players[clnum].name))
|
|
||||||
len = sizeof(details.players[clnum].name);
|
|
||||||
if (!strncmp(token, "\"\\s\\", 4))
|
|
||||||
{
|
|
||||||
details.players[clnum].isspec |= 1;
|
|
||||||
Q_strncpyz(details.players[clnum].name, token+4, len-3);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
Q_strncpyz(details.players[clnum].name, token+1, len);
|
|
||||||
details.players[clnum].name[len] = '\0';
|
|
||||||
|
|
||||||
token = strchr(msg+1, '\"');
|
|
||||||
if (!token)
|
|
||||||
break;
|
|
||||||
msg = strchr(token+1, '\"');
|
|
||||||
if (!msg)
|
|
||||||
break;
|
|
||||||
len = msg - token;
|
|
||||||
if (len >= sizeof(details.players[clnum].skin))
|
|
||||||
len = sizeof(details.players[clnum].skin);
|
|
||||||
Q_strncpyz(details.players[clnum].skin, token+1, len);
|
|
||||||
details.players[clnum].skin[len] = '\0';
|
|
||||||
|
|
||||||
token = strchr(msg+1, ' ');
|
|
||||||
if (!token)
|
|
||||||
break;
|
|
||||||
details.players[clnum].topc = atoi(token);
|
|
||||||
token = strchr(token+1, ' ');
|
token = strchr(token+1, ' ');
|
||||||
if (!token)
|
if (!token)
|
||||||
break;
|
break;
|
||||||
details.players[clnum].botc = atoi(token);
|
details.players[clnum].frags = atoi(token);
|
||||||
|
token = strchr(token+1, ' ');
|
||||||
token = strchr(msg+1, '\"');
|
if (!token)
|
||||||
Q_strncpyz(details.players[clnum].team, "", sizeof(details.players[clnum].team));
|
break;
|
||||||
if (token)
|
details.players[clnum].time = atoi(token);
|
||||||
|
msg = token;
|
||||||
|
token = strchr(msg+1, ' ');
|
||||||
|
if (!token) //probably q2 response
|
||||||
{
|
{
|
||||||
|
//see if this is actually a Quake2 server.
|
||||||
|
token = strchr(msg+1, '\"');
|
||||||
|
if (!token) //it wasn't.
|
||||||
|
break;
|
||||||
|
|
||||||
|
details.players[clnum].ping = details.players[clnum].frags;
|
||||||
|
details.players[clnum].frags = details.players[clnum].userid;
|
||||||
|
|
||||||
msg = strchr(token+1, '\"');
|
msg = strchr(token+1, '\"');
|
||||||
if (msg)
|
if (!msg)
|
||||||
|
break;
|
||||||
|
len = msg - token;
|
||||||
|
if (len >= sizeof(details.players[clnum].name))
|
||||||
|
len = sizeof(details.players[clnum].name);
|
||||||
|
Q_strncpyz(details.players[clnum].name, token+1, len);
|
||||||
|
|
||||||
|
details.players[clnum].skin[0] = '\0';
|
||||||
|
|
||||||
|
details.players[clnum].topc = 0;
|
||||||
|
details.players[clnum].botc = 0;
|
||||||
|
details.players[clnum].time = 0;
|
||||||
|
}
|
||||||
|
else //qw response
|
||||||
|
{
|
||||||
|
details.players[clnum].ping = atoi(token);
|
||||||
|
msg = token;
|
||||||
|
token = strchr(msg+1, ' ');
|
||||||
|
if (!token)
|
||||||
|
break;
|
||||||
|
|
||||||
|
token = strchr(token+1, '\"');
|
||||||
|
if (!token)
|
||||||
|
break;
|
||||||
|
msg = strchr(token+1, '\"');
|
||||||
|
if (!msg)
|
||||||
|
break;
|
||||||
|
len = msg - token;
|
||||||
|
if (len >= sizeof(details.players[clnum].name))
|
||||||
|
len = sizeof(details.players[clnum].name);
|
||||||
|
if (!strncmp(token, "\"\\s\\", 4))
|
||||||
{
|
{
|
||||||
len = msg - token;
|
details.players[clnum].isspec |= 1;
|
||||||
if (len >= sizeof(details.players[clnum].team))
|
Q_strncpyz(details.players[clnum].name, token+4, len-3);
|
||||||
len = sizeof(details.players[clnum].team);
|
}
|
||||||
Q_strncpyz(details.players[clnum].team, token+1, len);
|
else
|
||||||
details.players[clnum].team[len] = '\0';
|
Q_strncpyz(details.players[clnum].name, token+1, len);
|
||||||
|
details.players[clnum].name[len] = '\0';
|
||||||
|
|
||||||
|
token = strchr(msg+1, '\"');
|
||||||
|
if (!token)
|
||||||
|
break;
|
||||||
|
msg = strchr(token+1, '\"');
|
||||||
|
if (!msg)
|
||||||
|
break;
|
||||||
|
len = msg - token;
|
||||||
|
if (len >= sizeof(details.players[clnum].skin))
|
||||||
|
len = sizeof(details.players[clnum].skin);
|
||||||
|
Q_strncpyz(details.players[clnum].skin, token+1, len);
|
||||||
|
details.players[clnum].skin[len] = '\0';
|
||||||
|
|
||||||
|
token = strchr(msg+1, ' ');
|
||||||
|
if (!token)
|
||||||
|
break;
|
||||||
|
details.players[clnum].topc = atoi(token);
|
||||||
|
token = strchr(token+1, ' ');
|
||||||
|
if (!token)
|
||||||
|
break;
|
||||||
|
details.players[clnum].botc = atoi(token);
|
||||||
|
|
||||||
|
token = strchr(msg+1, '\"');
|
||||||
|
Q_strncpyz(details.players[clnum].team, "", sizeof(details.players[clnum].team));
|
||||||
|
if (token)
|
||||||
|
{
|
||||||
|
msg = strchr(token+1, '\"');
|
||||||
|
if (msg)
|
||||||
|
{
|
||||||
|
len = msg - token;
|
||||||
|
if (len >= sizeof(details.players[clnum].team))
|
||||||
|
len = sizeof(details.players[clnum].team);
|
||||||
|
Q_strncpyz(details.players[clnum].team, token+1, len);
|
||||||
|
details.players[clnum].team[len] = '\0';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
MasterInfo_AddPlayer(&info->adr, details.players[clnum].name, details.players[clnum].ping, details.players[clnum].frags, details.players[clnum].topc*4 | details.players[clnum].botc, details.players[clnum].skin, details.players[clnum].team);
|
MasterInfo_AddPlayer(&info->adr, details.players[clnum].name, details.players[clnum].ping, details.players[clnum].frags, details.players[clnum].topc*4 | details.players[clnum].botc, details.players[clnum].skin, details.players[clnum].team);
|
||||||
|
|
||||||
//WallFly is some q2 bot
|
//WallFly is some q2 bot
|
||||||
//[ServeMe] is some qw bot
|
//[ServeMe] is some qw bot
|
||||||
if (!strncmp(details.players[clnum].name, "WallFly", 7) || !strcmp(details.players[clnum].name, "[ServeMe]"))
|
if (!strncmp(details.players[clnum].name, "WallFly", 7) || !strcmp(details.players[clnum].name, "[ServeMe]"))
|
||||||
{
|
|
||||||
//not players nor real people. they don't count towards any metric
|
|
||||||
details.players[clnum].isspec |= 3;
|
|
||||||
}
|
|
||||||
//807 excludes the numerous bot names on some annoying qwtf server
|
|
||||||
//BOT: excludes fte's botclients (which always have a bot: prefix)
|
|
||||||
else if (details.players[clnum].ping == 807 || !strncmp(details.players[clnum].name, "BOT:", 4))
|
|
||||||
{
|
|
||||||
info->numbots++;
|
|
||||||
details.players[clnum].isspec |= 2;
|
|
||||||
}
|
|
||||||
else if (details.players[clnum].isspec & 1)
|
|
||||||
{
|
|
||||||
info->numspectators++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
info->numhumans++;
|
|
||||||
|
|
||||||
for (k = clnum, j = clnum-1; j >= 0; j--)
|
|
||||||
{
|
|
||||||
if ((details.players[k].isspec != details.players[j].isspec && !details.players[k].isspec) ||
|
|
||||||
details.players[k].frags > details.players[j].frags)
|
|
||||||
{
|
{
|
||||||
struct serverdetailedplayerinfo_s t = details.players[j];
|
//not players nor real people. they don't count towards any metric
|
||||||
details.players[j] = details.players[k];
|
details.players[clnum].isspec |= 3;
|
||||||
details.players[k] = t;
|
}
|
||||||
k = j;
|
//807 excludes the numerous bot names on some annoying qwtf server
|
||||||
|
//BOT: excludes fte's botclients (which always have a bot: prefix)
|
||||||
|
else if (details.players[clnum].ping == 807 || !strncmp(details.players[clnum].name, "BOT:", 4))
|
||||||
|
{
|
||||||
|
info->numbots++;
|
||||||
|
details.players[clnum].isspec |= 2;
|
||||||
|
}
|
||||||
|
else if (details.players[clnum].isspec & 1)
|
||||||
|
{
|
||||||
|
info->numspectators++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
break;
|
info->numhumans++;
|
||||||
|
|
||||||
|
for (k = clnum, j = clnum-1; j >= 0; j--)
|
||||||
|
{
|
||||||
|
if ((details.players[k].isspec != details.players[j].isspec && !details.players[k].isspec) ||
|
||||||
|
details.players[k].frags > details.players[j].frags)
|
||||||
|
{
|
||||||
|
struct serverdetailedplayerinfo_s t = details.players[j];
|
||||||
|
details.players[j] = details.players[k];
|
||||||
|
details.players[k] = t;
|
||||||
|
k = j;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
details.numplayers++;
|
||||||
|
|
||||||
|
info->players++;
|
||||||
|
|
||||||
|
msg = nl;
|
||||||
|
if (!msg)
|
||||||
|
break; //erm...
|
||||||
|
msg++;
|
||||||
}
|
}
|
||||||
details.numplayers++;
|
|
||||||
|
|
||||||
info->players++;
|
|
||||||
|
|
||||||
msg = nl;
|
|
||||||
if (!msg)
|
|
||||||
break; //erm...
|
|
||||||
msg++;
|
|
||||||
}
|
}
|
||||||
}
|
if (!info->moreinfo && ((slist_cacheinfo.value == 2 || NET_CompareAdr(&info->adr, &selectedserver.adr)) || (info->special & SS_KEEPINFO)))
|
||||||
if (!info->moreinfo && ((slist_cacheinfo.value == 2 || NET_CompareAdr(&info->adr, &selectedserver.adr)) || (info->special & SS_KEEPINFO)))
|
info->moreinfo = Z_Malloc(sizeof(serverdetailedinfo_t));
|
||||||
info->moreinfo = Z_Malloc(sizeof(serverdetailedinfo_t));
|
if (NET_CompareAdr(&info->adr, &selectedserver.adr))
|
||||||
if (NET_CompareAdr(&info->adr, &selectedserver.adr))
|
selectedserver.detail = info->moreinfo;
|
||||||
selectedserver.detail = info->moreinfo;
|
|
||||||
|
|
||||||
if (info->moreinfo)
|
if (info->moreinfo)
|
||||||
memcpy(info->moreinfo, &details, sizeof(serverdetailedinfo_t));
|
memcpy(info->moreinfo, &details, sizeof(serverdetailedinfo_t));
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1182,8 +1182,8 @@ int menuentsize;
|
||||||
|
|
||||||
// cvars
|
// cvars
|
||||||
#define MENUPROGSGROUP "Menu progs control"
|
#define MENUPROGSGROUP "Menu progs control"
|
||||||
cvar_t forceqmenu = SCVAR("forceqmenu", "0");
|
cvar_t forceqmenu = CVAR("forceqmenu", "0");
|
||||||
cvar_t pr_menuqc_coreonerror = SCVAR("pr_menuqc_coreonerror", "1");
|
cvar_t pr_menuqc_coreonerror = CVAR("pr_menuqc_coreonerror", "1");
|
||||||
|
|
||||||
|
|
||||||
//new generic functions.
|
//new generic functions.
|
||||||
|
|
|
@ -627,6 +627,13 @@ cvar_t r_part_maxdecals = CVAR("r_part_maxdecals", "8192");
|
||||||
|
|
||||||
particleengine_t *pe;
|
particleengine_t *pe;
|
||||||
|
|
||||||
|
static struct partalias_s
|
||||||
|
{
|
||||||
|
struct partalias_s *next;
|
||||||
|
const char *from;
|
||||||
|
const char *to;
|
||||||
|
} *partaliaslist;
|
||||||
|
|
||||||
void P_ParticleEffect_f(void);
|
void P_ParticleEffect_f(void);
|
||||||
static void P_ParticleEffectAlias_f(void);
|
static void P_ParticleEffectAlias_f(void);
|
||||||
|
|
||||||
|
@ -673,12 +680,18 @@ void P_InitParticleSystem(void)
|
||||||
R_Clutter_Init();
|
R_Clutter_Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct partalias_s
|
void P_ShutdownParticleSystem(void)
|
||||||
{
|
{
|
||||||
struct partalias_s *next;
|
struct partalias_s *l;
|
||||||
const char *from;
|
|
||||||
const char *to;
|
while (partaliaslist)
|
||||||
} *partaliaslist;
|
{
|
||||||
|
l = partaliaslist;
|
||||||
|
partaliaslist = l->next;
|
||||||
|
Z_Free(l);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void P_ParticleEffectAlias_f(void)
|
static void P_ParticleEffectAlias_f(void)
|
||||||
{
|
{
|
||||||
struct partalias_s **link, *l;
|
struct partalias_s **link, *l;
|
||||||
|
|
|
@ -87,46 +87,48 @@ extern cvar_t r_forceprogramify;
|
||||||
cvar_t mod_md3flags = CVARD ("mod_md3flags", "1", "The flags field of md3s was never officially defined. If this is set to 1, the flags will be treated identically to mdl files. Otherwise they will be ignored. Naturally, this is required to provide rotating pickups in quake.");
|
cvar_t mod_md3flags = CVARD ("mod_md3flags", "1", "The flags field of md3s was never officially defined. If this is set to 1, the flags will be treated identically to mdl files. Otherwise they will be ignored. Naturally, this is required to provide rotating pickups in quake.");
|
||||||
|
|
||||||
cvar_t r_ambient = CVARF ("r_ambient", "0",
|
cvar_t r_ambient = CVARF ("r_ambient", "0",
|
||||||
CVAR_CHEAT);
|
CVAR_CHEAT);
|
||||||
cvar_t r_bloodstains = CVARF ("r_bloodstains", "1", CVAR_ARCHIVE);
|
cvar_t r_bloodstains = CVARF ("r_bloodstains", "1", CVAR_ARCHIVE);
|
||||||
cvar_t r_bouncysparks = CVARFD ("r_bouncysparks", "1",
|
cvar_t r_bouncysparks = CVARFD ("r_bouncysparks", "1",
|
||||||
CVAR_ARCHIVE,
|
CVAR_ARCHIVE,
|
||||||
"Enables particle interaction with world surfaces, allowing for bouncy particles, stains, and decals.");
|
"Enables particle interaction with world surfaces, allowing for bouncy particles, stains, and decals.");
|
||||||
cvar_t r_drawentities = CVAR ("r_drawentities", "1");
|
cvar_t r_drawentities = CVAR ("r_drawentities", "1");
|
||||||
cvar_t r_drawflat = CVARAF ("r_drawflat", "0", "gl_textureless",
|
cvar_t r_drawflat = CVARAF ("r_drawflat", "0", "gl_textureless",
|
||||||
CVAR_ARCHIVE | CVAR_SEMICHEAT | CVAR_RENDERERCALLBACK | CVAR_SHADERSYSTEM);
|
CVAR_ARCHIVE | CVAR_SEMICHEAT | CVAR_RENDERERCALLBACK | CVAR_SHADERSYSTEM);
|
||||||
|
cvar_t r_lightmap = CVARF ("r_lightmap", "0",
|
||||||
|
CVAR_ARCHIVE | CVAR_SEMICHEAT | CVAR_RENDERERCALLBACK | CVAR_SHADERSYSTEM);
|
||||||
cvar_t r_wireframe = CVARFD ("r_wireframe", "0",
|
cvar_t r_wireframe = CVARFD ("r_wireframe", "0",
|
||||||
CVAR_CHEAT, "Developer feature where everything is drawn with wireframe over the top. Only active where cheats are permitted.");
|
CVAR_CHEAT, "Developer feature where everything is drawn with wireframe over the top. Only active where cheats are permitted.");
|
||||||
cvar_t r_wireframe_smooth = CVAR ("r_wireframe_smooth", "0");
|
cvar_t r_wireframe_smooth = CVAR ("r_wireframe_smooth", "0");
|
||||||
cvar_t r_refract_fbo = CVARD ("r_refract_fbo", "1", "Use an fbo for refraction. If 0, just renders as a portal and uses a copy of the current framebuffer.");
|
cvar_t r_refract_fbo = CVARD ("r_refract_fbo", "1", "Use an fbo for refraction. If 0, just renders as a portal and uses a copy of the current framebuffer.");
|
||||||
cvar_t gl_miptexLevel = CVAR ("gl_miptexLevel", "0");
|
cvar_t gl_miptexLevel = CVAR ("gl_miptexLevel", "0");
|
||||||
cvar_t r_drawviewmodel = CVARF ("r_drawviewmodel", "1", CVAR_ARCHIVE);
|
cvar_t r_drawviewmodel = CVARF ("r_drawviewmodel", "1", CVAR_ARCHIVE);
|
||||||
cvar_t r_drawviewmodelinvis = CVAR ("r_drawviewmodelinvis", "0");
|
cvar_t r_drawviewmodelinvis = CVAR ("r_drawviewmodelinvis", "0");
|
||||||
cvar_t r_dynamic = CVARF ("r_dynamic", IFMINIMAL("0","1"),
|
cvar_t r_dynamic = CVARF ("r_dynamic", IFMINIMAL("0","1"),
|
||||||
CVAR_ARCHIVE);
|
CVAR_ARCHIVE);
|
||||||
cvar_t r_fastturb = CVARF ("r_fastturb", "0",
|
cvar_t r_fastturb = CVARF ("r_fastturb", "0",
|
||||||
CVAR_SHADERSYSTEM);
|
CVAR_SHADERSYSTEM);
|
||||||
cvar_t r_fastsky = CVARF ("r_fastsky", "0",
|
cvar_t r_fastsky = CVARF ("r_fastsky", "0",
|
||||||
CVAR_ARCHIVE | CVAR_SHADERSYSTEM);
|
CVAR_ARCHIVE | CVAR_SHADERSYSTEM);
|
||||||
cvar_t r_fastskycolour = CVARF ("r_fastskycolour", "0",
|
cvar_t r_fastskycolour = CVARF ("r_fastskycolour", "0",
|
||||||
CVAR_RENDERERCALLBACK|CVAR_SHADERSYSTEM);
|
CVAR_RENDERERCALLBACK|CVAR_SHADERSYSTEM);
|
||||||
cvar_t r_fb_bmodels = CVARAF("r_fb_bmodels", "1",
|
cvar_t r_fb_bmodels = CVARAF("r_fb_bmodels", "1",
|
||||||
"gl_fb_bmodels", CVAR_SEMICHEAT|CVAR_RENDERERLATCH);
|
"gl_fb_bmodels", CVAR_SEMICHEAT|CVAR_RENDERERLATCH);
|
||||||
cvar_t r_fb_models = CVARAFD ("r_fb_models", "1",
|
cvar_t r_fb_models = CVARAFD ("r_fb_models", "1",
|
||||||
"gl_fb_models", CVAR_SEMICHEAT, "Force all non-player models to be fullbright in deathmatch. Because if you don't enable these cheats then you'll go splat because everone else uses them. QuakeWorld players suck.");
|
"gl_fb_models", CVAR_SEMICHEAT, "Force all non-player models to be fullbright in deathmatch. Because if you don't enable these cheats then you'll go splat because everone else uses them. QuakeWorld players suck.");
|
||||||
cvar_t r_skin_overlays = SCVARF ("r_skin_overlays", "1",
|
cvar_t r_skin_overlays = CVARF ("r_skin_overlays", "1",
|
||||||
CVAR_SEMICHEAT|CVAR_RENDERERLATCH);
|
CVAR_SEMICHEAT|CVAR_RENDERERLATCH);
|
||||||
cvar_t r_globalskin_first = CVARFD ("r_globalskin_first", "100", CVAR_RENDERERLATCH, "Specifies the first .skin value that is a global skin. Entities within this range will use the shader/image called 'gfx/skinSKIN.lmp' instead of their regular skin. See also: r_globalskin_count.");
|
cvar_t r_globalskin_first = CVARFD ("r_globalskin_first", "100", CVAR_RENDERERLATCH, "Specifies the first .skin value that is a global skin. Entities within this range will use the shader/image called 'gfx/skinSKIN.lmp' instead of their regular skin. See also: r_globalskin_count.");
|
||||||
cvar_t r_globalskin_count = CVARFD ("r_globalskin_count", "10", CVAR_RENDERERLATCH, "Specifies how many globalskins there are.");
|
cvar_t r_globalskin_count = CVARFD ("r_globalskin_count", "10", CVAR_RENDERERLATCH, "Specifies how many globalskins there are.");
|
||||||
cvar_t r_coronas = CVARFD ("r_coronas", "0", CVAR_ARCHIVE, "Draw coronas on realtime lights. Overrides glquake-esque flashblends.");
|
cvar_t r_coronas = CVARFD ("r_coronas", "0", CVAR_ARCHIVE, "Draw coronas on realtime lights. Overrides glquake-esque flashblends.");
|
||||||
cvar_t r_coronas_occlusion = CVARFD ("r_coronas_occlusion", "", CVAR_ARCHIVE, "Specifies that coronas should be occluded more carefully.\n0: No occlusion, at all.\n1: BSP occlusion only (simple tracelines).\n2: non-bsp occlusion also (complex tracelines).\n3: Depthbuffer reads (forces synchronisation).\n4: occlusion queries.");
|
cvar_t r_coronas_occlusion = CVARFD ("r_coronas_occlusion", "", CVAR_ARCHIVE, "Specifies that coronas should be occluded more carefully.\n0: No occlusion, at all.\n1: BSP occlusion only (simple tracelines).\n2: non-bsp occlusion also (complex tracelines).\n3: Depthbuffer reads (forces synchronisation).\n4: occlusion queries.");
|
||||||
cvar_t r_coronas_mindist = CVARFD ("r_coronas_mindist", "128", CVAR_ARCHIVE, "Coronas closer than this will be invisible, preventing near clip plane issues.");
|
cvar_t r_coronas_mindist = CVARFD ("r_coronas_mindist", "128", CVAR_ARCHIVE, "Coronas closer than this will be invisible, preventing near clip plane issues.");
|
||||||
cvar_t r_coronas_fadedist = CVARFD ("r_coronas_fadedist", "256", CVAR_ARCHIVE, "Coronas will fade out over this distance.");
|
cvar_t r_coronas_fadedist = CVARFD ("r_coronas_fadedist", "256", CVAR_ARCHIVE, "Coronas will fade out over this distance.");
|
||||||
|
|
||||||
cvar_t r_flashblend = SCVARF ("gl_flashblend", "0",
|
cvar_t r_flashblend = CVARF ("gl_flashblend", "0",
|
||||||
CVAR_ARCHIVE);
|
CVAR_ARCHIVE);
|
||||||
cvar_t r_flashblendscale = SCVARF ("gl_flashblendscale", "0.35",
|
cvar_t r_flashblendscale = CVARF ("gl_flashblendscale", "0.35",
|
||||||
CVAR_ARCHIVE);
|
CVAR_ARCHIVE);
|
||||||
cvar_t r_floorcolour = CVARAF ("r_floorcolour", "64 64 128",
|
cvar_t r_floorcolour = CVARAF ("r_floorcolour", "64 64 128",
|
||||||
"r_floorcolor", CVAR_RENDERERCALLBACK|CVAR_SHADERSYSTEM);
|
"r_floorcolor", CVAR_RENDERERCALLBACK|CVAR_SHADERSYSTEM);
|
||||||
//cvar_t r_floortexture = SCVARF ("r_floortexture", "",
|
//cvar_t r_floortexture = SCVARF ("r_floortexture", "",
|
||||||
|
@ -135,11 +137,11 @@ cvar_t r_fullbright = CVARFD ("r_fullbright", "0",
|
||||||
CVAR_CHEAT|CVAR_SHADERSYSTEM, "Ignore world lightmaps, drawing everything fully lit.");
|
CVAR_CHEAT|CVAR_SHADERSYSTEM, "Ignore world lightmaps, drawing everything fully lit.");
|
||||||
cvar_t r_fullbrightSkins = CVARF ("r_fullbrightSkins", "0.8", /*don't default to 1, as it looks a little ugly (too bright), but don't default to 0 either because then you're handicapped in the dark*/
|
cvar_t r_fullbrightSkins = CVARF ("r_fullbrightSkins", "0.8", /*don't default to 1, as it looks a little ugly (too bright), but don't default to 0 either because then you're handicapped in the dark*/
|
||||||
CVAR_SEMICHEAT|CVAR_SHADERSYSTEM);
|
CVAR_SEMICHEAT|CVAR_SHADERSYSTEM);
|
||||||
cvar_t r_lightmap_saturation = SCVAR ("r_lightmap_saturation", "1");
|
cvar_t r_lightmap_saturation = CVAR ("r_lightmap_saturation", "1");
|
||||||
cvar_t r_lightstylesmooth = CVARF ("r_lightstylesmooth", "0", CVAR_ARCHIVE);
|
cvar_t r_lightstylesmooth = CVARF ("r_lightstylesmooth", "0", CVAR_ARCHIVE);
|
||||||
cvar_t r_lightstylesmooth_limit = SCVAR ("r_lightstylesmooth_limit", "2");
|
cvar_t r_lightstylesmooth_limit = CVAR ("r_lightstylesmooth_limit", "2");
|
||||||
cvar_t r_lightstylespeed = SCVAR ("r_lightstylespeed", "10");
|
cvar_t r_lightstylespeed = CVAR ("r_lightstylespeed", "10");
|
||||||
cvar_t r_lightstylescale = SCVAR ("r_lightstylescale", "1");
|
cvar_t r_lightstylescale = CVAR ("r_lightstylescale", "1");
|
||||||
cvar_t r_hdr_irisadaptation = CVARF ("r_hdr_irisadaptation", "0", CVAR_ARCHIVE);
|
cvar_t r_hdr_irisadaptation = CVARF ("r_hdr_irisadaptation", "0", CVAR_ARCHIVE);
|
||||||
cvar_t r_hdr_irisadaptation_multiplier = CVAR ("r_hdr_irisadaptation_multiplier", "2");
|
cvar_t r_hdr_irisadaptation_multiplier = CVAR ("r_hdr_irisadaptation_multiplier", "2");
|
||||||
cvar_t r_hdr_irisadaptation_minvalue = CVAR ("r_hdr_irisadaptation_minvalue", "0.5");
|
cvar_t r_hdr_irisadaptation_minvalue = CVAR ("r_hdr_irisadaptation_minvalue", "0.5");
|
||||||
|
@ -162,9 +164,9 @@ cvar_t r_skyboxname = CVARFC ("r_skybox", "",
|
||||||
CVAR_RENDERERCALLBACK | CVAR_SHADERSYSTEM, R_SkyBox_Changed);
|
CVAR_RENDERERCALLBACK | CVAR_SHADERSYSTEM, R_SkyBox_Changed);
|
||||||
cvar_t r_softwarebanding_cvar = CVARFD ("r_softwarebanding", "0", CVAR_SHADERSYSTEM, "Utilise the Quake colormap in order to emulate 8bit software rendering. This results in banding as well as other artifacts that some believe adds character. Also forces nearest sampling on affected surfaces (palette indicies do not interpolate well).");
|
cvar_t r_softwarebanding_cvar = CVARFD ("r_softwarebanding", "0", CVAR_SHADERSYSTEM, "Utilise the Quake colormap in order to emulate 8bit software rendering. This results in banding as well as other artifacts that some believe adds character. Also forces nearest sampling on affected surfaces (palette indicies do not interpolate well).");
|
||||||
qboolean r_softwarebanding;
|
qboolean r_softwarebanding;
|
||||||
cvar_t r_speeds = SCVAR ("r_speeds", "0");
|
cvar_t r_speeds = CVAR ("r_speeds", "0");
|
||||||
cvar_t r_stainfadeammount = SCVAR ("r_stainfadeammount", "1");
|
cvar_t r_stainfadeammount = CVAR ("r_stainfadeammount", "1");
|
||||||
cvar_t r_stainfadetime = SCVAR ("r_stainfadetime", "1");
|
cvar_t r_stainfadetime = CVAR ("r_stainfadetime", "1");
|
||||||
cvar_t r_stains = CVARFC("r_stains", IFMINIMAL("0","0.75"),
|
cvar_t r_stains = CVARFC("r_stains", IFMINIMAL("0","0.75"),
|
||||||
CVAR_ARCHIVE,
|
CVAR_ARCHIVE,
|
||||||
Cvar_Limiter_ZeroToOne_Callback);
|
Cvar_Limiter_ZeroToOne_Callback);
|
||||||
|
@ -207,13 +209,13 @@ cvar_t scr_conspeed = CVAR ("scr_conspeed", "2000");
|
||||||
cvar_t scr_fov = CVARFDC("fov", "90",
|
cvar_t scr_fov = CVARFDC("fov", "90",
|
||||||
CVAR_ARCHIVE, "field of vision, 1-170 degrees, standard fov is 90, nquake defaults to 108.",
|
CVAR_ARCHIVE, "field of vision, 1-170 degrees, standard fov is 90, nquake defaults to 108.",
|
||||||
SCR_Fov_Callback);
|
SCR_Fov_Callback);
|
||||||
cvar_t scr_printspeed = SCVAR ("scr_printspeed", "16");
|
cvar_t scr_printspeed = CVAR ("scr_printspeed", "16");
|
||||||
cvar_t scr_showpause = SCVAR ("showpause", "1");
|
cvar_t scr_showpause = CVAR ("showpause", "1");
|
||||||
cvar_t scr_showturtle = SCVAR ("showturtle", "0");
|
cvar_t scr_showturtle = CVAR ("showturtle", "0");
|
||||||
cvar_t scr_turtlefps = SCVAR ("scr_turtlefps", "10");
|
cvar_t scr_turtlefps = CVAR ("scr_turtlefps", "10");
|
||||||
cvar_t scr_sshot_compression = SCVAR ("scr_sshot_compression", "75");
|
cvar_t scr_sshot_compression = CVAR ("scr_sshot_compression", "75");
|
||||||
cvar_t scr_sshot_type = SCVAR ("scr_sshot_type", "png");
|
cvar_t scr_sshot_type = CVAR ("scr_sshot_type", "png");
|
||||||
cvar_t scr_sshot_prefix = SCVAR ("scr_sshot_prefix", "screenshots/fte-");
|
cvar_t scr_sshot_prefix = CVAR ("scr_sshot_prefix", "screenshots/fte-");
|
||||||
cvar_t scr_viewsize = CVARFC("viewsize", "100",
|
cvar_t scr_viewsize = CVARFC("viewsize", "100",
|
||||||
CVAR_ARCHIVE,
|
CVAR_ARCHIVE,
|
||||||
SCR_Viewsize_Callback);
|
SCR_Viewsize_Callback);
|
||||||
|
@ -278,7 +280,7 @@ extern cvar_t r_drawworld;
|
||||||
extern cvar_t r_fullbright;
|
extern cvar_t r_fullbright;
|
||||||
cvar_t r_mirroralpha = CVARFD("r_mirroralpha","1", CVAR_CHEAT|CVAR_SHADERSYSTEM, "Specifies how the default shader is generated for the 'window02_1' texture. Values less than 1 will turn it into a mirror.");
|
cvar_t r_mirroralpha = CVARFD("r_mirroralpha","1", CVAR_CHEAT|CVAR_SHADERSYSTEM, "Specifies how the default shader is generated for the 'window02_1' texture. Values less than 1 will turn it into a mirror.");
|
||||||
extern cvar_t r_netgraph;
|
extern cvar_t r_netgraph;
|
||||||
cvar_t r_norefresh = SCVAR("r_norefresh","0");
|
cvar_t r_norefresh = CVAR("r_norefresh","0");
|
||||||
extern cvar_t r_novis;
|
extern cvar_t r_novis;
|
||||||
extern cvar_t r_speeds;
|
extern cvar_t r_speeds;
|
||||||
extern cvar_t r_waterwarp;
|
extern cvar_t r_waterwarp;
|
||||||
|
@ -341,7 +343,7 @@ cvar_t gl_lateswap = CVAR ("gl_lateswap", "0");
|
||||||
cvar_t gl_lerpimages = CVARFD ("gl_lerpimages", "1", CVAR_ARCHIVE, "Enables smoother resampling for images which are not power-of-two, when the drivers do not support non-power-of-two textures.");
|
cvar_t gl_lerpimages = CVARFD ("gl_lerpimages", "1", CVAR_ARCHIVE, "Enables smoother resampling for images which are not power-of-two, when the drivers do not support non-power-of-two textures.");
|
||||||
//cvar_t gl_lightmapmode = SCVARF("gl_lightmapmode", "",
|
//cvar_t gl_lightmapmode = SCVARF("gl_lightmapmode", "",
|
||||||
// CVAR_ARCHIVE);
|
// CVAR_ARCHIVE);
|
||||||
cvar_t gl_load24bit = SCVARF ("gl_load24bit", "1",
|
cvar_t gl_load24bit = CVARF ("gl_load24bit", "1",
|
||||||
CVAR_ARCHIVE);
|
CVAR_ARCHIVE);
|
||||||
|
|
||||||
cvar_t r_clear = CVARAF("r_clear","0",
|
cvar_t r_clear = CVARAF("r_clear","0",
|
||||||
|
@ -353,13 +355,13 @@ cvar_t gl_menutint_shader = CVARD ("gl_menutint_shader", "1", "Controls the
|
||||||
cvar_t gl_mindist = CVARAD ("gl_mindist", "1", "r_nearclip",
|
cvar_t gl_mindist = CVARAD ("gl_mindist", "1", "r_nearclip",
|
||||||
"Distance to the near clip plane. Smaller values may damage depth precision, high values can potentialy be used to see through walls...");
|
"Distance to the near clip plane. Smaller values may damage depth precision, high values can potentialy be used to see through walls...");
|
||||||
|
|
||||||
cvar_t gl_motionblur = SCVARF ("gl_motionblur", "0",
|
cvar_t gl_motionblur = CVARF ("gl_motionblur", "0",
|
||||||
CVAR_ARCHIVE);
|
CVAR_ARCHIVE);
|
||||||
cvar_t gl_motionblurscale = SCVAR ("gl_motionblurscale", "1");
|
cvar_t gl_motionblurscale = CVAR ("gl_motionblurscale", "1");
|
||||||
cvar_t gl_overbright = CVARFC ("gl_overbright", "1",
|
cvar_t gl_overbright = CVARFC ("gl_overbright", "1",
|
||||||
CVAR_ARCHIVE,
|
CVAR_ARCHIVE,
|
||||||
Surf_RebuildLightmap_Callback);
|
Surf_RebuildLightmap_Callback);
|
||||||
cvar_t gl_overbright_all = SCVARF ("gl_overbright_all", "0",
|
cvar_t gl_overbright_all = CVARF ("gl_overbright_all", "0",
|
||||||
CVAR_ARCHIVE);
|
CVAR_ARCHIVE);
|
||||||
cvar_t gl_picmip = CVARFD ("gl_picmip", "0", CVAR_ARCHIVE, "Reduce world/model texture sizes by some exponential factor.");
|
cvar_t gl_picmip = CVARFD ("gl_picmip", "0", CVAR_ARCHIVE, "Reduce world/model texture sizes by some exponential factor.");
|
||||||
cvar_t gl_picmip2d = CVARFD ("gl_picmip2d", "0", CVAR_ARCHIVE, "Reduce hud/menu texture sizes by some exponential factor.");
|
cvar_t gl_picmip2d = CVARFD ("gl_picmip2d", "0", CVAR_ARCHIVE, "Reduce hud/menu texture sizes by some exponential factor.");
|
||||||
|
@ -367,7 +369,7 @@ cvar_t gl_nohwblend = CVARD ("gl_nohwblend","1", "If 1, don't use hardwar
|
||||||
cvar_t gl_savecompressedtex = CVARD ("gl_savecompressedtex", "0", "Write out a copy of textures in a compressed format. The driver will do the compression on the fly, thus this setting is likely inferior to software which does not care so much about compression times.");
|
cvar_t gl_savecompressedtex = CVARD ("gl_savecompressedtex", "0", "Write out a copy of textures in a compressed format. The driver will do the compression on the fly, thus this setting is likely inferior to software which does not care so much about compression times.");
|
||||||
//cvar_t gl_schematics = CVARD ("gl_schematics", "0", "Gimmick rendering mode that draws the length of various world edges.");
|
//cvar_t gl_schematics = CVARD ("gl_schematics", "0", "Gimmick rendering mode that draws the length of various world edges.");
|
||||||
cvar_t gl_skyboxdist = CVARD ("gl_skyboxdist", "0", "The distance of the skybox. If 0, the engine will determine it based upon the far clip plane distance."); //0 = guess.
|
cvar_t gl_skyboxdist = CVARD ("gl_skyboxdist", "0", "The distance of the skybox. If 0, the engine will determine it based upon the far clip plane distance."); //0 = guess.
|
||||||
cvar_t gl_smoothcrosshair = SCVAR ("gl_smoothcrosshair", "1");
|
cvar_t gl_smoothcrosshair = CVAR ("gl_smoothcrosshair", "1");
|
||||||
cvar_t gl_maxdist = CVARD ("gl_maxdist", "0", "The distance of the far clip plane. If set to 0, some fancy maths will be used to place it at an infinite distance.");
|
cvar_t gl_maxdist = CVARD ("gl_maxdist", "0", "The distance of the far clip plane. If set to 0, some fancy maths will be used to place it at an infinite distance.");
|
||||||
|
|
||||||
#ifdef SPECULAR
|
#ifdef SPECULAR
|
||||||
|
@ -395,8 +397,8 @@ cvar_t vid_triplebuffer = CVARAFD ("vid_triplebuffer", "1", "gl_triplebuffe
|
||||||
cvar_t r_portalrecursion = CVARD ("r_portalrecursion", "1", "The number of portals the camera is allowed to recurse through.");
|
cvar_t r_portalrecursion = CVARD ("r_portalrecursion", "1", "The number of portals the camera is allowed to recurse through.");
|
||||||
cvar_t r_portaldrawplanes = CVARD ("r_portaldrawplanes", "0", "Draw front and back planes in portals. Debug feature.");
|
cvar_t r_portaldrawplanes = CVARD ("r_portaldrawplanes", "0", "Draw front and back planes in portals. Debug feature.");
|
||||||
cvar_t r_portalonly = CVARD ("r_portalonly", "0", "Don't draw things which are not portals. Debug feature.");
|
cvar_t r_portalonly = CVARD ("r_portalonly", "0", "Don't draw things which are not portals. Debug feature.");
|
||||||
cvar_t dpcompat_psa_ungroup = SCVAR ("dpcompat_psa_ungroup", "0");
|
cvar_t dpcompat_psa_ungroup = CVAR ("dpcompat_psa_ungroup", "0");
|
||||||
cvar_t r_noaliasshadows = SCVARF ("r_noaliasshadows", "0", CVAR_ARCHIVE);
|
cvar_t r_noaliasshadows = CVARF ("r_noaliasshadows", "0", CVAR_ARCHIVE);
|
||||||
cvar_t r_shadows = CVARFD ("r_shadows", "0", CVAR_ARCHIVE, "Draw basic blob shadows underneath entities without using realtime lighting.");
|
cvar_t r_shadows = CVARFD ("r_shadows", "0", CVAR_ARCHIVE, "Draw basic blob shadows underneath entities without using realtime lighting.");
|
||||||
cvar_t r_showbboxes = CVARD("r_showbboxes", "0", "Debugging. Shows bounding boxes. 1=ssqc, 2=csqc. Red=solid, Green=stepping/toss/bounce, Blue=onground.");
|
cvar_t r_showbboxes = CVARD("r_showbboxes", "0", "Debugging. Shows bounding boxes. 1=ssqc, 2=csqc. Red=solid, Green=stepping/toss/bounce, Blue=onground.");
|
||||||
cvar_t r_showfields = CVARD("r_showfields", "0", "Debugging. Shows entity fields boxes (entity closest to crosshair). 1=ssqc, 2=csqc.");
|
cvar_t r_showfields = CVARD("r_showfields", "0", "Debugging. Shows entity fields boxes (entity closest to crosshair). 1=ssqc, 2=csqc.");
|
||||||
|
@ -431,7 +433,7 @@ cvar_t vid_desktopgamma = CVARFD ("vid_desktopgamma", "0",
|
||||||
cvar_t r_fog_exp2 = CVARD ("r_fog_exp2", "1", "Expresses how fog fades with distance. 0 (matching DarkPlaces's default) is typically more realistic, while 1 (matching FitzQuake and others) is more common.");
|
cvar_t r_fog_exp2 = CVARD ("r_fog_exp2", "1", "Expresses how fog fades with distance. 0 (matching DarkPlaces's default) is typically more realistic, while 1 (matching FitzQuake and others) is more common.");
|
||||||
|
|
||||||
extern cvar_t gl_dither;
|
extern cvar_t gl_dither;
|
||||||
cvar_t gl_screenangle = SCVAR("gl_screenangle", "0");
|
cvar_t gl_screenangle = CVAR("gl_screenangle", "0");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef VKQUAKE
|
#ifdef VKQUAKE
|
||||||
|
@ -885,6 +887,7 @@ void Renderer_Init(void)
|
||||||
Cvar_Register (&gl_mipcap, GLRENDEREROPTIONS);
|
Cvar_Register (&gl_mipcap, GLRENDEREROPTIONS);
|
||||||
Cvar_Register (&gl_texture_anisotropic_filtering, GLRENDEREROPTIONS);
|
Cvar_Register (&gl_texture_anisotropic_filtering, GLRENDEREROPTIONS);
|
||||||
Cvar_Register (&r_drawflat, GRAPHICALNICETIES);
|
Cvar_Register (&r_drawflat, GRAPHICALNICETIES);
|
||||||
|
Cvar_Register (&r_lightmap, GRAPHICALNICETIES);
|
||||||
Cvar_Register (&r_menutint, GRAPHICALNICETIES);
|
Cvar_Register (&r_menutint, GRAPHICALNICETIES);
|
||||||
|
|
||||||
Cvar_Register (&r_fb_bmodels, GRAPHICALNICETIES);
|
Cvar_Register (&r_fb_bmodels, GRAPHICALNICETIES);
|
||||||
|
|
|
@ -37,7 +37,7 @@ cvar_t scr_scoreboard_showflags = CVARD("scr_scoreboard_showflags", "2", "Displa
|
||||||
cvar_t scr_scoreboard_fillalpha = CVARD("scr_scoreboard_fillalpha", "0.7", "Transparency amount for newstyle scoreboard.");
|
cvar_t scr_scoreboard_fillalpha = CVARD("scr_scoreboard_fillalpha", "0.7", "Transparency amount for newstyle scoreboard.");
|
||||||
cvar_t scr_scoreboard_teamscores = CVARD("scr_scoreboard_teamscores", "1", "Makes +showscores act as +showteamscores. Because reasons.");
|
cvar_t scr_scoreboard_teamscores = CVARD("scr_scoreboard_teamscores", "1", "Makes +showscores act as +showteamscores. Because reasons.");
|
||||||
cvar_t scr_scoreboard_teamsort = CVARD("scr_scoreboard_teamsort", "0", "On the scoreboard, sort players by their team BEFORE their personal score.");
|
cvar_t scr_scoreboard_teamsort = CVARD("scr_scoreboard_teamsort", "0", "On the scoreboard, sort players by their team BEFORE their personal score.");
|
||||||
cvar_t scr_scoreboard_titleseperator = SCVAR("scr_scoreboard_titleseperator", "1");
|
cvar_t scr_scoreboard_titleseperator = CVAR("scr_scoreboard_titleseperator", "1");
|
||||||
cvar_t sbar_teamstatus = CVARD("sbar_teamstatus", "1", "Display the last team say from each of your team members just above the sbar area.");
|
cvar_t sbar_teamstatus = CVARD("sbar_teamstatus", "1", "Display the last team say from each of your team members just above the sbar area.");
|
||||||
|
|
||||||
//===========================================
|
//===========================================
|
||||||
|
@ -3426,7 +3426,7 @@ void Sbar_DeathmatchOverlay (int start)
|
||||||
}
|
}
|
||||||
|
|
||||||
x = startx;
|
x = startx;
|
||||||
#define COLUMN(title, width, code, fill) if (showcolumns & (1<<COLUMN##title)) {Draw_FunString(x, y, #title); x += width+8;}
|
#define COLUMN(title, width, code, fill) if (width && (showcolumns & (1<<COLUMN##title))) {Draw_FunString(x, y, #title); x += width+8;}
|
||||||
ALLCOLUMNS
|
ALLCOLUMNS
|
||||||
#undef COLUMN
|
#undef COLUMN
|
||||||
|
|
||||||
|
|
|
@ -21,8 +21,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
#include "quakedef.h"
|
#include "quakedef.h"
|
||||||
#include "glquake.h"
|
#include "glquake.h"
|
||||||
|
|
||||||
cvar_t baseskin = SCVAR("baseskin", "");
|
cvar_t baseskin = CVAR("baseskin", "");
|
||||||
cvar_t noskins = SCVAR("noskins", "0");
|
cvar_t noskins = CVAR("noskins", "0");
|
||||||
|
|
||||||
extern cvar_t cl_teamskin;
|
extern cvar_t cl_teamskin;
|
||||||
extern cvar_t cl_enemyskin;
|
extern cvar_t cl_enemyskin;
|
||||||
|
|
|
@ -928,8 +928,8 @@ int *debug;
|
||||||
|
|
||||||
HHOOK llkeyboardhook;
|
HHOOK llkeyboardhook;
|
||||||
|
|
||||||
cvar_t sys_disableWinKeys = SCVAR("sys_disableWinKeys", "0");
|
cvar_t sys_disableWinKeys = CVAR("sys_disableWinKeys", "0");
|
||||||
cvar_t sys_disableTaskSwitch = SCVARF("sys_disableTaskSwitch", "0", CVAR_NOTFROMSERVER); // please don't encourage people to use this...
|
cvar_t sys_disableTaskSwitch = CVARF("sys_disableTaskSwitch", "0", CVAR_NOTFROMSERVER); // please don't encourage people to use this...
|
||||||
|
|
||||||
LRESULT CALLBACK LowLevelKeyboardProc (INT nCode, WPARAM wParam, LPARAM lParam)
|
LRESULT CALLBACK LowLevelKeyboardProc (INT nCode, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
|
|
|
@ -20,16 +20,16 @@ static void QDECL rulesetcallback(cvar_t *var, char *oldval)
|
||||||
Validation_Apply_Ruleset();
|
Validation_Apply_Ruleset();
|
||||||
}
|
}
|
||||||
|
|
||||||
cvar_t allow_f_version = SCVAR("allow_f_version", "1");
|
cvar_t allow_f_version = CVAR("allow_f_version", "1");
|
||||||
cvar_t allow_f_server = SCVAR("allow_f_server", "1");
|
cvar_t allow_f_server = CVAR("allow_f_server", "1");
|
||||||
cvar_t allow_f_modified = SCVAR("allow_f_modified", "1");
|
cvar_t allow_f_modified = CVAR("allow_f_modified", "1");
|
||||||
cvar_t allow_f_skins = SCVAR("allow_f_skins", "1");
|
cvar_t allow_f_skins = CVAR("allow_f_skins", "1");
|
||||||
cvar_t allow_f_ruleset = SCVAR("allow_f_ruleset", "1");
|
cvar_t allow_f_ruleset = CVAR("allow_f_ruleset", "1");
|
||||||
cvar_t allow_f_scripts = SCVAR("allow_f_scripts", "1");
|
cvar_t allow_f_scripts = CVAR("allow_f_scripts", "1");
|
||||||
cvar_t allow_f_fakeshaft = SCVAR("allow_f_fakeshaft", "1");
|
cvar_t allow_f_fakeshaft = CVAR("allow_f_fakeshaft", "1");
|
||||||
cvar_t allow_f_system = SCVAR("allow_f_system", "0");
|
cvar_t allow_f_system = CVAR("allow_f_system", "0");
|
||||||
cvar_t allow_f_cmdline = SCVAR("allow_f_cmdline", "0");
|
cvar_t allow_f_cmdline = CVAR("allow_f_cmdline", "0");
|
||||||
cvar_t auth_validateclients = SCVAR("auth_validateclients", "1");
|
cvar_t auth_validateclients = CVAR("auth_validateclients", "1");
|
||||||
cvar_t ruleset = CVARC("ruleset", "none", rulesetcallback);
|
cvar_t ruleset = CVARC("ruleset", "none", rulesetcallback);
|
||||||
|
|
||||||
|
|
||||||
|
@ -82,7 +82,7 @@ static void Validation_Version(void)
|
||||||
else if (r_shadow_realtime_dlight.ival)
|
else if (r_shadow_realtime_dlight.ival)
|
||||||
*s++ = 'S';
|
*s++ = 'S';
|
||||||
#endif
|
#endif
|
||||||
if (r_drawflat.ival)
|
if (r_drawflat.ival || r_lightmap.ival)
|
||||||
*s++ = 'F';
|
*s++ = 'F';
|
||||||
if (gl_load24bit.ival)
|
if (gl_load24bit.ival)
|
||||||
*s++ = 'H';
|
*s++ = 'H';
|
||||||
|
|
|
@ -44,62 +44,62 @@ when crossing a water boudnary.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef SIDEVIEWS
|
#ifdef SIDEVIEWS
|
||||||
cvar_t vsec_enabled[SIDEVIEWS] = {SCVAR("v2_enabled", "2"), SCVAR("v3_enabled", "0"), SCVAR("v4_enabled", "0"), SCVAR("v5_enabled", "0")};
|
cvar_t vsec_enabled[SIDEVIEWS] = {CVAR("v2_enabled", "2"), CVAR("v3_enabled", "0"), CVAR("v4_enabled", "0"), CVAR("v5_enabled", "0")};
|
||||||
cvar_t vsec_x[SIDEVIEWS] = {SCVAR("v2_x", "0"), SCVAR("v3_x", "0.25"), SCVAR("v4_x", "0.5"), SCVAR("v5_x", "0.75")};
|
cvar_t vsec_x[SIDEVIEWS] = {CVAR("v2_x", "0"), CVAR("v3_x", "0.25"), CVAR("v4_x", "0.5"), CVAR("v5_x", "0.75")};
|
||||||
cvar_t vsec_y[SIDEVIEWS] = {SCVAR("v2_y", "0"), SCVAR("v3_y", "0"), SCVAR("v4_y", "0"), SCVAR("v5_y", "0")};
|
cvar_t vsec_y[SIDEVIEWS] = {CVAR("v2_y", "0"), CVAR("v3_y", "0"), CVAR("v4_y", "0"), CVAR("v5_y", "0")};
|
||||||
cvar_t vsec_scalex[SIDEVIEWS] = {SCVAR("v2_scalex", "0.25"), SCVAR("v3_scalex", "0.25"), SCVAR("v4_scalex", "0.25"), SCVAR("v5_scalex", "0.25")};
|
cvar_t vsec_scalex[SIDEVIEWS] = {CVAR("v2_scalex", "0.25"), CVAR("v3_scalex", "0.25"), CVAR("v4_scalex", "0.25"), CVAR("v5_scalex", "0.25")};
|
||||||
cvar_t vsec_scaley[SIDEVIEWS] = {SCVAR("v2_scaley", "0.25"), SCVAR("v3_scaley", "0.25"), SCVAR("v4_scaley", "0.25"), SCVAR("v5_scaley", "0.25")};
|
cvar_t vsec_scaley[SIDEVIEWS] = {CVAR("v2_scaley", "0.25"), CVAR("v3_scaley", "0.25"), CVAR("v4_scaley", "0.25"), CVAR("v5_scaley", "0.25")};
|
||||||
cvar_t vsec_yaw[SIDEVIEWS] = {SCVAR("v2_yaw", "180"), SCVAR("v3_yaw", "90"), SCVAR("v4_yaw", "270"), SCVAR("v5_yaw", "0")};
|
cvar_t vsec_yaw[SIDEVIEWS] = {CVAR("v2_yaw", "180"), CVAR("v3_yaw", "90"), CVAR("v4_yaw", "270"), CVAR("v5_yaw", "0")};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
cvar_t cl_rollspeed = SCVAR("cl_rollspeed", "200");
|
cvar_t cl_rollspeed = CVAR("cl_rollspeed", "200");
|
||||||
cvar_t cl_rollangle = SCVAR("cl_rollangle", "2.0");
|
cvar_t cl_rollangle = CVAR("cl_rollangle", "2.0");
|
||||||
cvar_t v_deathtilt = SCVAR("v_deathtilt", "1");
|
cvar_t v_deathtilt = CVAR("v_deathtilt", "1");
|
||||||
|
|
||||||
cvar_t cl_bob = SCVAR("cl_bob","0.02");
|
cvar_t cl_bob = CVAR("cl_bob","0.02");
|
||||||
cvar_t cl_bobcycle = SCVAR("cl_bobcycle","0.6");
|
cvar_t cl_bobcycle = CVAR("cl_bobcycle","0.6");
|
||||||
cvar_t cl_bobup = SCVAR("cl_bobup","0.5");
|
cvar_t cl_bobup = CVAR("cl_bobup","0.5");
|
||||||
|
|
||||||
cvar_t v_kicktime = SCVAR("v_kicktime", "0.5");
|
cvar_t v_kicktime = CVAR("v_kicktime", "0.5");
|
||||||
cvar_t v_kickroll = SCVAR("v_kickroll", "0.6");
|
cvar_t v_kickroll = CVAR("v_kickroll", "0.6");
|
||||||
cvar_t v_kickpitch = SCVAR("v_kickpitch", "0.6");
|
cvar_t v_kickpitch = CVAR("v_kickpitch", "0.6");
|
||||||
|
|
||||||
cvar_t v_iyaw_cycle = SCVAR("v_iyaw_cycle", "2");
|
cvar_t v_iyaw_cycle = CVAR("v_iyaw_cycle", "2");
|
||||||
cvar_t v_iroll_cycle = SCVAR("v_iroll_cycle", "0.5");
|
cvar_t v_iroll_cycle = CVAR("v_iroll_cycle", "0.5");
|
||||||
cvar_t v_ipitch_cycle = SCVAR("v_ipitch_cycle", "1");
|
cvar_t v_ipitch_cycle = CVAR("v_ipitch_cycle", "1");
|
||||||
cvar_t v_iyaw_level = SCVAR("v_iyaw_level", "0.3");
|
cvar_t v_iyaw_level = CVAR("v_iyaw_level", "0.3");
|
||||||
cvar_t v_iroll_level = SCVAR("v_iroll_level", "0.1");
|
cvar_t v_iroll_level = CVAR("v_iroll_level", "0.1");
|
||||||
cvar_t v_ipitch_level = SCVAR("v_ipitch_level", "0.3");
|
cvar_t v_ipitch_level = CVAR("v_ipitch_level", "0.3");
|
||||||
cvar_t v_idlescale = SCVAR("v_idlescale", "0");
|
cvar_t v_idlescale = CVAR("v_idlescale", "0");
|
||||||
|
|
||||||
cvar_t crosshair = SCVARF("crosshair", "1", CVAR_ARCHIVE);
|
cvar_t crosshair = CVARF("crosshair", "1", CVAR_ARCHIVE);
|
||||||
cvar_t crosshaircolor = SCVARF("crosshaircolor", "255 255 255", CVAR_ARCHIVE);
|
cvar_t crosshaircolor = CVARF("crosshaircolor", "255 255 255", CVAR_ARCHIVE);
|
||||||
cvar_t crosshairsize = SCVARF("crosshairsize", "8", CVAR_ARCHIVE);
|
cvar_t crosshairsize = CVARF("crosshairsize", "8", CVAR_ARCHIVE);
|
||||||
|
|
||||||
cvar_t cl_crossx = SCVARF("cl_crossx", "0", CVAR_ARCHIVE);
|
cvar_t cl_crossx = CVARF("cl_crossx", "0", CVAR_ARCHIVE);
|
||||||
cvar_t cl_crossy = SCVARF("cl_crossy", "0", CVAR_ARCHIVE);
|
cvar_t cl_crossy = CVARF("cl_crossy", "0", CVAR_ARCHIVE);
|
||||||
cvar_t crosshaircorrect = SCVARF("crosshaircorrect", "0", CVAR_SEMICHEAT);
|
cvar_t crosshaircorrect = CVARF("crosshaircorrect", "0", CVAR_SEMICHEAT);
|
||||||
cvar_t crosshairimage = SCVAR("crosshairimage", "");
|
cvar_t crosshairimage = CVAR("crosshairimage", "");
|
||||||
cvar_t crosshairalpha = SCVAR("crosshairalpha", "1");
|
cvar_t crosshairalpha = CVAR("crosshairalpha", "1");
|
||||||
|
|
||||||
cvar_t gl_cshiftpercent = SCVAR("gl_cshiftpercent", "100");
|
cvar_t gl_cshiftpercent = CVAR("gl_cshiftpercent", "100");
|
||||||
cvar_t gl_cshiftenabled = CVARF("gl_polyblend", "1", CVAR_ARCHIVE);
|
cvar_t gl_cshiftenabled = CVARF("gl_polyblend", "1", CVAR_ARCHIVE);
|
||||||
|
|
||||||
cvar_t v_bonusflash = SCVAR("v_bonusflash", "1");
|
cvar_t v_bonusflash = CVAR("v_bonusflash", "1");
|
||||||
|
|
||||||
cvar_t v_contentblend = SCVARF("v_contentblend", "1", CVAR_ARCHIVE);
|
cvar_t v_contentblend = CVARF("v_contentblend", "1", CVAR_ARCHIVE);
|
||||||
cvar_t v_damagecshift = SCVAR("v_damagecshift", "1");
|
cvar_t v_damagecshift = CVAR("v_damagecshift", "1");
|
||||||
cvar_t v_quadcshift = SCVAR("v_quadcshift", "1");
|
cvar_t v_quadcshift = CVAR("v_quadcshift", "1");
|
||||||
cvar_t v_suitcshift = SCVAR("v_suitcshift", "1");
|
cvar_t v_suitcshift = CVAR("v_suitcshift", "1");
|
||||||
cvar_t v_ringcshift = SCVAR("v_ringcshift", "1");
|
cvar_t v_ringcshift = CVAR("v_ringcshift", "1");
|
||||||
cvar_t v_pentcshift = SCVAR("v_pentcshift", "1");
|
cvar_t v_pentcshift = CVAR("v_pentcshift", "1");
|
||||||
cvar_t v_gunkick = SCVAR("v_gunkick", "0");
|
cvar_t v_gunkick = CVAR("v_gunkick", "0");
|
||||||
cvar_t v_gunkick_q2 = SCVAR("v_gunkick_q2", "1");
|
cvar_t v_gunkick_q2 = CVAR("v_gunkick_q2", "1");
|
||||||
|
|
||||||
cvar_t v_viewheight = SCVAR("v_viewheight", "0");
|
cvar_t v_viewheight = CVAR("v_viewheight", "0");
|
||||||
cvar_t v_projectionmode = SCVAR("v_projectionmode", "0");
|
cvar_t v_projectionmode = CVAR("v_projectionmode", "0");
|
||||||
|
|
||||||
cvar_t v_depthsortentities = CVARAD("v_depthsortentities", "0", "v_reorderentitiesrandomly", "Reorder entities for transparency such that the furthest entities are drawn first, allowing nearer transparent entities to draw over the top of them.");
|
cvar_t v_depthsortentities = CVARAD("v_depthsortentities", "0", "v_reorderentitiesrandomly", "Reorder entities for transparency such that the furthest entities are drawn first, allowing nearer transparent entities to draw over the top of them.");
|
||||||
|
|
||||||
cvar_t scr_autoid = CVARD("scr_autoid", "1", "Display nametags above all players while spectating.");
|
cvar_t scr_autoid = CVARD("scr_autoid", "1", "Display nametags above all players while spectating.");
|
||||||
cvar_t scr_autoid_team = CVARD("scr_autoid_team", "1", "Display nametags above team members. 0: off. 1: display with half-alpha if occluded. 2: hide when occluded.");
|
cvar_t scr_autoid_team = CVARD("scr_autoid_team", "1", "Display nametags above team members. 0: off. 1: display with half-alpha if occluded. 2: hide when occluded.");
|
||||||
|
@ -109,9 +109,9 @@ cvar_t scr_autoid_weapon = CVARD("scr_autoid_weapon", "1", "Display the player'
|
||||||
cvar_t scr_autoid_teamcolour = CVARD("scr_autoid_teamcolour", STRINGIFY(COLOR_BLUE), "The colour for the text on the nametags of team members.");
|
cvar_t scr_autoid_teamcolour = CVARD("scr_autoid_teamcolour", STRINGIFY(COLOR_BLUE), "The colour for the text on the nametags of team members.");
|
||||||
cvar_t scr_autoid_enemycolour = CVARD("scr_autoid_enemycolour", STRINGIFY(COLOR_WHITE), "The colour for the text on the nametags of non-team members.");
|
cvar_t scr_autoid_enemycolour = CVARD("scr_autoid_enemycolour", STRINGIFY(COLOR_WHITE), "The colour for the text on the nametags of non-team members.");
|
||||||
|
|
||||||
cvar_t chase_active = CVAR("chase_active", "0");
|
cvar_t chase_active = CVAR("chase_active", "0");
|
||||||
cvar_t chase_back = CVAR("chase_back", "48");
|
cvar_t chase_back = CVAR("chase_back", "48");
|
||||||
cvar_t chase_up = CVAR("chase_up", "24");
|
cvar_t chase_up = CVAR("chase_up", "24");
|
||||||
|
|
||||||
|
|
||||||
extern cvar_t cl_chasecam;
|
extern cvar_t cl_chasecam;
|
||||||
|
@ -197,8 +197,8 @@ float V_CalcBob (playerview_t *pv, qboolean queryold)
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
||||||
|
|
||||||
cvar_t v_centermove = SCVAR("v_centermove", "0.15");
|
cvar_t v_centermove = CVAR("v_centermove", "0.15");
|
||||||
cvar_t v_centerspeed = SCVAR("v_centerspeed","500");
|
cvar_t v_centerspeed = CVAR("v_centerspeed","500");
|
||||||
|
|
||||||
|
|
||||||
void V_StartPitchDrift (playerview_t *pv)
|
void V_StartPitchDrift (playerview_t *pv)
|
||||||
|
|
|
@ -22,10 +22,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
#include "quakedef.h"
|
#include "quakedef.h"
|
||||||
#include "fs.h"
|
#include "fs.h"
|
||||||
|
|
||||||
cvar_t ruleset_allow_in = SCVAR("ruleset_allow_in", "1");
|
cvar_t ruleset_allow_in = CVAR("ruleset_allow_in", "1");
|
||||||
cvar_t rcon_level = SCVAR("rcon_level", "20");
|
cvar_t rcon_level = CVAR("rcon_level", "20");
|
||||||
cvar_t cmd_maxbuffersize = SCVAR("cmd_maxbuffersize", "65536");
|
cvar_t cmd_maxbuffersize = CVAR("cmd_maxbuffersize", "65536");
|
||||||
cvar_t dpcompat_set = SCVAR("dpcompat_set", "0");
|
cvar_t dpcompat_set = CVAR("dpcompat_set", "0");
|
||||||
int Cmd_ExecLevel;
|
int Cmd_ExecLevel;
|
||||||
qboolean cmd_didwait;
|
qboolean cmd_didwait;
|
||||||
qboolean cmd_blockwait;
|
qboolean cmd_blockwait;
|
||||||
|
@ -2614,28 +2614,33 @@ static const char *If_Token_Term(const char *func, const char **end)
|
||||||
}
|
}
|
||||||
else if (*com_token == '!')
|
else if (*com_token == '!')
|
||||||
{
|
{
|
||||||
func = If_Token(s, end, 0);
|
func = If_Token(s, &s, 0);
|
||||||
s2 = retbool(!is_true(func));
|
s2 = retbool(!is_true(func));
|
||||||
}
|
}
|
||||||
else if (*com_token == '~')
|
else if (*com_token == '~')
|
||||||
{
|
{
|
||||||
func = If_Token(s, end, 0);
|
func = If_Token(s, &s, 0);
|
||||||
s2 = retbool(~atoi(func));
|
s2 = retbool(~atoi(func));
|
||||||
}
|
}
|
||||||
|
else if (*com_token == '-')
|
||||||
|
{
|
||||||
|
func = If_Token(s, &s, 0);
|
||||||
|
s2 = retfloat(-atof(func));
|
||||||
|
}
|
||||||
else if (!strcmp(com_token, "int"))
|
else if (!strcmp(com_token, "int"))
|
||||||
{
|
{
|
||||||
func = If_Token(s, end, 0);
|
func = If_Token(s, &s, 0);
|
||||||
s2 = retint(atoi(func));
|
s2 = retint(atoi(func));
|
||||||
}
|
}
|
||||||
else if (!strcmp(com_token, "strlen"))
|
else if (!strcmp(com_token, "strlen"))
|
||||||
{
|
{
|
||||||
func = If_Token(s, end, 0);
|
func = If_Token(s, &s, 0);
|
||||||
s2 = retfloat(strlen(func));
|
s2 = retfloat(strlen(func));
|
||||||
}
|
}
|
||||||
else if (!strcmp(com_token, "eval"))
|
else if (!strcmp(com_token, "eval"))
|
||||||
{
|
{
|
||||||
//read the stuff to the right
|
//read the stuff to the right
|
||||||
func = If_Token(s, end, IF_PRI_MAX);
|
func = If_Token(s, &s, IF_PRI_MAX);
|
||||||
//and evaluate it
|
//and evaluate it
|
||||||
s2 = If_Token(func, &func, IF_PRI_MAX);
|
s2 = If_Token(func, &func, IF_PRI_MAX);
|
||||||
}
|
}
|
||||||
|
@ -2824,19 +2829,22 @@ static const char *If_Token(const char *func, const char **end, int pri)
|
||||||
s2 = If_Token_Term(func, &s);
|
s2 = If_Token_Term(func, &s);
|
||||||
*end = s;
|
*end = s;
|
||||||
|
|
||||||
while (*s == ' ' || *s == '\t')
|
if (s)
|
||||||
s++;
|
|
||||||
|
|
||||||
for (i = 0; i < countof(ifops); i++)
|
|
||||||
{
|
{
|
||||||
if (!strncmp(s, ifops[i].opname, ifops[i].opnamelen))
|
while (*s == ' ' || *s == '\t')
|
||||||
|
s++;
|
||||||
|
|
||||||
|
for (i = 0; i < countof(ifops); i++)
|
||||||
{
|
{
|
||||||
if (pri == ifops[i].pri)
|
if (!strncmp(s, ifops[i].opname, ifops[i].opnamelen))
|
||||||
{
|
{
|
||||||
s = If_Token(s + ifops[i].opnamelen, end, pri);
|
if (pri == ifops[i].pri)
|
||||||
s2 = If_Operator(ifops[i].op, s2, s);
|
{
|
||||||
|
s = If_Token(s + ifops[i].opnamelen, end, pri);
|
||||||
|
s2 = If_Operator(ifops[i].op, s2, s);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return s2;
|
return s2;
|
||||||
|
|
|
@ -25,6 +25,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
|
//by adding 'extern' to one definition of a function in a translation unit, then the definition in that TU is NOT considered an inline definition. meaning non-inlined references in other TUs can link to it instead of their own if needed.
|
||||||
|
fte_inlinebody conchar_t *Font_Decode(conchar_t *start, unsigned int *codeflags, unsigned int *codepoint);
|
||||||
|
|
||||||
|
|
||||||
// These 4 libraries required for the version command
|
// These 4 libraries required for the version command
|
||||||
|
|
||||||
#if defined(MINGW)
|
#if defined(MINGW)
|
||||||
|
|
|
@ -103,8 +103,6 @@ typedef struct cvar_s
|
||||||
#define CVARD(ConsoleName,Value,Description) CVARAFDC(ConsoleName, Value, NULL, 0, Description, NULL)
|
#define CVARD(ConsoleName,Value,Description) CVARAFDC(ConsoleName, Value, NULL, 0, Description, NULL)
|
||||||
#define CVAR(ConsoleName,Value) CVARD(ConsoleName, Value, NULL)
|
#define CVAR(ConsoleName,Value) CVARD(ConsoleName, Value, NULL)
|
||||||
|
|
||||||
#define SCVAR(ConsoleName,Value) CVAR(ConsoleName,Value)
|
|
||||||
#define SCVARF(ConsoleName,Value,Flags) CVARF(ConsoleName,Value,Flags)
|
|
||||||
#define CVARDP4(Flags,ConsoleName,Value,Description) CVARFD(ConsoleName, Value, Flags,Description)
|
#define CVARDP4(Flags,ConsoleName,Value,Description) CVARFD(ConsoleName, Value, Flags,Description)
|
||||||
|
|
||||||
typedef struct cvar_group_s
|
typedef struct cvar_group_s
|
||||||
|
|
|
@ -386,10 +386,10 @@ typedef struct cminfo_s
|
||||||
|
|
||||||
static q2mapsurface_t nullsurface;
|
static q2mapsurface_t nullsurface;
|
||||||
|
|
||||||
cvar_t map_noareas = SCVAR("map_noareas", "0"); //1 for lack of mod support.
|
cvar_t map_noareas = CVAR("map_noareas", "0"); //1 for lack of mod support.
|
||||||
cvar_t map_noCurves = SCVARF("map_noCurves", "0", CVAR_CHEAT);
|
cvar_t map_noCurves = CVARF("map_noCurves", "0", CVAR_CHEAT);
|
||||||
cvar_t map_autoopenportals = CVARD("map_autoopenportals", "0", "When set to 1, force-opens all area portals. Normally these start closed and are opened by doors when they move, but this requires the gamecode to signal this."); //1 for lack of mod support.
|
cvar_t map_autoopenportals = CVARD("map_autoopenportals", "0", "When set to 1, force-opens all area portals. Normally these start closed and are opened by doors when they move, but this requires the gamecode to signal this."); //1 for lack of mod support.
|
||||||
cvar_t r_subdivisions = SCVAR("r_subdivisions", "2");
|
cvar_t r_subdivisions = CVAR("r_subdivisions", "2");
|
||||||
|
|
||||||
static int CM_NumInlineModels (model_t *model);
|
static int CM_NumInlineModels (model_t *model);
|
||||||
static cmodel_t *CM_InlineModel (model_t *model, char *name);
|
static cmodel_t *CM_InlineModel (model_t *model, char *name);
|
||||||
|
|
|
@ -81,8 +81,8 @@ fragmentation works like IP, offset and morefrags. offset is *8 (decode: (offset
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int net_drop;
|
int net_drop;
|
||||||
cvar_t showpackets = SCVAR("showpackets", "0");
|
cvar_t showpackets = CVAR("showpackets", "0");
|
||||||
cvar_t showdrop = SCVAR("showdrop", "0");
|
cvar_t showdrop = CVAR("showdrop", "0");
|
||||||
cvar_t qport = CVARF("qport_", "0", CVAR_NOSAVE);
|
cvar_t qport = CVARF("qport_", "0", CVAR_NOSAVE);
|
||||||
cvar_t net_mtu = CVARD("net_mtu", "1440", "Specifies a maximum udp payload size, above which packets will be fragmented. If routers all worked properly this could be some massive value, and some massive value may work really nicely for lans. Use smaller values than the default if you're connecting through nested tunnels through routers that fail with IP fragmentation.");
|
cvar_t net_mtu = CVARD("net_mtu", "1440", "Specifies a maximum udp payload size, above which packets will be fragmented. If routers all worked properly this could be some massive value, and some massive value may work really nicely for lans. Use smaller values than the default if you're connecting through nested tunnels through routers that fail with IP fragmentation.");
|
||||||
cvar_t net_compress = CVARD("net_compress", "0", "Enables huffman compression of network packets.");
|
cvar_t net_compress = CVARD("net_compress", "0", "Enables huffman compression of network packets.");
|
||||||
|
|
|
@ -2785,6 +2785,19 @@ ftenet_generic_connection_t *FTENET_Generic_EstablishConnection(int adrfamily, i
|
||||||
if (ioctlsocket (newsocket, FIONBIO, &_true) == -1)
|
if (ioctlsocket (newsocket, FIONBIO, &_true) == -1)
|
||||||
Sys_Error ("UDP_OpenSocket: ioctl FIONBIO: %s", strerror(neterrno()));
|
Sys_Error ("UDP_OpenSocket: ioctl FIONBIO: %s", strerror(neterrno()));
|
||||||
|
|
||||||
|
//ipv6 sockets need to add themselves to a multicast group, so that we can receive broadcasts on a lan
|
||||||
|
#if defined(IPPROTO_IPV6)
|
||||||
|
if (family == AF_INET6 || hybrid || isserver)
|
||||||
|
{
|
||||||
|
struct ipv6_mreq req;
|
||||||
|
memset(&req, 0, sizeof(req));
|
||||||
|
req.ipv6mr_multiaddr.s6_addr[0] = 0xff;
|
||||||
|
req.ipv6mr_multiaddr.s6_addr[1] = 0x02;
|
||||||
|
req.ipv6mr_multiaddr.s6_addr[15]= 0x01;
|
||||||
|
req.ipv6mr_interface = 0;
|
||||||
|
setsockopt(newsocket, IPPROTO_IPV6, IPV6_JOIN_GROUP, (char *)&req, sizeof(req));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
// determine my name & address if we don't already know it
|
// determine my name & address if we don't already know it
|
||||||
|
|
|
@ -201,6 +201,7 @@ struct model_s;
|
||||||
struct msurface_s;
|
struct msurface_s;
|
||||||
|
|
||||||
void P_InitParticleSystem(void);
|
void P_InitParticleSystem(void);
|
||||||
|
void P_ShutdownParticleSystem(void);
|
||||||
void P_Shutdown(void);
|
void P_Shutdown(void);
|
||||||
void P_LoadedModel(struct model_s *mod); /*checks a model's various effects*/
|
void P_LoadedModel(struct model_s *mod); /*checks a model's various effects*/
|
||||||
void P_DefaultTrail (unsigned int entityeffects, unsigned int modelflags, int *trailid, int *trailpalidx);
|
void P_DefaultTrail (unsigned int entityeffects, unsigned int modelflags, int *trailid, int *trailpalidx);
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
#ifdef PLUGINS
|
#ifdef PLUGINS
|
||||||
|
|
||||||
cvar_t plug_sbar = CVARD("plug_sbar", "3", "Controls whether plugins are allowed to draw the hud, rather than the engine (when allowed by csqc). This is typically used to permit the ezhud plugin without needing to bother unloading it.\n=0: never use hud plugins.\n&1: Use hud plugins in deathmatch.\n&2: Use hud plugins in singleplayer/coop.\n=3: Always use hud plugins (when loaded).");
|
cvar_t plug_sbar = CVARD("plug_sbar", "3", "Controls whether plugins are allowed to draw the hud, rather than the engine (when allowed by csqc). This is typically used to permit the ezhud plugin without needing to bother unloading it.\n=0: never use hud plugins.\n&1: Use hud plugins in deathmatch.\n&2: Use hud plugins in singleplayer/coop.\n=3: Always use hud plugins (when loaded).");
|
||||||
cvar_t plug_loaddefault = SCVAR("plug_loaddefault", "1");
|
cvar_t plug_loaddefault = CVAR("plug_loaddefault", "1");
|
||||||
|
|
||||||
qintptr_t Plug_Bullet_Init(qintptr_t *args);
|
qintptr_t Plug_Bullet_Init(qintptr_t *args);
|
||||||
qintptr_t Plug_ODE_Init(qintptr_t *args);
|
qintptr_t Plug_ODE_Init(qintptr_t *args);
|
||||||
|
|
|
@ -1337,7 +1337,7 @@ void Shader_LightPass(const char *shortname, shader_t *s, const void *args)
|
||||||
{
|
{
|
||||||
char shadertext[8192*2];
|
char shadertext[8192*2];
|
||||||
extern cvar_t r_drawflat;
|
extern cvar_t r_drawflat;
|
||||||
sprintf(shadertext, LIGHTPASS_SHADER, r_drawflat.ival?"#FLAT":"");
|
sprintf(shadertext, LIGHTPASS_SHADER, (r_lightmap.ival||r_drawflat.ival)?"#FLAT":"");
|
||||||
Shader_DefaultScript(shortname, s, shadertext);
|
Shader_DefaultScript(shortname, s, shadertext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,10 +31,6 @@ struct font_s *font_tiny;
|
||||||
static int font_be_flags;
|
static int font_be_flags;
|
||||||
extern unsigned int r2d_be_flags;
|
extern unsigned int r2d_be_flags;
|
||||||
|
|
||||||
//by adding 'extern' to one definition of a function in a translation unit, then the definition in that TU is NOT considered an inline definition. meaning non-inlined references in other TUs can link to it instead of their own if needed.
|
|
||||||
fte_inlinebody conchar_t *Font_Decode(conchar_t *start, unsigned int *codeflags, unsigned int *codepoint);
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef AVAIL_FREETYPE
|
#ifdef AVAIL_FREETYPE
|
||||||
#include <ft2build.h>
|
#include <ft2build.h>
|
||||||
#include FT_FREETYPE_H
|
#include FT_FREETYPE_H
|
||||||
|
|
|
@ -53,9 +53,9 @@ extern cvar_t gl_part_flame;
|
||||||
extern cvar_t r_bloom;
|
extern cvar_t r_bloom;
|
||||||
extern cvar_t r_wireframe_smooth;
|
extern cvar_t r_wireframe_smooth;
|
||||||
|
|
||||||
cvar_t gl_affinemodels = SCVAR("gl_affinemodels","0");
|
cvar_t gl_affinemodels = CVAR("gl_affinemodels","0");
|
||||||
cvar_t gl_finish = SCVAR("gl_finish","0");
|
cvar_t gl_finish = CVAR("gl_finish","0");
|
||||||
cvar_t gl_dither = SCVAR("gl_dither", "1");
|
cvar_t gl_dither = CVAR("gl_dither", "1");
|
||||||
extern cvar_t r_stereo_separation;
|
extern cvar_t r_stereo_separation;
|
||||||
extern cvar_t r_stereo_convergence;
|
extern cvar_t r_stereo_convergence;
|
||||||
extern cvar_t r_stereo_method;
|
extern cvar_t r_stereo_method;
|
||||||
|
@ -80,7 +80,7 @@ extern cvar_t r_portaldrawplanes;
|
||||||
extern cvar_t r_portalonly;
|
extern cvar_t r_portalonly;
|
||||||
|
|
||||||
#ifdef R_XFLIP
|
#ifdef R_XFLIP
|
||||||
cvar_t r_xflip = SCVAR("leftisright", "0");
|
cvar_t r_xflip = CVAR("leftisright", "0");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern cvar_t scr_fov;
|
extern cvar_t scr_fov;
|
||||||
|
|
|
@ -4985,6 +4985,19 @@ void Shader_DefaultBSPLM(const char *shortname, shader_t *s, const void *args)
|
||||||
char *builtin = NULL;
|
char *builtin = NULL;
|
||||||
if (Shader_ParseShader("defaultwall", s))
|
if (Shader_ParseShader("defaultwall", s))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (!builtin && r_lightmap.ival)
|
||||||
|
builtin = (
|
||||||
|
"{\n"
|
||||||
|
"program drawflat_wall\n"
|
||||||
|
"{\n"
|
||||||
|
"map $lightmap\n"
|
||||||
|
"tcgen lightmap\n"
|
||||||
|
"rgbgen const 255 255 255\n"
|
||||||
|
"}\n"
|
||||||
|
"}\n"
|
||||||
|
);
|
||||||
|
|
||||||
if (!builtin && r_drawflat.ival)
|
if (!builtin && r_drawflat.ival)
|
||||||
builtin = (
|
builtin = (
|
||||||
"{\n"
|
"{\n"
|
||||||
|
|
|
@ -786,17 +786,18 @@ static void GL_DrawSkyBox (texid_t *texnums, batch_t *s)
|
||||||
=============
|
=============
|
||||||
R_InitSky
|
R_InitSky
|
||||||
|
|
||||||
A sky texture is 256*128, with the right side being a masked overlay
|
A sky image is 256*128 and comprises two logical textures.
|
||||||
|
the left is the transparent/blended part. the right is the opaque/background part.
|
||||||
==============
|
==============
|
||||||
*/
|
*/
|
||||||
void R_InitSky (shader_t *shader, const char *skyname, qbyte *src, unsigned int width, unsigned int height)
|
void R_InitSky (shader_t *shader, const char *skyname, qbyte *src, unsigned int width, unsigned int height)
|
||||||
{
|
{
|
||||||
int i, j, p;
|
int i, j, p;
|
||||||
unsigned trans[128*128];
|
unsigned *temp;
|
||||||
unsigned transpix, alphamask;
|
unsigned transpix, alphamask;
|
||||||
int r, g, b;
|
int r, g, b;
|
||||||
unsigned *rgba;
|
unsigned *rgba;
|
||||||
char name[MAX_QPATH];
|
char name[MAX_QPATH*2];
|
||||||
|
|
||||||
unsigned int stride = width;
|
unsigned int stride = width;
|
||||||
width /= 2;
|
width /= 2;
|
||||||
|
@ -804,15 +805,64 @@ void R_InitSky (shader_t *shader, const char *skyname, qbyte *src, unsigned int
|
||||||
if (width < 1 || height < 1 || stride != width*2 || !src)
|
if (width < 1 || height < 1 || stride != width*2 || !src)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (width*height > countof(trans))
|
//try to load dual-layer-single-image skies.
|
||||||
|
//this is always going to be lame special case crap
|
||||||
{
|
{
|
||||||
unsigned int wibuf[16] = {0};
|
size_t filesize = 0;
|
||||||
shader->defaulttextures->base = R_LoadTexture("$blackimage", 4, 4, TF_RGBA32, wibuf, IF_NOMIPMAP|IF_NOPICMIP|IF_NEAREST|IF_NOGAMMA);
|
qbyte *filedata = NULL;
|
||||||
shader->defaulttextures->base = R_LoadReplacementTexture(skyname, NULL, 0, src, stride, height, TF_SOLID8);
|
if (!filedata)
|
||||||
shader->defaulttextures->fullbright = shader->defaulttextures->base;
|
{
|
||||||
return;
|
Q_snprintfz(name, sizeof(name), "textures/%s.tga", skyname);
|
||||||
|
filedata = FS_LoadMallocFile(name, &filesize);
|
||||||
|
}
|
||||||
|
if (!filedata)
|
||||||
|
{
|
||||||
|
Q_snprintfz(name, sizeof(name), "textures/%s.png", skyname);
|
||||||
|
filedata = FS_LoadMallocFile(name, &filesize);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filedata)
|
||||||
|
{
|
||||||
|
int imagewidth, imageheight;
|
||||||
|
qboolean hasalpha; //fixme, if this is false, is it worth all this code?
|
||||||
|
unsigned int *imagedata = (unsigned int*)Read32BitImageFile(filedata, filesize, &imagewidth, &imageheight, &hasalpha, name);
|
||||||
|
Z_Free(filedata);
|
||||||
|
|
||||||
|
if (imagedata && !(imagewidth&1))
|
||||||
|
{
|
||||||
|
imagewidth>>=1;
|
||||||
|
|
||||||
|
temp = BZF_Malloc(imagewidth*imageheight*sizeof(*temp));
|
||||||
|
if (temp)
|
||||||
|
{
|
||||||
|
for (i=0 ; i<height ; i++)
|
||||||
|
for (j=0 ; j<width ; j++)
|
||||||
|
{
|
||||||
|
temp[i*width+j] = imagedata[i*(width<<1)+j+width];
|
||||||
|
}
|
||||||
|
Q_snprintfz(name, sizeof(name), "%s_solid", skyname);
|
||||||
|
Q_strlwr(name);
|
||||||
|
shader->defaulttextures->base = R_LoadReplacementTexture(name, NULL, IF_NOALPHA, temp, imagewidth, imageheight, TF_RGBX32);
|
||||||
|
|
||||||
|
for (i=0 ; i<height ; i++)
|
||||||
|
for (j=0 ; j<width ; j++)
|
||||||
|
{
|
||||||
|
temp[i*width+j] = imagedata[i*(width<<1)+j];
|
||||||
|
}
|
||||||
|
BZ_Free(imagedata);
|
||||||
|
Q_snprintfz(name, sizeof(name), "%s_alpha:%s_trans", skyname, skyname);
|
||||||
|
Q_strlwr(name);
|
||||||
|
shader->defaulttextures->fullbright = R_LoadReplacementTexture(name, NULL, 0, temp, imagewidth, imageheight, TF_RGBA32);
|
||||||
|
BZ_Free(temp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BZ_Free(imagedata);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
temp = BZ_Malloc(width*height*sizeof(*temp));
|
||||||
|
|
||||||
// make an average value for the back to avoid
|
// make an average value for the back to avoid
|
||||||
// a fringe on the top level
|
// a fringe on the top level
|
||||||
|
|
||||||
|
@ -822,7 +872,7 @@ void R_InitSky (shader_t *shader, const char *skyname, qbyte *src, unsigned int
|
||||||
{
|
{
|
||||||
p = src[i*stride + j + width];
|
p = src[i*stride + j + width];
|
||||||
rgba = &d_8to24rgbtable[p];
|
rgba = &d_8to24rgbtable[p];
|
||||||
trans[(i*width) + j] = *rgba;
|
temp[(i*width) + j] = *rgba;
|
||||||
r += ((qbyte *)rgba)[0];
|
r += ((qbyte *)rgba)[0];
|
||||||
g += ((qbyte *)rgba)[1];
|
g += ((qbyte *)rgba)[1];
|
||||||
b += ((qbyte *)rgba)[2];
|
b += ((qbyte *)rgba)[2];
|
||||||
|
@ -832,11 +882,12 @@ void R_InitSky (shader_t *shader, const char *skyname, qbyte *src, unsigned int
|
||||||
{
|
{
|
||||||
Q_snprintfz(name, sizeof(name), "%s_solid", skyname);
|
Q_snprintfz(name, sizeof(name), "%s_solid", skyname);
|
||||||
Q_strlwr(name);
|
Q_strlwr(name);
|
||||||
shader->defaulttextures->base = R_LoadReplacementTexture(name, NULL, IF_NOALPHA, trans, width, height, TF_RGBX32);
|
shader->defaulttextures->base = R_LoadReplacementTexture(name, NULL, IF_NOALPHA, temp, width, height, TF_RGBX32);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!shader->defaulttextures->fullbright)
|
if (!shader->defaulttextures->fullbright)
|
||||||
{
|
{
|
||||||
|
//fixme: use premultiplied alpha here.
|
||||||
((qbyte *)&transpix)[0] = r/(width*height);
|
((qbyte *)&transpix)[0] = r/(width*height);
|
||||||
((qbyte *)&transpix)[1] = g/(width*height);
|
((qbyte *)&transpix)[1] = g/(width*height);
|
||||||
((qbyte *)&transpix)[2] = b/(width*height);
|
((qbyte *)&transpix)[2] = b/(width*height);
|
||||||
|
@ -847,15 +898,16 @@ void R_InitSky (shader_t *shader, const char *skyname, qbyte *src, unsigned int
|
||||||
{
|
{
|
||||||
p = src[i*stride + j];
|
p = src[i*stride + j];
|
||||||
if (p == 0)
|
if (p == 0)
|
||||||
trans[(i*width) + j] = transpix;
|
temp[(i*width) + j] = transpix;
|
||||||
else
|
else
|
||||||
trans[(i*width) + j] = d_8to24rgbtable[p] & alphamask;
|
temp[(i*width) + j] = d_8to24rgbtable[p] & alphamask;
|
||||||
}
|
}
|
||||||
|
|
||||||
//FIXME: support _trans
|
//FIXME: support _trans
|
||||||
Q_snprintfz(name, sizeof(name), "%s_alpha", skyname);
|
Q_snprintfz(name, sizeof(name), "%s_alpha:%s_trans", skyname, skyname);
|
||||||
Q_strlwr(name);
|
Q_strlwr(name);
|
||||||
shader->defaulttextures->fullbright = R_LoadReplacementTexture(name, NULL, 0, trans, width, height, TF_RGBA32);
|
shader->defaulttextures->fullbright = R_LoadReplacementTexture(name, NULL, 0, temp, width, height, TF_RGBA32);
|
||||||
}
|
}
|
||||||
|
BZ_Free(temp);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -373,13 +373,13 @@ IWEBFILE *IWebFOpenRead(char *name) //fread(name, "rb");
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#ifndef CLIENTONLY
|
#ifndef CLIENTONLY
|
||||||
cvar_t ftpserver = SCVAR("sv_ftp", "0");
|
cvar_t ftpserver = CVAR("sv_ftp", "0");
|
||||||
cvar_t ftpserver_port = SCVAR("sv_ftp_port", "21");
|
cvar_t ftpserver_port = CVAR("sv_ftp_port", "21");
|
||||||
cvar_t httpserver = SCVAR("sv_http", "0");
|
cvar_t httpserver = CVAR("sv_http", "0");
|
||||||
cvar_t httpserver_port = SCVAR("sv_http_port", "80");
|
cvar_t httpserver_port = CVAR("sv_http_port", "80");
|
||||||
cvar_t sv_readlevel = SCVAR("sv_readlevel", "0"); //default to allow anyone
|
cvar_t sv_readlevel = CVAR("sv_readlevel", "0"); //default to allow anyone
|
||||||
cvar_t sv_writelevel = SCVAR("sv_writelevel", "35"); //allowed to write to uploads/uname
|
cvar_t sv_writelevel = CVAR("sv_writelevel", "35"); //allowed to write to uploads/uname
|
||||||
cvar_t sv_fulllevel = SCVAR("sv_fulllevel", "51"); //allowed to write anywhere, replace any file...
|
cvar_t sv_fulllevel = CVAR("sv_fulllevel", "51"); //allowed to write anywhere, replace any file...
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//this file contains functions called from each side.
|
//this file contains functions called from each side.
|
||||||
|
|
|
@ -76,7 +76,7 @@ int CheckParm (char *check);
|
||||||
int SafeOpenWrite (char *filename, int maxsize);
|
int SafeOpenWrite (char *filename, int maxsize);
|
||||||
int SafeOpenRead (char *filename);
|
int SafeOpenRead (char *filename);
|
||||||
void SafeRead (int handle, void *buffer, long count);
|
void SafeRead (int handle, void *buffer, long count);
|
||||||
void SafeWrite (int handle, void *buffer, long count);
|
void SafeWrite (int handle, const void *buffer, long count);
|
||||||
pbool SafeClose(int hand);
|
pbool SafeClose(int hand);
|
||||||
int SafeSeek(int hand, int ofs, int mode);
|
int SafeSeek(int hand, int ofs, int mode);
|
||||||
void *SafeMalloc (long size);
|
void *SafeMalloc (long size);
|
||||||
|
|
|
@ -242,7 +242,7 @@ int QC_strncasecmp(const char *s1, const char *s2, int n)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void editbadfile(char *fname, int line)
|
void editbadfile(const char *fname, int line)
|
||||||
{
|
{
|
||||||
if (!*errorfile)
|
if (!*errorfile)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
void GoToDefinition(char *name);
|
void GoToDefinition(char *name);
|
||||||
int Grep(char *filename, char *string);
|
int Grep(char *filename, char *string);
|
||||||
void EditFile(char *name, int line, pbool setcontrol);
|
void EditFile(const char *name, int line, pbool setcontrol);
|
||||||
|
|
||||||
void GUI_SetDefaultOpts(void);
|
void GUI_SetDefaultOpts(void);
|
||||||
int GUI_BuildParms(char *args, char **argv, pbool quick);
|
int GUI_BuildParms(char *args, char **argv, pbool quick);
|
||||||
|
|
|
@ -594,8 +594,6 @@ typedef struct
|
||||||
} dprograms_t;
|
} dprograms_t;
|
||||||
#define standard_dprograms_t_size ((size_t)&((dprograms_t*)NULL)->ofsfiles)
|
#define standard_dprograms_t_size ((size_t)&((dprograms_t*)NULL)->ofsfiles)
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -623,3 +621,5 @@ typedef struct typeinfo_s
|
||||||
int size;
|
int size;
|
||||||
string_t name;
|
string_t name;
|
||||||
} typeinfo_t;
|
} typeinfo_t;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
#ifndef PROGSINT_H_INCLUDED
|
||||||
|
#define PROGSINT_H_INCLUDED
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#ifndef _CRT_SECURE_NO_WARNINGS
|
#ifndef _CRT_SECURE_NO_WARNINGS
|
||||||
#define _CRT_SECURE_NO_WARNINGS
|
#define _CRT_SECURE_NO_WARNINGS
|
||||||
|
@ -518,3 +521,5 @@ char *QCC_COM_Parse (const char *data);
|
||||||
extern char qcc_token[1024];
|
extern char qcc_token[1024];
|
||||||
extern char *basictypenames[];
|
extern char *basictypenames[];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -377,17 +377,18 @@ typedef struct QCC_def_s
|
||||||
struct QCC_function_s *scope; // function the var was defined in, or NULL
|
struct QCC_function_s *scope; // function the var was defined in, or NULL
|
||||||
struct QCC_def_s *deftail; // arrays and structs create multiple globaldef objects providing different types at the different parts of the single object (struct), or alternative names (vectors). this allows us to correctly set the const type based upon how its initialised.
|
struct QCC_def_s *deftail; // arrays and structs create multiple globaldef objects providing different types at the different parts of the single object (struct), or alternative names (vectors). this allows us to correctly set the const type based upon how its initialised.
|
||||||
struct QCC_def_s *generatedfor;
|
struct QCC_def_s *generatedfor;
|
||||||
int initialized; // 1 when a declaration included "= immediate". 2 = extern. 3 = don't warn (unless actually called)
|
int initialized; // 1 when a declaration included "= immediate". 2 = extern. 3 = don't warn (unless actually used)
|
||||||
int constant; // 1 says we can use the value over and over again
|
int constant; // 1 says we can use the value over and over again
|
||||||
|
|
||||||
struct QCC_def_s *symbolheader; //this is the original symbol within which the def is stored.
|
struct QCC_def_s *symbolheader; //this is the original symbol within which the def is stored.
|
||||||
union QCC_eval_s *symboldata; //null if uninitialised.
|
union QCC_eval_s *symboldata; //null if uninitialised. use sym->symboldata[sym->ofs] to index.
|
||||||
unsigned int symbolsize; //total byte size of symbol
|
unsigned int symbolsize; //total byte size of symbol
|
||||||
|
|
||||||
int refcount; //if 0, temp can be reused. tracked on globals too in order to catch bugs that would otherwise be a little too obscure.
|
int refcount; //if 0, temp can be reused. tracked on globals too in order to catch bugs that would otherwise be a little too obscure.
|
||||||
int timescalled; //part of the opt_stripfunctions optimisation.
|
int timescalled; //part of the opt_stripfunctions optimisation.
|
||||||
|
|
||||||
int s_file;
|
const char *filen;
|
||||||
|
int s_filed;
|
||||||
int s_line;
|
int s_line;
|
||||||
|
|
||||||
int arraysize;
|
int arraysize;
|
||||||
|
@ -406,6 +407,8 @@ typedef struct QCC_def_s
|
||||||
pbool used:1; //if it remains 0, it may be stripped. this is forced for functions and fields. commonly 0 on fields.
|
pbool used:1; //if it remains 0, it may be stripped. this is forced for functions and fields. commonly 0 on fields.
|
||||||
pbool localscope:1; //is a local, as opposed to a static (which is only visible within its scope)
|
pbool localscope:1; //is a local, as opposed to a static (which is only visible within its scope)
|
||||||
pbool arraylengthprefix:1; //hexen2 style arrays have a length prefixed to them for auto bounds checks. this can only work reliably for simple non-struct arrays.
|
pbool arraylengthprefix:1; //hexen2 style arrays have a length prefixed to them for auto bounds checks. this can only work reliably for simple non-struct arrays.
|
||||||
|
pbool assumedtype:1; //#merged. the type is not reliable.
|
||||||
|
pbool weak:1; //ignore any initialiser value (only permitted on functions)
|
||||||
|
|
||||||
int fromstatement; //statement that it is valid from.
|
int fromstatement; //statement that it is valid from.
|
||||||
temp_t *temp;
|
temp_t *temp;
|
||||||
|
@ -462,8 +465,9 @@ struct QCC_function_s
|
||||||
{
|
{
|
||||||
int builtin; // the builtin number. >= 0
|
int builtin; // the builtin number. >= 0
|
||||||
int code; // first statement. if -1, is a builtin.
|
int code; // first statement. if -1, is a builtin.
|
||||||
string_t s_file; // source file with definition
|
dfunction_t *merged; // this function was merged. this is the index to use to ensure that the parms are sized correctly..
|
||||||
const char *file;
|
string_t s_filed; // source file with definition
|
||||||
|
const char *filen;
|
||||||
int line;
|
int line;
|
||||||
char *name; //internal name of function
|
char *name; //internal name of function
|
||||||
struct QCC_function_s *parentscope; //for nested functions
|
struct QCC_function_s *parentscope; //for nested functions
|
||||||
|
@ -568,6 +572,8 @@ extern pbool keyword_nosave; //don't write the def to the output.
|
||||||
extern pbool keyword_inline; //don't write the def to the output.
|
extern pbool keyword_inline; //don't write the def to the output.
|
||||||
extern pbool keyword_strip; //don't write the def to the output.
|
extern pbool keyword_strip; //don't write the def to the output.
|
||||||
extern pbool keyword_union; //you surly know what a union is!
|
extern pbool keyword_union; //you surly know what a union is!
|
||||||
|
extern pbool keyword_wrap;
|
||||||
|
extern pbool keyword_weak;
|
||||||
|
|
||||||
extern pbool keyword_unused;
|
extern pbool keyword_unused;
|
||||||
extern pbool keyword_used;
|
extern pbool keyword_used;
|
||||||
|
@ -885,6 +891,8 @@ extern compiler_flag_t compiler_flag[];
|
||||||
extern unsigned char qccwarningaction[WARN_MAX];
|
extern unsigned char qccwarningaction[WARN_MAX];
|
||||||
|
|
||||||
extern jmp_buf pr_parse_abort; // longjump with this on parse error
|
extern jmp_buf pr_parse_abort; // longjump with this on parse error
|
||||||
|
extern const char *s_filen; //name of the file we're currently compiling.
|
||||||
|
extern QCC_string_t s_filed; //name of the file we're currently compiling, as seen by whoever reads the .dat
|
||||||
extern int pr_source_line;
|
extern int pr_source_line;
|
||||||
extern char *pr_file_p;
|
extern char *pr_file_p;
|
||||||
|
|
||||||
|
@ -906,16 +914,18 @@ extern int pr_error_count, pr_warning_count;
|
||||||
|
|
||||||
void QCC_PR_NewLine (pbool incomment);
|
void QCC_PR_NewLine (pbool incomment);
|
||||||
#define GDF_NONE 0
|
#define GDF_NONE 0
|
||||||
#define GDF_SAVED 1
|
#define GDF_SAVED 1
|
||||||
#define GDF_STATIC 2
|
#define GDF_STATIC 2
|
||||||
#define GDF_CONST 4
|
#define GDF_CONST 4
|
||||||
#define GDF_STRIP 8 //always stripped, regardless of optimisations. used for class member fields
|
#define GDF_STRIP 8 //always stripped, regardless of optimisations. used for class member fields
|
||||||
#define GDF_SILENT 16 //used by the gui, to suppress ALL warnings associated with querying the def.
|
#define GDF_SILENT 16 //used by the gui, to suppress ALL warnings associated with querying the def.
|
||||||
#define GDF_INLINE 32 //attempt to inline calls to this function
|
#define GDF_INLINE 32 //attempt to inline calls to this function
|
||||||
#define GDF_USED 64 //don't strip this, ever.
|
#define GDF_USED 64 //don't strip this, ever.
|
||||||
|
#define GDF_BASICTYPE 128 //don't care about #merge types not being known correctly.
|
||||||
QCC_def_t *QCC_PR_GetDef (QCC_type_t *type, char *name, struct QCC_function_s *scope, pbool allocate, int arraysize, unsigned int flags);
|
QCC_def_t *QCC_PR_GetDef (QCC_type_t *type, char *name, struct QCC_function_s *scope, pbool allocate, int arraysize, unsigned int flags);
|
||||||
QCC_sref_t QCC_PR_GetSRef (QCC_type_t *type, char *name, struct QCC_function_s *scope, pbool allocate, int arraysize, unsigned int flags);
|
QCC_sref_t QCC_PR_GetSRef (QCC_type_t *type, char *name, struct QCC_function_s *scope, pbool allocate, int arraysize, unsigned int flags);
|
||||||
void QCC_FreeTemp(QCC_sref_t t);
|
void QCC_FreeTemp(QCC_sref_t t);
|
||||||
|
void QCC_FreeDef(QCC_def_t *def);
|
||||||
char *QCC_PR_CheckCompConstTooltip(char *word, char *outstart, char *outend);
|
char *QCC_PR_CheckCompConstTooltip(char *word, char *outstart, char *outend);
|
||||||
|
|
||||||
void QCC_PR_PrintDefs (void);
|
void QCC_PR_PrintDefs (void);
|
||||||
|
@ -940,8 +950,6 @@ void QCC_PR_ResetErrorScope(void);
|
||||||
|
|
||||||
extern pbool pr_dumpasm;
|
extern pbool pr_dumpasm;
|
||||||
|
|
||||||
extern QCC_string_t s_file; // filename for function definition
|
|
||||||
|
|
||||||
extern QCC_def_t def_ret, def_parms[MAX_PARMS];
|
extern QCC_def_t def_ret, def_parms[MAX_PARMS];
|
||||||
|
|
||||||
void QCC_PR_EmitArrayGetFunction(QCC_def_t *defscope, QCC_def_t *thearray, char *arrayname);
|
void QCC_PR_EmitArrayGetFunction(QCC_def_t *defscope, QCC_def_t *thearray, char *arrayname);
|
||||||
|
@ -1006,7 +1014,7 @@ typedef struct
|
||||||
int block;
|
int block;
|
||||||
int used;
|
int used;
|
||||||
int fileline;
|
int fileline;
|
||||||
char *filename;
|
const char *filename;
|
||||||
} precache_t;
|
} precache_t;
|
||||||
extern precache_t *precache_sound;
|
extern precache_t *precache_sound;
|
||||||
extern int numsounds;
|
extern int numsounds;
|
||||||
|
@ -1060,7 +1068,7 @@ static bool inline QCC_PR_CheckToken (char *string)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void inline QCC_PR_Expect (char *string)
|
static void inline QCC_PR_Expect (const char *string)
|
||||||
{
|
{
|
||||||
if (strcmp (string, pr_token))
|
if (strcmp (string, pr_token))
|
||||||
QCC_PR_ParseError ("expected %s, found %s",string, pr_token);
|
QCC_PR_ParseError ("expected %s, found %s",string, pr_token);
|
||||||
|
@ -1068,12 +1076,13 @@ static void inline QCC_PR_Expect (char *string)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void editbadfile(char *fname, int line);
|
void editbadfile(const char *fname, int line);
|
||||||
char *TypeName(QCC_type_t *type, char *buffer, int buffersize);
|
char *TypeName(QCC_type_t *type, char *buffer, int buffersize);
|
||||||
void QCC_PR_AddIncludePath(const char *newinc);
|
void QCC_PR_AddIncludePath(const char *newinc);
|
||||||
void QCC_PR_IncludeChunk (char *data, pbool duplicate, char *filename);
|
void QCC_PR_IncludeChunk (char *data, pbool duplicate, char *filename);
|
||||||
void QCC_PR_IncludeChunkEx(char *data, pbool duplicate, char *filename, CompilerConstant_t *cnst);
|
void QCC_PR_IncludeChunkEx(char *data, pbool duplicate, char *filename, CompilerConstant_t *cnst);
|
||||||
void QCC_PR_CloseProcessor(void);
|
void QCC_PR_CloseProcessor(void);
|
||||||
|
void QCC_FindBestInclude(char *newfile, char *currentfile, pbool verbose);
|
||||||
pbool QCC_PR_UnInclude(void);
|
pbool QCC_PR_UnInclude(void);
|
||||||
extern void *(*pHash_Get)(hashtable_t *table, const char *name);
|
extern void *(*pHash_Get)(hashtable_t *table, const char *name);
|
||||||
extern void *(*pHash_GetNext)(hashtable_t *table, const char *name, void *old);
|
extern void *(*pHash_GetNext)(hashtable_t *table, const char *name, void *old);
|
||||||
|
|
|
@ -568,7 +568,7 @@ void VARGS QCC_Error (int errortype, const char *error, ...)
|
||||||
printf ("\n************ ERROR ************\n%s\n", msg);
|
printf ("\n************ ERROR ************\n%s\n", msg);
|
||||||
|
|
||||||
|
|
||||||
editbadfile(strings+s_file, pr_source_line);
|
editbadfile(s_filen, pr_source_line);
|
||||||
|
|
||||||
numsourcefiles = 0;
|
numsourcefiles = 0;
|
||||||
|
|
||||||
|
@ -890,7 +890,7 @@ void ResizeBuf(int hand, int newsize)
|
||||||
qccfile[hand].buff = nb;
|
qccfile[hand].buff = nb;
|
||||||
qccfile[hand].buffsize = newsize;
|
qccfile[hand].buffsize = newsize;
|
||||||
}
|
}
|
||||||
void SafeWrite(int hand, void *buf, long count)
|
void SafeWrite(int hand, const void *buf, long count)
|
||||||
{
|
{
|
||||||
if (qccfile[hand].ofs +count >= qccfile[hand].buffsize)
|
if (qccfile[hand].ofs +count >= qccfile[hand].buffsize)
|
||||||
ResizeBuf(hand, qccfile[hand].ofs + count+(64*1024));
|
ResizeBuf(hand, qccfile[hand].ofs + count+(64*1024));
|
||||||
|
@ -1242,6 +1242,7 @@ long QCC_LoadFile (char *filename, void **bufferptr)
|
||||||
mem += sizeof(qcc_cachedsourcefile_t);
|
mem += sizeof(qcc_cachedsourcefile_t);
|
||||||
|
|
||||||
externs->ReadFile(filename, mem, len+2, NULL);
|
externs->ReadFile(filename, mem, len+2, NULL);
|
||||||
|
mem[len] = 0;
|
||||||
|
|
||||||
mem = QCC_SanitizeCharSet(mem, &len, NULL, &orig);
|
mem = QCC_SanitizeCharSet(mem, &len, NULL, &orig);
|
||||||
|
|
||||||
|
|
|
@ -78,6 +78,8 @@ pbool keyword_inline;
|
||||||
pbool keyword_strip;
|
pbool keyword_strip;
|
||||||
pbool keyword_ignore;
|
pbool keyword_ignore;
|
||||||
pbool keyword_union; //you surly know what a union is!
|
pbool keyword_union; //you surly know what a union is!
|
||||||
|
pbool keyword_weak;
|
||||||
|
pbool keyword_wrap;
|
||||||
|
|
||||||
#define keyword_not 1 //hexenc support needs this, and fteqcc can optimise without it, but it adds an extra token after the if, so it can cause no namespace conflicts
|
#define keyword_not 1 //hexenc support needs this, and fteqcc can optimise without it, but it adds an extra token after the if, so it can cause no namespace conflicts
|
||||||
|
|
||||||
|
@ -174,7 +176,7 @@ QCC_sref_t QCC_PR_ParseValue (QCC_type_t *assumeclass, pbool allowarrayassign, p
|
||||||
void QCC_Marshal_Locals(int firststatement, int laststatement);
|
void QCC_Marshal_Locals(int firststatement, int laststatement);
|
||||||
QCC_sref_t QCC_PR_ParseArrayPointer (QCC_sref_t d, pbool allowarrayassign, pbool makestructpointers);
|
QCC_sref_t QCC_PR_ParseArrayPointer (QCC_sref_t d, pbool allowarrayassign, pbool makestructpointers);
|
||||||
QCC_sref_t QCC_LoadFromArray(QCC_sref_t base, QCC_sref_t index, QCC_type_t *t, pbool preserve);
|
QCC_sref_t QCC_LoadFromArray(QCC_sref_t base, QCC_sref_t index, QCC_type_t *t, pbool preserve);
|
||||||
void QCC_PR_ParseInitializerDef(QCC_def_t *def);
|
void QCC_PR_ParseInitializerDef(QCC_def_t *def, unsigned int flags);
|
||||||
|
|
||||||
QCC_ref_t *QCC_DefToRef(QCC_ref_t *ref, QCC_sref_t def); //ref is a buffer to write into, to avoid excessive allocs
|
QCC_ref_t *QCC_DefToRef(QCC_ref_t *ref, QCC_sref_t def); //ref is a buffer to write into, to avoid excessive allocs
|
||||||
QCC_sref_t QCC_RefToDef(QCC_ref_t *ref, pbool freetemps);
|
QCC_sref_t QCC_RefToDef(QCC_ref_t *ref, pbool freetemps);
|
||||||
|
@ -186,7 +188,7 @@ QCC_ref_t *QCC_PR_BuildAccessorRef(QCC_ref_t *retbuf, QCC_sref_t base, QCC_sref_
|
||||||
QCC_sref_t QCC_StoreSRefToRef(QCC_ref_t *dest, QCC_sref_t source, pbool readable, pbool preservedest);
|
QCC_sref_t QCC_StoreSRefToRef(QCC_ref_t *dest, QCC_sref_t source, pbool readable, pbool preservedest);
|
||||||
QCC_sref_t QCC_StoreRefToRef(QCC_ref_t *dest, QCC_ref_t *source, pbool readable, pbool preservedest);
|
QCC_sref_t QCC_StoreRefToRef(QCC_ref_t *dest, QCC_ref_t *source, pbool readable, pbool preservedest);
|
||||||
void QCC_PR_DiscardRef(QCC_ref_t *ref);
|
void QCC_PR_DiscardRef(QCC_ref_t *ref);
|
||||||
QCC_function_t *QCC_PR_ParseImmediateStatements (QCC_def_t *def, QCC_type_t *type);
|
QCC_function_t *QCC_PR_ParseImmediateStatements (QCC_def_t *def, QCC_type_t *type, pbool dowrap);
|
||||||
const char *QCC_VarAtOffset(QCC_sref_t ref, unsigned int size);
|
const char *QCC_VarAtOffset(QCC_sref_t ref, unsigned int size);
|
||||||
QCC_sref_t QCC_EvaluateCast(QCC_sref_t src, QCC_type_t *cast, pbool implicit);
|
QCC_sref_t QCC_EvaluateCast(QCC_sref_t src, QCC_type_t *cast, pbool implicit);
|
||||||
|
|
||||||
|
@ -194,7 +196,7 @@ QCC_statement_t *QCC_Generate_OP_IFNOT(QCC_sref_t e, pbool preserve);
|
||||||
QCC_statement_t *QCC_Generate_OP_IF(QCC_sref_t e, pbool preserve);
|
QCC_statement_t *QCC_Generate_OP_IF(QCC_sref_t e, pbool preserve);
|
||||||
QCC_statement_t *QCC_Generate_OP_GOTO(void);
|
QCC_statement_t *QCC_Generate_OP_GOTO(void);
|
||||||
QCC_sref_t QCC_PR_GenerateLogicalNot(QCC_sref_t e, const char *errormessage);
|
QCC_sref_t QCC_PR_GenerateLogicalNot(QCC_sref_t e, const char *errormessage);
|
||||||
QCC_function_t *QCC_PR_GenerateQCFunction (QCC_def_t *def, QCC_type_t *type);
|
QCC_function_t *QCC_PR_GenerateQCFunction (QCC_def_t *def, QCC_type_t *type, pbool dowrap);
|
||||||
|
|
||||||
//NOTE: prints may use from the func argument's symbol, which can be awkward if its a temp.
|
//NOTE: prints may use from the func argument's symbol, which can be awkward if its a temp.
|
||||||
QCC_sref_t QCC_PR_GenerateFunctionCallSref (QCC_sref_t newself, QCC_sref_t func, QCC_sref_t *arglist, int argcount);
|
QCC_sref_t QCC_PR_GenerateFunctionCallSref (QCC_sref_t newself, QCC_sref_t func, QCC_sref_t *arglist, int argcount);
|
||||||
|
@ -232,7 +234,8 @@ QCC_type_t *pr_assumetermtype; //undefined things get this time, with no warnin
|
||||||
QCC_function_t *pr_assumetermscope;
|
QCC_function_t *pr_assumetermscope;
|
||||||
unsigned int pr_assumetermflags; //GDF_
|
unsigned int pr_assumetermflags; //GDF_
|
||||||
pbool pr_dumpasm;
|
pbool pr_dumpasm;
|
||||||
QCC_string_t s_file, s_file2; // filename for function definition
|
const char *s_filen;
|
||||||
|
QCC_string_t s_filed; // filename for function definition
|
||||||
|
|
||||||
unsigned int locals_marshalled; // largest local block size that needs to be allocated for locals overlapping.
|
unsigned int locals_marshalled; // largest local block size that needs to be allocated for locals overlapping.
|
||||||
|
|
||||||
|
@ -1482,7 +1485,7 @@ pbool QCC_StatementIsAJump(int stnum, int notifdest);
|
||||||
//typically used for debugging. Also used to determine function names for intrinsics.
|
//typically used for debugging. Also used to determine function names for intrinsics.
|
||||||
const char *QCC_GetSRefName(QCC_sref_t ref)
|
const char *QCC_GetSRefName(QCC_sref_t ref)
|
||||||
{
|
{
|
||||||
if (ref.sym && ref.sym->name && !ref.ofs)
|
if (ref.sym && ref.sym->name/* && !ref.ofs*/)
|
||||||
{
|
{
|
||||||
if (ref.sym->temp)
|
if (ref.sym->temp)
|
||||||
return ref.cast->name;
|
return ref.cast->name;
|
||||||
|
@ -4259,7 +4262,7 @@ void QCC_PrecacheSound (const char *n, int ch)
|
||||||
// QCC_Error ("PrecacheSound: numsounds == MAX_SOUNDS");
|
// QCC_Error ("PrecacheSound: numsounds == MAX_SOUNDS");
|
||||||
strcpy (precache_sound[i].name, n);
|
strcpy (precache_sound[i].name, n);
|
||||||
precache_sound[i].block = ch;
|
precache_sound[i].block = ch;
|
||||||
precache_sound[i].filename = strings+s_file;
|
precache_sound[i].filename = s_filen;
|
||||||
precache_sound[i].fileline = pr_source_line;
|
precache_sound[i].fileline = pr_source_line;
|
||||||
numsounds++;
|
numsounds++;
|
||||||
}
|
}
|
||||||
|
@ -4290,7 +4293,7 @@ void QCC_PrecacheModel (const char *n, int ch)
|
||||||
precache_model[i].block = ch - '0';
|
precache_model[i].block = ch - '0';
|
||||||
else
|
else
|
||||||
precache_model[i].block = 1;
|
precache_model[i].block = 1;
|
||||||
precache_model[i].filename = strings+s_file;
|
precache_model[i].filename = s_filen;
|
||||||
precache_model[i].fileline = pr_source_line;
|
precache_model[i].fileline = pr_source_line;
|
||||||
nummodels++;
|
nummodels++;
|
||||||
}
|
}
|
||||||
|
@ -4313,7 +4316,7 @@ void QCC_SetModel (const char *n)
|
||||||
precache_model[i].block = 0;
|
precache_model[i].block = 0;
|
||||||
precache_model[i].used=1;
|
precache_model[i].used=1;
|
||||||
|
|
||||||
precache_model[i].filename = strings+s_file;
|
precache_model[i].filename = s_filen;
|
||||||
precache_model[i].fileline = pr_source_line;
|
precache_model[i].fileline = pr_source_line;
|
||||||
nummodels++;
|
nummodels++;
|
||||||
}
|
}
|
||||||
|
@ -4335,7 +4338,7 @@ void QCC_SoundUsed (const char *n)
|
||||||
precache_sound[i].block = 0;
|
precache_sound[i].block = 0;
|
||||||
precache_sound[i].used=1;
|
precache_sound[i].used=1;
|
||||||
|
|
||||||
precache_sound[i].filename = strings+s_file;
|
precache_sound[i].filename = s_filen;
|
||||||
precache_sound[i].fileline = pr_source_line;
|
precache_sound[i].fileline = pr_source_line;
|
||||||
numsounds++;
|
numsounds++;
|
||||||
}
|
}
|
||||||
|
@ -6485,7 +6488,7 @@ void QCC_PR_EmitClassFromFunction(QCC_def_t *scope, QCC_type_t *basetype)
|
||||||
|
|
||||||
pr_source_line = pr_token_line_last = scope->s_line;
|
pr_source_line = pr_token_line_last = scope->s_line;
|
||||||
|
|
||||||
pr_scope = QCC_PR_GenerateQCFunction(scope, scope->type);
|
pr_scope = QCC_PR_GenerateQCFunction(scope, scope->type, false);
|
||||||
//reset the locals chain
|
//reset the locals chain
|
||||||
pr.local_head.nextlocal = NULL;
|
pr.local_head.nextlocal = NULL;
|
||||||
pr.local_tail = &pr.local_head;
|
pr.local_tail = &pr.local_head;
|
||||||
|
@ -7282,7 +7285,7 @@ QCC_ref_t *QCC_PR_ParseRefValue (QCC_ref_t *refbuf, QCC_type_t *assumeclass, pbo
|
||||||
{
|
{
|
||||||
QCC_PR_ParseWarning (ERR_UNKNOWNVALUE, "Class \"%s\" is not defined, cannot access memeber \"%s\"", assumeclass->name, name);
|
QCC_PR_ParseWarning (ERR_UNKNOWNVALUE, "Class \"%s\" is not defined, cannot access memeber \"%s\"", assumeclass->name, name);
|
||||||
if (!autoprototype && !autoprototyped)
|
if (!autoprototype && !autoprototyped)
|
||||||
QCC_PR_Note(ERR_UNKNOWNVALUE, strings+s_file, pr_source_line, "Consider using #pragma autoproto");
|
QCC_PR_Note(ERR_UNKNOWNVALUE, s_filen, pr_source_line, "Consider using #pragma autoproto");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -7515,6 +7518,8 @@ QCC_sref_t QCC_EvaluateCast(QCC_sref_t src, QCC_type_t *cast, pbool implicit)
|
||||||
}
|
}
|
||||||
else if (!implicit && !typecmp_lax(src.cast, cast))
|
else if (!implicit && !typecmp_lax(src.cast, cast))
|
||||||
src.cast = cast;
|
src.cast = cast;
|
||||||
|
else if (!implicit && cast->type == ev_void)
|
||||||
|
src.cast = type_void; //anything can be cast to void, but only do it explicitly.
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char typea[256];
|
char typea[256];
|
||||||
|
@ -7704,7 +7709,7 @@ QCC_ref_t *QCC_PR_RefTerm (QCC_ref_t *retbuf, unsigned int exprflags)
|
||||||
e = nullsref;
|
e = nullsref;
|
||||||
e.cast = type_float;
|
e.cast = type_float;
|
||||||
patch = QCC_Generate_OP_GOTO();
|
patch = QCC_Generate_OP_GOTO();
|
||||||
e = QCC_MakeIntConst(QCC_PR_ParseImmediateStatements (NULL, newtype) - functions);
|
e = QCC_MakeIntConst(QCC_PR_ParseImmediateStatements (NULL, newtype, false) - functions);
|
||||||
e.cast = newtype;
|
e.cast = newtype;
|
||||||
patch->a.ofs = &statements[numstatements] - patch;
|
patch->a.ofs = &statements[numstatements] - patch;
|
||||||
|
|
||||||
|
@ -9590,7 +9595,7 @@ void QCC_PR_ParseStatement_For(void)
|
||||||
{
|
{
|
||||||
d = QCC_PR_GetDef (type, QCC_PR_ParseName(), pr_scope, true, 0, 0);
|
d = QCC_PR_GetDef (type, QCC_PR_ParseName(), pr_scope, true, 0, 0);
|
||||||
QCC_PR_Expect("=");
|
QCC_PR_Expect("=");
|
||||||
QCC_PR_ParseInitializerDef(d);
|
QCC_PR_ParseInitializerDef(d, 0);
|
||||||
QCC_FreeDef(d);
|
QCC_FreeDef(d);
|
||||||
QCC_FreeDef(d);
|
QCC_FreeDef(d);
|
||||||
}
|
}
|
||||||
|
@ -11114,7 +11119,7 @@ void QCC_CheckForDeadAndMissingReturns(int first, int last, int rettype)
|
||||||
}
|
}
|
||||||
if (st2 == last)
|
if (st2 == last)
|
||||||
{
|
{
|
||||||
QCC_PR_Warning(WARN_UNREACHABLECODE, pr_scope->file, statements[st].linenum, "%s: contains unreachable code (line %i)", pr_scope->name, statements[st].linenum);
|
QCC_PR_Warning(WARN_UNREACHABLECODE, pr_scope->filen, statements[st].linenum, "%s: contains unreachable code (line %i)", pr_scope->name, statements[st].linenum);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -11287,12 +11292,12 @@ int QCC_CheckOneUninitialised(int firststatement, int laststatement, QCC_def_t *
|
||||||
|
|
||||||
if (st->op == OP_DONE || st->op == OP_RETURN)
|
if (st->op == OP_DONE || st->op == OP_RETURN)
|
||||||
{
|
{
|
||||||
if (st->a.sym == def && st->a.ofs >= min && st->a.ofs < max)
|
if (st->a.sym && st->a.sym->symbolheader == def && st->a.ofs >= min && st->a.ofs < max)
|
||||||
return i;
|
return i;
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (st->op == OP_GLOBALADDRESS && (st->a.sym == def || (st->a.sym == def->symbolheader)))
|
if (st->op == OP_GLOBALADDRESS && (st->a.sym->symbolheader == def || (st->a.sym->symbolheader == def)))
|
||||||
return -1; //assume taking a pointer to it is an initialisation.
|
return -1; //assume taking a pointer to it is an initialisation.
|
||||||
|
|
||||||
// this code catches gotos, but can cause issues with while statements.
|
// this code catches gotos, but can cause issues with while statements.
|
||||||
|
@ -11301,7 +11306,7 @@ int QCC_CheckOneUninitialised(int firststatement, int laststatement, QCC_def_t *
|
||||||
|
|
||||||
if (pr_opcodes[st->op].type_a)
|
if (pr_opcodes[st->op].type_a)
|
||||||
{
|
{
|
||||||
if (st->a.sym == def && st->a.ofs >= min && st->a.ofs < max)
|
if (st->a.sym && st->a.sym->symbolheader == def && st->a.ofs >= min && st->a.ofs < max)
|
||||||
{
|
{
|
||||||
if (OpAssignsToA(st->op))
|
if (OpAssignsToA(st->op))
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -11320,7 +11325,7 @@ int QCC_CheckOneUninitialised(int firststatement, int laststatement, QCC_def_t *
|
||||||
|
|
||||||
if (pr_opcodes[st->op].type_b)
|
if (pr_opcodes[st->op].type_b)
|
||||||
{
|
{
|
||||||
if (st->b.sym == def && st->b.ofs >= min && st->b.ofs < max)
|
if (st->b.sym && st->b.sym->symbolheader == def && st->b.ofs >= min && st->b.ofs < max)
|
||||||
{
|
{
|
||||||
if (OpAssignsToB(st->op))
|
if (OpAssignsToB(st->op))
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -11356,7 +11361,7 @@ int QCC_CheckOneUninitialised(int firststatement, int laststatement, QCC_def_t *
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pr_opcodes[st->op].type_c && st->c.sym == def && st->c.ofs >= min && st->c.ofs < max)
|
if (pr_opcodes[st->op].type_c && st->c.sym && st->c.sym->symbolheader == def && st->c.ofs >= min && st->c.ofs < max)
|
||||||
{
|
{
|
||||||
if (OpAssignsToC(st->op))
|
if (OpAssignsToC(st->op))
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -11407,7 +11412,7 @@ pbool QCC_CheckUninitialised(int firststatement, int laststatement)
|
||||||
err = QCC_CheckOneUninitialised(firststatement, laststatement, local, local->ofs, local->ofs + local->type->size * (local->arraysize?local->arraysize:1));
|
err = QCC_CheckOneUninitialised(firststatement, laststatement, local, local->ofs, local->ofs + local->type->size * (local->arraysize?local->arraysize:1));
|
||||||
if (err > 0)
|
if (err > 0)
|
||||||
{
|
{
|
||||||
QCC_PR_Warning(WARN_UNINITIALIZED, strings+s_file, statements[err].linenum, "Potentially uninitialised variable %s", local->name);
|
QCC_PR_Warning(WARN_UNINITIALIZED, s_filen, statements[err].linenum, "Potentially uninitialised variable %s", local->name);
|
||||||
result = true;
|
result = true;
|
||||||
// break;
|
// break;
|
||||||
}
|
}
|
||||||
|
@ -11448,13 +11453,13 @@ void QCC_Marshal_Locals(int firststatement, int laststatement)
|
||||||
//these matter when the function goes recursive (and locals marshalling counts as recursive every time).
|
//these matter when the function goes recursive (and locals marshalling counts as recursive every time).
|
||||||
if (local->symboldata[local->ofs]._int)
|
if (local->symboldata[local->ofs]._int)
|
||||||
{
|
{
|
||||||
QCC_PR_Note(ERR_INTERNAL, strings+local->s_file, local->s_line, "Marshaling non-const initialised %s", local->name);
|
QCC_PR_Note(ERR_INTERNAL, local->filen, local->s_line, "Marshaling non-const initialised %s", local->name);
|
||||||
error = true;
|
error = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (local->constant)
|
if (local->constant)
|
||||||
{
|
{
|
||||||
QCC_PR_Note(ERR_INTERNAL, strings+local->s_file, local->s_line, "Marshaling const %s", local->name);
|
QCC_PR_Note(ERR_INTERNAL, local->filen, local->s_line, "Marshaling const %s", local->name);
|
||||||
error = true;
|
error = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11551,9 +11556,9 @@ void QCC_WriteGUIAsmFunction(QCC_function_t *sc, unsigned int firststatement)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (currentsourcefile)
|
if (currentsourcefile)
|
||||||
printf("code: %s:%i: %i:%s;\n", sc->file, statements[i].linenum, currentsourcefile, line);
|
printf("code: %s:%i: %i:%s;\n", sc->filen, statements[i].linenum, currentsourcefile, line);
|
||||||
else
|
else
|
||||||
printf("code: %s:%i: %s;\n", sc->file, statements[i].linenum, line);
|
printf("code: %s:%i: %s;\n", sc->filen, statements[i].linenum, line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11649,8 +11654,8 @@ QCC_function_t *QCC_PR_GenerateBuiltinFunction (QCC_def_t *def, int builtinnum)
|
||||||
if (numfunctions >= MAX_FUNCTIONS)
|
if (numfunctions >= MAX_FUNCTIONS)
|
||||||
QCC_PR_ParseError(ERR_INTERNAL, "Too many functions - %i\nAdd \"MAX_FUNCTIONS\" \"%i\" to qcc.cfg", numfunctions, (numfunctions+4096)&~4095);
|
QCC_PR_ParseError(ERR_INTERNAL, "Too many functions - %i\nAdd \"MAX_FUNCTIONS\" \"%i\" to qcc.cfg", numfunctions, (numfunctions+4096)&~4095);
|
||||||
func = &functions[numfunctions++];
|
func = &functions[numfunctions++];
|
||||||
func->s_file = s_file2;
|
func->filen = s_filen;
|
||||||
func->file = strings+s_file;
|
func->s_filed = s_filed;
|
||||||
func->line = def->s_line; //FIXME
|
func->line = def->s_line; //FIXME
|
||||||
func->name = def->name;
|
func->name = def->name;
|
||||||
func->builtin = builtinnum;
|
func->builtin = builtinnum;
|
||||||
|
@ -11660,14 +11665,32 @@ QCC_function_t *QCC_PR_GenerateBuiltinFunction (QCC_def_t *def, int builtinnum)
|
||||||
func->def = def;
|
func->def = def;
|
||||||
return func;
|
return func;
|
||||||
}
|
}
|
||||||
QCC_function_t *QCC_PR_GenerateQCFunction (QCC_def_t *def, QCC_type_t *type)
|
QCC_function_t *QCC_PR_GenerateQCFunction (QCC_def_t *def, QCC_type_t *type, pbool dowrap)
|
||||||
{
|
{
|
||||||
QCC_function_t *func;
|
QCC_function_t *func;
|
||||||
if (numfunctions >= MAX_FUNCTIONS)
|
if (numfunctions >= MAX_FUNCTIONS)
|
||||||
QCC_PR_ParseError(ERR_INTERNAL, "Too many functions - %i\nAdd \"MAX_FUNCTIONS\" \"%i\" to qcc.cfg", numfunctions, (numfunctions+4096)&~4095);
|
QCC_PR_ParseError(ERR_INTERNAL, "Too many functions - %i\nAdd \"MAX_FUNCTIONS\" \"%i\" to qcc.cfg", numfunctions, (numfunctions+4096)&~4095);
|
||||||
func = &functions[numfunctions++];
|
if (dowrap && def->symboldata[0].function)
|
||||||
func->s_file = s_file2;
|
{
|
||||||
func->file = strings+s_file;
|
QCC_def_t *locals;
|
||||||
|
QCC_function_t *prior = &functions[numfunctions++];
|
||||||
|
func = &functions[def->symboldata[0].function];
|
||||||
|
memcpy(prior, func, sizeof(*prior));
|
||||||
|
memset(func, 0, sizeof(*func));
|
||||||
|
|
||||||
|
for (locals = prior->firstlocal; locals; locals = locals->nextlocal)
|
||||||
|
{
|
||||||
|
if (locals->scope != func)
|
||||||
|
QCC_PR_ParseError(ERR_INTERNAL, "internal consistency check failed while wrapping %s", def->name);
|
||||||
|
locals->scope = prior;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (dowrap)
|
||||||
|
QCC_PR_ParseError(ERR_INTERNAL, "cannot wrap bodyless function %s", def->name);
|
||||||
|
else
|
||||||
|
func = &functions[numfunctions++];
|
||||||
|
func->filen = s_filen;
|
||||||
|
func->s_filed = s_filed;
|
||||||
func->line = pr_source_line;//def?def->s_line:0; //FIXME
|
func->line = pr_source_line;//def?def->s_line:0; //FIXME
|
||||||
func->name = def?def->name:"";
|
func->name = def?def->name:"";
|
||||||
func->builtin = 0;
|
func->builtin = 0;
|
||||||
|
@ -11688,13 +11711,15 @@ Parse a function body
|
||||||
If def is set, allows stuff to refer back to a def for the function.
|
If def is set, allows stuff to refer back to a def for the function.
|
||||||
============
|
============
|
||||||
*/
|
*/
|
||||||
QCC_function_t *QCC_PR_ParseImmediateStatements (QCC_def_t *def, QCC_type_t *type)
|
QCC_function_t *QCC_PR_ParseImmediateStatements (QCC_def_t *def, QCC_type_t *type, pbool dowrap)
|
||||||
{
|
{
|
||||||
unsigned int u, p;
|
unsigned int u, p;
|
||||||
QCC_function_t *f;
|
QCC_function_t *f;
|
||||||
QCC_sref_t parm;
|
QCC_sref_t parm;
|
||||||
pbool needsdone=false;
|
pbool needsdone=false;
|
||||||
|
|
||||||
|
QCC_def_t *prior = NULL;
|
||||||
|
|
||||||
conditional = 0;
|
conditional = 0;
|
||||||
|
|
||||||
expandedemptymacro = false;
|
expandedemptymacro = false;
|
||||||
|
@ -11735,7 +11760,7 @@ QCC_function_t *QCC_PR_ParseImmediateStatements (QCC_def_t *def, QCC_type_t *typ
|
||||||
// if (type->vargs)
|
// if (type->vargs)
|
||||||
// QCC_PR_ParseError (ERR_FUNCTIONWITHVARGS, "QC function with variable arguments and function body");
|
// QCC_PR_ParseError (ERR_FUNCTIONWITHVARGS, "QC function with variable arguments and function body");
|
||||||
|
|
||||||
pr_scope = f = QCC_PR_GenerateQCFunction(def, type);
|
pr_scope = f = QCC_PR_GenerateQCFunction(def, type, dowrap);
|
||||||
|
|
||||||
//reset the locals chain
|
//reset the locals chain
|
||||||
pr.local_head.nextlocal = NULL;
|
pr.local_head.nextlocal = NULL;
|
||||||
|
@ -11799,6 +11824,20 @@ QCC_function_t *QCC_PR_ParseImmediateStatements (QCC_def_t *def, QCC_type_t *typ
|
||||||
QCC_FreeTemp(parm);
|
QCC_FreeTemp(parm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dowrap)
|
||||||
|
{ //if we're wrapping, then we moved the old function entry to the end and reused it for our function.
|
||||||
|
//so we need to define some local that refers to the prior def.
|
||||||
|
QCC_sref_t priorim = QCC_MakeIntConst(numfunctions-1);
|
||||||
|
prior;
|
||||||
|
prior = QCC_PR_DummyDef(f->type, "prior", f, 0, priorim.sym, 0, true, GDF_CONST); //create a union into it
|
||||||
|
prior->initialized = true;
|
||||||
|
prior->filen = functions[numfunctions-1].filen;
|
||||||
|
prior->s_filed = functions[numfunctions-1].s_filed;
|
||||||
|
prior->s_line = functions[numfunctions-1].line;
|
||||||
|
|
||||||
|
QCC_FreeTemp(priorim);
|
||||||
|
}
|
||||||
|
|
||||||
if (type->vargcount)
|
if (type->vargcount)
|
||||||
{
|
{
|
||||||
if (!pr_parm_argcount_name)
|
if (!pr_parm_argcount_name)
|
||||||
|
@ -11899,6 +11938,9 @@ QCC_function_t *QCC_PR_ParseImmediateStatements (QCC_def_t *def, QCC_type_t *typ
|
||||||
}
|
}
|
||||||
QCC_FreeTemps();
|
QCC_FreeTemps();
|
||||||
|
|
||||||
|
if (prior && !prior->referenced)
|
||||||
|
QCC_PR_ParseError(ERR_REDECLARATION, "Wrapper function does not refer to its prior function");
|
||||||
|
|
||||||
pr_token_line_last = pr_token_line;
|
pr_token_line_last = pr_token_line;
|
||||||
|
|
||||||
// this is cheap
|
// this is cheap
|
||||||
|
@ -12089,7 +12131,8 @@ QCC_def_t *QCC_PR_EmitArrayGetVector(QCC_sref_t array)
|
||||||
numslots = array.sym->arraysize*array.cast->size;
|
numslots = array.sym->arraysize*array.cast->size;
|
||||||
numslots = (numslots+2)/3;
|
numslots = (numslots+2)/3;
|
||||||
|
|
||||||
s_file = array.sym->s_file;
|
s_filen = array.sym->filen;
|
||||||
|
s_filed = array.sym->s_filed;
|
||||||
func = QCC_PR_GetDef(ftype, qcva("ArrayGetVec*%s", array.sym->name), NULL, true, 0, false);
|
func = QCC_PR_GetDef(ftype, qcva("ArrayGetVec*%s", array.sym->name), NULL, true, 0, false);
|
||||||
|
|
||||||
pr_source_line = pr_token_line_last = array.sym->s_line; //thankfully these functions are emitted after compilation.
|
pr_source_line = pr_token_line_last = array.sym->s_line; //thankfully these functions are emitted after compilation.
|
||||||
|
@ -12097,9 +12140,10 @@ QCC_def_t *QCC_PR_EmitArrayGetVector(QCC_sref_t array)
|
||||||
if (numfunctions >= MAX_FUNCTIONS)
|
if (numfunctions >= MAX_FUNCTIONS)
|
||||||
QCC_Error(ERR_INTERNAL, "Too many function defs");
|
QCC_Error(ERR_INTERNAL, "Too many function defs");
|
||||||
|
|
||||||
pr_scope = QCC_PR_GenerateQCFunction(func, ftype);
|
pr_scope = QCC_PR_GenerateQCFunction(func, ftype, false);
|
||||||
pr_source_line = pr_token_line_last = pr_scope->line = array.sym->s_line; //thankfully these functions are emitted after compilation.
|
pr_source_line = pr_token_line_last = pr_scope->line = array.sym->s_line; //thankfully these functions are emitted after compilation.
|
||||||
pr_scope->s_file = array.sym->s_file;
|
pr_scope->filen = array.sym->filen;
|
||||||
|
pr_scope->s_filed = array.sym->s_filed;
|
||||||
func->symboldata[func->ofs]._int = pr_scope - functions;
|
func->symboldata[func->ofs]._int = pr_scope - functions;
|
||||||
|
|
||||||
index = QCC_PR_GetSRef(type_float, "index___", pr_scope, true, 0, false);
|
index = QCC_PR_GetSRef(type_float, "index___", pr_scope, true, 0, false);
|
||||||
|
@ -12143,7 +12187,8 @@ void QCC_PR_EmitArrayGetFunction(QCC_def_t *scope, QCC_def_t *arraydef, char *ar
|
||||||
// if (flag_fasttrackarrays && numslots > 6)
|
// if (flag_fasttrackarrays && numslots > 6)
|
||||||
// fasttrackpossible = QCC_PR_GetSRef(type_float, "__ext__fasttrackarrays", NULL, true, 0, false);
|
// fasttrackpossible = QCC_PR_GetSRef(type_float, "__ext__fasttrackarrays", NULL, true, 0, false);
|
||||||
|
|
||||||
s_file = scope->s_file;
|
s_filen = scope->filen;
|
||||||
|
s_filed = scope->s_filed;
|
||||||
|
|
||||||
vectortrick = nullsref;
|
vectortrick = nullsref;
|
||||||
// if (numslots >= 15 && thearray.cast->type != ev_vector)
|
// if (numslots >= 15 && thearray.cast->type != ev_vector)
|
||||||
|
@ -12152,9 +12197,10 @@ void QCC_PR_EmitArrayGetFunction(QCC_def_t *scope, QCC_def_t *arraydef, char *ar
|
||||||
// vectortrick.cast = vectortrick.sym->type;
|
// vectortrick.cast = vectortrick.sym->type;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
pr_scope = QCC_PR_GenerateQCFunction(scope, scope->type);
|
pr_scope = QCC_PR_GenerateQCFunction(scope, scope->type, false);
|
||||||
pr_source_line = pr_token_line_last = pr_scope->line = thearray.sym->s_line; //thankfully these functions are emitted after compilation.
|
pr_source_line = pr_token_line_last = pr_scope->line = thearray.sym->s_line; //thankfully these functions are emitted after compilation.
|
||||||
pr_scope->s_file = thearray.sym->s_file;
|
pr_scope->filen = thearray.sym->filen;
|
||||||
|
pr_scope->s_filed = thearray.sym->s_filed;
|
||||||
|
|
||||||
index = QCC_PR_GetSRef(type_float, "__indexg", pr_scope, true, 0, false);
|
index = QCC_PR_GetSRef(type_float, "__indexg", pr_scope, true, 0, false);
|
||||||
|
|
||||||
|
@ -12334,10 +12380,12 @@ void QCC_PR_EmitArraySetFunction(QCC_def_t *scope, QCC_def_t *arraydef, char *ar
|
||||||
if (numfunctions >= MAX_FUNCTIONS)
|
if (numfunctions >= MAX_FUNCTIONS)
|
||||||
QCC_Error(ERR_INTERNAL, "Too many function defs");
|
QCC_Error(ERR_INTERNAL, "Too many function defs");
|
||||||
|
|
||||||
s_file = arraydef->s_file;
|
s_filen = arraydef->filen;
|
||||||
pr_scope = QCC_PR_GenerateQCFunction(scope, scope->type);
|
s_filed = arraydef->s_filed;
|
||||||
|
pr_scope = QCC_PR_GenerateQCFunction(scope, scope->type, false);
|
||||||
pr_source_line = pr_token_line_last = pr_scope->line = thearray.sym->s_line; //thankfully these functions are emitted after compilation.
|
pr_source_line = pr_token_line_last = pr_scope->line = thearray.sym->s_line; //thankfully these functions are emitted after compilation.
|
||||||
pr_scope->s_file = thearray.sym->s_file;
|
pr_scope->filen = thearray.sym->filen;
|
||||||
|
pr_scope->s_filed = thearray.sym->s_filed;
|
||||||
|
|
||||||
index = QCC_PR_GetSRef(type_float, "indexs___", pr_scope, true, 0, false);
|
index = QCC_PR_GetSRef(type_float, "indexs___", pr_scope, true, 0, false);
|
||||||
value = QCC_PR_GetSRef(thearray.cast, "value___", pr_scope, true, 0, false);
|
value = QCC_PR_GetSRef(thearray.cast, "value___", pr_scope, true, 0, false);
|
||||||
|
@ -12467,7 +12515,8 @@ QCC_def_t *QCC_PR_DummyDef(QCC_type_t *type, char *name, QCC_function_t *scope,
|
||||||
}
|
}
|
||||||
|
|
||||||
def->s_line = pr_source_line;
|
def->s_line = pr_source_line;
|
||||||
def->s_file = s_file;
|
def->filen = s_filen;
|
||||||
|
def->s_filed = s_filed;
|
||||||
if (a>=0)
|
if (a>=0)
|
||||||
def->initialized = 1;
|
def->initialized = 1;
|
||||||
|
|
||||||
|
@ -12517,7 +12566,7 @@ QCC_def_t *QCC_PR_DummyDef(QCC_type_t *type, char *name, QCC_function_t *scope,
|
||||||
}
|
}
|
||||||
|
|
||||||
def->symbolheader = rootsymbol;
|
def->symbolheader = rootsymbol;
|
||||||
def->symboldata = rootsymbol->symboldata;
|
def->symboldata = rootsymbol->symboldata + def->ofs;
|
||||||
def->symbolsize = (def->arraysize?def->arraysize:1) * type->size;
|
def->symbolsize = (def->arraysize?def->arraysize:1) * type->size;
|
||||||
|
|
||||||
if (type->type == ev_struct && (!arraysize || a>=0))
|
if (type->type == ev_struct && (!arraysize || a>=0))
|
||||||
|
@ -12732,7 +12781,7 @@ QCC_def_t *QCC_PR_GetDef (QCC_type_t *type, char *name, struct QCC_function_s *s
|
||||||
}
|
}
|
||||||
|
|
||||||
//ignore it if its static in some other file.
|
//ignore it if its static in some other file.
|
||||||
if (def->isstatic && strcmp(strings+def->s_file, strings+s_file))
|
if (def->isstatic && strcmp(def->filen, s_filen))
|
||||||
{
|
{
|
||||||
if (!foundstatic)
|
if (!foundstatic)
|
||||||
foundstatic = def; //save it off purely as a warning.
|
foundstatic = def; //save it off purely as a warning.
|
||||||
|
@ -12740,24 +12789,56 @@ QCC_def_t *QCC_PR_GetDef (QCC_type_t *type, char *name, struct QCC_function_s *s
|
||||||
continue; // in a different function
|
continue; // in a different function
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (def->assumedtype && !(flags & GDF_BASICTYPE))
|
||||||
|
{
|
||||||
|
if (allocate)
|
||||||
|
{ //if we're asserting a type for it in some def then it'll no longer be assumed.
|
||||||
|
if (def->type->type != type->type)
|
||||||
|
QCC_PR_ParseErrorPrintDef (ERR_TYPEMISMATCHREDEC, def, "Type mismatch on redeclaration of %s. Basic types are different.",name);
|
||||||
|
def->type = type;
|
||||||
|
def->assumedtype = false;
|
||||||
|
def->filen = s_filen;
|
||||||
|
def->s_line = pr_source_line;
|
||||||
|
if (flags & GDF_CONST)
|
||||||
|
def->constant = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ //we know enough of its type to write it out, but not enough to actually use it safely, so pretend this def isn't defined yet.
|
||||||
|
def = pHash_GetNext(&globalstable, name, def);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (type && typecmp(def->type, type))
|
if (type && typecmp(def->type, type))
|
||||||
{
|
{
|
||||||
if (pr_scope || typecmp_lax(def->type, type))
|
if (pr_scope || typecmp_lax(def->type, type))
|
||||||
{
|
{
|
||||||
if (!strcmp("droptofloor", def->name) || //vanilla
|
if (!pr_scope && (
|
||||||
|
!strcmp("droptofloor", def->name) || //vanilla
|
||||||
!strcmp("callfunction", def->name) || //should be (..., string name) but dpextensions gets this wrong.
|
!strcmp("callfunction", def->name) || //should be (..., string name) but dpextensions gets this wrong.
|
||||||
!strcmp("trailparticles", def->name) //dp got the two arguments the wrong way. fteqw doesn't care any more, but dp is still wrong.
|
!strcmp("trailparticles", def->name) //dp got the two arguments the wrong way. fteqw doesn't care any more, but dp is still wrong.
|
||||||
)
|
))
|
||||||
{
|
{
|
||||||
//this is a hack. droptofloor was wrongly declared in vanilla qc, which causes problems with replacement extensions.qc.
|
//this is a hack. droptofloor was wrongly declared in vanilla qc, which causes problems with replacement extensions.qc.
|
||||||
//yes, this is a selfish lazy hack for this, there's probably a better way, but at least we spit out a warning still.
|
//yes, this is a selfish lazy hack for this, there's probably a better way, but at least we spit out a warning still.
|
||||||
QCC_PR_ParseWarning (WARN_COMPATIBILITYHACK, "%s builtin was wrongly defined as %s. ignoring invalid dupe definition",name, TypeName(type, typebuf1, sizeof(typebuf1)));
|
QCC_PR_ParseWarning (WARN_COMPATIBILITYHACK, "%s builtin was wrongly defined as %s. ignoring later definition",name, TypeName(type, typebuf1, sizeof(typebuf1)));
|
||||||
QCC_PR_ParsePrintDef(WARN_COMPATIBILITYHACK, def);
|
QCC_PR_ParsePrintDef(WARN_COMPATIBILITYHACK, def);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//unequal even when we're lax
|
int flen = strlen(s_filen);
|
||||||
QCC_PR_ParseErrorPrintDef (ERR_TYPEMISMATCHREDEC, def, "Type mismatch on redeclaration of %s. %s, should be %s",name, TypeName(type, typebuf1, sizeof(typebuf1)), TypeName(def->type, typebuf2, sizeof(typebuf2)));
|
if (!pr_scope && flen >= 13 && !QC_strcasecmp(s_filen+flen-13, "extensions.qc") && def->type->type == ev_function)
|
||||||
|
{
|
||||||
|
//this is a hack. droptofloor was wrongly declared in vanilla qc, which causes problems with replacement extensions.qc.
|
||||||
|
//yes, this is a selfish lazy hack for this, there's probably a better way, but at least we spit out a warning still.
|
||||||
|
QCC_PR_ParseWarning (WARN_COMPATIBILITYHACK, "%s builtin was redefined as %s. ignoring alternative definition",name, TypeName(type, typebuf1, sizeof(typebuf1)));
|
||||||
|
QCC_PR_ParsePrintDef(WARN_COMPATIBILITYHACK, def);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//unequal even when we're lax
|
||||||
|
QCC_PR_ParseErrorPrintDef (ERR_TYPEMISMATCHREDEC, def, "Type mismatch on redeclaration of %s. %s, should be %s",name, TypeName(type, typebuf1, sizeof(typebuf1)), TypeName(def->type, typebuf2, sizeof(typebuf2)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -12919,7 +13000,7 @@ QCC_def_t *QCC_PR_DummyFieldDef(QCC_type_t *type, QCC_function_t *scope, int arr
|
||||||
def = QCC_PR_GetDef(ftype, newname, scope, true, 0, saved);
|
def = QCC_PR_GetDef(ftype, newname, scope, true, 0, saved);
|
||||||
if (parttype->type == ev_function)
|
if (parttype->type == ev_function)
|
||||||
def->initialized = true;
|
def->initialized = true;
|
||||||
def->symboldata->_int = *fieldofs;
|
def->symboldata[def->ofs]._int = *fieldofs;
|
||||||
*fieldofs += parttype->size;
|
*fieldofs += parttype->size;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -12954,7 +13035,9 @@ void QCC_PR_ExpandUnionToFields(QCC_type_t *type, unsigned int *fields)
|
||||||
QCC_PR_DummyFieldDef(pass, pr_scope, 1, fields, GDF_SAVED|GDF_CONST);
|
QCC_PR_DummyFieldDef(pass, pr_scope, 1, fields, GDF_SAVED|GDF_CONST);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QCC_PR_ParseInitializerType(int arraysize, QCC_def_t *basedef, QCC_sref_t def)
|
#define PIF_WRAP 1 //new initialisation is meant to wrap an existing one.
|
||||||
|
#define PIF_STRONGER 2 //previous initialisation was weak.
|
||||||
|
void QCC_PR_ParseInitializerType(int arraysize, QCC_def_t *basedef, QCC_sref_t def, unsigned int flags)
|
||||||
{
|
{
|
||||||
QCC_sref_t tmp;
|
QCC_sref_t tmp;
|
||||||
int i;
|
int i;
|
||||||
|
@ -12967,7 +13050,7 @@ void QCC_PR_ParseInitializerType(int arraysize, QCC_def_t *basedef, QCC_sref_t d
|
||||||
{
|
{
|
||||||
for (i = 0; i < arraysize; i++)
|
for (i = 0; i < arraysize; i++)
|
||||||
{
|
{
|
||||||
QCC_PR_ParseInitializerType(0, basedef, def);
|
QCC_PR_ParseInitializerType(0, basedef, def, flags);
|
||||||
def.ofs += def.cast->size;
|
def.ofs += def.cast->size;
|
||||||
if (!QCC_PR_CheckToken(","))
|
if (!QCC_PR_CheckToken(","))
|
||||||
{
|
{
|
||||||
|
@ -13020,10 +13103,18 @@ void QCC_PR_ParseInitializerType(int arraysize, QCC_def_t *basedef, QCC_sref_t d
|
||||||
{
|
{
|
||||||
for (i = 1; i < numfunctions; i++)
|
for (i = 1; i < numfunctions; i++)
|
||||||
{
|
{
|
||||||
if (!strcmp(functions[i].name, fname) && functions[i].code == -1 && functions[i].builtin == binum)
|
if (functions[i].code == -1 && functions[i].builtin == binum)
|
||||||
{
|
{
|
||||||
tmp = QCC_MakeIntConst(i);
|
if (!*functions[i].name)
|
||||||
break;
|
{
|
||||||
|
functions[i].name = qccHunkAlloc(strlen(fname)+1);
|
||||||
|
strcpy(functions[i].name, fname);
|
||||||
|
}
|
||||||
|
if (!strcmp(functions[i].name, fname))
|
||||||
|
{
|
||||||
|
tmp = QCC_MakeIntConst(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13031,10 +13122,15 @@ void QCC_PR_ParseInitializerType(int arraysize, QCC_def_t *basedef, QCC_sref_t d
|
||||||
{
|
{
|
||||||
for (i = 1; i < numfunctions; i++)
|
for (i = 1; i < numfunctions; i++)
|
||||||
{
|
{
|
||||||
if (!strcmp(functions[i].name, defname) && functions[i].code == -1 && functions[i].builtin == binum)
|
if (functions[i].code == -1 && functions[i].builtin == binum)
|
||||||
{
|
{
|
||||||
tmp = QCC_MakeIntConst(i);
|
if (!*functions[i].name)
|
||||||
break;
|
functions[i].name = (char*)defname;
|
||||||
|
if (!strcmp(functions[i].name, defname))
|
||||||
|
{
|
||||||
|
tmp = QCC_MakeIntConst(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13047,14 +13143,19 @@ void QCC_PR_ParseInitializerType(int arraysize, QCC_def_t *basedef, QCC_sref_t d
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (basedef->initialized == 1)
|
if (flags&PIF_WRAP)
|
||||||
|
{
|
||||||
|
if (!basedef->initialized || !def.sym->symboldata[def.ofs]._int)
|
||||||
|
QCC_PR_ParseErrorPrintSRef (ERR_REDECLARATION, def, "wrapper function does not wrap anything");
|
||||||
|
}
|
||||||
|
else if (basedef->initialized == 1 && !(flags & PIF_STRONGER))
|
||||||
{
|
{
|
||||||
//normally this is an error, but to aid supporting new stuff with old, we convert it into a warning if a vanilla(ish) qc function replaces extension builtins.
|
//normally this is an error, but to aid supporting new stuff with old, we convert it into a warning if a vanilla(ish) qc function replaces extension builtins.
|
||||||
//the qc function is the one that is used, but there is a warning so you know how to gain efficiency.
|
//the qc function is the one that is used, but there is a warning so you know how to gain efficiency.
|
||||||
int bi = -1;
|
int bi = -1;
|
||||||
if (def.cast->type == ev_function && !arraysize)
|
if (def.cast->type == ev_function && !arraysize)
|
||||||
{
|
{
|
||||||
if (!strcmp(defname, "anglemod"))
|
if (!strcmp(defname, "anglemod") || !strcmp(defname, "crossproduct"))
|
||||||
bi = def.sym->symboldata[def.ofs]._int;
|
bi = def.sym->symboldata[def.ofs]._int;
|
||||||
}
|
}
|
||||||
if (bi <= 0 || bi >= numfunctions)
|
if (bi <= 0 || bi >= numfunctions)
|
||||||
|
@ -13063,12 +13164,13 @@ void QCC_PR_ParseInitializerType(int arraysize, QCC_def_t *basedef, QCC_sref_t d
|
||||||
bi = functions[bi].code;
|
bi = functions[bi].code;
|
||||||
if (bi < 0)
|
if (bi < 0)
|
||||||
{
|
{
|
||||||
QCC_PR_ParseWarning(WARN_NOTSTANDARDBEHAVIOUR, "%s already declared as builtin", defname);
|
QCC_PR_ParseWarning(WARN_NOTSTANDARDBEHAVIOUR, "%s already declared as a builtin", defname);
|
||||||
QCC_PR_ParsePrintSRef(WARN_NOTSTANDARDBEHAVIOUR, def);
|
QCC_PR_ParsePrintSRef(WARN_NOTSTANDARDBEHAVIOUR, def);
|
||||||
basedef->initialized = 3;
|
basedef->initialized = 3;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
QCC_PR_ParseErrorPrintSRef (ERR_REDECLARATION, def, "redeclaration of function body");
|
QCC_PR_ParseErrorPrintSRef (ERR_REDECLARATION, def, "redeclaration of function body");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pr_scope)
|
if (pr_scope)
|
||||||
|
@ -13084,7 +13186,7 @@ void QCC_PR_ParseInitializerType(int arraysize, QCC_def_t *basedef, QCC_sref_t d
|
||||||
|
|
||||||
//generate a goto statement around the nested function, so that nothing is hurt.
|
//generate a goto statement around the nested function, so that nothing is hurt.
|
||||||
patch = QCC_Generate_OP_GOTO();
|
patch = QCC_Generate_OP_GOTO();
|
||||||
f = QCC_PR_ParseImmediateStatements (NULL, type);
|
f = QCC_PR_ParseImmediateStatements (NULL, type, flags&PIF_WRAP);
|
||||||
patch->a.ofs = &statements[numstatements] - patch;
|
patch->a.ofs = &statements[numstatements] - patch;
|
||||||
|
|
||||||
//make sure parent state is restored properly.
|
//make sure parent state is restored properly.
|
||||||
|
@ -13093,7 +13195,7 @@ void QCC_PR_ParseInitializerType(int arraysize, QCC_def_t *basedef, QCC_sref_t d
|
||||||
pr_scope = parent;
|
pr_scope = parent;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
f = QCC_PR_ParseImmediateStatements (def.sym, type);
|
f = QCC_PR_ParseImmediateStatements (def.sym, type, flags&PIF_WRAP);
|
||||||
|
|
||||||
//allow dupes if its a builtin
|
//allow dupes if its a builtin
|
||||||
if (!f->code && basedef->initialized)
|
if (!f->code && basedef->initialized)
|
||||||
|
@ -13158,7 +13260,7 @@ void QCC_PR_ParseInitializerType(int arraysize, QCC_def_t *basedef, QCC_sref_t d
|
||||||
def.cast = (type)->params[partnum].type;
|
def.cast = (type)->params[partnum].type;
|
||||||
def.ofs = offset + (type)->params[partnum].ofs;
|
def.ofs = offset + (type)->params[partnum].ofs;
|
||||||
|
|
||||||
QCC_PR_ParseInitializerType((type)->params[partnum].arraysize, basedef, def);
|
QCC_PR_ParseInitializerType((type)->params[partnum].arraysize, basedef, def, flags);
|
||||||
if (isunion || !QCC_PR_CheckToken(","))
|
if (isunion || !QCC_PR_CheckToken(","))
|
||||||
{
|
{
|
||||||
QCC_PR_Expect("}");
|
QCC_PR_Expect("}");
|
||||||
|
@ -13189,7 +13291,7 @@ void QCC_PR_ParseInitializerType(int arraysize, QCC_def_t *basedef, QCC_sref_t d
|
||||||
QCC_PR_ParsePrintSRef(WARN_UNINITIALIZED, tmp);
|
QCC_PR_ParsePrintSRef(WARN_UNINITIALIZED, tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (basedef->initialized && basedef->initialized != 3)
|
if (basedef->initialized && basedef->initialized != 3 && !(flags & PIF_STRONGER))
|
||||||
{
|
{
|
||||||
for (i = 0; (unsigned)i < type->size; i++)
|
for (i = 0; (unsigned)i < type->size; i++)
|
||||||
if (def.sym->symboldata[def.ofs+i]._int != tmp.sym->symboldata[tmp.ofs+i]._int)
|
if (def.sym->symboldata[def.ofs+i]._int != tmp.sym->symboldata[tmp.ofs+i]._int)
|
||||||
|
@ -13201,6 +13303,11 @@ void QCC_PR_ParseInitializerType(int arraysize, QCC_def_t *basedef, QCC_sref_t d
|
||||||
QCC_PR_ParseWarning (WARN_COMPATIBILITYHACK, "incompatible redeclaration. Please validate builtin numbers. parseentitydata is #613");
|
QCC_PR_ParseWarning (WARN_COMPATIBILITYHACK, "incompatible redeclaration. Please validate builtin numbers. parseentitydata is #613");
|
||||||
QCC_PR_ParsePrintSRef(WARN_COMPATIBILITYHACK, tmp);
|
QCC_PR_ParsePrintSRef(WARN_COMPATIBILITYHACK, tmp);
|
||||||
}
|
}
|
||||||
|
else if (!def.sym->arraysize && def.cast->type == ev_function && functions[def.sym->symboldata[def.ofs+i]._int].code>-1 && functions[tmp.sym->symboldata[tmp.ofs+i]._int].code==-1)
|
||||||
|
{
|
||||||
|
QCC_PR_ParseWarning (WARN_COMPATIBILITYHACK, "incompatible redeclaration. Ignoring replacement of qc function with builtin.");
|
||||||
|
QCC_PR_ParsePrintSRef(WARN_COMPATIBILITYHACK, tmp);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
QCC_PR_ParseErrorPrintSRef (ERR_REDECLARATION, def, "incompatible redeclaration");
|
QCC_PR_ParseErrorPrintSRef (ERR_REDECLARATION, def, "incompatible redeclaration");
|
||||||
}
|
}
|
||||||
|
@ -13300,9 +13407,9 @@ void QCC_PR_ParseInitializerType(int arraysize, QCC_def_t *basedef, QCC_sref_t d
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QCC_PR_ParseInitializerDef(QCC_def_t *def)
|
void QCC_PR_ParseInitializerDef(QCC_def_t *def, unsigned int flags)
|
||||||
{
|
{
|
||||||
QCC_PR_ParseInitializerType(def->arraysize, def, QCC_MakeSRef(def, def->ofs, def->type));
|
QCC_PR_ParseInitializerType(def->arraysize, def, QCC_MakeSRef(def, 0, def->type), flags);
|
||||||
if (!def->initialized || def->initialized == 3)
|
if (!def->initialized || def->initialized == 3)
|
||||||
def->initialized = 1;
|
def->initialized = 1;
|
||||||
}
|
}
|
||||||
|
@ -13431,6 +13538,8 @@ void QCC_PR_ParseDefs (char *classname)
|
||||||
pbool inlinefunction = false;
|
pbool inlinefunction = false;
|
||||||
pbool allowinline = false;
|
pbool allowinline = false;
|
||||||
pbool dostrip = false;
|
pbool dostrip = false;
|
||||||
|
pbool dowrap = false;
|
||||||
|
pbool doweak = false;
|
||||||
pbool forceused = false;
|
pbool forceused = false;
|
||||||
int arraysize;
|
int arraysize;
|
||||||
unsigned int gd_flags;
|
unsigned int gd_flags;
|
||||||
|
@ -13666,6 +13775,10 @@ void QCC_PR_ParseDefs (char *classname)
|
||||||
allowinline = true;
|
allowinline = true;
|
||||||
else if (QCC_PR_CheckKeyword(keyword_ignore, "ignore"))
|
else if (QCC_PR_CheckKeyword(keyword_ignore, "ignore"))
|
||||||
dostrip = true;
|
dostrip = true;
|
||||||
|
else if (QCC_PR_CheckKeyword(keyword_wrap, "wrap"))
|
||||||
|
dowrap = true;
|
||||||
|
else if (QCC_PR_CheckKeyword(keyword_weak, "weak"))
|
||||||
|
doweak = true;
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -13732,7 +13845,7 @@ void QCC_PR_ParseDefs (char *classname)
|
||||||
{
|
{
|
||||||
def->referenced = true;
|
def->referenced = true;
|
||||||
|
|
||||||
f = QCC_PR_ParseImmediateStatements (def, type);
|
f = QCC_PR_ParseImmediateStatements (def, type, false);
|
||||||
|
|
||||||
def->initialized = 1;
|
def->initialized = 1;
|
||||||
def->isstatic = isstatic;
|
def->isstatic = isstatic;
|
||||||
|
@ -13943,7 +14056,7 @@ void QCC_PR_ParseDefs (char *classname)
|
||||||
|
|
||||||
if (isstatic)
|
if (isstatic)
|
||||||
{
|
{
|
||||||
if (!strcmp(strings+def->s_file, strings+s_file))
|
if (!strcmp(def->filen, s_filen))
|
||||||
def->isstatic = isstatic;
|
def->isstatic = isstatic;
|
||||||
else //if (type->type != ev_function && defaultstatic) //functions don't quite consitiute a definition
|
else //if (type->type != ev_function && defaultstatic) //functions don't quite consitiute a definition
|
||||||
QCC_PR_ParseErrorPrintDef (ERR_REDECLARATION, def, "can't redefine non-static as static");
|
QCC_PR_ParseErrorPrintDef (ERR_REDECLARATION, def, "can't redefine non-static as static");
|
||||||
|
@ -13978,21 +14091,11 @@ void QCC_PR_ParseDefs (char *classname)
|
||||||
QCC_type_t *parentclass;
|
QCC_type_t *parentclass;
|
||||||
if (def->shared)
|
if (def->shared)
|
||||||
QCC_PR_ParseError (ERR_SHAREDINITIALISED, "shared values may not be assigned an initial value", name);
|
QCC_PR_ParseError (ERR_SHAREDINITIALISED, "shared values may not be assigned an initial value", name);
|
||||||
if (def->initialized == 1)
|
|
||||||
{
|
|
||||||
// if (def->type->type == ev_function)
|
|
||||||
// {
|
|
||||||
// i = G_FUNCTION(def->ofs);
|
|
||||||
// df = &functions[i];
|
|
||||||
// QCC_PR_ParseErrorPrintDef (ERR_REDECLARATION, def, "%s redeclared, prev instance is in %s", name, strings+df->s_file);
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// QCC_PR_ParseErrorPrintDef(ERR_REDECLARATION, def, "%s redeclared", name);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (autoprototype || dostrip)
|
//if weak, only use the first non-weak version of the function
|
||||||
|
if (autoprototype || dostrip || (def->initialized && doweak) || (!def->initialized && doweak && dowrap))
|
||||||
{ //ignore the code and stuff
|
{ //ignore the code and stuff
|
||||||
if (dostrip && !def->initialized)
|
if ((dostrip || doweak && dowrap) && !def->initialized)
|
||||||
def->initialized = 3;
|
def->initialized = 3;
|
||||||
if (dostrip)
|
if (dostrip)
|
||||||
def->referenced = true;
|
def->referenced = true;
|
||||||
|
@ -14045,7 +14148,11 @@ void QCC_PR_ParseDefs (char *classname)
|
||||||
parentclass = pr_classtype;
|
parentclass = pr_classtype;
|
||||||
pr_classtype = defclass?defclass:pr_classtype;
|
pr_classtype = defclass?defclass:pr_classtype;
|
||||||
def->constant = (isconstant || (!isvar && !pr_scope));
|
def->constant = (isconstant || (!isvar && !pr_scope));
|
||||||
QCC_PR_ParseInitializerDef(def);
|
QCC_PR_ParseInitializerDef(def, (dowrap?PIF_WRAP:0)|(def->weak?PIF_STRONGER:0));
|
||||||
|
if (doweak)
|
||||||
|
def->weak = true;
|
||||||
|
else
|
||||||
|
def->weak = false;
|
||||||
QCC_FreeDef(def);
|
QCC_FreeDef(def);
|
||||||
pr_classtype = parentclass;
|
pr_classtype = parentclass;
|
||||||
}
|
}
|
||||||
|
@ -14141,6 +14248,7 @@ compiles the 0 terminated text, adding defintions to the pr structure
|
||||||
*/
|
*/
|
||||||
pbool QCC_PR_CompileFile (char *string, char *filename)
|
pbool QCC_PR_CompileFile (char *string, char *filename)
|
||||||
{
|
{
|
||||||
|
char *tmp;
|
||||||
jmp_buf oldjb;
|
jmp_buf oldjb;
|
||||||
if (!pr.memory)
|
if (!pr.memory)
|
||||||
QCC_Error (ERR_INTERNAL, "PR_CompileFile: Didn't clear");
|
QCC_Error (ERR_INTERNAL, "PR_CompileFile: Didn't clear");
|
||||||
|
@ -14149,18 +14257,16 @@ pbool QCC_PR_CompileFile (char *string, char *filename)
|
||||||
|
|
||||||
compilingfile = filename;
|
compilingfile = filename;
|
||||||
|
|
||||||
|
s_filen = tmp = qccHunkAlloc(strlen(filename)+1);
|
||||||
|
strcpy(tmp, filename);
|
||||||
if (opt_filenames)
|
if (opt_filenames)
|
||||||
{
|
{
|
||||||
optres_filenames += strlen(filename);
|
optres_filenames += strlen(filename);
|
||||||
pr_file_p = qccHunkAlloc(strlen(filename)+1);
|
s_filed = 0;
|
||||||
strcpy(pr_file_p, filename);
|
|
||||||
s_file = pr_file_p - strings;
|
|
||||||
s_file2 = 0;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
s_filed = QCC_CopyString (filename);
|
||||||
s_file = s_file2 = QCC_CopyString (filename);
|
|
||||||
}
|
|
||||||
pr_file_p = string;
|
pr_file_p = string;
|
||||||
pr_assumetermtype = NULL;
|
pr_assumetermtype = NULL;
|
||||||
|
|
||||||
|
@ -14257,14 +14363,15 @@ pbool QCC_Include(char *filename)
|
||||||
char *newfile;
|
char *newfile;
|
||||||
char fname[512];
|
char fname[512];
|
||||||
char *opr_file_p;
|
char *opr_file_p;
|
||||||
QCC_string_t os_file, os_file2;
|
const char *os_filen;
|
||||||
|
QCC_string_t os_filed;
|
||||||
int opr_source_line;
|
int opr_source_line;
|
||||||
char *ocompilingfile;
|
char *ocompilingfile;
|
||||||
struct qcc_includechunk_s *oldcurrentchunk;
|
struct qcc_includechunk_s *oldcurrentchunk;
|
||||||
|
|
||||||
ocompilingfile = compilingfile;
|
ocompilingfile = compilingfile;
|
||||||
os_file = s_file;
|
os_filen = s_filen;
|
||||||
os_file2 = s_file2;
|
os_filed = s_filed;
|
||||||
opr_source_line = pr_source_line;
|
opr_source_line = pr_source_line;
|
||||||
opr_file_p = pr_file_p;
|
opr_file_p = pr_file_p;
|
||||||
oldcurrentchunk = currentchunk;
|
oldcurrentchunk = currentchunk;
|
||||||
|
@ -14277,8 +14384,8 @@ pbool QCC_Include(char *filename)
|
||||||
currentchunk = oldcurrentchunk;
|
currentchunk = oldcurrentchunk;
|
||||||
|
|
||||||
compilingfile = ocompilingfile;
|
compilingfile = ocompilingfile;
|
||||||
s_file = os_file;
|
s_filen = os_filen;
|
||||||
s_file2 = os_file2;
|
s_filed = os_filed;
|
||||||
pr_source_line = opr_source_line;
|
pr_source_line = opr_source_line;
|
||||||
pr_file_p = opr_file_p;
|
pr_file_p = opr_file_p;
|
||||||
|
|
||||||
|
|
|
@ -114,11 +114,20 @@ void QCC_PR_AddIncludePath(const char *newinc)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
if (!*newinc)
|
||||||
|
{
|
||||||
|
QCC_PR_ParseWarning(WARN_STRINGTOOLONG, "Invalid include path.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < MAXINCLUDEDIRS; i++)
|
for (i = 0; i < MAXINCLUDEDIRS; i++)
|
||||||
{
|
{
|
||||||
if (!*qccincludedir[i])
|
if (!*qccincludedir[i])
|
||||||
{
|
{
|
||||||
|
const char *e = newinc + strlen(newinc)-1;
|
||||||
QC_strlcpy(qccincludedir[i], newinc, sizeof(qccincludedir));
|
QC_strlcpy(qccincludedir[i], newinc, sizeof(qccincludedir));
|
||||||
|
if (*e != '/' && *e != '\\')
|
||||||
|
QC_strlcat(qccincludedir[i], "/", sizeof(qccincludedir));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!strcmp(qccincludedir[i], newinc))
|
if (!strcmp(qccincludedir[i], newinc))
|
||||||
|
@ -126,13 +135,10 @@ void QCC_PR_AddIncludePath(const char *newinc)
|
||||||
}
|
}
|
||||||
if (i == MAXINCLUDEDIRS)
|
if (i == MAXINCLUDEDIRS)
|
||||||
{
|
{
|
||||||
if (!s_file)
|
QCC_PR_ParseWarning(WARN_STRINGTOOLONG, "Too many include dirs. Ignoring and hoping the stars align.");
|
||||||
QCC_PR_Warning(WARN_STRINGTOOLONG, "cmdline", 0, "Too many include dirs. Ignoring and hoping the stars align.");
|
|
||||||
else
|
|
||||||
QCC_PR_ParseWarning(WARN_STRINGTOOLONG, "Too many include dirs. Ignoring and hoping the stars align.");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void QCC_PR_IncludeChunkEx (char *data, pbool duplicate, char *filename, CompilerConstant_t *cnst)
|
static void QCC_PR_IncludeChunkEx (char *data, pbool duplicate, char *filename, CompilerConstant_t *cnst)
|
||||||
{
|
{
|
||||||
qcc_includechunk_t *chunk = qccHunkAlloc(sizeof(qcc_includechunk_t));
|
qcc_includechunk_t *chunk = qccHunkAlloc(sizeof(qcc_includechunk_t));
|
||||||
chunk->prev = currentchunk;
|
chunk->prev = currentchunk;
|
||||||
|
@ -181,7 +187,7 @@ pbool QCC_PR_UnInclude(void)
|
||||||
PR_PrintNextLine
|
PR_PrintNextLine
|
||||||
==============
|
==============
|
||||||
*/
|
*/
|
||||||
void QCC_PR_PrintNextLine (void)
|
static void QCC_PR_PrintNextLine (void)
|
||||||
{
|
{
|
||||||
char *t;
|
char *t;
|
||||||
|
|
||||||
|
@ -191,7 +197,7 @@ void QCC_PR_PrintNextLine (void)
|
||||||
printf ("\n");
|
printf ("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void QCC_Canonicalize(char *fullname, size_t fullnamesize, char *newfile, char *base)
|
static void QCC_Canonicalize(char *fullname, size_t fullnamesize, char *newfile, char *base)
|
||||||
{
|
{
|
||||||
int doubledots;
|
int doubledots;
|
||||||
char *end = fullname;
|
char *end = fullname;
|
||||||
|
@ -269,10 +275,20 @@ void QCC_FindBestInclude(char *newfile, char *currentfile, pbool verbose)
|
||||||
|
|
||||||
if (verbose)
|
if (verbose)
|
||||||
{
|
{
|
||||||
if (autoprototype)
|
if (verbose == 2)
|
||||||
printf("prototyping include %s\n", fullname);
|
{
|
||||||
|
if (autoprototype)
|
||||||
|
printf("prototyping %s\n", fullname);
|
||||||
|
else
|
||||||
|
printf("compiling %s\n", fullname);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
printf("including %s\n", fullname);
|
{
|
||||||
|
if (autoprototype)
|
||||||
|
printf("prototyping include %s\n", fullname);
|
||||||
|
else
|
||||||
|
printf("including %s\n", fullname);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
QCC_Include(fullname);
|
QCC_Include(fullname);
|
||||||
}
|
}
|
||||||
|
@ -285,6 +301,7 @@ int QCC_PR_LexInteger (void);
|
||||||
void QCC_AddFile (char *filename);
|
void QCC_AddFile (char *filename);
|
||||||
void QCC_PR_LexString (void);
|
void QCC_PR_LexString (void);
|
||||||
pbool QCC_PR_SimpleGetToken (void);
|
pbool QCC_PR_SimpleGetToken (void);
|
||||||
|
pbool QCC_PR_SimpleGetString(void);
|
||||||
|
|
||||||
#define PPI_VALUE 0
|
#define PPI_VALUE 0
|
||||||
#define PPI_NOT 1
|
#define PPI_NOT 1
|
||||||
|
@ -800,9 +817,9 @@ pbool QCC_PR_Precompiler(void)
|
||||||
msg[a] = '\0';
|
msg[a] = '\0';
|
||||||
|
|
||||||
if (flag_msvcstyle)
|
if (flag_msvcstyle)
|
||||||
printf ("%s(%i) : #message: %s\n", strings + s_file, pr_source_line, msg);
|
printf ("%s(%i) : #message: %s\n", s_filen, pr_source_line, msg);
|
||||||
else
|
else
|
||||||
printf ("%s:%i: #message: %s\n", strings + s_file, pr_source_line, msg);
|
printf ("%s:%i: #message: %s\n", s_filen, pr_source_line, msg);
|
||||||
QCC_PR_SkipToEndOfLine(false);
|
QCC_PR_SkipToEndOfLine(false);
|
||||||
}
|
}
|
||||||
else if (!strncmp(directive, "copyright", 9))
|
else if (!strncmp(directive, "copyright", 9))
|
||||||
|
@ -852,6 +869,25 @@ pbool QCC_PR_Precompiler(void)
|
||||||
|
|
||||||
QCC_PR_SkipToEndOfLine(true);
|
QCC_PR_SkipToEndOfLine(true);
|
||||||
}
|
}
|
||||||
|
else if (!strncmp(directive, "merge", 5))
|
||||||
|
{
|
||||||
|
extern char destfile[1024];
|
||||||
|
pr_file_p=directive+5;
|
||||||
|
|
||||||
|
while(qcc_iswhitesameline(*pr_file_p))
|
||||||
|
pr_file_p++;
|
||||||
|
|
||||||
|
QCC_PR_SimpleGetString();
|
||||||
|
printf("Merging to %s\n", pr_token);
|
||||||
|
QCC_ImportProgs(pr_token);
|
||||||
|
if (!*destfile)
|
||||||
|
{
|
||||||
|
QCC_Canonicalize(destfile, sizeof(destfile), pr_token, compilingfile);
|
||||||
|
printf("Outputfile: %s\n", destfile);
|
||||||
|
}
|
||||||
|
|
||||||
|
QCC_PR_SkipToEndOfLine(true);
|
||||||
|
}
|
||||||
else if (!strncmp(directive, "includelist", 11))
|
else if (!strncmp(directive, "includelist", 11))
|
||||||
{
|
{
|
||||||
int defines=0;
|
int defines=0;
|
||||||
|
@ -946,7 +982,7 @@ pbool QCC_PR_Precompiler(void)
|
||||||
while(qcc_iswhitesameline(*pr_file_p))
|
while(qcc_iswhitesameline(*pr_file_p))
|
||||||
pr_file_p++;
|
pr_file_p++;
|
||||||
|
|
||||||
QCC_PR_LexString();
|
QCC_PR_SimpleGetString();
|
||||||
printf("Including datafile: %s\n", pr_token);
|
printf("Including datafile: %s\n", pr_token);
|
||||||
QCC_AddFile(pr_token);
|
QCC_AddFile(pr_token);
|
||||||
|
|
||||||
|
@ -970,21 +1006,11 @@ pbool QCC_PR_Precompiler(void)
|
||||||
while(qcc_iswhitesameline(*pr_file_p))
|
while(qcc_iswhitesameline(*pr_file_p))
|
||||||
pr_file_p++;
|
pr_file_p++;
|
||||||
|
|
||||||
QCC_PR_LexString();
|
QCC_PR_SimpleGetString();
|
||||||
strcpy(destfile, pr_token);
|
QCC_Canonicalize(destfile, sizeof(destfile), pr_token, compilingfile);
|
||||||
printf("Outputfile: %s\n", destfile);
|
printf("Outputfile: %s\n", pr_token);
|
||||||
|
|
||||||
pr_file_p++;
|
QCC_PR_SkipToEndOfLine(true);
|
||||||
|
|
||||||
for (a = 0; a < sizeof(msg)-1 && pr_file_p[a] != '\n' && pr_file_p[a] != '\0'; a++)
|
|
||||||
msg[a] = pr_file_p[a];
|
|
||||||
|
|
||||||
msg[a-1] = '\0';
|
|
||||||
|
|
||||||
while(*pr_file_p != '\n' && *pr_file_p != '\0') //read on until the end of the line
|
|
||||||
{
|
|
||||||
pr_file_p++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (!strncmp(directive, "pragma", 6))
|
else if (!strncmp(directive, "pragma", 6))
|
||||||
{
|
{
|
||||||
|
@ -2327,6 +2353,83 @@ void QCC_PR_ExpandMacro(void)
|
||||||
pr_immediate._float = (float)i;
|
pr_immediate._float = (float)i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pbool QCC_PR_SimpleGetString(void)
|
||||||
|
{
|
||||||
|
int c;
|
||||||
|
int i = 0;
|
||||||
|
char *f;
|
||||||
|
|
||||||
|
pr_token[0] = 0;
|
||||||
|
|
||||||
|
// skip whitespace
|
||||||
|
while ((c = *pr_file_p) && qcc_iswhite(c))
|
||||||
|
{
|
||||||
|
if (c=='\n')
|
||||||
|
return false;
|
||||||
|
pr_file_p++;
|
||||||
|
}
|
||||||
|
if (c == 0) //eof
|
||||||
|
return false;
|
||||||
|
//abort if there's a comment.
|
||||||
|
if (pr_file_p[0] == '/')
|
||||||
|
{
|
||||||
|
if (pr_file_p[1] == '/')
|
||||||
|
{ //comment alert
|
||||||
|
while(*pr_file_p && *pr_file_p != '\n')
|
||||||
|
pr_file_p++;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (pr_file_p[1] == '*')
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*pr_file_p != '\"')
|
||||||
|
return false; //nope, not a string.
|
||||||
|
f = pr_file_p+1;
|
||||||
|
while (*f)
|
||||||
|
{
|
||||||
|
if (*f == '\n' || !*f)
|
||||||
|
{ //bad string
|
||||||
|
QCC_Error (ERR_INTERNAL, "new line inside string");
|
||||||
|
pr_token[0] = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (*f == '\"')
|
||||||
|
{ //end-of-string
|
||||||
|
pr_token[i] = 0;
|
||||||
|
pr_file_p = f+1;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (i == sizeof(qcc_token)-1)
|
||||||
|
QCC_Error (ERR_INTERNAL, "token exceeds %i chars", i);
|
||||||
|
if (*f == '\\')
|
||||||
|
{
|
||||||
|
f++;
|
||||||
|
if (!*f)
|
||||||
|
f = "";
|
||||||
|
else if (*f == 'n')
|
||||||
|
{
|
||||||
|
pr_token[i++] = '\n';
|
||||||
|
f++;
|
||||||
|
}
|
||||||
|
else if (*f == 'r')
|
||||||
|
{
|
||||||
|
pr_token[i++] = '\r';
|
||||||
|
f++;
|
||||||
|
}
|
||||||
|
else if (*f == 't')
|
||||||
|
{
|
||||||
|
pr_token[i++] = '\t';
|
||||||
|
f++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
pr_token[i++] = *f++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
pr_token[i++] = *f++;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
// just parses text, returning false if an eol is reached
|
// just parses text, returning false if an eol is reached
|
||||||
pbool QCC_PR_SimpleGetToken (void)
|
pbool QCC_PR_SimpleGetToken (void)
|
||||||
{
|
{
|
||||||
|
@ -2872,7 +2975,7 @@ static char *QCC_PR_CheckBuiltinCompConst(char *constname, char *retbuf, size_t
|
||||||
}
|
}
|
||||||
if (!strcmp(constname, "__FILE__"))
|
if (!strcmp(constname, "__FILE__"))
|
||||||
{
|
{
|
||||||
QC_snprintfz(retbuf, retbufsize, "\"%s\"", strings + s_file);
|
QC_snprintfz(retbuf, retbufsize, "\"%s\"", s_filen);
|
||||||
return retbuf;
|
return retbuf;
|
||||||
}
|
}
|
||||||
if (!strcmp(constname, "__LINE__"))
|
if (!strcmp(constname, "__LINE__"))
|
||||||
|
@ -3165,9 +3268,9 @@ int QCC_PR_CheckCompConst(void)
|
||||||
if (flag_debugmacros)
|
if (flag_debugmacros)
|
||||||
{
|
{
|
||||||
if (flag_msvcstyle)
|
if (flag_msvcstyle)
|
||||||
printf ("%s(%i) : macro %s: %s\n", strings+s_file, pr_source_line, c->name, pr_file_p);
|
printf ("%s(%i) : macro %s: %s\n", s_filen, pr_source_line, c->name, pr_file_p);
|
||||||
else
|
else
|
||||||
printf ("%s:%i: macro %s: %s\n", strings+s_file, pr_source_line, c->name, pr_file_p);
|
printf ("%s:%i: macro %s: %s\n", s_filen, pr_source_line, c->name, pr_file_p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -3399,14 +3502,14 @@ void QCC_PR_ParsePrintDef (int type, QCC_def_t *def)
|
||||||
{
|
{
|
||||||
if (!qccwarningaction[type])
|
if (!qccwarningaction[type])
|
||||||
return;
|
return;
|
||||||
if (def->s_file)
|
if (def->filen)
|
||||||
{
|
{
|
||||||
char tybuffer[512];
|
char tybuffer[512];
|
||||||
char tmbuffer[512];
|
char tmbuffer[512];
|
||||||
char *modifiers;
|
char *modifiers;
|
||||||
if (QCC_Temp_Describe(def, tmbuffer, sizeof(tmbuffer)))
|
if (QCC_Temp_Describe(def, tmbuffer, sizeof(tmbuffer)))
|
||||||
{
|
{
|
||||||
printf ("%s:%i: (%s)(%s)\n", strings + def->s_file, def->s_line, TypeName(def->type, tybuffer, sizeof(tybuffer)), tmbuffer);
|
printf ("%s:%i: (%s)(%s)\n", def->filen, def->s_line, TypeName(def->type, tybuffer, sizeof(tybuffer)), tmbuffer);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -3416,9 +3519,9 @@ void QCC_PR_ParsePrintDef (int type, QCC_def_t *def)
|
||||||
else if (def->isstatic)
|
else if (def->isstatic)
|
||||||
modifiers = "static ";
|
modifiers = "static ";
|
||||||
if (flag_msvcstyle)
|
if (flag_msvcstyle)
|
||||||
printf ("%s(%i) : %s%s %s is defined here\n", strings + def->s_file, def->s_line, modifiers, TypeName(def->type, tybuffer, sizeof(tybuffer)), def->name);
|
printf ("%s(%i) : %s%s %s is defined here\n", def->filen, def->s_line, modifiers, TypeName(def->type, tybuffer, sizeof(tybuffer)), def->name);
|
||||||
else
|
else
|
||||||
printf ("%s:%i: %s%s %s is defined here\n", strings + def->s_file, def->s_line, modifiers, TypeName(def->type, tybuffer, sizeof(tybuffer)), def->name);
|
printf ("%s:%i: %s%s %s is defined here\n", def->filen, def->s_line, modifiers, TypeName(def->type, tybuffer, sizeof(tybuffer)), def->name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3455,7 +3558,7 @@ Aborts the current file load
|
||||||
============
|
============
|
||||||
*/
|
*/
|
||||||
#ifndef QCC
|
#ifndef QCC
|
||||||
void editbadfile(char *file, int line);
|
void editbadfile(const char *file, int line);
|
||||||
#endif
|
#endif
|
||||||
//will abort.
|
//will abort.
|
||||||
void VARGS QCC_PR_ParseError (int errortype, const char *error, ...)
|
void VARGS QCC_PR_ParseError (int errortype, const char *error, ...)
|
||||||
|
@ -3468,14 +3571,14 @@ void VARGS QCC_PR_ParseError (int errortype, const char *error, ...)
|
||||||
va_end (argptr);
|
va_end (argptr);
|
||||||
|
|
||||||
#ifndef QCC
|
#ifndef QCC
|
||||||
editbadfile(strings+s_file, pr_source_line);
|
editbadfile(s_filen, pr_source_line);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
QCC_PR_PrintScope();
|
QCC_PR_PrintScope();
|
||||||
if (flag_msvcstyle)
|
if (flag_msvcstyle)
|
||||||
printf ("%s(%i) : error: %s\n", strings + s_file, pr_source_line, string);
|
printf ("%s(%i) : error: %s\n", s_filen, pr_source_line, string);
|
||||||
else
|
else
|
||||||
printf ("%s:%i: error: %s\n", strings + s_file, pr_source_line, string);
|
printf ("%s:%i: error: %s\n", s_filen, pr_source_line, string);
|
||||||
|
|
||||||
longjmp (pr_parse_abort, 1);
|
longjmp (pr_parse_abort, 1);
|
||||||
}
|
}
|
||||||
|
@ -3490,13 +3593,13 @@ void VARGS QCC_PR_ParseErrorPrintDef (int errortype, QCC_def_t *def, const char
|
||||||
va_end (argptr);
|
va_end (argptr);
|
||||||
|
|
||||||
#ifndef QCC
|
#ifndef QCC
|
||||||
editbadfile(strings+s_file, pr_source_line);
|
editbadfile(s_filen, pr_source_line);
|
||||||
#endif
|
#endif
|
||||||
QCC_PR_PrintScope();
|
QCC_PR_PrintScope();
|
||||||
if (flag_msvcstyle)
|
if (flag_msvcstyle)
|
||||||
printf ("%s(%i) : error: %s\n", strings + s_file, pr_source_line, string);
|
printf ("%s(%i) : error: %s\n", s_filen, pr_source_line, string);
|
||||||
else
|
else
|
||||||
printf ("%s:%i: error: %s\n", strings + s_file, pr_source_line, string);
|
printf ("%s:%i: error: %s\n", s_filen, pr_source_line, string);
|
||||||
|
|
||||||
QCC_PR_ParsePrintDef(WARN_ERROR, def);
|
QCC_PR_ParsePrintDef(WARN_ERROR, def);
|
||||||
|
|
||||||
|
@ -3513,13 +3616,13 @@ void VARGS QCC_PR_ParseErrorPrintSRef (int errortype, QCC_sref_t def, const char
|
||||||
va_end (argptr);
|
va_end (argptr);
|
||||||
|
|
||||||
#ifndef QCC
|
#ifndef QCC
|
||||||
editbadfile(strings+s_file, pr_source_line);
|
editbadfile(s_filen, pr_source_line);
|
||||||
#endif
|
#endif
|
||||||
QCC_PR_PrintScope();
|
QCC_PR_PrintScope();
|
||||||
if (flag_msvcstyle)
|
if (flag_msvcstyle)
|
||||||
printf ("%s(%i) : error: %s\n", strings + s_file, pr_source_line, string);
|
printf ("%s(%i) : error: %s\n", s_filen, pr_source_line, string);
|
||||||
else
|
else
|
||||||
printf ("%s:%i: error: %s\n", strings + s_file, pr_source_line, string);
|
printf ("%s:%i: error: %s\n", s_filen, pr_source_line, string);
|
||||||
|
|
||||||
QCC_PR_ParsePrintSRef(WARN_ERROR, def);
|
QCC_PR_ParsePrintSRef(WARN_ERROR, def);
|
||||||
|
|
||||||
|
@ -3552,7 +3655,7 @@ pbool VARGS QCC_PR_PrintWarning (int type, const char *file, int line, const cha
|
||||||
if (!string)
|
if (!string)
|
||||||
;
|
;
|
||||||
else if (!file || !*file)
|
else if (!file || !*file)
|
||||||
printf (": werror%s: %s\n", wnam, string);
|
printf (":: werror%s: %s\n", wnam, string);
|
||||||
else if (flag_msvcstyle)
|
else if (flag_msvcstyle)
|
||||||
printf ("%s(%i) : werror%s: %s\n", file, line, wnam, string);
|
printf ("%s(%i) : werror%s: %s\n", file, line, wnam, string);
|
||||||
else
|
else
|
||||||
|
@ -3564,7 +3667,7 @@ pbool VARGS QCC_PR_PrintWarning (int type, const char *file, int line, const cha
|
||||||
if (!string)
|
if (!string)
|
||||||
;
|
;
|
||||||
else if (!file || !*file)
|
else if (!file || !*file)
|
||||||
printf (": warning%s: %s\n", wnam, string);
|
printf (":: warning%s: %s\n", wnam, string);
|
||||||
else if (flag_msvcstyle)
|
else if (flag_msvcstyle)
|
||||||
printf ("%s(%i) : warning%s: %s\n", file, line, wnam, string);
|
printf ("%s(%i) : warning%s: %s\n", file, line, wnam, string);
|
||||||
else
|
else
|
||||||
|
@ -3604,7 +3707,7 @@ pbool VARGS QCC_PR_ParseWarning (int type, const char *error, ...)
|
||||||
QC_vsnprintf (string,sizeof(string)-1, error,argptr);
|
QC_vsnprintf (string,sizeof(string)-1, error,argptr);
|
||||||
va_end (argptr);
|
va_end (argptr);
|
||||||
|
|
||||||
return QCC_PR_PrintWarning(type, strings + s_file, pr_source_line, string);
|
return QCC_PR_PrintWarning(type, s_filen, pr_source_line, string);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VARGS QCC_PR_Note (int type, const char *file, int line, const char *error, ...)
|
void VARGS QCC_PR_Note (int type, const char *file, int line, const char *error, ...)
|
||||||
|
@ -4607,8 +4710,10 @@ QCC_type_t *QCC_PR_ParseType (int newtype, pbool silentfail)
|
||||||
{
|
{
|
||||||
if (!qcc_typeinfo[i].typedefed)
|
if (!qcc_typeinfo[i].typedefed)
|
||||||
continue;
|
continue;
|
||||||
if (STRCMP(qcc_typeinfo[i].name, accessorname) == 0 && qcc_typeinfo[i].type == ev_accessor)
|
if (STRCMP(qcc_typeinfo[i].name, accessorname) == 0)
|
||||||
{
|
{
|
||||||
|
if (qcc_typeinfo[i].type != ev_accessor)
|
||||||
|
QCC_PR_ParseError(ERR_NOTANAME, "Type %s cannot be redefined as an accessor", accessorname);
|
||||||
newt = &qcc_typeinfo[i];
|
newt = &qcc_typeinfo[i];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -321,6 +321,57 @@ static pbool QCC_RegSetValue(HKEY base, char *keyname, char *valuename, int type
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
typedef struct vfile_s
|
||||||
|
{ //when originally running from a .dat, we load up all the functions and work from those rather than actual files.
|
||||||
|
//(these get re-written into the resulting .dat)
|
||||||
|
struct vfile_s *next;
|
||||||
|
void *fdata;
|
||||||
|
size_t fsize;
|
||||||
|
char name[1];
|
||||||
|
} vfile_t;
|
||||||
|
static vfile_t *qcc_vfiles;
|
||||||
|
vfile_t *QCC_FindVFile(const char *name)
|
||||||
|
{
|
||||||
|
vfile_t *f;
|
||||||
|
for (f = qcc_vfiles; f; f = f->next)
|
||||||
|
{
|
||||||
|
if (!strcmp(f->name, name))
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
//give it another go, for case
|
||||||
|
for (f = qcc_vfiles; f; f = f->next)
|
||||||
|
{
|
||||||
|
if (!QC_strcasecmp(f->name, name))
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
pbool QCC_AddVFile(const char *name, void *data, size_t size)
|
||||||
|
{
|
||||||
|
vfile_t *f = QCC_FindVFile(name);
|
||||||
|
if (!f)
|
||||||
|
{
|
||||||
|
f = malloc(sizeof(vfile_t) + strlen(name));
|
||||||
|
f->next = qcc_vfiles;
|
||||||
|
strcpy(f->name, name);
|
||||||
|
qcc_vfiles = f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
free(f->fdata);
|
||||||
|
f->fdata = malloc(size);
|
||||||
|
memcpy(f->fdata, data, size);
|
||||||
|
f->fsize = size;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QCC_EnumerateFilesResult(const char *name, const void *compdata, size_t compsize, int method, size_t plainsize)
|
||||||
|
{
|
||||||
|
void *buffer = malloc(plainsize);
|
||||||
|
if (QC_decode(NULL, compsize, plainsize, method, compdata, buffer))
|
||||||
|
QCC_AddVFile(name, buffer, plainsize);
|
||||||
|
free(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
==============
|
==============
|
||||||
LoadFile
|
LoadFile
|
||||||
|
@ -330,6 +381,17 @@ unsigned char *PDECL QCC_ReadFile (const char *fname, void *buffer, int len, siz
|
||||||
{
|
{
|
||||||
long length;
|
long length;
|
||||||
FILE *f;
|
FILE *f;
|
||||||
|
vfile_t *v = QCC_FindVFile(fname);
|
||||||
|
if (v)
|
||||||
|
{
|
||||||
|
if (len > v->fsize)
|
||||||
|
len = v->fsize;
|
||||||
|
memcpy(buffer, v->fdata, len);
|
||||||
|
if (sz)
|
||||||
|
*sz = len;
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
f = fopen(fname, "rb");
|
f = fopen(fname, "rb");
|
||||||
if (!f)
|
if (!f)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -347,6 +409,11 @@ int PDECL QCC_RawFileSize (const char *fname)
|
||||||
{
|
{
|
||||||
long length;
|
long length;
|
||||||
FILE *f;
|
FILE *f;
|
||||||
|
|
||||||
|
vfile_t *v = QCC_FindVFile(fname);
|
||||||
|
if (v)
|
||||||
|
return v->fsize;
|
||||||
|
|
||||||
f = fopen(fname, "rb");
|
f = fopen(fname, "rb");
|
||||||
if (!f)
|
if (!f)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -500,6 +567,9 @@ pbool PDECL QCC_WriteFile (const char *name, void *data, int len)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (QCC_FindVFile(name))
|
||||||
|
return QCC_AddVFile(name, data, len);
|
||||||
|
|
||||||
f = fopen(name, "wb");
|
f = fopen(name, "wb");
|
||||||
if (!f)
|
if (!f)
|
||||||
return false;
|
return false;
|
||||||
|
@ -1241,7 +1311,7 @@ enum {
|
||||||
|
|
||||||
static void EditorReload(editor_t *editor);
|
static void EditorReload(editor_t *editor);
|
||||||
int EditorSave(editor_t *edit);
|
int EditorSave(editor_t *edit);
|
||||||
void EditFile(char *name, int line, pbool setcontrol);
|
void EditFile(const char *name, int line, pbool setcontrol);
|
||||||
pbool EditorModified(editor_t *e);
|
pbool EditorModified(editor_t *e);
|
||||||
|
|
||||||
void QueryOpenFile(void)
|
void QueryOpenFile(void)
|
||||||
|
@ -1786,7 +1856,7 @@ char *GetTooltipText(editor_t *editor, int pos, pbool dwell)
|
||||||
{
|
{
|
||||||
if (line > functions[fno].line && bestline < functions[fno].line)
|
if (line > functions[fno].line && bestline < functions[fno].line)
|
||||||
{
|
{
|
||||||
if (!strcmp(editor->filename, functions[fno].file))
|
if (!strcmp(editor->filename, functions[fno].filen))
|
||||||
{
|
{
|
||||||
best = fno;
|
best = fno;
|
||||||
bestline = functions[fno].line;
|
bestline = functions[fno].line;
|
||||||
|
@ -2046,7 +2116,9 @@ static void UpdateEditorTitle(editor_t *editor)
|
||||||
encoding = "unknown";
|
encoding = "unknown";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (editor->modified)
|
if (QCC_FindVFile(editor->filename))
|
||||||
|
sprintf(title, "%s:%i - Virtual", editor->filename, 1+editor->curline);
|
||||||
|
else if (editor->modified)
|
||||||
sprintf(title, "*%s:%i - %s", editor->filename, 1+editor->curline, encoding);
|
sprintf(title, "*%s:%i - %s", editor->filename, 1+editor->curline, encoding);
|
||||||
else
|
else
|
||||||
sprintf(title, "%s:%i - %s", editor->filename, 1+editor->curline, encoding);
|
sprintf(title, "%s:%i - %s", editor->filename, 1+editor->curline, encoding);
|
||||||
|
@ -2386,7 +2458,7 @@ static void EditorReload(editor_t *editor)
|
||||||
}
|
}
|
||||||
|
|
||||||
//line is 0-based. use -1 for no reselection
|
//line is 0-based. use -1 for no reselection
|
||||||
void EditFile(char *name, int line, pbool setcontrol)
|
void EditFile(const char *name, int line, pbool setcontrol)
|
||||||
{
|
{
|
||||||
char title[1024];
|
char title[1024];
|
||||||
editor_t *neweditor;
|
editor_t *neweditor;
|
||||||
|
@ -2714,7 +2786,7 @@ unsigned char *GUIReadFile(const char *fname, void *buffer, int blen, size_t *sz
|
||||||
//our qcc itself is fine with utf-16, so long as it has a BOM.
|
//our qcc itself is fine with utf-16, so long as it has a BOM.
|
||||||
if (e->scintilla)
|
if (e->scintilla)
|
||||||
{
|
{
|
||||||
SendMessage(e->editpane, SCI_GETTEXT, blen, (LPARAM)buffer);
|
blen = SendMessage(e->editpane, SCI_GETTEXT, blen, (LPARAM)buffer);
|
||||||
}
|
}
|
||||||
else if (e->savefmt == UTF_ANSI)
|
else if (e->savefmt == UTF_ANSI)
|
||||||
{
|
{
|
||||||
|
@ -2738,7 +2810,9 @@ unsigned char *GUIReadFile(const char *fname, void *buffer, int blen, size_t *sz
|
||||||
SendMessage(e->editpane, SCI_SETSAVEPOINT, 0, 0); //tell the control that it was saved.
|
SendMessage(e->editpane, SCI_SETSAVEPOINT, 0, 0); //tell the control that it was saved.
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
QCC_WriteFileW(e->filename, (wchar_t*)buffer+1, blen);
|
QCC_WriteFileW(e->filename, (wchar_t*)buffer+1, blen);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5323,6 +5397,8 @@ void UpdateFileList(void)
|
||||||
int size;
|
int size;
|
||||||
char *buffer;
|
char *buffer;
|
||||||
|
|
||||||
|
AddSourceFile(NULL, progssrcname);
|
||||||
|
|
||||||
f = fopen (progssrcname, "rb");
|
f = fopen (progssrcname, "rb");
|
||||||
if (!f)
|
if (!f)
|
||||||
return;
|
return;
|
||||||
|
@ -5343,14 +5419,15 @@ void UpdateFileList(void)
|
||||||
if (*qcc_token == '#')
|
if (*qcc_token == '#')
|
||||||
{
|
{
|
||||||
//aaaahhh! newstyle!
|
//aaaahhh! newstyle!
|
||||||
AddSourceFile(NULL, progssrcname);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pr_file_p = QCC_COM_Parse(pr_file_p); //we dont care about the produced progs.dat
|
pr_file_p = QCC_COM_Parse(pr_file_p); //we dont care about the produced progs.dat
|
||||||
AddSourceFile(NULL, progssrcname);
|
|
||||||
while(pr_file_p)
|
while(pr_file_p)
|
||||||
{
|
{
|
||||||
|
if (*qcc_token == '#') //panic if there's preprocessor in there.
|
||||||
|
break;
|
||||||
|
|
||||||
AddSourceFile(progssrcname, qcc_token);
|
AddSourceFile(progssrcname, qcc_token);
|
||||||
pr_file_p = QCC_COM_Parse(pr_file_p); //we dont care about the produced progs.dat
|
pr_file_p = QCC_COM_Parse(pr_file_p); //we dont care about the produced progs.dat
|
||||||
}
|
}
|
||||||
|
@ -5552,6 +5629,38 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin
|
||||||
|
|
||||||
ShowWindow(mainwindow, SW_SHOWDEFAULT);
|
ShowWindow(mainwindow, SW_SHOWDEFAULT);
|
||||||
|
|
||||||
|
{
|
||||||
|
char *ext = strrchr(progssrcname, '.');
|
||||||
|
if (ext && !QC_strcasecmp(ext, ".dat"))
|
||||||
|
{
|
||||||
|
FILE *f = fopen(progssrcname, "rb");
|
||||||
|
if (f)
|
||||||
|
{
|
||||||
|
char *buf;
|
||||||
|
size_t size;
|
||||||
|
|
||||||
|
fseek(f, 0, SEEK_END);
|
||||||
|
size = ftell(f);
|
||||||
|
fseek(f, 0, SEEK_SET);
|
||||||
|
buf = malloc(size);
|
||||||
|
fread(buf, 1, size, f);
|
||||||
|
fclose(f);
|
||||||
|
QC_EnumerateFilesFromBlob(buf, size, QCC_EnumerateFilesResult);
|
||||||
|
free(buf);
|
||||||
|
}
|
||||||
|
strcpy(progssrcname, "progs.src");
|
||||||
|
|
||||||
|
for (i = 0; ; i++)
|
||||||
|
{
|
||||||
|
if (!strcmp("embedsrc", compiler_flag[i].abbrev))
|
||||||
|
{
|
||||||
|
compiler_flag[i].flags |= FLAG_SETINGUI;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (fl_compileonstart)
|
if (fl_compileonstart)
|
||||||
{
|
{
|
||||||
CreateOutputWindow(false);
|
CreateOutputWindow(false);
|
||||||
|
|
|
@ -99,21 +99,21 @@ void GoToDefinition(char *name)
|
||||||
if (fnum > 0 && fnum < numfunctions)
|
if (fnum > 0 && fnum < numfunctions)
|
||||||
{
|
{
|
||||||
fnc = &functions[fnum];
|
fnc = &functions[fnum];
|
||||||
if (fnc->code>=0 && fnc->s_file)
|
if (fnc->code>=0 && fnc->filen)
|
||||||
{
|
{
|
||||||
EditFile(strings+fnc->s_file, statements[fnc->code].linenum-1, false);
|
EditFile(fnc->filen, statements[fnc->code].linenum-1, false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!def->s_file)
|
if (!def->filen)
|
||||||
{
|
{
|
||||||
char msgbuffer[2048];
|
char msgbuffer[2048];
|
||||||
QC_snprintfz(msgbuffer, sizeof(msgbuffer), "Global definition of \"%s\" was not specified.", name);
|
QC_snprintfz(msgbuffer, sizeof(msgbuffer), "Global definition of \"%s\" was not specified.", name);
|
||||||
GUI_DialogPrint("Not found", msgbuffer);
|
GUI_DialogPrint("Not found", msgbuffer);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
EditFile(def->s_file+strings, def->s_line-1, false);
|
EditFile(def->filen, def->s_line-1, false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -413,6 +413,9 @@ void GUI_ParseCommandLine(char *args)
|
||||||
|
|
||||||
GUI_LoadConfig();
|
GUI_LoadConfig();
|
||||||
|
|
||||||
|
paramlen = strlen(parameters);
|
||||||
|
if (paramlen)
|
||||||
|
parameters[paramlen++] = ' ';
|
||||||
while(*args)
|
while(*args)
|
||||||
{
|
{
|
||||||
while (*args == ' ' || *args == '\t')
|
while (*args == ' ' || *args == '\t')
|
||||||
|
@ -686,7 +689,7 @@ void GUI_RevealOptions(void)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int GUI_BuildParms(char *args, char **argv, pbool quick)
|
int GUI_BuildParms(char *args, char **argv, pbool quick)//, char *forceoutputfile)
|
||||||
{
|
{
|
||||||
static char param[2048];
|
static char param[2048];
|
||||||
int paramlen = 0;
|
int paramlen = 0;
|
||||||
|
@ -770,6 +773,12 @@ int GUI_BuildParms(char *args, char **argv, pbool quick)
|
||||||
args=next;
|
args=next;
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
|
// if (*forceoutputfile)
|
||||||
|
// {
|
||||||
|
// argv[argc++] = "-destfile";
|
||||||
|
// argv[argc++] = forceoutputfile;
|
||||||
|
// }
|
||||||
|
|
||||||
if (*progssrcname)
|
if (*progssrcname)
|
||||||
{
|
{
|
||||||
argv[argc++] = "-srcfile";
|
argv[argc++] = "-srcfile";
|
||||||
|
|
|
@ -80,7 +80,7 @@ int numstatements;
|
||||||
|
|
||||||
|
|
||||||
QCC_function_t *functions;
|
QCC_function_t *functions;
|
||||||
dfunction_t *dfunctions;
|
//dfunction_t *dfunctions;
|
||||||
int numfunctions;
|
int numfunctions;
|
||||||
|
|
||||||
QCC_ddef_t *qcc_globals;
|
QCC_ddef_t *qcc_globals;
|
||||||
|
@ -200,6 +200,8 @@ struct {
|
||||||
{" F312", WARN_OVERFLOW},
|
{" F312", WARN_OVERFLOW},
|
||||||
{" F313", WARN_DENORMAL},
|
{" F313", WARN_DENORMAL},
|
||||||
{" F314", WARN_LAXCAST},
|
{" F314", WARN_LAXCAST},
|
||||||
|
{" F315", WARN_DUPLICATEPRECOMPILER},
|
||||||
|
{" F316", WARN_IDENTICALPRECOMPILER},
|
||||||
|
|
||||||
{" F208", WARN_NOTREFERENCEDCONST},
|
{" F208", WARN_NOTREFERENCEDCONST},
|
||||||
{" F209", WARN_EXTRAPRECACHE},
|
{" F209", WARN_EXTRAPRECACHE},
|
||||||
|
@ -319,7 +321,8 @@ compiler_flag_t compiler_flag[] = {
|
||||||
{&keyword_union, defaultkeyword, "union", "Keyword: union", "Disables the 'union' keyword."}, //you surly know what a union is!
|
{&keyword_union, defaultkeyword, "union", "Keyword: union", "Disables the 'union' keyword."}, //you surly know what a union is!
|
||||||
{&keyword_var, defaultkeyword, "var", "Keyword: var", "Disables the 'var' keyword."},
|
{&keyword_var, defaultkeyword, "var", "Keyword: var", "Disables the 'var' keyword."},
|
||||||
{&keyword_vector, defaultkeyword, "vector", "Keyword: vector", "Disables the 'vector' keyword."},
|
{&keyword_vector, defaultkeyword, "vector", "Keyword: vector", "Disables the 'vector' keyword."},
|
||||||
|
{&keyword_wrap, defaultkeyword, "wrap", "Keyword: wrap", "Disables the 'wrap' keyword."},
|
||||||
|
{&keyword_weak, defaultkeyword, "weak", "Keyword: weak", "Disables the 'weak' keyword."},
|
||||||
|
|
||||||
//options
|
//options
|
||||||
{&keywords_coexist, FLAG_ASDEFAULT, "kce", "Keywords Coexist", "If you want keywords to NOT be disabled when they a variable by the same name is defined, check here."},
|
{&keywords_coexist, FLAG_ASDEFAULT, "kce", "Keywords Coexist", "If you want keywords to NOT be disabled when they a variable by the same name is defined, check here."},
|
||||||
|
@ -767,7 +770,7 @@ int WriteSourceFiles(int h, pbool sourceaswell, pbool legacyembed)
|
||||||
#ifdef AVAIL_ZLIB
|
#ifdef AVAIL_ZLIB
|
||||||
idf[num].compmethod = 2;
|
idf[num].compmethod = 2;
|
||||||
#else
|
#else
|
||||||
idf[num].compmethod = 1;
|
idf[num].compmethod = 0;
|
||||||
#endif
|
#endif
|
||||||
idf[num].ofs = SafeSeek(h, 0, SEEK_CUR);
|
idf[num].ofs = SafeSeek(h, 0, SEEK_CUR);
|
||||||
idf[num].compsize = QC_encode(progfuncs, f->size, idf[num].compmethod, f->file, h);
|
idf[num].compsize = QC_encode(progfuncs, f->size, idf[num].compmethod, f->file, h);
|
||||||
|
@ -879,13 +882,21 @@ int WriteBodylessFuncs (int handle)
|
||||||
int ret=0;
|
int ret=0;
|
||||||
for (d=pr.def_head.next ; d ; d=d->next)
|
for (d=pr.def_head.next ; d ; d=d->next)
|
||||||
{
|
{
|
||||||
|
if (!d->used || !d->constant)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (d->type->type == ev_function && !d->scope)// function parms are ok
|
if (d->type->type == ev_function && !d->scope)// function parms are ok
|
||||||
{
|
{
|
||||||
if ((d->initialized == 2) && d->referenced)
|
if (d->initialized == 2)
|
||||||
{
|
{
|
||||||
SafeWrite(handle, d->name, strlen(d->name)+1);
|
SafeWrite(handle, d->name, strlen(d->name)+1);
|
||||||
ret++;
|
ret++;
|
||||||
}
|
}
|
||||||
|
if (d->initialized == 0)
|
||||||
|
{
|
||||||
|
QCC_PR_Warning(ERR_NOFUNC, d->filen, d->s_line, "function %s has no body", d->name);
|
||||||
|
QCC_PR_ParsePrintDef(ERR_NOFUNC, d);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1043,9 +1054,9 @@ void QCC_UnmarshalLocals(void)
|
||||||
if (verbose >= 3)
|
if (verbose >= 3)
|
||||||
{
|
{
|
||||||
if (onum == numpr_globals)
|
if (onum == numpr_globals)
|
||||||
printf("code: %s:%i: function %s no private locals\n", functions[i].file, functions[i].line, functions[i].name);
|
printf("code: %s:%i: function %s no private locals\n", functions[i].filen, functions[i].line, functions[i].name);
|
||||||
else
|
else
|
||||||
printf("code: %s:%i: function %s private locals %i-%i\n", functions[i].file, functions[i].line, functions[i].name, onum, numpr_globals);
|
printf("code: %s:%i: function %s private locals %i-%i\n", functions[i].filen, functions[i].line, functions[i].name, onum, numpr_globals);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1065,14 +1076,14 @@ void QCC_UnmarshalLocals(void)
|
||||||
if (verbose >= 3)
|
if (verbose >= 3)
|
||||||
{
|
{
|
||||||
if (onum == numpr_globals)
|
if (onum == numpr_globals)
|
||||||
printf("code: %s:%i: function %s no locals\n", functions[i].file, functions[i].line, functions[i].name);
|
printf("code: %s:%i: function %s no locals\n", functions[i].filen, functions[i].line, functions[i].name);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
printf("code: %s:%i: function %s overlapped locals %i-%i\n", functions[i].file, functions[i].line, functions[i].name, onum, numpr_globals);
|
printf("code: %s:%i: function %s overlapped locals %i-%i\n", functions[i].filen, functions[i].line, functions[i].name, onum, numpr_globals);
|
||||||
|
|
||||||
for (d = functions[i].firstlocal; d; d = d->nextlocal)
|
for (d = functions[i].firstlocal; d; d = d->nextlocal)
|
||||||
{
|
{
|
||||||
printf("code: %s:%i: %s @%i\n", functions[i].file, functions[i].line, d->name, d->ofs);
|
printf("code: %s:%i: %s @%i\n", functions[i].filen, functions[i].line, d->name, d->ofs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1296,7 +1307,7 @@ pbool QCC_WriteData (int crc)
|
||||||
funcs[i].first_statement = PRLittleLong (functions[i].code);
|
funcs[i].first_statement = PRLittleLong (functions[i].code);
|
||||||
funcs[i].parm_start = 0;//PRLittleLong (functions[i].parm_start);
|
funcs[i].parm_start = 0;//PRLittleLong (functions[i].parm_start);
|
||||||
funcs[i].s_name = PRLittleLong (QCC_CopyString(functions[i].name));
|
funcs[i].s_name = PRLittleLong (QCC_CopyString(functions[i].name));
|
||||||
funcs[i].s_file = PRLittleLong (functions[i].s_file);
|
funcs[i].s_file = PRLittleLong (functions[i].s_filed);
|
||||||
funcs[i].numparms = 0;//PRLittleLong ((functions[i].numparms>MAX_PARMS)?MAX_PARMS:functions[i].numparms);
|
funcs[i].numparms = 0;//PRLittleLong ((functions[i].numparms>MAX_PARMS)?MAX_PARMS:functions[i].numparms);
|
||||||
funcs[i].locals = 0;//PRLittleLong (functions[i].locals);
|
funcs[i].locals = 0;//PRLittleLong (functions[i].locals);
|
||||||
for (j = 0; j < MAX_PARMS; j++)
|
for (j = 0; j < MAX_PARMS; j++)
|
||||||
|
@ -1327,9 +1338,17 @@ pbool QCC_WriteData (int crc)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
funcs[i].s_name = PRLittleLong (QCC_CopyString(functions[i].name));
|
funcs[i].s_name = PRLittleLong (QCC_CopyString(functions[i].name));
|
||||||
funcs[i].s_file = PRLittleLong (functions[i].s_file);
|
funcs[i].s_file = PRLittleLong (functions[i].s_filed);
|
||||||
|
|
||||||
if (functions[i].code == -1)
|
if (functions[i].merged)
|
||||||
|
{
|
||||||
|
funcs[i].parm_start = functions[i].merged->parm_start;
|
||||||
|
funcs[i].locals = functions[i].merged->locals;
|
||||||
|
funcs[i].numparms = functions[i].merged->numparms;
|
||||||
|
for(p = 0; p < funcs[i].numparms; p++)
|
||||||
|
funcs[i].parm_size[p] = functions[i].merged->parm_size[p];
|
||||||
|
}
|
||||||
|
else if (functions[i].code == -1)
|
||||||
{
|
{
|
||||||
funcs[i].parm_start = 0;
|
funcs[i].parm_start = 0;
|
||||||
funcs[i].locals = 0;
|
funcs[i].locals = 0;
|
||||||
|
@ -1346,7 +1365,7 @@ pbool QCC_WriteData (int crc)
|
||||||
{
|
{
|
||||||
if (!local->used)
|
if (!local->used)
|
||||||
{ //all params should have been assigned space. logically we could have safely omitted the last ones, but blurgh.
|
{ //all params should have been assigned space. logically we could have safely omitted the last ones, but blurgh.
|
||||||
QCC_PR_Warning(ERR_INTERNAL, strings + local->s_file, local->s_line, "Argument %s was not marked used.\n", local->name);
|
QCC_PR_Warning(ERR_INTERNAL, local->filen, local->s_line, "Argument %s was not marked used.\n", local->name);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1394,10 +1413,10 @@ pbool QCC_WriteData (int crc)
|
||||||
funcs[i].numparms = PRLittleLong(funcs[i].numparms);
|
funcs[i].numparms = PRLittleLong(funcs[i].numparms);
|
||||||
|
|
||||||
if (funcs[i].locals && !funcs[i].parm_start)
|
if (funcs[i].locals && !funcs[i].parm_start)
|
||||||
QCC_PR_Warning(0, strings + funcs[i].s_file, functions[i].line, "%s:%i: func %s @%i locals@%i+%i, %i parms\n", functions[i].file, functions[i].line, strings+funcs[i].s_name, funcs[i].first_statement, funcs[i].parm_start, funcs[i].locals, funcs[i].numparms);
|
QCC_PR_Warning(0, strings + funcs[i].s_file, functions[i].line, "%s:%i: func %s @%i locals@%i+%i, %i parms\n", functions[i].filen, functions[i].line, strings+funcs[i].s_name, funcs[i].first_statement, funcs[i].parm_start, funcs[i].locals, funcs[i].numparms);
|
||||||
|
|
||||||
#ifdef DEBUG_DUMP
|
#ifdef DEBUG_DUMP
|
||||||
printf("code: %s:%i: func %s @%i locals@%i+%i, %i parms\n", functions[i].file, functions[i].line, strings+funcs[i].s_name, funcs[i].first_statement, funcs[i].parm_start, funcs[i].locals, funcs[i].numparms);
|
printf("code: %s:%i: func %s @%i locals@%i+%i, %i parms\n", functions[i].file, functions[i].line, strings+funcs[i].s_named, funcs[i].first_statement, funcs[i].parm_start, funcs[i].locals, funcs[i].numparms);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
funcdata = funcs;
|
funcdata = funcs;
|
||||||
|
@ -1454,15 +1473,15 @@ pbool QCC_WriteData (int crc)
|
||||||
else if (strcmp(def->name, "IMMEDIATE") && qccwarningaction[wt] && !(def->type->type == ev_function && def->symbolheader->timescalled) && !def->symbolheader->used)
|
else if (strcmp(def->name, "IMMEDIATE") && qccwarningaction[wt] && !(def->type->type == ev_function && def->symbolheader->timescalled) && !def->symbolheader->used)
|
||||||
{
|
{
|
||||||
char typestr[256];
|
char typestr[256];
|
||||||
if (QC_strcasestr(strings + def->s_file, "extensions") && !verbose)
|
if (QC_strcasestr(def->filen, "extensions") && !verbose)
|
||||||
{ //try to avoid annoying warnings from dpextensions.qc
|
{ //try to avoid annoying warnings from dpextensions.qc
|
||||||
extwarncount++;
|
extwarncount++;
|
||||||
QCC_PR_Warning(wt, strings + def->s_file, def->s_line, NULL);
|
QCC_PR_Warning(wt, def->filen, def->s_line, NULL);
|
||||||
}
|
}
|
||||||
else if (def->arraysize)
|
else if (def->arraysize)
|
||||||
QCC_PR_Warning(wt, strings + def->s_file, def->s_line, (dupewarncount++ >= 10 && !verbose)?NULL:"%s %s[%i] no references.", TypeName(def->type, typestr, sizeof(typestr)), def->name, def->arraysize);
|
QCC_PR_Warning(wt, def->filen, def->s_line, (dupewarncount++ >= 10 && !verbose)?NULL:"%s %s[%i] no references.", TypeName(def->type, typestr, sizeof(typestr)), def->name, def->arraysize);
|
||||||
else
|
else
|
||||||
QCC_PR_Warning(wt, strings + def->s_file, def->s_line, (dupewarncount++ >= 10 && !verbose)?NULL:"%s %s no references.", TypeName(def->type, typestr, sizeof(typestr)), def->name);
|
QCC_PR_Warning(wt, def->filen, def->s_line, (dupewarncount++ >= 10 && !verbose)?NULL:"%s %s no references.", TypeName(def->type, typestr, sizeof(typestr)), def->name);
|
||||||
}
|
}
|
||||||
pr_scope = NULL;
|
pr_scope = NULL;
|
||||||
|
|
||||||
|
@ -1470,7 +1489,7 @@ pbool QCC_WriteData (int crc)
|
||||||
{
|
{
|
||||||
optres_unreferenced++;
|
optres_unreferenced++;
|
||||||
#ifdef DEBUG_DUMP
|
#ifdef DEBUG_DUMP
|
||||||
printf("code: %s:%i: strip noref %s %s@%i;\n", strings+def->s_file, def->s_line, def->type->name, def->name, def->ofs);
|
printf("code: %s:%i: strip noref %s %s@%i;\n", def->filen, def->s_line, def->type->name, def->name, def->ofs);
|
||||||
#endif
|
#endif
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -1478,7 +1497,7 @@ pbool QCC_WriteData (int crc)
|
||||||
if ((def->type->type == ev_struct || def->type->type == ev_union || def->arraysize) && def->deftail)
|
if ((def->type->type == ev_struct || def->type->type == ev_union || def->arraysize) && def->deftail)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_DUMP
|
#ifdef DEBUG_DUMP
|
||||||
printf("code: %s:%i: strip struct %s %s@%i;\n", strings+def->s_file, def->s_line, def->type->name, def->name, def->ofs);
|
printf("code: %s:%i: strip struct %s %s@%i;\n", def->filen, def->s_line, def->type->name, def->name, def->ofs);
|
||||||
#endif
|
#endif
|
||||||
//the head of an array/struct is never written. only, its member fields are.
|
//the head of an array/struct is never written. only, its member fields are.
|
||||||
continue;
|
continue;
|
||||||
|
@ -2157,7 +2176,7 @@ strofs = (strofs+3)&~3;
|
||||||
printf("unable to write value for 'entity progs'\n"); //would not work anyway
|
printf("unable to write value for 'entity progs'\n"); //would not work anyway
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
QCC_PR_Warning(WARN_DENORMAL, strings + def->s_file, def->s_line, "'entity progs' is non-portable and will not work across engines nor cpus.");
|
QCC_PR_Warning(WARN_DENORMAL, def->filen, def->s_line, "'entity progs' is non-portable and will not work across engines nor cpus.");
|
||||||
|
|
||||||
if (def->initialized)
|
if (def->initialized)
|
||||||
i = PRLittleLong(qcc_pr_globals[def->ofs]._int);
|
i = PRLittleLong(qcc_pr_globals[def->ofs]._int);
|
||||||
|
@ -2264,6 +2283,289 @@ strofs = (strofs+3)&~3;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
#merge "oldprogs"
|
||||||
|
wrap void() worldspawn =
|
||||||
|
{
|
||||||
|
print("hello world\n");
|
||||||
|
prior();
|
||||||
|
};
|
||||||
|
|
||||||
|
Progs merging is done by loading in an existing progs.dat and essentially appending new stuff on the end.
|
||||||
|
The resulting output should be the same, other than wraps (which replaces the previous function global with the new one).
|
||||||
|
*/
|
||||||
|
static void QCC_MergeStrings(char *in, unsigned int num)
|
||||||
|
{
|
||||||
|
memcpy(strings, in, num);
|
||||||
|
strofs = num;
|
||||||
|
}
|
||||||
|
int QCC_MergeValidateString(int str)
|
||||||
|
{
|
||||||
|
if (str < 0 || str >= strofs)
|
||||||
|
str = 0;
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
static void QCC_MergeFunctions(dfunction_t *in, unsigned int num)
|
||||||
|
{
|
||||||
|
numfunctions = 0;
|
||||||
|
while(num --> 0)
|
||||||
|
{
|
||||||
|
if (in->first_statement <= 0)
|
||||||
|
{
|
||||||
|
functions[numfunctions].builtin = -in->first_statement;
|
||||||
|
functions[numfunctions].code = -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
functions[numfunctions].builtin = 0;
|
||||||
|
functions[numfunctions].code = in->first_statement;
|
||||||
|
}
|
||||||
|
functions[numfunctions].s_filed = QCC_MergeValidateString(in->s_file);
|
||||||
|
functions[numfunctions].filen = strings+functions[numfunctions].s_filed;
|
||||||
|
functions[numfunctions].line = 0;
|
||||||
|
functions[numfunctions].name = strings+QCC_MergeValidateString(in->s_name);
|
||||||
|
functions[numfunctions].parentscope = NULL;
|
||||||
|
functions[numfunctions].type = NULL;
|
||||||
|
functions[numfunctions].def = NULL;
|
||||||
|
functions[numfunctions].firstlocal = NULL;
|
||||||
|
functions[numfunctions].privatelocals = true;
|
||||||
|
functions[numfunctions].merged = in;
|
||||||
|
numfunctions++;
|
||||||
|
in++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static void QCC_MergeStatements16(dstatement16_t *in, unsigned int num)
|
||||||
|
{
|
||||||
|
QCC_statement_t *out = statements;
|
||||||
|
numstatements = num;
|
||||||
|
for (; num --> 0; out++, in++)
|
||||||
|
{
|
||||||
|
out->op = in->op;
|
||||||
|
out->a.sym = NULL;
|
||||||
|
out->a.cast = NULL;
|
||||||
|
out->a.ofs = in->a;
|
||||||
|
out->b.sym = NULL;
|
||||||
|
out->b.cast = NULL;
|
||||||
|
out->b.ofs = in->b;
|
||||||
|
out->c.sym = NULL;
|
||||||
|
out->c.cast = NULL;
|
||||||
|
out->c.ofs = in->c;
|
||||||
|
out->linenum = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
out->op = OP_DONE;
|
||||||
|
out->a.ofs = 0;
|
||||||
|
out->b.ofs = 0;
|
||||||
|
out->c.ofs = 0;
|
||||||
|
out->linenum = 0;
|
||||||
|
numstatements++;
|
||||||
|
}
|
||||||
|
QCC_def_t *QCC_PR_DummyDef(QCC_type_t *type, char *name, QCC_function_t *scope, int arraysize, QCC_def_t *rootsymbol, unsigned int ofs, int referable, unsigned int flags);
|
||||||
|
static etype_t QCC_MergeFindFieldType(unsigned int ofs, const char *fldname, ddef16_t *fields, size_t numfields)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
etype_t best = ev_void;
|
||||||
|
for (i = 0; i < numfields; i++)
|
||||||
|
{
|
||||||
|
if (fields[i].ofs == ofs)
|
||||||
|
{ //sometimes we have field unions. go for the exact name match if we can so we don't get confused over vectors/floats. otherwise just go with the first (and hope they're correctly ordered)
|
||||||
|
char *name = strings+QCC_MergeValidateString(fields[i].s_name);
|
||||||
|
if (!strcmp(name, fldname))
|
||||||
|
return fields[i].type;
|
||||||
|
if (best == ev_void)
|
||||||
|
best = fields[i].type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return best;
|
||||||
|
}
|
||||||
|
static void QCC_MergeUnstrip(dfunction_t *in, unsigned int num)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
char *name;
|
||||||
|
QCC_def_t *def;
|
||||||
|
|
||||||
|
//functions may have been stripped. this results in an annoying lack of errors, and will likely confuse function wrapping...
|
||||||
|
//generate a new def for each function, if it doesn't already exist.
|
||||||
|
//these are probably going to be wasteful dupes, but they'll just get stripped again if they're still not used.
|
||||||
|
for (i = 0; i < num; i++)
|
||||||
|
{
|
||||||
|
if (!in[i].s_name)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
name = strings+QCC_MergeValidateString(in[i].s_name);
|
||||||
|
|
||||||
|
def = QCC_PR_GetDef(NULL, name, NULL, false, 0, GDF_BASICTYPE);
|
||||||
|
if (!def)
|
||||||
|
{
|
||||||
|
def = QCC_PR_GetDef(type_function, name, NULL, true, 0, GDF_BASICTYPE);
|
||||||
|
def->symboldata[def->ofs].function = i;
|
||||||
|
def->initialized = true;
|
||||||
|
def->referenced = true;
|
||||||
|
def->assumedtype = true;
|
||||||
|
}
|
||||||
|
QCC_FreeDef(def);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
QCC_type_t *QCC_PR_FieldType (QCC_type_t *pointsto);
|
||||||
|
static void QCC_MergeGlobalDefs16(ddef16_t *in, size_t num, void *values, size_t defscount, ddef16_t *fields, size_t numfields)
|
||||||
|
{
|
||||||
|
QCC_def_t *root, *def;
|
||||||
|
QCC_type_t *type;
|
||||||
|
etype_t evt;
|
||||||
|
|
||||||
|
char *name;
|
||||||
|
unsigned int flags;
|
||||||
|
pbool referrable;
|
||||||
|
|
||||||
|
numpr_globals = 0; //that root object will replace the normal reserved globals.
|
||||||
|
root = QCC_PR_GetDef(type_void, "", NULL, true, 0, GDF_USED);
|
||||||
|
root->symboldata = values;
|
||||||
|
root->symbolsize = defscount;
|
||||||
|
|
||||||
|
for (; num --> 0; in++)
|
||||||
|
{
|
||||||
|
name = strings+QCC_MergeValidateString(in->s_name);
|
||||||
|
|
||||||
|
flags = GDF_USED;
|
||||||
|
if (in->type & DEF_SAVEGLOBAL)
|
||||||
|
flags |= GDF_SAVED;
|
||||||
|
|
||||||
|
evt = in->type&~DEF_SAVEGLOBAL;
|
||||||
|
if (evt == ev_field)
|
||||||
|
evt = QCC_MergeFindFieldType(root->symboldata[in->ofs]._int, name, fields, numfields);
|
||||||
|
switch(evt)
|
||||||
|
{
|
||||||
|
case ev_void:
|
||||||
|
type = type_void;
|
||||||
|
break;
|
||||||
|
case ev_vector:
|
||||||
|
type = type_vector;
|
||||||
|
break;
|
||||||
|
case ev_float:
|
||||||
|
type = type_float;
|
||||||
|
break;
|
||||||
|
case ev_string:
|
||||||
|
type = type_string;
|
||||||
|
break;
|
||||||
|
case ev_entity:
|
||||||
|
type = type_entity;
|
||||||
|
break;
|
||||||
|
case ev_integer:
|
||||||
|
type = type_integer;
|
||||||
|
break;
|
||||||
|
case ev_function:
|
||||||
|
type = type_function;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
type = type_variant;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if ((in->type&~DEF_SAVEGLOBAL) == ev_field)
|
||||||
|
{
|
||||||
|
type = QCC_PR_FieldType(type);
|
||||||
|
flags |= GDF_CONST;
|
||||||
|
}
|
||||||
|
|
||||||
|
referrable = true; //fixme: disable if this appears to be within a function's local storage
|
||||||
|
|
||||||
|
def = QCC_PR_DummyDef(type, name, NULL, 0, root, in->ofs, referrable, flags);
|
||||||
|
def->initialized = 1;
|
||||||
|
def->referenced = true;
|
||||||
|
def->assumedtype = true;
|
||||||
|
|
||||||
|
if (evt == ev_vector)
|
||||||
|
{
|
||||||
|
int j = 3;
|
||||||
|
if ((in->type&~DEF_SAVEGLOBAL) == ev_field)
|
||||||
|
{
|
||||||
|
for (j = 0; j < 3; j++)
|
||||||
|
{
|
||||||
|
if (in[j+1].ofs == in->ofs+j && (in[j+1].type&~DEF_SAVEGLOBAL) == ev_field && QCC_MergeFindFieldType(root->symboldata[in[j+1].ofs]._int, strings+QCC_MergeValidateString(in[j+1].s_name), fields, numfields) == ev_float)
|
||||||
|
continue;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (j = 0; j < 3; j++)
|
||||||
|
{
|
||||||
|
if (in[j+1].ofs == in->ofs+j && (in[j+1].type&~DEF_SAVEGLOBAL) == ev_float)
|
||||||
|
continue;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
in += j;
|
||||||
|
num -= j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
QCC_FreeDef(root);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*load a progs into the current compile state.*/
|
||||||
|
void QCC_ImportProgs(const char *filename)
|
||||||
|
{
|
||||||
|
int flen;
|
||||||
|
dprograms_t *prog;
|
||||||
|
|
||||||
|
//these keywords are implicitly enabled by #merge
|
||||||
|
keyword_weak = true;
|
||||||
|
keyword_wrap = true;
|
||||||
|
|
||||||
|
// if (strofs != 0) //could be fixed with relocs
|
||||||
|
// QCC_Error(ERR_BADEXTENSION, "#merge used too late. It must be used before any other definitions.");
|
||||||
|
if (numstatements != 1) //should be easy to deal with.
|
||||||
|
QCC_Error(ERR_BADEXTENSION, "#merge used too late. It must be used before any other definitions.");
|
||||||
|
if (numfunctions != 1) //could be fixed with relocs
|
||||||
|
QCC_Error(ERR_BADEXTENSION, "#merge used too late. It must be used before any other definitions.");
|
||||||
|
if (numglobaldefs != 1) //could be fixed by inserting it properly. any already-defined defs must have their parentdef changed to union them with imported ones.
|
||||||
|
QCC_Error(ERR_BADEXTENSION, "#merge used too late. It must be used before any other definitions (globals).");
|
||||||
|
if (numfielddefs != 1) //could be fixed with relocs
|
||||||
|
QCC_Error(ERR_BADEXTENSION, "#merge used too late. It must be used before any other definitions (fields).");
|
||||||
|
if (numpr_globals != RESERVED_OFS) //not normally changed until after compiling
|
||||||
|
QCC_Error(ERR_BADEXTENSION, "#merge used too late. It must be used before any other definitions (regs).");
|
||||||
|
|
||||||
|
flen = externs->FileSize(filename);
|
||||||
|
if (flen < 0)
|
||||||
|
{
|
||||||
|
QCC_Error(ERR_COULDNTOPENFILE, "Couldn't open file %s", filename);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf ("\nnote: The #merge feature is still experimental\n\n");
|
||||||
|
//FIXME: find overlapped locals. strip them. merge with new ones.
|
||||||
|
//FIXME: find temps. strip them. you get the idea.
|
||||||
|
//FIXME: find immediates. set up hash tables for them for reuse. HAH!
|
||||||
|
|
||||||
|
prog = qccHunkAlloc(flen);
|
||||||
|
|
||||||
|
externs->ReadFile(filename, prog, flen, NULL);
|
||||||
|
|
||||||
|
if (prog->version == 7 && prog->secondaryversion == PROG_SECONDARYVERSION16 && !prog->blockscompressed && !prog->numtypes)
|
||||||
|
;
|
||||||
|
else if (prog->version == 7 && prog->secondaryversion == PROG_SECONDARYVERSION32 && !prog->blockscompressed && !prog->numtypes)
|
||||||
|
;
|
||||||
|
else if (prog->version != 6)
|
||||||
|
{
|
||||||
|
QCC_Error(ERR_COULDNTOPENFILE, "Unsupported version: %s", filename);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QCC_MergeStrings(((char*)prog+prog->ofs_strings), prog->numstrings);
|
||||||
|
QCC_MergeFunctions((dfunction_t*)((char*)prog+prog->ofs_functions), prog->numfunctions);
|
||||||
|
pr.size_fields = prog->entityfields;
|
||||||
|
if (prog->version == 7 && prog->secondaryversion == PROG_SECONDARYVERSION32)
|
||||||
|
{
|
||||||
|
// QCC_MergeStatements32((dstatement32_t*)((char*)prog+prog->ofs_statements), prog->numstatements);
|
||||||
|
// QCC_MergeGlobalDefs32((ddef32_t*)((char*)prog+prog->ofs_globaldefs), prog->numglobaldefs, ((char*)prog)+prog->ofs_globals, prog->numglobals, (ddef16_t*)((char*)prog+prog->ofs_fielddefs), prog->numfielddefs);
|
||||||
|
QCC_Error(ERR_COULDNTOPENFILE, "32bit versions not supported: %s", filename);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QCC_MergeStatements16((dstatement16_t*)((char*)prog+prog->ofs_statements), prog->numstatements);
|
||||||
|
QCC_MergeGlobalDefs16((ddef16_t*)((char*)prog+prog->ofs_globaldefs), prog->numglobaldefs, ((char*)prog)+prog->ofs_globals, prog->numglobals, (ddef16_t*)((char*)prog+prog->ofs_fielddefs), prog->numfielddefs);
|
||||||
|
}
|
||||||
|
QCC_MergeUnstrip((dfunction_t*)((char*)prog+prog->ofs_functions), prog->numfunctions);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2618,8 +2920,13 @@ int QCC_PR_FinishCompilation (void)
|
||||||
QCC_type_t *t;
|
QCC_type_t *t;
|
||||||
int errors;
|
int errors;
|
||||||
|
|
||||||
|
pbool externokay = false;
|
||||||
|
|
||||||
errors = false;
|
errors = false;
|
||||||
|
|
||||||
|
if (qcc_targetformat == QCF_FTE || qcc_targetformat == QCF_FTEDEBUG || qcc_targetformat == QCF_FTEH2)
|
||||||
|
externokay = true;
|
||||||
|
|
||||||
// check to make sure all functions prototyped have code
|
// check to make sure all functions prototyped have code
|
||||||
for (d=pr.def_head.next ; d ; d=d->next)
|
for (d=pr.def_head.next ; d ; d=d->next)
|
||||||
{
|
{
|
||||||
|
@ -2652,13 +2959,21 @@ int QCC_PR_FinishCompilation (void)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
QCC_PR_Warning(ERR_NOFUNC, strings + d->s_file, d->s_line, "function %s has no body",d->name);
|
QCC_PR_Warning(ERR_NOFUNC, d->filen, d->s_line, "function %s has no body",d->name);
|
||||||
QCC_PR_ParsePrintDef(ERR_NOFUNC, d);
|
QCC_PR_ParsePrintDef(ERR_NOFUNC, d);
|
||||||
bodylessfuncs = true;
|
bodylessfuncs = true;
|
||||||
errors = true;
|
errors = true;
|
||||||
}
|
}
|
||||||
else if (d->initialized==2)
|
else if (d->initialized==2)
|
||||||
|
{
|
||||||
|
if (!externokay)
|
||||||
|
{
|
||||||
|
QCC_PR_Warning(ERR_NOFUNC, d->filen, d->s_line, "extern is not supported with this target format",d->name);
|
||||||
|
QCC_PR_ParsePrintDef(ERR_NOFUNC, d);
|
||||||
|
errors = true;
|
||||||
|
}
|
||||||
bodylessfuncs = true;
|
bodylessfuncs = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pr_scope = NULL;
|
pr_scope = NULL;
|
||||||
|
@ -2819,7 +3134,9 @@ unsigned short QCC_PR_WriteProgdefs (char *filename)
|
||||||
{
|
{
|
||||||
if (!strcmp (d->name, "end_sys_globals"))
|
if (!strcmp (d->name, "end_sys_globals"))
|
||||||
break;
|
break;
|
||||||
// if (d->ofs<RESERVED_OFS)
|
if (!*d->name)
|
||||||
|
continue;
|
||||||
|
// if (d->symbolheader->ofs<RESERVED_OFS)
|
||||||
// continue;
|
// continue;
|
||||||
|
|
||||||
switch (d->type->type)
|
switch (d->type->type)
|
||||||
|
@ -3389,6 +3706,11 @@ void QCC_CopyFiles (void)
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#define WINDOWSARG(x) x
|
||||||
|
#else
|
||||||
|
#define WINDOWSARG(x) false
|
||||||
|
#endif
|
||||||
|
|
||||||
void QCC_PR_CommandLinePrecompilerOptions (void)
|
void QCC_PR_CommandLinePrecompilerOptions (void)
|
||||||
{
|
{
|
||||||
|
@ -3400,6 +3722,47 @@ void QCC_PR_CommandLinePrecompilerOptions (void)
|
||||||
|
|
||||||
for (i = 1;i<myargc;i++)
|
for (i = 1;i<myargc;i++)
|
||||||
{
|
{
|
||||||
|
if ( !strcmp(myargv[i], "-v") )
|
||||||
|
verbose++; //verbose
|
||||||
|
else if ( !strcmp(myargv[i], "-srcfile") )
|
||||||
|
{
|
||||||
|
if (++i == myargc)
|
||||||
|
break;
|
||||||
|
for (j = 0; j < numsourcefiles; j++)
|
||||||
|
{
|
||||||
|
if (!strcmp(sourcefileslist[j], myargv[i]))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (j == numsourcefiles)
|
||||||
|
{
|
||||||
|
if (numsourcefiles < MAXSOURCEFILESLIST)
|
||||||
|
strcpy(sourcefileslist[numsourcefiles++], myargv[i]);
|
||||||
|
else
|
||||||
|
QCC_PR_Warning(0, NULL, WARN_BADPARAMS, "too many -srcfile arguments");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( !strcmp(myargv[i], "-src") )
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
strcpy (qccmsourcedir, myargv[i]);
|
||||||
|
strcat (qccmsourcedir, "/");
|
||||||
|
}
|
||||||
|
else if ( !strcmp(myargv[i], "-o") )
|
||||||
|
; //explicit output file
|
||||||
|
else if ( !strcmp(myargv[i], "-qc") )
|
||||||
|
QCC_PR_Warning(0, NULL, WARN_BADPARAMS, "Argument %s is experimental", myargv[i]); //compile without linking. output cannot be read by engines.
|
||||||
|
else if ( !strcmp(myargv[i], "-progdefs") )
|
||||||
|
; //write progdefs.h
|
||||||
|
else if ( !strcmp(myargv[i], "-copy") )
|
||||||
|
; //copy files / write pak files
|
||||||
|
else if ( !strcmp(myargv[i], "-bspmodels") )
|
||||||
|
QCC_PR_Warning(0, NULL, WARN_BADPARAMS, "Argument %s is not supported", myargv[i]);
|
||||||
|
else if ( !strcmp(myargv[i], "-h2") || !strcmp(myargv[i], "-fteh2") || !strcmp(myargv[i], "-fte") || !strcmp(myargv[i], "-dp") )
|
||||||
|
; //various targets
|
||||||
|
else if ( !strcmp(myargv[i], "-pak") || !strcmp(myargv[i], "-pak2") )
|
||||||
|
QCC_PR_Warning(0, NULL, WARN_BADPARAMS, "Argument %s is not supported", myargv[i]);
|
||||||
|
else
|
||||||
|
|
||||||
//compiler constant
|
//compiler constant
|
||||||
if ( !strncmp(myargv[i], "-D", 2) )
|
if ( !strncmp(myargv[i], "-D", 2) )
|
||||||
{
|
{
|
||||||
|
@ -3427,7 +3790,7 @@ void QCC_PR_CommandLinePrecompilerOptions (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
//optimisations.
|
//optimisations.
|
||||||
else if ( !strnicmp(myargv[i], "-O", 2) || !strnicmp(myargv[i], "/O", 2) )
|
else if ( !strnicmp(myargv[i], "-O", 2) || WINDOWSARG(!strnicmp(myargv[i], "/O", 2)) )
|
||||||
{
|
{
|
||||||
qcc_nopragmaoptimise = true;
|
qcc_nopragmaoptimise = true;
|
||||||
p = 0;
|
p = 0;
|
||||||
|
@ -3462,7 +3825,7 @@ void QCC_PR_CommandLinePrecompilerOptions (void)
|
||||||
QCC_PR_Warning(0, NULL, WARN_BADPARAMS, "Unrecognised optimisation parameter (%s)", myargv[i]);
|
QCC_PR_Warning(0, NULL, WARN_BADPARAMS, "Unrecognised optimisation parameter (%s)", myargv[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if ( !strnicmp(myargv[i], "-K", 2) || !strnicmp(myargv[i], "/K", 2) )
|
else if ( !strnicmp(myargv[i], "-K", 2) || WINDOWSARG(!strnicmp(myargv[i], "/K", 2)) )
|
||||||
{
|
{
|
||||||
p = 0;
|
p = 0;
|
||||||
if (!strnicmp(myargv[i]+2, "no-", 3))
|
if (!strnicmp(myargv[i]+2, "no-", 3))
|
||||||
|
@ -3487,7 +3850,7 @@ void QCC_PR_CommandLinePrecompilerOptions (void)
|
||||||
if (!compiler_flag[p].enabled)
|
if (!compiler_flag[p].enabled)
|
||||||
QCC_PR_Warning(0, NULL, WARN_BADPARAMS, "Unrecognised keyword parameter (%s)", myargv[i]);
|
QCC_PR_Warning(0, NULL, WARN_BADPARAMS, "Unrecognised keyword parameter (%s)", myargv[i]);
|
||||||
}
|
}
|
||||||
else if ( !strnicmp(myargv[i], "-F", 2) || !strnicmp(myargv[i], "/F", 2) )
|
else if ( !strnicmp(myargv[i], "-F", 2) || WINDOWSARG(!strnicmp(myargv[i], "/F", 2)) )
|
||||||
{
|
{
|
||||||
pbool state;
|
pbool state;
|
||||||
const char *arg;
|
const char *arg;
|
||||||
|
@ -3527,7 +3890,7 @@ void QCC_PR_CommandLinePrecompilerOptions (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
else if ( !strncmp(myargv[i], "-T", 2) || !strncmp(myargv[i], "/T", 2) )
|
else if ( !strncmp(myargv[i], "-T", 2) || WINDOWSARG(!strncmp(myargv[i], "/T", 2)) )
|
||||||
{
|
{
|
||||||
p = 0;
|
p = 0;
|
||||||
if (!strcmp("parse", myargv[i]+2))
|
if (!strcmp("parse", myargv[i]+2))
|
||||||
|
@ -3546,7 +3909,7 @@ void QCC_PR_CommandLinePrecompilerOptions (void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else if ( !strnicmp(myargv[i], "-W", 2) || !strnicmp(myargv[i], "/W", 2) )
|
else if ( !strnicmp(myargv[i], "-W", 2) || WINDOWSARG(!strnicmp(myargv[i], "/W", 2)) )
|
||||||
{
|
{
|
||||||
if (!stricmp(myargv[i]+2, "all"))
|
if (!stricmp(myargv[i]+2, "all"))
|
||||||
{
|
{
|
||||||
|
@ -3619,6 +3982,8 @@ void QCC_PR_CommandLinePrecompilerOptions (void)
|
||||||
QCC_PR_Warning(0, NULL, WARN_BADPARAMS, "Unrecognised warning parameter (%s)", myargv[i]);
|
QCC_PR_Warning(0, NULL, WARN_BADPARAMS, "Unrecognised warning parameter (%s)", myargv[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (*myargv[i] == '-' || WINDOWSARG(*myargv[i] == '/'))
|
||||||
|
QCC_PR_Warning(0, NULL, WARN_BADPARAMS, "Unrecognised parameter (%s)", myargv[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (werror)
|
if (werror)
|
||||||
|
@ -3661,6 +4026,9 @@ void QCC_SetDefaultProperties (void)
|
||||||
|
|
||||||
ForcedCRC = 0;
|
ForcedCRC = 0;
|
||||||
defaultstatic = 0;
|
defaultstatic = 0;
|
||||||
|
verbose = 0;
|
||||||
|
*qccmsourcedir = 0;
|
||||||
|
QCC_PR_CloseProcessor();
|
||||||
|
|
||||||
QCC_PR_DefineName("FTEQCC");
|
QCC_PR_DefineName("FTEQCC");
|
||||||
|
|
||||||
|
@ -3728,6 +4096,7 @@ void QCC_SetDefaultProperties (void)
|
||||||
qccwarningaction[WARN_UNINITIALIZED] = WA_IGNORE; //not sure about this being ignored by default.
|
qccwarningaction[WARN_UNINITIALIZED] = WA_IGNORE; //not sure about this being ignored by default.
|
||||||
qccwarningaction[WARN_SELFNOTTHIS] = WA_IGNORE;
|
qccwarningaction[WARN_SELFNOTTHIS] = WA_IGNORE;
|
||||||
qccwarningaction[WARN_EVILPREPROCESSOR] = WA_WARN;//FIXME: make into WA_ERROR;
|
qccwarningaction[WARN_EVILPREPROCESSOR] = WA_WARN;//FIXME: make into WA_ERROR;
|
||||||
|
qccwarningaction[WARN_IDENTICALPRECOMPILER] = WA_IGNORE;
|
||||||
|
|
||||||
if (qcc_targetformat == QCF_HEXEN2 || qcc_targetformat == QCF_FTEH2)
|
if (qcc_targetformat == QCF_HEXEN2 || qcc_targetformat == QCF_FTEH2)
|
||||||
qccwarningaction[WARN_CASEINSENSITIVEFRAMEMACRO] = WA_IGNORE; //hexenc consides these fair game.
|
qccwarningaction[WARN_CASEINSENSITIVEFRAMEMACRO] = WA_IGNORE; //hexenc consides these fair game.
|
||||||
|
@ -3891,11 +4260,17 @@ pbool QCC_main (int argc, char **argv) //as part of the quake engine
|
||||||
|
|
||||||
char *s;
|
char *s;
|
||||||
|
|
||||||
|
s_filen = "cmdline";
|
||||||
|
s_filed = 0;
|
||||||
|
pr_source_line = 0;
|
||||||
|
|
||||||
if (numsourcefiles && currentsourcefile == numsourcefiles)
|
if (numsourcefiles && currentsourcefile == numsourcefiles)
|
||||||
{
|
{
|
||||||
numsourcefiles = 0;
|
numsourcefiles = 0;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
else if (!numsourcefiles)
|
||||||
|
currentsourcefile = 0;
|
||||||
|
|
||||||
if (currentsourcefile && qccpersisthunk && numsourcefiles)
|
if (currentsourcefile && qccpersisthunk && numsourcefiles)
|
||||||
QCC_PR_ResetErrorScope(); //don't clear the ram if we're retaining def info
|
QCC_PR_ResetErrorScope(); //don't clear the ram if we're retaining def info
|
||||||
|
@ -4033,7 +4408,6 @@ pbool QCC_main (int argc, char **argv) //as part of the quake engine
|
||||||
|
|
||||||
|
|
||||||
tempsused = 0;
|
tempsused = 0;
|
||||||
s_file = 0;
|
|
||||||
|
|
||||||
QCC_PurgeTemps();
|
QCC_PurgeTemps();
|
||||||
|
|
||||||
|
@ -4090,12 +4464,6 @@ memset(pr_immediate_string, 0, sizeof(pr_immediate_string));
|
||||||
memset(&extra_parms, 0, sizeof(extra_parms));
|
memset(&extra_parms, 0, sizeof(extra_parms));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (p = 1; p<myargc; p++)
|
|
||||||
{
|
|
||||||
if ( !QC_strcasecmp("-v", myargv[p]) )
|
|
||||||
verbose++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( QCC_CheckParm ("/?") || QCC_CheckParm ("?") || QCC_CheckParm ("-?") || QCC_CheckParm ("-help") || QCC_CheckParm ("--help"))
|
if ( QCC_CheckParm ("/?") || QCC_CheckParm ("?") || QCC_CheckParm ("-?") || QCC_CheckParm ("-help") || QCC_CheckParm ("--help"))
|
||||||
{
|
{
|
||||||
printf ("qcc looks for progs.src in the current directory.\n");
|
printf ("qcc looks for progs.src in the current directory.\n");
|
||||||
|
@ -4130,15 +4498,8 @@ memset(pr_immediate_string, 0, sizeof(pr_immediate_string));
|
||||||
pHash_RemoveData = &Hash_RemoveDataInsensitive;
|
pHash_RemoveData = &Hash_RemoveDataInsensitive;
|
||||||
}
|
}
|
||||||
|
|
||||||
p = QCC_CheckParm ("-src");
|
if (*qccmsourcedir)
|
||||||
if (p && p < argc-1 )
|
|
||||||
{
|
|
||||||
strcpy (qccmsourcedir, argv[p+1]);
|
|
||||||
strcat (qccmsourcedir, "/");
|
|
||||||
printf ("Source directory: %s\n", qccmsourcedir);
|
printf ("Source directory: %s\n", qccmsourcedir);
|
||||||
}
|
|
||||||
else
|
|
||||||
*qccmsourcedir = '\0';
|
|
||||||
|
|
||||||
QCC_InitData ();
|
QCC_InitData ();
|
||||||
|
|
||||||
|
@ -4177,8 +4538,6 @@ memset(pr_immediate_string, 0, sizeof(pr_immediate_string));
|
||||||
if (!numsourcefiles)
|
if (!numsourcefiles)
|
||||||
{
|
{
|
||||||
p = QCC_CheckParm ("-qc");
|
p = QCC_CheckParm ("-qc");
|
||||||
if (!p || p >= argc-1 || argv[p+1][0] == '-')
|
|
||||||
p = QCC_CheckParm ("-srcfile");
|
|
||||||
if (p && p < argc-1 )
|
if (p && p < argc-1 )
|
||||||
sprintf (qccmprogsdat, "%s", argv[p+1]);
|
sprintf (qccmprogsdat, "%s", argv[p+1]);
|
||||||
else
|
else
|
||||||
|
@ -4335,6 +4694,13 @@ void QCC_ContinueCompile(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pr_file_p = qccmsrc;
|
||||||
|
s_filen = "";
|
||||||
|
s_filed = 0;
|
||||||
|
pr_source_line = 0;
|
||||||
|
QCC_PR_LexWhitespace(false);
|
||||||
|
qccmsrc = pr_file_p;
|
||||||
|
|
||||||
qccmsrc = QCC_COM_Parse(qccmsrc);
|
qccmsrc = QCC_COM_Parse(qccmsrc);
|
||||||
if (!qccmsrc)
|
if (!qccmsrc)
|
||||||
{
|
{
|
||||||
|
@ -4371,18 +4737,51 @@ void QCC_ContinueCompile(void)
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
QCC_GenerateRelativePath(qccmfilename, sizeof(qccmfilename), compilingrootfile, qcc_token);
|
|
||||||
|
|
||||||
|
QCC_FindBestInclude(qcc_token, compilingrootfile, 2);
|
||||||
|
/*
|
||||||
|
{
|
||||||
|
int includepath = 0;
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
if (includepath)
|
||||||
|
{
|
||||||
|
if (includepath > MAXINCLUDEDIRS || !*qccincludedir[includepath-1])
|
||||||
|
{
|
||||||
|
QCC_GenerateRelativePath(qccmfilename, sizeof(qccmfilename), compilingrootfile, qcc_token);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentfile = qccincludedir[includepath-1];
|
||||||
|
}
|
||||||
|
|
||||||
|
QCC_Canonicalize(qccmfilename, sizeof(fullname), qcc_token, compilingrootfile);
|
||||||
|
|
||||||
|
{
|
||||||
|
extern progfuncs_t *qccprogfuncs;
|
||||||
|
if (qccprogfuncs->funcs.parms->FileSize(qccmfilename) == -1)
|
||||||
|
{
|
||||||
|
includepath++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QCC_GenerateRelativePath(qccmfilename, sizeof(qccmfilename), compilingrootfile, qcc_token);
|
||||||
if (autoprototype)
|
if (autoprototype)
|
||||||
printf ("prototyping %s\n", qccmfilename);
|
printf ("prototyping %s\n", qccmfilename);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
printf ("compiling %s\n", qccmfilename);
|
printf ("compiling %s\n", qccmfilename);
|
||||||
}
|
}
|
||||||
|
|
||||||
QCC_LoadFile (qccmfilename, (void *)&qccmsrc2);
|
QCC_LoadFile (qccmfilename, (void *)&qccmsrc2);
|
||||||
|
|
||||||
if (!QCC_PR_CompileFile (qccmsrc2, qccmfilename) )
|
if (!QCC_PR_CompileFile (qccmsrc2, qccmfilename) )
|
||||||
QCC_Error (ERR_PARSEERRORS, "Errors have occured\n");
|
QCC_Error (ERR_PARSEERRORS, "Errors have occured\n");
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
void QCC_FinishCompile(void)
|
void QCC_FinishCompile(void)
|
||||||
{
|
{
|
||||||
|
@ -4394,7 +4793,8 @@ void QCC_FinishCompile(void)
|
||||||
if (setjmp(pr_parse_abort))
|
if (setjmp(pr_parse_abort))
|
||||||
QCC_Error(ERR_INTERNAL, "");
|
QCC_Error(ERR_INTERNAL, "");
|
||||||
|
|
||||||
s_file = 0;
|
s_filen = "";
|
||||||
|
s_filed = 0;
|
||||||
pr_source_line = 0;
|
pr_source_line = 0;
|
||||||
|
|
||||||
if (!QCC_PR_FinishCompilation ())
|
if (!QCC_PR_FinishCompilation ())
|
||||||
|
@ -4510,7 +4910,6 @@ void QCC_FinishCompile(void)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
extern QCC_string_t s_file, s_file2;
|
|
||||||
extern char *pr_file_p;
|
extern char *pr_file_p;
|
||||||
extern int pr_source_line;
|
extern int pr_source_line;
|
||||||
void QCC_PR_ParseDefs (char *classname);
|
void QCC_PR_ParseDefs (char *classname);
|
||||||
|
@ -4521,6 +4920,7 @@ void QCC_PR_ParseDefs (char *classname);
|
||||||
|
|
||||||
void StartNewStyleCompile(void)
|
void StartNewStyleCompile(void)
|
||||||
{
|
{
|
||||||
|
char *tmp;
|
||||||
if (setjmp(pr_parse_abort))
|
if (setjmp(pr_parse_abort))
|
||||||
{
|
{
|
||||||
if (++pr_error_count > MAX_ERRORS)
|
if (++pr_error_count > MAX_ERRORS)
|
||||||
|
@ -4535,8 +4935,17 @@ void StartNewStyleCompile(void)
|
||||||
|
|
||||||
compilingfile = qccmprogsdat;
|
compilingfile = qccmprogsdat;
|
||||||
|
|
||||||
|
s_filen = tmp = qccHunkAlloc(strlen(compilingfile)+1);
|
||||||
|
strcpy(tmp, compilingfile);
|
||||||
|
if (opt_filenames)
|
||||||
|
{
|
||||||
|
optres_filenames += strlen(compilingfile)+1;
|
||||||
|
s_filed = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
s_filed = QCC_CopyString (compilingfile);
|
||||||
|
|
||||||
pr_file_p = qccmsrc;
|
pr_file_p = qccmsrc;
|
||||||
s_file = s_file2 = QCC_CopyString (compilingfile);
|
|
||||||
|
|
||||||
pr_source_line = 0;
|
pr_source_line = 0;
|
||||||
|
|
||||||
|
@ -4565,9 +4974,19 @@ void new_QCC_ContinueCompile(void)
|
||||||
|
|
||||||
if (autoprototype && !parseonly)
|
if (autoprototype && !parseonly)
|
||||||
{
|
{
|
||||||
|
char *tmp;
|
||||||
qccmsrc = originalqccmsrc;
|
qccmsrc = originalqccmsrc;
|
||||||
|
|
||||||
|
s_filen = tmp = qccHunkAlloc(strlen(compilingfile)+1);
|
||||||
|
strcpy(tmp, compilingfile);
|
||||||
|
if (opt_filenames)
|
||||||
|
{
|
||||||
|
optres_filenames += strlen(compilingfile)+1;
|
||||||
|
s_filed = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
s_filed = QCC_CopyString (compilingfile);
|
||||||
pr_file_p = qccmsrc;
|
pr_file_p = qccmsrc;
|
||||||
s_file = s_file2 = QCC_CopyString (compilingfile);
|
|
||||||
|
|
||||||
autoprototyped = autoprototype;
|
autoprototyped = autoprototype;
|
||||||
QCC_SetDefaultProperties();
|
QCC_SetDefaultProperties();
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
pbool QC_decodeMethodSupported(int method);
|
pbool QC_decodeMethodSupported(int method);
|
||||||
char *QC_decode(progfuncs_t *progfuncs, int complen, int len, int method, char *info, char *buffer);
|
char *QC_decode(progfuncs_t *progfuncs, int complen, int len, int method, const char *info, char *buffer);
|
||||||
int QC_encode(progfuncs_t *progfuncs, int len, int method, char *in, int handle);
|
int QC_encode(progfuncs_t *progfuncs, int len, int method, const char *in, int handle);
|
||||||
|
pbool QC_EnumerateFilesFromBlob(const void *blob, size_t blobsize, void (*cb)(const char *name, const void *compdata, size_t compsize, int method, size_t plainsize));
|
||||||
int QC_encodecrc(int len, char *in);
|
int QC_encodecrc(int len, char *in);
|
||||||
|
|
||||||
char *PDECL filefromprogs(pubprogfuncs_t *progfuncs, progsnum_t prnum, char *fname, size_t *size, char *buffer);
|
char *PDECL filefromprogs(pubprogfuncs_t *progfuncs, progsnum_t prnum, char *fname, size_t *size, char *buffer);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#include "progsint.h"
|
#include "progsint.h"
|
||||||
//#include "qcc.h"
|
#include "qcc.h"
|
||||||
|
|
||||||
#ifndef NO_ZLIB
|
#ifndef NO_ZLIB
|
||||||
#define AVAIL_ZLIB
|
#define AVAIL_ZLIB
|
||||||
|
@ -35,7 +35,7 @@ pbool QC_decodeMethodSupported(int method)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *QC_decode(progfuncs_t *progfuncs, int complen, int len, int method, char *info, char *buffer)
|
char *QC_decode(progfuncs_t *progfuncs, int complen, int len, int method, const char *info, char *buffer)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
if (method == 0) //copy
|
if (method == 0) //copy
|
||||||
|
@ -49,11 +49,11 @@ char *QC_decode(progfuncs_t *progfuncs, int complen, int len, int method, char *
|
||||||
for (i = 0; i < len; i++)
|
for (i = 0; i < len; i++)
|
||||||
buffer[i] = info[i] ^ 0xA5;
|
buffer[i] = info[i] ^ 0xA5;
|
||||||
}
|
}
|
||||||
else if (method == 2) //compression (ZLIB)
|
|
||||||
{
|
|
||||||
#ifdef AVAIL_ZLIB
|
#ifdef AVAIL_ZLIB
|
||||||
|
else if (method == 2 || method == 8) //compression (ZLIB)
|
||||||
|
{
|
||||||
z_stream strm = {
|
z_stream strm = {
|
||||||
info,
|
(char*)info,
|
||||||
complen,
|
complen,
|
||||||
0,
|
0,
|
||||||
|
|
||||||
|
@ -73,12 +73,15 @@ char *QC_decode(progfuncs_t *progfuncs, int complen, int len, int method, char *
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
inflateInit(&strm);
|
if (method == 8)
|
||||||
|
inflateInit2(&strm, -MAX_WBITS);
|
||||||
|
else
|
||||||
|
inflateInit(&strm);
|
||||||
if (Z_STREAM_END != inflate(&strm, Z_FINISH)) //decompress it in one go.
|
if (Z_STREAM_END != inflate(&strm, Z_FINISH)) //decompress it in one go.
|
||||||
Sys_Error("Failed block decompression\n");
|
Sys_Error("Failed block decompression\n");
|
||||||
inflateEnd(&strm);
|
inflateEnd(&strm);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
//add your decryption/decompression routine here.
|
//add your decryption/decompression routine here.
|
||||||
else
|
else
|
||||||
Sys_Error("Bad file encryption routine\n");
|
Sys_Error("Bad file encryption routine\n");
|
||||||
|
@ -96,10 +99,10 @@ int QC_encodecrc(int len, char *in)
|
||||||
return 0;
|
return 0;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
void SafeWrite(int hand, void *buf, long count);
|
void SafeWrite(int hand, const void *buf, long count);
|
||||||
int SafeSeek(int hand, int ofs, int mode);
|
int SafeSeek(int hand, int ofs, int mode);
|
||||||
//we are allowed to trash our input here.
|
//we are allowed to trash our input here.
|
||||||
int QC_encode(progfuncs_t *progfuncs, int len, int method, char *in, int handle)
|
int QC_encode(progfuncs_t *progfuncs, int len, int method, const char *in, int handle)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
if (method == 0) //copy, allows a lame pass-through.
|
if (method == 0) //copy, allows a lame pass-through.
|
||||||
|
@ -107,20 +110,20 @@ int QC_encode(progfuncs_t *progfuncs, int len, int method, char *in, int handle)
|
||||||
SafeWrite(handle, in, len);
|
SafeWrite(handle, in, len);
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
else if (method == 1) //xor encryption, not secure. maybe useful for the string table.
|
/*else if (method == 1) //xor encryption, not secure. maybe useful for the string table.
|
||||||
{
|
{
|
||||||
for (i = 0; i < len; i++)
|
for (i = 0; i < len; i++)
|
||||||
in[i] = in[i] ^ 0xA5;
|
in[i] = in[i] ^ 0xA5;
|
||||||
SafeWrite(handle, in, len);
|
SafeWrite(handle, in, len);
|
||||||
return len;
|
return len;
|
||||||
}
|
}*/
|
||||||
else if (method == 2 || method == 8) //compression (ZLIB)
|
else if (method == 2 || method == 8) //compression (ZLIB)
|
||||||
{
|
{
|
||||||
#ifdef AVAIL_ZLIB
|
#ifdef AVAIL_ZLIB
|
||||||
char out[8192];
|
char out[8192];
|
||||||
|
|
||||||
z_stream strm = {
|
z_stream strm = {
|
||||||
in,
|
(char *)in,
|
||||||
len,
|
len,
|
||||||
0,
|
0,
|
||||||
|
|
||||||
|
@ -169,6 +172,75 @@ int QC_encode(progfuncs_t *progfuncs, int len, int method, char *in, int handle)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static int QC_ReadRawInt(const unsigned char *blob)
|
||||||
|
{
|
||||||
|
return (blob[0]<<0) | (blob[1]<<8) | (blob[2]<<16) | (blob[3]<<24);
|
||||||
|
}
|
||||||
|
static int QC_ReadRawShort(const unsigned char *blob)
|
||||||
|
{
|
||||||
|
return (blob[0]<<0) | (blob[1]<<8);
|
||||||
|
}
|
||||||
|
pbool QC_EnumerateFilesFromBlob(const void *blob, size_t blobsize, void (*cb)(const char *name, const void *compdata, size_t compsize, int method, size_t plainsize))
|
||||||
|
{
|
||||||
|
unsigned int cdentries;
|
||||||
|
unsigned int cdlen;
|
||||||
|
const unsigned char *eocd;
|
||||||
|
const unsigned char *cd;
|
||||||
|
int nl,el,cl;
|
||||||
|
if (blobsize < 22)
|
||||||
|
return false;
|
||||||
|
eocd = blob;
|
||||||
|
eocd += blobsize-22;
|
||||||
|
if (QC_ReadRawInt(eocd+0) != 0x06054b50)
|
||||||
|
return false;
|
||||||
|
if (QC_ReadRawShort(eocd+4) || QC_ReadRawShort(eocd+6) || QC_ReadRawShort(eocd+20) || QC_ReadRawShort(eocd+8) != QC_ReadRawShort(eocd+10))
|
||||||
|
return false;
|
||||||
|
cd = blob;
|
||||||
|
cd += QC_ReadRawInt(eocd+16);
|
||||||
|
cdlen = QC_ReadRawInt(eocd+12);
|
||||||
|
cdentries = QC_ReadRawInt(eocd+10);
|
||||||
|
if (cd+cdlen>=(const unsigned char*)blob+blobsize)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
|
||||||
|
for(; cdentries --> 0; cd += 46 + nl+el+cl)
|
||||||
|
{
|
||||||
|
if (QC_ReadRawInt(cd+0) != 0x02014b50)
|
||||||
|
break;
|
||||||
|
nl = QC_ReadRawShort(cd+28);
|
||||||
|
el = QC_ReadRawShort(cd+30);
|
||||||
|
cl = QC_ReadRawShort(cd+32);
|
||||||
|
|
||||||
|
if (QC_ReadRawShort(cd+8) != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
{
|
||||||
|
const unsigned char *le = (const unsigned char*)blob + QC_ReadRawInt(cd+42);
|
||||||
|
unsigned int csize, usize, method;
|
||||||
|
char name[256];
|
||||||
|
|
||||||
|
if (QC_ReadRawInt(le+0) != 0x04034b50)
|
||||||
|
continue;
|
||||||
|
if (QC_ReadRawShort(le+6) != 0) //general purpose flags
|
||||||
|
continue;
|
||||||
|
method = QC_ReadRawShort(le+8);
|
||||||
|
if (method != 0 && method != 8)
|
||||||
|
continue;
|
||||||
|
if (nl != QC_ReadRawShort(le+26))
|
||||||
|
continue; //name is weird...
|
||||||
|
if (el != QC_ReadRawShort(le+28))
|
||||||
|
continue; //name is weird...
|
||||||
|
|
||||||
|
csize = QC_ReadRawInt(le+18);
|
||||||
|
usize = QC_ReadRawInt(le+22);
|
||||||
|
QC_strlcpy(name, cd+46, (nl+1<sizeof(name))?nl+1:sizeof(name));
|
||||||
|
|
||||||
|
cb(name, le+30+QC_ReadRawShort(le+26)+QC_ReadRawShort(le+28), csize, method, usize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
char *PDECL filefromprogs(pubprogfuncs_t *ppf, progsnum_t prnum, char *fname, size_t *size, char *buffer)
|
char *PDECL filefromprogs(pubprogfuncs_t *ppf, progsnum_t prnum, char *fname, size_t *size, char *buffer)
|
||||||
{
|
{
|
||||||
progfuncs_t *progfuncs = (progfuncs_t*)ppf;
|
progfuncs_t *progfuncs = (progfuncs_t*)ppf;
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
#if !defined(MINIMAL) && !defined(OMIT_QCC)
|
#if !defined(MINIMAL) && !defined(OMIT_QCC)
|
||||||
|
|
||||||
|
//decompiling a progs should normally be done by walking the function table and emitting each def leading up to the one that refers to the function in question.
|
||||||
|
//this of course assumes strict ordering
|
||||||
|
|
||||||
//#include "qcc.h"
|
//#include "qcc.h"
|
||||||
#include "progsint.h"
|
#include "progsint.h"
|
||||||
#include "setjmp.h"
|
#include "setjmp.h"
|
||||||
|
@ -861,7 +864,7 @@ pbool PDECL QC_Decompile(pubprogfuncs_t *ppf, char *fname)
|
||||||
|
|
||||||
f=SafeOpenWrite("qcdtest/defs.qc", 1024*512);
|
f=SafeOpenWrite("qcdtest/defs.qc", 1024*512);
|
||||||
|
|
||||||
writes(f, "//Decompiled code can contain little type info.\r\n#define NOWARNINGS\r\n");
|
writes(f, "//Decompiled code can contain little type info.\r\n");
|
||||||
|
|
||||||
FigureOutTypes(progfuncs);
|
FigureOutTypes(progfuncs);
|
||||||
|
|
||||||
|
|
|
@ -2070,28 +2070,6 @@ void QC_Clear(void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
int prnumforfile;
|
|
||||||
int PR_SizeOfFile(char *filename)
|
|
||||||
{
|
|
||||||
size_t sz;
|
|
||||||
// int size;
|
|
||||||
if (!svprogfuncs)
|
|
||||||
return -1;
|
|
||||||
prnumforfile=svs.numprogs-1;
|
|
||||||
while(prnumforfile>=0)
|
|
||||||
{
|
|
||||||
if ((qbyte *)svprogfuncs->filefromprogs(svprogfuncs, prnumforfile, filename, &sz, NULL)==(qbyte *)-1)
|
|
||||||
return sz;
|
|
||||||
prnumforfile--;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
qbyte *PR_OpenFile(char *filename, qbyte *buffer)
|
|
||||||
{
|
|
||||||
return svprogfuncs->filefromprogs(svprogfuncs, prnumforfile, filename, NULL, buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//#define RETURN_EDICT(pf, e) (((int *)pr_globals)[OFS_RETURN] = EDICT_TO_PROG(pf, e))
|
//#define RETURN_EDICT(pf, e) (((int *)pr_globals)[OFS_RETURN] = EDICT_TO_PROG(pf, e))
|
||||||
#define RETURN_SSTRING(s) (((int *)pr_globals)[OFS_RETURN] = PR_SetString(prinst, s)) //static - exe will not change it.
|
#define RETURN_SSTRING(s) (((int *)pr_globals)[OFS_RETURN] = PR_SetString(prinst, s)) //static - exe will not change it.
|
||||||
|
@ -4314,7 +4292,7 @@ vector aim(entity, missilespeed)
|
||||||
=============
|
=============
|
||||||
*/
|
*/
|
||||||
//cvar_t sv_aim = {"sv_aim", "0.93"};
|
//cvar_t sv_aim = {"sv_aim", "0.93"};
|
||||||
cvar_t sv_aim = SCVAR("sv_aim", "2");
|
cvar_t sv_aim = CVAR("sv_aim", "2");
|
||||||
static void QCBUILTIN PF_aim (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
static void QCBUILTIN PF_aim (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||||
{
|
{
|
||||||
edict_t *ent, *check, *bestent;
|
edict_t *ent, *check, *bestent;
|
||||||
|
@ -10951,6 +10929,26 @@ void PR_DumpPlatform_f(void)
|
||||||
#else
|
#else
|
||||||
//eg: pr_dumpplatform -FFTE -TCS -O csplat
|
//eg: pr_dumpplatform -FFTE -TCS -O csplat
|
||||||
|
|
||||||
|
const char *keywords[] =
|
||||||
|
{
|
||||||
|
"ignore" //0
|
||||||
|
"qwqc", //qw
|
||||||
|
"nqqc", //nq
|
||||||
|
"ssqc" //qw|nq
|
||||||
|
"csqc" //cs
|
||||||
|
"csqwqc", //cs|qw
|
||||||
|
"csnqqc", //cs|nq
|
||||||
|
"gameqc" //cs|nq|qw
|
||||||
|
"menuonly" //mn
|
||||||
|
"mnqwqc", //mn|qw
|
||||||
|
"mnnqqc", //mn|nq
|
||||||
|
"mnssqc" //mn|qw|nq
|
||||||
|
"mncsqc" //mn|cs
|
||||||
|
"mncsqwqc", //mn|cs|qw
|
||||||
|
"mncsnqqc", //mn|cs|nq
|
||||||
|
"" //mn|cs|nq|qw
|
||||||
|
};
|
||||||
|
|
||||||
int idx;
|
int idx;
|
||||||
int i, j;
|
int i, j;
|
||||||
int d = 0, nd, k;
|
int d = 0, nd, k;
|
||||||
|
@ -11345,11 +11343,11 @@ void PR_DumpPlatform_f(void)
|
||||||
{"CONTENTBIT_MONSTERCLIP", "const int", QW|NQ|CS, NULL, 0,STRINGIFY(FTECONTENTS_MONSTERCLIP)},
|
{"CONTENTBIT_MONSTERCLIP", "const int", QW|NQ|CS, NULL, 0,STRINGIFY(FTECONTENTS_MONSTERCLIP)},
|
||||||
{"CONTENTBIT_BODY", "const int", QW|NQ|CS, NULL, 0,STRINGIFY(FTECONTENTS_BODY)},
|
{"CONTENTBIT_BODY", "const int", QW|NQ|CS, NULL, 0,STRINGIFY(FTECONTENTS_BODY)},
|
||||||
{"CONTENTBIT_CORPSE", "const int", QW|NQ|CS, NULL, 0,STRINGIFY(FTECONTENTS_CORPSE)},
|
{"CONTENTBIT_CORPSE", "const int", QW|NQ|CS, NULL, 0,STRINGIFY(FTECONTENTS_CORPSE)},
|
||||||
{"CONTENTBIT_Q2LADDER", "const int", QW|NQ|CS, NULL, 0,STRINGIFY(Q2CONTENTS_LADDER)},
|
{"CONTENTBIT_Q2LADDER", "const int", QW|NQ|CS, "Content bit specific to q2bsp", 0,STRINGIFY(Q2CONTENTS_LADDER)},
|
||||||
{"CONTENTBIT_SKY", "const int", QW|NQ|CS, NULL, 0,STRINGIFY(FTECONTENTS_SKY)},
|
{"CONTENTBIT_SKY", "const int", QW|NQ|CS, NULL, 0,STRINGIFY(FTECONTENTS_SKY)"i"},
|
||||||
{"CONTENTBITS_POINTSOLID", "const int", QW|NQ|CS, NULL, 0,STRINGIFY(MASK_POINTSOLID)},
|
{"CONTENTBITS_POINTSOLID", "const int", QW|NQ|CS, "Bits that traceline would normally consider solid", 0,"CONTENTBIT_SOLID|"STRINGIFY(Q2CONTENTS_WINDOW)"|CONTENTBIT_BODY"},
|
||||||
{"CONTENTBITS_BOXSOLID", "const int", QW|NQ|CS, NULL, 0,STRINGIFY(MASK_BOXSOLID)},
|
{"CONTENTBITS_BOXSOLID", "const int", QW|NQ|CS, "Bits that tracebox would normally consider solid", 0,"CONTENTBIT_SOLID|"STRINGIFY(Q2CONTENTS_WINDOW)"|CONTENTBIT_BODY|CONTENTBIT_PLAYERCLIP"},
|
||||||
{"CONTENTBITS_FLUID", "const int", QW|NQ|CS, NULL, 0,STRINGIFY(FTECONTENTS_FLUID)},
|
{"CONTENTBITS_FLUID", "const int", QW|NQ|CS, NULL, 0,"CONTENTBIT_WATER|CONTENTBIT_SLIME|CONTENTBIT_LAVA|CONTENTBIT_SKY"},
|
||||||
|
|
||||||
{"CHAN_AUTO", "const float", QW|NQ|CS, "The automatic channel, play as many sounds on this channel as you want, and they'll all play, however the other channels will replace each other.", CHAN_AUTO},
|
{"CHAN_AUTO", "const float", QW|NQ|CS, "The automatic channel, play as many sounds on this channel as you want, and they'll all play, however the other channels will replace each other.", CHAN_AUTO},
|
||||||
{"CHAN_WEAPON", "const float", QW|NQ|CS, NULL, CHAN_WEAPON},
|
{"CHAN_WEAPON", "const float", QW|NQ|CS, NULL, CHAN_WEAPON},
|
||||||
|
@ -11889,22 +11887,28 @@ void PR_DumpPlatform_f(void)
|
||||||
VFS_PRINTF(f, "#define %s\n", QSG_Extensions[i].name);
|
VFS_PRINTF(f, "#define %s\n", QSG_Extensions[i].name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VFS_PRINTF(f, "\n");
|
||||||
|
|
||||||
if (accessors)
|
if (accessors)
|
||||||
{
|
VFS_PRINTF(f, "#define _ACCESSORS;\n");
|
||||||
VFS_PRINTF(f, "accessor strbuf : float;\n");
|
|
||||||
VFS_PRINTF(f, "accessor searchhandle : float;\n");
|
VFS_PRINTF(f,
|
||||||
VFS_PRINTF(f, "accessor hashtable : float;\n");
|
"#ifdef _ACCESSORS\n"
|
||||||
VFS_PRINTF(f, "accessor infostring : string;\n");
|
"accessor strbuf : float;\n"
|
||||||
VFS_PRINTF(f, "accessor filestream : float;\n");
|
"accessor searchhandle : float;\n"
|
||||||
}
|
"accessor hashtable : float;\n"
|
||||||
else
|
"accessor infostring : string;\n"
|
||||||
{
|
"accessor filestream : float;\n"
|
||||||
VFS_PRINTF(f, "#define strbuf float\n");
|
"accessor filestream : float;\n"
|
||||||
VFS_PRINTF(f, "#define searchhandle float\n");
|
"#else\n"
|
||||||
VFS_PRINTF(f, "#define hashtable float\n");
|
"#define strbuf float\n"
|
||||||
VFS_PRINTF(f, "#define infostring string\n");
|
"#define searchhandle float\n"
|
||||||
VFS_PRINTF(f, "#define filestream float\n");
|
"#define hashtable float\n"
|
||||||
}
|
"#define infostring string\n"
|
||||||
|
"#define filestream float\n"
|
||||||
|
"#endif\n"
|
||||||
|
);
|
||||||
|
VFS_PRINTF(f, "\n");
|
||||||
|
|
||||||
|
|
||||||
for (i = 0; knowndefs[i].name; i++)
|
for (i = 0; knowndefs[i].name; i++)
|
||||||
|
@ -12238,6 +12242,7 @@ void PR_DumpPlatform_f(void)
|
||||||
|
|
||||||
if (accessors)
|
if (accessors)
|
||||||
{
|
{
|
||||||
|
VFS_PRINTF(f, "#ifdef _ACCESSORS\n");
|
||||||
VFS_PRINTF(f,
|
VFS_PRINTF(f,
|
||||||
"accessor strbuf : float\n{\n"
|
"accessor strbuf : float\n{\n"
|
||||||
"\tinline get float asfloat[float idx] = {return stof(bufstr_get(this, idx));};\n"
|
"\tinline get float asfloat[float idx] = {return stof(bufstr_get(this, idx));};\n"
|
||||||
|
@ -12274,6 +12279,7 @@ void PR_DumpPlatform_f(void)
|
||||||
"\tget string = fgets;\n"
|
"\tget string = fgets;\n"
|
||||||
"\tinline set string = {fputs(this,value);};\n"
|
"\tinline set string = {fputs(this,value);};\n"
|
||||||
"};\n");
|
"};\n");
|
||||||
|
VFS_PRINTF(f, "#endif\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
VFS_PRINTF(f, "#pragma noref 0\n");
|
VFS_PRINTF(f, "#pragma noref 0\n");
|
||||||
|
|
|
@ -738,7 +738,7 @@ typedef struct {
|
||||||
int maxsize;
|
int maxsize;
|
||||||
} dbuffer_t;
|
} dbuffer_t;
|
||||||
|
|
||||||
#define DEMO_FRAMES 64
|
#define DEMO_FRAMES 64 //why is this not just 2?
|
||||||
#define DEMO_FRAMES_MASK (DEMO_FRAMES - 1)
|
#define DEMO_FRAMES_MASK (DEMO_FRAMES - 1)
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
@ -758,6 +758,7 @@ typedef struct
|
||||||
qboolean fixangle[MAX_CLIENTS];
|
qboolean fixangle[MAX_CLIENTS];
|
||||||
float fixangletime[MAX_CLIENTS];
|
float fixangletime[MAX_CLIENTS];
|
||||||
vec3_t angles[MAX_CLIENTS];
|
vec3_t angles[MAX_CLIENTS];
|
||||||
|
qboolean resetdeltas;
|
||||||
int parsecount;
|
int parsecount;
|
||||||
int lastwritten;
|
int lastwritten;
|
||||||
demo_frame_t frames[DEMO_FRAMES];
|
demo_frame_t frames[DEMO_FRAMES];
|
||||||
|
@ -1486,7 +1487,7 @@ char *SV_Demo_CurrentOutput(void);
|
||||||
void SV_MVDInit(void);
|
void SV_MVDInit(void);
|
||||||
char *SV_MVDNum(char *buffer, int bufferlen, int num);
|
char *SV_MVDNum(char *buffer, int bufferlen, int num);
|
||||||
void SV_SendMVDMessage(void);
|
void SV_SendMVDMessage(void);
|
||||||
void SV_MVD_WriteReliables(void);
|
void SV_MVD_WriteReliables(qboolean writebroadcasts);
|
||||||
qboolean SV_ReadMVD (void);
|
qboolean SV_ReadMVD (void);
|
||||||
void SV_FlushDemoSignon (void);
|
void SV_FlushDemoSignon (void);
|
||||||
void DestFlush(qboolean compleate);
|
void DestFlush(qboolean compleate);
|
||||||
|
|
|
@ -37,7 +37,7 @@ qboolean SV_MayCheat(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
extern cvar_t cl_warncmd;
|
extern cvar_t cl_warncmd;
|
||||||
cvar_t sv_cheats = SCVARF("sv_cheats", "0", CVAR_LATCH);
|
cvar_t sv_cheats = CVARF("sv_cheats", "0", CVAR_LATCH);
|
||||||
extern redirect_t sv_redirected;
|
extern redirect_t sv_redirected;
|
||||||
|
|
||||||
extern cvar_t sv_public;
|
extern cvar_t sv_public;
|
||||||
|
|
|
@ -46,32 +46,32 @@ client_t *host_client; // current client
|
||||||
|
|
||||||
// bound the size of the physics time tic
|
// bound the size of the physics time tic
|
||||||
#ifdef SERVERONLY
|
#ifdef SERVERONLY
|
||||||
cvar_t sv_mintic = CVARD("sv_mintic","0.013", "The minimum interval between running physics frames.");
|
cvar_t sv_mintic = CVARD("sv_mintic","0.013", "The minimum interval between running physics frames.");
|
||||||
#else
|
#else
|
||||||
cvar_t sv_mintic = CVARD("sv_mintic","0", "The minimum interval between running physics frames."); //client builds can think as often as they want.
|
cvar_t sv_mintic = CVARD("sv_mintic","0", "The minimum interval between running physics frames."); //client builds can think as often as they want.
|
||||||
#endif
|
#endif
|
||||||
cvar_t sv_maxtic = CVARD("sv_maxtic","0.1", "The maximum interval between running physics frames. If the value is too low, multiple physics interations might be run at a time (based upon sv_limittics). Set identical to sv_mintic for fixed-interval ticks, which may be required if ODE is used.");//never run a tick slower than this
|
cvar_t sv_maxtic = CVARD("sv_maxtic","0.1", "The maximum interval between running physics frames. If the value is too low, multiple physics interations might be run at a time (based upon sv_limittics). Set identical to sv_mintic for fixed-interval ticks, which may be required if ODE is used.");//never run a tick slower than this
|
||||||
cvar_t sv_limittics = CVARD("sv_limittics","3", "The maximum number of ticks that may be run within a frame, to allow the server to catch up if it stalled or if sv_maxtic is too low.");//
|
cvar_t sv_limittics = CVARD("sv_limittics","3", "The maximum number of ticks that may be run within a frame, to allow the server to catch up if it stalled or if sv_maxtic is too low.");//
|
||||||
|
|
||||||
cvar_t sv_nailhack = CVARD("sv_nailhack","0", "If set to 1, disables the nail entity networking optimisation. This hack was popularised by qizmo which recommends it for better compression. Also allows clients to interplate nail positions and add trails.");
|
cvar_t sv_nailhack = CVARD("sv_nailhack","0", "If set to 1, disables the nail entity networking optimisation. This hack was popularised by qizmo which recommends it for better compression. Also allows clients to interplate nail positions and add trails.");
|
||||||
cvar_t sv_nopvs = CVARD("sv_nopvs", "0", "Set to 1 to ignore pvs on the server. This can make wallhacks more dangerous, so should only be used for debugging.");
|
cvar_t sv_nopvs = CVARD("sv_nopvs", "0", "Set to 1 to ignore pvs on the server. This can make wallhacks more dangerous, so should only be used for debugging.");
|
||||||
cvar_t fraglog_public = CVARD("fraglog_public", "1", "Enables support for connectionless fraglog requests");
|
cvar_t fraglog_public = CVARD("fraglog_public", "1", "Enables support for connectionless fraglog requests");
|
||||||
cvar_t fraglog_details = CVARD("fraglog_details", "1", "Bitmask\n1: killer+killee names.\n2: killer+killee teams\n4:timestamp.\n8:killer weapon\n16:killer+killee guid.\nFor compatibility, use 1(vanilla) or 7(mvdsv).");
|
cvar_t fraglog_details = CVARD("fraglog_details", "1", "Bitmask\n1: killer+killee names.\n2: killer+killee teams\n4:timestamp.\n8:killer weapon\n16:killer+killee guid.\nFor compatibility, use 1(vanilla) or 7(mvdsv).");
|
||||||
|
|
||||||
cvar_t timeout = SCVAR("timeout","65"); // seconds without any message
|
cvar_t timeout = CVAR("timeout","65"); // seconds without any message
|
||||||
cvar_t zombietime = SCVAR("zombietime", "2"); // seconds to sink messages
|
cvar_t zombietime = CVAR("zombietime", "2"); // seconds to sink messages
|
||||||
// after disconnect
|
// after disconnect
|
||||||
#ifdef SERVERONLY
|
#ifdef SERVERONLY
|
||||||
cvar_t developer = SCVAR("developer","0"); // show extra messages
|
cvar_t developer = CVAR("developer","0"); // show extra messages
|
||||||
|
|
||||||
cvar_t rcon_password = SCVARF("rcon_password", "", CVAR_NOUNSAFEEXPAND); // password for remote server commands
|
cvar_t rcon_password = CVARF("rcon_password", "", CVAR_NOUNSAFEEXPAND); // password for remote server commands
|
||||||
cvar_t password = SCVARF("password", "", CVAR_NOUNSAFEEXPAND); // password for entering the game
|
cvar_t password = CVARF("password", "", CVAR_NOUNSAFEEXPAND); // password for entering the game
|
||||||
#else
|
#else
|
||||||
extern cvar_t developer;
|
extern cvar_t developer;
|
||||||
extern cvar_t rcon_password;
|
extern cvar_t rcon_password;
|
||||||
extern cvar_t password;
|
extern cvar_t password;
|
||||||
#endif
|
#endif
|
||||||
cvar_t spectator_password = CVARF("spectator_password", "", CVAR_NOUNSAFEEXPAND); // password for entering as a sepctator
|
cvar_t spectator_password = CVARF("spectator_password", "", CVAR_NOUNSAFEEXPAND); // password for entering as a sepctator
|
||||||
|
|
||||||
cvar_t allow_download = CVARD("allow_download", "1", "If 1, permits downloading. Set to 0 to unconditionally block *ALL* downloads.");
|
cvar_t allow_download = CVARD("allow_download", "1", "If 1, permits downloading. Set to 0 to unconditionally block *ALL* downloads.");
|
||||||
cvar_t allow_download_skins = CVARD("allow_download_skins", "1", "0 blocks downloading of any file in the skins/ directory");
|
cvar_t allow_download_skins = CVARD("allow_download_skins", "1", "0 blocks downloading of any file in the skins/ directory");
|
||||||
|
@ -88,46 +88,46 @@ cvar_t allow_download_packages = CVARD("allow_download_packages", "1", "if 1, p
|
||||||
cvar_t allow_download_refpackages = CVARD("allow_download_refpackages", "1", "If set to 1, packages that contain files needed during spawn functions will be become 'referenced' and automatically downloaded to clients.\nThis cvar should probably not be set if you have large packages that provide replacement pickup models on public servers.\nThe path command will show a '(ref)' tag next to packages which clients will automatically attempt to download.");
|
cvar_t allow_download_refpackages = CVARD("allow_download_refpackages", "1", "If set to 1, packages that contain files needed during spawn functions will be become 'referenced' and automatically downloaded to clients.\nThis cvar should probably not be set if you have large packages that provide replacement pickup models on public servers.\nThe path command will show a '(ref)' tag next to packages which clients will automatically attempt to download.");
|
||||||
cvar_t allow_download_wads = CVARD("allow_download_wads", "1", "0 blocks downloading of any file in the wads/ directory, or is in the root directory with the extension .wad");
|
cvar_t allow_download_wads = CVARD("allow_download_wads", "1", "0 blocks downloading of any file in the wads/ directory, or is in the root directory with the extension .wad");
|
||||||
cvar_t allow_download_configs = CVARD("allow_download_configs", "0", "1 allows downloading of config files, either with the extension .cfg or in the subdir configs/.\n"CON_ERROR"THIS IS DANGEROUS AS IT CAN ALLOW PEOPLE TO READ YOUR RCON PASSWORD.");
|
cvar_t allow_download_configs = CVARD("allow_download_configs", "0", "1 allows downloading of config files, either with the extension .cfg or in the subdir configs/.\n"CON_ERROR"THIS IS DANGEROUS AS IT CAN ALLOW PEOPLE TO READ YOUR RCON PASSWORD.");
|
||||||
cvar_t allow_download_locs = CVARD("allow_download_locs", "1", "0 blocks downloading of any file in the locs/ directory");
|
cvar_t allow_download_locs = CVARD("allow_download_locs", "1", "0 blocks downloading of any file in the locs/ directory");
|
||||||
cvar_t allow_download_copyrighted = CVARD("allow_download_copyrighted", "0", "0 blocks download of packages that are considered copyrighted. Specifically, this means packages with a leading 'pak' prefix on the filename.\nIf you take your copyrights seriously, you should also set allow_download_pakmaps 0 and allow_download_pakcontents 0.");
|
cvar_t allow_download_copyrighted = CVARD("allow_download_copyrighted", "0", "0 blocks download of packages that are considered copyrighted. Specifically, this means packages with a leading 'pak' prefix on the filename.\nIf you take your copyrights seriously, you should also set allow_download_pakmaps 0 and allow_download_pakcontents 0.");
|
||||||
cvar_t allow_download_other = CVARD("allow_download_other", "0", "0 blocks downloading of any file that was not covered by any of the directory download blocks.");
|
cvar_t allow_download_other = CVARD("allow_download_other", "0", "0 blocks downloading of any file that was not covered by any of the directory download blocks.");
|
||||||
|
|
||||||
extern cvar_t sv_allow_splitscreen;
|
extern cvar_t sv_allow_splitscreen;
|
||||||
|
|
||||||
cvar_t sv_serverip = CVARD("sv_serverip", "", "Set this cvar to the server's public ip address if the server is behind a firewall and cannot detect its own public address. Providing a port is required if the firewall/nat remaps it, but is otherwise optional.");
|
cvar_t sv_serverip = CVARD("sv_serverip", "", "Set this cvar to the server's public ip address if the server is behind a firewall and cannot detect its own public address. Providing a port is required if the firewall/nat remaps it, but is otherwise optional.");
|
||||||
cvar_t sv_public = CVAR("sv_public", "0");
|
cvar_t sv_public = CVAR("sv_public", "0");
|
||||||
cvar_t sv_listen_qw = CVARAF("sv_listen_qw", "1", "sv_listen", 0);
|
cvar_t sv_listen_qw = CVARAF("sv_listen_qw", "1", "sv_listen", 0);
|
||||||
cvar_t sv_listen_nq = CVARD("sv_listen_nq", "2", "Allow new (net)quake clients to connect to the server.\n0 = don't let them in.\n1 = allow them in (WARNING: this allows 'qsmurf' DOS attacks).\n2 = accept (net)quake clients by emulating a challenge (as secure as QW/Q2 but does not fully conform to the NQ protocol).");
|
cvar_t sv_listen_nq = CVARD("sv_listen_nq", "2", "Allow new (net)quake clients to connect to the server.\n0 = don't let them in.\n1 = allow them in (WARNING: this allows 'qsmurf' DOS attacks).\n2 = accept (net)quake clients by emulating a challenge (as secure as QW/Q2 but does not fully conform to the NQ protocol).");
|
||||||
cvar_t sv_listen_dp = CVARD("sv_listen_dp", "0", "Allows the server to respond with the DP-specific handshake protocol.\nWarning: this can potentially get confused with quake2, and results in race conditions with both vanilla netquake and quakeworld protocols.\nOn the plus side, DP clients can usually be identified correctly, enabling a model+sound limit boost.");
|
cvar_t sv_listen_dp = CVARD("sv_listen_dp", "0", "Allows the server to respond with the DP-specific handshake protocol.\nWarning: this can potentially get confused with quake2, and results in race conditions with both vanilla netquake and quakeworld protocols.\nOn the plus side, DP clients can usually be identified correctly, enabling a model+sound limit boost.");
|
||||||
cvar_t sv_listen_q3 = CVAR("sv_listen_q3", "0");
|
cvar_t sv_listen_q3 = CVAR("sv_listen_q3", "0");
|
||||||
cvar_t sv_reportheartbeats = CVAR("sv_reportheartbeats", "1");
|
cvar_t sv_reportheartbeats = CVAR("sv_reportheartbeats", "1");
|
||||||
cvar_t sv_highchars = CVAR("sv_highchars", "1");
|
cvar_t sv_highchars = CVAR("sv_highchars", "1");
|
||||||
cvar_t sv_maxrate = CVAR("sv_maxrate", "30000");
|
cvar_t sv_maxrate = CVAR("sv_maxrate", "30000");
|
||||||
cvar_t sv_maxdrate = CVARAF("sv_maxdrate", "500000",
|
cvar_t sv_maxdrate = CVARAF("sv_maxdrate", "500000",
|
||||||
"sv_maxdownloadrate", 0);
|
"sv_maxdownloadrate", 0);
|
||||||
cvar_t sv_minping = CVARF("sv_minping", "", CVAR_SERVERINFO);
|
cvar_t sv_minping = CVARF("sv_minping", "", CVAR_SERVERINFO);
|
||||||
|
|
||||||
cvar_t sv_bigcoords = CVARFD("sv_bigcoords", "1", 0, "Uses floats for coordinates instead of 16bit values.\nAlso boosts angle precision, so can be useful even on small maps.\nAffects clients thusly:\nQW: enforces a mandatory protocol extension\nDP: enables DPP7 protocol support\nNQ: uses RMQ protocol (protocol 999).");
|
cvar_t sv_bigcoords = CVARFD("sv_bigcoords", "1", 0, "Uses floats for coordinates instead of 16bit values.\nAlso boosts angle precision, so can be useful even on small maps.\nAffects clients thusly:\nQW: enforces a mandatory protocol extension\nDP: enables DPP7 protocol support\nNQ: uses RMQ protocol (protocol 999).");
|
||||||
cvar_t sv_calcphs = CVARFD("sv_calcphs", "2", CVAR_LATCH, "Enables culling of sound effects. 0=always skip phs. Sounds are globally broadcast. 1=always generate phs. Sounds are always culled. On large maps the phs will be dumped to disk. 2=On large single-player maps, generation of phs is skipped. Otherwise like option 1.");
|
cvar_t sv_calcphs = CVARFD("sv_calcphs", "2", CVAR_LATCH, "Enables culling of sound effects. 0=always skip phs. Sounds are globally broadcast. 1=always generate phs. Sounds are always culled. On large maps the phs will be dumped to disk. 2=On large single-player maps, generation of phs is skipped. Otherwise like option 1.");
|
||||||
|
|
||||||
cvar_t sv_showconnectionlessmessages = CVARD("sv_showconnectionlessmessages", "0", "Display a line describing each connectionless message that arrives on the server. Primarily a debugging feature, but also potentially useful to admins.");
|
cvar_t sv_showconnectionlessmessages = CVARD("sv_showconnectionlessmessages", "0", "Display a line describing each connectionless message that arrives on the server. Primarily a debugging feature, but also potentially useful to admins.");
|
||||||
cvar_t sv_cullplayers_trace = CVARFD("sv_cullplayers_trace", "", CVAR_SERVERINFO, "Attempt to cull player entities using tracelines as an anti-wallhack.");
|
cvar_t sv_cullplayers_trace = CVARFD("sv_cullplayers_trace", "", CVAR_SERVERINFO, "Attempt to cull player entities using tracelines as an anti-wallhack.");
|
||||||
cvar_t sv_cullentities_trace = CVARFD("sv_cullentities_trace", "", CVAR_SERVERINFO, "Attempt to cull non-player entities using tracelines as an extreeme anti-wallhack.");
|
cvar_t sv_cullentities_trace = CVARFD("sv_cullentities_trace", "", CVAR_SERVERINFO, "Attempt to cull non-player entities using tracelines as an extreeme anti-wallhack.");
|
||||||
cvar_t sv_phs = CVARD("sv_phs", "1", "If 1, do not use the phs. It is generally better to use sv_calcphs instead, and leave this as 1.");
|
cvar_t sv_phs = CVARD("sv_phs", "1", "If 1, do not use the phs. It is generally better to use sv_calcphs instead, and leave this as 1.");
|
||||||
cvar_t sv_resetparms = CVAR("sv_resetparms", "0");
|
cvar_t sv_resetparms = CVAR("sv_resetparms", "0");
|
||||||
cvar_t sv_pupglow = CVARFD("sv_pupglow", "", CVAR_SERVERINFO, "Instructs clients to enable hexen2-style powerup pulsing.");
|
cvar_t sv_pupglow = CVARFD("sv_pupglow", "", CVAR_SERVERINFO, "Instructs clients to enable hexen2-style powerup pulsing.");
|
||||||
|
|
||||||
cvar_t sv_master = CVAR("sv_master", "0");
|
cvar_t sv_master = CVAR("sv_master", "0");
|
||||||
cvar_t sv_masterport = CVAR("sv_masterport", "0");
|
cvar_t sv_masterport = CVAR("sv_masterport", "0");
|
||||||
|
|
||||||
cvar_t pext_ezquake_nochunks = CVARD("pext_ezquake_nochunks", "0", "Prevents ezquake clients from being able to use the chunked download extension. This sidesteps numerous ezquake issues, and will make downloads slower but more robust.");
|
cvar_t pext_ezquake_nochunks = CVARD("pext_ezquake_nochunks", "0", "Prevents ezquake clients from being able to use the chunked download extension. This sidesteps numerous ezquake issues, and will make downloads slower but more robust.");
|
||||||
|
|
||||||
cvar_t sv_gamespeed = CVARAF("sv_gamespeed", "1", "slowmo", 0);
|
cvar_t sv_gamespeed = CVARAF("sv_gamespeed", "1", "slowmo", 0);
|
||||||
cvar_t sv_csqcdebug = CVAR("sv_csqcdebug", "0");
|
cvar_t sv_csqcdebug = CVAR("sv_csqcdebug", "0");
|
||||||
cvar_t sv_csqc_progname = CVAR("sv_csqc_progname", "csprogs.dat");
|
cvar_t sv_csqc_progname = CVAR("sv_csqc_progname", "csprogs.dat");
|
||||||
cvar_t pausable = CVAR("pausable", "1");
|
cvar_t pausable = CVAR("pausable", "1");
|
||||||
cvar_t sv_banproxies = CVARD("sv_banproxies", "0", "If enabled, anyone connecting via known proxy software will be refused entry. This should aid with blocking aimbots, but is only reliable for certain public proxies.");
|
cvar_t sv_banproxies = CVARD("sv_banproxies", "0", "If enabled, anyone connecting via known proxy software will be refused entry. This should aid with blocking aimbots, but is only reliable for certain public proxies.");
|
||||||
cvar_t sv_specprint = CVARD("sv_specprint", "3", "Bitfield that controls which player events spectators see when tracking that player.\n&1: spectators will see centerprints.\n&2: spectators will see sprints (pickup messages etc).\n&4: spectators will receive console commands, this is potentially risky.\nIndividual spectators can use 'setinfo sp foo' to limit this setting.");
|
cvar_t sv_specprint = CVARD("sv_specprint", "3", "Bitfield that controls which player events spectators see when tracking that player.\n&1: spectators will see centerprints.\n&2: spectators will see sprints (pickup messages etc).\n&4: spectators will receive console commands, this is potentially risky.\nIndividual spectators can use 'setinfo sp foo' to limit this setting.");
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -4415,6 +4415,11 @@ static void SV_PauseChanged(void)
|
||||||
ClientReliableWrite_Byte (cl, sv.paused!=0);
|
ClientReliableWrite_Byte (cl, sv.paused!=0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (sv.mvdrecording)
|
||||||
|
{
|
||||||
|
ClientReliableWrite_Begin (&demo.recorder, svc_setpause, 2);
|
||||||
|
ClientReliableWrite_Byte (&demo.recorder, sv.paused!=0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -40,7 +40,7 @@ cvar_t sv_demofps = CVAR("sv_demofps", "30");
|
||||||
cvar_t sv_demoPings = CVARD("sv_demoPings", "10", "Interval between ping updates in mvds");
|
cvar_t sv_demoPings = CVARD("sv_demoPings", "10", "Interval between ping updates in mvds");
|
||||||
cvar_t sv_demoMaxSize = CVARD("sv_demoMaxSize", "", "Demos will be truncated to be no larger than this size.");
|
cvar_t sv_demoMaxSize = CVARD("sv_demoMaxSize", "", "Demos will be truncated to be no larger than this size.");
|
||||||
cvar_t sv_demoExtraNames = CVAR("sv_demoExtraNames", "");
|
cvar_t sv_demoExtraNames = CVAR("sv_demoExtraNames", "");
|
||||||
cvar_t sv_demoExtensions = CVARD("sv_demoExtensions", "0", "Enables protocol extensions within MVDs. This will cause older/non-fte clients to error upon playback");
|
cvar_t sv_demoExtensions = CVARD("sv_demoExtensions", "", "Enables protocol extensions within MVDs. This will cause older/non-fte clients to error upon playback.\n0: off.\n1: all extensions.\n2: extensions also supported by a certain other engine.");
|
||||||
|
|
||||||
cvar_t qtv_password = CVAR( "qtv_password", "");
|
cvar_t qtv_password = CVAR( "qtv_password", "");
|
||||||
cvar_t qtv_streamport = CVARAF( "qtv_streamport", "0",
|
cvar_t qtv_streamport = CVARAF( "qtv_streamport", "0",
|
||||||
|
@ -105,7 +105,7 @@ static void DestClose(mvddest_t *d, enum mvdclosereason_e reason)
|
||||||
else if (d->desttype != DEST_STREAM)
|
else if (d->desttype != DEST_STREAM)
|
||||||
{
|
{
|
||||||
char buf[512];
|
char buf[512];
|
||||||
SV_BroadcastPrintf (PRINT_CHAT, "Server recording complete\n/download demos/%s", COM_QuotedString(d->name, buf, sizeof(buf), false));
|
SV_BroadcastPrintf (PRINT_CHAT, "Server recording complete\n^[/download %s^]\n", COM_QuotedString(va("demos/%s",d->name), buf, sizeof(buf), false));
|
||||||
}
|
}
|
||||||
|
|
||||||
Z_Free(d);
|
Z_Free(d);
|
||||||
|
@ -134,8 +134,11 @@ void DestFlush(qboolean compleate)
|
||||||
int len;
|
int len;
|
||||||
mvddest_t *d, *t;
|
mvddest_t *d, *t;
|
||||||
|
|
||||||
//make sure everything is flushed.
|
if (compleate)
|
||||||
MVDWrite_Begin(255, -1, 0);
|
{
|
||||||
|
//make sure everything is flushed.
|
||||||
|
MVDWrite_Begin(255, -1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
if (!demo.dest)
|
if (!demo.dest)
|
||||||
return;
|
return;
|
||||||
|
@ -380,7 +383,7 @@ void SV_MVD_RunPendingConnections(void)
|
||||||
start = start+1;
|
start = start+1;
|
||||||
while(*start == ' ' || *start == '\t')
|
while(*start == ' ' || *start == '\t')
|
||||||
start++;
|
start++;
|
||||||
Con_Printf("qtv, got (%s) (%s)\n", com_token, start);
|
Con_DPrintf("qtv, got (%s) (%s)\n", com_token, start);
|
||||||
if (!strcmp(com_token, "VERSION"))
|
if (!strcmp(com_token, "VERSION"))
|
||||||
{
|
{
|
||||||
start = COM_ParseToken(start, NULL);
|
start = COM_ParseToken(start, NULL);
|
||||||
|
@ -429,6 +432,14 @@ void SV_MVD_RunPendingConnections(void)
|
||||||
{
|
{
|
||||||
//compression not supported yet
|
//compression not supported yet
|
||||||
}
|
}
|
||||||
|
else if (!strcmp(com_token, "QTV_EZQUAKE_EXT"))
|
||||||
|
{
|
||||||
|
//if we were treating this as a regular client over tcp (qizmo...)
|
||||||
|
}
|
||||||
|
else if (!strcmp(com_token, "USERINFO"))
|
||||||
|
{
|
||||||
|
//if we were treating this as a regular client over tcp (qizmo...)
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//not recognised.
|
//not recognised.
|
||||||
|
@ -865,77 +876,9 @@ void SV_MVD_FullClientUpdate(sizebuf_t *msg, client_t *player)
|
||||||
MSG_WriteString (msg, info);
|
MSG_WriteString (msg, info);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
/*
|
|
||||||
==============
|
|
||||||
DemoWriteToDisk
|
|
||||||
|
|
||||||
Writes to disk a message meant for specifc client
|
|
||||||
or all messages if type == 0
|
|
||||||
Message is cleared from demobuf after that
|
|
||||||
==============
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void SV_MVDWriteToDisk(int type, int to, float time)
|
|
||||||
{
|
|
||||||
int pos = 0, oldm, oldd;
|
|
||||||
header_t *p;
|
|
||||||
int size;
|
|
||||||
sizebuf_t msg;
|
|
||||||
|
|
||||||
p = (header_t *)demo.dbuf->sb.data;
|
|
||||||
demo.dbuf->h = NULL;
|
|
||||||
|
|
||||||
oldm = demo.dbuf->bufsize;
|
|
||||||
oldd = demobuffer->start;
|
|
||||||
while (pos < demo.dbuf->bufsize)
|
|
||||||
{
|
|
||||||
size = p->size;
|
|
||||||
pos += header + size;
|
|
||||||
|
|
||||||
// no type means we are writing to disk everything
|
|
||||||
if (!type || (p->type == type && p->to == to))
|
|
||||||
{
|
|
||||||
if (size)
|
|
||||||
{
|
|
||||||
msg.data = p->data;
|
|
||||||
msg.cursize = size;
|
|
||||||
|
|
||||||
SV_WriteMVDMessage(&msg, p->type, p->to, time);
|
|
||||||
}
|
|
||||||
|
|
||||||
// data is written so it need to be cleard from demobuf
|
|
||||||
if (demo.dbuf->sb.data != (qbyte*)p)
|
|
||||||
memmove(demo.dbuf->sb.data + size + header, demo.dbuf->sb.data, (qbyte*)p - demo.dbuf->sb.data);
|
|
||||||
|
|
||||||
demo.dbuf->bufsize -= size + header;
|
|
||||||
demo.dbuf->sb.data += size + header;
|
|
||||||
pos -= size + header;
|
|
||||||
demo.dbuf->sb.maxsize -= size + header;
|
|
||||||
demobuffer->start += size + header;
|
|
||||||
}
|
|
||||||
// move along
|
|
||||||
p = (header_t *)(p->data + size);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (demobuffer->start == demobuffer->last)
|
|
||||||
{
|
|
||||||
if (demobuffer->start == demobuffer->end)
|
|
||||||
{
|
|
||||||
demobuffer->end = 0; // demobuffer is empty
|
|
||||||
demo.dbuf->sb.data = demobuffer->data;
|
|
||||||
}
|
|
||||||
|
|
||||||
// go back to begining of the buffer
|
|
||||||
demobuffer->last = demobuffer->end;
|
|
||||||
demobuffer->start = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
sizebuf_t *MVDWrite_Begin(qbyte type, int to, int size)
|
sizebuf_t *MVDWrite_Begin(qbyte type, int to, int size)
|
||||||
{
|
{
|
||||||
if (demomsg.cursize && demomsgtype != type && demomsgto != to && demomsg.cursize+size > sizeof(demomsgbuf))
|
if (demomsg.cursize && (demomsgtype != type || demomsgto != to || demomsg.cursize+size > sizeof(demomsgbuf)))
|
||||||
{
|
{
|
||||||
SV_WriteMVDMessage(&demomsg, demomsgtype, demomsgto, demo_prevtime);
|
SV_WriteMVDMessage(&demomsg, demomsgtype, demomsgto, demo_prevtime);
|
||||||
demomsg.cursize = 0;
|
demomsg.cursize = 0;
|
||||||
|
@ -945,51 +888,9 @@ sizebuf_t *MVDWrite_Begin(qbyte type, int to, int size)
|
||||||
demomsgto = to;
|
demomsgto = to;
|
||||||
|
|
||||||
demomsg.maxsize = demomsg.cursize+size;
|
demomsg.maxsize = demomsg.cursize+size;
|
||||||
demomsg.cursize = 0;
|
|
||||||
demomsg.data = demomsgbuf;
|
demomsg.data = demomsgbuf;
|
||||||
demomsg.prim = demo.recorder.netchan.netprim;
|
demomsg.prim = demo.recorder.netchan.netprim;
|
||||||
return &demomsg;
|
return &demomsg;
|
||||||
#if 0
|
|
||||||
qbyte *p;
|
|
||||||
qboolean move = false;
|
|
||||||
|
|
||||||
// will it fit?
|
|
||||||
while (demo.dbuf->bufsize + size + header > demo.dbuf->sb.maxsize)
|
|
||||||
{
|
|
||||||
// if we reached the end of buffer move msgbuf to the begining
|
|
||||||
if (!move && demobuffer->end > demobuffer->start)
|
|
||||||
move = true;
|
|
||||||
|
|
||||||
if (!SV_MVDWritePackets(1))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (move && demobuffer->start > demo.dbuf->bufsize + header + size)
|
|
||||||
MVDMoveBuf();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (demo.dbuf->h == NULL || demo.dbuf->h->type != type || demo.dbuf->h->to != to || demo.dbuf->h->full) {
|
|
||||||
MVDSetBuf(type, to);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (demo.dbuf->h->size + size > MAX_QWMSGLEN)
|
|
||||||
{
|
|
||||||
demo.dbuf->h->full = 1;
|
|
||||||
MVDSetBuf(type, to);
|
|
||||||
}
|
|
||||||
|
|
||||||
// we have to make room for new data
|
|
||||||
if (demo.dbuf->sb.cursize != demo.dbuf->bufsize) {
|
|
||||||
p = demo.dbuf->sb.data + demo.dbuf->sb.cursize;
|
|
||||||
memmove(p+size, p, demo.dbuf->bufsize - demo.dbuf->sb.cursize);
|
|
||||||
}
|
|
||||||
|
|
||||||
demo.dbuf->bufsize += size;
|
|
||||||
demo.dbuf->h->size += size;
|
|
||||||
if ((demobuffer->end += size) > demobuffer->last)
|
|
||||||
demobuffer->last = demobuffer->end;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1007,19 +908,30 @@ void SV_WriteMVDMessage (sizebuf_t *msg, int type, int to, float time)
|
||||||
if (!sv.mvdrecording)
|
if (!sv.mvdrecording)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (msg->overflowed)
|
||||||
|
{
|
||||||
|
msg->overflowed = false;
|
||||||
|
Con_Printf("SV_WriteMVDMessage: message overflowed\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
msec = (time - demo_prevtime)*1000;
|
msec = (time - demo_prevtime)*1000;
|
||||||
if (abs(msec) > 1000)
|
if (abs(msec) > 1000)
|
||||||
{
|
{
|
||||||
//catastoptic slip. debugging? reset any sync
|
//catastoptic slip. debugging? reset any sync
|
||||||
msec = 0;
|
msec = 1;
|
||||||
demo_prevtime = time;
|
demo_prevtime = time;
|
||||||
}
|
}
|
||||||
else
|
else if (msec > 0)
|
||||||
{
|
{ //if there was any progress, make sure we write msecs >0
|
||||||
if (msec > 255) msec = 255;
|
if (msec > 255)
|
||||||
if (msec < 2) msec = 0;
|
msec = 255;
|
||||||
|
if (msec < 1)
|
||||||
|
msec = 1;
|
||||||
demo_prevtime += msec*0.001;
|
demo_prevtime += msec*0.001;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
msec = 0;
|
||||||
|
|
||||||
c = msec;
|
c = msec;
|
||||||
DemoWrite(&c, sizeof(c));
|
DemoWrite(&c, sizeof(c));
|
||||||
|
@ -1065,20 +977,23 @@ void SV_WriteMVDMessage (sizebuf_t *msg, int type, int to, float time)
|
||||||
}
|
}
|
||||||
|
|
||||||
//if you use ClientReliable to write to demo.recorder's message buffer (for code reuse) call this function to ensure its flushed.
|
//if you use ClientReliable to write to demo.recorder's message buffer (for code reuse) call this function to ensure its flushed.
|
||||||
void SV_MVD_WriteReliables(void)
|
void SV_MVD_WriteReliables(qboolean writebroadcasts)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
//chuck in the broadcast reliables
|
if (writebroadcasts)
|
||||||
ClientReliableCheckBlock(&demo.recorder, sv.reliable_datagram.cursize);
|
{
|
||||||
ClientReliableWrite_SZ(&demo.recorder, sv.reliable_datagram.data, sv.reliable_datagram.cursize);
|
//chuck in the broadcast reliables
|
||||||
//and the broadcast unreliables. everything is reliables when it comes to mvds
|
ClientReliableCheckBlock(&demo.recorder, sv.reliable_datagram.cursize);
|
||||||
ClientReliableCheckBlock(&demo.recorder, sv.datagram.cursize);
|
ClientReliableWrite_SZ(&demo.recorder, sv.reliable_datagram.data, sv.reliable_datagram.cursize);
|
||||||
ClientReliableWrite_SZ(&demo.recorder, sv.datagram.data, sv.datagram.cursize);
|
//and the broadcast unreliables. everything is reliables when it comes to mvds
|
||||||
|
ClientReliableCheckBlock(&demo.recorder, sv.datagram.cursize);
|
||||||
|
ClientReliableWrite_SZ(&demo.recorder, sv.datagram.data, sv.datagram.cursize);
|
||||||
|
}
|
||||||
|
|
||||||
if (demo.recorder.netchan.message.cursize)
|
if (demo.recorder.netchan.message.cursize)
|
||||||
{
|
{
|
||||||
SV_WriteMVDMessage(&demo.recorder.netchan.message, dem_all, 0, sv.time);
|
SV_WriteMVDMessage(&demo.recorder.netchan.message, dem_all, 0, demo_prevtime);
|
||||||
demo.recorder.netchan.message.cursize = 0;
|
demo.recorder.netchan.message.cursize = 0;
|
||||||
}
|
}
|
||||||
for (i = 0; i < demo.recorder.num_backbuf; i++)
|
for (i = 0; i < demo.recorder.num_backbuf; i++)
|
||||||
|
@ -1086,7 +1001,7 @@ void SV_MVD_WriteReliables(void)
|
||||||
demo.recorder.backbuf.data = demo.recorder.backbuf_data[i];
|
demo.recorder.backbuf.data = demo.recorder.backbuf_data[i];
|
||||||
demo.recorder.backbuf.cursize = demo.recorder.backbuf_size[i];
|
demo.recorder.backbuf.cursize = demo.recorder.backbuf_size[i];
|
||||||
if (demo.recorder.backbuf.cursize)
|
if (demo.recorder.backbuf.cursize)
|
||||||
SV_WriteMVDMessage(&demo.recorder.backbuf, dem_all, 0, sv.time);
|
SV_WriteMVDMessage(&demo.recorder.backbuf, dem_all, 0, demo_prevtime);
|
||||||
demo.recorder.backbuf_size[i] = 0;
|
demo.recorder.backbuf_size[i] = 0;
|
||||||
}
|
}
|
||||||
demo.recorder.num_backbuf = 0;
|
demo.recorder.num_backbuf = 0;
|
||||||
|
@ -1143,6 +1058,8 @@ qboolean SV_MVDWritePackets (int num)
|
||||||
//flush any intermediate data
|
//flush any intermediate data
|
||||||
MVDWrite_Begin(255, -1, 0);
|
MVDWrite_Begin(255, -1, 0);
|
||||||
|
|
||||||
|
msg.allowoverflow = true; //fixme
|
||||||
|
msg.overflowed = false;
|
||||||
msg.prim = svs.netprim;
|
msg.prim = svs.netprim;
|
||||||
msg.data = msg_buf;
|
msg.data = msg_buf;
|
||||||
msg.maxsize = sizeof(msg_buf);
|
msg.maxsize = sizeof(msg_buf);
|
||||||
|
@ -1714,6 +1631,7 @@ qboolean SV_MVD_Record (mvddest_t *dest)
|
||||||
if (!dest)
|
if (!dest)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
SV_MVD_WriteReliables(false);
|
||||||
DestFlush(true);
|
DestFlush(true);
|
||||||
|
|
||||||
if (!sv.mvdrecording)
|
if (!sv.mvdrecording)
|
||||||
|
@ -1726,7 +1644,7 @@ qboolean SV_MVD_Record (mvddest_t *dest)
|
||||||
demo.datagram.data = demo.datagram_data;
|
demo.datagram.data = demo.datagram_data;
|
||||||
demo.datagram.prim = demo.recorder.netchan.netprim;
|
demo.datagram.prim = demo.recorder.netchan.netprim;
|
||||||
|
|
||||||
if (sv_demoExtensions.ival == 2)
|
if (sv_demoExtensions.ival == 2 || !*sv_demoExtensions.string)
|
||||||
{ /*more limited subset supported by ezquake*/
|
{ /*more limited subset supported by ezquake*/
|
||||||
demo.recorder.fteprotocolextensions = PEXT_CHUNKEDDOWNLOADS|PEXT_256PACKETENTITIES|PEXT_FLOATCOORDS|PEXT_MODELDBL|PEXT_ENTITYDBL|PEXT_ENTITYDBL2|PEXT_SPAWNSTATIC2;
|
demo.recorder.fteprotocolextensions = PEXT_CHUNKEDDOWNLOADS|PEXT_256PACKETENTITIES|PEXT_FLOATCOORDS|PEXT_MODELDBL|PEXT_ENTITYDBL|PEXT_ENTITYDBL2|PEXT_SPAWNSTATIC2;
|
||||||
// demo.recorder.fteprotocolextensions |= PEXT_HLBSP; /*ezquake DOES have this, but it is pointless and should have been in some feature mask rather than protocol extensions*/
|
// demo.recorder.fteprotocolextensions |= PEXT_HLBSP; /*ezquake DOES have this, but it is pointless and should have been in some feature mask rather than protocol extensions*/
|
||||||
|
@ -1773,6 +1691,7 @@ qboolean SV_MVD_Record (mvddest_t *dest)
|
||||||
SV_MVD_SendInitialGamestate(dest);
|
SV_MVD_SendInitialGamestate(dest);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SV_EnableClientsCSQC(void);
|
void SV_EnableClientsCSQC(void);
|
||||||
void SV_MVD_SendInitialGamestate(mvddest_t *dest)
|
void SV_MVD_SendInitialGamestate(mvddest_t *dest)
|
||||||
{
|
{
|
||||||
|
@ -1788,7 +1707,10 @@ void SV_MVD_SendInitialGamestate(mvddest_t *dest)
|
||||||
if (!demo.dest)
|
if (!demo.dest)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
SV_MVD_WriteReliables(false);
|
||||||
|
|
||||||
sv.mvdrecording = true;
|
sv.mvdrecording = true;
|
||||||
|
demo.resetdeltas = true;
|
||||||
|
|
||||||
host_client = &demo.recorder;
|
host_client = &demo.recorder;
|
||||||
if (host_client->fteprotocolextensions & PEXT_CSQC)
|
if (host_client->fteprotocolextensions & PEXT_CSQC)
|
||||||
|
@ -1860,7 +1782,6 @@ void SV_MVD_SendInitialGamestate(mvddest_t *dest)
|
||||||
SV_WriteRecordMVDMessage (&buf);
|
SV_WriteRecordMVDMessage (&buf);
|
||||||
SZ_Clear (&buf);
|
SZ_Clear (&buf);
|
||||||
|
|
||||||
#if 1
|
|
||||||
demo.recorder.prespawn_stage = PRESPAWN_SERVERINFO;
|
demo.recorder.prespawn_stage = PRESPAWN_SERVERINFO;
|
||||||
demo.recorder.prespawn_idx = 0;
|
demo.recorder.prespawn_idx = 0;
|
||||||
demo.recorder.netchan.message = buf;
|
demo.recorder.netchan.message = buf;
|
||||||
|
@ -1875,181 +1796,10 @@ void SV_MVD_SendInitialGamestate(mvddest_t *dest)
|
||||||
demo.recorder.prespawn_allow_modellist = true; //normally set for the server to wait for ack. we don't want to wait.
|
demo.recorder.prespawn_allow_modellist = true; //normally set for the server to wait for ack. we don't want to wait.
|
||||||
|
|
||||||
SV_SendClientPrespawnInfo(&demo.recorder);
|
SV_SendClientPrespawnInfo(&demo.recorder);
|
||||||
SV_WriteRecordMVDMessage (&demo.recorder.netchan.message);
|
SV_MVD_WriteReliables(false);
|
||||||
SZ_Clear (&demo.recorder.netchan.message);
|
|
||||||
}
|
}
|
||||||
memset(&demo.recorder.netchan.message, 0, sizeof(demo.recorder.netchan.message));
|
memset(&demo.recorder.netchan.message, 0, sizeof(demo.recorder.netchan.message));
|
||||||
#else
|
|
||||||
// send music
|
|
||||||
MSG_WriteByte (&buf, svc_cdtrack);
|
|
||||||
MSG_WriteByte (&buf, 0); // none in demos
|
|
||||||
|
|
||||||
// send server info string
|
|
||||||
MSG_WriteByte (&buf, svc_stufftext);
|
|
||||||
MSG_WriteString (&buf, va("fullserverinfo \"%s\"\n", svs.info) );
|
|
||||||
|
|
||||||
// flush packet
|
|
||||||
SV_WriteRecordMVDMessage (&buf);
|
|
||||||
SZ_Clear (&buf);
|
|
||||||
|
|
||||||
// soundlist
|
|
||||||
MSG_WriteByte (&buf, svc_soundlist); /*FIXME: soundlist2*/
|
|
||||||
MSG_WriteByte (&buf, 0);
|
|
||||||
|
|
||||||
n = 0;
|
|
||||||
s = sv.strings.sound_precache[n+1];
|
|
||||||
while (*s)
|
|
||||||
{
|
|
||||||
MSG_WriteString (&buf, s);
|
|
||||||
if (buf.cursize > MAX_QWMSGLEN/2)
|
|
||||||
{
|
|
||||||
MSG_WriteByte (&buf, 0);
|
|
||||||
MSG_WriteByte (&buf, n);
|
|
||||||
SV_WriteRecordMVDMessage (&buf);
|
|
||||||
SZ_Clear (&buf);
|
|
||||||
MSG_WriteByte (&buf, svc_soundlist);
|
|
||||||
MSG_WriteByte (&buf, n + 1);
|
|
||||||
}
|
|
||||||
n++;
|
|
||||||
s = sv.strings.sound_precache[n+1];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (buf.cursize)
|
|
||||||
{
|
|
||||||
MSG_WriteByte (&buf, 0);
|
|
||||||
MSG_WriteByte (&buf, 0);
|
|
||||||
SV_WriteRecordMVDMessage (&buf);
|
|
||||||
SZ_Clear (&buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
// modellist
|
|
||||||
MSG_WriteByte (&buf, svc_modellist); /*FIXME: modellist2*/
|
|
||||||
MSG_WriteByte (&buf, 0);
|
|
||||||
|
|
||||||
n = 0;
|
|
||||||
s = sv.strings.model_precache[n+1];
|
|
||||||
while (s)
|
|
||||||
{
|
|
||||||
MSG_WriteString (&buf, s);
|
|
||||||
if (buf.cursize > MAX_QWMSGLEN/2)
|
|
||||||
{
|
|
||||||
MSG_WriteByte (&buf, 0);
|
|
||||||
MSG_WriteByte (&buf, n);
|
|
||||||
SV_WriteRecordMVDMessage (&buf);
|
|
||||||
SZ_Clear (&buf);
|
|
||||||
MSG_WriteByte (&buf, svc_modellist);
|
|
||||||
MSG_WriteByte (&buf, n + 1);
|
|
||||||
}
|
|
||||||
n++;
|
|
||||||
s = sv.strings.model_precache[n+1];
|
|
||||||
}
|
|
||||||
if (buf.cursize)
|
|
||||||
{
|
|
||||||
MSG_WriteByte (&buf, 0);
|
|
||||||
MSG_WriteByte (&buf, 0);
|
|
||||||
SV_WriteRecordMVDMessage (&buf);
|
|
||||||
SZ_Clear (&buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
// baselines
|
|
||||||
{
|
|
||||||
entity_state_t from;
|
|
||||||
edict_t *ent;
|
|
||||||
entity_state_t *state;
|
|
||||||
|
|
||||||
memset(&from, 0, sizeof(from));
|
|
||||||
|
|
||||||
for (n = 0; n < sv.world.num_edicts; n++)
|
|
||||||
{
|
|
||||||
ent = EDICT_NUM(svprogfuncs, n);
|
|
||||||
state = &ent->baseline;
|
|
||||||
|
|
||||||
if (!state->number || !state->modelindex)
|
|
||||||
{ //ent doesn't have a baseline
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (demo.recorder.fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS)
|
|
||||||
{
|
|
||||||
MSG_WriteByte(&buf, svcfte_spawnbaseline2);
|
|
||||||
SVFTE_EmitBaseline(state, true, &buf);
|
|
||||||
}
|
|
||||||
else if (!ent)
|
|
||||||
{
|
|
||||||
MSG_WriteByte(&buf, svc_spawnbaseline);
|
|
||||||
|
|
||||||
MSG_WriteShort (&buf, n);
|
|
||||||
|
|
||||||
MSG_WriteByte (&buf, 0);
|
|
||||||
|
|
||||||
MSG_WriteByte (&buf, 0);
|
|
||||||
MSG_WriteByte (&buf, 0);
|
|
||||||
MSG_WriteByte (&buf, 0);
|
|
||||||
for (i=0 ; i<3 ; i++)
|
|
||||||
{
|
|
||||||
MSG_WriteCoord(&buf, 0);
|
|
||||||
MSG_WriteAngle(&buf, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (demo.recorder.fteprotocolextensions & PEXT_SPAWNSTATIC2)
|
|
||||||
{
|
|
||||||
MSG_WriteByte(&buf, svcfte_spawnbaseline2);
|
|
||||||
SVQW_WriteDelta(&from, state, &buf, true, demo.recorder.fteprotocolextensions);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
MSG_WriteByte(&buf, svc_spawnbaseline);
|
|
||||||
|
|
||||||
MSG_WriteShort (&buf, n);
|
|
||||||
|
|
||||||
MSG_WriteByte (&buf, state->modelindex&255);
|
|
||||||
|
|
||||||
MSG_WriteByte (&buf, state->frame);
|
|
||||||
MSG_WriteByte (&buf, (int)state->colormap);
|
|
||||||
MSG_WriteByte (&buf, (int)state->skinnum);
|
|
||||||
for (i=0 ; i<3 ; i++)
|
|
||||||
{
|
|
||||||
MSG_WriteCoord(&buf, state->origin[i]);
|
|
||||||
MSG_WriteAngle(&buf, state->angles[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (buf.cursize > MAX_QWMSGLEN/2)
|
|
||||||
{
|
|
||||||
SV_WriteRecordMVDMessage (&buf);
|
|
||||||
SZ_Clear (&buf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//prespawn
|
|
||||||
|
|
||||||
for (n = 0; n < sv.num_signon_buffers; n++)
|
|
||||||
{
|
|
||||||
if (buf.cursize+sv.signon_buffer_size[n] > MAX_QWMSGLEN/2)
|
|
||||||
{
|
|
||||||
SV_WriteRecordMVDMessage (&buf);
|
|
||||||
SZ_Clear (&buf);
|
|
||||||
}
|
|
||||||
SZ_Write (&buf,
|
|
||||||
sv.signon_buffers[n],
|
|
||||||
sv.signon_buffer_size[n]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (buf.cursize > MAX_QWMSGLEN/2)
|
|
||||||
{
|
|
||||||
SV_WriteRecordMVDMessage (&buf);
|
|
||||||
SZ_Clear (&buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
MSG_WriteByte (&buf, svc_stufftext);
|
|
||||||
MSG_WriteString (&buf, va("cmd spawn %i\n",svs.spawncount) );
|
|
||||||
|
|
||||||
if (buf.cursize)
|
|
||||||
{
|
|
||||||
SV_WriteRecordMVDMessage (&buf);
|
|
||||||
SZ_Clear (&buf);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
// send current status of all other players
|
// send current status of all other players
|
||||||
|
|
||||||
for (i = 0; i < demo.recorder.max_net_clients && i < svs.allocated_client_slots; i++)
|
for (i = 0; i < demo.recorder.max_net_clients && i < svs.allocated_client_slots; i++)
|
||||||
|
@ -2060,6 +1810,7 @@ void SV_MVD_SendInitialGamestate(mvddest_t *dest)
|
||||||
|
|
||||||
if (buf.cursize > MAX_QWMSGLEN/2)
|
if (buf.cursize > MAX_QWMSGLEN/2)
|
||||||
{
|
{
|
||||||
|
//flush backbuffer
|
||||||
SV_WriteRecordMVDMessage (&buf);
|
SV_WriteRecordMVDMessage (&buf);
|
||||||
SZ_Clear (&buf);
|
SZ_Clear (&buf);
|
||||||
}
|
}
|
||||||
|
@ -2096,8 +1847,8 @@ void SV_MVD_SendInitialGamestate(mvddest_t *dest)
|
||||||
{
|
{
|
||||||
for (j = 0; j < MAX_CL_STATS; j++)
|
for (j = 0; j < MAX_CL_STATS; j++)
|
||||||
{
|
{
|
||||||
demo.statsi[i][j] ^= -1;
|
demo.statsi[i][j] = 0x7fffffff;
|
||||||
demo.statsf[i][j] *= -0.41426712; //randomish value
|
demo.statsf[i][j] = -0x7fffffff;
|
||||||
}
|
}
|
||||||
demo.playerreset[i] = true;
|
demo.playerreset[i] = true;
|
||||||
}
|
}
|
||||||
|
@ -2108,7 +1859,7 @@ void SV_MVD_SendInitialGamestate(mvddest_t *dest)
|
||||||
MSG_WriteString (&buf, "skins\n");
|
MSG_WriteString (&buf, "skins\n");
|
||||||
|
|
||||||
SV_WriteRecordMVDMessage (&buf);
|
SV_WriteRecordMVDMessage (&buf);
|
||||||
|
SV_MVD_WriteReliables(false);
|
||||||
SV_WriteSetMVDMessage();
|
SV_WriteSetMVDMessage();
|
||||||
|
|
||||||
singledest = NULL;
|
singledest = NULL;
|
||||||
|
|
|
@ -42,18 +42,18 @@ solid_edge items only clip against bsp models.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
cvar_t sv_maxvelocity = SCVAR("sv_maxvelocity","10000");
|
cvar_t sv_maxvelocity = CVAR("sv_maxvelocity","10000");
|
||||||
|
|
||||||
cvar_t sv_gravity = SCVAR( "sv_gravity", "800");
|
cvar_t sv_gravity = CVAR( "sv_gravity", "800");
|
||||||
cvar_t sv_stopspeed = SCVAR( "sv_stopspeed", "100");
|
cvar_t sv_stopspeed = CVAR( "sv_stopspeed", "100");
|
||||||
cvar_t sv_maxspeed = SCVAR( "sv_maxspeed", "320");
|
cvar_t sv_maxspeed = CVAR( "sv_maxspeed", "320");
|
||||||
cvar_t sv_spectatormaxspeed = SCVAR( "sv_spectatormaxspeed", "500");
|
cvar_t sv_spectatormaxspeed = CVAR( "sv_spectatormaxspeed", "500");
|
||||||
cvar_t sv_accelerate = SCVAR( "sv_accelerate", "10");
|
cvar_t sv_accelerate = CVAR( "sv_accelerate", "10");
|
||||||
cvar_t sv_airaccelerate = SCVAR( "sv_airaccelerate", "0.7");
|
cvar_t sv_airaccelerate = CVAR( "sv_airaccelerate", "0.7");
|
||||||
cvar_t sv_wateraccelerate = SCVAR( "sv_wateraccelerate", "10");
|
cvar_t sv_wateraccelerate = CVAR( "sv_wateraccelerate", "10");
|
||||||
cvar_t sv_friction = SCVAR( "sv_friction", "4");
|
cvar_t sv_friction = CVAR( "sv_friction", "4");
|
||||||
cvar_t sv_waterfriction = SCVAR( "sv_waterfriction", "4");
|
cvar_t sv_waterfriction = CVAR( "sv_waterfriction", "4");
|
||||||
cvar_t sv_gameplayfix_noairborncorpse = SCVAR( "sv_gameplayfix_noairborncorpse", "0");
|
cvar_t sv_gameplayfix_noairborncorpse = CVAR( "sv_gameplayfix_noairborncorpse", "0");
|
||||||
cvar_t sv_gameplayfix_multiplethinks = CVARD( "sv_gameplayfix_multiplethinks", "1", "Enables multiple thinks per entity per frame so small nextthink times are accurate. QuakeWorld mods expect a value of 1.");
|
cvar_t sv_gameplayfix_multiplethinks = CVARD( "sv_gameplayfix_multiplethinks", "1", "Enables multiple thinks per entity per frame so small nextthink times are accurate. QuakeWorld mods expect a value of 1.");
|
||||||
cvar_t sv_gameplayfix_stepdown = CVARD( "sv_gameplayfix_stepdown", "0", "Attempt to step down steps, instead of only up them. Affects non-predicted movetype_walk.");
|
cvar_t sv_gameplayfix_stepdown = CVARD( "sv_gameplayfix_stepdown", "0", "Attempt to step down steps, instead of only up them. Affects non-predicted movetype_walk.");
|
||||||
#if !defined(CLIENTONLY) && defined(NQPROT) && !defined(NOLEGACY)
|
#if !defined(CLIENTONLY) && defined(NQPROT) && !defined(NOLEGACY)
|
||||||
|
|
|
@ -2634,7 +2634,7 @@ void SV_FlushBroadcasts (void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SV_MVD_WriteReliables();
|
SV_MVD_WriteReliables(true);
|
||||||
|
|
||||||
SZ_Clear (&sv.reliable_datagram);
|
SZ_Clear (&sv.reliable_datagram);
|
||||||
SZ_Clear (&sv.datagram);
|
SZ_Clear (&sv.datagram);
|
||||||
|
@ -3322,8 +3322,6 @@ void SV_SendMVDMessage(void)
|
||||||
// possibly a nails update
|
// possibly a nails update
|
||||||
msg.cursize = 0;
|
msg.cursize = 0;
|
||||||
msg.prim = demo.recorder.netchan.netprim;
|
msg.prim = demo.recorder.netchan.netprim;
|
||||||
if (!demo.recorder.delta_sequence)
|
|
||||||
demo.recorder.delta_sequence = -1;
|
|
||||||
|
|
||||||
// copy the accumulated multicast datagram
|
// copy the accumulated multicast datagram
|
||||||
// for this client out to the message
|
// for this client out to the message
|
||||||
|
@ -3339,7 +3337,13 @@ void SV_SendMVDMessage(void)
|
||||||
SV_MVDWritePackets(1);
|
SV_MVDWritePackets(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
demo.recorder.delta_sequence = demo.recorder.netchan.incoming_sequence&255;
|
if (demo.resetdeltas)
|
||||||
|
{
|
||||||
|
demo.resetdeltas = false;
|
||||||
|
demo.recorder.delta_sequence = -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
demo.recorder.delta_sequence = demo.recorder.netchan.incoming_sequence&255;
|
||||||
demo.recorder.netchan.incoming_sequence++;
|
demo.recorder.netchan.incoming_sequence++;
|
||||||
demo.frames[demo.parsecount&DEMO_FRAMES_MASK].time = demo.time = sv.time;
|
demo.frames[demo.parsecount&DEMO_FRAMES_MASK].time = demo.time = sv.time;
|
||||||
|
|
||||||
|
|
|
@ -102,11 +102,11 @@ static dllfunction_t sqlitefuncs[] =
|
||||||
dllhandle_t *sqlitehandle;
|
dllhandle_t *sqlitehandle;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
cvar_t sql_driver = SCVARF("sv_sql_driver", "", CVAR_NOUNSAFEEXPAND);
|
cvar_t sql_driver = CVARF("sv_sql_driver", "", CVAR_NOUNSAFEEXPAND);
|
||||||
cvar_t sql_host = SCVARF("sv_sql_host", "127.0.0.1", CVAR_NOUNSAFEEXPAND);
|
cvar_t sql_host = CVARF("sv_sql_host", "127.0.0.1", CVAR_NOUNSAFEEXPAND);
|
||||||
cvar_t sql_username = SCVARF("sv_sql_username", "", CVAR_NOUNSAFEEXPAND);
|
cvar_t sql_username = CVARF("sv_sql_username", "", CVAR_NOUNSAFEEXPAND);
|
||||||
cvar_t sql_password = SCVARF("sv_sql_password", "", CVAR_NOUNSAFEEXPAND);
|
cvar_t sql_password = CVARF("sv_sql_password", "", CVAR_NOUNSAFEEXPAND);
|
||||||
cvar_t sql_defaultdb = SCVARF("sv_sql_defaultdb", "", CVAR_NOUNSAFEEXPAND);
|
cvar_t sql_defaultdb = CVARF("sv_sql_defaultdb", "", CVAR_NOUNSAFEEXPAND);
|
||||||
|
|
||||||
void SQL_PushResult(sqlserver_t *server, queryresult_t *qres)
|
void SQL_PushResult(sqlserver_t *server, queryresult_t *qres)
|
||||||
{
|
{
|
||||||
|
|
|
@ -42,9 +42,9 @@ cvar_t cl_rollangle = SCVAR("cl_rollangle", "2.0");
|
||||||
extern cvar_t cl_rollspeed;
|
extern cvar_t cl_rollspeed;
|
||||||
extern cvar_t cl_rollangle;
|
extern cvar_t cl_rollangle;
|
||||||
#endif
|
#endif
|
||||||
cvar_t sv_spectalk = SCVAR("sv_spectalk", "1");
|
cvar_t sv_spectalk = CVAR("sv_spectalk", "1");
|
||||||
|
|
||||||
cvar_t sv_mapcheck = SCVAR("sv_mapcheck", "1");
|
cvar_t sv_mapcheck = CVAR("sv_mapcheck", "1");
|
||||||
|
|
||||||
cvar_t sv_fullredirect = CVARD("sv_fullredirect", "", "This is the ip:port to redirect players to when the server is full");
|
cvar_t sv_fullredirect = CVARD("sv_fullredirect", "", "This is the ip:port to redirect players to when the server is full");
|
||||||
cvar_t sv_antilag = CVARFD("sv_antilag", "", CVAR_SERVERINFO, "Attempt to backdate impacts to compensate for lag. 0=completely off. 1=mod-controlled. 2=forced, which might break certain uses of traceline.");
|
cvar_t sv_antilag = CVARFD("sv_antilag", "", CVAR_SERVERINFO, "Attempt to backdate impacts to compensate for lag. 0=completely off. 1=mod-controlled. 2=forced, which might break certain uses of traceline.");
|
||||||
|
@ -60,9 +60,9 @@ cvar_t sv_protocol_nq = CVARD("sv_protocol_nq", "", "Specifies the default prot
|
||||||
cvar_t sv_minpitch = CVARAFD("minpitch", "", "sv_minpitch", CVAR_SERVERINFO, "Assumed to be -70");
|
cvar_t sv_minpitch = CVARAFD("minpitch", "", "sv_minpitch", CVAR_SERVERINFO, "Assumed to be -70");
|
||||||
cvar_t sv_maxpitch = CVARAFD("maxpitch", "", "sv_maxpitch", CVAR_SERVERINFO, "Assumed to be 80");
|
cvar_t sv_maxpitch = CVARAFD("maxpitch", "", "sv_maxpitch", CVAR_SERVERINFO, "Assumed to be 80");
|
||||||
|
|
||||||
cvar_t sv_cmdlikercon = SCVAR("sv_cmdlikercon", "0"); //set to 1 to allow a password of username:password instead of the correct rcon password.
|
cvar_t sv_cmdlikercon = CVAR("sv_cmdlikercon", "0"); //set to 1 to allow a password of username:password instead of the correct rcon password.
|
||||||
cvar_t cmd_allowaccess = SCVAR("cmd_allowaccess", "0"); //set to 1 to allow cmd to execute console commands on the server.
|
cvar_t cmd_allowaccess = CVAR("cmd_allowaccess", "0"); //set to 1 to allow cmd to execute console commands on the server.
|
||||||
cvar_t cmd_gamecodelevel = SCVAR("cmd_gamecodelevel", STRINGIFY(RESTRICT_LOCAL)); //execution level which gamecode is told about (for unrecognised commands)
|
cvar_t cmd_gamecodelevel = CVAR("cmd_gamecodelevel", STRINGIFY(RESTRICT_LOCAL)); //execution level which gamecode is told about (for unrecognised commands)
|
||||||
|
|
||||||
cvar_t sv_pure = CVARFD("sv_pure", "", CVAR_SERVERINFO, "The most evil cvar in the world, many clients will ignore this.\n0=standard quake rules.\n1=clients should prefer files within packages present on the server.\n2=clients should use *only* files within packages present on the server.\nDue to quake 1.01/1.06 differences, a setting of 2 only works in total conversions.");
|
cvar_t sv_pure = CVARFD("sv_pure", "", CVAR_SERVERINFO, "The most evil cvar in the world, many clients will ignore this.\n0=standard quake rules.\n1=clients should prefer files within packages present on the server.\n2=clients should use *only* files within packages present on the server.\nDue to quake 1.01/1.06 differences, a setting of 2 only works in total conversions.");
|
||||||
cvar_t sv_nqplayerphysics = CVARAD("sv_nqplayerphysics", "0", "sv_nomsec", "Disable player prediction and run NQ-style player physics instead. This can be used for compatibility with mods that expect exact behaviour.");
|
cvar_t sv_nqplayerphysics = CVARAD("sv_nqplayerphysics", "0", "sv_nomsec", "Disable player prediction and run NQ-style player physics instead. This can be used for compatibility with mods that expect exact behaviour.");
|
||||||
|
@ -98,14 +98,14 @@ extern cvar_t pm_airstep;
|
||||||
extern cvar_t pm_walljump;
|
extern cvar_t pm_walljump;
|
||||||
extern cvar_t pm_watersinkspeed;
|
extern cvar_t pm_watersinkspeed;
|
||||||
extern cvar_t pm_flyfriction;
|
extern cvar_t pm_flyfriction;
|
||||||
cvar_t sv_pushplayers = SCVAR("sv_pushplayers", "0");
|
cvar_t sv_pushplayers = CVAR("sv_pushplayers", "0");
|
||||||
|
|
||||||
//yes, realip cvars need to be fully initialised or realip will be disabled
|
//yes, realip cvars need to be fully initialised or realip will be disabled
|
||||||
cvar_t sv_getrealip = CVARD("sv_getrealip", "0", "Attempt to obtain a more reliable IP for clients, rather than just their proxy.");
|
cvar_t sv_getrealip = CVARD("sv_getrealip", "0", "Attempt to obtain a more reliable IP for clients, rather than just their proxy.");
|
||||||
cvar_t sv_realip_kick = SCVAR("sv_realip_kick", "0");
|
cvar_t sv_realip_kick = CVAR("sv_realip_kick", "0");
|
||||||
cvar_t sv_realiphostname_ipv4 = CVARD("sv_realiphostname_ipv4", "", "This is the server's public ip:port. This is needed for realip to work when the autodetected/local ip is not globally routable");
|
cvar_t sv_realiphostname_ipv4 = CVARD("sv_realiphostname_ipv4", "", "This is the server's public ip:port. This is needed for realip to work when the autodetected/local ip is not globally routable");
|
||||||
cvar_t sv_realiphostname_ipv6 = CVARD("sv_realiphostname_ipv6", "", "This is the server's public ip:port. This is needed for realip to work when the autodetected/local ip is not globally routable");
|
cvar_t sv_realiphostname_ipv6 = CVARD("sv_realiphostname_ipv6", "", "This is the server's public ip:port. This is needed for realip to work when the autodetected/local ip is not globally routable");
|
||||||
cvar_t sv_realip_timeout = SCVAR("sv_realip_timeout", "10");
|
cvar_t sv_realip_timeout = CVAR("sv_realip_timeout", "10");
|
||||||
|
|
||||||
#ifdef VOICECHAT
|
#ifdef VOICECHAT
|
||||||
cvar_t sv_voip = CVARD("sv_voip", "1", "Enable reception of voice packets.");
|
cvar_t sv_voip = CVARD("sv_voip", "1", "Enable reception of voice packets.");
|
||||||
|
@ -1015,7 +1015,7 @@ void SV_SendClientPrespawnInfo(client_t *client)
|
||||||
else if (client->prespawn_idx == 4)
|
else if (client->prespawn_idx == 4)
|
||||||
{
|
{
|
||||||
ClientReliableWrite_Begin(client, svc_setpause, 2);
|
ClientReliableWrite_Begin(client, svc_setpause, 2);
|
||||||
ClientReliableWrite_Byte (client, sv.paused);
|
ClientReliableWrite_Byte (client, sv.paused!=0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -2847,6 +2847,9 @@ qboolean VK_Init(rendererstate_t *info, const char *sysextname, qboolean (*creat
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//create the platform-specific surface
|
||||||
|
createSurface();
|
||||||
|
|
||||||
//figure out which gpu we're going to use
|
//figure out which gpu we're going to use
|
||||||
{
|
{
|
||||||
uint32_t gpucount = 0, i;
|
uint32_t gpucount = 0, i;
|
||||||
|
@ -2863,7 +2866,24 @@ qboolean VK_Init(rendererstate_t *info, const char *sysextname, qboolean (*creat
|
||||||
for (i = 0; i < gpucount; i++)
|
for (i = 0; i < gpucount; i++)
|
||||||
{
|
{
|
||||||
VkPhysicalDeviceProperties props;
|
VkPhysicalDeviceProperties props;
|
||||||
|
uint32_t j, queue_count;
|
||||||
vkGetPhysicalDeviceProperties(devs[i], &props);
|
vkGetPhysicalDeviceProperties(devs[i], &props);
|
||||||
|
vkGetPhysicalDeviceQueueFamilyProperties(devs[i], &queue_count, NULL);
|
||||||
|
|
||||||
|
for (j = 0; j < queue_count; j++)
|
||||||
|
{
|
||||||
|
VkBool32 supportsPresent;
|
||||||
|
VkAssert(vkGetPhysicalDeviceSurfaceSupportKHR(devs[i], j, vk.surface, &supportsPresent));
|
||||||
|
if (supportsPresent)
|
||||||
|
break; //okay, this one should be usable
|
||||||
|
}
|
||||||
|
if (j == queue_count)
|
||||||
|
{
|
||||||
|
//no queues can present to that surface, so I guess we can't use that device
|
||||||
|
Con_DPrintf("vulkan: ignoring device %s as it can't present to window\n", props.deviceName);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (!vk.gpu)
|
if (!vk.gpu)
|
||||||
vk.gpu = devs[i];
|
vk.gpu = devs[i];
|
||||||
switch(props.deviceType)
|
switch(props.deviceType)
|
||||||
|
@ -2954,9 +2974,6 @@ qboolean VK_Init(rendererstate_t *info, const char *sysextname, qboolean (*creat
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
//create the platform-specific surface
|
|
||||||
createSurface();
|
|
||||||
|
|
||||||
//figure out which of the device's queue's we're going to use
|
//figure out which of the device's queue's we're going to use
|
||||||
{
|
{
|
||||||
uint32_t queue_count, i;
|
uint32_t queue_count, i;
|
||||||
|
|
Loading…
Reference in a new issue