rewrote ban code, merging bans+nonbans+cuffs+mute+cripple+deaf+lagged+vip. added timeouts. new penalties have no dedicated command. use the addip command for it.

maplist command now generates links.
implemented skin objects for q3. added a csqc builtin for it. also supports compositing skins.
playing demos inside zips/pk3s/paks should now work.
bumped default rate cvar.
added cl_transfer to attempt to connect to a new server without disconnecting first.
rewrote fog command. alpha and mindist arguments are now supported. fog change also happens over a short time period.
added new args to the showpic console command. can now create clickable items for touchscreen/absmouse users.
fixed menus to properly support right-aligned text. this finally fixes variable-width fonts.
rewrote console tab completion suggestions display. now clickable links.
strings obtained from qc are now marked as const. this has required quite a few added consts all over the place.
probably crappy attempt at adding joypad support to the sdl port. no idea if it works.
changed key bind event code. buttons now track which event they should trigger when released, instead of being the same one the whole time. this allows +forward etc clickable buttons on screen. Also simplified modifier keys - they no longer trigger random events when pressing the modifier key itself.
Right modifiers can now be bound separately from left modifiers. Right will use left's binding if not otherwise bound. Bind assumes left if there's no prefix.
multiplayer->setup->network menu no longer crashes. added rgb colours to the translation view (but not to the colour-changing keys).
added modelviewer command to view models.
added menu_mods menu to switch mods in a more friendly way. will be shown by default if multiple manifests exist in the binarydir.
clamped classic tracer density. scrag particles no longer look quite so buggy.
added ifdefs to facilitate a potential winrt port. the engine should now have no extra dependencies, but still needs system code+audio drivers to be written.
if it can't set a renderer, it'll now try to use *every* renderer until it finds one that works.
added experimental mapcluster server mode (that console command). New maps will be started up as required.
rewrote skeletal blending code a bit.
added cylinder geomtypes.
fix cfg_save writing to the wrong path bug.
VFS_CLOSE now returns a boolean. false means there was some sort of fatal error (either crc when reading was bad, or the write got corrupted or something). Typically ignorable, depends how robust you want to be.
win32 tls code now supports running as a server. added connect tls://address support, as well as equivalent sv_addport support.
exposed basic model loading api to plugins.
d3d11 backend now optionally supports tessellation hlsl. no suitable hlsl provided by default. !!tess to enable.
attempted to add gamma ramp support for d3d11.
added support for shader blobs to speed up load times. r_shaderblobs 1 to enable. almost vital for d3d11.
added vid_srgb cvar.
shadowless lights are no longer disabled if shadows are not supported.
attempt to add support for touchscreens in win7/8.
Wrote gimmicky lua support, using lua instead of ssqc. define VM_LUA to enable.
updated saved game code. can again load saved games from vanilla-like engines.
changed scale clamping. 0.0001 should no longer appear as 1.
changed default mintic from 0.03 to 0.013 to match vanilla qw. I don't know why it was at 0.03. probably a typo.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4623 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2014-03-30 08:55:06 +00:00
parent 7e80062ab9
commit 2e1a70e319
192 changed files with 14252 additions and 6093 deletions

View File

@ -317,7 +317,7 @@ ifeq ($(FTE_TARGET),macosx)
endif
BASELDFLAGS ?= -lm -ldl -lpthread
ifneq (,$(findstring win,$(FTE_TARGET)))
ifeq (win,$(findstring cyg,$(FTE_TARGET))$(findstring win,$(FTE_TARGET)))
BASELDFLAGS=-lm
MINGW_LIBS_DIR=$(LIBS_DIR)/mingw-libs
@ -544,6 +544,7 @@ PROGS_OBJS = \
SERVER_OBJS = \
pr_cmds.o \
pr_q1qvm.o \
pr_lua.o \
sv_master.o \
sv_init.o \
sv_main.o \
@ -852,27 +853,51 @@ endif
ifeq ($(FTE_TARGET),vc)
DEBUG_CFLAGS=
MSVCDIR=Microsoft Visual Studio 10.0
WINDOWSSDKDIR=C:/Program Files/Microsoft SDKs/Windows/v7.1
ifeq ($(BITS),64)
WINDRES=x86_64-w64-mingw32-windres
MSVCPATH=C:/Program Files (x86)/$(MSVCDIR)/VC/BIN/amd64/
ifeq ($(WINRT),1)
WINDOWSSDKDIR=C:/Program Files (x86)/Windows Kits/8.1
MSVCINC=-I"C:\Program Files (x86)\$(MSVCDIR)\VC\ATLMFC\INCLUDE" -I"C:\Program Files (x86)\$(MSVCDIR)\VC\INCLUDE" -I"C:\Program Files (x86)\Microsoft Visual Studio 8\VC\PlatformSDK\include" -I"C:\Program Files (x86)\Microsoft Visual Studio 8\SDK\v2.0\include"
MSVCLIB=/LIBPATH:"C:\Program Files (x86)\$(MSVCPATH)\VC\ATLMFC\LIB\amd64" /LIBPATH:"C:\Program Files (x86)\$(MSVCPATH)\VC\LIB\amd64" /LIBPATH:"$(WINDOWSSDKDIR)\lib\amd64" /LIBPATH:"C:\Program Files (x86)\$(MSVCPATH)\SDK\v2.0\LIB\AMD64"
JPEGLIB=libs/libjpeg$(BITS).lib
ifeq ($(BITS),64)
WINDRES=x86_64-w64-mingw32-windres
MSVCPATH=C:/Program Files (x86)/$(MSVCDIR)/VC/BIN/amd64/
else
WINDRES=i686-w64-mingw32-windres
MSVCPATH=C:/Program Files (x86)/$(MSVCDIR)/VC/BIN/
SDKINC=-I"$(WINDOWSSDKDIR)\Include\shared" -I"$(WINDOWSSDKDIR)\Include\um"
MSVCINC=-I"C:\Program Files (x86)\$(MSVCDIR)\VC\INCLUDE"
#-I"C:\Program Files (x86)\$(MSVCDIR)\VC\ATLMFC\INCLUDE"
# -I"C:\Program Files (x86)\$(MSVCDIR)\VC\PlatformSDK\include" -I"C:\Program Files (x86)\$(MSVCDIR)\SDK\v2.0\include"
MSVCLIB=/LIBPATH:"C:\Program Files (x86)\$(MSVCDIR)\VC\ATLMFC\LIB" /LIBPATH:"C:\Program Files (x86)\$(MSVCDIR)\VC\LIB" /LIBPATH:"$(WINDOWSSDKDIR)/lib/winv6.3/um/x86" /LIBPATH:"C:\Program Files (x86)\$(MSVCDIR)\SDK\v2.0\LIB"
JPEGLIB=libs/jpeg.lib
endif
else
WINDRES=i686-w64-mingw32-windres
MSVCPATH=C:/Program Files (x86)/$(MSVCDIR)/VC/BIN/
WINDOWSSDKDIR=C:/Program Files/Microsoft SDKs/Windows/v7.1
MSVCINC=-I"C:\Program Files (x86)\$(MSVCDIR)\VC\ATLMFC\INCLUDE" -I"C:\Program Files (x86)\$(MSVCDIR)\VC\INCLUDE" -I"C:\Program Files (x86)\$(MSVCDIR)\VC\PlatformSDK\include" -I"C:\Program Files (x86)\$(MSVCDIR)\SDK\v2.0\include"
MSVCLIB=/LIBPATH:"C:\Program Files (x86)\$(MSVCDIR)\VC\ATLMFC\LIB" /LIBPATH:"C:\Program Files (x86)\$(MSVCDIR)\VC\LIB" /LIBPATH:"$(WINDOWSSDKDIR)\lib" /LIBPATH:"C:\Program Files (x86)\$(MSVCDIR)\SDK\v2.0\LIB"
JPEGLIB=libs/jpeg.lib
ifeq ($(BITS),64)
WINDRES=x86_64-w64-mingw32-windres
MSVCPATH=C:/Program Files (x86)/$(MSVCDIR)/VC/BIN/amd64/
MSVCINC=-I"C:\Program Files (x86)\$(MSVCDIR)\VC\ATLMFC\INCLUDE" -I"C:\Program Files (x86)\$(MSVCDIR)\VC\INCLUDE" -I"C:\Program Files (x86)\Microsoft Visual Studio 8\VC\PlatformSDK\include" -I"C:\Program Files (x86)\Microsoft Visual Studio 8\SDK\v2.0\include"
MSVCLIB=/LIBPATH:"C:\Program Files (x86)\$(MSVCPATH)\VC\ATLMFC\LIB\amd64" /LIBPATH:"C:\Program Files (x86)\$(MSVCPATH)\VC\LIB\amd64" /LIBPATH:"$(WINDOWSSDKDIR)\lib\amd64" /LIBPATH:"C:\Program Files (x86)\$(MSVCPATH)\SDK\v2.0\LIB\AMD64"
JPEGLIB=libs/libjpeg$(BITS).lib
else
WINDRES=i686-w64-mingw32-windres
MSVCPATH=C:/Program Files (x86)/$(MSVCDIR)/VC/BIN/
MSVCINC=-I"C:\Program Files (x86)\$(MSVCDIR)\VC\ATLMFC\INCLUDE" -I"C:\Program Files (x86)\$(MSVCDIR)\VC\INCLUDE" -I"C:\Program Files (x86)\$(MSVCDIR)\VC\PlatformSDK\include" -I"C:\Program Files (x86)\$(MSVCDIR)\SDK\v2.0\include"
MSVCLIB=/LIBPATH:"C:\Program Files (x86)\$(MSVCDIR)\VC\ATLMFC\LIB" /LIBPATH:"C:\Program Files (x86)\$(MSVCDIR)\VC\LIB" /LIBPATH:"$(WINDOWSSDKDIR)\lib" /LIBPATH:"C:\Program Files (x86)\$(MSVCDIR)\SDK\v2.0\LIB"
JPEGLIB=libs/jpeg.lib
endif
endif
STRIP=@echo strip
EXEPOSTFIX=.exe
CC="$(MSVCPATH)cl" $(MSVCINC) -D_CRT_SECURE_NO_WARNINGS
CC="$(MSVCPATH)cl" $(SDKINC) $(MSVCINC) -D_CRT_SECURE_NO_WARNINGS
DEBUG_CFLAGS ?= -Od $(CPUOPTIMIZATIONS) /fp:fast
PROFILE_CFLAGS = -O2 -Ot -Ox -GL $(CPUOPTIMISATIONS) /fp:fast
PROFILE_LDFLAGS = /LTCG:PGINSTRUMENT
@ -880,8 +905,8 @@ ifeq ($(FTE_TARGET),vc)
RELEASE_LDFLAGS = /LTCG
# /LTCG:PGOPTIMIZE
DO_CC=@$(CC) /nologo $(ALL_CFLAGS) -Fo$(shell cygpath -m $@) -c $(shell cygpath -m $<)
DO_LD=$(DO_ECHO) "$(MSVCPATH)link" /nologo /out:"$(shell cygpath -m $@)" /nodefaultlib:libc.lib /LARGEADDRESSAWARE /nodefaultlib:MSVCRT $(MSVCLIB) /manifest:no /OPT:REF wsock32.lib user32.lib kernel32.lib advapi32.lib winmm.lib libs/zlib$(BITS).lib shell32.lib
DO_CC=$(CC) /nologo $(ALL_CFLAGS) -Fo$(shell cygpath -m $@) -c $(shell cygpath -m $<)
DO_LD=$(DO_ECHO) "$(MSVCPATH)link" /nologo /out:"$(shell cygpath -m $@)" /nodefaultlib:libc.lib /LARGEADDRESSAWARE /nodefaultlib:MSVCRT $(MSVCLIB) $(SDKLIB) /manifest:no /OPT:REF wsock32.lib user32.lib kernel32.lib advapi32.lib winmm.lib libs/zlib$(BITS).lib shell32.lib
PRECOMPHEADERS =
DEPCC=

View File

@ -23,6 +23,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "quakedef.h"
#include "winquake.h"
#ifdef WINRT
#include "cd_null.c"
#else
#if defined(_MSC_VER) && (_MSC_VER < 1300)
#define DWORD_PTR DWORD
#endif
@ -366,3 +370,4 @@ void CDAudio_Update(void)
void CDAudio_Init(void)
{
}
#endif

View File

@ -24,7 +24,7 @@ extern int mod_numknown;
#define VM_FROMMHANDLE(a) ((a&&((unsigned int)a)<=mod_numknown)?mod_known+a-1:NULL)
#define VM_TOMHANDLE(a) (a?a-mod_known+1:0)
#define VM_FROMSHANDLE(a) (a?r_shaders[a-1]:NULL)
#define VM_FROMSHANDLE(a) ((a&&(unsigned int)a<=r_numshaders)?r_shaders[a-1]:NULL)
#define VM_TOSHANDLE(a) (a?a->id+1:0)
extern model_t box_model;
@ -730,14 +730,14 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
int i;
char *mapname = VM_POINTER(arg[0]);
strcpy(cl.model_name[1], mapname);
cl.worldmodel = cl.model_precache[1] = Mod_ForName(mapname, false);
cl.worldmodel = cl.model_precache[1] = Mod_ForName(mapname, MLV_SILENT);
if (cl.worldmodel->needload)
Host_EndGame("Couldn't load map");
Host_EndGame("Couldn't load map %s", mapname);
for (i=1 ; i<cl.model_precache[1]->numsubmodels ; i++)
{
strcpy(cl.model_name[1+i], va("*%i", i));
cl.model_precache[i+1] = Mod_ForName (cl.model_name[i+1], false);
cl.model_precache[i+1] = Mod_ForName (cl.model_name[i+1], MLV_SILENT);
}
}
@ -772,16 +772,18 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
case CG_R_REGISTERMODEL: //precache model
{
char *name = VM_POINTER(arg[0]);
model_t *mod;
mod = Mod_ForName(VM_POINTER(arg[0]), false);
mod = Mod_ForName(name, MLV_SILENT);
if (mod->needload || mod->type == mod_dummy)
return 0;
VM_LONG(ret) = VM_TOMHANDLE(mod);
VM_LONG(ret) = 0;
else
VM_LONG(ret) = VM_TOMHANDLE(mod);
}
break;
case CG_R_REGISTERSKIN:
VM_LONG(ret) = VM_TOSTRCACHE(arg[0]);
VM_LONG(ret) = Mod_RegisterSkinFile(VM_POINTER(arg[0]));
break;
case CG_R_REGISTERSHADER:
@ -969,7 +971,7 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
VALIDATEPOINTER(arg[1], sizeof(q3usercmd_t));
VM_LONG(ret) = CGQ3_GetUserCmd(VM_LONG(arg[0]), VM_POINTER(arg[1]));
break;
case CG_SETUSERCMDVALUE: //weaponselect, zoomsensativity.
case CG_SETUSERCMDVALUE: //weaponselect, zoomsensitivity.
ccs.selected_weapon = VM_LONG(arg[0]);
in_sensitivityscale = VM_FLOAT(arg[1]);
break;
@ -1163,6 +1165,16 @@ void CG_Stop (void)
}
}
qboolean CG_VideoRestarted(void)
{
if (cgvm)
{
VM_Call(cgvm, CG_INIT, ccs.serverMessageNum, ccs.lastServerCommandNum, cl.playerview[0].playernum);
return true;
}
return false;
}
void CG_Start (void)
{
SCR_SetLoadingStage(0);

View File

@ -1643,6 +1643,13 @@ void CL_PlayDemoStream(vfsfile_t *file, struct dl_download *dl, char *filename,
TP_ExecTrigger ("f_demostart");
}
vfsfile_t *CL_OpenFileInZipOrSys(char *name)
{
if (*name == '#')
return VFSOS_Open(name+1, "rb");
else
return CL_OpenFileInPackage(NULL, name);
}
void CL_PlayDemo(char *demoname)
{
char name[256];
@ -1654,10 +1661,7 @@ void CL_PlayDemo(char *demoname)
//
Q_strncpyz (name, demoname, sizeof(name));
COM_DefaultExtension (name, ".qwd", sizeof(name));
if (*name == '#')
f = VFSOS_Open(name+1, "rb");
else
f = FS_OpenVFS(name, "rb", FS_GAME);
f = CL_OpenFileInZipOrSys(name);
if (!f)
{
Q_strncpyz (name, demoname, sizeof(name));
@ -1683,7 +1687,6 @@ void CL_PlayDemo(char *demoname)
return;
}
Q_strncpyz (lastdemoname, demoname, sizeof(lastdemoname));
Con_Printf ("Playing demo from %s.\n", name);
if (!VFS_GETLEN (f))
{
@ -1958,7 +1961,7 @@ void CL_QTVPoll (void)
MC_AddCenterPicture(sourcesmenu, 4, 24, "gfx/p_option.lmp");
}
if (init_numplayers == true && init_numviewers == true)
MC_AddConsoleCommand(sourcesmenu, 42, (sourcenum++)*8 + 32, va("%s (p%i, v%i)", srchost, numplayers, numviewers), va("qtvplay %i@%s\n", streamid, qtvhostname));
MC_AddConsoleCommand(sourcesmenu, 42, 170, (sourcenum++)*8 + 32, va("%s (p%i, v%i)", srchost, numplayers, numviewers), va("qtvplay %i@%s\n", streamid, qtvhostname));
//else
// FIXME: add error message here
}

View File

@ -2932,7 +2932,7 @@ static void CL_TransitionPacketEntities(int newsequence, packet_entities_t *newp
if (age > 1)
age = 1;
if (cl_predict_players.ival)
if (cl_predict_players.ival && pmove.numphysent)
{
CL_PredictEntityMovement(from, age);
VectorCopy(from->u.q1.predorg, le->origin);
@ -3076,7 +3076,7 @@ static qboolean CL_ChooseInterpolationFrames(int *newf, int *oldf, float servert
This can happen if the client's predicted time is greater than the most recently received packet.
This should of course not happen...
*/
Con_DPrintf("Warning: No lerp-to frame packet\n");
// Con_DPrintf("Warning: No lerp-to frame packet\n");
/*just grab the most recent frame that is valid*/
for (i = cls.netchan.incoming_sequence; i >= cls.netchan.incoming_sequence-UPDATE_MASK; i--)
@ -3152,8 +3152,8 @@ void CL_TransitionEntities (void)
else
frac = (servertime-packold->servertime)/(packnew->servertime-packold->servertime);
// Con_Printf("%f %f %f (%f) (%i)\n", packold->servertime, servertime, packnew->servertime, frac, newff);
// Con_Printf("%f %f %f\n", cl.oldgametime, servertime, cl.gametime);
// if (!cl.paused)
// Con_Printf("%f %f %f (%f) (%i) %f %f %f\n", packold->servertime, servertime, packnew->servertime, frac, newff, cl.oldgametime, servertime, cl.gametime);
CL_TransitionPacketEntities(newff, packnew, packold, frac, servertime);
cl.packfrac = frac;
@ -3268,6 +3268,7 @@ void CL_LinkPacketEntities (void)
ent = &cl_visedicts[cl_numvisedicts];
ent->rtype = RT_MODEL;
ent->playerindex = -1;
ent->customskin = 0;
ent->topcolour = TOP_DEFAULT;
ent->bottomcolour = BOTTOM_DEFAULT;
ent->h2playerclass = 0;

View File

@ -37,7 +37,7 @@ cvar_t cl_netfps = CVAR("cl_netfps", "150");
cvar_t cl_sparemsec = CVARC("cl_sparemsec", "10", CL_SpareMsec_Callback);
cvar_t cl_queueimpulses = CVAR("cl_queueimpulses", "0");
cvar_t cl_smartjump = CVAR("cl_smartjump", "1");
cvar_t cl_run = CVARD("cl_run", "1", "Enables autorun, doubling the effective value of cl_forwardspeed and friends.");
cvar_t cl_run = CVARD("cl_run", "0", "Enables autorun, inverting the state of the +speed key.");
cvar_t cl_prydoncursor = CVAR("cl_prydoncursor", ""); //for dp protocol
cvar_t cl_instantrotate = CVARF("cl_instantrotate", "1", CVAR_SEMICHEAT);
@ -1120,9 +1120,6 @@ void VARGS CL_SendClientCommand(qboolean reliable, char *format, ...)
Q_vsnprintfz (string,sizeof(string), format,argptr);
va_end (argptr);
Con_DPrintf("Queing stringcmd %s\n", string);
#ifdef Q3CLIENT
if (cls.protocol == CP_QUAKE3)
{
@ -1477,7 +1474,7 @@ qboolean CLQW_SendCmd (sizebuf_t *buf)
MSG_WriteByte (buf, 0);
// write our lossage percentage
lost = CL_CalcNet();
lost = CL_CalcNet(r_netgraph.value);
MSG_WriteByte (buf, (qbyte)lost);
firstsize=0;
@ -1585,7 +1582,7 @@ void CL_SendCmd (double frametime, qboolean mainloop)
CL_BaseMove (cmd, plnum, 1, 1);
// allow mice or other external controllers to add to the move
IN_Move (mousemovements[plnum], plnum);
IN_Move (mousemovements[plnum], plnum, frametime);
independantphysics[plnum].forwardmove += mousemovements[plnum][0];
independantphysics[plnum].sidemove += mousemovements[plnum][1];
independantphysics[plnum].upmove += mousemovements[plnum][2];
@ -1620,7 +1617,7 @@ void CL_SendCmd (double frametime, qboolean mainloop)
cls.netchan.outgoing_sequence = cl.movesequence;
}
IN_Move (NULL, 0);
IN_Move (NULL, 0, frametime);
return; // sendcmds come from the demo
}
@ -1696,7 +1693,7 @@ void CL_SendCmd (double frametime, qboolean mainloop)
{
// CL_BaseMove (&independantphysics[plnum], plnum, (msecstouse - independantphysics[plnum].msec), wantfps);
CL_AdjustAngles (plnum, frametime);
IN_Move (mousemovements[plnum], plnum);
IN_Move (mousemovements[plnum], plnum, frametime);
CL_ClampPitch(plnum);
independantphysics[plnum].forwardmove += mousemovements[plnum][0];
independantphysics[plnum].sidemove += mousemovements[plnum][1];

File diff suppressed because it is too large Load Diff

View File

@ -182,7 +182,7 @@ void Master_SetupSockets(void);
void Master_QueryServer(serverinfo_t *server);
void MasterInfo_WriteServers(void);
int Master_KeyForName(char *keyname);
int Master_KeyForName(const char *keyname);
float Master_ReadKeyFloat(serverinfo_t *server, int keynum);
char *Master_ReadKeyString(serverinfo_t *server, int keynum);
@ -194,5 +194,5 @@ qboolean Master_GetSortDescending(void);
int Master_NumSorted(void);
void Master_ClearMasks(void);
serverinfo_t *Master_SortedServer(int idx);
void Master_SetMaskString(qboolean or, hostcachekey_t field, char *param, slist_test_t testop);
void Master_SetMaskString(qboolean or, hostcachekey_t field, const char *param, slist_test_t testop);
void Master_SetMaskInteger(qboolean or, hostcachekey_t field, int param, slist_test_t testop);

View File

@ -258,7 +258,7 @@ char *svc_nqstrings[] =
"NEW PROTOCOL(80)", //80
"NEW PROTOCOL(81)", //81
"NEW PROTOCOL(82)", //82
"NEW PROTOCOL(83)", //83
"nqsvcfte_cgamepacket(83)", //83
"NEW PROTOCOL(84)", //84
"NEW PROTOCOL(85)", //85
"nqsvcfte_updateentities", //86
@ -312,7 +312,7 @@ void CL_Parse_Disconnected(void)
int packet_latency[NET_TIMINGS];
int CL_CalcNet (void)
int CL_CalcNet (float scale)
{
int i;
outframe_t *frame;
@ -354,7 +354,7 @@ int CL_CalcNet (void)
// else if (frame->invalid)
// packet_latency[i&NET_TIMINGSMASK] = 9998; // invalid delta
else
packet_latency[i&NET_TIMINGSMASK] = frame->latency * 60;
packet_latency[i&NET_TIMINGSMASK] = frame->latency * 60 * scale;
}
if (sent < 1)
@ -411,7 +411,7 @@ void CL_AckedInputFrame(int inseq, int outseq, qboolean worldstateokay)
//=============================================================================
int CL_IsDownloading(char *localname)
int CL_IsDownloading(const char *localname)
{
downloadlist_t *dl;
/*check for dupes*/
@ -428,7 +428,7 @@ int CL_IsDownloading(char *localname)
//note: this will overwrite existing files.
//returns true if the download is going to be downloaded after the call.
qboolean CL_EnqueDownload(char *filename, char *localname, unsigned int flags)
qboolean CL_EnqueDownload(const char *filename, const char *localname, unsigned int flags)
{
char *ext;
downloadlist_t *dl;
@ -653,7 +653,7 @@ void CL_DownloadFinished(void)
{
if (!FS_Rename(tempname+8, filename+8, FS_ROOT))
{
char nativetmp[MAX_OSPATH], nativefinal[MAX_OSPATH];;
char nativetmp[MAX_OSPATH], nativefinal[MAX_OSPATH];
FS_NativePath(tempname+8, FS_ROOT, nativetmp, sizeof(nativetmp));
FS_NativePath(filename+8, FS_ROOT, nativefinal, sizeof(nativefinal));
Con_Printf("Couldn't rename %s to %s\n", nativetmp, nativefinal);
@ -661,11 +661,11 @@ void CL_DownloadFinished(void)
}
else if (!strncmp(tempname,"skins/",6))
{
if (!FS_Rename(tempname+6, filename+6, FS_SKINS))
if (!FS_Rename(tempname, filename, FS_PUBBASEGAMEONLY))
{
char nativetmp[MAX_OSPATH], nativefinal[MAX_OSPATH];;
FS_NativePath(tempname+6, FS_SKINS, nativetmp, sizeof(nativetmp));
FS_NativePath(filename+6, FS_SKINS, nativefinal, sizeof(nativefinal));
char nativetmp[MAX_OSPATH], nativefinal[MAX_OSPATH];
FS_NativePath(tempname, FS_PUBBASEGAMEONLY, nativetmp, sizeof(nativetmp));
FS_NativePath(filename, FS_PUBBASEGAMEONLY, nativefinal, sizeof(nativefinal));
Con_Printf("Couldn't rename %s to %s\n", nativetmp, nativefinal);
}
}
@ -673,7 +673,7 @@ void CL_DownloadFinished(void)
{
if (!FS_Rename(tempname, filename, FS_GAME))
{
char nativetmp[MAX_OSPATH], nativefinal[MAX_OSPATH];;
char nativetmp[MAX_OSPATH], nativefinal[MAX_OSPATH];
FS_NativePath(tempname, FS_GAME, nativetmp, sizeof(nativetmp));
FS_NativePath(filename, FS_GAME, nativefinal, sizeof(nativefinal));
Con_Printf("Couldn't rename %s to %s\n", nativetmp, nativefinal);
@ -716,7 +716,7 @@ void CL_DownloadFinished(void)
{
if (!strcmp(cl.model_name[i], filename))
{
cl.model_precache[i] = Mod_ForName(cl.model_name[i], false); //throw away result.
cl.model_precache[i] = Mod_ForName(cl.model_name[i], MLV_WARN); //throw away result.
if (i == 1)
cl.worldmodel = cl.model_precache[i];
break;
@ -726,7 +726,7 @@ void CL_DownloadFinished(void)
{
if (!strcmp(cl.model_csqcname[i], filename))
{
cl.model_csqcprecache[i] = Mod_ForName(cl.model_csqcname[i], false); //throw away result.
cl.model_csqcprecache[i] = Mod_ForName(cl.model_csqcname[i], MLV_WARN); //throw away result.
break;
}
}
@ -734,7 +734,7 @@ void CL_DownloadFinished(void)
{
if (!strcmp(cl.model_name_vwep[i], filename))
{
cl.model_precache_vwep[i] = Mod_ForName(cl.model_name_vwep[i], false);
cl.model_precache_vwep[i] = Mod_ForName(cl.model_name_vwep[i], MLV_WARN);
break;
}
}
@ -746,7 +746,7 @@ void CL_DownloadFinished(void)
}
}
qboolean CL_CheckFile(char *filename)
qboolean CL_CheckFile(const char *filename)
{
if (strstr (filename, ".."))
{
@ -761,7 +761,7 @@ qboolean CL_CheckFile(char *filename)
return false;
}
qboolean CL_CheckDLFile(char *filename)
qboolean CL_CheckDLFile(const char *filename)
{
if (!strncmp(filename, "package/", 8))
{
@ -785,7 +785,7 @@ Returns true if the file exists, returns false if it triggered a download.
===============
*/
qboolean CL_CheckOrEnqueDownloadFile (char *filename, char *localname, unsigned int flags)
qboolean CL_CheckOrEnqueDownloadFile (const char *filename, const char *localname, unsigned int flags)
{ //returns false if we don't have the file yet.
if (flags & DLLF_NONGAME)
{
@ -1160,7 +1160,7 @@ int CL_LoadModels(int stage, qboolean dontactuallyload)
if (cl.playerview[0].playernum == -1)
{ //q2 cinematic - don't load the models.
cl.worldmodel = cl.model_precache[1] = Mod_ForName ("", false);
cl.worldmodel = cl.model_precache[1] = Mod_ForName ("", MLV_WARN);
}
else
{
@ -1183,7 +1183,7 @@ int CL_LoadModels(int stage, qboolean dontactuallyload)
cl.model_precache[i] = NULL;
else
#endif
cl.model_precache[i] = Mod_ForName (cl.model_name[i], false);
cl.model_precache[i] = Mod_ForName (cl.model_name[i], MLV_WARN);
S_ExtraUpdate();
@ -1201,7 +1201,7 @@ int CL_LoadModels(int stage, qboolean dontactuallyload)
#ifdef CSQC_DAT
CSQC_LoadResource(cl.model_name_vwep[i], "vwep");
#endif
cl.model_precache_vwep[i] = Mod_ForName (cl.model_name_vwep[i], false);
cl.model_precache_vwep[i] = Mod_ForName (cl.model_name_vwep[i], MLV_WARN);
endstage();
}
}
@ -1243,7 +1243,7 @@ int CL_LoadModels(int stage, qboolean dontactuallyload)
else
CSQC_LoadResource(cl.model_csqcname[i], "model");
#endif
cl.model_csqcprecache[i] = Mod_ForName (cl.model_csqcname[i], false);
cl.model_csqcprecache[i] = Mod_ForName (cl.model_csqcname[i], MLV_WARN);
S_ExtraUpdate();
@ -1335,7 +1335,7 @@ int CL_LoadSounds(int stage, qboolean dontactuallyload)
return stage;
}
void Sound_CheckDownload(char *s)
void Sound_CheckDownload(const char *s)
{
char mangled[512];
@ -1640,7 +1640,7 @@ char *ZLibDownloadDecode(int *messagesize, char *input, int finalsize)
}
#endif
downloadlist_t *CL_DownloadFailed(char *name, qboolean cancel)
downloadlist_t *CL_DownloadFailed(const char *name, qboolean cancel)
{
//add this to our failed list. (so we don't try downloading it again...)
downloadlist_t *failed, **link, *dl;
@ -1992,18 +1992,18 @@ void CL_ParseDownload (void)
// open the file if not opened yet
if (!cls.downloadqw)
{
if (strncmp(cls.downloadtempname,"skins/",6))
if (!strncmp(cls.downloadtempname,"skins/",6))
{
Q_snprintfz(name, sizeof(name), "%s", cls.downloadtempname);
FS_CreatePath (name, FS_PUBBASEGAMEONLY);
cls.downloadqw = FS_OpenVFS (name, "wb", FS_PUBBASEGAMEONLY);
}
else
{
Q_snprintfz(name, sizeof(name), "%s", cls.downloadtempname);
FS_CreatePath (name, FS_GAME);
cls.downloadqw = FS_OpenVFS (name, "wb", FS_GAME);
}
else
{
Q_snprintfz(name, sizeof(name)-6, "%s", cls.downloadtempname+6);
FS_CreatePath (name, FS_SKINS);
cls.downloadqw = FS_OpenVFS (name, "wb", FS_SKINS);
}
if (!cls.downloadqw)
{
msg_readcount += size;
@ -3491,7 +3491,7 @@ void CLQ2_ParseConfigString (void)
cl.model_precache[i-Q2CS_MODELS] = NULL;
}
else
cl.model_precache[i-Q2CS_MODELS] = Mod_ForName (cl.model_name[i-Q2CS_MODELS], false);
cl.model_precache[i-Q2CS_MODELS] = Mod_ForName (cl.model_name[i-Q2CS_MODELS], MLV_WARN);
}
}
else if (i >= Q2CS_SOUNDS && i < Q2CS_SOUNDS+Q2MAX_MODELS)
@ -4978,7 +4978,7 @@ void CL_PrintChat(player_info_t *plr, char *rawmsg, char *msg, int plrflags)
else
Q_strncatz(fullchatmessage, "\1", sizeof(fullchatmessage));
#if defined(_WIN32) && !defined(NOMEDIA)
#if defined(_WIN32) && !defined(NOMEDIA) && !defined(WINRT)
TTS_SayChatString(&msg);
#endif
@ -5213,8 +5213,8 @@ void CL_ParseStuffCmd(char *msg, int destsplit) //this protects stuffcmds from n
Q_strncpyz(cl.model_name_vwep[i], mname, sizeof(cl.model_name_vwep[i]));
if (cls.state == ca_active)
{
CL_CheckOrEnqueDownloadFile(mname, NULL, 0);
cl.model_precache_vwep[i] = Mod_ForName(mname, false);
CL_CheckOrEnqueDownloadFile(cl.model_name_vwep[i], NULL, 0);
cl.model_precache_vwep[i] = Mod_ForName(cl.model_name_vwep[i], MLV_WARN);
}
}
}
@ -5281,7 +5281,7 @@ void CL_ParsePrecache(void)
{
model_t *model;
CL_CheckOrEnqueDownloadFile(s, s, 0);
model = Mod_ForName(s, i == 1);
model = Mod_ForName(s, (i == 1)?MLV_ERROR:MLV_WARN);
if (!model)
Con_Printf("svc_precache: Mod_ForName(\"%s\") failed\n", s);
cl.model_precache[i] = model;
@ -5315,7 +5315,7 @@ void CL_ParsePrecache(void)
if (cl.particle_ssname[i])
free(cl.particle_ssname[i]);
cl.particle_ssname[i] = strdup(s);
cl.particle_ssprecache[i] = 1+P_FindParticleType(s);
cl.particle_ssprecache[i] = P_FindParticleType(s);
cl.particle_ssprecaches = true;
}
else
@ -5419,7 +5419,7 @@ void CLQW_ParseServerMessage (void)
if (cmd == svcfte_choosesplitclient)
{
SHOWNET(svc_qwstrings[cmd]);
SHOWNET2(svc_qwstrings[cmd], cmd);
destsplit = MSG_ReadByte() % MAX_SPLITS;
cmd = MSG_ReadByte();
@ -5434,7 +5434,7 @@ void CLQW_ParseServerMessage (void)
break;
}
SHOWNET(svc_qwstrings[cmd]);
SHOWNET2(svc_qwstrings[cmd], cmd);
// other commands
switch (cmd)
@ -6650,12 +6650,13 @@ void CLNQ_ParseServerMessage (void)
Cmd_ExecuteString("bf", RESTRICT_SERVER);
break;
case svcfitz_fog:
cl.fog_density = MSG_ReadByte()/255.0f;
cl.fog_colour[0] = MSG_ReadByte()/255.0f;
cl.fog_colour[1] = MSG_ReadByte()/255.0f;
cl.fog_colour[2] = MSG_ReadByte()/255.0f;
/*time =*/ MSG_ReadShort();
cl.fog_locked = !!cl.fog_density;
CL_ResetFog();
cl.fog.density = MSG_ReadByte()/255.0f;
cl.fog.colour[0] = MSG_ReadByte()/255.0f;
cl.fog.colour[1] = MSG_ReadByte()/255.0f;
cl.fog.colour[2] = MSG_ReadByte()/255.0f;
cl.fog.time += ((unsigned short)MSG_ReadShort()) / 100.0;
cl.fog_locked = !!cl.fog.density;
break;
case svcfitz_spawnbaseline2:
i = MSGCL_ReadEntity ();

View File

@ -594,6 +594,35 @@ qintptr_t VARGS Plug_S_RawAudio(void *offset, quintptr_t mask, const qintptr_t *
return 0;
}
#include "com_mesh.h"
qintptr_t VARGS Plug_Mod_GetPluginModelFuncs(void *offset, quintptr_t mask, const qintptr_t *arg)
{
#ifdef SKELETALMODELS
static modplugfuncs_t funcs =
{
Mod_RegisterModelFormatText,
Mod_RegisterModelFormatMagic,
Mod_UnRegisterModelFormat,
Mod_UnRegisterAllModelFormats,
ZG_Malloc,
R_ConcatTransforms,
Matrix3x4_Invert_Simple,
COM_StripExtension,
GenMatrixPosQuat4Scale,
Alias_ForceConvertBoneData,
R_RegisterShader,
R_RegisterSkin,
R_BuildDefaultTexnums
};
if (VM_LONG(arg[0]) == sizeof(funcs))
return (qintptr_t)&funcs;
else
#endif
return 0;
}
void Plug_Client_Init(void)
{
Plug_RegisterBuiltin("CL_GetStats", Plug_CL_GetStats, PLUG_BIF_NEEDSRENDERER);
@ -629,6 +658,8 @@ void Plug_Client_Init(void)
Plug_RegisterBuiltin("SetUserInfo", Plug_SetUserInfo, PLUG_BIF_NEEDSRENDERER);
Plug_RegisterBuiltin("S_RawAudio", Plug_S_RawAudio, PLUG_BIF_NEEDSRENDERER);
Plug_RegisterBuiltin("Mod_GetPluginModelFuncs", Plug_Mod_GetPluginModelFuncs, PLUG_BIF_NEEDSRENDERER|PLUG_BIF_DLLONLY);
}
void Plug_Client_Close(plugin_t *plug)

View File

@ -1177,9 +1177,6 @@ void CL_PredictMove (void)
{
int i;
//work out which packet entities are solid
CL_SetSolidEntities ();
// Set up prediction for other players
CL_SetUpPlayerPrediction(false);

View File

@ -584,7 +584,7 @@ void SCR_CheckDrawCenterString (void)
}
}
void R_DrawTextField(int x, int y, int w, int h, char *text, unsigned int defaultmask, unsigned int fieldflags)
void R_DrawTextField(int x, int y, int w, int h, const char *text, unsigned int defaultmask, unsigned int fieldflags)
{
cprint_t p;
vrect_t r;
@ -663,9 +663,11 @@ static void SCR_DrawSimMTouchCursor(void)
typedef struct showpic_s {
struct showpic_s *next;
qbyte zone;
short x, y;
qboolean persist;
short x, y, w, h;
char *name;
char *picname;
char *tcommand;
} showpic_t;
showpic_t *showpics;
@ -745,13 +747,54 @@ void SCR_ShowPics_Draw(void)
p = R2D_SafeCachePic(sp->picname);
if (!p)
continue;
R2D_ScalePic(x, y, p->width, p->height, p);
R2D_ScalePic(x, y, sp->w?sp->w:p->width, sp->h?sp->h:p->height, p);
}
}
void SCR_ShowPic_Clear(void)
char *SCR_ShowPics_ClickCommand(int cx, int cy)
{
downloadlist_t *failed;
float x, y, w, h;
showpic_t *sp;
mpic_t *p;
for (sp = showpics; sp; sp = sp->next)
{
if (!sp->tcommand || !*sp->tcommand)
continue;
x = sp->x;
y = sp->y;
w = sp->w;
h = sp->h;
SP_RecalcXY(&x, &y, sp->zone);
if (!w || !h)
{
if (!*sp->picname)
continue;
for (failed = cl.faileddownloads; failed; failed = failed->next)
{ //don't try displaying ones that we know to have failed.
if (!strcmp(failed->rname, sp->picname))
break;
}
if (failed)
continue;
p = R2D_SafeCachePic(sp->picname);
if (!p)
continue;
w = w?w:sp->w;
h = h?h:sp->h;
}
if (cx >= x && cx < x+w)
if (cy >= y && cy < y+h)
return sp->tcommand; //if they overlap, that's your own damn fault.
}
return NULL;
}
//all=false clears only server pics, not ones from configs.
void SCR_ShowPic_Clear(qboolean all)
{
showpic_t **link, *sp;
int pnum;
for (pnum = 0; pnum < MAX_SPLITS; pnum++)
@ -760,12 +803,19 @@ void SCR_ShowPic_Clear(void)
scr_centerprint[pnum].charcount = 0;
}
while((sp = showpics))
for (link = &showpics; (sp=*link); )
{
showpics = sp->next;
if (sp->persist)
{
link = &sp->next;
continue;
}
*link = sp->next;
Z_Free(sp->name);
Z_Free(sp->picname);
Z_Free(sp->tcommand);
Z_Free(sp);
}
}
@ -879,7 +929,8 @@ void SCR_ShowPic_Script_f(void)
{
char *imgname;
char *name;
int x, y;
char *tcommand;
int x, y, w, h;
int zone;
showpic_t *sp;
@ -889,17 +940,27 @@ void SCR_ShowPic_Script_f(void)
y = atoi(Cmd_Argv(4));
zone = atoi(Cmd_Argv(5));
w = atoi(Cmd_Argv(6));
h = atoi(Cmd_Argv(7));
tcommand = Cmd_Argv(8);
sp = SCR_ShowPic_Find(name);
Z_Free(sp->picname);
sp->picname = Z_Malloc(strlen(imgname)+1);
strcpy(sp->picname, imgname);
Z_Free(sp->tcommand);
sp->picname = Z_StrDup(imgname);
sp->tcommand = Z_StrDup(tcommand);
sp->zone = zone;
sp->x = x;
sp->y = y;
sp->w = w;
sp->h = h;
if (!sp->persist)
sp->persist = !Cmd_FromGamecode();
}
//=============================================================================

View File

@ -711,7 +711,7 @@ void CL_AddBeam (int tent, int ent, vec3_t start, vec3_t end) //fixme: use TE_ n
if (ruleset_allow_particle_lightning.ival && btype >= 0)
m = NULL;
else
m = Mod_ForName(mname, false);
m = Mod_ForName(mname, MLV_WARN);
if (m && m->needload)
CL_CheckOrEnqueDownloadFile(m->name, NULL, 0);
@ -835,23 +835,23 @@ void CL_ParseStream (int type)
switch(type)
{
case TEH2_STREAM_LIGHTNING_SMALL:
b->model = Mod_ForName("models/stltng2.mdl", true);
b->model = Mod_ForName("models/stltng2.mdl", MLV_WARN);
b->flags |= 2;
b->particleeffect = P_FindParticleType("te_stream_lightning_small");
break;
case TEH2_STREAM_LIGHTNING:
b->model = Mod_ForName("models/stlghtng.mdl", true);
b->model = Mod_ForName("models/stlghtng.mdl", MLV_WARN);
b->flags |= 2;
b->particleeffect = P_FindParticleType("te_stream_lightning");
break;
case TEH2_STREAM_ICECHUNKS:
b->model = Mod_ForName("models/stice.mdl", true);
b->model = Mod_ForName("models/stice.mdl", MLV_WARN);
b->flags |= 2;
b->particleeffect = P_FindParticleType("te_stream_icechunks");
if (cl_legacystains.ival) Surf_AddStain(end, -10, -10, 0, 20);
break;
case TEH2_STREAM_SUNSTAFF1:
b->model = Mod_ForName("models/stsunsf1.mdl", true);
b->model = Mod_ForName("models/stsunsf1.mdl", MLV_WARN);
b->particleeffect = P_FindParticleType("te_stream_sunstaff1");
if (b->particleeffect < 0)
{
@ -859,26 +859,26 @@ void CL_ParseStream (int type)
if (b2)
{
memcpy(b2, b, sizeof(*b2));
b2->model = Mod_ForName("models/stsunsf2.mdl", true);
b2->model = Mod_ForName("models/stsunsf2.mdl", MLV_WARN);
b2->alpha = 0.5;
}
}
break;
case TEH2_STREAM_SUNSTAFF2:
b->model = Mod_ForName("models/stsunsf1.mdl", true);
b->model = Mod_ForName("models/stsunsf1.mdl", MLV_WARN);
b->particleeffect = P_FindParticleType("te_stream_sunstaff2");
if (cl_legacystains.ival) Surf_AddStain(end, -10, -10, -10, 20);
break;
case TEH2_STREAM_COLORBEAM:
b->model = Mod_ForName("models/stclrbm.mdl", true);
b->model = Mod_ForName("models/stclrbm.mdl", MLV_WARN);
b->particleeffect = P_FindParticleType("te_stream_colorbeam");
break;
case TEH2_STREAM_GAZE:
b->model = Mod_ForName("models/stmedgaz.mdl", true);
b->model = Mod_ForName("models/stmedgaz.mdl", MLV_WARN);
b->particleeffect = P_FindParticleType("te_stream_gaze");
break;
case TEH2_STREAM_FAMINE:
b->model = Mod_ForName("models/fambeam.mdl", true);
b->model = Mod_ForName("models/fambeam.mdl", MLV_WARN);
b->particleeffect = P_FindParticleType("te_stream_famine");
break;
default:
@ -909,17 +909,13 @@ void CL_ParseTEnt (void)
// explosion_t *ex;
int cnt, colour;
type = MSG_ReadByte ();
#ifdef CSQC_DAT
if (type != TE_GUNSHOT)
{
//I know I'm going to regret this.
if (CSQC_ParseTempEntity((unsigned char)type))
return;
}
//I know I'm going to regret this.
if (CSQC_ParseTempEntity())
return;
#endif
type = MSG_ReadByte ();
if (nqprot)
{
@ -1157,7 +1153,7 @@ void CL_ParseTEnt (void)
explosion_t *ex = CL_AllocExplosion ();
VectorCopy (pos, ex->origin);
ex->start = cl.time;
ex->model = Mod_ForName ("progs/s_explod.spr", true);
ex->model = Mod_ForName ("progs/s_explod.spr", MLV_WARN);
}
break;
case TE_EXPLOSION: // rocket explosion
@ -1197,7 +1193,7 @@ void CL_ParseTEnt (void)
explosion_t *ex = CL_AllocExplosion ();
VectorCopy (pos, ex->origin);
ex->start = cl.time;
ex->model = Mod_ForName ("progs/s_explod.spr", true);
ex->model = Mod_ForName ("progs/s_explod.spr", MLV_WARN);
}
break;
@ -1919,7 +1915,9 @@ void CL_RefreshCustomTEnts(void)
for (i = 0; i <= MAX_SSPARTICLESPRE; i++)
{
if (cl.particle_ssname[i])
cl.particle_ssprecache[i] = 1+P_FindParticleType(cl.particle_ssname[i]);
cl.particle_ssprecache[i] = P_FindParticleType(cl.particle_ssname[i]);
else
cl.particle_ssprecache[i] = P_INVALID;
}
}
if (cl.particle_csprecaches)
@ -1927,7 +1925,9 @@ void CL_RefreshCustomTEnts(void)
for (i = 0; i <= MAX_CSPARTICLESPRE; i++)
{
if (cl.particle_csname[i])
cl.particle_csprecache[i] = 1+P_FindParticleType(cl.particle_csname[i]);
cl.particle_csprecache[i] = P_FindParticleType(cl.particle_csname[i]);
else
cl.particle_csprecache[i] = P_INVALID;
}
}
}
@ -1953,12 +1953,12 @@ int CL_TranslateParticleFromServer(int qceffect)
if (cl.particle_ssprecaches && qceffect >= 0 && qceffect < MAX_SSPARTICLESPRE)
{
/*proper precaches*/
return cl.particle_ssprecache[qceffect]-1;
return cl.particle_ssprecache[qceffect];
}
else if (-qceffect >= 0 && -qceffect < MAX_CSPARTICLESPRE)
{
qceffect = -qceffect;
return cl.particle_csprecache[qceffect]-1;
return cl.particle_csprecache[qceffect];
}
else
return -1;
@ -2177,7 +2177,7 @@ void CL_SmokeAndFlash(vec3_t origin)
ex->flags = Q2RF_TRANSLUCENT;
ex->alpha = 1;
ex->start = cl.time;
ex->model = Mod_ForName (q2tentmodels[q2cl_mod_smoke].modelname, false);
ex->model = Mod_ForName (q2tentmodels[q2cl_mod_smoke].modelname, MLV_WARN);
ex = CL_AllocExplosion ();
VectorCopy (origin, ex->origin);
@ -2186,7 +2186,7 @@ void CL_SmokeAndFlash(vec3_t origin)
ex->flags = Q2RF_FULLBRIGHT;
ex->numframes = 2;
ex->start = cl.time;
ex->model = Mod_ForName (q2tentmodels[q2cl_mod_flash].modelname, false);
ex->model = Mod_ForName (q2tentmodels[q2cl_mod_flash].modelname, MLV_WARN);
}
void CL_Laser (vec3_t start, vec3_t end, int colors)
@ -2347,7 +2347,7 @@ void CLQ2_ParseTEnt (void)
ex = CL_AllocExplosion ();
VectorCopy (pos, ex->origin);
ex->start = cl.time;
ex->model = Mod_ForName (q2tentmodels[q2cl_mod_explode].modelname, false);
ex->model = Mod_ForName (q2tentmodels[q2cl_mod_explode].modelname, MLV_WARN);
ex->firstframe = 0;
ex->numframes = 4;
ex->flags = Q2RF_FULLBRIGHT|Q2RF_ADDITIVE|RF_NOSHADOW|Q2RF_TRANSLUCENT;
@ -2435,7 +2435,7 @@ void CLQ2_ParseTEnt (void)
VectorCopy (pos, ex->origin);
VectorClear(ex->angles);
ex->start = cl.time;
ex->model = Mod_ForName (q2tentmodels[q2cl_mod_explo4].modelname, true);
ex->model = Mod_ForName (q2tentmodels[q2cl_mod_explo4].modelname, MLV_WARN);
ex->firstframe = 30;
ex->alpha = 1;
ex->flags |= Q2RF_TRANSLUCENT;
@ -2530,7 +2530,7 @@ void CLQ2_ParseTEnt (void)
VectorCopy (pos, ex->origin);
VectorClear(ex->angles);
ex->start = cl.time;
ex->model = Mod_ForName (q2tentmodels[q2cl_mod_explo4].modelname, false);
ex->model = Mod_ForName (q2tentmodels[q2cl_mod_explo4].modelname, MLV_WARN);
ex->alpha = 1;
ex->flags |= Q2RF_TRANSLUCENT;
if (rand()&1)
@ -2678,7 +2678,7 @@ void CLQ2_ParseTEnt (void)
ex = CL_AllocExplosion ();
VectorCopy (pos, ex->origin);
ex->start = cl.time;
ex->model = Mod_ForName (q2tentmodels[q2cl_mod_explode].modelname, false);
ex->model = Mod_ForName (q2tentmodels[q2cl_mod_explode].modelname, MLV_WARN);
ex->firstframe = 0;
ex->numframes = 4;
ex->flags = Q2RF_FULLBRIGHT|RF_NOSHADOW;
@ -2728,7 +2728,7 @@ void CLQ2_ParseTEnt (void)
ex = CL_AllocExplosion ();
VectorCopy (pos, ex->origin);
ex->start = cl.time;
ex->model = Mod_ForName (q2tentmodels[q2cl_mod_explode].modelname, false);
ex->model = Mod_ForName (q2tentmodels[q2cl_mod_explode].modelname, MLV_WARN);
ex->firstframe = 0;
ex->numframes = 4;
ex->flags = Q2RF_FULLBRIGHT|RF_NOSHADOW;
@ -2786,7 +2786,7 @@ void CLQ2_ParseTEnt (void)
// ex->type = ex_poly;
ex->flags = Q2RF_FULLBRIGHT|RF_NOSHADOW;
ex->angles[1] = rand() % 360;
ex->model = Mod_ForName (q2tentmodels[q2cl_mod_explo4].modelname, false);
ex->model = Mod_ForName (q2tentmodels[q2cl_mod_explo4].modelname, MLV_WARN);
if (rand() < RAND_MAX/2)
ex->firstframe = 15;
ex->numframes = 15;
@ -3106,21 +3106,21 @@ void CL_UpdateBeams (void)
playerview_t *pv = &cl.playerview[j];
if (b->entity == ((cl.spectator&&pv->cam_auto)?pv->cam_spec_track+1:(pv->playernum+1)))
{
player_state_t *pl;
// player_state_t *pl;
// VectorSubtract(cl.simorg, b->start, org);
// VectorAdd(b->end, org, b->end); //move the end point by simorg-start
pl = &cl.inframes[cl.parsecount&UPDATE_MASK].playerstate[b->entity-1];
if (pl->messagenum == cl.parsecount || cls.protocol == CP_NETQUAKE)
// pl = &cl.inframes[cl.parsecount&UPDATE_MASK].playerstate[b->entity-1];
// if (pl->messagenum == cl.parsecount || cls.protocol == CP_NETQUAKE)
{
vec3_t fwd, org, ang;
float delta, f, len;
if (cl.spectator && pv->cam_auto)
{ //if we're tracking someone, use their origin explicitly.
vieworg = pl->origin;
}
else
// if (cl.spectator && pv->cam_auto)
// { //if we're tracking someone, use their origin explicitly.
// vieworg = pl->origin;
// }
// else
vieworg = pv->simorg;
viewang = pv->simangles;

View File

@ -405,10 +405,8 @@ void VQ3_AddEntity(const q3refEntity_t *q3)
ent.scale = 1;
ent.rtype = q3->reType;
if (q3->customSkin)
ent.skinnum = Mod_SkinNumForName(ent.model, VM_FROMSTRCACHE(q3->customSkin));
else
ent.skinnum = q3->skinNum;
ent.customskin = q3->customSkin;
ent.skinnum = q3->skinNum;
ent.shaderRGBAf[0] = q3->shaderRGBA[0]/255.0f;
ent.shaderRGBAf[1] = q3->shaderRGBA[1]/255.0f;
@ -430,6 +428,10 @@ void VQ3_AddEntity(const q3refEntity_t *q3)
if (q3->renderfx & Q3RF_NOSHADOW)
ent.flags |= RF_NOSHADOW;
ent.topcolour = TOP_DEFAULT;
ent.bottomcolour = BOTTOM_DEFAULT;
ent.playerindex = -1;
VectorCopy(q3->origin, ent.origin);
VectorCopy(q3->oldorigin, ent.oldorigin);
V_AddAxisEntity(&ent);
@ -839,7 +841,12 @@ static qintptr_t UI_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
case UI_R_REGISTERMODEL: //precache model
{
char *name = VM_POINTER(arg[0]);
VM_LONG(ret) = VM_TOMHANDLE(Mod_ForName(name, false));
model_t *mod;
mod = Mod_ForName(name, MLV_SILENT);
if (mod->needload || mod->type == mod_dummy)
VM_LONG(ret) = 0;
else
VM_LONG(ret) = VM_TOMHANDLE(mod);
}
break;
case UI_R_MODELBOUNDS:
@ -863,7 +870,7 @@ static qintptr_t UI_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
break;
case UI_R_REGISTERSKIN:
VM_LONG(ret) = VM_TOSTRCACHE(arg[0]);
VM_LONG(ret) = Mod_RegisterSkinFile(VM_POINTER(arg[0]));
break;
case UI_R_REGISTERFONT: //register font

View File

@ -696,8 +696,8 @@ typedef struct
vec3_t skyaxis;
qboolean fog_locked;
float fog_density;
vec3_t fog_colour;
fogstate_t fog;
fogstate_t oldfog;
char levelname[40]; // for display on solo scoreboard
@ -807,7 +807,7 @@ extern cvar_t ruleset_allow_particle_lightning;
extern cvar_t ruleset_allow_overlongsounds;
extern cvar_t ruleset_allow_larger_models;
extern cvar_t ruleset_allow_modified_eyes;
extern cvar_t ruleset_allow_sensative_texture_replacements;
extern cvar_t ruleset_allow_sensitive_texture_replacements;
extern cvar_t ruleset_allow_localvolume;
extern cvar_t ruleset_allow_shaders;
@ -953,7 +953,7 @@ void CL_BaseMove (usercmd_t *cmd, int pnum, float extra, float wantfps);
float CL_KeyState (kbutton_t *key, int pnum);
char *Key_KeynumToString (int keynum);
int Key_StringToKeynum (char *str, int *modifier);
int Key_StringToKeynum (const char *str, int *modifier);
char *Key_GetBinding(int keynum);
void CL_UseIndepPhysics(qboolean allow);
@ -1015,7 +1015,7 @@ void CL_ParseQTVFile(vfsfile_t *f, const char *fname, qtvfile_t *result);
#define NET_TIMINGS 256
#define NET_TIMINGSMASK 255
extern int packet_latency[NET_TIMINGS];
int CL_CalcNet (void);
int CL_CalcNet (float scale);
void CL_ClearParseState(void);
void CL_Parse_Disconnected(void);
void CL_DumpPacket(void);
@ -1027,17 +1027,17 @@ void CLQ2_ParseServerMessage (void);
#endif
void CL_NewTranslation (int slot);
int CL_IsDownloading(char *localname);
qboolean CL_CheckOrEnqueDownloadFile (char *filename, char *localname, unsigned int flags);
qboolean CL_EnqueDownload(char *filename, char *localname, unsigned int flags);
downloadlist_t *CL_DownloadFailed(char *name, qboolean cancel);
int CL_IsDownloading(const char *localname);
qboolean CL_CheckOrEnqueDownloadFile (const char *filename, const char *localname, unsigned int flags);
qboolean CL_EnqueDownload(const char *filename, const char *localname, unsigned int flags);
downloadlist_t *CL_DownloadFailed(const char *name, qboolean cancel);
int CL_DownloadRate(void);
void CL_GetDownloadSizes(unsigned int *filecount, unsigned int *totalsize, qboolean *somesizesunknown);
qboolean CL_ParseOOBDownload(void);
void CL_DownloadFinished(void);
void CL_RequestNextDownload (void);
void CL_SendDownloadReq(sizebuf_t *msg);
void Sound_CheckDownload(char *s); /*checkorenqueue a sound file*/
void Sound_CheckDownload(const char *s); /*checkorenqueue a sound file*/
qboolean CL_IsUploading(void);
void CL_NextUpload(void);
@ -1155,7 +1155,7 @@ qboolean CSQC_ParseGamePacket(void);
qboolean CSQC_CenterPrint(int lplayernum, char *cmd);
void CSQC_Input_Frame(int lplayernum, usercmd_t *cmd);
void CSQC_WorldLoaded(void);
qboolean CSQC_ParseTempEntity(unsigned char firstbyte);
qboolean CSQC_ParseTempEntity(void);
qboolean CSQC_ConsoleCommand(char *cmd);
qboolean CSQC_KeyPress(int key, int unicode, qboolean down, int devid);
qboolean CSQC_MouseMove(float xdelta, float ydelta, int devid);
@ -1333,6 +1333,7 @@ void CL_BeginServerReconnect(void);
void SV_User_f (void); //called by client version of the function
void SV_Serverinfo_f (void);
void SV_ConSay_f(void);
@ -1374,12 +1375,12 @@ struct cin_s *Media_StartCin(char *name);
texid_tf Media_UpdateForShader(cin_t *cin);
void Media_ShutdownCin(cin_t *cin);
#endif
qboolean Media_BackgroundTrack(char *initialtrack, char *looptrack); //new background music interface
qboolean Media_BackgroundTrack(const char *initialtrack, const char *looptrack); //new background music interface
void Media_NumberedTrack(unsigned int initialtrack, unsigned int looptrack); //legacy cd interface for protocols that only support numbered tracks.
void Media_EndedTrack(void); //cd is no longer running, media code needs to pick a new track (cd track or faketrack)
//these accept NULL for cin to mean the current fullscreen video
void Media_Send_Command(cin_t *cin, char *command);
void Media_Send_Command(cin_t *cin, const char *command);
void Media_Send_MouseMove(cin_t *cin, float x, float y);
void Media_Send_Resize(cin_t *cin, int x, int y);
void Media_Send_GetSize(cin_t *cin, int *x, int *y);
@ -1415,7 +1416,7 @@ typedef struct
void (VARGS *key) (void *ctx, int code, int unicode, int event);
qboolean (VARGS *setsize) (void *ctx, int width, int height);
void (VARGS *getsize) (void *ctx, int *width, int *height);
void (VARGS *changestream) (void *ctx, char *streamname);
void (VARGS *changestream) (void *ctx, const char *streamname);
} media_decoder_funcs_t;
typedef struct {
char *drivername;

View File

@ -1312,9 +1312,9 @@ void CLQ2_AddPacketEntities (q2frame_t *frame)
{
char *pmodel = Info_ValueForKey(player->userinfo, "model");
if (*pmodel)
ent.model = Mod_ForName(va("players/%s/tris.md2", pmodel), false);
ent.model = Mod_ForName(va("players/%s/tris.md2", pmodel), MLV_WARN);
if (!ent.model || ent.model->needload)
ent.model = Mod_ForName("players/male/tris.md2", false);
ent.model = Mod_ForName("players/male/tris.md2", MLV_SILENT);
}
ent.playerindex = (s1->skinnum&0xff)%cl.allocated_client_slots;
player->model = ent.model;
@ -1535,7 +1535,7 @@ void CLQ2_AddPacketEntities (q2frame_t *frame)
i = (s1->skinnum >> 8); // 0 is default weapon model
if (i >= 0 && i < cl.numq2visibleweapons)
ent.model = Mod_ForName(va("players/%s/%s", modelname, cl.q2visibleweapons[i]), false);
ent.model = Mod_ForName(va("players/%s/%s", modelname, cl.q2visibleweapons[i]), MLV_WARN);
/*
ci = &cl.clientinfo[s1->skinnum & 0xff];
i = (s1->skinnum >> 8); // 0 is default weapon model

View File

@ -538,6 +538,10 @@ void CLQ3_ParseGameState(void)
// wipe the client_state_t struct
//
CL_ClearState();
ccs.firstParseEntity = 0;
memset(ccs.parseEntities, 0, sizeof(ccs.parseEntities));
memset(ccs.baselines, 0, sizeof(ccs.baselines));
cl.minpitch = -90;
cl.maxpitch = 90;

View File

@ -142,7 +142,7 @@ void Con_Destroy (console_t *con)
con_current = &con_main;
}
/*obtains a console_t without creating*/
console_t *Con_FindConsole(char *name)
console_t *Con_FindConsole(const char *name)
{
console_t *con;
if (!strcmp(name, "current") && con_current)
@ -155,7 +155,7 @@ console_t *Con_FindConsole(char *name)
return NULL;
}
/*creates a potentially duplicate console_t - please use Con_FindConsole first, as its confusing otherwise*/
console_t *Con_Create(char *name, unsigned int flags)
console_t *Con_Create(const char *name, unsigned int flags)
{
console_t *con;
if (!strcmp(name, "current"))
@ -717,7 +717,7 @@ void Con_PrintCon (console_t *con, char *txt)
else
con->current->time = realtime;
#if defined(_WIN32) && !defined(NOMEDIA)
#if defined(_WIN32) && !defined(NOMEDIA) && !defined(WINRT)
if (con->current)
TTS_SayConString((conchar_t*)(con->current+1));
#endif
@ -1128,18 +1128,26 @@ int Con_DrawInput (console_t *con, qboolean focused, int left, int right, int y,
/*just above that, we have the tab completion list*/
if (con_commandmatch && con_displaypossibilities.value)
{
int lines;
conchar_t *starts[32];
conchar_t *ends[32];
conchar_t *end;
char *cmd;
conchar_t *end, *s;
char *cmd;//, *desc;
int cmdstart;
size_t newlen;
cmdstart = text[1] == '/'?2:1;
end = maskedtext;
if (!con->completionline || con->completionline->length + 512 > con->completionline->maxlength)
{
newlen = (con->completionline?con->completionline->length:0) + 2048;
Z_Free(con->completionline);
con->completionline = Z_Malloc(sizeof(*con->completionline) + newlen*sizeof(conchar_t));
con->completionline->maxlength = newlen;
}
con->completionline->length = 0;
for (i = 1; ; i++)
{
cmd = Cmd_CompleteCommand (text+cmdstart, true, true, i, NULL);
cmd = Cmd_CompleteCommand (text+cmdstart, true, true, i, NULL);//&desc);
if (!cmd)
{
if (i <= 2)
@ -1147,19 +1155,16 @@ int Con_DrawInput (console_t *con, qboolean focused, int left, int right, int y,
break;
}
end = COM_ParseFunString((COLOR_GREEN<<CON_FGSHIFT), va("%s\t", cmd), end, (maskedtext+sizeof(maskedtext)/sizeof(maskedtext[0])-1-end)*sizeof(maskedtext[0]), true);
s = (conchar_t*)(con->completionline+1);
// if (desc)
// end = COM_ParseFunString((COLOR_GREEN<<CON_FGSHIFT), va("^[^2/%s\\tip\\%s^]\t", cmd, desc), s+con->completionline->length, (con->completionline->maxlength-con->completionline->length)*sizeof(maskedtext[0]), true);
// else
end = COM_ParseFunString((COLOR_GREEN<<CON_FGSHIFT), va("^[^2/%s^]\t", cmd), s+con->completionline->length, (con->completionline->maxlength-con->completionline->length)*sizeof(maskedtext[0]), true);
con->completionline->length = end - s;
}
lines = Font_LineBreaks(maskedtext, end, right - left, 32, starts, ends);
while(lines-->0)
{
rhs = left;
y -= Font_CharHeight();
for (cchar = starts[lines]; cchar < ends[lines]; cchar++)
{
rhs = Font_DrawChar(rhs, y, *cchar);
}
}
if (con->completionline->length)
y = Con_DrawConsoleLines(con, con->completionline, left, right, y, 0, selactive, selsx, selex, selsy, seley);
}
return y;
@ -1302,9 +1307,10 @@ void Con_DrawNotify (void)
foo[pos] = i;
//k, build the string properly.
end = COM_ParseFunString(CON_WHITEMASK, foo, markup, sizeof(markup) - sizeof(markup[0]), PFS_KEEPMARKUP | PFS_FORCEUTF8);
end = COM_ParseFunString(CON_WHITEMASK, foo, markup, sizeof(markup) - sizeof(markup[0])-1, PFS_KEEPMARKUP | PFS_FORCEUTF8);
//and overwrite the cursor so that it blinks.
*end = ' '|CON_WHITEMASK;
if (((int)(realtime*con_cursorspeed)&1))
*c = 0xe00b|CON_WHITEMASK;
if (c == end)
@ -1563,6 +1569,7 @@ static int Con_DrawConsoleLines(console_t *con, conline_t *l, int sx, int ex, in
int i;
int x;
if (l != con->completionline)
if (l != con->footerline)
if (l != con->current)
{
@ -1730,18 +1737,18 @@ static int Con_DrawConsoleLines(console_t *con, conline_t *l, int sx, int ex, in
sstart = sx+picw;
send = sstart;
for (i = 0; i < linelength; i++)
send += Font_CharWidth(s[i]);
send = Font_CharEndCoord(font_console, send, s[i]);
//show something on blank lines
if (send == sstart)
send = sstart + Font_CharWidth(' ');
send = Font_CharEndCoord(font_console, send, ' ');
if (y >= seley)
{
send = sstart;
for (i = 0; i < linelength; )
{
send += Font_CharWidth(s[i++]);
send = Font_CharEndCoord(font_console, send, s[i++]);
if (send > selex)
break;
@ -1757,10 +1764,10 @@ static int Con_DrawConsoleLines(console_t *con, conline_t *l, int sx, int ex, in
{
for (i = 0; i < linelength; i++)
{
x = Font_CharWidth(s[i]);
if (sstart + x > selsx)
x = Font_CharEndCoord(font_console, sstart, s[i]);
if (x > selsx)
break;
sstart += x;
sstart = x;
}
con->selstartline = l;
@ -1969,6 +1976,7 @@ char *Con_CopyConsole(qboolean nomarkup, qboolean onlyiflink)
char *result;
int outlen, maxlen;
int finalendoffset;
unsigned int uc;
if (!con->selstartline || !con->selendline)
return NULL;
@ -1989,7 +1997,8 @@ char *Con_CopyConsole(qboolean nomarkup, qboolean onlyiflink)
while (cur > (conchar_t*)(l+1))
{
cur--;
if ((*cur & CON_CHARMASK) == ' ')
uc = (*cur & CON_CHARMASK);
if (uc == ' ' || uc == '\t')
{
cur++;
break;
@ -1999,7 +2008,8 @@ char *Con_CopyConsole(qboolean nomarkup, qboolean onlyiflink)
}
while (finalendoffset < con->selendline->length)
{
if ((((conchar_t*)(l+1))[finalendoffset] & CON_CHARMASK) != ' ')
uc = (((conchar_t*)(l+1))[finalendoffset] & CON_CHARMASK);
if (uc != ' ' && uc != '\t' && ((conchar_t*)(l+1))[finalendoffset] != CON_LINKEND)
finalendoffset++;
else
break;
@ -2023,20 +2033,19 @@ char *Con_CopyConsole(qboolean nomarkup, qboolean onlyiflink)
}
}
//scan forwards to find the end of the selected link
for(lend = (conchar_t*)(con->selendline+1) + finalendoffset; lend < (conchar_t*)(con->selendline+1) + con->selendline->length; lend++)
if (*cur == CON_LINKSTART)
{
if (*lend == CON_LINKEND)
for(lend = (conchar_t*)(con->selendline+1) + finalendoffset; lend < (conchar_t*)(con->selendline+1) + con->selendline->length; lend++)
{
finalendoffset = lend+1 - (conchar_t*)(con->selendline+1);
break;
if (*lend == CON_LINKEND)
{
finalendoffset = lend+1 - (conchar_t*)(con->selendline+1);
break;
}
}
}
if (onlyiflink)
{
if (*cur != CON_LINKSTART)
return NULL;
}
else if (onlyiflink)
return NULL;
maxlen = 1024*1024;
result = Z_Malloc(maxlen+1);

View File

@ -2274,7 +2274,7 @@ typedef struct {
} ddsheader;
texid_tf GL_ReadTextureDDS(char *iname, unsigned char *buffer, int filesize)
texid_tf GL_ReadTextureDDS(const char *iname, unsigned char *buffer, int filesize)
{
extern int gl_filter_min;
extern int gl_filter_max;
@ -2368,7 +2368,7 @@ texid_tf GL_ReadTextureDDS(char *iname, unsigned char *buffer, int filesize)
#endif
#ifdef IMAGEFMT_BLP
texid_tf GL_ReadBLPFile(char *iname, unsigned char *buffer, int filesize)
texid_tf GL_ReadBLPFile(const char *iname, unsigned char *buffer, int filesize, int *width, int *height)
{
extern int gl_filter_min;
extern int gl_filter_max;
@ -2400,8 +2400,8 @@ texid_tf GL_ReadBLPFile(char *iname, unsigned char *buffer, int filesize)
if (memcmp(blp->blp2, "BLP2", 4) || blp->type != 1 || qrenderer != QR_OPENGL)
return r_nulltex;
w = blp->xres;
h = blp->yres;
*width = w = blp->xres;
*height = h = blp->yres;
texnum = GL_AllocNewTexture(iname, w, h, 0);
GL_MTBind(0, GL_TEXTURE_2D, texnum);
@ -2465,10 +2465,11 @@ texid_tf GL_ReadBLPFile(char *iname, unsigned char *buffer, int filesize)
if (!tmpmem)
tmpmem = malloc(4*w*h);
//8bit palette index
//load the rgb data first (8-bit paletted)
for (i = 0; i < w*h; i++)
tmpmem[i] = blp->palette[*in++] | 0xff000000;
//and then change the alpha bits accordingly.
switch(blp->alphadepth)
{
case 0:
@ -2561,7 +2562,7 @@ qbyte *Read32BitImageFile(qbyte *buf, int len, int *width, int *height, qboolean
int w = LittleLong(((int*)buf)[0]);
int h = LittleLong(((int*)buf)[1]);
int i;
if (w >= 4 && h >= 4 && w*h+sizeof(int)*2 == com_filesize)
if (w >= 3 && h >= 4 && w*h+sizeof(int)*2 == com_filesize)
{
qboolean foundalpha = false;
qbyte *in = (qbyte*)((int*)buf+2);
@ -2686,7 +2687,7 @@ static struct
};
int image_width, image_height;
qboolean R_LoadTextureFromMemory(texid_t *tex, int flags, char *iname, char *fname, qbyte *filedata, int filesize)
qboolean R_LoadTextureFromMemory(texid_t *tex, int flags, const char *iname, char *fname, qbyte *filedata, int filesize)
{
qboolean hasalpha;
qbyte *rgbadata;
@ -2700,7 +2701,7 @@ qboolean R_LoadTextureFromMemory(texid_t *tex, int flags, char *iname, char *fna
#ifdef IMAGEFMT_BLP
if (filedata[0] == 'B' && filedata[1] == 'L' && filedata[2] == 'P' && filedata[3] == '2')
{
*tex = GL_ReadBLPFile(iname, filedata, filesize);
*tex = GL_ReadBLPFile(iname, filedata, filesize, &image_width, &image_height);
if (TEXVALID(*tex))
return true;
}
@ -2752,7 +2753,7 @@ qboolean R_LoadTextureFromMemory(texid_t *tex, int flags, char *iname, char *fna
Con_Printf("Unable to read file %s (format unsupported)\n", fname);
return false;
}
texid_t R_LoadHiResTexture(char *name, char *subpath, unsigned int flags)
texid_t R_LoadHiResTexture(const char *name, const char *subpath, unsigned int flags)
{
qboolean alphaed;
char *buf;
@ -2975,7 +2976,7 @@ texid_t R_LoadHiResTexture(char *name, char *subpath, unsigned int flags)
}
return r_nulltex;
}
texid_t R_LoadReplacementTexture(char *name, char *subpath, unsigned int flags)
texid_t R_LoadReplacementTexture(const char *name, const char *subpath, unsigned int flags)
{
if (!gl_load24bit.value)
return r_nulltex;
@ -2983,7 +2984,7 @@ texid_t R_LoadReplacementTexture(char *name, char *subpath, unsigned int flags)
}
extern cvar_t r_shadow_bumpscale_bumpmap;
texid_t R_LoadBumpmapTexture(char *name, char *subpath)
texid_t R_LoadBumpmapTexture(const char *name, const char *subpath)
{
char *buf, *data;
texid_t tex;

View File

@ -26,7 +26,8 @@ struct eventlist_s
IEV_KEYDOWN,
IEV_KEYRELEASE,
IEV_MOUSEABS,
IEV_MOUSEDELTA
IEV_MOUSEDELTA,
IEV_JOYAXIS
} type;
int devid;
@ -41,6 +42,11 @@ struct eventlist_s
{
int scancode, unicode;
} keyboard;
struct
{
int axis;
float value;
} joy;
};
} eventlist[EVENTQUEUELENGTH];
volatile int events_avail; /*volatile to make sure the cc doesn't try leaving these cached in a register*/
@ -67,7 +73,7 @@ struct mouse_s
M_MOUSE, //using deltas
M_TOUCH //using absolutes
} type;
int qdeviceid;
int qdeviceid; //so we can just use pointers.
vec2_t oldpos;
vec2_t downpos;
float moveddist; //how far it has moved while held. this provides us with our emulated mouse1 when they release the press
@ -77,7 +83,13 @@ struct mouse_s
int down;
} ptr[MAXPOINTERS];
#define MAXJOYAXIS 6
#define MAXJOYSTICKS 4
struct joy_s
{
int qdeviceid;
int axis[MAXJOYAXIS];
} joy[MAXJOYSTICKS];
void IN_Shutdown(void)
{
@ -88,20 +100,25 @@ void IN_ReInit(void)
{
int i;
events_avail = 0;
events_used = 0;
for (i = 0; i < MAXPOINTERS; i++)
{
ptr[i].type = M_INVALID;
ptr[i].qdeviceid = i;
}
for (i = 0; i < MAXJOYSTICKS; i++)
{
joy[i].qdeviceid = i;
}
INS_ReInit();
}
void IN_Init(void)
{
events_avail = 0;
events_used = 0;
Cvar_Register (&m_filter, "input controls");
Cvar_Register (&m_accel, "input controls");
Cvar_Register (&m_forcewheel, "Input Controls");
@ -114,6 +131,40 @@ void IN_Init(void)
INS_Init();
}
//tells the keys.c code whether the cursor is currently active, causing mouse clicks instead of binds.
qboolean IN_MouseDevIsTouch(int devid)
{
if (devid < MAXPOINTERS)
return ptr[devid].type == M_TOUCH;
return false;
}
//there was no ui to click on at least...
//translates MOUSE1 press events into begin-look-or-strafe events.
//translates to MOUSE2 accordingly
//returns 0 if it ate it completely.
int IN_TranslateMButtonPress(int devid)
{
int ret;
if (!ptr[devid].down)
{
//set the cursor-pressed state, so we begin to look/strafe around
ptr[devid].down = 1;
ptr[devid].moveddist = 0;
ptr[devid].downpos[0] = ptr[devid].oldpos[0];
ptr[devid].downpos[1] = ptr[devid].oldpos[1];
ptr[devid].delta[0] = 0;
ptr[devid].delta[1] = 0;
ret = 0; //eat it
}
else
{
//this is the key binding that the press should use
ret = (m_strafeonright.ival && ptr[devid].downpos[0] > vid.pixelwidth/2)?K_MOUSE2:K_MOUSE1;
}
return ret;
}
/*a 'pointer' is either a multitouch pointer, or a separate device
note that mice use the keyboard button api, but separate devices*/
void IN_Commands(void)
@ -137,39 +188,15 @@ void IN_Commands(void)
else
{
if (ev->type == IEV_KEYDOWN)
{
ptr[ev->devid].down = 1;
ptr[ev->devid].moveddist = 0;
ptr[ev->devid].downpos[0] = ptr[ev->devid].oldpos[0];
ptr[ev->devid].downpos[1] = ptr[ev->devid].oldpos[1];
ptr[ev->devid].delta[0] = 0;
ptr[ev->devid].delta[1] = 0;
if (ev->mouse.tsize > m_fatpressthreshold.value)
{
int key = (m_strafeonright.ival && ptr[ev->devid].downpos[0] > vid.pixelwidth/2)?K_MOUSE2:K_MOUSE1;
Key_Event(ev->devid, key, 0, true);
ptr[ev->devid].down = 2;
}
}
Key_Event(ev->devid, ev->keyboard.scancode, ev->keyboard.unicode, ev->type == IEV_KEYDOWN);
else
{
if (ptr[ev->devid].down > 1)
if (ptr[ev->devid].down == 1 || ptr[ev->devid].moveddist < m_slidethreshold.value)
{
int key = (m_strafeonright.ival && ptr[ev->devid].downpos[0] > vid.pixelwidth/2)?K_MOUSE2:K_MOUSE1;
Key_Event(ev->devid, key, 0, false);
ptr[ev->devid].down = 1;
}
if (ptr[ev->devid].down)
{
if (ptr[ev->devid].moveddist < m_slidethreshold.value)
{
/*if its on the right, make it a mouse2*/
int key = (m_strafeonright.ival && ptr[ev->devid].downpos[0] > vid.pixelwidth/2)?K_MOUSE2:K_MOUSE1;
Key_Event(ev->devid, key, 0, true);
Key_Event(ev->devid, key, 0, false);
}
ptr[ev->devid].down = 2;
Key_Event(ev->devid, K_MOUSE1, 0, true);
}
Key_Event(ev->devid, K_MOUSE1, 0, false);
ptr[ev->devid].down = 0;
}
break;
@ -177,6 +204,9 @@ void IN_Commands(void)
}
Key_Event(ev->devid, ev->keyboard.scancode, ev->keyboard.unicode, ev->type == IEV_KEYDOWN);
break;
case IEV_JOYAXIS:
joy[ev->devid].axis[ev->joy.axis] = ev->joy.value;
break;
case IEV_MOUSEDELTA:
if (ev->devid < MAXPOINTERS)
{
@ -237,15 +267,13 @@ void IN_Commands(void)
if (ptr[ev->devid].down > 1 && ev->mouse.tsize < m_fatpressthreshold.value)
{
int key = (m_strafeonright.ival && ptr[ev->devid].downpos[0] > vid.pixelwidth/2)?K_MOUSE2:K_MOUSE1;
Key_Event(ev->devid, key, 0, false);
ptr[ev->devid].down = 1;
Key_Event(ev->devid, K_MOUSE1, 0, false);
}
if (ptr[ev->devid].down == 1 && ev->mouse.tsize > m_fatpressthreshold.value)
{
int key = (m_strafeonright.ival && ptr[ev->devid].downpos[0] > vid.pixelwidth/2)?K_MOUSE2:K_MOUSE1;
Key_Event(ev->devid, key, 0, true);
ptr[ev->devid].down = 2;
Key_Event(ev->devid, K_MOUSE1, 0, true);
}
}
break;
@ -407,15 +435,15 @@ void IN_MoveMouse(struct mouse_s *mouse, float *movements, int pnum)
}
else
{
//if game is not focused, kill any mouse look
if (Key_Dest_Has(~kdm_game))
if (mx || my)
if (CSQC_MouseMove(mx, my, mouse->qdeviceid))
{
mx = 0;
my = 0;
}
if (mx || my)
if (CSQC_MouseMove(mx, my, mouse->qdeviceid))
//if game is not focused, kill any mouse look
if (Key_Dest_Has(~kdm_game))
{
mx = 0;
my = 0;
@ -487,12 +515,109 @@ void IN_MoveMouse(struct mouse_s *mouse, float *movements, int pnum)
}
}
void IN_Move (float *movements, int pnum)
static float joydeadzone(float mag, float deadzone)
{
if (mag > 1) //erg?
mag = 1;
if (mag > deadzone)
{
mag -= deadzone;
mag = mag / (1.f-deadzone);
}
else
mag = 0;
return mag;
}
void IN_MoveJoystick(struct joy_s *joy, float *movements, int pnum, float frametime)
{
float mag;
vec3_t jlook, jstrafe;
int wpnum;
/*each device will be processed when its player comes to be processed*/
wpnum = cl.splitclients;
if (wpnum < 1)
wpnum = 1;
if (cl_forcesplitclient.ival)
wpnum = (cl_forcesplitclient.ival-1) % wpnum;
else
wpnum = joy->qdeviceid % wpnum;
if (wpnum != pnum)
return;
jlook[0] = joy->axis[0];
jlook[1] = joy->axis[1];
jlook[2] = joy->axis[2];
jstrafe[0] = joy->axis[3];
jstrafe[1] = joy->axis[4];
jstrafe[2] = joy->axis[5];
//uses a radial deadzone for x+y axis, and separate out the z axis, just because most controllers are 2d affairs with any 3rd axis being a separate knob.
//deadzone values are stolen from microsoft's xinput documentation. they seem quite large to me - I guess that means that xbox controllers are just dodgy imprecise crap with excessive amounts of friction and finger grease.
mag = joydeadzone(sqrt(jlook[0]*jlook[0] + jlook[1]*jlook[1]), 0.239);
mag = pow(mag, 2);
jlook[0] *= mag;
jlook[1] *= mag;
mag = joydeadzone(fabs(jlook[2]), 0.00092);
jlook[2] *= mag;
mag = joydeadzone(sqrt(jstrafe[0]*jstrafe[0] + jstrafe[1]*jstrafe[1]), 0.265);
mag = pow(mag, 2);
jstrafe[0] *= mag;
jstrafe[1] *= mag;
mag = joydeadzone(fabs(jstrafe[2]), 0.00092);
jstrafe[2] *= mag;
if (Key_Dest_Has(~kdm_game))
{
VectorClear(jlook);
VectorClear(jstrafe);
}
VectorScale(jlook, frametime, jlook);
VectorScale(jstrafe, frametime, jstrafe);
if (!movements) //if this is null, gamecode should still get inputs, just no camera looking or anything.
return;
//angle changes
cl.playerview[pnum].viewanglechange[YAW] -= m_yaw.value * jlook[0];
cl.playerview[pnum].viewanglechange[PITCH] += m_pitch.value * jlook[1];
// cl.playerview[pnum].viewanglechange[ROLL] += m_roll.value * jlook[2]; //this would be too weird.
if (in_mlook.state[pnum] & 1)
V_StopPitchDrift (&cl.playerview[pnum]);
//movement
movements[1] += m_side.value * jstrafe[0]; //x=right=1
movements[0] -= m_forward.value * jstrafe[1]; //y=forward=0
movements[2] += m_side.value * jstrafe[2]; //z=up=2
}
void IN_Move (float *movements, int pnum, float frametime)
{
int i;
INS_Move(movements, pnum);
for (i = 0; i < MAXPOINTERS; i++)
IN_MoveMouse(&ptr[i], movements, pnum);
for (i = 0; i < MAXJOYSTICKS; i++)
IN_MoveJoystick(&joy[i], movements, pnum, frametime);
}
void IN_JoystickAxisEvent(int devid, int axis, float value)
{
struct eventlist_s *ev = in_newevent();
if (!ev)
return;
ev->type = IEV_JOYAXIS;
ev->devid = devid;
ev->joy.axis = axis;
ev->joy.value = value;
in_finishevent();
}
void IN_KeyEvent(int devid, int down, int keycode, int unicode)

View File

@ -48,6 +48,214 @@ void IN_DeactivateMouse(void)
#endif
}
#if SDL_MAJOR_VERSION >= 2
#define MAX_JOYSTICKS 4
static struct sdljoy_s
{
//fte doesn't distinguish between joysticks and controllers.
//in sdl, controllers are some glorified version of joysticks apparently.
char *devname;
SDL_Joystick *joystick;
SDL_GameController *controller;
SDL_JoystickID id;
} sdljoy[MAX_JOYSTICKS];
//the enumid is the value for the open function rather than the working id.
static void J_ControllerAdded(int enumid)
{
char *cname;
int i;
for (i = 0; i < MAX_JOYSTICKS; i++)
if (j_controller[i] == NULL)
break;
if (i == MAX_JOYSTICKS)
return;
sdljoy[i].controller = SDL_GameControllerOpen(enumid);
if (!sdljoy[i].controller)
return;
sdljoy[i].joystick = SDL_GameControllerGetJoystick(sdljoy[i].controller);
sdljoy[i].id = SDL_JoystickInstanceID(sdljoy[i].joystick);
cname = SDL_GameControllerName(sdljoy[i].controller);
if (!cname)
cname = "Unknown Controller";
Con_Printf("Found new controller (%i): %s\n", i, cname);
sdljoy[i].devname = Z_StrDup(cname);
}
static void J_JoystickAdded(int enumid)
{
char *cname;
int i;
for (i = 0; i < MAX_JOYSTICKS; i++)
if (sdljoy[i].joystick == NULL)
break;
if (i == MAX_JOYSTICKS)
return;
sdljoy[i].joystick = SDL_JoystickOpen(enumid);
if (!sdljoy[i].joystick)
return;
sdljoy[i].id = SDL_JoystickInstanceID(sdljoy[i].joystick);
cname = SDL_GameControllerName(sdljoy[i].controller);
if (!cname)
cname = "Unknown Joystick";
Con_Printf("Found new joystick (%i): %s\n", i, cname);
}
static struct sdljoy_s *J_DevId(int jid)
{
for (i = 0; i < MAX_JOYSTICKS; i++)
if (sdljoy[i].joystick && sdljoy[i].id == jid)
return &sdljoy[i];
return NULL;
}
static void J_ControllerAxis(int jid, int axis, int value)
{
int axismap[] = {0,1,3,4,2,5};
struct sdljoy_s *joy = J_DevId(jid);
if (joy && axis < sizeof(axismap)/sizeof(axismap[0]))
IN_JoystickAxisEvent(joy - sdljoy, axismap[axis], value / 32767.0);
}
static void J_JoystickAxis(int jid, int axis, int value)
{
int axismap[] = {0,1,3,4,2,5};
struct sdljoy_s *joy = J_DevId(jid);
if (joy && axis < sizeof(axismap)/sizeof(axismap[0]))
IN_JoystickAxisEvent(joy - sdljoy, axismap[axis], value / 32767.0);
}
//we don't do hats and balls and stuff.
static void J_ControllerButton(int jid, int button, qboolean pressed)
{
//controllers have reliable button maps.
//but that doesn't meant that fte has specific k_ names for those buttons, but the mapping should be reliable, at least until they get mapped to proper k_ values.
int buttonmap[] = {
#if 0
//NOTE: DP has specific 'X360' buttons for many of these. of course, its not an exact mapping...
K_X360_A, /*SDL_CONTROLLER_BUTTON_A*/
K_X360_B, /*SDL_CONTROLLER_BUTTON_B*/
K_X360_X, /*SDL_CONTROLLER_BUTTON_X*/
K_X360_Y, /*SDL_CONTROLLER_BUTTON_Y*/
K_X360_BACK, /*SDL_CONTROLLER_BUTTON_BACK*/
K_AUX2, /*SDL_CONTROLLER_BUTTON_GUIDE*/
K_X360_START, /*SDL_CONTROLLER_BUTTON_START*/
K_X360_LEFT_THUMB, /*SDL_CONTROLLER_BUTTON_LEFTSTICK*/
K_X360_RIGHT_THUMB, /*SDL_CONTROLLER_BUTTON_RIGHTSTICK*/
K_X360_LEFT_SHOULDER, /*SDL_CONTROLLER_BUTTON_LEFTSHOULDER*/
K_X360_RIGHT_SHOULDER, /*SDL_CONTROLLER_BUTTON_RIGHTSHOULDER*/
K_X360_DPAD_UP, /*SDL_CONTROLLER_BUTTON_DPAD_UP*/
K_X360_DPAD_DOWN, /*SDL_CONTROLLER_BUTTON_DPAD_DOWN*/
K_X360_DPAD_LEFT, /*SDL_CONTROLLER_BUTTON_DPAD_LEFT*/
K_X360_DPAD_RIGHT /*SDL_CONTROLLER_BUTTON_DPAD_RIGHT*/
#else
K_JOY1, /*SDL_CONTROLLER_BUTTON_A*/
K_JOY2, /*SDL_CONTROLLER_BUTTON_B*/
K_JOY3, /*SDL_CONTROLLER_BUTTON_X*/
K_JOY4, /*SDL_CONTROLLER_BUTTON_Y*/
K_AUX1, /*SDL_CONTROLLER_BUTTON_BACK*/
K_AUX2, /*SDL_CONTROLLER_BUTTON_GUIDE*/
K_AUX3, /*SDL_CONTROLLER_BUTTON_START*/
K_AUX4, /*SDL_CONTROLLER_BUTTON_LEFTSTICK*/
K_AUX5, /*SDL_CONTROLLER_BUTTON_RIGHTSTICK*/
K_AUX6, /*SDL_CONTROLLER_BUTTON_LEFTSHOULDER*/
K_AUX7, /*SDL_CONTROLLER_BUTTON_RIGHTSHOULDER*/
K_AUX8, /*SDL_CONTROLLER_BUTTON_DPAD_UP*/
K_AUX9, /*SDL_CONTROLLER_BUTTON_DPAD_DOWN*/
K_AUX10, /*SDL_CONTROLLER_BUTTON_DPAD_LEFT*/
K_AUX11 /*SDL_CONTROLLER_BUTTON_DPAD_RIGHT*/
#endif
};
struct sdljoy_s *joy = J_DevId(jid);
if (joy && button < sizeof(buttonmap)/sizeof(buttonmap[0]))
IN_KeyEvent(joy - sdljoy, pressed, buttonmap[button], 0);
}
static void J_JoystickButton(int jid, int button, qboolean pressed)
{
//generic joysticks have no specific mappings. they're really random like that.
int buttonmap[] = {
K_JOY1,
K_JOY2,
K_JOY3,
K_JOY4,
K_AUX1,
K_AUX2,
K_AUX3,
K_AUX4,
K_AUX5,
K_AUX6,
K_AUX7,
K_AUX8,
K_AUX9,
K_AUX10,
K_AUX11,
K_AUX12,
K_AUX13,
K_AUX14,
K_AUX15,
K_AUX16,
K_AUX17,
K_AUX18,
K_AUX19,
K_AUX20,
K_AUX21,
K_AUX22,
K_AUX23,
K_AUX24,
K_AUX25,
K_AUX26,
K_AUX27,
K_AUX28,
K_AUX29,
K_AUX30,
K_AUX31,
K_AUX32
};
struct sdljoy_s *joy = J_DevId(jid);
if (joy && button < sizeof(buttonmap)/sizeof(buttonmap[0]))
IN_KeyEvent(joy - sdljoy, pressed, buttonmap[button], 0);
}
static void J_Kill(int jid, qboolean verbose)
{
int i;
struct sdljoy_s *joy = J_DevId(jid);
if (!joy)
return;
//make sure all the axis are nulled out, to avoid surprises.
for (i = 0; i < 6; i++)
IN_JoystickAxisEvent(joy - sdljoy, i, 0);
if (joy->controller)
{
for (i = 0; i < 32; i++)
J_ControllerButton(jid, i, false);
Con_Printf("Controller unplugged(%i): %s\n", joy - sdljoy, joy->devname);
SDL_GameControllerClose(joy->controller);
}
else
{
for (i = 0; i < 32; i++)
J_JoystickButton(jid, i, false);
Con_Printf("Joystick unplugged(%i): %s\n", joy - sdljoy, joy->devname);
SDL_JoystickClose(joy->joystick);
}
joy->controller = NULL;
joy->joystick = NULL;
Z_Free(joy->devname);
joy->devname = NULL;
}
static void J_KillAll(void)
{
int i;
for (i = 0; i < MAX_JOYSTICKS; i++)
J_Kill(sdljoy[i].id, false);
}
#endif
#if SDL_MAJOR_VERSION >= 2
unsigned int MySDL_MapKey(unsigned int sdlkey)
{
@ -620,6 +828,41 @@ void Sys_SendKeyEvents(void)
case SDL_QUIT:
Cbuf_AddText("quit\n", RESTRICT_LOCAL);
break;
#if SDL_MAJOR_VERSION >= 2
//actually, joysticks *should* work with sdl1 as well, but there are some differences (like no hot plugging, I think).
case SDL_JOYAXISMOTION:
break;
// case SDL_JOYBALLMOTION:
// case SDL_JOYHATMOTION:
break;
case SDL_JOYBUTTONDOWN:
case SDL_JOYBUTTONUP:
J_JoystickButton(event.jbutton.which, event.jbutton.button, event.type==SDL_CONTROLLERBUTTONDOWN);
break;
case SDL_JOYDEVICEADDED:
J_JoystickAdded(event.jdevice.which);
break;
case SDL_JOYDEVICEREMOVED:
J_Kill(event.jdevice.which, true);
break;
case SDL_CONTROLLERAXISMOTION:
J_ControllerAxis(event.caxis.which, event.caxis.axis, event.caxis.value);
break;
case SDL_CONTROLLERBUTTONDOWN:
case SDL_CONTROLLERBUTTONUP:
J_ControllerButton(event.cbutton.which, event.cbutton.button, event.type==SDL_CONTROLLERBUTTONDOWN);
break;
case SDL_CONTROLLERDEVICEADDED:
J_ControllerAdded(event.cdevice.which);
break;
case SDL_CONTROLLERDEVICEREMOVED:
J_Kill(event.cdevice.which, true);
break;
// case SDL_CONTROLLERDEVICEREMAPPED:
// break;
#endif
}
}
}
@ -632,6 +875,11 @@ void Sys_SendKeyEvents(void)
void INS_Shutdown (void)
{
IN_DeactivateMouse();
#if SDL_MAJOR_VERSION >= 2
J_KillAll();
SDL_QuitSubSystem(SDL_INIT_JOYSTICK|SDL_INIT_GAMECONTROLLER);
#endif
}
void INS_ReInit (void)
@ -654,6 +902,9 @@ void INS_Move(float *movements, int pnum)
}
void INS_Init (void)
{
#if SDL_MAJOR_VERSION >= 2
SDL_InitSubSystem(SDL_INIT_JOYSTICK|SDL_INIT_GAMECONTROLLER);
#endif
}
void INS_Accumulate(void) //input polling
{

View File

@ -23,7 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "quakedef.h"
#include "winquake.h"
//#include "dosisms.h"
#ifndef WINRT
#define USINGRAWINPUT
#ifdef USINGRAWINPUT
@ -2113,3 +2113,4 @@ void INS_TranslateKeyEvent(WPARAM wParam, LPARAM lParam, qboolean down, int qdev
Key_Event (qdeviceid, qcode, unicode, down);
}
#endif

View File

@ -28,7 +28,10 @@ void IN_Shutdown (void);
void IN_Commands (void);
// oportunity for devices to stick commands on the script buffer
void IN_Move (float *movements, int pnum);
qboolean IN_MouseDevIsTouch(int devid); //check if a mouse devid is a touch screen, and thus if we should check the cursor and simulate a ui event or not
int IN_TranslateMButtonPress(int devid); //allow the touchscreen code to swallow mouse1 as a begin-looking event
void IN_Move (float *movements, int pnum, float frametime);
// add additional movement on top of the keyboard move cmd
extern cvar_t in_xflip;

View File

@ -53,7 +53,10 @@ int keyshift[K_MAX]; // key to map to if shift held down in console
int key_repeats[K_MAX]; // if > 1, it is autorepeating
qboolean keydown[K_MAX];
qboolean deltaused[K_MAX][KEY_MODIFIERSTATES];
#define MAX_INDEVS 8
char *releasecommand[K_MAX][MAX_INDEVS]; //this is the console command to be invoked when the key is released. should free it.
qbyte releasecommandlevel[K_MAX][MAX_INDEVS]; //and this is the cbuf level it is to be run at.
void Con_Selectioncolour_Callback(struct cvar_s *var, char *oldvalue);
@ -721,6 +724,12 @@ void Key_DefaultLinkClicked(char *text, char *info)
Cbuf_AddText(va("\nplaydemo %s\n", c), RESTRICT_LOCAL);
return;
}
c = Info_ValueForKey(info, "map");
if (*c && !strchr(c, ';') && !strchr(c, '\n'))
{
Cbuf_AddText(va("\nmap %s\n", c), RESTRICT_LOCAL);
return;
}
c = Info_ValueForKey(info, "cmd");
if (*c && !strchr(c, ';') && !strchr(c, '\n'))
{
@ -751,12 +760,19 @@ void Key_DefaultLinkClicked(char *text, char *info)
Con_Footerf(false, "%s", c);
return;
}
if (!*info && *text == '/')
//if there's no info and the text starts with a leading / then insert it as a suggested/completed console command
//skip any leading colour code.
if (text[0] == '^' && text[1] >= '0' && text[1] <= '9')
text+=2;
if (*text == '/')
{
int tlen = info - text;
Z_Free(key_lines[edit_line]);
key_lines[edit_line] = BZ_Malloc(strlen(text) + 2);
key_lines[edit_line] = BZ_Malloc(tlen + 2);
key_lines[edit_line][0] = ']';
strcpy(key_lines[edit_line]+1, text);
memcpy(key_lines[edit_line]+1, text, tlen);
key_lines[edit_line][1+tlen] = 0;
key_linepos = strlen(key_lines[edit_line]);
return;
}
@ -1424,7 +1440,7 @@ the given string. Single ascii characters return themselves, while
the K_* names are matched up.
===================
*/
int Key_StringToKeynum (char *str, int *modifier)
int Key_StringToKeynum (const char *str, int *modifier)
{
keyname_t *kn;
char *underscore;
@ -1670,9 +1686,12 @@ void Key_BindLevel_f (void)
return;
}
if (modifier == ~0) //modifier unspecified. default to no modifier
modifier = 0;
if (c == 2)
{
if (keybindings[b])
if (keybindings[b][modifier])
Con_Printf ("\"%s\" (%i)= \"%s\"\n", Cmd_Argv(1), bindcmdlevel[b][modifier], keybindings[b][modifier] );
else
Con_Printf ("\"%s\" is not bound\n", Cmd_Argv(1) );
@ -1899,89 +1918,27 @@ Should NOT be called during an interrupt!
*/
void Key_Event (int devid, int key, unsigned int unicode, qboolean down)
{
char *kb;
int bl, bkey;
char *dc, *uc;
char p[16];
char cmd[1024];
int keystate, oldstate;
int modifierstate;
int conkey = consolekeys[key] || (unicode && (key != '`' || key_linepos>1)); //if the input line is empty, allow ` to toggle the console, otherwise enter it as actual text.
// Con_Printf ("%i : %i : %i\n", key, unicode, down); //@@@
oldstate = KeyModifier(keydown[K_LSHIFT]|keydown[K_RSHIFT], keydown[K_LALT]|keydown[K_RALT], keydown[K_LCTRL]|keydown[K_RCTRL]);
//bug: my keyboard doesn't fire release events if the other shift is already pressed.
//hack around that by just force-releasing eg left if right is pressed, but only on inital press to avoid potential infinite loops if the state got bad.
//ctrl+alt don't seem to have the problem.
//you can still see a difference in that
if (key == K_LSHIFT && !keydown[K_LSHIFT] && keydown[K_RSHIFT])
Key_Event(devid, K_RSHIFT, 0, false);
if (key == K_RSHIFT && !keydown[K_RSHIFT] && keydown[K_LSHIFT])
Key_Event(devid, K_LSHIFT, 0, false);
modifierstate = KeyModifier(keydown[K_LSHIFT]|keydown[K_RSHIFT], keydown[K_LALT]|keydown[K_RALT], keydown[K_LCTRL]|keydown[K_RCTRL]);
keydown[key] = down;
if (key == K_LSHIFT || key == K_RSHIFT || key == K_LALT || key == K_RALT || key == K_LCTRL || key == K_RCTRL)
{
int k;
keystate = KeyModifier(keydown[K_LSHIFT]|keydown[K_RSHIFT], keydown[K_LALT]|keydown[K_RALT], keydown[K_LCTRL]|keydown[K_RCTRL]);
for (k = 0; k < K_MAX; k++)
{ //go through the old state removing all depressed keys. they are all up now.
if (k == K_LSHIFT || k == K_RSHIFT || k == K_LALT || k == K_RALT || k == K_LCTRL || k == K_RCTRL)
continue;
if (deltaused[k][oldstate])
{
if (keybindings[k][oldstate] == keybindings[k][keystate] || !strcmp(keybindings[k][oldstate], keybindings[k][keystate]))
{ //bindings match. skip this key
// Con_Printf ("keeping bind %i\n", k); //@@@
deltaused[k][oldstate] = false;
deltaused[k][keystate] = true;
continue;
}
// Con_Printf ("removing bind %i\n", k); //@@@
deltaused[k][oldstate] = false;
kb = keybindings[k][oldstate];
if (kb && kb[0] == '+')
{
Q_snprintfz (cmd, sizeof(cmd), "-%s %i\n", kb+1, k+oldstate*256);
Cbuf_AddText (cmd, bindcmdlevel[k][oldstate]);
}
if (keyshift[k] != k)
{
kb = keybindings[keyshift[k]][oldstate];
if (kb && kb[0] == '+')
{
Q_snprintfz (cmd, sizeof(cmd), "-%s %i\n", kb+1, k+oldstate*256);
Cbuf_AddText (cmd, bindcmdlevel[k][oldstate]);
}
}
if (keydown[k] && !Key_Dest_Has(~kdm_game))
{
deltaused[k][keystate] = true;
// Con_Printf ("adding bind %i\n", k); //@@@
kb = keybindings[k][keystate];
if (kb)
{
if (kb[0] == '+')
{ // button commands add keynum as a parm
Q_snprintfz (cmd, sizeof(cmd), "%s %i\n", kb, k+keystate*256);
Cbuf_AddText (cmd, bindcmdlevel[k][keystate]);
}
else
{
Cbuf_AddText (kb, bindcmdlevel[k][keystate]);
Cbuf_AddText ("\n", bindcmdlevel[k][keystate]);
}
}
}
}
}
keystate = oldstate = 0;
}
else
keystate = oldstate;
if (!down)
key_repeats[key] = 0;
@ -2011,7 +1968,8 @@ void Key_Event (int devid, int key, unsigned int unicode, qboolean down)
{
if (down)
{
Con_ToggleConsole_Force();
if (!Key_Dest_Has(kdm_console)) //don't toggle it when the console is already down. this allows typing blind to not care if its already active.
Con_ToggleConsole_Force();
return;
}
}
@ -2104,35 +2062,12 @@ void Key_Event (int devid, int key, unsigned int unicode, qboolean down)
Media_Send_KeyEvent(NULL, key, unicode, down?0:1);
#endif
if (!deltaused[key][keystate]) //this wasn't down, so don't make it leave down state.
return;
deltaused[key][keystate] = false;
if (key == K_RALT) //simulate a singular alt for binds. really though, this code should translate to csqc/menu keycodes and back to resolve the weirdness instead.
key = K_ALT;
if (key == K_RCTRL) //simulate a singular alt for binds. really though, this code should translate to csqc/menu keycodes and back to resolve the weirdness instead.
key = K_CTRL;
if (key == K_RSHIFT)//simulate a singular alt for binds. really though, this code should translate to csqc/menu keycodes and back to resolve the weirdness instead.
key = K_SHIFT;
if (devid)
Q_snprintfz (p, sizeof(p), "p %i ", devid+1);
else
*p = 0;
kb = keybindings[key][keystate];
if (kb && kb[0] == '+')
uc = releasecommand[key][devid%MAX_INDEVS];
if (uc) //this wasn't down, so don't crash on bad commands.
{
Q_snprintfz (cmd, sizeof(cmd), "-%s%s %i\n", p, kb+1, key+oldstate*256);
Cbuf_AddText (cmd, bindcmdlevel[key][keystate]);
}
if (keyshift[key] != key)
{
kb = keybindings[keyshift[key]][keystate];
if (kb && kb[0] == '+')
{
Q_snprintfz (cmd, sizeof(cmd), "-%s%s %i\n", p, kb+1, key+oldstate*256);
Cbuf_AddText (cmd, bindcmdlevel[key][keystate]);
}
releasecommand[key][devid%MAX_INDEVS] = NULL;
Cbuf_AddText (uc, releasecommandlevel[key][devid%MAX_INDEVS]);
Z_Free(uc);
}
return;
}
@ -2197,47 +2132,88 @@ void Key_Event (int devid, int key, unsigned int unicode, qboolean down)
if (key_repeats[key] > 1)
return;
deltaused[key][keystate] = true;
if (devid)
Q_snprintfz (p, sizeof(p), "p %i ", devid+1);
else
*p = 0;
if (key == K_RALT) //simulate a singular alt for binds. really though, this code should translate to csqc/menu keycodes and back to resolve the weirdness instead.
key = K_ALT;
if (key == K_RCTRL) //simulate a singular alt for binds. really though, this code should translate to csqc/menu keycodes and back to resolve the weirdness instead.
key = K_CTRL;
if (key == K_RSHIFT)//simulate a singular alt for binds. really though, this code should translate to csqc/menu keycodes and back to resolve the weirdness instead.
key = K_SHIFT;
dc = keybindings[key][modifierstate];
bl = bindcmdlevel[key][modifierstate];
if ((key == K_MOUSE1 || key == K_MOUSE2) && 1)
//simulate singular shift+alt+ctrl for binds (no left/right). really though, this code should translate to csqc/menu keycodes and back to resolve the weirdness instead.
if (key == K_RALT && (!dc || !*dc))
{
int nkey = Sbar_TranslateHudClick();
if (nkey)
{
//handle +/- events 'properly' the only safe way we can - by releasing them instantly and discarding the mouse-up event.
Key_Event(devid, nkey, 0, true);
Key_Event(devid, nkey, 0, false);
return;
}
bkey = K_LALT;
dc = keybindings[bkey][modifierstate];
bl = bindcmdlevel[bkey][modifierstate];
}
kb = keybindings[key][keystate];
if (kb)
else if (key == K_RCTRL && (!dc || !*dc))
{
if (kb[0] == '+')
{ // button commands add keynum as a parm
Q_snprintfz (cmd, sizeof(cmd), "+%s%s %i\n", p, kb+1, key+oldstate*256);
Cbuf_AddText (cmd, bindcmdlevel[key][keystate]);
}
bkey = K_LCTRL;
dc = keybindings[bkey][modifierstate];
bl = bindcmdlevel[bkey][modifierstate];
}
else if (key == K_RSHIFT && (!dc || !*dc))
{
bkey = K_LSHIFT;
dc = keybindings[bkey][modifierstate];
bl = bindcmdlevel[bkey][modifierstate];
}
else
bkey = key;
if (key == K_MOUSE1 && IN_MouseDevIsTouch(devid))
{
dc = SCR_ShowPics_ClickCommand(mousecursor_x, mousecursor_y);
if (dc)
bl = RESTRICT_INSECURE;
else
{
if (*p)Cbuf_AddText (p, bindcmdlevel[key][keystate]);
Cbuf_AddText (kb, bindcmdlevel[key][keystate]);
Cbuf_AddText ("\n", bindcmdlevel[key][keystate]);
int bkey = Sbar_TranslateHudClick();
if (bkey)
{
dc = keybindings[bkey][modifierstate];
bl = bindcmdlevel[bkey][modifierstate];
}
}
if (!dc) //no buttons to click,
{
bkey = IN_TranslateMButtonPress(devid);
if (bkey)
{
dc = keybindings[bkey][modifierstate];
bl = bindcmdlevel[bkey][modifierstate];
}
else
return;
}
}
if (!dc)
dc = "";
if (dc[0] == '+')
{
uc = va("-%s%s %i\n", p, dc+1, bkey);
dc = va("+%s%s %i\n", p, dc+1, bkey);
}
else
{
uc = NULL;
dc = va("%s%s\n", p, dc);
}
//don't mess up if we ran out of devices, just silently release the one that it conflicted with (and only if its in conflict).
if (releasecommand[key][devid%MAX_INDEVS] && (!uc || strcmp(uc, releasecommand[key][devid%MAX_INDEVS])))
{
Cbuf_AddText (releasecommand[key][devid%MAX_INDEVS], releasecommandlevel[key][devid%MAX_INDEVS]);
Z_Free(releasecommand[key][devid%MAX_INDEVS]);
releasecommand[key][devid%MAX_INDEVS] = NULL;
}
Cbuf_AddText (dc, bl);
if (uc)
releasecommand[key][devid%MAX_INDEVS] = Z_StrDup(uc);
releasecommandlevel[key][devid%MAX_INDEVS] = bl;
}
/*

View File

@ -429,7 +429,7 @@ void M_AddItemsToDownloadMenu(menu_t *m)
break;
if (!mo)
{
MC_AddConsoleCommand(m, 6*8, y, path+prefixlen, va("menu_download \"%s/\"", path));
MC_AddConsoleCommand(m, 6*8, 170, y, path+prefixlen, va("menu_download \"%s/\"", path));
y += 8;
}
}
@ -445,9 +445,9 @@ void M_AddItemsToDownloadMenu(menu_t *m)
}
y+=4;
MC_AddCommand(m, 0, y, " Back", MD_PopMenu);
MC_AddCommand(m, 0, 170, y, "Back", MD_PopMenu);
y+=8;
MC_AddCommand(m, 0, y, " Apply", MD_ApplyDownloads);
MC_AddCommand(m, 0, 170, y, "Apply", MD_ApplyDownloads);
/*
for (pn = 1, p = availablepackages; p && pn < info->firstpackagenum ; p=p->next, pn++)
@ -785,8 +785,8 @@ void Menu_DownloadStuff_f (void)
downloadablelistreceived[i] = 0;
}
MC_AddWhiteText(menu, 24, 8, "Downloads", false);
MC_AddWhiteText(menu, 16, 24, "\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\37", false);
MC_AddWhiteText(menu, 24, 170, 8, "Downloads", false);
MC_AddWhiteText(menu, 16, 170, 24, "\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\37", false);
{
static qboolean loadedinstalled;

View File

@ -408,20 +408,19 @@ static void MenuDrawItems(int xpos, int ypos, menuoption_t *option, menu_t *menu
{
case mt_text:
if (!option->text.text)
{
{ //blinking cursor image hack
if ((int)(realtime*4)&1)
Draw_FunString(xpos+option->common.posx, ypos+option->common.posy, "^Ue00d");
}
else if (option->common.width)
Draw_FunStringWidth(xpos + option->common.posx, ypos+option->common.posy, option->text.text, option->common.width, true, option->text.isred);
else if (option->text.isred)
Draw_AltFunString(xpos+option->common.posx, ypos+option->common.posy, option->text.text);
else
Draw_FunString(xpos+option->common.posx, ypos+option->common.posy, option->text.text);
break;
case mt_button:
if (!menu->cursoritem && menu->selecteditem == option)
Draw_AltFunString(xpos+option->common.posx, ypos+option->common.posy, option->button.text);
else
Draw_FunString(xpos+option->common.posx, ypos+option->common.posy, option->button.text);
Draw_FunStringWidth(xpos + option->common.posx, ypos+option->common.posy, option->button.text, option->common.width, true, !menu->cursoritem && menu->selecteditem == option);
break;
case mt_hexen2buttonbigfont:
Draw_Hexen2BigFontString(xpos+option->common.posx, ypos+option->common.posy, option->button.text);
@ -661,13 +660,14 @@ static void MenuDraw(menu_t *menu)
}
menutext_t *MC_AddWhiteText(menu_t *menu, int x, int y, const char *text, qboolean rightalign)
menutext_t *MC_AddWhiteText(menu_t *menu, int lhs, int rhs, int y, const char *text, qboolean rightalign)
{
menutext_t *n = Z_Malloc(sizeof(menutext_t));
n->common.type = mt_text;
n->common.iszone = true;
n->common.posx = x;
n->common.posx = lhs;
n->common.posy = y;
n->common.width = rhs?rhs-lhs:0;
n->text = text;
if (rightalign && text)
@ -678,13 +678,14 @@ menutext_t *MC_AddWhiteText(menu_t *menu, int x, int y, const char *text, qboole
return n;
}
menutext_t *MC_AddBufferedText(menu_t *menu, int x, int y, const char *text, qboolean rightalign, qboolean red)
menutext_t *MC_AddBufferedText(menu_t *menu, int lhs, int rhs, int y, const char *text, qboolean rightalign, qboolean red)
{
menutext_t *n = Z_Malloc(sizeof(menutext_t) + strlen(text)+1);
n->common.type = mt_text;
n->common.iszone = true;
n->common.posx = x;
n->common.posx = lhs;
n->common.posy = y;
n->common.width = rhs?rhs-lhs:0;
n->text = (char *)(n+1);
strcpy((char *)(n+1), text);
n->isred = red;
@ -697,10 +698,10 @@ menutext_t *MC_AddBufferedText(menu_t *menu, int x, int y, const char *text, qbo
return n;
}
menutext_t *MC_AddRedText(menu_t *menu, int x, int y, const char *text, qboolean rightalign)
menutext_t *MC_AddRedText(menu_t *menu, int lhs, int rhs, int y, const char *text, qboolean rightalign)
{
menutext_t *n;
n = MC_AddWhiteText(menu, x, y, text, false);
n = MC_AddWhiteText(menu, lhs, rhs, y, text, false);
n->isred = true;
return n;
}
@ -1138,15 +1139,15 @@ menucombo_t *MC_AddCvarCombo(menu_t *menu, int tx, int cx, int y, const char *ca
return n;
}
menubutton_t *MC_AddConsoleCommand(menu_t *menu, int x, int y, const char *text, const char *command)
menubutton_t *MC_AddConsoleCommand(menu_t *menu, int lhs, int rhs, int y, const char *text, const char *command)
{
menubutton_t *n = Z_Malloc(sizeof(menubutton_t)+strlen(text)+1+strlen(command)+1);
n->common.type = mt_button;
n->common.iszone = true;
n->common.posx = x;
n->common.posx = lhs;
n->common.posy = y;
n->common.height = 8;
n->common.width = strlen(text)*8;
n->common.width = rhs?rhs - lhs:strlen(text)*8;
n->text = (char *)(n+1);
strcpy((char *)(n+1), text);
n->command = n->text + strlen(n->text)+1;
@ -1194,25 +1195,25 @@ menubutton_t *MC_AddConsoleCommandHexen2BigFont(menu_t *menu, int x, int y, cons
return n;
}
menubutton_t *MC_AddCommand(menu_t *menu, int x, int y, char *text, qboolean (*command) (union menuoption_s *,struct menu_s *,int))
menubutton_t *MC_AddCommand(menu_t *menu, int lhs, int rhs, int y, char *text, qboolean (*command) (union menuoption_s *,struct menu_s *,int))
{
menubutton_t *n = Z_Malloc(sizeof(menubutton_t));
n->common.type = mt_button;
n->common.iszone = true;
n->common.posx = x;
n->common.posx = lhs;
n->common.posy = y;
n->text = text;
n->command = NULL;
n->key = command;
n->common.height = 8;
n->common.width = strlen(text)*8;
n->common.width = rhs?rhs-lhs:strlen(text)*8;
n->common.next = menu->options;
menu->options = (menuoption_t *)n;
return n;
}
menubutton_t *VARGS MC_AddConsoleCommandf(menu_t *menu, int x, int y, const char *text, char *command, ...)
menubutton_t *VARGS MC_AddConsoleCommandf(menu_t *menu, int lhs, int rhs, int y, const char *text, char *command, ...)
{
va_list argptr;
static char string[1024];
@ -1225,8 +1226,9 @@ menubutton_t *VARGS MC_AddConsoleCommandf(menu_t *menu, int x, int y, const char
n = Z_Malloc(sizeof(menubutton_t) + strlen(string)+1);
n->common.type = mt_button;
n->common.iszone = true;
n->common.posx = x;
n->common.posx = lhs;
n->common.posy = y;
n->common.width = rhs-lhs;
n->text = text;
n->command = (char *)(n+1);
strcpy((char *)(n+1), string);
@ -1751,7 +1753,7 @@ typedef struct {
menu_t *parent;
} guiinfo_t;
qboolean MC_GuiKey(int key, menu_t *menu)
static qboolean MC_GuiKey(int key, menu_t *menu)
{
guiinfo_t *info = (guiinfo_t *)menu->data;
switch(key)
@ -1798,7 +1800,7 @@ qboolean MC_GuiKey(int key, menu_t *menu)
gui->text[2] = "Hello yet again";
for (y = 0, i = 0; gui->text[i]; i++, y+=1*8)
{
info->op[i] = MC_AddRedText(info->dropout, 0, y, gui->text[i], false);
info->op[i] = MC_AddRedText(info->dropout, 0, 0, y, gui->text[i], false);
}
}
break;
@ -1919,28 +1921,28 @@ void M_Menu_Main_f (void)
MC_AddSelectablePicture(mainm, 68, 173, "pics/m_main_quit");
#ifndef CLIENTONLY
b = MC_AddConsoleCommand (mainm, 68, 13, "", "menu_single\n");
b = MC_AddConsoleCommand (mainm, 68, 320, 13, "", "menu_single\n");
b->common.tooltip = "Singleplayer.";
mainm->selecteditem = (menuoption_t *)b;
b->common.width = 12*20;
b->common.height = 32;
#endif
b = MC_AddConsoleCommand (mainm, 68, 53, "", "menu_multi\n");
b = MC_AddConsoleCommand (mainm, 68, 320, 53, "", "menu_multi\n");
b->common.tooltip = "Multiplayer.";
#ifdef CLIENTONLY
mainm->selecteditem = (menuoption_t *)b;
#endif
b->common.width = 12*20;
b->common.height = 32;
b = MC_AddConsoleCommand (mainm, 68, 93, "", "menu_options\n");
b = MC_AddConsoleCommand (mainm, 68, 320, 93, "", "menu_options\n");
b->common.tooltip = "Options.";
b->common.width = 12*20;
b->common.height = 32;
b = MC_AddConsoleCommand (mainm, 68, 133, "", "menu_video\n");
b = MC_AddConsoleCommand (mainm, 68, 320, 133, "", "menu_video\n");
b->common.tooltip = "Video Options.";
b->common.width = 12*20;
b->common.height = 32;
b = MC_AddConsoleCommand (mainm, 68, 173, "", "menu_quit\n");
b = MC_AddConsoleCommand (mainm, 68, 320, 173, "", "menu_quit\n");
b->common.tooltip = "Quit to DOS.";
b->common.width = 12*20;
b->common.height = 32;
@ -1997,12 +1999,12 @@ void M_Menu_Main_f (void)
p = R2D_SafeCachePic("gfx/ttl_main.lmp");
if (!p)
{
MC_AddRedText(mainm, 16, 0, "MAIN MENU", false);
MC_AddRedText(mainm, 16, 170, 0, "MAIN MENU", false);
mainm->selecteditem = (menuoption_t *)
MC_AddConsoleCommand (mainm, 64, 32, "Join server", "menu_servers\n");
MC_AddConsoleCommand (mainm, 64, 40, "Options", "menu_options\n");
MC_AddConsoleCommand (mainm, 64, 48, "Quit", "menu_quit\n");
MC_AddConsoleCommand (mainm, 64, 170, 32, "Join server", "menu_servers\n");
MC_AddConsoleCommand (mainm, 64, 170, 40, "Options", "menu_options\n");
MC_AddConsoleCommand (mainm, 64, 170, 48, "Quit", "menu_quit\n");
return;
}
mainm->key = MC_Main_Key;
@ -2031,12 +2033,12 @@ void M_Menu_Main_f (void)
p = R2D_SafeCachePic("gfx/ttl_main.lmp");
if (!p)
{
MC_AddRedText(mainm, 16, 0, "MAIN MENU", false);
MC_AddRedText(mainm, 16, 170, 0, "MAIN MENU", false);
mainm->selecteditem = (menuoption_t *)
MC_AddConsoleCommand (mainm, 64, 32, "Join server", "menu_servers\n");
MC_AddConsoleCommand (mainm, 64, 40, "Options", "menu_options\n");
MC_AddConsoleCommand (mainm, 64, 48, "Quit", "menu_quit\n");
MC_AddConsoleCommand (mainm, 64, 170, 32, "Join server", "menu_servers\n");
MC_AddConsoleCommand (mainm, 64, 170, 40, "Options", "menu_options\n");
MC_AddConsoleCommand (mainm, 64, 170, 48, "Quit", "menu_quit\n");
return;
}
mainm->key = MC_Main_Key;
@ -2048,32 +2050,32 @@ void M_Menu_Main_f (void)
p = R2D_SafeCachePic("gfx/mainmenu.lmp");
b=MC_AddConsoleCommand (mainm, 72, 32, "", "menu_single\n");
b=MC_AddConsoleCommand (mainm, 72, 312, 32, "", "menu_single\n");
b->common.tooltip = "Start singleplayer Quake game.";
mainm->selecteditem = (menuoption_t *)b;
b->common.width = p->width;
b->common.height = 20;
b=MC_AddConsoleCommand (mainm, 72, 52, "", "menu_multi\n");
b=MC_AddConsoleCommand (mainm, 72, 312, 52, "", "menu_multi\n");
b->common.tooltip = "Multiplayer menu.";
b->common.width = p->width;
b->common.height = 20;
b=MC_AddConsoleCommand (mainm, 72, 72, "", "menu_options\n");
b=MC_AddConsoleCommand (mainm, 72, 312, 72, "", "menu_options\n");
b->common.tooltip = "Options menu.";
b->common.width = p->width;
b->common.height = 20;
if (m_helpismedia.value)
{
b=MC_AddConsoleCommand(mainm, 72, 92, "", "menu_media\n");
b=MC_AddConsoleCommand(mainm, 72, 312, 92, "", "menu_media\n");
b->common.tooltip = "Media menu.";
}
else
{
b=MC_AddConsoleCommand(mainm, 72, 92, "", "help\n");
b=MC_AddConsoleCommand(mainm, 72, 312, 92, "", "help\n");
b->common.tooltip = "Help menu.";
}
b->common.width = p->width;
b->common.height = 20;
b=MC_AddConsoleCommand (mainm, 72, 112, "", "menu_quit\n");
b=MC_AddConsoleCommand (mainm, 72, 312, 112, "", "menu_quit\n");
b->common.tooltip = "Exit to DOS.";
b->common.width = p->width;
b->common.height = 20;
@ -2112,10 +2114,10 @@ int MC_AddBulk(struct menu_s *menu, menubulk_t *bulk, int xstart, int xtextend,
control = NULL;
continue;
case 0: // white text
control = (union menuoption_s *)MC_AddWhiteText(menu, x, y, bulk->text, bulk->rightalign);
control = (union menuoption_s *)MC_AddWhiteText(menu, xleft, xtextend, y, bulk->text, bulk->rightalign);
break;
case 1: // red text
control = (union menuoption_s *)MC_AddRedText(menu, x, y, bulk->text, bulk->rightalign);
control = (union menuoption_s *)MC_AddRedText(menu, xleft, xtextend, y, bulk->text, bulk->rightalign);
break;
case 2: // spacing
spacing = bulk->spacing;
@ -2128,10 +2130,10 @@ int MC_AddBulk(struct menu_s *menu, menubulk_t *bulk, int xstart, int xtextend,
{
default:
case 0: // console command
control = (union menuoption_s *)MC_AddConsoleCommand(menu, x, y, bulk->text, bulk->consolecmd);
control = (union menuoption_s *)MC_AddConsoleCommand(menu, xleft, xtextend, y, bulk->text, bulk->consolecmd);
break;
case 1: // function command
control = (union menuoption_s *)MC_AddCommand(menu, x, y, bulk->text, bulk->command);
control = (union menuoption_s *)MC_AddCommand(menu, xleft, xtextend, y, bulk->text, bulk->command);
break;
}
break;
@ -2190,6 +2192,6 @@ int MC_AddBulk(struct menu_s *menu, menubulk_t *bulk, int xstart, int xtextend,
menu->selecteditem = selected;
if (selected)
selectedy = selected->common.posy;
menu->cursoritem = (menuoption_t*)MC_AddWhiteText(menu, xtextend + 8, selectedy, NULL, false);
menu->cursoritem = (menuoption_t*)MC_AddWhiteText(menu, xtextend + 8, 0, selectedy, NULL, false);
return y;
}

View File

@ -666,7 +666,7 @@ void M_Menu_ServerList2_f(void)
MC_AddCheckBoxFunc(menu, 128, 208, vid.height - 64+8*6, "Hide Empty", SL_ReFilter, 6);
MC_AddCheckBoxFunc(menu, 128, 208, vid.height - 64+8*7, "Hide Full ", SL_ReFilter, 7);
MC_AddCommand(menu, 64, 0, info->refreshtext, SL_DoRefresh);
MC_AddCommand(menu, 64, 208, 0, info->refreshtext, SL_DoRefresh);
info->filter[1] = !sb_hidenetquake.value;
info->filter[2] = !sb_hidequakeworld.value;
@ -778,8 +778,8 @@ void M_QuickConnect_f(void)
cust->common.height = 8;
cust->common.width = vid.width-8;
MC_AddCommand(menu, 64, 128, "Refresh", SL_DoRefresh);
MC_AddCommand(menu, 64, 136, "Cancel", M_QuickConnect_Cancel);
MC_AddCommand(menu, 64, 0, 128, "Refresh", SL_DoRefresh);
MC_AddCommand(menu, 64, 0, 136, "Cancel", M_QuickConnect_Cancel);
}

View File

@ -54,7 +54,7 @@ void Media_Clear (void)
}
//fake cd tracks.
qboolean Media_BackgroundTrack(char *track, char *looptrack)
qboolean Media_BackgroundTrack(const char *track, const char *looptrack)
{
unsigned int tracknum;
#if !defined(NOMEDIA)
@ -206,10 +206,10 @@ void Media_EndedTrack(void)
#include "winquake.h"
#ifdef _WIN32
#if defined(_WIN32) && !defined(WINRT)
#define WINAMP
#endif
#if defined(_WIN32)
#if defined(_WIN32) && !defined(WINRT)
#define WINAVI
#endif
@ -1262,7 +1262,7 @@ struct cin_s
void (*key) (struct cin_s *cin, int code, int unicode, int event);
qboolean (*setsize) (struct cin_s *cin, int width, int height);
void (*getsize) (struct cin_s *cin, int *width, int *height);
void (*changestream) (struct cin_s *cin, char *streamname);
void (*changestream) (struct cin_s *cin, const char *streamname);
@ -1761,7 +1761,7 @@ void Media_Plugin_GetSize(cin_t *cin, int *width, int *height)
cin->plugin.funcs->getsize(cin->plugin.ctx, width, height);
currentplug = oldplug;
}
void Media_Plugin_ChangeStream(cin_t *cin, char *streamname)
void Media_Plugin_ChangeStream(cin_t *cin, const char *streamname)
{
struct plugin_s *oldplug = currentplug;
currentplug = cin->plugin.plug;
@ -2579,18 +2579,26 @@ qboolean Media_ShowFilm(void)
}
Media_StopFilm(false);
}
else
else if (cin)
{
int cw = cin->outwidth, ch = cin->outheight;
float ratiox, ratioy;
if (cin->cursormove)
cin->cursormove(cin, mousecursor_x/(float)vid.width, mousecursor_y/(float)vid.height);
if (cin->setsize)
cin->setsize(cin, vid.pixelwidth, vid.pixelheight);
ratiox = (float)cin->outwidth / vid.pixelwidth;
ratioy = (float)cin->outheight / vid.pixelheight;
//FIXME: should have a proper aspect ratio setting. RoQ files are always power of two, which makes things ugly.
if (1)
{
cw = 4;
ch = 3;
}
if (!cin->outheight || !cin->outwidth)
ratiox = (float)cw / vid.pixelwidth;
ratioy = (float)ch / vid.pixelheight;
if (!ch || !cw)
{
R2D_ImageColours(0, 0, 0, 1);
R2D_FillBlock(0, 0, vid.width, vid.height);
@ -2598,7 +2606,7 @@ qboolean Media_ShowFilm(void)
}
else if (ratiox > ratioy)
{
int h = (vid.width * cin->outheight) / cin->outwidth;
int h = (vid.width * ch) / cw;
int p = vid.height - h;
//letterbox
@ -2611,7 +2619,7 @@ qboolean Media_ShowFilm(void)
}
else
{
int w = (vid.height * cin->outwidth) / cin->outheight;
int w = (vid.height * cw) / ch;
int p = vid.width - w;
//sidethingies
R2D_ImageColours(0, 0, 0, 1);
@ -2656,7 +2664,7 @@ texid_tf Media_UpdateForShader(cin_t *cin)
}
#endif
void Media_Send_Command(cin_t *cin, char *command)
void Media_Send_Command(cin_t *cin, const char *command)
{
if (!cin)
cin = R_ShaderGetCinematic(videoshader);
@ -3443,7 +3451,7 @@ void Media_RecordDemo_f(void)
CL_Stopdemo_f(); //capturing failed for some reason
}
#ifdef _WIN32
#if defined(_WIN32) && !defined(WINRT)
typedef struct ISpNotifySink ISpNotifySink;
typedef void *ISpNotifyCallback;
typedef void __stdcall SPNOTIFYCALLBACK(WPARAM wParam, LPARAM lParam);
@ -4136,7 +4144,7 @@ qboolean S_LoadMP3Sound (sfx_t *s, qbyte *data, int datalen, int sndspeed);
void Media_Init(void)
{
#ifdef _WIN32
#if defined(_WIN32) && !defined(WINRT)
Cmd_AddCommand("tts", TTS_Say_f);
Cmd_AddCommand("stt", STT_Init_f);
Cvar_Register(&tts_mode, "Gimmicks");

View File

@ -6,8 +6,6 @@
extern cvar_t maxclients;
menutext_t *MC_AddWhiteText(menu_t *menu, int x, int y, const char *text, qboolean rightalign);
/* MULTIPLAYER MENU */
void M_Menu_MultiPlayer_f (void)
{
@ -29,13 +27,13 @@ void M_Menu_MultiPlayer_f (void)
MC_AddCenterPicture(menu, 4, 24, "pics/m_banner_multiplayer");
menu->selecteditem = (menuoption_t*)
MC_AddConsoleCommand (menu, 64, 40, "Join network server", "menu_slist\n");
MC_AddConsoleCommand (menu, 64, 40, "Quick Connect", "quickconnect qw\n");
MC_AddConsoleCommand (menu, 64, 48, "Start network server", "menu_newmulti\n");
MC_AddConsoleCommand (menu, 64, 56, "Player setup", "menu_setup\n");
MC_AddConsoleCommand (menu, 64, 64, "Demos", "menu_demo\n");
MC_AddConsoleCommand (menu, 64, 170, 40, "Join network server", "menu_slist\n");
MC_AddConsoleCommand (menu, 64, 170, 48, "Quick Connect", "quickconnect qw\n");
MC_AddConsoleCommand (menu, 64, 170, 56, "Start network server", "menu_newmulti\n");
MC_AddConsoleCommand (menu, 64, 170, 64, "Player setup", "menu_setup\n");
MC_AddConsoleCommand (menu, 64, 170, 72, "Demos", "menu_demo\n");
menu->cursoritem = (menuoption_t*)MC_AddWhiteText(menu, 48, 40, NULL, false);
menu->cursoritem = (menuoption_t*)MC_AddWhiteText(menu, 48, 0, 40, NULL, false);
return;
}
else if (mgt == MGT_HEXEN2)
@ -77,29 +75,29 @@ void M_Menu_MultiPlayer_f (void)
MC_AddCenterPicture(menu, 4, 24, "gfx/p_multi.lmp");
MC_AddPicture(menu, 72, 32, 232, 64, "gfx/mp_menu.lmp");
}
b = MC_AddConsoleCommand(menu, 72, 320, 32, "", "menu_slist\n");
menu->selecteditem = (menuoption_t*)b;
b->common.height = 20;
b->common.width = p?p->width:320;
b = MC_AddConsoleCommand(menu, 72, 320, 52, "", "menu_newmulti\n");
b->common.height = 20;
b->common.width = p?p->width:320;
b = MC_AddConsoleCommand(menu, 72, 320, 72, "", "menu_setup\n");
b->common.height = 20;
b->common.width = p?p->width:320;
b = MC_AddConsoleCommand(menu, 72, 320, 92, "", "menu_demo\n");
MC_AddWhiteText(menu, 72, 0, 92+20/2-6, "Demos", false);
b->common.height = 20/2+2;
b->common.width = p?p->width:320;
b = MC_AddConsoleCommand(menu, 72, 320, 112, "", "quickconnect qw\n");
MC_AddWhiteText(menu, 72, 0, 112+20/2-6, "Quick Connect", false);
b->common.height = 20/2+2;
b->common.width = p?p->width:320;
}
b = MC_AddConsoleCommand(menu, 72, 32, "", "menu_slist\n");
menu->selecteditem = (menuoption_t*)b;
b->common.height = 20;
b->common.width = p?p->width:320;
b = MC_AddConsoleCommand(menu, 72, 52, "", "menu_newmulti\n");
b->common.height = 20;
b->common.width = p?p->width:320;
b = MC_AddConsoleCommand(menu, 72, 72, "", "menu_setup\n");
b->common.height = 20;
b->common.width = p?p->width:320;
b = MC_AddConsoleCommand(menu, 72, 92, "", "menu_demo\n");
MC_AddWhiteText(menu, 72, 92+20/2-6, "Demos", false);
b->common.height = 20/2+2;
b->common.width = p?p->width:320;
b = MC_AddConsoleCommand(menu, 72, 112, "", "quickconnect qw\n");
MC_AddWhiteText(menu, 72, 112+20/2-6, "Quick Connect", false);
b->common.height = 20/2+2;
b->common.width = p?p->width:320;
menu->cursoritem = (menuoption_t*)MC_AddCursor(menu, 54, 32);
}
@ -269,7 +267,7 @@ void MSetupQ2_TransDraw (int x, int y, menucustom_t *option, menu_t *menu)
void MSetup_TransDraw (int x, int y, menucustom_t *option, menu_t *menu)
{
qbyte translationTable[256];
unsigned int translationTable[256];
setupmenu_t *info = menu->data;
mpic_t *p;
void *f;
@ -310,6 +308,7 @@ void MSetup_TransDraw (int x, int y, menucustom_t *option, menu_t *menu)
}
}
R2D_ImageColours(1,1,1,1);
p = R2D_SafeCachePic ("gfx/bigbox.lmp");
if (p)
R2D_ScalePic (x-12, y-8, 72, 72, p);
@ -383,7 +382,7 @@ void M_Menu_Setup_f (void)
b->common.width = 12*20;
b->common.height = 20;
*/
menu->cursoritem = (menuoption_t*)MC_AddWhiteText(menu, 54, 32, NULL, false);
menu->cursoritem = (menuoption_t*)MC_AddWhiteText(menu, 54, 0, 32, NULL, false);
}
return;
}
@ -424,15 +423,15 @@ void M_Menu_Setup_f (void)
ci->draw = MSetup_TransDraw;
ci->key = NULL;
MC_AddCommand(menu, 64, 96, "Top colour", SetupMenuColour);
MC_AddCommand(menu, 64, 120, "Lower colour", SetupMenuColour);
MC_AddCommand(menu, 64, 160, 96, "Top colour", SetupMenuColour);
MC_AddCommand(menu, 64, 160, 120, "Lower colour", SetupMenuColour);
MC_AddCommand(menu, 64, 152, "Accept changes", ApplySetupMenu);
b = MC_AddConsoleCommand(menu, 64, 168, "Network Settings", "menu_network\n");
MC_AddCommand(menu, 64, 160, 152, "Accept changes", ApplySetupMenu);
b = MC_AddConsoleCommand(menu, 64, 160, 168, "Network Settings", "menu_network\n");
b->common.tooltip = "Change network and client prediction settings.";
b = MC_AddConsoleCommand(menu, 64, 176, "Teamplay Settings", "menu_teamplay\n");
b = MC_AddConsoleCommand(menu, 64, 160, 176, "Teamplay Settings", "menu_teamplay\n");
b->common.tooltip = "Change teamplay macro settings.";
menu->cursoritem = (menuoption_t*)MC_AddWhiteText(menu, 54, 32, NULL, false);
menu->cursoritem = (menuoption_t*)MC_AddWhiteText(menu, 54, 0, 32, NULL, false);
info->lowercolour = bottomcolor.value;
@ -598,9 +597,9 @@ void M_Menu_GameOptions_f (void)
// MC_AddPicture(menu, 72, 32, ("gfx/mp_menu.lmp") );
menu->selecteditem = (menuoption_t*)
MC_AddCommand (menu, 64, y, " Start game", MultiBeginGame);y+=16;
MC_AddCommand (menu, 64, 160, y, "Start game", MultiBeginGame);y+=16;
info->hostnameedit = MC_AddEdit (menu, 64, 160, y, " Hostname", name.string);y+=16;
info->hostnameedit = MC_AddEdit (menu, 64, 160, y, "Hostname", name.string);y+=16;
for (players = 0; players < sizeof(numplayeroptions)/ sizeof(numplayeroptions[0]); players++)
{
@ -610,23 +609,21 @@ void M_Menu_GameOptions_f (void)
info->numplayers = MC_AddCombo (menu, 64, 160, y, "Max players", (const char **)numplayeroptions, players);y+=8;
info->deathmatch = MC_AddCombo (menu, 64, 160, y, " Deathmatch", (const char **)deathmatchoptions, deathmatch.value);y+=8;
info->teamplay = MC_AddCombo (menu, 64, 160, y, " Teamplay", (const char **)teamplayoptions, teamplay.value);y+=8;
info->skill = MC_AddCombo (menu, 64, 160, y, " Skill", (const char **)skilloptions, skill.value);y+=8;
info->rundedicated = MC_AddCheckBox(menu, 64, 160, y, " dedicated", NULL, 0);y+=8;
info->deathmatch = MC_AddCombo (menu, 64, 160, y, "Deathmatch", (const char **)deathmatchoptions, deathmatch.value);y+=8;
info->teamplay = MC_AddCombo (menu, 64, 160, y, "Teamplay", (const char **)teamplayoptions, teamplay.value);y+=8;
info->skill = MC_AddCombo (menu, 64, 160, y, "Skill", (const char **)skilloptions, skill.value);y+=8;
info->rundedicated = MC_AddCheckBox(menu, 64, 160, y, "dedicated", NULL, 0);y+=8;
y+=8;
info->timelimit = MC_AddCombo (menu, 64, 160, y, " Time Limit", (const char **)timelimitoptions, timelimit.value/5);y+=8;
info->fraglimit = MC_AddCombo (menu, 64, 160, y, " Frag Limit", (const char **)fraglimitoptions, fraglimit.value/10);y+=8;
y+=8;
MC_AddSlider (menu, 64-7*8, 160, y, "Extra edict support", &pr_maxedicts, 512, 2047, 256);y+=8;
info->timelimit = MC_AddCombo (menu, 64, 160, y, "Time Limit", (const char **)timelimitoptions, timelimit.value/5);y+=8;
info->fraglimit = MC_AddCombo (menu, 64, 160, y, "Frag Limit", (const char **)fraglimitoptions, fraglimit.value/10);y+=8;
y+=8;
if (mgt == MGT_QUAKE2)
info->mapnameedit = MC_AddEdit (menu, 64, 160, y, " map", "base1");
info->mapnameedit = MC_AddEdit (menu, 64, 160, y, "map", "base1");
else
info->mapnameedit = MC_AddEdit (menu, 64, 160, y, " map", "start");
info->mapnameedit = MC_AddEdit (menu, 64, 160, y, "map", "start");
y += 16;
menu->cursoritem = (menuoption_t*)MC_AddWhiteText(menu, 54, 32, NULL, false);
menu->cursoritem = (menuoption_t*)MC_AddWhiteText(menu, 54, 0, 32, NULL, false);
info->lowercolour = bottomcolor.value;
@ -656,7 +653,7 @@ void M_Menu_Teamplay_f (void)
menubulk_t bulk[] =
{
MB_REDTEXT("Teamplay Options", false),
MB_TEXT("\x80\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x82", false),
MB_TEXT("^Ue080^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue082", false),
MB_COMBOCVAR("Skins", noskins, noskinsoptions, noskinsvalues, "Enable or disable player skin usage. No download will use skins but will not download them from the server."),
MB_EDITCVARTIP("Enemy Skin", "cl_enemyskin", "Override enemy skin with this."),
MB_EDITCVARTIP("Team Skin", "cl_teamskin", "Override teammate skin with this."),
@ -686,7 +683,7 @@ void M_Menu_Teamplay_Locations_f (void)
menubulk_t bulk[] =
{
MB_REDTEXT("Teamplay Location Names", false),
MB_TEXT("\x80\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x82", false),
MB_TEXT("^Ue080^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue082", false),
MB_EDITCVARSLIM("Separator", "loc_name_separator", "Location name seperator character(s)"),
MB_SPACING(4),
MB_EDITCVARSLIM("Super Shotgun", "loc_name_ssg", "Short name for Super Shotgun in teamplay location 'reports'"),
@ -720,7 +717,7 @@ void M_Menu_Teamplay_Needs_f (void)
menubulk_t bulk[] =
{
MB_REDTEXT("Teamplay Needed Items", false),
MB_TEXT("\x80\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x82", false),
MB_TEXT("^Ue080^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue082", false),
MB_EDITCVARSLIM("Shells", "tp_need_shells", "Short name for Shotgun Shells in teamplay 'need' reports"),
MB_EDITCVARSLIM("Nails", "tp_need_nails", "Short name for Nails in teamplay 'need' reports"),
MB_EDITCVARSLIM("Rockets", "tp_need_rockets", "Short name for Rockets/Grenades in teamplay 'need' reports"),
@ -746,7 +743,7 @@ void M_Menu_Teamplay_Items_f (void)
menubulk_t bulk[] =
{
MB_REDTEXT("Teamplay Item Names", false),
MB_TEXT("\x80\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x82", false),
MB_TEXT("^Ue080^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue082", false),
MB_CONSOLECMD("Armor", "menu_teamplay_armor\n", "Modify team play macro armor names."),
MB_CONSOLECMD("Weapon", "menu_teamplay_weapons\n", "Modify team play macro weapon names."),
MB_CONSOLECMD("Powerups", "menu_teamplay_powerups\n", "Modify team play macro powerup names."),
@ -766,7 +763,7 @@ void M_Menu_Teamplay_Items_Armor_f (void)
menubulk_t bulk[] =
{
MB_REDTEXT("Teamplay Armor Names", false),
MB_TEXT("\x80\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x82", false),
MB_TEXT("^Ue080^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue082", false),
MB_EDITCVARSLIM("Armor", "tp_name_armor", "Short name for Armor type"),
MB_EDITCVARSLIM("Green Type -", "tp_name_armortype_ga", "Short name for Green Armor type"),
MB_EDITCVARSLIM("Yellow Type -", "tp_name_armortype_ya", "Short name for Yellow Armor type"),
@ -788,7 +785,7 @@ void M_Menu_Teamplay_Items_Weapons_f (void)
menubulk_t bulk[] =
{
MB_REDTEXT("Teamplay Weapon Names", false),
MB_TEXT("\x80\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x82", false),
MB_TEXT("^Ue080^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue082", false),
MB_EDITCVARSLIM("Weapon", "tp_name_weapon", "Short name for Weapon"),
MB_SPACING(4),
MB_EDITCVARSLIM("Axe", "tp_name_axe", "Short name for Weapon"),
@ -812,7 +809,7 @@ void M_Menu_Teamplay_Items_Powerups_f (void)
menubulk_t bulk[] =
{
MB_REDTEXT("Teamplay Powerup Names", false),
MB_TEXT("\x80\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x82", false),
MB_TEXT("^Ue080^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue082", false),
MB_EDITCVARSLIM("Quad Damage", "tp_name_quad", "Short name for Quad Damage"),
MB_EDITCVARSLIM("Pentagram", "tp_name_pent", "Short name for Pentgram of Protection"),
MB_EDITCVARSLIM("Ring of Invis", "tp_name_ring", "Short name for Ring Of Invisibilty"),
@ -839,7 +836,7 @@ void M_Menu_Teamplay_Items_Ammo_Health_f (void)
menubulk_t bulk[] =
{
MB_REDTEXT("Teamplay Ammo/Health", false),
MB_TEXT("\x80\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x82", false),
MB_TEXT("^Ue080^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue082", false),
MB_EDITCVARSLIM("Shells", "tp_name_shells", "Short name for Shells"),
MB_EDITCVARSLIM("Nails", "tp_name_nails", "Short name for Nails"),
MB_EDITCVARSLIM("Rockets", "tp_name_rockets", "Short name for Rockets"),
@ -861,7 +858,7 @@ void M_Menu_Teamplay_Items_Team_Fortress_f (void)
menubulk_t bulk[] =
{
MB_REDTEXT("Teamplay Team Fortress", false),
MB_TEXT("\x80\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x82", false),
MB_TEXT("^Ue080^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue082", false),
MB_EDITCVARSLIM("Sentry Gun", "tp_name_sentry", "Short name for the Engineer's Sentry Gun"),
MB_EDITCVARSLIM("Dispenser", "tp_name_disp", "Short name for the Engineer's Ammo Dispenser"),
MB_EDITCVARSLIM("Flag", "tp_name_flag", "Short name for Flag"),
@ -878,7 +875,7 @@ void M_Menu_Teamplay_Items_Status_Location_Misc_f (void)
menubulk_t bulk[] =
{
MB_REDTEXT("Teamplay Misc", false),
MB_TEXT("\x80\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x82", false),
MB_TEXT("^Ue080^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue082", false),
MB_EDITCVARSLIM("Enemy", "tp_name_enemy", "Short for Enemy in teamplay 'status' & 'location' reports"),
MB_EDITCVARSLIM("Teammate", "tp_name_teammate", "Short for Enemy in teamplay 'status' & 'location' reports"),
MB_SPACING(4),
@ -912,6 +909,7 @@ void M_Menu_Network_f (void)
"Lower Latency",
"Smoother",
"Smooth Demos Only",
NULL
};
static const char *smoothingvalues[] = {"0", "1", "2", NULL};
extern cvar_t cl_download_csprogs, cl_download_redirection, requiredownloads, cl_solid_players;
@ -921,7 +919,7 @@ void M_Menu_Network_f (void)
menubulk_t bulk[] =
{
MB_REDTEXT("Network Settings", false),
MB_TEXT("\x80\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x82", false),
MB_TEXT("^Ue080^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue082", false),
MB_EDITCVARSLIM("Network FPS", "cl_netfps", "Sets ammount of FPS used to communicate with server (sent and received)"),
MB_EDITCVARSLIM("Rate", "rate", "Maximum bytes per second that the server should send to the client"),
MB_EDITCVARSLIM("Download Rate", "drate", "Maximum bytes per second that the server should send maps and demos to the client"),

View File

@ -36,21 +36,33 @@ menu_t *M_Options_Title(int *y, int infosize)
//these are awkward/strange
qboolean M_Options_AlwaysRun (menucheck_t *option, struct menu_s *menu, chk_set_t set)
{
if (set == CHK_CHECKED)
return cl_forwardspeed.value > 200;
else if (cl_forwardspeed.value > 200)
if (M_GameType() == MGT_QUAKE2)
{
Cvar_SetValue (&cl_forwardspeed, 200);
if (*cl_backspeed.string)
Cvar_SetValue (&cl_backspeed, 200);
return false;
extern cvar_t cl_run;
//quake2 mods have a nasty tendancy to hack at the various cvars, which breaks everything
if (set != CHK_CHECKED)
Cvar_SetValue(&cl_run, !cl_run.ival);
return cl_run.ival;
}
else
{
Cvar_SetValue (&cl_forwardspeed, 400);
if (*cl_backspeed.string)
Cvar_SetValue (&cl_backspeed, 400);
return true;
//for better compat with other quake engines, we just ignore the cl_run cvar, at least for the menu.
if (set == CHK_CHECKED)
return cl_forwardspeed.value > 200;
else if (cl_forwardspeed.value > 200)
{
Cvar_SetValue (&cl_forwardspeed, 200);
if (*cl_backspeed.string)
Cvar_SetValue (&cl_backspeed, 200);
return false;
}
else
{
Cvar_SetValue (&cl_forwardspeed, 400);
if (*cl_backspeed.string)
Cvar_SetValue (&cl_backspeed, 400);
return true;
}
}
}
qboolean M_Options_InvertMouse (menucheck_t *option, struct menu_s *menu, chk_set_t set)
@ -223,9 +235,9 @@ void M_Menu_Audio_Speakers_f (void)
menu->event = M_Audio_StartSound;
for (i = 0; i < 6; i++)
info->speaker[i] = MC_AddBufferedText(menu, 0, 0, va("%i", i), false, true);
info->speaker[i] = MC_AddBufferedText(menu, 0, 0, 0, va("%i", i), false, true);
info->testsoundsource = MC_AddBufferedText(menu, 0, 0, "X", false, true);
info->testsoundsource = MC_AddBufferedText(menu, 0, 0, 0, "X", false, true);
info->card = sndcardinfo;
@ -364,7 +376,7 @@ void M_Menu_Audio_f (void)
menubulk_t bulk[] = {
MB_REDTEXT("Sound Options", false),
MB_TEXT("\x80\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x82", false),
MB_TEXT("^Ue080^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue082", false),
MB_SPACING(8),
MB_CONSOLECMD("Restart Sound", "snd_restart\n", "Restart audio systems and apply set options."),
MB_SPACING(4),
@ -392,7 +404,7 @@ void M_Menu_Audio_f (void)
#ifdef VOICECHAT
MB_REDTEXT("Voice Options", false),
MB_TEXT("\x80\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x82", false),
MB_TEXT("^Ue080^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue082", false),
MB_COMBOCVAR("Microphone Device", snd_voip_capturedevice, (const char**)info->capdevdescs, (const char**)info->capdevnames, NULL),
MB_SLIDER("Voice Volume", snd_voip_play, 0, 2, 0.1, NULL),
MB_CHECKBOXCVAR("Microphone Test", snd_voip_test, 0),
@ -483,7 +495,7 @@ void M_Menu_Particles_f (void)
int y;
menubulk_t bulk[] = {
MB_REDTEXT("Particle Options", false),
MB_TEXT("\x80\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x82", false),
MB_TEXT("^Ue080^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue082", false),
// MB_COMBOCVAR("Particle System", r_particlesystem, psystemopts, psystemvals, "Selects particle system to use. Classic is standard Quake particles, script is FTE style scripted particles, and none disables particles entirely."),
MB_COMBOCVAR("Particle Set", r_particledesc, pdescopts, pdescvals, "Selects particle set to use with the scripted particle system."),
MB_SPACING(4),
@ -597,7 +609,7 @@ const char *presetexec[] =
"r_particledesc \"high tsshaft\";"
#endif
"gl_specular 1;"
"r_loadlit 2;"
// "r_loadlit 2;"
"r_waterstyle 2;"
"gl_blendsprites 1;"
// "r_fastsky -1;"
@ -640,7 +652,7 @@ void M_Menu_Preset_f (void)
menubulk_t bulk[] =
{
MB_REDTEXT("Please Choose Preset", false),
MB_TEXT("\x80\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x82", false),
MB_TEXT("^Ue080^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue082", false),
MB_CONSOLECMD("286 (untextured)", "fps_preset 286;menupop\n", "Lacks textures, particles, pretty much everything."),
MB_CONSOLECMD("fast (deathmatch)", "fps_preset fast;menupop\n", "Fullscreen effects off to give consistant framerates"),
MB_CONSOLECMD("normal (faithful)", "fps_preset normal;menupop\n", "This is for Quake purists!"),
@ -749,7 +761,7 @@ void M_Menu_FPS_f (void)
menubulk_t bulk[] =
{
MB_REDTEXT("FPS Options", false),
MB_TEXT("\x80\x81\x81\x81\x81\x81\x81\x81\x81\x81\x82", false),
MB_TEXT("^Ue080^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue082", false),
MB_COMBORETURN("Preset", presetname, 2, info->preset, "Select a builtin configuration of graphical settings."),
MB_CMD("Apply", M_PresetApply, "Applies selected preset."),
MB_SPACING(4),
@ -795,7 +807,7 @@ void M_Menu_Render_f (void)
menubulk_t bulk[] =
{
MB_REDTEXT("Rendering Options", false),
MB_TEXT("\x80\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x82", false),
MB_TEXT("^Ue080^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue082", false),
MB_CHECKBOXCVAR("Calculate VIS", r_novis, 0),
MB_CHECKBOXCVAR("Fast Sky", r_fastsky, 0),
MB_CHECKBOXCVAR("Disable Model Lerp", r_nolerp, 0),
@ -888,7 +900,7 @@ void M_Menu_Textures_f (void)
menubulk_t bulk[] =
{
MB_REDTEXT("Texture Options", false),
MB_TEXT("\x80\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x82", false),
MB_TEXT("^Ue080^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue082", false),
MB_CHECKBOXCVAR("Load Replacements", gl_load24bit, 0),
MB_CHECKBOXCVAR("Simple Texturing", r_drawflat, 0),
MB_COMBOCVAR("3D Filter Mode", gl_texturemode, texturefilternames, texturefiltervalues, "Chooses the texture filtering method used for 3D objects."),
@ -1120,7 +1132,7 @@ void M_Menu_Lighting_f (void)
menubulk_t bulk[] =
{
MB_REDTEXT("Lighting Options", false),
MB_TEXT("\x80\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x82", false),
MB_TEXT("^Ue080^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue082", false),
#ifdef RTLIGHTS
MB_COMBORETURN("Lighting Mode", lightingopts, lightselect, info->lightcombo, "Selects method used for world lighting. Realtime lighting requires appropriate realtime lighting files for maps."),
MB_COMBORETURN("Dynamic Lighting Mode", dlightopts, dlightselect, info->dlightcombo, "Selects method used for dynamic lighting such as explosion lights and muzzle flashes."),
@ -1384,8 +1396,8 @@ void M_Menu_Singleplayer_Cheats_Quake (void)
/*anything that doesn't match will end up with 0*/
#endif
MC_AddRedText(menu, 16, y, " Quake Singleplayer Cheats", false); y+=8;
MC_AddWhiteText(menu, 16, y, "<><E282AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ", false); y+=8;
MC_AddRedText(menu, 16, 170, y, " Quake Singleplayer Cheats", false); y+=8;
MC_AddWhiteText(menu, 16, 170, y, "<><E282AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ", false); y+=8;
y+=8;
#ifndef CLIENTONLY
info->skillcombo = MC_AddCombo(menu,16,170, y, "Difficulty", skilloptions, currentskill); y+=8;
@ -1395,10 +1407,10 @@ void M_Menu_Singleplayer_Cheats_Quake (void)
#ifdef TEXTEDITOR
MC_AddCheckBox(menu, 16, 170, y, "Debugger", &debugger, 0); y+=8;
#endif
MC_AddConsoleCommand(menu, 16, y, " Toggle Godmode", "god\n"); y+=8;
MC_AddConsoleCommand(menu, 16, y, " Toggle Flymode", "fly\n"); y+=8;
MC_AddConsoleCommand(menu, 16, y, " Toggle Noclip", "noclip\n"); y+=8;
MC_AddConsoleCommand(menu, 16, y, " Quad Damage", "impulse 255\n"); y+=8;
MC_AddConsoleCommand(menu, 16, 170, y, " Toggle Godmode", "god\n"); y+=8;
MC_AddConsoleCommand(menu, 16, 170, y, " Toggle Flymode", "fly\n"); y+=8;
MC_AddConsoleCommand(menu, 16, 170, y, " Toggle Noclip", "noclip\n"); y+=8;
MC_AddConsoleCommand(menu, 16, 170, y, " Quad Damage", "impulse 255\n"); y+=8;
#ifndef CLIENTONLY
MC_AddSlider(menu, 16, 170, y, "Gravity", &sv_gravity,0,800,25); y+=8;
#endif
@ -1408,20 +1420,20 @@ void M_Menu_Singleplayer_Cheats_Quake (void)
#ifndef CLIENTONLY
MC_AddSlider(menu, 16, 170, y, "Max Movement Speed", &sv_maxspeed,0,1000,50); y+=8;
#endif
MC_AddConsoleCommand(menu, 16, y, " Silver & Gold Keys", "impulse 13\nimpulse 14\n"); y+=8;
MC_AddConsoleCommand(menu, 16, y, "All Weapons & Items", "impulse 9\n"); y+=8;
MC_AddConsoleCommand(menu, 16, y, "No Enemy Targetting", "notarget\n"); y+=8;
MC_AddConsoleCommand(menu, 16, 170, y, " Silver & Gold Keys", "impulse 13\nimpulse 14\n"); y+=8;
MC_AddConsoleCommand(menu, 16, 170, y, "All Weapons & Items", "impulse 9\n"); y+=8;
MC_AddConsoleCommand(menu, 16, 170, y, "No Enemy Targetting", "notarget\n"); y+=8;
#ifndef CLIENTONLY
MC_AddConsoleCommand(menu, 16, y, " Restart Map", "restart\n"); y+=8;
MC_AddConsoleCommand(menu, 16, 170, y, "Restart Map", "restart\n"); y+=8;
#else
MC_AddConsoleCommand(menu, 16, y, " Suicide", "kill\n"); y+=8;
MC_AddConsoleCommand(menu, 16, 170, y, "Suicide", "kill\n"); y+=8;
#endif
y+=8;
MC_AddCommand(menu, 16, y, " Apply Changes", M_Apply_SP_Cheats); y+=8;
MC_AddCommand(menu, 16, 170, y, "Apply Changes", M_Apply_SP_Cheats); y+=8;
menu->selecteditem = (union menuoption_s *)info->skillcombo;
menu->cursoritem = (menuoption_t*)MC_AddWhiteText(menu, 170, cursorpositionY, NULL, false);
menu->cursoritem = (menuoption_t*)MC_AddWhiteText(menu, 170, 0, cursorpositionY, NULL, false);
}
// Quake 2
@ -1498,16 +1510,16 @@ void M_Menu_Singleplayer_Cheats_Quake2 (void)
/*anything that doesn't match will end up with 0*/
#endif
MC_AddRedText(menu, 16, y, " Quake2 Singleplayer Cheats", false); y+=8;
MC_AddWhiteText(menu, 16, y, " <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ", false); y+=8;
MC_AddRedText(menu, 16, 170, y, "Quake2 Singleplayer Cheats", false); y+=8;
MC_AddWhiteText(menu, 16, 170, y, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ", false); y+=8;
y+=8;
#ifndef CLIENTONLY
info->skillcombo = MC_AddCombo(menu,16,170, y, "Difficulty", skilloptions, currentskill); y+=8;
info->mapcombo = MC_AddCombo(menu,16,170, y, "Map", mapoptions_q2, currentmap); y+=8;
MC_AddCheckBox(menu, 16, 170, y, "Cheats", &sv_cheats,0); y+=8;
#endif
MC_AddConsoleCommand(menu, 16, y, " Toggle Godmode", "god\n"); y+=8;
MC_AddConsoleCommand(menu, 16, y, " Toggle Noclip", "noclip\n"); y+=8;
MC_AddConsoleCommand(menu, 16, 170, y, "Toggle Godmode", "god\n"); y+=8;
MC_AddConsoleCommand(menu, 16, 170, y, "Toggle Noclip", "noclip\n"); y+=8;
#ifndef CLIENTONLY
MC_AddSlider(menu, 16, 170, y, "Gravity", &sv_gravity,0,850,25); y+=8;
#endif
@ -1517,35 +1529,35 @@ void M_Menu_Singleplayer_Cheats_Quake2 (void)
#ifndef CLIENTONLY
MC_AddSlider(menu, 16, 170, y, "Max Movement Speed", &sv_maxspeed,0,1000,50); y+=8;
#endif
MC_AddConsoleCommand(menu, 16, y, " Unlimited Ammo", "dmflags 8192\n"); y+=8;
MC_AddConsoleCommand(menu, 16, y, " Quad Damage", "give quad damage\n"); y+=8;
MC_AddConsoleCommand(menu, 16, y, " Blue & Red Key", "give blue key\ngive red key\n"); y+=8;
MC_AddConsoleCommand(menu, 16, y, " Pyramid Key", "give pyramid key\n"); y+=8;
MC_AddConsoleCommand(menu, 16, y, "All Weapons & Items", "give all\n"); y+=8;
MC_AddConsoleCommand(menu, 16, y, " Data Spinner", "give data spinner\n"); y+=8;
MC_AddConsoleCommand(menu, 16, y, " Power Cube", "give power cube\n"); y+=8;
MC_AddConsoleCommand(menu, 16, y, " Data CD", "give data cd\n"); y+=8;
MC_AddConsoleCommand(menu, 16, y, " Ammo Pack", "give ammo pack\n"); y+=8;
MC_AddConsoleCommand(menu, 16, y, " Bandolier", "give bandolier\n"); y+=8;
MC_AddConsoleCommand(menu, 16, y, " Adrenaline", "give adrenaline\n"); y+=8;
MC_AddConsoleCommand(menu, 16, y, " Ancient Head", "give ancient head\n"); y+=8;
MC_AddConsoleCommand(menu, 16, y, " Environment Suit", "give environment suit\n"); y+=8;
MC_AddConsoleCommand(menu, 16, y, " Rebreather", "give rebreather\n"); y+=8;
MC_AddConsoleCommand(menu, 16, y, " Invulnerability", "give invulnerability\n"); y+=8;
MC_AddConsoleCommand(menu, 16, y, " Silencer", "give silencer\n"); y+=8;
MC_AddConsoleCommand(menu, 16, y, " Power Shield", "give power shield\n"); y+=8;
MC_AddConsoleCommand(menu, 16, y, " Commander's Head", "give commander's head\n"); y+=8;
MC_AddConsoleCommand(menu, 16, y, " Security Pass", "give security pass\n"); y+=8;
MC_AddConsoleCommand(menu, 16, y, " Airstrike Marker", "give airstrike marker\n"); y+=8;
MC_AddConsoleCommand(menu, 16, 170, y, "Unlimited Ammo", "dmflags 8192\n"); y+=8;
MC_AddConsoleCommand(menu, 16, 170, y, "Quad Damage", "give quad damage\n"); y+=8;
MC_AddConsoleCommand(menu, 16, 170, y, "Blue & Red Key", "give blue key\ngive red key\n"); y+=8;
MC_AddConsoleCommand(menu, 16, 170, y, "Pyramid Key", "give pyramid key\n"); y+=8;
MC_AddConsoleCommand(menu, 16, 170, y, "All Weapons & Items", "give all\n"); y+=8;
MC_AddConsoleCommand(menu, 16, 170, y, "Data Spinner", "give data spinner\n"); y+=8;
MC_AddConsoleCommand(menu, 16, 170, y, "Power Cube", "give power cube\n"); y+=8;
MC_AddConsoleCommand(menu, 16, 170, y, "Data CD", "give data cd\n"); y+=8;
MC_AddConsoleCommand(menu, 16, 170, y, "Ammo Pack", "give ammo pack\n"); y+=8;
MC_AddConsoleCommand(menu, 16, 170, y, "Bandolier", "give bandolier\n"); y+=8;
MC_AddConsoleCommand(menu, 16, 170, y, "Adrenaline", "give adrenaline\n"); y+=8;
MC_AddConsoleCommand(menu, 16, 170, y, "Ancient Head", "give ancient head\n"); y+=8;
MC_AddConsoleCommand(menu, 16, 170, y, "Environment Suit", "give environment suit\n"); y+=8;
MC_AddConsoleCommand(menu, 16, 170, y, "Rebreather", "give rebreather\n"); y+=8;
MC_AddConsoleCommand(menu, 16, 170, y, "Invulnerability", "give invulnerability\n"); y+=8;
MC_AddConsoleCommand(menu, 16, 170, y, "Silencer", "give silencer\n"); y+=8;
MC_AddConsoleCommand(menu, 16, 170, y, "Power Shield", "give power shield\n"); y+=8;
MC_AddConsoleCommand(menu, 16, 170, y, "Commander's Head", "give commander's head\n"); y+=8;
MC_AddConsoleCommand(menu, 16, 170, y, "Security Pass", "give security pass\n"); y+=8;
MC_AddConsoleCommand(menu, 16, 170, y, "Airstrike Marker", "give airstrike marker\n"); y+=8;
#ifndef CLIENTONLY
MC_AddConsoleCommand(menu, 16, y, " Restart Map", va("restart\n")); y+=8;
MC_AddConsoleCommand(menu, 16, 170, y, "Restart Map", va("restart\n")); y+=8;
#endif
y+=8;
MC_AddCommand(menu, 16, y, " Apply Changes", M_Apply_SP_Cheats_Q2); y+=8;
MC_AddCommand(menu, 16, 170, y, "Apply Changes", M_Apply_SP_Cheats_Q2); y+=8;
menu->selecteditem = (union menuoption_s *)info->skillcombo;
menu->cursoritem = (menuoption_t*)MC_AddWhiteText(menu, 170, cursorpositionY, NULL, false);
menu->cursoritem = (menuoption_t*)MC_AddWhiteText(menu, 170, 0, cursorpositionY, NULL, false);
}
// Hexen 2
@ -1856,8 +1868,8 @@ void M_Menu_Singleplayer_Cheats_Hexen2 (void)
else
currentmap = 0;
MC_AddRedText(menu, 16, y, " Hexen2 Singleplayer Cheats", false); y+=8;
MC_AddWhiteText(menu, 16, y, " <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ", false); y+=8;
MC_AddRedText(menu, 16, 170, y, "Hexen2 Singleplayer Cheats", false); y+=8;
MC_AddWhiteText(menu, 16, 170, y, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ", false); y+=8;
y+=8;
#ifndef CLIENTONLY
info->skillcombo = MC_AddCombo(menu,16,170, y, "Difficulty", skilloptions, currentskill); y+=8;
@ -1866,9 +1878,9 @@ void M_Menu_Singleplayer_Cheats_Hexen2 (void)
#ifndef CLIENTONLY
MC_AddCheckBox(menu, 16, 170, y, "Cheats", &sv_cheats,0); y+=8;
#endif
MC_AddConsoleCommand(menu, 16, y, " Toggle Godmode", "god\n"); y+=8;
MC_AddConsoleCommand(menu, 16, y, " Toggle Flymode", "fly\n"); y+=8;
MC_AddConsoleCommand(menu, 16, y, " Toggle Noclip", "noclip\n"); y+=8;
MC_AddConsoleCommand(menu, 16, 170, y, "Toggle Godmode", "god\n"); y+=8;
MC_AddConsoleCommand(menu, 16, 170, y, "Toggle Flymode", "fly\n"); y+=8;
MC_AddConsoleCommand(menu, 16, 170, y, "Toggle Noclip", "noclip\n"); y+=8;
#ifndef CLIENTONLY
MC_AddSlider(menu, 16, 170, y, "Gravity", &sv_gravity,0,800,25); y+=8;
#endif
@ -1878,29 +1890,29 @@ void M_Menu_Singleplayer_Cheats_Hexen2 (void)
#ifndef CLIENTONLY
MC_AddSlider(menu, 16, 170, y, "Max Movement Speed", &sv_maxspeed,0,1000,50); y+=8;
#endif
MC_AddConsoleCommand(menu, 16, y, " Sheep Transformation", "impulse 14\n"); y+=8;
MC_AddConsoleCommand(menu, 16, y, " Change To Paladin (lvl3+)", "impulse 171\n"); y+=8;
MC_AddConsoleCommand(menu, 16, y, " Change To Crusader (lvl3+)", "impulse 172\n"); y+=8;
MC_AddConsoleCommand(menu, 16, y, "Change to Necromancer (lvl3+)", "impulse 173\n"); y+=8;
MC_AddConsoleCommand(menu, 16, y, " Change to Assassin (lvl3+)", "impulse 174\n"); y+=8;
MC_AddConsoleCommand(menu, 16, y, " Remove Monsters", "impulse 35\n"); y+=8;
MC_AddConsoleCommand(menu, 16, y, " Freeze Monsters", "impulse 36\n"); y+=8;
MC_AddConsoleCommand(menu, 16, y, " Unfreeze Monsters", "impulse 37\n"); y+=8;
MC_AddConsoleCommand(menu, 16, y, " Increase Level By 1", "impulse 40\n"); y+=8;
MC_AddConsoleCommand(menu, 16, y, " Increase Experience", "impulse 41\n"); y+=8;
MC_AddConsoleCommand(menu, 16, y, " Display Co-ordinates", "impulse 42\n"); y+=8;
MC_AddConsoleCommand(menu, 16, y, " All Weapons & Mana", "impulse 9\n"); y+=8;
MC_AddConsoleCommand(menu, 16, y, " All Weapons & Mana & Items", "impulse 43\n"); y+=8;
MC_AddConsoleCommand(menu, 16, y, " No Enemy Targetting", "notarget\n"); y+=8;
MC_AddConsoleCommand(menu, 16, y, " Enable Crosshair", "crosshair 1\n"); y+=8;
MC_AddConsoleCommand(menu, 16, y, " 20 Of Each Artifact", "impulse 299\n"); y+=8;
MC_AddConsoleCommand(menu, 16, y, " Restart Map", "impulse 99\n"); y+=8;
MC_AddConsoleCommand(menu, 16, 170, y, "Sheep Transformation", "impulse 14\n"); y+=8;
MC_AddConsoleCommand(menu, 16, 170, y, "Change To Paladin (lvl3+)", "impulse 171\n"); y+=8;
MC_AddConsoleCommand(menu, 16, 170, y, "Change To Crusader (lvl3+)", "impulse 172\n"); y+=8;
MC_AddConsoleCommand(menu, 16, 170, y, "Change to Necromancer (lvl3+)", "impulse 173\n"); y+=8;
MC_AddConsoleCommand(menu, 16, 170, y, "Change to Assassin (lvl3+)", "impulse 174\n"); y+=8;
MC_AddConsoleCommand(menu, 16, 170, y, "Remove Monsters", "impulse 35\n"); y+=8;
MC_AddConsoleCommand(menu, 16, 170, y, "Freeze Monsters", "impulse 36\n"); y+=8;
MC_AddConsoleCommand(menu, 16, 170, y, "Unfreeze Monsters", "impulse 37\n"); y+=8;
MC_AddConsoleCommand(menu, 16, 170, y, "Increase Level By 1", "impulse 40\n"); y+=8;
MC_AddConsoleCommand(menu, 16, 170, y, "Increase Experience", "impulse 41\n"); y+=8;
MC_AddConsoleCommand(menu, 16, 170, y, "Display Co-ordinates", "impulse 42\n"); y+=8;
MC_AddConsoleCommand(menu, 16, 170, y, "All Weapons & Mana", "impulse 9\n"); y+=8;
MC_AddConsoleCommand(menu, 16, 170, y, "All Weapons & Mana & Items", "impulse 43\n"); y+=8;
MC_AddConsoleCommand(menu, 16, 170, y, "No Enemy Targetting", "notarget\n"); y+=8;
MC_AddConsoleCommand(menu, 16, 170, y, "Enable Crosshair", "crosshair 1\n"); y+=8;
MC_AddConsoleCommand(menu, 16, 170, y, "20 Of Each Artifact", "impulse 299\n"); y+=8;
MC_AddConsoleCommand(menu, 16, 170, y, "Restart Map", "impulse 99\n"); y+=8;
y+=8;
MC_AddCommand(menu, 16, y, " Apply Changes", M_Apply_SP_Cheats_H2); y+=8;
MC_AddCommand(menu, 16, 170, y, "Apply Changes", M_Apply_SP_Cheats_H2); y+=8;
menu->selecteditem = (union menuoption_s *)info->skillcombo;
menu->cursoritem = (menuoption_t*)MC_AddWhiteText(menu, 250, cursorpositionY, NULL, false);
menu->cursoritem = (menuoption_t*)MC_AddWhiteText(menu, 250, 0, cursorpositionY, NULL, false);
}
void M_Menu_Singleplayer_Cheats_f (void)
@ -2358,7 +2370,7 @@ void M_Menu_Video_f (void)
menubulk_t bulk[] =
{
MB_REDTEXT("Video Options", false),
MB_TEXT("\x80\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x82", false),
MB_TEXT("^Ue080^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue082", false),
#ifdef MULTIRENDERER
MB_COMBOCVAR("Renderer", vid_renderer, rendererops, renderervalues, NULL),
#endif
@ -2448,3 +2460,290 @@ void M_Menu_Video_f (void)
*/
menu->event = CheckCustomMode;
}
typedef struct
{
int skingroup;
int framegroup;
double framechangetime;
double skinchangetime;
float pitch;
float yaw;
float dist;
char modelname[MAX_QPATH];
char forceshader[MAX_QPATH];
} modelview_t;
static unsigned int genhsv(float h_, float s, float v)
{
float r=0, g=1, b=0;
float h = h_ - floor(h_);
int i = floor(h * 6);
float f = h * 6 - i;
float p = v * (1 - s);
float q = v * (1 - f * s);
float t = v * (1 - (1 - f) * s);
switch(i)
{
case 0: r = v, g = t, b = p; break;
case 1: r = q, g = v, b = p; break;
case 2: r = p, g = v, b = t; break;
case 3: r = p, g = q, b = v; break;
case 4: r = t, g = p, b = v; break;
case 5: r = v, g = p, b = q; break;
}
return 0xff000000 |
((int)(r*255)<<16) |
((int)(g*255)<<8) |
((int)(b*255)<<0);
};
const char *Mod_FrameNameForNum(model_t *model, int num);
const char *Mod_SkinNameForNum(model_t *model, int num);
static void M_ModelViewerDraw(int x, int y, struct menucustom_s *c, struct menu_s *m)
{
static playerview_t pv;
entity_t ent;
vec3_t fwd, rgt, up;
const char *fname;
modelview_t *mods = c->dptr;
memset(&pv, 0, sizeof(pv));
CL_DecayLights ();
CL_ClearEntityLists();
V_ClearRefdef(&pv);
r_refdef.drawsbar = false;
V_CalcRefdef(&pv);
r_refdef.grect.width = vid.width;
r_refdef.grect.height = vid.height;
r_refdef.grect.x = 0;
r_refdef.grect.y = 0;
r_refdef.time = realtime;
r_refdef.flags = Q2RDF_NOWORLDMODEL;
r_refdef.afov = 60;
r_refdef.fov_x = 0;
r_refdef.fov_y = 0;
r_refdef.dirty |= RDFD_FOV;
VectorClear(r_refdef.viewangles);
r_refdef.viewangles[0] = mods->pitch;
r_refdef.viewangles[1] = mods->yaw;
AngleVectors(r_refdef.viewangles, fwd, rgt, up);
VectorScale(fwd, -mods->dist, r_refdef.vieworg);
memset(&ent, 0, sizeof(ent));
ent.scale = 1;
ent.model = Mod_ForName(mods->modelname, MLV_WARN);
if (!ent.model)
return; //panic!
ent.origin[2] -= (ent.model->maxs[2]-ent.model->mins[2]) * 0.5 + ent.model->mins[2];
Vector4Set(ent.shaderRGBAf, 1, 1, 1, 1);
if (strstr(mods->modelname, "player"))
{
ent.bottomcolour = genhsv(realtime*0.1 + 0, 1, 1);
ent.topcolour = genhsv(realtime*0.1 + 0.5, 1, 1);
}
else
{
ent.topcolour = TOP_DEFAULT;
ent.bottomcolour = BOTTOM_DEFAULT;
}
// ent.fatness = sin(realtime)*5;
ent.playerindex = -1;
ent.scale = 33.3333;
ent.skinnum = mods->skingroup;
ent.shaderTime = realtime;
ent.framestate.g[FS_REG].frame[0] = mods->framegroup;
ent.framestate.g[FS_REG].frametime[0] = realtime - mods->framechangetime;
ent.framestate.g[FS_REG].frametime[1] = realtime - mods->framechangetime;
ent.customskin = Mod_RegisterSkinFile(va("%s_0.skin", mods->modelname));
V_AddEntity(&ent);
V_ApplyRefdef();
R_RenderView();
fname = Mod_FrameNameForNum(ent.model, mods->framegroup);
if (!fname)
fname = "Unknown Frame";
Draw_FunString(0, 0, va("%i: %s", mods->framegroup, fname));
fname = Mod_SkinNameForNum(ent.model, mods->skingroup);
if (!fname)
fname = "Unknown Skin";
Draw_FunString(0, 8, va("%i: %s", mods->skingroup, fname));
}
static qboolean M_ModelViewerKey(struct menucustom_s *c, struct menu_s *m, int key)
{
modelview_t *mods = c->dptr;
if (key == 'w')
{
mods->dist *= 0.9;
if (mods->dist < 5)
mods->dist = 5;
}
else if (key == 's')
mods->dist /= 0.9;
else if (key == K_UPARROW)
mods->pitch += 5;
else if (key == K_DOWNARROW)
mods->pitch -= 5;
else if (key == K_LEFTARROW)
mods->yaw -= 5;
else if (key == K_RIGHTARROW)
mods->yaw += 5;
else if (key == K_HOME)
{
mods->skingroup = max(0, mods->skingroup-1);
mods->skinchangetime = realtime;
}
else if (key == K_END)
{
mods->skingroup += 1;
mods->skinchangetime = realtime;
}
else if (key == K_PGDN)
{
mods->framegroup = max(0, mods->framegroup-1);
mods->framechangetime = realtime;
}
else if (key == K_PGUP)
{
mods->framegroup += 1;
mods->framechangetime = realtime;
}
else
return false;
return true;
}
void M_Menu_ModelViewer_f(void)
{
modelview_t *mv;
menucustom_t *c;
menu_t *menu;
Key_Dest_Add(kdm_menu);
menu = M_CreateMenu(sizeof(*mv));
mv = menu->data;
c = MC_AddCustom(menu, 64, 32, mv, 0);
menu->cursoritem = (menuoption_t*)c;
c->draw = M_ModelViewerDraw;
c->key = M_ModelViewerKey;
mv->yaw = 180 + crandom()*45;
mv->dist = 150;
Q_strncpyz(mv->modelname, Cmd_Argv(1), sizeof(mv->modelname));
Q_strncpyz(mv->forceshader, Cmd_Argv(2), sizeof(mv->forceshader));
}
typedef struct
{
ftemanifest_t **manifests;
size_t nummanifests;
int y;
} modmenu_t;
static void Mods_Draw(int x, int y, struct menucustom_s *c, struct menu_s *m)
{
modmenu_t *mods = c->dptr;
int i, ym;
c->common.height = vid.height - y;
ym = y+c->common.height;
mods->y = y;
for (i = 0; y+8 <= ym && i < mods->nummanifests; y+=8, i++)
{
if (mousecursor_y >= y && mousecursor_y < y+8)
Draw_AltFunString(x, y, mods->manifests[i]->formalname);
else
Draw_FunString(x, y, mods->manifests[i]->formalname);
}
}
static qboolean Mods_Key(struct menucustom_s *c, struct menu_s *m, int key)
{
modmenu_t *mods = c->dptr;
int i;
ftemanifest_t *man;
if (key == K_MOUSE1)
{
i = (mousecursor_y - mods->y)/8;
if (i < 0 || i > mods->nummanifests)
return false;
man = mods->manifests[i];
mods->manifests[i] = NULL;
M_RemoveMenu(m);
FS_ChangeGame(man, true);
//starting to a blank state generally means that the current config settings are utterly useless and windowed by default.
//so generally when switching to a *real* game, we want to restart video just so things like fullscreen etc are saved+used properly.
//if we're already running a game, this should probably just be a vid_reload instead to ensure that the conback etc is reloaded.
Cbuf_AddText("\nvid_restart\n", RESTRICT_LOCAL);
return true;
}
return false;
}
static void Mods_Remove (struct menu_s *m)
{
modmenu_t *mods = m->data;
int i;
for (i = 0; i < mods->nummanifests; i++)
{
if (mods->manifests[i])
FS_Manifest_Free(mods->manifests[i]);
}
Z_Free(mods->manifests);
mods->manifests = NULL;
}
static qboolean Mods_AddMod(void *usr, ftemanifest_t *man)
{
modmenu_t *mods = usr;
int i = mods->nummanifests;
mods->manifests = BZ_Realloc(mods->manifests, (i+1) * sizeof(*mods->manifests));
mods->manifests[i] = man;
mods->nummanifests = i+1;
return true;
}
#include "fs.h"
void M_Menu_Mods_f (void)
{
modmenu_t *mods;
menucustom_t *c;
menu_t *menu;
Key_Dest_Add(kdm_menu);
menu = M_CreateMenu(sizeof(modmenu_t));
mods = menu->data;
MC_AddPicture(menu, 16, 4, 32, 144, "gfx/qplaque.lmp");
MC_AddCenterPicture(menu, 0, 24, "gfx/p_option.lmp");
c = MC_AddCustom(menu, 64, 32, mods, 0);
menu->cursoritem = (menuoption_t*)c;
c->draw = Mods_Draw;
c->key = Mods_Key;
menu->remove = Mods_Remove;
FS_EnumerateKnownGames(Mods_AddMod, menu->data);
if (mods->nummanifests == 1)
{
ftemanifest_t *man = mods->manifests[0];
mods->manifests[0] = NULL;
M_RemoveMenu(menu);
FS_ChangeGame(man, true);
}
}

View File

@ -243,10 +243,10 @@ void M_MenuS_Text_f (void)
return;
}
if (Cmd_Argc() == 4)
MC_AddBufferedText(menu_script, x, y, text, false, false);
MC_AddBufferedText(menu_script, x, 0, y, text, false, false);
else
{
option = (menuoption_t *)MC_AddConsoleCommand(menu_script, x, y, text, va("menucallback %s\n", command));
option = (menuoption_t *)MC_AddConsoleCommand(menu_script, x, 0, y, text, va("menucallback %s\n", command));
if (selectitem-- == 0)
menu_script->selecteditem = option;
}

View File

@ -79,13 +79,13 @@ void M_Menu_Save_f (void)
menu->data = menu+1;
MC_AddCenterPicture (menu, 4, 24, "gfx/p_save.lmp");
menu->cursoritem = (menuoption_t *)MC_AddRedText(menu, 8, 32, NULL, false);
menu->cursoritem = (menuoption_t *)MC_AddRedText(menu, 8, 0, 32, NULL, false);
M_ScanSaves ();
for (i=0 ; i< MAX_SAVEGAMES; i++)
{
op = (menuoption_t *)MC_AddConsoleCommandf(menu, 16, 32+8*i, m_filenames[i], "savegame s%i\nclosemenu\n", i);
op = (menuoption_t *)MC_AddConsoleCommandf(menu, 16, 170, 32+8*i, m_filenames[i], "savegame s%i\nclosemenu\n", i);
if (!menu->selecteditem)
menu->selecteditem = op;
}
@ -103,16 +103,16 @@ void M_Menu_Load_f (void)
menu->data = menu+1;
MC_AddCenterPicture(menu, 4, 24, "gfx/p_load.lmp");
menu->cursoritem = (menuoption_t *)MC_AddRedText(menu, 8, 32, NULL, false);
menu->cursoritem = (menuoption_t *)MC_AddRedText(menu, 8, 0, 32, NULL, false);
M_ScanSaves ();
for (i=0 ; i< MAX_SAVEGAMES; i++)
{
if (loadable[i])
op = (menuoption_t *)MC_AddConsoleCommandf(menu, 16, 32+8*i, m_filenames[i], "loadgame s%i\nclosemenu\n", i);
op = (menuoption_t *)MC_AddConsoleCommandf(menu, 16, 170, 32+8*i, m_filenames[i], "loadgame s%i\nclosemenu\n", i);
else
MC_AddWhiteText(menu, 16, 32+8*i, m_filenames[i], false);
MC_AddWhiteText(menu, 16, 170, 32+8*i, m_filenames[i], false);
if (!menu->selecteditem && op)
menu->selecteditem = op;
}
@ -136,8 +136,8 @@ void M_Menu_SinglePlayer_f (void)
#ifdef CLIENTONLY
menu = M_CreateMenu(0);
MC_AddWhiteText(menu, 84, 12*8, "This build is unable", false);
MC_AddWhiteText(menu, 84, 13*8, "to start a local game", false);
MC_AddWhiteText(menu, 84, 0, 12*8, "This build is unable", false);
MC_AddWhiteText(menu, 84, 0, 13*8, "to start a local game", false);
MC_AddBox (menu, 60, 10*8, 25, 4);
#else
@ -151,14 +151,14 @@ void M_Menu_SinglePlayer_f (void)
//quake2 uses the 'newgame' alias.
menu->selecteditem = (menuoption_t*)
MC_AddConsoleCommand (menu, 64, 40, "Easy", "closemenu; skill 0;deathmatch 0; coop 0;newgame\n");
MC_AddConsoleCommand (menu, 64, 48, "Medium", "closemenu; skill 1;deathmatch 0; coop 0;newgame\n");
MC_AddConsoleCommand (menu, 64, 56, "Hard", "closemenu; skill 2;deathmatch 0; coop 0;newgame\n");
MC_AddConsoleCommand (menu, 64, 170, 40, "Easy", "closemenu; skill 0;deathmatch 0; coop 0;newgame\n");
MC_AddConsoleCommand (menu, 64, 170, 48, "Medium", "closemenu; skill 1;deathmatch 0; coop 0;newgame\n");
MC_AddConsoleCommand (menu, 64, 170, 56, "Hard", "closemenu; skill 2;deathmatch 0; coop 0;newgame\n");
MC_AddConsoleCommand (menu, 64, 72, "Load Game", "menu_load\n");
MC_AddConsoleCommand (menu, 64, 80, "Save Game", "menu_save\n");
MC_AddConsoleCommand (menu, 64, 170, 72, "Load Game", "menu_load\n");
MC_AddConsoleCommand (menu, 64, 170, 80, "Save Game", "menu_save\n");
menu->cursoritem = (menuoption_t*)MC_AddWhiteText(menu, 48, 40, NULL, false);
menu->cursoritem = (menuoption_t*)MC_AddWhiteText(menu, 48, 0, 40, NULL, false);
return;
}
else if (mgt == MGT_HEXEN2)
@ -194,7 +194,7 @@ void M_Menu_SinglePlayer_f (void)
MC_AddCenterPicture(menu, 0, 60, "gfx/menu/title2.lmp");
if (cl_splitscreen.ival)
MC_AddBufferedText(menu, 80, (y+=8)+12, va("Player %i\n", pnum), false, true);
MC_AddBufferedText(menu, 80, 0, (y+=8)+12, va("Player %i\n", pnum), false, true);
for (i = 0; i < 4+havemp; i++)
{
@ -335,21 +335,21 @@ void M_Menu_SinglePlayer_f (void)
{
MC_AddBox (menu, 60, 10*8, 23, 4);
MC_AddWhiteText(menu, 92, 12*8, "Could find file", false);
MC_AddWhiteText(menu, 92, 13*8, "gfx/sp_menu.lmp", false);
MC_AddWhiteText(menu, 92, 0, 12*8, "Couldn't find file", false);
MC_AddWhiteText(menu, 92, 0, 13*8, "gfx/sp_menu.lmp", false);
}
else
{
MC_AddPicture(menu, 72, 32, 232, 64, "gfx/sp_menu.lmp");
b = MC_AddConsoleCommand (menu, 16, 32, "", "closemenu;disconnect;maxclients 1;deathmatch 0;coop 0;startmap_sp\n");
b = MC_AddConsoleCommand (menu, 16, 304, 32, "", "closemenu;disconnect;maxclients 1;deathmatch 0;coop 0;startmap_sp\n");
menu->selecteditem = (menuoption_t *)b;
b->common.width = p->width;
b->common.height = 20;
b = MC_AddConsoleCommand (menu, 16, 52, "", "menu_load\n");
b = MC_AddConsoleCommand (menu, 16, 304, 52, "", "menu_load\n");
b->common.width = p->width;
b->common.height = 20;
b = MC_AddConsoleCommand (menu, 16, 72, "", "menu_save\n");
b = MC_AddConsoleCommand (menu, 16, 304, 72, "", "menu_save\n");
b->common.width = p->width;
b->common.height = 20;
@ -374,7 +374,7 @@ typedef struct {
int pathlen;
char path[MAX_OSPATH];
int fsroot; //FS_ROOT, FS_GAME, FS_GAMEONLY. if FS_ROOT, executed command will have a leading #
int fsroot; //FS_SYSTEM, FS_GAME, FS_GAMEONLY. if FS_SYSTEM, executed command will have a leading #
char *command[64]; //these let the menu be used for nearly any sort of file browser.
char *ext[64];
@ -491,8 +491,7 @@ static qboolean M_DemoKey(menucustom_t *control, menu_t *menu, int key)
extnum = 0;
Cbuf_AddText(va("%s \"%s%s\"\n", info->command[extnum], (info->fsroot==FS_ROOT)?"#":"", info->selected->name), RESTRICT_LOCAL);
M_ToggleMenu_f();
M_RemoveMenu(menu);
}
}
return true;
@ -660,8 +659,8 @@ static void ShowDemoMenu (menu_t *menu, const char *path)
{
if (!strcmp(path, "../"))
{
info->fsroot = FS_ROOT;
FS_NativePath("", FS_ROOT, info->path, sizeof(info->path));
info->fsroot = FS_SYSTEM;
while((s = strchr(info->path, '\\')))
*s = '/';
}
@ -686,7 +685,7 @@ static void ShowDemoMenu (menu_t *menu, const char *path)
info->pathlen = strlen(info->path);
M_Demo_Flush(menu->data);
if (info->fsroot == FS_ROOT)
if (info->fsroot == FS_SYSTEM)
{
s = strchr(info->path, '/');
if (s && strchr(s+1, '/'))
@ -705,7 +704,7 @@ static void ShowDemoMenu (menu_t *menu, const char *path)
Q_snprintfz(match, sizeof(match), "../");
DemoAddItem(match, 0, info, NULL);
}
if (info->fsroot == FS_ROOT)
if (info->fsroot == FS_SYSTEM)
{
Q_snprintfz(match, sizeof(match), *info->path?"%s*":"/*", info->path);
Sys_EnumerateFiles("", match, DemoAddItem, info, NULL);
@ -732,20 +731,32 @@ void M_Menu_Demos_f (void)
info->fsroot = FS_GAME;
info->command[0] = "playdemo";
info->ext[0] = ".qwd";
info->command[1] = "playdemo";
info->ext[1] = ".dem";
info->command[2] = "playdemo";
info->ext[2] = ".dm2";
info->command[3] = "playdemo";
info->ext[3] = ".mvd";
info->numext = 0;
info->command[info->numext] = "playdemo";
info->ext[info->numext++] = ".qwd";
info->command[info->numext] = "playdemo";
info->ext[info->numext++] = ".dem";
info->command[info->numext] = "playdemo";
info->ext[info->numext++] = ".dm2";
info->command[info->numext] = "playdemo";
info->ext[info->numext++] = ".mvd";
info->command[info->numext] = "playdemo";
info->ext[info->numext++] = ".mvd.gz";
//there are also qizmo demos (.qwz) out there...
//we don't support them, but if we were to ask quizmo to decode them for us, we could do.
info->numext = 4;
MC_AddWhiteText(menu, 24, 8, "Choose a Demo", false);
MC_AddWhiteText(menu, 16, 24, "\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\37", false);
//and some archive formats... for the luls
info->command[info->numext] = NULL;
info->ext[info->numext++] = ".zip";
info->command[info->numext] = NULL;
info->ext[info->numext++] = ".pk3";
info->command[info->numext] = NULL;
info->ext[info->numext++] = ".pk4";
info->command[info->numext] = NULL;
info->ext[info->numext++] = ".pak";
MC_AddWhiteText(menu, 24, 170, 8, "Choose a Demo", false);
MC_AddWhiteText(menu, 16, 170, 24, "\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\37", false);
info->list = MC_AddCustom(menu, 0, 32, NULL, 0);
info->list->draw = M_DemoDraw;
@ -788,8 +799,8 @@ void M_Menu_MediaFiles_f (void)
info->numext++;
#endif
MC_AddWhiteText(menu, 24, 8, "Media List", false);
MC_AddWhiteText(menu, 16, 24, "\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\37", false);
MC_AddWhiteText(menu, 24, 170, 8, "Media List", false);
MC_AddWhiteText(menu, 16, 170, 24, "\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\37", false);
info->list = MC_AddCustom(menu, 0, 32, NULL, 0);
info->list->draw = M_DemoDraw;

View File

@ -23,6 +23,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
void M_Menu_Audio_f (void);
void M_Menu_Demos_f (void);
void M_Menu_Mods_f (void);
void M_Menu_ModelViewer_f(void);
m_state_t m_state;
@ -51,11 +53,9 @@ void M_DrawScalePic (int x, int y, int w, int h, mpic_t *pic)
R2D_ScalePic (x + ((vid.width - 320)>>1), y, w, h, pic);
}
void M_BuildTranslationTable(int top, int bottom, qbyte *translationTable)
void M_BuildTranslationTable(int top, int bottom, unsigned int *translationTable)
{
int j;
qbyte *dest, *source;
qbyte identityTable[256];
int pc = Cvar_Get("cl_playerclass", "1", 0, "Hexen2")->value;
if (h2playertranslations && pc)
@ -67,38 +67,49 @@ void M_BuildTranslationTable(int top, int bottom, qbyte *translationTable)
colorB = colorA + 256;
sourceA = colorB + (top * 256);
sourceB = colorB + (bottom * 256);
for(i=0;i<256;i++)
for(i=0;i<255;i++)
{
if (bottom > 0 && (colorB[i] != 255))
translationTable[i] = sourceB[i];
translationTable[i] = d_8to24rgbtable[sourceB[i]] | 0xff000000;
else if (top > 0 && (colorA[i] != 255))
translationTable[i] = sourceA[i];
translationTable[i] = d_8to24rgbtable[sourceA[i]] | 0xff000000;
else
translationTable[i] = i;
translationTable[i] = d_8to24rgbtable[i] | 0xff000000;
}
}
else
{
top *= 16;
bottom *= 16;
for (j = 0; j < 256; j++)
identityTable[j] = j;
dest = translationTable;
source = identityTable;
memcpy (dest, source, 256);
if (top < 128) // the artists made some backwards ranges. sigh.
memcpy (dest + TOP_RANGE, source + top, 16);
else
for (j=0 ; j<16 ; j++)
dest[TOP_RANGE+j] = source[top+15-j];
if (bottom < 128)
memcpy (dest + BOTTOM_RANGE, source + bottom, 16);
else
for (j=0 ; j<16 ; j++)
dest[BOTTOM_RANGE+j] = source[bottom+15-j];
for(j=0;j<255;j++)
{
if (j >= TOP_RANGE && j < TOP_RANGE + (1<<4))
{
if (top >= 16)
{
*((unsigned char*)&translationTable[j]+0) = (((top&0xff0000)>>16)**((unsigned char*)&d_8to24rgbtable[j&15]+0))>>8;
*((unsigned char*)&translationTable[j]+1) = (((top&0x00ff00)>> 8)**((unsigned char*)&d_8to24rgbtable[j&15]+1))>>8;
*((unsigned char*)&translationTable[j]+2) = (((top&0x0000ff)>> 0)**((unsigned char*)&d_8to24rgbtable[j&15]+2))>>8;
*((unsigned char*)&translationTable[j]+3) = 0xff;
}
else
translationTable[j] = d_8to24rgbtable[top<8?j-TOP_RANGE+(top<<4):(top<<4)+15-(j-TOP_RANGE)] | 0xff000000;
}
else if (j >= BOTTOM_RANGE && j < BOTTOM_RANGE + (1<<4))
{
if (bottom >= 16)
{
*((unsigned char*)&translationTable[j]+0) = (((bottom&0xff0000)>>16)**((unsigned char*)&d_8to24rgbtable[j&15]+0))>>8;
*((unsigned char*)&translationTable[j]+1) = (((bottom&0x00ff00)>> 8)**((unsigned char*)&d_8to24rgbtable[j&15]+1))>>8;
*((unsigned char*)&translationTable[j]+2) = (((bottom&0x0000ff)>> 0)**((unsigned char*)&d_8to24rgbtable[j&15]+2))>>8;
*((unsigned char*)&translationTable[j]+3) = 0xff;
}
else
translationTable[j] = d_8to24rgbtable[bottom<8?j-BOTTOM_RANGE+(bottom<<4):(bottom<<4)+15-(j-BOTTOM_RANGE)] | 0xff000000;
}
else
translationTable[j] = d_8to24rgbtable[j] | 0xff000000;
}
}
translationTable[255] = 0; //alpha
}
@ -454,7 +465,7 @@ int M_FindKeysForBind (char *command, int *keylist, int total)
return count;
}
void M_FindKeysForCommand (int pnum, char *command, int *twokeys)
void M_FindKeysForCommand (int pnum, const char *command, int *twokeys)
{
char prefix[5];
@ -485,7 +496,7 @@ void M_FindKeysForCommand (int pnum, char *command, int *twokeys)
M_FindKeysForBind(va("%s%s", prefix, command), twokeys, 2);
}
void M_UnbindCommand (char *command)
void M_UnbindCommand (const char *command)
{
int j;
int l;
@ -507,32 +518,38 @@ void M_UnbindCommand (char *command)
/* HELP MENU */
int help_page;
char *helpstyle;
int num_help_pages;
int helppagemin;
struct
{
char *pattern;
int base;
} helpstyles[] =
{
{"gfx/help%i.dxt",0}, //quake extended
{"gfx/help%i.tga",0}, //quake extended
{"gfx/help%i.png",0}, //quake extended
{"gfx/help%i.jpeg",0}, //quake extended
{"gfx/help%i.lmp",0}, //quake
{"gfx/menu/help%02i.lmp",1} //hexen2
};
void M_Menu_Help_f (void)
{
int i;
Key_Dest_Add(kdm_menu);
m_state = m_help;
help_page = 0;
if (COM_FDepthFile("gfx/help0.lmp", true) <= COM_FDepthFile("gfx/menu/help1.lmp", true))
{
helpstyle = "gfx/help%i.lmp";
helppagemin=0;
}
else
{
helpstyle = "gfx/menu/help%02i.lmp";
helppagemin = 1;
}
num_help_pages = 1;
while(num_help_pages < 100)
{
if (!COM_FDepthFile(va(helpstyle, num_help_pages+helppagemin), true))
for (i = 0; i < sizeof(helpstyles)/sizeof(helpstyles[0]); i++)
{
if (COM_FDepthFile(va(helpstyles[i].pattern, num_help_pages+helpstyles[i].base), true))
break;
}
if (i == sizeof(helpstyles)/sizeof(helpstyles[0]))
break;
num_help_pages++;
}
@ -542,8 +559,10 @@ void M_Menu_Help_f (void)
void M_Help_Draw (void)
{
mpic_t *pic;
pic = R2D_SafeCachePic(va(helpstyle, help_page+helppagemin));
int i;
mpic_t *pic = NULL;
for (i = 0; i < sizeof(helpstyles)/sizeof(helpstyles[0]) && !pic; i++)
pic = R2D_SafeCachePic(va(helpstyles[i].pattern, help_page+helpstyles[i].base));
if (!pic)
M_Menu_Main_f ();
else
@ -649,13 +668,13 @@ void M_Menu_Prompt (void (*callback)(void *, int), void *ctx, char *m1, char *m2
strcpy(t, optioncancel);
optioncancel = t;
MC_AddWhiteText(&m->m, 64, 84, m1, false);
MC_AddWhiteText(&m->m, 64, 92, m2, false);
MC_AddWhiteText(&m->m, 64, 100, m3, false);
MC_AddWhiteText(&m->m, 64, 0, 84, m1, false);
MC_AddWhiteText(&m->m, 64, 0, 92, m2, false);
MC_AddWhiteText(&m->m, 64, 0, 100, m3, false);
m->b_yes = MC_AddCommand(&m->m, 64, 116, optionyes, M_Menu_Prompt_Button);
m->b_no = MC_AddCommand(&m->m, 144,116, optionno, M_Menu_Prompt_Button);
m->b_cancel = MC_AddCommand(&m->m, 224,116, optioncancel, M_Menu_Prompt_Button);
m->b_yes = MC_AddCommand(&m->m, 64, 0, 116, optionyes, M_Menu_Prompt_Button);
m->b_no = MC_AddCommand(&m->m, 144,0, 116, optionno, M_Menu_Prompt_Button);
m->b_cancel = MC_AddCommand(&m->m, 224,0, 116, optioncancel, M_Menu_Prompt_Button);
m->m.selecteditem = (menuoption_t *)m->b_cancel;
@ -920,14 +939,14 @@ void M_Menu_Quit_f (void)
quitmenu = M_CreateMenuInfront(0);
quitmenu->key = MC_SaveQuit_Key;
MC_AddWhiteText(quitmenu, 64, 84, "You have unsaved settings ", false);
MC_AddWhiteText(quitmenu, 64, 92, " Would you like to ", false);
MC_AddWhiteText(quitmenu, 64, 100, " save them now? ", false);
quitmenu->selecteditem = (menuoption_t *)
MC_AddConsoleCommand (quitmenu, 64, 116, "Yes", "menu_quit forcesave\n");
MC_AddConsoleCommand (quitmenu, 144,116, "No", "menu_quit force\n");
MC_AddConsoleCommand (quitmenu, 224,116, "Cancel", "menupop\n");
MC_AddWhiteText(quitmenu, 64, 0, 84, "You have unsaved settings ", false);
MC_AddWhiteText(quitmenu, 64, 0, 92, " Would you like to ", false);
MC_AddWhiteText(quitmenu, 64, 0, 100, " save them now? ", false);
quitmenu->selecteditem = (menuoption_t *)
MC_AddConsoleCommand (quitmenu, 64, 0, 116, "Yes", "menu_quit forcesave\n");
MC_AddConsoleCommand (quitmenu, 144,0, 116, "No", "menu_quit force\n");
MC_AddConsoleCommand (quitmenu, 224,0, 116, "Cancel", "menupop\n");
MC_AddBox (quitmenu, 56, 76, 25, 5);
break;
@ -942,14 +961,14 @@ void M_Menu_Quit_f (void)
i = rand()&7;
MC_AddWhiteText(quitmenu, 64, 84, quitMessage[i*4+0], false);
MC_AddWhiteText(quitmenu, 64, 92, quitMessage[i*4+1], false);
MC_AddWhiteText(quitmenu, 64, 100, quitMessage[i*4+2], false);
MC_AddWhiteText(quitmenu, 64, 108, quitMessage[i*4+3], false);
MC_AddWhiteText(quitmenu, 64, 0, 84, quitMessage[i*4+0], false);
MC_AddWhiteText(quitmenu, 64, 0, 92, quitMessage[i*4+1], false);
MC_AddWhiteText(quitmenu, 64, 0, 100, quitMessage[i*4+2], false);
MC_AddWhiteText(quitmenu, 64, 0, 108, quitMessage[i*4+3], false);
quitmenu->selecteditem = (menuoption_t *)
MC_AddConsoleCommand (quitmenu, 120, 116, "Yes", "menu_quit force\n");
MC_AddConsoleCommand (quitmenu, 208,116, "No", "menupop\n");
MC_AddConsoleCommand (quitmenu, 120, 0, 116, "Yes", "menu_quit force\n");
MC_AddConsoleCommand (quitmenu, 208, 0, 116, "No", "menupop\n");
MC_AddBox (quitmenu, 56, 76, 24, 5);
break;
@ -1007,6 +1026,8 @@ void M_Init_Internal (void)
Cmd_AddCommand ("menu_quit", M_Menu_Quit_f);
Cmd_AddCommand ("menu_media", M_Menu_Media_f);
Cmd_AddCommand ("menu_mediafiles", M_Menu_MediaFiles_f);
Cmd_AddCommand ("menu_mods", M_Menu_Mods_f);
Cmd_AddCommand ("modelviewer", M_Menu_ModelViewer_f);
#ifdef CL_MASTER
Cmd_AddCommand ("menu_servers", M_Menu_ServerList2_f);
@ -1111,12 +1132,13 @@ void M_DeInit_Internal (void)
Cmd_RemoveCommand ("quickconnect");
}
void M_Shutdown(void)
void M_Shutdown(qboolean total)
{
#ifdef MENU_DAT
MP_Shutdown();
#endif
M_DeInit_Internal();
if (total)
M_DeInit_Internal();
}
void M_Reinit(void)

View File

@ -103,7 +103,7 @@ void M_SomeInitialisationFunctionCalledAtStartup(void)
//
void M_Init (void);
void M_Reinit(void);
void M_Shutdown(void);
void M_Shutdown(qboolean total);
void M_Keydown (int key, int unicode);
void M_Keyup (int key, int unicode);
void M_Draw (int uimenu);
@ -290,9 +290,9 @@ typedef struct menu_s {
menuoption_t *cursoritem;
} menu_t;
menutext_t *MC_AddBufferedText(menu_t *menu, int x, int y, const char *text, qboolean rightalign, qboolean red);
menutext_t *MC_AddRedText(menu_t *menu, int x, int y, const char *text, qboolean rightalign);
menutext_t *MC_AddWhiteText(menu_t *menu, int x, int y, const char *text, qboolean rightalign);
menutext_t *MC_AddBufferedText(menu_t *menu, int lhs, int rhs, int y, const char *text, qboolean rightalign, qboolean red);
menutext_t *MC_AddRedText(menu_t *menu, int lhs, int rhs, int y, const char *text, qboolean rightalign);
menutext_t *MC_AddWhiteText(menu_t *menu, int lhs, int rhs, int y, const char *text, qboolean rightalign);
menubind_t *MC_AddBind(menu_t *menu, int cx, int bx, int y, const char *caption, char *command);
menubox_t *MC_AddBox(menu_t *menu, int x, int y, int width, int height);
menupicture_t *MC_AddPicture(menu_t *menu, int x, int y, int width, int height, char *picname);
@ -302,15 +302,14 @@ menupicture_t *MC_AddCursor(menu_t *menu, int x, int y);
menuslider_t *MC_AddSlider(menu_t *menu, int tx, int sx, int y, const char *text, cvar_t *var, float min, float max, float delta);
menucheck_t *MC_AddCheckBox(menu_t *menu, int tx, int cx, int y, const char *text, cvar_t *var, int cvarbitmask);
menucheck_t *MC_AddCheckBoxFunc(menu_t *menu, int tx, int cx, int y, const char *text, qboolean (*func) (menucheck_t *option, menu_t *menu, chk_set_t set), int bits);
menubutton_t *MC_AddConsoleCommand(menu_t *menu, int x, int y, const char *text, const char *command);
menubutton_t *MC_AddConsoleCommand(menu_t *menu, int lhs, int rhs, int y, const char *text, const char *command);
menubutton_t *MC_AddConsoleCommandQBigFont(menu_t *menu, int x, int y, const char *text, const char *command);
mpic_t *QBigFontWorks(void);
menubutton_t *MC_AddConsoleCommandHexen2BigFont(menu_t *menu, int x, int y, const char *text, const char *command);
menubutton_t *VARGS MC_AddConsoleCommandf(menu_t *menu, int x, int y, const char *text, char *command, ...);
menubutton_t *MC_AddCommand(menu_t *menu, int x, int y, char *text, qboolean (*command) (union menuoption_s *,struct menu_s *,int));
menubutton_t *VARGS MC_AddConsoleCommandf(menu_t *menu, int lhs, int rhs, int y, const char *text, char *command, ...);
menubutton_t *MC_AddCommand(menu_t *menu, int lhs, int rhs, int y, char *text, qboolean (*command) (union menuoption_s *,struct menu_s *,int));
menucombo_t *MC_AddCombo(menu_t *menu, int tx, int cx, int y, const char *caption, const char **ops, int initialvalue);
menucombo_t *MC_AddCvarCombo(menu_t *menu, int tx, int cx, int y, const char *caption, cvar_t *cvar, const char **ops, const char **values);
menubutton_t *MC_AddCommand(menu_t *menu, int x, int y, char *text, qboolean (*command) (union menuoption_s *,struct menu_s *,int));
menuedit_t *MC_AddEdit(menu_t *menu, int cx, int ex, int y, char *text, char *def);
menuedit_t *MC_AddEditCvar(menu_t *menu, int cx, int ex, int y, char *text, char *name, qboolean slim);
menucustom_t *MC_AddCustom(menu_t *menu, int x, int y, void *dptr, int dint);
@ -432,15 +431,15 @@ void M_DrawServers(void);
void M_SListKey(int key);
//drawing funcs
void M_BuildTranslationTable(int top, int bottom, qbyte *translationTable);
void M_BuildTranslationTable(int top, int bottom, unsigned int *translationTable);
void M_DrawCharacter (int cx, int line, unsigned int num);
void M_Print (int cx, int cy, qbyte *str);
void M_PrintWhite (int cx, int cy, qbyte *str);
void M_DrawScalePic (int x, int y, int w, int h, mpic_t *pic);
void M_FindKeysForCommand (int pnum, char *command, int *twokeys);
void M_UnbindCommand (char *command);
void M_FindKeysForCommand (int pnum, const char *command, int *twokeys);
void M_UnbindCommand (const char *command);
void MP_CvarChanged(cvar_t *var);
qboolean MP_Init (void);

View File

@ -10,7 +10,13 @@ struct entity_s;
struct dlight_s;
struct galiasbone_s;
typedef enum
{
SKEL_RELATIVE, //relative to parent.
SKEL_ABSOLUTE, //relative to model. doesn't blend very well.
SKEL_INVERSE_RELATIVE, //pre-inverted. faster than regular relative but has weirdness with skeletal objects. blends okay.
SKEL_INVERSE_ABSOLUTE //final renderable type.
} skeltype_t;
#ifdef HALFLIFEMODELS
#define MAX_BONE_CONTROLLERS 5
@ -32,9 +38,11 @@ typedef struct {
int endbone;
} g[FS_COUNT];
#ifdef SKELETALOBJECTS
float *bonestate;
int bonecount;
qboolean boneabs;
skeltype_t skeltype;
#endif
#ifdef HALFLIFEMODELS
float bonecontrols[MAX_BONE_CONTROLLERS]; //hl special bone controllers
@ -55,12 +63,12 @@ typedef struct {
extern r_qrenderer_t qrenderer;
extern char *q_renderername;
mpic_t *R2D_SafeCachePic (char *path);
mpic_t *R2D_SafePicFromWad (char *name);
mpic_t *R2D_SafeCachePic (const char *path);
mpic_t *R2D_SafePicFromWad (const char *name);
void R2D_DrawCrosshair (void);
void R2D_ScalePic (float x, float y, float width, float height, mpic_t *pic);
void R2D_SubPic(float x, float y, float width, float height, mpic_t *pic, float srcx, float srcy, float srcwidth, float srcheight);
void R2D_TransPicTranslate (float x, float y, int width, int height, qbyte *pic, qbyte *translation);
void R2D_TransPicTranslate (float x, float y, int width, int height, qbyte *pic, unsigned int *palette);
void R2D_TileClear (float x, float y, float w, float h);
void R2D_FadeScreen (void);
@ -98,7 +106,7 @@ extern void SCR_SetUpToDrawConsole (void);
extern void SCR_EraseCenterString (void);
extern void SCR_CenterPrint (int pnum, char *str, qboolean skipgamecode);
void R_DrawTextField(int x, int y, int w, int h, char *text, unsigned int defaultmask, unsigned int fieldflags);
void R_DrawTextField(int x, int y, int w, int h, const char *text, unsigned int defaultmask, unsigned int fieldflags);
#define CPRINT_BALIGN (1<<0) //B
#define CPRINT_TALIGN (1<<1) //T
#define CPRINT_LALIGN (1<<2) //L
@ -118,25 +126,32 @@ enum mod_purge_e
MP_FLUSH, //user flush command. anything flushable goes.
MP_RESET //*everything* is destroyed. renderer is going down.
};
enum mlverbosity_e
{
MLV_SILENT,
MLV_WARN,
MLV_ERROR
};
extern void Mod_ClearAll (void);
extern void Mod_Purge (enum mod_purge_e type);
extern struct model_s *Mod_ForName (char *name, qboolean crash);
extern struct model_s *Mod_FindName (char *name);
extern struct model_s *Mod_FindName (const char *name); //find without loading. needload should be set.
extern struct model_s *Mod_ForName (const char *name, enum mlverbosity_e verbosity); //finds+loads
extern struct model_s *Mod_LoadModel (struct model_s *mod, enum mlverbosity_e verbose); //makes sure a model is loaded
extern void *Mod_Extradata (struct model_s *mod); // handles caching
extern void Mod_TouchModel (char *name);
extern void Mod_TouchModel (const char *name);
extern void Mod_NowLoadExternal (void);
extern void Mod_Think (void);
extern int Mod_SkinNumForName (struct model_s *model, char *name);
extern int Mod_FrameNumForName (struct model_s *model, char *name);
extern int Mod_SkinNumForName (struct model_s *model, const char *name);
extern int Mod_FrameNumForName (struct model_s *model, const char *name);
extern float Mod_GetFrameDuration (struct model_s *model, int framenum);
#undef FNC
extern qboolean Mod_GetTag (struct model_s *model, int tagnum, framestate_t *framestate, float *transforms);
extern int Mod_TagNumForName (struct model_s *model, char *name);
extern int Mod_TagNumForName (struct model_s *model, const char *name);
int Mod_GetNumBones(struct model_s *model, qboolean allowtags);
int Mod_GetBoneRelations(struct model_s *model, int firstbone, int lastbone, framestate_t *fstate, float *result);
@ -291,12 +306,12 @@ typedef struct rendererinfo_s {
void (*Draw_Init) (void);
void (*Draw_Shutdown) (void);
texid_tf (*IMG_LoadTexture) (char *identifier, int width, int height, uploadfmt_t fmt, void *data, unsigned int flags);
texid_tf (*IMG_LoadTexture8Pal24) (char *identifier, int width, int height, qbyte *data, qbyte *palette24, unsigned int flags);
texid_tf (*IMG_LoadTexture8Pal32) (char *identifier, int width, int height, qbyte *data, qbyte *palette32, unsigned int flags);
texid_tf (*IMG_LoadCompressed) (char *name);
texid_tf (*IMG_FindTexture) (char *identifier, unsigned int flags);
texid_tf (*IMG_AllocNewTexture) (char *identifier, int w, int h, unsigned int flags);
texid_tf (*IMG_LoadTexture) (const char *identifier, int width, int height, uploadfmt_t fmt, void *data, unsigned int flags);
texid_tf (*IMG_LoadTexture8Pal24) (const char *identifier, int width, int height, qbyte *data, qbyte *palette24, unsigned int flags);
texid_tf (*IMG_LoadTexture8Pal32) (const char *identifier, int width, int height, qbyte *data, qbyte *palette32, unsigned int flags);
texid_tf (*IMG_LoadCompressed) (const char *name);
texid_tf (*IMG_FindTexture) (const char *identifier, unsigned int flags);
texid_tf (*IMG_AllocNewTexture) (const char *identifier, int w, int h, unsigned int flags);
void (*IMG_Upload) (texid_t tex, char *name, uploadfmt_t fmt, void *data, void *palette, int width, int height, unsigned int flags);
void (*IMG_DestroyTexture) (texid_t tex);
@ -385,4 +400,5 @@ typedef struct rendererinfo_s {
texid_t R2D_RT_Configure(unsigned int id, int width, int height, uploadfmt_t rtfmt);
texid_t R2D_RT_GetTexture(unsigned int id, unsigned int *width, unsigned int *height);
texid_t R2D_RT_DetachTexture(unsigned int id);

View File

@ -63,7 +63,7 @@ typedef struct {
hostcachekey_t fieldindex;
float operandi;
char *operands;
const char *operands;
qboolean or;
int compareop;
@ -175,7 +175,7 @@ qboolean Master_CompareInteger(int a, int b, slist_test_t rule)
}
return false;
}
qboolean Master_CompareString(char *a, char *b, slist_test_t rule)
qboolean Master_CompareString(const char *a, const char *b, slist_test_t rule)
{
switch(rule)
{
@ -325,7 +325,7 @@ void Master_ClearMasks(void)
numvisrules = 0;
}
void Master_SetMaskString(qboolean or, hostcachekey_t field, char *param, slist_test_t testop)
void Master_SetMaskString(qboolean or, hostcachekey_t field, const char *param, slist_test_t testop)
{
if (numvisrules == MAX_VISRULES)
return; //just don't add it.
@ -540,7 +540,7 @@ char *Master_ReadKeyString(serverinfo_t *server, int keynum)
return "";
}
int Master_KeyForName(char *keyname)
int Master_KeyForName(const char *keyname)
{
int i;
if (!strcmp(keyname, "map"))

View File

@ -27,9 +27,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define POLYS
void D_DrawParticleTrans (vec3_t porg, float palpha, float pscale, unsigned int pcolour, blendmode_t blendmode);
typedef enum {
DODGY,
@ -95,7 +92,7 @@ static union c
} classiccolours[BUFFERVERTS];
static vec2_t classictexcoords[BUFFERVERTS];
static index_t classicindexes[BUFFERVERTS];
mesh_t classicmesh;
static mesh_t classicmesh;
#endif
static shader_t *classicshader;
@ -103,7 +100,7 @@ static shader_t *classicshader;
//obtains an index for the name, even if it is unknown (one can be loaded after. will only fail if the effect limit is reached)
//technically this function is not meant to fail often, but thats fine so long as the other functions are meant to safely reject invalid effect numbers.
static int PClassic_FindParticleType(char *name)
static int PClassic_FindParticleType(const char *name)
{
if (!stricmp("tr_rocket", name))
return ROCKET_TRAIL;
@ -134,7 +131,7 @@ static int PClassic_FindParticleType(char *name)
return P_INVALID;
}
qboolean PClassic_Query(int type, int body, char *outstr, int outstrlen)
static qboolean PClassic_Query(int type, int body, char *outstr, int outstrlen)
{
char *n = NULL;
switch(type)
@ -765,6 +762,10 @@ static float Classic_ParticleTrail (vec3_t start, vec3_t end, float leftover, ef
scale = 6; break;
default:
scale = 3; break;
case TRACER1_TRAIL:
case TRACER2_TRAIL:
scale = (r_part_density.value < 0.5)?6*r_part_density.value:3;
break;
}
scale /= r_part_density.value;

View File

@ -5,7 +5,7 @@
#include "renderque.h"
//returns a valid effect if its existance is known.
static int PNULL_FindParticleType(char *name)
static int PNULL_FindParticleType(const char *name)
{
// Con_DPrintf("P_FindParticleType %s\n", name);
return P_INVALID;

View File

@ -462,7 +462,7 @@ static int P_AllocateParticleType(char *config, char *name) //guarentees that th
}
//public interface. get without creating.
static int PScript_FindParticleType(char *name)
static int PScript_FindParticleType(const char *name)
{
int i;
part_type_t *ptype = NULL;
@ -3171,7 +3171,7 @@ static void PScript_EffectSpawned(part_type_t *ptype, vec3_t org, vec3_t dir, in
{
mod = &ptype->models[rand() % ptype->nummodels];
if (!mod->model)
mod->model = Mod_ForName(mod->name, false);
mod->model = Mod_ForName(mod->name, MLV_WARN);
if (mod->model && !mod->model->needload)
{
vec3_t morg, mdir;

View File

@ -284,7 +284,7 @@ int MP_TranslateQCtoFTECodes(int code)
//string findkeysforcommand(string command) = #610;
void QCBUILTIN PF_cl_findkeysforcommand (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *cmdname = PR_GetStringOfs(prinst, OFS_PARM0);
const char *cmdname = PR_GetStringOfs(prinst, OFS_PARM0);
int keynums[2];
char keyname[512];
@ -308,7 +308,7 @@ void QCBUILTIN PF_cl_stringtokeynum(pubprogfuncs_t *prinst, struct globalvars_s
{
int i;
int modifier;
char *s;
const char *s;
s = PR_GetStringOfs(prinst, OFS_PARM0);
i = Key_StringToKeynum(s, &modifier);
@ -353,7 +353,7 @@ void QCBUILTIN PF_cl_runningserver (pubprogfuncs_t *prinst, struct globalvars_s
// #487 float(string name) gecko_create( string name )
void QCBUILTIN PF_cs_gecko_create (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *shadername = PR_GetStringOfs(prinst, OFS_PARM0);
const char *shadername = PR_GetStringOfs(prinst, OFS_PARM0);
cin_t *cin;
cin = R_ShaderGetCinematic(R_RegisterShader(shadername, SUF_2D,
"{\n"
@ -375,8 +375,8 @@ void QCBUILTIN PF_cs_gecko_destroy (pubprogfuncs_t *prinst, struct globalvars_s
// #489 void(string name) gecko_navigate( string name, string URI )
void QCBUILTIN PF_cs_gecko_navigate (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *shader = PR_GetStringOfs(prinst, OFS_PARM0);
char *command = PR_GetStringOfs(prinst, OFS_PARM1);
const char *shader = PR_GetStringOfs(prinst, OFS_PARM0);
const char *command = PR_GetStringOfs(prinst, OFS_PARM1);
cin_t *cin;
cin = R_ShaderFindCinematic(shader);
@ -388,7 +388,7 @@ void QCBUILTIN PF_cs_gecko_navigate (pubprogfuncs_t *prinst, struct globalvars_s
// #490 float(string name) gecko_keyevent( string name, float key, float eventtype )
void QCBUILTIN PF_cs_gecko_keyevent (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *shader = PR_GetStringOfs(prinst, OFS_PARM0);
const char *shader = PR_GetStringOfs(prinst, OFS_PARM0);
int key = G_FLOAT(OFS_PARM1);
int eventtype = G_FLOAT(OFS_PARM2);
cin_t *cin;
@ -401,7 +401,7 @@ void QCBUILTIN PF_cs_gecko_keyevent (pubprogfuncs_t *prinst, struct globalvars_s
// #491 void gecko_mousemove( string name, float x, float y )
void QCBUILTIN PF_cs_gecko_mousemove (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *shader = PR_GetStringOfs(prinst, OFS_PARM0);
const char *shader = PR_GetStringOfs(prinst, OFS_PARM0);
float posx = G_FLOAT(OFS_PARM1);
float posy = G_FLOAT(OFS_PARM2);
cin_t *cin;
@ -414,7 +414,7 @@ void QCBUILTIN PF_cs_gecko_mousemove (pubprogfuncs_t *prinst, struct globalvars_
// #492 void gecko_resize( string name, float w, float h )
void QCBUILTIN PF_cs_gecko_resize (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *shader = PR_GetStringOfs(prinst, OFS_PARM0);
const char *shader = PR_GetStringOfs(prinst, OFS_PARM0);
float sizex = G_FLOAT(OFS_PARM1);
float sizey = G_FLOAT(OFS_PARM2);
cin_t *cin;
@ -426,7 +426,7 @@ void QCBUILTIN PF_cs_gecko_resize (pubprogfuncs_t *prinst, struct globalvars_s *
// #493 vector gecko_get_texture_extent( string name )
void QCBUILTIN PF_cs_gecko_get_texture_extent (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *shader = PR_GetStringOfs(prinst, OFS_PARM0);
const char *shader = PR_GetStringOfs(prinst, OFS_PARM0);
float *ret = G_VECTOR(OFS_RETURN);
int sx, sy;
cin_t *cin;
@ -448,7 +448,7 @@ void QCBUILTIN PF_cs_gecko_get_texture_extent (pubprogfuncs_t *prinst, struct gl
void QCBUILTIN PF_soundlength (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *sample = PR_GetStringOfs(prinst, OFS_PARM0);
const char *sample = PR_GetStringOfs(prinst, OFS_PARM0);
sfx_t *sfx = S_PrecacheSound(sample);
if (!sfx || sfx->failedload)
@ -512,7 +512,7 @@ void QCBUILTIN PF_cl_sethostcachemaskstring(pubprogfuncs_t *prinst, struct globa
{
int mask = G_FLOAT(OFS_PARM0);
int field = G_FLOAT(OFS_PARM1);
char *str = PR_GetStringOfs(prinst, OFS_PARM2);
const char *str = PR_GetStringOfs(prinst, OFS_PARM2);
int op = G_FLOAT(OFS_PARM3);
Master_SetMaskString(mask, field, str, op);
@ -571,7 +571,7 @@ void QCBUILTIN PF_cl_gethostcachestring (pubprogfuncs_t *prinst, struct globalva
//float gethostcacheindexforkey(string key) = #622;
void QCBUILTIN PF_cl_gethostcacheindexforkey(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *keyname = PR_GetStringOfs(prinst, OFS_PARM0);
const char *keyname = PR_GetStringOfs(prinst, OFS_PARM0);
G_FLOAT(OFS_RETURN) = Master_KeyForName(keyname);
}
@ -610,12 +610,10 @@ void PF_cl_addwantedhostcachekey(pubprogfuncs_t *prinst, struct globalvars_s *pr
#endif
void QCBUILTIN PF_shaderforname (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *str = PR_GetStringOfs(prinst, OFS_PARM0);
char *defaultbody = PF_VarString(prinst, 1, pr_globals);
const char *str = PR_GetStringOfs(prinst, OFS_PARM0);
const char *defaultbody = PF_VarString(prinst, 1, pr_globals);
shader_t *shad;

View File

@ -64,7 +64,6 @@ static unsigned int csprogs_checksum;
static csqctreadstate_t *csqcthreads;
qboolean csqc_resortfrags;
qboolean csqc_addcrosshair;
static int csqc_fakereadbyte;
world_t csqc_world;
int csqc_playerseat; //can be negative.
@ -81,7 +80,7 @@ cvar_t pr_csqc_memsize = CVAR("pr_csqc_memsize", "-1");
cvar_t cl_csqcdebug = CVAR("cl_csqcdebug", "0"); //prints entity numbers which arrive (so I can tell people not to apply it to players...)
cvar_t cl_nocsqc = CVAR("cl_nocsqc", "0");
cvar_t pr_csqc_coreonerror = CVAR("pr_csqc_coreonerror", "1");
cvar_t pr_csqc_formenus = CVAR("pr_csqc_formenus", "1");
cvar_t pr_csqc_formenus = CVAR("pr_csqc_formenus", "0");
extern cvar_t dpcompat_stats;
cvar_t dpcompat_corruptglobals = CVAR("dpcompat_corruptglobals", "0");
@ -382,6 +381,7 @@ typedef struct csqcedict_s
//add whatever you wish here
trailstate_t *trailstate;
int skinobject;
} csqcedict_t;
@ -426,7 +426,7 @@ static int maxcsqcentities;
static int csqcentsize;
static char *csqcmapentitydata;
static const char *csqcmapentitydata;
static qboolean csqcmapentitydataloaded;
qboolean csqc_deprecated_warned;
@ -525,7 +525,7 @@ static void QCBUILTIN PF_cs_remove (pubprogfuncs_t *prinst, struct globalvars_s
static void QCBUILTIN PF_cvar (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
cvar_t *var;
char *str;
const char *str;
str = PR_GetStringOfs(prinst, OFS_PARM0);
@ -588,7 +588,7 @@ static model_t *CSQC_GetModelForIndex(int index)
else if (index < 0 && index > -MAX_CSMODELS)
{
if (!cl.model_csqcprecache[-index])
cl.model_csqcprecache[-index] = Mod_ForName(cl.model_csqcname[-index], false);
cl.model_csqcprecache[-index] = Mod_ForName(cl.model_csqcname[-index], MLV_WARN);
return cl.model_csqcprecache[-index];
}
else
@ -724,6 +724,7 @@ static qboolean CopyCSQCEdictToEntity(csqcedict_t *in, entity_t *out)
out->forcedshader = r_shaders[(ival-1)];
else
out->forcedshader = NULL;
out->customskin = (in->skinobject<0)?-in->skinobject:in->skinobject;
out->keynum = -in->entnum;
@ -782,7 +783,7 @@ static void QCBUILTIN PF_R_AddDecal(pubprogfuncs_t *prinst, struct globalvars_s
static void QCBUILTIN PF_R_DynamicLight_Set(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *s;
const char *s;
dlight_t *l;
unsigned int lno = G_FLOAT(OFS_PARM0);
int field = G_FLOAT(OFS_PARM1);
@ -924,7 +925,7 @@ static void QCBUILTIN PF_R_DynamicLight_Add(pubprogfuncs_t *prinst, struct globa
float radius = G_FLOAT(OFS_PARM1);
float *rgb = G_VECTOR(OFS_PARM2);
float style = (prinst->callargc > 3)?G_FLOAT(OFS_PARM3):0;
char *cubemapname = (prinst->callargc > 4)?PR_GetStringOfs(prinst, OFS_PARM4):"";
const char *cubemapname = (prinst->callargc > 4)?PR_GetStringOfs(prinst, OFS_PARM4):"";
int pflags = (prinst->callargc > 5)?G_FLOAT(OFS_PARM5):PFLAGS_CORONA;
wedict_t *self = PROG_TO_WEDICT(prinst, *csqcg.self);
@ -1629,6 +1630,7 @@ static void QCBUILTIN PF_R_RenderScene(pubprogfuncs_t *prinst, struct globalvars
Sbar_DrawScoreboard ();
}
#endif
SCR_ShowPics_Draw();
}
if (csqc_addcrosshair)
@ -1862,7 +1864,7 @@ static void QCBUILTIN PF_cs_pointcontents(pubprogfuncs_t *prinst, struct globalv
G_FLOAT(OFS_RETURN) = Q1CONTENTS_EMPTY;
}
static int FindModel(char *name, int *free)
static int FindModel(const char *name, int *free)
{
int i;
@ -1900,7 +1902,7 @@ static void csqc_setmodel(pubprogfuncs_t *prinst, csqcedict_t *ent, int modelind
return;
ent->v->model = PR_SetString(prinst, cl.model_csqcname[-modelindex]);
if (!cl.model_csqcprecache[-modelindex])
cl.model_csqcprecache[-modelindex] = Mod_ForName(cl.model_csqcname[-modelindex], false);
cl.model_csqcprecache[-modelindex] = Mod_ForName(cl.model_csqcname[-modelindex], MLV_WARN);
model = cl.model_csqcprecache[-modelindex];
}
else
@ -1927,7 +1929,7 @@ static void csqc_setmodel(pubprogfuncs_t *prinst, csqcedict_t *ent, int modelind
static void QCBUILTIN PF_cs_SetModel(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
csqcedict_t *ent = (void*)G_EDICT(prinst, OFS_PARM0);
char *modelname = PR_GetStringOfs(prinst, OFS_PARM1);
const char *modelname = PR_GetStringOfs(prinst, OFS_PARM1);
int freei;
int modelindex = FindModel(modelname, &freei);
@ -1954,7 +1956,7 @@ static void QCBUILTIN PF_cs_SetModelIndex(pubprogfuncs_t *prinst, struct globalv
static void QCBUILTIN PF_cs_PrecacheModel(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int modelindex, freei;
char *modelname = PR_GetStringOfs(prinst, OFS_PARM0);
const char *modelname = PR_GetStringOfs(prinst, OFS_PARM0);
int i;
if (!*modelname)
@ -1969,7 +1971,7 @@ static void QCBUILTIN PF_cs_PrecacheModel(pubprogfuncs_t *prinst, struct globalv
break;
if (!strcmp(cl.model_name[i], modelname))
{
cl.model_precache[i] = Mod_ForName(cl.model_name[i], false);
cl.model_precache[i] = Mod_ForName(cl.model_name[i], MLV_WARN);
break;
}
}
@ -1989,9 +1991,14 @@ static void QCBUILTIN PF_cs_PrecacheModel(pubprogfuncs_t *prinst, struct globalv
G_FLOAT(OFS_RETURN) = modelindex;
}
static void QCBUILTIN PF_cs_precachefile(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
const char *filename = PR_GetStringOfs(prinst, OFS_PARM0);
G_FLOAT(OFS_RETURN) = CL_CheckOrEnqueDownloadFile(filename, NULL, 0);
}
static void QCBUILTIN PF_cs_PrecacheSound(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *soundname = PR_GetStringOfs(prinst, OFS_PARM0);
const char *soundname = PR_GetStringOfs(prinst, OFS_PARM0);
Sound_CheckDownload(soundname);
S_PrecacheSound(soundname);
}
@ -2005,6 +2012,26 @@ static void QCBUILTIN PF_cs_ModelnameForIndex(pubprogfuncs_t *prinst, struct glo
else
G_INT(OFS_RETURN) = (int)PR_SetString(prinst, cl.model_name[modelindex]);
}
void QCBUILTIN PF_cs_setcustomskin (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
csqcedict_t *ent = (void*)G_EDICT(prinst, OFS_PARM0);
const char *fname = PR_GetStringOfs(prinst, OFS_PARM1);
const char *skindata = PF_VarString(prinst, 2, pr_globals);
if (ent->skinobject > 0)
{
Mod_WipeSkin(ent->skinobject);
ent->skinobject = 0;
}
if (*fname || *skindata)
{
if (*skindata)
ent->skinobject = Mod_ReadSkinFile(fname, skindata);
else
ent->skinobject = -(int)Mod_RegisterSkinFile(fname);
}
}
static void QCBUILTIN PF_ReadByte(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
@ -2014,15 +2041,7 @@ static void QCBUILTIN PF_ReadByte(pubprogfuncs_t *prinst, struct globalvars_s *p
G_FLOAT(OFS_RETURN) = -1;
return;
}
if (csqc_fakereadbyte != -1)
{
G_FLOAT(OFS_RETURN) = csqc_fakereadbyte;
csqc_fakereadbyte = -1;
}
else
{
G_FLOAT(OFS_RETURN) = MSG_ReadByte();
}
G_FLOAT(OFS_RETURN) = MSG_ReadByte();
}
static void QCBUILTIN PF_ReadChar(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
@ -2143,7 +2162,7 @@ static void QCBUILTIN PF_objerror (pubprogfuncs_t *prinst, struct globalvars_s *
}
}
static void QCBUILTIN PF_cs_setsensativityscaler (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
static void QCBUILTIN PF_cs_setsensitivityscaler (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
in_sensitivityscale = G_FLOAT(OFS_PARM0);
}
@ -2220,7 +2239,9 @@ static void QCBUILTIN PF_cs_trailparticles (pubprogfuncs_t *prinst, struct globa
static void QCBUILTIN PF_cs_particleeffectnum (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int i;
char *effectname = PR_GetStringOfs(prinst, OFS_PARM0);
const char *effectname = PR_GetStringOfs(prinst, OFS_PARM0);
G_FLOAT(OFS_RETURN) = 0; //default to failure.
//use the server's index first.
for (i = 1; i < MAX_SSPARTICLESPRE && cl.particle_ssname[i]; i++)
@ -2236,7 +2257,10 @@ static void QCBUILTIN PF_cs_particleeffectnum (pubprogfuncs_t *prinst, struct gl
{
if (!strcmp(cl.particle_csname[i], effectname))
{
G_FLOAT(OFS_RETURN) = -i;
//effects can be in the list despite now being stale. they still take up a slot to avoid reuse as the qc can potentially still potentially reference it.
//csqc needs to be able to detect a now-stale effect
if (cl.particle_csprecache[i] != P_INVALID)
G_FLOAT(OFS_RETURN) = -i;
return;
}
}
@ -2244,12 +2268,14 @@ static void QCBUILTIN PF_cs_particleeffectnum (pubprogfuncs_t *prinst, struct gl
{
free(cl.particle_csname[i]);
cl.particle_csname[i] = NULL;
cl.particle_csprecache[i] = 1+P_FindParticleType(effectname);
if (cl.particle_csprecache[i])
cl.particle_csprecache[i] = P_FindParticleType(effectname);
if (cl.particle_csprecache[i] != P_INVALID)
{
//it exists, allow it.
cl.particle_csname[i] = strdup(effectname);
G_FLOAT(OFS_RETURN) = -i;
G_FLOAT(OFS_RETURN) = -i;
}
}
G_FLOAT(OFS_RETURN) = 0;
//if we're using dp network protocols, we should use the effectinfo.txt file as a lookup table instead.
//G_FLOAT(OFS_RETURN) = COM_Effectinfo_ForName(effectname);
@ -2275,8 +2301,8 @@ static void QCBUILTIN PF_cs_sendevent (pubprogfuncs_t *prinst, struct globalvars
{
csqcedict_t *ent;
int i;
char *eventname = PR_GetStringOfs(prinst, OFS_PARM0);
char *argtypes = PR_GetStringOfs(prinst, OFS_PARM1);
const char *eventname = PR_GetStringOfs(prinst, OFS_PARM0);
const char *argtypes = PR_GetStringOfs(prinst, OFS_PARM1);
if (!cls.state)
return;
@ -2532,7 +2558,7 @@ static void QCBUILTIN PF_cs_getentitytoken (pubprogfuncs_t *prinst, struct globa
{
if (prinst->callargc)
{
char *s = PR_GetStringOfs(prinst, OFS_PARM0);
const char *s = PR_GetStringOfs(prinst, OFS_PARM0);
if (*s == 0)
s = cl.worldmodel?cl.worldmodel->entities:NULL;
csqcmapentitydata = s;
@ -2674,7 +2700,7 @@ static void QCBUILTIN PF_cs_getplayerkey (pubprogfuncs_t *prinst, struct globalv
char buffer[64];
char *ret;
int pnum = G_FLOAT(OFS_PARM0);
char *keyname = PR_GetStringOfs(prinst, OFS_PARM1);
const char *keyname = PR_GetStringOfs(prinst, OFS_PARM1);
if (pnum < 0)
{
if (csqc_resortfrags)
@ -2787,7 +2813,7 @@ static void QCBUILTIN PF_cs_getplayerkey (pubprogfuncs_t *prinst, struct globalv
static void QCBUILTIN PF_checkextension (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *extname = PR_GetStringOfs(prinst, OFS_PARM0);
const char *extname = PR_GetStringOfs(prinst, OFS_PARM0);
int i;
for (i = 0; i < QSG_Extensions_count; i++)
{
@ -2809,7 +2835,7 @@ static void QCBUILTIN PF_checkextension (pubprogfuncs_t *prinst, struct globalva
static void QCBUILTIN PF_cs_sound(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *sample;
const char *sample;
int channel;
csqcedict_t *entity;
float volume;
@ -2835,7 +2861,7 @@ static void QCBUILTIN PF_cs_sound(pubprogfuncs_t *prinst, struct globalvars_s *p
static void QCBUILTIN PF_cs_pointsound(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *sample;
const char *sample;
float *origin;
float volume;
float attenuation;
@ -2920,13 +2946,13 @@ static void QCBUILTIN PF_cs_particle4(pubprogfuncs_t *prinst, struct globalvars_
void QCBUILTIN PF_cl_effect(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
float *org = G_VECTOR(OFS_PARM0);
char *name = PR_GetStringOfs(prinst, OFS_PARM1);
const char *name = PR_GetStringOfs(prinst, OFS_PARM1);
float startframe = G_FLOAT(OFS_PARM2);
float endframe = G_FLOAT(OFS_PARM3);
float framerate = G_FLOAT(OFS_PARM4);
model_t *mdl;
mdl = Mod_ForName(name, false);
mdl = Mod_ForName(name, MLV_WARN);
if (mdl)
CL_SpawnSpriteEffect(org, NULL, mdl, startframe, endframe, framerate, 1, 0, 0);
else
@ -2935,7 +2961,7 @@ void QCBUILTIN PF_cl_effect(pubprogfuncs_t *prinst, struct globalvars_s *pr_glob
void QCBUILTIN PF_cl_ambientsound(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *samp;
const char *samp;
float *pos;
float vol, attenuation;
@ -2957,7 +2983,7 @@ static void QCBUILTIN PF_cs_vectorvectors (pubprogfuncs_t *prinst, struct global
static void QCBUILTIN PF_cs_lightstyle (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int stnum = G_FLOAT(OFS_PARM0);
char *str = PR_GetStringOfs(prinst, OFS_PARM1);
const char *str = PR_GetStringOfs(prinst, OFS_PARM1);
int colourflags = 7;
if ((unsigned)stnum >= MAX_LIGHTSTYLES)
@ -2970,38 +2996,6 @@ static void QCBUILTIN PF_cs_lightstyle (pubprogfuncs_t *prinst, struct globalvar
cl_lightstyle[stnum].length = Q_strlen(cl_lightstyle[stnum].map);
}
static void QCBUILTIN PF_cs_findradius (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
csqcedict_t *ent, *chain;
float rad;
float *org;
vec3_t eorg;
int i, j;
chain = (csqcedict_t *)*prinst->parms->sv_edicts;
org = G_VECTOR(OFS_PARM0);
rad = G_FLOAT(OFS_PARM1);
for (i=1 ; i<*prinst->parms->sv_num_edicts ; i++)
{
ent = (void*)EDICT_NUM(prinst, i);
if (ent->isfree)
continue;
// if (ent->v->solid == SOLID_NOT && !sv_gameplayfix_blowupfallenzombies.value)
// continue;
for (j=0 ; j<3 ; j++)
eorg[j] = org[j] - (ent->v->origin[j] + (ent->v->mins[j] + ent->v->maxs[j])*0.5);
if (Length(eorg) > rad)
continue;
ent->v->chain = EDICT_TO_PROG(prinst, (void*)chain);
chain = ent;
}
RETURN_EDICT(prinst, (void*)chain);
}
//entity(string field, float match) findchainflags = #450
//chained search for float, int, and entity reference fields
static void QCBUILTIN PF_cs_findchainflags (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
@ -3063,7 +3057,7 @@ static void QCBUILTIN PF_cs_findchainfloat (pubprogfuncs_t *prinst, struct globa
static void QCBUILTIN PF_cs_findchain (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int i, f;
char *s;
const char *s;
string_t t;
csqcedict_t *ent, *chain;
@ -3418,7 +3412,7 @@ void CSQC_RunThreads(void)
static void QCBUILTIN PF_cs_addprogs (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *s = PR_GetStringOfs(prinst, OFS_PARM0);
const char *s = PR_GetStringOfs(prinst, OFS_PARM0);
int newp;
if (!s || !*s)
newp = -1;
@ -3975,7 +3969,7 @@ void CSQC_DeltaEnd(void)
static void QCBUILTIN PF_DeltaListen(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int i;
char *mname = PR_GetStringOfs(prinst, OFS_PARM0);
const char *mname = PR_GetStringOfs(prinst, OFS_PARM0);
func_t func = G_INT(OFS_PARM1);
unsigned int flags = G_FLOAT(OFS_PARM2);
@ -4324,7 +4318,7 @@ static struct {
//20
{"precache_model", PF_cs_PrecacheModel, 20}, // #20 void(string str) precache_model (QUAKE)
{"stuffcmd", PF_NoCSQC, 21}, // #21 void(entity client, string s) stuffcmd (QUAKE) (don't support)
{"findradius", PF_cs_findradius, 22}, // #22 entity(vector org, float rad) findradius (QUAKE)
{"findradius", PF_findradius, 22}, // #22 entity(vector org, float rad) findradius (QUAKE)
{"bprint", PF_NoCSQC, 23}, // #23 void(string s, ...) bprint (QUAKE) (don't support)
{"sprint", PF_NoCSQC, 24}, // #24 void(entity e, string s, ...) sprint (QUAKE) (don't support)
{"dprint", PF_dprint, 25}, // #25 void(string s, ...) dprint (QUAKE)
@ -4376,8 +4370,8 @@ static struct {
{"etos", PF_etos, 65}, // #65 string(entity ent) etos (DP_QC_ETOS)
{"?", PF_Fixme, 66}, // #66
{"movetogoal", PF_cs_movetogoal, 67}, // #67 void(float step) movetogoal (QUAKE)
{"precache_file", PF_NoCSQC, 68}, // #68 void(string s) precache_file (QUAKE) (don't support)
{"movetogoal", PF_cs_movetogoal, 67}, // #67 void(float step) movetogoal (QUAKE)
{"precache_file", PF_cs_precachefile, 68}, // #68 void(string s) precache_file (QUAKE) (don't support)
{"makestatic", PF_cs_makestatic, 69}, // #69 void(entity e) makestatic (QUAKE)
//70
{"changelevel", PF_NoCSQC, 70}, // #70 void(string mapname) changelevel (QUAKE) (don't support)
@ -4388,7 +4382,7 @@ static struct {
{"precache_model2", PF_cs_PrecacheModel, 75}, // #75 void(string str) precache_model2 (QUAKE)
{"precache_sound2", PF_cs_PrecacheSound, 76}, // #76 void(string str) precache_sound2 (QUAKE)
{"precache_file2", PF_NoCSQC, 77}, // #77 void(string str) precache_file2 (QUAKE)
{"precache_file2", PF_cs_precachefile, 77}, // #77 void(string str) precache_file2 (QUAKE)
{"setspawnparms", PF_NoCSQC, 78}, // #78 void() setspawnparms (QUAKE) (don't support)
{"logfrag", PF_NoCSQC, 79}, // #79 void(entity killer, entity killee) logfrag (QW_ENGINE) (don't support)
@ -4602,7 +4596,7 @@ static struct {
{"getmousepos", PF_cl_getmousepos, 344}, // #344 This is a DP extension
{"getinputstate", PF_cs_getinputstate, 345}, // #345 float(float framenum) getinputstate (EXT_CSQC)
{"setsensitivityscaler", PF_cs_setsensativityscaler, 346}, // #346 void(float sens) setsensitivityscaler (EXT_CSQC)
{"setsensitivityscaler", PF_cs_setsensitivityscaler, 346}, // #346 void(float sens) setsensitivityscaler (EXT_CSQC)
{"runstandardplayerphysics",PF_cs_runplayerphysics, 347}, // #347 void() runstandardplayerphysics (EXT_CSQC)
@ -4644,6 +4638,7 @@ static struct {
{"dynamiclight_set", PF_R_DynamicLight_Set, 373},
{"particleeffectquery", PF_cs_particleeffectquery, 374},
{"adddecal", PF_R_AddDecal, 375},
{"setcustomskin", PF_cs_setcustomskin, 376},
{"memalloc", PF_memalloc, 384},
{"memfree", PF_memfree, 385},
@ -4997,6 +4992,10 @@ pbool QDECL CSQC_EntFree (struct edict_s *e)
ent->xv->drawmask = 0;
ent->xv->renderflags = 0;
if (ent->skinobject>0)
Mod_WipeSkin(ent->skinobject);
ent->skinobject = 0;
#ifdef USEODE
World_ODE_RemoveFromEntity(&csqc_world, (wedict_t*)ent);
World_ODE_RemoveJointFromEntity(&csqc_world, (wedict_t*)ent);
@ -5228,9 +5227,6 @@ qboolean CSQC_Inited(void)
qboolean CSQC_UnconnectedOkay(qboolean inprinciple)
{
#ifndef _DEBUG
return false;
#endif
if (!pr_csqc_formenus.ival)
return false;
@ -5377,6 +5373,8 @@ qboolean CSQC_Init (qboolean anycsqc, qboolean csdatenabled, unsigned int checks
if (csprogsnum != -1)
Con_Printf(CON_WARNING "Running outdated or unknown csprogs.dat version\n");
}
if (csprogsnum == -1)
Con_DPrintf("Loaded csprogs.dat\n");
}
if (csqc_singlecheats || anycsqc)
@ -5403,7 +5401,6 @@ qboolean CSQC_Init (qboolean anycsqc, qboolean csdatenabled, unsigned int checks
csqc_world.physicstime = 0;
csqc_fakereadbyte = -1;
memset(csqcent, 0, sizeof(*csqcent)*maxcsqcentities); //clear the server->csqc entity translations.
for (i = 0; i < csqcprogs->numprogs; i++)
@ -5477,7 +5474,7 @@ void CSQC_WorldLoaded(void)
{
char *map;
csqcedict_t *worldent;
char *entfile;
const char *entfile;
if (!csqcprogs)
return;
@ -5503,7 +5500,7 @@ void CSQC_WorldLoaded(void)
if (csqcg.worldloaded)
PR_ExecuteProgram(csqcprogs, csqcg.worldloaded);
csqcmapentitydata = NULL;
BZ_Free(entfile);
BZ_Free((char*)entfile);
worldent->readonly = true;
}
@ -5842,6 +5839,8 @@ qboolean CSQC_DrawView(void)
if (csqcg.intermission)
*csqcg.intermission = cl.intermission;
//work out which packet entities are solid
CL_SetSolidEntities ();
CL_TransitionEntities();
if (cl.worldmodel)
CL_PredictMove ();
@ -5998,22 +5997,24 @@ static void CSQC_GameCommand_f(void)
PR_ExecuteProgram (csqcprogs, csqcg.gamecommand);
}
#ifdef warningmsg
#pragma warningmsg("do we really need the firstbyte parameter here?")
#endif
qboolean CSQC_ParseTempEntity(unsigned char firstbyte)
qboolean CSQC_ParseTempEntity(void)
{
int orc;
void *pr_globals;
if (!csqcprogs || !csqcg.parse_tempentity)
return false;
csqc_fakereadbyte = firstbyte;
pr_globals = PR_globals(csqcprogs, PR_CURRENT);
csqc_mayread = true;
orc = msg_readcount;
PR_ExecuteProgram (csqcprogs, csqcg.parse_tempentity);
csqc_mayread = false;
csqc_fakereadbyte = -1;
return !!G_FLOAT(OFS_RETURN);
if (G_FLOAT(OFS_RETURN))
return true;
//failed. reset the read position.
msg_readcount = orc;
msg_badread = false;
return false;
}
qboolean CSQC_ParseGamePacket(void)

View File

@ -115,7 +115,7 @@ void PR_CL_BeginString(pubprogfuncs_t *prinst, float vx, float vy, float szx, fl
}
Font_BeginScaledString(font, vx, vy, szx, szy, px, py);
}
int PR_findnamedfont(char *name, qboolean isslotname)
int PR_findnamedfont(const char *name, qboolean isslotname)
{
int i;
if (isslotname)
@ -176,14 +176,14 @@ void PR_ResetFonts(unsigned int purgeowner)
}
void QCBUILTIN PF_CL_findfont (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *slotname = PR_GetStringOfs(prinst, OFS_PARM0);
const char *slotname = PR_GetStringOfs(prinst, OFS_PARM0);
G_FLOAT(OFS_RETURN) = PR_findnamedfont(slotname, true) + 1; //return default on failure.
}
void QCBUILTIN PF_CL_loadfont (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *slotname = PR_GetStringOfs(prinst, OFS_PARM0);
char *facename = PR_GetStringOfs(prinst, OFS_PARM1);
char *sizestr = PR_GetStringOfs(prinst, OFS_PARM2);
const char *slotname = PR_GetStringOfs(prinst, OFS_PARM0);
const char *facename = PR_GetStringOfs(prinst, OFS_PARM1);
const char *sizestr = PR_GetStringOfs(prinst, OFS_PARM2);
int slotnum = G_FLOAT(OFS_PARM3);
//float fix_scale = G_FLOAT(OFS_PARM4);
//float fix_voffset = G_FLOAT(OFS_PARM5);
@ -345,7 +345,7 @@ void QCBUILTIN PF_CL_DrawTextField (pubprogfuncs_t *prinst, struct globalvars_s
float *pos = G_VECTOR(OFS_PARM0);
float *size = G_VECTOR(OFS_PARM1);
unsigned int flags = G_FLOAT(OFS_PARM2);
char *text = PR_GetStringOfs(prinst, OFS_PARM3);
const char *text = PR_GetStringOfs(prinst, OFS_PARM3);
R_DrawTextField(pos[0], pos[1], size[0], size[1], text, CON_WHITEMASK, flags);
}
@ -353,7 +353,7 @@ void QCBUILTIN PF_CL_DrawTextField (pubprogfuncs_t *prinst, struct globalvars_s
void QCBUILTIN PF_CL_drawcolouredstring (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
float *pos = G_VECTOR(OFS_PARM0);
char *text = PR_GetStringOfs(prinst, OFS_PARM1);
const char *text = PR_GetStringOfs(prinst, OFS_PARM1);
float *size = G_VECTOR(OFS_PARM2);
float alpha = 0;
float flag = 0;
@ -411,7 +411,7 @@ void QCBUILTIN PF_CL_stringwidth(pubprogfuncs_t *prinst, struct globalvars_s *pr
{
conchar_t buffer[2048], *end;
float px, py;
char *text = PR_GetStringOfs(prinst, OFS_PARM0);
const char *text = PR_GetStringOfs(prinst, OFS_PARM0);
int usecolours = G_FLOAT(OFS_PARM1);
float *size = (prinst->callargc > 2)?G_VECTOR(OFS_PARM2):NULL;
@ -428,7 +428,7 @@ void QCBUILTIN PF_CL_stringwidth(pubprogfuncs_t *prinst, struct globalvars_s *pr
void QCBUILTIN PF_CL_drawpic (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
float *pos = G_VECTOR(OFS_PARM0);
char *picname = PR_GetStringOfs(prinst, OFS_PARM1);
const char *picname = PR_GetStringOfs(prinst, OFS_PARM1);
float *size = G_VECTOR(OFS_PARM2);
float *rgb = G_VECTOR(OFS_PARM3);
float alpha = G_FLOAT(OFS_PARM4);
@ -458,7 +458,7 @@ void QCBUILTIN PF_CL_drawsubpic (pubprogfuncs_t *prinst, struct globalvars_s *pr
{
float *pos = G_VECTOR(OFS_PARM0);
float *size = G_VECTOR(OFS_PARM1);
char *picname = PR_GetStringOfs(prinst, OFS_PARM2);
const char *picname = PR_GetStringOfs(prinst, OFS_PARM2);
float *srcPos = G_VECTOR(OFS_PARM3);
float *srcSize = G_VECTOR(OFS_PARM4);
float *rgb = G_VECTOR(OFS_PARM5);
@ -488,14 +488,14 @@ void QCBUILTIN PF_CL_drawsubpic (pubprogfuncs_t *prinst, struct globalvars_s *pr
void QCBUILTIN PF_CL_is_cached_pic (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *str;
const char *str;
str = PR_GetStringOfs(prinst, OFS_PARM0);
G_FLOAT(OFS_RETURN) = !!R_RegisterCustom(str, SUF_2D, NULL, NULL);
}
void QCBUILTIN PF_CL_precache_pic (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *str;
const char *str;
mpic_t *pic;
float fromwad;
@ -573,7 +573,7 @@ void QCBUILTIN PF_CL_drawcharacter (pubprogfuncs_t *prinst, struct globalvars_s
void QCBUILTIN PF_CL_drawrawstring (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
float *pos = G_VECTOR(OFS_PARM0);
char *text = PR_GetStringOfs(prinst, OFS_PARM1);
const char *text = PR_GetStringOfs(prinst, OFS_PARM1);
float *size = G_VECTOR(OFS_PARM2);
float *rgb = G_VECTOR(OFS_PARM3);
float alpha = G_FLOAT(OFS_PARM4);
@ -595,7 +595,7 @@ void QCBUILTIN PF_CL_drawrawstring (pubprogfuncs_t *prinst, struct globalvars_s
while(*text)
{
if (1)//VMUTF8)
c = unicode_decode(&error, text, &text, false);
c = unicode_decode(&error, text, (char**)&text, false);
else
{
//FIXME: which charset is this meant to be using?
@ -666,7 +666,7 @@ void QCBUILTIN PF_CL_drawline (pubprogfuncs_t *prinst, struct globalvars_s *pr_g
//vector drawgetimagesize(string pic) = #460;
void QCBUILTIN PF_CL_drawgetimagesize (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *picname = PR_GetStringOfs(prinst, OFS_PARM0);
const char *picname = PR_GetStringOfs(prinst, OFS_PARM0);
mpic_t *p = R2D_SafeCachePic(picname);
float *ret = G_VECTOR(OFS_RETURN);
@ -715,9 +715,9 @@ void QCBUILTIN PF_cl_getmousepos (pubprogfuncs_t *prinst, struct globalvars_s *p
void QCBUILTIN PF_SubConGetSet (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *conname = PR_GetStringOfs(prinst, OFS_PARM0);
char *field = PR_GetStringOfs(prinst, OFS_PARM1);
char *value = (prinst->callargc>2)?PR_GetStringOfs(prinst, OFS_PARM2):NULL;
const char *conname = PR_GetStringOfs(prinst, OFS_PARM0);
const char *field = PR_GetStringOfs(prinst, OFS_PARM1);
const char *value = (prinst->callargc>2)?PR_GetStringOfs(prinst, OFS_PARM2):NULL;
console_t *con = Con_FindConsole(conname);
G_INT(OFS_RETURN) = 0;
if (!con)
@ -795,8 +795,8 @@ void QCBUILTIN PF_SubConGetSet (pubprogfuncs_t *prinst, struct globalvars_s *pr_
void QCBUILTIN PF_SubConPrintf (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char outbuf[4096];
char *conname = PR_GetStringOfs(prinst, OFS_PARM0);
char *fmt = PR_GetStringOfs(prinst, OFS_PARM1);
const char *conname = PR_GetStringOfs(prinst, OFS_PARM0);
const char *fmt = PR_GetStringOfs(prinst, OFS_PARM1);
console_t *con = Con_FindConsole(conname);
if (!con)
return;
@ -805,7 +805,7 @@ void QCBUILTIN PF_SubConPrintf (pubprogfuncs_t *prinst, struct globalvars_s *pr_
}
void QCBUILTIN PF_SubConDraw (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *conname = PR_GetStringOfs(prinst, OFS_PARM0);
const char *conname = PR_GetStringOfs(prinst, OFS_PARM0);
float *pos = G_VECTOR(OFS_PARM1);
float *size = G_VECTOR(OFS_PARM2);
float fontsize = G_FLOAT(OFS_PARM3);
@ -826,7 +826,7 @@ qboolean Key_Console (console_t *con, unsigned int unicode, int key);
void Key_ConsoleRelease (console_t *con, unsigned int unicode, int key);
void QCBUILTIN PF_SubConInput (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *conname = PR_GetStringOfs(prinst, OFS_PARM0);
const char *conname = PR_GetStringOfs(prinst, OFS_PARM0);
int ie = G_FLOAT(OFS_PARM1);
float pa = G_FLOAT(OFS_PARM2);
float pb = G_FLOAT(OFS_PARM3);
@ -914,7 +914,7 @@ void QCBUILTIN PF_mod (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
G_FLOAT(OFS_RETURN) = a % b;
}
char *RemapCvarNameFromDPToFTE(char *name)
const char *RemapCvarNameFromDPToFTE(const char *name)
{
if (!stricmp(name, "vid_bitsperpixel"))
return "vid_bpp";
@ -942,7 +942,7 @@ char *RemapCvarNameFromDPToFTE(char *name)
static void QCBUILTIN PF_menu_cvar (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
cvar_t *var;
char *str;
const char *str;
str = PR_GetStringOfs(prinst, OFS_PARM0);
@ -971,7 +971,7 @@ static void QCBUILTIN PF_menu_cvar (pubprogfuncs_t *prinst, struct globalvars_s
}
static void QCBUILTIN PF_menu_cvar_set (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *var_name, *val;
const char *var_name, *val;
cvar_t *var;
var_name = PR_GetStringOfs(prinst, OFS_PARM0);
@ -983,7 +983,7 @@ static void QCBUILTIN PF_menu_cvar_set (pubprogfuncs_t *prinst, struct globalvar
}
static void QCBUILTIN PF_menu_cvar_string (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *str = PR_GetStringOfs(prinst, OFS_PARM0);
const char *str = PR_GetStringOfs(prinst, OFS_PARM0);
cvar_t *cv = Cvar_Get(RemapCvarNameFromDPToFTE(str), "", 0, "QC variables");
G_INT( OFS_RETURN ) = (int)PR_SetString( prinst, cv->string );
}
@ -1076,7 +1076,7 @@ static void QCBUILTIN PF_Fixme (pubprogfuncs_t *prinst, struct globalvars_s *pr_
void QCBUILTIN PF_CL_precache_sound (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *str;
const char *str;
str = PR_GetStringOfs(prinst, OFS_PARM0);
@ -1185,13 +1185,13 @@ static void QCBUILTIN PF_CopyEntity (pubprogfuncs_t *prinst, struct globalvars_s
void QCBUILTIN PF_localsound (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *soundname = PR_GetStringOfs(prinst, OFS_PARM0);
const char *soundname = PR_GetStringOfs(prinst, OFS_PARM0);
S_LocalSound (soundname);
}
void QCBUILTIN PF_menu_checkextension (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *extname = PR_GetStringOfs(prinst, OFS_PARM0);
const char *extname = PR_GetStringOfs(prinst, OFS_PARM0);
int i;
G_FLOAT(OFS_RETURN) = 0;
@ -1221,7 +1221,7 @@ void QCBUILTIN PF_CL_precache_file (pubprogfuncs_t *prinst, struct globalvars_s
void QCBUILTIN PF_menu_findchain (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int i, f;
char *s;
const char *s;
string_t t;
menuedict_t *ent, *chain; //note, all edicts share the common header, but don't use it's fields!
eval_t *val;
@ -1330,7 +1330,7 @@ void QCBUILTIN PF_IsNotNull(pubprogfuncs_t *prinst, struct globalvars_s *pr_glob
//returns number of single quoted strings in the string.
void QCBUILTIN PF_altstr_count(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *s;
const char *s;
int count = 0;
s = PR_GetStringOfs(prinst, OFS_PARM0);
for (;*s;s++)
@ -1349,7 +1349,7 @@ void QCBUILTIN PF_altstr_count(pubprogfuncs_t *prinst, struct globalvars_s *pr_g
void QCBUILTIN PF_altstr_prepare(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char outstr[8192], *out;
char *instr, *in;
const char *instr, *in;
int size;
// VM_SAFEPARMCOUNT( 1, VM_altstr_prepare );
@ -1375,7 +1375,8 @@ void QCBUILTIN PF_altstr_prepare(pubprogfuncs_t *prinst, struct globalvars_s *pr
//string altstr_get(string str, float num) = #84;
void QCBUILTIN PF_altstr_get(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *altstr, *pos, outstr[8192], *out;
const char *altstr, *pos;
char outstr[8192], *out;
int count, size;
// VM_SAFEPARMCOUNT( 2, VM_altstr_get );
@ -1422,8 +1423,8 @@ void QCBUILTIN PF_altstr_get(pubprogfuncs_t *prinst, struct globalvars_s *pr_glo
void QCBUILTIN PF_altstr_set(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int num;
char *altstr, *str;
char *in;
const char *altstr, *str;
const char *in;
char outstr[8192], *out;
// VM_SAFEPARMCOUNT( 3, VM_altstr_set );
@ -1845,8 +1846,11 @@ void MP_Shutdown (void)
Master_ClearMasks();
#endif
Key_Dest_Remove(kdm_menu);
m_state = 0;
if (m_state == m_menu_dat)
{
Key_Dest_Remove(kdm_menu);
m_state = 0;
}
key_dest_absolutemouse &= ~kdm_menu;
}
@ -1905,8 +1909,6 @@ qboolean MP_Init (void)
if (forceqmenu.value)
return false;
M_DeInit_Internal();
MP_SetupBuiltins();
memset(&menuc_eval_chain, 0, sizeof(menuc_eval_chain));
@ -1974,6 +1976,8 @@ qboolean MP_Init (void)
}
inmenuprogs++;
M_DeInit_Internal();
PF_InitTempStrings(menu_world.progs);
mp_time = (float*)PR_FindGlobal(menu_world.progs, "time", 0, NULL);
@ -2049,7 +2053,7 @@ void MP_CoreDump_f(void)
void MP_Reload_f(void)
{
M_Shutdown();
M_Shutdown(true);
M_Reinit();
}

View File

@ -89,11 +89,7 @@ typedef struct skelobject_s
model_t *model;
world_t *world; /*be it ssqc or csqc*/
enum
{
SKOT_RELATIVE, //relative to parent
SKOT_ABSOLUTE //relative to model
} type;
skeltype_t type;
unsigned int numbones;
float *bonematrix;
@ -124,7 +120,7 @@ void skel_copy_toabs(skelobject_t *skelobjdst, skelobject_t *skelobjsrc, int sta
if (!boneinfo)
return;
endbone = min(endbone, maxbones-1);
if (skelobjsrc->type == SKOT_ABSOLUTE)
if (skelobjsrc->type == SKEL_ABSOLUTE)
{
if (skelobjsrc != skelobjdst)
{
@ -171,7 +167,7 @@ void skel_copy_toabs(skelobject_t *skelobjdst, skelobject_t *skelobjsrc, int sta
}
}
skelobjdst->type = SKOT_ABSOLUTE;
skelobjdst->type = SKEL_ABSOLUTE;
}
static void bonemat_fromidentity(float *out)
{
@ -303,7 +299,7 @@ typedef struct {
odebodyinfo_t defbody;
odejointinfo_t defjoint;
} dollcreatectx_t;
static dollcreatectx_t *rag_createdoll(model_t *mod, char *fname, int numbones)
static dollcreatectx_t *rag_createdoll(model_t *mod, const char *fname, int numbones)
{
int i;
dollcreatectx_t *ctx;
@ -603,7 +599,7 @@ static doll_t *rag_finishdoll(dollcreatectx_t *ctx)
return d;
};
doll_t *rag_createdollfromstring(model_t *mod, char *fname, int numbones, char *file)
doll_t *rag_createdollfromstring(model_t *mod, const char *fname, int numbones, const char *file)
{
int linenum = 0;
dollcreatectx_t *ctx;
@ -949,7 +945,7 @@ void skel_info_f(void)
if (skelobjects[i].world == &csqc_world)
Con_Printf(" CSQC\n");
#endif
Con_Printf(" type: %s\n", (skelobjects[i].type == SKOT_RELATIVE)?"parentspace":"modelspace");
Con_Printf(" type: %s\n", (skelobjects[i].type == SKEL_RELATIVE)?"parentspace":"modelspace");
Con_Printf(" model: %s\n", skelobjects[i].model->name);
Con_Printf(" bone count: %i\n", skelobjects[i].numbones);
#ifdef RAGDOLL
@ -1066,7 +1062,7 @@ void skel_lookup(pubprogfuncs_t *prinst, int skelidx, framestate_t *out)
skelobject_t *sko = skel_get(prinst, skelidx);
if (sko && sko->inuse)
{
out->boneabs = sko->type;
out->skeltype = sko->type;
out->bonecount = sko->numbones;
out->bonestate = sko->bonematrix;
}
@ -1354,7 +1350,7 @@ void rag_derive(skelobject_t *sko, skelobject_t *asko, float *emat)
}
//if it wasn't before, it definitely is now.
sko->type = SKOT_ABSOLUTE;
sko->type = SKEL_ABSOLUTE;
}
//called each physics frame to update the body velocities for animation
@ -1411,7 +1407,7 @@ void rag_updatedeltaent(entity_t *ent, lerpents_t *le)
skelobject_t skorel = {0};
float relmat[MAX_BONES*12];
skorel.bonematrix = relmat;
skorel.type = SKOT_RELATIVE;
skorel.type = SKEL_RELATIVE;
if (mod->dollinfo)
{
@ -1425,7 +1421,7 @@ void rag_updatedeltaent(entity_t *ent, lerpents_t *le)
if (!sko)
return; //couldn't get one, ran out of memory or something?
sko->model = mod;
sko->type = SKOT_RELATIVE;
sko->type = SKEL_RELATIVE;
le->skeletalobject = (sko - skelobjects) + 1;
}
else
@ -1466,7 +1462,7 @@ void rag_updatedeltaent(entity_t *ent, lerpents_t *le)
ent->framestate.bonestate = sko->bonematrix;
ent->framestate.bonecount = sko->numbones;
ent->framestate.boneabs = sko->type == SKOT_ABSOLUTE;
ent->framestate.skeltype = sko->type;
}
}
#endif
@ -1480,7 +1476,7 @@ void QCBUILTIN PF_skel_ragedit(pubprogfuncs_t *prinst, struct globalvars_s *pr_g
//do we want to be able to generate a ragdoll object with this function too?
#ifdef RAGDOLL
wedict_t *wed = (wedict_t*)G_EDICT(prinst, OFS_PARM0);
char *ragname = PR_GetStringOfs(prinst, OFS_PARM1);
const char *ragname = PR_GetStringOfs(prinst, OFS_PARM1);
int parentskel = G_FLOAT(OFS_PARM2);
int skelidx;
skelobject_t *sko, *psko;
@ -1500,7 +1496,7 @@ void QCBUILTIN PF_skel_ragedit(pubprogfuncs_t *prinst, struct globalvars_s *pr_g
//the parent skeletal object must be relative, if specified.
psko = skel_get(prinst, parentskel);
if (psko && psko->type != SKOT_RELATIVE)
if (psko && psko->type != SKEL_RELATIVE)
return;
sko = skel_get(prinst, skelidx);
@ -1634,7 +1630,7 @@ void QCBUILTIN PF_skel_create (pubprogfuncs_t *prinst, struct globalvars_s *pr_g
int type;
midx = G_FLOAT(OFS_PARM0);
type = (prinst->callargc > 1)?G_FLOAT(OFS_PARM1):SKOT_RELATIVE;
type = (prinst->callargc > 1)?G_FLOAT(OFS_PARM1):SKEL_RELATIVE;
//default to failure
G_FLOAT(OFS_RETURN) = 0;
@ -1643,7 +1639,7 @@ void QCBUILTIN PF_skel_create (pubprogfuncs_t *prinst, struct globalvars_s *pr_g
if (!model)
return; //no model set, can't get a skeleton
numbones = Mod_GetNumBones(model, type != SKOT_RELATIVE);
numbones = Mod_GetNumBones(model, type != SKEL_RELATIVE);
if (!numbones)
{
// isabs = true;
@ -1724,14 +1720,14 @@ void QCBUILTIN PF_skel_build(pubprogfuncs_t *prinst, struct globalvars_s *pr_glo
if (lastbone < firstbone)
lastbone = firstbone;
if (skelobj->type != SKOT_RELATIVE)
if (skelobj->type != SKEL_RELATIVE)
{
if (firstbone > 0 || lastbone < skelobj->numbones || retainfrac)
{
Con_Printf("skel_build on non-relative skeleton\n");
return;
}
skelobj->type = SKOT_RELATIVE; //entire model will get replaced, convert it.
skelobj->type = SKEL_RELATIVE; //entire model will get replaced, convert it.
}
if (retainfrac == 0)
@ -1840,7 +1836,7 @@ void QCBUILTIN PF_skel_get_boneparent (pubprogfuncs_t *prinst, struct globalvars
void QCBUILTIN PF_skel_find_bone (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int skelidx = G_FLOAT(OFS_PARM0);
char *bname = PR_GetStringOfs(prinst, OFS_PARM1);
const char *bname = PR_GetStringOfs(prinst, OFS_PARM1);
skelobject_t *skelobj;
skelobj = skel_get(prinst, skelidx);
@ -1859,7 +1855,7 @@ void QCBUILTIN PF_skel_get_bonerel (pubprogfuncs_t *prinst, struct globalvars_s
skelobject_t *skelobj = skel_get(prinst, skelidx);
if (!skelobj || (unsigned int)boneidx >= skelobj->numbones)
bonematident_toqcvectors(w->g.v_forward, w->g.v_right, w->g.v_up, G_VECTOR(OFS_RETURN));
else if (skelobj->type!=SKOT_RELATIVE)
else if (skelobj->type!=SKEL_RELATIVE)
{
float tmp[12];
float invparent[12];
@ -1886,7 +1882,7 @@ void QCBUILTIN PF_skel_get_boneabs (pubprogfuncs_t *prinst, struct globalvars_s
if (!skelobj || (unsigned int)boneidx >= skelobj->numbones)
bonematident_toqcvectors(w->g.v_forward, w->g.v_right, w->g.v_up, G_VECTOR(OFS_RETURN));
else if (skelobj->type != SKOT_RELATIVE)
else if (skelobj->type != SKEL_RELATIVE)
{
//can just copy it out
bonemat_toqcvectors(skelobj->bonematrix + boneidx*12, w->g.v_forward, w->g.v_right, w->g.v_up, G_VECTOR(OFS_RETURN));
@ -1966,7 +1962,7 @@ void QCBUILTIN PF_skel_set_bone_world (pubprogfuncs_t *prinst, struct globalvars
float parentent[12];
framestate_t fstate;
w->Get_FrameState(w, ent, &fstate);
if (skelobj->type == SKOT_ABSOLUTE || !Mod_GetTag(skelobj->model, Mod_GetBoneParent(skelobj->model, boneidx+1), &fstate, parentabs))
if (skelobj->type == SKEL_ABSOLUTE || !Mod_GetTag(skelobj->model, Mod_GetBoneParent(skelobj->model, boneidx+1), &fstate, parentabs))
{
bonemat_fromentity(w, ent, parentw);
}
@ -2110,7 +2106,7 @@ void QCBUILTIN PF_skel_copybones (pubprogfuncs_t *prinst, struct globalvars_s *p
startbone++;
}
}
else if (skelobjsrc->type == SKOT_RELATIVE && skelobjdst->type == SKOT_ABSOLUTE)
else if (skelobjsrc->type == SKEL_RELATIVE && skelobjdst->type == SKEL_ABSOLUTE)
{
/*copy from relative to absolute*/
skel_copy_toabs(skelobjdst, skelobjsrc, startbone, endbone);
@ -2180,7 +2176,7 @@ void QCBUILTIN PF_gettagindex (pubprogfuncs_t *prinst, struct globalvars_s *pr_g
{
world_t *w = prinst->parms->user;
wedict_t *ent = G_WEDICT(prinst, OFS_PARM0);
char *tagname = PR_GetStringOfs(prinst, OFS_PARM1);
const char *tagname = PR_GetStringOfs(prinst, OFS_PARM1);
model_t *mod = *tagname?w->Get_CModel(w, ent->v->modelindex):NULL;
if (mod)
G_FLOAT(OFS_RETURN) = Mod_TagNumForName(mod, tagname);
@ -2206,21 +2202,6 @@ void QCBUILTIN PF_frametoname (pubprogfuncs_t *prinst, struct globalvars_s *pr_g
G_INT(OFS_RETURN) = 0; //null string (which is also empty in qc)
}
//string(float modidx, float skinnum) skintoname
void QCBUILTIN PF_skintoname (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
world_t *w = prinst->parms->user;
unsigned int modelindex = G_FLOAT(OFS_PARM0);
unsigned int skinnum = G_FLOAT(OFS_PARM1);
model_t *mod = w->Get_CModel(w, modelindex);
const char *n = Mod_SkinNameForNum(mod, skinnum);
if (n)
RETURN_TSTRING(n);
else
G_INT(OFS_RETURN) = 0; //null string (which is also empty in qc)
}
void QCBUILTIN PF_frameforname (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
world_t *w = prinst->parms->user;
@ -2245,6 +2226,21 @@ void QCBUILTIN PF_frameduration (pubprogfuncs_t *prinst, struct globalvars_s *pr
else
G_FLOAT(OFS_RETURN) = 0;
}
//string(float modidx, float skinnum) skintoname
void QCBUILTIN PF_skintoname (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
world_t *w = prinst->parms->user;
unsigned int modelindex = G_FLOAT(OFS_PARM0);
unsigned int skinnum = G_FLOAT(OFS_PARM1);
model_t *mod = w->Get_CModel(w, modelindex);
const char *n = Mod_SkinNameForNum(mod, skinnum);
if (n)
RETURN_TSTRING(n);
else
G_INT(OFS_RETURN) = 0; //null string (which is also empty in qc)
}
void QCBUILTIN PF_skinforname (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
#ifndef SERVERONLY

View File

@ -184,7 +184,9 @@ extern "C" {
#include "world.h"
#include "q2game.h"
#include "../http/iweb.h"
#ifndef CLIENTONLY
#ifdef CLIENTONLY
#define SSV_IsSubServer() false
#else
#include "server.h"
#endif

View File

@ -200,6 +200,7 @@ void R2D_Init(void)
"if $nofixed\n"
"program default2d\n"
"endif\n"
"affine\n"
"nomipmaps\n"
"{\n"
"map $diffuse\n"
@ -268,6 +269,7 @@ void R2D_Init(void)
shader_gammacb = R_RegisterShader("gammacbshader", SUF_NONE,
"{\n"
"program defaultgammacb\n"
"affine\n"
"cull back\n"
"{\n"
"map $currentrender\n"
@ -288,6 +290,7 @@ void R2D_Init(void)
);
shader_menutint = R_RegisterShader("menutint", SUF_NONE,
"{\n"
"affine\n"
"if $glsl && gl_menutint_shader != 0\n"
"program menutint\n"
"{\n"
@ -307,6 +310,7 @@ void R2D_Init(void)
"if $nofixed\n"
"program default2d\n"
"endif\n"
"affine\n"
"nomipmaps\n"
"{\n"
"map $diffuse\n"
@ -342,7 +346,7 @@ void R2D_Init(void)
R2D_Font_Changed();
}
mpic_t *R2D_SafeCachePic (char *path)
mpic_t *R2D_SafeCachePic (const char *path)
{
shader_t *s;
if (!qrenderer)
@ -354,7 +358,7 @@ mpic_t *R2D_SafeCachePic (char *path)
}
mpic_t *R2D_SafePicFromWad (char *name)
mpic_t *R2D_SafePicFromWad (const char *name)
{
char newnamewad[32];
char newnamegfx[32];
@ -465,25 +469,18 @@ void R2D_SubPic(float x, float y, float width, float height, mpic_t *pic, float
}
/* this is an ugly special case drawing func that's only used for the player color selection menu */
void R2D_TransPicTranslate (float x, float y, int width, int height, qbyte *pic, qbyte *translation)
void R2D_TransPicTranslate (float x, float y, int width, int height, qbyte *pic, unsigned int *palette)
{
int v, u;
unsigned trans[64*64], *dest;
qbyte *src;
int p;
dest = trans;
for (v=0 ; v<64 ; v++, dest += 64)
{
src = &pic[ ((v*height)>>6) *width];
for (u=0 ; u<64 ; u++)
{
p = src[(u*width)>>6];
if (p == 255)
dest[u] = 0x0;
else
dest[u] = d_8to24rgbtable[translation[p]];
}
dest[u] = palette[src[(u*width)>>6]];
}
if (!TEXVALID(translate_texture))
@ -498,6 +495,8 @@ void R2D_TransPicTranslate (float x, float y, int width, int height, qbyte *pic,
"{\n"
"map $diffuse\n"
"blendfunc blend\n"
"rgbgen vertex\n"
"alphagen vertex\n"
"}\n"
"}\n");
translate_shader->defaulttextures.base = translate_texture;
@ -631,7 +630,7 @@ void R2D_Conback_Callback(struct cvar_s *var, char *oldvalue)
}
}
#if defined(_WIN32) && !defined(FTE_SDL)
#if defined(_WIN32) && !defined(FTE_SDL) && !defined(WINRT)
#include <windows.h>
qboolean R2D_Font_WasAdded(char *buffer, char *fontfilename)
{
@ -699,6 +698,10 @@ void R2D_Font_Changed(void)
Font_Free(font_default);
font_default = NULL;
if (font_tiny)
Font_Free(font_tiny);
font_tiny = NULL;
#if defined(MENU_DAT) || defined(CSQC_DAT)
PR_ResetFonts(0);
#endif
@ -706,7 +709,7 @@ void R2D_Font_Changed(void)
if (qrenderer == QR_NONE)
return;
#if defined(_WIN32) && !defined(FTE_SDL)
#if defined(_WIN32) && !defined(FTE_SDL) && !defined(WINRT)
if (!strcmp(gl_font.string, "?"))
{
BOOL (APIENTRY *pChooseFontA)(LPCHOOSEFONTA) = NULL;
@ -1368,5 +1371,20 @@ texid_t R2D_RT_GetTexture(unsigned int id, unsigned int *width, unsigned int *he
return rendertargets[id].id;
}
texid_t R2D_RT_DetachTexture(unsigned int id)
{
texid_t r;
id--;
if (id >= numrendertargets)
return r_nulltex;
r = rendertargets[id].id;
rendertargets[id].id = r_nulltex;
rendertargets[id].fmt = TF_INVALID;
rendertargets[id].width = 0;
rendertargets[id].height = 0;
return r;
}
#endif

View File

@ -20,7 +20,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
// r_surf.c: surface-related refresh code
#include "quakedef.h"
#if defined(GLQUAKE) || defined(D3DQUAKE)
#ifndef SERVERONLY
#include "glquake.h"
#include "shader.h"
#include "renderque.h"
@ -1967,12 +1967,26 @@ void Surf_SetupFrame(void)
R_AnimateLight();
r_framecount++;
if (r_refdef.recurse)
{
VectorCopy(r_refdef.pvsorigin, pvsorg);
}
else
{
VectorCopy(r_refdef.vieworg, pvsorg);
}
r_viewcontents = 0;
if (r_refdef.flags & Q2RDF_NOWORLDMODEL)
{
}
else if (!cl.worldmodel || cl.worldmodel->needload || cl.worldmodel->fromgame == fg_doom3 )
{
r_viewleaf = NULL;
r_viewleaf2 = NULL;
}
#ifdef Q2BSPS
else if (cl.worldmodel && (cl.worldmodel->fromgame == fg_quake2 || cl.worldmodel->fromgame == fg_quake3))
else if (cl.worldmodel->fromgame == fg_quake2 || cl.worldmodel->fromgame == fg_quake3)
{
static mleaf_t fakeleaf;
mleaf_t *leaf;
@ -1984,16 +1998,9 @@ void Surf_SetupFrame(void)
r_oldviewcluster = r_viewcluster;
r_oldviewcluster2 = r_viewcluster2;
if (r_refdef.recurse)
{
leaf = Mod_PointInLeaf (cl.worldmodel, r_refdef.pvsorigin);
r_viewcontents = cl.worldmodel->funcs.PointContents(cl.worldmodel, NULL, r_refdef.pvsorigin);
}
else
{
leaf = Mod_PointInLeaf (cl.worldmodel, r_origin);
r_viewcontents = cl.worldmodel->funcs.PointContents(cl.worldmodel, NULL, r_origin);
}
leaf = Mod_PointInLeaf (cl.worldmodel, pvsorg);
r_viewcontents = cl.worldmodel->funcs.PointContents(cl.worldmodel, NULL, pvsorg);
r_viewcluster = r_viewcluster2 = leaf->cluster;
// check above and below so crossing solid water doesn't draw wrong
@ -2001,7 +2008,7 @@ void Surf_SetupFrame(void)
{ // look down a bit
vec3_t temp;
VectorCopy (r_origin, temp);
VectorCopy (pvsorg, temp);
temp[2] -= 16;
leaf = Mod_PointInLeaf (cl.worldmodel, temp);
if ( !(leaf->contents & Q2CONTENTS_SOLID) &&
@ -2012,7 +2019,7 @@ void Surf_SetupFrame(void)
{ // look up a bit
vec3_t temp;
VectorCopy (r_origin, temp);
VectorCopy (pvsorg, temp);
temp[2] += 16;
leaf = Mod_PointInLeaf (cl.worldmodel, temp);
if ( !(leaf->contents & Q2CONTENTS_SOLID) &&
@ -2021,22 +2028,8 @@ void Surf_SetupFrame(void)
}
}
#endif
else if (cl.worldmodel && cl.worldmodel->fromgame == fg_doom3)
{
r_viewleaf = NULL;
r_viewleaf2 = NULL;
}
else
{
if (r_refdef.recurse)
{
VectorCopy(r_refdef.pvsorigin, pvsorg);
}
else
{
VectorCopy(r_origin, pvsorg);
}
r_viewleaf = Mod_PointInLeaf (cl.worldmodel, pvsorg);
if (!r_viewleaf)
@ -2095,7 +2088,7 @@ void Surf_SetupFrame(void)
#ifdef TERRAIN
if (!(r_refdef.flags & Q2RDF_NOWORLDMODEL) && cl.worldmodel && cl.worldmodel->terrain)
{
r_viewcontents |= Heightmap_PointContents(cl.worldmodel, NULL, r_origin);
r_viewcontents |= Heightmap_PointContents(cl.worldmodel, NULL, pvsorg);
}
#endif
@ -2106,18 +2099,19 @@ void Surf_SetupFrame(void)
VectorCopy(pmove.player_maxs, t2);
VectorClear(pmove.player_maxs);
VectorClear(pmove.player_mins);
r_viewcontents |= PM_ExtraBoxContents(r_origin);
r_viewcontents |= PM_ExtraBoxContents(pvsorg);
VectorCopy(t1, pmove.player_mins);
VectorCopy(t2, pmove.player_maxs);
}
V_SetContentsColor (r_viewcontents);
if (!r_secondaryview)
V_SetContentsColor (r_viewcontents);
if (r_refdef.audio.defaulted)
{
//first scene is the 'main' scene and audio defaults to that (unless overridden later in the frame)
r_refdef.audio.defaulted = false;
VectorCopy(r_origin, r_refdef.audio.origin);
VectorCopy(r_refdef.vieworg, r_refdef.audio.origin);
VectorCopy(vpn, r_refdef.audio.forward);
VectorCopy(vright, r_refdef.audio.right);
VectorCopy(vup, r_refdef.audio.up);
@ -2283,8 +2277,6 @@ void Surf_DrawWorld (void)
return;
}
Surf_SetupFrame();
currentmodel = cl.worldmodel;
currententity = &r_worldentity;
@ -2460,6 +2452,7 @@ void Surf_LightmapMode(void)
switch(qrenderer)
{
default:
case QR_SOFTWARE:
lightmap_bytes = 4;
lightmap_bgra = true;
@ -2472,8 +2465,8 @@ void Surf_LightmapMode(void)
lightmap_bgra = true;
break;
#endif
case QR_OPENGL:
#ifdef GLQUAKE
case QR_OPENGL:
/*favour bgra if the gpu supports it, otherwise use rgb only if it'll be used*/
lightmap_bgra = false;
if (gl_config.gles)
@ -2496,8 +2489,6 @@ void Surf_LightmapMode(void)
lightmap_bytes = 1;
break;
#endif
default:
break;
}
}
@ -2703,6 +2694,7 @@ void Surf_BuildModelLightmaps (model_t *m)
int j;
unsigned char *src;
unsigned char *dst;
if (*m->name != '*')
for (i = 0; i < m->lightmaps.count; i++)
{
if (lightmap[newfirst+i]->external)

View File

@ -75,6 +75,8 @@ typedef enum {
RT_MAX_REF_ENTITY_TYPE
} refEntityType_t;
typedef unsigned int skinid_t; //skin 0 is 'unused'
struct dlight_s;
typedef struct entity_s
{
@ -97,6 +99,7 @@ typedef struct entity_s
struct model_s *model; // NULL = no model
int skinnum; // for Alias models
skinid_t customskin; // quake3 style skins
int playerindex; //for qw skins
int topcolour; //colourmapping
@ -138,6 +141,22 @@ typedef struct entity_s
#endif
} entity_t;
#define MAX_GEOMSETS 32
typedef struct
{
char skinname[MAX_QPATH];
int nummappings;
int maxmappings;
qbyte geomset[MAX_GEOMSETS]; //allows selecting a single set of geometry from alternatives. this might be a can of worms.
struct
{
char surface[MAX_QPATH];
shader_t *shader;
texnums_t texnums;
int needsfree; //which textures need to be freed.
} mappings[1];
} skinfile_t;
// plane_t structure
typedef struct mplane_s
{
@ -149,6 +168,27 @@ typedef struct mplane_s
} mplane_t;
#define MAXFRUSTUMPLANES 7 //4 side, 1 near, 1 far (fog), 1 water plane.
typedef struct
{
//note: uniforms expect specific padding/ordering. be really careful with reordering this
vec3_t colour; //w_fog[0].xyz
float alpha; //w_fog[0].w scales clamped fog value
float density; //w_fog[1].x egads, everyone has a different opinion.
float depthbias; //w_fog[1].y distance until the fog actually starts
float glslpad1; //w_fog[1].z
float glslpad2; //w_fog[1].w
// float alpha;
// float start;
// float end;
// float height;
// float fadedepth;
float time; //timestamp for when its current.
} fogstate_t;
void CL_BlendFog(fogstate_t *result, fogstate_t *oldf, float time, fogstate_t *newf);
void CL_ResetFog(void);
#define R_MAX_RECURSE 6
#define R_POSTPROC_PASSES 6
#define RDFD_FOV 1
@ -180,7 +220,7 @@ typedef struct
mplane_t frustum[MAXFRUSTUMPLANES];
int frustum_numplanes;
vec4_t gfog_rgbd;
fogstate_t globalfog;
pxrect_t pxrect; /*vrect, but in pixels rather than virtual coords*/
qboolean externalview; /*draw external models and not viewmodels*/
@ -227,6 +267,7 @@ void R_DrawSkyChain (struct batch_s *batch); /*called from the backend, and call
void R_InitSky (struct texnums_s *ret, struct texture_s *mt, qbyte *src); /*generate q1 sky texnums*/
//r_surf.c
void Surf_SetupFrame(void); //determine pvs+viewcontents
void Surf_DrawWorld(void);
void Surf_GenBrushBatches(struct batch_s **batches, entity_t *ent);
void Surf_StainSurf(struct msurface_s *surf, float *parms);
@ -325,37 +366,37 @@ enum imageflags
/*it seems a little excessive to have to include glquake (and windows headers), just to load some textures/shaders for the backend*/
#ifdef GLQUAKE
texid_tf GL_AllocNewTexture(char *name, int w, int h, unsigned int flags);
void GL_UploadFmt(texid_t tex, char *name, enum uploadfmt fmt, void *data, void *palette, int width, int height, unsigned int flags);
texid_tf GL_LoadTextureFmt (char *identifier, int width, int height, enum uploadfmt fmt, void *data, unsigned int flags);
texid_tf GL_AllocNewTexture(const char *name, int w, int h, unsigned int flags);
void GL_UploadFmt(texid_t tex, const char *name, enum uploadfmt fmt, void *data, void *palette, int width, int height, unsigned int flags);
texid_tf GL_LoadTextureFmt (const char *identifier, int width, int height, enum uploadfmt fmt, void *data, unsigned int flags);
void GL_DestroyTexture(texid_t tex);
#endif
#ifdef D3DQUAKE
texid_t D3D9_LoadTexture (char *identifier, int width, int height, enum uploadfmt fmt, void *data, unsigned int flags);
texid_t D3D9_LoadTexture8Pal24 (char *identifier, int width, int height, qbyte *data, qbyte *palette24, unsigned int flags);
texid_t D3D9_LoadTexture8Pal32 (char *identifier, int width, int height, qbyte *data, qbyte *palette32, unsigned int flags);
texid_t D3D9_LoadCompressed (char *name);
texid_t D3D9_FindTexture (char *identifier, unsigned int flags);
texid_t D3D9_AllocNewTexture(char *ident, int width, int height, unsigned int flags);
void D3D9_Upload (texid_t tex, char *name, enum uploadfmt fmt, void *data, void *palette, int width, int height, unsigned int flags);
texid_t D3D9_LoadTexture (const char *identifier, int width, int height, enum uploadfmt fmt, void *data, unsigned int flags);
texid_t D3D9_LoadTexture8Pal24 (const char *identifier, int width, int height, qbyte *data, qbyte *palette24, unsigned int flags);
texid_t D3D9_LoadTexture8Pal32 (const char *identifier, int width, int height, qbyte *data, qbyte *palette32, unsigned int flags);
texid_t D3D9_LoadCompressed (const char *name);
texid_t D3D9_FindTexture (const char *identifier, unsigned int flags);
texid_t D3D9_AllocNewTexture(const char *ident, int width, int height, unsigned int flags);
void D3D9_Upload (texid_t tex, const char *name, enum uploadfmt fmt, void *data, void *palette, int width, int height, unsigned int flags);
void D3D9_DestroyTexture (texid_t tex);
void D3D9_Image_Shutdown(void);
texid_t D3D11_LoadTexture (char *identifier, int width, int height, enum uploadfmt fmt, void *data, unsigned int flags);
texid_t D3D11_LoadTexture8Pal24 (char *identifier, int width, int height, qbyte *data, qbyte *palette24, unsigned int flags);
texid_t D3D11_LoadTexture8Pal32 (char *identifier, int width, int height, qbyte *data, qbyte *palette32, unsigned int flags);
texid_t D3D11_LoadCompressed (char *name);
texid_t D3D11_FindTexture (char *identifier, unsigned int flags);
texid_t D3D11_AllocNewTexture(char *ident, int width, int height, unsigned int flags);
void D3D11_Upload (texid_t tex, char *name, enum uploadfmt fmt, void *data, void *palette, int width, int height, unsigned int flags);
texid_t D3D11_LoadTexture (const char *identifier, int width, int height, enum uploadfmt fmt, void *data, unsigned int flags);
texid_t D3D11_LoadTexture8Pal24 (const char *identifier, int width, int height, qbyte *data, qbyte *palette24, unsigned int flags);
texid_t D3D11_LoadTexture8Pal32 (const char *identifier, int width, int height, qbyte *data, qbyte *palette32, unsigned int flags);
texid_t D3D11_LoadCompressed (const char *name);
texid_t D3D11_FindTexture (const char *identifier, unsigned int flags);
texid_t D3D11_AllocNewTexture(const char *ident, int width, int height, unsigned int flags);
void D3D11_Upload (texid_t tex, const char *name, enum uploadfmt fmt, void *data, void *palette, int width, int height, unsigned int flags);
void D3D11_DestroyTexture (texid_t tex);
void D3D11_Image_Shutdown(void);
#endif
extern int image_width, image_height;
texid_tf R_LoadReplacementTexture(char *name, char *subpath, unsigned int flags);
texid_tf R_LoadHiResTexture(char *name, char *subpath, unsigned int flags);
texid_tf R_LoadBumpmapTexture(char *name, char *subpath);
texid_tf R_LoadReplacementTexture(const char *name, const char *subpath, unsigned int flags);
texid_tf R_LoadHiResTexture(const char *name, const char *subpath, unsigned int flags);
texid_tf R_LoadBumpmapTexture(const char *name, const char *subpath);
qbyte *Read32BitImageFile(qbyte *buf, int len, int *width, int *height, qboolean *hasalpha, char *fname);
@ -366,19 +407,23 @@ extern texid_t balltexture;
extern texid_t beamtexture;
extern texid_t ptritexture;
skinid_t Mod_RegisterSkinFile(const char *skinname);
skinid_t Mod_ReadSkinFile(const char *skinname, const char *skintext);
void Mod_WipeSkin(skinid_t id);
skinfile_t *Mod_LookupSkin(skinid_t id);
void Mod_Init (qboolean initial);
void Mod_Shutdown (qboolean final);
int Mod_TagNumForName(struct model_s *model, char *name);
int Mod_SkinNumForName(struct model_s *model, char *name);
int Mod_FrameNumForName(struct model_s *model, char *name);
int Mod_TagNumForName(struct model_s *model, const char *name);
int Mod_SkinNumForName(struct model_s *model, const char *name);
int Mod_FrameNumForName(struct model_s *model, const char *name);
float Mod_GetFrameDuration(struct model_s *model, int frameno);
void Mod_ResortShaders(void);
void Mod_ClearAll (void);
struct model_s *Mod_ForName (char *name, qboolean crash);
struct model_s *Mod_FindName (char *name);
struct model_s *Mod_FindName (const char *name);
void *Mod_Extradata (struct model_s *mod); // handles caching
void Mod_TouchModel (char *name);
void Mod_TouchModel (const char *name);
void Mod_RebuildLightmaps (void);
struct mleaf_s *Mod_PointInLeaf (struct model_s *model, float *p);
@ -388,8 +433,8 @@ void Mod_NowLoadExternal(void);
void GLR_LoadSkys (void);
void R_BloomRegister(void);
int Mod_RegisterModelFormatText(void *module, const char *formatname, char *magictext, qboolean (QDECL *load) (struct model_s *mod, void *buffer));
int Mod_RegisterModelFormatMagic(void *module, const char *formatname, unsigned int magic, qboolean (QDECL *load) (struct model_s *mod, void *buffer));
int Mod_RegisterModelFormatText(void *module, const char *formatname, char *magictext, qboolean (QDECL *load) (struct model_s *mod, void *buffer, size_t fsize));
int Mod_RegisterModelFormatMagic(void *module, const char *formatname, unsigned int magic, qboolean (QDECL *load) (struct model_s *mod, void *buffer, size_t fsize));
void Mod_UnRegisterModelFormat(int idx);
void Mod_UnRegisterAllModelFormats(void *module);
@ -451,7 +496,7 @@ void AddOcranaLEDsIndexed (qbyte *image, int h, int w);
void Renderer_Init(void);
void Renderer_Start(void);
qboolean Renderer_Started(void);
void R_ShutdownRenderer(void);
void R_ShutdownRenderer(qboolean videotoo);
void R_RestartRenderer_f (void);//this goes here so we can save some stack when first initing the sw renderer.
//used to live in glquake.h

View File

@ -121,7 +121,7 @@ cvar_t r_loadlits = CVARF ("r_loadlit", "1", CVAR_ARCHIVE);
cvar_t r_menutint = SCVARF ("r_menutint", "0.68 0.4 0.13",
CVAR_RENDERERCALLBACK);
cvar_t r_netgraph = SCVAR ("r_netgraph", "0");
cvar_t r_lerpmuzzlehack = CVARF ("r_lerpmuzzlehack", "1", CVAR_ARCHIVE);
extern cvar_t r_lerpmuzzlehack;
cvar_t r_nolerp = CVARF ("r_nolerp", "0", CVAR_ARCHIVE);
cvar_t r_noframegrouplerp = CVARF ("r_noframegrouplerp", "0", CVAR_ARCHIVE);
cvar_t r_nolightdir = CVARF ("r_nolightdir", "0", CVAR_ARCHIVE);
@ -159,7 +159,7 @@ cvar_t scr_chatmodecvar = CVAR ("scr_chatmode", "0");
cvar_t scr_conalpha = CVARC ("scr_conalpha", "0.7",
Cvar_Limiter_ZeroToOne_Callback);
cvar_t scr_consize = CVAR ("scr_consize", "0.5");
cvar_t scr_conspeed = CVAR ("scr_conspeed", "300");
cvar_t scr_conspeed = CVAR ("scr_conspeed", "2000");
// 10 - 170
cvar_t scr_fov = CVARFC("fov", "90",
CVAR_ARCHIVE,
@ -209,6 +209,8 @@ cvar_t vid_multisample = CVARF ("vid_multisample", "0",
CVAR_ARCHIVE | CVAR_RENDERERLATCH);
cvar_t vid_refreshrate = CVARF ("vid_displayfrequency", "0",
CVAR_ARCHIVE | CVAR_RENDERERLATCH);
cvar_t vid_srgb = CVARF ("vid_srgb", "0",
CVAR_ARCHIVE);
cvar_t vid_wndalpha = CVAR ("vid_wndalpha", "1");
//more readable defaults to match conwidth/conheight.
cvar_t vid_width = CVARFD ("vid_width", "0",
@ -255,7 +257,7 @@ cvar_t vid_gl_context_debug = CVARD ("vid_gl_context_debug", "0", "Requests
cvar_t vid_gl_context_es = CVARD ("vid_gl_context_es", "0", "Requests an OpenGLES context. Be sure to set vid_gl_context_version to 2 or so."); //requires version set correctly, no debug, no compat
#endif
#if defined(GLQUAKE) || defined(D3DQUAKE)
#if 1
cvar_t gl_ati_truform = CVAR ("gl_ati_truform", "0");
cvar_t gl_ati_truform_type = CVAR ("gl_ati_truform_type", "1");
cvar_t gl_ati_truform_tesselation = CVAR ("gl_ati_truform_tesselation", "3");
@ -263,6 +265,7 @@ cvar_t gl_blend2d = CVAR ("gl_blend2d", "1");
cvar_t gl_blendsprites = CVARD ("gl_blendsprites", "0", "Blend sprites instead of alpha testing them");
cvar_t r_deluxemapping = CVARAFD ("r_deluxemapping", "0", "r_glsl_deluxemapping",
CVAR_ARCHIVE | CVAR_RENDERERLATCH, "Enables bumpmapping based upon precomputed light directions");
cvar_t r_shaderblobs = CVARD ("r_shaderblobs", "0", "If enabled, can massively accelerate vid restarts / loading (especially with the d3d renderer). Can cause issues when upgrading engine versions, so this is disabled by default.");
cvar_t gl_compress = CVARFD ("gl_compress", "0", CVAR_ARCHIVE, "Enable automatic texture compression even for textures which are not pre-compressed.");
cvar_t gl_conback = CVARFDC ("gl_conback", "",
CVAR_RENDERERCALLBACK, "Specifies which conback shader/image to use. The Quake fallback is gfx/conback.lmp", R2D_Conback_Callback);
@ -361,7 +364,7 @@ cvar_t vid_hardwaregamma = CVARFD ("vid_hardwaregamma", "1",
cvar_t vid_desktopgamma = CVARFD ("vid_desktopgamma", "0",
CVAR_ARCHIVE | CVAR_RENDERERLATCH, "Apply gamma ramps upon the desktop rather than the window.");
cvar_t r_fog_exp2 = CVARD ("r_fog_exp2", "1", "Expresses how fog fades with distance. 0 (matching DarkPlaces) is typically more realistic, while 1 (matching FitzQuake and others) is more common.");
cvar_t r_fog_exp2 = CVARD ("r_fog_exp2", "1", "Expresses how fog fades with distance. 0 (matching DarkPlaces's default) is typically more realistic, while 1 (matching FitzQuake and others) is more common.");
extern cvar_t gl_dither;
cvar_t gl_screenangle = SCVAR("gl_screenangle", "0");
@ -438,6 +441,7 @@ void GLRenderer_Init(void)
Cvar_Register (&gl_picmip, GLRENDEREROPTIONS);
Cvar_Register (&gl_picmip2d, GLRENDEREROPTIONS);
Cvar_Register (&r_shaderblobs, GLRENDEREROPTIONS);
Cvar_Register (&gl_mipcap, GLRENDEREROPTIONS);
Cvar_Register (&gl_texturemode, GLRENDEREROPTIONS);
Cvar_Register (&gl_texturemode2d, GLRENDEREROPTIONS);
@ -595,6 +599,7 @@ void Renderer_Init(void)
Cvar_Register (&vid_height, VIDCOMMANDGROUP);
Cvar_Register (&vid_refreshrate, VIDCOMMANDGROUP);
Cvar_Register (&vid_multisample, GLRENDEREROPTIONS);
Cvar_Register (&vid_srgb, GLRENDEREROPTIONS);
Cvar_Register (&vid_desktopsettings, VIDCOMMANDGROUP);
@ -845,9 +850,6 @@ rendererinfo_t swrendererinfo;
rendererinfo_t *rendererinfo[] =
{
#ifndef NPQTV
&dedicatedrendererinfo,
#endif
#ifdef GLQUAKE
#ifdef FTE_RPI
&rpirendererinfo,
@ -864,6 +866,9 @@ rendererinfo_t *rendererinfo[] =
#ifdef SWQUAKE
&swrendererinfo,
#endif
#ifndef NPQTV
&dedicatedrendererinfo,
#endif
};
@ -916,9 +921,8 @@ void D3DSucks(void)
Sys_Error("Failed to reload content after mode switch\n");
}
void R_ShutdownRenderer(void)
void R_ShutdownRenderer(qboolean videotoo)
{
CL_AllowIndependantSendCmd(false); //FIXME: figure out exactly which parts are going to affect the model loading.
P_Shutdown();
@ -935,7 +939,7 @@ void R_ShutdownRenderer(void)
if (Draw_Shutdown)
Draw_Shutdown();
if (VID_DeInit)
if (VID_DeInit && videotoo)
{
TRACE(("dbg: R_ApplyRenderer: VID_DeInit\n"));
VID_DeInit();
@ -983,7 +987,7 @@ qboolean R_ApplyRenderer (rendererstate_t *newr)
if (!newr->renderer)
return false;
R_ShutdownRenderer();
R_ShutdownRenderer(true);
if (qrenderer == QR_NONE)
{
@ -1094,6 +1098,8 @@ TRACE(("dbg: R_ApplyRenderer: screen inited\n"));
Sbar_Flush();
IN_ReInit();
Cvar_ForceCallback(&v_gamma);
}
else
{
@ -1137,7 +1143,7 @@ TRACE(("dbg: R_ApplyRenderer: initing mods\n"));
#endif
TRACE(("dbg: R_ApplyRenderer: reloading server map\n"));
sv.world.worldmodel = Mod_ForName (sv.modelname, false);
sv.world.worldmodel = Mod_ForName (sv.modelname, MLV_WARN);
TRACE(("dbg: R_ApplyRenderer: loaded\n"));
if (sv.world.worldmodel->needload)
{
@ -1202,6 +1208,14 @@ TRACE(("dbg: R_ApplyRenderer: clearing world\n"));
}
}
}
#endif
#ifdef Q3SERVER
else if (svs.gametype == GT_QUAKE3)
{
//traditionally a q3 server can just keep hold of its world cmodel and nothing is harmed.
//this means we just need to reload the worldmodel and all is fine...
//there are some edge cases however, like lingering pointers refering to entities.
}
#endif
else
SV_UnspawnServer();
@ -1215,6 +1229,19 @@ TRACE(("dbg: R_ApplyRenderer: clearing world\n"));
CL_InitDlights();
TRACE(("dbg: R_ApplyRenderer: starting on client state\n"));
if (newr)
memcpy(&currentrendererstate, newr, sizeof(currentrendererstate));
#ifdef Q3SERVER
if (svs.gametype == GT_QUAKE3)
{
CG_Stop();
CG_Start();
R_NewMap();
}
else
#endif
if (cl.worldmodel)
{
cl.worldmodel = NULL;
@ -1227,7 +1254,6 @@ TRACE(("dbg: R_ApplyRenderer: reloading ALL models\n"));
if (!cl.model_name[i][0])
break;
cl.model_precache[i] = NULL;
TRACE(("dbg: R_ApplyRenderer: reloading model %s\n", cl.model_name[i]));
#ifdef Q2CLIENT //skip vweps
@ -1235,9 +1261,9 @@ TRACE(("dbg: R_ApplyRenderer: reloading ALL models\n"));
cl.model_precache[i] = NULL;
else
#endif
cl.model_precache[i] = Mod_ForName (cl.model_name[i], false);
cl.model_precache[i] = Mod_ForName (cl.model_name[i], MLV_SILENT);
if (!cl.model_precache[i] && i == 1)
if ((!cl.model_precache[i] || cl.model_precache[i]->type == mod_dummy) && i == 1)
{
Con_Printf ("\nThe required model file '%s' could not be found.\n\n"
, cl.model_name[i]);
@ -1254,7 +1280,7 @@ TRACE(("dbg: R_ApplyRenderer: reloading ALL models\n"));
for (i=0; i < MAX_VWEP_MODELS; i++)
{
if (*cl.model_name_vwep[i])
cl.model_precache_vwep[i] = Mod_ForName (cl.model_name_vwep[i], false);
cl.model_precache_vwep[i] = Mod_ForName (cl.model_name_vwep[i], MLV_SILENT);
else
cl.model_precache_vwep[i] = NULL;
}
@ -1267,7 +1293,7 @@ TRACE(("dbg: R_ApplyRenderer: reloading ALL models\n"));
cl.model_csqcprecache[i] = NULL;
TRACE(("dbg: R_ApplyRenderer: reloading csqc model %s\n", cl.model_csqcname[i]));
cl.model_csqcprecache[i] = Mod_ForName (cl.model_csqcname[i], false);
cl.model_csqcprecache[i] = Mod_ForName (cl.model_csqcname[i], MLV_SILENT);
if (!cl.model_csqcprecache[i])
{
@ -1340,13 +1366,12 @@ TRACE(("dbg: R_ApplyRenderer: efrags\n"));
TRACE(("dbg: R_ApplyRenderer: done\n"));
if (newr)
memcpy(&currentrendererstate, newr, sizeof(currentrendererstate));
return true;
}
void R_ReloadRenderer_f (void)
{
R_ShutdownRenderer(false);
//reloads textures without destroying video context.
R_ApplyRenderer_Load(NULL);
}
@ -1371,6 +1396,7 @@ qboolean R_BuildRenderstate(rendererstate_t *newr, char *rendererstring)
newr->fullscreen = vid_fullscreen.value;
newr->rate = vid_refreshrate.value;
newr->stereo = (r_stereo_method.ival == 1);
newr->srgb = vid_srgb.ival;
if (!*vid_vsync.string || vid_vsync.value < 0)
newr->wait = -1;
@ -1483,7 +1509,7 @@ TRACE(("dbg: R_RestartRenderer_f\n"));
return;
}
M_Shutdown();
M_Shutdown(false);
Media_CaptureDemoEnd();
TRACE(("dbg: R_RestartRenderer_f renderer %i\n", newr.renderer));
@ -1499,7 +1525,9 @@ TRACE(("dbg: R_RestartRenderer_f\n"));
}
else
{
int i;
qboolean failed = true;
rendererinfo_t *skip = newr.renderer;
if (newr.rate != 0)
{
@ -1516,23 +1544,31 @@ TRACE(("dbg: R_RestartRenderer_f\n"));
failed = !R_ApplyRenderer(&newr);
}
if (failed)
for (i = 0; failed && i < sizeof(rendererinfo)/sizeof(rendererinfo[0]); i++)
{
newr.renderer = &dedicatedrendererinfo;
if (R_ApplyRenderer(&newr))
newr.renderer = rendererinfo[i];
if (newr.renderer && newr.renderer != skip)
{
TRACE(("dbg: R_RestartRenderer_f going to dedicated\n"));
Con_Printf(CON_ERROR "Video mode switch failed. Old mode wasn't supported either. Console forced.\n\nChange the following vars to something useable, and then use the setrenderer command.\n");
Con_Printf("%s: %s\n", vid_width.name, vid_width.string);
Con_Printf("%s: %s\n", vid_height.name, vid_height.string);
Con_Printf("%s: %s\n", vid_bpp.name, vid_bpp.string);
Con_Printf("%s: %s\n", vid_refreshrate.name, vid_refreshrate.string);
Con_Printf("%s: %s\n", vid_renderer.name, vid_renderer.string);
Con_Printf("%s: %s\n", gl_driver.name, gl_driver.string);
Con_Printf(CON_NOTICE "Trying %s\n", newr.renderer->description);
failed = !R_ApplyRenderer(&newr);
}
else
Sys_Error("Couldn't fall back to previous renderer\n");
}
//if we ended up resorting to our last choice (dedicated) then print some informative message about it
//fixme: on unixy systems, we should make sure we're actually printing to something (ie: that we're not running via some x11 shortcut with our stdout redirected to /dev/nul
if (!failed && newr.renderer == &dedicatedrendererinfo)
{
Con_Printf(CON_ERROR "Video mode switch failed. Console forced.\n\nPlease change the following vars to something useable, and then use the setrenderer command.\n");
Con_Printf("%s: %s\n", vid_width.name, vid_width.string);
Con_Printf("%s: %s\n", vid_height.name, vid_height.string);
Con_Printf("%s: %s\n", vid_bpp.name, vid_bpp.string);
Con_Printf("%s: %s\n", vid_refreshrate.name, vid_refreshrate.string);
Con_Printf("%s: %s\n", vid_renderer.name, vid_renderer.string);
Con_Printf("%s: %s\n", gl_driver.name, gl_driver.string);
}
if (failed)
Sys_Error("Unable to initialise any video mode\n");
}
}
@ -2245,7 +2281,7 @@ void R_SetFrustum (float projmat[16], float viewmat[16])
r_refdef.frustum_numplanes++;
//do far plane
//fog will not logically not actually reach 0, though precision issues will force it. we cut off at an exponant of -500
//fog will logically not actually reach 0, though precision issues will force it. we cut off at an exponant of -500
if (r_refdef.gfog_rgbd[3]
#ifdef TERRAIN
&& cl.worldmodel && cl.worldmodel->type == mod_heightmap
@ -2261,9 +2297,9 @@ void R_SetFrustum (float projmat[16], float viewmat[16])
/*Documentation: the GLSL/GL will do this maths:
float dist = 1024;
if (r_fog_exp2.ival)
fog = pow(2, -r_refdef.gfog_rgbd[3] * r_refdef.gfog_rgbd[3] * dist * dist * 1.442695);
fog = pow(2, -r_refdef.globalfog.density * r_refdef.globalfog.density * dist * dist * 1.442695);
else
fog = pow(2, -r_refdef.gfog_rgbd[3] * dist * 1.442695);
fog = pow(2, -r_refdef.globalfog.density * dist * 1.442695);
*/
//the fog factor cut-off where its pointless to allow it to get closer to 0 (0 is technically infinite)
@ -2272,9 +2308,9 @@ void R_SetFrustum (float projmat[16], float viewmat[16])
//figure out the eyespace distance required to reach that fog value
culldist = log(fog);
if (r_fog_exp2.ival)
culldist = sqrt(culldist / (-r_refdef.gfog_rgbd[3] * r_refdef.gfog_rgbd[3]));
culldist = sqrt(culldist / (-r_refdef.globalfog.density * r_refdef.globalfog.density));
else
culldist = culldist / (-r_refdef.gfog_rgbd[3]);
culldist = culldist / (-r_refdef.globalfog.density);
//anything drawn beyond this point is fully obscured by fog
r_refdef.frustum[r_refdef.frustum_numplanes].normal[0] = mvp[3] - mvp[2];

View File

@ -73,7 +73,9 @@ void SCR_ShowPic_Create(void);
void SCR_ShowPic_Hide(void);
void SCR_ShowPic_Move(void);
void SCR_ShowPic_Update(void);
void SCR_ShowPic_Clear(void);
void SCR_ShowPic_Clear(qboolean all);
char *SCR_ShowPics_ClickCommand(int cx, int cy);
void SCR_ShowPic_Script_f(void);
//a header is better than none...
void Draw_TextBox (int x, int y, int width, int lines);
@ -95,7 +97,7 @@ void SCR_SetLoadingFile(char *str);
/*fonts*/
void Font_Init(void);
void Font_Shutdown(void);
struct font_s *Font_LoadFont(int height, char *fontfilename);
struct font_s *Font_LoadFont(int height, const char *fontfilename);
void Font_Free(struct font_s *f);
void Font_BeginString(struct font_s *font, float vx, float vy, int *px, int *py);
void Font_BeginScaledString(struct font_s *font, float vx, float vy, float szx, float szy, float *px, float *py); /*avoid using*/

View File

@ -158,7 +158,7 @@ void Skin_Find (player_info_t *sc)
*s = '\0';
#ifdef Q2CLIENT
if (cls.protocol == CP_QUAKE2)
model = Mod_ForName(va("players/%s/tris.md2", name), false);
model = Mod_ForName(va("players/%s/tris.md2", name), MLV_SILENT);
else
#endif
model = NULL;//Mod_ForName(va("models/players/%s.mdl", name), false);

View File

@ -298,7 +298,7 @@ static void PrintALError(char *string)
Con_Printf("OpenAL - %s: %x: %s\n",string,err,text);
}
void OpenAL_LoadCache(unsigned int *bufptr, sfxcache_t *sc)
void OpenAL_LoadCache(unsigned int *bufptr, sfxcache_t *sc, float volume)
{
unsigned int fmt;
unsigned int size;
@ -334,20 +334,50 @@ void OpenAL_LoadCache(unsigned int *bufptr, sfxcache_t *sc)
PrintALError("pre Buffer Data");
palGenBuffers(1, bufptr);
/*openal is inconsistant and supports only 8bit unsigned or 16bit signed*/
if (sc->width == 1)
if (volume != 1)
{
unsigned char *tmp = malloc(size);
char *src = sc->data;
int i;
for (i = 0; i < size; i++)
if (sc->width == 1)
{
tmp[i] = src[i]+128;
unsigned char *tmp = malloc(size);
char *src = sc->data;
int i;
for (i = 0; i < size; i++)
{
tmp[i] = src[i]*volume+128; //signed->unsigned
}
palBufferData(*bufptr, fmt, tmp, size, sc->speed);
free(tmp);
}
else
{
short *tmp = malloc(size);
short *src = (short*)sc->data;
int i;
for (i = 0; i < (size>>1); i++)
{
tmp[i] = bound(-32767, src[i]*volume, 32767); //signed.
}
palBufferData(*bufptr, fmt, tmp, size, sc->speed);
free(tmp);
}
palBufferData(*bufptr, fmt, tmp, size, sc->speed);
free(tmp);
}
else
palBufferData(*bufptr, fmt, sc->data, size, sc->speed);
{
if (sc->width == 1)
{
unsigned char *tmp = malloc(size);
char *src = sc->data;
int i;
for (i = 0; i < size; i++)
{
tmp[i] = src[i]+128;
}
palBufferData(*bufptr, fmt, tmp, size, sc->speed);
free(tmp);
}
else
palBufferData(*bufptr, fmt, sc->data, size, sc->speed);
}
//FIXME: we need to handle oal-oom error codes
@ -385,7 +415,7 @@ static void OpenAL_ListenerUpdate(soundcardinfo_t *sc, vec3_t origin, vec3_t for
if (!s_al_static_listener.value)
{
palListenerf(AL_GAIN, volume.value*voicevolumemod);
palListenerf(AL_GAIN, 1);
palListenerfv(AL_POSITION, oali->ListenPos);
palListenerfv(AL_VELOCITY, oali->ListenVel);
palListenerfv(AL_ORIENTATION, oali->ListenOri);
@ -398,7 +428,7 @@ static void OpenAL_ChannelUpdate(soundcardinfo_t *sc, channel_t *chan, unsigned
oalinfo_t *oali = sc->handle;
ALuint src;
sfx_t *sfx = chan->sfx;
float pitch;
float pitch, cvolume;
int chnum = chan - sc->channel;
ALuint buf;
@ -453,6 +483,10 @@ static void OpenAL_ChannelUpdate(soundcardinfo_t *sc, channel_t *chan, unsigned
return;
}
cvolume = chan->master_vol/255.0f;
if (!(chan->flags & CF_ABSVOLUME))
cvolume *= volume.value*voicevolumemod;
if (schanged || sfx->decoder.decodedata)
{
if (!sfx->openal_buffer)
@ -473,7 +507,7 @@ static void OpenAL_ChannelUpdate(soundcardinfo_t *sc, channel_t *chan, unsigned
//build a buffer with it and queue it up.
//buffer will be purged later on when its unqueued
OpenAL_LoadCache(&buf, &sbuf);
OpenAL_LoadCache(&buf, &sbuf, max(1,cvolume));
palSourceQueueBuffers(src, 1, &buf);
//yay
@ -485,14 +519,15 @@ static void OpenAL_ChannelUpdate(soundcardinfo_t *sc, channel_t *chan, unsigned
}
else
{
OpenAL_LoadCache(&sfx->openal_buffer, sfx->decoder.buf);
OpenAL_LoadCache(&sfx->openal_buffer, sfx->decoder.buf, 1);
palSourcei(src, AL_BUFFER, sfx->openal_buffer);
}
}
else
palSourcei(src, AL_BUFFER, sfx->openal_buffer);
}
palSourcef(src, AL_GAIN, chan->master_vol/255.0f);
palSourcef(src, AL_GAIN, min(cvolume, 1)); //openal only supports a max volume of 1. anything above is an error and will be clamped.
if (chan->entnum == -1 || chan->entnum == cl.playerview[0].viewentity)
palSourcefv(src, AL_POSITION, vec3_origin);
else

View File

@ -951,7 +951,8 @@ static qboolean QDECL DSOUND_InitCard (soundcardinfo_t *sc, const char *device)
}
//wait for the thread to finish (along with all its error con printfs etc
Sys_ConditionWait(cond);
if (!Sys_ConditionWait(cond))
Con_SafePrintf ("Looks like the sound thread isn't starting up\n");
Sys_UnlockConditional(cond);
Sys_DestroyConditional(cond);

View File

@ -30,7 +30,7 @@ static void S_StopAllSounds_f (void);
static void S_UpdateCard(soundcardinfo_t *sc);
static void S_ClearBuffer (soundcardinfo_t *sc);
static sfx_t *S_FindName (char *name);
static sfx_t *S_FindName (const char *name);
// =======================================================================
// Internal sound data & structures
@ -131,7 +131,7 @@ cvar_t snd_voip_showmeter = CVARAFD("cl_voip_showmeter", "1", NULL, CVAR_ARCHIV
cvar_t snd_voip_play = CVARAFDC("cl_voip_play", "1", NULL, CVAR_ARCHIVE, "Enables voip playback. Value is a volume scaler.", S_Voip_Play_Callback);
cvar_t snd_voip_ducking = CVARAFD("cl_voip_ducking", "0.5", NULL, CVAR_ARCHIVE, "Scales game audio by this much when someone is talking to you. Does not affect your speaker volume when you speak (minimum of cl_voip_capturingvol and cl_voip_ducking is used).");
cvar_t snd_voip_micamp = CVARAFDC("cl_voip_micamp", "2", NULL, CVAR_ARCHIVE, "Amplifies your microphone when using voip.", 0);
cvar_t snd_voip_codec = CVARAFDC("cl_voip_codec", "0", NULL, CVAR_ARCHIVE, "0: speex. 1: raw. 2: opus.", 0);
cvar_t snd_voip_codec = CVARAFDC("cl_voip_codec", "0", NULL, CVAR_ARCHIVE, "0: speex(@11khz). 1: raw. 2: opus. 3: speex(@8khz). 4: speex(@16). 5:speex(@32).", 0);
cvar_t snd_voip_noisefilter = CVARAFDC("cl_voip_noisefilter", "1", NULL, CVAR_ARCHIVE, "Enable the use of the noise cancelation filter.", 0);
cvar_t snd_voip_autogain = CVARAFDC("cl_voip_autogain", "0", NULL, CVAR_ARCHIVE, "Attempts to normalize your voice levels to a standard level. Useful for lazy people, but interferes with voice activation levels.", 0);
#endif
@ -2007,7 +2007,7 @@ S_FindName
also touches it
==================
*/
static sfx_t *S_FindName (char *name)
static sfx_t *S_FindName (const char *name)
{
int i;
sfx_t *sfx;
@ -2112,7 +2112,7 @@ S_PrecacheSound
==================
*/
sfx_t *S_PrecacheSound (char *name)
sfx_t *S_PrecacheSound (const char *name)
{
sfx_t *sfx;
@ -2834,7 +2834,7 @@ void S_ExtraUpdate (void)
if (!sound_started)
return;
#ifdef _WIN32
#if defined(_WIN32) && !defined(WINRT)
INS_Accumulate ();
#endif
@ -3015,7 +3015,7 @@ void S_SoundList_f(void)
}
void S_LocalSound (char *sound)
void S_LocalSound (const char *sound)
{
sfx_t *sfx;

View File

@ -19,6 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "quakedef.h"
#include "winquake.h"
#ifndef WINRT
// 64K is > 1 second at 16-bit, 22050 Hz
#define WAV_BUFFERS 64
@ -367,3 +368,4 @@ int WAV_InitCard (soundcardinfo_t *sc, int cardnum)
return true;
}
int (*pWAV_InitCard) (soundcardinfo_t *sc, int cardnum) = &WAV_InitCard;
#endif

View File

@ -132,7 +132,7 @@ qboolean S_HaveOutput(void);
void S_Music_Clear(sfx_t *onlyifsample);
void S_Music_Seek(float time);
sfx_t *S_PrecacheSound (char *sample);
sfx_t *S_PrecacheSound (const char *sample);
void S_TouchSound (char *sample);
void S_UntouchAll(void);
void S_ClearPrecache (void);
@ -237,7 +237,7 @@ extern cvar_t snd_mixerthread;
extern int snd_blocked;
void S_LocalSound (char *s);
void S_LocalSound (const char *s);
qboolean S_LoadSound (sfx_t *s);
typedef qboolean (*S_LoadSound_t) (sfx_t *s, qbyte *data, int datalen, int sndspeed);

View File

@ -36,6 +36,254 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <process.h>
#endif
wchar_t *widen(wchar_t *out, size_t outlen, const char *utf8);
char *narrowen(char *out, size_t outlen, wchar_t *wide);
#ifdef WINRT //you're going to need a different sys_ port.
qboolean isDedicated = false;
qboolean ActiveApp;
void VARGS Sys_Error (const char *error, ...){} //eep
void VARGS Sys_Printf (char *fmt, ...){} //safe, but not ideal (esp for debugging)
void Sys_SendKeyEvents (void){} //safe, but not ideal
void Sys_ServerActivity(void){} //empty is safe
void Sys_RecentServer(char *command, char *target, char *title, char *desc){} //empty is safe
qboolean Sys_InitTerminal(void){return false;} //failure will break 'setrenderer sv'
char *Sys_ConsoleInput (void){return NULL;} //safe to stub
void Sys_CloseTerminal (void){} //called when switching from dedicated->non-dedicated
dllhandle_t *Sys_LoadLibrary(const char *name, dllfunction_t *funcs){return NULL;} //can just about get away with it
void *Sys_GetAddressForName(dllhandle_t *module, const char *exportname){return NULL;}
void Sys_CloseLibrary(dllhandle_t *lib){} //safe, ish
void Sys_Init (void){} //safe, stub is fine. used to register system-specific cvars/commands.
void Sys_Shutdown(void){} //safe
qboolean Sys_RandomBytes(qbyte *string, int len){return false;}
qboolean Sys_GetDesktopParameters(int *width, int *height, int *bpp, int *refreshrate){return false;}
void INS_Move(float *movements, int pnum){} //safe
void INS_Commands(void){} //safe
void INS_Init(void){} //safe. should be xinput2 I guess. nothing else is actually supported. touchscreens don't really count.
void INS_ReInit(void){} //safe
void INS_Shutdown(void){} //safe
void INS_UpdateGrabs(int fullscreen, int activeapp){} //safe
void *RT_GetCoreWindow(int *width, int *height){return NULL;} //I already wrote the d3d code, but it needs a window to attach to. you can override width+height by writing to them
void D3D11_DoResize(int newwidth, int newheight); //already written, call if resized since getcorewindow
static char *clippy;
char *Sys_GetClipboard(void)
{
return Z_StrDup(clippy);
}
void Sys_CloseClipboard(char *bf)
{
Z_Free(bf);
}
void Sys_SaveClipboard(char *text)
{
Z_Free(clippy);
clippy = Z_StrDup(text);
}
static LARGE_INTEGER timestart, timefreq;
static qboolean timeinited = false;
unsigned int Sys_Milliseconds(void)
{
LARGE_INTEGER cur, diff;
if (!timeinited)
{
timeinited = true;
QueryPerformanceFrequency(&timefreq);
QueryPerformanceCounter(&timestart);
}
QueryPerformanceCounter(&cur);
diff.QuadPart = cur.QuadPart - timestart.QuadPart;
diff.QuadPart *= 1000;
diff.QuadPart /= timefreq.QuadPart;
return diff.QuadPart;
}
double Sys_DoubleTime (void)
{
LARGE_INTEGER cur, diff;
if (!timeinited)
{
timeinited = true;
QueryPerformanceFrequency(&timefreq);
QueryPerformanceCounter(&timestart);
}
QueryPerformanceCounter(&cur);
diff.QuadPart = cur.QuadPart - timestart.QuadPart;
diff.QuadPart *= 1000;
return (double)diff.QuadPart / (double)timefreq.QuadPart; //I hope the timefreq doesn't get rounded and cause milliseconds and doubletime to start to drift apart.
}
void Sys_Quit (void)
{
Host_Shutdown ();
exit(1);
}
void Sys_mkdir (char *path)
{
wchar_t wide[MAX_OSPATH];
widen(wide, sizeof(wide), path);
CreateDirectoryW(wide, NULL);
}
qboolean Sys_remove (char *path)
{
wchar_t wide[MAX_OSPATH];
widen(wide, sizeof(wide), path);
if (DeleteFileW(wide))
return true; //success
if (GetLastError() == ERROR_FILE_NOT_FOUND)
return true; //succeed when the file already didn't exist
return false; //other errors? panic
}
qboolean Sys_Rename (char *oldfname, char *newfname)
{
wchar_t oldwide[MAX_OSPATH];
wchar_t newwide[MAX_OSPATH];
widen(oldwide, sizeof(oldwide), oldfname);
widen(newwide, sizeof(newwide), newfname);
return MoveFileExW(oldwide, newwide, MOVEFILE_REPLACE_EXISTING|MOVEFILE_COPY_ALLOWED);
}
//enumeratefiles is recursive for */* to work
static int Sys_EnumerateFiles2 (const char *match, int matchstart, int neststart, int (QDECL *func)(const char *fname, qofs_t fsize, void *parm, searchpathfuncs_t *spath), void *parm, searchpathfuncs_t *spath)
{
qboolean go;
HANDLE r;
WIN32_FIND_DATAW fd;
int nest = neststart; //neststart refers to just after a /
qboolean wild = false;
while(match[nest] && match[nest] != '/')
{
if (match[nest] == '?' || match[nest] == '*')
wild = true;
nest++;
}
if (match[nest] == '/')
{
char submatch[MAX_OSPATH];
char tmproot[MAX_OSPATH];
if (!wild)
return Sys_EnumerateFiles2(match, matchstart, nest+1, func, parm, spath);
if (nest-neststart+1> MAX_OSPATH)
return 1;
memcpy(submatch, match+neststart, nest - neststart);
submatch[nest - neststart] = 0;
nest++;
if (neststart+4 > MAX_OSPATH)
return 1;
memcpy(tmproot, match, neststart);
strcpy(tmproot+neststart, "*.*");
{
wchar_t wroot[MAX_OSPATH];
r = FindFirstFileExW(widen(wroot, sizeof(wroot), tmproot), FindExInfoStandard, &fd, FindExSearchNameMatch, NULL, 0);
}
strcpy(tmproot+neststart, "");
if (r==(HANDLE)-1)
return 1;
go = true;
do
{
char utf8[MAX_OSPATH];
char file[MAX_OSPATH];
narrowen(utf8, sizeof(utf8), fd.cFileName);
if (*utf8 == '.'); //don't ever find files with a name starting with '.'
else if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) //is a directory
{
if (wildcmp(submatch, utf8))
{
int newnest;
if (strlen(tmproot) + strlen(utf8) + strlen(match+nest) + 2 < MAX_OSPATH)
{
Q_snprintfz(file, sizeof(file), "%s%s/", tmproot, utf8);
newnest = strlen(file);
strcpy(file+newnest, match+nest);
go = Sys_EnumerateFiles2(file, matchstart, newnest, func, parm, spath);
}
}
}
} while(FindNextFileW(r, &fd) && go);
FindClose(r);
}
else
{
const char *submatch = match + neststart;
char tmproot[MAX_OSPATH];
if (neststart+4 > MAX_OSPATH)
return 1;
memcpy(tmproot, match, neststart);
strcpy(tmproot+neststart, "*.*");
{
wchar_t wroot[MAX_OSPATH];
r = FindFirstFileExW(widen(wroot, sizeof(wroot), tmproot), FindExInfoStandard, &fd, FindExSearchNameMatch, NULL, 0);
}
strcpy(tmproot+neststart, "");
if (r==(HANDLE)-1)
return 1;
go = true;
do
{
char utf8[MAX_OSPATH];
char file[MAX_OSPATH];
narrowen(utf8, sizeof(utf8), fd.cFileName);
if (*utf8 == '.')
; //don't ever find files with a name starting with '.' (includes .. and . directories, and unix hidden files)
else if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) //is a directory
{
if (wildcmp(submatch, utf8))
{
if (strlen(tmproot+matchstart) + strlen(utf8) + 2 < MAX_OSPATH)
{
Q_snprintfz(file, sizeof(file), "%s%s/", tmproot+matchstart, utf8);
go = func(file, qofs_Make(fd.nFileSizeLow, fd.nFileSizeHigh), parm, spath);
}
}
}
else
{
if (wildcmp(submatch, utf8))
{
if (strlen(tmproot+matchstart) + strlen(utf8) + 1 < MAX_OSPATH)
{
Q_snprintfz(file, sizeof(file), "%s%s", tmproot+matchstart, utf8);
go = func(file, qofs_Make(fd.nFileSizeLow, fd.nFileSizeHigh), parm, spath);
}
}
}
} while(FindNextFileW(r, &fd) && go);
FindClose(r);
}
return go;
}
int Sys_EnumerateFiles (const char *gpath, const char *match, int (QDECL *func)(const char *fname, qofs_t fsize, void *parm, searchpathfuncs_t *spath), void *parm, searchpathfuncs_t *spath)
{
char fullmatch[MAX_OSPATH];
int start;
if (strlen(gpath) + strlen(match) + 2 > MAX_OSPATH)
return 1;
strcpy(fullmatch, gpath);
start = strlen(fullmatch);
if (start && fullmatch[start-1] != '/')
fullmatch[start++] = '/';
fullmatch[start] = 0;
strcat(fullmatch, match);
return Sys_EnumerateFiles2(fullmatch, start, start, func, parm, spath);
}
#else
#if defined(GLQUAKE) && defined(DEBUG)
#define PRINTGLARRAYS
#endif
@ -448,7 +696,14 @@ DWORD CrashExceptionHandler (qboolean iswatchdog, DWORD exceptionCode, LPEXCEPTI
Sys_SaveClipboard(stacklog+logstart);
#ifdef _MSC_VER
if (MessageBoxA(0, stacklog, "KABOOM!", MB_ICONSTOP|MB_YESNO) != IDYES)
{
if (pIsDebuggerPresent ())
{
//its possible someone attached a debugger while we were showing that message
return EXCEPTION_CONTINUE_SEARCH;
}
return EXCEPTION_EXECUTE_HANDLER;
}
#else
MessageBox(0, stacklog, "KABOOM!", MB_ICONSTOP);
return EXCEPTION_EXECUTE_HANDLER;
@ -485,10 +740,10 @@ DWORD CrashExceptionHandler (qboolean iswatchdog, DWORD exceptionCode, LPEXCEPTI
}
/*take a dump*/
if (*com_homedir)
Q_strncpyz(dumpPath, com_homedir, sizeof(dumpPath));
else if (*com_quakedir)
Q_strncpyz(dumpPath, com_quakedir, sizeof(dumpPath));
if (*com_homepath)
Q_strncpyz(dumpPath, com_homepath, sizeof(dumpPath));
else if (*com_gamepath)
Q_strncpyz(dumpPath, com_gamepath, sizeof(dumpPath));
else
GetTempPath (sizeof(dumpPath)-16, dumpPath);
Q_strncatz(dumpPath, DISTRIBUTION"CrashDump.dmp", sizeof(dumpPath));
@ -677,10 +932,6 @@ FILE IO
===============================================================================
*/
wchar_t *widen(wchar_t *out, size_t outlen, const char *utf8);
char *narrowen(char *out, size_t outlen, wchar_t *wide);
void Sys_mkdir (char *path)
{
if (WinNT)
@ -1193,13 +1444,21 @@ void VARGS Sys_Printf (char *fmt, ...)
wchar_t wide[1024], *out;
int wlen;
if (!houtput && !debugout)
if (!houtput && !debugout && !SSV_IsSubServer())
return;
va_start (argptr,fmt);
vsnprintf (text, sizeof(text), fmt, argptr);
va_end (argptr);
#ifdef SUBSERVERS
if (SSV_IsSubServer())
{
SSV_PrintToMaster(text);
return;
}
#endif
end = COM_ParseFunString(CON_WHITEMASK, text, msg, sizeof(msg), false);
out = wide;
in = msg;
@ -1451,7 +1710,7 @@ void Sys_SaveClipboard(char *text)
while (*text)
{
//NOTE: should be \r\n and not just \n
*temp++ = utf8_decode(&error, text, &text);
*temp++ = utf8_decode(&error, text, &text) & 0xff;
}
*temp = 0;
strcpy(temp, text);
@ -1487,6 +1746,55 @@ char *Sys_ConsoleInput (void)
HANDLE th;
char *clipText, *textCopied;
#ifdef SUBSERVERS
if (SSV_IsSubServer())
{
DWORD avail;
static char text[1024], *nl;
static int textpos = 0;
HANDLE input = GetStdHandle(STD_INPUT_HANDLE);
for (;;)
{
if (!PeekNamedPipe(input, NULL, 0, NULL, &avail, NULL))
{
SV_FinalMessage("Cluster shut down\n");
Cmd_ExecuteString("quit force", RESTRICT_LOCAL);
}
else if (avail)
{
if (avail > sizeof(text)-1-textpos)
avail = sizeof(text)-1-textpos;
if (ReadFile(input, text+textpos, avail, &avail, NULL))
{
textpos += avail;
while(textpos >= 2)
{
unsigned short len = text[0] | (text[1]<<8);
if (textpos >= len && len >= 2)
{
memcpy(net_message.data, text+2, len-2);
net_message.cursize = len-2;
MSG_BeginReading (msg_nullnetprim);
SSV_ReadFromControlServer();
memmove(text, text+len, textpos - len);
textpos -= len;
}
else
break;
}
}
}
else
break;
}
return NULL;
}
#endif
if (!hinput)
return NULL;
@ -1608,6 +1916,10 @@ BOOL WINAPI HandlerRoutine (DWORD dwCtrlType)
qboolean Sys_InitTerminal (void)
{
DWORD m;
if (SSV_IsSubServer())
return true; //just pretend we did
if (!AllocConsole())
return false;
@ -1963,7 +2275,7 @@ static IShellLinkW *CreateShellLink(char *command, char *target, char *title, ch
IShellLinkW_SetIconLocation(link, buf, 0); /*grab the first icon from our exe*/
IShellLinkW_SetPath(link, buf); /*program to run*/
Q_strncpyz(tmp, com_quakedir, sizeof(tmp));
Q_strncpyz(tmp, com_gamepath, sizeof(tmp));
/*normalize the gamedir, so we don't end up with the same thing multiple times*/
for(s = tmp; *s; s++)
{
@ -2884,24 +3196,28 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin
parms.argc = com_argc;
parms.argv = com_argv;
#if !defined(CLIENTONLY) && !defined(SERVERONLY)
#if !defined(CLIENTONLY) && !defined(SERVERONLY)
if (COM_CheckParm ("-dedicated"))
isDedicated = true;
#ifdef SUBSERVERS
if (COM_CheckParm("-clusterslave"))
isDedicated = isClusterSlave = true;
#endif
#endif
if (isDedicated)
{
#if !defined(CLIENTONLY)
#if !defined(CLIENTONLY)
if (!Sys_InitTerminal())
Sys_Error ("Couldn't allocate dedicated server console");
#endif
#endif
}
if (!Sys_Startup_CheckMem(&parms))
Sys_Error ("Not enough memory free; check disk space\n");
#ifndef CLIENTONLY
#ifndef CLIENTONLY
if (isDedicated) //compleate denial to switch to anything else - many of the client structures are not initialized.
{
int delay;
@ -2919,19 +3235,19 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin
}
return TRUE;
}
#endif
#endif
tevent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (!tevent)
Sys_Error ("Couldn't create event");
#ifdef SERVERONLY
#ifdef SERVERONLY
Sys_Printf ("SV_Init\n");
SV_Init(&parms);
#else
#else
Sys_Printf ("Host_Init\n");
Host_Init (&parms);
#endif
#endif
oldtime = Sys_DoubleTime ();
@ -3064,3 +3380,4 @@ void Sys_Sleep (double seconds)
{
Sleep(seconds * 1000);
}
#endif

View File

@ -2,11 +2,7 @@
#include <ctype.h>
#ifdef _WIN32
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#include "winquake.h"
#endif
typedef struct f_modified_s {
@ -59,7 +55,7 @@ static Security_Supported_Binaries_t Security_Supported_Binaries;
static Security_Shutdown_t Security_Shutdown;
#ifdef _WIN32
#if 0//def _WIN32
static void *secmodule;
#endif
@ -209,7 +205,7 @@ void InitValidation(void)
Cvar_Register(&allow_f_cmdline, "Authentication");
Cvar_Register(&ruleset, "Authentication");
#ifdef _WIN32
#if 0//def _WIN32
secmodule = LoadLibrary("fteqw-security.dll");
if (secmodule)
{
@ -242,7 +238,7 @@ void InitValidation(void)
Cvar_Register(&auth_validateclients, "Authentication");
return;
}
#ifdef _WIN32
#if 0//def _WIN32
FreeLibrary(secmodule);
#endif
}
@ -380,7 +376,7 @@ rulesetrule_t rulesetrules_strict[] = {
{"ruleset_allow_overlong_sounds", "0"},
{"ruleset_allow_larger_models", "0"},
{"ruleset_allow_modified_eyes", "0"},
{"ruleset_allow_sensative_texture_replacements", "0"},
{"ruleset_allow_sensitive_texture_replacements", "0"},
{"ruleset_allow_localvolume", "0"},
{"ruleset_allow_fbmodels", "0"},
{"tp_disputablemacros", "0"},
@ -397,7 +393,7 @@ rulesetrule_t rulesetrules_nqr[] = {
{"ruleset_allow_packet", "0"},
{"ruleset_allow_frj", "0"},
{"ruleset_allow_modified_eyes", "0"},
{"ruleset_allow_sensative_texture_replacements", "0"},
{"ruleset_allow_sensitive_texture_replacements", "0"},
{"ruleset_allow_localvolume", "0"},
{"ruleset_allow_shaders", "0"},
{"ruleset_allow_fbmodels", "0"},

View File

@ -33,6 +33,7 @@ typedef struct {
int height;
qboolean fullscreen;
qboolean stereo;
qboolean srgb;
int bpp;
int rate;
int wait; //-1 = default, 0 = off, 1 = on, 2 = every other

View File

@ -290,6 +290,7 @@ void V_DriftPitch (playerview_t *pv)
==============================================================================
*/
void V_Gamma_Callback(struct cvar_s *var, char *oldvalue);
cshift_t cshift_empty = { {130,80,50}, 0 };
cshift_t cshift_water = { {130,80,50}, 128 };
@ -298,9 +299,9 @@ cshift_t cshift_lava = { {255,80,0}, 150 };
cshift_t cshift_server = { {130,80,50}, 0 };
cvar_t v_gamma = CVARFD("gamma", "1.0", CVAR_ARCHIVE|CVAR_RENDERERCALLBACK, "Controls how bright the screen is. Setting this to anything but 1 without hardware gamma requires glsl support and can noticably harm your framerate.");
cvar_t v_contrast = CVARFD("contrast", "1.0", CVAR_ARCHIVE, "Scales colour values linearly to make your screen easier to see. Setting this to anything but 1 without hardware gamma will reduce your framerates a little.");
cvar_t v_brightness = CVARFD("brightness", "0.0", CVAR_ARCHIVE, "Brightness is how much 'white' to add to each and every pixel on the screen.");
cvar_t v_gamma = CVARFDC("gamma", "1.0", CVAR_ARCHIVE|CVAR_RENDERERCALLBACK, "Controls how bright the screen is. Setting this to anything but 1 without hardware gamma requires glsl support and can noticably harm your framerate.", V_Gamma_Callback);
cvar_t v_contrast = CVARFDC("contrast", "1.0", CVAR_ARCHIVE, "Scales colour values linearly to make your screen easier to see. Setting this to anything but 1 without hardware gamma will reduce your framerates a little.", V_Gamma_Callback);
cvar_t v_brightness = CVARFDC("brightness", "0.0", CVAR_ARCHIVE, "Brightness is how much 'white' to add to each and every pixel on the screen.", V_Gamma_Callback);
qbyte gammatable[256]; // palette is sent through this
@ -362,13 +363,11 @@ void BuildGammaTable (float g, float c, float b)
V_CheckGamma
=================
*/
#if defined(GLQUAKE) || defined(D3DQUAKE)
void GLV_Gamma_Callback(struct cvar_s *var, char *oldvalue)
void V_Gamma_Callback(struct cvar_s *var, char *oldvalue)
{
BuildGammaTable (v_gamma.value, v_contrast.value, v_brightness.value);
V_UpdatePalette (true);
}
#endif
/*
===============
@ -758,10 +757,13 @@ void V_UpdatePalette (qboolean force)
ramps[2][i] = gammatable[ib]<<8;
}
applied = rf->VID_ApplyGammaRamps ((unsigned short*)ramps);
if (!applied && r2d_canhwgamma)
rf->VID_ApplyGammaRamps (NULL);
r2d_canhwgamma = applied;
if (qrenderer)
{
applied = rf->VID_ApplyGammaRamps ((unsigned short*)ramps);
if (!applied && r2d_canhwgamma)
rf->VID_ApplyGammaRamps (NULL);
r2d_canhwgamma = applied;
}
}
RSpeedEnd(RSPEED_PALETTEFLASHES);
@ -1225,8 +1227,8 @@ void V_CalcRefdef (playerview_t *pv)
return;
#endif
VectorCopy(cl.fog_colour, r_refdef.gfog_rgbd);
r_refdef.gfog_rgbd[3] = cl.fog_density / 64;
CL_BlendFog(&r_refdef.globalfog, &cl.oldfog, realtime, &cl.fog);
r_refdef.globalfog.density /= 64; //FIXME
if (v_viewheight.value < -7)
bob=-7;
@ -1628,14 +1630,14 @@ void V_RenderView (void)
}
else
{
if (r_worldentity.model)
if (r_worldentity.model && !r_worldentity.model->needload)
{
RSpeedMark();
CL_AllowIndependantSendCmd(false);
CL_SetSolidEntities ();
CL_TransitionEntities();
CL_PredictMove ();
// build a refresh entity list

View File

@ -424,7 +424,7 @@ qbyte *W_ConvertWAD3Texture(miptex_t *tex, int *width, int *height, qboolean *us
return data;
}
qbyte *W_GetTexture(char *name, int *width, int *height, qboolean *usesalpha)//returns rgba
qbyte *W_GetTexture(const char *name, int *width, int *height, qboolean *usesalpha)//returns rgba
{
char texname[17];
int i, j;

View File

@ -115,4 +115,4 @@ void Mod_ParseWadsFromEntityLump(char *data);
qbyte *W_ConvertWAD3Texture(miptex_t *tex, int *width, int *height, qboolean *usesalpha);
void Mod_ParseInfoFromEntityLump(struct model_s *wmodel, char *data, char *mapname);
qboolean Wad_NextDownload (void);
qbyte *W_GetTexture(char *name, int *width, int *height, qboolean *usesalpha);
qbyte *W_GetTexture(const char *name, int *width, int *height, qboolean *usesalpha);

View File

@ -41,6 +41,14 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define _LPCWAVEFORMATEX_DEFINED
#if defined(WINAPI_FAMILY) && !defined(WINRT)
#if WINAPI_FAMILY != WINAPI_FAMILY_DESKTOP_APP
//don't just define it. things that don't #include winquake.h / glquake.h need it too.
#error "WINRT needs to be defined for non-desktop"
#endif
#endif
#ifndef WM_MOUSEWHEEL
#define WM_MOUSEWHEEL 0x020A
#endif
@ -96,7 +104,7 @@ void S_BlockSound (void);
void S_UnblockSound (void);
void VID_SetDefaultMode (void);
/*
int (PASCAL FAR *pWSAStartup)(WORD wVersionRequired, LPWSADATA lpWSAData);
int (PASCAL FAR *pWSACleanup)(void);
int (PASCAL FAR *pWSAGetLastError)(void);
@ -115,6 +123,7 @@ struct hostent FAR * (PASCAL FAR *pgethostbyaddr)(const char FAR * addr,
int len, int type);
int (PASCAL FAR *pgetsockname)(SOCKET s, struct sockaddr FAR *name,
int FAR * namelen);
*/
#endif
#endif

View File

@ -1051,7 +1051,9 @@ char *Macro_CombinedHealth(void)
//work out the max useful armour
//this will under-exagurate, due to usage of ceil based on damage
m = h/(1-t);
if (a > m && m > 0)
if (m < 0)
a = 0;
else if (m < a)
a = m;
h = h + a;

View File

@ -106,7 +106,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define AVAIL_D3D
#endif
#if defined(_WIN32) && !defined(FTE_SDL)
#if defined(_WIN32) && !defined(FTE_SDL) && !defined(WINRT)
#define HAVE_WINSSPI //built in component, checks against windows' root ca database and revocations etc.
#elif defined(__linux__) || defined(__CYGWIN__)
#define HAVE_GNUTLS //currently disabled as it does not validate the server's certificate, beware the mitm attack.
@ -188,6 +188,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifdef SERVERONLY
#define USE_MYSQL //allow mysql in dedicated servers.
#endif
#if defined(_WIN32) && !defined(FTE_SDL) && !defined(WINRT)
//#define SUBSERVERS //use subserver code.
#endif
#define SIDEVIEWS 4 //enable secondary/reverse views.
@ -234,6 +237,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#endif
#define VM_Q1 //q1 qvm gamecode interface
//#define VM_LUA //q1 lua gamecode interface
#define TCPCONNECT //a tcpconnect command, that allows the player to connect to tcp-encapsulated qw protocols.
#define IRCCONNECT //an ircconnect command, that allows the player to connect to irc-encapsulated qw protocols... yeah, really.
@ -289,6 +293,17 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#undef Q3CLIENT
#undef Q3SERVER //trying to trim memory use
#endif
#ifdef WINRT
#undef TCPCONNECT //err...
#undef IRCCONNECT //not happening
#undef AVAIL_DSOUND //yeah, good luck there
#undef AVAIL_DINPUT //nope, not supported.
#undef SV_MASTER //no socket interface
#undef CL_MASTER //no socket interface
#undef WEBSERVER //http/ftp servers
#undef WEBCLIENT //http/ftp clients.
#undef MULTITHREAD
#endif
#ifdef ANDROID
#undef RTLIGHTS
#ifndef SPEEX_STATIC
@ -350,7 +365,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#endif
#ifndef AVAIL_ZLIB
#undef SUPPORT_ICE
#undef SUPPORT_ICE //depends upon zlib's crc32 for fingerprinting. I cba writing my own.
#endif
#ifdef SERVERONLY //remove options that don't make sense on only a server
@ -484,12 +499,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define ARCH_CPU_POSTFIX "unk"
#endif
#if (defined(_M_IX86) || defined(__i386__)) && !defined(__amd64__) && !defined(_AMD64_)
#define UNALIGNED_OK 1 // set to 0 if unaligned accesses are not supported
#else
#define UNALIGNED_OK 0
#endif
#ifdef _MSC_VER
#define VARGS __cdecl
#define MSVCDISABLEWARNINGS
@ -512,7 +521,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define NORETURN __attribute__((noreturn))
#endif
//I'm making my own restrict, because msvc can't cope if I #define restrict to __restrict, and quite possibly other platforms too
//I'm making my own restrict, because msvc's headers can't cope if I #define restrict to __restrict, and quite possibly other platforms too
#if __STDC_VERSION__ >= 199901L
#define fte_restrict restrict
#elif defined(_MSC_VER)

View File

@ -895,7 +895,7 @@ typedef struct pvscache_s
{
int num_leafs;
short leafnums[MAX_ENT_LEAFS];
#ifdef Q2BSPS
#if defined(Q2BSPS) || defined(TERRAIN)
int areanum; //q2bsp
int areanum2; //q2bsp
int headnode; //q2bsp

View File

@ -45,10 +45,10 @@ typedef struct cmdalias_s
cmdalias_t *cmd_alias;
cvar_t cl_warncmd = SCVAR("cl_warncmd", "1");
cvar_t cl_aliasoverlap = SCVARF("cl_aliasoverlap", "1", CVAR_NOTFROMSERVER);
cvar_t cl_warncmd = CVARF("cl_warncmd", "1", CVAR_NOSAVE|CVAR_NORESET);
cvar_t cl_aliasoverlap = CVARF("cl_aliasoverlap", "1", CVAR_NOTFROMSERVER);
cvar_t tp_disputablemacros = SCVARF("tp_disputablemacros", "1", CVAR_SEMICHEAT);
cvar_t tp_disputablemacros = CVARF("tp_disputablemacros", "1", CVAR_SEMICHEAT);
//=============================================================================
@ -843,7 +843,7 @@ void Cmd_DeleteAlias(char *name)
}
}
char *Cmd_AliasExist(char *name, int restrictionlevel)
char *Cmd_AliasExist(const char *name, int restrictionlevel)
{
cmdalias_t *a;
// if the alias already exists, reuse it
@ -1061,7 +1061,7 @@ char *VARGS Cmd_Args (void)
return cmd_args;
}
void Cmd_Args_Set(char *newargs)
void Cmd_Args_Set(const char *newargs)
{
if (cmd_args_buf)
Z_Free(cmd_args_buf);
@ -1365,7 +1365,7 @@ Cmd_TokenizeString
Parses the given string into command line tokens, stopping at the \n
============
*/
char *Cmd_TokenizeString (char *text, qboolean expandmacros, qboolean qctokenize)
const char *Cmd_TokenizeString (const char *text, qboolean expandmacros, qboolean qctokenize)
{
int i;
@ -1668,7 +1668,7 @@ int Cmd_Level(char *name)
Cmd_Exists
============
*/
qboolean Cmd_Exists (char *cmd_name)
qboolean Cmd_Exists (const char *cmd_name)
{
cmd_function_t *cmd;
@ -2862,8 +2862,8 @@ void Cmd_WriteConfig_f(void)
snprintf(fname, sizeof(fname), "configs/%s", filename);
COM_DefaultExtension(fname, ".cfg", sizeof(fname));
FS_CreatePath(fname, FS_CONFIGONLY);
f = FS_OpenVFS(fname, "wb", FS_CONFIGONLY);
FS_CreatePath(fname, FS_BASEGAMEONLY);
f = FS_OpenVFS(fname, "wb", FS_BASEGAMEONLY);
}
if (!f)
{

View File

@ -86,7 +86,7 @@ qboolean Cmd_AddCommandD (char *cmd_name, xcommand_t function, char *description
// if function is NULL, the command will be forwarded to the server
// as a clc_stringcmd instead of executed locally
qboolean Cmd_Exists (char *cmd_name);
qboolean Cmd_Exists (const char *cmd_name);
// used by the cvar code to check for cvar / command name overlap
char *Cmd_Describe (char *cmd_name);
@ -115,19 +115,19 @@ int Cmd_CheckParm (char *parm);
// Returns the position (1 to argc-1) in the command's argument list
// where the given parameter apears, or 0 if not present
char *Cmd_AliasExist(char *name, int restrictionlevel);
char *Cmd_AliasExist(const char *name, int restrictionlevel);
void Alias_WipeStuffedAliases(void);
void Cmd_AddMacro(char *s, char *(*f)(void), int disputableintentions);
void Cmd_TokenizePunctation (char *text, char *punctuation);
char *Cmd_TokenizeString (char *text, qboolean expandmacros, qboolean qctokenize);
const char *Cmd_TokenizeString (const char *text, qboolean expandmacros, qboolean qctokenize);
// Takes a null terminated string. Does not need to be /n terminated.
// breaks the string up into arg tokens.
void Cmd_ExecuteString (char *text, int restrictionlevel);
void Cmd_Args_Set(char *newargs);
void Cmd_Args_Set(const char *newargs);
#define RESTRICT_MAX_TOTAL 31
#define RESTRICT_MAX_USER 29 //1-64 it's all about bit size. This is max settable. servers are +1 or +2

File diff suppressed because it is too large Load Diff

View File

@ -6,8 +6,8 @@
#include <stdlib.h>
#endif
int HLMod_BoneForName(model_t *mod, char *name);
int HLMod_FrameForName(model_t *mod, char *name);
int HLMod_BoneForName(model_t *mod, const char *name);
int HLMod_FrameForName(model_t *mod, const char *name);
//a single pose within an animation (note: always refered to via a framegroup, even if there's only one frame in that group).
typedef struct
@ -32,14 +32,14 @@ typedef struct
typedef struct
{
#ifdef SKELETALMODELS
qboolean isheirachical; //for models with transforms, states that bones need to be transformed from their parent.
skeltype_t skeltype; //for models with transforms, states that bones need to be transformed from their parent.
//this is actually bad, and can result in bones shortening as they interpolate.
float *boneofs; //numposes*12*numbones
#endif
qboolean loop;
int numposes;
float rate;
galiaspose_t *poseofs;
float *boneofs; //numposes*12*numbones
char name[64];
} galiasgroup_t;
@ -52,8 +52,9 @@ struct galiasbone_s
float inverse[12];
};
typedef struct
typedef struct FTE_DEPRECATED
{
//DEPRECATED
//skeletal poses refer to this.
int vertexindex;
int boneindex;
@ -100,6 +101,9 @@ typedef struct
typedef struct galiasinfo_s
{
char surfacename[MAX_QPATH];
unsigned short geomset;
unsigned short geomid;
index_t *ofs_indexes;
int numindexes;
@ -118,6 +122,8 @@ typedef struct galiasinfo_s
#ifndef SERVERONLY
vec2_t *ofs_st_array;
vec4_t *ofs_rgbaf;
byte_vec4_t *ofs_rgbaub;
#endif
int groups;
@ -148,6 +154,7 @@ typedef struct galiasinfo_s
#endif
vboarray_t vboindicies;
vboarray_t vbotexcoords;
vboarray_t vborgba; //yeah, just you try reading THAT as an actual word.
//these exist only in the root mesh.
int numtagframes;
@ -155,9 +162,29 @@ typedef struct galiasinfo_s
md3tag_t *ofstags;
} galiasinfo_t;
float *Alias_GetBonePositions(galiasinfo_t *inf, framestate_t *fstate, float *buffer, int buffersize, qboolean renderable);
typedef struct
{
int (*RegisterModelFormatText)(void *module, const char *formatname, char *magictext, qboolean (QDECL *load) (struct model_s *mod, void *buffer, size_t fsize));
int (*RegisterModelFormatMagic)(void *module, const char *formatname, unsigned int magic, qboolean (QDECL *load) (struct model_s *mod, void *buffer, size_t fsize));
void (*UnRegisterModelFormat)(int idx);
void (*UnRegisterAllModelFormats)(void *module);
void *(*ZG_Malloc)(zonegroup_t *ctx, int size);
void (*ConcatTransforms) (float in1[3][4], float in2[3][4], float out[3][4]);
void (*M3x4_Invert) (const float *in1, float *out);
void (*StripExtension) (const char *in, char *out, int outlen);
void (*GenMatrixPosQuat4Scale)(vec3_t pos, vec4_t quat, vec3_t scale, float result[12]);
void (*ForceConvertBoneData)(skeltype_t sourcetype, const float *sourcedata, size_t bonecount, galiasbone_t *bones, skeltype_t desttype, float *destbuffer, size_t destbonecount);
shader_t *(*RegisterShader) (const char *name, unsigned int usageflags, const char *shaderscript);
shader_t *(*RegisterSkin) (const char *shadername, const char *modname);
void (*BuildDefaultTexnums)(texnums_t *tn, shader_t *shader);
} modplugfuncs_t;
#ifdef SKELETALMODELS
void Alias_TransformVerticies(float *bonepose, galisskeletaltransforms_t *weights, int numweights, vecV_t *xyzout, vec3_t *normout);
void Alias_ForceConvertBoneData(skeltype_t sourcetype, const float *sourcedata, size_t bonecount, galiasbone_t *bones, skeltype_t desttype, float *destbuffer, size_t destbonecount);
#endif
qboolean Alias_GAliasBuildMesh(mesh_t *mesh, vbo_t **vbop, galiasinfo_t *inf, int surfnum, entity_t *e, qboolean allowskel);
void Alias_FlushCache(void);
@ -166,7 +193,7 @@ void Alias_Register(void);
void Mod_DoCRC(model_t *mod, char *buffer, int buffersize);
qboolean QDECL Mod_LoadHLModel (model_t *mod, void *buffer);
qboolean QDECL Mod_LoadHLModel (model_t *mod, void *buffer, size_t fsize);
#ifdef MAP_PROC
qboolean Mod_LoadMap_Proc(model_t *mode, void *buffer);
#endif

View File

@ -1673,7 +1673,7 @@ static void World_ODE_Frame_JointFromEntity(world_t *world, wedict_t *ed)
}
}
static qboolean GenerateCollisionMesh(world_t *world, model_t *mod, wedict_t *ed, vec3_t geomcenter)
static qboolean GenerateCollisionMesh_BSP(world_t *world, model_t *mod, wedict_t *ed, vec3_t geomcenter)
{
unsigned int sno;
msurface_t *surf;
@ -1770,6 +1770,81 @@ static qboolean GenerateCollisionMesh(world_t *world, model_t *mod, wedict_t *ed
return true;
}
#include "com_mesh.h"
static qboolean GenerateCollisionMesh_Alias(world_t *world, model_t *mod, wedict_t *ed, vec3_t geomcenter)
{
mesh_t mesh;
unsigned int numverts;
unsigned int numindexes,i;
galiasinfo_t *inf;
unsigned int surfnum = 0;
entity_t re;
numverts = 0;
numindexes = 0;
//fill in the parts of the entity_t that Alias_GAliasBuildMesh needs.
world->Get_FrameState(world, ed, &re.framestate);
re.fatness = ed->xv->fatness;
re.model = mod;
inf = Mod_Extradata (mod);
while(inf)
{
numverts += inf->numverts;
numindexes += inf->numindexes;
inf = inf->nextsurf;
}
if (!numindexes)
{
Con_DPrintf("entity %i (classname %s) has no geometry\n", NUM_FOR_EDICT(world->progs, (edict_t*)ed), PR_GetString(world->progs, ed->v->classname));
return false;
}
ed->ode.ode_element3i = BZ_Malloc(numindexes*sizeof(*ed->ode.ode_element3i));
ed->ode.ode_vertex3f = BZ_Malloc(numverts*sizeof(vec3_t));
numverts = 0;
numindexes = 0;
inf = Mod_Extradata (mod);
while(inf)
{
Alias_GAliasBuildMesh(&mesh, NULL, inf, surfnum++, &re, false);
for (i = 0; i < mesh.numvertexes; i++)
VectorSubtract(mesh.xyz_array[i], geomcenter, (ed->ode.ode_vertex3f + 3*(numverts+i)));
for (i = 0; i < mesh.numindexes; i+=3)
{
//flip the triangles as we go
ed->ode.ode_element3i[numindexes+i+0] = numverts+mesh.indexes[i+2];
ed->ode.ode_element3i[numindexes+i+1] = numverts+mesh.indexes[i+1];
ed->ode.ode_element3i[numindexes+i+2] = numverts+mesh.indexes[i+0];
}
numverts += inf->numverts;
numindexes += inf->numindexes;
inf = inf->nextsurf;
}
Alias_FlushCache(); //it got built using an entity on the stack, make sure other stuff doesn't get hurt.
ed->ode.ode_numvertices = numverts;
ed->ode.ode_numtriangles = numindexes/3;
return true;
}
static qboolean GenerateCollisionMesh(world_t *world, model_t *mod, wedict_t *ed, vec3_t geomcenter)
{
switch(mod->type)
{
case mod_brush:
return GenerateCollisionMesh_BSP(world, mod, ed, geomcenter);
case mod_alias:
return GenerateCollisionMesh_Alias(world, mod, ed, geomcenter);
default:
return false; //panic!
}
}
qboolean World_ODE_RagMatrixToBody(odebody_t *bodyptr, float *mat)
{
dVector3 r[3];
@ -2070,7 +2145,6 @@ static void World_ODE_Frame_BodyFromEntity(world_t *world, wedict_t *ed)
dMass mass;
float test;
void *dataID;
dVector3 capsulerot[3];
model_t *model;
int axisindex;
int modelindex = 0;
@ -2146,6 +2220,13 @@ static void World_ODE_Frame_BodyFromEntity(world_t *world, wedict_t *ed)
case GEOMTYPE_BOX:
case GEOMTYPE_SPHERE:
case GEOMTYPE_CAPSULE:
case GEOMTYPE_CAPSULE_X:
case GEOMTYPE_CAPSULE_Y:
case GEOMTYPE_CAPSULE_Z:
case GEOMTYPE_CYLINDER:
case GEOMTYPE_CYLINDER_X:
case GEOMTYPE_CYLINDER_Y:
case GEOMTYPE_CYLINDER_Z:
VectorCopy(ed->v->mins, entmins);
VectorCopy(ed->v->maxs, entmaxs);
if (ed->xv->mass)
@ -2232,30 +2313,95 @@ static void World_ODE_Frame_BodyFromEntity(world_t *world, wedict_t *ed)
dMassSetSphereTotal(&mass, massval, geomsize[0] * 0.5f);
break;
case GEOMTYPE_CAPSULE:
axisindex = 0;
if (geomsize[axisindex] < geomsize[1])
axisindex = 1;
if (geomsize[axisindex] < geomsize[2])
axisindex = 2;
case GEOMTYPE_CAPSULE_X:
case GEOMTYPE_CAPSULE_Y:
case GEOMTYPE_CAPSULE_Z:
if (geomtype == GEOMTYPE_CAPSULE)
{
axisindex = 0;
if (geomsize[axisindex] < geomsize[1])
axisindex = 1;
if (geomsize[axisindex] < geomsize[2])
axisindex = 2;
}
else
axisindex = geomtype-GEOMTYPE_CAPSULE_X;
// the qc gives us 3 axis radius, the longest axis is the capsule
// axis, since ODE doesn't like this idea we have to create a
// capsule which uses the standard orientation, and apply a
// transform to it
memset(capsulerot, 0, sizeof(capsulerot));
if (axisindex == 0)
{
Matrix4x4_CM_ModelMatrix(ed->ode.ode_offsetmatrix, geomcenter[0], geomcenter[1], geomcenter[2], 0, 0, 90, 1);
radius = min(geomsize[1], geomsize[2]) * 0.5f;
}
else if (axisindex == 1)
{
Matrix4x4_CM_ModelMatrix(ed->ode.ode_offsetmatrix, geomcenter[0], geomcenter[1], geomcenter[2], 90, 0, 0, 1);
radius = min(geomsize[0], geomsize[2]) * 0.5f;
}
else
{
Matrix4x4_CM_ModelMatrix(ed->ode.ode_offsetmatrix, geomcenter[0], geomcenter[1], geomcenter[2], 0, 0, 0, 1);
radius = geomsize[!axisindex] * 0.5f; // any other axis is the radius
radius = min(geomsize[0], geomsize[1]) * 0.5f;
}
length = geomsize[axisindex] - radius*2;
if (length <= 0)
{
radius -= (1 - length)*0.5;
length = 1;
}
// because we want to support more than one axisindex, we have to
// create a transform, and turn on its cleanup setting (which will
// cause the child to be destroyed when it is destroyed)
ed->ode.ode_geom = (void *)dCreateCapsule(world->ode.ode_space, radius, length);
dMassSetCapsuleTotal(&mass, massval, axisindex+1, radius, length);
break;
case GEOMTYPE_CYLINDER:
case GEOMTYPE_CYLINDER_X:
case GEOMTYPE_CYLINDER_Y:
case GEOMTYPE_CYLINDER_Z:
if (geomtype == GEOMTYPE_CYLINDER)
{
axisindex = 0;
if (geomsize[axisindex] < geomsize[1])
axisindex = 1;
if (geomsize[axisindex] < geomsize[2])
axisindex = 2;
}
else
axisindex = geomtype-GEOMTYPE_CYLINDER_X;
// the qc gives us 3 axis radius, the longest axis is the capsule
// axis, since ODE doesn't like this idea we have to create a
// capsule which uses the standard orientation, and apply a
// transform to it
if (axisindex == 0)
{
Matrix4x4_CM_ModelMatrix(ed->ode.ode_offsetmatrix, geomcenter[0], geomcenter[1], geomcenter[2], 0, 0, 90, 1);
radius = min(geomsize[1], geomsize[2]) * 0.5f;
}
else if (axisindex == 1)
{
Matrix4x4_CM_ModelMatrix(ed->ode.ode_offsetmatrix, geomcenter[0], geomcenter[1], geomcenter[2], 90, 0, 0, 1);
radius = min(geomsize[0], geomsize[2]) * 0.5f;
}
else
{
Matrix4x4_CM_ModelMatrix(ed->ode.ode_offsetmatrix, geomcenter[0], geomcenter[1], geomcenter[2], 0, 0, 0, 1);
radius = min(geomsize[0], geomsize[1]) * 0.5f;
}
length = geomsize[axisindex] - radius*2;
if (length <= 0)
{
radius -= (1 - length)*0.5;
length = 1;
}
// because we want to support more than one axisindex, we have to
// create a transform, and turn on its cleanup setting (which will
// cause the child to be destroyed when it is destroyed)
ed->ode.ode_geom = (void *)dCreateCylinder(world->ode.ode_space, radius, length);
dMassSetCylinderTotal(&mass, massval, axisindex+1, radius, length);
break;
default:
Sys_Error("World_ODE_BodyFromEntity: unrecognized solid value %i was accepted by filter\n", solid);
}

View File

@ -648,10 +648,10 @@ float Q_atof (const char *str)
attempts to remove leet strange chars from a name
the resulting string is not intended to be visible to humans, but this functions results can be matched against each other.
*/
void deleetstring(char *result, char *leet)
void deleetstring(char *result, const char *leet)
{
char *s = result;
char *s2 = leet;
const char *s2 = leet;
while(*s2)
{
if (*s2 == (char)0xff)
@ -1434,6 +1434,24 @@ float MSG_ReadFloat (void)
return dat.f;
}
char *MSG_ReadStringBuffer (char *out, size_t outsize)
{
int l,c;
l = 0;
do
{
c = MSG_ReadChar ();
if (msg_badread || c == 0)
break;
out[l] = c;
l++;
} while (l < outsize-1);
out[l] = 0;
return out;
}
char *MSG_ReadString (void)
{
static char string[8192];
@ -2299,14 +2317,14 @@ unsigned int unicode_encode(char *out, unsigned int unicode, int maxlen, qboolea
}
//char-based strlen.
unsigned int unicode_charcount(char *in, size_t buffersize, qboolean markup)
unsigned int unicode_charcount(const char *in, size_t buffersize, qboolean markup)
{
int error;
char *end = in + buffersize;
const char *end = in + buffersize;
int chars = 0;
for(chars = 0; in < end && *in; chars+=1)
{
unicode_decode(&error, in, &in, markup);
unicode_decode(&error, in, (char**)&in, markup);
if (in > end)
break; //exceeded buffer size uncleanly
@ -2315,9 +2333,9 @@ unsigned int unicode_charcount(char *in, size_t buffersize, qboolean markup)
}
//handy hacky function.
unsigned int unicode_byteofsfromcharofs(char *str, unsigned int charofs, qboolean markup)
unsigned int unicode_byteofsfromcharofs(const char *str, unsigned int charofs, qboolean markup)
{
char *in = str;
const char *in = str;
int error;
int chars;
for(chars = 0; *in; chars+=1)
@ -2325,19 +2343,19 @@ unsigned int unicode_byteofsfromcharofs(char *str, unsigned int charofs, qboolea
if (chars >= charofs)
return in - str;
unicode_decode(&error, in, &in, markup);
unicode_decode(&error, in, (char**)&in, markup);
}
return in - str;
}
//handy hacky function.
unsigned int unicode_charofsfrombyteofs(char *str, unsigned int byteofs, qboolean markup)
unsigned int unicode_charofsfrombyteofs(const char *str, unsigned int byteofs, qboolean markup)
{
int error;
char *end = str + byteofs;
const char *end = str + byteofs;
int chars = 0;
for(chars = 0; str < end && *str; chars+=1)
{
unicode_decode(&error, str, &str, markup);
unicode_decode(&error, str, (char**)&str, markup);
if (str > end)
break; //exceeded buffer size uncleanly
@ -2363,7 +2381,7 @@ int towlower(int c)
}
#endif
size_t unicode_strtoupper(char *in, char *out, size_t outsize, qboolean markup)
size_t unicode_strtoupper(const char *in, char *out, size_t outsize, qboolean markup)
{
//warning: towupper is locale-specific (eg: turkish has both I and dotted-I and thus i should transform to dotted-I rather than to I).
//also it can't easily cope with accent prefixes.
@ -2374,7 +2392,7 @@ size_t unicode_strtoupper(char *in, char *out, size_t outsize, qboolean markup)
while(*in)
{
c = unicode_decode(&error, in, &in, markup);
c = unicode_decode(&error, in, (char**)&in, markup);
if (c >= 0xe020 && c <= 0xe07f) //quake-char-aware.
c = towupper(c & 0x7f) + (c & 0xff80);
else
@ -2387,7 +2405,7 @@ size_t unicode_strtoupper(char *in, char *out, size_t outsize, qboolean markup)
return l;
}
size_t unicode_strtolower(char *in, char *out, size_t outsize, qboolean markup)
size_t unicode_strtolower(const char *in, char *out, size_t outsize, qboolean markup)
{
//warning: towlower is locale-specific (eg: turkish has both i and dotless-i and thus I should transform to dotless-i rather than to i).
//also it can't easily cope with accent prefixes.
@ -2398,7 +2416,7 @@ size_t unicode_strtolower(char *in, char *out, size_t outsize, qboolean markup)
while(*in)
{
c = unicode_decode(&error, in, &in, markup);
c = unicode_decode(&error, in, (char**)&in, markup);
if (c >= 0xe020 && c <= 0xe07f) //quake-char-aware.
c = towlower(c & 0x7f) + (c & 0xff80);
else
@ -2976,6 +2994,30 @@ conchar_t *COM_ParseFunString(conchar_t defaultflags, const char *str, conchar_t
}
continue;
}
else if (str[0] == '=' && str[1] == '`' && str[2] == 'u' && str[3] == '8' && str[4] == ':' && !keepmarkup)
{
int l;
char temp[1024];
str += 5;
while(*str)
{
l = 0;
while (*str && l < sizeof(temp)-32 && !(str[0] == '`' && str[1] == '='))
temp[l++] = *str++;
//recurse
temp[l] = 0;
l = COM_ParseFunString(ext, temp, out, outsize, PFS_FORCEUTF8) - out;
outsize -= l;
out += l;
if (str[0] == '`' && str[1] == '=')
{
str+=2;
break;
}
}
continue;
}
/*
else if ((str[0] == 'h' && str[1] == 't' && str[2] == 't' && str[3] == 'p' && str[4] == ':' && !linkstart && !(flags & (PFS_NOMARKUP|PFS_KEEPMARKUP))) ||
(str[0] == 'h' && str[1] == 't' && str[2] == 't' && str[3] == 'p' && str[4] == 's' && str[5] == ':' && !linkstart && !(flags & (PFS_NOMARKUP|PFS_KEEPMARKUP))))
@ -4341,6 +4383,7 @@ int memsearch (qbyte *start, int count, int search)
return -1;
}
/*
struct effectinfo_s
{
struct effectinfo_s *next;
@ -4486,7 +4529,7 @@ char *COM_Effectinfo_ForNumber(unsigned int efnum)
}
return "";
}
*/
/*************************************************************************/
/*remaps map checksums from known non-cheat GPL maps to authentic id1 maps*/
@ -4569,7 +4612,7 @@ Searches the string for the given
key and returns the associated value, or an empty string.
===============
*/
char *Info_ValueForKey (char *s, const char *key)
char *Info_ValueForKey (const char *s, const char *key)
{
char pkey[1024];
static char value[4][1024]; // use two buffers so compares

View File

@ -195,6 +195,7 @@ struct client_s;
unsigned int MSGSV_ReadEntity (struct client_s *fromclient);
unsigned int MSGCL_ReadEntity (void);
float MSG_ReadFloat (void);
char *MSG_ReadStringBuffer (char *out, size_t outsize);
char *MSG_ReadString (void);
char *MSG_ReadStringLine (void);
@ -256,7 +257,7 @@ int Q_strncasecmp (const char *s1, const char *s2, int n);
int Q_strcasecmp (const char *s1, const char *s2);
int Q_atoi (const char *str);
float Q_atof (const char *str);
void deleetstring(char *result, char *leet);
void deleetstring(char *result, const char *leet);
//============================================================================
@ -303,14 +304,17 @@ unsigned int iso88591_encode(char *out, unsigned int unicode, int maxlen, qboole
unsigned int qchar_encode(char *out, unsigned int unicode, int maxlen, qboolean markup);
unsigned int COM_DeQuake(conchar_t chr);
//small macro to tell COM_ParseFunString (and related functions like con_printf) that the input is a utf-8 string.
#define U8(s) "=`u8:"s"`="
//handles whatever charset is active, including ^U stuff.
unsigned int unicode_byteofsfromcharofs(char *str, unsigned int charofs, qboolean markup);
unsigned int unicode_charofsfrombyteofs(char *str, unsigned int byteofs, qboolean markup);
unsigned int unicode_byteofsfromcharofs(const char *str, unsigned int charofs, qboolean markup);
unsigned int unicode_charofsfrombyteofs(const char *str, unsigned int byteofs, qboolean markup);
unsigned int unicode_encode(char *out, unsigned int unicode, int maxlen, qboolean markup);
unsigned int unicode_decode(int *error, const void *in, char **out, qboolean markup);
size_t unicode_strtolower(char *in, char *out, size_t outsize, qboolean markup);
size_t unicode_strtoupper(char *in, char *out, size_t outsize, qboolean markup);
unsigned int unicode_charcount(char *in, size_t buffersize, qboolean markup);
size_t unicode_strtolower(const char *in, char *out, size_t outsize, qboolean markup);
size_t unicode_strtoupper(const char *in, char *out, size_t outsize, qboolean markup);
unsigned int unicode_charcount(const char *in, size_t buffersize, qboolean markup);
char *COM_SkipPath (const char *pathname);
void COM_StripExtension (const char *in, char *out, int outlen);
@ -331,8 +335,8 @@ extern int com_filesize;
extern qboolean com_file_untrusted;
struct cache_user_s;
extern char com_quakedir[MAX_OSPATH];
extern char com_homedir[MAX_OSPATH];
extern char com_gamepath[MAX_OSPATH];
extern char com_homepath[MAX_OSPATH];
extern char com_configdir[MAX_OSPATH]; //dir to put cfg_save configs in
//extern char *com_basedir;
@ -342,7 +346,7 @@ void COM_WriteFile (const char *filename, const void *data, int len);
#if defined(__amd64__) || defined(_AMD64_) || __WORDSIZE == 64
#define FS_64BIT
#endif
#ifdef FS_64BIT
#if 1//def FS_64BIT
typedef unsigned long long qofs_t; //type to use for a file offset
#define qofs_Make(low,high) (low | (((qofs_t)(high))<<32))
#define qofs_Low(o) ((o)&0xffffffffu)
@ -397,7 +401,7 @@ typedef struct vfsfile_s
qboolean (QDECL *Seek) (struct vfsfile_s *file, qofs_t pos); //returns false for error
qofs_t (QDECL *Tell) (struct vfsfile_s *file);
qofs_t (QDECL *GetLen) (struct vfsfile_s *file); //could give some lag
void (QDECL *Close) (struct vfsfile_s *file);
qboolean (QDECL *Close) (struct vfsfile_s *file); //returns false if there was some error.
void (QDECL *Flush) (struct vfsfile_s *file);
qboolean seekingisabadplan;
@ -407,25 +411,26 @@ typedef struct vfsfile_s
} vfsfile_t;
typedef struct searchpathfuncs_s searchpathfuncs_t;
#define VFS_CLOSE(vf) (vf->Close(vf))
#define VFS_TELL(vf) (vf->Tell(vf))
#define VFS_GETLEN(vf) (vf->GetLen(vf))
#define VFS_SEEK(vf,pos) (vf->Seek(vf,pos))
#define VFS_READ(vf,buffer,buflen) (vf->ReadBytes(vf,buffer,buflen))
#define VFS_WRITE(vf,buffer,buflen) (vf->WriteBytes(vf,buffer,buflen))
#define VFS_FLUSH(vf) do{if(vf->Flush)vf->Flush(vf);}while(0)
#define VFS_PUTS(vf,s) do{const char *t=s;vf->WriteBytes(vf,t,strlen(t));}while(0)
#define VFS_CLOSE(vf) ((vf)->Close(vf))
#define VFS_TELL(vf) ((vf)->Tell(vf))
#define VFS_GETLEN(vf) ((vf)->GetLen(vf))
#define VFS_SEEK(vf,pos) ((vf)->Seek(vf,pos))
#define VFS_READ(vf,buffer,buflen) ((vf)->ReadBytes(vf,buffer,buflen))
#define VFS_WRITE(vf,buffer,buflen) ((vf)->WriteBytes(vf,buffer,buflen))
#define VFS_FLUSH(vf) do{if((vf)->Flush)(vf)->Flush(vf);}while(0)
#define VFS_PUTS(vf,s) do{const char *t=s;(vf)->WriteBytes(vf,t,strlen(t));}while(0)
char *VFS_GETS(vfsfile_t *vf, char *buffer, int buflen);
void VARGS VFS_PRINTF(vfsfile_t *vf, char *fmt, ...) LIKEPRINTF(2);
enum fs_relative{
FS_GAME, //standard search (not generally valid for save/rename/delete/etc)
FS_BINARYPATH, //for dlls and stuff
FS_ROOT, //./
FS_ROOT, //./ (the root basepath or root homepath.)
FS_GAMEONLY, //$gamedir/
FS_GAMEDOWNLOADCACHE, //typically the same as FS_GAMEONLY
FS_CONFIGONLY, //fte/ (should still be part of the game path)
FS_SKINS //qw/skins/
FS_BASEGAMEONLY, //fte/ (fixme: should be the last basegame.)
FS_PUBBASEGAMEONLY, //qw/ (fixme: should be the last non-private basedir)
FS_SYSTEM //a system path. absolute paths are explicitly allowed and expected.
};
void FS_FlushFSHashReally(void);
@ -447,6 +452,8 @@ void FS_ReloadPackFiles(void);
char *FSQ3_GenerateClientPacksList(char *buffer, int maxlen, int basechecksum);
void FS_PureMode(int mode, char *packagelist, char *crclist, int seed); //implies an fs_restart
//recursively tries to open files until it can get a zip.
vfsfile_t *CL_OpenFileInPackage(searchpathfuncs_t *search, char *name);
qbyte *QDECL COM_LoadStackFile (const char *path, void *buffer, int bufsize);
qbyte *COM_LoadTempFile (const char *path);
@ -461,7 +468,13 @@ qboolean FS_Restarted(unsigned int *since);
typedef struct
{
qboolean blockupdate; //set to block the updateurl from being used this session. this avoids recursive updates when manifests contain the same update url.
int minver; //if the engine svn revision is lower than this, the manifest will not be used as an 'upgrade'.
int maxver; //if not 0, the manifest will not be used
qboolean disablehomedir;
char *updateurl; //url to download an updated manifest file from.
char *updatefile; //this is the file that needs to be written to update the manifest.
char *installation; //optional hardcoded commercial name, used for scanning the registry to find existing installs.
char *formalname; //the commercial name of the game. you'll get FULLENGINENAME otherwise.
char *protocolname; //the name used for purposes of dpmaster
@ -481,19 +494,20 @@ typedef struct
} package[64];
} ftemanifest_t;
void FS_Manifest_Free(ftemanifest_t *man);
ftemanifest_t *FS_Manifest_Parse(const char *data);
ftemanifest_t *FS_Manifest_Parse(const char *fname, const char *data);
void COM_InitFilesystem (void); //does not set up any gamedirs.
qboolean FS_ChangeGame(ftemanifest_t *newgame, qboolean allowreloadconfigs);
void FS_Shutdown(void);
void COM_Gamedir (const char *dir);
char *FS_GetGamedir(void);
char *FS_GetGamedir(qboolean publicpathonly);
char *FS_GetBasedir(void);
char *FS_GetManifestArgs(void);
struct zonegroup_s;
void *FS_LoadMallocGroupFile(struct zonegroup_s *ctx, char *path);
qbyte *FS_LoadMallocFile (const char *path);
qofs_t FS_LoadFile(char *name, void **file);
qofs_t FS_LoadFile(const char *name, void **file);
void FS_FreeFile(void *file);
qbyte *COM_LoadFile (const char *path, int usehunk);
@ -513,7 +527,7 @@ char *COM_Effectinfo_ForNumber(unsigned int efnum);
unsigned int COM_RemapMapChecksum(unsigned int checksum);
#define MAX_INFO_KEY 256
char *Info_ValueForKey (char *s, const char *key);
char *Info_ValueForKey (const char *s, const char *key);
void Info_RemoveKey (char *s, const char *key);
char *Info_KeyForNumber (char *s, int num);
void Info_RemovePrefixedKeys (char *start, char prefix);
@ -524,14 +538,14 @@ void Info_Print (char *s, char *lineprefix);
void Info_WriteToFile(vfsfile_t *f, char *info, char *commandname, int cvarflags);
void Com_BlocksChecksum (int blocks, void **buffer, int *len, unsigned char *outbuf);
unsigned int Com_BlockChecksum (void *buffer, int length);
void Com_BlockFullChecksum (void *buffer, int len, unsigned char *outbuf);
unsigned int Com_BlockChecksum (const void *buffer, int length);
void Com_BlockFullChecksum (const void *buffer, int len, unsigned char *outbuf);
qbyte COM_BlockSequenceCheckByte (qbyte *base, int length, int sequence, unsigned mapchecksum);
qbyte COM_BlockSequenceCRCByte (qbyte *base, int length, int sequence);
qbyte Q2COM_BlockSequenceCRCByte (qbyte *base, int length, int sequence);
int SHA1(char *digest, int maxdigestsize, char *string, int stringlen);
int SHA1_HMAC(unsigned char *digest, int maxdigestsize, unsigned char *data, int datalen, unsigned char *key, int keylen);
int SHA1(char *digest, int maxdigestsize, const char *string, int stringlen);
int SHA1_HMAC(unsigned char *digest, int maxdigestsize, const unsigned char *data, int datalen, const unsigned char *key, int keylen);
int version_number(void);
char *version_string(void);

View File

@ -139,6 +139,7 @@ typedef struct console_s
void (*redirect) (struct console_s *con, int key); //if present, called every character.
void *userdata;
conline_t *completionline; //temp text at the bottom of the console
conline_t *footerline; //temp text at the bottom of the console
conline_t *selstartline, *selendline;
unsigned int selstartoffset, selendoffset;
@ -199,8 +200,8 @@ int Con_IsActive (console_t *con);
void Con_Destroy (console_t *con);
void Con_SetActive (console_t *con);
qboolean Con_NameForNum(int num, char *buffer, int buffersize);
console_t *Con_FindConsole(char *name);
console_t *Con_Create(char *name, unsigned int flags);
console_t *Con_FindConsole(const char *name);
console_t *Con_Create(const char *name, unsigned int flags);
void Con_SetVisible (console_t *con);
void Con_PrintCon (console_t *con, char *txt);

View File

@ -81,7 +81,7 @@ unsigned short QCRC_Value(unsigned short crcvalue)
return crcvalue ^ QCRC_XOR_VALUE;
}
unsigned short QCRC_Block (qbyte *start, int count)
unsigned short QCRC_Block (const qbyte *start, int count)
{
unsigned short crc;
@ -92,7 +92,7 @@ unsigned short QCRC_Block (qbyte *start, int count)
return crc;
}
unsigned short QCRC_Block_AsLower (qbyte *start, int count)
unsigned short QCRC_Block_AsLower (const qbyte *start, int count)
{
unsigned short crc;
@ -103,7 +103,7 @@ unsigned short QCRC_Block_AsLower (qbyte *start, int count)
return crc;
}
void QCRC_AddBlock (unsigned short *crcvalue, qbyte *start, int count)
void QCRC_AddBlock (unsigned short *crcvalue, const qbyte *start, int count)
{
while (count--)
QCRC_ProcessByte(crcvalue, *start++);

View File

@ -20,8 +20,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
/* crc.h */
void QCRC_Init(unsigned short *crcvalue);
void QCRC_AddBlock (unsigned short *crcvalue, qbyte *start, int count);
void QCRC_AddBlock (unsigned short *crcvalue, const qbyte *start, int count);
void QCRC_ProcessByte(unsigned short *crcvalue, qbyte data);
unsigned short QCRC_Value(unsigned short crcvalue);
unsigned short QCRC_Block (qbyte *start, int count);
unsigned short QCRC_Block_AsLower (qbyte *start, int count);
unsigned short QCRC_Block (const qbyte *start, int count);
unsigned short QCRC_Block_AsLower (const qbyte *start, int count);

View File

@ -68,7 +68,7 @@ Cvar_FindVar
*/
cvar_t *Cvar_FindVar (const char *var_name)
{
return Hash_GetInsensative(&cvar_hash, var_name);
return Hash_GetInsensitive(&cvar_hash, var_name);
/*
cvar_group_t *grp;
cvar_t *var;
@ -791,10 +791,21 @@ cvar_t *Cvar_SetCore (cvar_t *var, const char *value, qboolean force)
var->modified++; //only modified if it changed.
if (var->callback)
var->callback(var, latch);
if ((var->flags & CVAR_ARCHIVE) && !(var->flags & CVAR_SERVEROVERRIDE) && cl_warncmd.ival)
Cvar_ConfigChanged();
}
if ((var->flags & CVAR_ARCHIVE) && !(var->flags & CVAR_SERVEROVERRIDE) && cl_warncmd.ival)
{
if (var->latched_string)
{
if (strcmp(var->latched_string, value))
Cvar_ConfigChanged();
}
else
{
if (strcmp(latch, value))
Cvar_ConfigChanged();
}
}
Z_Free (latch); // free the old value string
}
@ -968,7 +979,7 @@ void Cvar_SetValue (cvar_t *var, float value)
if (value == (int)value)
sprintf (val, "%i",(int)value); //make it look nicer.
else
sprintf (val, "%f",value);
sprintf (val, "%g",value);
Cvar_Set (var, val);
}
@ -1063,9 +1074,9 @@ qboolean Cvar_Register (cvar_t *variable, const char *groupname)
Cvar_Free(old);
Hash_AddInsensative(&cvar_hash, variable->name, variable, &variable->hbn1);
Hash_AddInsensitive(&cvar_hash, variable->name, variable, &variable->hbn1);
if (variable->name2)
Hash_AddInsensative(&cvar_hash, variable->name2, variable, &variable->hbn2);
Hash_AddInsensitive(&cvar_hash, variable->name2, variable, &variable->hbn2);
return false;
}
@ -1088,9 +1099,9 @@ qboolean Cvar_Register (cvar_t *variable, const char *groupname)
variable->restriction = 0; //exe registered vars
group->cvars = variable;
Hash_AddInsensative(&cvar_hash, variable->name, variable, &variable->hbn1);
Hash_AddInsensitive(&cvar_hash, variable->name, variable, &variable->hbn1);
if (variable->name2)
Hash_AddInsensative(&cvar_hash, variable->name2, variable, &variable->hbn2);
Hash_AddInsensitive(&cvar_hash, variable->name2, variable, &variable->hbn2);
variable->string = NULL;

File diff suppressed because it is too large Load Diff

View File

@ -2,9 +2,10 @@
#define FSVER 2
#define FF_NOTFOUND 0 //file wasn't found
#define FF_FOUND 1 //file was found
#define FF_SYMLINK 2 //file contents are the name of a different file (symlink). do a recursive lookup on the name
#define FF_NOTFOUND (0u) //file wasn't found
#define FF_FOUND (1u<<0u) //file was found
#define FF_SYMLINK (1u<<1u) //file contents are the name of a different file (symlink). do a recursive lookup on the name
#define FF_DIRECTORY (1u<<2u)
typedef struct
{
@ -14,6 +15,7 @@ typedef struct
extern hashtable_t filesystemhash; //this table is the one to build your hash references into
extern int fs_hash_dups; //for tracking efficiency. no functional use.
extern int fs_hash_files; //for tracking efficiency. no functional use.
extern qboolean fs_readonly; //if true, fopen(, "w") should always fail.
struct searchpath_s;
struct searchpathfuncs_s
@ -54,9 +56,12 @@ int FS_RegisterFileSystemType(void *module, const char *extension, searchpathfun
void FS_UnRegisterFileSystemType(int idx);
void FS_UnRegisterFileSystemModule(void *module);
void FS_EnumerateKnownGames(qboolean (*callback)(void *usr, ftemanifest_t *man), void *usr);
#define SPF_REFERENCED 1 //something has been loaded from this path. should filter out client references...
#define SPF_COPYPROTECTED 2 //downloads are not allowed fom here.
#define SPF_TEMPORARY 4 //a map-specific path, purged at map change.
#define SPF_EXPLICIT 8 //a root gamedir (bumps depth on gamedir depth checks).
#define SPF_UNTRUSTED 16 //has been downloaded from somewhere. configs inside it should never be execed with local access rights.
#define SPF_PRIVATE 32 //private to the client. ie: the fte dir.
qboolean FS_LoadPackageFromFile(vfsfile_t *vfs, char *pname, char *localname, int *crc, unsigned int flags);

View File

@ -225,11 +225,12 @@ static qofs_t QDECL VFSPAK_GetLen (struct vfsfile_s *vfs)
vfspack_t *vfsp = (vfspack_t*)vfs;
return vfsp->length;
}
static void QDECL VFSPAK_Close(vfsfile_t *vfs)
static qboolean QDECL VFSPAK_Close(vfsfile_t *vfs)
{
vfspack_t *vfsp = (vfspack_t*)vfs;
FSPAK_ClosePath(&vfsp->parentpak->pub); //tell the parent that we don't need it open any more (reference counts)
Z_Free(vfsp); //free ourselves.
return true;
}
static vfsfile_t *QDECL FSPAK_OpenVFS(searchpathfuncs_t *handle, flocation_t *loc, const char *mode)
{

View File

@ -8,7 +8,7 @@
#define Z_Free free
#define Z_Malloc malloc
#else
#if !defined(_WIN32) || defined(FTE_SDL)
#if !defined(_WIN32) || defined(FTE_SDL) || defined(WINRT)
#define FSSTDIO_OpenPath VFSOS_OpenPath
#endif
#define FSSTDIO_OpenTemp FS_OpenTemp
@ -62,21 +62,27 @@ static qofs_t QDECL VFSSTDIO_GetSize (struct vfsfile_s *file)
return maxlen;
}
static void QDECL VFSSTDIO_Close(vfsfile_t *file)
static qboolean QDECL VFSSTDIO_Close(vfsfile_t *file)
{
qboolean success;
vfsstdiofile_t *intfile = (vfsstdiofile_t*)file;
success = !ferror(intfile->handle);
fclose(intfile->handle);
Z_Free(file);
return success;
}
#ifdef _WIN32
static void QDECL VFSSTDIO_CloseTemp(vfsfile_t *file)
static qboolean QDECL VFSSTDIO_CloseTemp(vfsfile_t *file)
{
qboolean success;
vfsstdiofile_t *intfile = (vfsstdiofile_t*)file;
char *fname = (char*)(intfile+1);
success = !ferror(intfile->handle);
fclose(intfile->handle);
_unlink(fname);
Z_Free(file);
return success;
}
#endif
@ -184,7 +190,7 @@ vfsfile_t *VFSSTDIO_Open(const char *osname, const char *mode, qboolean *needsfl
return (vfsfile_t*)file;
}
#if !defined(_WIN32) || defined(FTE_SDL)
#if !defined(_WIN32) || defined(FTE_SDL) || defined(WINRT)
vfsfile_t *VFSOS_Open(const char *osname, const char *mode)
{
vfsfile_t *f;

View File

@ -2,33 +2,6 @@
#include "fs.h"
#include "winquake.h"
#ifndef INVALID_SET_FILE_POINTER
#define INVALID_SET_FILE_POINTER ~0
#endif
//read-only memory mapped files.
//for write access, we use the stdio module as a fallback.
//do you think anyone will ever notice that utf8 filenames work even in windows? probably not. oh well, worth a try.
#define VFSW32_Open VFSOS_Open
#define VFSW32_OpenPath VFSOS_OpenPath
typedef struct {
searchpathfuncs_t pub;
HANDLE changenotification;
void (QDECL *AddFileHash)(int depth, const char *fname, fsbucket_t *filehandle, void *pathhandle);
int hashdepth;
char rootpath[1];
} vfsw32path_t;
typedef struct {
vfsfile_t funcs;
HANDLE hand;
HANDLE mmh;
void *mmap;
unsigned int length;
unsigned int offset;
} vfsw32file_t;
//outlen is the size of out in _BYTES_.
wchar_t *widen(wchar_t *out, size_t outlen, const char *utf8)
{
@ -99,6 +72,35 @@ char *narrowen(char *out, size_t outlen, wchar_t *wide)
}
#ifndef WINRT //winrt is too annoying. lets just use stdio.
#ifndef INVALID_SET_FILE_POINTER
#define INVALID_SET_FILE_POINTER ~0
#endif
//read-only memory mapped files.
//for write access, we use the stdio module as a fallback.
//do you think anyone will ever notice that utf8 filenames work even in windows? probably not. oh well, worth a try.
#define VFSW32_Open VFSOS_Open
#define VFSW32_OpenPath VFSOS_OpenPath
typedef struct {
searchpathfuncs_t pub;
HANDLE changenotification;
void (QDECL *AddFileHash)(int depth, const char *fname, fsbucket_t *filehandle, void *pathhandle);
int hashdepth;
char rootpath[1];
} vfsw32path_t;
typedef struct {
vfsfile_t funcs;
HANDLE hand;
HANDLE mmh;
void *mmap;
unsigned int length;
unsigned int offset;
} vfsw32file_t;
static int QDECL VFSW32_ReadBytes (struct vfsfile_s *file, void *buffer, int bytestoread)
{
DWORD read;
@ -174,7 +176,7 @@ static qofs_t QDECL VFSW32_GetSize (struct vfsfile_s *file)
lo = GetFileSize(intfile->hand, &hi);
return qofs_Make(lo,hi);
}
static void QDECL VFSW32_Close(vfsfile_t *file)
static qboolean QDECL VFSW32_Close(vfsfile_t *file)
{
vfsw32file_t *intfile = (vfsw32file_t*)file;
if (intfile->mmap)
@ -184,6 +186,7 @@ static void QDECL VFSW32_Close(vfsfile_t *file)
}
CloseHandle(intfile->hand);
Z_Free(file);
return true;
}
//WARNING: handle can be null
@ -203,6 +206,9 @@ static vfsfile_t *QDECL VFSW32_OpenInternal(vfsw32path_t *handle, const char *qu
if (strchr(mode, '+'))
read = write = true;
if (fs_readonly && (write || append))
return NULL;
if (!WinNT)
{
if ((write && read) || append)
@ -222,6 +228,7 @@ static vfsfile_t *QDECL VFSW32_OpenInternal(vfsw32path_t *handle, const char *qu
h = INVALID_HANDLE_VALUE;
if (write || append)
{
//this extra block is to avoid flushing fs caches needlessly
h = CreateFileW(wide, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (h == INVALID_HANDLE_VALUE)
{
@ -246,7 +253,10 @@ static vfsfile_t *QDECL VFSW32_OpenInternal(vfsw32path_t *handle, const char *qu
h = INVALID_HANDLE_VALUE;
}
if (h == INVALID_HANDLE_VALUE)
{
DWORD e = GetLastError();
return NULL;
}
if (!didexist)
{
@ -370,13 +380,15 @@ static void QDECL VFSW32_BuildHash(searchpathfuncs_t *handle, int hashdepth, voi
wp->hashdepth = hashdepth;
Sys_EnumerateFiles(wp->rootpath, "*", VFSW32_RebuildFSHash, AddFileHash, handle);
}
#include <errno.h>
static unsigned int QDECL VFSW32_FLocate(searchpathfuncs_t *handle, flocation_t *loc, const char *filename, void *hashedresult)
{
vfsw32path_t *wp = (void*)handle;
FILE *f;
int len;
char netpath[MAX_OSPATH];
wchar_t wide[MAX_OSPATH];
qofs_t len;
HANDLE h;
DWORD attr;
if (hashedresult && (void *)hashedresult != wp)
@ -394,23 +406,35 @@ static unsigned int QDECL VFSW32_FLocate(searchpathfuncs_t *handle, flocation_t
snprintf (netpath, sizeof(netpath)-1, "%s/%s", wp->rootpath, filename);
if (!WinNT)
f = fopen(netpath, "rb");
{
WIN32_FIND_DATAA fda;
h = FindFirstFileA(netpath, &fda);
attr = fda.dwFileAttributes;
len = (h == INVALID_HANDLE_VALUE)?0:qofs_Make(fda.nFileSizeLow, fda.nFileSizeHigh);
}
else
f = _wfopen(widen(wide, sizeof(wide), netpath), L"rb");
if (!f)
{
WIN32_FIND_DATAW fdw;
h = FindFirstFileW(widen(wide, sizeof(wide), netpath), &fdw);
attr = fdw.dwFileAttributes;
len = (h == INVALID_HANDLE_VALUE)?0:qofs_Make(fdw.nFileSizeLow, fdw.nFileSizeHigh);
}
if (h == INVALID_HANDLE_VALUE)
{
// int e = GetLastError();
// if (e == ERROR_PATH_NOT_FOUND) //then look inside a zip
return FF_NOTFOUND;
fseek(f, 0, SEEK_END);
len = ftell(f);
fclose(f);
}
FindClose(h);
if (loc)
{
loc->len = len;
loc->offset = 0;
loc->index = 0;
snprintf(loc->rawname, sizeof(loc->rawname), "%s/%s", wp->rootpath, filename);
Q_strncpyz(loc->rawname, netpath, sizeof(loc->rawname));
}
if (attr & FILE_ATTRIBUTE_DIRECTORY)
return FF_DIRECTORY; //not actually openable.
return FF_FOUND;
}
static void QDECL VFSW32_ReadFile(searchpathfuncs_t *handle, flocation_t *loc, char *buffer)
@ -440,6 +464,8 @@ static qboolean QDECL VFSW32_RenameFile(searchpathfuncs_t *handle, const char *o
vfsw32path_t *wp = (vfsw32path_t*)handle;
char oldsyspath[MAX_OSPATH];
char newsyspath[MAX_OSPATH];
if (fs_readonly)
return false;
snprintf (oldsyspath, sizeof(oldsyspath)-1, "%s/%s", wp->rootpath, oldfname);
snprintf (newsyspath, sizeof(newsyspath)-1, "%s/%s", wp->rootpath, newfname);
return Sys_Rename(oldsyspath, newsyspath);
@ -448,6 +474,8 @@ static qboolean QDECL VFSW32_RemoveFile(searchpathfuncs_t *handle, const char *f
{
vfsw32path_t *wp = (vfsw32path_t*)handle;
char syspath[MAX_OSPATH];
if (fs_readonly)
return false;
snprintf (syspath, sizeof(syspath)-1, "%s/%s", wp->rootpath, filename);
return Sys_remove(syspath);
}
@ -455,6 +483,8 @@ static qboolean QDECL VFSW32_MkDir(searchpathfuncs_t *handle, const char *filena
{
vfsw32path_t *wp = (vfsw32path_t*)handle;
char syspath[MAX_OSPATH];
if (fs_readonly)
return false;
snprintf (syspath, sizeof(syspath)-1, "%s/%s", wp->rootpath, filename);
Sys_mkdir(syspath);
return true;
@ -492,3 +522,4 @@ searchpathfuncs_t *QDECL VFSW32_OpenPath(vfsfile_t *mustbenull, const char *desc
return &np->pub;
}
#endif

View File

@ -604,15 +604,20 @@ static qofs_t QDECL VFSZIP_GetLen (struct vfsfile_s *file)
vfszip_t *vfsz = (vfszip_t*)file;
return vfsz->length;
}
static void QDECL VFSZIP_Close (struct vfsfile_s *file)
static qboolean QDECL VFSZIP_Close (struct vfsfile_s *file)
{
vfszip_t *vfsz = (vfszip_t*)file;
if (vfsz->defer)
VFS_CLOSE(vfsz->defer);
if (vfsz->decompress)
FSZIP_Decompress_Destroy(vfsz->decompress);
FSZIP_ClosePath(&vfsz->parent->pub);
Z_Free(vfsz);
return true; //FIXME: return an error if the crc was wrong.
}
static qboolean FSZIP_ValidateLocalHeader(zipfile_t *zip, zpackfile_t *zfile, qofs_t *datastart, qofs_t *datasize);
@ -627,7 +632,7 @@ static vfsfile_t *QDECL FSZIP_OpenVFS(searchpathfuncs_t *handle, flocation_t *lo
if (strcmp(mode, "rb"))
return NULL; //urm, unable to write/append
if (loc->len < 0)
if (qofs_Error(loc->len))
return NULL;
flags = zip->files[loc->index].flags;

View File

@ -6049,4 +6049,9 @@ void CM_Init(void) //register cvars.
Cvar_Register(&map_autoopenportals, MAPOPTIONS);
Cvar_Register(&r_subdivisions, MAPOPTIONS);
}
void CM_Shutdown(void)
{
ZG_FreeGroup(&box_model.memgroup);
box_planes = NULL;
}
#endif

View File

@ -757,6 +757,38 @@ void VectorTransform (const vec3_t in1, const matrix3x4 in2, vec3_t out)
out[2] = DotProduct(in1, in2[2]) + in2[2][3];
}
void GenMatrixPosQuat4Scale(vec3_t pos, vec4_t quat, vec3_t scale, float result[12])
{
float xx, xy, xz, xw, yy, yz, yw, zz, zw;
float x2, y2, z2;
float s;
x2 = quat[0] + quat[0];
y2 = quat[1] + quat[1];
z2 = quat[2] + quat[2];
xx = quat[0] * x2; xy = quat[0] * y2; xz = quat[0] * z2;
yy = quat[1] * y2; yz = quat[1] * z2; zz = quat[2] * z2;
xw = quat[3] * x2; yw = quat[3] * y2; zw = quat[3] * z2;
s = scale[0];
result[0*4+0] = s*(1.0f - (yy + zz));
result[1*4+0] = s*(xy + zw);
result[2*4+0] = s*(xz - yw);
s = scale[1];
result[0*4+1] = s*(xy - zw);
result[1*4+1] = s*(1.0f - (xx + zz));
result[2*4+1] = s*(yz + xw);
s = scale[2];
result[0*4+2] = s*(xz + yw);
result[1*4+2] = s*(yz - xw);
result[2*4+2] = s*(1.0f - (xx + yy));
result[0*4+3] = pos[0];
result[1*4+3] = pos[1];
result[2*4+3] = pos[2];
}
#ifdef HALFLIFEMODELS
void AngleQuaternion( const vec3_t angles, vec4_t quaternion )
@ -1646,7 +1678,7 @@ void Matrix3x4_InvertTo4x4_Simple (const float *in1, float *out)
out[15] = 1;
}
void Matrix3x4_InvertTo3x3(float *in, float *result)
void Matrix3x4_InvertTo3x3(const float *in, float *result)
{
float t1[16], tr[16];
memcpy(t1, in, sizeof(float)*12);

View File

@ -182,6 +182,8 @@ void Matrix3x4_RM_Transform3(const float *matrix, const float *vector, float *p
float *Matrix4x4_CM_NewRotation(float a, float x, float y, float z);
float *Matrix4x4_CM_NewTranslation(float x, float y, float z);
void GenMatrixPosQuat4Scale(vec3_t pos, vec4_t quat, vec3_t scale, float result[12]);
#define AngleVectorsFLU(a,f,l,u) do{AngleVectors(a,f,l,u);VectorNegate(l,l);}while(0)
//projection matricies of different types... gesh
@ -194,7 +196,7 @@ void Matrix4x4_CM_Projection_Inf(float *proj, float fovx, float fovy, float nea
fixed16_t Mul16_30 (fixed16_t multiplier, fixed16_t multiplicand);
int Q_log2 (int val);
void Matrix3x4_InvertTo3x3(float *in, float *result);
void Matrix3x4_InvertTo3x3(const float *in, float *result);
fixed16_t Mul16_30 (fixed16_t multiplier, fixed16_t multiplicand);
int Q_log2 (int val);

View File

@ -27,7 +27,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//FIXME: should split this into loopback/dgram/stream/irc
//with the ipv4/v6/x as a separate parameter
typedef enum {NA_INVALID, NA_LOOPBACK, NA_IP, NA_IPV6, NA_IPX, NA_BROADCAST_IP, NA_BROADCAST_IP6, NA_BROADCAST_IPX, NA_TCP, NA_TCPV6, NA_IRC, NA_WEBSOCKET, NA_NATPMP} netadrtype_t;
typedef enum {NA_INVALID, NA_LOOPBACK, NA_IP, NA_IPV6, NA_IPX, NA_BROADCAST_IP, NA_BROADCAST_IP6, NA_BROADCAST_IPX, NA_TCP, NA_TCPV6, NA_TLSV4, NA_TLSV6, NA_IRC, NA_WEBSOCKET, NA_NATPMP} netadrtype_t;
typedef enum {NS_CLIENT, NS_SERVER} netsrc_t;
@ -92,7 +92,7 @@ void NET_CloseServer (void);
void UDP_CloseSocket (int socket);
void NET_Shutdown (void);
int NET_GetPacket (netsrc_t netsrc, int firstsock);
qboolean NET_SendPacket (netsrc_t socket, int length, void *data, netadr_t *to);
qboolean NET_SendPacket (netsrc_t socket, int length, const void *data, netadr_t *to);
int NET_LocalAddressForRemote(struct ftenet_connections_s *collection, netadr_t *remote, netadr_t *local, int idx);
void NET_PrintAddresses(struct ftenet_connections_s *collection);
qboolean NET_AddressSmellsFunny(netadr_t *a);

View File

@ -425,9 +425,15 @@ nqprot_t NQNetChan_Process(netchan_t *chan)
chan->last_received = realtime;
}
else if (sequence < chan->reliable_sequence)
Con_DPrintf("Stale ack recieved\n");
{
if (showdrop.ival)
Con_Printf("Stale ack recieved\n");
}
else if (sequence > chan->reliable_sequence)
Con_Printf("Future ack recieved\n");
{
if (showdrop.ival)
Con_Printf("Future ack recieved\n");
}
if (showpackets.value)
Con_Printf ("in %s a=%i %i\n"
@ -442,7 +448,8 @@ nqprot_t NQNetChan_Process(netchan_t *chan)
{
if (sequence <= chan->incoming_unreliable)
{
Con_DPrintf("Stale datagram recieved (%i<=%i)\n", sequence, chan->incoming_unreliable);
if (showdrop.ival)
Con_Printf("Stale datagram recieved (%i<=%i)\n", sequence, chan->incoming_unreliable);
return NQP_ERROR;
}
drop = sequence - chan->incoming_unreliable - 1;
@ -516,7 +523,10 @@ nqprot_t NQNetChan_Process(netchan_t *chan)
}
}
else
Con_DPrintf("Stale reliable (%i)\n", sequence);
{
if (showdrop.ival)
Con_Printf("Stale reliable (%i)\n", sequence);
}
return NQP_ERROR;
}
@ -553,7 +563,7 @@ int Netchan_Transmit (netchan_t *chan, int length, qbyte *data, int rate)
send.maxsize = MAX_NQMSGLEN + PACKET_HEADER;
send.cursize = 0;
if (chan->remote_address.type == NA_TCP && chan->reliable_length)
if ((chan->remote_address.type == NA_TCP || chan->remote_address.type == NA_TCPV6 || chan->remote_address.type == NA_TLSV4 || chan->remote_address.type == NA_TLSV6) && chan->reliable_length)
{
//if over tcp, everything is assumed to be reliable. pretend it got acked.
chan->reliable_length = 0; //they got the entire message
@ -775,7 +785,8 @@ int Netchan_Transmit (netchan_t *chan, int length, qbyte *data, int rate)
#endif
if (showpackets.value)
Con_Printf ("--> s=%i(%i) a=%i(%i) %i\n"
Con_Printf ("%s --> s=%i(%i) a=%i(%i) %i\n"
, chan->sock == NS_SERVER?"s2c":"c2s"
, chan->outgoing_sequence
, send_reliable
, chan->incoming_sequence
@ -832,7 +843,8 @@ qboolean Netchan_Process (netchan_t *chan)
sequence_ack &= ~(1<<31);
if (showpackets.value)
Con_Printf ("<-- s=%i(%i) a=%i(%i) %i%s\n"
Con_Printf ("%s <-- s=%i(%i) a=%i(%i) %i%s\n"
, chan->sock == NS_SERVER?"c2s":"s2c"
, sequence
, reliable_message
, sequence_ack

View File

@ -2,7 +2,7 @@
#if defined(HAVE_WINSSPI)
cvar_t *tls_ignorecertificateerrors;
#include <windows.h>
#include "winquake.h"
#define SECURITY_WIN32
#include <security.h>
#include <sspi.h>
@ -16,6 +16,7 @@ static struct
SECURITY_STATUS (WINAPI *pEncryptMessage) (PCtxtHandle,ULONG,PSecBufferDesc,ULONG);
SECURITY_STATUS (WINAPI *pAcquireCredentialsHandleA) (SEC_CHAR*,SEC_CHAR*,ULONG,PLUID,PVOID,SEC_GET_KEY_FN,PVOID,PCredHandle,PTimeStamp);
SECURITY_STATUS (WINAPI *pInitializeSecurityContextA) (PCredHandle,PCtxtHandle,SEC_CHAR*,ULONG,ULONG,ULONG,PSecBufferDesc,ULONG,PCtxtHandle,PSecBufferDesc,PULONG,PTimeStamp);
SECURITY_STATUS (WINAPI *pAcceptSecurityContext) (PCredHandle,PCtxtHandle,PSecBufferDesc,unsigned long,unsigned long,PCtxtHandle,PSecBufferDesc,unsigned long SEC_FAR *,PTimeStamp);
SECURITY_STATUS (WINAPI *pCompleteAuthToken) (PCtxtHandle,PSecBufferDesc);
SECURITY_STATUS (WINAPI *pQueryContextAttributesA) (PCtxtHandle,ULONG,PVOID);
SECURITY_STATUS (WINAPI *pFreeCredentialsHandle) (PCredHandle);
@ -28,6 +29,9 @@ static struct
BOOL (WINAPI *pCertVerifyCertificateChainPolicy) (LPCSTR,PCCERT_CHAIN_CONTEXT,PCERT_CHAIN_POLICY_PARA,PCERT_CHAIN_POLICY_STATUS);
void (WINAPI *pCertFreeCertificateChain) (PCCERT_CHAIN_CONTEXT);
DWORD (WINAPI *pCertNameToStrA) (DWORD dwCertEncodingType, PCERT_NAME_BLOB pName, DWORD dwStrType, LPTSTR psz, DWORD csz);
PCCERT_CONTEXT (WINAPI *pCertCreateSelfSignCertificate) (HCRYPTPROV,PCERT_NAME_BLOB,DWORD,PCRYPT_KEY_PROV_INFO,PCRYPT_ALGORITHM_IDENTIFIER,PSYSTEMTIME,PSYSTEMTIME,PCERT_EXTENSIONS);
BOOL (WINAPI *pCertStrToNameA) (DWORD,LPCSTR,DWORD,void *,BYTE *,DWORD *,LPCSTR *);
} crypt;
static qboolean SSL_Init(void)
{
@ -37,6 +41,7 @@ static qboolean SSL_Init(void)
{(void**)&secur.pEncryptMessage, "EncryptMessage"},
{(void**)&secur.pAcquireCredentialsHandleA, "AcquireCredentialsHandleA"},
{(void**)&secur.pInitializeSecurityContextA, "InitializeSecurityContextA"},
{(void**)&secur.pAcceptSecurityContext, "AcceptSecurityContext"},
{(void**)&secur.pCompleteAuthToken, "CompleteAuthToken"},
{(void**)&secur.pQueryContextAttributesA, "QueryContextAttributesA"},
{(void**)&secur.pFreeCredentialsHandle, "FreeCredentialsHandle"},
@ -50,6 +55,8 @@ static qboolean SSL_Init(void)
{(void**)&crypt.pCertVerifyCertificateChainPolicy, "CertVerifyCertificateChainPolicy"},
{(void**)&crypt.pCertFreeCertificateChain, "CertFreeCertificateChain"},
{(void**)&crypt.pCertNameToStrA, "CertNameToStrA"},
{(void**)&crypt.pCertCreateSelfSignCertificate, "CertCreateSelfSignCertificate"},
{(void**)&crypt.pCertStrToNameA, "CertStrToNameA"},
{NULL, NULL}
};
@ -114,6 +121,7 @@ static int SSPI_CopyIntoBuffer(struct sslbuf *buf, const void *data, unsigned in
static void SSPI_Error(sslfile_t *f, char *error)
{
f->handshaking = HS_ERROR;
Sys_Printf("%s", error);
if (f->stream)
VFS_CLOSE(f->stream);
@ -184,7 +192,11 @@ static void SSPI_Decode(sslfile_t *f)
{
if (ss == SEC_E_INCOMPLETE_MESSAGE)
return; //no error if its incomplete, we can just get more data later on.
SSPI_Error(f, "DecryptMessage failed\n");
switch(ss)
{
case SEC_E_INVALID_HANDLE: SSPI_Error(f, "DecryptMessage failed: SEC_E_INVALID_HANDLE\n"); break;
default: SSPI_Error(f, va("DecryptMessage failed: %0#x\n", ss)); break;
}
return;
}
@ -383,15 +395,84 @@ static DWORD VerifyServerCertificate(PCCERT_CONTEXT pServerCert, PWSTR pwszServe
return Status;
}
static void SSPI_Handshake (sslfile_t *f)
static PCCERT_CONTEXT SSPI_GetServerCertificate(void)
{
static PCCERT_CONTEXT ret;
char *issuertext = "CN=127.0.0.1, O=\"FTE QuakeWorld\", OU=Testing, C=TR";
CERT_NAME_BLOB issuerblob;
CRYPT_ALGORITHM_IDENTIFIER sigalg;
SYSTEMTIME expiredate;
if (ret)
return ret;
memset(&sigalg, 0, sizeof(sigalg));
sigalg.pszObjId = szOID_RSA_SHA1RSA;
GetSystemTime(&expiredate);
expiredate.wYear += 2; //2 years hence. woo
memset(&issuerblob, 0, sizeof(issuerblob));
crypt.pCertStrToNameA(X509_ASN_ENCODING, issuertext, CERT_X500_NAME_STR, NULL, issuerblob.pbData, &issuerblob.cbData, NULL);
issuerblob.pbData = Z_Malloc(issuerblob.cbData);
crypt.pCertStrToNameA(X509_ASN_ENCODING, issuertext, CERT_X500_NAME_STR, NULL, issuerblob.pbData, &issuerblob.cbData, NULL);
ret = crypt.pCertCreateSelfSignCertificate(
0,
&issuerblob,
0,
NULL,
&sigalg,
NULL,
&expiredate,
NULL
);
Z_Free(issuerblob.pbData);
return ret;
}
static void SSPI_GenServerCredentials(sslfile_t *f)
{
SECURITY_STATUS ss;
TimeStamp Lifetime;
SecBufferDesc OutBuffDesc;
SecBuffer OutSecBuff;
SecBufferDesc InBuffDesc;
SecBuffer InSecBuff[2];
ULONG ContextAttributes;
SCHANNEL_CRED SchannelCred;
PCCERT_CONTEXT cred;
memset(&SchannelCred, 0, sizeof(SchannelCred));
SchannelCred.dwVersion = SCHANNEL_CRED_VERSION;
SchannelCred.grbitEnabledProtocols = (SP_PROT_TLS1|SP_PROT_SSL3) & SP_PROT_SERVERS;
SchannelCred.dwFlags |= SCH_CRED_NO_SYSTEM_MAPPER|SCH_CRED_DISABLE_RECONNECTS; /*don't use windows login info or anything*/
cred = SSPI_GetServerCertificate();
SchannelCred.cCreds = 1;
SchannelCred.paCred = &cred;
if (!cred)
{
SSPI_Error(f, "Unable to load/generate certificate\n");
return;
}
ss = secur.pAcquireCredentialsHandleA (NULL, UNISP_NAME_A, SECPKG_CRED_INBOUND, NULL, &SchannelCred, NULL, NULL, &f->cred, &Lifetime);
if (ss < 0)
{
SSPI_Error(f, "AcquireCredentialsHandle failed\n");
return;
}
}
static void SSPI_Handshake (sslfile_t *f)
{
SECURITY_STATUS ss;
TimeStamp Lifetime;
SecBufferDesc OutBuffDesc;
SecBuffer OutSecBuff;
SecBufferDesc InBuffDesc;
SecBuffer InSecBuff[2];
ULONG ContextAttributes;
SCHANNEL_CRED SchannelCred;
if (f->outcrypt.avail)
@ -402,6 +483,8 @@ static void SSPI_Handshake (sslfile_t *f)
return;
}
//FIXME: skip this if we've had no new data since last time
OutBuffDesc.ulVersion = SECBUFFER_VERSION;
OutBuffDesc.cBuffers = 1;
OutBuffDesc.pBuffers = &OutSecBuff;
@ -410,7 +493,9 @@ static void SSPI_Handshake (sslfile_t *f)
OutSecBuff.BufferType = SECBUFFER_TOKEN;
OutSecBuff.pvBuffer = f->outcrypt.data + f->outcrypt.avail;
if (f->handshaking == HS_STARTCLIENT)
if (f->handshaking == HS_ERROR)
return; //gave up.
else if (f->handshaking == HS_STARTCLIENT)
{
//no input data yet.
f->handshaking = HS_CLIENT;
@ -429,7 +514,7 @@ static void SSPI_Handshake (sslfile_t *f)
ss = secur.pInitializeSecurityContextA (&f->cred, NULL, NULL, MessageAttribute, 0, SECURITY_NATIVE_DREP, NULL, 0, &f->sechnd, &OutBuffDesc, &ContextAttributes, &Lifetime);
}
else
else if (f->handshaking == HS_CLIENT)
{
//only if we actually have data.
if (!f->incrypt.avail)
@ -460,6 +545,41 @@ static void SSPI_Handshake (sslfile_t *f)
}
else f->incrypt.avail = 0;
}
else if (f->handshaking == HS_STARTSERVER || f->handshaking == HS_SERVER)
{
//only if we actually have data.
if (!f->incrypt.avail)
return;
InBuffDesc.ulVersion = SECBUFFER_VERSION;
InBuffDesc.cBuffers = 2;
InBuffDesc.pBuffers = InSecBuff;
InSecBuff[0].BufferType = SECBUFFER_TOKEN;
InSecBuff[0].cbBuffer = f->incrypt.avail;
InSecBuff[0].pvBuffer = f->incrypt.data;
InSecBuff[1].BufferType = SECBUFFER_EMPTY;
InSecBuff[1].pvBuffer = NULL;
InSecBuff[1].cbBuffer = 0;
ss = secur.pAcceptSecurityContext(&f->cred, (f->handshaking==HS_SERVER)?&f->sechnd:NULL, &InBuffDesc, ASC_REQ_ALLOCATE_MEMORY|ASC_REQ_STREAM|ASC_REQ_CONFIDENTIALITY, SECURITY_NATIVE_DREP, &f->sechnd, &OutBuffDesc, &ContextAttributes, &Lifetime);
if (ss == SEC_E_INCOMPLETE_MESSAGE)
return;
f->handshaking = HS_SERVER;
//any extra data should still remain for the next time around. this might be more handshake data or payload data.
if (InSecBuff[1].BufferType == SECBUFFER_EXTRA)
{
memmove(f->incrypt.data, f->incrypt.data + (f->incrypt.avail - InSecBuff[1].cbBuffer), InSecBuff[1].cbBuffer);
f->incrypt.avail = InSecBuff[1].cbBuffer;
}
else f->incrypt.avail = 0;
}
else
return;
if (ss == SEC_I_INCOMPLETE_CREDENTIALS)
{
@ -469,7 +589,14 @@ static void SSPI_Handshake (sslfile_t *f)
if (ss < 0)
{
SSPI_Error(f, "InitializeSecurityContext failed\n");
switch(ss)
{
case SEC_E_ALGORITHM_MISMATCH: SSPI_Error(f, "InitializeSecurityContext failed: SEC_E_ALGORITHM_MISMATCH\n"); break;
case SEC_E_INVALID_HANDLE: SSPI_Error(f, "InitializeSecurityContext failed: SEC_E_INVALID_HANDLE\n"); break;
case SEC_E_ILLEGAL_MESSAGE: SSPI_Error(f, "InitializeSecurityContext failed: SEC_E_ILLEGAL_MESSAGE\n"); break;
case SEC_E_INVALID_TOKEN: SSPI_Error(f, "InitializeSecurityContext failed: SEC_E_INVALID_TOKEN\n"); break;
default: SSPI_Error(f, va("InitializeSecurityContext failed: %#x\n", ss)); break;
}
return;
}
@ -501,26 +628,29 @@ static void SSPI_Handshake (sslfile_t *f)
secur.pQueryContextAttributesA(&f->sechnd, SECPKG_ATTR_STREAM_SIZES, &strsizes);
f->headersize = strsizes.cbHeader;
f->footersize = strsizes.cbTrailer;
f->handshaking = HS_ESTABLISHED;
if (*f->wpeername)
{
ss = secur.pQueryContextAttributesA(&f->sechnd, SECPKG_ATTR_REMOTE_CERT_CONTEXT, &remotecert);
if (ss != SEC_E_OK)
if (f->handshaking != HS_SERVER)
{ //server takes an annonymous client. client expects a proper certificate.
if (*f->wpeername)
{
f->handshaking = HS_ERROR;
SSPI_Error(f, "unable to read server's certificate\n");
return;
}
if (VerifyServerCertificate(remotecert, f->wpeername, 0))
{
f->handshaking = HS_ERROR;
SSPI_Error(f, "Error validating certificante\n");
ss = secur.pQueryContextAttributesA(&f->sechnd, SECPKG_ATTR_REMOTE_CERT_CONTEXT, &remotecert);
if (ss != SEC_E_OK)
{
f->handshaking = HS_ERROR;
SSPI_Error(f, "unable to read server's certificate\n");
return;
}
if (VerifyServerCertificate(remotecert, f->wpeername, 0))
{
f->handshaking = HS_ERROR;
SSPI_Error(f, "Error validating certificante\n");
return;
}
}
else
Sys_Printf("SSL/TLS Server name not specified, skipping verification\n");
}
else
Sys_Printf("SSL/TLS Server name not specified, skipping verification\n");
f->handshaking = HS_ESTABLISHED;
SSPI_Encode(f);
}
@ -587,10 +717,13 @@ static qofs_t QDECL SSPI_GetLen (struct vfsfile_s *file)
{
return 0;
}
static void QDECL SSPI_Close (struct vfsfile_s *file)
static qboolean QDECL SSPI_Close (struct vfsfile_s *file)
{
SSPI_Error((sslfile_t*)file, "");
Z_Free(file);
sslfile_t *f = (sslfile_t *)file;
qboolean success = f->stream != NULL;
SSPI_Error(f, "");
Z_Free(f);
return success;
}
#include <wchar.h>
@ -609,11 +742,13 @@ vfsfile_t *FS_OpenSSL(const char *hostname, vfsfile_t *source, qboolean server)
if (!hostname)
hostname = "";
/*
if (server) //unsupported
{
VFS_CLOSE(source);
return NULL;
}
*/
newf = Z_Malloc(sizeof(*newf));
while(*hostname)
@ -644,6 +779,9 @@ vfsfile_t *FS_OpenSSL(const char *hostname, vfsfile_t *source, qboolean server)
newf->funcs.WriteBytes = SSPI_WriteBytes;
newf->funcs.seekingisabadplan = true;
if (server)
SSPI_GenServerCredentials(newf);
return &newf->funcs;
}
#endif

View File

@ -35,7 +35,7 @@ sizebuf_t net_message;
//#define MAX_UDP_PACKET (MAX_MSGLEN*2) // one more than msg + header
#define MAX_UDP_PACKET 8192 // one more than msg + header
qbyte net_message_buffer[MAX_OVERALLMSGLEN];
#ifdef _WIN32
#if defined(_WIN32) && defined(HAVE_PACKET)
WSADATA winsockdata;
#endif
@ -86,11 +86,12 @@ static qboolean allowconnects = false;
#define MAX_LOOPBACK 8
#define MAX_LOOPBACK 64
typedef struct
{
qbyte data[MAX_OVERALLMSGLEN];
qbyte *data;
int datalen;
int datamax;
} loopmsg_t;
typedef struct
@ -123,6 +124,7 @@ int NetadrToSockadr (netadr_t *a, struct sockaddr_qstorage *s)
((struct sockaddr_in*)s)->sin_port = a->port;
return sizeof(struct sockaddr_in);
case NA_TLSV4:
case NA_TCP:
case NA_IP:
memset (s, 0, sizeof(struct sockaddr_in));
@ -144,6 +146,7 @@ int NetadrToSockadr (netadr_t *a, struct sockaddr_qstorage *s)
((struct sockaddr_in6*)s)->sin6_port = a->port;
return sizeof(struct sockaddr_in6);
case NA_TLSV6:
case NA_TCPV6:
case NA_IPV6:
memset (s, 0, sizeof(struct sockaddr_in6));
@ -272,7 +275,7 @@ qboolean NET_CompareAdr (netadr_t *a, netadr_t *b)
#endif
#ifdef HAVE_IPV4
if (a->type == NA_IP || a->type == NA_BROADCAST_IP || a->type == NA_TCP)
if (a->type == NA_IP || a->type == NA_BROADCAST_IP || a->type == NA_TCP || a->type == NA_TLSV4)
{
if ((memcmp(a->address.ip, b->address.ip, sizeof(a->address.ip)) == 0) && a->port == b->port)
return true;
@ -281,7 +284,7 @@ qboolean NET_CompareAdr (netadr_t *a, netadr_t *b)
#endif
#ifdef IPPROTO_IPV6
if (a->type == NA_IPV6 || a->type == NA_BROADCAST_IP6 || a->type == NA_TCPV6)
if (a->type == NA_IPV6 || a->type == NA_BROADCAST_IP6 || a->type == NA_TCPV6 || a->type == NA_TLSV6)
{
if ((memcmp(a->address.ip6, b->address.ip6, sizeof(a->address.ip6)) == 0) && a->port == b->port)
return true;
@ -327,7 +330,7 @@ qboolean NET_CompareBaseAdr (netadr_t *a, netadr_t *b)
return true;
#ifdef HAVE_IPV4
if (a->type == NA_IP || a->type == NA_TCP)
if (a->type == NA_IP || a->type == NA_TCP || a->type == NA_TLSV4)
{
if ((memcmp(a->address.ip, b->address.ip, sizeof(a->address.ip)) == 0))
return true;
@ -335,7 +338,7 @@ qboolean NET_CompareBaseAdr (netadr_t *a, netadr_t *b)
}
#endif
#ifdef IPPROTO_IPV6
if (a->type == NA_IPV6 || a->type == NA_BROADCAST_IP6)
if (a->type == NA_IPV6 || a->type == NA_TCPV6 || a->type == NA_TLSV6)
{
if ((memcmp(a->address.ip6, b->address.ip6, 16) == 0))
return true;
@ -432,10 +435,11 @@ char *NET_AdrToString (char *s, int len, netadr_t *a)
break;
#endif
#ifdef TCPCONNECT
case NA_TLSV4:
case NA_TCP:
if (len < 7)
return "?";
snprintf (s, len, "tcp://");
snprintf (s, len, (a->type == NA_TLSV4)?"tls://":"tcp://");
s += 6;
len -= 6;
//fallthrough
@ -463,10 +467,11 @@ char *NET_AdrToString (char *s, int len, netadr_t *a)
break;
#endif
#ifdef TCPCONNECT
case NA_TLSV6:
case NA_TCPV6:
if (len < 7)
return "?";
snprintf (s, len, "tcp://");
snprintf (s, len, (a->type == NA_TLSV4)?"tls://":"tcp://");
s += 6;
len -= 6;
//fallthrough
@ -562,7 +567,7 @@ char *NET_AdrToString (char *s, int len, netadr_t *a)
break;
#endif
case NA_LOOPBACK:
snprintf (s, len, "QLoopBack");
snprintf (s, len, "QLoopBack:%i", a->port);
break;
#ifdef IRCCONNECT
@ -597,12 +602,25 @@ char *NET_BaseAdrToString (char *s, int len, netadr_t *a)
a->address.ip[2],
a->address.ip[3]);
break;
case NA_TLSV4:
case NA_TLSV6:
snprintf (s, len, "tls://");
if (len > 6)
{
a->type = (a->type-NA_TLSV4)+NA_IP;
NET_BaseAdrToString(s+6, len-6, a);
a->type = (a->type-NA_IP)+NA_TLSV4;
}
break;
case NA_TCP:
snprintf (s, len, "tcp://%i.%i.%i.%i",
a->address.ip[0],
a->address.ip[1],
a->address.ip[2],
a->address.ip[3]);
case NA_TCPV6:
snprintf (s, len, "tcp://");
if (len > 6)
{
a->type = (a->type-NA_TCP)+NA_IP;
NET_BaseAdrToString(s+6, len-6, a);
a->type = (a->type-NA_IP)+NA_TCP;
}
break;
#ifdef IPPROTO_IPV6
case NA_BROADCAST_IP6:
@ -911,6 +929,16 @@ qboolean NET_StringToAdr (const char *s, int defaultport, netadr_t *a)
a->type = NA_LOOPBACK;
return true;
}
if (!strncmp(s, "QLoopBack", 9))
{
memset (a, 0, sizeof(*a));
a->type = NA_LOOPBACK;
if (s[9] == ':')
a->port = atoi(s+10);
else
a->port = defaultport;
return true;
}
#ifdef HAVE_WEBSOCKCL
if (!strncmp (s, "ws://", 5) || !strncmp (s, "wss://", 6))
@ -961,6 +989,30 @@ qboolean NET_StringToAdr (const char *s, int defaultport, netadr_t *a)
}
return false;
}
if (!strncmp (s, "tls://", 6))
{
//make sure that the rest of the address is a valid ip address (4 or 6)
if (!NET_StringToSockaddr (s+6, defaultport, &sadr, NULL, NULL))
{
a->type = NA_INVALID;
return false;
}
SockadrToNetadr (&sadr, a);
if (a->type == NA_IP)
{
a->type = NA_TLSV4;
return true;
}
if (a->type == NA_IPV6)
{
a->type = NA_TLSV6;
return true;
}
return false;
}
#endif
#ifdef IRCCONNECT
if (!strncmp (s, "irc://", 6))
@ -1046,6 +1098,8 @@ void NET_IntegerToMask (netadr_t *a, netadr_t *amask, int bits)
{
case NA_INVALID:
break;
case NA_TCP:
case NA_TLSV4:
case NA_IP:
case NA_BROADCAST_IP:
n = amask->address.ip;
@ -1065,6 +1119,8 @@ void NET_IntegerToMask (netadr_t *a, netadr_t *amask, int bits)
*n = i;
}
break;
case NA_TCPV6:
case NA_TLSV6:
case NA_IPV6:
case NA_BROADCAST_IP6:
#ifdef IPPROTO_IPV6
@ -1112,8 +1168,6 @@ void NET_IntegerToMask (netadr_t *a, netadr_t *amask, int bits)
// warning: enumeration value âNA_*â not handled in switch
case NA_NATPMP:
case NA_WEBSOCKET:
case NA_TCP:
case NA_TCPV6:
case NA_IRC:
break;
@ -1530,12 +1584,13 @@ qboolean NET_GetLoopPacket (int sock, netadr_t *from, sizebuf_t *message)
from->type = NA_LOOPBACK;
message->packing = SZ_RAWBYTES;
message->currentbit = 0;
loop->msgs[i].datalen = 0;
return true;
}
void NET_SendLoopPacket (int sock, int length, void *data, netadr_t *to)
void NET_SendLoopPacket (int sock, int length, const void *data, netadr_t *to)
{
int i;
loopback_t *loop;
@ -1543,14 +1598,16 @@ void NET_SendLoopPacket (int sock, int length, void *data, netadr_t *to)
sock &= 1;
loop = &loopbacks[sock^1];
if (length > sizeof(loop->msgs[i].data))
{
Con_Printf("NET_SendLoopPacket: Loopback buffer is too small");
return;
}
i = loop->send & (MAX_LOOPBACK-1);
if (length > loop->msgs[i].datamax)
{
loop->msgs[i].datamax = length + 1024;
BZ_Free(loop->msgs[i].data);
loop->msgs[i].data = BZ_Malloc(loop->msgs[i].datamax);
}
if (loop->msgs[i].datalen)
Con_Printf("Warning: loopback queue overflow\n");
loop->send++;
memcpy (loop->msgs[i].data, data, length);
@ -1582,7 +1639,7 @@ int FTENET_Loop_SetReceiveFDSet(ftenet_generic_connection_t *gcon, fd_set *fdset
}
#endif
qboolean FTENET_Loop_SendPacket(ftenet_generic_connection_t *con, int length, void *data, netadr_t *to)
qboolean FTENET_Loop_SendPacket(ftenet_generic_connection_t *con, int length, const void *data, netadr_t *to)
{
if (to->type == NA_LOOPBACK)
{
@ -1646,6 +1703,8 @@ static ftenet_generic_connection_t *FTENET_UDP4_EstablishConnection(qboolean iss
static ftenet_generic_connection_t *FTENET_UDP6_EstablishConnection(qboolean isserver, const char *address);
static ftenet_generic_connection_t *FTENET_TCP4Connect_EstablishConnection(qboolean isserver, const char *address);
static ftenet_generic_connection_t *FTENET_TCP6Connect_EstablishConnection(qboolean isserver, const char *address);
static ftenet_generic_connection_t *FTENET_TLS4Connect_EstablishConnection(qboolean isserver, const char *address);
static ftenet_generic_connection_t *FTENET_TLS6Connect_EstablishConnection(qboolean isserver, const char *address);
#ifdef USEIPX
static ftenet_generic_connection_t *FTENET_IPX_EstablishConnection(qboolean isserver, const char *address);
#endif
@ -1880,7 +1939,7 @@ qboolean FTENET_NATPMP_GetPacket(struct ftenet_generic_connection_s *con)
}
return false;
}
qboolean FTENET_NATPMP_SendPacket(struct ftenet_generic_connection_s *con, int length, void *data, netadr_t *to)
qboolean FTENET_NATPMP_SendPacket(struct ftenet_generic_connection_s *con, int length, const void *data, netadr_t *to)
{
return false;
}
@ -2015,9 +2074,11 @@ qboolean FTENET_AddToCollection(ftenet_connections_t *col, const char *name, con
#endif
#ifdef TCPCONNECT
case NA_TCP: establish = FTENET_TCP4Connect_EstablishConnection; break;
case NA_TLSV4: establish = FTENET_TLS4Connect_EstablishConnection; break;
#endif
#if defined(TCPCONNECT) && defined(IPPROTO_IPV6)
case NA_TCPV6: establish = FTENET_TCP6Connect_EstablishConnection; break;
case NA_TLSV6: establish = FTENET_TLS6Connect_EstablishConnection; break;
#endif
}
@ -2048,7 +2109,7 @@ void FTENET_Generic_Close(ftenet_generic_connection_t *con)
Z_Free(con);
}
#ifdef _WIN32
#if defined(_WIN32) && defined(HAVE_PACKET)
int FTENET_GetLocalAddress(int port, qboolean ipx, qboolean ipv4, qboolean ipv6, unsigned int *adrflags, netadr_t *addresses, int maxaddresses)
{
//in win32, we can look up our own hostname to retrieve a list of local interface addresses.
@ -2375,7 +2436,7 @@ qboolean FTENET_Generic_GetPacket(ftenet_generic_connection_t *con)
#endif
}
qboolean FTENET_Generic_SendPacket(ftenet_generic_connection_t *con, int length, void *data, netadr_t *to)
qboolean FTENET_Generic_SendPacket(ftenet_generic_connection_t *con, int length, const void *data, netadr_t *to)
{
#ifndef HAVE_PACKET
return false;
@ -2646,7 +2707,7 @@ ftenet_generic_connection_t *FTENET_IPX_EstablishConnection(qboolean isserver, c
#ifdef TCPCONNECT
typedef struct ftenet_tcpconnect_stream_s {
SOCKET socketnum;
vfsfile_t *clientstream;
int inlen;
int outlen;
@ -2662,16 +2723,19 @@ typedef struct ftenet_tcpconnect_stream_s {
} clienttype;
char inbuffer[3000];
char outbuffer[3000];
vfsfile_t *file;
vfsfile_t *dlfile; //if the client looked like an http client, this is the file that they're downloading.
float timeouttime;
netadr_t remoteaddr;
struct ftenet_tcpconnect_stream_s *next;
SOCKET socketnum; //for select.
int fakesequence; //TCPC_WEBSOCKETNQ
} ftenet_tcpconnect_stream_t;
typedef struct {
ftenet_generic_connection_t generic;
qboolean tls;
int active;
ftenet_tcpconnect_stream_t *tcpstreams;
@ -2717,7 +2781,6 @@ qboolean FTENET_TCPConnect_GetPacket(ftenet_generic_connection_t *gcon)
{
ftenet_tcpconnect_connection_t *con = (ftenet_tcpconnect_connection_t*)gcon;
int ret;
int err;
char adr[MAX_ADR_SIZE];
struct sockaddr_qstorage from;
int fromlen;
@ -2727,7 +2790,7 @@ qboolean FTENET_TCPConnect_GetPacket(ftenet_generic_connection_t *gcon)
st = con->tcpstreams;
//remove any stale ones
while (con->tcpstreams && con->tcpstreams->socketnum == INVALID_SOCKET)
while (con->tcpstreams && con->tcpstreams->clientstream == NULL)
{
st = con->tcpstreams;
con->tcpstreams = con->tcpstreams->next;
@ -2737,7 +2800,7 @@ qboolean FTENET_TCPConnect_GetPacket(ftenet_generic_connection_t *gcon)
for (st = con->tcpstreams; st; st = st->next)
{//client receiving only via tcp
while (st->next && st->next->socketnum == INVALID_SOCKET)
while (st->next && st->next->clientstream == NULL)
{
ftenet_tcpconnect_stream_t *temp;
temp = st->next;
@ -2754,34 +2817,14 @@ qboolean FTENET_TCPConnect_GetPacket(ftenet_generic_connection_t *gcon)
goto closesvstream;
}
ret = recv(st->socketnum, st->inbuffer+st->inlen, sizeof(st->inbuffer)-st->inlen, 0);
if (ret == 0)
ret = VFS_READ(st->clientstream, st->inbuffer+st->inlen, sizeof(st->inbuffer)-st->inlen);
if (ret < 0)
{
Con_Printf ("tcp peer %s closed connection\n", NET_AdrToString (adr, sizeof(adr), &st->remoteaddr));
goto closesvstream;
}
else if (ret == -1)
{
err = neterrno();
if (err == NET_EWOULDBLOCK)
ret = 0;
else
{
if (err == NET_ECONNABORTED || err == NET_ECONNRESET)
{
Con_TPrintf ("Connection lost or aborted\n"); //server died/connection lost.
}
else if (err == NET_ENOTCONN)
Con_Printf ("TCPConnect_GetPacket: connection failed\n");
else
Con_Printf ("TCPConnect_GetPacket: Error (%i): %s\n", err, strerror(err));
closesvstream:
closesocket(st->socketnum);
st->socketnum = INVALID_SOCKET;
continue;
}
VFS_CLOSE(st->clientstream);
st->clientstream = NULL;
continue;
}
st->inlen += ret;
@ -2799,7 +2842,7 @@ closesvstream:
if (con->generic.islisten)
{
//send the qizmo handshake response.
send(st->socketnum, "qizmo\n", 6, 0);
VFS_WRITE(st->clientstream, "qizmo\n", 6);
}
}
else if (con->generic.islisten && !strncmp(st->inbuffer, "GET ", 4))
@ -2943,7 +2986,7 @@ closesvstream:
"Sec-WebSocket-Version: 13\r\n"
"\r\n");
//send the websocket handshake rejection.
send(st->socketnum, resp, strlen(resp), 0);
VFS_WRITE(st->clientstream, resp, strlen(resp));
goto closesvstream;
}
@ -2985,7 +3028,7 @@ closesvstream:
"%s"
"\r\n", acceptkey, protoname);
//send the websocket handshake response.
send(st->socketnum, resp, strlen(resp), 0);
VFS_WRITE(st->clientstream, resp, strlen(resp));
//and the connection is okay
@ -3060,7 +3103,7 @@ closesvstream:
}
//send the websocket handshake rejection.
send(st->socketnum, resp, strlen(resp), 0);
VFS_WRITE(st->clientstream, resp, strlen(resp));
goto closesvstream;
}
@ -3069,7 +3112,7 @@ closesvstream:
else
{
handshakeerror:
Con_Printf ("Unknown TCP handshake from %s\n", NET_AdrToString (adr, sizeof(adr), &net_from));
Con_Printf ("Unknown TCP handshake from %s\n", NET_AdrToString (adr, sizeof(adr), &st->remoteaddr));
goto closesvstream;
}
@ -3078,7 +3121,7 @@ handshakeerror:
if (st->outlen)
{ /*try and flush the old data*/
int done;
done = send(st->socketnum, st->outbuffer, st->outlen, 0);
done = VFS_WRITE(st->clientstream, st->outbuffer, st->outlen);
if (done > 0)
{
memmove(st->outbuffer, st->outbuffer + done, st->outlen - done);
@ -3089,11 +3132,11 @@ handshakeerror:
}
if (!st->outlen)
{
st->outlen = VFS_READ(st->file, st->outbuffer, sizeof(st->outbuffer));
st->outlen = VFS_READ(st->dlfile, st->outbuffer, sizeof(st->outbuffer));
if (st->outlen <= 0)
{
VFS_CLOSE(st->file);
st->file = NULL;
VFS_CLOSE(st->dlfile);
st->dlfile = NULL;
st->clienttype = TCPC_UNKNOWN;
Con_Printf ("Outgoing file transfer complete\n");
}
@ -3313,25 +3356,41 @@ handshakeerror:
newsock = accept(con->generic.thesocket, (struct sockaddr*)&from, &fromlen);
if (newsock != INVALID_SOCKET)
{
char tmpbuf[256];
int _true = true;
ioctlsocket(newsock, FIONBIO, (u_long *)&_true);
setsockopt(newsock, IPPROTO_TCP, TCP_NODELAY, (char *)&_true, sizeof(_true));
con->active++;
st = Z_Malloc(sizeof(*con->tcpstreams));
/*grab the net address*/
SockadrToNetadr(&from, &st->remoteaddr);
st->clienttype = TCPC_UNKNOWN;
st->next = con->tcpstreams;
con->tcpstreams = st;
st->socketnum = newsock;
st->clientstream = FS_OpenTCPSocket(newsock, false, NET_AdrToString(tmpbuf, sizeof(tmpbuf), &st->remoteaddr));
st->inlen = 0;
/*grab the net address*/
SockadrToNetadr(&from, &st->remoteaddr);
/*sockadr doesn't contain transport info, so fix that up here*/
if (st->remoteaddr.type == NA_IP)
st->remoteaddr.type = NA_TCP;
else if (st->remoteaddr.type == NA_IPV6)
st->remoteaddr.type = NA_TCPV6;
#ifdef HAVE_SSL
if (con->tls) //if we're meant to be using tls, wrap the stream in a tls connection
{
st->clientstream = FS_OpenSSL(NULL, st->clientstream, true);
/*sockadr doesn't contain transport info, so fix that up here*/
if (st->remoteaddr.type == NA_IP)
st->remoteaddr.type = NA_TLSV4;
else if (st->remoteaddr.type == NA_IPV6)
st->remoteaddr.type = NA_TLSV6;
}
else
#endif
{
/*sockadr doesn't contain transport info, so fix that up here*/
if (st->remoteaddr.type == NA_IP)
st->remoteaddr.type = NA_TCP;
else if (st->remoteaddr.type == NA_IPV6)
st->remoteaddr.type = NA_TCPV6;
}
st->timeouttime = timeval + 30;
}
@ -3339,14 +3398,14 @@ handshakeerror:
return false;
}
qboolean FTENET_TCPConnect_SendPacket(ftenet_generic_connection_t *gcon, int length, void *data, netadr_t *to)
qboolean FTENET_TCPConnect_SendPacket(ftenet_generic_connection_t *gcon, int length, const void *data, netadr_t *to)
{
ftenet_tcpconnect_connection_t *con = (ftenet_tcpconnect_connection_t*)gcon;
ftenet_tcpconnect_stream_t *st;
for (st = con->tcpstreams; st; st = st->next)
{
if (st->socketnum == INVALID_SOCKET)
if (st->clientstream == NULL)
continue;
if (NET_CompareAdr(to, &st->remoteaddr))
@ -3459,7 +3518,7 @@ qboolean FTENET_TCPConnect_SendPacket(ftenet_generic_connection_t *gcon, int len
if (st->outlen)
{ /*try and flush the old data*/
int done;
done = send(st->socketnum, st->outbuffer, st->outlen, 0);
done = VFS_WRITE(st->clientstream, st->outbuffer, st->outlen);
if (done > 0)
{
memmove(st->outbuffer, st->outbuffer + done, st->outlen - done);
@ -3486,8 +3545,8 @@ void FTENET_TCPConnect_Close(ftenet_generic_connection_t *gcon)
st = con->tcpstreams;
con->tcpstreams = st->next;
if (st->socketnum != INVALID_SOCKET)
closesocket(st->socketnum);
if (st->clientstream != NULL)
VFS_CLOSE(st->clientstream);
BZ_Free(st);
}
@ -3504,7 +3563,7 @@ int FTENET_TCPConnect_SetReceiveFDSet(ftenet_generic_connection_t *gcon, fd_set
for (st = con->tcpstreams; st; st = st->next)
{
if (st->socketnum == INVALID_SOCKET)
if (st->clientstream == NULL || st->socketnum == INVALID_SOCKET)
continue;
FD_SET(st->socketnum, fdset); // network socket
if (maxfd < st->socketnum)
@ -3531,12 +3590,14 @@ ftenet_generic_connection_t *FTENET_TCPConnect_EstablishConnection(int affamily,
netadr_t adr;
struct sockaddr_qstorage qs;
int family;
if (!strncmp(address, "tcp://", 6))
address += 6;
if (!strncmp(address, "ws://", 5))
address += 5;
if (!strncmp(address, "wss://", 6))
address += 6;
#ifndef HAVE_SSL
if ((affamily == NA_TLSV4 || affamily == NA_TLSV6))
{
Con_Printf("tls not supported in this build\n");
return NULL;
}
#endif
if (isserver)
{
@ -3544,10 +3605,22 @@ ftenet_generic_connection_t *FTENET_TCPConnect_EstablishConnection(int affamily,
//unable to listen on tcp if we have no packet interface
return NULL;
#else
if (!strncmp(address, "tls://", 6))
address += 6;
if (!strncmp(address, "tcp://", 6))
address += 6;
if (!strncmp(address, "ws://", 5))
address += 5;
if (!strncmp(address, "wss://", 6))
address += 6;
if (!NET_PortToAdr(affamily, address, &adr))
return NULL; //couldn't resolve the name
if (adr.type == NA_IP)
adr.type = NA_TCP;
else if (adr.type == NA_IPV6)
adr.type = NA_TCPV6;
temp = NetadrToSockadr(&adr, &qs);
family = ((struct sockaddr_in*)&qs)->sin_family;
@ -3579,6 +3652,8 @@ ftenet_generic_connection_t *FTENET_TCPConnect_EstablishConnection(int affamily,
if (adr.type == NA_IP)
adr.type = NA_TCP;
else if (adr.type == NA_IPV6)
adr.type = NA_TCPV6;
newsocket = TCP_OpenStream(&adr);
if (newsocket == INVALID_SOCKET)
return NULL;
@ -3590,6 +3665,7 @@ ftenet_generic_connection_t *FTENET_TCPConnect_EstablishConnection(int affamily,
newcon = Z_Malloc(sizeof(*newcon));
if (newcon)
{
newcon->tls = (affamily == NA_TLSV4 || affamily == NA_TLSV6);
if (isserver)
newcon->generic.GetLocalAddresses = FTENET_Generic_GetLocalAddresses;
newcon->generic.GetPacket = FTENET_TCPConnect_GetPacket;
@ -3613,16 +3689,22 @@ ftenet_generic_connection_t *FTENET_TCPConnect_EstablishConnection(int affamily,
newcon->tcpstreams = Z_Malloc(sizeof(*newcon->tcpstreams));
newcon->tcpstreams->next = NULL;
newcon->tcpstreams->socketnum = newsocket;
newcon->tcpstreams->clientstream = FS_OpenTCPSocket(newsocket, true, address);
newcon->tcpstreams->inlen = 0;
newcon->tcpstreams->remoteaddr = adr;
#ifdef HAVE_SSL
if (newcon->tls) //if we're meant to be using tls, wrap the stream in a tls connection
newcon->tcpstreams->clientstream = FS_OpenSSL(address, newcon->tcpstreams->clientstream, false);
#endif
#ifdef FTE_TARGET_WEB
newcon->tcpstreams->clienttype = TCPC_UNFRAMED;
#else
//send the qizmo greeting.
newcon->tcpstreams->clienttype = TCPC_UNKNOWN;
send(newsocket, "qizmo\n", 6, 0);
VFS_WRITE(newcon->tcpstreams->clientstream, "qizmo\n", 6);
#endif
newcon->tcpstreams->timeouttime = Sys_DoubleTime() + 30;
@ -3647,12 +3729,20 @@ ftenet_generic_connection_t *FTENET_TCP6Connect_EstablishConnection(qboolean iss
{
return FTENET_TCPConnect_EstablishConnection(NA_TCPV6, isserver, address);
}
ftenet_generic_connection_t *FTENET_TLS6Connect_EstablishConnection(qboolean isserver, const char *address)
{
return FTENET_TCPConnect_EstablishConnection(NA_TLSV6, isserver, address);
}
#endif
ftenet_generic_connection_t *FTENET_TCP4Connect_EstablishConnection(qboolean isserver, const char *address)
{
return FTENET_TCPConnect_EstablishConnection(NA_TCP, isserver, address);
}
ftenet_generic_connection_t *FTENET_TLS4Connect_EstablishConnection(qboolean isserver, const char *address)
{
return FTENET_TCPConnect_EstablishConnection(NA_TLSV4, isserver, address);
}
#endif
@ -4064,7 +4154,7 @@ qboolean FTENET_IRCConnect_GetPacket(ftenet_generic_connection_t *gcon)
return false;
}
qboolean FTENET_IRCConnect_SendPacket(ftenet_generic_connection_t *gcon, int length, void *data, netadr_t *to)
qboolean FTENET_IRCConnect_SendPacket(ftenet_generic_connection_t *gcon, int length, const void *data, netadr_t *to)
{
ftenet_ircconnect_connection_t *con = (ftenet_ircconnect_connection_t*)gcon;
@ -4677,7 +4767,7 @@ int NET_LocalAddressForRemote(ftenet_connections_t *collection, netadr_t *remote
return collection->conn[remote->connum-1]->GetLocalAddresses(collection->conn[remote->connum-1], &adrflags, local, 1);
}
qboolean NET_SendPacket (netsrc_t netsrc, int length, void *data, netadr_t *to)
qboolean NET_SendPacket (netsrc_t netsrc, int length, const void *data, netadr_t *to)
{
// char buffer[64];
ftenet_connections_t *collection;
@ -4739,6 +4829,8 @@ qboolean NET_EnsureRoute(ftenet_connections_t *collection, char *routename, char
switch(adr.type)
{
case NA_WEBSOCKET:
case NA_TLSV4:
case NA_TLSV6:
case NA_TCP:
case NA_TCPV6:
case NA_IRC:
@ -5205,7 +5297,7 @@ qboolean NET_Sleep(int msec, qboolean stdinissocket)
//thus its only needed on windows and with ipv4.
void NET_GetLocalAddress (int socket, netadr_t *out)
{
#ifdef _WIN32
#if defined(_WIN32) && defined(HAVE_PACKET)
char buff[512];
char adrbuf[MAX_ADR_SIZE];
struct sockaddr_qstorage address;
@ -5345,7 +5437,7 @@ NET_Init
*/
void NET_Init (void)
{
#ifdef _WIN32
#if defined(_WIN32) && defined(HAVE_PACKET)
int r;
#ifdef IPPROTO_IPV6
HMODULE ws2_32dll;
@ -5365,7 +5457,7 @@ void NET_Init (void)
pgetaddrinfo = NULL;
#endif
r = WSAStartup (MAKEWORD(1, 1), &winsockdata);
r = WSAStartup (MAKEWORD(2, 2), &winsockdata);
if (r)
Sys_Error ("Winsock initialization failed.");
@ -5605,7 +5697,7 @@ void NET_Shutdown (void)
#endif
#ifdef _WIN32
#if defined(_WIN32) && defined(HAVE_PACKET)
#ifdef SERVERTONLY
if (!serverthreadID) //running as subsystem of client. Don't close all of it's sockets too.
#endif
@ -5781,37 +5873,42 @@ qofs_t QDECL VFSTCP_GetLen (struct vfsfile_s *file)
{
return 0;
}
void QDECL VFSTCP_Close (struct vfsfile_s *file)
qboolean QDECL VFSTCP_Close (struct vfsfile_s *file)
{
VFSTCP_Error((tcpfile_t*)file);
Z_Free(file);
tcpfile_t *f = (tcpfile_t *)file;
qboolean success = f->sock != INVALID_SOCKET;
VFSTCP_Error(f);
Z_Free(f);
return success;
}
vfsfile_t *FS_OpenTCP(const char *name, int defaultport)
vfsfile_t *FS_OpenTCPSocket(SOCKET sock, qboolean conpending, const char *peername)
{
tcpfile_t *newf;
int sock;
if (sock == INVALID_SOCKET)
return NULL;
newf = Z_Malloc(sizeof(*newf) + strlen(peername));
strcpy(newf->peer, peername);
newf->conpending = conpending;
newf->sock = sock;
newf->funcs.Close = VFSTCP_Close;
newf->funcs.Flush = NULL;
newf->funcs.GetLen = VFSTCP_GetLen;
newf->funcs.ReadBytes = VFSTCP_ReadBytes;
newf->funcs.Seek = VFSTCP_Seek;
newf->funcs.Tell = VFSTCP_Tell;
newf->funcs.WriteBytes = VFSTCP_WriteBytes;
newf->funcs.seekingisabadplan = true;
return &newf->funcs;
}
vfsfile_t *FS_OpenTCP(const char *name, int defaultport)
{
netadr_t adr = {0};
if (NET_StringToAdr(name, defaultport, &adr))
{
sock = TCP_OpenStream(&adr);
if (sock == INVALID_SOCKET)
return NULL;
newf = Z_Malloc(sizeof(*newf) + strlen(name));
strcpy(newf->peer, name);
newf->conpending = true;
newf->sock = sock;
newf->funcs.Close = VFSTCP_Close;
newf->funcs.Flush = NULL;
newf->funcs.GetLen = VFSTCP_GetLen;
newf->funcs.ReadBytes = VFSTCP_ReadBytes;
newf->funcs.Seek = VFSTCP_Seek;
newf->funcs.Tell = VFSTCP_Tell;
newf->funcs.WriteBytes = VFSTCP_WriteBytes;
newf->funcs.seekingisabadplan = true;
return &newf->funcs;
return FS_OpenTCPSocket(TCP_OpenStream(&adr), true, name);
}
else
return NULL;

View File

@ -1,11 +1,11 @@
#if !defined(NACL) && !defined(FTE_TARGET_WEB)
#if !defined(NACL) && !defined(FTE_TARGET_WEB) && !defined(WINRT)
#define HAVE_IPV4 //says we can send and receive AF_INET ipv4 udp packets.
#define HAVE_TCP //says we can use tcp too (either ipv4 or ipv6)
#define HAVE_PACKET //if we have the socket api at all...
#endif
#if defined(NACL) || defined(FTE_TARGET_WEB)
#ifndef HAVE_PACKET
struct sockaddr
{
@ -30,12 +30,16 @@
char url[64];
};
#define ntohs BigShort
#define htons BigShort
#define htonl BigLong
#define ntohl BigLong
#elif defined(_WIN32)
#ifdef _MSC_VER
#define USEIPX
#endif
#define WIN32_LEAN_AND_MEAN
#define byte winbyte
#include <windows.h>
#include <winsock2.h>
// #include "winquake.h"
@ -99,34 +103,6 @@
#ifndef IPV6_V6ONLY
#define IPV6_V6ONLY 27
#endif
#ifdef EADDRNOTAVAIL
#undef EADDRNOTAVAIL
#endif
#ifdef EAFNOSUPPORT
#undef EAFNOSUPPORT
#endif
#ifdef ECONNABORTED
#undef ECONNABORTED
#endif
#ifdef ECONNREFUSED
#undef ECONNREFUSED
#endif
#ifdef ECONNREFUSED
#undef ECONNREFUSED
#endif
#ifdef EMSGSIZE
#undef EMSGSIZE
#endif
#ifdef EWOULDBLOCK
#undef EWOULDBLOCK
#endif
#ifdef EACCES
#undef EACCES
#endif
#ifdef ENOTCONN
#undef ENOTCONN
#endif
#else
#include <sys/time.h>
#include <sys/types.h>
@ -278,7 +254,7 @@ typedef struct ftenet_generic_connection_s {
int (*GetLocalAddresses)(struct ftenet_generic_connection_s *con, unsigned int *adrflags, netadr_t *addresses, int maxaddresses);
qboolean (*ChangeLocalAddress)(struct ftenet_generic_connection_s *con, const char *newaddress);
qboolean (*GetPacket)(struct ftenet_generic_connection_s *con);
qboolean (*SendPacket)(struct ftenet_generic_connection_s *con, int length, void *data, netadr_t *to);
qboolean (*SendPacket)(struct ftenet_generic_connection_s *con, int length, const void *data, netadr_t *to);
void (*Close)(struct ftenet_generic_connection_s *con);
#ifdef HAVE_PACKET
int (*SetReceiveFDSet) (struct ftenet_generic_connection_s *con, fd_set *fdset); /*set for connections which have multiple sockets (ie: listening tcp connections)*/
@ -310,3 +286,8 @@ void FTENET_CloseCollection(ftenet_connections_t *col);
qboolean FTENET_AddToCollection(struct ftenet_connections_s *col, const char *name, const char *address, netadrtype_t addrtype, qboolean islisten);
int NET_EnumerateAddresses(ftenet_connections_t *collection, struct ftenet_generic_connection_s **con, int *adrflags, netadr_t *addresses, int maxaddresses);
vfsfile_t *FS_OpenSSL(const char *hostname, vfsfile_t *source, qboolean server);
#ifdef HAVE_PACKET
vfsfile_t *FS_OpenTCPSocket(SOCKET socket, qboolean conpending, const char *peername); //conpending allows us to reject any writes until the connection has succeeded
#endif
vfsfile_t *FS_OpenTCP(const char *name, int defaultport);

View File

@ -123,7 +123,7 @@ typedef struct {
char *name1;
char *name2;
int (*FindParticleType) (char *name);
int (*FindParticleType) (const char *name);
qboolean (*ParticleQuery) (int type, int body, char *outstr, int outstrlen);
int (*RunParticleEffectTypeString) (vec3_t org, vec3_t dir, float count, char *name);

View File

@ -764,7 +764,7 @@ static int Plug_NewStreamHandle(plugstream_e type)
return i;
}
#ifndef NACL
#ifdef HAVE_PACKET
//EBUILTIN(int, NET_TCPListen, (char *ip, int port, int maxcount));
//returns a new socket with listen enabled.
static qintptr_t VARGS Plug_Net_TCPListen(void *offset, quintptr_t mask, const qintptr_t *arg)
@ -939,6 +939,7 @@ qintptr_t VARGS Plug_FS_Open(void *offset, quintptr_t mask, const qintptr_t *arg
if (VM_OOB(arg[1], sizeof(int)))
return -2;
ret = VM_POINTER(arg[1]);
*ret = -1;
switch(arg[2])
{
@ -1059,7 +1060,7 @@ void Plug_Net_Close_Internal(int handle)
pluginstreamarray[handle].vfs = NULL;
break;
case STREAM_SOCKET:
#ifndef NACL
#ifdef HAVE_PACKET
closesocket(pluginstreamarray[handle].socket);
#endif
break;
@ -1081,7 +1082,7 @@ qintptr_t VARGS Plug_Net_Recv(void *offset, quintptr_t mask, const qintptr_t *ar
return -2;
switch(pluginstreamarray[handle].type)
{
#ifndef NACL
#ifdef HAVE_PACKET
case STREAM_SOCKET:
read = recv(pluginstreamarray[handle].socket, dest, destlen, 0);
if (read < 0)
@ -1112,7 +1113,7 @@ qintptr_t VARGS Plug_Net_Send(void *offset, quintptr_t mask, const qintptr_t *ar
return -2;
switch(pluginstreamarray[handle].type)
{
#ifndef NACL
#ifdef HAVE_PACKET
case STREAM_SOCKET:
written = send(pluginstreamarray[handle].socket, src, srclen, 0);
if (written < 0)
@ -1157,7 +1158,7 @@ qintptr_t VARGS Plug_Net_SendTo(void *offset, quintptr_t mask, const qintptr_t *
return -2;
switch(pluginstreamarray[handle].type)
{
#ifndef NACL
#ifdef HAVE_PACKET
case STREAM_SOCKET:
written = sendto(pluginstreamarray[handle].socket, src, srclen, 0, (struct sockaddr*)&sockaddr, sizeof(sockaddr));
if (written < 0)
@ -1289,7 +1290,7 @@ void Plug_Initialise(qboolean fromgamedir)
Plug_RegisterBuiltin("Cvar_GetString", Plug_Cvar_GetString, 0);
Plug_RegisterBuiltin("Cvar_GetFloat", Plug_Cvar_GetFloat, 0);
#ifndef NACL
#ifdef HAVE_PACKET
Plug_RegisterBuiltin("Net_TCPListen", Plug_Net_TCPListen, 0);
Plug_RegisterBuiltin("Net_Accept", Plug_Net_Accept, 0);
Plug_RegisterBuiltin("Net_TCPConnect", Plug_Net_TCPConnect, 0);

View File

@ -14,16 +14,20 @@
static char *cvargroup_progs = "Progs variables";
cvar_t sv_gameplayfix_blowupfallenzombies = CVARD("sv_gameplayfix_blowupfallenzombies", "0", "Allow findradius to find non-solid entities. This may break certain mods.");
cvar_t pr_droptofloorunits = CVAR("pr_droptofloorunits", "");
cvar_t pr_brokenfloatconvert = SCVAR("pr_brokenfloatconvert", "0");
cvar_t pr_tempstringcount = SCVAR("pr_tempstringcount", "");//"16");
cvar_t pr_tempstringsize = SCVAR("pr_tempstringsize", "4096");
cvar_t pr_enable_uriget = SCVAR("pr_enable_uriget", "1");
int tokenizeqc(char *str, qboolean dpfuckage);
int tokenizeqc(const char *str, qboolean dpfuckage);
void skel_info_f(void);
void skel_generateragdoll_f(void);
void PF_Common_RegisterCvars(void)
{
Cvar_Register (&sv_gameplayfix_blowupfallenzombies, cvargroup_progs);
Cvar_Register (&pr_droptofloorunits, cvargroup_progs);
Cvar_Register (&pr_brokenfloatconvert, cvargroup_progs);
Cvar_Register (&pr_tempstringcount, cvargroup_progs);
Cvar_Register (&pr_tempstringsize, cvargroup_progs);
@ -43,7 +47,8 @@ char *PF_VarString (pubprogfuncs_t *prinst, int first, struct globalvars_s *pr_g
int i;
static char buffer[2][VARSTRINGLEN];
static int bufnum;
char *s, *out;
const char *s;
char *out;
out = buffer[(bufnum++)&1];
@ -169,7 +174,7 @@ void VARGS PR_BIError(pubprogfuncs_t *progfuncs, char *format, ...)
vsnprintf (string,sizeof(string)-1, format,argptr);
va_end (argptr);
if (developer.value)
if (developer.value || !progfuncs)
{
struct globalvars_s *pr_globals = PR_globals(progfuncs, PR_CURRENT);
Con_Printf("%s\n", string);
@ -625,7 +630,7 @@ void QCBUILTIN PF_setattachment(pubprogfuncs_t *prinst, struct globalvars_s *pr_
{
wedict_t *e = G_WEDICT(prinst, OFS_PARM0);
wedict_t *tagentity = G_WEDICT(prinst, OFS_PARM1);
char *tagname = PR_GetStringOfs(prinst, OFS_PARM2);
const char *tagname = PR_GetStringOfs(prinst, OFS_PARM2);
world_t *world = prinst->parms->user;
model_t *model;
@ -829,7 +834,7 @@ void QCBUILTIN PF_FindString (pubprogfuncs_t *prinst, struct globalvars_s *pr_gl
{
int e;
int f;
char *s;
const char *s;
string_t t;
wedict_t *ed;
@ -867,7 +872,7 @@ void QCBUILTIN PF_FindString (pubprogfuncs_t *prinst, struct globalvars_s *pr_gl
//string(string cvarname) cvar_string
void QCBUILTIN PF_cvar_string (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *str = PR_GetStringOfs(prinst, OFS_PARM0);
const char *str = PR_GetStringOfs(prinst, OFS_PARM0);
cvar_t *cv = Cvar_Get(str, "", 0, "QC variables");
RETURN_CSTRING(cv->string);
}
@ -875,7 +880,7 @@ void QCBUILTIN PF_cvar_string (pubprogfuncs_t *prinst, struct globalvars_s *pr_g
//string(string cvarname) cvar_defstring
void QCBUILTIN PF_cvar_defstring (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *str = PR_GetStringOfs(prinst, OFS_PARM0);
const char *str = PR_GetStringOfs(prinst, OFS_PARM0);
cvar_t *cv = Cvar_Get(str, "", 0, "QC variables");
RETURN_CSTRING(cv->defaultstr);
}
@ -883,7 +888,7 @@ void QCBUILTIN PF_cvar_defstring (pubprogfuncs_t *prinst, struct globalvars_s *p
//string(string cvarname) cvar_description
void QCBUILTIN PF_cvar_description (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *str = PR_GetStringOfs(prinst, OFS_PARM0);
const char *str = PR_GetStringOfs(prinst, OFS_PARM0);
cvar_t *cv = Cvar_Get(str, "", 0, "QC variables");
RETURN_CSTRING(cv->description);
}
@ -891,7 +896,7 @@ void QCBUILTIN PF_cvar_description (pubprogfuncs_t *prinst, struct globalvars_s
//float(string name) cvar_type
void QCBUILTIN PF_cvar_type (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *str = PR_GetStringOfs(prinst, OFS_PARM0);
const char *str = PR_GetStringOfs(prinst, OFS_PARM0);
int ret = 0;
cvar_t *v;
@ -914,7 +919,7 @@ void QCBUILTIN PF_cvar_type (pubprogfuncs_t *prinst, struct globalvars_s *pr_glo
//void(string cvarname, string newvalue) cvar
void QCBUILTIN PF_cvar_set (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *var_name, *val;
const char *var_name, *val;
cvar_t *var;
var_name = PR_GetStringOfs(prinst, OFS_PARM0);
@ -928,7 +933,7 @@ void QCBUILTIN PF_cvar_set (pubprogfuncs_t *prinst, struct globalvars_s *pr_glob
void QCBUILTIN PF_cvar_setlatch (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *var_name, *val;
const char *var_name, *val;
cvar_t *var;
var_name = PR_GetStringOfs(prinst, OFS_PARM0);
@ -942,7 +947,7 @@ void QCBUILTIN PF_cvar_setlatch (pubprogfuncs_t *prinst, struct globalvars_s *pr
void QCBUILTIN PF_cvar_setf (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *var_name;
const char *var_name;
float val;
cvar_t *var;
@ -959,7 +964,7 @@ void QCBUILTIN PF_cvar_setf (pubprogfuncs_t *prinst, struct globalvars_s *pr_glo
//float(string name, string value) registercvar
void QCBUILTIN PF_registercvar (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *name, *value;
const char *name, *value;
value = PR_GetStringOfs(prinst, OFS_PARM0);
if (Cvar_FindVar(value))
@ -1124,7 +1129,7 @@ void QCBUILTIN PF_hash_getkey (pubprogfuncs_t *prinst, struct globalvars_s *pr_g
void QCBUILTIN PF_hash_delete (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
pf_hashtab_t *tab = PF_hash_findtab(prinst, G_FLOAT(OFS_PARM0));
char *name = PR_GetStringOfs(prinst, OFS_PARM1);
const char *name = PR_GetStringOfs(prinst, OFS_PARM1);
pf_hashentry_t *ent = NULL;
memset(G_VECTOR(OFS_RETURN), 0, sizeof(vec3_t));
if (tab)
@ -1141,7 +1146,7 @@ void QCBUILTIN PF_hash_delete (pubprogfuncs_t *prinst, struct globalvars_s *pr_g
void QCBUILTIN PF_hash_get (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
pf_hashtab_t *tab = PF_hash_findtab(prinst, G_FLOAT(OFS_PARM0));
char *name = PR_GetStringOfs(prinst, OFS_PARM1);
const char *name = PR_GetStringOfs(prinst, OFS_PARM1);
pf_hashentry_t *ent = NULL;
if (tab)
{
@ -1181,7 +1186,7 @@ void QCBUILTIN PF_hash_getcb (pubprogfuncs_t *prinst, struct globalvars_s *pr_gl
void QCBUILTIN PF_hash_add (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
pf_hashtab_t *tab = PF_hash_findtab(prinst, G_FLOAT(OFS_PARM0));
char *name = PR_GetStringOfs(prinst, OFS_PARM1);
const char *name = PR_GetStringOfs(prinst, OFS_PARM1);
void *data = G_VECTOR(OFS_PARM2);
qboolean replace = (prinst->callargc>3)?G_FLOAT(OFS_PARM3):false;
pf_hashentry_t *ent = NULL;
@ -1191,7 +1196,7 @@ void QCBUILTIN PF_hash_add (pubprogfuncs_t *prinst, struct globalvars_s *pr_glob
Hash_Remove(&tab->tab, name);
if (tab->dupestrings)
{
char *value = PR_GetStringOfs(prinst, OFS_PARM2);
const char *value = PR_GetStringOfs(prinst, OFS_PARM2);
int nlen = strlen(name);
int vlen = strlen(data);
ent = BZ_Malloc(sizeof(*ent) + nlen+1 + vlen+1);
@ -1270,7 +1275,7 @@ pf_fopen_files_t pf_fopen_files[MAX_QC_FILES];
//returns false if the file is denied.
//fallbackread can be NULL, if the qc is not allowed to read that (original) file at all.
qboolean QC_FixFileName(char *name, char **result, char **fallbackread)
qboolean QC_FixFileName(const char *name, const char **result, const char **fallbackread)
{
if (strchr(name, ':') || //dos/win absolute path, ntfs ADS, amiga drives. reject them all.
strchr(name, '\\') || //windows-only paths.
@ -1290,7 +1295,7 @@ qboolean QC_FixFileName(char *name, char **result, char **fallbackread)
void QCBUILTIN PF_fopen (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *name = PR_GetStringOfs(prinst, OFS_PARM0);
const char *name = PR_GetStringOfs(prinst, OFS_PARM0);
int fmode = G_FLOAT(OFS_PARM1);
int fsize = G_FLOAT(OFS_PARM2);
char *fallbackread;
@ -1323,6 +1328,11 @@ void QCBUILTIN PF_fopen (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals
case FRIK_FILE_MMAP_RW:
{
vfsfile_t *f = FS_OpenVFS(pf_fopen_files[i].name, "rb", FS_GAME);
if (!f && fallbackread)
{
Q_strncpyz(pf_fopen_files[i].name, fallbackread, sizeof(pf_fopen_files[i].name));
f = FS_OpenVFS(pf_fopen_files[i].name, "rb", FS_GAME);
}
if (f)
{
pf_fopen_files[i].bufferlen = pf_fopen_files[i].len = VFS_GETLEN(f);
@ -1610,7 +1620,7 @@ void PF_fcloseall (pubprogfuncs_t *prinst)
//DP_QC_WHICHPACK
void QCBUILTIN PF_whichpack (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *srcname = PR_GetStringOfs(prinst, OFS_PARM0);
const char *srcname = PR_GetStringOfs(prinst, OFS_PARM0);
qboolean makereferenced = prinst->callargc>1?G_FLOAT(OFS_PARM1):true;
flocation_t loc;
@ -1735,8 +1745,8 @@ int QDECL search_enumerate(const char *name, qofs_t fsize, void *parm, searchpat
//float search_begin(string pattern, float caseinsensitive, float quiet) = #74;
void QCBUILTIN PF_search_begin (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{ //< 0 for error, > 0 for handle.
char *pattern = PR_GetStringOfs(prinst, OFS_PARM0);
// qboolean caseinsensative = G_FLOAT(OFS_PARM1);
const char *pattern = PR_GetStringOfs(prinst, OFS_PARM0);
// qboolean caseinsensitive = G_FLOAT(OFS_PARM1);
// qboolean quiet = G_FLOAT(OFS_PARM2);
prvmsearch_t *s;
@ -1825,14 +1835,14 @@ void PR_fclose_progs (pubprogfuncs_t *prinst)
//float isfunction(string function_name)
void QCBUILTIN PF_isfunction (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *name = PR_GetStringOfs(prinst, OFS_PARM0);
const char *name = PR_GetStringOfs(prinst, OFS_PARM0);
G_FLOAT(OFS_RETURN) = !!PR_FindFunction(prinst, name, PR_ANY);
}
//void callfunction(...)
void QCBUILTIN PF_callfunction (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *name;
const char *name;
func_t f;
if (prinst->callargc < 1)
PR_BIError(prinst, "callfunction needs at least one argument\n");
@ -1846,8 +1856,8 @@ void QCBUILTIN PF_callfunction (pubprogfuncs_t *prinst, struct globalvars_s *pr_
//void loadfromfile(string file)
void QCBUILTIN PF_loadfromfile (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *filename = PR_GetStringOfs(prinst, OFS_PARM0);
char *file = COM_LoadTempFile(filename);
const char *filename = PR_GetStringOfs(prinst, OFS_PARM0);
const char *file = COM_LoadTempFile(filename);
int size;
@ -1884,7 +1894,7 @@ void QCBUILTIN PF_writetofile(pubprogfuncs_t *prinst, struct globalvars_s *pr_gl
void QCBUILTIN PF_loadfromdata (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *file = PR_GetStringOfs(prinst, OFS_PARM0);
const char *file = PR_GetStringOfs(prinst, OFS_PARM0);
int size;
@ -1905,7 +1915,7 @@ void QCBUILTIN PF_loadfromdata (pubprogfuncs_t *prinst, struct globalvars_s *pr_
void QCBUILTIN PF_parseentitydata(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
void *ed = G_EDICT(prinst, OFS_PARM0);
char *file = PR_GetStringOfs(prinst, OFS_PARM1);
const char *file = PR_GetStringOfs(prinst, OFS_PARM1);
int size;
@ -1954,6 +1964,49 @@ void QCBUILTIN PF_edict_for_num(pubprogfuncs_t *prinst, struct globalvars_s *pr_
RETURN_EDICT(prinst, ent);
}
/*
=================
PF_findradius
Returns a chain of entities that have origins within a spherical area
findradius (origin, radius)
=================
*/
void QCBUILTIN PF_findradius (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
extern cvar_t sv_gameplayfix_blowupfallenzombies;
edict_t *ent, *chain;
float rad;
float *org;
vec3_t eorg;
int i, j;
chain = (edict_t *)sv.world.edicts;
org = G_VECTOR(OFS_PARM0);
rad = G_FLOAT(OFS_PARM1);
rad = rad*rad;
for (i=1 ; i<sv.world.num_edicts ; i++)
{
ent = EDICT_NUM(svprogfuncs, i);
if (ent->isfree)
continue;
if (ent->v->solid == SOLID_NOT && (progstype != PROG_QW || !((int)ent->v->flags & FL_FINDABLE_NONSOLID)) && !sv_gameplayfix_blowupfallenzombies.value)
continue;
for (j=0 ; j<3 ; j++)
eorg[j] = org[j] - (ent->v->origin[j] + (ent->v->mins[j] + ent->v->maxs[j])*0.5);
if (DotProduct(eorg,eorg) > rad)
continue;
ent->v->chain = EDICT_TO_PROG(prinst, chain);
chain = ent;
}
RETURN_EDICT(prinst, chain);
}
//entity nextent(entity)
void QCBUILTIN PF_nextent (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
@ -2004,12 +2057,12 @@ void QCBUILTIN PF_print (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals
}
//FTE_STRINGS
//C style strncasecmp (compare first n characters - case insensative)
//C style strcasecmp (case insensative string compare)
//C style strncasecmp (compare first n characters - case insensitive)
//C style strcasecmp (case insensitive string compare)
void QCBUILTIN PF_strncasecmp (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *a = PR_GetStringOfs(prinst, OFS_PARM0);
char *b = PR_GetStringOfs(prinst, OFS_PARM1);
const char *a = PR_GetStringOfs(prinst, OFS_PARM0);
const char *b = PR_GetStringOfs(prinst, OFS_PARM1);
if (prinst->callargc > 2)
{
@ -2038,11 +2091,11 @@ void QCBUILTIN PF_strncasecmp (pubprogfuncs_t *prinst, struct globalvars_s *pr_g
}
//FTE_STRINGS
//C style strncmp (compare first n characters - case sensative. Note that there is no strcmp provided)
//C style strncmp (compare first n characters - case sensitive. Note that there is no strcmp provided)
void QCBUILTIN PF_strncmp (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *a = PR_GetStringOfs(prinst, OFS_PARM0);
char *b = PR_GetStringOfs(prinst, OFS_PARM1);
const char *a = PR_GetStringOfs(prinst, OFS_PARM0);
const char *b = PR_GetStringOfs(prinst, OFS_PARM1);
if (prinst->callargc > 2)
{
@ -2073,8 +2126,8 @@ void QCBUILTIN PF_strncmp (pubprogfuncs_t *prinst, struct globalvars_s *pr_globa
//uses qw style \key\value strings
void QCBUILTIN PF_infoget (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *info = PR_GetStringOfs(prinst, OFS_PARM0);
char *key = PR_GetStringOfs(prinst, OFS_PARM1);
const char *info = PR_GetStringOfs(prinst, OFS_PARM0);
const char *key = PR_GetStringOfs(prinst, OFS_PARM1);
key = Info_ValueForKey(info, key);
@ -2084,9 +2137,9 @@ void QCBUILTIN PF_infoget (pubprogfuncs_t *prinst, struct globalvars_s *pr_globa
//uses qw style \key\value strings
void QCBUILTIN PF_infoadd (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *info = PR_GetStringOfs(prinst, OFS_PARM0);
char *key = PR_GetStringOfs(prinst, OFS_PARM1);
char *value = PF_VarString(prinst, 2, pr_globals);
const char *info = PR_GetStringOfs(prinst, OFS_PARM0);
const char *key = PR_GetStringOfs(prinst, OFS_PARM1);
const char *value = PF_VarString(prinst, 2, pr_globals);
char temp[8192];
Q_strncpyz(temp, info, MAXTEMPBUFFERLEN);
@ -2296,7 +2349,7 @@ void QCBUILTIN PF_str2chr (pubprogfuncs_t *prinst, struct globalvars_s *pr_globa
{
int err;
char *next;
char *instr = PR_GetStringOfs(prinst, OFS_PARM0);
const char *instr = PR_GetStringOfs(prinst, OFS_PARM0);
int ofs = (prinst->callargc>1)?G_FLOAT(OFS_PARM1):0;
if (VMUTF8)
@ -2326,8 +2379,8 @@ void QCBUILTIN PF_str2chr (pubprogfuncs_t *prinst, struct globalvars_s *pr_globa
//strstr, without generating a new string. Use in conjunction with FRIK_FILE's substring for more similar strstr.
void QCBUILTIN PF_strstrofs (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *instr = PR_GetStringOfs(prinst, OFS_PARM0);
char *match = PR_GetStringOfs(prinst, OFS_PARM1);
const char *instr = PR_GetStringOfs(prinst, OFS_PARM0);
const char *match = PR_GetStringOfs(prinst, OFS_PARM1);
int firstofs = (prinst->callargc>2)?G_FLOAT(OFS_PARM2):0;
@ -2350,7 +2403,7 @@ void QCBUILTIN PF_strstrofs (pubprogfuncs_t *prinst, struct globalvars_s *pr_glo
//float(string input) stof
void QCBUILTIN PF_stof (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *s;
const char *s;
s = PR_GetStringOfs(prinst, OFS_PARM0);
@ -2387,7 +2440,7 @@ void QCBUILTIN PF_itos (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
//int(string input) stoi
void QCBUILTIN PF_stoi (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *input = PR_GetStringOfs(prinst, OFS_PARM0);
const char *input = PR_GetStringOfs(prinst, OFS_PARM0);
G_INT(OFS_RETURN) = atoi(input);
}
@ -2406,7 +2459,7 @@ void QCBUILTIN PF_htos (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
//int(string input) stoh
void QCBUILTIN PF_stoh (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *input = PR_GetStringOfs(prinst, OFS_PARM0);
const char *input = PR_GetStringOfs(prinst, OFS_PARM0);
G_INT(OFS_RETURN) = strtoul(input, NULL, 16);
}
@ -2459,7 +2512,7 @@ void QCBUILTIN PF_dupstring(pubprogfuncs_t *prinst, struct globalvars_s *pr_glob
{
char *buf;
int len = 0;
char *s[8];
const char *s[8];
int l[8];
int i;
for (i = 0; i < prinst->callargc; i++)
@ -2492,7 +2545,7 @@ void QCBUILTIN PF_strcat (pubprogfuncs_t *prinst, struct globalvars_s *pr_global
{
char *buf;
int len = 0;
char *s[8];
const char *s[8];
int l[8];
int i;
for (i = 0; i < prinst->callargc; i++)
@ -2516,7 +2569,7 @@ void QCBUILTIN PF_strcat (pubprogfuncs_t *prinst, struct globalvars_s *pr_global
void QCBUILTIN PF_substring (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int start, length, slen;
char *s;
const char *s;
char *string;
s = PR_GetStringOfs(prinst, OFS_PARM0);
@ -2574,9 +2627,9 @@ void QCBUILTIN PF_strlen(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals
//float(string input, string token) instr
void QCBUILTIN PF_instr (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *sub;
char *s1;
char *s2;
const char *sub;
const char *s1;
const char *s2;
s1 = PR_GetStringOfs(prinst, OFS_PARM0);
s2 = PF_VarString(prinst, 1, pr_globals);
@ -2599,9 +2652,9 @@ void QCBUILTIN PF_strreplace (pubprogfuncs_t *prinst, struct globalvars_s *pr_gl
{
char resultbuf[4096];
char *result = resultbuf;
char *search = PR_GetStringOfs(prinst, OFS_PARM0);
char *replace = PR_GetStringOfs(prinst, OFS_PARM1);
char *subject = PR_GetStringOfs(prinst, OFS_PARM2);
const char *search = PR_GetStringOfs(prinst, OFS_PARM0);
const char *replace = PR_GetStringOfs(prinst, OFS_PARM1);
const char *subject = PR_GetStringOfs(prinst, OFS_PARM2);
int searchlen = strlen(search);
int replacelen = strlen(replace);
@ -2628,9 +2681,9 @@ void QCBUILTIN PF_strireplace (pubprogfuncs_t *prinst, struct globalvars_s *pr_g
{
char resultbuf[4096];
char *result = resultbuf;
char *search = PR_GetStringOfs(prinst, OFS_PARM0);
char *replace = PR_GetStringOfs(prinst, OFS_PARM1);
char *subject = PR_GetStringOfs(prinst, OFS_PARM2);
const char *search = PR_GetStringOfs(prinst, OFS_PARM0);
const char *replace = PR_GetStringOfs(prinst, OFS_PARM1);
const char *subject = PR_GetStringOfs(prinst, OFS_PARM2);
int searchlen = strlen(search);
int replacelen = strlen(replace);
@ -2667,7 +2720,7 @@ void QCBUILTIN PF_etos (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
// #476 float(string s) strlennocol - returns how many characters are in a string, minus color codes
void QCBUILTIN PF_strlennocol (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *in = PR_GetStringOfs(prinst, OFS_PARM0);
const char *in = PR_GetStringOfs(prinst, OFS_PARM0);
char result[8192];
unsigned int flagged[8192];
unsigned int len = 0;
@ -2683,7 +2736,7 @@ void QCBUILTIN PF_strlennocol (pubprogfuncs_t *prinst, struct globalvars_s *pr_g
// string (string s) strdecolorize - returns the passed in string with color codes stripped
void QCBUILTIN PF_strdecolorize (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *in = PR_GetStringOfs(prinst, OFS_PARM0);
const char *in = PR_GetStringOfs(prinst, OFS_PARM0);
char result[8192];
unsigned int flagged[8192];
COM_ParseFunString(CON_WHITEMASK, in, flagged, sizeof(flagged), false);
@ -2695,7 +2748,7 @@ void QCBUILTIN PF_strdecolorize (pubprogfuncs_t *prinst, struct globalvars_s *pr
//DP_QC_STRING_CASE_FUNCTIONS
void QCBUILTIN PF_strtolower (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *in = PR_GetStringOfs(prinst, OFS_PARM0);
const char *in = PR_GetStringOfs(prinst, OFS_PARM0);
char result[8192];
unicode_strtolower(in, result, sizeof(result), VMUTF8MARKUP);
@ -2706,7 +2759,7 @@ void QCBUILTIN PF_strtolower (pubprogfuncs_t *prinst, struct globalvars_s *pr_gl
//DP_QC_STRING_CASE_FUNCTIONS
void QCBUILTIN PF_strtoupper (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *in = PR_GetStringOfs(prinst, OFS_PARM0);
const char *in = PR_GetStringOfs(prinst, OFS_PARM0);
char result[8192];
unicode_strtoupper(in, result, sizeof(result), VMUTF8MARKUP);
@ -2902,7 +2955,7 @@ void QCBUILTIN PF_buf_sort (pubprogfuncs_t *prinst, struct globalvars_s *pr_glo
void QCBUILTIN PF_buf_implode (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int bufno = G_FLOAT(OFS_PARM0)-BUFSTRBASE;
char *glue = PR_GetStringOfs(prinst, OFS_PARM1);
const char *glue = PR_GetStringOfs(prinst, OFS_PARM1);
unsigned int gluelen = strlen(glue);
unsigned int retlen, l, i;
char **strings;
@ -2977,7 +3030,7 @@ void QCBUILTIN PF_bufstr_set (pubprogfuncs_t *prinst, struct globalvars_s *pr_g
{
int bufno = G_FLOAT(OFS_PARM0)-BUFSTRBASE;
int index = G_FLOAT(OFS_PARM1);
char *string = PR_GetStringOfs(prinst, OFS_PARM2);
const char *string = PR_GetStringOfs(prinst, OFS_PARM2);
int oldcount;
if ((unsigned int)bufno >= NUMSTRINGBUFS)
@ -3001,7 +3054,7 @@ void QCBUILTIN PF_bufstr_set (pubprogfuncs_t *prinst, struct globalvars_s *pr_g
strbuflist[bufno].used = index+1;
}
int PF_bufstr_add_internal(int bufno, char *string, int appendonend)
int PF_bufstr_add_internal(int bufno, const char *string, int appendonend)
{
int index;
if (appendonend)
@ -3043,7 +3096,7 @@ int PF_bufstr_add_internal(int bufno, char *string, int appendonend)
void QCBUILTIN PF_bufstr_add (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int bufno = G_FLOAT(OFS_PARM0)-BUFSTRBASE;
char *string = PR_GetStringOfs(prinst, OFS_PARM1);
const char *string = PR_GetStringOfs(prinst, OFS_PARM1);
int order = G_FLOAT(OFS_PARM2);
if ((unsigned int)bufno >= NUMSTRINGBUFS)
@ -3075,8 +3128,8 @@ void QCBUILTIN PF_bufstr_free (pubprogfuncs_t *prinst, struct globalvars_s *pr_
void QCBUILTIN PF_buf_cvarlist (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int bufno = G_FLOAT(OFS_PARM0)-BUFSTRBASE;
char *pattern = PR_GetStringOfs(prinst, OFS_PARM1);
char *antipattern = PR_GetStringOfs(prinst, OFS_PARM2);
const char *pattern = PR_GetStringOfs(prinst, OFS_PARM1);
const char *antipattern = PR_GetStringOfs(prinst, OFS_PARM2);
int i;
cvar_group_t *grp;
cvar_t *var;
@ -3109,7 +3162,7 @@ void QCBUILTIN PF_buf_cvarlist (pubprogfuncs_t *prinst, struct globalvars_s *pr
//directly reads a file into a stringbuffer
void QCBUILTIN PF_buf_loadfile (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *fname = PR_GetStringOfs(prinst, OFS_PARM0);
const char *fname = PR_GetStringOfs(prinst, OFS_PARM0);
int bufno = G_FLOAT(OFS_PARM1)-BUFSTRBASE;
vfsfile_t *file;
char line[8192];
@ -3195,11 +3248,10 @@ void QCBUILTIN PF_crc16 (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals
G_FLOAT(OFS_RETURN) = QCRC_Block(str, len);
}
int SHA1(char *digest, int maxdigestsize, char *string, int stringlen);
void QCBUILTIN PF_digest_hex (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *hashtype = PR_GetStringOfs(prinst, OFS_PARM0);
char *str = PF_VarString(prinst, 1, pr_globals);
const char *hashtype = PR_GetStringOfs(prinst, OFS_PARM0);
const char *str = PF_VarString(prinst, 1, pr_globals);
int digestsize, i;
unsigned char digest[64];
unsigned char hexdig[sizeof(digest)*2+1];
@ -3243,7 +3295,7 @@ void QCBUILTIN PF_uri_escape (pubprogfuncs_t *prinst, struct globalvars_s *pr_g
unsigned char result[8192];
unsigned char *o = result;
unsigned char *s = PR_GetStringOfs(prinst, OFS_PARM0);
const unsigned char *s = PR_GetStringOfs(prinst, OFS_PARM0);
*result = 0;
while (*s && o < result+sizeof(result)-4)
{
@ -3355,10 +3407,10 @@ void QCBUILTIN PF_uri_get (pubprogfuncs_t *prinst, struct globalvars_s *pr_glob
world_t *w = prinst->parms->user;
struct dl_download *dl;
unsigned char *url = PR_GetStringOfs(prinst, OFS_PARM0);
const unsigned char *url = PR_GetStringOfs(prinst, OFS_PARM0);
float id = G_FLOAT(OFS_PARM1);
char *mimetype = (prinst->callargc >= 3)?PR_GetStringOfs(prinst, OFS_PARM2):"";
char *dataorsep = PR_GetStringOfs(prinst, OFS_PARM3);
const char *mimetype = (prinst->callargc >= 3)?PR_GetStringOfs(prinst, OFS_PARM2):"";
const char *dataorsep = PR_GetStringOfs(prinst, OFS_PARM3);
int strbufid = G_FLOAT(OFS_PARM4);
//float cryptokey = G_FLOAT(OFS_PARM5); //DP feature, not supported in FTE.
@ -3371,7 +3423,7 @@ void QCBUILTIN PF_uri_get (pubprogfuncs_t *prinst, struct globalvars_s *pr_glob
if (*mimetype)
{
char *data;
const char *data;
Con_DPrintf("PF_uri_post(%s,%g)\n", url, id);
if (strbufid)
{
@ -3403,7 +3455,7 @@ void QCBUILTIN PF_uri_get (pubprogfuncs_t *prinst, struct globalvars_s *pr_glob
}
void QCBUILTIN PF_netaddress_resolve(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *address = PR_GetStringOfs(prinst, OFS_PARM0);
const char *address = PR_GetStringOfs(prinst, OFS_PARM0);
int defaultport = (prinst->callargc > 1)?G_FLOAT(OFS_PARM1):0;
netadr_t adr;
char result[256];
@ -3439,9 +3491,9 @@ void QCBUILTIN PF_ArgC (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals
G_FLOAT(OFS_RETURN) = qctoken_count;
}
int tokenizeqc(char *str, qboolean dpfuckage)
int tokenizeqc(const char *str, qboolean dpfuckage)
{
char *start = str;
const char *start = str;
while(qctoken_count > 0)
{
qctoken_count--;
@ -3483,11 +3535,11 @@ void QCBUILTIN PF_tokenize_console (pubprogfuncs_t *prinst, struct globalvars_s
void QCBUILTIN PF_tokenizebyseparator (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *str = PR_GetStringOfs(prinst, OFS_PARM0);
char *sep[7];
const char *str = PR_GetStringOfs(prinst, OFS_PARM0);
const char *sep[7];
int seplen[7];
int seps = 0, s;
char *start = str;
const char *start = str;
int tlen;
qboolean found = true;
@ -3589,7 +3641,7 @@ void QCBUILTIN PF_ArgV (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals
void QCBUILTIN PF_argescape(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char temp[8192];
char *str = PR_GetStringOfs(prinst, OFS_PARM0);
const char *str = PR_GetStringOfs(prinst, OFS_PARM0);
RETURN_TSTRING(COM_QuotedString(str, temp, sizeof(temp)));
}
@ -3760,6 +3812,53 @@ void QCBUILTIN PF_anglemod (pubprogfuncs_t *prinst, struct globalvars_s *pr_glob
}
//Maths functions
////////////////////////////////////////////////////
/*
===============
PF_droptofloor
void() droptofloor
===============
*/
void QCBUILTIN PF_droptofloor (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
extern cvar_t pr_droptofloorunits;
world_t *world = prinst->parms->user;
wedict_t *ent;
vec3_t end;
vec3_t start;
trace_t trace;
const float *gravitydir;
extern const vec3_t standardgravity;
ent = PROG_TO_WEDICT(prinst, pr_global_struct->self);
if (ent->xv->gravitydir[2] || ent->xv->gravitydir[1] || ent->xv->gravitydir[0])
gravitydir = ent->xv->gravitydir;
else
gravitydir = standardgravity;
VectorCopy (ent->v->origin, end);
if (pr_droptofloorunits.value > 0)
VectorMA(end, pr_droptofloorunits.value, gravitydir, end);
else
VectorMA(end, 256, gravitydir, end);
VectorCopy (ent->v->origin, start);
trace = World_Move (world, start, ent->v->mins, ent->v->maxs, end, MOVE_NORMAL, ent);
if (trace.fraction == 1 || trace.allsolid)
G_FLOAT(OFS_RETURN) = 0;
else
{
VectorCopy (trace.endpos, ent->v->origin);
World_LinkEdict (world, ent, false);
ent->v->flags = (int)ent->v->flags | FL_ONGROUND;
ent->v->groundentity = EDICT_TO_PROG(prinst, trace.ent);
G_FLOAT(OFS_RETURN) = 1;
}
}
////////////////////////////////////////////////////
//Vector functions
@ -4054,7 +4153,7 @@ void QCBUILTIN PF_externvalue (pubprogfuncs_t *prinst, struct globalvars_s *pr_g
void QCBUILTIN PF_externcall (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) //this func calls a function in annother progs (by name)
{
int progsnum;
char *funcname;
const char *funcname;
int i;
string_t failedst = G_INT(OFS_PARM1);
func_t f;
@ -4215,7 +4314,7 @@ void QCBUILTIN PF_calltimeofday (pubprogfuncs_t *prinst, struct globalvars_s *pr
}
}
void QCBUILTIN PF_sprintf_internal (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals, char *s, int firstarg, char *outbuf, int outbuflen)
void QCBUILTIN PF_sprintf_internal (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals, const char *s, int firstarg, char *outbuf, int outbuflen)
{
const char *s0;
char *o = outbuf, *end = outbuf + outbuflen, *err;
@ -4608,7 +4707,7 @@ void QCBUILTIN PF_putentityfieldstring (pubprogfuncs_t *prinst, struct globalvar
{
unsigned int fidx = G_FLOAT(OFS_PARM0);
wedict_t *ent = (wedict_t *)G_EDICT(prinst, OFS_PARM1);
char *str = PR_GetStringOfs(prinst, OFS_PARM2);
const char *str = PR_GetStringOfs(prinst, OFS_PARM2);
eval_t *eval;
unsigned int count = 0;
fdef_t *fdef = prinst->FieldInfo(prinst, &count);
@ -4624,7 +4723,7 @@ void QCBUILTIN PF_putentityfieldstring (pubprogfuncs_t *prinst, struct globalvar
//must match ordering in Cmd_ExecuteString.
void QCBUILTIN PF_checkcommand (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *str = PR_GetStringOfs(prinst, OFS_PARM0);
const char *str = PR_GetStringOfs(prinst, OFS_PARM0);
//functions, aliases, cvars. in that order.
if (Cmd_Exists(str))
{
@ -4722,7 +4821,7 @@ void PR_AutoCvar(pubprogfuncs_t *prinst, cvar_t *var)
void PDECL PR_FoundAutoCvarGlobal(pubprogfuncs_t *progfuncs, char *name, eval_t *val, etype_t type, void *ctx)
{
cvar_t *var;
char *vals;
const char *vals;
int nlen;
name += 9; //autocvar_
@ -4946,6 +5045,7 @@ lh_extension_t QSG_Extensions[] = {
{"DP_SV_EXTERIORMODELFORCLIENT"},
{"DP_SV_NODRAWTOCLIENT"}, //I prefer my older system. Guess I might as well remove that older system at some point.
{"DP_SV_PLAYERPHYSICS"},
//FTE cannot implement this one, because dp's arguments are the wrong way around. its otherwise implemented. {"DP_SV_POINTPARTICLES"},
{"DP_SV_POINTSOUND", 1, NULL, {"pointsound"}},
{"DP_SV_PRECACHEANYTIME"},
{"DP_SV_SETCOLOR"},
@ -4954,7 +5054,7 @@ lh_extension_t QSG_Extensions[] = {
{"DP_SV_WRITEUNTERMINATEDSTRING", 1, NULL, {"WriteUnterminatedString"}},
{"DP_TE_BLOOD", 1, NULL, {"te_blood"}},
{"DP_TE_BLOODSHOWER", 1, NULL, {"te_bloodshower"}},
{"_DP_TE_CUSTOMFLASH", 1, NULL, {"te_customflash"}},
{"DP_TE_CUSTOMFLASH", 1, NULL, {"te_customflash"}},
{"DP_TE_EXPLOSIONRGB", 1, NULL, {"te_explosionrgb"}},
{"_DP_TE_FLAMEJET", 1, NULL, {"te_flamejet"}},
{"DP_TE_PARTICLECUBE", 1, NULL, {"te_particlecube"}},

View File

@ -123,6 +123,7 @@ void QCBUILTIN PF_stov (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
void QCBUILTIN PF_dupstring(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_forgetstring(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_Spawn (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_droptofloor (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_min (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_max (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_registercvar (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
@ -133,7 +134,7 @@ void QCBUILTIN PF_atan (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
void QCBUILTIN PF_atan2 (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_tan (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_localcmd (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_sprintf_internal (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals, char *s, int firstarg, char *outbuf, int outbuflen);
void QCBUILTIN PF_sprintf_internal (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals, const char *s, int firstarg, char *outbuf, int outbuflen);
void QCBUILTIN PF_sprintf (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_random (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_fclose (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
@ -304,6 +305,7 @@ void QCBUILTIN PF_strpad (pubprogfuncs_t *prinst, struct globalvars_s *pr_global
void QCBUILTIN PF_digest_hex (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_findradius (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_edict_for_num (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_num_for_edict (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_cvar_defstring (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
@ -442,21 +444,22 @@ void QCBUILTIN PF_WriteEntity (pubprogfuncs_t *prinst, struct globalvars_s *pr_g
void QCBUILTIN PF_multicast (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_svtraceline (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_changelevel (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_applylightstyle(int style, char *val, int col);
void PF_ambientsound_Internal (float *pos, char *samp, float vol, float attenuation);
void QCBUILTIN PF_applylightstyle(int style, const char *val, int col);
void PF_ambientsound_Internal (float *pos, const char *samp, float vol, float attenuation);
void QCBUILTIN PF_makestatic (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_logfrag (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_ExecuteCommand (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_setspawnparms (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_ForceInfoKey(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_precache_vwep_model(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
int PF_ForceInfoKey_Internal(unsigned int entnum, const char *key, const char *value);
int PF_checkclient_Internal (pubprogfuncs_t *prinst);
void PF_precache_sound_Internal (pubprogfuncs_t *prinst, char *s);
int PF_precache_model_Internal (pubprogfuncs_t *prinst, char *s, qboolean queryonly);
void PF_setmodel_Internal (pubprogfuncs_t *prinst, edict_t *e, char *m);
char *PF_infokey_Internal (int entnum, char *value);
void PF_centerprint_Internal (int entnum, qboolean plaque, char *s);
void PF_WriteString_Internal (int target, char *str);
void PF_precache_sound_Internal (pubprogfuncs_t *prinst, const char *s);
int PF_precache_model_Internal (pubprogfuncs_t *prinst, const char *s, qboolean queryonly);
void PF_setmodel_Internal (pubprogfuncs_t *prinst, edict_t *e, const char *m);
char *PF_infokey_Internal (int entnum, const char *value);
void PF_stuffcmd_Internal(int entnum, const char *str);
void PF_centerprint_Internal (int entnum, qboolean plaque, const char *s);
void PF_WriteString_Internal (int target, const char *str);
pbool QDECL ED_CanFree (edict_t *ed);
#endif

View File

@ -111,8 +111,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define PORT_QWCLIENT 27001
#define PORT_QWMASTER 27000
#define PORT_QWSERVER 27500
#define PORT_Q2CLIENT 27901
#define PORT_Q2SERVER 27910
#define PORT_Q2CLIENT 27901
#define PORT_Q2SERVER 27910
#define PORT_Q3SERVER 27960
//hexen2: 26900
@ -310,6 +311,47 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define svc_invalid 256
enum clustercmdops_e
{
ccmd_bad = 0, //abort!
ccmd_stuffcmd = 1, //regular ol stuffcmd
//string concommand
ccmd_print = 2,
//string message
ccmd_acceptserver,
//serverid
ccmd_takeplayer, //master->server, saying to allocate a slot for a player.
//long plid
//long fromsvid (0=no reply needed)
//byte statcount
//float stats[statcount]
ccmd_transferplayer, //server->master, asking to move them to a new server.
//long plid
//string map
//byte ipv4=0, ipv6=1
//byte statcount
//float stats[statcount]
ccmd_transferedplayer, //master->server, saying the transfer was completed. original server no longer owns the player.
//long toserver,
//long playerid
ccmd_tookplayer, //server->master->server, saying that a player was taken.
//long svid (this is always the *other* server)
//long plid
//string addr (this is the client's address when sent to the master, and the server's address that took the message in the message to the source server)
ccmd_transferabort, //server->master->server, saying that a player was rejected.
//long plid
//long fromsvid
//string server
ccmd_saveplayer, //server->master, saves a player's stats.
//long plid
//byte statcount
//float stats[statcount]
ccmd_serveraddress, //server->master, contains a few net addresses
//string address[]
//byte 0
};
enum svcq2_ops_e
{
svcq2_bad, //0

View File

@ -286,9 +286,9 @@ int VM_GetFileList(char *path, char *ext, char *output, int buffersize)
if (!strcmp(path, "$modlist"))
{
vms.skip=0;
Sys_EnumerateFiles((vms.dir=com_quakedir), "*", VMEnumMods, &vms, NULL);
if (*com_homedir)
Sys_EnumerateFiles((vms.dir=com_homedir), "*", VMEnumMods, &vms, NULL);
Sys_EnumerateFiles((vms.dir=com_gamepath), "*", VMEnumMods, &vms, NULL);
if (*com_homepath)
Sys_EnumerateFiles((vms.dir=com_homepath), "*", VMEnumMods, &vms, NULL);
}
else if (*(char *)ext == '.' || *(char *)ext == '/')
COM_EnumerateFiles(va("%s/*%s", path, ext), VMEnum, &vms);

View File

@ -44,15 +44,15 @@ typedef struct
} SHA1_CTX;
#define DIGEST_SIZE 20
void SHA1Transform(unsigned int state[5], unsigned char buffer[64]);
void SHA1Transform(unsigned int state[5], const unsigned char buffer[64]);
void SHA1Init(SHA1_CTX* context);
void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int len);
void SHA1Update(SHA1_CTX* context, const unsigned char* data, unsigned int len);
void SHA1Final(unsigned char digest[DIGEST_SIZE], SHA1_CTX* context);
/* Hash a single 512-bit block. This is the core of the algorithm. */
void SHA1Transform(unsigned int state[5], unsigned char buffer[64])
void SHA1Transform(unsigned int state[5], const unsigned char buffer[64])
{
unsigned int a, b, c, d, e;
typedef union
@ -122,7 +122,7 @@ void SHA1Init(SHA1_CTX* context)
/* Run your data through this. */
void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int len)
void SHA1Update(SHA1_CTX* context, const unsigned char* data, unsigned int len)
{
unsigned int i, j;
@ -179,7 +179,7 @@ memset(&finalcount, 0, 8);
}
int SHA1(char *digest, int maxdigestsize, char *string, int stringlen)
int SHA1(char *digest, int maxdigestsize, const char *string, int stringlen)
{
SHA1_CTX context;
if (maxdigestsize < DIGEST_SIZE)
@ -216,7 +216,7 @@ hacked up a bit by someone else...
#define IPAD 0x36
#define OPAD 0x5c
static void memxor(char *dest, char *src, size_t length)
static void memxor(char *dest, const char *src, size_t length)
{
size_t i;
for (i = 0; i < length; i++)
@ -226,8 +226,8 @@ static void memxor(char *dest, char *src, size_t length)
}
int SHA1_HMAC(unsigned char *digest, int maxdigestsize,
unsigned char *data, int datalen,
unsigned char *key, int keylen)
const unsigned char *data, int datalen,
const unsigned char *key, int keylen)
{
SHA1_CTX inner;
SHA1_CTX outer;

View File

@ -21,14 +21,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <sys/types.h>
#include <sys/timeb.h>
#include <winsock.h>
#include "winquake.h"
#include <conio.h>
#ifdef MULTITHREAD
#if !defined(WINRT) && defined(MULTITHREAD)
#include <process.h>
#endif
#ifdef MULTITHREAD
/* Thread creation calls */
typedef struct threadwrap_s
{
@ -309,4 +306,113 @@ void Sys_DestroyConditional(void *condv)
DeleteCriticalSection(&cv->mainlock);
free(cv);
}
#endif
#ifdef SUBSERVERS
typedef struct slaveserver_s
{
pubsubserver_t pub;
HANDLE inpipe;
HANDLE outpipe;
qbyte inbuffer[2048];
int inbufsize;
} winsubserver_t;
pubsubserver_t *Sys_ForkServer(void)
{
char exename[256];
char curdir[256];
char cmdline[8192];
PROCESS_INFORMATION childinfo;
STARTUPINFO startinfo;
SECURITY_ATTRIBUTES pipesec = {sizeof(pipesec), NULL, TRUE};
winsubserver_t *ctx = Z_Malloc(sizeof(*ctx));
GetModuleFileName(NULL, exename, sizeof(exename));
GetCurrentDirectory(sizeof(curdir), curdir);
Q_snprintfz(cmdline, sizeof(cmdline), "foo -clusterslave %s", FS_GetManifestArgs()); //fixme: include which manifest is in use, so configs get set up the same.
memset(&startinfo, 0, sizeof(startinfo));
startinfo.cb = sizeof(startinfo);
startinfo.hStdInput = NULL;
startinfo.hStdError = NULL;
startinfo.hStdOutput = NULL;
startinfo.dwFlags |= STARTF_USESTDHANDLES;
//create pipes for the stdin/stdout.
CreatePipe(&ctx->inpipe, &startinfo.hStdOutput, &pipesec, 0);
CreatePipe(&startinfo.hStdInput, &ctx->outpipe, &pipesec, 0);
SetHandleInformation(ctx->inpipe, HANDLE_FLAG_INHERIT, 0);
SetHandleInformation(ctx->outpipe, HANDLE_FLAG_INHERIT, 0);
SetHandleInformation(startinfo.hStdOutput, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT);
SetHandleInformation(startinfo.hStdInput, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT);
CreateProcess(exename, cmdline, NULL, NULL, TRUE, 0, NULL, curdir, &startinfo, &childinfo);
//these ends of the pipes were inherited by now, so we can discard them in the caller.
CloseHandle(startinfo.hStdOutput);
CloseHandle(startinfo.hStdInput);
return &ctx->pub;
}
void Sys_InstructSlave(pubsubserver_t *ps, sizebuf_t *cmd)
{
winsubserver_t *s = (winsubserver_t*)ps;
DWORD written = 0;
cmd->data[0] = cmd->cursize & 0xff;
cmd->data[1] = (cmd->cursize>>8) & 0xff;
WriteFile(s->outpipe, cmd->data, cmd->cursize, &written, NULL);
}
void SSV_InstructMaster(sizebuf_t *cmd)
{
HANDLE output = GetStdHandle(STD_OUTPUT_HANDLE);
DWORD written = 0;
cmd->data[0] = cmd->cursize & 0xff;
cmd->data[1] = (cmd->cursize>>8) & 0xff;
WriteFile(output, cmd->data, cmd->cursize, &written, NULL);
}
int Sys_SubServerRead(pubsubserver_t *ps)
{
DWORD avail;
winsubserver_t *s = (winsubserver_t*)ps;
if (!PeekNamedPipe(s->inpipe, NULL, 0, NULL, &avail, NULL))
{
CloseHandle(s->inpipe);
CloseHandle(s->outpipe);
Con_Printf("%i:%s has died\n", s->pub.id, s->pub.name);
return -1;
}
else if (avail)
{
if (avail > sizeof(s->inbuffer)-1-s->inbufsize)
avail = sizeof(s->inbuffer)-1-s->inbufsize;
if (ReadFile(s->inpipe, s->inbuffer+s->inbufsize, avail, &avail, NULL))
s->inbufsize += avail;
}
if(s->inbufsize >= 2)
{
unsigned short len = s->inbuffer[0] | (s->inbuffer[1]<<8);
if (s->inbufsize >= len && len>=2)
{
memcpy(net_message.data, s->inbuffer+2, len-2);
net_message.cursize = len-2;
memmove(s->inbuffer, s->inbuffer+len, s->inbufsize - len);
s->inbufsize -= len;
MSG_BeginReading (msg_nullnetprim);
return 1;
}
}
return 0;
}
#endif

View File

@ -133,6 +133,7 @@ int VM_GetFileList(char *path, char *ext, char *output, int buffersize);
#ifdef VM_CG
void CG_Stop (void);
void CG_Start (void);
qboolean CG_VideoRestarted(void);
int CG_Refresh(void);
qboolean CG_Command(void);
qboolean CG_KeyPress(int key, int unicode, int down);

View File

@ -398,7 +398,7 @@ void *BZ_MallocNamed(int size, char *file, int line) //BZ_MallocNamed but allowe
return mem;
}
#else
void *BZ_Malloc(int size) //Doesn't clear. The expectation is a large file, rather than sensative data structures.
void *BZ_Malloc(int size) //Doesn't clear. The expectation is a large file, rather than sensitive data structures.
{
void *mem = BZF_Malloc(size);
if (!mem)

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