Q2 now runs properly.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@902 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2005-03-18 06:13:11 +00:00
parent 300734ae71
commit 74f9fa8581
10 changed files with 185 additions and 156 deletions

View File

@ -62,7 +62,7 @@ Q2SOLID_BSP // bsp clip, touch on edge
#define MAXTOUCH 32
typedef struct
typedef struct q2pmove_s
{
// state (in / out)
q2pmove_state_t s;
@ -85,10 +85,12 @@ typedef struct
int waterlevel;
// callbacks to test the world
q2trace_t (*trace) (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end);
int (*pointcontents) (vec3_t point);
q2trace_t (VARGS *trace) (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end);
int (VARGS *pointcontents) (vec3_t point);
} q2pmove_t;
void VARGS Q2_Pmove (q2pmove_t *pmove);
//===============================================================
// link_t is only used for entity area links now
@ -173,6 +175,7 @@ struct q2edict_s
//
// functions provided by the main engine
//
//yes, these are all VARGS, for the calling convention rather than actually being varargs.
typedef struct
{
// special messages
@ -180,73 +183,73 @@ typedef struct
void (VARGS *dprintf) (char *fmt, ...);
void (VARGS *cprintf) (q2edict_t *ent, int printlevel, char *fmt, ...);
void (VARGS *centerprintf) (q2edict_t *ent, char *fmt, ...);
void (*sound) (q2edict_t *ent, int channel, int soundindex, float volume, float attenuation, float timeofs);
void (*positioned_sound) (vec3_t origin, q2edict_t *ent, int channel, int soundinedex, float volume, float attenuation, float timeofs);
void (VARGS *sound) (q2edict_t *ent, int channel, int soundindex, float volume, float attenuation, float timeofs);
void (VARGS *positioned_sound) (vec3_t origin, q2edict_t *ent, int channel, int soundinedex, float volume, float attenuation, float timeofs);
// config strings hold all the index strings, the lightstyles,
// and misc data like the sky definition and cdtrack.
// All of the current configstrings are sent to clients when
// they connect, and changes are sent to all connected clients.
void (*configstring) (int num, char *string);
void (VARGS *configstring) (int num, char *string);
void (VARGS *error) (char *fmt, ...);
// the *index functions create configstrings and some internal server state
int (*modelindex) (char *name);
int (*soundindex) (char *name);
int (*imageindex) (char *name);
int (VARGS *modelindex) (char *name);
int (VARGS *soundindex) (char *name);
int (VARGS *imageindex) (char *name);
void (*setmodel) (q2edict_t *ent, char *name);
void (VARGS *setmodel) (q2edict_t *ent, char *name);
// collision detection
q2trace_t (*trace) (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, q2edict_t *passent, int contentmask);
int (*pointcontents) (vec3_t point);
qboolean (*inPVS) (vec3_t p1, vec3_t p2);
qboolean (*inPHS) (vec3_t p1, vec3_t p2);
void (*SetAreaPortalState) (int portalnum, qboolean open);
qboolean (*AreasConnected) (int area1, int area2);
q2trace_t (VARGS *trace) (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, q2edict_t *passent, int contentmask);
int (VARGS *pointcontents) (vec3_t point);
qboolean (VARGS *inPVS) (vec3_t p1, vec3_t p2);
qboolean (VARGS *inPHS) (vec3_t p1, vec3_t p2);
void (VARGS *SetAreaPortalState) (int portalnum, qboolean open);
qboolean (VARGS *AreasConnected) (int area1, int area2);
// an entity will never be sent to a client or used for collision
// if it is not passed to linkentity. If the size, position, or
// solidity changes, it must be relinked.
void (*linkentity) (q2edict_t *ent);
void (*unlinkentity) (q2edict_t *ent); // call before removing an interactive edict
int (*BoxEdicts) (vec3_t mins, vec3_t maxs, q2edict_t **list, int maxcount, int areatype);
void (*Pmove) (q2pmove_t *pmove); // player movement code common with client prediction
void (VARGS *linkentity) (q2edict_t *ent);
void (VARGS *unlinkentity) (q2edict_t *ent); // call before removing an interactive edict
int (VARGS *BoxEdicts) (vec3_t mins, vec3_t maxs, q2edict_t **list, int maxcount, int areatype);
void (VARGS *Pmove) (q2pmove_t *pmove); // player movement code common with client prediction
// network messaging
void (*multicast) (vec3_t origin, multicast_t to);
void (*unicast) (q2edict_t *ent, qboolean reliable);
void (*WriteChar) (int c);
void (*WriteByte) (int c);
void (*WriteShort) (int c);
void (*WriteLong) (int c);
void (*WriteFloat) (float f);
void (*WriteString) (char *s);
void (*WritePosition) (vec3_t pos); // some fractional bits
void (*WriteDir) (vec3_t pos); // single byte encoded, very coarse
void (*WriteAngle) (float f);
void (VARGS *multicast) (vec3_t origin, multicast_t to);
void (VARGS *unicast) (q2edict_t *ent, qboolean reliable);
void (VARGS *WriteChar) (int c);
void (VARGS *WriteByte) (int c);
void (VARGS *WriteShort) (int c);
void (VARGS *WriteLong) (int c);
void (VARGS *WriteFloat) (float f);
void (VARGS *WriteString) (char *s);
void (VARGS *WritePosition) (vec3_t pos); // some fractional bits
void (VARGS *WriteDir) (vec3_t pos); // single byte encoded, very coarse
void (VARGS *WriteAngle) (float f);
// managed memory allocation
void *(*TagMalloc) (int size, int tag);
void (*TagFree) (void *block);
void (*FreeTags) (int tag);
void *(VARGS *TagMalloc) (int size, int tag);
void (VARGS *TagFree) (void *block);
void (VARGS *FreeTags) (int tag);
// console variable interaction
cvar_t *(*cvar) (char *var_name, char *value, int flags);
cvar_t *(*cvar_set) (char *var_name, char *value);
cvar_t *(*cvar_forceset) (char *var_name, char *value);
cvar_t *(VARGS *cvar) (char *var_name, char *value, int flags);
cvar_t *(VARGS *cvar_set) (char *var_name, char *value);
cvar_t *(VARGS *cvar_forceset) (char *var_name, char *value);
// ClientCommand and ServerCommand parameter access
int (*argc) (void);
char *(*argv) (int n);
char *(*args) (void); // concatenation of all argv >= 1
int (VARGS *argc) (void);
char *(VARGS *argv) (int n);
char *(VARGS *args) (void); // concatenation of all argv >= 1
// add commands to the server console as if they were typed in
// for map changing, etc
void (*AddCommandString) (char *text);
void (VARGS *AddCommandString) (char *text);
void (*DebugGraph) (float value, int color);
void (VARGS *DebugGraph) (float value, int color);
} game_import_t;
//
@ -259,38 +262,38 @@ typedef struct
// the init function will only be called when a game starts,
// not each time a level is loaded. Persistant data for clients
// and the server can be allocated in init
void (*Init) (void);
void (*Shutdown) (void);
void (VARGS *Init) (void);
void (VARGS *Shutdown) (void);
// each new level entered will cause a call to SpawnEntities
void (*SpawnEntities) (char *mapname, char *entstring, char *spawnpoint);
void (VARGS *SpawnEntities) (char *mapname, char *entstring, char *spawnpoint);
// Read/Write Game is for storing persistant cross level information
// about the world state and the clients.
// WriteGame is called every time a level is exited.
// ReadGame is called on a loadgame.
void (*WriteGame) (char *filename, qboolean autosave);
void (*ReadGame) (char *filename);
void (VARGS *WriteGame) (char *filename, qboolean autosave);
void (VARGS *ReadGame) (char *filename);
// ReadLevel is called after the default map information has been
// loaded with SpawnEntities
void (*WriteLevel) (char *filename);
void (*ReadLevel) (char *filename);
void (VARGS *WriteLevel) (char *filename);
void (VARGS *ReadLevel) (char *filename);
qboolean (*ClientConnect) (q2edict_t *ent, char *userinfo);
void (*ClientBegin) (q2edict_t *ent);
void (*ClientUserinfoChanged) (q2edict_t *ent, char *userinfo);
void (*ClientDisconnect) (q2edict_t *ent);
void (*ClientCommand) (q2edict_t *ent);
void (*ClientThink) (q2edict_t *ent, q2usercmd_t *cmd);
qboolean (VARGS *ClientConnect) (q2edict_t *ent, char *userinfo);
void (VARGS *ClientBegin) (q2edict_t *ent);
void (VARGS *ClientUserinfoChanged) (q2edict_t *ent, char *userinfo);
void (VARGS *ClientDisconnect) (q2edict_t *ent);
void (VARGS *ClientCommand) (q2edict_t *ent);
void (VARGS *ClientThink) (q2edict_t *ent, q2usercmd_t *cmd);
void (*RunFrame) (void);
void (VARGS *RunFrame) (void);
// ServerCommand will be called when an "sv <command>" command is issued on the
// server console.
// The game can issue gi.argc() / gi.argv() commands to get the rest
// of the parameters
void (*ServerCommand) (void);
void (VARGS *ServerCommand) (void);
//
// global variables shared between game and server

View File

@ -30,7 +30,12 @@ void SV_SavegameComment (char *text)
i = SAVEGAME_COMMENT_LENGTH;
memcpy (text, mapname, i);
}
sprintf (kills,"kills:%3i/%3i", (int)pr_global_struct->killed_monsters, (int)pr_global_struct->total_monsters);
if (ge) //q2
{
sprintf (kills,"");
}
else
sprintf (kills,"kills:%3i/%3i", (int)pr_global_struct->killed_monsters, (int)pr_global_struct->total_monsters);
memcpy (text+22, kills, strlen(kills));
// convert space to _ to make stdio happy
for (i=0 ; i<SAVEGAME_COMMENT_LENGTH ; i++)
@ -466,6 +471,7 @@ qboolean SV_LoadLevelCache(char *level, char *startspot, qboolean ignoreplayers)
int filelen, filepos;
char *file;
gametype_e gametype;
levelcache_t *cache;
@ -480,17 +486,25 @@ qboolean SV_LoadLevelCache(char *level, char *startspot, qboolean ignoreplayers)
if (!cache)
return false; //not visited yet. Ignore the existing caches as fakes.
gametype = cache->gametype;
sprintf (name, "%s/saves/%s", com_gamedir, level);
COM_DefaultExtension (name, ".lvc");
// Con_TPrintf (STL_LOADGAMEFROM, name);
#ifdef Q2SERVER
if (ge)
if (gametype == GT_QUAKE2)
{
SV_SpawnServer (level, startspot, false, false);
SV_ClearWorld();
if (!ge)
{
Con_Printf("Incorrect gamecode type.\n");
return false;
}
ge->ReadLevel(name);
for (i=0 ; i<100 ; i++) //run for 10 secs to iron out a few bugs.
@ -540,6 +554,11 @@ qboolean SV_LoadLevelCache(char *level, char *startspot, qboolean ignoreplayers)
fscanf (f, "%f\n",&time);
SV_SpawnServer (mapname, startspot, false, false);
if (svs.gametype != gametype)
{
Con_Printf("Incorrect gamecode type. Cannot load game.\n");
return false;
}
if (sv.state != ss_active)
{
fclose (f);
@ -670,6 +689,7 @@ void SV_SaveLevelCache(qboolean dontharmgame)
cache->mapname = (char *)(cache+1);
strcpy(cache->mapname, sv.name);
cache->gametype = svs.gametype;
cache->next = svs.levcache;
svs.levcache = cache;
}
@ -682,7 +702,7 @@ void SV_SaveLevelCache(qboolean dontharmgame)
Con_TPrintf (STL_SAVEGAMETO, name);
#ifdef Q2SERVER
if (!svprogfuncs)
if (ge)
{
char path[256];
strcpy(path, name);
@ -805,7 +825,7 @@ void SV_Savegame_f (void)
return;
}
SV_SavegameComment(comment);
fprintf (f, "%d\n", FTESAVEGAME_VERSION);
fprintf (f, "%d\n", FTESAVEGAME_VERSION+svs.gametype);
fprintf (f, "%s\n", comment);
fprintf(f, "%i\n", sv.allocated_client_slots);
@ -914,6 +934,7 @@ void SV_Loadgame_f (void)
int clnum;
int slots;
client_t *cl;
gametype_e gametype;
int len, buflen=0;
char *buffer=NULL;
@ -933,25 +954,30 @@ void SV_Loadgame_f (void)
fgets(str, sizeof(str)-1, f);
version = atoi(str);
if (version != FTESAVEGAME_VERSION)
if (version < FTESAVEGAME_VERSION || version >= FTESAVEGAME_VERSION+GT_MAX)
{
fclose (f);
Con_TPrintf (STL_BADSAVEVERSION, version, FTESAVEGAME_VERSION);
return;
}
gametype = version - FTESAVEGAME_VERSION;
fgets(str, sizeof(str)-1, f);
#ifndef SERVERONLY
if (!cls.state)
#endif
Con_TPrintf (STL_LOADGAMEFROM, filename);
for (clnum = 0; clnum < MAX_CLIENTS; clnum++) //clear the server for the level change.
{
cl = &svs.clients[clnum];
if (cl->state <= cs_zombie)
continue;
MSG_WriteByte (&cl->netchan.message, svc_stufftext);
if (cl->isq2client)
MSG_WriteByte (&cl->netchan.message, svcq2_stufftext);
else
MSG_WriteByte (&cl->netchan.message, svc_stufftext);
MSG_WriteString (&cl->netchan.message, "echo Loading Game;disconnect;wait;wait;reconnect\n"); //kindly ask the client to come again.
cl->istobeloaded = false;
}
@ -1039,8 +1065,6 @@ void SV_Loadgame_f (void)
Cmd_ExecuteString(str, RESTRICT_RCON);
}
SV_FlushLevelCache();
fgets(str, sizeof(str)-1, f);
@ -1063,9 +1087,10 @@ void SV_Loadgame_f (void)
if (!*str)
continue;
cache = Z_Malloc(sizeof(levelcache_t)+strlen(sv.name)+1);
cache = Z_Malloc(sizeof(levelcache_t)+strlen(str)+1);
cache->mapname = (char *)(cache+1);
strcpy(cache->mapname, str);
cache->gametype = gametype;
cache->next = svs.levcache;
@ -1073,7 +1098,6 @@ void SV_Loadgame_f (void)
sprintf (filename, "%s/saves/%s/%s.lvc", com_gamedir, savename, cache->mapname);
fi = fopen(filename, "rb");
if (!fi)
@ -1116,9 +1140,7 @@ void SV_Loadgame_f (void)
fclose(f);
SV_LoadLevelCache(str, "", true);
sv.allocated_client_slots = slots;
}
#endif

View File

@ -642,17 +642,19 @@ typedef struct bannedips_s {
netadr_t adr;
} bannedips_t;
typedef struct levelcache_s {
struct levelcache_s *next;
char *mapname;
} levelcache_t;
typedef enum {
GT_PROGS, //q1, qw, h2 are similar enough that we consider it only one game mode. (We don't support the h2 protocol)
GT_QUAKE2, //q2 servers run from a q2 game dll
GT_QUAKE3 //q3 servers run off the q3 qvm api
GT_QUAKE3, //q3 servers run off the q3 qvm api
GT_MAX
} gametype_e;
typedef struct levelcache_s {
struct levelcache_s *next;
char *mapname;
gametype_e gametype;
} levelcache_t;
typedef struct
{
gametype_e gametype;
@ -891,7 +893,7 @@ void SV_FilterImpulseInit(void);
//svq2_game.c
qboolean SVQ2_InitGameProgs(void);
void SVQ2_ShutdownGameProgs (void);
void VARGS SVQ2_ShutdownGameProgs (void);
//svq2_ents.c
void SV_BuildClientFrame (client_t *client);
@ -923,7 +925,7 @@ void SV_ClearQCStats(void);
void SV_SendClientMessages (void);
void SV_Multicast (vec3_t origin, multicast_t to);
void VARGS SV_Multicast (vec3_t origin, multicast_t to);
#define FULLDIMENSIONMASK 0xffffffff
void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int with, int without);
@ -1136,7 +1138,10 @@ int SV_RateForClient(client_t *cl);
void SVVC_Frame (qboolean enabled);
void SV_CalcPHS (void);
#ifdef Q2SERVER
void SVQ2_LinkEdict(q2edict_t *ent);
void VARGS SVQ2_LinkEdict(q2edict_t *ent);
void VARGS SVQ2_UnlinkEdict(q2edict_t *ent);
int VARGS SVQ2_AreaEdicts (vec3_t mins, vec3_t maxs, q2edict_t **list,
int maxcount, int areatype);
#endif
void SV_GetConsoleCommands (void);

View File

@ -440,6 +440,7 @@ void SV_Map_f (void)
Con_TPrintf (STL_MAPCOMMANDUSAGE);
return;
}
strcpy (level, Cmd_Argv(1));
startspot = ((Cmd_Argc() == 2)?NULL:Cmd_Argv(2));
@ -510,7 +511,24 @@ void SV_Map_f (void)
SV_SaveSpawnparms (issamelevel);
if (startspot && !issamelevel && !newunit)
SV_SaveLevelCache(false);
{
if (ge)
{
qboolean savedinuse[MAX_CLIENTS];
for (i=0 ; i<sv.allocated_client_slots; i++)
{
savedinuse[i] = svs.clients[i].q2edict->inuse;
svs.clients[i].q2edict->inuse = false;
}
SV_SaveLevelCache(false);
for (i=0 ; i<sv.allocated_client_slots; i++)
{
svs.clients[i].q2edict->inuse = savedinuse[i];
}
}
else
SV_SaveLevelCache(false);
}
for (i=0 ; i<MAX_CLIENTS ; i++) //we need to drop all q2 clients. We don't mix q1w with q2.
{

View File

@ -445,7 +445,9 @@ void SV_UnspawnServer (void) //terminate the running server.
if (svs.clients[i].state)
SV_DropClient(svs.clients+i);
}
#ifdef Q2SERVER
SVQ2_ShutdownGameProgs();
#endif
sv.worldmodel = NULL;
sv.state = ss_dead;
*sv.name = '\0';

View File

@ -292,7 +292,8 @@ void SV_DropClient (client_t *drop)
return;
}
// add the disconnect
MSG_WriteByte (&drop->netchan.message, drop->isq2client?svcq2_disconnect:svc_disconnect);
if (drop->state != cs_zombie)
MSG_WriteByte (&drop->netchan.message, drop->isq2client?svcq2_disconnect:svc_disconnect);
#ifdef SVRANKING
if (drop->state == cs_spawned)
@ -2701,6 +2702,8 @@ void SV_Impulse_f (void)
Con_Printf("No empty player slots\n");
return;
}
if (!svprogfuncs)
return;
pr_global_struct->time = sv.time;

View File

@ -666,7 +666,7 @@ void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int
}
//version does all the work now
void SV_Multicast (vec3_t origin, multicast_t to)
void VARGS SV_Multicast (vec3_t origin, multicast_t to)
{
SV_MulticastProtExt(origin, to, FULLDIMENSIONMASK, 0, 0);
}

View File

@ -1195,7 +1195,14 @@ void SV_Begin_f (void)
for (split = host_client; split; split = split->controlled)
{
if (split->istobeloaded)
#ifdef Q2SERVER
if (ge)
{
ge->ClientBegin(split->q2edict);
split->istobeloaded = false;
}
#endif
else if (split->istobeloaded)
{
sendangles = true;
split->istobeloaded = false;
@ -1276,12 +1283,6 @@ void SV_Begin_f (void)
host_client = oh;
}
}
#ifdef Q2SERVER
else
{
ge->ClientBegin(split->q2edict);
}
#endif
}
}
}
@ -3705,15 +3706,6 @@ void SV_RunCmd (usercmd_t *ucmd, qboolean recurse)
qboolean jumpable;
extern cvar_t sv_gravity;
#ifdef Q2SERVER
if (!svprogfuncs)
{
ge->ClientThink (host_client->q2edict, (q2usercmd_t*)ucmd);
return;
}
#endif
// DMW copied this KK hack copied from QuakeForge anti-cheat
// (also extra inside parm on all SV_RunCmds that follow)
@ -4381,6 +4373,12 @@ void SVQ2_ExecuteClientMessage (client_t *cl)
int seq_hash;
int lastframe;
if (!ge)
{
Con_Printf("Q2 client without Q2 server\n");
SV_DropClient(cl);
}
// calc ping time
frame = &cl->q2frames[cl->netchan.incoming_acknowledged & Q2UPDATE_MASK];
@ -4479,36 +4477,22 @@ void SVQ2_ExecuteClientMessage (client_t *cl)
if (!sv.paused)
{
/*if (sv_nomsec.value)
{
cmd = newcmd;
SV_ClientThink ();
cl->lastcmd = newcmd;
cl->lastcmd.buttons = 0; // avoid multiple fires on lag
break;
}*/
SV_PreRunCmd();
if (net_drop < 20)
{
while (net_drop > 2)
{
SV_RunCmd (&cl->lastcmd, false);
ge->ClientThink (host_client->q2edict, (q2usercmd_t*)&cl->lastcmd);
net_drop--;
}
if (net_drop > 1)
SV_RunCmd (&oldest, false);
ge->ClientThink (host_client->q2edict, (q2usercmd_t*)&oldest);
if (net_drop > 0)
SV_RunCmd (&oldcmd, false);
ge->ClientThink (host_client->q2edict, (q2usercmd_t*)&oldcmd);
}
SV_RunCmd (&newcmd, false);
SV_PostRunCmd();
ge->ClientThink (host_client->q2edict, (q2usercmd_t*)&newcmd);
}
cl->lastcmd = newcmd;
cl->lastcmd.buttons = 0; // avoid multiple fires on lag
break;
case clcq2_userinfo:

View File

@ -10,11 +10,6 @@ qboolean SVQ2_InitGameProgs(void)
#else
game_export_t *ge;
int SVQ2_AreaEdicts (vec3_t mins, vec3_t maxs, q2edict_t **list,
int maxcount, int areatype);
void SVQ2_LinkEdict(q2edict_t *ent);
void SVQ2_UnlinkEdict(q2edict_t *ent);
trace_t SVQ2_Move (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int type, q2edict_t *passedict);
@ -31,7 +26,7 @@ PF_Unicast
Sends the contents of the mutlicast buffer to a single client
===============
*/
static void PFQ2_Unicast (q2edict_t *ent, qboolean reliable)
static void VARGS PFQ2_Unicast (q2edict_t *ent, qboolean reliable)
{
int p;
client_t *client;
@ -172,7 +167,7 @@ PF_Configstring
===============
*/
static void PFQ2_Configstring (int i, char *val)
static void VARGS PFQ2_Configstring (int i, char *val)
{
int j;
if (i < 0 || i >= Q2MAX_CONFIGSTRINGS)
@ -278,17 +273,17 @@ static int SVQ2_FindIndex (char *name, int start, int max, char *strings, int st
}
static int SVQ2_ModelIndex (char *name)
static int VARGS SVQ2_ModelIndex (char *name)
{
return SVQ2_FindIndex (name, Q2CS_MODELS, Q2MAX_MODELS, sv.model_precache[1], sizeof(sv.model_precache[0]), true);
}
static int SVQ2_SoundIndex (char *name)
static int VARGS SVQ2_SoundIndex (char *name)
{
return SVQ2_FindIndex (name, Q2CS_SOUNDS, Q2MAX_SOUNDS, sv.sound_precache[1], sizeof(sv.sound_precache[0]), true);
}
static int SVQ2_ImageIndex (char *name)
static int VARGS SVQ2_ImageIndex (char *name)
{
return SVQ2_FindIndex (name, Q2CS_IMAGES, Q2MAX_IMAGES, sv.image_precache[1], sizeof(sv.image_precache[0]), true);
}
@ -300,7 +295,7 @@ PF_setmodel
Also sets mins and maxs for inline bmodels
=================
*/
static void PFQ2_setmodel (q2edict_t *ent, char *name)
static void VARGS PFQ2_setmodel (q2edict_t *ent, char *name)
{
int i;
model_t *mod;
@ -335,18 +330,18 @@ static qboolean CMQ2_Q1BSP_SetAreaPortalState (int portalnum, qboolean open)
return true;
}*/
static void PFQ2_WriteChar (int c) {MSG_WriteChar (&sv.multicast, c);}
static void PFQ2_WriteByte (int c) {MSG_WriteByte (&sv.multicast, c);}
static void PFQ2_WriteShort (int c) {MSG_WriteShort (&sv.multicast, c);}
static void PFQ2_WriteLong (int c) {MSG_WriteLong (&sv.multicast, c);}
static void PFQ2_WriteFloat (float f) {MSG_WriteFloat (&sv.multicast, f);}
static void PFQ2_WriteString (char *s) {MSG_WriteString (&sv.multicast, s);}
static void PFQ2_WriteAngle (float f) {MSG_WriteAngle (&sv.multicast, f);}
static void PFQ2_WritePos (vec3_t pos) { MSG_WriteCoord (&sv.multicast, pos[0]);
static void VARGS PFQ2_WriteChar (int c) {MSG_WriteChar (&sv.multicast, c);}
static void VARGS PFQ2_WriteByte (int c) {MSG_WriteByte (&sv.multicast, c);}
static void VARGS PFQ2_WriteShort (int c) {MSG_WriteShort (&sv.multicast, c);}
static void VARGS PFQ2_WriteLong (int c) {MSG_WriteLong (&sv.multicast, c);}
static void VARGS PFQ2_WriteFloat (float f) {MSG_WriteFloat (&sv.multicast, f);}
static void VARGS PFQ2_WriteString (char *s) {MSG_WriteString (&sv.multicast, s);}
static void VARGS PFQ2_WriteAngle (float f) {MSG_WriteAngle (&sv.multicast, f);}
static void VARGS PFQ2_WritePos (vec3_t pos) { MSG_WriteCoord (&sv.multicast, pos[0]);
MSG_WriteCoord (&sv.multicast, pos[1]);
MSG_WriteCoord (&sv.multicast, pos[2]);
}
static void PFQ2_WriteDir (vec3_t dir) {MSG_WriteDir (&sv.multicast, dir);}
static void VARGS PFQ2_WriteDir (vec3_t dir) {MSG_WriteDir (&sv.multicast, dir);}
/*
=================
@ -355,7 +350,7 @@ PF_inPVS
Also checks portalareas so that doors block sight
=================
*/
static qboolean PFQ2_inPVS (vec3_t p1, vec3_t p2)
static qboolean VARGS PFQ2_inPVS (vec3_t p1, vec3_t p2)
{
int leafnum;
int cluster;
@ -385,7 +380,7 @@ PF_inPHS
Also checks portalareas so that doors block sound
=================
*/
static qboolean PFQ2_inPHS (vec3_t p1, vec3_t p2)
static qboolean VARGS PFQ2_inPHS (vec3_t p1, vec3_t p2)
{
int leafnum;
int cluster;
@ -429,7 +424,7 @@ static qboolean PFQ2_inPHS (vec3_t p1, vec3_t p2)
#define Q2CHAN_BODY 4*/
#define Q2CHAN_RELIABLE 16
void SVQ2_StartSound (vec3_t origin, q2edict_t *entity, int channel,
void VARGS SVQ2_StartSound (vec3_t origin, q2edict_t *entity, int channel,
int soundindex, float volume,
float attenuation, float timeofs)
{
@ -540,7 +535,7 @@ void SVQ2_StartSound (vec3_t origin, q2edict_t *entity, int channel,
}
}
static void PFQ2_StartSound (q2edict_t *entity, int channel, int sound_num, float volume,
static void VARGS PFQ2_StartSound (q2edict_t *entity, int channel, int sound_num, float volume,
float attenuation, float timeofs)
{
if (!entity)
@ -548,7 +543,7 @@ static void PFQ2_StartSound (q2edict_t *entity, int channel, int sound_num, floa
SVQ2_StartSound (NULL, entity, channel, sound_num, volume, attenuation, timeofs);
}
static q2trace_t SVQ2_Trace (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, q2edict_t *passedict, int contentmask)
static q2trace_t VARGS SVQ2_Trace (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, q2edict_t *passedict, int contentmask)
{
q2trace_t ret;
trace_t tr;
@ -562,19 +557,19 @@ static q2trace_t SVQ2_Trace (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end,
return ret;
}
static int SVQ2_PointContents (vec3_t p)
static int VARGS SVQ2_PointContents (vec3_t p)
{
q2trace_t tr = SVQ2_Trace(p, NULL, NULL, p, NULL, ~0);
return tr.contents;
// return CM_PointContents(p, 0);
}
static cvar_t *Q2Cvar_Get (char *var_name, char *value, int flags)
static cvar_t *VARGS Q2Cvar_Get (char *var_name, char *value, int flags)
{
return Cvar_Get(var_name, value, flags, "Quake2 game variables");
}
cvar_t *Q2Cvar_Set (char *var_name, char *value)
cvar_t *VARGS Q2Cvar_Set (char *var_name, char *value)
{
cvar_t *var = Cvar_FindVar(var_name);
if (!var)
@ -584,7 +579,7 @@ cvar_t *Q2Cvar_Set (char *var_name, char *value)
}
return Cvar_Set(var, value);
}
cvar_t *Q2Cvar_ForceSet (char *var_name, char *value)
cvar_t *VARGS Q2Cvar_ForceSet (char *var_name, char *value)
{
cvar_t *var = Cvar_FindVar(var_name);
if (!var)
@ -605,7 +600,7 @@ Called when either the entire server is being killed, or
it is changing to a different game directory.
===============
*/
void SVQ2_ShutdownGameProgs (void)
void VARGS SVQ2_ShutdownGameProgs (void)
{
if (!ge)
return;
@ -614,7 +609,7 @@ void SVQ2_ShutdownGameProgs (void)
ge = NULL;
}
static void AddCommandString(char *command)
static void VARGS AddCommandString(char *command)
{
Cbuf_AddText(command, RESTRICT_LOCAL);
}
@ -627,15 +622,12 @@ Init the game subsystem for a new map
===============
*/
void Q2SCR_DebugGraph(float value, int color)
void VARGS Q2SCR_DebugGraph(float value, int color)
{return;}
void Q2_Pmove (q2pmove_t *pmove);
qboolean SVQ2_InitGameProgs(void)
{
static game_import_t import;
volatile static game_import_t import; //volatile because msvc sucks
if (COM_CheckParm("-noq2dll"))
{
SVQ2_ShutdownGameProgs();
@ -725,7 +717,7 @@ qboolean SVQ2_InitGameProgs(void)
*/
}
ge = (game_export_t *)Sys_GetGameAPI (&import);
ge = (game_export_t *)Sys_GetGameAPI ((game_import_t*)&import);
if (!ge)
return false;

View File

@ -644,7 +644,7 @@ void SV_LinkEdict (edict_t *ent, qboolean touch_triggers)
#ifdef Q2SERVER
void SVQ2_UnlinkEdict(q2edict_t *ent)
void VARGS SVQ2_UnlinkEdict(q2edict_t *ent)
{
if (!ent->area.prev)
return; // not linked in anywhere
@ -652,7 +652,7 @@ void SVQ2_UnlinkEdict(q2edict_t *ent)
ent->area.prev = ent->area.next = NULL;
}
void SVQ2_LinkEdict(q2edict_t *ent)
void VARGS SVQ2_LinkEdict(q2edict_t *ent)
{
areanode_t *node;
int leafs[MAX_TOTAL_ENT_LEAFS];
@ -1353,7 +1353,7 @@ void SVQ2_AreaEdicts_r (areanode_t *node)
SVQ2_AreaEdicts_r ( node->children[1] );
}
int SVQ2_AreaEdicts (vec3_t mins, vec3_t maxs, q2edict_t **list,
int VARGS SVQ2_AreaEdicts (vec3_t mins, vec3_t maxs, q2edict_t **list,
int maxcount, int areatype)
{
area_mins = mins;