Added support for q1-like qvms (mvdsv style). only tested with ktx so disabled by default for now, couple of related cleanups too

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@2633 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2007-09-02 19:55:17 +00:00
parent 619bb7a1cd
commit dc3e0d5872
25 changed files with 2587 additions and 813 deletions

View File

@ -7,18 +7,36 @@ CPUOPTIMIZATIONS=
BASE_DIR=.
#we only autodetect one cross target
#only limited forms of cross-making is supported
#only the following 3 are supported
#linux->win32
#linux->linux32
#linux->linux64
#if you are cross compiling, you'll need to use FTE_TARGET=mytaget
#correct the gcc build when cross compiling
ifeq ($(FTE_TARGET),win32)
ifeq ($(shell $(CC) -v 2>&1 | grep mingw),)
#CC didn't state that it was mingw... so try fixing that up
CC=i586-mingw32msvc-gcc
W32_FLAGS=-Ilibs/dxsdk7/include
ifneq ($(shell i586-mingw32msvc-gcc -v 2>&1 | grep mingw),)
#yup, the alternative exists (this matches the one debian has)
CC=i586-mingw32msvc-gcc
# BITS?=32
endif
endif
endif
#if you have an x86, you can get gcc to build 32bit or 64bit specific builds, instead of builds for the native platform
ifeq ($(FTE_TARGET),linux32)
FTE_TARGET=linux
CC=gcc -m32
BITS=32
endif
ifeq ($(FTE_TARGET),linux64)
FTE_TARGET=linux
CC=gcc -m64
BITS=64
endif
ifeq ($(FTE_TARGET),) #user didn't specify prefered target
ifneq ($(shell $(CC) -v 2>&1 | grep mingw),)
@ -275,6 +293,7 @@ PROGS_OBJS = \
SERVER_OBJS = \
pr_cmds.o \
pr_q1qvm.o \
sv_master.o \
sv_init.o \
sv_main.o \
@ -345,20 +364,20 @@ COMMON_OBJS = $(COMMON_ASM_OBJS) \
#the defaults for sdl come first
GLCL_OBJS=$(GL_OBJS) $(GLQUAKE_OBJS) gl_vidsdl.o snd_sdl.o cd_sdl.o sys_sdl.o in_sdl.o
GL_EXE_NAME=../fteqw_sdl.gl
GLCL_EXE_NAME=../fteqwcl_sdl.gl
GL_EXE_NAME=../fteqw_sdl.gl$(BITS)
GLCL_EXE_NAME=../fteqwcl_sdl.gl$(BITS)
ifdef windir
GL_LDFLAGS=$(GLLDFLAGS) -lmingw32 -lwsock32 `sdl-config --libs`
else
GL_LDFLAGS=$(GLLDFLAGS) -lpng -ljpeg `sdl-config --libs`
endif
GL_CFLAGS=$(GLCFLAGS) `sdl-config --cflags`
GLB_DIR=gl_sdl
GLCL_DIR=glcl_sdl
GLB_DIR=gl_sdl$(BITS)
GLCL_DIR=glcl_sdl$(BITS)
SWCL_OBJS=$(SOFTWARE_OBJS) vid_sdl.o snd_sdl.o cd_sdl.o sys_sdl.o in_sdl.o
SW_EXE_NAME=../fteqw_sdl.sw
SWCL_EXE_NAME=../fteqwcl_sdl.sw
SW_EXE_NAME=../fteqw_sdl.sw$(BITS)
SWCL_EXE_NAME=../fteqwcl_sdl.sw$(BITS)
ifdef windir
SW_LDFLAGS=$(SWLDFLAGS) -lmingw32 -lwsock32 -lSDLmain -lSDL
else
@ -366,11 +385,11 @@ else
SW_LDFLAGS=$(SWLDFLAGS) `sdl-config --libs` -lpng -ljpeg
endif
SW_CFLAGS=$(SWCFLAGS) `sdl-config --cflags`
SWB_DIR=sw_sdl
SWCL_DIR=swcl_sdl
SWB_DIR=sw_sdl$(BITS)
SWCL_DIR=swcl_sdl$(BITS)
SV_OBJS=$(COMMON_OBJS) $(SERVER_OBJS) $(PROGS_OBJS) $(SERVERONLY_OBJS)
SV_EXE_NAME=../fteqw.sv
SV_EXE_NAME=../fteqw.sv$(BITS)
SV_CFLAGS=$(SERVER_ONLY_CFLAGS)
#specific targets override those defaults as needed.
@ -427,6 +446,8 @@ endif
MB_DIR=m_mgw
MCL_DIR=mcl_mgw
MINGL_EXE_NAME=../fteminglqw.exe
MINGL_DIR=mingl_mgw
endif
ifeq ($(FTE_TARGET),bsd)
#mostly uses the linux stuff.
@ -471,9 +492,9 @@ endif
MB_DIR=m_bsd
MCL_DIR=mcl_bsd
endif
ifeq ($(FTE_TARGET),linux)
ifneq ($(shell echo $(FTE_TARGET)|grep linux),)
SV_DIR=sv_linux
SV_DIR=sv_linux$(BITS)
SV_LDFLAGS=-lz
ifeq ($(USEASM),true)
@ -481,41 +502,41 @@ ifeq ($(USEASM),true)
else
GLCL_OBJS=$(GL_OBJS) $(GLQUAKE_OBJS) gl_vidlinuxglx.o snd_linux.o snd_alsa.oo cd_linux.o sys_linux.o
endif
GL_EXE_NAME=../fteqw.gl
GLCL_EXE_NAME=../fteqwcl.gl
GL_EXE_NAME=../fteqw.gl$(BITS)
GLCL_EXE_NAME=../fteqwcl.gl$(BITS)
GL_LDFLAGS=$(GLLDFLAGS) $(GLXLDFLAGS) -lXxf86vm
GL_CFLAGS=$(GLCFLAGS) -I/usr/X11R6/include
GLB_DIR=gl_linux
GLCL_DIR=glcl_linux
GLB_DIR=gl_linux$(BITS)
GLCL_DIR=glcl_linux$(BITS)
ifeq ($(USEASM),true)
SWCL_OBJS=$(SOFTWARE_OBJS) vid_x.o snd_linux.o snd_alsa.oo cd_linux.o sys_linux.o sys_dosa.o
else
SWCL_OBJS=$(SOFTWARE_OBJS) vid_x.o snd_linux.o snd_alsa.oo cd_linux.o sys_linux.o
endif
SW_EXE_NAME=../fteqw.sw
SWCL_EXE_NAME=../fteqwcl.sw
SW_EXE_NAME=../fteqw.sw$(BITS)
SWCL_EXE_NAME=../fteqwcl.sw$(BITS)
SW_LDFLAGS=$(SWLDFLAGS) $(XLDFLAGS) -lXxf86vm
SW_CFLAGS=$(SWCFLAGS) -I/usr/X11R6/include
SWB_DIR=sw_linux
SWCL_DIR=swcl_linux
SWB_DIR=sw_linux$(BITS)
SWCL_DIR=swcl_linux$(BITS)
ifeq ($(USEASM),true)
MCL_OBJS=$(GLQUAKE_OBJS) $(SOFTWARE_OBJS) gl_vidlinuxglx.o vid_x.o snd_linux.o snd_alsa.oo cd_linux.o sys_linux.o sys_dosa.o
else
MCL_OBJS=$(GLQUAKE_OBJS) $(SOFTWARE_OBJS) gl_vidlinuxglx.o vid_x.o snd_linux.o snd_alsa.oo cd_linux.o sys_linux.o
endif
M_EXE_NAME=../fteqw
MCL_EXE_NAME=../fteqwcl
M_EXE_NAME=../fteqw$(BITS)
MCL_EXE_NAME=../fteqwcl$(BITS)
M_LDFLAGS=$(GLLDFLAGS) $(GLXLDFLAGS) -lXxf86vm
M_CFLAGS=$(SWCFLAGS) $(GLCFLAGS) -I/usr/X11R6/include
MB_DIR=m_linux
MCL_DIR=mcl_linux
MB_DIR=m_linux$(BITS)
MCL_DIR=mcl_linux$(BITS)
MINGL_EXE_NAME=../fteqw.mingl
MINGL_DIR=mingl_linux
MINGL_EXE_NAME=../fteqw.mingl$(BITS)
MINGL_DIR=mingl_linux$(BITS)
endif
ifeq ($(FTE_TARGET),morphos)
@ -602,7 +623,20 @@ endif
SV_DIR?=sv_sdl
.default: help
all: sv-rel sw-rel gl-rel m-rel
all: rel
rel: sv-rel sw-rel gl-rel m-rel mingl-rel
dbg: sv-dbg sw-dbg gl-dbg m-dbg mingl-dbg
relcl: swcl-rel glcl-rel mcl-rel
releases:
#this is for releasing things from a linux box
#just go through compiling absolutly everything
-$(MAKE) FTE_TARGET=linux32 rel
-$(MAKE) FTE_TARGET=linux64 rel
-$(MAKE) FTE_TARGET=win32 rel
# -$(MAKE) FTE_TARGET=linux32 relcl
# -$(MAKE) FTE_TARGET=linux64 relcl
# -$(MAKE) FTE_TARGET=win32 relcl
autoconfig: clean
/bin/bash makeconfig.sh y
@ -731,9 +765,9 @@ mcl-rel:
mcl-dbg:
$(MAKE) mcl-tmp TYPE=_cl-dbg OUT_DIR="$(DEBUG_DIR)/$(MCL_DIR)"
m-rel:
$(MAKE) m-tmp TYPE=_clsv-rel OUT_DIR="$(RELEASE_DIR)/$(MCL_DIR)"
$(MAKE) m-tmp TYPE=_clsv-rel OUT_DIR="$(RELEASE_DIR)/$(MB_DIR)"
m-dbg:
$(MAKE) m-tmp TYPE=_clsv-dbg OUT_DIR="$(DEBUG_DIR)/$(MCL_DIR)"
$(MAKE) m-tmp TYPE=_clsv-dbg OUT_DIR="$(DEBUG_DIR)/$(MB_DIR)"
.PHONY: m-tmp mcl-tmp sw-tmp swcl-tmp mingl-tmp glcl-tmp gl-tmp sv-tmp _clsv-dbg _clsv-rel _cl-dbg _cl-rel _out-rel _out-dbg
@ -763,6 +797,7 @@ help:
@-echo "Specfic targets:"
@-echo "clean - removes all output (use make dirs afterwards)"
@-echo "all - make all the targets possible"
@-echo "rel - make the releases for the default system"
@-echo ""
@-echo "Normal targets:"
@-echo "(each of these targets must have the postfix -rel or -dbg)"

View File

@ -546,17 +546,17 @@ static long CG_SystemCallsEx(void *offset, unsigned int mask, int fn, const long
case CG_FS_FOPENFILE: //fopen
if (arg[1])
VALIDATEPOINTER(arg[1], 4);
VM_LONG(ret) = VMUI_fopen(VM_POINTER(arg[0]), VM_POINTER(arg[1]), VM_LONG(arg[2]), 1);
VM_LONG(ret) = VM_fopen(VM_POINTER(arg[0]), VM_POINTER(arg[1]), VM_LONG(arg[2]), 1);
break;
case CG_FS_READ: //fread
VALIDATEPOINTER(arg[1], 4);
VM_LONG(ret) = VMUI_FRead(VM_POINTER(arg[0]), VM_LONG(arg[1]), VM_LONG(arg[2]), 1);
VM_LONG(ret) = VM_FRead(VM_POINTER(arg[0]), VM_LONG(arg[1]), VM_LONG(arg[2]), 1);
break;
case CG_FS_WRITE: //fwrite
break;
case CG_FS_FCLOSEFILE: //fclose
VMUI_fclose(VM_LONG(arg[0]), 1);
VM_fclose(VM_LONG(arg[0]), 1);
break;
case CG_CM_POINTCONTENTS: //int trap_CM_PointContents( const vec3_t p, clipHandle_t model );
@ -1094,7 +1094,7 @@ void CG_Stop (void)
{
VM_Call(cgvm, CG_SHUTDOWN);
VM_Destroy(cgvm);
VMUI_fcloseall(1);
VM_fcloseall(1);
cgvm = NULL;
}
#endif

View File

@ -299,289 +299,6 @@ netadr_t ui_pings[MAX_PINGREQUESTS];
#define UITAGNUM 2452
#define MAX_VMUI_FILES 8
typedef struct {
char name[256];
char *data;
int bufferlen;
int len;
int ofs;
int accessmode;
int owner;
} vmui_fopen_files_t;
vmui_fopen_files_t vmui_fopen_files[MAX_VMUI_FILES];
int VMUI_fopen (char *name, int *handle, int fmode, int owner)
{
int i;
if (!handle)
return FS_FLocateFile(name, FSLFRT_IFFOUND, NULL);
*handle = 0;
for (i = 0; i < MAX_VMUI_FILES; i++)
if (!vmui_fopen_files[i].data)
break;
if (i == MAX_VMUI_FILES) //too many already open
{
return -1;
}
if (name[1] == ':' || //dos filename absolute path specified - reject.
*name == '\\' || *name == '/' || //absolute path was given - reject
strstr(name, "..")) //someone tried to be cleaver.
{
return -1;
}
Q_strncpyz(vmui_fopen_files[i].name, name, sizeof(vmui_fopen_files[i].name));
vmui_fopen_files[i].accessmode = fmode;
vmui_fopen_files[i].owner = owner;
switch (fmode)
{
case 0: //read
vmui_fopen_files[i].data = COM_LoadMallocFile(name);
vmui_fopen_files[i].bufferlen = vmui_fopen_files[i].len = com_filesize;
vmui_fopen_files[i].ofs = 0;
if (vmui_fopen_files[i].data)
break;
else
return -1;
break;
/*
case 2: //append
case 3: //append
vmui_fopen_files[i].data = COM_LoadMallocFile(name);
vmui_fopen_files[i].ofs = vmui_fopen_files[i].bufferlen = vmui_fopen_files[i].len = com_filesize;
if (vmui_fopen_files[i].data)
break;
//fall through
case 1: //write
vmui_fopen_files[i].bufferlen = 8192;
vmui_fopen_files[i].data = BZ_Malloc(vmui_fopen_files[i].bufferlen);
vmui_fopen_files[i].len = 0;
vmui_fopen_files[i].ofs = 0;
break;
*/
default: //bad
return -1;
}
*handle = i+1;
return vmui_fopen_files[i].len;
}
void VMUI_fclose (int fnum, int owner)
{
fnum--;
if (fnum < 0 || fnum >= MAX_VMUI_FILES)
return; //out of range
if (vmui_fopen_files[fnum].owner != owner)
return; //cgs?
if (!vmui_fopen_files[fnum].data)
return; //not open
switch(vmui_fopen_files[fnum].accessmode)
{
case 0:
BZ_Free(vmui_fopen_files[fnum].data);
break;
case 1:
case 2:
case 3:
COM_WriteFile(vmui_fopen_files[fnum].name, vmui_fopen_files[fnum].data, vmui_fopen_files[fnum].len);
BZ_Free(vmui_fopen_files[fnum].data);
break;
}
vmui_fopen_files[fnum].data = NULL;
}
int VMUI_FRead (char *dest, int quantity, int fnum, int owner)
{
fnum--;
if (fnum < 0 || fnum >= MAX_VMUI_FILES)
return 0; //out of range
if (vmui_fopen_files[fnum].owner != owner)
return 0; //cgs?
if (!vmui_fopen_files[fnum].data)
return 0; //not open
if (quantity > vmui_fopen_files[fnum].len - vmui_fopen_files[fnum].ofs)
quantity = vmui_fopen_files[fnum].len - vmui_fopen_files[fnum].ofs;
memcpy(dest, vmui_fopen_files[fnum].data + vmui_fopen_files[fnum].ofs, quantity);
vmui_fopen_files[fnum].ofs += quantity;
return quantity;
}
/*
void VMUI_fputs (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int fnum = G_FLOAT(OFS_PARM0);
char *msg = PF_VarString(prinst, 1, pr_globals);
int len = strlen(msg);
if (fnum < 0 || fnum >= MAX_QC_FILES)
return; //out of range
if (!pf_fopen_files[fnum].data)
return; //not open
if (pf_fopen_files[fnum].prinst != prinst)
return; //this just isn't ours.
if (pf_fopen_files[fnum].bufferlen < pf_fopen_files[fnum].ofs + len)
{
char *newbuf;
pf_fopen_files[fnum].bufferlen = pf_fopen_files[fnum].bufferlen*2 + len;
newbuf = BZF_Malloc(pf_fopen_files[fnum].bufferlen);
memcpy(newbuf, pf_fopen_files[fnum].data, pf_fopen_files[fnum].len);
BZ_Free(pf_fopen_files[fnum].data);
pf_fopen_files[fnum].data = newbuf;
}
memcpy(pf_fopen_files[fnum].data + pf_fopen_files[fnum].ofs, msg, len);
if (pf_fopen_files[fnum].len < pf_fopen_files[fnum].ofs + len)
pf_fopen_files[fnum].len = pf_fopen_files[fnum].ofs + len;
pf_fopen_files[fnum].ofs+=len;
}
*/
void VMUI_fcloseall (int owner)
{
int i;
for (i = 1; i <= MAX_VMUI_FILES; i++)
{
VMUI_fclose(i, owner);
}
}
typedef struct {
char *initialbuffer;
char *buffer;
char *dir;
int found;
int bufferleft;
int skip;
} vmsearch_t;
int VMEnum(char *match, int size, void *args)
{
char *check;
int newlen;
match += ((vmsearch_t *)args)->skip;
newlen = strlen(match)+1;
if (newlen > ((vmsearch_t *)args)->bufferleft)
return false; //too many files for the buffer
check = ((vmsearch_t *)args)->initialbuffer;
while(check < ((vmsearch_t *)args)->buffer)
{
if (!stricmp(check, match))
return true; //we found this one already
check += strlen(check)+1;
}
memcpy(((vmsearch_t *)args)->buffer, match, newlen);
((vmsearch_t *)args)->buffer+=newlen;
((vmsearch_t *)args)->bufferleft-=newlen;
((vmsearch_t *)args)->found++;
return true;
}
static int IfFound(char *match, int size, void *args)
{
*(qboolean*)args = true;
return true;
}
int VMEnumMods(char *match, int size, void *args)
{
char *check;
char desc[1024];
int newlen;
int desclen;
qboolean foundone;
vfsfile_t *f;
newlen = strlen(match)+1;
if (*match && match[newlen-2] != '/')
return true;
match[newlen-2] = '\0';
newlen--;
if (!stricmp(match, "baseq3"))
return true; //we don't want baseq3
foundone = false;
Sys_EnumerateFiles(va("%s/%s/", ((vmsearch_t *)args)->dir, match), "*.pk3", IfFound, &foundone);
if (foundone == false)
return true; //we only count directories with a pk3 file
Q_strncpyz(desc, match, sizeof(desc));
f = FS_OpenVFS(va("%s/description.txt", match), "rb", FS_BASE);
if (f)
{
VFS_GETS(f, desc, sizeof(desc));
VFS_CLOSE(f);
}
desclen = strlen(desc)+1;
if (newlen+desclen+5 > ((vmsearch_t *)args)->bufferleft)
return false; //too many files for the buffer
check = ((vmsearch_t *)args)->initialbuffer;
while(check < ((vmsearch_t *)args)->buffer)
{
if (!stricmp(check, match))
return true; //we found this one already
check += strlen(check)+1;
check += strlen(check)+1;
}
memcpy(((vmsearch_t *)args)->buffer, match, newlen);
((vmsearch_t *)args)->buffer+=newlen;
((vmsearch_t *)args)->bufferleft-=newlen;
memcpy(((vmsearch_t *)args)->buffer, desc, desclen);
((vmsearch_t *)args)->buffer+=desclen;
((vmsearch_t *)args)->bufferleft-=desclen;
((vmsearch_t *)args)->found++;
return true;
}
int VMQ3_GetFileList(char *path, char *ext, char *output, int buffersize)
{
vmsearch_t vms;
vms.initialbuffer = vms.buffer = output;
vms.skip = strlen(path)+1;
vms.bufferleft = buffersize;
vms.found=0;
if (!strcmp(path, "$modlist"))
{
vms.skip=0;
Sys_EnumerateFiles((vms.dir=com_quakedir), "*", VMEnumMods, &vms);
if (*com_homedir)
Sys_EnumerateFiles((vms.dir=com_homedir), "*", VMEnumMods, &vms);
}
else if (*(char *)ext == '.' || *(char *)ext == '/')
COM_EnumerateFiles(va("%s/*%s", path, ext), VMEnum, &vms);
else
COM_EnumerateFiles(va("%s/*.%s", path, ext), VMEnum, &vms);
return vms.found;
}
@ -988,25 +705,25 @@ long UI_SystemCallsEx(void *offset, unsigned int mask, int fn, const long *arg)
case UI_FS_FOPENFILE: //fopen
if ((int)arg[1] + 4 >= mask || VM_POINTER(arg[1]) < offset)
break; //out of bounds.
VM_LONG(ret) = VMUI_fopen(VM_POINTER(arg[0]), VM_POINTER(arg[1]), VM_LONG(arg[2]), 0);
VM_LONG(ret) = VM_fopen(VM_POINTER(arg[0]), VM_POINTER(arg[1]), VM_LONG(arg[2]), 0);
break;
case UI_FS_READ: //fread
if ((int)arg[0] + VM_LONG(arg[1]) >= mask || VM_POINTER(arg[0]) < offset)
break; //out of bounds.
VM_LONG(ret) = VMUI_FRead(VM_POINTER(arg[0]), VM_LONG(arg[1]), VM_LONG(arg[2]), 0);
VM_LONG(ret) = VM_FRead(VM_POINTER(arg[0]), VM_LONG(arg[1]), VM_LONG(arg[2]), 0);
break;
case UI_FS_WRITE: //fwrite
break;
case UI_FS_FCLOSEFILE: //fclose
VMUI_fclose(VM_LONG(arg[0]), 0);
VM_fclose(VM_LONG(arg[0]), 0);
break;
case UI_FS_GETFILELIST: //fs listing
if ((int)arg[2] + arg[3] >= mask || VM_POINTER(arg[2]) < offset)
break; //out of bounds.
return VMQ3_GetFileList(VM_POINTER(arg[0]), VM_POINTER(arg[1]), VM_POINTER(arg[2]), VM_LONG(arg[3]));
return VM_GetFileList(VM_POINTER(arg[0]), VM_POINTER(arg[1]), VM_POINTER(arg[2]), VM_LONG(arg[3]));
case UI_R_REGISTERMODEL: //precache model
{
@ -1736,7 +1453,7 @@ void UI_Stop (void)
{
VM_Call(uivm, UI_SHUTDOWN);
VM_Destroy(uivm);
VMUI_fcloseall(0);
VM_fcloseall(0);
uivm = NULL;
}
}
@ -1762,7 +1479,7 @@ void UI_Start (void)
{
Con_Printf("User-Interface VM uses incompatable API version (%i)\n", apiversion);
VM_Destroy(uivm);
VMUI_fcloseall(0);
VM_fcloseall(0);
uivm = NULL;
return;
}

View File

@ -73,6 +73,15 @@ void *Sys_GetGameAPI (void *parms)
const char *debugdir = "debug";
#endif
#elif defined __amd64__
const char *gamename = "gameamd.dll";
#ifdef NDEBUG
const char *debugdir = "release";
#else
const char *debugdir = "debug";
#endif
#elif defined _M_ALPHA
const char *gamename = "gameaxp.dll";

View File

@ -126,6 +126,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define PPL //per pixel lighting (stencil shadowing)
#define DDS //a sort of image file format.
//fixme: test this a bit #define VM_Q1 //q1 qvm gamecode interface
#define TCPCONNECT //a tcpconnect command, that allows the player to connect to tcp-encapsulated qw protocols.
#define PLUGINS
@ -149,7 +151,15 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#endif
#ifndef _WIN32
#undef QTERM
#undef QTERM //not supported - FIXME: move to native plugin
#endif
#ifdef __amd64__
//nah... not gonna work too well
#undef VM_Q1
#undef Q3CLIENT
#undef Q3SERVER
#undef PLUGINS
#endif
#if (defined(Q2CLIENT) || defined(Q2SERVER))
@ -174,14 +184,14 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#undef WEBCLIENT
#undef TEXTEDITOR
#undef RUNTIMELIGHTING
// #undef PLUGINS //we don't have any server side stuff.
#undef Q3SHADERS
#undef TERRAIN
#undef TERRAIN //not supported
#endif
#ifdef CLIENTONLY //remove optional server componants that make no sence on a client only build.
#undef Q2SERVER
#undef Q3SERVER
#undef WEBSERVER
#undef VM_Q1
//this is regretable, but the csqc/ssqc needs a cleanup to move common builtins to a common c file.
#undef CSQC_DAT
@ -230,7 +240,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define VM_UI
#endif
#if defined(VM_UI) || defined(VM_CG) || defined(Q3SERVER) || defined(PLUGINS)
#if defined(VM_Q1) || defined(VM_UI) || defined(VM_CG) || defined(Q3SERVER) || defined(PLUGINS)
#define VM_ANY
#endif
@ -380,6 +390,7 @@ STAT_VIEW2 = 20,
STAT_VIEWZOOM = 21, // DP
//note that hexen2 stats are only used in hexen2 gamemodes, and can be read by csqc without further server changes.
//when running hexen2 mods, the server specifically sets up these stats for the csqc.
STAT_H2_LEVEL = 32, // changes stat bar
STAT_H2_INTELLIGENCE, // changes stat bar
STAT_H2_WISDOM, // changes stat bar
@ -456,28 +467,29 @@ STAT_H2_MAXHEALTH,
STAT_H2_MAXMANA,
STAT_H2_FLAGS,
MAX_CL_STATS = 256
#define STAT_MOVEVARS_WALLFRICTION 237 // DP
#define STAT_MOVEVARS_FRICTION 238 // DP
#define STAT_MOVEVARS_WATERFRICTION 239 // DP
#define STAT_MOVEVARS_TICRATE 240 // DP
#define STAT_MOVEVARS_TIMESCALE 241 // DP
#define STAT_MOVEVARS_GRAVITY 242 // DP
#define STAT_MOVEVARS_STOPSPEED 243 // DP
#define STAT_MOVEVARS_MAXSPEED 244 // DP
#define STAT_MOVEVARS_SPECTATORMAXSPEED 245 // DP
#define STAT_MOVEVARS_ACCELERATE 246 // DP
#define STAT_MOVEVARS_AIRACCELERATE 247 // DP
#define STAT_MOVEVARS_WATERACCELERATE 248 // DP
#define STAT_MOVEVARS_ENTGRAVITY 249 // DP
#define STAT_MOVEVARS_JUMPVELOCITY 250 // DP
#define STAT_MOVEVARS_EDGEFRICTION 251 // DP
#define STAT_MOVEVARS_MAXAIRSPEED 252 // DP
#define STAT_MOVEVARS_STEPHEIGHT 253 // DP
#define STAT_MOVEVARS_AIRACCEL_QW 254 // DP
#define STAT_MOVEVARS_AIRACCEL_SIDEWAYS_FRICTION 255 // DP
STAT_MOVEVARS_WALLFRICTION = 237, // DP
STAT_MOVEVARS_FRICTION = 238, // DP
STAT_MOVEVARS_WATERFRICTION = 239, // DP
STAT_MOVEVARS_TICRATE = 240, // DP
STAT_MOVEVARS_TIMESCALE = 241, // DP
STAT_MOVEVARS_GRAVITY = 242, // DP
STAT_MOVEVARS_STOPSPEED = 243, // DP
STAT_MOVEVARS_MAXSPEED = 244, // DP
STAT_MOVEVARS_SPECTATORMAXSPEED = 245, // DP
STAT_MOVEVARS_ACCELERATE = 246, // DP
STAT_MOVEVARS_AIRACCELERATE = 247, // DP
STAT_MOVEVARS_WATERACCELERATE = 248, // DP
STAT_MOVEVARS_ENTGRAVITY = 249, // DP
STAT_MOVEVARS_JUMPVELOCITY = 250, // DP
STAT_MOVEVARS_EDGEFRICTION = 251, // DP
STAT_MOVEVARS_MAXAIRSPEED = 252, // DP
STAT_MOVEVARS_STEPHEIGHT = 253, // DP
STAT_MOVEVARS_AIRACCEL_QW = 254, // DP
STAT_MOVEVARS_AIRACCEL_SIDEWAYS_FRICTION = 255, // DP
MAX_CL_STATS = 256
};
//

View File

@ -2,6 +2,307 @@
//this file contains q3 netcode related things.
//field info, netchan, and the WriteBits stuff (which should probably be moved to common.c with the others)
//also contains vm filesystem
#define MAX_VM_FILES 8
typedef struct {
char name[256];
char *data;
int bufferlen;
int len;
int ofs;
int accessmode;
int owner;
} vm_fopen_files_t;
vm_fopen_files_t vm_fopen_files[MAX_VM_FILES];
//FIXME: why does this not use the VFS system?
int VM_fopen (char *name, int *handle, int fmode, int owner)
{
int i;
if (!handle)
return FS_FLocateFile(name, FSLFRT_IFFOUND, NULL);
*handle = 0;
for (i = 0; i < MAX_VM_FILES; i++)
if (!vm_fopen_files[i].data)
break;
if (i == MAX_VM_FILES) //too many already open
{
return -1;
}
if (name[1] == ':' || //dos filename absolute path specified - reject.
*name == '\\' || *name == '/' || //absolute path was given - reject
strstr(name, "..")) //someone tried to be cleaver.
{
return -1;
}
Q_strncpyz(vm_fopen_files[i].name, name, sizeof(vm_fopen_files[i].name));
vm_fopen_files[i].accessmode = fmode;
vm_fopen_files[i].owner = owner;
switch (fmode)
{
case VM_FS_READ:
vm_fopen_files[i].data = COM_LoadMallocFile(name);
vm_fopen_files[i].bufferlen = vm_fopen_files[i].len = com_filesize;
vm_fopen_files[i].ofs = 0;
if (vm_fopen_files[i].data)
break;
else
return -1;
break;
/*
case VM_FS_APPEND:
case VM_FS_APPEND2:
vm_fopen_files[i].data = COM_LoadMallocFile(name);
vm_fopen_files[i].ofs = vm_fopen_files[i].bufferlen = vm_fopen_files[i].len = com_filesize;
if (vm_fopen_files[i].data)
break;
//fall through
case VM_FS_WRITE:
vm_fopen_files[i].bufferlen = 8192;
vm_fopen_files[i].data = BZ_Malloc(vm_fopen_files[i].bufferlen);
vm_fopen_files[i].len = 0;
vm_fopen_files[i].ofs = 0;
break;
*/
default: //bad
return -1;
}
*handle = i+1;
return vm_fopen_files[i].len;
}
void VM_fclose (int fnum, int owner)
{
fnum--;
if (fnum < 0 || fnum >= MAX_VM_FILES)
return; //out of range
if (vm_fopen_files[fnum].owner != owner)
return; //cgs?
if (!vm_fopen_files[fnum].data)
return; //not open
switch(vm_fopen_files[fnum].accessmode)
{
case VM_FS_READ:
BZ_Free(vm_fopen_files[fnum].data);
break;
case VM_FS_WRITE:
case VM_FS_APPEND:
case VM_FS_APPEND2:
COM_WriteFile(vm_fopen_files[fnum].name, vm_fopen_files[fnum].data, vm_fopen_files[fnum].len);
BZ_Free(vm_fopen_files[fnum].data);
break;
}
vm_fopen_files[fnum].data = NULL;
}
int VM_FRead (char *dest, int quantity, int fnum, int owner)
{
fnum--;
if (fnum < 0 || fnum >= MAX_VM_FILES)
return 0; //out of range
if (vm_fopen_files[fnum].owner != owner)
return 0; //cgs?
if (!vm_fopen_files[fnum].data)
return 0; //not open
if (quantity > vm_fopen_files[fnum].len - vm_fopen_files[fnum].ofs)
quantity = vm_fopen_files[fnum].len - vm_fopen_files[fnum].ofs;
memcpy(dest, vm_fopen_files[fnum].data + vm_fopen_files[fnum].ofs, quantity);
vm_fopen_files[fnum].ofs += quantity;
return quantity;
}
/*
void VM_fputs (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int fnum = G_FLOAT(OFS_PARM0);
char *msg = PF_VarString(prinst, 1, pr_globals);
int len = strlen(msg);
if (fnum < 0 || fnum >= MAX_QC_FILES)
return; //out of range
if (!pf_fopen_files[fnum].data)
return; //not open
if (pf_fopen_files[fnum].prinst != prinst)
return; //this just isn't ours.
if (pf_fopen_files[fnum].bufferlen < pf_fopen_files[fnum].ofs + len)
{
char *newbuf;
pf_fopen_files[fnum].bufferlen = pf_fopen_files[fnum].bufferlen*2 + len;
newbuf = BZF_Malloc(pf_fopen_files[fnum].bufferlen);
memcpy(newbuf, pf_fopen_files[fnum].data, pf_fopen_files[fnum].len);
BZ_Free(pf_fopen_files[fnum].data);
pf_fopen_files[fnum].data = newbuf;
}
memcpy(pf_fopen_files[fnum].data + pf_fopen_files[fnum].ofs, msg, len);
if (pf_fopen_files[fnum].len < pf_fopen_files[fnum].ofs + len)
pf_fopen_files[fnum].len = pf_fopen_files[fnum].ofs + len;
pf_fopen_files[fnum].ofs+=len;
}
*/
void VM_fcloseall (int owner)
{
int i;
for (i = 1; i <= MAX_VM_FILES; i++)
{
VM_fclose(i, owner);
}
}
typedef struct {
char *initialbuffer;
char *buffer;
char *dir;
int found;
int bufferleft;
int skip;
} vmsearch_t;
static int VMEnum(char *match, int size, void *args)
{
char *check;
int newlen;
match += ((vmsearch_t *)args)->skip;
newlen = strlen(match)+1;
if (newlen > ((vmsearch_t *)args)->bufferleft)
return false; //too many files for the buffer
check = ((vmsearch_t *)args)->initialbuffer;
while(check < ((vmsearch_t *)args)->buffer)
{
if (!stricmp(check, match))
return true; //we found this one already
check += strlen(check)+1;
}
memcpy(((vmsearch_t *)args)->buffer, match, newlen);
((vmsearch_t *)args)->buffer+=newlen;
((vmsearch_t *)args)->bufferleft-=newlen;
((vmsearch_t *)args)->found++;
return true;
}
static int IfFound(char *match, int size, void *args)
{
*(qboolean*)args = true;
return true;
}
static int VMEnumMods(char *match, int size, void *args)
{
char *check;
char desc[1024];
int newlen;
int desclen;
qboolean foundone;
vfsfile_t *f;
newlen = strlen(match)+1;
if (*match && match[newlen-2] != '/')
return true;
match[newlen-2] = '\0';
newlen--;
if (!stricmp(match, "baseq3"))
return true; //we don't want baseq3
foundone = false;
Sys_EnumerateFiles(va("%s/%s/", ((vmsearch_t *)args)->dir, match), "*.pk3", IfFound, &foundone);
if (foundone == false)
return true; //we only count directories with a pk3 file
Q_strncpyz(desc, match, sizeof(desc));
f = FS_OpenVFS(va("%s/description.txt", match), "rb", FS_BASE);
if (f)
{
VFS_GETS(f, desc, sizeof(desc));
VFS_CLOSE(f);
}
desclen = strlen(desc)+1;
if (newlen+desclen+5 > ((vmsearch_t *)args)->bufferleft)
return false; //too many files for the buffer
check = ((vmsearch_t *)args)->initialbuffer;
while(check < ((vmsearch_t *)args)->buffer)
{
if (!stricmp(check, match))
return true; //we found this one already
check += strlen(check)+1;
check += strlen(check)+1;
}
memcpy(((vmsearch_t *)args)->buffer, match, newlen);
((vmsearch_t *)args)->buffer+=newlen;
((vmsearch_t *)args)->bufferleft-=newlen;
memcpy(((vmsearch_t *)args)->buffer, desc, desclen);
((vmsearch_t *)args)->buffer+=desclen;
((vmsearch_t *)args)->bufferleft-=desclen;
((vmsearch_t *)args)->found++;
return true;
}
int VM_GetFileList(char *path, char *ext, char *output, int buffersize)
{
vmsearch_t vms;
vms.initialbuffer = vms.buffer = output;
vms.skip = strlen(path)+1;
vms.bufferleft = buffersize;
vms.found=0;
if (!strcmp(path, "$modlist"))
{
vms.skip=0;
Sys_EnumerateFiles((vms.dir=com_quakedir), "*", VMEnumMods, &vms);
if (*com_homedir)
Sys_EnumerateFiles((vms.dir=com_homedir), "*", VMEnumMods, &vms);
}
else if (*(char *)ext == '.' || *(char *)ext == '/')
COM_EnumerateFiles(va("%s/*%s", path, ext), VMEnum, &vms);
else
COM_EnumerateFiles(va("%s/*.%s", path, ext), VMEnum, &vms);
return vms.found;
}
#if defined(Q3SERVER) || defined(Q3CLIENT)

View File

@ -148,7 +148,13 @@ void *Sys_LoadDLL(const char *name, void **vmMain, int (EXPORT_FN *syscall)(int
return 0;
#endif
#if defined(__amd64__)
sprintf(dllname, "%samd.so", name);
#elif defined(_M_IX86) || defined(__i386__)
sprintf(dllname, "%sx86.so", name);
#else
sprintf(dllname, "%sunk.so", name);
#endif
hVM=NULL;
{

View File

@ -68,13 +68,6 @@ qboolean UI_DrawIntermission(void);
qboolean UI_DrawFinale(void);
int UI_MenuState(void);
int VMUI_fopen (char *name, int *handle, int fmode, int owner);
int VMUI_FRead (char *dest, int quantity, int fnum, int owner);
void VMUI_fclose (int fnum, int owner);
void VMUI_fcloseall (int owner);
int VMQ3_GetFileList(char *path, char *ext, char *output, int buffersize);
//sans botlib
struct pc_token_s;
int Script_LoadFile(char *filename);
@ -83,6 +76,16 @@ int Script_Read(int handle, struct pc_token_s *token);
void Script_Get_File_And_Line(int handle, char *filename, int *line);
#endif
#define VM_FS_READ 0
#define VM_FS_WRITE 1
#define VM_FS_APPEND 2
#define VM_FS_APPEND2 3 //I don't know, don't ask me. look at q3 source
int VM_fopen (char *name, int *handle, int fmode, int owner);
int VM_FRead (char *dest, int quantity, int fnum, int owner);
void VM_fclose (int fnum, int owner);
void VM_fcloseall (int owner);
int VM_GetFileList(char *path, char *ext, char *output, int buffersize);
#ifdef VM_CG
void CG_Stop (void);
void CG_Start (void);

View File

@ -12,6 +12,8 @@ It doesn't use persistant connections.
*/
qboolean HTTP_CL_Get(char *url, char *localfile, void (*NotifyFunction)(char *localfile, qboolean sucess));
typedef struct http_con_s {
int sock;

View File

@ -856,16 +856,24 @@ void NPP_QWFlush(void)
case svc_updateuserinfo:
if (buffer[6])
{
Q_strncpyz(svs.clients[buffer[1]].userinfo, (buffer+6), sizeof(svs.clients[0].userinfo));
if (*Info_ValueForKey(svs.clients[buffer[1]].userinfo, "name"))
SV_ExtractFromUserinfo(&svs.clients[buffer[1]]);
else
*svs.clients[buffer[1]].name = '\0';
unsigned int j = buffer[1];
if (j < MAX_CLIENTS)
{
Q_strncpyz(svs.clients[j].userinfo, (buffer+6), sizeof(svs.clients[j].userinfo));
if (*Info_ValueForKey(svs.clients[j].userinfo, "name"))
SV_ExtractFromUserinfo(&svs.clients[j]);
else
*svs.clients[j].name = '\0';
}
}
else
{
*svs.clients[buffer[1]].name = '\0';
*svs.clients[buffer[1]].userinfo = '\0';
unsigned int j = buffer[1];
if (j < MAX_CLIENTS)
{
*svs.clients[j].name = '\0';
*svs.clients[j].userinfo = '\0';
}
}
break;
@ -1766,10 +1774,13 @@ void NPP_MVDFlush(void)
case svc_updateuserinfo:
// ignoreprotocol = true;
{
int j;
unsigned int j;
j = buffer[1];
sv.recordedplayer[j].userid = buffer[2] | (buffer[3]<<8) | (buffer[4]<<16) | (buffer[5]<<24);
Q_strncpyz(sv.recordedplayer[j].userinfo, buffer+6, sizeof(sv.recordedplayer[j].userinfo));
if (j < MAX_CLIENTS)
{
sv.recordedplayer[j].userid = buffer[2] | (buffer[3]<<8) | (buffer[4]<<16) | (buffer[5]<<24);
Q_strncpyz(sv.recordedplayer[j].userinfo, buffer+6, sizeof(sv.recordedplayer[j].userinfo));
}
}
break;
case svc_setangle: //FIXME: forward on to trackers.

View File

@ -150,13 +150,17 @@ pbool QC_WriteFile(char *name, void *data, int len)
void ED_Spawned (struct edict_s *ent)
{
ent->v->dimension_see = 255;
ent->v->dimension_seen = 255;
ent->v->dimension_ghost = 0;
ent->v->dimension_solid = 255;
ent->v->dimension_hit = 255;
#ifdef VM_Q1
if (!ent->xv)
ent->xv = (extentvars_t *)(ent->v+1);
#endif
ent->xv->dimension_see = 255;
ent->xv->dimension_seen = 255;
ent->xv->dimension_ghost = 0;
ent->xv->dimension_solid = 255;
ent->xv->dimension_hit = 255;
ent->v->Version = sv.csqcentversion[ent->entnum]+1;
ent->xv->Version = sv.csqcentversion[ent->entnum]+1;
}
pbool ED_CanFree (edict_t *ed)
@ -203,15 +207,15 @@ pbool ED_CanFree (edict_t *ed)
ed->v->think = 0;
}
ed->v->SendEntity = 0;
sv.csqcentversion[ed->entnum] = ed->v->Version+1;
ed->xv->SendEntity = 0;
sv.csqcentversion[ed->entnum] = ed->xv->Version+1;
return true;
}
void StateOp (progfuncs_t *prinst, float var, func_t func)
{
entvars_t *vars = PROG_TO_EDICT(prinst, pr_global_struct->self)->v;
stdentvars_t *vars = PROG_TO_EDICT(prinst, pr_global_struct->self)->v;
if (progstype == PROG_H2)
vars->nextthink = pr_global_struct->time+0.05;
else
@ -221,7 +225,7 @@ void StateOp (progfuncs_t *prinst, float var, func_t func)
}
void CStateOp (progfuncs_t *prinst, float startFrame, float endFrame, func_t currentfunc)
{
entvars_t *vars = PROG_TO_EDICT(prinst, pr_global_struct->self)->v;
stdentvars_t *vars = PROG_TO_EDICT(prinst, pr_global_struct->self)->v;
vars->nextthink = pr_global_struct->time+0.05;
vars->think = currentfunc;
@ -257,7 +261,7 @@ void CStateOp (progfuncs_t *prinst, float startFrame, float endFrame, func_t cur
}
void CWStateOp (progfuncs_t *prinst, float startFrame, float endFrame, func_t currentfunc)
{
entvars_t *vars = PROG_TO_EDICT(prinst, pr_global_struct->self)->v;
stdentvars_t *vars = PROG_TO_EDICT(prinst, pr_global_struct->self)->v;
vars->nextthink = pr_global_struct->time+0.05;
vars->think = currentfunc;
@ -294,7 +298,7 @@ void CWStateOp (progfuncs_t *prinst, float startFrame, float endFrame, func_t cu
void ThinkTimeOp (progfuncs_t *prinst, edict_t *ed, float var)
{
entvars_t *vars = ed->v;
stdentvars_t *vars = ed->v;
#ifdef PARANOID
NUM_FOR_EDICT(ed); // Make sure it's in range
#endif
@ -429,7 +433,8 @@ void PR_Deinit(void)
if (svprogfuncs)
{
PR_fclose_progs(svprogfuncs);
CloseProgs(svprogfuncs);
if (svprogfuncs->parms)
CloseProgs(svprogfuncs);
Z_FreeTags(Z_QC_TAG);
}
@ -1442,8 +1447,29 @@ qboolean PR_UserCmd(char *s)
return true;
}
#ifdef VM_Q1
if (svs.gametype == GT_Q1QVM)
{
pr_global_struct->time = sv.time;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player);
Q1QVM_ClientCommand();
return true; //qvm can print something if it wants
}
#endif
if (mod_UserCmd && pr_imitatemvdsv.value >= 0)
{ //we didn't recognise it. see if the mod does.
//ktpro bug warning:
//admin + judge. I don't know the exact rules behind this bug, so I just ban the entire command
//I can't be arsed detecting ktpro specifically, so assume we're always running ktpro
if (!strncmp(s, "admin", 5) || !strncmp(s, "judge", 5))
{
Con_Printf("Blocking potentially unsafe ktpro command: %s\n", s);
return true;
}
pr_globals = PR_globals(svprogfuncs, PR_CURRENT);
pr_global_struct->time = sv.time;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player);
@ -1919,16 +1945,11 @@ setmodel(entity, model)
Also sets size, mins, and maxs for inline bmodels
=================
*/
void PF_setmodel (progfuncs_t *prinst, struct globalvars_s *pr_globals)
void PF_setmodel_Internal (progfuncs_t *prinst, edict_t *e, char *m)
{
edict_t *e;
char *m;
int i;
model_t *mod;
e = G_EDICT(prinst, OFS_PARM0);
m = PR_GetStringOfs(prinst, OFS_PARM1);
// check to see if model was properly precached
if (!m || !*m)
i = 0;
@ -2055,6 +2076,17 @@ void PF_setmodel (progfuncs_t *prinst, struct globalvars_s *pr_globals)
}
}
void PF_setmodel (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
edict_t *e;
char *m;
e = G_EDICT(prinst, OFS_PARM0);
m = PR_GetStringOfs(prinst, OFS_PARM1);
PF_setmodel_Internal(prinst, e, m);
}
void PF_set_puzzle_model (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{ //qc/hc lacks string manipulation.
char *shortname;
@ -2821,7 +2853,7 @@ if the tryents flag is set.
traceline (vector1, vector2, tryents)
=================
*/
static void PF_traceline (progfuncs_t *prinst, struct globalvars_s *pr_globals)
void PF_svtraceline (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
float *v1, *v2, *mins, *maxs;
trace_t trace;
@ -2845,10 +2877,10 @@ static void PF_traceline (progfuncs_t *prinst, struct globalvars_s *pr_globals)
maxs = vec3_origin;
}
savedhull = ent->v->hull;
ent->v->hull = 0;
savedhull = ent->xv->hull;
ent->xv->hull = 0;
trace = SV_Move (v1, mins, maxs, v2, nomonsters, ent);
ent->v->hull = savedhull;
ent->xv->hull = savedhull;
if (trace.startsolid)
if (!sv_gameplayfix_honest_tracelines.value)
@ -2888,10 +2920,10 @@ static void PF_traceboxh2 (progfuncs_t *prinst, struct globalvars_s *pr_globals)
nomonsters = G_FLOAT(OFS_PARM4);
ent = G_EDICT(prinst, OFS_PARM5);
savedhull = ent->v->hull;
ent->v->hull = 0;
savedhull = ent->xv->hull;
ent->xv->hull = 0;
trace = SV_Move (v1, mins, maxs, v2, nomonsters, ent);
ent->v->hull = savedhull;
ent->xv->hull = savedhull;
pr_global_struct->trace_allsolid = trace.allsolid;
pr_global_struct->trace_startsolid = trace.startsolid;
@ -2924,10 +2956,10 @@ static void PF_traceboxdp (progfuncs_t *prinst, struct globalvars_s *pr_globals)
nomonsters = G_FLOAT(OFS_PARM4);
ent = G_EDICT(prinst, OFS_PARM5);
savedhull = ent->v->hull;
ent->v->hull = 0;
savedhull = ent->xv->hull;
ent->xv->hull = 0;
trace = SV_Move (v1, mins, maxs, v2, nomonsters, ent);
ent->v->hull = savedhull;
ent->xv->hull = savedhull;
pr_global_struct->trace_allsolid = trace.allsolid;
pr_global_struct->trace_startsolid = trace.startsolid;
@ -3663,21 +3695,10 @@ void PF_precache_file (progfuncs_t *prinst, struct globalvars_s *pr_globals)
G_INT(OFS_RETURN) = G_INT(OFS_PARM0);
}
void PF_precache_sound (progfuncs_t *prinst, struct globalvars_s *pr_globals)
void PF_precache_sound_Internal (progfuncs_t *prinst, char *s)
{
char *s;
int i;
s = PR_GetStringOfs(prinst, OFS_PARM0);
/*
if (sv.state != ss_loading)
{
PR_BIError (prinst, "PF_Precache_*: Precache can only be done in spawn functions (%s)", s);
return;
}
*/
G_INT(OFS_RETURN) = G_INT(OFS_PARM0);
if (s[0] <= ' ')
{
PR_BIError (prinst, "PF_precache_sound: Bad string");
@ -3709,23 +3730,21 @@ void PF_precache_sound (progfuncs_t *prinst, struct globalvars_s *pr_globals)
}
PR_BIError (prinst, "PF_precache_sound: overflow");
}
void PF_precache_model (progfuncs_t *prinst, struct globalvars_s *pr_globals)
void PF_precache_sound (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *s;
int i;
s = PR_GetStringOfs(prinst, OFS_PARM0);
/*
if (sv.state != ss_loading)
{
PR_BIError (prinst, "PF_Precache_*: Precache can only be done in spawn functions (%s)", s);
G_FLOAT(OFS_RETURN) = 1;
return;
}
*/
G_INT(OFS_RETURN) = G_INT(OFS_PARM0);
PF_precache_sound_Internal(prinst, s);
}
void PF_precache_model_Internal (progfuncs_t *prinst, char *s)
{
int i;
if (s[0] <= ' ')
{
PR_BIError (prinst, "Bad string");
@ -3766,6 +3785,16 @@ void PF_precache_model (progfuncs_t *prinst, struct globalvars_s *pr_globals)
}
PR_BIError (prinst, "PF_precache_model: overflow");
}
void PF_precache_model (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *s;
s = PR_GetStringOfs(prinst, OFS_PARM0);
G_INT(OFS_RETURN) = G_INT(OFS_PARM0);
PF_precache_model_Internal(prinst, s);
}
void PF_precache_puzzle_model (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{ //qc/hc lacks string manipulation.
@ -5042,7 +5071,7 @@ void PF_makestatic (progfuncs_t *prinst, struct globalvars_s *pr_globals)
mdlindex = SV_ModelIndex(PR_GetString(prinst, ent->v->model));
if (ent->v->drawflags || ent->v->alpha || mdlindex > 255 || ent->v->frame > 255 || ent->v->scale || ent->v->abslight)
if (ent->xv->drawflags || ent->xv->alpha || mdlindex > 255 || ent->v->frame > 255 || ent->xv->scale || ent->xv->abslight)
{
if (sv.numextrastatics==sizeof(sv.extendedstatics)/sizeof(sv.extendedstatics[0]))
return; //fail the whole makestatic thing.
@ -5058,14 +5087,14 @@ void PF_makestatic (progfuncs_t *prinst, struct globalvars_s *pr_globals)
state->colormap = ent->v->colormap;
state->skinnum = ent->v->skin;
state->effects = ent->v->effects;
state->hexen2flags = ent->v->drawflags;
state->abslight = (int)(ent->v->abslight*255) & 255;
state->trans = ent->v->alpha*255;
if (!ent->v->alpha)
state->hexen2flags = ent->xv->drawflags;
state->abslight = (int)(ent->xv->abslight*255) & 255;
state->trans = ent->xv->alpha*255;
if (!ent->xv->alpha)
state->trans = 255;
state->fatness = ent->v->fatness;
state->scale = ent->v->scale*16.0;
if (!ent->v->scale)
state->fatness = ent->xv->fatness;
state->scale = ent->xv->scale*16.0;
if (!ent->xv->scale)
state->scale = 1*16;
if (progstype != PROG_QW) //don't send extra nq effects to a qw client.
@ -5195,6 +5224,55 @@ PF_infokey
string(entity e, string key) infokey
==============
*/
char *PF_infokey_Internal (int entnum, char *key)
{
char *value;
char ov[256];
if (entnum == 0)
{
if (pr_imitatemvdsv.value && !strcmp(key, "*version"))
value = "2.40";
else
{
if ((value = Info_ValueForKey (svs.info, key)) == NULL || !*value)
value = Info_ValueForKey(localinfo, key);
}
}
else if (entnum <= MAX_CLIENTS)
{
value = ov;
if (!strcmp(key, "ip") || !strcmp(key, "realip")) //note: FTE doesn't support mvdsv's realip stuff, so pretend that we do if the mod asks
value = strcpy(ov, NET_BaseAdrToString (svs.clients[entnum-1].netchan.remote_address));
else if (!strcmp(key, "ping"))
sprintf(ov, "%d", SV_CalcPing (&svs.clients[entnum-1]));
else if (!strcmp(key, "*userid"))
sprintf(ov, "%d", svs.clients[entnum-1].userid);
else if (!strcmp(key, "download"))
sprintf(ov, "%d", svs.clients[entnum-1].download != NULL ? (int)(100*svs.clients[entnum-1].downloadcount/svs.clients[entnum-1].downloadsize) : -1);
// else if (!strcmp(key, "login")) //mvdsv
// value = "";
else if (!strcmp(key, "trustlevel")) //info for progs.
{
#ifdef SVRANKING
rankstats_t rs;
if (!svs.clients[entnum-1].rankid)
value = "";
else if (Rank_GetPlayerStats(svs.clients[entnum-1].rankid, &rs))
sprintf(ov, "%d", rs.trustlevel);
else
#endif
value = "";
}
else
value = Info_ValueForKey (svs.clients[entnum-1].userinfo, key);
} else
value = "";
return value;
}
void PF_infokey (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
edict_t *e;
@ -5207,45 +5285,7 @@ void PF_infokey (progfuncs_t *prinst, struct globalvars_s *pr_globals)
e1 = NUM_FOR_EDICT(prinst, e);
key = PR_GetStringOfs(prinst, OFS_PARM1);
if (e1 == 0)
{
if (pr_imitatemvdsv.value && !strcmp(key, "*version"))
value = "2.40";
else
{
if ((value = Info_ValueForKey (svs.info, key)) == NULL || !*value)
value = Info_ValueForKey(localinfo, key);
}
}
else if (e1 <= MAX_CLIENTS)
{
value = ov;
if (!strcmp(key, "ip") || !strcmp(key, "realip")) //note: FTE doesn't support mvdsv's realip stuff, so pretend that we do if the mod asks
value = strcpy(ov, NET_BaseAdrToString (svs.clients[e1-1].netchan.remote_address));
else if (!strcmp(key, "ping"))
sprintf(ov, "%d", SV_CalcPing (&svs.clients[e1-1]));
else if (!strcmp(key, "*userid"))
sprintf(ov, "%d", svs.clients[e1-1].userid);
else if (!strcmp(key, "download"))
sprintf(ov, "%d", svs.clients[e1-1].download != NULL ? (int)(100*svs.clients[e1-1].downloadcount/svs.clients[e1-1].downloadsize) : -1);
// else if (!strcmp(key, "login")) //mvdsv
// value = "";
else if (!strcmp(key, "trustlevel")) //info for progs.
{
#ifdef SVRANKING
rankstats_t rs;
if (!svs.clients[e1-1].rankid)
value = "";
else if (Rank_GetPlayerStats(svs.clients[e1-1].rankid, &rs))
sprintf(ov, "%d", rs.trustlevel);
else
#endif
value = "";
}
else
value = Info_ValueForKey (svs.clients[e1-1].userinfo, key);
} else
value = "";
value = PF_infokey_Internal (e1, key);
G_INT(OFS_RETURN) = PR_TempString(prinst, value);
}
@ -7486,7 +7526,7 @@ void PR_SetPlayerClass(client_t *cl, int classnum, qboolean fromqc)
return;
if (cl->playerclass != classnum)
{
cl->edict->v->playerclass = classnum;
cl->edict->xv->playerclass = classnum;
cl->playerclass = classnum;
sprintf(temp,"%i",(int)classnum);
@ -7525,7 +7565,7 @@ void PF_setclass (progfuncs_t *prinst, struct globalvars_s *pr_globals)
client = &svs.clients[entnum-1];
e->v->playerclass = NewClass;
e->xv->playerclass = NewClass;
client->playerclass = NewClass;
sprintf(temp,"%d",(int)NewClass);
@ -8942,8 +8982,8 @@ void PF_setattachment(progfuncs_t *prinst, struct globalvars_s *pr_globals)
}
e->v->tag_entity = EDICT_TO_PROG(prinst,tagentity);
e->v->tag_index = tagidx;
e->xv->tag_entity = EDICT_TO_PROG(prinst,tagentity);
e->xv->tag_index = tagidx;
}
// #451 float(entity ent, string tagname) gettagindex (DP_MD3_TAGSINFO)
@ -9320,7 +9360,7 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
{"vectoyaw", PF_vectoyaw, 13, 13, 13}, // float(vector v) vectoyaw = #13;
{"spawn", PF_Spawn, 14, 14, 14}, // entity() spawn = #14;
{"remove", PF_Remove, 15, 15, 15}, // void(entity e) remove = #15;
{"traceline", PF_traceline, 16, 16, 16}, // float(vector v1, vector v2, float tryents) traceline = #16;
{"traceline", PF_svtraceline, 16, 16, 16}, // float(vector v1, vector v2, float tryents) traceline = #16;
{"checkclient", PF_checkclient, 17, 17, 17}, // entity() clientlist = #17;
{"find", PF_FindString, 18, 18, 18}, // entity(entity start, .string fld, string match) find = #18;
{"precache_sound", PF_precache_sound, 19, 19, 19}, // void(string s) precache_sound = #19;
@ -9896,11 +9936,25 @@ int pr_numbuiltins = sizeof(pr_builtin)/sizeof(pr_builtin[0]);
void PR_RegisterFields(void) //it's just easier to do it this way.
{
#define fieldfloat(name) PR_RegisterFieldVar(svprogfuncs, ev_float, #name, (int)&((entvars_t*)0)->name, -1)
#define fieldvector(name) PR_RegisterFieldVar(svprogfuncs, ev_vector, #name, (int)&((entvars_t*)0)->name, -1)
#define fieldentity(name) PR_RegisterFieldVar(svprogfuncs, ev_entity, #name, (int)&((entvars_t*)0)->name, -1)
#define fieldstring(name) PR_RegisterFieldVar(svprogfuncs, ev_string, #name, (int)&((entvars_t*)0)->name, -1)
#define fieldfunction(name) PR_RegisterFieldVar(svprogfuncs, ev_function, #name, (int)&((entvars_t*)0)->name, -1)
#define fieldfloat(name) PR_RegisterFieldVar(svprogfuncs, ev_float, #name, (int)&((stdentvars_t*)0)->name, -1)
#define fieldvector(name) PR_RegisterFieldVar(svprogfuncs, ev_vector, #name, (int)&((stdentvars_t*)0)->name, -1)
#define fieldentity(name) PR_RegisterFieldVar(svprogfuncs, ev_entity, #name, (int)&((stdentvars_t*)0)->name, -1)
#define fieldstring(name) PR_RegisterFieldVar(svprogfuncs, ev_string, #name, (int)&((stdentvars_t*)0)->name, -1)
#define fieldfunction(name) PR_RegisterFieldVar(svprogfuncs, ev_function, #name, (int)&((stdentvars_t*)0)->name, -1)
#ifdef VM_Q1
#define fieldxfloat(name) PR_RegisterFieldVar(svprogfuncs, ev_float, #name, sizeof(stdentvars_t) + (int)&((extentvars_t*)0)->name, -1)
#define fieldxvector(name) PR_RegisterFieldVar(svprogfuncs, ev_vector, #name, sizeof(stdentvars_t) + (int)&((extentvars_t*)0)->name, -1)
#define fieldxentity(name) PR_RegisterFieldVar(svprogfuncs, ev_entity, #name, sizeof(stdentvars_t) + (int)&((extentvars_t*)0)->name, -1)
#define fieldxstring(name) PR_RegisterFieldVar(svprogfuncs, ev_string, #name, sizeof(stdentvars_t) + (int)&((extentvars_t*)0)->name, -1)
#define fieldxfunction(name) PR_RegisterFieldVar(svprogfuncs, ev_function, #name, sizeof(stdentvars_t) + (int)&((extentvars_t*)0)->name, -1)
#else
#define fieldxfloat fieldfloat
#define fieldxvector fieldvector
#define fieldxentity fieldentity
#define fieldxstring fieldstring
#define fieldxfunction fieldfunction
#endif
fieldfloat(modelindex);
fieldvector(absmin);
@ -9946,12 +10000,6 @@ void PR_RegisterFields(void) //it's just easier to do it this way.
fieldfloat(button0);
fieldfloat(button1);
fieldfloat(button2);
fieldfloat(button3);
fieldfloat(button4);
fieldfloat(button5);
fieldfloat(button6);
fieldfloat(button7);
fieldfloat(button8);
fieldfloat(impulse);
fieldfloat(fixangle);
fieldvector(v_angle);
@ -9985,65 +10033,70 @@ void PR_RegisterFields(void) //it's just easier to do it this way.
fieldstring(noise3);
//the rest are extras. (not in header)
fieldfloat(gravity); //standard extension
fieldfloat(maxspeed); //standard extension
fieldfloat(items2); //standard nq
fieldvector(punchangle);//standard nq
fieldfloat(scale);
//fieldfloat(transparency);
fieldfloat(alpha);
fieldfloat(fatness);
fieldentity(view2);
fieldvector(movement);
fieldfloat(fteflags);
fieldfloat(vweapmodelindex);
fieldxfloat(button3);
fieldxfloat(button4);
fieldxfloat(button5);
fieldxfloat(button6);
fieldxfloat(button7);
fieldxfloat(button8);
fieldxfloat(gravity); //standard extension
fieldxfloat(maxspeed); //standard extension
fieldxfloat(items2); //standard nq
fieldxvector(punchangle);//standard nq
fieldxfloat(scale);
fieldxfloat(alpha);
fieldxfloat(fatness);
fieldxentity(view2);
fieldxvector(movement);
fieldxfloat(fteflags);
fieldxfloat(vweapmodelindex);
//dp extra fields
fieldentity(nodrawtoclient);
fieldentity(drawonlytoclient);
fieldentity(viewmodelforclient);
fieldentity(exteriormodeltoclient);
fieldxentity(nodrawtoclient);
fieldxentity(drawonlytoclient);
fieldxentity(viewmodelforclient);
fieldxentity(exteriormodeltoclient);
fieldfloat(viewzoom);
fieldxfloat(viewzoom);
fieldentity(tag_entity);
fieldfloat(tag_index);
fieldxentity(tag_entity);
fieldxfloat(tag_index);
fieldfloat(glow_size);
fieldfloat(glow_color);
fieldfloat(glow_trail);
fieldxfloat(glow_size);
fieldxfloat(glow_color);
fieldxfloat(glow_trail);
fieldvector(colormod);
fieldxvector(colormod);
fieldvector(color);
fieldfloat(light_lev);
fieldfloat(style);
fieldfloat(pflags);
fieldxvector(color);
fieldxfloat(light_lev);
fieldxfloat(style);
fieldxfloat(pflags);
fieldfloat(clientcolors);
fieldxfloat(clientcolors);
//hexen 2 stuff
fieldfloat(playerclass);
fieldfloat(hull);
fieldfloat(hasted);
fieldxfloat(playerclass);
fieldxfloat(hull);
fieldxfloat(hasted);
fieldfloat(light_level);
fieldfloat(abslight);
fieldfloat(drawflags);
fieldentity(movechain);
fieldfunction(chainmoved);
fieldxfloat(light_level);
fieldxfloat(abslight);
fieldxfloat(drawflags);
fieldxentity(movechain);
fieldxfunction(chainmoved);
//QSG_DIMENSION_PLANES
fieldfloat(dimension_see);
fieldfloat(dimension_seen);
fieldfloat(dimension_ghost);
fieldfloat(dimension_ghost_alpha);
fieldfloat(dimension_solid);
fieldfloat(dimension_hit);
fieldxfloat(dimension_see);
fieldxfloat(dimension_seen);
fieldxfloat(dimension_ghost);
fieldxfloat(dimension_ghost_alpha);
fieldxfloat(dimension_solid);
fieldxfloat(dimension_hit);
fieldfunction(SendEntity);
fieldfloat(Version);
fieldxfunction(SendEntity);
fieldxfloat(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).

1407
engine/server/pr_q1qvm.c Executable file

File diff suppressed because it is too large Load Diff

View File

@ -84,13 +84,13 @@ typedef struct nqglobalvars_s
#define P_VEC(v) (pr_global_struct->V_##v)
typedef struct entvars_s
typedef struct stdentvars_s //standard = standard for qw
{
float modelindex;
vec3_t absmin;
vec3_t absmax;
float ltime;
int lastruntime;
int lastruntime; //type doesn't match the qc, we use a hidden double instead. this is dead.
float movetype;
float solid;
vec3_t origin;
@ -128,14 +128,8 @@ typedef struct entvars_s
float deadflag;
vec3_t view_ofs;
float button0;
float button1;
float button1; //dead field in nq mode
float button2;
float button3; //3 and 1 are the same
float button4;
float button5;
float button6;
float button7;
float button8;
float impulse;
float fixangle;
vec3_t v_angle;
@ -162,32 +156,47 @@ typedef struct entvars_s
int dmg_inflictor;
int owner;
vec3_t movedir;
string_t message; //WARNING: hexen2 uses a float and not a string
float sounds;
string_t noise;
string_t noise1;
string_t noise2;
string_t noise3;
#ifdef VM_Q1
} stdentvars_t;
typedef struct extentvars_s
{
#endif
//extra vars. use these if you wish.
float gravity;
float maxspeed;
float items2;
vec3_t punchangle;
float scale;
float alpha;
float fatness;
int view2;
float maxspeed; //added in quake 1.09
float gravity; //added in quake 1.09 (for hipnotic)
float items2; //added in quake 1.09 (for hipnotic)
vec3_t punchangle; //std in nq
float scale; //DP_ENT_SCALE
float alpha; //DP_ENT_ALPHA
float fatness; //FTE_PEXT_FATNESS
int view2; //FTE_PEXT_VIEW2
float fteflags;
vec3_t movement;
vec3_t movement;
float vweapmodelindex;
//dp extra fields
int nodrawtoclient;
int nodrawtoclient; //
int drawonlytoclient;
int viewmodelforclient;
int viewmodelforclient; //DP_ENT_VIEWMODEL
int exteriormodeltoclient;
float button3; //DP_INPUTBUTTONS (note in qw, we set 1 to equal 3, to match zquake/fuhquake/mvdsv)
float button4;
float button5;
float button6;
float button7;
float button8;
float viewzoom;
float viewzoom; //DP_VIEWZOOM
int tag_entity;
float tag_index;
@ -218,7 +227,7 @@ typedef struct entvars_s
float hull;
float drawflags;
int movechain;
int movechain;
func_t chainmoved;
float light_level;//hexen2's grabbing light level from client
@ -228,5 +237,10 @@ typedef struct entvars_s
//csqc stuph.
func_t SendEntity;
float Version;
} entvars_t;
#ifdef VM_Q1
} extentvars_t;
#else
} stdentvars_t;
#endif

View File

@ -69,9 +69,16 @@ typedef struct edict_s
float freetime; // sv.time when the object was freed
int entnum;
qboolean readonly; //world
entvars_t *v;
#ifndef VM_Q1
stdentvars_t *v;
#define xv v
#else
stdentvars_t *v;
//the rest is free for adaption
extentvars_t *xv;
#endif
link_t area; // linked to a division node or leaf
int num_leafs;

View File

@ -684,6 +684,7 @@ typedef struct filteredip_s {
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_Q1QVM,
GT_QUAKE2, //q2 servers run from a q2 game dll
GT_QUAKE3, //q3 servers run off the q3 qvm api
GT_MAX

View File

@ -282,7 +282,7 @@ static qboolean SV_AddCSQCUpdate (client_t *client, edict_t *ent)
if (!(client->csqcactive))
return false;
if (!ent->v->SendEntity)
if (!ent->xv->SendEntity)
return false;
csqcent[csqcnuments++] = ent;
@ -319,10 +319,10 @@ void SV_EmitCSQCUpdate(client_t *client, sizebuf_t *msg)
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];
if ((int)ent->xv->Version < sv.csqcentversion[ent->entnum])
ent->xv->Version = sv.csqcentversion[ent->entnum];
else
sv.csqcentversion[ent->entnum] = (int)ent->v->Version;
sv.csqcentversion[ent->entnum] = (int)ent->xv->Version;
//If it's not changed, don't send
if (client->csqcentversions[ent->entnum] == sv.csqcentversion[ent->entnum])
@ -333,7 +333,7 @@ void SV_EmitCSQCUpdate(client_t *client, sizebuf_t *msg)
//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);
PR_ExecuteProgram(svprogfuncs, ent->xv->SendEntity);
if (G_INT(OFS_RETURN)) //0 means not to tell the client about it.
{
if (msg->cursize + csqcmsgbuffer.cursize+5 >= msg->maxsize)
@ -485,7 +485,7 @@ void SV_WriteDelta (entity_state_t *from, entity_state_t *to, sizebuf_t *msg, qb
for (i=0 ; i<3 ; i++)
{
miss = to->origin[i] - from->origin[i];
if ( miss < -0.1 || miss > 0.1 )
// if ( miss < -0.1 || miss > 0.1 )
{
bits |= U_ORIGIN1<<i;
}
@ -519,7 +519,7 @@ void SV_WriteDelta (entity_state_t *from, entity_state_t *to, sizebuf_t *msg, qb
if ( (to->effects&0xff00) != (fromeffects&0xff00) )
evenmorebits |= U_EFFECTS16;
if ( to->modelindex != from->modelindex )
// if ( to->modelindex != from->modelindex )
{
bits |= U_MODEL;
if (to->modelindex > 255)
@ -1702,7 +1702,7 @@ void SV_WritePlayersToClient (client_t *client, edict_t *clent, qbyte *pvs, size
if (!sv.worldmodel->funcs.EdictInFatPVS(sv.worldmodel, ent))
continue;
if (!((int)clent->v->dimension_see & ((int)ent->v->dimension_seen | (int)ent->v->dimension_ghost)))
if (!((int)clent->xv->dimension_see & ((int)ent->xv->dimension_seen | (int)ent->xv->dimension_ghost)))
continue; //not in this dimension - sorry...
if (sv_cullplayers_trace.value || sv_cullentities_trace.value)
if (Cull_Traceline(clent, ent))
@ -1715,10 +1715,10 @@ void SV_WritePlayersToClient (client_t *client, edict_t *clent, qbyte *pvs, size
{
clstate_t clst;
clst.playernum = j;
clst.onladder = (int)ent->v->fteflags&FF_LADDER;
clst.onladder = (int)ent->xv->fteflags&FF_LADDER;
clst.lastcmd = &cl->lastcmd;
clst.modelindex = vent->v->modelindex;
clst.modelindex2 = vent->v->vweapmodelindex;
clst.modelindex2 = vent->xv->vweapmodelindex;
clst.frame = vent->v->frame;
clst.weaponframe = ent->v->weaponframe;
clst.angles = ent->v->angles;
@ -1734,22 +1734,22 @@ void SV_WritePlayersToClient (client_t *client, edict_t *clent, qbyte *pvs, size
clst.skin = vent->v->skin;
clst.mins = vent->v->mins;
clst.hull = vent->v->hull;
clst.hull = vent->xv->hull;
clst.maxs = vent->v->maxs;
clst.scale = vent->v->scale;
clst.transparency = vent->v->alpha;
clst.scale = vent->xv->scale;
clst.transparency = vent->xv->alpha;
//QSG_DIMENSION_PLANES - if the only shared dimensions are ghost dimensions, Set half alpha.
if (((int)clent->v->dimension_see & (int)ent->v->dimension_ghost))
if (!((int)clent->v->dimension_see & ((int)ent->v->dimension_seen & ~(int)ent->v->dimension_ghost)) )
if (((int)clent->xv->dimension_see & (int)ent->xv->dimension_ghost))
if (!((int)clent->xv->dimension_see & ((int)ent->xv->dimension_seen & ~(int)ent->xv->dimension_ghost)) )
{
if (ent->v->dimension_ghost_alpha)
clst.transparency *= ent->v->dimension_ghost_alpha;
if (ent->xv->dimension_ghost_alpha)
clst.transparency *= ent->xv->dimension_ghost_alpha;
else
clst.transparency *= 0.5;
}
clst.fatness = vent->v->fatness;
clst.fatness = vent->xv->fatness;
clst.localtime = cl->localtime;
clst.health = ent->v->health;
clst.spectator = 0;
@ -1804,10 +1804,10 @@ void SV_WritePlayersToClient (client_t *client, edict_t *clent, qbyte *pvs, size
//FIXME: Name flags
//player is visible, now would be a good time to update what the player is like.
pflags = 0;
if (client->fteprotocolextensions & PEXT_VWEAP && client->otherclientsknown[j].vweap != ent->v->vweapmodelindex)
if (client->fteprotocolextensions & PEXT_VWEAP && client->otherclientsknown[j].vweap != ent->xv->vweapmodelindex)
{
pflags |= 1;
client->otherclientsknown[j].vweap = ent->v->vweapmodelindex;
client->otherclientsknown[j].vweap = ent->xv->vweapmodelindex;
}
if (pflags)
{
@ -1911,12 +1911,12 @@ int glowsize=0, glowcolor=0, colourmod=0;
if (0)
{
if (ent->baseline.trans != ent->v->alpha)
if (!(ent->baseline.trans == 1 && !ent->v->alpha))
if (ent->baseline.trans != ent->xv->alpha)
if (!(ent->baseline.trans == 1 && !ent->xv->alpha))
bits |= DPU_ALPHA;
if (ent->baseline.scale != ent->v->scale)
if (ent->baseline.scale != ent->xv->scale)
{
if (ent->v->scale != 0 || ent->baseline.scale != 1)
if (ent->xv->scale != 0 || ent->baseline.scale != 1)
bits |= DPU_SCALE;
}
@ -1926,16 +1926,16 @@ int glowsize=0, glowcolor=0, colourmod=0;
if ((ent->baseline.effects&0xff00) != ((int)eff & 0xff00))
bits |= DPU_EFFECTS2;
if (ent->v->exteriormodeltoclient == EDICT_TO_PROG(svprogfuncs, host_client->edict))
if (ent->xv->exteriormodeltoclient == EDICT_TO_PROG(svprogfuncs, host_client->edict))
bits |= DPU_EXTERIORMODEL;
if (ent->v->viewmodelforclient == EDICT_TO_PROG(svprogfuncs, host_client->edict))
if (ent->xv->viewmodelforclient == EDICT_TO_PROG(svprogfuncs, host_client->edict))
bits |= DPU_VIEWMODEL;
glowsize = ent->v->glow_size*0.25f;
glowcolor = ent->v->glow_color;
glowsize = ent->xv->glow_size*0.25f;
glowcolor = ent->xv->glow_color;
colourmod = ((int)bound(0, ent->v->colormod[0] * (7.0f / 32.0f), 7) << 5) | ((int)bound(0, ent->v->colormod[1] * (7.0f / 32.0f), 7) << 2) | ((int)bound(0, ent->v->colormod[2] * (3.0f / 32.0f), 3) << 0);
colourmod = ((int)bound(0, ent->xv->colormod[0] * (7.0f / 32.0f), 7) << 5) | ((int)bound(0, ent->xv->colormod[1] * (7.0f / 32.0f), 7) << 2) | ((int)bound(0, ent->xv->colormod[2] * (3.0f / 32.0f), 3) << 0);
if (0 != glowsize)
bits |= DPU_GLOWSIZE;
@ -1992,8 +1992,8 @@ int glowsize=0, glowcolor=0, colourmod=0;
if (bits & NQU_ORIGIN3) MSG_WriteCoord (msg, ent->v->origin[2]);
if (bits & NQU_ANGLE3) MSG_WriteAngle(msg, ent->v->angles[2]);
if (bits & DPU_ALPHA) MSG_WriteByte(msg, ent->v->alpha*255);
if (bits & DPU_SCALE) MSG_WriteByte(msg, ent->v->scale*16);
if (bits & DPU_ALPHA) MSG_WriteByte(msg, ent->xv->alpha*255);
if (bits & DPU_SCALE) MSG_WriteByte(msg, ent->xv->scale*16);
if (bits & DPU_EFFECTS2) MSG_WriteByte(msg, eff >> 8);
if (bits & DPU_GLOWSIZE) MSG_WriteByte(msg, glowsize);
if (bits & DPU_GLOWCOLOR) MSG_WriteByte(msg, glowcolor);
@ -2044,7 +2044,7 @@ void SV_GibFilterInit(void)
Z_Free(gf);
}
if (svs.gametype != GT_PROGS)
if (svs.gametype != GT_PROGS && svs.gametype != GT_Q1QVM)
return;
file = COM_LoadStackFile("gibfiltr.cfg", buffer, sizeof(buffer));
@ -2179,8 +2179,8 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore
sv.worldmodel->funcs.FatPVS(sv.worldmodel, org, false);
#ifdef PEXT_VIEW2
if (clent->v->view2)
sv.worldmodel->funcs.FatPVS(sv.worldmodel, PROG_TO_EDICT(svprogfuncs, clent->v->view2)->v->origin, true);
if (clent->xv->view2)
sv.worldmodel->funcs.FatPVS(sv.worldmodel, PROG_TO_EDICT(svprogfuncs, clent->xv->view2)->v->origin, true);
#endif
for (split = client->controlled; split; split = split->controlled)
sv.worldmodel->funcs.FatPVS(sv.worldmodel, split->edict->v->origin, true);
@ -2204,8 +2204,8 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore
SV_Q1BSP_FatPVS (org);
#ifdef PEXT_VIEW2
if (clent->v->view2)
SV_Q1BSP_AddToFatPVS (PROG_TO_EDICT(svprogfuncs, clent->v->view2)->v->origin, sv.worldmodel->nodes); //add a little more...
if (clent->xv->view2)
SV_Q1BSP_AddToFatPVS (PROG_TO_EDICT(svprogfuncs, clent->xv->view2)->v->origin, sv.worldmodel->nodes); //add a little more...
#endif
for (split = client->controlled; split; split = split->controlled)
SV_Q1BSP_AddToFatPVS (split->edict->v->origin, sv.worldmodel->nodes); //add a little more...
@ -2314,21 +2314,21 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore
state->colormap = clent->v->colormap;
state->skinnum = clent->v->skin;
state->effects = clent->v->effects;
state->hexen2flags = clent->v->drawflags;
state->abslight = clent->v->abslight;
state->hexen2flags = clent->xv->drawflags;
state->abslight = clent->xv->abslight;
#ifdef PEXT_SCALE
state->scale = clent->v->scale*16;
state->scale = clent->xv->scale*16;
if (!state->scale)
state->scale = 1*16;
#endif
#ifdef PEXT_TRANS
state->trans = clent->v->alpha*255;
state->trans = clent->xv->alpha*255;
if (!state->trans)
state->trans = 255;
#endif
#ifdef PEXT_FATNESS
state->fatness = clent->v->fatness*2;
state->fatness = clent->xv->fatness*2;
#endif
if (progstype == PROG_QW)
@ -2366,7 +2366,7 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore
ent = EDICT_NUM(svprogfuncs, e);
// ignore ents without visible models
if (!ent->v->SendEntity && (!ent->v->modelindex || !*PR_GetString(svprogfuncs, ent->v->model)) && !((int)ent->v->pflags & PFLAGS_FULLDYNAMIC))
if (!ent->xv->SendEntity && (!ent->v->modelindex || !*PR_GetString(svprogfuncs, ent->v->model)) && !((int)ent->xv->pflags & PFLAGS_FULLDYNAMIC))
continue;
if (progstype != PROG_QW)
@ -2389,17 +2389,17 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore
if (!ignorepvs && ent != clent)
{
//branch out to the pvs testing.
if (ent->v->viewmodelforclient == EDICT_TO_PROG(svprogfuncs, client->edict))
if (ent->xv->viewmodelforclient == EDICT_TO_PROG(svprogfuncs, client->edict))
{
//unconditional
}
else if (ent->v->tag_entity)
else if (ent->xv->tag_entity)
{
edict_t *p = ent;
int c = 10;
while(p->v->tag_entity&&c-->0)
while(p->xv->tag_entity&&c-->0)
{
p = EDICT_NUM(svprogfuncs, p->v->tag_entity);
p = EDICT_NUM(svprogfuncs, p->xv->tag_entity);
}
if (!sv.worldmodel->funcs.EdictInFatPVS(sv.worldmodel, p))
continue;
@ -2422,16 +2422,16 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore
// continue;
if (ent->v->nodrawtoclient) //DP extension.
if (ent->v->nodrawtoclient == EDICT_TO_PROG(svprogfuncs, client->edict))
if (ent->xv->nodrawtoclient) //DP extension.
if (ent->xv->nodrawtoclient == EDICT_TO_PROG(svprogfuncs, client->edict))
continue;
if (ent->v->drawonlytoclient)
if (ent->v->drawonlytoclient != EDICT_TO_PROG(svprogfuncs, client->edict))
if (ent->xv->drawonlytoclient)
if (ent->xv->drawonlytoclient != EDICT_TO_PROG(svprogfuncs, client->edict))
{
client_t *split;
for (split = client->controlled; split; split=split->controlled)
{
if (split->edict->v->view2 == EDICT_TO_PROG(svprogfuncs, ent))
if (split->edict->xv->view2 == EDICT_TO_PROG(svprogfuncs, ent))
break;
}
if (!split)
@ -2440,7 +2440,7 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore
//QSG_DIMENSION_PLANES
if (client->edict)
if (!((int)client->edict->v->dimension_see & ((int)ent->v->dimension_seen | (int)ent->v->dimension_ghost)))
if (!((int)client->edict->xv->dimension_see & ((int)ent->xv->dimension_seen | (int)ent->xv->dimension_ghost)))
continue; //not in this dimension - sorry...
@ -2555,9 +2555,9 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore
#define RENDER_COLORMAPPED 32
state->dpflags = 0;
if (ent->v->viewmodelforclient)
if (ent->xv->viewmodelforclient)
{
if (ent->v->viewmodelforclient == EDICT_TO_PROG(svprogfuncs, client->edict))
if (ent->xv->viewmodelforclient == EDICT_TO_PROG(svprogfuncs, client->edict))
state->dpflags |= RENDER_VIEWMODEL;
else
{ //noone else sees it.
@ -2565,13 +2565,13 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore
continue;
}
}
if (ent->v->exteriormodeltoclient)
if (ent->xv->exteriormodeltoclient)
{
if (ent->v->exteriormodeltoclient == EDICT_TO_PROG(svprogfuncs, client->edict))
if (ent->xv->exteriormodeltoclient == EDICT_TO_PROG(svprogfuncs, client->edict))
state->dpflags |= RENDER_EXTERIORMODEL;
//everyone else sees it normally.
}
state->number = e;
state->flags = 0;
VectorCopy (ent->v->origin, state->origin);
@ -2581,17 +2581,17 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore
state->colormap = ent->v->colormap;
state->skinnum = ent->v->skin;
state->effects = ent->v->effects;
state->hexen2flags = ent->v->drawflags;
state->abslight = (int)(ent->v->abslight*255) & 255;
state->tagentity = ent->v->tag_entity;
state->tagindex = ent->v->tag_index;
state->hexen2flags = ent->xv->drawflags;
state->abslight = (int)(ent->xv->abslight*255) & 255;
state->tagentity = ent->xv->tag_entity;
state->tagindex = ent->xv->tag_index;
state->light[0] = ent->v->color[0]*255;
state->light[1] = ent->v->color[1]*255;
state->light[2] = ent->v->color[2]*255;
state->light[3] = ent->v->light_lev;
state->lightstyle = ent->v->style;
state->lightpflags = ent->v->pflags;
state->light[0] = ent->xv->color[0]*255;
state->light[1] = ent->xv->color[1]*255;
state->light[2] = ent->xv->color[2]*255;
state->light[3] = ent->xv->light_lev;
state->lightstyle = ent->xv->style;
state->lightpflags = ent->xv->pflags;
if ((int)ent->v->flags & FL_CLASS_DEPENDENT && client->playerclass) //hexen2 wierdness.
{
@ -2642,7 +2642,7 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore
state->effects &= ~ (QWEF_FLAG1|QWEF_FLAG2);
}
if (!ent->v->colormod[0] && !ent->v->colormod[1] && !ent->v->colormod[2])
if (!ent->xv->colormod[0] && !ent->xv->colormod[1] && !ent->xv->colormod[2])
{
state->colormod[0] = (256)/8;
state->colormod[1] = (256)/8;
@ -2650,39 +2650,39 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore
}
else
{
i = ent->v->colormod[0]*(256/8); state->colormod[0] = bound(0, i, 255);
i = ent->v->colormod[1]*(256/8); state->colormod[1] = bound(0, i, 255);
i = ent->v->colormod[2]*(256/8); state->colormod[2] = bound(0, i, 255);
i = ent->xv->colormod[0]*(256/8); state->colormod[0] = bound(0, i, 255);
i = ent->xv->colormod[1]*(256/8); state->colormod[1] = bound(0, i, 255);
i = ent->xv->colormod[2]*(256/8); state->colormod[2] = bound(0, i, 255);
}
state->glowsize = ent->v->glow_size*0.25;
state->glowcolour = ent->v->glow_color;
if (ent->v->glow_trail)
state->glowsize = ent->xv->glow_size*0.25;
state->glowcolour = ent->xv->glow_color;
if (ent->xv->glow_trail)
state->dpflags |= RENDER_GLOWTRAIL;
#ifdef PEXT_SCALE
state->scale = ent->v->scale*16;
if (!ent->v->scale)
state->scale = ent->xv->scale*16;
if (!ent->xv->scale)
state->scale = 1*16;
#endif
#ifdef PEXT_TRANS
state->trans = ent->v->alpha*255;
if (!ent->v->alpha)
state->trans = ent->xv->alpha*255;
if (!ent->xv->alpha)
state->trans = 255;
//QSG_DIMENSION_PLANES - if the only shared dimensions are ghost dimensions, Set half alpha.
if (client->edict)
if (((int)client->edict->v->dimension_see & (int)ent->v->dimension_ghost))
if (!((int)client->edict->v->dimension_see & ((int)ent->v->dimension_seen & ~(int)ent->v->dimension_ghost)) )
if (((int)client->edict->xv->dimension_see & (int)ent->xv->dimension_ghost))
if (!((int)client->edict->xv->dimension_see & ((int)ent->xv->dimension_seen & ~(int)ent->xv->dimension_ghost)) )
{
if (ent->v->dimension_ghost_alpha)
state->trans *= ent->v->dimension_ghost_alpha;
if (ent->xv->dimension_ghost_alpha)
state->trans *= ent->xv->dimension_ghost_alpha;
else
state->trans *= 0.5;
}
#endif
#ifdef PEXT_FATNESS
state->fatness = ent->v->fatness*2;
state->fatness = ent->xv->fatness*2;
#endif
}
#ifdef NQPROT

View File

@ -209,17 +209,17 @@ void SV_EdictToEntState (int num, edict_t *ent, entity_state_t *state)
state->colormap = ent->v->colormap;
state->skinnum = ent->v->skin;
state->effects = ent->v->effects;
state->hexen2flags = ent->v->drawflags;
state->abslight = (int)(ent->v->abslight*255) & 255;
state->tagentity = ent->v->tag_entity;
state->tagindex = ent->v->tag_index;
state->hexen2flags = ent->xv->drawflags;
state->abslight = (int)(ent->xv->abslight*255) & 255;
state->tagentity = ent->xv->tag_entity;
state->tagindex = ent->xv->tag_index;
state->light[0] = ent->v->color[0]*255;
state->light[1] = ent->v->color[1]*255;
state->light[2] = ent->v->color[2]*255;
state->light[3] = ent->v->light_lev;
state->lightstyle = ent->v->style;
state->lightpflags = ent->v->pflags;
state->light[0] = ent->xv->color[0]*255;
state->light[1] = ent->xv->color[1]*255;
state->light[2] = ent->xv->color[2]*255;
state->light[3] = ent->xv->light_lev;
state->lightstyle = ent->xv->style;
state->lightpflags = ent->xv->pflags;
/* if ((int)ent->v->flags & FL_CLASS_DEPENDENT && client->playerclass) //hexen2 wierdness.
{
@ -239,12 +239,12 @@ void SV_EdictToEntState (int num, edict_t *ent, entity_state_t *state)
state->hexen2flags |= MLS_FULLBRIGHT;
}
if (!ent->v->alpha)
if (!ent->xv->alpha)
state->trans = 255;
else
state->trans = ent->v->alpha*255;
state->trans = ent->xv->alpha*255;
if (!ent->v->colormod[0] && !ent->v->colormod[1] && !ent->v->colormod[2])
if (!ent->xv->colormod[0] && !ent->xv->colormod[1] && !ent->xv->colormod[2])
{
state->colormod[0] = (256)/8;
state->colormod[1] = (256)/8;
@ -252,22 +252,22 @@ void SV_EdictToEntState (int num, edict_t *ent, entity_state_t *state)
}
else
{
i = ent->v->colormod[0]*(256/8); state->colormod[0] = bound(0, i, 255);
i = ent->v->colormod[1]*(256/8); state->colormod[1] = bound(0, i, 255);
i = ent->v->colormod[2]*(256/8); state->colormod[2] = bound(0, i, 255);
i = ent->xv->colormod[0]*(256/8); state->colormod[0] = bound(0, i, 255);
i = ent->xv->colormod[1]*(256/8); state->colormod[1] = bound(0, i, 255);
i = ent->xv->colormod[2]*(256/8); state->colormod[2] = bound(0, i, 255);
}
state->glowsize = ent->v->glow_size*0.25;
state->glowcolour = ent->v->glow_color;
state->glowsize = ent->xv->glow_size*0.25;
state->glowcolour = ent->xv->glow_color;
#define RENDER_GLOWTRAIL 2
if (ent->v->glow_trail)
if (ent->xv->glow_trail)
state->dpflags |= RENDER_GLOWTRAIL;
if (!ent->v->scale)
if (!ent->xv->scale)
state->scale = 1*16;
else
state->scale = ent->v->scale*16;
state->scale = ent->xv->scale*16;
state->fatness = ent->v->fatness*2;
state->fatness = ent->xv->fatness*2;
}
void SVNQ_CreateBaseline (void)
@ -367,6 +367,20 @@ void SV_SaveSpawnparms (qboolean dontsave)
memcpy(host_client->spawninfo, buf, bufsize);
host_client->spawninfotime = sv.time;
}
#ifdef VM_Q1
else if (svs.gametype == GT_Q1QVM)
{
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, host_client->edict);
Q1QVM_SetChangeParms();
for (j=0 ; j<NUM_SPAWN_PARMS ; j++)
{
if (spawnparamglobals[j])
host_client->spawn_parms[j] = *spawnparamglobals[j];
else
host_client->spawn_parms[j] = 0;
}
}
#endif
else if (pr_nqglobal_struct->SetChangeParms)
{
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, host_client->edict);
@ -833,11 +847,13 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
if (svprogfuncs) //we don't want the q1 stuff anymore.
if (svs.gametype == GT_PROGS)
{
CloseProgs(svprogfuncs);
svprogfuncs = NULL;
if (svprogfuncs) //we don't want the q1 stuff anymore.
{
CloseProgs(svprogfuncs);
svprogfuncs = NULL;
}
}
sv.state = ss_loading;
@ -852,6 +868,11 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
if ((sv.worldmodel->fromgame == fg_quake2 || sv.worldmodel->fromgame == fg_quake3) && !*progs.string && SVQ2_InitGameProgs()) //these are the rules for running a q2 server
newgametype = GT_QUAKE2; //we loaded the dll
else
#endif
#ifdef VM_Q1
if (PR_LoadQ1QVM())
newgametype = GT_Q1QVM;
else
#endif
{
newgametype = GT_PROGS; //let's just hope this loads.
@ -880,10 +901,14 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
if (newgametype != GT_QUAKE2) //we don't want the q2 stuff anymore.
SVQ2_ShutdownGameProgs ();
#endif
#ifdef VM_Q1
if (newgametype != GT_Q1QVM)
Q1QVM_Shutdown();
#endif
sv.models[1] = sv.worldmodel;
if (svs.gametype == GT_PROGS)
if (svs.gametype == GT_PROGS || svs.gametype == GT_Q1QVM)
{
strcpy(sv.strings.sound_precache[0], "");
sv.strings.model_precache[0] = "";
@ -945,6 +970,9 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
{
case GT_MAX:
break;
#ifdef VM_Q1
case GT_Q1QVM:
#endif
case GT_PROGS:
ent = EDICT_NUM(svprogfuncs, 0);
ent->isfree = false;
@ -1020,6 +1048,7 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
if (svprogfuncs)
{
//world entity is hackily spawned
extern cvar_t coop, pr_imitatemvdsv;
eval_t *eval;
ent = EDICT_NUM(svprogfuncs, 0);
@ -1029,11 +1058,7 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
ent->v->solid = SOLID_BSP;
ent->v->movetype = MOVETYPE_PUSH;
ent->v->dimension_see = 255;
ent->v->dimension_seen = 255;
ent->v->dimension_ghost = 0;
ent->v->dimension_solid = 255;
ent->v->dimension_hit = 255;
ED_Spawned(ent);
if (progstype == PROG_QW && pr_imitatemvdsv.value>0)
{
@ -1139,6 +1164,9 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
{
case GT_MAX:
break;
#ifdef VM_Q1
case GT_Q1QVM:
#endif
case GT_PROGS:
pr_edict_size = PR_LoadEnts(svprogfuncs, file, spawnflagmask);
break;
@ -1159,6 +1187,9 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
{
case GT_MAX:
break;
#ifdef VM_Q1
case GT_Q1QVM:
#endif
case GT_PROGS:
pr_edict_size = PR_LoadEnts(svprogfuncs, sv.worldmodel->entities, spawnflagmask);
break;
@ -1192,6 +1223,8 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
else
snprintf(sv.mapname, sizeof(sv.mapname), "%s", PR_GetString(svprogfuncs, val->string));
}
else
snprintf(sv.mapname, sizeof(sv.mapname), "%s", sv.name);
if (Cvar_Get("sv_readonlyworld", "1", 0, "DP compatability")->value)
ent->readonly = true; //lock it down!
@ -1272,7 +1305,7 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
SCR_ImageName(server);
#endif
if (svs.gametype == GT_PROGS)
if (svs.gametype == GT_PROGS || svs.gametype == GT_Q1QVM)
{
for (i = 0; i < sv.allocated_client_slots; i++)
{
@ -1290,7 +1323,7 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
}
SV_SetUpClientEdict(host_client, sv_player);
sv_player->v->clientcolors = atoi(Info_ValueForKey(host_client->userinfo, "topcolor"))*16 + atoi(Info_ValueForKey(host_client->userinfo, "bottomcolor"));
sv_player->xv->clientcolors = atoi(Info_ValueForKey(host_client->userinfo, "topcolor"))*16 + atoi(Info_ValueForKey(host_client->userinfo, "bottomcolor"));
// call the spawn function
pr_global_struct->time = sv.time;

View File

@ -226,6 +226,7 @@ void SV_Shutdown (void)
sv_fraglogfile = NULL;
}
PR_Deinit();
if (sv.mvdrecording)
@ -265,7 +266,7 @@ void VARGS SV_Error (char *error, ...)
{
extern cvar_t pr_ssqc_coreonerror;
if (svprogfuncs && pr_ssqc_coreonerror.value)
if (svprogfuncs && pr_ssqc_coreonerror.value && svprogfuncs->save_ents)
{
int size = 1024*1024*8;
char *buffer = BZ_Malloc(size);
@ -419,24 +420,36 @@ void SV_DropClient (client_t *drop)
{
case GT_MAX:
break;
#ifdef VM_Q1
case GT_Q1QVM:
#endif
case GT_PROGS:
if (svprogfuncs)
{
if (drop->state == cs_spawned)
{
if (!drop->spectator)
#ifdef VM_Q1
if (svs.gametype == GT_Q1QVM)
{
// call the prog function for removing a client
// this will set the body to a dead frame, among other things
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, drop->edict);
PR_ExecuteProgram (svprogfuncs, pr_global_struct->ClientDisconnect);
Q1QVM_DropClient(drop);
}
else if (SpectatorDisconnect)
else
#endif
{
if (!drop->spectator)
{
// call the prog function for removing a client
// this will set the body to a dead frame, among other things
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, drop->edict);
PR_ExecuteProgram (svprogfuncs, SpectatorDisconnect);
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, drop->edict);
PR_ExecuteProgram (svprogfuncs, pr_global_struct->ClientDisconnect);
}
else if (SpectatorDisconnect)
{
// call the prog function for removing a client
// this will set the body to a dead frame, among other things
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, drop->edict);
PR_ExecuteProgram (svprogfuncs, SpectatorDisconnect);
}
}
}
@ -516,7 +529,7 @@ void SV_DropClient (client_t *drop)
drop->frameunion.frames = NULL;
}
if (svs.gametype == GT_PROGS) //gamecode should do it all for us.
if (svs.gametype == GT_PROGS || svs.gametype == GT_Q1QVM) //gamecode should do it all for us.
{
// send notification to all remaining clients
SV_FullClientUpdate (drop, &sv.reliable_datagram, 0);
@ -1220,7 +1233,7 @@ void SVC_GetChallenge (void)
over = buf + strlen(buf) + 1;
if (svs.gametype == GT_PROGS)
if (svs.gametype == GT_PROGS || svs.gametype == GT_Q1QVM)
{
#ifdef PROTOCOL_VERSION_FTE
//tell the client what fte extensions we support
@ -1250,7 +1263,7 @@ void SVC_GetChallenge (void)
}
#endif
}
if (sv_listen_qw.value || svs.gametype != GT_PROGS)
if (sv_listen_qw.value || (svs.gametype != GT_PROGS && svs.gametype != GT_Q1QVM))
Netchan_OutOfBand(NS_SERVER, net_from, over-buf, buf);
if (sv_listen_dp.value && (sv_listen_nq.value || sv_bigcoords.value || !sv_listen_qw.value))
@ -1271,8 +1284,15 @@ void SV_GetNewSpawnParms(client_t *cl)
if (svprogfuncs) //q2 dlls don't use parms in this mannor. It's all internal to the dll.
{
// call the progs to get default spawn parms for the new client
if (pr_nqglobal_struct->SetNewParms)
PR_ExecuteProgram (svprogfuncs, pr_global_struct->SetNewParms);
#ifdef VM_Q1
if (svs.gametype == GT_Q1QVM)
Q1QVM_SetNewParms();
else
#endif
{
if (pr_nqglobal_struct->SetNewParms)
PR_ExecuteProgram (svprogfuncs, pr_global_struct->SetNewParms);
}
for (i=0 ; i<NUM_SPAWN_PARMS ; i++)
{
if (spawnparamglobals[i])
@ -1817,6 +1837,9 @@ client_t *SVC_DirectConnect(void)
edictnum = (newcl-svs.clients)+1;
switch (svs.gametype)
{
#ifdef VM_Q1
case GT_Q1QVM:
#endif
case GT_PROGS:
ent = EDICT_NUM(svprogfuncs, edictnum);
#ifdef Q2SERVER
@ -3818,9 +3841,9 @@ void SV_ExtractFromUserinfo (client_t *cl)
if (bottom > 13)
bottom = 13;
cl->playercolor = top*16 + bottom;
if (svs.gametype == GT_PROGS)
if (svs.gametype == GT_PROGS || svs.gametype == GT_Q1QVM)
{
cl->edict->v->clientcolors = cl->playercolor;
cl->edict->xv->clientcolors = cl->playercolor;
MSG_WriteByte (&sv.nqreliable_datagram, svc_updatecolors);
MSG_WriteByte (&sv.nqreliable_datagram, cl-svs.clients);
MSG_WriteByte (&sv.nqreliable_datagram, cl->playercolor);
@ -3931,7 +3954,10 @@ void SV_Init (quakeparms_t *parms)
Con_TPrintf (TL_EXEDATETIME, __DATE__, __TIME__);
Con_TPrintf (TL_HEAPSIZE,parms->memsize/ (1024*1024.0));
Con_TPrintf (TL_VERSION, DISTRIBUTION, build_number());
if (sizeof(void*) == 8)
Con_TPrintf (TL_VERSION, DISTRIBUTION"-64", build_number());
else
Con_TPrintf (TL_VERSION, DISTRIBUTION"-32", build_number());
Con_TPrintf (STL_INITED);

View File

@ -72,10 +72,10 @@ realcheck:
start[0] = stop[0] = (mins[0] + maxs[0])*0.5;
start[1] = stop[1] = (mins[1] + maxs[1])*0.5;
stop[2] = start[2] - 2*movevars.stepheight;
savedhull = ent->v->hull;
ent->v->hull = 0;
savedhull = ent->xv->hull;
ent->xv->hull = 0;
trace = SV_Move (start, vec3_origin, vec3_origin, stop, true, ent);
ent->v->hull = savedhull;
ent->xv->hull = savedhull;
if (trace.fraction == 1.0)
return false;
@ -88,10 +88,10 @@ realcheck:
start[0] = stop[0] = x ? maxs[0] : mins[0];
start[1] = stop[1] = y ? maxs[1] : mins[1];
savedhull = ent->v->hull;
ent->v->hull = 0;
savedhull = ent->xv->hull;
ent->xv->hull = 0;
trace = SV_Move (start, vec3_origin, vec3_origin, stop, true, ent);
ent->v->hull = savedhull;
ent->xv->hull = savedhull;
if (trace.fraction != 1.0 && trace.endpos[2] > bottom)
bottom = trace.endpos[2];

View File

@ -158,7 +158,12 @@ qboolean SV_RunThink (edict_t *ent)
pr_global_struct->time = thinktime;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, ent);
pr_global_struct->other = EDICT_TO_PROG(svprogfuncs, sv.edicts);
PR_ExecuteProgram (svprogfuncs, ent->v->think);
#ifdef VM_Q1
if (svs.gametype == GT_Q1QVM)
Q1QVM_Think();
else
#endif
PR_ExecuteProgram (svprogfuncs, ent->v->think);
return !ent->isfree;
}
@ -179,7 +184,12 @@ qboolean SV_RunThink (edict_t *ent)
pr_global_struct->time = thinktime;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, ent);
pr_global_struct->other = EDICT_TO_PROG(svprogfuncs, sv.edicts);
PR_ExecuteProgram (svprogfuncs, ent->v->think);
#ifdef VM_Q1
if (svs.gametype == GT_Q1QVM)
Q1QVM_Think();
else
#endif
PR_ExecuteProgram (svprogfuncs, ent->v->think);
if (ent->isfree)
return false;
@ -210,14 +220,24 @@ void SV_Impact (edict_t *e1, edict_t *e2)
{
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, e1);
pr_global_struct->other = EDICT_TO_PROG(svprogfuncs, e2);
PR_ExecuteProgram (svprogfuncs, e1->v->touch);
#ifdef VM_Q1
if (svs.gametype == GT_Q1QVM)
Q1QVM_Touch();
else
#endif
PR_ExecuteProgram (svprogfuncs, e1->v->touch);
}
if (e2->v->touch && e2->v->solid != SOLID_NOT)
{
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, e2);
pr_global_struct->other = EDICT_TO_PROG(svprogfuncs, e1);
PR_ExecuteProgram (svprogfuncs, e2->v->touch);
#ifdef VM_Q1
if (svs.gametype == GT_Q1QVM)
Q1QVM_Touch();
else
#endif
PR_ExecuteProgram (svprogfuncs, e2->v->touch);
}
pr_global_struct->self = old_self;
@ -641,7 +661,12 @@ qboolean SV_PushAngles (edict_t *pusher, vec3_t move, vec3_t amove)
{
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, pusher);
pr_global_struct->other = EDICT_TO_PROG(svprogfuncs, check);
PR_ExecuteProgram (svprogfuncs, pusher->v->blocked);
#ifdef VM_Q1
if (svs.gametype == GT_Q1QVM)
Q1QVM_Blocked();
else
#endif
PR_ExecuteProgram (svprogfuncs, pusher->v->blocked);
}
// move back any entities we already moved
@ -791,7 +816,12 @@ qboolean SV_Push (edict_t *pusher, vec3_t move, vec3_t amove)
{
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, pusher);
pr_global_struct->other = EDICT_TO_PROG(svprogfuncs, check);
PR_ExecuteProgram (svprogfuncs, pusher->v->blocked);
#ifdef VM_Q1
if (svs.gametype == GT_Q1QVM)
Q1QVM_Blocked();
else
#endif
PR_ExecuteProgram (svprogfuncs, pusher->v->blocked);
}
// move back any entities we already moved
@ -877,7 +907,12 @@ VectorCopy (ent->v->angles, oldang);
pr_global_struct->time = sv.time;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, ent);
pr_global_struct->other = EDICT_TO_PROG(svprogfuncs, sv.edicts);
PR_ExecuteProgram (svprogfuncs, ent->v->think);
#ifdef VM_Q1
if (svs.gametype == GT_Q1QVM)
Q1QVM_Think();
else
#endif
PR_ExecuteProgram (svprogfuncs, ent->v->think);
if (ent->isfree)
return;
VectorSubtract (ent->v->origin, oldorg, move);
@ -914,16 +949,16 @@ void SV_Physics_Follow (edict_t *ent)
// LordHavoc: implemented rotation on MOVETYPE_FOLLOW objects
e = PROG_TO_EDICT(svprogfuncs, ent->v->aiment);
if (e->v->angles[0] == ent->v->punchangle[0] && e->v->angles[1] == ent->v->punchangle[1] && e->v->angles[2] == ent->v->punchangle[2])
if (e->v->angles[0] == ent->xv->punchangle[0] && e->v->angles[1] == ent->xv->punchangle[1] && e->v->angles[2] == ent->xv->punchangle[2])
{
// quick case for no rotation
VectorAdd(e->v->origin, ent->v->view_ofs, ent->v->origin);
}
else
{
angles[0] = -ent->v->punchangle[0];
angles[1] = ent->v->punchangle[1];
angles[2] = ent->v->punchangle[2];
angles[0] = -ent->xv->punchangle[0];
angles[1] = ent->xv->punchangle[1];
angles[2] = ent->xv->punchangle[2];
AngleVectors (angles, vf, vr, vu);
v[0] = ent->v->view_ofs[0] * vf[0] + ent->v->view_ofs[1] * vr[0] + ent->v->view_ofs[2] * vu[0];
v[1] = ent->v->view_ofs[0] * vf[1] + ent->v->view_ofs[1] * vr[1] + ent->v->view_ofs[2] * vu[1];
@ -1171,7 +1206,12 @@ void SV_ProgStartFrame (void)
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv.edicts);
pr_global_struct->other = EDICT_TO_PROG(svprogfuncs, sv.edicts);
pr_global_struct->time = sv.time;
PR_ExecuteProgram (svprogfuncs, pr_global_struct->StartFrame);
#ifdef VM_Q1
if (svs.gametype == GT_Q1QVM)
Q1QVM_StartFrame();
else
#endif
PR_ExecuteProgram (svprogfuncs, pr_global_struct->StartFrame);
}
@ -1721,8 +1761,13 @@ void SV_RunEntity (edict_t *ent)
//
pr_global_struct->time = sv.time;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, ent);
if (pr_global_struct->PlayerPreThink)
PR_ExecuteProgram (svprogfuncs, pr_global_struct->PlayerPreThink);
#ifdef VM_Q1
if (svs.gametype == GT_Q1QVM)
Q1QVM_PlayerPreThink();
else
#endif
if (pr_global_struct->PlayerPreThink)
PR_ExecuteProgram (svprogfuncs, pr_global_struct->PlayerPreThink);
if (readyforjump) //qw progs can't jump for themselves...
{
@ -1739,7 +1784,7 @@ void SV_RunEntity (edict_t *ent)
movechain = PROG_TO_EDICT(svprogfuncs, ent->v->movechain);
movechain = PROG_TO_EDICT(svprogfuncs, ent->xv->movechain);
if (movechain != sv.edicts)
{
VectorCopy(ent->v->origin,initial_origin);
@ -1777,7 +1822,7 @@ void SV_RunEntity (edict_t *ent)
if (!SV_RunThink (ent))
return;
if (!SV_CheckWater (ent) && ! ((int)ent->v->flags & FL_WATERJUMP) )
SV_AddGravity (ent, ent->v->gravity);
SV_AddGravity (ent, ent->xv->gravity);
SV_CheckStuck (ent);
SV_WalkMove (ent);
@ -1800,17 +1845,22 @@ void SV_RunEntity (edict_t *ent)
VectorSubtract(ent->v->angles, initial_angle, moveang)
VectorSubtract(ent->v->origin, initial_origin, moveorg)
for(i=16;i && movechain != sv.edicts && !movechain->isfree;i--, movechain = PROG_TO_EDICT(svprogfuncs, movechain->v->movechain))
for(i=16;i && movechain != sv.edicts && !movechain->isfree;i--, movechain = PROG_TO_EDICT(svprogfuncs, movechain->xv->movechain))
{
if ((int)movechain->v->flags & FL_MOVECHAIN_ANGLE)
VectorAdd(movechain->v->angles, moveang, movechain->v->angles);
VectorAdd(movechain->v->origin, moveorg, movechain->v->origin);
if (movechain->v->chainmoved && callfunc)
if (movechain->xv->chainmoved && callfunc)
{
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, movechain);
pr_global_struct->other = EDICT_TO_PROG(svprogfuncs, ent);
PR_ExecuteProgram(svprogfuncs, movechain->v->chainmoved);
#ifdef VM_Q1
if (svs.gametype == GT_Q1QVM)
Q1QVM_ChainMoved();
else
#endif
PR_ExecuteProgram(svprogfuncs, movechain->xv->chainmoved);
}
}
}
@ -1822,8 +1872,15 @@ void SV_RunEntity (edict_t *ent)
pr_global_struct->time = sv.time;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, ent);
if (pr_global_struct->PlayerPostThink)
PR_ExecuteProgram (svprogfuncs, pr_global_struct->PlayerPostThink);
#ifdef VM_Q1
if (svs.gametype == GT_Q1QVM)
Q1QVM_PostThink();
else
#endif
{
if (pr_global_struct->PlayerPostThink)
PR_ExecuteProgram (svprogfuncs, pr_global_struct->PlayerPostThink);
}
}
}
@ -1864,7 +1921,7 @@ trace_t SV_Trace_Toss (edict_t *tossent, edict_t *ignore)
vec3_t origin, velocity;
// this has to fetch the field from the original edict, since our copy is truncated
gravity = tossent->v->gravity;
gravity = tossent->xv->gravity;
if (!gravity)
gravity = 1.0;
gravity *= sv_gravity.value * 0.05;
@ -1910,7 +1967,7 @@ qboolean SV_Physics (void)
static double old_time;
if (svs.gametype != GT_PROGS) //make tics multiples of sv_maxtic (defaults to 0.1)
if (svs.gametype != GT_PROGS && svs.gametype != GT_Q1QVM) //make tics multiples of sv_maxtic (defaults to 0.1)
{
host_frametime = sv.time - old_time;
if (host_frametime<0)
@ -2008,7 +2065,17 @@ qboolean SV_Physics (void)
if (retouch)
pr_global_struct->force_retouch-=1;
if (EndFrameQC)
#ifdef VM_Q1
if (svs.gametype == GT_Q1QVM)
{
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv.edicts);
pr_global_struct->other = EDICT_TO_PROG(svprogfuncs, sv.edicts);
pr_global_struct->time = sv.time;
Q1QVM_EndFrame();
}
else
#endif
if (EndFrameQC)
{
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv.edicts);
pr_global_struct->other = EDICT_TO_PROG(svprogfuncs, sv.edicts);

View File

@ -660,7 +660,7 @@ void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int
goto inrange;
}
else if (svprogfuncs)
if (!((int)client->edict->v->dimension_see & dimension_mask))
if (!((int)client->edict->xv->dimension_see & dimension_mask))
continue;
// -1 is because pvs rows are 1 based, not 0 based like leafs
@ -878,9 +878,9 @@ void SV_StartSound (edict_t *entity, int channel, char *sample, int volume,
MSG_WriteCoord (&sv.nqmulticast, origin[i]);
#endif
if (use_phs)
SV_MulticastProtExt(origin, reliable ? MULTICAST_PHS_R : MULTICAST_PHS, entity->v->dimension_seen, requiredextensions, 0);
SV_MulticastProtExt(origin, reliable ? MULTICAST_PHS_R : MULTICAST_PHS, entity->xv->dimension_seen, requiredextensions, 0);
else
SV_MulticastProtExt(origin, reliable ? MULTICAST_ALL_R : MULTICAST_ALL, entity->v->dimension_seen, requiredextensions, 0);
SV_MulticastProtExt(origin, reliable ? MULTICAST_ALL_R : MULTICAST_ALL, entity->xv->dimension_seen, requiredextensions, 0);
}
/*
@ -1290,22 +1290,22 @@ void SV_UpdateClientStats (client_t *client, int pnum)
// stuff the sigil bits into the high bits of items for sbar
if (pr_items2)
stats[STAT_ITEMS] = (int)ent->v->items | ((int)ent->v->items2 << 23);
stats[STAT_ITEMS] = (int)ent->v->items | ((int)ent->xv->items2 << 23);
else
stats[STAT_ITEMS] = (int)ent->v->items | ((int)pr_global_struct->serverflags << 28);
stats[STAT_VIEWHEIGHT] = ent->v->view_ofs[2];
#ifdef PEXT_VIEW2
if (ent->v->view2)
stats[STAT_VIEW2] = NUM_FOR_EDICT(svprogfuncs, PROG_TO_EDICT(svprogfuncs, ent->v->view2));
if (ent->xv->view2)
stats[STAT_VIEW2] = NUM_FOR_EDICT(svprogfuncs, PROG_TO_EDICT(svprogfuncs, ent->xv->view2));
else
stats[STAT_VIEW2] = 0;
#endif
if (!ent->v->viewzoom)
if (!ent->xv->viewzoom)
stats[STAT_VIEWZOOM] = 255;
else
stats[STAT_VIEWZOOM] = ent->v->viewzoom*255;
stats[STAT_VIEWZOOM] = ent->xv->viewzoom*255;
if (host_client->protocol == SCP_DARKPLACES7)
{
@ -1529,13 +1529,13 @@ void SV_UpdateToReliableMessages (void)
// check for changes to be sent over the reliable streams to all clients
for (i=0, host_client = svs.clients ; i<MAX_CLIENTS ; i++, host_client++)
{
if (svs.gametype == GT_PROGS && host_client->state == cs_spawned)
if ((svs.gametype == GT_Q1QVM || svs.gametype == GT_PROGS) && host_client->state == cs_spawned)
{
//DP_SV_CLIENTCOLORS
if (host_client->edict->v->clientcolors != host_client->playercolor)
if (host_client->edict->xv->clientcolors != host_client->playercolor)
{
Info_SetValueForKey(host_client->userinfo, "topcolor", va("%i", (int)host_client->edict->v->clientcolors/16), sizeof(host_client->userinfo));
Info_SetValueForKey(host_client->userinfo, "bottomcolor", va("%i", (int)host_client->edict->v->clientcolors&15), sizeof(host_client->userinfo));
Info_SetValueForKey(host_client->userinfo, "topcolor", va("%i", (int)host_client->edict->xv->clientcolors/16), sizeof(host_client->userinfo));
Info_SetValueForKey(host_client->userinfo, "bottomcolor", va("%i", (int)host_client->edict->xv->clientcolors&15), sizeof(host_client->userinfo));
{
SV_ExtractFromUserinfo (host_client); //this will take care of nq for us anyway.
@ -1634,7 +1634,7 @@ void SV_UpdateToReliableMessages (void)
// maxspeed/entgravity changes
ent = host_client->edict;
newval = ent->v->gravity*sv_gravity.value;
newval = ent->xv->gravity*sv_gravity.value;
if (progstype != PROG_QW)
{
if (!newval)
@ -1650,14 +1650,14 @@ void SV_UpdateToReliableMessages (void)
}
host_client->entgravity = newval;
}
newval = ent->v->maxspeed;
newval = ent->xv->maxspeed;
if (progstype != PROG_QW)
{
if (!newval)
newval = sv_maxspeed.value;
}
if (ent->v->hasted)
newval*=ent->v->hasted;
if (ent->xv->hasted)
newval*=ent->xv->hasted;
#ifdef SVCHAT //enforce a no moving time when chatting. Prevent client prediction going mad.
if (host_client->chat.active)
newval = 0;

View File

@ -82,6 +82,16 @@ void *Sys_GetGameAPI (void *parms)
const char *debugdir = "debug";
#endif
#elif defined __amd64__
const char *gamename = "gameamd.dll";
#ifdef NDEBUG
const char *debugdir = "release";
#else
const char *debugdir = "debug";
#endif
#elif defined _M_ALPHA
const char *gamename = "gameaxp.dll";

View File

@ -1244,8 +1244,8 @@ void SV_Spawn_f (void)
if (split->istobeloaded) //minimal setup
{
split->entgravity = ent->v->gravity;
split->maxspeed = ent->v->maxspeed;
split->entgravity = ent->xv->gravity;
split->maxspeed = ent->xv->maxspeed;
}
else
{
@ -1348,7 +1348,7 @@ void SV_Begin_f (void)
}
if (progstype == PROG_H2)
host_client->edict->v->playerclass = host_client->playerclass; //make sure it's set the same as the userinfo
host_client->edict->xv->playerclass = host_client->playerclass; //make sure it's set the same as the userinfo
for (split = host_client; split; split = split->controlled)
{
@ -1441,14 +1441,21 @@ void SV_Begin_f (void)
}
// call the spawn function
pr_global_struct->time = sv.time;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, split->edict);
PR_ExecuteProgram (svprogfuncs, pr_global_struct->ClientConnect);
// actually spawn the player
pr_global_struct->time = sv.time;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, split->edict);
PR_ExecuteProgram (svprogfuncs, pr_global_struct->PutClientInServer);
#ifdef VM_Q1
if (svs.gametype == GT_Q1QVM)
Q1QVM_ClientConnect(split);
else
#endif
{
pr_global_struct->time = sv.time;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, split->edict);
PR_ExecuteProgram (svprogfuncs, pr_global_struct->ClientConnect);
// actually spawn the player
pr_global_struct->time = sv.time;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, split->edict);
PR_ExecuteProgram (svprogfuncs, pr_global_struct->PutClientInServer);
}
oh = host_client;
SV_PreRunCmd();
@ -2471,6 +2478,17 @@ SV_Kill_f
void SV_Kill_f (void)
{
float floodtime;
#ifdef VM_Q1
if (svs.gametype == GT_Q1QVM)
{
pr_global_struct->time = sv.time;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player);
Q1QVM_ClientCommand();
return;
}
#endif
if (sv_player->v->health <= 0)
{
SV_ClientTPrintf (host_client, PRINT_HIGH, STL_NOSUICIDEWHENDEAD);
@ -3163,8 +3181,20 @@ void ED_ClearEdict (progfuncs_t *progfuncs, edict_t *e);
void SV_SetUpClientEdict (client_t *cl, edict_t *ent)
{
extern int pr_teamfield;
if (progstype != PROG_NQ) //allow frikbots to work in NQ mods (but not qw!)
ED_ClearEdict(svprogfuncs, ent);
#ifdef VM_Q1
if (svs.gametype == GT_Q1QVM)
{
string_t preserve;
preserve = ent->v->netname;
Q1QVMED_ClearEdict(ent, true);
ent->v->netname = preserve;
}
else
#endif
{
if (progstype != PROG_NQ) //allow frikbots to work in NQ mods (but not qw!)
ED_ClearEdict(svprogfuncs, ent);
}
ED_Spawned(ent);
ent->isfree = false;
@ -3181,12 +3211,12 @@ void SV_SetUpClientEdict (client_t *cl, edict_t *ent)
tc = 0;
if (bc < 0 || bc > 13)
bc = 0;
ent->v->clientcolors = 16*tc + bc;
ent->xv->clientcolors = 16*tc + bc;
}
ent->v->gravity = cl->entgravity = 1.0;
ent->v->maxspeed = cl->maxspeed = sv_maxspeed.value;
ent->xv->gravity = cl->entgravity = 1.0;
ent->xv->maxspeed = cl->maxspeed = sv_maxspeed.value;
ent->v->movetype = MOVETYPE_NOCLIP;
}
/*
@ -3679,8 +3709,8 @@ void SVNQ_Spawn_f (void)
if (host_client->istobeloaded) //minimal setup
{
host_client->entgravity = ent->v->gravity*sv_gravity.value;
host_client->maxspeed = ent->v->maxspeed;
host_client->entgravity = ent->xv->gravity*sv_gravity.value;
host_client->maxspeed = ent->xv->maxspeed;
}
else
{
@ -3691,9 +3721,9 @@ void SVNQ_Spawn_f (void)
ent->v->team = 0; // FIXME
ent->v->netname = PR_SetString(svprogfuncs, host_client->name);
host_client->entgravity = ent->v->gravity = 1.0;
host_client->entgravity = ent->xv->gravity = 1.0;
host_client->entgravity*=sv_gravity.value;
host_client->maxspeed = ent->v->maxspeed = sv_maxspeed.value;
host_client->maxspeed = ent->xv->maxspeed = sv_maxspeed.value;
}
//
@ -4222,8 +4252,8 @@ void AddLinksToPmove ( areanode_t *node )
if (pmove.numphysent == MAX_PHYSENTS)
break;
pe = &pmove.physents[pmove.numphysent];
pe->notouch = !((int)sv_player->v->dimension_solid & (int)check->v->dimension_hit);
if (!((int)sv_player->v->dimension_hit & (int)check->v->dimension_solid))
pe->notouch = !((int)sv_player->xv->dimension_solid & (int)check->xv->dimension_hit);
if (!((int)sv_player->xv->dimension_hit & (int)check->xv->dimension_solid))
continue;
pmove.numphysent++;
@ -4262,14 +4292,14 @@ void AddLinksToPmove ( areanode_t *node )
if (i != 3)
continue;
if (!((int)sv_player->v->dimension_hit & (int)check->v->dimension_solid))
if (!((int)sv_player->xv->dimension_hit & (int)check->xv->dimension_solid))
continue;
model = sv.models[(int)check->v->modelindex];
if (model)
// test the point
if ( model->funcs.PointContents (model, sv_player->v->origin) == FTECONTENTS_SOLID )
sv_player->v->fteflags = (int)sv_player->v->fteflags | FF_LADDER; //touch that ladder!
sv_player->xv->fteflags = (int)sv_player->xv->fteflags | FF_LADDER; //touch that ladder!
}
}
@ -4541,19 +4571,19 @@ void SV_RunCmd (usercmd_t *ucmd, qboolean recurse)
}
if (progstype == PROG_H2)
sv_player->v->light_level = 128; //hmm... HACK!!!
sv_player->xv->light_level = 128; //hmm... HACK!!!
sv_player->v->button0 = ucmd->buttons & 1;
sv_player->v->button2 = (ucmd->buttons >> 1) & 1;
if (pr_allowbutton1.value) //many mods use button1 - it's just a wasted field to many mods. So only work it if the cvar allows.
sv_player->v->button1 = ((ucmd->buttons >> 2) & 1);
// DP_INPUTBUTTONS
sv_player->v->button3 = ((ucmd->buttons >> 2) & 1);
sv_player->v->button4 = ((ucmd->buttons >> 3) & 1);
sv_player->v->button5 = ((ucmd->buttons >> 4) & 1);
sv_player->v->button6 = ((ucmd->buttons >> 5) & 1);
sv_player->v->button7 = ((ucmd->buttons >> 6) & 1);
sv_player->v->button8 = ((ucmd->buttons >> 7) & 1);
sv_player->xv->button3 = ((ucmd->buttons >> 2) & 1);
sv_player->xv->button4 = ((ucmd->buttons >> 3) & 1);
sv_player->xv->button5 = ((ucmd->buttons >> 4) & 1);
sv_player->xv->button6 = ((ucmd->buttons >> 5) & 1);
sv_player->xv->button7 = ((ucmd->buttons >> 6) & 1);
sv_player->xv->button8 = ((ucmd->buttons >> 7) & 1);
if (ucmd->impulse && SV_FiltureImpulse(ucmd->impulse, host_client->trustlevel))
sv_player->v->impulse = ucmd->impulse;
@ -4563,9 +4593,9 @@ void SV_RunCmd (usercmd_t *ucmd, qboolean recurse)
sv_player->v->button0 = 0;
}
sv_player->v->movement[0] = ucmd->forwardmove * host_frametime;
sv_player->v->movement[1] = ucmd->sidemove * host_frametime;
sv_player->v->movement[2] = ucmd->upmove * host_frametime;
sv_player->xv->movement[0] = ucmd->forwardmove * host_frametime;
sv_player->xv->movement[1] = ucmd->sidemove * host_frametime;
sv_player->xv->movement[2] = ucmd->upmove * host_frametime;
SV_CheckVelocity(sv_player);
@ -4613,7 +4643,13 @@ void SV_RunCmd (usercmd_t *ucmd, qboolean recurse)
}
else
jumpable = false;
PR_ExecuteProgram (svprogfuncs, pr_global_struct->PlayerPreThink);
#ifdef VM_Q1
if (svs.gametype == GT_Q1QVM)
Q1QVM_PlayerPreThink();
else
#endif
PR_ExecuteProgram (svprogfuncs, pr_global_struct->PlayerPreThink);
if (progstype != PROG_QW)
{
@ -4659,9 +4695,9 @@ void SV_RunCmd (usercmd_t *ucmd, qboolean recurse)
pmove.physents[0].model = sv.worldmodel;
pmove.cmd = *ucmd;
if (sv.worldmodel->fromgame == fg_quake2 || sv.worldmodel->fromgame == fg_quake3)
pmove.hullnum = ((int)sv_player->v->fteflags&FF_CROUCHING)?3:1;
pmove.hullnum = ((int)sv_player->xv->fteflags&FF_CROUCHING)?3:1;
else
pmove.hullnum = SV_HullNumForPlayer(sv_player->v->hull, sv_player->v->mins, sv_player->v->maxs);
pmove.hullnum = SV_HullNumForPlayer(sv_player->xv->hull, sv_player->v->mins, sv_player->v->maxs);
movevars.entgravity = host_client->entgravity/movevars.gravity;
movevars.maxspeed = host_client->maxspeed;
@ -4673,22 +4709,22 @@ void SV_RunCmd (usercmd_t *ucmd, qboolean recurse)
movevars.walljump = (pm_walljump.value);
movevars.slidyslopes = (pm_slidyslopes.value!=0);
if (sv_player->v->hasted)
movevars.maxspeed*=sv_player->v->hasted;
if (sv_player->xv->hasted)
movevars.maxspeed*=sv_player->xv->hasted;
for (i=0 ; i<3 ; i++)
{
pmove_mins[i] = pmove.origin[i] - 256;
pmove_maxs[i] = pmove.origin[i] + 256;
}
sv_player->v->fteflags = (int)sv_player->v->fteflags & ~FF_LADDER; //assume not touching ladder trigger
sv_player->xv->fteflags = (int)sv_player->xv->fteflags & ~FF_LADDER; //assume not touching ladder trigger
#if 1
AddLinksToPmove ( sv_areanodes );
#else
AddAllEntsToPmove ();
#endif
if ((int)sv_player->v->fteflags & FF_LADDER)
if ((int)sv_player->xv->fteflags & FF_LADDER)
pmove.onladder = true;
else
pmove.onladder = false;
@ -4799,7 +4835,12 @@ if (sv_player->v->health > 0 && before && !after )
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, ent);
pr_global_struct->other = EDICT_TO_PROG(svprogfuncs, sv_player);
pr_global_struct->time = sv.time;
PR_ExecuteProgram (svprogfuncs, ent->v->touch);
#ifdef VM_Q1
if (svs.gametype == GT_Q1QVM)
Q1QVM_Touch();
else
#endif
PR_ExecuteProgram (svprogfuncs, ent->v->touch);
playertouch[n/8] |= 1 << (n%8);
}
}
@ -4818,17 +4859,31 @@ void SV_PostRunCmd(void)
if (!svprogfuncs)
return;
if (!host_client->spectator) {
#ifdef VM_Q1
if (svs.gametype == GT_Q1QVM)
{
pr_global_struct->time = sv.time;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player);
Q1QVM_PostThink();
}
else
#endif
{
if (!host_client->spectator)
{
pr_global_struct->time = sv.time;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player);
PR_ExecuteProgram (svprogfuncs, pr_global_struct->PlayerPostThink);
PR_ExecuteProgram (svprogfuncs, pr_global_struct->PlayerPostThink);
SV_RunNewmis ();
} else if (SpectatorThink) {
pr_global_struct->time = sv.time;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player);
PR_ExecuteProgram (svprogfuncs, SpectatorThink);
SV_RunNewmis ();
}
else if (SpectatorThink)
{
pr_global_struct->time = sv.time;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player);
PR_ExecuteProgram (svprogfuncs, SpectatorThink);
}
}
}
@ -5036,12 +5091,12 @@ haveannothergo:
if (pr_allowbutton1.value) //many mods use button1 - it's just a wasted field to many mods. So only work it if the cvar allows.
sv_player->v->button1 = ((newcmd.buttons >> 2) & 1);
// DP_INPUTBUTTONS
sv_player->v->button3 = ((newcmd.buttons >> 2) & 1);
sv_player->v->button4 = ((newcmd.buttons >> 3) & 1);
sv_player->v->button5 = ((newcmd.buttons >> 4) & 1);
sv_player->v->button6 = ((newcmd.buttons >> 5) & 1);
sv_player->v->button7 = ((newcmd.buttons >> 6) & 1);
sv_player->v->button8 = ((newcmd.buttons >> 7) & 1);
sv_player->xv->button3 = ((newcmd.buttons >> 2) & 1);
sv_player->xv->button4 = ((newcmd.buttons >> 3) & 1);
sv_player->xv->button5 = ((newcmd.buttons >> 4) & 1);
sv_player->xv->button6 = ((newcmd.buttons >> 5) & 1);
sv_player->xv->button7 = ((newcmd.buttons >> 6) & 1);
sv_player->xv->button8 = ((newcmd.buttons >> 7) & 1);
cl->lastcmd = newcmd;
@ -5393,12 +5448,12 @@ void SVNQ_ReadClientMove (usercmd_t *move)
if (pr_allowbutton1.value) //many mods use button1 - it's just a wasted field to many mods. So only work it if the cvar allows.
host_client->edict->v->button1 = ((bits >> 2) & 1);
// DP_INPUTBUTTONS
host_client->edict->v->button3 = ((bits >> 2) & 1);
host_client->edict->v->button4 = ((bits >> 3) & 1);
host_client->edict->v->button5 = ((bits >> 4) & 1);
host_client->edict->v->button6 = ((bits >> 5) & 1);
host_client->edict->v->button7 = ((bits >> 6) & 1);
host_client->edict->v->button8 = ((bits >> 7) & 1);
host_client->edict->xv->button3 = ((bits >> 2) & 1);
host_client->edict->xv->button4 = ((bits >> 3) & 1);
host_client->edict->xv->button5 = ((bits >> 4) & 1);
host_client->edict->xv->button6 = ((bits >> 5) & 1);
host_client->edict->xv->button7 = ((bits >> 6) & 1);
host_client->edict->xv->button8 = ((bits >> 7) & 1);
if (host_client->last_sequence)
SV_RunEntity(host_client->edict);
@ -5724,9 +5779,9 @@ void SV_AirMove (void)
// else
// scale = val->_float;
maxspeed=sv_player->v->maxspeed;//FIXME: This isn't fully compatable code...
if (sv_player->v->hasted)
maxspeed*=sv_player->v->hasted;
maxspeed=sv_player->xv->maxspeed;//FIXME: This isn't fully compatable code...
if (sv_player->xv->hasted)
maxspeed*=sv_player->xv->hasted;
if (wishspeed > maxspeed*scale)
{
@ -5847,9 +5902,9 @@ void SV_ClientThink (void)
cmd = host_client->lastcmd;
sv_player = host_client->edict;
sv_player->v->movement[0] = cmd.forwardmove;
sv_player->v->movement[1] = cmd.sidemove;
sv_player->v->movement[2] = cmd.upmove;
sv_player->xv->movement[0] = cmd.forwardmove;
sv_player->xv->movement[1] = cmd.sidemove;
sv_player->xv->movement[2] = cmd.upmove;
if (SV_PlayerPhysicsQC)
{

View File

@ -985,25 +985,25 @@ long Q3G_SystemCallsEx(void *offset, unsigned int mask, int fn, const long *arg)
case G_FS_FOPEN_FILE: //fopen
if ((int)arg[1] + 4 >= mask || VM_POINTER(arg[1]) < offset)
break; //out of bounds.
VM_LONG(ret) = VMUI_fopen(VM_POINTER(arg[0]), VM_POINTER(arg[1]), VM_LONG(arg[2]), 0);
VM_LONG(ret) = VM_fopen(VM_POINTER(arg[0]), VM_POINTER(arg[1]), VM_LONG(arg[2]), 0);
break;
case G_FS_READ: //fread
if ((int)arg[0] + VM_LONG(arg[1]) >= mask || VM_POINTER(arg[0]) < offset)
break; //out of bounds.
VMUI_FRead(VM_POINTER(arg[0]), VM_LONG(arg[1]), VM_LONG(arg[2]), 0);
VM_FRead(VM_POINTER(arg[0]), VM_LONG(arg[1]), VM_LONG(arg[2]), 0);
break;
case G_FS_WRITE: //fwrite
break;
case G_FS_FCLOSE_FILE: //fclose
VMUI_fclose(VM_LONG(arg[0]), 0);
VM_fclose(VM_LONG(arg[0]), 0);
break;
case G_FS_GETFILELIST: //fs listing
if ((int)arg[2] + arg[3] >= mask || VM_POINTER(arg[2]) < offset)
break; //out of bounds.
return VMQ3_GetFileList(VM_POINTER(arg[0]), VM_POINTER(arg[1]), VM_POINTER(arg[2]), VM_LONG(arg[3]));
return VM_GetFileList(VM_POINTER(arg[0]), VM_POINTER(arg[1]), VM_POINTER(arg[2]), VM_LONG(arg[3]));
case G_LOCATE_GAME_DATA: // ( gentity_t *gEnts, int numGEntities, int sizeofGEntity_t, 15
// playerState_t *clients, int sizeofGameClient );
@ -1682,23 +1682,23 @@ void *BL_HunkMalloc(int size)
int BL_FOpenFile(const char *name, fileHandle_t *handle, fsMode_t mode)
{
return VMUI_fopen((char*)name, (int*)handle, mode, Z_TAG_BOTLIB);
return VM_fopen((char*)name, (int*)handle, mode, Z_TAG_BOTLIB);
}
int BL_FRead( void *buffer, int len, fileHandle_t f )
{
return VMUI_FRead(buffer, len, (int)f, Z_TAG_BOTLIB);
return VM_FRead(buffer, len, (int)f, Z_TAG_BOTLIB);
}
//int BL_FWrite( const void *buffer, int len, fileHandle_t f )
//{
// return VMUI_FWrite(buffer, len, f, Z_TAG_BOTLIB);
// return VM_FWrite(buffer, len, f, Z_TAG_BOTLIB);
//}
void BL_FCloseFile( fileHandle_t f )
{
VMUI_fclose((int)f, Z_TAG_BOTLIB);
VM_fclose((int)f, Z_TAG_BOTLIB);
}
//int BL_Seek( fileHandle_t f )
//{
// VMUI_fseek(f, Z_TAG_BOTLIB)
// VM_fseek(f, Z_TAG_BOTLIB)
//}
char *BL_BSPEntityData(void)
{

View File

@ -243,7 +243,7 @@ void SV_TouchLinks ( edict_t *ent, areanode_t *node )
|| ent->v->absmax[2] < touch->v->absmin[2] )
continue;
if (!((int)ent->v->dimension_solid & (int)touch->v->dimension_hit))
if (!((int)ent->xv->dimension_solid & (int)touch->xv->dimension_hit))
continue;
nodelinks[linkcount++] = touch;
@ -268,13 +268,18 @@ void SV_TouchLinks ( edict_t *ent, areanode_t *node )
|| ent->v->absmax[2] < touch->v->absmin[2] )
continue;
if (!((int)ent->v->dimension_solid & (int)touch->v->dimension_hit)) //didn't change did it?...
if (!((int)ent->xv->dimension_solid & (int)touch->xv->dimension_hit)) //didn't change did it?...
continue;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, touch);
pr_global_struct->other = EDICT_TO_PROG(svprogfuncs, ent);
pr_global_struct->time = sv.time;
PR_ExecuteProgram (svprogfuncs, touch->v->touch);
#ifdef VM_Q1
if (svs.gametype == GT_Q1QVM)
Q1QVM_Touch();
else
#endif
PR_ExecuteProgram (svprogfuncs, touch->v->touch);
if (ent->isfree)
break;
@ -1448,7 +1453,7 @@ void SV_ClipMoveToEntities ( moveclip_t *clip )
if (clip->passedict->v->solid == SOLID_SLIDEBOX && touch->v->solid == SOLID_CORPSE)
continue;
if (!((int)clip->passedict->v->dimension_hit & (int)touch->v->dimension_solid))
if (!((int)clip->passedict->xv->dimension_hit & (int)touch->xv->dimension_solid))
continue;
// if ( !(clip->contentmask & CONTENTS_DEADMONSTER)
@ -1621,7 +1626,7 @@ void SV_ClipToEverything (moveclip_t *clip)
if (clip->passedict->v->solid == SOLID_SLIDEBOX && touch->v->solid == SOLID_CORPSE)
continue;
if (!((int)clip->passedict->v->dimension_hit & (int)touch->v->dimension_solid))
if (!((int)clip->passedict->xv->dimension_hit & (int)touch->xv->dimension_solid))
continue;
}
@ -1699,7 +1704,7 @@ void SV_ClipToLinks ( areanode_t *node, moveclip_t *clip )
if (clip->passedict->v->solid == SOLID_SLIDEBOX && touch->v->solid == SOLID_CORPSE)
continue;
*/
if (!((int)clip->passedict->v->dimension_hit & (int)touch->v->dimension_solid))
if (!((int)clip->passedict->xv->dimension_hit & (int)touch->xv->dimension_solid))
continue;
}
@ -1762,7 +1767,7 @@ void SV_ClipToLinks ( areanode_t *node, moveclip_t *clip )
if (clip->passedict->v->solid == SOLID_SLIDEBOX && touch->v->solid == SOLID_CORPSE)
continue;
if (!((int)clip->passedict->v->dimension_hit & (int)touch->v->dimension_solid))
if (!((int)clip->passedict->xv->dimension_hit & (int)touch->xv->dimension_solid))
continue;
}
@ -1919,8 +1924,8 @@ trace_t SV_Move (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int type, e
memset ( &clip, 0, sizeof ( moveclip_t ) );
if (passedict && passedict->v->hull)
hullnum = passedict->v->hull;
if (passedict && passedict->xv->hull)
hullnum = passedict->xv->hull;
else if (sv_compatablehulls.value)
hullnum = 0;
else