provide builtin mappings for id (none, really), qf and ktpro/qwe (qw only),

add qwe builtin extensions to qw-server. provide sv_progs_ext to control
the builtin mapping. valid values are "id", "qf" (our old static builtins),
"qwe"/"ktpro" (either works. for ktpro mod support) and "none" (no
mapping). any other value is equivalent to "none".
This commit is contained in:
Bill Currie 2004-01-06 07:00:39 +00:00
parent d7592781d7
commit 133879f8fa
12 changed files with 739 additions and 42 deletions

View file

@ -178,6 +178,23 @@ qboolean PR_EdictValid (progs_t *pr, int e);
#define E_GSTRING(p,e,o) (PR_GetString (p, E_STRING (e, o)))
#define E_DSTRING(p,e,o) (PR_GetDString (p, E_STRING (e, o)))
/*
Builtins are arranged into groups of 65536 to allow for diffent expantion
sets. eg, stock id is 0x0000xxxx, quakeforge is 0x000fxxxx. predefined
groups go up to 0x0fffxxxx allowing 4096 different groups. Builtins
0x10000000 to 0x7fffffff are reserved for auto-allocation. The range
0x8000000 to 0xffffffff is unavailable due to the builtin number being
a negative statement address.
*/
#define PR_RANGE_SHIFT 16
#define PR_RANGE_MASK 0xffff0000
#define PR_RANGE_QF 0x000f
#define PR_RANGE_AUTO 0x1000
#define PR_RANGE_NONE 0xffff
#define PR_AUTOBUILTIN (PR_RANGE_AUTO << PR_RANGE_SHIFT)
typedef void (*builtin_proc) (progs_t *pr);
typedef struct {
const char *name;

View file

@ -592,6 +592,8 @@ PR_gametype (progs_t *pr)
RETURN_STRING (pr, pr_gametype);
}
#define QF (PR_RANGE_QF << PR_RANGE_SHIFT) |
static builtin_t builtins[] = {
{"break", PF_break, 6},
{"random", PF_random, 7},
@ -617,15 +619,15 @@ static builtin_t builtins[] = {
{"stof", PF_stof, 81},
{"strlen", PF_strlen, 100},
{"charcount", PF_charcount, 101},
{"sprintf", PF_sprintf, 109},
{"ftoi", PF_ftoi, 110},
{"itof", PF_itof, 111},
{"itos", PF_itos, 112},
{"stoi", PF_stoi, 113},
{"stov", PF_stov, 114},
{"gametype", PR_gametype, 115},
{"strlen", PF_strlen, QF 100},
{"charcount", PF_charcount, QF 101},
{"sprintf", PF_sprintf, QF 109},
{"ftoi", PF_ftoi, QF 110},
{"itof", PF_itof, QF 111},
{"itos", PF_itos, QF 112},
{"stoi", PF_stoi, QF 113},
{"stov", PF_stov, QF 114},
{"gametype", PR_gametype, QF 115},
{0}
};

View file

@ -54,16 +54,6 @@ static __attribute__ ((unused)) const char rcsid[] =
#include "compat.h"
/*
Builtins are arranged into groups of 65536 to allow for diffent expantion
sets. eg, stock id is 0x0000xxxx, quakeforge is 0x000fxxxx. predefined
groups go up to 0x0fffxxxx allowing 4096 different groups. Builtins
0x10000000 to 0x7fffffff are reserved for auto-allocation. The range
0x8000000 to 0xffffffff is unavailable due to the builtin number being
a negative statement address.
*/
#define PR_AUTOBUILTIN 0x10000000
static const char *
builtin_get_key (void *_bi, void *unused)
{

View file

@ -187,6 +187,9 @@ typedef struct
extern sv_fields_t sv_fields;
#define PR_RANGE_ID 0x0000
#define PR_RANGE_ID_MAX 82
#if TYPECHECK_PROGS
#define SVFIELD(e,f,t) E_var (e, PR_AccessField (&sv_pr_state, #f, ev_##t, __FILE__, __LINE__), t)
#else

View file

@ -1351,6 +1351,8 @@ PF_checkextension (progs_t *pr)
R_FLOAT (pr) = 0; // FIXME: make this function actually useful
}
#define QF (PR_RANGE_QF << PR_RANGE_SHIFT) |
static builtin_t builtins[] = {
{"makevectors", PF_makevectors, 1},
{"setorigin", PF_setorigin, 2},
@ -1397,12 +1399,12 @@ static builtin_t builtins[] = {
{"precache_sound2", PF_precache_sound, 76},
{"precache_file2", PF_precache_file, 77},
{"setspawnparms", PF_setspawnparms, 78},
{"hullpointcontents", PF_hullpointcontents, 93},
{"getboxbounds", PF_getboxbounds, 94},
{"getboxhull", PF_getboxhull, 95},
{"freeboxhull", PF_freeboxhull, 96},
{"rotate_bbox", PF_rotate_bbox, 97},
{"checkextension", PF_checkextension, 99},
{"hullpointcontents", PF_hullpointcontents, QF 93},
{"getboxbounds", PF_getboxbounds, QF 94},
{"getboxhull", PF_getboxhull, QF 95},
{"freeboxhull", PF_freeboxhull, QF 96},
{"rotate_bbox", PF_rotate_bbox, QF 97},
{"checkextension", PF_checkextension, QF 99},
{0}
};

View file

@ -43,6 +43,7 @@ static __attribute__ ((unused)) const char rcsid[] =
#include "QF/cvar.h"
#include "QF/quakefs.h"
#include "compat.h"
#include "host.h"
#include "server.h"
#include "sv_progs.h"
@ -55,6 +56,7 @@ sv_fields_t sv_fields;
cvar_t *sv_progs;
cvar_t *sv_progs_zone;
cvar_t *sv_progs_ext;
cvar_t *pr_checkextensions;
cvar_t *nomonsters;
@ -71,6 +73,22 @@ cvar_t *saved4;
func_t EndFrame;
static int sv_range;
static unsigned
bi_map (progs_t *pr, unsigned binum)
{
unsigned range;
if (sv_range != PR_RANGE_NONE) {
range = (binum & PR_RANGE_MASK) >> PR_RANGE_SHIFT;
if (!range && binum > PR_RANGE_ID_MAX)
binum |= sv_range << PR_RANGE_SHIFT;
}
return binum;
}
static int
prune_edict (progs_t *pr, edict_t *ent)
{
@ -143,12 +161,25 @@ SV_LoadProgs (void)
ddef_t *def;
dfunction_t *f;
const char *progs_name = "progs.dat";
const char *range;
if (qfs_gamedir->gamecode && *qfs_gamedir->gamecode)
progs_name = qfs_gamedir->gamecode;
if (*sv_progs->string)
progs_name = sv_progs->string;
if (strequal (sv_progs_ext->string, "qf")) {
sv_range = PR_RANGE_QF;
range = "QF";
} else if (strequal (sv_progs_ext->string, "id")) {
sv_range = PR_RANGE_ID;
range = "ID";
} else {
sv_range = PR_RANGE_NONE;
range = "None";
}
Con_DPrintf ("Using %s builtin extention mapping\n", range);
PR_LoadProgs (&sv_pr_state, progs_name, sv.max_edicts,
sv_progs_zone->int_val * 1024);
if (!sv_pr_state.progs)
@ -342,6 +373,7 @@ SV_Progs_Init (void)
sv_pr_state.unlink = SV_UnlinkEdict;
sv_pr_state.parse_field = parse_field;
sv_pr_state.prune_edict = prune_edict;
sv_pr_state.bi_map = bi_map;
SV_PR_Cmds_Init ();
@ -362,6 +394,9 @@ SV_Progs_Init_Cvars (void)
"Override the default game progs.");
sv_progs_zone = Cvar_Get ("sv_progs_zone", "256", CVAR_NONE, NULL,
"size of the zone for progs in kb");
sv_progs_ext = Cvar_Get ("sv_progs_ext", "qf", CVAR_NONE, NULL,
"extention mapping to use: "
"none, id, qf");
pr_checkextensions = Cvar_Get ("pr_checkextensions", "1", CVAR_ROM, NULL,
"indicate the presence of the "
"checkextentions qc function");

36
qw/include/sv_pr_qwe.h Normal file
View file

@ -0,0 +1,36 @@
/*
sv_pr_qwe.h
server side QuakeC builtins
Copyright (C) 1996-1997 Id Software, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
$Id$
*/
#ifndef __sv_pr_qwe_h
#define __sv_pr_qwe_h
struct progs_s;
void SV_PR_QWE_Init (struct progs_s *pr);
#endif // __sv_pr_qwe_h

View file

@ -176,6 +176,10 @@ extern sv_fields_t sv_fields;
extern struct progs_s sv_pr_state;
#define PR_RANGE_ID 0x0000
#define PR_RANGE_ID_MAX 82
#define PR_RANGE_QWE 0x0001
#if TYPECHECK_PROGS
#define SVFIELD(e,f,t) E_var (e, PR_AccessField (&sv_pr_state, #f, ev_##t, __FILE__, __LINE__), t)
#else

View file

@ -70,8 +70,8 @@ EXTRA_DIST=sv_sys_win.c sv_sys_unix.c
libqw_server_a_SOURCES= \
crudefile.c sv_ccmds.c sv_demo.c sv_ents.c sv_gib.c sv_init.c sv_main.c \
sv_move.c sv_nchan.c sv_phys.c sv_pr_cmds.c sv_progs.c sv_send.c \
sv_user.c world.c $(syssv_SRC)
sv_move.c sv_nchan.c sv_phys.c sv_pr_cmds.c sv_pr_qwe.c sv_progs.c \
sv_send.c sv_user.c world.c $(syssv_SRC)
qf_server_LIBS= \
$(SERVER_PLUGIN_STATIC_LIBS) \

View file

@ -1912,6 +1912,8 @@ PR_SV_Spawn (progs_t *pr)
SV_Spawn (cl);
}
#define QF (PR_RANGE_QF << PR_RANGE_SHIFT) |
static builtin_t builtins[] = {
{"makevectors", PF_makevectors, 1},
{"setorigin", PF_setorigin, 2},
@ -1974,22 +1976,22 @@ static builtin_t builtins[] = {
{"logfrag", PF_logfrag, 79},
{"infokey", PF_infokey, 80},
{"multicast", PF_multicast, 82},
{"testentitypos", PF_testentitypos, 92},
{"hullpointcontents", PF_hullpointcontents, 93},
{"getboxbounds", PF_getboxbounds, 94},
{"getboxhull", PF_getboxhull, 95},
{"freeboxhull", PF_freeboxhull, 96},
{"rotate_bbox", PF_rotate_bbox, 97},
{"testentitypos", PF_testentitypos, QF 92},
{"hullpointcontents", PF_hullpointcontents, QF 93},
{"getboxbounds", PF_getboxbounds, QF 94},
{"getboxhull", PF_getboxhull, QF 95},
{"freeboxhull", PF_freeboxhull, QF 96},
{"rotate_bbox", PF_rotate_bbox, QF 97},
{"checkmove", PF_checkmove, 98},
{"checkextension", PF_checkextension, 99},
{"setinfokey", PF_setinfokey, 102},
{"cfopen", PF_cfopen, 103},
{"cfclose", PF_cfclose, 104},
{"cfread", PF_cfread, 105},
{"cfwrite", PF_cfwrite, 106},
{"cfeof", PF_cfeof, 107},
{"cfquota", PF_cfquota, 108},
{"checkmove", PF_checkmove, QF 98},
{"checkextension", PF_checkextension, QF 99},
{"setinfokey", PF_setinfokey, QF 102},
{"cfopen", PF_cfopen, QF 103},
{"cfclose", PF_cfclose, QF 104},
{"cfread", PF_cfread, QF 105},
{"cfwrite", PF_cfwrite, QF 106},
{"cfeof", PF_cfeof, QF 107},
{"cfquota", PF_cfquota, QF 108},
{"SV_AllocClient", PF_SV_AllocClient, -1},
{"SV_FreeClient", PF_SV_FreeClient, -1},

566
qw/source/sv_pr_qwe.c Normal file
View file

@ -0,0 +1,566 @@
/*
sv_pr_qwe.c
qwe extentions needed by the KTPro mod
Copyright (C) 2003 Bill Currie
Author: Bill Currie <bill@taniwha.org>
Date: 2003/11/17
taken from qwe (actual author currently unkown, probably
`highlander') and ported to qf
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
static __attribute__ ((unused))
const char rcsid[] = "$Id$";
#ifdef HAVE_STRING_H
# include <string.h>
#endif
#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif
#include "QF/cbuf.h"
#include "QF/cmd.h"
#include "QF/dstring.h"
#include "QF/idparse.h"
#include "QF/progs.h"
#include "QF/quakefs.h"
#include "QF/sys.h"
#include "QF/va.h"
#include "sv_demo.h"
#include "sv_pr_qwe.h"
#include "sv_progs.h"
typedef struct {
func_t timeofday;
func_t ConsoleCmd;
func_t UserCmd;
} qwe_funcs_t;
static qwe_funcs_t qwe_funcs;
static void
PF_executecmd (progs_t * pr)
{
int old_other, old_self; // mod_consolecmd will be executed, so
// we need to store these
old_self = *sv_globals.self;
old_other = *sv_globals.other;
Cbuf_Execute (sv_cbuf);
*sv_globals.self = old_self;
*sv_globals.other = old_other;
}
/*
PF_tokanize
tokanize string
void tokanize(string)
*/
static void
PF_tokanize (progs_t * pr)
{
const char *str;
str = P_GSTRING (pr, 0);
COM_TokenizeString (str, sv_args);
cmd_args = sv_args;
}
/*
PF_argc
returns number of tokens (must be executed after PF_Tokanize!)
float argc(void)
*/
static void
PF_argc (progs_t * pr)
{
R_FLOAT (pr) = (float) Cmd_Argc ();
}
/*
PF_argv
returns token requested by user (must be executed after PF_Tokanize!)
string argc(float)
*/
static void
PF_argv (progs_t * pr)
{
int num;
num = (int) P_FLOAT (pr, 0);
if (num < 0)
num = 0;
if (num > Cmd_Argc () - 1)
num = Cmd_Argc () - 1;
RETURN_STRING (pr, Cmd_Argv (num));
}
/*
PF_teamfield
string teamfield(.string field)
*/
static void
PF_teamfield (progs_t * pr)
{
sv_fields.team_str = P_INT (pr, 0);
}
/*
PF_substr
string substr(string str, float start, float len)
*/
static void
PF_substr (progs_t * pr)
{
const char *s;
char *tmp;
int start, len, l;
s = P_GSTRING (pr, 0);
start = (int) P_FLOAT (pr, 1);
len = (int) P_FLOAT (pr, 2);
l = strlen (s);
if (start >= l || !len || !*s) {
R_STRING (pr) = 0;
return;
}
s += start;
l -= start;
if (len > l + 1)
len = l + 1;
tmp = Hunk_TempAlloc (len);
strncpy (tmp, s, len - 1);
tmp[len] = 0;
RETURN_STRING (pr, tmp);
}
/*
PF_strcat
string strcat(string str1, string str2)
*/
static void
PF_strcat (progs_t * pr)
{
RETURN_STRING (pr, PF_VarString (pr, 0));
}
/*
PF_strlen
float strlen(string str)
*/
static void
PF_strlen (progs_t * pr)
{
R_FLOAT (pr) = (float) strlen (P_GSTRING (pr, 0));
}
/*
PF_str2byte
float str2byte (string str)
*/
static void
PF_str2byte (progs_t * pr)
{
R_FLOAT (pr) = (float) *P_GSTRING (pr, 0);
}
/*
PF_str2short
float str2short (string str)
*/
static void
PF_str2short (progs_t * pr)
{
const unsigned char *str = P_GSTRING (pr, 0);
R_FLOAT (pr) = (short) ((str[1] << 8) | str[0]);
}
/*
PF_newstr
string newstr (string str [, float size])
ignores size (there for compatability with qwe)
*/
static void
PF_newstr (progs_t * pr)
{
const char *s;
dstring_t *dstr;
int i;
s = P_GSTRING (pr, 0);
i = PR_NewString (pr);
dstr = PR_GetDString (pr, i);
dstring_copystr (dstr, s);
R_STRING (pr) = i;
}
/*
PF_frestr
void freestr (string str)
*/
static void
PF_freestr (progs_t * pr)
{
PR_FreeString (pr, P_STRING (pr, 0));
}
/*
PF_readcmd
string readmcmd (string str)
*/
static void
PF_readcmd (progs_t *pr)
{
const char *s;
redirect_t old;
s = P_GSTRING (pr, 0);
Cbuf_Execute (sv_cbuf);
Cbuf_AddText (sv_cbuf, s);
old = sv_redirected;
if (old != RD_NONE)
SV_EndRedirect ();
SV_BeginRedirect (RD_MOD);
Cbuf_Execute (sv_cbuf);
RETURN_STRING (pr, outputbuf.str);
SV_EndRedirect ();
if (old != RD_NONE)
SV_BeginRedirect (old);
}
/*
PF_redirectcmd
void redirectcmd (entity to, string str)
*/
static void
PF_redirectcmd (progs_t *pr)
{
const char *s;
int entnum;
extern redirect_t sv_redirected;
if (sv_redirected)
return;
entnum = P_EDICTNUM (pr, 0);
if (entnum < 1 || entnum > MAX_CLIENTS)
PR_RunError (pr, "Parm 0 not a client");
s = P_GSTRING (pr, 1);
Cbuf_AddText (sv_cbuf, s);
SV_BeginRedirect (RD_MOD + entnum);
Cbuf_Execute (sv_cbuf);
SV_EndRedirect ();
}
static void
PF_calltimeofday (progs_t * pr)
{
date_t date;
dfunction_t *f;
if ((f = ED_FindFunction (pr, "timeofday")) != NULL) {
Sys_TimeOfDay (&date);
PR_PushFrame (&sv_pr_state);
P_FLOAT (pr, 0) = (float) date.sec;
P_FLOAT (pr, 1) = (float) date.min;
P_FLOAT (pr, 2) = (float) date.hour;
P_FLOAT (pr, 3) = (float) date.day;
P_FLOAT (pr, 4) = (float) date.mon;
P_FLOAT (pr, 5) = (float) date.year;
P_STRING (pr, 6) = PR_SetTempString (pr, date.str);
PR_ExecuteProgram (pr, (func_t) (f - sv_pr_state.pr_functions));
PR_PopFrame (&sv_pr_state);
}
}
/*
PF_forcedemoframe
void PF_forcedemoframe(float now)
Forces demo frame
if argument 'now' is set, frame is written instantly
*/
static void
PF_forcedemoframe (progs_t * pr)
{
demo.forceFrame = 1;
if (P_FLOAT (pr, 0) == 1)
SV_SendDemoMessage ();
}
/*
PF_strcpy
void strcpy(string dst, string src)
*/
static void
PF_strcpy (progs_t * pr)
{
dstring_copystr (P_DSTRING (pr, 0), P_GSTRING (pr, 1));
}
/*
PF_strncpy
void strcpy(string dst, string src, float count)
*/
static void
PF_strncpy (progs_t * pr)
{
dstring_t *dst = P_DSTRING (pr, 0);
const char *src = P_GSTRING (pr, 1);
size_t count = P_FLOAT (pr, 2);
dst->size = count;
dstring_adjust (dst);
strncpy (dst->str, src, count);
}
/*
PF_strstr
string strstr(string str, string sub)
*/
static void
PF_strstr (progs_t * pr)
{
const char *str, *sub, *p;
str = P_GSTRING (pr, 0);
sub = P_GSTRING (pr, 1);
if ((p = strstr (str, sub)) == NULL) {
R_STRING (pr) = 0;
return;
}
R_STRING (pr) = p - pr->pr_strings;
}
static inline void
clean_text (unsigned char *text)
{
while (*text) {
*text = sys_char_map[*text];
text++;
}
}
/*
PF_log
void log(string name, float console, string text)
*/
static void
PF_log (progs_t * pr)
{
const char *name;
char *text;
QFile *file;
name = va ("%s/%s.log", qfs_gamedir->dir.def, P_GSTRING (pr, 0));
file = QFS_Open (name, "a");
text = PF_VarString (pr, 2);
clean_text (text);
if (P_FLOAT (pr, 1))
Sys_Printf ("%s", text);
if (!file) {
Sys_Printf ("coldn't open log file %s\n", name);
} else {
Qputs (file, text);
Qflush (file);
Qclose (file);
}
}
/*
PF_conprint
*/
static void
PF_conprint (progs_t * pr)
{
Con_Printf ("%s", PF_VarString (pr, 0));
}
#define QWE (PR_RANGE_QWE << PR_RANGE_SHIFT) |
static builtin_t builtins[] = {
{"QWE:executecmd", PF_executecmd, QWE 83},
{"QWE:tokanize" /* sic */, PF_tokanize, QWE 84},
{"QWE:argc", PF_argc, QWE 85},
{"QWE:argv", PF_argv, QWE 86},
{"QWE:teamfield", PF_teamfield, QWE 87},
{"QWE:substr", PF_substr, QWE 88},
{"QWE:strcat", PF_strcat, QWE 89},
{"QWE:strlen", PF_strlen, QWE 90},
{"QWE:str2byte", PF_str2byte, QWE 91},
{"QWE:str2short", PF_str2short, QWE 92},
{"QWE:newstr", PF_newstr, QWE 93},
{"QWE:freestr", PF_freestr, QWE 94},
{"QWE:conprint", PF_conprint, QWE 95},
{"QWE:readcmd", PF_readcmd, QWE 96},
{"QWE:strcpy", PF_strcpy, QWE 97},
{"QWE:strstr", PF_strstr, QWE 98},
{"QWE:strncpy", PF_strncpy, QWE 99},
{"QWE:log", PF_log, QWE 100},
{"QWE:redirectcmd", PF_redirectcmd, QWE 101},
{"QWE:calltimeofday", PF_calltimeofday, QWE 102},
{"QWE:forceddemoframe", PF_forcedemoframe, QWE 103},
};
static struct {
const char *name;
int *field;
} qwe_func_list[] = {
{"timeofday", &qwe_funcs.timeofday},
{"ConsoleCmd", &qwe_funcs.ConsoleCmd},
{"UserCmd", &qwe_funcs.UserCmd},
{"localinfoChanged", &sv_funcs.LocalinfoChanged},
{"UserInfo_Changed", &sv_funcs.UserInfoChanged},
{"ChatMessage", &sv_funcs.ChatMessage},
};
static int
qwe_console_cmd (void)
{
if (qwe_funcs.ConsoleCmd) {
if (sv_redirected != RD_MOD) {
*sv_globals.time = sv.time;
*sv_globals.self = 0;
}
PR_ExecuteProgram (&sv_pr_state, qwe_funcs.ConsoleCmd);
return (int) R_FLOAT (&sv_pr_state);
}
return false;
}
static int
qwe_user_cmd (void)
{
if (qwe_funcs.UserCmd) {
if (sv_redirected != RD_MOD) {
*sv_globals.time = sv.time;
*sv_globals.self = EDICT_TO_PROG(&sv_pr_state, sv_player);
}
PR_ExecuteProgram (&sv_pr_state, qwe_funcs.UserCmd);
return (int) R_FLOAT (&sv_pr_state);
}
return false;
}
static int
qwe_load (progs_t * pr)
{
int i;
for (i = 0; i < sizeof (qwe_func_list) / sizeof (qwe_func_list[0]); i++) {
dfunction_t *f = ED_FindFunction (pr, qwe_func_list[i].name);
*qwe_func_list[i].field = 0;
if (f)
*qwe_func_list[i].field = (func_t) (f - pr->pr_functions);
}
return 1;
}
void
SV_PR_QWE_Init (progs_t *pr)
{
PR_RegisterBuiltins (pr, builtins);
PR_AddLoadFunc (pr, qwe_load);
sv_cbuf->unknown_command = qwe_console_cmd;
ucmd_unknown = qwe_user_cmd;
}

View file

@ -43,6 +43,7 @@
#include "compat.h"
#include "server.h"
#include "sv_progs.h"
#include "sv_pr_qwe.h"
#include "world.h"
sv_globals_t sv_globals;
@ -53,12 +54,29 @@ progs_t sv_pr_state;
cvar_t *r_skyname;
cvar_t *sv_progs;
cvar_t *sv_progs_zone;
cvar_t *sv_progs_ext;
cvar_t *pr_checkextensions;
cvar_t *sv_old_entity_free;
cvar_t *sv_hide_version_info;
static int reserved_edicts = MAX_CLIENTS;
static int sv_range;
static unsigned
bi_map (progs_t *pr, unsigned binum)
{
unsigned range;
if (sv_range != PR_RANGE_NONE) {
range = (binum & PR_RANGE_MASK) >> PR_RANGE_SHIFT;
if (!range && binum > PR_RANGE_ID_MAX)
binum |= sv_range << PR_RANGE_SHIFT;
}
return binum;
}
static void
free_edict (progs_t *pr, edict_t *ent)
{
@ -162,9 +180,26 @@ SV_LoadProgs (void)
ddef_t *def;
dfunction_t *f;
const char *progs_name = "qwprogs.dat";
const char *range;
memset (&sv_funcs, 0, sizeof (sv_funcs));
if (strequal (sv_progs_ext->string, "qf")) {
sv_range = PR_RANGE_QF;
range = "QF";
} else if (strequal (sv_progs_ext->string, "id")) {
sv_range = PR_RANGE_ID;
range = "ID";
} else if (strequal (sv_progs_ext->string, "qwe")
|| strequal (sv_progs_ext->string, "ktpro")) {
sv_range = PR_RANGE_QWE;
range = "QWE/KTPro";
} else {
sv_range = PR_RANGE_NONE;
range = "None";
}
Con_DPrintf ("Using %s builtin extention mapping\n", range);
if (qfs_gamedir->gamecode && *qfs_gamedir->gamecode)
progs_name = qfs_gamedir->gamecode;
if (*sv_progs->string)
@ -351,9 +386,11 @@ SV_Progs_Init (void)
sv_pr_state.parse_field = parse_field;
sv_pr_state.prune_edict = prune_edict;
sv_pr_state.free_edict = free_edict; // eww, I hate the need for this :(
sv_pr_state.bi_map = bi_map;
PR_Resources_Init (&sv_pr_state);
SV_PR_Cmds_Init ();
SV_PR_QWE_Init (&sv_pr_state);
Cmd_Progs_Init (&sv_pr_state);
Hash_Progs_Init (&sv_pr_state);
@ -376,6 +413,9 @@ SV_Progs_Init_Cvars (void)
"Override the default game progs.");
sv_progs_zone = Cvar_Get ("sv_progs_zone", "256", CVAR_NONE, NULL,
"size of the zone for progs in kb");
sv_progs_ext = Cvar_Get ("sv_progs_ext", "qf", CVAR_NONE, NULL,
"extention mapping to use: "
"none, id, qf, qwe, ktpro");
pr_checkextensions = Cvar_Get ("pr_checkextensions", "1", CVAR_ROM, NULL,
"indicate the presence of the "
"checkextentions qc function");