cygwin, mingw should compile, plugins in dedicated servers, and stuff.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@1711 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2005-12-15 19:15:39 +00:00
parent 55fe54ae60
commit 13d0a98133
20 changed files with 705 additions and 426 deletions

View File

@ -4,10 +4,20 @@ CPUOPTIMIZATIONS=
BASE_DIR=.
#we only autodetect one cross target
#linux->win32
#if you are cross compiling, you'll need to use FTE_TARGET=mytaget
ifeq ($(FTE_TARGET),) #user didn't specify prefered target
ifneq ($(shell gcc -v 2>&1 | grep mingw),)
FTE_TARGET=win32
else
endif
ifneq ($(shell gcc -v 2>&1 | grep cygwin),)
FTE_TARGET=cygwin
endif
ifeq ($(FTE_TARGET),) #still not set
ifeq ($(shell uname),Linux)
FTE_TARGET=linux
endif
@ -58,7 +68,7 @@ ifeq ($(USEASM),true)
endif
BASELDFLAGS=-lm
#BASELDFLAGS=-lm -lz
GLXLDFLAGS=-L/usr/X11R6/lib -lX11 -lXext -lpng -ljpeg -lXxf86vm
GLXLDFLAGS=-L/usr/X11R6/lib -lX11 -lXext -lpng -ljpeg
GLSLDFLAGS=-L/usr/X11R6/lib -lMesaGL -lglide -lvga
XLDFLAGS=-L/usr/X11R6/lib -lX11 -lXext -lpng -ljpeg
SLDFLAGS=-lvga
@ -396,7 +406,7 @@ else
endif
GL_EXE_NAME=../fteqw.gl
GLCL_EXE_NAME=../fteqwcl.gl
GL_LDFLAGS= -L/usr/local/lib $(GLLDFLAGS) $(GLXLDFLAGS)
GL_LDFLAGS= -L/usr/local/lib $(GLLDFLAGS) $(GLXLDFLAGS) -lXxf86vm
GL_CFLAGS=$(GLCFLAGS) -I/usr/local/include
GLB_DIR=gl_bsd
GLCL_DIR=glcl_bsd
@ -420,7 +430,7 @@ else
endif
M_EXE_NAME=../fteqw
MCL_EXE_NAME=../fteqwcl
M_LDFLAGS=$(GLLDFLAGS) $(GLXLDFLAGS)
M_LDFLAGS=$(GLLDFLAGS) $(GLXLDFLAGS) -lXxf86vm
M_CFLAGS=$(SWCFLAGS) $(GLCFLAGS)
MB_DIR=m_bsd
MCL_DIR=mcl_bsd
@ -437,7 +447,7 @@ else
endif
GL_EXE_NAME=../fteqw.gl
GLCL_EXE_NAME=../fteqwcl.gl
GL_LDFLAGS=$(GLLDFLAGS) $(GLXLDFLAGS)
GL_LDFLAGS=$(GLLDFLAGS) $(GLXLDFLAGS) -lXxf86vm
GL_CFLAGS=$(GLCFLAGS)
GLB_DIR=gl_linux
GLCL_DIR=glcl_linux
@ -461,7 +471,7 @@ else
endif
M_EXE_NAME=../fteqw
MCL_EXE_NAME=../fteqwcl
M_LDFLAGS=$(GLLDFLAGS) $(GLXLDFLAGS)
M_LDFLAGS=$(GLLDFLAGS) $(GLXLDFLAGS) -lXxf86vm
M_CFLAGS=$(SWCFLAGS) $(GLCFLAGS)
MB_DIR=m_linux
MCL_DIR=mcl_linux
@ -472,6 +482,53 @@ endif
MINGL_DIR=mingl_linux
endif
ifeq ($(FTE_TARGET),cygwin)
SV_DIR=sv_cygwin
SV_LDFLAGS=-lz
ifeq ($(USEASM),true)
GLCL_OBJS=$(GL_OBJS) $(GLQUAKE_OBJS) gl_vidlinuxglx.o snd_linux.o cd_null.o sys_linux.o sys_dosa.o
else
GLCL_OBJS=$(GL_OBJS) $(GLQUAKE_OBJS) gl_vidlinuxglx.o snd_linux.o cd_null.o sys_linux.o
endif
GL_EXE_NAME=../fteqwglcyg.exe
GLCL_EXE_NAME=../fteqwclglcyg.exe
GL_LDFLAGS=$(GLLDFLAGS) $(GLXLDFLAGS)
GL_CFLAGS=$(GLCFLAGS)
GLB_DIR=gl_cygwin
GLCL_DIR=glcl_cygwin
ifeq ($(USEASM),true)
SWCL_OBJS=$(SOFTWARE_OBJS) vid_x.o snd_linux.o cd_null.o sys_linux.o sys_dosa.o
else
SWCL_OBJS=$(SOFTWARE_OBJS) vid_x.o snd_linux.o cd_null.o sys_linux.o
endif
SW_EXE_NAME=../fteqwswcyg.exe
SWCL_EXE_NAME=../fteqwclswcyg.exe
SW_LDFLAGS=$(SWLDFLAGS) $(XLDFLAGS)
SW_CFLAGS=$(SWCFLAGS)
SWB_DIR=sw_cygwin
SWCL_DIR=swcl_cygwin
ifeq ($(USEASM),true)
MCL_OBJS=$(GLQUAKE_OBJS) $(SOFTWARE_OBJS) gl_vidlinuxglx.o vid_x.o snd_linux.o cd_null.o sys_linux.o sys_dosa.o
else
MCL_OBJS=$(GLQUAKE_OBJS) $(SOFTWARE_OBJS) gl_vidlinuxglx.o vid_x.o snd_linux.o cd_null.o sys_linux.o
endif
M_EXE_NAME=../fteqwcyg.exe
MCL_EXE_NAME=../fteqwclcyg.exe
M_LDFLAGS=$(GLLDFLAGS) $(GLXLDFLAGS)
M_CFLAGS=$(SWCFLAGS) $(GLCFLAGS)
MB_DIR=m_cygwin
MCL_DIR=mcl_cygwin
MINGL_EXE_NAME=../fteqwminglcyg.exe
MINGL_DIR=mingl_cygwin
endif
SV_DIR?=sv_sdl
.default: help
@ -542,7 +599,7 @@ _clsv-dbg: debugdir
sv-tmp: reldir debugdir
$(MAKE) $(TYPE) OUT_DIR="$(OUT_DIR)" EXE_NAME="$(SV_EXE_NAME)" WCFLAGS="$(SV_CFLAGS)" LDFLAGS="$(SV_LDFLAGS)" OBJS="SV_OBJS"
$(MAKE) $(TYPE) OUT_DIR="$(OUT_DIR)" EXE_NAME="$(SV_EXE_NAME)" WCFLAGS="$(SV_CFLAGS)" LDFLAGS="$(SV_LDFLAGS) $(LDFLAGS)" OBJS="SV_OBJS"
sv-rel:
$(MAKE) sv-tmp TYPE=_out-rel OUT_DIR="$(RELEASE_DIR)/$(SV_DIR)"
sv-dbg:
@ -553,9 +610,9 @@ sv-dbg:
glcl-tmp:
$(MAKE) $(TYPE) OUT_DIR="$(OUT_DIR)" EXE_NAME="$(GLCL_EXE_NAME)" WCFLAGS="$(GL_CFLAGS)" LDFLAGS="$(GL_LDFLAGS)" SOBJS="$(GLCL_OBJS)"
$(MAKE) $(TYPE) OUT_DIR="$(OUT_DIR)" EXE_NAME="$(GLCL_EXE_NAME)" WCFLAGS="$(GL_CFLAGS)" LDFLAGS="$(GL_LDFLAGS) $(LDFLAGS)" SOBJS="$(GLCL_OBJS)"
gl-tmp:
$(MAKE) $(TYPE) OUT_DIR="$(OUT_DIR)" EXE_NAME="$(GL_EXE_NAME)" WCFLAGS="$(GL_CFLAGS)" LDFLAGS="$(GL_LDFLAGS)" SOBJS="$(GLCL_OBJS)"
$(MAKE) $(TYPE) OUT_DIR="$(OUT_DIR)" EXE_NAME="$(GL_EXE_NAME)" WCFLAGS="$(GL_CFLAGS)" LDFLAGS="$(GL_LDFLAGS) $(LDFLAGS)" SOBJS="$(GLCL_OBJS)"
glcl-rel:
$(MAKE) glcl-tmp TYPE=_cl-rel OUT_DIR="$(RELEASE_DIR)/$(GLCL_DIR)"
@ -568,15 +625,15 @@ gl-dbg:
mingl-tmp: reldir
$(MAKE) $(TYPE) OUT_DIR="$(OUT_DIR)" EXE_NAME="$(MINGL_EXE_NAME)" WCFLAGS="$(GL_CFLAGS) -DMINIMAL" LDFLAGS="$(GL_LDFLAGS)" SOBJS="$(GLCL_OBJS)"
$(MAKE) $(TYPE) OUT_DIR="$(OUT_DIR)" EXE_NAME="$(MINGL_EXE_NAME)" WCFLAGS="$(GL_CFLAGS) -DMINIMAL" LDFLAGS="$(GL_LDFLAGS) $(LDFLAGS)" SOBJS="$(GLCL_OBJS)"
mingl-rel:
$(MAKE) mingl-tmp TYPE=_cl-rel OUT_DIR="$(RELEASE_DIR)/$(MINGL_DIR)"
swcl-tmp:
$(MAKE) $(TYPE) OUT_DIR="$(OUT_DIR)" EXE_NAME="$(SWCL_EXE_NAME)" WCFLAGS="$(SW_CFLAGS)" LDFLAGS="$(SW_LDFLAGS)" SOBJS="$(SWCL_OBJS)"
$(MAKE) $(TYPE) OUT_DIR="$(OUT_DIR)" EXE_NAME="$(SWCL_EXE_NAME)" WCFLAGS="$(SW_CFLAGS)" LDFLAGS="$(SW_LDFLAGS) $(LDFLAGS)" SOBJS="$(SWCL_OBJS)"
sw-tmp:
$(MAKE) $(TYPE) OUT_DIR="$(OUT_DIR)" EXE_NAME="$(SW_EXE_NAME)" WCFLAGS="$(SW_CFLAGS)" LDFLAGS="$(SW_LDFLAGS)" SOBJS="$(SWCL_OBJS)"
$(MAKE) $(TYPE) OUT_DIR="$(OUT_DIR)" EXE_NAME="$(SW_EXE_NAME)" WCFLAGS="$(SW_CFLAGS)" LDFLAGS="$(SW_LDFLAGS) $(LDFLAGS)" SOBJS="$(SWCL_OBJS)"
swcl-rel:
$(MAKE) swcl-tmp TYPE=_cl-rel OUT_DIR="$(RELEASE_DIR)/$(SWCL_DIR)"
@ -588,9 +645,9 @@ sw-dbg:
$(MAKE) sw-tmp TYPE=_clsv-dbg OUT_DIR="$(DEBUG_DIR)/$(SWB_DIR)"
mcl-tmp:
$(MAKE) $(TYPE) OUT_DIR="$(OUT_DIR)" EXE_NAME="$(MCL_EXE_NAME)" WCFLAGS="$(M_CFLAGS)" LDFLAGS="$(M_LDFLAGS)" SOBJS="$(MCL_OBJS)"
$(MAKE) $(TYPE) OUT_DIR="$(OUT_DIR)" EXE_NAME="$(MCL_EXE_NAME)" WCFLAGS="$(M_CFLAGS)" LDFLAGS="$(M_LDFLAGS) $(LDFLAGS)" SOBJS="$(MCL_OBJS)"
m-tmp:
$(MAKE) $(TYPE) OUT_DIR="$(OUT_DIR)" EXE_NAME="$(M_EXE_NAME)" WCFLAGS="$(M_CFLAGS)" LDFLAGS="$(M_LDFLAGS)" SOBJS="$(MCL_OBJS)"
$(MAKE) $(TYPE) OUT_DIR="$(OUT_DIR)" EXE_NAME="$(M_EXE_NAME)" WCFLAGS="$(M_CFLAGS)" LDFLAGS="$(M_LDFLAGS) $(LDFLAGS)" SOBJS="$(MCL_OBJS)"
mcl-rel:
$(MAKE) mcl-tmp TYPE=_cl-rel OUT_DIR="$(RELEASE_DIR)/$(MCL_DIR)"
@ -636,6 +693,10 @@ help:
@-echo "gl"
@-echo "sw"
install:
-cp debug/*.* /opt/quake/
-cp release/*.* /opt/quake/
clean:
-rm -f -r $(RELEASE_DIR)
-rm -f -r $(DEBUG_DIR)

View File

@ -21,6 +21,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "quakedef.h"
void CL_FinishTimeDemo (void);
#define realtime demtime
float demtime;
int cls_lastto;
int cls_lasttype;
@ -184,6 +186,8 @@ qboolean CL_GetDemoMessage (void)
usercmd_t *pcmd;
q1usercmd_t q1cmd;
realtime += host_frametime *0.1;
#ifdef NQPROT
if (cls.demoplayback == DPB_NETQUAKE || cls.demoplayback == DPB_QUAKE2)
{ //read the nq demo

View File

@ -2521,6 +2521,7 @@ void CL_Init (void)
Cvar_Register (&cfg_save_name, cl_controlgroup);
cl_demospeed.name2 = "demo_setspeed";
Cvar_Register (&cl_demospeed, "Demo playback");
Cvar_Register (&cl_warncmd, "Warnings");
Cvar_Register (&cl_upspeed, cl_inputgroup);
@ -2916,7 +2917,7 @@ void Host_Frame (double time)
*/
Mod_Think(); //think even on idle (which means small walls and a fast cpu can get more surfaces done.
if (cl_maxfps.value>0 && cl_netfps.value>0)
if (cl_maxfps.value>0 && cl_netfps.value>0 || cls.demoplayback)
{ //limit the fps freely, and expect the netfps to cope.
if ((realtime - oldrealtime) < 1/cl_maxfps.value)
return;

View File

@ -847,7 +847,9 @@ void M_Init_Internal (void)
Cmd_AddRemCommand ("menu_options", M_Menu_Options_f);
Cmd_AddRemCommand ("menu_video", M_Menu_Video_f);
Cmd_AddRemCommand ("menu_audio", M_Menu_Audio_f);
#ifndef __CYGWIN__
Cmd_AddRemCommand ("menu_speakers", M_Menu_Audio_Speakers_f);
#endif
Cmd_AddRemCommand ("menu_fps", M_Menu_FPS_f);
Cmd_AddRemCommand ("menu_particles", M_Menu_Particles_f);
Cmd_AddRemCommand ("menu_particlesets", M_Menu_ParticleSets_f);

View File

@ -112,8 +112,10 @@ void Master_SetupSockets(void)
int i;
for (i = 0; i < POLLUDPSOCKETS; i++)
pollsocketsUDP[i] = INVALID_SOCKET;
#ifdef USEIPX
for (i = 0; i < POLLIPXSOCKETS; i++)
pollsocketsIPX[i] = INVALID_SOCKET;
#endif
}
void Master_HideServer(serverinfo_t *server)

View File

@ -19,6 +19,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// quakedef.h -- primary header for client
#ifndef __QUAKEDEF_H__
#define __QUAKEDEF_H__
#include "bothdefs.h" //first thing included by ALL files.
#if _MSC_VER
@ -251,3 +254,4 @@ extern qboolean isDedicated;
}
#endif
#endif //__QUAKEDEF_H__

View File

@ -519,7 +519,7 @@ int DSOUND_InitCard (soundcardinfo_t *sc, int cardnum)
char *buffer;
if (COM_CheckParm("-wavonly"))
return;
return SND_NOMORE;
sc->sn.numchannels = 2;

View File

@ -25,7 +25,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define MACOSX
#endif
#if defined(__MINGW32_VERSION) || defined(__MINGW__)
#if defined(__MINGW32_VERSION) || defined(__MINGW__) || defined(__MINGW32__)
#define MINGW
#endif
#if !defined(MINGW) && defined(__GNUC__) && defined(_WIN32)
@ -187,7 +187,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#undef IRCCLIENT
#undef TEXTEDITOR
#undef RUNTIMELIGHTING
#undef PLUGINS //we don't have any server side stuff.
// #undef PLUGINS //we don't have any server side stuff.
#undef Q3SHADERS
#undef TERRAIN
#endif

View File

@ -269,6 +269,7 @@ extern char com_gamedir[MAX_OSPATH];
extern char *com_basedir;
void COM_WriteFile (char *filename, void *data, int len);
FILE *COM_WriteFileOpen (char *filename);
typedef struct {
struct searchpath_s *search;

View File

@ -1052,7 +1052,7 @@ int TCP_OpenStream (netadr_t remoteaddr)
struct sockaddr_qstorage qs;
temp = NetadrToSockadr(&remoteaddr, &qs);
if ((newsocket = socket (((struct sockaddr_in*)&qs)->sin_family, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)
return INVALID_SOCKET;

View File

@ -5,6 +5,95 @@
#include "quakedef.h"
#ifdef PLUGINS
//#define GNUTLS
#ifdef GNUTLS
#if defined(_WIN32) && !defined(MINGW)
//lets rip stuff out of the header and supply a seperate dll.
//gnutls is huge.
//also this helps get around the whole msvc/mingw thing.
struct DSTRUCT;
typedef struct DSTRUCT* gnutls_certificate_credentials;
typedef gnutls_certificate_credentials gnutls_certificate_client_credentials;
typedef struct DSTRUCT* gnutls_anon_client_credentials;
struct gnutls_session_int;
typedef struct gnutls_session_int* gnutls_session;
typedef void * gnutls_transport_ptr;
typedef enum gnutls_kx_algorithm { GNUTLS_KX_RSA=1, GNUTLS_KX_DHE_DSS,
GNUTLS_KX_DHE_RSA, GNUTLS_KX_ANON_DH, GNUTLS_KX_SRP,
GNUTLS_KX_RSA_EXPORT, GNUTLS_KX_SRP_RSA, GNUTLS_KX_SRP_DSS
} gnutls_kx_algorithm;
typedef enum gnutls_certificate_type { GNUTLS_CRT_X509=1, GNUTLS_CRT_OPENPGP
} gnutls_certificate_type;
typedef enum gnutls_connection_end { GNUTLS_SERVER=1, GNUTLS_CLIENT } gnutls_connection_end;
typedef enum gnutls_credentials_type { GNUTLS_CRD_CERTIFICATE=1, GNUTLS_CRD_ANON, GNUTLS_CRD_SRP } gnutls_credentials_type;
typedef enum gnutls_close_request { GNUTLS_SHUT_RDWR=0, GNUTLS_SHUT_WR=1 } gnutls_close_request;
#define GNUTLS_E_AGAIN -28
#define GNUTLS_E_INTERRUPTED -52
int (VARGS *gnutls_bye)( gnutls_session session, gnutls_close_request how);
void (VARGS *gnutls_perror)( int error);
int (VARGS *gnutls_handshake)( gnutls_session session);
void (VARGS *gnutls_transport_set_ptr)(gnutls_session session, gnutls_transport_ptr ptr);
int (VARGS *gnutls_certificate_type_set_priority)( gnutls_session session, const int*);
int (VARGS *gnutls_credentials_set)( gnutls_session, gnutls_credentials_type type, void* cred);
int (VARGS *gnutls_kx_set_priority)( gnutls_session session, const int*);
int (VARGS *gnutls_init)(gnutls_session * session, gnutls_connection_end con_end);
int (VARGS *gnutls_set_default_priority)(gnutls_session session);
int (VARGS *gnutls_certificate_allocate_credentials)( gnutls_certificate_credentials *sc);
int (VARGS *gnutls_anon_allocate_client_credentials)( gnutls_anon_client_credentials *sc);
int (VARGS *gnutls_global_init)(void);
int (VARGS *gnutls_record_send)( gnutls_session session, const void *data, size_t sizeofdata);
int (VARGS *gnutls_record_recv)( gnutls_session session, void *data, size_t sizeofdata);
qboolean Init_GNUTLS(void)
{
HMODULE hmod;
hmod = LoadLibrary("gnutls.dll");
if (!hmod)
return false;
gnutls_bye = (void*)GetProcAddress(hmod, "gnutls_bye");
gnutls_perror = (void*)GetProcAddress(hmod, "gnutls_perror");
gnutls_handshake = (void*)GetProcAddress(hmod, "gnutls_handshake");
gnutls_transport_set_ptr = (void*)GetProcAddress(hmod, "gnutls_transport_set_ptr");
gnutls_certificate_type_set_priority = (void*)GetProcAddress(hmod, "gnutls_certificate_type_set_priority");
gnutls_credentials_set = (void*)GetProcAddress(hmod, "gnutls_credentials_set");
gnutls_kx_set_priority = (void*)GetProcAddress(hmod, "gnutls_kx_set_priority");
gnutls_init = (void*)GetProcAddress(hmod, "gnutls_init");
gnutls_set_default_priority = (void*)GetProcAddress(hmod, "gnutls_set_default_priority");
gnutls_certificate_allocate_credentials = (void*)GetProcAddress(hmod, "gnutls_certificate_allocate_credentials");
gnutls_anon_allocate_client_credentials = (void*)GetProcAddress(hmod, "gnutls_anon_allocate_client_credentials");
gnutls_global_init = (void*)GetProcAddress(hmod, "gnutls_global_init");
gnutls_record_send = (void*)GetProcAddress(hmod, "gnutls_record_send");
gnutls_record_recv = (void*)GetProcAddress(hmod, "gnutls_record_recv");
if (!gnutls_bye || !gnutls_perror || !gnutls_handshake || !gnutls_transport_set_ptr
|| !gnutls_certificate_type_set_priority || !gnutls_credentials_set
|| !gnutls_kx_set_priority || !gnutls_init || !gnutls_set_default_priority
|| !gnutls_certificate_allocate_credentials || !gnutls_anon_allocate_client_credentials
|| !gnutls_global_init || !gnutls_record_send || !gnutls_record_recv)
{
Con_Printf("gnutls.dll doesn't contain all required exports\n");
FreeLibrary(hmod);
return false;
}
return true;
}
#else
#include <gnutls/gnutls.h>
qboolean Init_GNUTLS(void) {return true;}
#endif
#endif
cvar_t plug_sbar = {"plug_sbar", "1"};
cvar_t plug_loaddefault = {"plug_loaddefault", "1"};
@ -18,8 +107,10 @@ cvar_t plug_loaddefault = {"plug_loaddefault", "1"};
typedef struct plugin_s {
char *name;
vm_t *vm;
int tick;
int executestring;
#ifndef SERVERONLY
int conexecutecommand;
int menufunction;
int sbarlevel[3]; //0 - main sbar, 1 - supplementry sbar sections (make sure these can be switched off), 2 - overlays (scoreboard). menus kill all.
@ -27,7 +118,7 @@ typedef struct plugin_s {
//protocol-in-a-plugin
int connectionlessclientpacket;
#endif
int messagefunction;
struct plugin_s *next;
@ -37,6 +128,16 @@ void Plug_SubConsoleCommand(console_t *con, char *line);
plugin_t *currentplug;
#ifndef SERVERONLY
#include "cl_plugin.inc"
#else
void Plug_Client_Init(void){}
void Plug_Client_Close(plugin_t *plug) {}
#endif
//custom plugin builtins.
typedef int (VARGS *Plug_Builtin_t)(void *offset, unsigned int mask, const long *arg);
void Plug_RegisterBuiltin(char *name, Plug_Builtin_t bi, int flags);
@ -52,8 +153,6 @@ void Plug_Shutdown(void);
static plugin_t *plugs;
static plugin_t *menuplug; //plugin that has the current menu
static plugin_t *protocolclientplugin;
typedef struct {
@ -68,7 +167,7 @@ void Plug_RegisterBuiltin(char *name, Plug_Builtin_t bi, int flags)
{
//randomize the order a little.
int newnum;
newnum = (rand()%128)+1;
while(newnum < numplugbuiltins && plugbuiltins[newnum].func)
newnum+=128;
@ -80,7 +179,7 @@ void Plug_RegisterBuiltin(char *name, Plug_Builtin_t bi, int flags)
}
//got an empty number.
Con_Printf("%s: %i\n", name, newnum);
Con_DPrintf("%s: %i\n", name, newnum);
plugbuiltins[newnum].name = name;
plugbuiltins[newnum].func = bi;
plugbuiltins[newnum].flags = flags;
@ -91,7 +190,7 @@ static void Plug_RegisterBuiltinIndex(char *name, Plug_Builtin_t bi, int flags,
{
//randomize the order a little.
int newnum;
newnum = rand()%128;
while(newnum+1 < numplugbuiltins && plugbuiltins[newnum+1].func)
newnum+=128;
@ -189,7 +288,7 @@ plugin_t *Plug_Load(char *file)
newplug = Z_Malloc(sizeof(plugin_t)+strlen(file)+1);
newplug->name = (char*)(newplug+1);
strcpy(newplug->name, file);
newplug->vm = VM_Create(NULL, file, Plug_SystemCalls, Plug_SystemCallsEx);
currentplug = newplug;
if (newplug->vm)
@ -206,8 +305,10 @@ plugin_t *Plug_Load(char *file)
return NULL;
}
#ifndef SERVERONLY
if (newplug->reschange)
VM_Call(newplug->vm, newplug->reschange, vid.width, vid.height);
#endif
}
else
{
@ -224,14 +325,19 @@ int Plug_Emumerated (char *name, int size, void *param)
char vmname[MAX_QPATH];
strcpy(vmname, name);
vmname[strlen(vmname) - strlen(param)] = '\0';
Plug_Load(vmname);
if (!Plug_Load(vmname))
Con_Printf("Couldn't load plugin %s\n", vmname);
return true;
}
int VARGS Plug_Con_Print(void *offset, unsigned int mask, const long *arg)
{
#ifndef SERVERONLY
Con_Print((char*)VM_POINTER(arg[0]));
#else
Con_Printf("%s", (char*)VM_POINTER(arg[0]));
#endif
return 0;
}
int VARGS Plug_Sys_Error(void *offset, unsigned int mask, const long *arg)
@ -250,6 +356,7 @@ int VARGS Plug_ExportToEngine(void *offset, unsigned int mask, const long *arg)
currentplug->tick = arg[1];
else if (!strcmp(name, "ExecuteCommand"))
currentplug->executestring = arg[1];
#ifndef SERVERONLY
else if (!strcmp(name, "ConExecuteCommand"))
currentplug->conexecutecommand = arg[1];
else if (!strcmp(name, "MenuEvent"))
@ -266,11 +373,39 @@ int VARGS Plug_ExportToEngine(void *offset, unsigned int mask, const long *arg)
currentplug->connectionlessclientpacket = arg[1];
else if (!strcmp(name, "MessageEvent"))
currentplug->messagefunction = arg[1];
#endif
else
return 0;
return 1;
}
//retrieve a plugin's name
int VARGS Plug_GetPluginName(void *offset, unsigned int mask, const long *arg)
{
int plugnum = VM_LONG(arg[0]);
plugin_t *plug;
//int plugnum (0 for current), char *buffer, int bufferlen
if (VM_OOB(arg[1], arg[2]))
return false;
if (plugnum <= 0)
{
Q_strncpyz(VM_POINTER(arg[1]), currentplug->name, VM_LONG(arg[2]));
return true;
}
for (plug = plugs; plug; plug = plug->next)
{
if (--plugnum == 0)
{
Q_strncpyz(VM_POINTER(arg[1]), plug->name, VM_LONG(arg[2]));
return true;
}
}
return false;
}
typedef void (*funcptr_t) ();
int VARGS Plug_ExportNative(void *offset, unsigned int mask, const long *arg)
{
@ -280,9 +415,11 @@ int VARGS Plug_ExportNative(void *offset, unsigned int mask, const long *arg)
func = *(funcptr_t*)arg;
#ifndef SERVERONLY
if (!strcmp(name, "S_LoadSound"))
S_RegisterSoundInputPlugin(func);
else
#endif
return 0;
return 1;
}
@ -380,277 +517,6 @@ int VARGS Plug_Cmd_Argc(void *offset, unsigned int mask, const long *arg)
return Cmd_Argc();
}
int VARGS Plug_Menu_Control(void *offset, unsigned int mask, const long *arg)
{
switch(VM_LONG(arg[0]))
{
case 0: //take away all menus
case 1:
if (menuplug)
{
plugin_t *oldplug = currentplug;
currentplug = menuplug;
Plug_Menu_Event(3, 0);
menuplug = NULL;
currentplug = oldplug;
key_dest = key_game;
}
if (VM_LONG(arg[0]) != 1)
return 1;
//give us menu control
menuplug = currentplug;
key_dest = key_menu;
m_state = m_plugin;
return 1;
case 2: //weather it's us or not.
return currentplug == menuplug && m_state == m_plugin;
case 3: //weather a menu is active
return key_dest == key_menu;
default:
return 0;
}
}
typedef struct {
//Make SURE that the engine has resolved all cvar pointers into globals before this happens.
plugin_t *plugin;
char name[64];
qboolean picfromwad;
mpic_t *pic;
} pluginimagearray_t;
int pluginimagearraylen;
pluginimagearray_t *pluginimagearray;
int VARGS Plug_Draw_LoadImage(void *offset, unsigned int mask, const long *arg)
{
char *name = VM_POINTER(arg[0]);
qboolean fromwad = arg[1];
int i;
mpic_t *pic;
for (i = 0; i < pluginimagearraylen; i++)
{
if (!pluginimagearray[i].plugin)
break;
if (pluginimagearray[i].plugin == currentplug)
{
if (!strcmp(name, pluginimagearray[i].name))
break;
}
}
if (i == pluginimagearraylen)
{
pluginimagearraylen++;
pluginimagearray = BZ_Realloc(pluginimagearray, pluginimagearraylen*sizeof(pluginimagearray_t));
}
if (pluginimagearray[i].pic)
return i; //already loaded.
if (qrenderer)
{
if (fromwad)
pic = Draw_SafePicFromWad(name);
else
{
#ifdef RGLQUAKE //GL saves images persistantly (so don't bother with cachepic stuff)
if (qrenderer == QR_OPENGL)
pic = Draw_SafeCachePic(name);
else
#endif
pic = NULL;
}
}
else
pic = NULL;
Q_strncpyz(pluginimagearray[i].name, name, sizeof(pluginimagearray[i].name));
pluginimagearray[i].picfromwad = fromwad;
pluginimagearray[i].pic = pic;
pluginimagearray[i].plugin = currentplug;
return i;
}
void Plug_DrawReloadImages(void)
{
int i;
for (i = 0; i < pluginimagearraylen; i++)
{
if (!pluginimagearray[i].plugin)
{
pluginimagearray[i].pic = NULL;
continue;
}
if (pluginimagearray[i].picfromwad)
pluginimagearray[i].pic = Draw_SafePicFromWad(pluginimagearray[i].name);
#ifdef RGLQUAKE
else if (qrenderer == QR_OPENGL)
pluginimagearray[i].pic = Draw_SafeCachePic(pluginimagearray[i].name);
#endif
else
pluginimagearray[i].pic = NULL;
}
}
void Plug_FreePlugImages(plugin_t *plug)
{
int i;
for (i = 0; i < pluginimagearraylen; i++)
{
if (pluginimagearray[i].plugin == plug)
{
pluginimagearray[i].plugin = 0;
pluginimagearray[i].pic = NULL;
pluginimagearray[i].name[0] = '\0';
}
}
}
//int Draw_Image (float x, float y, float w, float h, float s1, float t1, float s2, float t2, qhandle_t image)
int VARGS Plug_Draw_Image(void *offset, unsigned int mask, const long *arg)
{
mpic_t *pic;
int i;
if (!qrenderer)
return 0;
if (!Draw_Image)
return 0;
i = VM_LONG(arg[8]);
if (i < 0 || i >= pluginimagearraylen)
return -1; // you fool
if (pluginimagearray[i].plugin != currentplug)
return -1;
if (pluginimagearray[i].pic)
pic = pluginimagearray[i].pic;
else if (pluginimagearray[i].picfromwad)
return 0; //wasn't loaded.
else
pic = Draw_CachePic(pluginimagearray[i].name);
Draw_Image(VM_FLOAT(arg[0]), VM_FLOAT(arg[1]), VM_FLOAT(arg[2]), VM_FLOAT(arg[3]), VM_FLOAT(arg[4]), VM_FLOAT(arg[5]), VM_FLOAT(arg[6]), VM_FLOAT(arg[7]), pic);
return 1;
}
//x1,y1,x2,y2
int VARGS Plug_Draw_Line(void *offset, unsigned int mask, const long *arg)
{
switch(qrenderer) //FIXME: I don't want qrenderer seen outside the refresh
{
#ifdef RGLQUAKE
case QR_OPENGL:
qglDisable(GL_TEXTURE_2D);
qglBegin(GL_LINES);
qglVertex2f(VM_FLOAT(arg[0]), VM_FLOAT(arg[1]));
qglVertex2f(VM_FLOAT(arg[2]), VM_FLOAT(arg[3]));
qglEnd();
qglEnable(GL_TEXTURE_2D);
break;
#endif
}
return 1;
}
int VARGS Plug_Draw_Character(void *offset, unsigned int mask, const long *arg)
{
Draw_Character(arg[0], arg[1], (unsigned int)arg[2]);
return 0;
}
int VARGS Plug_Draw_Fill(void *offset, unsigned int mask, const long *arg)
{
float x, y, width, height;
x = VM_FLOAT(arg[0]);
y = VM_FLOAT(arg[1]);
width = VM_FLOAT(arg[2]);
height = VM_FLOAT(arg[3]);
switch(qrenderer) //FIXME: I don't want qrenderer seen outside the refresh
{
#ifdef RGLQUAKE
case QR_OPENGL:
qglDisable(GL_TEXTURE_2D);
qglBegin(GL_QUADS);
qglVertex2f(x, y);
qglVertex2f(x+width, y);
qglVertex2f(x+width, y+height);
qglVertex2f(x, y+height);
qglEnd();
qglEnable(GL_TEXTURE_2D);
return 1;
#endif
default:
break;
}
return 0;
}
int VARGS Plug_Draw_ColourP(void *offset, unsigned int mask, const long *arg)
{
qbyte *pal = host_basepal + VM_LONG(arg[0])*3;
if (arg[0]<0 || arg[0]>255)
return false;
if (Draw_ImageColours)
{
Draw_ImageColours(pal[0]/255.0f, pal[1]/255.0f, pal[2]/255.0f, 1);
return 1;
}
return 0;
}
int VARGS Plug_Draw_Colour3f(void *offset, unsigned int mask, const long *arg)
{
if (Draw_ImageColours)
{
Draw_ImageColours(VM_FLOAT(arg[0]), VM_FLOAT(arg[1]), VM_FLOAT(arg[2]), 1);
return 1;
}
return 0;
}
int VARGS Plug_Draw_Colour4f(void *offset, unsigned int mask, const long *arg)
{
if (Draw_ImageColours)
{
Draw_ImageColours(VM_FLOAT(arg[0]), VM_FLOAT(arg[1]), VM_FLOAT(arg[2]), VM_FLOAT(arg[3]));
return 1;
}
return 0;
}
int VARGS Plug_Media_ShowFrameRGBA_32(void *offset, unsigned int mask, const long *arg)
{
void *src = VM_POINTER(arg[0]);
int srcwidth = VM_LONG(arg[1]);
int srcheight = VM_LONG(arg[2]);
int x = VM_LONG(arg[3]);
int y = VM_LONG(arg[4]);
int width = VM_LONG(arg[5]);
int height = VM_LONG(arg[6]);
Media_ShowFrameRGBA_32(src, srcwidth, srcheight);
return 0;
}
int VARGS Plug_LocalSound(void *offset, unsigned int mask, const long *arg)
{
S_LocalSound(VM_POINTER(arg[0]));
return 0;
}
int VARGS Plug_SCR_CenterPrint(void *offset, unsigned int mask, const long *arg)
{
SCR_CenterPrint(0, VM_POINTER(arg[0]));
return 0;
}
int VARGS Plug_Key_GetKeyCode(void *offset, unsigned int mask, const long *arg)
{
int modifier;
return Key_StringToKeynum(VM_POINTER(arg[0]), &modifier);
}
//void Cvar_SetString (char *name, char *value);
int VARGS Plug_Cvar_SetString(void *offset, unsigned int mask, const long *arg)
{
@ -800,68 +666,10 @@ void VARGS Plug_FreeConCommands(plugin_t *plug)
}
}
int VARGS Plug_CL_GetStats(void *offset, unsigned int mask, const long *arg)
{
int i;
int pnum = VM_LONG(arg[0]);
unsigned int *stats = VM_POINTER(arg[1]);
int pluginstats = VM_LONG(arg[2]);
int max;
if (VM_OOB(arg[1], arg[2]*4))
return 0;
max = pluginstats;
if (max > MAX_CL_STATS)
max = MAX_CL_STATS;
for (i = 0; i < max; i++)
{ //fill stats with the right player's stats
stats[i] = cl.stats[pnum][i];
}
for (; i < pluginstats; i++) //plugin has too many stats (wow)
stats[i] = 0; //fill the rest.
return max;
}
int VARGS Plug_Con_SubPrint(void *offset, unsigned int mask, const long *arg)
{
char *name = VM_POINTER(arg[0]);
char *text = VM_POINTER(arg[1]);
console_t *con;
con = Con_FindConsole(name);
if (!con)
{
con = Con_Create(name);
Con_SetVisible(con);
if (currentplug->conexecutecommand)
{
con->userdata = currentplug;
con->linebuffered = Plug_SubConsoleCommand;
}
}
Con_PrintCon(con, text);
return 1;
}
int VARGS Plug_Con_RenameSub(void *offset, unsigned int mask, const long *arg)
{
char *name = VM_POINTER(arg[0]);
console_t *con;
con = Con_FindConsole(name);
if (!con)
return 0;
Q_strncpyz(con->name, name, sizeof(con->name));
return 1;
}
typedef enum{
STREAM_NONE,
STREAM_SOCKET,
STREAM_TLS,
STREAM_OSFILE,
STREAM_FILE
} plugstream_e;
@ -877,6 +685,9 @@ typedef struct {
int curlen;
int curpos;
} file;
#ifdef GNUTLS
gnutls_session session;
#endif
} pluginstream_t;
pluginstream_t *pluginstreamarray;
int pluginstreamarraylen;
@ -913,7 +724,7 @@ int VARGS Plug_Net_TCPListen(void *offset, unsigned int mask, const long *arg)
int sock;
struct sockaddr_qstorage address;
int _true = 1;
char *localip = VM_POINTER(arg[0]);
unsigned short localport = VM_LONG(arg[1]);
int maxcount = VM_LONG(arg[2]);
@ -1047,7 +858,7 @@ int VARGS Plug_Net_TCPConnect(void *offset, unsigned int mask, const long *arg)
closesocket(sock);
return -2;
}
if (ioctlsocket (sock, FIONBIO, &_true) == -1) //now make it non blocking.
{
return -1;
@ -1058,6 +869,104 @@ int VARGS Plug_Net_TCPConnect(void *offset, unsigned int mask, const long *arg)
return handle;
}
#ifdef GNUTLS
int VARGS Plug_Net_SetTLSClient(void *offset, unsigned int mask, const long *arg)
{
static gnutls_anon_client_credentials anoncred;
static gnutls_certificate_credentials xcred;
int ret;
long _false = false;
long _true = true;
/* Need to enable anonymous KX specifically. */
const int kx_prio[] = {GNUTLS_KX_ANON_DH, 0};
const int cert_type_priority[3] = {GNUTLS_CRT_X509, GNUTLS_CRT_OPENPGP, 0};
pluginstream_t *stream;
int handle = VM_LONG(arg[0]);
qboolean anon = false;
if (handle < 0 || handle >= pluginstreamarraylen || pluginstreamarray[handle].plugin != currentplug)
{
Con_Printf("Plug_Net_SetTLSClient: socket does not belong to you (or is invalid)\n");
return -2;
}
stream = &pluginstreamarray[handle];
if (stream->type != STREAM_SOCKET)
{ //not a socket - invalid
Con_Printf("Plug_Net_SetTLSClient: Not a socket handle\n");
return -2;
}
{
static qboolean needinit = true;
if (needinit)
{
gnutls_global_init ();
gnutls_anon_allocate_client_credentials (&anoncred);
gnutls_certificate_allocate_credentials (&xcred);
// gnutls_certificate_set_x509_trust_file (xcred, "ca.pem", GNUTLS_X509_FMT_PEM);
needinit = false;
}
}
stream->type = STREAM_TLS;
// Initialize TLS session
gnutls_init (&stream->session, GNUTLS_CLIENT);
// Use default priorities
gnutls_set_default_priority (stream->session);
if (anon)
{
gnutls_kx_set_priority (stream->session, kx_prio);
gnutls_credentials_set (stream->session, GNUTLS_CRD_ANON, anoncred);
}
else
{
gnutls_certificate_type_set_priority (stream->session, cert_type_priority);
gnutls_credentials_set (stream->session, GNUTLS_CRD_CERTIFICATE, xcred);
}
// connect to the peer
gnutls_transport_set_ptr (stream->session, (gnutls_transport_ptr) stream->socket);
// Perform the TLS handshake
ioctlsocket (stream->socket, FIONBIO, &_false);
ret = GNUTLS_E_AGAIN;
while ((ret == GNUTLS_E_AGAIN) || (ret == GNUTLS_E_INTERRUPTED))
{
ret = gnutls_handshake (stream->session);
}
if (ret < 0)
{
Con_Printf ("^1*** TLS handshake failed\n");
gnutls_perror (ret);
stream->type = STREAM_SOCKET; //go back to regular socket
gnutls_bye (pluginstreamarray[handle].session, GNUTLS_SHUT_RDWR);
return -2;
}
ioctlsocket (stream->socket, FIONBIO, &_true);
return 0;
}
#endif
int VARGS Plug_FS_Open(void *offset, unsigned int mask, const long *arg)
{
//modes:
@ -1075,7 +984,7 @@ int VARGS Plug_FS_Open(void *offset, unsigned int mask, const long *arg)
if (VM_OOB(arg[1], sizeof(int)))
return -2;
ret = VM_POINTER(arg[1]);
if (arg[2] == 1)
{
data = COM_LoadMallocFile(VM_POINTER(arg[0]));
@ -1090,7 +999,7 @@ int VARGS Plug_FS_Open(void *offset, unsigned int mask, const long *arg)
*ret = handle;
return com_filesize;
return com_filesize;
}
else if (arg[2] == 2)
{
@ -1107,7 +1016,7 @@ int VARGS Plug_FS_Open(void *offset, unsigned int mask, const long *arg)
*ret = handle;
return com_filesize;
return com_filesize;
}
else
return -2;
@ -1193,6 +1102,23 @@ int VARGS Plug_Net_Recv(void *offset, unsigned int mask, const long *arg)
else if (read == 0)
return -2; //closed by remote connection.
return read;
#ifdef GNUTLS
case STREAM_TLS:
read = gnutls_record_recv(pluginstreamarray[handle].session, dest, destlen);
if (read < 0)
{
if (read == GNUTLS_E_AGAIN || read == -9)
return -1;
else
{
Con_Printf("TLS Read Error %i (bufsize %i)\n", read, destlen);
return -2;
}
}
else if (read == 0)
return -2; //closed by remote connection.
return read;
#endif
case STREAM_FILE:
if (pluginstreamarray[handle].file.curlen - pluginstreamarray[handle].file.curpos < destlen)
{
@ -1229,11 +1155,28 @@ int VARGS Plug_Net_Send(void *offset, unsigned int mask, const long *arg)
else if (written == 0)
return -2; //closed by remote connection.
return written;
#ifdef GNUTLS
case STREAM_TLS:
written = gnutls_record_send(pluginstreamarray[handle].session, src, srclen);
if (written < 0)
{
if (written == GNUTLS_E_AGAIN || written == GNUTLS_E_INTERRUPTED)
return -1;
else
{
Con_Printf("TLS Send Error %i (%i bytes)\n", written, srclen);
return -2;
}
}
else if (written == 0)
return -2; //closed by remote connection.
return written;
#endif
case STREAM_FILE:
if (pluginstreamarray[handle].file.buflen < pluginstreamarray[handle].file.curpos + srclen)
{
pluginstreamarray[handle].file.buflen = pluginstreamarray[handle].file.curpos + srclen+8192;
pluginstreamarray[handle].file.buffer =
pluginstreamarray[handle].file.buffer =
BZ_Realloc(pluginstreamarray[handle].file.buffer, pluginstreamarray[handle].file.buflen);
}
memcpy(pluginstreamarray[handle].file.buffer + pluginstreamarray[handle].file.curpos, src, srclen);
@ -1285,14 +1228,18 @@ int VARGS Plug_Net_SendTo(void *offset, unsigned int mask, const long *arg)
return -2;
}
}
int VARGS Plug_Net_Close(void *offset, unsigned int mask, const long *arg)
{
int handle = VM_LONG(arg[0]);
if (handle < 0 || handle >= pluginstreamarraylen || pluginstreamarray[handle].plugin != currentplug)
return -2;
void Plug_Net_Close_Internal(int handle)
{
switch(pluginstreamarray[handle].type)
{
#ifdef GNUTLS
case STREAM_TLS:
gnutls_bye (pluginstreamarray[handle].session, GNUTLS_SHUT_RDWR);
pluginstreamarray[handle].type = STREAM_SOCKET;
Plug_Net_Close_Internal(handle);
return;
#endif
case STREAM_SOCKET:
closesocket(pluginstreamarray[handle].socket);
break;
@ -1304,7 +1251,14 @@ int VARGS Plug_Net_Close(void *offset, unsigned int mask, const long *arg)
}
pluginstreamarray[handle].plugin = NULL;
}
int VARGS Plug_Net_Close(void *offset, unsigned int mask, const long *arg)
{
int handle = VM_LONG(arg[0]);
if (handle < 0 || handle >= pluginstreamarraylen || pluginstreamarray[handle].plugin != currentplug)
return -2;
Plug_Net_Close_Internal(handle);
return 0;
}
@ -1382,10 +1336,6 @@ void Plug_Init(void)
Plug_RegisterBuiltin("Cmd_Argv", Plug_Cmd_Argv, 0);
Plug_RegisterBuiltin("Cmd_AddText", Plug_Cmd_AddText, 0);
Plug_RegisterBuiltin("CL_GetStats", Plug_CL_GetStats, 0);
Plug_RegisterBuiltin("Menu_Control", Plug_Menu_Control, 0);
Plug_RegisterBuiltin("Key_GetKeyCode", Plug_Key_GetKeyCode, 0);
Plug_RegisterBuiltin("Cvar_Register", Plug_Cvar_Register, 0);
Plug_RegisterBuiltin("Cvar_Update", Plug_Cvar_Update, 0);
Plug_RegisterBuiltin("Cvar_SetString", Plug_Cvar_SetString, 0);
@ -1393,21 +1343,13 @@ void Plug_Init(void)
Plug_RegisterBuiltin("Cvar_GetString", Plug_Cvar_GetString, 0);
Plug_RegisterBuiltin("Cvar_GetFloat", Plug_Cvar_GetFloat, 0);
Plug_RegisterBuiltin("Draw_LoadImage", Plug_Draw_LoadImage, 0);
Plug_RegisterBuiltin("Draw_Image", Plug_Draw_Image, 0);
Plug_RegisterBuiltin("Draw_Character", Plug_Draw_Character, 0);
Plug_RegisterBuiltin("Draw_Fill", Plug_Draw_Fill, 0);
Plug_RegisterBuiltin("Draw_Line", Plug_Draw_Line, 0);
Plug_RegisterBuiltin("Draw_Colourp", Plug_Draw_ColourP, 0);
Plug_RegisterBuiltin("Draw_Colour3f", Plug_Draw_Colour3f, 0);
Plug_RegisterBuiltin("Draw_Colour4f", Plug_Draw_Colour4f, 0);
Plug_RegisterBuiltin("Con_SubPrint", Plug_Con_SubPrint, 0);
Plug_RegisterBuiltin("Con_RenameSub", Plug_Con_RenameSub, 0);
Plug_RegisterBuiltin("Net_TCPListen", Plug_Net_TCPListen, 0);
Plug_RegisterBuiltin("Net_Accept", Plug_Net_Accept, 0);
Plug_RegisterBuiltin("Net_TCPConnect", Plug_Net_TCPConnect, 0);
#ifdef GNUTLS
if (Init_GNUTLS())
Plug_RegisterBuiltin("Net_SetTLSClient", Plug_Net_SetTLSClient, 0);
#endif
Plug_RegisterBuiltin("Net_Recv", Plug_Net_Recv, 0);
Plug_RegisterBuiltin("Net_Send", Plug_Net_Send, 0);
Plug_RegisterBuiltin("Net_SendTo", Plug_Net_SendTo, 0);
@ -1427,10 +1369,9 @@ void Plug_Init(void)
Plug_RegisterBuiltin("cos", Plug_cos, 0);
Plug_RegisterBuiltin("atan2", Plug_atan2, 0);
Plug_RegisterBuiltin("GetPluginName", Plug_GetPluginName, 0);
Plug_RegisterBuiltin("LocalSound", Plug_LocalSound, 0);
Plug_RegisterBuiltin("SCR_CenterPrint", Plug_SCR_CenterPrint, 0);
Plug_RegisterBuiltin("Media_ShowFrameRGBA_32", Plug_Media_ShowFrameRGBA_32, 0);
Plug_Client_Init();
if (plug_loaddefault.value)
{
@ -1456,6 +1397,7 @@ void Plug_Tick(void)
currentplug = oldplug;
}
#ifndef SERVERONLY
void Plug_ResChanged(void)
{
plugin_t *oldplug = currentplug;
@ -1466,6 +1408,7 @@ void Plug_ResChanged(void)
}
currentplug = oldplug;
}
#endif
qboolean Plugin_ExecuteString(void)
{
@ -1488,6 +1431,7 @@ qboolean Plugin_ExecuteString(void)
return false;
}
#ifndef SERVERONLY
void Plug_SubConsoleCommand(console_t *con, char *line)
{
char buffer[2048];
@ -1499,7 +1443,9 @@ void Plug_SubConsoleCommand(console_t *con, char *line)
VM_Call(currentplug->vm, currentplug->conexecutecommand, 0);
currentplug = oldplug;
}
#endif
#ifndef SERVERONLY
qboolean Plug_Menu_Event(int eventtype, int param) //eventtype = draw/keydown/keyup, param = time/key
{
plugin_t *oc=currentplug;
@ -1514,7 +1460,8 @@ qboolean Plug_Menu_Event(int eventtype, int param) //eventtype = draw/keydown/ke
currentplug=oc;
return ret;
}
#endif
#ifndef SERVERONLY
int Plug_ConnectionlessClientPacket(char *buffer, int size)
{
for (currentplug = plugs; currentplug; currentplug = currentplug->next)
@ -1540,7 +1487,8 @@ int Plug_ConnectionlessClientPacket(char *buffer, int size)
}
return false;
}
#endif
#ifndef SERVERONLY
void Plug_SBar(void)
{
plugin_t *oc=currentplug;
@ -1599,6 +1547,7 @@ void Plug_SBar(void)
currentplug = oc;
}
#endif
int Plug_Message(int clientnum, int messagelevel, char *buffer)
{
@ -1633,22 +1582,12 @@ void Plug_Close(plugin_t *plug)
Con_Printf("Closing plugin %s\n", plug->name);
VM_Destroy(plug->vm);
Plug_FreePlugImages(plug);
Plug_FreeConCommands(plug);
Plug_Client_Close(plug);
if (currentplug == plug)
currentplug = NULL;
if (menuplug == plug)
{
menuplug = NULL;
key_dest = key_game;
}
if (protocolclientplugin == plug)
{
protocolclientplugin = NULL;
if (cls.protocol == CP_PLUGIN)
cls.protocol = CP_UNKNOWN;
}
}
void Plug_Close_f(void)

View File

@ -142,7 +142,7 @@ void *Sys_LoadDLL(const char *name, void **vmMain, int (EXPORT_FN *syscall)(int
void (*dllEntry)(int (EXPORT_FN *syscall)(int arg, ... ));
char dllname[MAX_OSPATH];
void *hVM;
#ifdef __MORPHOS__
if (DynLoadBase == 0)
return 0;
@ -163,12 +163,17 @@ void *Sys_LoadDLL(const char *name, void **vmMain, int (EXPORT_FN *syscall)(int
return NULL; // couldn't find one anywhere
_snprintf (name, sizeof(name), "%s/%s", gpath, dllname);
Con_Printf("Loading native: %s\n", name);
hVM = dlopen (name, RTLD_NOW);
if (hVM)
{
Con_DPrintf ("dlopen (%s)\n",name);
Con_DPrintf ("Sys_LoadDLL: dlopen (%s)\n",name);
break;
}
else
{
Con_DPrintf("Sys_LoadDLL: dlerror()=\"%s\"", dlerror());
}
}
}
@ -177,6 +182,7 @@ void *Sys_LoadDLL(const char *name, void **vmMain, int (EXPORT_FN *syscall)(int
dllEntry=(void *)dlsym(hVM, "dllEntry");
if(!dllEntry)
{
Con_Printf("Sys_LoadDLL: %s does not have a dllEntry function\n");
dlclose(hVM);
return NULL;
}
@ -186,6 +192,7 @@ void *Sys_LoadDLL(const char *name, void **vmMain, int (EXPORT_FN *syscall)(int
*vmMain=(void *)dlsym(hVM, "vmMain");
if(!*vmMain)
{
Con_Printf("Sys_LoadDLL: %s does not have a vmMain function\n");
dlclose(hVM);
return NULL;
}
@ -519,7 +526,7 @@ qvm_t *QVM_Load(const char *name, sys_callqvm_t syscall)
void QVM_UnLoad(qvm_t *qvm)
{
Z_Free(qvm->mem_ptr);
Z_Free(qvm);
Z_Free(qvm);
}
@ -1054,7 +1061,7 @@ qboolean VM_Restart(vm_t *vm)
if(!vm) return false;
// save params
Q_strncpyz(name, vm->name, sizeof(name));
Q_strncpyz(name, vm->name, sizeof(name));
syscalldll=vm->syscalldll;
syscallqvm=vm->syscallqvm;

View File

@ -2147,6 +2147,18 @@ void GLDraw_Image(float x, float y, float w, float h, float s1, float t1, float
draw_mesh_st[3][0] = s1;
draw_mesh_st[3][1] = t2;
if (gl_blend2d.value)
{
qglDisable(GL_ALPHA_TEST);
qglEnable(GL_BLEND);
}
else
{
qglEnable(GL_ALPHA_TEST);
qglDisable(GL_BLEND);
}
GL_DrawMesh(&draw_mesh, gl->texnum);
}

View File

@ -41,7 +41,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <X11/extensions/xf86dga.h>
#endif
#define WITH_VMODE //undefine this if the following include fails.
#ifdef __linux__
#define WITH_VMODE //undefine this if the following include fails.
#endif
#ifdef WITH_VMODE
#include <X11/extensions/xf86vmode.h>
#endif
@ -138,13 +140,13 @@ void GLX_CloseLibrary(void)
qboolean GLX_InitLibrary(char *driver)
{
if (driver && *driver)
gllibrary = dlopen(driver, RTLD_LOCAL | RTLD_LAZY);
gllibrary = dlopen(driver, RTLD_LAZY);
else
gllibrary = NULL;
if (!gllibrary)
gllibrary = dlopen("libGL.so", RTLD_LOCAL | RTLD_LAZY);
gllibrary = dlopen("libGL.so", RTLD_LAZY);
if (!gllibrary) //I hate this.
gllibrary = dlopen("libGL.so.1", RTLD_LOCAL | RTLD_LAZY);
gllibrary = dlopen("libGL.so.1", RTLD_LAZY);
if (!gllibrary)
return false;
@ -427,13 +429,14 @@ static void GetEvent(void)
b = 4;
if (b>=0)
Key_Event(K_MOUSE1 + b, true);
#ifdef WITH_VMODE
if (vidmode_ext && vidmode_usemode>=0)
if (!ActiveApp)
{ //KDE doesn't seem to like us, in that you can't alt-tab back or click to activate.
//This allows us to steal input focus back from the window manager
XSetInputFocus(vid_dpy, vid_window, RevertToParent, CurrentTime);
}
#endif
break;
case ButtonRelease:
@ -455,7 +458,7 @@ static void GetEvent(void)
case FocusIn:
v_gamma.modified = true;
ActiveApp = true;
#ifdef WITH_VMODE
if (vidmode_ext && vidmode_usemode>=0)
{
if (!vidmode_active)
@ -467,7 +470,7 @@ static void GetEvent(void)
}
XF86VidModeSetViewPort(vid_dpy, scrnum, 0, 0);
}
#endif
break;
case FocusOut:
#ifdef WITH_VMODE

View File

@ -221,7 +221,7 @@ compiler_flag_t compiler_flag[] = {
{&flag_laxcasts, FLAG_MIDCOMPILE,"lax", "Lax type checks", "Disables many errors (generating warnings instead) when function calls or operations refer to two normally incompatable types. This is required for reacc support, and can also allow certain (evil) mods to compile that were originally written for frikqcc."}, //Allow lax casting. This'll produce loadsa warnings of course. But allows compilation of certain dodgy code.
{&flag_hashonly, FLAG_MIDCOMPILE,"hashonly", "Hash-only constants", "Allows use of only #constant for precompiler constants, allows certain preqcc using mods to compile"},
{&opt_logicops, FLAG_MIDCOMPILE,"lo", "Logic ops", "This changes the behaviour of your code. It generates additional if operations to early-out in if statements. With this flag, the line if (0 && somefunction()) will never call the function. It can thus be considered an optimisation. However, due to the change of behaviour, it is not considered so by fteqcc. Note that due to inprecisions with floats, this flag can cause runaway loop errors within the player walk and run functions. This code is advised:\nplayer_stand1:\n if (self.velocity_x || self.velocity_y)\nplayer_run\n if (!(self.velocity_x || self.velocity_y))"},
{&flag_fasttrackarrays, FLAG_MIDCOMPILE,"fastarrays", "fast arrays where possible", "Generates extra instructions inside array handling functions to detect engine and use extension opcodes in supporting engines.\nAdds a global which is set by the engine if the engine supports the extra opcodes. Note that this applies to al lor none."}, //correction for if(string) no-ifstring to get the standard behaviour.
{&flag_fasttrackarrays, FLAG_MIDCOMPILE|FLAG_ASDEFAULT,"fastarrays", "fast arrays where possible", "Generates extra instructions inside array handling functions to detect engine and use extension opcodes only in supporting engines.\nAdds a global which is set by the engine if the engine supports the extra opcodes. Note that this applies to all arrays or none."}, //correction for if(string) no-ifstring to get the standard behaviour.
{NULL}
};

View File

@ -348,6 +348,7 @@ typedef struct client_s
int challenge;
int userid; // identifying number
char userinfobasic[MAX_INFO_STRING];
char userinfo[EXTENDED_INFO_STRING]; // infostring
usercmd_t lastcmd; // for filling in big drops and partial predictions
@ -875,7 +876,7 @@ struct quakeparms_s;
void SV_Init (struct quakeparms_s *parms);
int SV_CalcPing (client_t *cl);
void SV_FullClientUpdate (client_t *client, sizebuf_t *buf);
void SV_FullClientUpdate (client_t *client, sizebuf_t *buf, unsigned int ftepext);
void SV_FullClientUpdateToClient (client_t *client, client_t *cl);
void SVNQ_FullClientUpdate (client_t *client, sizebuf_t *buf);

View File

@ -1639,6 +1639,32 @@ void SV_SendGameCommand_f(void)
Con_Printf("This command requires a Q2 sever\n");
}
void PIN_LoadMessages(void);
void PIN_SaveMessages(void);
void PIN_DeleteOldestMessage(void);
void PIN_MakeMessage(char *from, char *msg);
void SV_Pin_Save_f(void)
{
PIN_SaveMessages();
}
void SV_Pin_Reload_f(void)
{
PIN_LoadMessages();
}
void SV_Pin_Delete_f(void)
{
PIN_DeleteOldestMessage();
}
void SV_Pin_Add_f(void)
{
PIN_MakeMessage(Cmd_Argv(0), Cmd_Argv(1));
}
/*
==================
SV_InitOperatorCommands
@ -1704,6 +1730,11 @@ void SV_InitOperatorCommands (void)
Cmd_AddCommand ("sv_settimer", SV_SetTimer_f);
Cmd_AddCommand ("stuffcmd", SV_StuffToClient_f);
Cmd_AddCommand ("pin_save", SV_Pin_Save_f);
Cmd_AddCommand ("pin_reload", SV_Pin_Reload_f);
Cmd_AddCommand ("pin_delete", SV_Pin_Delete_f);
Cmd_AddCommand ("pin_add", SV_Pin_Add_f);
cl_warncmd.value = 1;
}

View File

@ -469,6 +469,7 @@ void SV_DropClient (client_t *drop)
drop->edict->v->frags = 0;
drop->name[0] = 0;
memset (drop->userinfo, 0, sizeof(drop->userinfo));
memset (drop->userinfobasic, 0, sizeof(drop->userinfobasic));
if (drop->frames) //union of the same sort of structure
{
@ -480,7 +481,7 @@ void SV_DropClient (client_t *drop)
return;
// send notification to all remaining clients
SV_FullClientUpdate (drop, &sv.reliable_datagram);
SV_FullClientUpdate (drop, &sv.reliable_datagram, 0);
#ifdef NQPROT
SVNQ_FullClientUpdate (drop, &sv.nqreliable_datagram);
#endif
@ -493,6 +494,134 @@ void SV_DropClient (client_t *drop)
}
//====================================================================
typedef struct pinnedmessages_s {
struct pinnedmessages_s *next;
char setby[64];
char message[1024];
} pinnedmessages_t;
pinnedmessages_t *pinned;
qboolean dopinnedload = true;
void PIN_DeleteOldestMessage(void);
void PIN_MakeMessage(char *from, char *msg);
void PIN_LoadMessages(void)
{
char setby[64];
char message[1024];
int i;
char *file;
char *lstart;
dopinnedload = false;
while(pinned)
PIN_DeleteOldestMessage();
file = COM_LoadMallocFile("pinned.txt");
if (!file)
return;
lstart = file;
for(;;)
{
while (*lstart <= ' ' && *lstart)
lstart++;
for (i = 0; *lstart && i < sizeof(message)-1; i++)
{
if (*lstart == '\n' || *lstart == '\r')
break;
message[i] = *lstart++;
}
message[i] = '\0';
while (*lstart <= ' ' && *lstart)
lstart++;
for (i = 0; *lstart && i < sizeof(setby)-1; i++)
{
if (*lstart == '\n' || *lstart == '\r')
break;
setby[i] = *lstart++;
}
setby[i] = '\0';
if (!*setby)
break;
PIN_MakeMessage(setby, message);
}
BZ_Free(file);
}
void PIN_SaveMessages(void)
{
pinnedmessages_t *p;
FILE *f;
f = COM_WriteFileOpen("pinned.txt");
if (!f)
{
Con_Printf("couldn't write anything\n");
return;
}
for (p = pinned; p; p = p->next)
fprintf(f, "%s\r\n\t%s\r\n\n", p->message, p->setby);
fclose(f);
}
void PIN_DeleteOldestMessage(void)
{
pinnedmessages_t *old = pinned;
pinned = pinned->next;
Z_Free(old);
}
void PIN_MakeMessage(char *from, char *msg)
{
pinnedmessages_t *p;
pinnedmessages_t *new;
new = BZ_Malloc(sizeof(pinnedmessages_t));
Q_strncpyz(new->setby, from, sizeof(new->setby));
Q_strncpyz(new->message, msg, sizeof(new->message));
new->next = NULL;
if (!pinned)
pinned = new;
else
{
for (p = pinned; ; p = p->next)
{
if (!p->next)
{
p->next = new;
break;
}
}
}
}
void PIN_ShowMessages(client_t *cl)
{
pinnedmessages_t *p;
if (dopinnedload)
PIN_LoadMessages();
if (!pinned)
return;
SV_ClientPrintf(cl, PRINT_HIGH, "\n<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ÿ\n\n");
for (p = pinned; p; p = p->next)
{
SV_ClientPrintf(cl, PRINT_HIGH, "%s\n\n <20>%s\n", p->message, p->setby);
SV_ClientPrintf(cl, PRINT_HIGH, "\n<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ÿ\n\n");
}
}
//====================================================================
/*
@ -536,6 +665,22 @@ int SV_CalcPing (client_t *cl)
return 0;
}
void SV_GenerateBasicUserInfo(client_t *cl)
{
char *key, *s;
int i;
for (i= 1; (key = Info_KeyForNumber(cl->userinfo, i)); i++)
{
if (!*key)
break;
if (!SV_UserInfoIsBasic(key))
continue;
s = Info_ValueForKey(cl->userinfo, key);
Info_SetValueForStarKey (cl->userinfobasic, key, s, sizeof(cl->userinfobasic));
}
}
/*
===================
SV_FullClientUpdate
@ -543,7 +688,7 @@ SV_FullClientUpdate
Writes all update values to a sizebuf
===================
*/
void SV_FullClientUpdate (client_t *client, sizebuf_t *buf)
void SV_FullClientUpdate (client_t *client, sizebuf_t *buf, unsigned int ftepext)
{
int i;
char info[MAX_INFO_STRING];
@ -598,7 +743,10 @@ void SV_FullClientUpdate (client_t *client, sizebuf_t *buf)
MSG_WriteByte (buf, i);
MSG_WriteFloat (buf, realtime - client->connection_started);
strcpy (info, client->userinfo);
if (ftepext & PEXT_CSQC)
strcpy (info, client->userinfo);
else
strcpy (info, client->userinfobasic);
Info_RemoveKey(info, "password"); //main password key
Info_RemovePrefixedKeys (info, '_'); // server passwords, etc
@ -672,10 +820,10 @@ void SV_FullClientUpdateToClient (client_t *client, client_t *cl)
else
ClientReliableCheckBlock(cl, 24 + strlen(client->userinfo));
if (cl->num_backbuf) {
SV_FullClientUpdate (client, &cl->backbuf);
SV_FullClientUpdate (client, &cl->backbuf, cl->fteprotocolextensions);
ClientReliable_FinishWrite(cl);
} else
SV_FullClientUpdate (client, &cl->netchan.message);
SV_FullClientUpdate (client, &cl->netchan.message, cl->fteprotocolextensions);
}
}
@ -1704,6 +1852,7 @@ client_t *SVC_DirectConnect(void)
// parse some info from the info strings
SV_ExtractFromUserinfo (newcl);
SV_GenerateBasicUserInfo (newcl);
// JACK: Init the floodprot stuff.
for (i=0; i<10; i++)
@ -1900,6 +2049,8 @@ client_t *SVC_DirectConnect(void)
Sys_ServerActivity();
PIN_ShowMessages(newcl);
if (ISNQCLIENT(newcl))
{
newcl->netchan.message.maxsize = sizeof(newcl->netchan.message_buf);
@ -1907,6 +2058,8 @@ client_t *SVC_DirectConnect(void)
SVNQ_New_f();
}
return newcl;
}
@ -2857,6 +3010,10 @@ void SV_MVDStream_Poll(void);
if (isDedicated)
#endif
{
#ifdef PLUGINS
Plug_Tick();
#endif
SV_GetConsoleCommands ();
// process console commands
@ -3577,7 +3734,6 @@ void SV_ExtractFromUserinfo (client_t *cl)
#endif
}
//============================================================================
/*
@ -3664,11 +3820,17 @@ void SV_Init (quakeparms_t *parms)
{
Sys_Init ();
PM_Init ();
#ifdef PLUGINS
Plug_Init();
#endif
Hunk_AllocName (0, "-HOST_HUNKLEVEL-");
host_hunklevel = Hunk_LowMark ();
host_initialized = true;
Con_TPrintf (TL_EXEDATETIME, __DATE__, __TIME__);
Con_TPrintf (TL_HEAPSIZE,parms->memsize/ (1024*1024.0));

View File

@ -1569,7 +1569,7 @@ void SV_UpdateToReliableMessages (void)
if (host_client->sendinfo)
{
host_client->sendinfo = false;
SV_FullClientUpdate (host_client, &sv.reliable_datagram);
SV_FullClientUpdate (host_client, &sv.reliable_datagram, host_client->fteprotocolextensions);
}
if (host_client->old_frags != (int)host_client->edict->v->frags)
{

View File

@ -2239,6 +2239,27 @@ void SV_Msg_f (void)
SV_ClientTPrintf (host_client, PRINT_HIGH, STL_MSGLEVELSET, host_client->messagelevel);
}
qboolean SV_UserInfoIsBasic(char *infoname)
{
int i;
char *basicinfos[] = {
"name",
"team",
"skin",
"topcolor",
"bottomcolor",
NULL};
for (i = 0; basicinfos[i]; i++)
{
if (!strcmp(infoname, basicinfos[i]))
return true;
}
return false;
}
/*
==================
SV_SetInfo_f
@ -2248,9 +2269,11 @@ Allow clients to change userinfo
*/
void SV_SetInfo_f (void)
{
int i;
int i, j;
char oldval[MAX_INFO_STRING];
char *key, *val;
qboolean basic; //infos that we send to any old qw client.
client_t *client;
if (Cmd_Argc() == 1)
@ -2269,6 +2292,9 @@ void SV_SetInfo_f (void)
if (Cmd_Argv(1)[0] == '*')
return; // don't set priveledged values
if (strstr(Cmd_Argv(1), "\\") || strstr(Cmd_Argv(2), "\\"))
return; // illegal char
strcpy(oldval, Info_ValueForKey(host_client->userinfo, Cmd_Argv(1)));
Info_SetValueForKey (host_client->userinfo, Cmd_Argv(1), Cmd_Argv(2), sizeof(host_client->userinfo));
@ -2294,10 +2320,33 @@ void SV_SetInfo_f (void)
i = host_client - svs.clients;
key = Cmd_Argv(1);
val = Info_ValueForKey(host_client->userinfo, key);
MSG_WriteByte (&sv.reliable_datagram, svc_setinfo);
MSG_WriteByte (&sv.reliable_datagram, i);
MSG_WriteString (&sv.reliable_datagram, key);
MSG_WriteString (&sv.reliable_datagram, val);
basic = SV_UserInfoIsBasic(key);
if (basic)
Info_SetValueForKey (host_client->userinfobasic, key, val, sizeof(host_client->userinfobasic));
for (j = 0; j < MAX_CLIENTS; j++)
{
client = svs.clients+j;
if (client->state < cs_connected)
continue; // reliables go to all connected or spawned
if (client->controller)
continue; //splitscreen
if (client->protocol == SCP_BAD)
continue; //botclient
if (ISQWCLIENT(client))
{
if (basic || (client->fteprotocolextensions & PEXT_CSQC))
{
MSG_WriteByte (&sv.reliable_datagram, svc_setinfo);
MSG_WriteByte (&sv.reliable_datagram, i);
MSG_WriteString (&sv.reliable_datagram, key);
MSG_WriteString (&sv.reliable_datagram, val);
}
}
}
if (sv.mvdrecording)
{