SOFTWARE RENDERING IS BROKEN: DO NOT USE ASM VERSION.

Lots of changes.
CSQC should be functional, but is still tied to debug builds. It WILL have some bugs still, hopefully I'll be able to clean them up better if people test it a bit.
Precompiled headers are working properly now. Compile times are now much quicker in msvc. This takes most of the files this commit.
Restructured how client commands work. They're buffered outside the network message, some multithreaded code is in. It needs a bit of testing before it's active.


git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@885 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2005-02-28 07:16:19 +00:00
parent b8acd511de
commit 9ae7e2621d
105 changed files with 6457 additions and 1803 deletions

View File

@ -20,6 +20,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
// Quake is a trademark of Id Software, Inc., (c) 1996 Id Software, Inc. All
// rights reserved.
#include "quakedef.h"
#ifdef __CYGWIN__
#include "cd_null.c"
#else
@ -38,8 +40,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <linux/cdrom.h>
#include "quakedef.h"
static qboolean cdValid = false;
static qboolean playing = false;
static qboolean wasPlaying = false;

View File

@ -123,8 +123,7 @@ void Cam_Unlock(int pnum)
{
if (autocam[pnum])
{
MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
MSG_WriteString (&cls.netchan.message, "ptrack");
CL_SendClientCommand("ptrack");
autocam[pnum] = CAM_NONE;
locked[pnum] = false;
Sbar_Changed();
@ -133,13 +132,11 @@ void Cam_Unlock(int pnum)
void Cam_Lock(int pnum, int playernum)
{
char st[40];
cam_lastviewtime[pnum] = -1000;
sprintf(st, "ptrack %i", playernum);
MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
MSG_WriteString (&cls.netchan.message, st);
CL_SendClientCommand("ptrack %i", playernum);
spec_track[pnum] = playernum;
locked[pnum] = false;

View File

@ -1186,12 +1186,33 @@ entity_state_t *CL_FindPacketEntity(int num)
}
#endif
//return 0 to 1
//1 being entirly new frame.
float CL_LerpEntityFrac(float lerprate, float lerptime)
{
float f;
if (!lerprate)
{
return 0;
}
else
{
f = 1-(cl.time-lerptime)/lerprate;
}
if (f<0)f=0;
if (f>1)f=1;
return f;
}
void CL_RotateAroundTag(entity_t *ent, int num, int tagent, int tagnum)
{
entity_state_t *ps;
float *org=NULL, *ang=NULL;
vec3_t axis[3];
vec3_t temp[3];
vec3_t destorg;
int model = 0; //these two are only initialised because msvc sucks at detecting usage.
int frame = 0;
@ -1204,6 +1225,8 @@ void CL_RotateAroundTag(entity_t *ent, int num, int tagent, int tagnum)
if (cl.lerpents[tagent].tagent)
CL_RotateAroundTag(ent, num, cl.lerpents[tagent].tagent, cl.lerpents[tagent].tagindex);
ent->keynum = tagent;
ps = CL_FindPacketEntity(tagent);
if (ps)
{
@ -1244,18 +1267,43 @@ void CL_RotateAroundTag(entity_t *ent, int num, int tagent, int tagnum)
tagaxis = NULL;
if (tagaxis)
{
VectorAdd(org, ent->origin, destorg);
VectorMA(destorg, tagorg[0], ent->axis[0], destorg);
VectorMA(destorg, tagorg[1], ent->axis[1], destorg);
VectorMA(destorg, tagorg[2], ent->axis[2], destorg);
VectorCopy(destorg, ent->origin);
// Con_Printf("Found tag %i\n", cl.lerpents[tagent].tagindex);
R_ConcatRotations(ent->axis, (void*)tagaxis, temp);
Matrix3_Multiply(axis, ent->axis, temp); //the ent->axis here is the result of the parent's transforms
Matrix3_Multiply((void*)tagaxis, temp, ent->axis);
}
else //hrm.
{
memcpy(temp, ent->axis, sizeof(temp));
// memcpy(axis, ent->axis, sizeof(temp));
}
R_ConcatRotations(axis, temp, ent->axis);
}
if (org)
VectorAdd(ent->origin, org, ent->origin);
// if (org)
// VectorAdd(ent->origin, org, ent->origin);
}
void V_AddEntity(entity_t *in)
{
entity_t *ent;
if (cl_numvisedicts == MAX_VISEDICTS)
return; // object list is full
ent = &cl_visedicts[cl_numvisedicts];
cl_numvisedicts++;
*ent = *in;
ent->angles[0]*=-1;
AngleVectors(ent->angles, ent->axis[0], ent->axis[1], ent->axis[2]);
VectorInverse(ent->axis[1]);
ent->angles[0]*=-1;
}
/*
===============
CL_LinkPacketEntities

View File

@ -21,12 +21,18 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "quakedef.h"
#ifdef _WIN32
#include "winquake.h" //fps indep stuff.
#endif
float in_sensitivityscale;
cvar_t cl_nodelta = {"cl_nodelta","0"};
cvar_t cl_c2spps = {"cl_c2spps", "0"};
cvar_t cl_c2sImpulseBackup = {"cl_c2sImpulseBackup","3"};
cvar_t cl_netfps = {"cl_netfps", "74"};
cvar_t cl_netfps = {"cl_netfps", "0"};
@ -744,8 +750,7 @@ void CLNQ_SendCmd(void)
if (name.modified)
{
name.modified = false;
MSG_WriteByte(&cls.netchan.message, clc_stringcmd);
MSG_WriteString(&cls.netchan.message, va("name \"%s\"\n", name.string));
CL_SendClientCommand("name \"%s\"\n", name.string);
}
if (nq_dp_protocol > 0)
@ -795,7 +800,7 @@ void AddComponant(vec3_t angles, vec3_t dest, float fm, float rm, float um)
}
#define bound(n,v,x) v<n?n:(v>x?x:v)
qboolean CL_Net_FilterTime (double time)
qboolean CL_FilterTime (double time, float wantfps)
{
extern cvar_t rate;
float fps, fpscap;
@ -805,16 +810,16 @@ qboolean CL_Net_FilterTime (double time)
if (cls.demoplayback != DPB_NONE)
{
if (!cl_netfps.value)
if (!wantfps)
return true;
fps = max (30.0, cl_netfps.value);
fps = max (30.0, wantfps);
}
else
{
fpscap = cls.maxfps ? max (30.0, cls.maxfps) : 0x7fff;
if (cl_netfps.value)
fps = bound (10.0, cl_netfps.value, fpscap);
if (wantfps>0)
fps = bound (10.0, wantfps, fpscap);
else
{
// if (com_serveractive)
@ -830,6 +835,139 @@ qboolean CL_Net_FilterTime (double time)
return true;
}
qboolean allowindepphys;
typedef struct clcmdbuf_s {
struct clcmdbuf_s *next;
int len;
char command[4]; //this is dynamically allocated, so this is variably sized.
} clcmdbuf_t;
clcmdbuf_t *clientcmdlist;
void VARGS CL_SendClientCommand(char *format, ...)
{
qboolean oldallow;
va_list argptr;
char string[2048];
clcmdbuf_t *buf, *prev;
va_start (argptr, format);
_vsnprintf (string,sizeof(string)-1, format,argptr);
va_end (argptr);
// Con_Printf("Queing stringcmd %s\n", string);
#ifdef Q3CLIENT
if (cls.q2server==2)
{
CLQ3_SendClientCommand("%s", string);
return;
}
#endif
oldallow = allowindepphys;
CL_AllowIndependantSendCmd(false);
buf = Z_Malloc(sizeof(*buf)+strlen(string));
strcpy(buf->command, string);
buf->len = strlen(buf->command);
//add to end of the list so that the first of the list is the first to be sent.
if (!clientcmdlist)
clientcmdlist = buf;
else
{
for (prev = clientcmdlist; prev->next; prev=prev->next)
;
prev->next = buf;
}
CL_AllowIndependantSendCmd(oldallow);
}
void CL_FlushClientCommands(void)
{
clcmdbuf_t *next;
CL_AllowIndependantSendCmd(false);
while(clientcmdlist)
{
next = clientcmdlist->next;
Z_Free(clientcmdlist);
clientcmdlist=next;
}
}
#ifdef _WIN32
qboolean runningindepphys;
CRITICAL_SECTION indepcriticialsection;
HANDLE indepphysicsthread;
void CL_AllowIndependantSendCmd(qboolean allow)
{
if (!runningindepphys)
return;
if (allowindepphys != allow && runningindepphys)
{
if (allow)
LeaveCriticalSection(&indepcriticialsection);
else
EnterCriticalSection(&indepcriticialsection);
}
allowindepphys = allow;
}
unsigned long _stdcall CL_IndepPhysicsThread(void *param)
{
int sleeptime;
float fps;
while(1)
{
EnterCriticalSection(&indepcriticialsection);
CL_SendCmd();
LeaveCriticalSection(&indepcriticialsection);
fps = cl_netfps.value*10; //try and be generous. (This isn't the framerate capping function).
if (fps < 10)
fps = 10;
sleeptime = 1000/fps;
Sleep(sleeptime);
}
}
void CL_UseIndepPhysics(qboolean allow)
{
if (runningindepphys == allow)
return;
if (allow)
{ //enable it
DWORD tid; //*sigh*...
InitializeCriticalSection(&indepcriticialsection);
runningindepphys = true;
indepphysicsthread = CreateThread(NULL, 8192, CL_IndepPhysicsThread, NULL, 0, &tid);
}
else
{
//shut it down.
EnterCriticalSection(&indepcriticialsection);
TerminateThread(indepphysicsthread, 0);
CloseHandle(indepphysicsthread);
LeaveCriticalSection(&indepcriticialsection);
runningindepphys = false;
}
}
#else
void CL_AllowIndependantSendCmd(qboolean allow)
{
}
#endif
/*
=================
CL_SendCmd
@ -860,6 +998,8 @@ void CL_SendCmd (void)
int clientcount;
extern cvar_t cl_maxfps;
#ifdef Q3CLIENT
if (cls.q2server==2)
{ //guess what? q3 rules don't require network packet limiting!
@ -886,6 +1026,19 @@ void CL_SendCmd (void)
}
#endif
{
clcmdbuf_t *next;
while (clientcmdlist)
{
next = clientcmdlist->next;
MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
MSG_WriteString (&cls.netchan.message, clientcmdlist->command);
// Con_Printf("Sending stringcmd %s\n", clientcmdlist->command);
Z_Free(clientcmdlist);
clientcmdlist = next;
}
}
if (cls.demoplayback != DPB_NONE)
{
if (cls.demoplayback == DPB_MVD)
@ -937,7 +1090,7 @@ void CL_SendCmd (void)
msecstouse = (int)msecs; //casts round down.
if (!CL_Net_FilterTime(msecstouse) && msecstouse<255)
if (!CL_FilterTime(msecstouse, cl_netfps.value<=0?cl_maxfps.value:cl_netfps.value) && msecstouse<255)
{
usercmd_t new;

View File

@ -357,6 +357,9 @@ void CL_SendConnectPacket (
#ifdef PEXT_CHUNKEDDOWNLOADS
fteprotextsupported |= PEXT_CHUNKEDDOWNLOADS;
#endif
#ifdef PEXT_CSQC
fteprotextsupported |= PEXT_CSQC;
#endif
fteprotextsupported &= ftepext;
@ -770,6 +773,8 @@ void CL_ClearState (void)
#define SV_UnspawnServer()
#endif
CL_AllowIndependantSendCmd(false); //model stuff could be a problem.
S_StopAllSounds (true);
Cvar_ApplyLatches(CVAR_SERVEROVERRIDE);
@ -1399,8 +1404,13 @@ void CL_Packet_f (void)
if (adr.ip[2] == 0)
if (adr.ip[3] == 1)
{
adr.ip[0] = cls.netchan.remote_address.ip[0];
adr.ip[1] = cls.netchan.remote_address.ip[1];
adr.ip[2] = cls.netchan.remote_address.ip[2];
adr.ip[3] = cls.netchan.remote_address.ip[3];
adr.port = cls.netchan.remote_address.port;
Con_Printf ("^b^1Server is broken. Ignoring 'realip' packet request\n");
return;
}
Con_DPrintf ("Sending realip packet\n");
@ -1582,8 +1592,7 @@ void CL_Reconnect_f (void)
if (cls.state == ca_connected)
{
Con_TPrintf (TLC_RECONNECTING);
MSG_WriteChar (&cls.netchan.message, clc_stringcmd);
MSG_WriteString (&cls.netchan.message, "new");
CL_SendClientCommand("new");
return;
}
@ -1798,8 +1807,7 @@ client_connect: //fixme: make function
#ifdef NQPROT
cls.netchan.qsocket = cls.netcon;
#endif
MSG_WriteChar (&cls.netchan.message, clc_stringcmd);
MSG_WriteString (&cls.netchan.message, "new");
CL_SendClientCommand("new");
cls.state = ca_connected;
Con_TPrintf (TLC_CONNECTED);
allowremotecmd = false; // localid required now for remote cmds
@ -2127,8 +2135,7 @@ void CL_Download_f (void)
cls.downloadmethod = DL_QWPENDING;
MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
SZ_Print (&cls.netchan.message, va("download %s\n",url));*/
CL_SendClientCommand("download %s\n",url);*/
}
#ifdef _WINDOWS
@ -2530,54 +2537,6 @@ qboolean Host_SimulationTime(float time)
}
#endif
/*
===================
CL_FilterTime
Returns false if the time is too short to run a frame
===================
*/
#define bound(n,v,x) v<n?n:(v>x?x:v)
qboolean CL_Net_FilterTime (double time);
qboolean CL_FilterTime (double time)
{
float fps;
// float fpscap;
if (cls.timedemo)
return true;
// if (cls.demoplayback)
// {
if (!cl_maxfps.value)
return true;
if (cl_maxfps.value < 0)
return CL_Net_FilterTime(time*1000);
fps = max (30.0, cl_maxfps.value);
/* }
else
{
fpscap = cls.maxfps ? max (30.0, cls.maxfps) : 0x7fff;
if (cl_maxfps.value)
fps = bound (10.0, cl_maxfps.value, fpscap);
else
{
// if (com_serveractive)
// fps = fpscap;
// else
fps = bound (30.0, rate.value/80.0, fpscap);
}
}
*/
if (time < 1.0 / fps)
return false;
return true;
}
/*
==================
Host_Frame
@ -2590,8 +2549,10 @@ extern float recordavi_frametime;
extern qboolean recordingdemo;
#endif
extern cvar_t cl_netfps;
int nopacketcount;
void SNDDMA_SetUnderWater(qboolean underwater);
qboolean CL_FilterTime (double time, float wantfps);
void Host_Frame (float time)
{
static double time1 = 0;
@ -2606,7 +2567,7 @@ void Host_Frame (float time)
return; // something bad happened, or the server disconnected
#if defined(WINAVI) && !defined(NOMEDIA)
if (cls.demoplayback && recordingdemo)
if (cls.demoplayback && recordingdemo && recordavi_frametime>0.01)
time = recordavi_frametime;
#endif
@ -2672,8 +2633,16 @@ void Host_Frame (float time)
*/
Mod_Think(); //think even on idle (which means small walls and a fast cpu can get more surfaces done.
if (!CL_FilterTime(realtime - oldrealtime))
return;
if (cl_maxfps.value>0 && cl_netfps.value>0)
{ //limit the fps freely, and expect the netfps to cope.
if ((realtime - oldrealtime) < 1/cl_maxfps.value)
return;
}
else
{
if (!CL_FilterTime((realtime - oldrealtime)*1000, cl_maxfps.value>0?cl_maxfps.value:cl_netfps.value))
return;
}
host_frametime = realtime - oldrealtime;
oldrealtime = realtime;
@ -2703,14 +2672,16 @@ void Host_Frame (float time)
RSpeedRemark();
CL_AllowIndependantSendCmd(false);
if (cls.downloadtype == dl_none && !*cls.downloadname && cl.downloadlist)
{
CL_RequestNextDownload();
}
CL_RequestNextDownload();
// fetch results from server
CL_ReadPackets ();
CL_AllowIndependantSendCmd(true);
// send intentions now
// resend a connection request if necessary
if (cls.state == ca_disconnected)

View File

@ -604,8 +604,7 @@ void CL_SendDownloadRequest(char *filename)
COM_StripExtension (cls.downloadname, cls.downloadtempname);
strcat (cls.downloadtempname, ".tmp");
MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
MSG_WriteString (&cls.netchan.message, va("download %s", cls.downloadname));
CL_SendClientCommand("download %s", cls.downloadname);
//prevent ftp/http from changing stuff
cls.downloadmethod = DL_QWPENDING;
@ -816,7 +815,9 @@ void Model_NextDownload (void)
if (CL_CheckMD2Skins(s))
return;
}
CL_AllowIndependantSendCmd(false); //stop it now, the indep stuff *could* require model tracing.
if (cl.playernum[0] == -1)
{ //q2 cinematic - don't load the models.
cl.worldmodel = cl.model_precache[1] = Mod_ForName ("", false);
@ -827,12 +828,12 @@ void Model_NextDownload (void)
{
if (!cl.model_name[i][0])
break;
Hunk_Check();
cl.model_precache[i] = NULL;
cl.model_precache[i] = Mod_ForName (cl.model_name[i], false);
Hunk_Check();
if (!cl.model_precache[i] || (i == 1 && (cl.model_precache[i]->type == mod_dummy || cl.model_precache[i]->needload)))
@ -879,9 +880,8 @@ void Model_NextDownload (void)
#endif
{
// done with modellist, request first of static signon messages
MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
// MSG_WriteString (&cls.netchan.message, va("prespawn %i 0 %i", cl.servercount, cl.worldmodel->checksum2));
MSG_WriteString (&cls.netchan.message, va(prespawn_name, cl.servercount, cl.worldmodel->checksum2));
// CL_SendClientCommand("prespawn %i 0 %i", cl.servercount, cl.worldmodel->checksum2);
CL_SendClientCommand(prespawn_name, cl.servercount, cl.worldmodel->checksum2);
}
}
@ -945,9 +945,8 @@ void Sound_NextDownload (void)
else
#endif
{
MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
// MSG_WriteString (&cls.netchan.message, va("modellist %i 0", cl.servercount));
MSG_WriteString (&cls.netchan.message, va(modellist_name, cl.servercount, 0));
// CL_SendClientCommand ("modellist %i 0", cl.servercount);
CL_SendClientCommand (modellist_name, cl.servercount, 0);
}
}
@ -1009,8 +1008,7 @@ void CL_SendDownloadReq(sizebuf_t *msg)
}
else
{
MSG_WriteByte(msg, clc_stringcmd);
MSG_WriteString(msg, va("nextdl %i\n", i));
CL_SendClientCommand("nextdl %i\n", i);
}
return;
}
@ -1335,8 +1333,7 @@ void CL_ParseDownload (void)
// request next block
cls.downloadpercent = percent;
MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
SZ_Print (&cls.netchan.message, "nextdl");
CL_SendClientCommand("nextdl");
}
else
{
@ -1602,16 +1599,14 @@ void CL_ParseServerData (void)
#ifdef PEXT_PK3DOWNLOADS
if (cls.fteprotocolextensions & PEXT_PK3DOWNLOADS) //instead of going for a soundlist, go for the pk3 list instead. The server will make us go for the soundlist after.
{
MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
MSG_WriteString (&cls.netchan.message, va("pk3list %i 0", cl.servercount, 0));
CL_SendClientCommand ("pk3list %i 0", cl.servercount, 0);
}
else
#endif
{
// ask for the sound list next
MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
// MSG_WriteString (&cls.netchan.message, va("soundlist %i 0", cl.servercount));
MSG_WriteString (&cls.netchan.message, va(soundlist_name, cl.servercount, 0));
// CL_SendClientCommand ("soundlist %i 0", cl.servercount);
CL_SendClientCommand (soundlist_name, cl.servercount, 0);
}
// now waiting for downloads, etc
@ -1848,8 +1843,7 @@ void CLNQ_ParseServerData(void) //Doesn't change gamedir - use with caution.
cls.state = ca_onserver;
}
void CLNQ_SignonReply (void)
{
char str[8192];
{
extern cvar_t topcolor;
extern cvar_t bottomcolor;
@ -1858,26 +1852,20 @@ Con_DPrintf ("CL_SignonReply: %i\n", cls.signon);
switch (cls.signon)
{
case 1:
MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
MSG_WriteString (&cls.netchan.message, "prespawn");
CL_SendClientCommand("prespawn");
break;
case 2:
MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
MSG_WriteString (&cls.netchan.message, va("name \"%s\"\n", name.string));
CL_SendClientCommand("name \"%s\"\n", name.string);
name.modified = false;
MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
MSG_WriteString (&cls.netchan.message, va("color %i %i\n", (int)topcolor.value, (int)bottomcolor.value));
CL_SendClientCommand("color %i %i\n", (int)topcolor.value, (int)bottomcolor.value);
MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
sprintf (str, "spawn %s", "");
MSG_WriteString (&cls.netchan.message, str);
CL_SendClientCommand("spawn %s", "");
break;
case 3:
MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
MSG_WriteString (&cls.netchan.message, "begin");
CL_SendClientCommand("begin");
Cache_Report (); // print remaining memory
#ifdef VM_CG
CG_Start();
@ -2052,7 +2040,8 @@ void CL_ParseSoundlist (void)
numsounds = MSG_ReadByte();
for (;;) {
for (;;)
{
str = MSG_ReadString ();
if (!str[0])
break;
@ -2069,10 +2058,10 @@ void CL_ParseSoundlist (void)
n = MSG_ReadByte();
if (n) {
MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
// MSG_WriteString (&cls.netchan.message, va("soundlist %i %i", cl.servercount, n));
MSG_WriteString (&cls.netchan.message, va(soundlist_name, cl.servercount, n));
if (n)
{
// CL_SendClientCommand("soundlist %i %i", cl.servercount, n);
CL_SendClientCommand(soundlist_name, cl.servercount, n);
return;
}
@ -2140,10 +2129,10 @@ void CL_ParseModellist (qboolean lots)
n = MSG_ReadByte();
if (n) {
MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
// MSG_WriteString (&cls.netchan.message, va("modellist %i %i", cl.servercount, n));
MSG_WriteString (&cls.netchan.message, va(modellist_name, cl.servercount, (nummodels&0xff00) + n));
if (n)
{
// CL_SendClientCommand("modellist %i %i", cl.servercount, n);
CL_SendClientCommand(modellist_name, cl.servercount, (nummodels&0xff00) + n);
return;
}
@ -4141,6 +4130,12 @@ void CL_ParseServerMessage (void)
case svcqw_effect2:
CL_ParseEffect(true);
break;
#ifdef PEXT_CSQC
case svc_csqcentities:
CSQC_ParseEntities();
break;
#endif
}
}
}
@ -4229,8 +4224,7 @@ void CLQ2_ParseServerMessage (void)
return;
case svcq2_reconnect: //8
Con_TPrintf (TLC_RECONNECTING);
MSG_WriteChar (&cls.netchan.message, clc_stringcmd);
MSG_WriteString (&cls.netchan.message, "new");
CL_SendClientCommand("new");
break;
case svcq2_sound: //9 // <see code>
CLQ2_ParseStartSoundPacket();

View File

@ -580,7 +580,9 @@ void CL_PredictMovePNum (int pnum)
}
if (cls.netchan.outgoing_sequence - cl.validsequence >= UPDATE_BACKUP-1)
{
{ //lagging like poo.
if (!cl.intermission) //keep the angles working though.
VectorCopy (cl.viewangles[pnum], cl.simangles[pnum]);
return;
}

View File

@ -992,6 +992,16 @@ void SCR_DrawFPS (void)
lastframetime = t;
}
if (show_fps.value == 2) //alternate mode that displays the lowest noticed
{
if (lastfps > 1/host_frametime)
{
lastfps = 1/host_frametime;
fps_count = 0;
lastframetime = t;
}
}
sprintf(str, "%3.1f FPS", lastfps);
SCR_StringXY(str, show_fps_x.value, show_fps_y.value);
}
@ -1260,7 +1270,7 @@ void SCR_SetUpToDrawConsole (void)
if (clearconsole++ < vid.numpages)
{
if (qrenderer == QR_SOFTWARE)
if (qrenderer == QR_SOFTWARE && !media_filmtype)
{
scr_copytop = 1;
Draw_TileClear (0, (int) scr_con_current, vid.width, vid.height - (int) scr_con_current);
@ -1270,7 +1280,7 @@ void SCR_SetUpToDrawConsole (void)
}
else if (clearnotify++ < vid.numpages)
{
if (qrenderer == QR_SOFTWARE)
if (qrenderer == QR_SOFTWARE && !media_filmtype)
{
scr_copytop = 1;
Draw_TileClear (0, 0, vid.width, con_notifylines);
@ -1870,7 +1880,8 @@ void SCR_DrawTwoDimensional(int uimenu, qboolean nohud)
else
SCR_DrawFPS ();
SCR_CheckDrawCenterString ();
// qglTexEnvi ( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
if (qrenderer == QR_OPENGL)
qglTexEnvi ( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
#ifdef TEXTEDITOR
if (editoractive)
Editor_Draw();

View File

@ -629,6 +629,8 @@ extern kbutton_t in_mlook, in_klook;
extern kbutton_t in_strafe;
extern kbutton_t in_speed;
extern float in_sensitivityscale;
void CL_InitInput (void);
void CL_SendCmd (void);
void CL_SendMove (usercmd_t *cmd);
@ -653,6 +655,9 @@ float CL_KeyState (kbutton_t *key, int pnum);
char *Key_KeynumToString (int keynum);
int Key_StringToKeynum (char *str, int *modifier);
void VARGS CL_SendClientCommand(char *format, ...);
void CL_AllowIndependantSendCmd(qboolean allow);
//
// cl_demo.c
//

View File

@ -1,7 +1,5 @@
#include "bothdefs.h"
#ifndef NOMEDIA
#include "quakedef.h"
#ifndef NOMEDIA
typedef struct
{
@ -93,8 +91,7 @@ void CIN_FinishCinematic (void)
// tell the server to advance to the next map / cinematic
if (cls.state == ca_active)
{
MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
SZ_Print (&cls.netchan.message, va("nextserver %i\n", cl.servercount));
CL_SendClientCommand("nextserver %i", cl.servercount);
}
}

View File

@ -1,6 +1,5 @@
#include "bothdefs.h"
#ifdef Q2CLIENT
#include "quakedef.h"
#ifdef Q2CLIENT
extern cvar_t r_drawviewmodel;
@ -940,25 +939,9 @@ struct model_s *S_RegisterSexedModel (entity_state_t *ent, char *base)
*/
void V_AddEntity(entity_t *in)
{
entity_t *ent;
if (cl_numvisedicts == MAX_VISEDICTS)
return; // object list is full
ent = &cl_visedicts[cl_numvisedicts];
cl_numvisedicts++;
*ent = *in;
ent->angles[0]*=-1;
AngleVectors(ent->angles, ent->axis[0], ent->axis[1], ent->axis[2]);
VectorInverse(ent->axis[1]);
ent->angles[0]*=-1;
}
void V_AddLight (vec3_t org, float quant, float r, float g, float b)
{
CL_NewDlightRGB (0, org[0], org[1], org[2], quant, 0.1, r, g, b);
CL_NewDlightRGB (0, org[0], org[1], org[2], quant, 0, r, g, b);
}
/*
===============

View File

@ -1008,8 +1008,8 @@ static void ProcessMouse(mouse_t *mouse, usercmd_t *cmd, int pnum)
mouse->old_delta[0] = mx;
mouse->old_delta[1] = my;
mouse_x *= sensitivity.value;
mouse_y *= sensitivity.value;
mouse_x *= sensitivity.value*in_sensitivityscale;
mouse_y *= sensitivity.value*in_sensitivityscale;
if (!cmd)
{

View File

@ -1,3 +1,5 @@
//read menu.h
#include "quakedef.h"
int omousex;

View File

@ -1,7 +1,6 @@
#include "bothdefs.h"
#include "quakedef.h"
#ifdef CL_MASTER
#include "quakedef.h"
#include "cl_master.h"
enum {

View File

@ -1,3 +1,5 @@
//read menu.h
#include "quakedef.h"
#include "winquake.h"

View File

@ -1,3 +1,5 @@
//read menu.h
#include "quakedef.h"
#include "winquake.h"

View File

@ -1,3 +1,5 @@
//read menu.h
#include "quakedef.h"
int selectitem;

View File

@ -1,3 +1,5 @@
//read menu.h
#include "quakedef.h"
#include "winquake.h"
#ifndef CLIENTONLY

View File

@ -18,14 +18,86 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
//
// the net drivers should just set the apropriate bits in m_activenet,
// instead of having the menu code look through their internal tables
//
#define MNET_IPX 1
#define MNET_TCP 2
//There are still menu states, which say which menu gets absolute control.
//Some of the destinations are healthier than others. :)
//m_none - menu is disabled
//m_complex - hirachy of item types
//m_help - old q1 style help menu (fixme: make m_complex)
//m_keys - old q1 style key menu (fixme: make m_complex)
//m_slist - serverbrowser. Takes full control of screen.
//m_media - an mp3 player type thing. It was never really compleate.
// It should perhaps either be fixed or removed.
//m_xwindows- Run an X windowing syatem. Fixme: make plugin.
//m_plugin - A QVM based or DLL based plugin.
//m_menu_dat- A QC based version of m_plugin. This should be compatable with DP's menu.dat stuff.
//the m_complex menu state is the most advanced, and drives the bulk of FTE's menus in an event driven way.
//It consists of menus and items. Fairly basic really.
//Each item type has a structure (or shares a structure).
//Each of these structures contain a menucommon_t.
//The backend of this system lives in m_items.c.
//If you're creating your own quake menu, there should be little need to go in there.
//These are the item types:
//mt_childwindow -
//mt_button - Executes a console command or callback on enter. Uses conchars.
//mt_buttonbigfont - Used by hexen2's menus. Uses gfx/menu/bigfont.lmp as it's charactures.
//mt_box - A 2d box. The same one as the quit dialog from q1, but resized.
//mt_colouredbox - Not used.
//mt_line - Not used.
//mt_edit - A one row edit box, either attached to a cvar, or an apply button.
//mt_text - unselectable. Otherwise like mt_button
//mt_slider - a horizontal slider, like quake's gamma option, attached to a cvar.
//mt_combo - multiple specific options. Created with specifically structured info.
//mt_bind - a key binding option.
//mt_checkbox - a yes/no toggle, attached to a cvar.
//mt_picture - Just draws a lmp from it's x/y.
//mt_menudot - The 24*24 rotating quake menudot. Should be specified as the cursoritem, and should be placed to match the selecteditem's y position.
//mt_custom - Just an option with callbacks. This is the basis of the top/bottom color seletion, and could be used for all sorts of things.
//Sample menu creation, entirly within /* and */
//Note that most of FTE's menus are more complicated, as FTE runs on Q1/Q2/H2 data, and it's choice of menu images reflects this.
//Most of the normal menus also have more items too, of course.
//FTE's menu console commands are registered from M_Init_Internal instead of M_Init as implied here. Why?
//FTE's menu.dat support unregisters the menu console commands so the menu.dat can use those commands instead.
//This results in more user friendliness for mods but makes the code a little more confusing.
//If you make the menu name unique enough, then there's no need to follow the standard menu code.
/*
//M_SomeMenuConsoleCommand_f
//Spawns a sample menu.
void M_SomeMenuConsoleCommand_f (void)
{
menu_t *m = M_CreateMenu(0);
int y = 32;
//add the title
MC_AddCenterPicture(m, 4, "gfx/p_option.lmp");
//add the blinking > thingie
//(note NULL instead of a valid string, this should really be a variant of mt_menudot instead)
menu->cursoritem = (menuoption_t*)MC_AddWhiteText(menu, 200, y, NULL, false);
//Set up so the first item is selected. :)
m->selecteditem = (menuoption_t*)
//Add the items.
MC_AddConsoleCommand(menu, 16, y, " Customize controls", "menu_keys\n"); y+=8;
MC_AddSlider(menu, 16, y, " Mouse Speed", &sensitivity, 1, 10); y+=8;
MC_AddCheckBox(menu, 16, y, " Lookstrafe", &lookstrafe,0); y+=8;
}
//eg: M_Init
void M_SomeInitialisationFunctionCalledAtStartup(void)
{
Cmd_AddCommand("menu_somemenu", M_SomeMenuConsoleCommand_f);
}
*/
extern int m_activenet;
//
// menus
@ -197,9 +269,7 @@ menuslider_t *MC_AddSlider(menu_t *menu, int x, int y, const char *text, cvar_t
menucheck_t *MC_AddCheckBox(menu_t *menu, int x, int y, const char *text, cvar_t *var, int cvarbitmask);
menubutton_t *MC_AddConsoleCommand(menu_t *menu, int x, int y, const char *text, const char *command);
menubutton_t *MC_AddCommand(menu_t *menu, int x, int y, char *text, qboolean (*command) (union menuoption_s *,struct menu_s *,int));
menucombo_t *MC_AddCombo(menu_t *menu, int x, int y, const char *caption, const char **text, int initialvalue);
menubutton_t *MC_AddCommand(menu_t *menu, int x, int y, char *text, qboolean (*command) (union menuoption_s *,struct menu_s *,int));
menuedit_t *MC_AddEdit(menu_t *menu, int x, int y, char *text, char *def);
menuedit_t *MC_AddEditCvar(menu_t *menu, int x, int y, char *text, char *name);

View File

@ -1,8 +1,7 @@
#include "bothdefs.h"
#include "quakedef.h"
#ifdef CL_MASTER
#include "quakedef.h"
#include "cl_master.h"
#define NET_GAMENAME_NQ "QUAKE"

View File

@ -8,25 +8,104 @@
progfuncs_t *csqcprogs;
typedef struct {
//These are the functions the engine will call to, found by name.
func_t init_function;
func_t shutdown_function;
func_t draw_function;
func_t keydown_function;
func_t keyup_function;
func_t parse_stuffcmd;
func_t parse_centerprint;
func_t ent_update;
func_t ent_remove;
//These are pointers to the csqc's globals.
float *time; //float Written before entering most qc functions
int *self; //entity Written before entering most qc functions
float *forward; //vector written by anglevectors
float *right; //vector written by anglevectors
float *up; //vector written by anglevectors
float *trace_allsolid; //bool written by traceline
float *trace_startsolid; //bool written by traceline
float *trace_fraction; //float written by traceline
float *trace_inwater; //bool written by traceline
float *trace_inopen; //bool written by traceline
float *trace_endpos; //vector written by traceline
float *trace_plane_normal; //vector written by traceline
float *trace_plane_dist; //float written by traceline
int *trace_ent; //entity written by traceline
} csqcglobals_t;
static csqcglobals_t csqcg;
void CSQC_FindGlobals(void)
{
csqcg.time = (float*)PR_FindGlobal(csqcprogs, "time", 0);
if (csqcg.time)
*csqcg.time = Sys_DoubleTime();
csqcg.self = (int*)PR_FindGlobal(csqcprogs, "self", 0);
csqcg.forward = (float*)PR_FindGlobal(csqcprogs, "v_forward", 0);
csqcg.right = (float*)PR_FindGlobal(csqcprogs, "v_right", 0);
csqcg.up = (float*)PR_FindGlobal(csqcprogs, "v_up", 0);
csqcg.init_function = PR_FindFunction(csqcprogs, "CSQC_Init", PR_ANY);
csqcg.shutdown_function = PR_FindFunction(csqcprogs, "CSQC_Shutdown", PR_ANY);
csqcg.draw_function = PR_FindFunction(csqcprogs, "CSQC_UpdateView", PR_ANY);
csqcg.keydown_function = PR_FindFunction(csqcprogs, "CSQC_KeyDown", PR_ANY);
csqcg.keyup_function = PR_FindFunction(csqcprogs, "CSQC_KeyUp", PR_ANY);
csqcg.parse_stuffcmd = PR_FindFunction(csqcprogs, "CSQC_Parse_StuffCmd", PR_ANY);
csqcg.parse_centerprint = PR_FindFunction(csqcprogs, "CSQC_Parse_CenterPrint", PR_ANY);
csqcg.ent_update = PR_FindFunction(csqcprogs, "CSQC_Ent_Update", PR_ANY);
csqcg.ent_remove = PR_FindFunction(csqcprogs, "CSQC_Ent_Remove", PR_ANY);
}
//this is the list for all the csqc fields.
//(the #define is so the list always matches the ones pulled out)
#define csqcfields \
fieldfloat(modelindex); \
fieldvector(origin); \
fieldvector(angles); \
fieldfloat(alpha); /*transparency*/ \
fieldfloat(scale); /*model scale*/ \
fieldfloat(fatness); /*expand models X units along thier normals.*/ \
fieldfloat(skin); \
fieldfloat(colormap); \
fieldfloat(frame); \
fieldfloat(oldframe); \
fieldfloat(lerpfrac); \
\
fieldfloat(drawmask); /*So that the qc can specify all rockets at once or all bannanas at once*/ \
fieldfunction(predraw); /*If present, is called just before it's drawn.*/ \
\
fieldstring(model);
//note: doesn't even have to match the clprogs.dat :)
typedef struct {
//CHANGING THIS STRUCTURE REQUIRES CHANGES IN CSQC_InitFields
//fields the client will pull out of the edict for rendering.
float modelindex; //csqc modelindexes
vec3_t origin;
vec3_t angles;
float alpha; //transparency
float scale; //model scale
float fatness; //expand models X units along thier normals.
float skin;
float colormap;
float frame;
float oldframe;
float lerpfrac;
float drawmask; //drawentities uses this mask for it.
string_t model;
#define fieldfloat(name) float name
#define fieldvector(name) vec3_t name
#define fieldentity(name) int name
#define fieldstring(name) string_t name
#define fieldfunction(name) func_t name
csqcfields
#undef fieldfloat
#undef fieldvector
#undef fieldentity
#undef fieldstring
#undef fieldfunction
} csqcentvars_t;
typedef struct csqcedict_s
@ -39,6 +118,9 @@ typedef struct csqcedict_s
csqcentvars_t v;
} csqcedict_t;
csqcedict_t *csqc_edicts; //consider this 'world'
void CSQC_InitFields(void)
{ //CHANGING THIS FUNCTION REQUIRES CHANGES TO csqcentvars_t
#define fieldfloat(name) PR_RegisterFieldVar(csqcprogs, ev_float, #name, (int)&((csqcedict_t*)0)->v.name - (int)&((csqcedict_t*)0)->v, -1)
@ -46,24 +128,16 @@ void CSQC_InitFields(void)
#define fieldentity(name) PR_RegisterFieldVar(csqcprogs, ev_entity, #name, (int)&((csqcedict_t*)0)->v.name - (int)&((csqcedict_t*)0)->v, -1)
#define fieldstring(name) PR_RegisterFieldVar(csqcprogs, ev_string, #name, (int)&((csqcedict_t*)0)->v.name - (int)&((csqcedict_t*)0)->v, -1)
#define fieldfunction(name) PR_RegisterFieldVar(csqcprogs, ev_function, #name, (int)&((csqcedict_t*)0)->v.name - (int)&((csqcedict_t*)0)->v, -1)
fieldfloat(modelindex);
fieldvector(origin);
fieldvector(angles);
fieldfloat(alpha); //transparency
fieldfloat(scale); //model scale
fieldfloat(fatness); //expand models X units along thier normals.
fieldfloat(skin);
fieldfloat(colormap);
fieldfloat(frame);
fieldfloat(oldframe);
fieldfloat(lerpfrac);
fieldfloat(drawmask);
fieldstring(model);
csqcfields
#undef fieldfloat
#undef fieldvector
#undef fieldentity
#undef fieldstring
#undef fieldfunction
}
csqcedict_t *csqcent[MAX_EDICTS];
#define RETURN_SSTRING(s) (*(char **)&((int *)pr_globals)[OFS_RETURN] = PR_SetString(prinst, s)) //static - exe will not change it.
char *PF_TempStr(void);
@ -150,6 +224,22 @@ void PF_CL_drawgetimagesize (progfuncs_t *prinst, struct globalvars_s *pr_global
void PF_fclose_progs (progfuncs_t *prinst);
char *PF_VarString (progfuncs_t *prinst, int first, struct globalvars_s *pr_globals);
static void PF_Remove_ (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
csqcedict_t *ed;
ed = (csqcedict_t*)G_EDICT(prinst, OFS_PARM0);
if (ed->isfree)
{
Con_DPrintf("CSQC Tried removing free entity\n");
return;
}
ED_Free (prinst, (void*)ed);
}
static void PF_cvar (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
cvar_t *var;
@ -170,7 +260,7 @@ static void PF_Fixme (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
Con_Printf("\n");
prinst->PR_RunError(prinst, "\nBuiltin %i not implemented.\nMenu is not compatable.", prinst->lastcalledbuiltinnumber);
prinst->RunError(prinst, "\nBuiltin %i not implemented.\nMenu is not compatable.", prinst->lastcalledbuiltinnumber);
PR_BIError (prinst, "bulitin not implemented");
}
@ -178,7 +268,9 @@ static void PF_Fixme (progfuncs_t *prinst, struct globalvars_s *pr_globals)
static void PF_makevectors (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
// AngleVectors (G_VECTOR(OFS_PARM0), CSQC_VEC(v_forward), CSQC_VEC(v_right), CSQC_VEC(v_up));
if (!csqcg.forward || !csqcg.right || !csqcg.up)
Host_EndGame("PF_makevectors: one of v_forward, v_right or v_up was not defined\n");
AngleVectors (G_VECTOR(OFS_PARM0), csqcg.forward, csqcg.right, csqcg.up);
}
static void PF_R_AddEntity(progfuncs_t *prinst, struct globalvars_s *pr_globals)
@ -186,19 +278,29 @@ static void PF_R_AddEntity(progfuncs_t *prinst, struct globalvars_s *pr_globals)
csqcedict_t *in = (void*)G_EDICT(prinst, OFS_PARM0);
entity_t ent;
int i;
memset(&ent, 0, sizeof(ent));
model_t *model;
if (in->v.predraw)
{
int oldself = *csqcg.self;
*csqcg.self = EDICT_TO_PROG(prinst, (void*)in);
PR_ExecuteProgram(prinst, in->v.predraw);
*csqcg.self = oldself;
}
i = in->v.modelindex;
if (i == 0)
return;
else if (i > 0 && i < MAX_MODELS)
ent.model = cl.model_precache[i];
model = cl.model_precache[i];
else if (i < 0 && i > -MAX_CSQCMODELS)
ent.model = cl.model_csqcprecache[-i];
model = cl.model_csqcprecache[-i];
else
return; //there might be other ent types later as an extension that stop this.
memset(&ent, 0, sizeof(ent));
ent.model = model;
if (!ent.model)
{
Con_Printf("PF_R_AddEntity: model wasn't precached!\n");
@ -213,6 +315,7 @@ static void PF_R_AddEntity(progfuncs_t *prinst, struct globalvars_s *pr_globals)
ent.angles[0] = in->v.angles[0];
ent.angles[1] = in->v.angles[1];
ent.angles[2] = in->v.angles[2];
memcpy(ent.origin, in->v.origin, sizeof(vec3_t));
AngleVectors(ent.angles, ent.axis[0], ent.axis[1], ent.axis[2]);
VectorInverse(ent.axis[1]);
@ -222,6 +325,14 @@ static void PF_R_AddEntity(progfuncs_t *prinst, struct globalvars_s *pr_globals)
V_AddEntity(&ent);
}
static void PF_R_AddDynamicLight(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
float *org = G_VECTOR(OFS_PARM0);
float radius = G_FLOAT(OFS_PARM1);
float *rgb = G_VECTOR(OFS_PARM2);
V_AddLight(org, radius, rgb[0]/5, rgb[1]/5, rgb[2]/5);
}
#define MASK_ENGINE 1
static void PF_R_AddEntityMask(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
@ -414,7 +525,8 @@ static void PF_R_SetViewFlag(progfuncs_t *prinst, struct globalvars_s *pr_global
static void PF_R_RenderScene(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
R_PushDlights ();
if (cl.worldmodel)
R_PushDlights ();
#ifdef RGLQUAKE
if (qrenderer == QR_OPENGL)
@ -494,6 +606,77 @@ static void PF_CSQC_SetOrigin(progfuncs_t *prinst, struct globalvars_s *pr_globa
//fixme: add some sort of fast area grid
}
//FIXME: Not fully functional
static void PF_CSQC_traceline(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
float *v1, *v2, *mins, *maxs;
trace_t trace;
int nomonsters;
edict_t *ent;
// int savedhull;
v1 = G_VECTOR(OFS_PARM0);
v2 = G_VECTOR(OFS_PARM1);
nomonsters = G_FLOAT(OFS_PARM2);
ent = G_EDICT(prinst, OFS_PARM3);
// if (*prinst->callargc == 6)
// {
// mins = G_VECTOR(OFS_PARM4);
// maxs = G_VECTOR(OFS_PARM5);
// }
// else
{
mins = vec3_origin;
maxs = vec3_origin;
}
/*
savedhull = ent->v.hull;
ent->v.hull = 0;
trace = SV_Move (v1, mins, maxs, v2, nomonsters, ent);
ent->v.hull = savedhull;
*/
memset(&trace, 0, sizeof(trace));
trace.fraction = 1;
cl.worldmodel->hulls->funcs.RecursiveHullCheck (cl.worldmodel->hulls, 0, 0, 1, v1, v2, &trace);
*csqcg.trace_allsolid = trace.allsolid;
*csqcg.trace_startsolid = trace.startsolid;
*csqcg.trace_fraction = trace.fraction;
*csqcg.trace_inwater = trace.inwater;
*csqcg.trace_inopen = trace.inopen;
VectorCopy (trace.endpos, csqcg.trace_endpos);
VectorCopy (trace.plane.normal, csqcg.trace_plane_normal);
*csqcg.trace_plane_dist = trace.plane.dist;
// if (trace.ent)
// *csqcg.trace_ent = EDICT_TO_PROG(prinst, trace.ent);
// else
*csqcg.trace_ent = EDICT_TO_PROG(prinst, (void*)csqc_edicts);
}
static void PF_CSQC_pointcontents(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
float *v;
int cont;
v = G_VECTOR(OFS_PARM0);
cont = cl.worldmodel->hulls[0].funcs.HullPointContents(&cl.worldmodel->hulls[0], v);
if (cont & FTECONTENTS_SOLID)
G_FLOAT(OFS_RETURN) = Q1CONTENTS_SOLID;
else if (cont & FTECONTENTS_SKY)
G_FLOAT(OFS_RETURN) = Q1CONTENTS_SKY;
else if (cont & FTECONTENTS_LAVA)
G_FLOAT(OFS_RETURN) = Q1CONTENTS_LAVA;
else if (cont & FTECONTENTS_SLIME)
G_FLOAT(OFS_RETURN) = Q1CONTENTS_SLIME;
else if (cont & FTECONTENTS_WATER)
G_FLOAT(OFS_RETURN) = Q1CONTENTS_WATER;
else
G_FLOAT(OFS_RETURN) = Q1CONTENTS_EMPTY;
}
static int FindModel(char *name, int *free)
{
int i;
@ -554,20 +737,11 @@ static void PF_CSQC_SetModelIndex(progfuncs_t *prinst, struct globalvars_s *pr_g
}
static void PF_CSQC_PrecacheModel(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int modelindex, freei;
char *modelname = PR_GetStringOfs(prinst, OFS_PARM0);
int i;
for (i = 1; i < MAX_CSQCMODELS; i++)
{
if (!*cl.model_csqcname[i])
break;
if (!strcmp(cl.model_csqcname[i], modelname))
{
cl.model_csqcprecache[i] = Mod_ForName(cl.model_csqcname[i], false);
break;
}
}
for (i = 1; i < MAX_MODELS; i++) //I regret this.
for (i = 1; i < MAX_MODELS; i++) //Make sure that the server specified model is loaded..
{
if (!*cl.model_name[i])
break;
@ -577,7 +751,25 @@ static void PF_CSQC_PrecacheModel(progfuncs_t *prinst, struct globalvars_s *pr_g
break;
}
}
modelindex = FindModel(modelname, &freei); //now load it
if (!modelindex)
{
if (!freei)
Host_EndGame("CSQC ran out of model slots\n");
Q_strncpyz(cl.model_csqcname[-freei], modelname, sizeof(cl.model_csqcname[-freei])); //allocate a slot now
modelindex = freei;
cl.model_csqcprecache[-freei] = Mod_ForName(cl.model_csqcname[-freei], false);
}
}
static void PF_CSQC_PrecacheSound(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *soundname = PR_GetStringOfs(prinst, OFS_PARM0);
S_PrecacheSound(soundname);
}
static void PF_CSQC_ModelnameForIndex(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int modelindex = G_FLOAT(OFS_PARM0);
@ -588,6 +780,78 @@ static void PF_CSQC_ModelnameForIndex(progfuncs_t *prinst, struct globalvars_s *
G_INT(OFS_RETURN) = (int)PR_SetString(prinst, cl.model_name[modelindex]);
}
static void PF_ReadByte(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
G_FLOAT(OFS_RETURN) = MSG_ReadByte();
}
static void PF_ReadChar(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
G_FLOAT(OFS_RETURN) = MSG_ReadChar();
}
static void PF_ReadShort(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
G_FLOAT(OFS_RETURN) = MSG_ReadShort();
}
static void PF_ReadLong(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
G_FLOAT(OFS_RETURN) = MSG_ReadLong();
}
static void PF_ReadCoord(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
G_FLOAT(OFS_RETURN) = MSG_ReadCoord();
}
static void PF_ReadString(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *str = PF_TempStr();
char *read = MSG_ReadString();
Q_strncpyz(str, read, MAXTEMPBUFFERLEN);
}
static void PF_ReadAngle(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
G_FLOAT(OFS_RETURN) = MSG_ReadAngle();
}
static void PF_objerror (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *s;
edict_t *ed;
s = PF_VarString(prinst, 0, pr_globals);
/* Con_Printf ("======OBJECT ERROR in %s:\n%s\n", PR_GetString(pr_xfunction->s_name),s);
*/ ed = PROG_TO_EDICT(prinst, pr_global_struct->self);
/* ED_Print (ed);
*/
ED_Print(prinst, ed);
Con_Printf("%s", s);
if (developer.value)
(*prinst->pr_trace) = 2;
else
{
ED_Free (prinst, ed);
prinst->AbortStack(prinst);
PR_BIError (prinst, "Program error: %s", s);
if (sv.time > 10)
Cbuf_AddText("restart\n", RESTRICT_LOCAL);
}
}
static void PF_cs_setsensativityscaler (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
in_sensitivityscale = G_FLOAT(OFS_PARM0);
}
//warning: functions that depend on globals are bad, mkay?
builtin_t csqc_builtins[] = {
//0
@ -603,15 +867,15 @@ builtin_t csqc_builtins[] = {
PF_normalize,
//10
PF_error,
PF_Fixme, //PF_objerror,
PF_objerror,
PF_vlen,
PF_vectoyaw,
PF_Spawn,
PF_Fixme, //PF_Remove,
PF_Fixme, //PF_traceline,
PF_Remove_, //PF_Remove,
PF_CSQC_traceline, //PF_traceline,
PF_Fixme, //PF_checkclient, (don't support)
PF_FindString,
PF_Fixme, //PF_precache_sound,
PF_CSQC_PrecacheSound, //PF_precache_sound,
//20
PF_CSQC_PrecacheModel, //PF_precache_model,
PF_Fixme, //PF_stuffcmd, (don't support)
@ -636,7 +900,7 @@ PF_ceil,
PF_Fixme,
//40
PF_Fixme, //PF_checkbottom,
PF_Fixme, //PF_pointcontents,
PF_CSQC_pointcontents, //PF_pointcontents,
PF_Fixme,
PF_fabs,
PF_Fixme, //PF_aim, hehehe... (don't support)
@ -649,14 +913,15 @@ PF_Fixme, //PF_changeyaw,
PF_Fixme,
PF_vectoangles,
PF_Fixme,
PF_Fixme,
PF_Fixme,
PF_Fixme,
PF_Fixme,
PF_Fixme,
PF_Fixme,
PF_Fixme,
PF_ReadByte,
PF_ReadChar,
PF_ReadShort,
PF_ReadLong,
PF_ReadCoord,
PF_ReadAngle,
PF_ReadString,
PF_Fixme,//PF_ReadEntity,
//60
PF_Fixme,
@ -678,7 +943,7 @@ PF_cvar_set,
PF_Fixme, //PF_centerprint,
PF_Fixme, //PF_ambientsound,
PF_Fixme, //PF_precache_model,
PF_CSQC_PrecacheModel, //PF_precache_model,
PF_Fixme, //PF_precache_sound,
PF_Fixme, //PF_precache_file,
PF_Fixme, //PF_setspawnparms,
@ -753,7 +1018,7 @@ PF_R_AddEntity,
PF_R_SetViewFlag,
PF_R_RenderScene,
PF_Fixme,
PF_R_AddDynamicLight,
PF_Fixme,
PF_Fixme,
PF_Fixme,
@ -775,10 +1040,10 @@ PF_CL_drawgetimagesize,//9
PF_cs_getstatf,
PF_cs_getstati,
PF_cs_getstats,
PF_Fixme,
PF_Fixme,
PF_CSQC_SetModelIndex,
PF_CSQC_ModelnameForIndex,
PF_Fixme,
PF_cs_setsensativityscaler,
PF_Fixme,
PF_Fixme,
PF_Fixme,
@ -910,20 +1175,8 @@ int csqc_numbuiltins = sizeof(csqc_builtins)/sizeof(csqc_builtins[0]);
jmp_buf csqc_abort;
progparms_t csqcprogparms;
csqcedict_t *csqc_edicts;
int num_csqc_edicts;
func_t csqc_init_function;
func_t csqc_shutdown_function;
func_t csqc_draw_function;
func_t csqc_keydown_function;
func_t csqc_keyup_function;
func_t csqc_parse_stuffcmd;
func_t csqc_parse_centerprint;
float *csqc_time;
int COM_FileSize(char *path);
@ -962,23 +1215,8 @@ void CSQC_Shutdown(void)
Con_Printf("Closed csqc\n");
}
csqcprogs = NULL;
}
void CSQC_FindGlobals(void)
{
csqc_time = (float*)PR_FindGlobal(csqcprogs, "time", 0);
if (csqc_time)
*csqc_time = Sys_DoubleTime();
csqc_init_function = PR_FindFunction(csqcprogs, "CSQC_Init", PR_ANY);
csqc_shutdown_function = PR_FindFunction(csqcprogs, "CSQC_Shutdown", PR_ANY);
csqc_draw_function = PR_FindFunction(csqcprogs, "CSQC_UpdateView", PR_ANY);
csqc_keydown_function = PR_FindFunction(csqcprogs, "CSQC_KeyDown", PR_ANY);
csqc_keyup_function = PR_FindFunction(csqcprogs, "CSQC_KeyUp", PR_ANY);
csqc_parse_stuffcmd = PR_FindFunction(csqcprogs, "CSQC_Parse_StuffCmd", PR_ANY);
csqc_parse_centerprint = PR_FindFunction(csqcprogs, "CSQC_Parse_CenterPrint", PR_ANY);
in_sensitivityscale = 1;
}
double csqctime;
@ -1001,7 +1239,7 @@ void CSQC_Init (void)
csqcprogparms.printf = (void *)Con_Printf;//Con_Printf;//void (*printf) (char *, ...);
csqcprogparms.Sys_Error = Sys_Error;
csqcprogparms.Abort = CSQC_Abort;
csqcprogparms.edictsize = sizeof(csqcedict_t);
csqcprogparms.edictsize = sizeof(csqcedict_t)-sizeof(csqcentvars_t);
csqcprogparms.entspawn = NULL;//void (*entspawn) (struct edict_s *ent); //ent has been spawned, but may not have all the extra variables (that may need to be set) set
csqcprogparms.entcanfree = NULL;//bool (*entcanfree) (struct edict_s *ent); //return true to stop ent from being freed
@ -1033,6 +1271,7 @@ void CSQC_Init (void)
csqctime = Sys_DoubleTime();
if (!csqcprogs)
{
in_sensitivityscale = 1;
csqcprogs = InitProgs(&csqcprogparms);
PR_Configure(csqcprogs, NULL, -1, 1);
@ -1049,17 +1288,20 @@ void CSQC_Init (void)
CSQC_Shutdown();
return;
}
memset(csqcent, 0, sizeof(csqcent));
csqcentsize = PR_InitEnts(csqcprogs, 3072);
CSQC_FindGlobals();
ED_Alloc(csqcprogs); //we need a word entity.
//world edict becomes readonly
EDICT_NUM(csqcprogs, 0)->readonly = true;
EDICT_NUM(csqcprogs, 0)->isfree = false;
if (csqc_init_function)
PR_ExecuteProgram(csqcprogs, csqc_init_function);
if (csqcg.init_function)
PR_ExecuteProgram(csqcprogs, csqcg.init_function);
Con_Printf("Loaded csqc\n");
}
@ -1067,7 +1309,7 @@ void CSQC_Init (void)
qboolean CSQC_DrawView(void)
{
if (!csqc_draw_function || !csqcprogs)
if (!csqcg.draw_function || !csqcprogs)
return false;
r_secondaryview = 0;
@ -1075,7 +1317,10 @@ qboolean CSQC_DrawView(void)
if (cl.worldmodel)
R_LessenStains();
PR_ExecuteProgram(csqcprogs, csqc_draw_function);
if (csqcg.time)
*csqcg.time = Sys_DoubleTime();
PR_ExecuteProgram(csqcprogs, csqcg.draw_function);
return true;
}
@ -1084,7 +1329,7 @@ qboolean CSQC_StuffCmd(char *cmd)
{
void *pr_globals;
char *str;
if (!csqcprogs || !csqc_parse_stuffcmd)
if (!csqcprogs || !csqcg.parse_stuffcmd)
return false;
str = PF_TempStr();
@ -1093,14 +1338,14 @@ qboolean CSQC_StuffCmd(char *cmd)
pr_globals = PR_globals(csqcprogs, PR_CURRENT);
(*(char **)&((int *)pr_globals)[OFS_PARM0] = PR_SetString(csqcprogs, str));
PR_ExecuteProgram (csqcprogs, csqc_parse_stuffcmd);
PR_ExecuteProgram (csqcprogs, csqcg.parse_stuffcmd);
return true;
}
qboolean CSQC_CenterPrint(char *cmd)
{
void *pr_globals;
char *str;
if (!csqcprogs || !csqc_parse_centerprint)
if (!csqcprogs || !csqcg.parse_centerprint)
return false;
str = PF_TempStr();
@ -1109,19 +1354,25 @@ qboolean CSQC_CenterPrint(char *cmd)
pr_globals = PR_globals(csqcprogs, PR_CURRENT);
(*(char **)&((int *)pr_globals)[OFS_PARM0] = PR_SetString(csqcprogs, str));
PR_ExecuteProgram (csqcprogs, csqc_parse_centerprint);
PR_ExecuteProgram (csqcprogs, csqcg.parse_centerprint);
return G_FLOAT(OFS_RETURN);
}
//this protocol allows up to 32767 edicts.
#ifdef PEXT_CSQC
void CSQC_ParseEntities(void)
{
/*
csqcedict_t *ent;
unsigned short entnum;
void *pr_globals;
if (!csqcprogs)
Host_EndGame
Host_EndGame("CSQC needs to be initialized on this server.\n");
pr_globals = PR_globals(csqcprogs, PR_CURRENT);
if (csqcg.time)
*csqcg.time = Sys_DoubleTime();
for(;;)
{
@ -1133,36 +1384,41 @@ void CSQC_ParseEntities(void)
entnum &= ~0x8000;
if (!entnum)
{
Con_Printf("CSQC cannot remove world!\n");
continue;
}
Host_EndGame("CSQC cannot remove world!\n");
if (entnum >= MAX_EDICTS)
Host_EndGame("CSQC recieved too many edicts!\n");
ent = csqcent[entnum];
if (!ent) //hrm.
continue;
*csqc_globals->self = EDICT_TO_PROG(svprogfuncs, ent);
PR_ExecuteProgram(csqcprogs, csqc_ent_remove);
*csqcg.self = EDICT_TO_PROG(csqcprogs, (void*)ent);
PR_ExecuteProgram(csqcprogs, csqcg.ent_remove);
csqcent[entnum] = NULL;
//the csqc is expected to call the remove builtin.
}
else
{
if (entnum >= MAX_EDICTS)
Host_EndGame("CSQC recieved too many edicts!\n");
ent = csqcent[entnum];
if (!ent)
{
ent = ED_Alloc(csqcprogs);
ent = (csqcedict_t*)ED_Alloc(csqcprogs);
csqcent[entnum] = ent;
G_FLOAT(OFS_PARM0) = true;
}
else
G_FLOAT(OFS_PARM0) = false;
*csqc_globals->self = EDICT_TO_PROG(svprogfuncs, ent);
PR_ExecuteProgram(csqcprogs, csqc_ent_update);
*csqcg.self = EDICT_TO_PROG(csqcprogs, (void*)ent);
PR_ExecuteProgram(csqcprogs, csqcg.ent_update);
}
}*/
}
}
#endif
#endif

View File

@ -428,14 +428,14 @@ void PF_nonfatalobjerror (progfuncs_t *prinst, struct globalvars_s *pr_globals)
s = PF_VarString(prinst, 0, pr_globals);
prinst->PR_StackTrace(prinst);
PR_StackTrace(prinst);
selfp = prinst->FindGlobal(prinst, "self", PR_CURRENT);
selfp = PR_FindGlobal(prinst, "self", PR_CURRENT);
if (selfp && selfp->_int)
{
ed = PROG_TO_EDICT(prinst, selfp->_int);
prinst->PR_PrintEdict(prinst, ed);
PR_PrintEdict(prinst, ed);
if (developer.value)
@ -471,7 +471,7 @@ static void PF_Fixme (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
Con_Printf("\n");
prinst->PR_RunError(prinst, "\nBuiltin %i not implemented.\nMenu is not compatable.", prinst->lastcalledbuiltinnumber);
prinst->RunError(prinst, "\nBuiltin %i not implemented.\nMenu is not compatable.", prinst->lastcalledbuiltinnumber);
PR_BIError (prinst, "bulitin not implemented");
}
@ -772,19 +772,19 @@ void PF_getmousepos (progfuncs_t *prinst, struct globalvars_s *pr_globals)
}
void PF_Remove_ (progfuncs_t *prinst, struct globalvars_s *pr_globals)
static void PF_Remove_ (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
void *ed;
menuedict_t *ed;
ed = G_EDICT(prinst, OFS_PARM0);
/*
ed = (void*)G_EDICT(prinst, OFS_PARM0);
if (ed->isfree)
{
Con_DPrintf("Tried removing free entity\n");
return;
}
*/
ED_Free (prinst, ed);
ED_Free (prinst, (void*)ed);
}
static void PF_CopyEntity (progfuncs_t *prinst, struct globalvars_s *pr_globals)

View File

@ -21,6 +21,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "bothdefs.h" //first thing included by ALL files.
#pragma message("blah")
#if _MSC_VER
#define MSVCDISABLEWARNINGS
@ -73,6 +74,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#pragma warning(3:4673) // thrown object cannot be handled in catch block
#pragma warning(3:4674) // dtor of thrown object is inaccessible
#pragma warning(3:4705) // statement has no effect (example: a+1;)
#pragma warning( 4 : 4267) //truncation from const double to float
#endif
@ -89,6 +93,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifdef SERVERONLY
#define isDedicated true
#endif
#ifdef CLIENTONLY
#define isDedicated false
#endif
#ifdef __linux__
#define PNG_SUCKS_WITH_SETJMP //cos it does.

View File

@ -1359,6 +1359,8 @@ qboolean R_ApplyRenderer (rendererstate_t *newr)
if (newr->bpp == -1)
return false;
CL_AllowIndependantSendCmd(false); //FIXME: figure out exactly which parts are going to affect the model loading.
IN_Shutdown();
if (R_DeInit)

View File

@ -20,14 +20,13 @@
* Tim Ferguson: http://www.csse.monash.edu.au/~timf/
* ------------------------------------------------------------------------ */
#include "bothdefs.h"
#include "quakedef.h"
#ifndef NOMEDIA
//#include <stdio.h>
//#include <stdlib.h>
//#include <string.h>
#include "quakedef.h"
#include "roq.h"
//#define DBUG 1

View File

@ -1896,8 +1896,7 @@ void Sbar_DeathmatchOverlay (int start)
)
{
cl.last_ping_request = realtime;
MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
SZ_Print (&cls.netchan.message, "pings");
CL_SendClientCommand("pings");
}
scr_copyeverything = 1;
@ -2056,8 +2055,7 @@ void Sbar_ChatModeOverlay(void)
)
{
cl.last_ping_request = realtime;
MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
SZ_Print (&cls.netchan.message, "pings");
CL_SendClientCommand("pings");
}
scr_copyeverything = 1;

View File

@ -494,9 +494,7 @@ void Skin_NextDownload (void)
#ifdef CSQC_DAT
CSQC_Init();
#endif
MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
MSG_WriteString (&cls.netchan.message,
va("begin %i", cl.servercount));
CL_SendClientCommand("begin %i", cl.servercount);
Cache_Report (); // print remaining memory
}
}

View File

@ -19,10 +19,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// snd_dma.c -- main control for any streaming sound output devices
#ifndef __CYGWIN__
#include "quakedef.h"
#ifndef __CYGWIN__
#ifdef _WIN32
#include "winquake.h"
#endif

View File

@ -19,10 +19,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// snd_mem.c: sound caching
#ifndef __CYGWIN__
#include "quakedef.h"
#ifndef __CYGWIN__
#include "winquake.h"
int cache_full_cycle;

View File

@ -19,10 +19,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// snd_mix.c -- portable code to mix sounds for snd_dma.c
#ifndef __CYGWIN__
#include "quakedef.h"
#ifndef __CYGWIN__
#ifndef NOSOUNDASM
#define NOSOUNDASM //since channels per sound card went to 6 (portable_samplegroup_t was changed)
#endif

View File

@ -196,9 +196,11 @@ Handles both say and say_team
void CL_Say_f (void)
{
char output[8192];
char string[256];
char *msg;
int c;
output[0] = '\0';
if (cls.state == ca_disconnected || cls.demoplayback)
{
#ifndef CLIENT_ONLY
@ -219,21 +221,17 @@ void CL_Say_f (void)
}
}
MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
Q_strncpyz(string, Cmd_Argv(0), sizeof(string));
for (msg = string; *msg; msg++)
Q_strncpyz(output, Cmd_Argv(0), sizeof(string));
for (msg = output; *msg; msg++)
if (*msg >= 'A' && *msg <= 'Z')
*msg = *msg - 'A' + 'a';
SZ_Print (&cls.netchan.message, string);
cls.netchan.message.cursize--;
msg = Cmd_Args();
if (Cmd_Argc() > 1)
{
SZ_Print (&cls.netchan.message," ");
cls.netchan.message.cursize--;
MSG_WriteChar(&cls.netchan.message, '\"');
Q_strncatz(output, " \"", sizeof(output));
while(*msg)
{
c = *msg;
@ -247,40 +245,29 @@ void CL_Say_f (void)
switch(*msg)
{
case 'n':
SZ_Print(&cls.netchan.message, name.string);
cls.netchan.message.cursize--;
Q_strncatz(output, name.string, sizeof(output));
msg++;
continue;
case 'h':
SZ_Print(&cls.netchan.message, va("%i", cl.stats[0][STAT_HEALTH]));
cls.netchan.message.cursize--; //remove the null term
Q_strncatz(output, va("%i", cl.stats[0][STAT_HEALTH]), sizeof(output));
msg++;
continue;
case 'a':
SZ_Print(&cls.netchan.message, va("%i", cl.stats[0][STAT_ARMOR]));
cls.netchan.message.cursize--;
Q_strncatz(output, va("%i", cl.stats[0][STAT_ARMOR]), sizeof(output));
msg++;
continue;
case 'A':
SZ_Print(&cls.netchan.message, TP_ArmourType());
cls.netchan.message.cursize--;
Q_strncatz(output, TP_ArmourType(), sizeof(output));
msg++;
continue;
case 'l':
SZ_Print(&cls.netchan.message, CL_LocationName(r_refdef.vieworg));
cls.netchan.message.cursize--;
Q_strncatz(output, CL_LocationName(cl.simorg[0]), sizeof(output));
msg++;
continue;
case 'S':
SZ_Print(&cls.netchan.message, TP_ClassForTFSkin());
cls.netchan.message.cursize--;
Q_strncatz(output, TP_ClassForTFSkin(), sizeof(output));
msg++;
continue;
case '\0': //whoops.
MSG_WriteChar(&cls.netchan.message, '%');
MSG_WriteChar(&cls.netchan.message, '\"');
MSG_WriteChar(&cls.netchan.message, *msg);
return;
case '%':
c = '%';
break;
@ -333,14 +320,14 @@ void CL_Say_f (void)
}
MSG_WriteChar(&cls.netchan.message, c);
Q_strncatz(output, va("%c", c), sizeof(output));
msg++;
}
MSG_WriteChar(&cls.netchan.message, '\"');
Q_strncatz(output, "\"", sizeof(output));
}
MSG_WriteChar(&cls.netchan.message, '\0');
CL_SendClientCommand("%s", output);
}
void TP_Init(void)

View File

@ -488,7 +488,7 @@ void Editor_Key(int key)
break;
case K_F6:
if (editprogfuncs)
editprogfuncs->PR_StackTrace(editprogfuncs);
PR_StackTrace(editprogfuncs);
break;
case K_F7:
EditorSaveFile(OpenEditorFile);

View File

@ -1436,6 +1436,8 @@ void V_RenderView (void)
if (cl.worldmodel)
{
CL_AllowIndependantSendCmd(false);
//work out which packet entities are solid
CL_SetSolidEntities ();
@ -1450,6 +1452,8 @@ void V_RenderView (void)
// build a refresh entity list
CL_EmitEntities ();
CL_AllowIndependantSendCmd(true);
}
view_frame = &cl.frames[cls.netchan.incoming_sequence & UPDATE_MASK];

View File

@ -33,3 +33,4 @@ void GLV_UpdatePalette (void);
void SWV_UpdatePalette (void);
qboolean V_CheckGamma (void);
void V_AddEntity(entity_t *in);
void V_AddLight (vec3_t org, float quant, float r, float g, float b);

View File

@ -19,6 +19,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// winquake.h: Win32-specific Quake header file
#ifndef WINQUAKE_H
#define WINQUAKE_H
#ifdef _WIN32
#if defined(_WIN32) && !defined(WIN32)
@ -196,3 +199,5 @@ struct hostent FAR * (PASCAL FAR *pgethostbyaddr)(const char FAR * addr,
int (PASCAL FAR *pgetsockname)(SOCKET s, struct sockaddr FAR *name,
int FAR * namelen);
#endif
#endif

View File

@ -29,10 +29,9 @@
//TP_SearchForMsgTriggers: should only allow safe commands. work out what the meaning of safe commands is.
#include "bothdefs.h"
#include "quakedef.h"
#if 1 //def ZQUAKETEAMPLAY
#include "quakedef.h"
//#include "version.h"
#include "sound.h"
//#include "pmove.h"
@ -55,8 +54,6 @@ typedef qboolean qbool;
*/
#define Q_rint(f) ((int)((f)+0.5))
void Cmd_AddMacro(char *s, char *(*f)(void));
#ifndef HAVE_STRLCAT
static size_t strlcat (char *dst, const char *src, size_t size)
{
@ -99,56 +96,68 @@ static void VARGS Q_snprintfz (char *dest, size_t size, char *fmt, ...)
dest[size-1] = 0;
}
cvar_t cl_fakename = {"cl_fakename", ""};
//a list of all the cvars
//this is down to the fact that I keep defining them but forgetting to register. :/
#define TP_CVARS \
TP_CVAR(cl_fakename, ""); \
TP_CVAR(cl_parseSay, "1"); \
TP_CVAR(cl_parseFunChars, "1"); \
TP_CVAR(cl_triggers, "1"); \
TP_CVAR(tp_forceTriggers, "0"); \
TP_CVAR(tp_loadlocs, "1"); \
TP_CVAR(cl_teamskin, ""); \
TP_CVAR(cl_enemyskin, ""); \
TP_CVAR(tp_soundtrigger, "~"); \
\
TP_CVAR(tp_name_none, ""); \
TP_CVAR(tp_name_axe, "axe"); \
TP_CVAR(tp_name_sg, "sg"); \
TP_CVAR(tp_name_ssg, "ssg"); \
TP_CVAR(tp_name_ng, "ng"); \
TP_CVAR(tp_name_sng, "sng"); \
TP_CVAR(tp_name_gl, "gl"); \
TP_CVAR(tp_name_rl, "rl"); \
TP_CVAR(tp_name_lg, "lg"); \
TP_CVAR(tp_name_ra, "ra"); \
TP_CVAR(tp_name_ya, "ya"); \
TP_CVAR(tp_name_ga, "ga"); \
TP_CVAR(tp_name_quad, "quad"); \
TP_CVAR(tp_name_pent, "pent"); \
TP_CVAR(tp_name_ring, "ring"); \
TP_CVAR(tp_name_suit, "suit"); \
TP_CVAR(tp_name_shells, "shells"); \
TP_CVAR(tp_name_nails, "nails"); \
TP_CVAR(tp_name_rockets, "rockets"); \
TP_CVAR(tp_name_cells, "cells"); \
TP_CVAR(tp_name_mh, "mega"); \
TP_CVAR(tp_name_health, "health"); \
TP_CVAR(tp_name_backpack, "pack"); \
TP_CVAR(tp_name_flag, "flag"); \
TP_CVAR(tp_name_nothing, "nothing"); \
TP_CVAR(tp_name_someplace, "someplace"); \
TP_CVAR(tp_name_at, "at"); \
TP_CVAR(tp_need_ra, "50"); \
TP_CVAR(tp_need_ya, "50"); \
TP_CVAR(tp_need_ga, "50"); \
TP_CVAR(tp_need_health, "50"); \
TP_CVAR(tp_need_weapon, "35687"); \
TP_CVAR(tp_need_rl, "1"); \
TP_CVAR(tp_need_rockets, "5"); \
TP_CVAR(tp_need_cells, "20"); \
TP_CVAR(tp_need_nails, "40"); \
TP_CVAR(tp_need_shells, "10"); \
TP_CVAR(tp_name_disp, "dispenser"); \
TP_CVAR(tp_name_sentry, "sentry gun"); \
TP_CVAR(tp_name_rune_1, "resistance rune"); \
TP_CVAR(tp_name_rune_2, "strength rune"); \
TP_CVAR(tp_name_rune_3, "haste rune"); \
TP_CVAR(tp_name_rune_4, "regeneration rune")
cvar_t cl_parseSay = {"cl_parseSay", "1"};
cvar_t cl_parseFunChars = {"cl_parseFunChars", "1"};
cvar_t cl_triggers = {"cl_triggers", "0"};
cvar_t tp_forceTriggers = {"tp_forceTriggers", "0"};
cvar_t tp_loadlocs = {"tp_loadlocs", "1"};
cvar_t cl_teamskin = {"teamskin", ""};
cvar_t cl_enemyskin = {"enemyskin", ""};
cvar_t tp_soundtrigger = {"tp_soundtrigger", "~"};
cvar_t tp_name_axe = {"tp_name_axe", "axe"};
cvar_t tp_name_sg = {"tp_name_sg", "sg"};
cvar_t tp_name_ssg = {"tp_name_ssg", "ssg"};
cvar_t tp_name_ng = {"tp_name_ng", "ng"};
cvar_t tp_name_sng = {"tp_name_sng", "sng"};
cvar_t tp_name_gl = {"tp_name_gl", "gl"};
cvar_t tp_name_rl = {"tp_name_rl", "rl"};
cvar_t tp_name_lg = {"tp_name_lg", "lg"};
cvar_t tp_name_ra = {"tp_name_ra", "ra"};
cvar_t tp_name_ya = {"tp_name_ya", "ya"};
cvar_t tp_name_ga = {"tp_name_ga", "ga"};
cvar_t tp_name_quad = {"tp_name_quad", "quad"};
cvar_t tp_name_pent = {"tp_name_pent", "pent"};
cvar_t tp_name_ring = {"tp_name_ring", "ring"};
cvar_t tp_name_suit = {"tp_name_suit", "suit"};
cvar_t tp_name_shells = {"tp_name_shells", "shells"};
cvar_t tp_name_nails = {"tp_name_nails", "nails"};
cvar_t tp_name_rockets = {"tp_name_rockets", "rockets"};
cvar_t tp_name_cells = {"tp_name_cells", "cells"};
cvar_t tp_name_mh = {"tp_name_mh", "mega"};
cvar_t tp_name_health = {"tp_name_health", "health"};
cvar_t tp_name_backpack = {"tp_name_backpack", "pack"};
cvar_t tp_name_flag = {"tp_name_flag", "flag"};
cvar_t tp_name_nothing = {"tp_name_nothing", "nothing"};
cvar_t tp_name_someplace = {"tp_name_someplace", "someplace"};
cvar_t tp_name_at = {"tp_name_at", "at"};
cvar_t tp_need_ra = {"tp_need_ra", "50"};
cvar_t tp_need_ya = {"tp_need_ya", "50"};
cvar_t tp_need_ga = {"tp_need_ga", "50"};
cvar_t tp_need_health = {"tp_need_health", "50"};
cvar_t tp_need_weapon = {"tp_need_weapon", "35687"};
cvar_t tp_need_rl = {"tp_need_rl", "1"};
cvar_t tp_need_rockets = {"tp_need_rockets", "5"};
cvar_t tp_need_cells = {"tp_need_cells", "20"};
cvar_t tp_need_nails = {"tp_need_nails", "40"};
cvar_t tp_need_shells = {"tp_need_shells", "10"};
//create the globals for all the TP cvars.
#define TP_CVAR(name,def) cvar_t name = {#name, def}
TP_CVARS;
#undef TP_CVAR
extern cvar_t host_mapname;
@ -178,6 +187,7 @@ typedef struct tvars_s {
char pointname[32];
vec3_t pointorg;
char pointloc[MAX_LOC_NAME];
int droppedweapon;
} tvars_t;
tvars_t vars;
@ -292,42 +302,51 @@ static char *Macro_Ammo (void)
return macro_buf;
}
static char *Weapon_NumToString (int wnum)
{
switch (wnum)
{
case IT_AXE: return tp_name_axe.string;
case IT_SHOTGUN: return tp_name_sg.string;
case IT_SUPER_SHOTGUN: return tp_name_ssg.string;
case IT_NAILGUN: return tp_name_ng.string;
case IT_SUPER_NAILGUN: return tp_name_sng.string;
case IT_GRENADE_LAUNCHER: return tp_name_gl.string;
case IT_ROCKET_LAUNCHER: return tp_name_rl.string;
case IT_LIGHTNING: return tp_name_lg.string;
default: return tp_name_none.string;
}
}
static char *Macro_Weapon (void)
{
switch (cl.stats[SP][STAT_ACTIVEWEAPON])
{
case IT_AXE: return "axe";
case IT_SHOTGUN: return "sg";
case IT_SUPER_SHOTGUN: return "ssg";
case IT_NAILGUN: return "ng";
case IT_SUPER_NAILGUN: return "sng";
case IT_GRENADE_LAUNCHER: return "gl";
case IT_ROCKET_LAUNCHER: return "rl";
case IT_LIGHTNING: return "lg";
default:
return "";
}
return Weapon_NumToString(cl.stats[SP][STAT_ACTIVEWEAPON]);
}
static char *Macro_DroppedWeapon (void)
{
return Weapon_NumToString(vars.droppedweapon);
}
static char *Macro_Weapons (void) {
macro_buf[0] = 0;
if (cl.stats[SP][STAT_ITEMS] & IT_LIGHTNING)
strcpy(macro_buf, "lg");
strcpy(macro_buf, tp_name_lg.string);
if (cl.stats[SP][STAT_ITEMS] & IT_ROCKET_LAUNCHER)
MacroBuf_strcat_with_separator ("rl");
MacroBuf_strcat_with_separator (tp_name_rl.string);
if (cl.stats[SP][STAT_ITEMS] & IT_GRENADE_LAUNCHER)
MacroBuf_strcat_with_separator ("gl");
MacroBuf_strcat_with_separator (tp_name_gl.string);
if (cl.stats[SP][STAT_ITEMS] & IT_SUPER_NAILGUN)
MacroBuf_strcat_with_separator ("sng");
MacroBuf_strcat_with_separator (tp_name_sng.string);
if (cl.stats[SP][STAT_ITEMS] & IT_NAILGUN)
MacroBuf_strcat_with_separator ("ng");
MacroBuf_strcat_with_separator (tp_name_ng.string);
if (cl.stats[SP][STAT_ITEMS] & IT_SUPER_SHOTGUN)
MacroBuf_strcat_with_separator ("ssg");
MacroBuf_strcat_with_separator (tp_name_ssg.string);
if (cl.stats[SP][STAT_ITEMS] & IT_SHOTGUN)
MacroBuf_strcat_with_separator ("sg");
MacroBuf_strcat_with_separator (tp_name_sg.string);
if (cl.stats[SP][STAT_ITEMS] & IT_AXE)
MacroBuf_strcat_with_separator ("axe");
MacroBuf_strcat_with_separator (tp_name_axe.string);
// if (!macro_buf[0])
// strlcpy(macro_buf, tp_name_none.string, sizeof(macro_buf));
@ -383,19 +402,7 @@ static int _Macro_BestWeapon (void)
static char *Macro_BestWeapon (void)
{
switch (_Macro_BestWeapon())
{
case IT_AXE: return "axe";
case IT_SHOTGUN: return "sg";
case IT_SUPER_SHOTGUN: return "ssg";
case IT_NAILGUN: return "ng";
case IT_SUPER_NAILGUN: return "sng";
case IT_GRENADE_LAUNCHER: return "gl";
case IT_ROCKET_LAUNCHER: return "rl";
case IT_LIGHTNING: return "lg";
default:
return "";
}
return Weapon_NumToString(_Macro_BestWeapon());
}
static char *Macro_BestAmmo (void)
@ -490,6 +497,7 @@ static char *Macro_LastDeath (void)
return tp_name_someplace.string;
}
static char *Macro_Location2 (void)
{
if (vars.deathtrigger_time && realtime - vars.deathtrigger_time <= 5)
@ -838,48 +846,50 @@ $triggermatch is the last chat message that exec'd a msg_trigger.
static void TP_InitMacros(void)
{
Cmd_AddMacro("qt", Macro_Quote);
Cmd_AddMacro("latency", Macro_Latency);
Cmd_AddMacro("health", Macro_Health);
Cmd_AddMacro("armortype", Macro_ArmorType);
Cmd_AddMacro("armor", Macro_Armor);
Cmd_AddMacro("shells", Macro_Shells);
Cmd_AddMacro("nails", Macro_Nails);
Cmd_AddMacro("rockets", Macro_Rockets);
Cmd_AddMacro("cells", Macro_Cells);
Cmd_AddMacro("weaponnum", Macro_WeaponNum);
Cmd_AddMacro("weapons", Macro_Weapons);
Cmd_AddMacro("weapon", Macro_Weapon);
Cmd_AddMacro("ammo", Macro_Ammo);
Cmd_AddMacro("bestweapon", Macro_BestWeapon);
Cmd_AddMacro("bestammo", Macro_BestAmmo);
Cmd_AddMacro("powerups", Macro_Powerups);
Cmd_AddMacro("location", Macro_Location);
Cmd_AddMacro("deathloc", Macro_LastDeath);
Cmd_AddMacro("time", Macro_Time);
Cmd_AddMacro("date", Macro_Date);
Cmd_AddMacro("tookatloc", Macro_TookAtLoc);
Cmd_AddMacro("tookloc", Macro_TookLoc);
Cmd_AddMacro("took", Macro_Took);
Cmd_AddMacro("tf_skin", Macro_TF_Skin);
Cmd_AddMacro("qt", Macro_Quote, false);
Cmd_AddMacro("latency", Macro_Latency, false);
Cmd_AddMacro("health", Macro_Health, true);
Cmd_AddMacro("armortype", Macro_ArmorType, true);
Cmd_AddMacro("armor", Macro_Armor, true);
Cmd_AddMacro("shells", Macro_Shells, true);
Cmd_AddMacro("nails", Macro_Nails, true);
Cmd_AddMacro("rockets", Macro_Rockets, true);
Cmd_AddMacro("cells", Macro_Cells, true);
Cmd_AddMacro("weaponnum", Macro_WeaponNum, true);
Cmd_AddMacro("weapons", Macro_Weapons, true);
Cmd_AddMacro("weapon", Macro_Weapon, true);
Cmd_AddMacro("ammo", Macro_Ammo, true);
Cmd_AddMacro("bestweapon", Macro_BestWeapon, true);
Cmd_AddMacro("bestammo", Macro_BestAmmo, true);
Cmd_AddMacro("powerups", Macro_Powerups, true);
Cmd_AddMacro("location", Macro_Location, false);
Cmd_AddMacro("deathloc", Macro_LastDeath, true);
Cmd_AddMacro("time", Macro_Time, true);
Cmd_AddMacro("date", Macro_Date, false);
Cmd_AddMacro("tookatloc", Macro_TookAtLoc, true);
Cmd_AddMacro("tookloc", Macro_TookLoc, true);
Cmd_AddMacro("took", Macro_Took, true);
Cmd_AddMacro("tf_skin", Macro_TF_Skin, true);
Cmd_AddMacro("droppedweapon", Macro_DroppedWeapon, true);
//ones added by Spike, for fuhquake compatability
Cmd_AddMacro("connectiontype", Macro_ConnectionType);
Cmd_AddMacro("demoplayback", Macro_demoplayback);
Cmd_AddMacro("need", Macro_Need);
Cmd_AddMacro("point", Macro_PointName);
Cmd_AddMacro("pointatloc", Macro_PointNameAtLocation);
Cmd_AddMacro("pointloc", Macro_PointLocation);
Cmd_AddMacro("matchname", Macro_Match_Name);
Cmd_AddMacro("matchtype", Macro_Match_Type);
Cmd_AddMacro("connectiontype", Macro_ConnectionType, false);
Cmd_AddMacro("demoplayback", Macro_demoplayback, false);
Cmd_AddMacro("need", Macro_Need, true);
Cmd_AddMacro("point", Macro_PointName, true);
Cmd_AddMacro("pointatloc", Macro_PointNameAtLocation, true);
Cmd_AddMacro("pointloc", Macro_PointLocation, true);
Cmd_AddMacro("matchname", Macro_Match_Name, false);
Cmd_AddMacro("matchtype", Macro_Match_Type, false);
// Cmd_AddMacro("droploc", Macro_LastDrop);
// Cmd_AddMacro("droptime", Macro_LastDropTime);
// Cmd_AddMacro("ledpoint", Macro_Point_LED);
// Cmd_AddMacro("ledstatus", Macro_MyStatus_LED);
// Cmd_AddMacro("matchstatus", Macro_Match_Status);
// Cmd_AddMacro("mp3info", );
// Cmd_AddMacro("triggermatch", Macro_LastTrigger_Match);
// Cmd_AddMacro("droploc", Macro_LastDrop, true);
// Cmd_AddMacro("droptime", Macro_LastDropTime, true);
// Cmd_AddMacro("ledpoint", Macro_Point_LED, true);
// Cmd_AddMacro("ledstatus", Macro_MyStatus_LED, true);
// Cmd_AddMacro("matchstatus", Macro_Match_Status, false);
// Cmd_AddMacro("mp3info", , false);
// Cmd_AddMacro("triggermatch", Macro_LastTrigger_Match, false);
}
#define MAX_MACRO_STRING 1024
@ -1665,7 +1675,8 @@ int TP_CategorizeMessage (char *s, int *offset)
// symbolic names used in tp_took, tp_pickup, tp_point commands
static char *pknames[] = {"quad", "pent", "ring", "suit", "ra", "ya", "ga",
"mh", "health", "lg", "rl", "gl", "sng", "ng", "ssg", "pack",
"cells", "rockets", "nails", "shells", "flag", "pointed"};
"cells", "rockets", "nails", "shells", "flag", "pointed",
"sentry", "disp", "runes"};
#define it_quad (1<<0)
#define it_pent (1<<1)
@ -1689,7 +1700,10 @@ static char *pknames[] = {"quad", "pent", "ring", "suit", "ra", "ya", "ga",
#define it_shells (1<<19)
#define it_flag (1<<20)
#define it_pointed (1<<21) // only valid for tp_took
#define NUM_ITEMFLAGS 22
#define it_sentry (1 << 22)
#define it_disp (1 << 23)
#define it_runes (1 << 24)
#define NUM_ITEMFLAGS 25
#define it_powerups (it_quad|it_pent|it_ring)
#define it_weapons (it_lg|it_rl|it_gl|it_sng|it_ng|it_ssg)
@ -1926,8 +1940,46 @@ static item_t tp_items[] = {
},
{ it_ra|it_ya|it_ga, NULL, "progs/armor.mdl",
{0, 0, 24}, 22,
},
{ it_flag, &tp_name_flag, "progs/w_g_key.mdl",
{0, 0, 20}, 18,
},
{ it_flag, &tp_name_flag, "progs/w_s_key.mdl",
{0, 0, 20}, 18,
},
{ it_flag, &tp_name_flag, "progs/m_g_key.mdl",
{0, 0, 20}, 18,
},
{ it_flag, &tp_name_flag, "progs/m_s_key.mdl",
{0, 0, 20}, 18,
},
{ it_flag, &tp_name_flag, "progs/b_s_key.mdl",
{0, 0, 20}, 18,
},
{ it_flag, &tp_name_flag, "progs/b_g_key.mdl",
{0, 0, 20}, 18,
},
{ it_flag, &tp_name_flag, "progs/flag.mdl",
{0, 0, 14}, 25,
},
{ it_runes, &tp_name_rune_1, "progs/end1.mdl",
{0, 0, 20}, 18,
},
{ it_runes, &tp_name_rune_2, "progs/end2.mdl",
{0, 0, 20}, 18,
},
{ it_runes, &tp_name_rune_3, "progs/end3.mdl",
{0, 0, 20}, 18,
},
{ it_runes, &tp_name_rune_4, "progs/end4.mdl",
{0, 0, 20}, 18,
},
{ it_sentry, &tp_name_sentry, "progs/turrgun.mdl",
{0, 0, 23}, 25,
},
{ it_disp, &tp_name_disp, "progs/disp.mdl",
{0, 0, 24}, 25,
}
};
#define NUMITEMS (sizeof(tp_items) / sizeof(tp_items[0]))
@ -2133,22 +2185,11 @@ more:
return;
}
if (!strcmp(s, "items/armor1.wav"))
{
item_t *item;
switch (FindNearestItem (it_armor, &item)) {
case 1: ExecTookTrigger (tp_name_ga.string, it_ga, org); break;
case 2: ExecTookTrigger (tp_name_ya.string, it_ya, org); break;
case 3: ExecTookTrigger (tp_name_ra.string, it_ra, org); break;
}
return;
}
// backpack or ammo
if (!strcmp (s, "weapons/lock4.wav"))
{
item_t *item;
if (!FindNearestItem (it_ammo|it_pack, &item))
if (!FindNearestItem (it_ammo|it_pack|it_runes, &item))
return;
ExecTookTrigger (item->cvar->string, item->itemflag, org);
}
@ -2316,8 +2357,10 @@ void TP_StatChanged (int stat, int value)
if (stat == STAT_HEALTH)
{
if (value > 0) {
if (vars.health <= 0) {
if (value > 0)
{
if (vars.health <= 0)
{
// we just respawned
vars.respawntrigger_time = realtime;
@ -2327,10 +2370,16 @@ void TP_StatChanged (int stat, int value)
vars.health = value;
return;
}
if (vars.health > 0) { // We have just died
if (vars.health > 0)
{ // We have just died
vars.droppedweapon = cl.stats[SP][STAT_ACTIVEWEAPON];
vars.deathtrigger_time = realtime;
strcpy (vars.lastdeathloc, Macro_Location());
if (!cl.spectator && CountTeammates()) {
if (!cl.spectator && CountTeammates())
{
if (cl.teamfortress && (cl.stats[SP][STAT_ITEMS] & (IT_KEY1|IT_KEY2))
&& Cmd_AliasExist("f_flagdeath", RESTRICT_LOCAL))
TP_ExecTrigger ("f_flagdeath");
@ -2549,6 +2598,11 @@ void TP_Init (void)
{
#define TEAMPLAYVARS "Teamplay Variables"
//register all the TeamPlay cvars.
#define TP_CVAR(name,def) Cvar_Register (&name, TEAMPLAYVARS);
TP_CVARS;
#undef TP_CVAR
Cvar_Register (&cl_parseFunChars, TEAMPLAYVARS);
Cvar_Register (&cl_parseSay, TEAMPLAYVARS);
Cvar_Register (&cl_triggers, TEAMPLAYVARS);
@ -2655,22 +2709,7 @@ static void CL_Say (qboolean team, char *extra)
return;
}
#endif
#ifdef Q2CLIENT
MSG_WriteByte (&cls.netchan.message, cls.q2server?clcq2_stringcmd:clc_stringcmd);
#else
MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
#endif
SZ_Print (&cls.netchan.message, team ? "say_team " : "say ");
if (sendtext[0] < 32)
SZ_Print (&cls.netchan.message, "\""); // add quotes so that old servers parse the message correctly
if (extra)
SZ_Print (&cls.netchan.message, extra);
SZ_Print (&cls.netchan.message, sendtext);
if (sendtext[0] < 32)
SZ_Print (&cls.netchan.message, "\""); // add quotes so that old servers parse the message correctly
CL_SendClientCommand("%s \"%s%s\"", team ? "say_team " : "say ", extra?extra:"", sendtext);
}

View File

@ -66,7 +66,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#undef USE_MADLIB //no internal mp3 playing
#undef AVAIL_DX7 //no d3d support
#define NOMEDIA //NO playing of avis/cins/roqs
#define NOVOICECHAT //NO sound recording, tcp streaming and playback on a remote client. not finalised.
#define MD3MODELS //we DO want to use quake3 alias models. This might be a minimal build, but we still want this.
@ -116,7 +115,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define Q3SHADERS
// #define VOICECHAT //experimental
// #define VOICECHAT //not added yet.
//these things were moved to plugins.
//#define IRCCLIENT //connects to irc servers.

View File

@ -45,9 +45,9 @@ typedef struct cmdalias_s
cmdalias_t *cmd_alias;
cvar_t cl_warncmd = {"cl_warncmd", "0"};
cvar_t cl_aliasoverlap = {"cl_aliasoverlap", "1", NULL, CVAR_NOTFROMSERVER};
cvar_t cl_aliasoverlap = {"cl_aliasoverlap", "1", NULL, CVAR_NOTFROMSERVER};
cvar_t tp_disputablemacros = {"tp_disputablemacros", "1", NULL, CVAR_SEMICHEAT};
//=============================================================================
@ -66,17 +66,20 @@ cvar_t cl_aliasoverlap = {"cl_aliasoverlap", "1", NULL, CVAR_NOTFROMSERVER};
typedef struct {
char name[32];
char *(*func) (void);
int disputableintentions;
} macro_command_t;
static macro_command_t macro_commands[MAX_MACROS];
static int macro_count = 0;
void Cmd_AddMacro(char *s, char *(*f)(void))
void Cmd_AddMacro(char *s, char *(*f)(void), int disputableintentions)
{
if (macro_count == MAX_MACROS)
Sys_Error("Cmd_AddMacro: macro_count == MAX_MACROS");
Q_strncpyz(macro_commands[macro_count].name, s, sizeof(macro_commands[macro_count].name));
macro_commands[macro_count++].func = f;
macro_commands[macro_count].func = f;
macro_commands[macro_count].disputableintentions = disputableintentions;
macro_count++;
}
char *TP_MacroString (char *s, int *len)
@ -89,11 +92,13 @@ char *TP_MacroString (char *s, int *len)
macro = &macro_commands[i];
if (!Q_strcasecmp(s, macro->name))
{
if (macro->disputableintentions)
if (!tp_disputablemacros.value)
continue;
if (len)
*len = strlen(macro->name);
return macro->func();
}
macro++;
}
return NULL;
}
@ -1555,17 +1560,10 @@ void Cmd_ForwardToServer (void)
}
#endif
#ifdef Q2CLIENT
MSG_WriteByte (&cls.netchan.message, cls.q2server?clcq2_stringcmd:clc_stringcmd);
#else
MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
#endif
SZ_Print (&cls.netchan.message, Cmd_Argv(0));
if (Cmd_Argc() > 1)
{
SZ_Print (&cls.netchan.message, " ");
SZ_Print (&cls.netchan.message, Cmd_Args());
}
CL_SendClientCommand("%s %s", Cmd_Argv(0), Cmd_Args());
else
CL_SendClientCommand("%s", Cmd_Argv(0));
}
// don't forward the first argument
@ -1585,23 +1583,8 @@ void Cmd_ForwardToServer_f (void)
if (cls.demoplayback)
return; // not really connected
#ifdef Q3CLIENT
if (cls.q2server == 2)
{
CLQ3_SendClientCommand("%s", Cmd_Args());
return;
}
#endif
if (Cmd_Argc() > 1)
{
#ifdef Q2CLIENT
MSG_WriteByte (&cls.netchan.message, cls.q2server?clcq2_stringcmd:clc_stringcmd);
#else
MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
#endif
SZ_Print (&cls.netchan.message, Cmd_Args());
}
CL_SendClientCommand("%s", Cmd_Args());
}
#else
void Cmd_ForwardToServer (void)
@ -2685,6 +2668,8 @@ void Cmd_Init (void)
Cmd_AddCommand ("fs_flush", COM_RefreshFSCache_f);
Cvar_Register(&com_fs_cache, "Filesystem");
Cvar_Register(&tp_disputablemacros, "Teamplay");
#ifndef SERVERONLY
rcon_level.value = atof(rcon_level.string); //client is restricted to not be allowed to change restrictions.
#else

View File

@ -102,6 +102,8 @@ int Cmd_CheckParm (char *parm);
char *Cmd_AliasExist(char *name, int restrictionlevel);
void Alias_WipeStuffedAliaes(void);
void Cmd_AddMacro(char *s, char *(*f)(void), int disputableintentions);
void Cmd_TokenizeString (char *text, qboolean expandmacros, qboolean qctokenize);
// Takes a null terminated string. Does not need to be /n terminated.
// breaks the string up into arg tokens.

View File

@ -19,11 +19,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// common.c -- misc functions used in client and server
#include <ctype.h>
#include "quakedef.h"
#include <ctype.h>
@ -1611,6 +1609,22 @@ skipwhite:
goto skipwhite;
}
}
//skip / * comments
if (c == '/' && data[1] == '*' && !qctokenize)
{
data+=2;
while(*data)
{
if (*data == '*' && data[1] == '/')
{
data+=2;
goto skipwhite;
}
data++;
}
goto skipwhite;
}
// handle quoted strings specially

View File

@ -251,8 +251,7 @@ cvar_t *Cvar_SetCore (cvar_t *var, char *value, qboolean force)
else
#endif
{
MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
SZ_Print (&cls.netchan.message, va("setinfo \"%s\" \"%s\"\n", var->name, value));
CL_SendClientCommand("setinfo \"%s\" \"%s\"\n", var->name, value);
}
}
}
@ -584,10 +583,7 @@ qboolean Cvar_Command (int level)
#ifndef SERVERONLY
if (Cmd_ExecLevel > RESTRICT_SERVER)
{ //directed at a secondary player.
char *msg;
msg = va("%i setinfo %s \"%s\"", Cmd_ExecLevel - RESTRICT_SERVER-1, v->name, str);
MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
MSG_WriteString (&cls.netchan.message, msg);
CL_SendClientCommand("%i setinfo %s \"%s\"", Cmd_ExecLevel - RESTRICT_SERVER-1, v->name, str);
return true;
}

View File

@ -22,10 +22,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
// huff.c - Huffman compression routines for data bitstream
//
#include "bothdefs.h"
#ifdef HUFFNETWORK
#include "quakedef.h"
#ifdef HUFFNETWORK
#define ID_INLINE
#define VALUE(a) (*(int *)&(a))

View File

@ -832,12 +832,36 @@ void ML_ModelViewMatrix(float *modelview, vec3_t viewangles, vec3_t vieworg)
//figure out the current modelview matrix
//I would if some of these, but then I'd still need a couple of copys
Matrix4_Multiply(modelview, Matrix4_NewRotation(-viewangles[2], 1, 0, 0), tempmat); // put Z going up
Matrix4_Multiply(tempmat, Matrix4_NewRotation(-viewangles[0], 0, 1, 0), modelview); // put Z going up
Matrix4_Multiply(modelview, Matrix4_NewRotation(-viewangles[1], 0, 0, 1), tempmat); // put Z going up
Matrix4_Multiply(modelview, Matrix4_NewRotation(-viewangles[2], 1, 0, 0), tempmat);
Matrix4_Multiply(tempmat, Matrix4_NewRotation(-viewangles[0], 0, 1, 0), modelview);
Matrix4_Multiply(modelview, Matrix4_NewRotation(-viewangles[1], 0, 0, 1), tempmat);
Matrix4_Multiply(tempmat, Matrix4_NewTranslation(-vieworg[0], -vieworg[1], -vieworg[2]), modelview); // put Z going up
}
void ML_ModelViewMatrixFromAxis(float *modelview, vec3_t pn, vec3_t right, vec3_t up, vec3_t vieworg)
{
float tempmat[16];
tempmat[ 0] = right[0];
tempmat[ 1] = up[0];
tempmat[ 2] = -pn[0];
tempmat[ 3] = 0;
tempmat[ 4] = right[1];
tempmat[ 5] = up[1];
tempmat[ 6] = -pn[1];
tempmat[ 7] = 0;
tempmat[ 8] = right[2];
tempmat[ 9] = up[2];
tempmat[10] = -pn[2];
tempmat[11] = 0;
tempmat[12] = 0;
tempmat[13] = 0;
tempmat[14] = 0;
tempmat[15] = 1;
Matrix4_Multiply(tempmat, Matrix4_NewTranslation(-vieworg[0], -vieworg[1], -vieworg[2]), modelview); // put Z going up
}
void ML_ProjectionMatrix(float *proj, float wdivh, float fovy)
{

View File

@ -310,7 +310,7 @@ void Netchan_Transmit (netchan_t *chan, int length, qbyte *data, int rate)
// write the packet header
send.data = send_buf;
send.maxsize = MAX_QWMSGLEN + PACKET_HEADER; //dmw wasn't quite true.
send.maxsize = MAX_QWMSGLEN + PACKET_HEADER; //dmw: wasn't quite true.
send.cursize = 0;
w1 = chan->outgoing_sequence | (send_reliable<<31);

View File

@ -719,6 +719,7 @@ void NET_SendPacket (netsrc_t netsrc, int length, void *data, netadr_t to)
if (to.type == NA_LOOPBACK)
{
// if (Cvar_Get("drop", "0", 0, "network debugging")->value)
// if ((rand()&15)==15) //simulate PL
// return;
NET_SendLoopPacket(netsrc, length, data, to);

View File

@ -60,6 +60,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define PEXT_CHUNKEDDOWNLOADS 0x20000000 //alternate file download method. Hopefully it'll give quadroupled download speed, especially on higher pings.
#endif
#ifdef _DEBUG
#ifdef CSQC_DAT
#define PEXT_CSQC 0x40000000 //csqc additions
#endif
#endif
//ZQuake transparent protocol extensions.
@ -236,6 +242,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define svcqw_effect 74 // [vector] org [byte] modelindex [byte] startframe [byte] framecount [byte] framerate
#define svcqw_effect2 75 // [vector] org [short] modelindex [short] startframe [byte] framecount [byte] framerate
#ifdef PEXT_CSQC
#define svc_csqcentities 76 //entity lump for csqc
#endif
#define svc_invalid 256

View File

@ -1,10 +1,9 @@
#include "bothdefs.h"
#include "quakedef.h"
#ifdef EMAILCLIENT
//code to sit on an imap server and check for new emails every now and then.
#include "quakedef.h"
#include "winquake.h"
#ifdef _WIN32

View File

@ -1,4 +1,4 @@
#include "bothdefs.h"
#include "quakedef.h"
#ifdef EMAILCLIENT
@ -9,7 +9,6 @@
//so we have a special state.
#include "quakedef.h"
#include "winquake.h"
#ifdef _WIN32

View File

@ -1,8 +1,7 @@
#include "bothdefs.h"
#include "quakedef.h"
#ifdef EMAILSERVER
#include "quakedef.h"
#include "winquake.h"
//FIXME: the DELE command's effects arn't properly checked.

View File

@ -1,4 +1,4 @@
#include "bothdefs.h"
#include "quakedef.h"
#ifdef EMAILSERVER

File diff suppressed because it is too large Load Diff

View File

@ -356,9 +356,7 @@ static void R_GAliasAddDlights(mesh_t *mesh, vec3_t org, vec3_t angles)
int l, v;
vec3_t rel;
vec3_t dir;
vec3_t axis[3];
float dot, d, a, f;
AngleVectors(angles, axis[0], axis[1], axis[2]);
for (l=0 ; l<MAX_DLIGHTS ; l++)
{
if (cl_dlights[l].radius)
@ -369,9 +367,9 @@ static void R_GAliasAddDlights(mesh_t *mesh, vec3_t org, vec3_t angles)
if (Length(dir)>cl_dlights[l].radius+mesh->radius) //far out man!
continue;
rel[0] = -DotProduct(dir, axis[0]);
rel[1] = DotProduct(dir, axis[1]); //quake's crazy.
rel[2] = -DotProduct(dir, axis[2]);
rel[0] = -DotProduct(dir, currententity->axis[0]);
rel[1] = -DotProduct(dir, currententity->axis[1]); //quake's crazy.
rel[2] = -DotProduct(dir, currententity->axis[2]);
/*
glBegin(GL_LINES);
glVertex3f(0,0,0);
@ -593,7 +591,7 @@ static galiastexnum_t *GL_ChooseSkin(galiasinfo_t *inf, char *modelname, entity_
int tc, bc;
if (gl_nocolors.value)
if (!gl_nocolors.value)
{
if (e->scoreboard)
{
@ -1100,8 +1098,8 @@ void R_DrawGAliasModel (entity_t *e)
currententity = e;
if (e->flags & Q2RF_VIEWERMODEL && e->keynum == cl.playernum[r_refdef.currentplayernum]+1)
return;
// if (e->flags & Q2RF_VIEWERMODEL && e->keynum == cl.playernum[r_refdef.currentplayernum]+1)
// return;
{
extern int cl_playerindex;
@ -1118,9 +1116,9 @@ void R_DrawGAliasModel (entity_t *e)
VectorAdd (e->origin, clmodel->mins, mins);
VectorAdd (e->origin, clmodel->maxs, maxs);
if (!(e->flags & Q2RF_WEAPONMODEL))
if (R_CullBox (mins, maxs))
return;
// if (!(e->flags & Q2RF_WEAPONMODEL))
// if (R_CullBox (mins, maxs))
// return;
if (!(r_refdef.flags & 1)) //RDF_NOWORLDMODEL
{
@ -1221,23 +1219,14 @@ void R_DrawGAliasModel (entity_t *e)
//#define SHOWLIGHTDIR
{ //lightdir is absolute, shadevector is relative
vec3_t entaxis[3];
e->angles[0]*=-1;
AngleVectors(e->angles, entaxis[0], entaxis[1], entaxis[2]);
e->angles[0]*=-1;
entaxis[1][0]*=-1;
entaxis[1][1]*=-1;
entaxis[1][2]*=-1;
shadevector[0] = DotProduct(lightdir, entaxis[0]);
shadevector[1] = DotProduct(lightdir, entaxis[1]);
shadevector[2] = DotProduct(lightdir, entaxis[2]);
shadevector[0] = DotProduct(lightdir, e->axis[0]);
shadevector[1] = DotProduct(lightdir, e->axis[1]);
shadevector[2] = DotProduct(lightdir, e->axis[2]);
VectorNormalize(shadevector);
VectorCopy(shadevector, mesh.lightaxis[2]);
VectorVectors(mesh.lightaxis[2], mesh.lightaxis[1], mesh.lightaxis[0]);
mesh.lightaxis[0][0]*=-1;
mesh.lightaxis[0][1]*=-1;
mesh.lightaxis[0][2]*=-1;
VectorInverse(mesh.lightaxis[1]);
}
/*
an = e->angles[1]/180*M_PI;
@ -2153,12 +2142,11 @@ void GL_LoadQ1Model (model_t *mod, void *buffer)
!strcmp(loadmodel->name, "progs/player.mdl") ? pmodel_name : emodel_name,
st, MAX_INFO_STRING);
if (cls.state >= ca_connected) {
MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
sprintf(st, "setinfo %s %d",
if (cls.state >= ca_connected)
{
CL_SendClientCommand("setinfo %s %d",
!strcmp(loadmodel->name, "progs/player.mdl") ? pmodel_name : emodel_name,
(int)crc);
SZ_Print (&cls.netchan.message, st);
}
}

View File

@ -1,8 +1,7 @@
#include "bothdefs.h"
#include "quakedef.h"
#ifdef HALFLIFEMODELS
#include "quakedef.h"
#include "glquake.h"
/*
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
@ -112,12 +111,11 @@ void Mod_LoadHLModel (model_t *mod, void *buffer)
!strcmp(mod->name, "progs/player.mdl") ? pmodel_name : emodel_name,
st, MAX_INFO_STRING);
if (cls.state >= ca_connected) {
MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
sprintf(st, "setinfo %s %d",
if (cls.state >= ca_connected)
{
CL_SendClientCommand("setinfo %s %d",
!strcmp(mod->name, "progs/player.mdl") ? pmodel_name : emodel_name,
(int)crc);
SZ_Print (&cls.netchan.message, st);
}
}

View File

@ -9,6 +9,7 @@ void GL_SelectTexture (GLenum target);
void R_RenderDynamicLightmaps (msurface_t *fa);
void R_BlendLightmaps (void);
extern qboolean r_inmirror;
extern int gldepthfunc;
extern int *lightmap_textures;
extern int lightmap_bytes; // 1, 2, or 4
@ -1693,7 +1694,7 @@ void PPL_BaseTextures(model_t *model)
}
}
}
if (mirrortexturenum>=0 && model == cl.worldmodel && r_mirroralpha.value != 1.0)
if (!r_inmirror && mirrortexturenum>=0 && model == cl.worldmodel && r_mirroralpha.value != 1.0)
{
t = model->textures[mirrortexturenum];
if (t)
@ -1807,6 +1808,7 @@ void PPL_BaseBModelTextures(entity_t *e)
void PPL_BaseEntTextures(void)
{
extern qboolean r_inmirror;
extern model_t *currentmodel;
int i,j;
@ -1818,21 +1820,34 @@ void PPL_BaseEntTextures(void)
{
currententity = &cl_visedicts[i];
j = currententity->keynum;
while(j)
if (r_inmirror)
{
if (j == cl.viewentity[r_refdef.currentplayernum]+1)
break;
j = cl.lerpents[j].tagent;
if (currententity->flags & Q2RF_WEAPONMODEL)
continue;
}
if (j)
continue;
else
{
#if 0
if (currententity->keynum == r_refdef.currentplayernum+1)
continue;
#else
j = currententity->keynum;
while(j)
{
if (j == (cl.viewentity[r_refdef.currentplayernum]?cl.viewentity[r_refdef.currentplayernum]:(cl.playernum[r_refdef.currentplayernum]+1)))
break;
if (cl.viewentity[r_refdef.currentplayernum] && currententity->keynum == cl.viewentity[r_refdef.currentplayernum])
continue;
if (!Cam_DrawPlayer(0, currententity->keynum-1))
continue;
j = cl.lerpents[j].tagent;
}
if (j)
continue;
#endif
if (cl.viewentity[r_refdef.currentplayernum] && currententity->keynum == cl.viewentity[r_refdef.currentplayernum])
continue;
if (!Cam_DrawPlayer(0, currententity->keynum-1))
continue;
}
if (!currententity->model)
continue;

View File

@ -65,6 +65,7 @@ int mirrortexturenum; // quake texturenum, not gltexturenum
qboolean mirror;
mplane_t *mirror_plane;
msurface_t *r_mirror_chain;
qboolean r_inmirror; //or out-of-body
void R_DrawAliasModel (entity_t *e);
@ -1293,7 +1294,6 @@ void R_SetupGL (void)
float screenaspect;
extern int glwidth, glheight;
int x, x2, y2, y, w, h;
//
// set up viewpoint
//
@ -1349,29 +1349,24 @@ void R_SetupGL (void)
qglCullFace(GL_BACK);
}
else
{
#ifdef R_XFLIP
if (r_xflip.value)
{
qglScalef (1, -1, 1);
qglCullFace(GL_BACK);
}
else
#endif
qglCullFace(GL_FRONT);
}
qglMatrixMode(GL_MODELVIEW);
qglLoadIdentity ();
qglRotatef (-90, 1, 0, 0); // put Z going up
qglRotatef (90, 0, 0, 1); // put Z going up
#ifdef R_XFLIP
if (r_xflip.value)
{
qglScalef (1, -1, 1);
qglCullFace(GL_BACK);
}
#endif
qglRotatef (-r_refdef.viewangles[2], 1, 0, 0);
qglRotatef (-r_refdef.viewangles[0], 0, 1, 0);
qglRotatef (-r_refdef.viewangles[1], 0, 0, 1);
qglTranslatef (-r_refdef.vieworg[0], -r_refdef.vieworg[1], -r_refdef.vieworg[2]);
ML_ModelViewMatrixFromAxis(r_world_matrix, vpn, vright, vup, r_refdef.vieworg);
qglLoadMatrixf(r_world_matrix);
qglGetFloatv (GL_MODELVIEW_MATRIX, r_world_matrix);
//
// set drawing parms
@ -1647,40 +1642,105 @@ void R_MirrorAddPlayerModels (void)
void R_Mirror (void)
{
float d;
msurface_t *s;
msurface_t *s, *prevs, *prevr, *rejects;
// entity_t *ent;
mplane_t *mirror_plane;
int oldvisents;
vec3_t oldangles, oldorg; //cache - for rear view mirror and stuff.
vec3_t oldangles, oldorg, oldvpn, oldvright, oldvup; //cache - for rear view mirror and stuff.
if (!mirror)
{
r_inmirror = false;
return;
}
oldvisents = cl_numvisedicts;
R_MirrorAddPlayerModels(); //we need to add the player model. Invisible in mirror otherwise.
r_inmirror = true;
memcpy(oldangles, r_refdef.viewangles, sizeof(vec3_t));
memcpy(oldorg, r_refdef.vieworg, sizeof(vec3_t));
memcpy(oldvpn, vpn, sizeof(vec3_t));
memcpy(oldvright, vright, sizeof(vec3_t));
memcpy(oldvup, vup, sizeof(vec3_t));
memcpy (r_base_world_matrix, r_world_matrix, sizeof(r_base_world_matrix));
d = DotProduct (r_refdef.vieworg, mirror_plane->normal) - mirror_plane->dist;
VectorMA (r_refdef.vieworg, -2*d, mirror_plane->normal, r_refdef.vieworg);
while(r_mirror_chain)
{
s = r_mirror_chain;
r_mirror_chain = r_mirror_chain->texturechain;
//this loop figures out all surfaces with the same plane.
//yes, this can mean that the list is reversed a few times, but we do have depth testing to solve that anyway.
for(prevs = s,prevr=NULL,rejects=NULL;r_mirror_chain;r_mirror_chain=r_mirror_chain->texturechain)
{
if (s->plane->dist != r_mirror_chain->plane->dist || s->plane->signbits != r_mirror_chain->plane->signbits
|| s->plane->normal[0] != r_mirror_chain->plane->normal[0] || s->plane->normal[1] != r_mirror_chain->plane->normal[1] || s->plane->normal[2] != r_mirror_chain->plane->normal[2])
{ //reject
if (prevr)
prevr->texturechain = r_mirror_chain;
else
rejects = r_mirror_chain;
prevr = r_mirror_chain;
}
else
{ //matches
prevs->texturechain = r_mirror_chain;
prevs = r_mirror_chain;
}
}
prevs->texturechain = NULL;
if (prevr)
prevr->texturechain = NULL;
r_mirror_chain = rejects;
mirror_plane = s->plane;
//enable stencil writing
qglClearStencil(0);
qglEnable(GL_STENCIL_TEST);
qglStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); //replace where it passes
qglStencilFunc( GL_ALWAYS, 1, ~0 ); //always pass (where z passes set to 1)
qglColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );
qglDepthMask( GL_FALSE );
for (prevs = s; s; s=s->texturechain) //write the polys to the stencil buffer.
R_RenderBrushPoly (s);
qglColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
qglDepthMask( GL_TRUE );
qglStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
qglStencilFunc( GL_EQUAL, 1, ~0 ); //pass if equal to 1
// oldvisents = cl_numvisedicts;
// R_MirrorAddPlayerModels(); //we need to add the player model. Invisible in mirror otherwise.
d = DotProduct (oldorg, mirror_plane->normal) - mirror_plane->dist;
VectorMA (oldorg, -2*d, mirror_plane->normal, r_refdef.vieworg);
memcpy(r_origin, r_refdef.vieworg, sizeof(vec3_t));
d = DotProduct (vpn, mirror_plane->normal);
VectorMA (vpn, -2*d, mirror_plane->normal, vpn);
d = DotProduct (oldvpn, mirror_plane->normal);
VectorMA (oldvpn, -2*d, mirror_plane->normal, vpn);
d = DotProduct (oldvright, mirror_plane->normal);
VectorMA (oldvright, -2*d, mirror_plane->normal, vright);
d = DotProduct (oldvup, mirror_plane->normal);
VectorMA (oldvup, -2*d, mirror_plane->normal, vup);
r_refdef.viewangles[0] = -asin (vpn[2])/M_PI*180;
r_refdef.viewangles[1] = atan2 (vpn[1], vpn[0])/M_PI*180;
r_refdef.viewangles[2] = -r_refdef.viewangles[2];
r_refdef.viewangles[2] = -oldangles[2];
vpn[0]*=0.001;
vpn[1]*=0.001;
vpn[2]*=0.001;
/*
r_refdef.vieworg[0] = 400;
r_refdef.vieworg[1] = 575;
r_refdef.vieworg[2] = 64;
*/
AngleVectors (r_refdef.viewangles, vpn, vright, vup);
// AngleVectors (r_refdef.viewangles, vpn, vright, vup);
gldepthmin = 0.5;
@ -1700,6 +1760,7 @@ void R_Mirror (void)
memcpy(r_refdef.viewangles, oldangles, sizeof(vec3_t));
memcpy(r_refdef.vieworg, oldorg, sizeof(vec3_t));
qglMatrixMode(GL_PROJECTION);
if (mirror_plane->normal[2])
@ -1711,26 +1772,34 @@ void R_Mirror (void)
qglLoadMatrixf (r_base_world_matrix);
qglDisable(GL_STENCIL_TEST);
// blend on top
qglDisable(GL_ALPHA_TEST);
qglEnable (GL_BLEND);
qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
qglColor4f (1,1,1,r_mirroralpha.value);
s = r_mirror_chain;
for ( ; s ; s=s->texturechain)
R_RenderBrushPoly (s);
for ( ; s ; s=s->texturechain)
{
qglEnable (GL_BLEND);
R_RenderBrushPoly (s);
}
cl.worldmodel->textures[mirrortexturenum]->texturechain = NULL;
qglDisable (GL_BLEND);
qglColor4f (1,1,1,1);
//put things back for rear views
qglCullFace(GL_BACK);
// cl_numvisedicts = oldvisents;
}
memcpy(r_refdef.viewangles, oldangles, sizeof(vec3_t));
memcpy(r_refdef.vieworg, oldorg, sizeof(vec3_t));
cl_numvisedicts = oldvisents;
AngleVectors (r_refdef.viewangles, vpn, vright, vup);
r_inmirror = false;
}
//#endif

View File

@ -320,6 +320,10 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name))
}
// glslang
//the gf2 to gf4 cards emulate vertex_shader and thus supports shader_objects.
//but our code kinda requires both for clean workings.
if (!!strstr(gl_extensions, "GL_ARB_fragment_shader"))
if (!!strstr(gl_extensions, "GL_ARB_vertex_shader"))
if (!!strstr(gl_extensions, "GL_ARB_shader_objects"))
{
gl_config.arb_shader_objects = true;
@ -410,7 +414,7 @@ GLhandleARB GLSlang_CreateProgram (GLhandleARB vert, GLhandleARB frag)
{
qglGetInfoLogARB(program, sizeof(str), NULL, str);
Con_Printf("Program link error: %s\n", str);
return (int)NULL;
return (GLhandleARB)0;
}
return program;

View File

@ -1,10 +1,9 @@
#include "bothdefs.h"
#include "quakedef.h"
#if defined(GLQUAKE) || (!defined(GLQUAKE) && !defined(SWQUAKE))
#if defined(RGLQUAKE) || (!defined(RGLQUAKE) && !defined(SWQUAKE))
#ifdef RUNTIMELIGHTING
#if defined(GLQUAKE)
#include "quakedef.h"
#if defined(RGLQUAKE)
extern model_t *lightmodel;

View File

@ -1,4 +1,4 @@
#include "bothdefs.h"
#include "quakedef.h"
#ifdef WEBCLIENT

View File

@ -1,4 +1,4 @@
#include "bothdefs.h"
#include "quakedef.h"
#ifdef WEBSERVER
@ -132,8 +132,9 @@ void FTP_ServerShutdown(void)
IWebPrintf("FTP server is deactivated\n");
}
int SendFileNameTo(char *fname, int size, void *socket)
static int SendFileNameTo(char *fname, int size, void *param)
{
int socket = (int)param; //64->32... this is safe due to where it's called from. It's just not so portable.
// int i;
char buffer[256+1];
char *slash;
@ -159,7 +160,7 @@ int SendFileNameTo(char *fname, int size, void *socket)
// strcpy(buffer, fname);
// for (i = strlen(buffer); i < 40; i+=8)
// strcat(buffer, "\t");
send((int)socket, buffer, strlen(buffer), 0);
send(socket, buffer, strlen(buffer), 0);
return true;
}
@ -564,7 +565,7 @@ iwboolean FTP_ServerThinkForConnection(FTPclient_t *cl)
strcat(buffer, "*");
QueueMessage (cl, "125 Opening FAKE ASCII mode data connection for file.\r\n");
COM_EnumerateFiles(buffer, SendFileNameTo, (void *)cl->datasock);
COM_EnumerateFiles(buffer, SendFileNameTo, (void*)cl->datasock); //32->64 this is safe
QueueMessage (cl, "226 Transfer complete.\r\n");

View File

@ -1,4 +1,4 @@
#include "bothdefs.h"
#include "quakedef.h"
#ifdef WEBCLIENT

View File

@ -1,4 +1,4 @@
#include "bothdefs.h"
#include "quakedef.h"
#ifdef WEBSERVER

View File

@ -53,15 +53,16 @@ char **com_argv;
#ifndef QUAKEDEF_H__
#include "quakedef.h"
#ifdef _WIN32
#include "winquake.h"
#endif
#else
//#include <netinet/in.h>
#endif
#endif
#ifdef _WIN32
#include "winquake.h"
#endif
#define IWEBACC_READ 1
#define IWEBACC_WRITE 2
#define IWEBACC_FULL 4

View File

@ -1,3 +1,5 @@
#include "bothdefs.h"
#ifdef WEBSVONLY
#define WEBSERVER
#else

View File

@ -1,4 +1,4 @@
#include "bothdefs.h"
#include "quakedef.h"
#ifdef WEBSERVER

View File

@ -1,4 +1,4 @@
#include "bothdefs.h"
#include "quakedef.h"
#ifdef IRCCLIENT

View File

@ -19,7 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// net_dgrm.c
#include "../client/quakedef.h"
#include "quakedef.h"
#ifdef NQPROT

View File

@ -19,7 +19,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// net_loop.c
#include "../client/quakedef.h"
#include "quakedef.h"
#if !(defined(CLIENTONLY) || defined(SERVERONLY))
#ifdef NQPROT
#include "net_loop.h"

View File

@ -19,9 +19,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// net_main.c
#define NOCOM
#include "quakedef.h"
#include "../client/quakedef.h"
#define NOCOM
#ifdef NQPROT

View File

@ -19,4 +19,4 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// net_vcr.c
#include "../client/quakedef.h"
#include "quakedef.h"

View File

@ -17,7 +17,7 @@ along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "../client/quakedef.h"
#include "quakedef.h"
#ifdef NQPROT
#include "../client/winquake.h"

View File

@ -1,15 +1,50 @@
QCC_OBJS=qccmain.c qcc_cmdlib.c qcc_pr_comp.c qcc_pr_lex.c comprout.c hash.c qcd_main.c
QCC_OBJS=qccmain.o qcc_cmdlib.o qcc_pr_comp.o qcc_pr_lex.o comprout.o hash.o qcd_main.o
GTKGUI_OBJS=qcc_gtk.o qccguistuff.c
CC=gcc
CC=gcc -Wall -DQCCONLY
DO_CC=$(CC) $(BASE_CFLAGS) -DUSEGUI -o $@ -c $< $(CFLAGS) `pkg-config --cflags gtk+-2.0`
all: qcc
BASE_CFLAGS=-ggdb
CFLAGS =
win_nocyg: $(QCC_OBJS) qccgui.c qccguistuff.c
$(CC) -DQCCONLY -o fteqcc.exe -O3 -s $(QCC_OBJS) -mno-cygwin -mwindows
$(CC) $(BASE_CFLAGS) -o fteqcc.exe -O3 -s $(QCC_OBJS) -mno-cygwin -mwindows
nocyg: $(QCC_OBJS) qccgui.c qccguistuff.c
$(CC) -DQCCONLY -o fteqcc.exe -O3 -s $(QCC_OBJS) -mno-cygwin
$(CC) $(BASE_CFLAGS) -o fteqcc.exe -O3 -s $(QCC_OBJS) -mno-cygwin
win: $(QCC_OBJS) qccgui.c qccguistuff.c
$(CC) -DQCCONLY -o fteqcc.exe -O3 -s $(QCC_OBJS) -mwindows
$(CC) $(BASE_CFLAGS) -o fteqcc.exe -O3 -s $(QCC_OBJS) -mwindows
qcc: $(QCC_OBJS)
$(CC) -DQCCONLY -o fteqcc.bin -O3 -s $(QCC_OBJS)
$(CC) $(BASE_CFLAGS) -o fteqcc.bin -O3 -s $(QCC_OBJS)
qccmain.o: qccmain.c qcc.h
$(DO_CC)
qcc_cmdlib.o: qcc_cmdlib.c qcc.h
$(DO_CC)
qcc_pr_comp.o: qcc_pr_comp.c qcc.h
$(DO_CC)
qcc_pr_lex.o: qcc_pr_lex.c qcc.h
$(DO_CC)
comprout.o: comprout.c qcc.h
$(DO_CC)
hash.o: hash.c qcc.h
$(DO_CC)
qcd_main.o: qcd_main.c qcc.h
$(DO_CC)
qccguistuff.o: qccguistuff.c qcc.h
$(DO_CC)
qcc_gtk.o: qcc_gtk.c qcc.h
$(DO_CC)
gtkgui: $(QCC_OBJS) $(GTKGUI_OBJS)
$(CC) $(BASE_CFLAGS) -DQCCONLY -DUSEGUI -o fteqccgui.bin -O3 $(GTKGUI_OBJS) $(QCC_OBJS) `pkg-config --libs gtk+-2.0`

View File

@ -56,7 +56,7 @@ pbool PreCompile(void)
{
qccClearHunk();
strcpy(qcc_gamedir, "");
qcchunk = malloc(qcchunksize=16*1024*1024);
qcchunk = malloc(qcchunksize=32*1024*1024);
qccalloced=0;
return !!qcchunk;

View File

@ -904,43 +904,120 @@ reeval:
case OP_BITAND_IF:
OPC->_int = (OPA->_int & (int)OPB->_float);
break;
case OP_BITOR_IF:
OPC->_int = (OPA->_int | (int)OPB->_float);
break;
case OP_BITAND_FI:
OPC->_int = ((int)OPA->_float & OPB->_int);
break;
case OP_BITOR_FI:
OPC->_int = ((int)OPA->_float | OPB->_int);
break;
case OP_MUL_IF:
OPC->_float = (OPA->_int * OPB->_float);
break;
case OP_MUL_FI:
OPC->_float = (OPA->_float * OPB->_int);
break;
case OP_MUL_IF:
case OP_MUL_FI:
case OP_MUL_VI:
case OP_DIV_IF:
case OP_DIV_FI:
case OP_BITAND_IF:
case OP_BITOR_IF:
case OP_BITAND_FI:
case OP_BITOR_FI:
case OP_AND_I:
case OP_OR_I:
case OP_AND_IF:
case OP_OR_IF:
case OP_AND_FI:
case OP_OR_FI:
case OP_NOT_I:
case OP_NE_IF:
case OP_NE_FI:
case OP_GSTOREP_I:
case OP_GSTOREP_F:
case OP_GSTOREP_ENT:
case OP_GSTOREP_FLD: // integers
case OP_GSTOREP_S:
case OP_GSTOREP_FNC: // pointers
case OP_GSTOREP_V:
case OP_GADDRESS:
case OP_GLOAD_I:
case OP_GLOAD_F:
case OP_GLOAD_FLD:
case OP_GLOAD_ENT:
case OP_GLOAD_S:
case OP_GLOAD_FNC:
case OP_BOUNDCHECK:
PR_RunError(progfuncs, "Extra opcode not implemented\n");
break;
case OP_MUL_VI:
OPC->vector[0] = OPA->vector[0] * OPB->_int;
OPC->vector[1] = OPA->vector[0] * OPB->_int;
OPC->vector[2] = OPA->vector[0] * OPB->_int;
break;
case OP_MUL_IV:
OPC->vector[0] = OPB->_int * OPA->vector[0];
OPC->vector[1] = OPB->_int * OPA->vector[1];
OPC->vector[2] = OPB->_int * OPA->vector[2];
break;
case OP_DIV_IF:
OPC->_float = (OPA->_int / OPB->_float);
break;
case OP_DIV_FI:
OPC->_float = (OPA->_float / OPB->_int);
break;
case OP_AND_I:
OPC->_int = (OPA->_int && OPB->_int);
break;
case OP_OR_I:
OPC->_int = (OPA->_int || OPB->_int);
break;
case OP_AND_IF:
OPC->_int = (OPA->_int && OPB->_float);
break;
case OP_OR_IF:
OPC->_int = (OPA->_int || OPB->_float);
break;
case OP_AND_FI:
OPC->_int = (OPA->_float && OPB->_int);
break;
case OP_OR_FI:
OPC->_int = (OPA->_float || OPB->_int);
break;
case OP_NOT_I:
OPC->_int = !OPA->_int;
break;
case OP_NE_IF:
OPC->_int = (OPA->_int != OPB->_float);
break;
case OP_NE_FI:
OPC->_int = (OPA->_float != OPB->_int);
break;
case OP_GSTOREP_I:
case OP_GSTOREP_F:
case OP_GSTOREP_ENT:
case OP_GSTOREP_FLD: // integers
case OP_GSTOREP_S:
case OP_GSTOREP_FNC: // pointers
case OP_GSTOREP_V:
case OP_GADDRESS:
case OP_GLOAD_I:
case OP_GLOAD_F:
case OP_GLOAD_FLD:
case OP_GLOAD_ENT:
case OP_GLOAD_S:
case OP_GLOAD_FNC:
pr_xstatement = st-pr_statements;
PR_RunError(progfuncs, "Extra opcode not implemented\n");
break;
case OP_BOUNDCHECK:
if (OPA->_int < st->c || OPA->_int >= st->b)
{
pr_xstatement = st-pr_statements;
PR_RunError(progfuncs, "Progs boundcheck failed. Value is %i.", OPA->_int);
}
break;
case OP_PUSH:
OPC->_int = (int)&localstack[localstack_used+pr_spushed];
pr_spushed += OPA->_int;
if (pr_spushed + localstack_used >= LOCALSTACK_SIZE)
{
pr_spushed = 0;
pr_xstatement = st-pr_statements;
PR_RunError(progfuncs, "Progs pushed too much");
}
break;
case OP_POP:
pr_spushed -= OPA->_int;
if (pr_spushed < 0)
{
pr_spushed = 0;
pr_xstatement = st-pr_statements;
PR_RunError(progfuncs, "Progs poped more than it pushed");
}
break;
default:
if (st->op & 0x8000) //break point!
@ -960,7 +1037,7 @@ PR_RunError(progfuncs, "Extra opcode not implemented\n");
fakeop.op &= ~0x8000;
st = &fakeop; //a little remapping...
#else
st->op &= ~0x8000;
st->op &= ~0x8000; //just remove the breakpoint and go around again, but this time in the debugger.
#endif
goto reeval; //reexecute

View File

@ -1,2 +1,20 @@
void GoToDefinition(char *name);
void EditFile(char *name, int line);
void GUI_SetDefaultOpts(void);
int GUI_BuildParms(char *args, char **argv);
char *QCC_ReadFile (char *fname, void *buffer, int len);
int QCC_FileSize (char *fname);
pbool QCC_WriteFile (char *name, void *data, int len);
void GUI_DialogPrint(char *title, char *text);
extern char parameters[16384];
extern char progssrcname[256];
extern char progssrcdir[256];
extern pbool fl_hexen2;
extern pbool fl_autohighlight;
extern pbool fl_compileonstart;
extern pbool fl_showall;

View File

@ -410,7 +410,7 @@ progexterns_t defexterns = {
NULL, //builtin_t *globalbuiltins; //these are available to all progs
0, //int numglobalbuiltins;
PR_COMPILENEXIST,
PR_NOCOMPILE,
&safetime, //double *gametime;

View File

@ -305,6 +305,8 @@ enum {
//back to ones that we do use.
OP_STOREP_P,
OP_PUSH, //push 4octets onto the local-stack (which is ALWAYS poped on function return). Returns a pointer.
OP_POP, //pop those ones that were pushed (don't over do it). Needs assembler.
OP_NUMOPS
};
@ -422,7 +424,8 @@ typedef struct
#define PROG_VERSION 6
#define PROG_DEBUGVERSION 7
#define PROG_KKQWSVVERSION 7
#define PROG_EXTENDEDVERSION 7
#define PROG_SECONDARYVERSION16 (*(int*)"1FTE" ^ *(int*)"PROG") //something unlikly and still meaningful (to me)
#define PROG_SECONDARYVERSION32 (*(int*)"1FTE" ^ *(int*)"32B ") //something unlikly and still meaningful (to me)
typedef struct

View File

@ -2252,7 +2252,7 @@ retry:
// printf("Opening standard progs file \"%s\"\n", filename);
current_progstate->intsize = 16;
}
else if (pr_progs->version == PROG_DEBUGVERSION)
else if (pr_progs->version == PROG_EXTENDEDVERSION)
{
if (pr_progs->secondaryversion == PROG_SECONDARYVERSION16)
{
@ -2287,7 +2287,7 @@ retry:
}
//progs contains enough info for use to recompile it.
if (trysleft && externs->autocompile == PR_COMPILECHANGED && pr_progs->version == PROG_DEBUGVERSION)
if (trysleft && externs->autocompile == PR_COMPILECHANGED && pr_progs->version == PROG_EXTENDEDVERSION)
{
if (PR_TestRecompile(progfuncs))
{
@ -2324,7 +2324,7 @@ retry:
pr_linenums=NULL;
pr_types=NULL;
if (pr_progs->version == PROG_DEBUGVERSION)
if (pr_progs->version == PROG_EXTENDEDVERSION)
{
if (pr_progs->ofslinenums)
pr_linenums = (int *)((qbyte *)pr_progs + pr_progs->ofslinenums);
@ -2520,7 +2520,7 @@ retry:
((int *)glob)[i] = LittleLong (((int *)glob)[i]);
#endif
if (pr_progs->version == PROG_DEBUGVERSION)
if (pr_progs->version == PROG_EXTENDEDVERSION)
{
if (pr_types)
{
@ -2802,7 +2802,7 @@ retry:
}
}
if (pr_progs->version == PROG_DEBUGVERSION && pr_progs->numbodylessfuncs)
if (pr_progs->version == PROG_EXTENDEDVERSION && pr_progs->numbodylessfuncs)
{
s = &((char *)pr_progs)[pr_progs->ofsbodylessfuncs];
for (i = 0; i < pr_progs->numbodylessfuncs; i++)
@ -2862,7 +2862,7 @@ retry:
}
}
if (pr_progs->version == PROG_DEBUGVERSION && pr_progs->numbodylessfuncs)
if (pr_progs->version == PROG_EXTENDEDVERSION && pr_progs->numbodylessfuncs)
{
s = &((char *)pr_progs)[pr_progs->ofsbodylessfuncs];
for (i = 0; i < pr_progs->numbodylessfuncs; i++)

View File

@ -238,6 +238,7 @@ int PR_EnterFunction (progfuncs_t *progfuncs, dfunction_t *f, int progsnum)
pr_stack[pr_depth].s = pr_xstatement;
pr_stack[pr_depth].f = pr_xfunction;
pr_stack[pr_depth].progsnum = progsnum;
pr_stack[pr_depth].pushed = pr_spushed;
pr_depth++;
if (pr_depth == MAX_STACK_DEPTH)
{
@ -253,6 +254,8 @@ int PR_EnterFunction (progfuncs_t *progfuncs, dfunction_t *f, int progsnum)
return pr_xstatement;
}
localstack_used += pr_spushed; //make sure the call doesn't hurt pushed pointers
// save off any locals that the new function steps on (to a side place, fromwhere they are restored on exit)
c = f->locals;
if (localstack_used + c > LOCALSTACK_SIZE)
@ -303,6 +306,9 @@ int PR_LeaveFunction (progfuncs_t *progfuncs)
PR_MoveParms(progfuncs, pr_stack[pr_depth].progsnum, pr_typecurrent);
PR_SwitchProgs(progfuncs, pr_stack[pr_depth].progsnum);
pr_xfunction = pr_stack[pr_depth].f;
pr_spushed = pr_stack[pr_depth].pushed;
localstack_used -= pr_spushed;
return pr_stack[pr_depth].s;
}
@ -786,6 +792,7 @@ void PR_ExecuteCode (progfuncs_t *progfuncs, int s)
printf ("runaway loop error"); \
while(pr_depth > prinst->exitdepth) \
PR_LeaveFunction(progfuncs); \
pr_spushed = 0; \
return; \
}

View File

@ -150,7 +150,6 @@ struct edict_s *RestoreEnt (progfuncs_t *progfuncs, char *buf, int *size, struct
char *PF_VarString (int first);
void PR_StackTrace (progfuncs_t *progfuncs);
extern int outputversion;
extern int noextensions;
#ifndef COMPILER
@ -315,6 +314,7 @@ typedef struct
int s;
dfunction_t *f;
int progsnum;
int pushed;
} prstack_t;
@ -363,6 +363,8 @@ vars(prstack_t, pr_stack, MAX_STACK_DEPTH);
#define pr_stack prinst->pr_stack
var(int, pr_depth);
#define pr_depth prinst->pr_depth
var(int, spushed);
#define pr_spushed prinst->spushed
#define LOCALSTACK_SIZE 4096
vars(int, localstack, LOCALSTACK_SIZE);

View File

@ -41,22 +41,22 @@ typedef struct {
int spare[2];
} evalc_t;
#define sizeofevalc sizeof(evalc_t)
typedef enum {ev_void, ev_string, ev_float, ev_vector, ev_entity, ev_field, ev_function, ev_pointer, ev_integer, ev_struct, ev_union, ev_variant} etype_t;
typedef enum {ev_void, ev_string, ev_float, ev_vector, ev_entity, ev_field, ev_function, ev_pointer, ev_integer, ev_variant, ev_struct, ev_union} etype_t;
struct progfuncs_s {
int progsversion; //PROGSTRUCT_VERSION
void (*PR_Configure) (progfuncs_t *prinst, void *mem, int memsize, int max_progs); //configure buffers and memory. Used to reset and must be called first.
progsnum_t (*PR_LoadProgs) (progfuncs_t *prinst, char *s, int headercrc, builtin_t *builtins, int numbuiltins); //load a progs
int (*PR_InitEnts) (progfuncs_t *prinst, int max_ents); //returns size of edicts for use with nextedict macro
void (*PR_ExecuteProgram) (progfuncs_t *prinst, func_t fnum); //start execution
pbool (*PR_SwitchProgs) (progfuncs_t *prinst, progsnum_t num); //switch to a different progs - my aim is to make this obsolete
void (*Configure) (progfuncs_t *prinst, void *mem, int memsize, int max_progs); //configure buffers and memory. Used to reset and must be called first.
progsnum_t (*LoadProgs) (progfuncs_t *prinst, char *s, int headercrc, builtin_t *builtins, int numbuiltins); //load a progs
int (*InitEnts) (progfuncs_t *prinst, int max_ents); //returns size of edicts for use with nextedict macro
void (*ExecuteProgram) (progfuncs_t *prinst, func_t fnum); //start execution
pbool (*SwitchProgs) (progfuncs_t *prinst, progsnum_t num); //switch to a different progs - my aim is to make this obsolete
struct globalvars_s *(*globals) (progfuncs_t *prinst, progsnum_t num); //get the globals of a progs
struct entvars_s *(*entvars) (progfuncs_t *prinst, struct edict_s *ent); //return a pointer to the entvars of an ent
void (VARGS *PR_RunError) (progfuncs_t *prinst, char *msg, ...); //builtins call this to say there was a problem
void (*PR_PrintEdict) (progfuncs_t *prinst, struct edict_s *ed); //get a listing of all vars on an edict (sent back via 'print')
void (VARGS *RunError) (progfuncs_t *prinst, char *msg, ...); //builtins call this to say there was a problem
void (*PrintEdict) (progfuncs_t *prinst, struct edict_s *ed); //get a listing of all vars on an edict (sent back via 'print')
struct edict_s *(*ED_Alloc) (progfuncs_t *prinst);
void (*ED_Free) (progfuncs_t *prinst, struct edict_s *ed);
@ -66,17 +66,17 @@ struct progfuncs_s {
void (*SetGlobalEdict) (progfuncs_t *prinst, struct edict_s *ed, int ofs); //set a global to an edict (partially obsolete)
char *(*PR_VarString) (progfuncs_t *prinst, int first); //returns a string made up of multiple arguments
char *(*VarString) (progfuncs_t *prinst, int first); //returns a string made up of multiple arguments
struct progstate_s **progstate; //these are so the macros work properly
// struct edict_s **sv_edicts;
// int *sv_num_edicts;
func_t (*PR_FindFunction) (progfuncs_t *prinst, char *funcname, progsnum_t num);
func_t (*FindFunction) (progfuncs_t *prinst, char *funcname, progsnum_t num);
int (*PR_StartCompile) (progfuncs_t *prinst, int argv, char **argc); //1 if can compile, 0 if failed to compile
int (*PR_ContinueCompile) (progfuncs_t *prinst); //2 if finished, 1 if more to go, 0 if failed
int (*StartCompile) (progfuncs_t *prinst, int argv, char **argc); //1 if can compile, 0 if failed to compile
int (*ContinueCompile) (progfuncs_t *prinst); //2 if finished, 1 if more to go, 0 if failed
char *(*filefromprogs) (progfuncs_t *prinst, progsnum_t prnum, char *fname, int *size, char *buffer); //reveals encoded/added files from already loaded progs
char *(*filefromnewprogs) (progfuncs_t *prinst, char *prname, char *fname, int *size, char *buffer); //reveals encoded/added files from a progs on the disk somewhere
@ -99,7 +99,7 @@ struct progfuncs_s {
int *pr_trace; //start calling the editor for each line executed
void (*PR_StackTrace) (progfuncs_t *prinst);
void (*StackTrace) (progfuncs_t *prinst);
int (*ToggleBreak) (progfuncs_t *prinst, char *filename, int linenum, int mode);
@ -198,11 +198,11 @@ typedef union eval_s
#ifndef DLL_PROG
#define PR_Configure(pf, mem, memsize, max_progs) (*pf->PR_Configure) (pf, mem, memsize, max_progs)
#define PR_LoadProgs(pf, s, headercrc, builtins, numb) (*pf->PR_LoadProgs) (pf, s, headercrc, builtins, numb)
#define PR_InitEnts(pf, maxents) (*pf->PR_InitEnts) (pf, maxents)
#define PR_ExecuteProgram(pf, fnum) (*pf->PR_ExecuteProgram) (pf, fnum)
#define PR_SwitchProgs(pf, num) (*pf->PR_SwitchProgs) (pf, num);
#define PR_Configure(pf, mem, memsize, max_progs) (*pf->Configure) (pf, mem, memsize, max_progs)
#define PR_LoadProgs(pf, s, headercrc, builtins, numb) (*pf->LoadProgs) (pf, s, headercrc, builtins, numb)
#define PR_InitEnts(pf, maxents) (*pf->InitEnts) (pf, maxents)
#define PR_ExecuteProgram(pf, fnum) (*pf->ExecuteProgram) (pf, fnum)
#define PR_SwitchProgs(pf, num) (*pf->SwitchProgs) (pf, num);
#define PR_globals(pf, num) (*pf->globals) (pf, num)
#define PR_entvars(pf, ent) (*pf->entvars) (pf, ent)
@ -217,17 +217,27 @@ typedef union eval_s
#define EDICT_NUM(pf, num) (*pf->EDICT_NUM) (pf, num)
#define NUM_FOR_EDICT(pf, e) (*pf->NUM_FOR_EDICT) (pf, e)
#define SetGlobalEdict(pf, ed, ofs) (*pf->SetGlobalEdict) (pf, ed, ofs)
#define PR_VarString (*progfuncs->PR_VarString)
#define PR_VarString(pf,first) (*pf->VarString) (pf,first)
#define PR_StartCompile(pf,argc,argv) (*pf->StartCompile) (pf,argc,argv)
#define PR_ContinueCompile(pf) (*pf->ContinueCompile) (pf)
#define PR_StackTrace(pf) (*pf->StackTrace) (pf)
#define PR_AbortStack(pf) (*pf->AbortStack) (pf)
#define PR_RunError(pf,str) (*pf->RunError) (pf,str)
#define PR_PrintEdict(pf,ed) (*pf->PrintEdict) (pf, ed)
//#define sv_edicts (*progfuncs->sv_edicts)
#define current_progstate (*progfuncs->progstate)
//#define current_progstate (*progfuncs->progstate)
//#define pr_num_edicts (*progfuncs->sv_num_edicts)
#define PR_FindFunction(pf, name, num) (*pf->PR_FindFunction) (pf, name, num)
#define PR_FindFunction(pf, name, num) (*pf->FindFunction) (pf, name, num)
#define PR_FindGlobal(pf, name, progs) (*pf->FindGlobal) (pf, name, progs)
#define PR_AddString(pf, ed) (*pf->AddString) (pf, ed)
#define PR_Alloc (*progfuncs->Tempmem)
#define PR_Alloc(pf,size) (*pf->Tempmem) (pf, size)
#define PROG_TO_EDICT(pf, ed) (*pf->ProgsToEdict) (pf, ed)
#define EDICT_TO_PROG(pf, ed) (*pf->EdictToProgs) (pf, ed)

View File

@ -155,6 +155,11 @@ SOURCE=.\qcc_cmdlib.c
# End Source File
# Begin Source File
SOURCE=.\qcc_gtk.c
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=.\qcc_pr_comp.c
# End Source File
# Begin Source File

View File

@ -68,7 +68,7 @@ extern int MAX_CONSTANTS;
#define MAXCONSTANTPARAMLENGTH 32
#define MAXCONSTANTPARAMS 4
typedef enum {QCF_STANDARD, QCF_HEXEN2, QCF_FTE, QCF_FTE32, QCF_FTEDEBUG, QCF_FTEDEBUG32, QCF_KK7} qcc_targetformat_t;
typedef enum {QCF_STANDARD, QCF_HEXEN2, QCF_FTE, QCF_FTEDEBUG, QCF_KK7} qcc_targetformat_t;
extern qcc_targetformat_t qcc_targetformat;
@ -371,10 +371,10 @@ typedef union QCC_eval_s
union QCC_eval_s *ptr;
} QCC_eval_t;
const extern int type_size[9];
const extern int type_size[12];
//extern QCC_def_t *def_for_type[9];
extern QCC_type_t *type_void, *type_string, *type_float, *type_vector, *type_entity, *type_field, *type_function, *type_pointer, *type_integer, *type_floatfield;
extern QCC_type_t *type_void, *type_string, *type_float, *type_vector, *type_entity, *type_field, *type_function, *type_pointer, *type_integer, *type_variant, *type_floatfield;
struct QCC_function_s
{
@ -486,6 +486,7 @@ extern pbool opt_compound_jumps;
extern pbool opt_stripfunctions;
extern pbool opt_locals_marshalling;
extern pbool opt_logicops;
extern pbool opt_vectorcalls;
extern int optres_shortenifnots;
extern int optres_overlaptemps;
@ -527,6 +528,7 @@ void QCC_RemapOffsets(unsigned int firststatement, unsigned int laststatement, u
#ifndef COMMONINLINES
pbool QCC_PR_Check (char *string);
pbool QCC_PR_CheckInsens (char *string);
void QCC_PR_Expect (char *string);
#endif
void VARGS QCC_PR_ParseError (int errortype, char *error, ...);
@ -685,17 +687,31 @@ enum {
WARN_MAX
};
#define FLAG_KILLSDEBUGGERS 1
#define FLAG_ASDEFAULT 2
#define FLAG_SETINGUI 4
#define FLAG_HIDDENINGUI 8
typedef struct {
pbool *enabled;
char *abbrev;
int optimisationlevel;
int flags; //1: kills debuggers. 2: applied as default.
char *fullname;
char *description;
void *guiinfo;
} optimisations_t;
extern optimisations_t optimisations[];
typedef struct {
pbool *enabled;
int flags; //2 applied as default
char *abbrev;
char *fullname;
char *description;
void *guiinfo;
} compiler_flag_t;
extern compiler_flag_t compiler_flag[];
extern pbool qccwarningdisabled[WARN_MAX];
extern jmp_buf pr_parse_abort; // longjump with this on parse error
@ -853,4 +869,4 @@ char *TypeName(QCC_type_t *type);
void QCC_PR_IncludeChunk (char *data, pbool duplicate, char *filename);
extern void *(*pHash_Get)(hashtable_t *table, char *name);
extern void *(*pHash_GetNext)(hashtable_t *table, char *name, void *old);
extern void *(*pHash_Add)(hashtable_t *table, char *name, void *data, bucket_t *);
extern void *(*pHash_Add)(hashtable_t *table, char *name, void *data, bucket_t *);

View File

@ -885,8 +885,6 @@ void QCC_AddFile (char *filename)
externs->ReadFile(filename, mem, len+1);
mem[len] = '\0';
outputversion = PROG_DEBUGVERSION;
}
void *FS_ReadToMem(char *filename, void *mem, int *len)
{

View File

@ -61,6 +61,7 @@ pbool opt_compound_jumps; //jumps to jump statements jump to the final point.
pbool opt_stripfunctions; //if a functions is only ever called directly or by exe, don't emit the def.
pbool opt_locals_marshalling; //make the local vars of all functions occupy the same globals.
pbool opt_logicops; //don't make conditions enter functions if the return value will be discarded due to a previous value. (C style if statements)
pbool opt_vectorcalls; //vectors can be packed into 3 floats, which can yield lower numpr_globals, but cost two more statements per call (only works for q1 calling conventions).
//bool opt_comexprremoval;
//these are the results of the opt_. The values are printed out when compilation is compleate, showing effectivness.
@ -435,26 +436,28 @@ QCC_opcode_t pr_opcodes[] =
{7, "<>", "GSTOREP_I", -1, ASSOC_LEFT, &type_float, &type_float, &type_float},
{7, "<>", "GSTOREP_F", -1, ASSOC_LEFT, &type_float, &type_float, &type_float},
{7, "<>", "GSTOREP_ENT", -1, ASSOC_LEFT, &type_float, &type_float, &type_float},
{7, "<>", "GSTOREP_FLD", -1, ASSOC_LEFT, &type_float, &type_float, &type_float},
{7, "<>", "GSTOREP_S", -1, ASSOC_LEFT, &type_float, &type_float, &type_float},
{7, "<>", "GSTORE_PFNC", -1, ASSOC_LEFT, &type_float, &type_float, &type_float},
{7, "<>", "GSTOREP_V", -1, ASSOC_LEFT, &type_float, &type_float, &type_float},
{7, "<>", "GSTOREP_I", -1, ASSOC_LEFT, &type_float, &type_float, &type_float},
{7, "<>", "GSTOREP_F", -1, ASSOC_LEFT, &type_float, &type_float, &type_float},
{7, "<>", "GSTOREP_ENT", -1, ASSOC_LEFT, &type_float, &type_float, &type_float},
{7, "<>", "GSTOREP_FLD", -1, ASSOC_LEFT, &type_float, &type_float, &type_float},
{7, "<>", "GSTOREP_S", -1, ASSOC_LEFT, &type_float, &type_float, &type_float},
{7, "<>", "GSTORE_PFNC", -1, ASSOC_LEFT, &type_float, &type_float, &type_float},
{7, "<>", "GSTOREP_V", -1, ASSOC_LEFT, &type_float, &type_float, &type_float},
{7, "<>", "GADDRESS", -1, ASSOC_LEFT, &type_float, &type_float, &type_float},
{7, "<>", "GADDRESS", -1, ASSOC_LEFT, &type_float, &type_float, &type_float},
{7, "<>", "GLOAD_I", -1, ASSOC_LEFT, &type_float, &type_float, &type_float},
{7, "<>", "GLOAD_F", -1, ASSOC_LEFT, &type_float, &type_float, &type_float},
{7, "<>", "GLOAD_FLD", -1, ASSOC_LEFT, &type_float, &type_float, &type_float},
{7, "<>", "GLOAD_ENT", -1, ASSOC_LEFT, &type_float, &type_float, &type_float},
{7, "<>", "GLOAD_S", -1, ASSOC_LEFT, &type_float, &type_float, &type_float},
{7, "<>", "GLOAD_FNC", -1, ASSOC_LEFT, &type_float, &type_float, &type_float},
{7, "<>", "GLOAD_I", -1, ASSOC_LEFT, &type_float, &type_float, &type_float},
{7, "<>", "GLOAD_F", -1, ASSOC_LEFT, &type_float, &type_float, &type_float},
{7, "<>", "GLOAD_FLD", -1, ASSOC_LEFT, &type_float, &type_float, &type_float},
{7, "<>", "GLOAD_ENT", -1, ASSOC_LEFT, &type_float, &type_float, &type_float},
{7, "<>", "GLOAD_S", -1, ASSOC_LEFT, &type_float, &type_float, &type_float},
{7, "<>", "GLOAD_FNC", -1, ASSOC_LEFT, &type_float, &type_float, &type_float},
{7, "<>", "BOUNDCHECK", -1, ASSOC_LEFT, &type_float, &type_float, &type_float},
{7, "<>", "BOUNDCHECK", -1, ASSOC_LEFT, &type_float, &type_float, &type_float},
{7, "=", "STOREP_P", 6, ASSOC_RIGHT, &type_pointer, &type_pointer, &type_void},
{7, "=", "STOREP_P", 6, ASSOC_RIGHT, &type_pointer, &type_pointer, &type_void},
{7, "<PUSH>", "PUSH", -1, ASSOC_RIGHT, &type_float, &type_void, &type_pointer},
{7, "<POP>", "POP", -1, ASSOC_RIGHT, &type_float, &type_void, &type_void},
{0, NULL}
};
@ -663,9 +666,7 @@ pbool QCC_OPCodeValid(QCC_opcode_t *op)
return true;
return false;
case QCF_FTE:
case QCF_FTE32:
case QCF_FTEDEBUG:
case QCF_FTEDEBUG32:
return true;
}
return false;
@ -2064,12 +2065,17 @@ QCC_def_t *QCC_PR_ParseFunctionCall (QCC_def_t *func) //warning, the func could
t = func->type;
if (t->type != ev_function)
if (t->type == ev_variant)
{
t->aux_type = type_variant;
}
if (t->type != ev_function && t->type != ev_variant)
{
QCC_PR_ParseErrorPrintDef (ERR_NOTAFUNCTION, func, "not a function");
}
if (!t->num_parms) //intrinsics. These base functions have variable arguments. I would check for (...) args too, but that might be used for extended builtin functionality. (this code wouldn't compile otherwise)
if (!t->num_parms&&t->type != ev_variant) //intrinsics. These base functions have variable arguments. I would check for (...) args too, but that might be used for extended builtin functionality. (this code wouldn't compile otherwise)
{
if (!strcmp(func->name, "random"))
{
@ -2428,7 +2434,12 @@ QCC_def_t *QCC_PR_ParseFunctionCall (QCC_def_t *func) //warning, the func could
// copy the arguments to the global parameter variables
arg = 0;
if (t->num_parms < 0)
if (t->type == ev_variant)
{
extraparms = true;
np = 0;
}
else if (t->num_parms < 0)
{
extraparms = true;
np = (t->num_parms * -1) - 1;
@ -2436,161 +2447,219 @@ QCC_def_t *QCC_PR_ParseFunctionCall (QCC_def_t *func) //warning, the func could
else
np = t->num_parms;
if (!QCC_PR_Check(")"))
{
p = t->param;
do
if (opt_vectorcalls && (t->num_parms == 1 && t->param->type == ev_vector))
{ //if we're using vectorcalls
//if it's a function, takes a vector
vec3_t arg;
if (pr_token_type == tt_immediate && pr_immediate_type == type_vector)
{
if (extraparms && arg >= MAX_PARMS)
QCC_PR_ParseErrorPrintDef (ERR_TOOMANYPARAMETERSVARARGS, func, "More than %i parameters on varargs function", MAX_PARMS);
else if (arg >= MAX_PARMS+MAX_EXTRA_PARMS)
QCC_PR_ParseErrorPrintDef (ERR_TOOMANYTOTALPARAMETERS, func, "More than %i parameters", MAX_PARMS+MAX_EXTRA_PARMS);
if (!extraparms && arg >= t->num_parms)
{
QCC_PR_ParseWarning (WARN_TOOMANYPARAMETERSFORFUNC, "too many parameters");
QCC_PR_ParsePrintDef(WARN_TOOMANYPARAMETERSFORFUNC, func);
}
memcpy(arg, pr_immediate.vector, sizeof(arg));
while(*pr_file_p == ' ' || *pr_file_p == '\t' || *pr_file_p == '\n')
pr_file_p++;
if (*pr_file_p == ')')
{ //woot
def_parms[0].ofs = OFS_PARM0+0;
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_STORE_F], QCC_MakeFloatDef(arg[0]), &def_parms[0], (QCC_dstatement_t **)0xffffffff));
def_parms[0].ofs = OFS_PARM0+1;
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_STORE_F], QCC_MakeFloatDef(arg[1]), &def_parms[0], (QCC_dstatement_t **)0xffffffff));
def_parms[0].ofs = OFS_PARM0+2;
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_STORE_F], QCC_MakeFloatDef(arg[2]), &def_parms[0], (QCC_dstatement_t **)0xffffffff));
def_parms[0].ofs = OFS_PARM0;
e = QCC_PR_Expression (TOP_PRIORITY);
if (arg == 0 && func->name)
{
// save information for model and sound caching
if (!strncmp(func->name,"precache_", 9))
{
if (!strncmp(func->name+9,"sound", 5))
QCC_PrecacheSound (e, func->name[14]);
else if (!strncmp(func->name+9,"model", 5))
QCC_PrecacheModel (e, func->name[14]);
else if (!strncmp(func->name+9,"texture", 7))
QCC_PrecacheTexture (e, func->name[16]);
else if (!strncmp(func->name+9,"file", 4))
QCC_PrecacheFile (e, func->name[13]);
}
}
if (arg>=MAX_PARMS)
{
if (!extra_parms[arg - MAX_PARMS])
{
d = (QCC_def_t *) qccHunkAlloc (sizeof(QCC_def_t));
d->name = "extra parm";
d->ofs = QCC_GetFreeOffsetSpace (3);
extra_parms[arg - MAX_PARMS] = d;
}
d = extra_parms[arg - MAX_PARMS];
QCC_PR_Lex();
QCC_PR_Expect(")");
}
else
d = &def_parms[arg];
if (pr_classtype && e->type->type == ev_field && p->type != ev_field)
{ //convert.
oself = QCC_PR_GetDef(type_entity, "self", NULL, true, 1);
switch(e->type->aux_type->type)
{ //bum
e = QCC_PR_Expression (TOP_PRIORITY);
if (e->type->type != ev_vector)
{
case ev_string:
e = QCC_PR_Statement(pr_opcodes+OP_LOAD_S, oself, e, NULL);
break;
case ev_integer:
e = QCC_PR_Statement(pr_opcodes+OP_LOAD_I, oself, e, NULL);
break;
case ev_float:
e = QCC_PR_Statement(pr_opcodes+OP_LOAD_F, oself, e, NULL);
break;
case ev_function:
e = QCC_PR_Statement(pr_opcodes+OP_LOAD_FNC, oself, e, NULL);
break;
case ev_vector:
e = QCC_PR_Statement(pr_opcodes+OP_LOAD_V, oself, e, NULL);
break;
case ev_entity:
e = QCC_PR_Statement(pr_opcodes+OP_LOAD_ENT, oself, e, NULL);
break;
default:
QCC_Error(ERR_INTERNAL, "Bad member type. Try forced expansion");
}
}
if (p)
{
if (typecmp(e->type, p))
/*if (e->type->type != ev_integer && p->type != ev_function)
if (e->type->type != ev_function && p->type != ev_integer)
if ( e->type->type != p->type )*/
{
if (p->type == ev_integer && e->type->type == ev_float) //convert float -> int... is this a constant?
e = QCC_PR_Statement(pr_opcodes+OP_CONV_FTOI, e, NULL, NULL);
else if (p->type == ev_float && e->type->type == ev_integer) //convert float -> int... is this a constant?
e = QCC_PR_Statement(pr_opcodes+OP_CONV_ITOF, e, NULL, NULL);
else if (p->type != ev_variant) //can cast to variant whatever happens
if (flag_laxcasts)
{
if (flag_laxcasts)
{
QCC_PR_ParseWarning(WARN_LAXCAST, "type mismatch on parm %i - (%s should be %s)", arg+1, TypeName(e->type), TypeName(p));
QCC_PR_ParsePrintDef(WARN_LAXCAST, func);
}
else
QCC_PR_ParseErrorPrintDef (ERR_TYPEMISMATCHPARM, func, "type mismatch on parm %i - (%s should be %s)", arg+1, TypeName(e->type), TypeName(p));
QCC_PR_ParseWarning(WARN_LAXCAST, "type mismatch on parm %i - (%s should be %s)", 1, TypeName(e->type), TypeName(type_vector));
QCC_PR_ParsePrintDef(WARN_LAXCAST, func);
}
else
QCC_PR_ParseErrorPrintDef (ERR_TYPEMISMATCHPARM, func, "type mismatch on parm %i - (%s should be %s)", 1, TypeName(e->type), TypeName(type_vector));
}
QCC_PR_Expect(")");
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_STORE_V], e, &def_parms[0], (QCC_dstatement_t **)0xffffffff));
}
}
else
{ //bother
e = QCC_PR_Expression (TOP_PRIORITY);
if (e->type->type != ev_vector)
{
if (flag_laxcasts)
{
QCC_PR_ParseWarning(WARN_LAXCAST, "type mismatch on parm %i - (%s should be %s)", 1, TypeName(e->type), TypeName(type_vector));
QCC_PR_ParsePrintDef(WARN_LAXCAST, func);
}
else
QCC_PR_ParseErrorPrintDef (ERR_TYPEMISMATCHPARM, func, "type mismatch on parm %i - (%s should be %s)", 1, TypeName(e->type), TypeName(type_vector));
}
QCC_PR_Expect(")");
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_STORE_V], e, &def_parms[0], (QCC_dstatement_t **)0xffffffff));
}
}
else
{
if (!QCC_PR_Check(")"))
{
p = t->param;
do
{
if (extraparms && arg >= MAX_PARMS)
QCC_PR_ParseErrorPrintDef (ERR_TOOMANYPARAMETERSVARARGS, func, "More than %i parameters on varargs function", MAX_PARMS);
else if (arg >= MAX_PARMS+MAX_EXTRA_PARMS)
QCC_PR_ParseErrorPrintDef (ERR_TOOMANYTOTALPARAMETERS, func, "More than %i parameters", MAX_PARMS+MAX_EXTRA_PARMS);
if (!extraparms && arg >= t->num_parms)
{
QCC_PR_ParseWarning (WARN_TOOMANYPARAMETERSFORFUNC, "too many parameters");
QCC_PR_ParsePrintDef(WARN_TOOMANYPARAMETERSFORFUNC, func);
}
e = QCC_PR_Expression (TOP_PRIORITY);
if (arg == 0 && func->name)
{
// save information for model and sound caching
if (!strncmp(func->name,"precache_", 9))
{
if (!strncmp(func->name+9,"sound", 5))
QCC_PrecacheSound (e, func->name[14]);
else if (!strncmp(func->name+9,"model", 5))
QCC_PrecacheModel (e, func->name[14]);
else if (!strncmp(func->name+9,"texture", 7))
QCC_PrecacheTexture (e, func->name[16]);
else if (!strncmp(func->name+9,"file", 4))
QCC_PrecacheFile (e, func->name[13]);
}
}
d->type = p;
if (arg>=MAX_PARMS)
{
if (!extra_parms[arg - MAX_PARMS])
{
d = (QCC_def_t *) qccHunkAlloc (sizeof(QCC_def_t));
d->name = "extra parm";
d->ofs = QCC_GetFreeOffsetSpace (3);
extra_parms[arg - MAX_PARMS] = d;
}
d = extra_parms[arg - MAX_PARMS];
}
else
d = &def_parms[arg];
p=p->next;
}
// a vector copy will copy everything
else
d->type = type_void;
if (pr_classtype && e->type->type == ev_field && p->type != ev_field)
{ //convert.
oself = QCC_PR_GetDef(type_entity, "self", NULL, true, 1);
switch(e->type->aux_type->type)
{
case ev_string:
e = QCC_PR_Statement(pr_opcodes+OP_LOAD_S, oself, e, NULL);
break;
case ev_integer:
e = QCC_PR_Statement(pr_opcodes+OP_LOAD_I, oself, e, NULL);
break;
case ev_float:
e = QCC_PR_Statement(pr_opcodes+OP_LOAD_F, oself, e, NULL);
break;
case ev_function:
e = QCC_PR_Statement(pr_opcodes+OP_LOAD_FNC, oself, e, NULL);
break;
case ev_vector:
e = QCC_PR_Statement(pr_opcodes+OP_LOAD_V, oself, e, NULL);
break;
case ev_entity:
e = QCC_PR_Statement(pr_opcodes+OP_LOAD_ENT, oself, e, NULL);
break;
default:
QCC_Error(ERR_INTERNAL, "Bad member type. Try forced expansion");
}
}
if (arg == 1 && !STRCMP(func->name, "setmodel"))
{
QCC_SetModel(e);
}
if (p)
{
if (typecmp(e->type, p))
/*if (e->type->type != ev_integer && p->type != ev_function)
if (e->type->type != ev_function && p->type != ev_integer)
if ( e->type->type != p->type )*/
{
if (p->type == ev_integer && e->type->type == ev_float) //convert float -> int... is this a constant?
e = QCC_PR_Statement(pr_opcodes+OP_CONV_FTOI, e, NULL, NULL);
else if (p->type == ev_float && e->type->type == ev_integer) //convert float -> int... is this a constant?
e = QCC_PR_Statement(pr_opcodes+OP_CONV_ITOF, e, NULL, NULL);
else if (p->type != ev_variant) //can cast to variant whatever happens
{
if (flag_laxcasts)
{
QCC_PR_ParseWarning(WARN_LAXCAST, "type mismatch on parm %i - (%s should be %s)", arg+1, TypeName(e->type), TypeName(p));
QCC_PR_ParsePrintDef(WARN_LAXCAST, func);
}
else
QCC_PR_ParseErrorPrintDef (ERR_TYPEMISMATCHPARM, func, "type mismatch on parm %i - (%s should be %s)", arg+1, TypeName(e->type), TypeName(p));
}
}
param[arg] = e;
/* if (e->type->size>1)
QCC_PR_Statement (&pr_opcodes[OP_STORE_V], e, d, (QCC_dstatement_t **)0xffffffff);
else
QCC_PR_Statement (&pr_opcodes[OP_STORE_F], e, d, (QCC_dstatement_t **)0xffffffff);
*/
arg++;
} while (QCC_PR_Check (","));
d->type = p;
if (t->num_parms != -1 && arg < np)
QCC_PR_ParseWarning (WARN_TOOFEWPARAMS, "too few parameters on call to %s", func->name);
QCC_PR_Expect (")");
}
else if (np)
{
QCC_PR_ParseWarning (WARN_TOOFEWPARAMS, "%s: Too few parameters", func->name);
QCC_PR_ParsePrintDef (WARN_TOOFEWPARAMS, func);
}
p=p->next;
}
// a vector copy will copy everything
else
d->type = type_void;
// qcc_functioncalled++;
for (i = 0; i < arg; i++)
{
if (i>=MAX_PARMS)
d = extra_parms[i - MAX_PARMS];
else
d = &def_parms[i];
if (arg == 1 && !STRCMP(func->name, "setmodel"))
{
QCC_SetModel(e);
}
if (callconvention == OP_CALL1H)
if (i < 2)
{
param[i]->references++;
d->references++;
QCC_FreeTemp(param[i]);
continue;
}
param[arg] = e;
/* if (e->type->size>1)
QCC_PR_Statement (&pr_opcodes[OP_STORE_V], e, d, (QCC_dstatement_t **)0xffffffff);
else
QCC_PR_Statement (&pr_opcodes[OP_STORE_F], e, d, (QCC_dstatement_t **)0xffffffff);
*/
arg++;
} while (QCC_PR_Check (","));
if (param[i]->type->size>1 || !opt_nonvec_parms)
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_STORE_V], param[i], d, (QCC_dstatement_t **)0xffffffff));
else
if (t->num_parms != -1 && arg < np)
QCC_PR_ParseWarning (WARN_TOOFEWPARAMS, "too few parameters on call to %s", func->name);
QCC_PR_Expect (")");
}
else if (np)
{
d->type = param[i]->type;
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_STORE_F], param[i], d, (QCC_dstatement_t **)0xffffffff));
optres_nonvec_parms++;
QCC_PR_ParseWarning (WARN_TOOFEWPARAMS, "%s: Too few parameters", func->name);
QCC_PR_ParsePrintDef (WARN_TOOFEWPARAMS, func);
}
// qcc_functioncalled++;
for (i = 0; i < arg; i++)
{
if (i>=MAX_PARMS)
d = extra_parms[i - MAX_PARMS];
else
d = &def_parms[i];
if (callconvention == OP_CALL1H)
if (i < 2)
{
param[i]->references++;
d->references++;
QCC_FreeTemp(param[i]);
continue;
}
if (param[i]->type->size>1 || !opt_nonvec_parms)
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_STORE_V], param[i], d, (QCC_dstatement_t **)0xffffffff));
else
{
d->type = param[i]->type;
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_STORE_F], param[i], d, (QCC_dstatement_t **)0xffffffff));
optres_nonvec_parms++;
}
}
}
@ -2684,11 +2753,19 @@ QCC_def_t *QCC_PR_ParseFunctionCall (QCC_def_t *func) //warning, the func could
if (old)
{
d = QCC_GetTemp(t->aux_type);
if (t->aux_type->size == 3)
QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_STORE_V, &def_ret, d, NULL));
else
if (t->type == ev_variant)
{
d = QCC_GetTemp(type_variant);
QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_STORE_F, &def_ret, d, NULL));
}
else
{
d = QCC_GetTemp(t->aux_type);
if (t->aux_type->size == 3)
QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_STORE_V, &def_ret, d, NULL));
else
QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_STORE_F, &def_ret, d, NULL));
}
if (def_ret.type->size == 3)
QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_STORE_V, old, &def_ret, NULL));
else
@ -2700,7 +2777,10 @@ QCC_def_t *QCC_PR_ParseFunctionCall (QCC_def_t *func) //warning, the func could
return d;
}
def_ret.type = t->aux_type;
if (t->type == ev_variant)
def_ret.type = type_variant;
else
def_ret.type = t->aux_type;
if (def_ret.temp->used)
QCC_PR_ParseWarning(WARN_FIXEDRETURNVALUECONFLICT, "Return value conflict - output is inefficient");
def_ret.temp->used = true;
@ -3136,7 +3216,7 @@ QCC_def_t *QCC_PR_ParseValue (QCC_type_t *assumeclass)
}
else
{
od = d = QCC_PR_GetDef (type_float, name, pr_scope, true, 1);
od = d = QCC_PR_GetDef (type_variant, name, pr_scope, true, 1);
if (!d)
QCC_PR_ParseError (ERR_UNKNOWNVALUE, "Unknown value \"%s\"", name);
else
@ -5240,18 +5320,22 @@ void QCC_PR_ParseState (void)
QCC_def_t *framef, *frame;
QCC_def_t *self;
QCC_def_t *cycle_wrapped;
temp_t *ftemp;
self = QCC_PR_GetDef(type_entity, "self", NULL, false, 0);
framef = QCC_PR_GetDef(NULL, "frame", NULL, false, 0);
cycle_wrapped = QCC_PR_GetDef(type_float, "cycle_wrapped", NULL, false, 0);
frame = QCC_PR_Statement(&pr_opcodes[OP_LOAD_F], self, framef, NULL);
QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_F], QCC_MakeFloatDef(0), cycle_wrapped, NULL));
if (cycle_wrapped)
QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_F], QCC_MakeFloatDef(0), cycle_wrapped, NULL));
QCC_UnFreeTemp(frame);
//make sure the frame is within the bounds given.
ftemp = frame->temp;
frame->temp = NULL;
t1 = QCC_PR_Statement(&pr_opcodes[OP_LT], frame, s1, NULL);
QCC_UnFreeTemp(frame);
t2 = QCC_PR_Statement(&pr_opcodes[OP_GT], frame, def, NULL);
QCC_UnFreeTemp(frame);
t1 = QCC_PR_Statement(&pr_opcodes[OP_OR], t1, t2, NULL);
QCC_PR_SimpleStatement(OP_IFNOT, t1->ofs, 2, 0);
QCC_FreeTemp(t1);
@ -5267,7 +5351,8 @@ void QCC_PR_ParseState (void)
QCC_FreeTemp(t1);
QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_F], s1, frame, NULL));
QCC_UnFreeTemp(frame);
QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_F], QCC_MakeFloatDef(1), cycle_wrapped, NULL));
if (cycle_wrapped)
QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_F], QCC_MakeFloatDef(1), cycle_wrapped, NULL));
QCC_PR_SimpleStatement(OP_GOTO, 6, 0, 0);
//reverse animation.
@ -5277,10 +5362,13 @@ void QCC_PR_ParseState (void)
QCC_FreeTemp(t1);
QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_F], def, frame, NULL));
QCC_UnFreeTemp(frame);
QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_F], QCC_MakeFloatDef(1), cycle_wrapped, NULL));
if (cycle_wrapped)
QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_F], QCC_MakeFloatDef(1), cycle_wrapped, NULL));
//self.frame = frame happens with the normal state opcode.
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_STATE], frame, pr_scope, NULL));
frame->temp = ftemp;
QCC_FreeTemp(frame);
}
return;
@ -7158,7 +7246,7 @@ void QCC_PR_ParseDefs (char *classname)
return;
}
if (1)//flag_acc)
if (flag_acc)
{
char *oldp;
if (QCC_PR_CheckInsens ("CodeSys")) //reacc support.
@ -7451,17 +7539,53 @@ void QCC_PR_ParseDefs (char *classname)
if ( QCC_PR_Check ("[") )
{
if (pr_immediate_type->type == ev_integer)
arraysize = pr_immediate._int;
else if (pr_immediate_type->type == ev_float && (float)(int)pr_immediate._float == pr_immediate._float)
arraysize = (int)pr_immediate._float;
char *oldprfile = pr_file_p;
arraysize = 0;
if (QCC_PR_Check("]"))
{
QCC_PR_Expect("=");
QCC_PR_Expect("{");
QCC_PR_Lex();
arraysize++;
while(1)
{
if(pr_token_type == tt_eof)
break;
if (QCC_PR_Check(","))
arraysize++;
if (QCC_PR_Check("}"))
break;
QCC_PR_Lex();
}
pr_file_p = oldprfile;
QCC_PR_Lex();
}
else
{
if(pr_token_type == tt_name)
{
def = QCC_PR_GetDef(NULL, QCC_PR_ParseName(), pr_scope, false, 0);
if (def && def->arraysize==1)
{
if (def->type->type == ev_integer)
arraysize = G_INT(def->ofs);
else if (def->type->type == ev_float && (float)(int)G_FLOAT(def->ofs) == G_FLOAT(def->ofs))
arraysize = (int)G_FLOAT(def->ofs);
}
}
else if (pr_token_type == tt_immediate)
{
arraysize = atoi (pr_token);
QCC_PR_Lex();
}
QCC_PR_Expect("]");
}
if (arraysize < 1)
{
QCC_PR_ParseError (ERR_BADARRAYSIZE, "Definition of array (%s) size is not of a numerical value", name);
arraysize=0; //grrr...
}
QCC_PR_Lex();
QCC_PR_Expect("]");
}
else
arraysize = 1;
@ -7636,16 +7760,21 @@ lazyfunctiondeclaration:
i = 0;
do
{
name = QCC_PR_ParseName ();
d = QCC_PR_GetDef (NULL, name, pr_scope, false, 0);
if (!d)
QCC_PR_ParseError(ERR_NOTDEFINED, "%s was not defined", name);
if (QCC_PR_Check("0"))
G_FUNCTION(def->ofs+i) = 0;
else
{
if (!d->initialized)
QCC_PR_ParseWarning(WARN_NOTDEFINED, "initialisation of function arrays must be placed after the body of all functions used (%s)", name);
G_FUNCTION(def->ofs+i) = G_FUNCTION(d->ofs);
name = QCC_PR_ParseName ();
d = QCC_PR_GetDef (NULL, name, pr_scope, false, 0);
if (!d)
QCC_PR_ParseError(ERR_NOTDEFINED, "%s was not defined", name);
else
{
if (!d->initialized)
QCC_PR_ParseWarning(WARN_NOTDEFINED, "initialisation of function arrays must be placed after the body of all functions used (%s)", name);
G_FUNCTION(def->ofs+i) = G_FUNCTION(d->ofs);
}
}
i++;

View File

@ -60,11 +60,12 @@ QCC_type_t *type_function;// = {ev_function/*, &def_function*/,NULL,&type_void};
// type_function is a void() function used for state defs
QCC_type_t *type_pointer;// = {ev_pointer/*, &def_pointer*/};
QCC_type_t *type_integer;// = {ev_integer/*, &def_integer*/};
QCC_type_t *type_variant;// = {ev_integer/*, &def_integer*/};
QCC_type_t *type_floatfield;// = {ev_field/*, &def_field*/, NULL, &type_float};
#ifdef QCCONLY
const int type_size[9] = {1,1,1,3,1,1,1,1,1};
const int type_size[12] = {1,1,1,3,1,1,1,1,1, 1, 0,0};
#endif
/*QCC_def_t def_void = {type_void, "temp"};
@ -141,47 +142,32 @@ void QCC_PR_PrintNextLine (void)
printf ("\n");
}
/*
==============
PR_NewLine
Call at start of file and when *pr_file_p == '\n'
==============
*/
int ForcedCRC;
int QCC_PR_LexInteger (void);
void QCC_AddFile (char *filename);
void QCC_PR_LexString (void);
pbool QCC_PR_SimpleGetToken (void);
void QCC_PR_NewLine (pbool incomment)
/*
==============
QCC_PR_Precompiler
==============
Runs precompiler stage
*/
pbool QCC_PR_Precompiler(void)
{
char msg[1024];
int ifmode;
int a;
pbool m;
static int ifs = 0;
int level; //#if level
pbool eval = false;
if (*pr_file_p == '\n')
{
pr_file_p++;
m = true;
}
else
m = false;
pr_source_line++;
pr_line_start = pr_file_p;
while(*pr_file_p==' ' || *pr_file_p == '\t')
pr_file_p++;
if (incomment) //no constants if in a comment.
{
}
else if (*pr_file_p == '#')
if (*pr_file_p == '#')
{
char *directive;
for (directive = pr_file_p+1; *directive; directive++)
for (directive = pr_file_p+1; *directive; directive++) //so # define works
{
if (*directive == '\r' || *directive == '\n')
QCC_PR_ParseError(ERR_UNKNOWNPUCTUATION, "Hanging # with no directive\n");
@ -196,8 +182,6 @@ void QCC_PR_NewLine (pbool incomment)
{
pr_file_p++;
}
if (!m)
pr_file_p++;
}
else if (!strncmp(directive, "undef", 5))
{
@ -213,8 +197,6 @@ void QCC_PR_NewLine (pbool incomment)
{
pr_file_p++;
}
if (!m)
pr_file_p++;
}
else if (!strncmp(directive, "if", 2))
{
@ -259,7 +241,7 @@ void QCC_PR_NewLine (pbool incomment)
if (QCC_PR_CheckCompConstDefined(pr_token))
eval = true;
if (ifmode == 1)
if (ifmode == 1)
eval = eval?false:true;
}
@ -315,7 +297,7 @@ void QCC_PR_NewLine (pbool incomment)
ifs -= 1;
level = 1;
while(*pr_file_p != '\n' && *pr_file_p != '\0') //read on until the end of the line
{
pr_file_p++;
@ -372,7 +354,7 @@ void QCC_PR_NewLine (pbool incomment)
else if (!strncmp(directive, "eof", 3))
{
pr_file_p = NULL;
return;
return true;
}
else if (!strncmp(directive, "error", 5))
{
@ -684,7 +666,7 @@ void QCC_PR_NewLine (pbool incomment)
{
if (qcc_targetformat == QCF_HEXEN2 && numstatements)
QCC_PR_ParseWarning(WARN_BADTARGET, "Cannot switch from hexen2 target \'%s\'. Ignored.", msg);
else if (!QC_strcasecmp(msg, "H2"))
else if (!QC_strcasecmp(msg, "H2") || !QC_strcasecmp(msg, "HEXEN2"))
{
if (numstatements)
QCC_PR_ParseWarning(WARN_BADTARGET, "Cannot switch from hexen2 target \'%s\'. Ignored.", msg);
@ -697,21 +679,10 @@ void QCC_PR_NewLine (pbool incomment)
qcc_targetformat = QCF_FTEDEBUG;
else if (!QC_strcasecmp(msg, "FTE"))
qcc_targetformat = QCF_FTE;
else if (!QC_strcasecmp(msg, "FTEDEBUG32") || !QC_strcasecmp(msg, "FTE32DEBUG"))
qcc_targetformat = QCF_FTEDEBUG32;
else if (!QC_strcasecmp(msg, "FTE32"))
qcc_targetformat = QCF_FTE32;
else if (!QC_strcasecmp(msg, "STANDARD") || !QC_strcasecmp(msg, "ID"))
qcc_targetformat = QCF_STANDARD;
else if (!QC_strcasecmp(msg, "DEBUG"))
{
if (qcc_targetformat == QCF_FTE32)
qcc_targetformat = QCF_FTEDEBUG32;
else if (qcc_targetformat == QCF_FTE)
qcc_targetformat = QCF_FTEDEBUG;
else if (qcc_targetformat == QCF_STANDARD)
qcc_targetformat = QCF_FTEDEBUG;
}
qcc_targetformat = QCF_FTEDEBUG;
else
QCC_PR_ParseWarning(WARN_BADTARGET, "Unknown target \'%s\'. Ignored.", msg);
}
@ -757,6 +728,40 @@ void QCC_PR_NewLine (pbool incomment)
else
QCC_PR_ParseWarning(WARN_BADPRAGMA, "Unknown pragma \'%s\'", qcc_token);
}
return true;
}
return false;
}
/*
==============
PR_NewLine
Call at start of file and when *pr_file_p == '\n'
==============
*/
void QCC_PR_NewLine (pbool incomment)
{
pbool m;
if (*pr_file_p == '\n')
{
pr_file_p++;
m = true;
}
else
m = false;
pr_source_line++;
pr_line_start = pr_file_p;
while(*pr_file_p==' ' || *pr_file_p == '\t')
pr_file_p++;
if (incomment) //no constants if in a comment.
{
}
else if (QCC_PR_Precompiler())
{
}
// if (pr_dumpasm)
@ -1380,7 +1385,7 @@ void QCC_PR_LexWhitespace (void)
//============================================================================
#define MAX_FRAMES 8192
char pr_framemodelname[64];
char pr_framemacros[MAX_FRAMES][16];
int pr_framemacrovalue[MAX_FRAMES];
int pr_nummacros, pr_oldmacros;
@ -1395,35 +1400,39 @@ void QCC_PR_ClearGrabMacros (void)
pr_savedmacro = -1;
}
void QCC_PR_FindMacro (void)
int QCC_PR_FindMacro (char *name)
{
int i;
for (i=pr_nummacros-1 ; i>=0 ; i--)
{
if (!STRCMP (pr_token, pr_framemacros[i]))
if (!STRCMP (name, pr_framemacros[i]))
{
sprintf (pr_token,"%d", pr_framemacrovalue[i]);
pr_token_type = tt_immediate;
pr_immediate_type = type_float;
pr_immediate._float = (float)pr_framemacrovalue[i];
return;
return pr_framemacrovalue[i];
}
}
for (i=pr_nummacros-1 ; i>=0 ; i--)
{
if (!stricmp (pr_token, pr_framemacros[i]))
if (!stricmp (name, pr_framemacros[i]))
{
sprintf (pr_token,"%d", pr_framemacrovalue[i]);
pr_token_type = tt_immediate;
pr_immediate_type = type_float;
pr_immediate._float = (float)pr_framemacrovalue[i];
QCC_PR_ParseWarning(WARN_CASEINSENSATIVEFRAMEMACRO, "Case insensative frame macro");
return;
return pr_framemacrovalue[i];
}
}
QCC_PR_ParseError (ERR_BADFRAMEMACRO, "Unknown frame macro $%s", pr_token);
return -1;
}
void QCC_PR_ExpandMacro(void)
{
int i = QCC_PR_FindMacro(pr_token);
if (i < 0)
QCC_PR_ParseError (ERR_BADFRAMEMACRO, "Unknown frame macro $%s", pr_token);
sprintf (pr_token,"%d", i);
pr_token_type = tt_immediate;
pr_immediate_type = type_float;
pr_immediate._float = (float)i;
}
// just parses text, returning false if an eol is reached
@ -1447,6 +1456,8 @@ pbool QCC_PR_SimpleGetToken (void)
pr_file_p++;
return false;
}
if (pr_file_p[1] == '*')
return false;
}
i = 0;
@ -1457,33 +1468,36 @@ pbool QCC_PR_SimpleGetToken (void)
pr_file_p++;
}
pr_token[i] = 0;
return true;
return i!=0;
}
void QCC_PR_MacroFrame(char *name, int value)
{
int i;
for (i=pr_nummacros-1 ; i>=0 ; i--)
{
if (!STRCMP (name, pr_framemacros[i]))
{
pr_framemacrovalue[i] = value;
if (i>=pr_oldmacros)
QCC_PR_ParseWarning(WARN_DUPLICATEMACRO, "Duplicate macro defined (%s)", pr_token);
//else it's from an old file, and shouldn't be mentioned.
return;
}
}
strcpy (pr_framemacros[pr_nummacros], name);
pr_framemacrovalue[pr_nummacros] = value;
pr_nummacros++;
if (pr_nummacros >= MAX_FRAMES)
QCC_PR_ParseError(ERR_TOOMANYFRAMEMACROS, "Too many frame macros defined");
}
void QCC_PR_ParseFrame (void)
{
int i;
while (QCC_PR_SimpleGetToken ())
{
for (i=pr_nummacros-1 ; i>=0 ; i--)
{
if (!STRCMP (pr_token, pr_framemacros[i]))
{
pr_framemacrovalue[i] = pr_macrovalue++;
if (i>pr_oldmacros)
QCC_PR_ParseWarning(WARN_DUPLICATEMACRO, "Duplicate macro defined (%s)", pr_token);
break;
}
}
if (i>=0)
continue;
strcpy (pr_framemacros[pr_nummacros], pr_token);
pr_framemacrovalue[pr_nummacros] = pr_macrovalue++;
pr_nummacros++;
if (pr_nummacros >= MAX_FRAMES)
QCC_PR_ParseError(ERR_TOOMANYFRAMEMACROS, "Too many frame macros defined");
QCC_PR_MacroFrame(pr_token, pr_macrovalue++);
}
}
@ -1540,14 +1554,33 @@ void QCC_PR_LexGrab (void)
else if (!STRCMP (pr_token, "framerestore"))
{
QCC_PR_SimpleGetToken ();
QCC_PR_FindMacro();
QCC_PR_ExpandMacro();
pr_macrovalue = (int)pr_immediate._float;
QCC_PR_Lex ();
}
else if (!STRCMP (pr_token, "modelname"))
{
int i;
QCC_PR_SimpleGetToken ();
if (*pr_framemodelname)
QCC_PR_MacroFrame(pr_framemodelname, pr_macrovalue);
strncpy(pr_framemodelname, pr_token, sizeof(pr_framemodelname)-1);
pr_framemodelname[sizeof(pr_framemodelname)-1] = '\0';
i = QCC_PR_FindMacro(pr_framemodelname);
if (i)
pr_macrovalue = i;
else
i = 0;
QCC_PR_Lex ();
}
// look for a frame name macro
else
QCC_PR_FindMacro ();
QCC_PR_ExpandMacro ();
}
//===========================
@ -1834,13 +1867,17 @@ int QCC_PR_CheakCompConst(void)
}
strncpy(pr_token, pr_file_p, end-pr_file_p);
pr_token[end-pr_file_p]='\0';
if (!strcmp(pr_token, "varkeyword"))
printf("varkeyword!!!\n");
// printf("%s\n", pr_token);
c = pHash_Get(&compconstantstable, pr_token);
if (c)
{
pr_file_p = oldpr_file_p+strlen(c->name);
QCC_PR_LexWhitespace();
while(*pr_file_p == ' ' || *pr_file_p == '\t')
pr_file_p++;
if (c->numparams>=0)
{
if (*pr_file_p == '(')
@ -1853,7 +1890,8 @@ int QCC_PR_CheakCompConst(void)
int plevel=0;
pr_file_p++;
QCC_PR_LexWhitespace();
while(*pr_file_p == ' ' || *pr_file_p == '\t')
pr_file_p++;
start = pr_file_p;
while(1)
{
@ -1871,7 +1909,8 @@ int QCC_PR_CheakCompConst(void)
}
*pr_file_p = '\0';
pr_file_p++;
QCC_PR_LexWhitespace();
while(*pr_file_p == ' ' || *pr_file_p == '\t')
pr_file_p++;
if (param == MAXCONSTANTPARAMS)
QCC_PR_ParseError(ERR_TOOMANYPARAMS, "Too many parameters in macro call");
} else if (*pr_file_p == ')' )
@ -1900,7 +1939,7 @@ int QCC_PR_CheakCompConst(void)
}
buffer[p] = 0;
if (*pr_file_p == '#') //if you ask for #a##b you will be shot. use #a #b instead.
if (*pr_file_p == '#') //if you ask for #a##b you will be shot. use #a #b instead, or chain macros.
{
if (pr_file_p[1] == '#')
{ //concatinate (srip out whitespace)
@ -2986,6 +3025,8 @@ QCC_type_t *QCC_PR_ParseType (int newtype)
if (i == numtypeinfos)
{
if (!*name)
return NULL;
if (!stricmp("Void", name))
type = type_void;
else if (!stricmp("Real", name))

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,17 @@
#include "qcc.h"
#include "gui.h"
//common gui things
pbool fl_hexen2;
pbool fl_autohighlight;
pbool fl_compileonstart;
pbool fl_showall;
char parameters[16384];
char progssrcname[256];
char progssrcdir[256];
void GoToDefinition(char *name)
{
QCC_def_t *def;
@ -19,7 +30,7 @@ void GoToDefinition(char *name)
if (!globalstable.numbuckets)
{
MessageBox(NULL, "You need to compile first.", "Not found", 0);
GUI_DialogPrint("Not found", "You need to compile first.");
return;
}
@ -40,5 +51,246 @@ void GoToDefinition(char *name)
EditFile(def->s_file+strings, def->s_line-1);
}
else
MessageBox(NULL, "Global instance of var was not found", "Not found", 0);
GUI_DialogPrint("Not found", "Global instance of var was not found.");
}
//this function takes the windows specified commandline and strips out all the options menu items.
void GUI_ParseCommandLine(char *args)
{
int paramlen=0;
int l, p;
char *next;
while(*args)
{
while (*args <= ' ' && *args)
args++;
for (next = args; *next>' '; next++)
;
strncpy(parameters+paramlen, args, next-args);
parameters[paramlen+next-args] = '\0';
l = strlen(parameters+paramlen)+1;
if (!strnicmp(parameters+paramlen, "-O", 2) || !strnicmp(parameters+paramlen, "/O", 2))
{ //strip out all -O
if (parameters[paramlen+2])
{
if (parameters[paramlen+2] >= '0' && parameters[paramlen+2] <= '3')
{
p = parameters[paramlen+2]-'0';
for (l = 0; optimisations[l].enabled; l++)
{
if (optimisations[l].optimisationlevel<=p)
optimisations[l].flags |= FLAG_SETINGUI;
else
optimisations[l].flags &= ~FLAG_SETINGUI;
}
}
else if (!strncmp(parameters+paramlen+2, "no-", 3))
{
if (parameters[paramlen+5])
{
for (p = 0; optimisations[p].enabled; p++)
if ((*optimisations[p].abbrev && !strcmp(parameters+paramlen+5, optimisations[p].abbrev)) || !strcmp(parameters+paramlen+5, optimisations[p].fullname))
{
optimisations[p].flags &= ~FLAG_SETINGUI;
break;
}
if (!optimisations[p].enabled)
{
parameters[paramlen+next-args] = ' ';
paramlen += l;
}
}
}
else
{
for (p = 0; optimisations[p].enabled; p++)
if ((*optimisations[p].abbrev && !strcmp(parameters+paramlen+2, optimisations[p].abbrev)) || !strcmp(parameters+paramlen+2, optimisations[p].fullname))
{
optimisations[p].flags |= FLAG_SETINGUI;
break;
}
if (!optimisations[p].enabled)
{
parameters[paramlen+next-args] = ' ';
paramlen += l;
}
}
}
}
/*
else if (!strnicmp(parameters+paramlen, "-Fno-kce", 8) || !strnicmp(parameters+paramlen, "/Fno-kce", 8)) //keywords stuph
{
fl_nokeywords_coexist = true;
}
else if (!strnicmp(parameters+paramlen, "-Fkce", 5) || !strnicmp(parameters+paramlen, "/Fkce", 5))
{
fl_nokeywords_coexist = false;
}
else if (!strnicmp(parameters+paramlen, "-Facc", 5) || !strnicmp(parameters+paramlen, "/Facc", 5))
{
fl_acc = true;
}
else if (!strnicmp(parameters+paramlen, "-autoproto", 10) || !strnicmp(parameters+paramlen, "/autoproto", 10))
{
fl_autoprototype = true;
}
*/
else if (!strnicmp(parameters+paramlen, "-showall", 8) || !strnicmp(parameters+paramlen, "/showall", 8))
{
fl_showall = true;
}
else if (!strnicmp(parameters+paramlen, "-ah", 3) || !strnicmp(parameters+paramlen, "/ah", 3))
{
fl_autohighlight = true;
}
else if (!strnicmp(parameters+paramlen, "-ac", 3) || !strnicmp(parameters+paramlen, "/ac", 3))
{
fl_compileonstart = true;
}
else if (!strnicmp(parameters+paramlen, "-T", 2) || !strnicmp(parameters+paramlen, "/T", 2)) //the target
{
if (!strnicmp(parameters+paramlen+2, "h2", 2))
{
fl_hexen2 = true;
}
else
{
fl_hexen2 = false;
parameters[paramlen+next-args] = ' ';
paramlen += l;
}
}
else
{
parameters[paramlen+next-args] = ' ';
paramlen += l;
}
args=next;
}
if (paramlen)
parameters[paramlen-1] = '\0';
else
*parameters = '\0';
}
void GUI_SetDefaultOpts(void)
{
int i;
for (i = 0; compiler_flag[i].enabled; i++) //enabled is a pointer
{
if (compiler_flag[i].flags & FLAG_ASDEFAULT)
compiler_flag[i].flags |= FLAG_SETINGUI;
else
compiler_flag[i].flags &= ~FLAG_SETINGUI;
}
for (i = 0; optimisations[i].enabled; i++) //enabled is a pointer
{
if (optimisations[i].flags & FLAG_ASDEFAULT)
optimisations[i].flags |= FLAG_SETINGUI;
else
optimisations[i].flags &= ~FLAG_SETINGUI;
}
}
void GUI_RevealOptions(void)
{
int i;
for (i = 0; compiler_flag[i].enabled; i++) //enabled is a pointer
{
if (fl_showall && compiler_flag[i].flags & FLAG_HIDDENINGUI)
compiler_flag[i].flags &= ~FLAG_HIDDENINGUI;
}
for (i = 0; optimisations[i].enabled; i++) //enabled is a pointer
{
if (fl_showall && optimisations[i].flags & FLAG_HIDDENINGUI)
optimisations[i].flags &= ~FLAG_HIDDENINGUI;
if (optimisations[i].flags & FLAG_HIDDENINGUI) //hidden optimisations are disabled as default
optimisations[i].optimisationlevel = 4;
}
}
int GUI_BuildParms(char *args, char **argv)
{
static char param[2048];
int paramlen = 0;
int argc;
char *next;
int i;
argc = 1;
argv[0] = "fteqcc";
while(*args)
{
while (*args <= ' '&& *args)
args++;
for (next = args; *next>' '; next++)
;
strncpy(param+paramlen, args, next-args);
param[paramlen+next-args] = '\0';
argv[argc++] = param+paramlen;
paramlen += strlen(param+paramlen)+1;
args=next;
}
if (fl_hexen2)
{
strcpy(param+paramlen, "-Th2");
argv[argc++] = param+paramlen;
paramlen += strlen(param+paramlen)+1;
}
for (i = 0; optimisations[i].enabled; i++) //enabled is a pointer
{
if (optimisations[i].flags & FLAG_SETINGUI)
sprintf(param+paramlen, "-O%s", optimisations[i].abbrev);
else
sprintf(param+paramlen, "-Ono-%s", optimisations[i].abbrev);
argv[argc++] = param+paramlen;
paramlen += strlen(param+paramlen)+1;
}
/* while(*args)
{
while (*args <= ' '&& *args)
args++;
for (next = args; *next>' '; next++)
;
strncpy(param+paramlen, args, next-args);
param[paramlen+next-args] = '\0';
argv[argc++] = param+paramlen;
paramlen += strlen(param+paramlen)+1;
args=next;
}*/
if (*progssrcname)
{
argv[argc++] = "-srcfile";
argv[argc++] = progssrcname;
}
if (*progssrcdir)
{
argv[argc++] = "-src";
argv[argc++] = progssrcdir;
}
return argc;
}

View File

@ -4,8 +4,6 @@
#include "qcc.h"
int mkdir(const char *path);
int outputversion;
char QCC_copyright[1024];
int QCC_packid;
char QCC_Packname[5][128];
@ -40,6 +38,7 @@ int *qcc_tempofs;
int tempsstart;
int numtemps;
pbool compressoutput;
pbool newstylesource;
char destfile[1024];
@ -152,66 +151,64 @@ optimisations_t optimisations[] =
//level 2 = speed optimisations
//level 3 = dodgy optimisations.
//level 4 = experimental...
{&opt_assignments, "t", 1, 2, "assignments"},
{&opt_shortenifnots, "i", 1, 2, "shortenifs"},
{&opt_nonvec_parms, "p", 1, 2, "nonvec_parms"},
{&opt_constant_names, "c", 2, 1, "constant_names"},
{&opt_constant_names_strings, "cs", 3, 1, "constant_names_strings"},
{&opt_dupconstdefs, "d", 1, 2, "dupconstdefs"},
{&opt_noduplicatestrings, "s", 1, 0, "noduplicatestrings"},
{&opt_locals, "l", 1, 1, "locals"},
{&opt_function_names, "n", 1, 1, "function_names"},
{&opt_filenames, "f", 1, 1, "filenames"},
{&opt_unreferenced, "u", 1, 2, "unreferenced"},
{&opt_overlaptemps, "r", 1, 2, "overlaptemps"},
{&opt_constantarithmatic, "a", 1, 2, "constantarithmatic"},
{&opt_precache_file, "pf", 2, 0, "precache_file"},
{&opt_return_only, "ro", 3, 0, "return_only"},
{&opt_compound_jumps, "cj", 3, 0, "compound_jumps"},
// {&opt_comexprremoval, "cer", 4, 0, "expression_removal"}, //this would be too hard...
{&opt_stripfunctions, "sf", 3, 0, "strip_functions"},
{&opt_locals_marshalling, "lm", 4, 1, "locals_marshalling"},
{&opt_logicops, "o", 2, 0, "logicops"},
{&opt_assignments, "t", 1, FLAG_ASDEFAULT, "assignments", "c = a*b is performed in one operation rather than two, and can cause older decompilers to fail."},
{&opt_shortenifnots, "i", 1, FLAG_ASDEFAULT, "shortenifs", "if (!a) was traditionally compiled in two statements. This optimisation does it in one, but can cause some decompilers to get confused."},
{&opt_nonvec_parms, "p", 1, FLAG_ASDEFAULT, "nonvec_parms", "In the origional qcc, function parameters were specified as a vector store even for floats. This fixes that."},
{&opt_constant_names, "c", 2, FLAG_KILLSDEBUGGERS, "constant_names", "This optimisation strips out the names of constants (but not strings) from your progs, resulting in smaller files. It makes decompilers leave out names or fabricate numerical ones."},
{&opt_constant_names_strings, "cs", 3, FLAG_KILLSDEBUGGERS, "constant_names_strings", "This optimisation strips out the names of string constants from your progs. However, this can break addons, so don't use it in those cases."},
{&opt_dupconstdefs, "d", 1, FLAG_ASDEFAULT, "dupconstdefs", "This will merge definitions of constants which are the same value. Pay extra attention to assignment to constant warnings."},
{&opt_noduplicatestrings, "s", 1, 0, "noduplicatestrings", "This will compact the string table that is stored in the progs. It will be considerably smaller with this."},
{&opt_locals, "l", 1, FLAG_KILLSDEBUGGERS, "locals", "Strips out local names and definitions. This makes it REALLY hard to decompile"},
{&opt_function_names, "n", 1, FLAG_KILLSDEBUGGERS, "function_names", "This strips out the names of functions which are never called. Doesn't make much of an impact though."},
{&opt_filenames, "f", 1, FLAG_KILLSDEBUGGERS, "filenames", "This strips out the filenames of the progs. This can confuse the really old decompilers, but is nothing to the more recent ones."},
{&opt_unreferenced, "u", 1, FLAG_ASDEFAULT, "unreferenced", "Removes the entries of unreferenced variables. Doesn't make a difference in well maintained code."},
{&opt_overlaptemps, "r", 1, FLAG_ASDEFAULT, "overlaptemps", "Optimises the pr_globals count by overlapping temporaries. In QC, every multiplication, division or operation in general produces a temporary variable. This optimisation prevents excess, and in the case of Hexen2's gamecode, reduces the count by 50k. This is the most important optimisation, ever."},
{&opt_constantarithmatic, "a", 1, FLAG_ASDEFAULT, "constantarithmatic", "5*6 actually emits an operation into the progs. This prevents that happening, effectivly making the compiler see 30"},
{&opt_precache_file, "pf", 2, 0, "precache_file", "Strip out stuff wasted used in function calls and strings to the precache_file builtin (which is actually a stub in quake)."},
{&opt_return_only, "ro", 3, 0, "return_only", "Functions ending in a return statement do not need a done statement at the end of the function. This can confuse some decompilers, making functions appear larger than they were."},
{&opt_compound_jumps, "cj", 3, 0, "compound_jumps", "This optimisation plays an effect mostly with nested if/else statements, instead of jumping to an unconditional jump statement, it'll jump to the final destination instead. This will bewilder decompilers."},
// {&opt_comexprremoval, "cer", 4, 0, "expression_removal", "Eliminate common sub-expressions"}, //this would be too hard...
{&opt_stripfunctions, "sf", 3, 0, "strip_functions", "Strips out the 'defs' of functions that were only ever called directly. This does not affect saved games."},
{&opt_locals_marshalling, "lm", 4, FLAG_HIDDENINGUI|FLAG_KILLSDEBUGGERS, "locals_marshalling", "Store all locals in one section of the pr_globals. Vastly reducing it. This effectivly does the job of overlaptemps. It's been noticed as buggy by a few, however, and the curcumstances where it causes problems are not yet known."},
{&opt_vectorcalls, "vc", 4, 0, "vectorcalls", "Where a function is called with just a vector, this causes the function call to store three floats instead of one vector. This can save a good number of pr_globals where those vectors contain many duplicate coordinates but do not match entirly."},
{NULL}
};
struct {
pbool *enabled;
pbool defaultval;
char *name;
} compiler_flag[] = {
compiler_flag_t compiler_flag[] = {
//keywords
{&keyword_var, true, "var"},
{&keyword_thinktime, false, "thinktime"},
{&keyword_switch, true, "switch"},
{&keyword_for, true, "for"},
{&keyword_case, true, "case"},
{&keyword_default, true, "default"},
{&keyword_do, true, "do"},
{&keyword_asm, true, "asm"},
{&keyword_goto, true, "goto"},
{&keyword_break, true, "break"},
{&keyword_continue, true, "continue"},
{&keyword_state, false, "state"},
{&keyword_string, true, "string"},
{&keyword_float, true, "float"},
{&keyword_entity, true, "entity"},
{&keyword_vector, true, "vector"},
{&keyword_const, true, "const"},
{&keyword_integer, true, "integer"},
{&keyword_int, true, "int"},
{&keyword_class, true, "class"},
{&keyword_var, FLAG_HIDDENINGUI|FLAG_ASDEFAULT, "var", "Keyword: var", "Disables the 'var' keyword."},
{&keyword_thinktime, FLAG_HIDDENINGUI|0, "thinktime", "Keyword: thinktime", "Disables the 'thinktime' keyword."},
{&keyword_switch, FLAG_HIDDENINGUI|FLAG_ASDEFAULT, "switch", "Keyword: switch", "Disables the 'switch' keyword."},
{&keyword_for, FLAG_HIDDENINGUI|FLAG_ASDEFAULT, "for", "Keyword: for", "Disables the 'for' keyword."},
{&keyword_case, FLAG_HIDDENINGUI|FLAG_ASDEFAULT, "case", "Keyword: case", "Disables the 'case' keyword."},
{&keyword_default, FLAG_HIDDENINGUI|FLAG_ASDEFAULT, "default", "Keyword: default", "Disables the 'default' keyword."},
{&keyword_do, FLAG_HIDDENINGUI|FLAG_ASDEFAULT, "do", "Keyword: do", "Disables the 'do' keyword."},
{&keyword_asm, FLAG_HIDDENINGUI|FLAG_ASDEFAULT, "asm", "Keyword: asm", "Disables the 'asm' keyword."},
{&keyword_goto, FLAG_HIDDENINGUI|FLAG_ASDEFAULT, "goto", "Keyword: goto", "Disables the 'goto' keyword."},
{&keyword_break, FLAG_HIDDENINGUI|FLAG_ASDEFAULT, "break", "Keyword: break", "Disables the 'break' keyword."},
{&keyword_continue, FLAG_HIDDENINGUI|FLAG_ASDEFAULT, "continue", "Keyword: continue", "Disables the 'continue' keyword."},
{&keyword_state, FLAG_HIDDENINGUI|0, "state", "Keyword: state", "Disables the 'state' keyword."},
{&keyword_string, FLAG_HIDDENINGUI|FLAG_ASDEFAULT, "string", "Keyword: string", "Disables the 'string' keyword."},
{&keyword_float, FLAG_HIDDENINGUI|FLAG_ASDEFAULT, "float", "Keyword: float", "Disables the 'float' keyword."},
{&keyword_entity, FLAG_HIDDENINGUI|FLAG_ASDEFAULT, "entity", "Keyword: entity", "Disables the 'entity' keyword."},
{&keyword_vector, FLAG_HIDDENINGUI|FLAG_ASDEFAULT, "vector", "Keyword: vector", "Disables the 'vector' keyword."},
{&keyword_const, FLAG_HIDDENINGUI|FLAG_ASDEFAULT, "const", "Keyword: const", "Disables the 'const' keyword."},
{&keyword_integer, FLAG_HIDDENINGUI|FLAG_ASDEFAULT, "integer", "Keyword: integer", "Disables the 'integer' keyword."},
{&keyword_int, FLAG_HIDDENINGUI|FLAG_ASDEFAULT, "int", "Keyword: int", "Disables the 'int' keyword."},
{&keyword_class, FLAG_HIDDENINGUI|FLAG_ASDEFAULT, "class", "Keyword: class", "Disables the 'class' keyword."},
//options
{&keywords_coexist, true, "kce"},
{&output_parms, false, "parms"}, //controls weather to define PARMx for the parms (note - this can screw over some decompilers)
{&autoprototype, false, "autoproto"}, //so you no longer need to prototype functions and things in advance.
{&writeasm, false, "wasm"}, //spit out a qc.asm file, containing an assembler dump of the ENTIRE progs. (Doesn't include initialisation of constants)
{&flag_ifstring, true, "ifstring"}, //correction for if(string) no-ifstring to get the standard behaviour.
{&flag_acc, false, "acc"}, //reacc like behaviour of src files.
{&flag_caseinsensative, false, "caseinsens"}, //symbols will be matched to an insensative case if the specified case doesn't exist. This should b usable for any mod
{&flag_laxcasts, false, "lax"}, //Allow lax casting. This'll produce loadsa warnings of course. But allows compilation of certain dodgy code.
{&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."},
{&output_parms, 0, "parms", "Define offset parms", "if PARM0 PARM1 etc should be defined by the compiler. These are useful if you make use of the asm keyword for function calls, or you wish to create your own variable arguments. This is an easy way to break decompilers."}, //controls weather to define PARMx for the parms (note - this can screw over some decompilers)
{&autoprototype, 0, "autoproto", "Automatic Prototyping","Causes compilation to take two passes instead of one. The first pass, only the definitions are read. The second pass actually compiles your code. This means you never have to remember to prototype functions again."}, //so you no longer need to prototype functions and things in advance.
{&writeasm, 0, "wasm", "Dump Assembler", "Writes out a qc.asm which contains all your functions but in assembler. This is a great way to look for bugs in fteqcc, but can also be used to see exactly what your functions turn into, and thus how to optimise statements better."}, //spit out a qc.asm file, containing an assembler dump of the ENTIRE progs. (Doesn't include initialisation of constants)
{&flag_ifstring, 0, "ifstring", "if(string) fix", "Causes if(string) to behave identically to if(string!="") This is most useful with addons of course, but also has adverse effects with FRIK_FILE's fgets, where it becomes impossible to determin the end of the file. In such a case, you can still use asm {IF string 2;RETURN} to detect eof and leave the function."}, //correction for if(string) no-ifstring to get the standard behaviour.
{&flag_acc, 0, "acc", "Reacc support", "Reacc is a pascall like compiler. It was released before the Quake source was released. This flag has a few effects. It sorts all qc files in the current directory into alphabetical order to compile them. It also allows Reacc global/field distinctions, as well as allows ¦ as EOF. Whilst case insensativity and lax type checking are supported by reacc, they are seperate compiler flags in fteqcc."}, //reacc like behaviour of src files.
{&flag_caseinsensative, 0, "caseinsens", "Case insensativity", "Causes fteqcc to become case insensative whilst compiling names. It's generally not advised to use this as it compiles a little more slowly and provides little benefit. However, it is required for full reacc support."}, //symbols will be matched to an insensative case if the specified case doesn't exist. This should b usable for any mod
{&flag_laxcasts, 0, "lax", "Lax type checks", "Disables many errors (generating warnings instead) when function calls or operations refer to two normally incompatable types. This is required for reacc support, and can also allow certain (evil) mods to compile that were origionally written for frikqcc."}, //Allow lax casting. This'll produce loadsa warnings of course. But allows compilation of certain dodgy code.
{&opt_logicops, 0, "lo", "Logic ops", "This changes the behaviour of your code. It generates additional if operations to early-out in if statements. With this flag, the line if (0 && somefunction()) will never call the function. It can thus be considered an optimisation. However, due to the change of behaviour, it is not considered so by fteqcc. Note that due to inprecisions with floats, this flag can cause runaway loop errors within the player walk and run functions. This code is advised:\nplayer_stand1:\n if (self.velocity_x || self.velocity_y)\nplayer_run\n if (!(self.velocity_x || self.velocity_y))"},
{NULL}
};
@ -219,11 +216,12 @@ struct {
qcc_targetformat_t target;
char *name;
} targets[] = {
{QCF_STANDARD, "q1"},
{QCF_STANDARD, "standard"},
{QCF_STANDARD, "q1"},
{QCF_STANDARD, "quakec"},
{QCF_HEXEN2, "h2"},
{QCF_HEXEN2, "hexen2"},
{QCF_HEXEN2, "h2"},
{QCF_KK7, "kkqwsv"},
{QCF_KK7, "kk7"},
{QCF_KK7, "bigprogs"},
{QCF_KK7, "version7"},
@ -536,7 +534,7 @@ void QCC_WriteData (int crc)
dprograms_t progs;
int h;
int i, len;
pbool debugdefined = false;
pbool debugtarget = false;
pbool types = false;
int outputsize = 16;
@ -557,22 +555,13 @@ void QCC_WriteData (int crc)
if (bodylessfuncs)
printf("Warning: There are some functions without bodies.\n");
if (outputversion > PROG_VERSION)
{
printf("Forcing target to FTE due to additional opcodes\n");
qcc_targetformat = QCF_FTE;
outputversion = PROG_DEBUGVERSION; //force it.
}
else if (numpr_globals > 65530 )
if (numpr_globals > 65530 )
{
printf("Forcing target to FTE32 due to numpr_globals\n");
qcc_targetformat = QCF_FTE32;
outputsize = 32;
outputversion = PROG_DEBUGVERSION; //force it.
}
else if (qcc_targetformat == QCF_HEXEN2)
{
outputversion = PROG_VERSION;
printf("Progs execution requires a Hexen2 compatable engine\n");
break;
}
@ -585,39 +574,37 @@ void QCC_WriteData (int crc)
break;
}
//intentional
qcc_targetformat = QCF_FTE;
case QCF_FTEDEBUG:
case QCF_FTEDEBUG32:
case QCF_FTE:
case QCF_FTE32:
if (qcc_targetformat == QCF_FTEDEBUG || qcc_targetformat == QCF_FTEDEBUG32)
debugdefined = true;
if (qcc_targetformat == QCF_FTE32 || qcc_targetformat == QCF_FTEDEBUG32)
outputsize = 32;
else if (numpr_globals > 65530)
if (qcc_targetformat == QCF_FTEDEBUG)
debugtarget = true;
if (numpr_globals > 65530)
{
printf("Forcing 32 bit target due to numpr_globals\n");
printf("Using 32 bit target due to numpr_globals\n");
outputsize = 32;
}
//compression of blocks?
if (QCC_PR_CheckCompConstDefined("OP_COMP_STATEMENTS")) progs.blockscompressed |=1;
if (QCC_PR_CheckCompConstDefined("OP_COMP_DEFS")) progs.blockscompressed |=2;
if (QCC_PR_CheckCompConstDefined("OP_COMP_FIELDS")) progs.blockscompressed |=4;
if (QCC_PR_CheckCompConstDefined("OP_COMP_FUNCTIONS")) progs.blockscompressed |=8;
if (QCC_PR_CheckCompConstDefined("OP_COMP_STRINGS")) progs.blockscompressed |=16;
if (QCC_PR_CheckCompConstDefined("OP_COMP_GLOBALS")) progs.blockscompressed |=32;
if (QCC_PR_CheckCompConstDefined("OP_COMP_LINES")) progs.blockscompressed |=64;
if (QCC_PR_CheckCompConstDefined("OP_COMP_TYPES")) progs.blockscompressed |=128;
if (compressoutput) progs.blockscompressed |=1; //statements
if (compressoutput) progs.blockscompressed |=2; //defs
if (compressoutput) progs.blockscompressed |=4; //fields
if (compressoutput) progs.blockscompressed |=8; //functions
if (compressoutput) progs.blockscompressed |=16; //strings
if (compressoutput) progs.blockscompressed |=32; //globals
if (compressoutput) progs.blockscompressed |=64; //line numbers
if (compressoutput) progs.blockscompressed |=128; //types
//include a type block?
types = !!QCC_PR_CheckCompConstDefined("TYPES"); //useful for debugging and saving (maybe, anyway...).
outputversion = PROG_DEBUGVERSION;
types = debugtarget;//!!QCC_PR_CheckCompConstDefined("TYPES"); //useful for debugging and saving (maybe, anyway...).
printf("An FTE executor will be required\n");
break;
case QCF_KK7:
outputversion = PROG_DEBUGVERSION;
if (bodylessfuncs)
printf("Warning: There are some functions without bodies.\n");
if (numpr_globals > 65530)
printf("Warning: Saving is not supported. Ensure all engine read fields and globals are defined early on.\n");
printf("A KK compatable executor will be required (FTE/KK)\n");
break;
@ -1041,12 +1028,19 @@ strofs = (strofs+3)&~3;
progs.ofs_types = 0;
progs.numtypes = 0;
if (qcc_targetformat == QCF_KK7)
{
outputversion = 7;
}
else if (outputversion >= PROG_DEBUGVERSION)
switch(qcc_targetformat)
{
case QCF_KK7:
progs.version = PROG_KKQWSVVERSION;
break;
case QCF_STANDARD:
case QCF_HEXEN2: //urgh
progs.version = PROG_VERSION;
break;
case QCF_FTE:
case QCF_FTEDEBUG:
progs.version = PROG_EXTENDEDVERSION;
if (outputsize == 32)
progs.secondaryversion = PROG_SECONDARYVERSION32;
else
@ -1055,7 +1049,7 @@ strofs = (strofs+3)&~3;
progs.ofsbodylessfuncs = SafeSeek (h, 0, SEEK_CUR);
progs.numbodylessfuncs = WriteBodylessFuncs(h);
if (debugdefined)
if (debugtarget)
{
progs.ofslinenums = SafeSeek (h, 0, SEEK_CUR);
if (progs.blockscompressed&64)
@ -1097,11 +1091,10 @@ strofs = (strofs+3)&~3;
progs.numtypes = 0;
}
progs.ofsfiles = WriteSourceFiles(h, &progs, debugdefined);
progs.ofsfiles = WriteSourceFiles(h, &progs, debugtarget);
break;
}
progs.version = outputversion;
printf ("%6i TOTAL SIZE\n", (int)SafeSeek (h, 0, SEEK_CUR));
progs.entityfields = pr.size_fields;
@ -1118,7 +1111,7 @@ strofs = (strofs+3)&~3;
SafeWrite (h, &progs, sizeof(progs));
SafeClose (h);
if (outputversion != 7 || !debugdefined)
if (!debugtarget)
{
if (opt_filenames)
{
@ -1433,6 +1426,7 @@ void QCC_PR_BeginCompilation (void *memory, int memsize)
type_function = QCC_PR_NewType("function", ev_function);
type_pointer = QCC_PR_NewType("pointer", ev_pointer);
type_integer = QCC_PR_NewType("__integer", ev_integer);
type_variant = QCC_PR_NewType("__variant", ev_variant);
type_floatfield = QCC_PR_NewType("fieldfloat", ev_field);
type_floatfield->aux_type = type_float;
@ -1648,9 +1642,7 @@ unsigned short QCC_PR_WriteProgdefs (char *filename)
{
extern int ForcedCRC;
#define ADD2(p) strncat(file, p, PROGDEFS_MAX_SIZE-1 - strlen(file)) //no crc (later changes)
int sent1=0xffffffff;
char file[PROGDEFS_MAX_SIZE];
int sent2=0xffffffff;
QCC_def_t *d;
int f;
unsigned short crc;
@ -2262,7 +2254,7 @@ void QCC_PR_CommandLinePrecompilerOptions (void)
if (!strnicmp(myargv[i]+2, "no-", 3))
{
for (p = 0; compiler_flag[p].enabled; p++)
if (!stricmp(myargv[i]+5, compiler_flag[p].name))
if (!stricmp(myargv[i]+5, compiler_flag[p].abbrev))
{
*compiler_flag[p].enabled = false;
break;
@ -2271,7 +2263,7 @@ void QCC_PR_CommandLinePrecompilerOptions (void)
else
{
for (p = 0; compiler_flag[p].enabled; p++)
if (!stricmp(myargv[i]+2, compiler_flag[p].name))
if (!stricmp(myargv[i]+2, compiler_flag[p].abbrev))
{
*compiler_flag[p].enabled = true;
break;
@ -2287,7 +2279,7 @@ void QCC_PR_CommandLinePrecompilerOptions (void)
if (!strnicmp(myargv[i]+2, "no-", 3))
{
for (p = 0; compiler_flag[p].enabled; p++)
if (!stricmp(myargv[i]+5, compiler_flag[p].name))
if (!stricmp(myargv[i]+5, compiler_flag[p].abbrev))
{
*compiler_flag[p].enabled = false;
break;
@ -2296,7 +2288,7 @@ void QCC_PR_CommandLinePrecompilerOptions (void)
else
{
for (p = 0; compiler_flag[p].enabled; p++)
if (!stricmp(myargv[i]+2, compiler_flag[p].name))
if (!stricmp(myargv[i]+2, compiler_flag[p].abbrev))
{
*compiler_flag[p].enabled = true;
break;
@ -2416,7 +2408,7 @@ void QCC_SetDefaultProperties (void)
{
for (i = 0; optimisations[i].enabled; i++)
{
if (optimisations[i].flags & 2)
if (optimisations[i].flags & FLAG_ASDEFAULT)
*optimisations[i].enabled = true;
else
*optimisations[i].enabled = false;
@ -2477,7 +2469,7 @@ void QCC_SetDefaultProperties (void)
{
for (i = 0; optimisations[i].enabled; i++)
{
if (optimisations[i].flags & 1)
if (optimisations[i].flags & FLAG_KILLSDEBUGGERS)
*optimisations[i].enabled = false;
}
}
@ -2569,11 +2561,13 @@ void QCC_main (int argc, char **argv) //as part of the quake engine
MAX_STRINGS = 1000000;
MAX_GLOBALS = 32768;
MAX_FIELDS = 2048;
MAX_STATEMENTS = 0x20000;
MAX_STATEMENTS = 0x80000;
MAX_FUNCTIONS = 16384;
maxtypeinfos = 16384;
MAX_CONSTANTS = 2048;
compressoutput = 0;
p = externs->FileSize("qcc.cfg");
if (p < 0)
p = externs->FileSize("src/qcc.cfg");
@ -2635,12 +2629,10 @@ void QCC_main (int argc, char **argv) //as part of the quake engine
strcpy(QCC_copyright, "This file was created with ForeThought's modified QuakeC compiler\nThanks to ID Software");
for (p = 0; p < 5; p++)
strcpy(QCC_Packname[p], "");
outputversion = PROG_VERSION;
for (p = 0; compiler_flag[p].enabled; p++)
{
*compiler_flag[p].enabled = compiler_flag[p].defaultval;
*compiler_flag[p].enabled = compiler_flag[p].flags & FLAG_ASDEFAULT;
}
QCC_SetDefaultProperties();
@ -3322,6 +3314,7 @@ void Sys_Error(const char *text, ...)
QCC_Error(ERR_INTERNAL, "%s", msg);
}
#ifndef USEGUI
int main (int argc, char **argv)
{
int sucess;
@ -3345,6 +3338,7 @@ int main (int argc, char **argv)
return !sucess;
}
#endif
#endif
#endif

View File

@ -139,9 +139,10 @@ char *filefromprogs(progfuncs_t *progfuncs, progsnum_t prnum, char *fname, int *
includeddatafile_t *s;
if (!pr_progstate[prnum].progs)
return NULL;
if (pr_progstate[prnum].progs->version < PROG_DEBUGVERSION)
if (pr_progstate[prnum].progs->version != PROG_EXTENDEDVERSION)
return NULL;
if (!pr_progstate[prnum].progs->ofsfiles)
if (!pr_progstate[prnum].progs->secondaryversion != PROG_SECONDARYVERSION16 &&
!pr_progstate[prnum].progs->secondaryversion != PROG_SECONDARYVERSION32)
return NULL;
num = *(int*)((char *)pr_progstate[prnum].progs + pr_progstate[prnum].progs->ofsfiles);
@ -179,7 +180,7 @@ char *filefromnewprogs(progfuncs_t *progfuncs, char *prname, char *fname, int *s
return NULL;
}
if (progs.progs->version < PROG_DEBUGVERSION)
if (progs.progs->version < PROG_EXTENDEDVERSION)
return NULL;
if (!progs.progs->ofsfiles)
return NULL;

View File

@ -757,6 +757,8 @@ void FigureOutTypes(progfuncs_t *progfuncs)
type_pointer = QCC_PR_NewType("pointer", ev_pointer);
type_integer = QCC_PR_NewType("integer", ev_integer);
// type_variant = QCC_PR_NewType("__variant", ev_variant);
type_floatfield = QCC_PR_NewType("fieldfloat", ev_field);
type_floatfield->aux_type = type_float;
type_pointer->aux_type = QCC_PR_NewType("pointeraux", ev_float);

View File

@ -1,6 +1,6 @@
//network interface
#include "bothdefs.h"
#include "quakedef.h"
#ifndef NOMEDIA

View File

@ -1,5 +1,3 @@
#include "quakedef.h"
#ifdef _WIN32 //for multithreaded reading
#define BOOL WINDOWSSUCKS_BOOL
#define INT32 WINDOWSSUCKS_INT32

View File

@ -1,4 +1,4 @@
#include "bothdefs.h"
#include "quakedef.h"
#ifndef NOMEDIA

View File

@ -1,4 +1,4 @@
#include "bothdefs.h"
#include "quakedef.h"
#ifndef NOMEDIA

View File

@ -32,13 +32,6 @@ static qboolean ignoreprotocol;
#define TE_LIGHTNING4_NEH 17 // [string] model [entity] entity [vector] start [vector] end
#define TE_EXPLOSIONSMALL2 20 // org.
//share with pr_cmds.
#define MSG_BROADCAST 0 // unreliable to all
#define MSG_ONE 1 // reliable to one (msg_entity)
#define MSG_ALL 2 // reliable to all
#define MSG_INIT 3 // write to the init string
#define MSG_MULTICAST 4 // for multicast()
client_t *Write_GetClient(void);
sizebuf_t *WriteDest (int dest);
#ifdef NQPROT

View File

@ -141,6 +141,8 @@ void ED_Spawned (struct edict_s *ent)
ent->v.dimension_ghost = 0;
ent->v.dimension_solid = 255;
ent->v.dimension_hit = 255;
ent->v.Version = sv.csqcentversion[ent->entnum]+1;
}
pbool ED_CanFree (edict_t *ed)
@ -171,6 +173,8 @@ pbool ED_CanFree (edict_t *ed)
ed->v.think = 0;
ed->v.solid = 0;
sv.csqcentversion[ed->entnum] = ed->v.Version+1;
return true;
}
@ -706,8 +710,8 @@ void PR_Compile_f(void)
if (!svprogfuncs)
Q_SetProgsParms(true);
if (svprogfuncs->PR_StartCompile(svprogfuncs, argc, argv))
while(svprogfuncs->PR_ContinueCompile(svprogfuncs));
if (PR_StartCompile(svprogfuncs, argc, argv))
while(PR_ContinueCompile(svprogfuncs));
time = Sys_DoubleTime() - time;
@ -1347,8 +1351,8 @@ void VARGS PR_BIError(progfuncs_t *progfuncs, char *format, ...)
}
else
{
progfuncs->PR_StackTrace(progfuncs);
progfuncs->AbortStack(progfuncs);
PR_StackTrace(progfuncs);
PR_AbortStack(progfuncs);
progfuncs->parms->Abort ("%s", string);
}
}
@ -1546,7 +1550,7 @@ void PF_instr (progfuncs_t *prinst, globalvars_t *pr_globals)
sub = strstr(s1, s2);
if (sub == NULL)
RETURN_SSTRING("");
G_INT(OFS_RETURN) = 0;
else
RETURN_SSTRING(sub); //last as long as the origional string
}
@ -1590,7 +1594,7 @@ void PF_error (progfuncs_t *prinst, struct globalvars_s *pr_globals)
ED_Print (ed);
*/
prinst->PR_StackTrace(prinst);
PR_StackTrace(prinst);
Con_Printf("%s\n", s);
@ -1602,7 +1606,7 @@ void PF_error (progfuncs_t *prinst, struct globalvars_s *pr_globals)
}
else
{
prinst->AbortStack(prinst);
PR_AbortStack(prinst);
PR_BIError (prinst, "Program error: %s", s);
}
}
@ -1617,7 +1621,7 @@ removed, but the level can continue.
objerror(value)
=================
*/
void PF_objerror (progfuncs_t *prinst, struct globalvars_s *pr_globals)
static void PF_objerror (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *s;
edict_t *ed;
@ -2567,7 +2571,7 @@ if the tryents flag is set.
traceline (vector1, vector2, tryents)
=================
*/
void PF_traceline (progfuncs_t *prinst, struct globalvars_s *pr_globals)
static void PF_traceline (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
float *v1, *v2, *mins, *maxs;
trace_t trace;
@ -2613,7 +2617,7 @@ void PF_traceline (progfuncs_t *prinst, struct globalvars_s *pr_globals)
pr_global_struct->trace_ent = EDICT_TO_PROG(prinst, sv.edicts);
}
void PF_traceboxh2 (progfuncs_t *prinst, struct globalvars_s *pr_globals)
static void PF_traceboxh2 (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
float *v1, *v2, *mins, *maxs;
trace_t trace;
@ -2650,7 +2654,7 @@ void PF_traceboxh2 (progfuncs_t *prinst, struct globalvars_s *pr_globals)
pr_global_struct->trace_ent = EDICT_TO_PROG(prinst, sv.edicts);
}
void PF_traceboxdp (progfuncs_t *prinst, struct globalvars_s *pr_globals)
static void PF_traceboxdp (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
float *v1, *v2, *mins, *maxs;
trace_t trace;
@ -2688,7 +2692,7 @@ void PF_traceboxdp (progfuncs_t *prinst, struct globalvars_s *pr_globals)
}
extern trace_t SV_Trace_Toss (edict_t *ent, edict_t *ignore);
void PF_TraceToss (progfuncs_t *prinst, struct globalvars_s *pr_globals)
static void PF_TraceToss (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
trace_t trace;
edict_t *ent;
@ -2963,9 +2967,9 @@ void PF_localcmd (progfuncs_t *prinst, struct globalvars_s *pr_globals)
str = PR_GetStringOfs(prinst, OFS_PARM0);
if (!strcmp(str, "host_framerate 0\n"))
Cbuf_AddText ("sv_mintic 0\n", RESTRICT_RCON); //hmm... do this better...
Cbuf_AddText ("sv_mintic 0\n", RESTRICT_SERVER); //hmm... do this better...
else
Cbuf_AddText (str, RESTRICT_RCON);
Cbuf_AddText (str, RESTRICT_SERVER);
}
/*
@ -3159,7 +3163,7 @@ void PF_dprintv (progfuncs_t *prinst, struct globalvars_s *pr_globals)
}
#define MAX_TEMPSTRS 16
#define MAXTEMPBUFFERLEN 1024
#define MAXTEMPBUFFERLEN 4096
char *PF_TempStr(void)
{
static char pr_string_temparr[MAX_TEMPSTRS][MAXTEMPBUFFERLEN];
@ -4120,8 +4124,15 @@ client_t *Write_GetClient(void)
return &svs.clients[entnum-1];
}
extern sizebuf_t csqcmsgbuffer;
void PF_WriteByte (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
if (G_FLOAT(OFS_PARM0) == MSG_CSQC)
{ //csqc buffers are always written.
MSG_WriteByte(&csqcmsgbuffer, G_FLOAT(OFS_PARM1));
return;
}
if (qc_nonetaccess.value || sv.demofile)
return;
@ -4154,6 +4165,12 @@ void PF_WriteByte (progfuncs_t *prinst, struct globalvars_s *pr_globals)
void PF_WriteChar (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
if (G_FLOAT(OFS_PARM0) == MSG_CSQC)
{ //csqc buffers are always written.
MSG_WriteChar(&csqcmsgbuffer, G_FLOAT(OFS_PARM1));
return;
}
if (qc_nonetaccess.value || sv.demofile)
return;
pr_netprogfuncs = prinst;
@ -4185,6 +4202,12 @@ void PF_WriteChar (progfuncs_t *prinst, struct globalvars_s *pr_globals)
void PF_WriteShort (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
if (G_FLOAT(OFS_PARM0) == MSG_CSQC)
{ //csqc buffers are always written.
MSG_WriteShort(&csqcmsgbuffer, G_FLOAT(OFS_PARM1));
return;
}
if (qc_nonetaccess.value || sv.demofile)
return;
@ -4217,6 +4240,12 @@ void PF_WriteShort (progfuncs_t *prinst, struct globalvars_s *pr_globals)
void PF_WriteLong (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
if (G_FLOAT(OFS_PARM0) == MSG_CSQC)
{ //csqc buffers are always written.
MSG_WriteLong(&csqcmsgbuffer, G_FLOAT(OFS_PARM1));
return;
}
if (qc_nonetaccess.value || sv.demofile)
return;
@ -4249,6 +4278,12 @@ void PF_WriteLong (progfuncs_t *prinst, struct globalvars_s *pr_globals)
void PF_WriteAngle (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
if (G_FLOAT(OFS_PARM0) == MSG_CSQC)
{ //csqc buffers are always written.
MSG_WriteAngle(&csqcmsgbuffer, G_FLOAT(OFS_PARM1));
return;
}
if (qc_nonetaccess.value || sv.demofile)
return;
pr_netprogfuncs = prinst;
@ -4280,6 +4315,12 @@ void PF_WriteAngle (progfuncs_t *prinst, struct globalvars_s *pr_globals)
void PF_WriteCoord (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
if (G_FLOAT(OFS_PARM0) == MSG_CSQC)
{ //csqc buffers are always written.
MSG_WriteCoord(&csqcmsgbuffer, G_FLOAT(OFS_PARM1));
return;
}
if (qc_nonetaccess.value || sv.demofile)
return;
@ -4312,10 +4353,15 @@ void PF_WriteCoord (progfuncs_t *prinst, struct globalvars_s *pr_globals)
void PF_WriteString (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *str;
char *str = PF_VarString(prinst, 1, pr_globals);;
if (G_FLOAT(OFS_PARM0) == MSG_CSQC)
{ //csqc buffers are always written.
MSG_WriteString(&csqcmsgbuffer, str);
return;
}
if (qc_nonetaccess.value || sv.demofile)
return;
str = PF_VarString(prinst, 1, pr_globals);
pr_netprogfuncs = prinst;
pr_netglob = pr_globals;
@ -4347,6 +4393,12 @@ void PF_WriteString (progfuncs_t *prinst, struct globalvars_s *pr_globals)
void PF_WriteEntity (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
if (G_FLOAT(OFS_PARM0) == MSG_CSQC)
{ //csqc buffers are always written.
MSG_WriteShort(&csqcmsgbuffer, G_EDICTNUM(prinst, OFS_PARM1));
return;
}
if (qc_nonetaccess.value || sv.demofile)
return;
@ -4382,8 +4434,9 @@ void PF_WriteEntity (progfuncs_t *prinst, struct globalvars_s *pr_globals)
void PF_WriteString2 (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int old;
char *str;
if (qc_nonetaccess.value || sv.demofile)
char *str = PF_VarString(prinst, 1, pr_globals);
if (G_FLOAT(OFS_PARM0) != MSG_CSQC && (qc_nonetaccess.value || sv.demofile))
return;
str = PF_VarString(prinst, 1, pr_globals);
@ -4836,9 +4889,9 @@ qboolean printedheader = false;
Con_Printf("\n");
if (progstype == PROG_QW)
prinst->PR_RunError(prinst, "\nBuiltin %i not implemented.\nMods designed for mvdsv may need pr_imitatemvdsv to be enabled.", prinst->lastcalledbuiltinnumber);
prinst->RunError(prinst, "\nBuiltin %i not implemented.\nMods designed for mvdsv may need pr_imitatemvdsv to be enabled.", prinst->lastcalledbuiltinnumber);
else
prinst->PR_RunError(prinst, "\nBuiltin %i not implemented.\nMod is not compatable.", prinst->lastcalledbuiltinnumber);
prinst->RunError(prinst, "\nBuiltin %i not implemented.\nMod is not compatable.", prinst->lastcalledbuiltinnumber);
PR_BIError (prinst, "bulitin not implemented");
}
@ -5284,6 +5337,8 @@ void PF_strncasecmp (progfuncs_t *prinst, struct globalvars_s *pr_globals)
#define MAX_QC_FILES 8
#define FIRST_QC_FILE_INDEX 1000
typedef struct {
char name[256];
char *data;
@ -5319,8 +5374,6 @@ void PF_fopen (progfuncs_t *prinst, struct globalvars_s *pr_globals)
return;
}
pf_fopen_files[i].prinst = prinst;
Q_strncpyz(pf_fopen_files[i].name, va("data/%s", name), sizeof(pf_fopen_files[i].name));
pf_fopen_files[i].accessmode = fmode;
@ -5335,7 +5388,10 @@ void PF_fopen (progfuncs_t *prinst, struct globalvars_s *pr_globals)
}
if (pf_fopen_files[i].data)
G_FLOAT(OFS_RETURN) = i;
{
G_FLOAT(OFS_RETURN) = i + FIRST_QC_FILE_INDEX;
pf_fopen_files[i].prinst = prinst;
}
else
G_FLOAT(OFS_RETURN) = -1;
@ -5347,7 +5403,8 @@ void PF_fopen (progfuncs_t *prinst, struct globalvars_s *pr_globals)
pf_fopen_files[i].ofs = pf_fopen_files[i].bufferlen = pf_fopen_files[i].len = com_filesize;
if (pf_fopen_files[i].data)
{
G_FLOAT(OFS_RETURN) = i;
G_FLOAT(OFS_RETURN) = i + FIRST_QC_FILE_INDEX;
pf_fopen_files[i].prinst = prinst;
break;
}
//file didn't exist - fall through
@ -5356,7 +5413,8 @@ void PF_fopen (progfuncs_t *prinst, struct globalvars_s *pr_globals)
pf_fopen_files[i].data = BZ_Malloc(pf_fopen_files[i].bufferlen);
pf_fopen_files[i].len = 0;
pf_fopen_files[i].ofs = 0;
G_FLOAT(OFS_RETURN) = i;
G_FLOAT(OFS_RETURN) = i + FIRST_QC_FILE_INDEX;
pf_fopen_files[i].prinst = prinst;
break;
default: //bad
G_FLOAT(OFS_RETURN) = -1;
@ -5366,15 +5424,24 @@ void PF_fopen (progfuncs_t *prinst, struct globalvars_s *pr_globals)
void PF_fclose (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int fnum = G_FLOAT(OFS_PARM0);
int fnum = G_FLOAT(OFS_PARM0)-FIRST_QC_FILE_INDEX;
if (fnum < 0 || fnum >= MAX_QC_FILES)
{
Con_Printf("PF_fclose: File out of range\n");
return; //out of range
}
if (!pf_fopen_files[fnum].data)
{
Con_Printf("PF_fclose: File is not open\n");
return; //not open
}
if (pf_fopen_files[fnum].prinst != prinst)
{
Con_Printf("PF_fclose: File is from wrong instance\n");
return; //this just isn't ours.
}
switch(pf_fopen_files[fnum].accessmode)
{
@ -5388,24 +5455,34 @@ void PF_fclose (progfuncs_t *prinst, struct globalvars_s *pr_globals)
break;
}
pf_fopen_files[fnum].data = NULL;
pf_fopen_files[fnum].prinst = NULL;
}
void PF_fgets (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char c, *s, *o, *max;
int fnum = G_FLOAT(OFS_PARM0);
int fnum = G_FLOAT(OFS_PARM0) - FIRST_QC_FILE_INDEX;
char *pr_string_temp = PF_TempStr();
*pr_string_temp = '\0';
RETURN_SSTRING(pr_string_temp);
if (fnum < 0 || fnum >= MAX_QC_FILES)
{
Con_Printf("PF_fgets: File out of range\n");
return; //out of range
}
if (!pf_fopen_files[fnum].data)
{
Con_Printf("PF_fgets: File is not open\n");
return; //not open
}
if (pf_fopen_files[fnum].prinst != prinst)
{
Con_Printf("PF_fgets: File is from wrong instance\n");
return; //this just isn't ours.
}
//read up to the next \n, ignoring any \rs.
o = pr_string_temp;
@ -5435,17 +5512,26 @@ void PF_fgets (progfuncs_t *prinst, struct globalvars_s *pr_globals)
void PF_fputs (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int fnum = G_FLOAT(OFS_PARM0);
int fnum = G_FLOAT(OFS_PARM0) - FIRST_QC_FILE_INDEX;
char *msg = PF_VarString(prinst, 1, pr_globals);
int len = strlen(msg);
if (fnum < 0 || fnum >= MAX_QC_FILES)
{
Con_Printf("PF_fgets: File out of range\n");
return; //out of range
}
if (!pf_fopen_files[fnum].data)
{
Con_Printf("PF_fgets: File is not open\n");
return; //not open
}
if (pf_fopen_files[fnum].prinst != prinst)
{
Con_Printf("PF_fgets: File is from wrong instance\n");
return; //this just isn't ours.
}
if (pf_fopen_files[fnum].bufferlen < pf_fopen_files[fnum].ofs + len)
{
@ -5470,7 +5556,7 @@ void PF_fcloseall (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
if (pf_fopen_files[i].prinst != prinst)
continue;
G_FLOAT(OFS_PARM0) = i;
G_FLOAT(OFS_PARM0) = i+FIRST_QC_FILE_INDEX;
PF_fclose(prinst, pr_globals);
}
}
@ -5585,11 +5671,13 @@ lh_extension_t QSG_Extensions[] = {
{"ZQ_MOVETYPE_FLY"},
{"ZQ_MOVETYPE_NOCLIP"},
{"ZQ_MOVETYPE_NONE"}
// {"ZQ_QC_PARTICLE"} //particle builtin works in QW ( we don't mimic ZQ fully so...)
// {"ZQ_QC_PARTICLE"} //particle builtin works in QW ( we don't mimic ZQ fully though)
};
//some of these are overkill yes, but they are all derived from the fteextensions flags and document the underlaying protocol available.
//(which is why there are two lists of extensions here)
//note: not all of these are actually supported. This list mearly reflects the values of the PEXT_ constants.
//Check protocol.h to make sure that the related PEXT is enabled. The engine will only accept if they are actually supported.
lh_extension_t FTE_Protocol_Extensions[] =
{
{"FTE_PEXT_SETVIEW"}, //nq setview works.
@ -5598,16 +5686,8 @@ lh_extension_t FTE_Protocol_Extensions[] =
{"DP_ENT_ALPHA"}, //transparent entites
{"FTE_PEXT_VIEW2"}, //secondary view.
{"FTE_PEXT_BULLETENS"}, //bulleten boards (scrolling text on walls)
#ifdef PEXT_ZLIBDL
{"FTE_PEXT_ZLIBDL"}, //supposed download optimisation (unimportant to qc)
#else
{NULL},
#endif
#ifdef PEXT_LIGHTUPDATES
{"FTE_PEXT_LIGHTUPDATES"}, //zap.mdl is sent as a nail packet.
#else
{NULL},
#endif
{"FTE_PEXT_FATNESS"}, //entities may be expanded along thier vertex normals
{"DP_HALFLIFE_MAP"}, //entitiy can visit a hl bsp
{"FTE_PEXT_TE_BULLET"}, //additional particle effect. Like TE_SPIKE and TE_SUPERSPIKE
@ -5615,29 +5695,22 @@ lh_extension_t FTE_Protocol_Extensions[] =
{"FTE_PEXT_MODELDBL"}, //max of 512 models
{"FTE_PEXT_ENTITYDBL"}, //max of 1024 ents
{"FTE_PEXT_ENTITYDBL2"}, //max of 2048 ents
#ifdef PEXT_ORIGINDBL
{"FTE_PEXT_ORIGINDBL"}, //-8k to +8k map size.
#else
{NULL},
#endif
{"FTE_PEXT_VWEAP"},
#ifdef Q2BSPS
{"FTE_PEXT_Q2BSP"}, //supports q2 maps. No bugs are apparent.
#else
{NULL},
#endif
#ifdef Q3BSPS
{"FTE_PEXT_Q3BSP"}, //quake3 bsp support. dp probably has an equivelent, but this is queryable per client.
#else
{NULL},
#endif
{"UDC_EXTEFFECT", 0, &pr_udc_exteffect_enabled}, //hmm. crap.
{NULL}, //splitscreen - not queryable.
{"FTE_HEXEN2"}, //client can use hexen2 maps. server can use hexen2 progs
{"FTE_PEXT_SPAWNSTATIC"}, //means that static entities can have alpha/scale and anything else the engine supports on normal ents. (Added for >256 models, while still being compatable - previous system failed with -1 skins)
{"FTE_PEXT_CUSTOMTENTS", 2, NULL, {"RegisterTempEnt", "CustomTempEnt"}},
{"FTE_PEXT_256PACKETENTITIES"}, //client is able to receive unlimited packet entities (server caps itself to 256 to prevent insanity).
{"TEI_SHOWLMP2", 6, NULL, {"showpic", "hidepic", "movepic", "changepic", "showpicent", "hidepicent"}} //telejano doesn't actually export the moveent/changeent (we don't want to either cos it would stop frik_file stuff being autoregistered)
{"FTE_PEXT_64PLAYERS"},
{"TEI_SHOWLMP2", 6, NULL, {"showpic", "hidepic", "movepic", "changepic", "showpicent", "hidepicent"}}, //telejano doesn't actually export the moveent/changeent (we don't want to either cos it would stop frik_file stuff being autoregistered)
{"DP_GFX_QUAKE3MODELTAGS", 1, NULL, {"setattachment"}},
{"FTE_PK3DOWNLOADS"},
{"PEXT_CHUNKEDDOWNLOADS"},
{"EXT_CSQC"}
};
@ -5678,14 +5751,12 @@ lh_extension_t *checkfteextensioncl(int mask, char *name) //true if the cient ex
unsigned int m = 1;
for (i = 0; i < sizeof(FTE_Protocol_Extensions)/sizeof(lh_extension_t); i++)
{
if (mask & m) //suported
if (mask & (1<<i)) //suported
{
if (FTE_Protocol_Extensions[i].name) //some were removed
if (!stricmp(name, FTE_Protocol_Extensions[i].name)) //name matches
return &FTE_Protocol_Extensions[i];
}
m=m<<2;
}
return NULL;
}
@ -5696,9 +5767,12 @@ lh_extension_t *checkfteextensionsv(char *name) //true if the server supports an
for (i = 0; i < sizeof(FTE_Protocol_Extensions)/sizeof(lh_extension_t); i++)
{
if (FTE_Protocol_Extensions[i].name) //some were removed
if (!stricmp(name, FTE_Protocol_Extensions[i].name)) //name matches
return &FTE_Protocol_Extensions[i];
if (svs.fteprotocolextensions & (1<<i))
{
if (FTE_Protocol_Extensions[i].name) //some were removed
if (!stricmp(name, FTE_Protocol_Extensions[i].name)) //name matches
return &FTE_Protocol_Extensions[i];
}
}
return NULL;
}
@ -5771,6 +5845,7 @@ void PF_checkextension (progfuncs_t *prinst, struct globalvars_s *pr_globals)
*ext->enabled = true;
G_FLOAT(OFS_RETURN) = true;
Con_Printf("Extension %s is supported\n", s);
}
else
G_FLOAT(OFS_RETURN) = false;
@ -7457,7 +7532,7 @@ void PF_ShowPic(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{ //to a single client
entnum = G_EDICTNUM(prinst, OFS_PARM5)-1;
if (entnum < 0 || entnum >= sv.allocated_client_slots)
prinst->PR_RunError (prinst, "WriteDest: not a client");
PR_RunError (prinst, "WriteDest: not a client");
if (!(svs.clients[entnum].fteprotocolextensions & PEXT_SHOWPIC))
return; //need an extension for this. duh.
@ -7490,7 +7565,7 @@ void PF_HidePic(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{ //to a single client
entnum = G_EDICTNUM(prinst, OFS_PARM1)-1;
if (entnum < 0 || entnum >= sv.allocated_client_slots)
prinst->PR_RunError (prinst, "WriteDest: not a client");
PR_RunError (prinst, "WriteDest: not a client");
if (!(svs.clients[entnum].fteprotocolextensions & PEXT_SHOWPIC))
return; //need an extension for this. duh.
@ -7525,7 +7600,7 @@ void PF_MovePic(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{ //to a single client
entnum = G_EDICTNUM(prinst, OFS_PARM4)-1;
if (entnum < 0 || entnum >= sv.allocated_client_slots)
prinst->PR_RunError (prinst, "WriteDest: not a client");
PR_RunError (prinst, "WriteDest: not a client");
if (!(svs.clients[entnum].fteprotocolextensions & PEXT_SHOWPIC))
return; //need an extension for this. duh.
@ -7558,7 +7633,7 @@ void PF_ChangePic(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{ //to a single client
entnum = G_EDICTNUM(prinst, OFS_PARM2)-1;
if (entnum < 0 || entnum >= sv.allocated_client_slots)
prinst->PR_RunError (prinst, "WriteDest: not a client");
PR_RunError (prinst, "WriteDest: not a client");
if (!(svs.clients[entnum].fteprotocolextensions & PEXT_SHOWPIC))
return; //need an extension for this. duh.
@ -7701,6 +7776,21 @@ void PF_setattachment(progfuncs_t *prinst, struct globalvars_s *pr_globals)
te->_float = e->tagindex;
}
void PF_clientstat(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *name = PF_VarString(prinst, 2, pr_globals);
SV_QCStat(G_FLOAT(OFS_PARM0), name, G_FLOAT(OFS_PARM1));
}
void PF_runclientphys(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
pmove.numphysent = 1;
pmove.physents[0].model = sv.worldmodel;
// AddLinksToPmove ( sv_areanodes );
PM_PlayerMove();
}
BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
{"fixme", PF_Fixme, 0, 0, 0},
@ -7881,7 +7971,7 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
{"precache_sound4", PF_precache_sound, 0, 0, 101, 0},
{"precache_model4", PF_precache_model, 0, 0, 102, 0},
{"precache_file4", PF_precache_file, 0, 0, 103, 0},
{"stopsound4", PF_StopSound, 0, 0, 106, 0},
{"stopsound", PF_StopSound, 0, 0, 106, 0},
{"precache_model4", PF_precache_model, 0, 0, 116, 0},//please don't use...
{"precache_sound4", PF_precache_sound, 0, 0, 117, 0},
@ -7965,6 +8055,7 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
{"map_builtin", PF_builtinsupported,0, 0, 0, 220}, //like #100 - takes 2 args. arg0 is builtinname, 1 is number to map to.
//FTE_STRINGS
{"strstrofs", PF_strstrofs, 0, 0, 0, 221},
{"str2chr", PF_str2chr, 0, 0, 0, 222},
{"chr2str", PF_chr2str, 0, 0, 0, 223},
@ -7974,8 +8065,16 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
{"strncmp", PF_strncmp, 0, 0, 0, 228},
{"strcasecmp", PF_strcasecmp, 0, 0, 0, 229},
{"strncasecmp", PF_strncasecmp, 0, 0, 0, 230},
//END FTE_STRINGS
//FTE_CALLTIMEOFDAY
{"calltimeofday", PF_calltimeofday, 0, 0, 0, 231},
//EXT_CSQC
{"clientstat", PF_clientstat, 0, 0, 0, 232},
{"runclientphys", PF_runclientphys, 0, 0, 0, 233},
//END EXT_CSQC
//end fte extras
//DP extras
@ -8369,6 +8468,13 @@ void PR_RegisterFields(void) //it's just easier to do it this way.
fieldfloat(dimension_solid);
fieldfloat(dimension_hit);
fieldfunction(SendEntity);
fieldfloat(Version);
//Tell the qc library to split the entity fields each side.
//the fields above become < 0, the remaining fields specified by the qc stay where the mod specified, as far as possible (with addons at least).
//this means that custom array offsets still work in mods like ktpro.
if (pr_fixbrokenqccarrays.value)
PR_RegisterFieldVar(svprogfuncs, 0, NULL, 0,0);
}

View File

@ -268,5 +268,10 @@ typedef struct entvars_s
float light_level;//hexen2's grabbing light level from client
float abslight; //hexen2's force a lightlevel
float hasted; //hexen2 uses this AS WELL as maxspeed
//csqc stuph.
func_t SendEntity;
float Version;
} entvars_t;

View File

@ -255,6 +255,8 @@ typedef struct
//end this lot... (demo playback)
svcustomtents_t customtents[255];
int csqcentversion[MAX_EDICTS];//prevents ent versions from going backwards
} server_t;
@ -398,6 +400,12 @@ typedef struct client_s
int spec_track; // entnum of player tracking
#ifdef PEXT_CSQC
int csqclastsentsequence;
int csqcentsequence[MAX_EDICTS];//the sequence number a csqc entity was sent in
int csqcentversions[MAX_EDICTS];//the version of the entity when it was sent in that sequenced packet.
#endif
//true/false/persist
qbyte ismuted;
qbyte iscuffed;
@ -421,6 +429,8 @@ typedef struct client_s
int delta_sequence; // -1 = no compression
netchan_t netchan;
int lastsequence_acknoledged;
svvoicechat_t voicechat;
#ifdef SVCHAT
@ -749,6 +759,15 @@ typedef enum multicast_e
} multicast_t;
#endif
//shared with qc
#define MSG_BROADCAST 0 // unreliable to all
#define MSG_ONE 1 // reliable to one (msg_entity)
#define MSG_ALL 2 // reliable to all
#define MSG_INIT 3 // write to the init string
#define MSG_MULTICAST 4 // for multicast()
#define MSG_CSQC 5 // for writing csqc entities
//============================================================================
extern cvar_t sv_mintic, sv_maxtic;

View File

@ -143,16 +143,6 @@ qboolean SV_DemoNailUpdate (int i)
return true;
}
static qboolean SV_AddCSQCUpdate (edict_t *ent)
{
// if (!ent->sendcsqc)
return false;
// csqcent[csqcnuments++] = ent;
// return true;
}
#ifdef PEXT_LIGHTUPDATES
qboolean SV_AddLightUpdate (edict_t *ent)
{
@ -271,9 +261,159 @@ void SV_EmitNailUpdate (sizebuf_t *msg, qboolean recorder)
}
}
//=============================================================================
//this is the bit of the code that sends the csqc entity deltas out.
//whenever the entity in question has a newer version than we sent to the client, we need to resend.
//So, we track the outgoing sequence that an entity was sent in, and the version.
//Upon detection of a dropped packet, we resend all entities who were last sent in that packet.
//When an entities' last sent version doesn't match the current version, we send.
static qboolean SV_AddCSQCUpdate (client_t *client, edict_t *ent)
{
#ifndef PEXT_CSQC
return false;
#else
if (!(client->fteprotocolextensions & PEXT_CSQC))
return false;
if (!ent->v.SendEntity)
return false;
csqcent[csqcnuments++] = ent;
return true;
#endif
}
sizebuf_t csqcmsgbuffer;
void SV_EmitCSQCUpdate(client_t *client, sizebuf_t *msg)
{
#ifdef PEXT_CSQC
qbyte messagebuffer[1024];
int en;
int currentsequence = client->netchan.outgoing_sequence;
unsigned short mask;
globalvars_t *pr_globals = PR_globals(svprogfuncs, PR_CURRENT);
edict_t *ent;
qboolean writtenheader = false;
// if (!csqcnuments)
// return;
if (!(client->fteprotocolextensions & PEXT_CSQC))
return;
//FIXME: prioritise the list of csqc ents somehow
csqcmsgbuffer.data = messagebuffer;
csqcmsgbuffer.maxsize = sizeof(messagebuffer);
csqcmsgbuffer.packing = msg->packing;
for (en = 0; en < csqcnuments; en++)
{
ent = csqcent[en];
//prevent mishaps with entities being respawned and things.
if ((int)ent->v.Version < sv.csqcentversion[ent->entnum])
ent->v.Version = sv.csqcentversion[ent->entnum];
else
sv.csqcentversion[ent->entnum] = (int)ent->v.Version;
//If it's not changed, don't send
if (client->csqcentversions[ent->entnum] == sv.csqcentversion[ent->entnum])
continue;
csqcmsgbuffer.cursize = 0;
csqcmsgbuffer.currentbit = 0;
//Ask CSQC to write a buffer for it.
G_INT(OFS_PARM0) = EDICT_TO_PROG(svprogfuncs, client->edict);
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, ent);
PR_ExecuteProgram(svprogfuncs, ent->v.SendEntity);
if (G_INT(OFS_RETURN)) //0 means not to tell the client about it.
{
if (msg->cursize + csqcmsgbuffer.cursize+5 >= msg->maxsize)
{
if (csqcmsgbuffer.cursize < 32)
break;
continue;
}
if (!writtenheader)
{
writtenheader=true;
MSG_WriteByte(msg, svc_csqcentities);
}
MSG_WriteShort(msg, ent->entnum);
//FIXME: Add a developer mode to write the length of each entity.
SZ_Write(msg, csqcmsgbuffer.data, csqcmsgbuffer.cursize);
Con_Printf("Sending update packet %i\n", ent->entnum);
}
else if (sv.csqcentversion[ent->entnum])
{ //Don't want to send.
if (!writtenheader)
{
writtenheader=true;
MSG_WriteByte(msg, svc_csqcentities);
}
mask = (unsigned)ent->entnum | 0x8000;
MSG_WriteShort(msg, mask);
Con_Printf("Sending remove 2 packet\n");
}
client->csqcentversions[ent->entnum] = sv.csqcentversion[ent->entnum];
client->csqcentsequence[ent->entnum] = currentsequence;
}
for (en = 1; en < sv.num_edicts; en++)
{
if (client->csqcentversions[en] && (client->csqcentversions[en] != sv.csqcentversion[en]))
{
ent = EDICT_NUM(svprogfuncs, en);
// if (!ent->isfree)
// continue;
if (msg->cursize + 5 >= msg->maxsize) //try removing next frame instead.
{
}
else
{
if (!writtenheader)
{
writtenheader=true;
MSG_WriteByte(msg, svc_csqcentities);
}
Con_Printf("Sending remove packet %i\n", en);
mask = (unsigned)en | 0x8000;
MSG_WriteShort(msg, mask);
client->csqcentversions[en] = 0;
client->csqcentsequence[en] = currentsequence;
}
}
}
if (writtenheader)
MSG_WriteShort(msg, 0); //a 0 means no more.
csqcnuments = 0;
//prevent the qc from trying to use it at inopertune times.
csqcmsgbuffer.maxsize = 0;
csqcmsgbuffer.data = NULL;
#endif
}
void SV_CSQC_DroppedPacket(client_t *client, int sequence)
{
#ifdef PEXT_CSQC
int i;
for (i = 0; i < sv.num_edicts; i++)
if (client->csqcentsequence[i] == sequence)
client->csqcentversions[i]--; //do that update thang (but later).
#endif
}
//=============================================================================
@ -1335,7 +1475,7 @@ void SV_WritePlayersToClient (client_t *client, edict_t *clent, qbyte *pvs, size
continue; //not in this dimension - sorry...
}
if (SV_AddCSQCUpdate(ent))
if (SV_AddCSQCUpdate(client, ent))
continue;
{
@ -2095,7 +2235,7 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore
if (!((int)client->edict->v.dimension_see & ((int)ent->v.dimension_seen | (int)ent->v.dimension_ghost)))
continue; //not in this dimension - sorry...
if (SV_AddCSQCUpdate(ent)) //csqc took it.
if (SV_AddCSQCUpdate(client, ent)) //csqc took it.
continue;
#ifdef NQPROT
@ -2250,6 +2390,8 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore
SV_EmitPacketEntities (client, pack, msg);
SV_EmitCSQCUpdate(client, msg);
// now add the specialized nail update
SV_EmitNailUpdate (msg, ignorepvs);
}

View File

@ -754,9 +754,19 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
if (!svs.clients[i].state && svs.clients[i].name[0]) //this is a bot.
svs.clients[i].name[0] = '\0'; //make it go away
#ifdef PEXT_CSQC
memset(svs.clients[i].csqcentsequence, 0, sizeof(svs.clients[i].csqcentsequence));
memset(svs.clients[i].csqcentversions, 0, sizeof(svs.clients[i].csqcentversions));
#endif
}
sv.allocated_client_slots = i;
#ifdef PEXT_CSQC
for (i=0 ; i<MAX_EDICTS ; i++)
sv.csqcentversion[i] = 1; //force all csqc edicts to start off as version 1
#endif
}
#ifdef Q2SERVER
else

Some files were not shown because too many files have changed in this diff Show More