mirror of
https://github.com/UberGames/ioef.git
synced 2025-03-22 00:40:57 +00:00
Merge ioef with latest ioquake3 master. No function tests have been done yet. GL2 renderer not done either, which is a different beast.
This commit is contained in:
parent
9d6a95d4ad
commit
bd8c98e3ac
68 changed files with 4000 additions and 265 deletions
47
Makefile
47
Makefile
|
@ -32,8 +32,11 @@ endif
|
|||
ifndef BUILD_MISSIONPACK
|
||||
BUILD_MISSIONPACK=
|
||||
endif
|
||||
ifndef BUILD_ELITEFORCE
|
||||
BUILD_ELITEFORCE =
|
||||
endif
|
||||
ifndef BUILD_RENDERER_OPENGL2
|
||||
BUILD_RENDERER_OPENGL2=
|
||||
BUILD_RENDERER_OPENGL2=0
|
||||
endif
|
||||
|
||||
#############################################################################
|
||||
|
@ -101,7 +104,11 @@ endif
|
|||
export CROSS_COMPILING
|
||||
|
||||
ifndef VERSION
|
||||
VERSION=1.36
|
||||
ifeq ($(BUILD_ELITEFORCE),1)
|
||||
VERSION=1.38
|
||||
else
|
||||
VERSION=1.36
|
||||
endif
|
||||
endif
|
||||
|
||||
ifndef CLIENTBIN
|
||||
|
@ -176,6 +183,10 @@ ifndef USE_CODEC_VORBIS
|
|||
USE_CODEC_VORBIS=0
|
||||
endif
|
||||
|
||||
ifndef USE_CODEC_MP3
|
||||
USE_CODEC_MP3=0
|
||||
endif
|
||||
|
||||
ifndef USE_CODEC_OPUS
|
||||
USE_CODEC_OPUS=1
|
||||
endif
|
||||
|
@ -263,6 +274,10 @@ NSISDIR=misc/nsis
|
|||
SDLHDIR=$(MOUNT_DIR)/SDL2
|
||||
LIBSDIR=$(MOUNT_DIR)/libs
|
||||
|
||||
ifeq ($(BUILD_ELITEFORCE),1)
|
||||
CFLAGS += -DELITEFORCE
|
||||
endif
|
||||
|
||||
bin_path=$(shell which $(1) 2> /dev/null)
|
||||
|
||||
# We won't need this if we only build the server
|
||||
|
@ -360,6 +375,7 @@ ifneq (,$(findstring "$(PLATFORM)", "linux" "gnu_kfreebsd" "kfreebsd-gnu" "gnu")
|
|||
|
||||
THREAD_LIBS=-lpthread
|
||||
LIBS=-ldl -lm
|
||||
LIBS += -L/emul/linux/x86/usr/lib
|
||||
|
||||
CLIENT_LIBS=$(SDL_LIBS)
|
||||
RENDERER_LIBS = $(SDL_LIBS) -lGL
|
||||
|
@ -377,6 +393,10 @@ ifneq (,$(findstring "$(PLATFORM)", "linux" "gnu_kfreebsd" "kfreebsd-gnu" "gnu")
|
|||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(USE_CODEC_MP3),1)
|
||||
CLIENT_LIBS += -lmad
|
||||
endif
|
||||
|
||||
ifeq ($(USE_MUMBLE),1)
|
||||
CLIENT_LIBS += -lrt
|
||||
endif
|
||||
|
@ -450,6 +470,11 @@ ifeq ($(PLATFORM),darwin)
|
|||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(USE_CODEC_MP3),1)
|
||||
BASE_CFLAGS += -DUSE_CODEC_MP3=1
|
||||
CLIENT_LIBS += -lmad
|
||||
endif
|
||||
|
||||
ifeq ($(USE_CURL),1)
|
||||
CLIENT_CFLAGS += $(CURL_CFLAGS)
|
||||
ifneq ($(USE_CURL_DLOPEN),1)
|
||||
|
@ -547,6 +572,14 @@ ifdef MINGW
|
|||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(USE_CODEC_MP3),1)
|
||||
ifeq ($(ARCH),x64)
|
||||
CLIENT_LIBS += $(LIBSDIR)/win64/libmad.a
|
||||
else
|
||||
CLIENT_LIBS += $(LIBSDIR)/win32/libmad.a
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(ARCH),x86_64)
|
||||
OPTIMIZEVM = -O3
|
||||
OPTIMIZE = $(OPTIMIZEVM) -ffast-math
|
||||
|
@ -681,6 +714,10 @@ ifeq ($(PLATFORM),freebsd)
|
|||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(USE_CODEC_MP3),1)
|
||||
CLIENT_LIBS += -lmad
|
||||
endif
|
||||
|
||||
# cross-compiling tweaks
|
||||
ifeq ($(ARCH),x86)
|
||||
ifeq ($(CROSS_COMPILING),1)
|
||||
|
@ -986,6 +1023,10 @@ ifeq ($(USE_VOIP),1)
|
|||
NEED_OPUS=1
|
||||
endif
|
||||
|
||||
ifeq ($(USE_CODEC_MP3),1)
|
||||
CLIENT_CFLAGS += -DUSE_CODEC_MP3=1
|
||||
endif
|
||||
|
||||
ifeq ($(USE_CODEC_OPUS),1)
|
||||
CLIENT_CFLAGS += -DUSE_CODEC_OPUS
|
||||
NEED_OPUS=1
|
||||
|
@ -1563,6 +1604,7 @@ Q3OBJ = \
|
|||
$(B)/client/snd_codec.o \
|
||||
$(B)/client/snd_codec_wav.o \
|
||||
$(B)/client/snd_codec_ogg.o \
|
||||
$(B)/client/snd_codec_mp3.o \
|
||||
$(B)/client/snd_codec_opus.o \
|
||||
\
|
||||
$(B)/client/qal.o \
|
||||
|
@ -2082,6 +2124,7 @@ endif
|
|||
endif
|
||||
|
||||
|
||||
$(B)/client/snd_codec_mp3.o : $(CDIR)/snd_codec_mp3.c; $(DO_CC)
|
||||
|
||||
#############################################################################
|
||||
# DEDICATED SERVER
|
||||
|
|
|
@ -51,7 +51,20 @@ enum {
|
|||
ET_PLAYER,
|
||||
ET_ITEM,
|
||||
ET_MISSILE,
|
||||
#ifdef ELITEFORCE
|
||||
ET_ALT_MISSILE,
|
||||
ET_MOVER,
|
||||
ET_BEAM,
|
||||
ET_PORTAL,
|
||||
ET_SPEAKER,
|
||||
ET_PUSH_TRIGGER,
|
||||
ET_TELEPORT_TRIGGER,
|
||||
ET_INVISIBLE,
|
||||
ET_USEABLE,
|
||||
ET_EVENTS
|
||||
#else
|
||||
ET_MOVER
|
||||
#endif
|
||||
};
|
||||
|
||||
//===========================================================================
|
||||
|
|
|
@ -2805,10 +2805,17 @@ int BotChatLength(int chatstate)
|
|||
void BotEnterChat(int chatstate, int clientto, int sendto)
|
||||
{
|
||||
bot_chatstate_t *cs;
|
||||
int clientnum;
|
||||
|
||||
cs = BotChatStateFromHandle(chatstate);
|
||||
if (!cs) return;
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
clientnum = clientto;
|
||||
#else
|
||||
clientnum = cs->client;
|
||||
#endif
|
||||
|
||||
if (strlen(cs->chatmessage))
|
||||
{
|
||||
BotRemoveTildes(cs->chatmessage);
|
||||
|
@ -2818,13 +2825,15 @@ void BotEnterChat(int chatstate, int clientto, int sendto)
|
|||
else {
|
||||
switch(sendto) {
|
||||
case CHAT_TEAM:
|
||||
EA_Command(cs->client, va("say_team %s", cs->chatmessage));
|
||||
EA_Command(clientnum, va("say_team %s", cs->chatmessage));
|
||||
break;
|
||||
#ifndef ELITEFORCE
|
||||
case CHAT_TELL:
|
||||
EA_Command(cs->client, va("tell %d %s", clientto, cs->chatmessage));
|
||||
EA_Command(clientnum, va("tell %d %s", clientto, cs->chatmessage));
|
||||
break;
|
||||
#endif
|
||||
default: //CHAT_ALL
|
||||
EA_Command(cs->client, va("say %s", cs->chatmessage));
|
||||
EA_Command(clientnum, va("say %s", cs->chatmessage));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -2876,13 +2885,19 @@ void BotSetChatGender(int chatstate, int gender)
|
|||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
#ifdef ELITEFORCE
|
||||
void BotSetChatName(int chatstate, char *name)
|
||||
#else
|
||||
void BotSetChatName(int chatstate, char *name, int client)
|
||||
#endif
|
||||
{
|
||||
bot_chatstate_t *cs;
|
||||
|
||||
cs = BotChatStateFromHandle(chatstate);
|
||||
if (!cs) return;
|
||||
#ifndef ELITEFORCE
|
||||
cs->client = client;
|
||||
#endif
|
||||
Com_Memset(cs->name, 0, sizeof(cs->name));
|
||||
strncpy(cs->name, name, sizeof(cs->name));
|
||||
cs->name[sizeof(cs->name)-1] = '\0';
|
||||
|
@ -2981,11 +2996,13 @@ int BotSetupChatAI(void)
|
|||
file = LibVarString("matchfile", "match.c");
|
||||
matchtemplates = BotLoadMatchTemplates(file);
|
||||
//
|
||||
#ifndef ELITEFORCE
|
||||
if (!LibVarValue("nochat", "0"))
|
||||
{
|
||||
file = LibVarString("rchatfile", "rchat.c");
|
||||
replychats = BotLoadReplyChat(file);
|
||||
} //end if
|
||||
#endif
|
||||
|
||||
InitConsoleMessageHeap();
|
||||
|
||||
|
|
|
@ -109,5 +109,8 @@ int BotLoadChatFile(int chatstate, char *chatfile, char *chatname);
|
|||
//store the gender of the bot in the chat state
|
||||
void BotSetChatGender(int chatstate, int gender);
|
||||
//store the bot name in the chat state
|
||||
#ifdef ELITEFORCE
|
||||
void BotSetChatName(int chatstate, char *name);
|
||||
#else
|
||||
void BotSetChatName(int chatstate, char *name, int client);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -374,7 +374,11 @@ void InitLevelItemHeap(void)
|
|||
|
||||
if (levelitemheap) FreeMemory(levelitemheap);
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
max_levelitems = (int) LibVarValue("max_levelitems", "1024");
|
||||
#else
|
||||
max_levelitems = (int) LibVarValue("max_levelitems", "256");
|
||||
#endif
|
||||
levelitemheap = (levelitem_t *) GetClearedMemory(max_levelitems * sizeof(levelitem_t));
|
||||
|
||||
for (i = 0; i < max_levelitems-1; i++)
|
||||
|
|
|
@ -417,7 +417,11 @@ int BotChooseBestFightWeapon(int weaponstate, int *inventory)
|
|||
if (!ws->weaponweightconfig) return 0;
|
||||
|
||||
bestweight = 0;
|
||||
#ifdef ELITEFORCE
|
||||
bestweapon = 1;
|
||||
#else
|
||||
bestweapon = 0;
|
||||
#endif
|
||||
for (i = 0; i < wc->numweapons; i++)
|
||||
{
|
||||
if (!wc->weaponinfo[i].valid) continue;
|
||||
|
|
|
@ -171,6 +171,22 @@ void EA_Attack(int client)
|
|||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
#ifdef ELITEFORCE
|
||||
void EA_AltAttack(int client)
|
||||
{
|
||||
bot_input_t *bi;
|
||||
|
||||
bi = &botinputs[client];
|
||||
|
||||
bi->actionflags |= ACTION_ALTATTACK;
|
||||
} //end of the function EA_AltAttack
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
#endif
|
||||
void EA_Talk(int client)
|
||||
{
|
||||
bot_input_t *bi;
|
||||
|
@ -205,7 +221,11 @@ void EA_Respawn(int client)
|
|||
|
||||
bi = &botinputs[client];
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
bi->actionflags |= ACTION_ATTACK;
|
||||
#else
|
||||
bi->actionflags |= ACTION_RESPAWN;
|
||||
#endif
|
||||
} //end of the function EA_Respawn
|
||||
//===========================================================================
|
||||
//
|
||||
|
|
|
@ -45,6 +45,13 @@ void EA_MoveBack(int client);
|
|||
void EA_MoveLeft(int client);
|
||||
void EA_MoveRight(int client);
|
||||
void EA_Attack(int client);
|
||||
#ifdef ELITEFORCE
|
||||
void EA_AltAttack(int client);
|
||||
void EA_UseItem(int client, char *it);
|
||||
void EA_DropItem(int client, char *it);
|
||||
void EA_UseInv(int client, char *inv);
|
||||
void EA_DropInv(int client, char *inv);
|
||||
#endif
|
||||
void EA_Respawn(int client);
|
||||
void EA_Talk(int client);
|
||||
void EA_Gesture(int client);
|
||||
|
|
|
@ -740,6 +740,13 @@ static void Init_EA_Export( ea_export_t *ea ) {
|
|||
ea->EA_Gesture = EA_Gesture;
|
||||
ea->EA_Talk = EA_Talk;
|
||||
ea->EA_Attack = EA_Attack;
|
||||
#ifdef ELITEFORCE
|
||||
ea->EA_AltAttack = EA_AltAttack;
|
||||
ea->EA_UseItem = EA_UseItem;
|
||||
ea->EA_DropItem = EA_DropItem;
|
||||
ea->EA_UseInv = EA_UseInv;
|
||||
ea->EA_DropInv = EA_DropInv;
|
||||
#endif
|
||||
ea->EA_Use = EA_Use;
|
||||
ea->EA_Respawn = EA_Respawn;
|
||||
ea->EA_Crouch = EA_Crouch;
|
||||
|
|
|
@ -81,6 +81,9 @@ struct weaponinfo_s;
|
|||
//action flags
|
||||
#define ACTION_ATTACK 0x00000001
|
||||
#define ACTION_USE 0x00000002
|
||||
#ifdef ELITEFORCE
|
||||
#define ACTION_ALTATTACK 0x00000004
|
||||
#endif
|
||||
#define ACTION_RESPAWN 0x00000008
|
||||
#define ACTION_JUMP 0x00000010
|
||||
#define ACTION_MOVEUP 0x00000020
|
||||
|
@ -276,6 +279,13 @@ typedef struct ea_export_s
|
|||
void (*EA_Gesture)(int client);
|
||||
void (*EA_Talk)(int client);
|
||||
void (*EA_Attack)(int client);
|
||||
#ifdef ELITEFORCE
|
||||
void (*EA_AltAttack)(int client);
|
||||
void (*EA_UseItem)(int client, char *it);
|
||||
void (*EA_DropItem)(int client, char *it);
|
||||
void (*EA_UseInv)(int client, char *inv);
|
||||
void (*EA_DropInv)(int client, char *inv);
|
||||
#endif
|
||||
void (*EA_Use)(int client);
|
||||
void (*EA_Respawn)(int client);
|
||||
void (*EA_MoveUp)(int client);
|
||||
|
@ -331,7 +341,11 @@ typedef struct ai_export_s
|
|||
void (*BotReplaceSynonyms)(char *string, unsigned long int context);
|
||||
int (*BotLoadChatFile)(int chatstate, char *chatfile, char *chatname);
|
||||
void (*BotSetChatGender)(int chatstate, int gender);
|
||||
#ifdef ELITEFORCE
|
||||
void (*BotSetChatName)(int chatstate, char *name);
|
||||
#else
|
||||
void (*BotSetChatName)(int chatstate, char *name, int client);
|
||||
#endif
|
||||
//-----------------------------------
|
||||
// be_ai_goal.h
|
||||
//-----------------------------------
|
||||
|
|
|
@ -131,6 +131,7 @@ typedef enum {
|
|||
CG_SETUSERCMDVALUE,
|
||||
CG_R_REGISTERSHADERNOMIP,
|
||||
CG_MEMORY_REMAINING,
|
||||
#ifndef ELITEFORCE
|
||||
CG_R_REGISTERFONT,
|
||||
CG_KEY_ISDOWN,
|
||||
CG_KEY_GETCATCHER,
|
||||
|
@ -170,7 +171,10 @@ typedef enum {
|
|||
CG_STARTCAMERA,
|
||||
CG_GETCAMERAINFO,
|
||||
*/
|
||||
|
||||
#else
|
||||
CG_R_REGISTERSHADER3D, //59
|
||||
CG_CVAR_SET_NO_MODIFY, // 60
|
||||
#endif
|
||||
CG_MEMSET = 100,
|
||||
CG_MEMCPY,
|
||||
CG_STRNCPY,
|
||||
|
@ -182,7 +186,9 @@ typedef enum {
|
|||
CG_CEIL,
|
||||
CG_TESTPRINTINT,
|
||||
CG_TESTPRINTFLOAT,
|
||||
#ifndef ELITEFORCE
|
||||
CG_ACOS
|
||||
#endif
|
||||
} cgameImport_t;
|
||||
|
||||
|
||||
|
@ -225,7 +231,7 @@ typedef enum {
|
|||
|
||||
CG_LAST_ATTACKER,
|
||||
// int (*CG_LastAttacker)( void );
|
||||
|
||||
#ifndef ELITEFORCE
|
||||
CG_KEY_EVENT,
|
||||
// void (*CG_KeyEvent)( int key, qboolean down );
|
||||
|
||||
|
@ -233,6 +239,7 @@ typedef enum {
|
|||
// void (*CG_MouseEvent)( int dx, int dy );
|
||||
CG_EVENT_HANDLING
|
||||
// void (*CG_EventHandling)(int type);
|
||||
#endif
|
||||
} cgameExport_t;
|
||||
|
||||
//----------------------------------------------
|
||||
|
|
|
@ -291,9 +291,19 @@ rescan:
|
|||
// https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=552
|
||||
// allow server to indicate why they were disconnected
|
||||
if ( argc >= 2 )
|
||||
{
|
||||
#ifdef ELITEFORCE
|
||||
Cbuf_AddText(va("err_dialog \"%s\"", Cmd_Argv(1)));
|
||||
#endif
|
||||
Com_Error( ERR_SERVERDISCONNECT, "Server disconnected - %s", Cmd_Argv( 1 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef ELITEFORCE
|
||||
Cbuf_AddText(va("err_dialog \"%s\"", Cmd_Argv(1)));
|
||||
#endif
|
||||
Com_Error( ERR_SERVERDISCONNECT, "Server disconnected" );
|
||||
}
|
||||
}
|
||||
|
||||
if ( !strcmp( cmd, "bcs0" ) ) {
|
||||
|
@ -448,17 +458,21 @@ intptr_t CL_CgameSystemCalls( intptr_t *args ) {
|
|||
case CG_FS_FCLOSEFILE:
|
||||
FS_FCloseFile( args[1] );
|
||||
return 0;
|
||||
#ifndef ELITEFORCE
|
||||
case CG_FS_SEEK:
|
||||
return FS_Seek( args[1], args[2], args[3] );
|
||||
#endif
|
||||
case CG_SENDCONSOLECOMMAND:
|
||||
Cbuf_AddText( VMA(1) );
|
||||
return 0;
|
||||
case CG_ADDCOMMAND:
|
||||
CL_AddCgameCommand( VMA(1) );
|
||||
return 0;
|
||||
#ifndef ELITEFORCE
|
||||
case CG_REMOVECOMMAND:
|
||||
Cmd_RemoveCommandSafe( VMA(1) );
|
||||
return 0;
|
||||
#endif
|
||||
case CG_SENDCLIENTCOMMAND:
|
||||
CL_AddReliableCommand(VMA(1), qfalse);
|
||||
return 0;
|
||||
|
@ -479,8 +493,10 @@ intptr_t CL_CgameSystemCalls( intptr_t *args ) {
|
|||
return CM_InlineModel( args[1] );
|
||||
case CG_CM_TEMPBOXMODEL:
|
||||
return CM_TempBoxModel( VMA(1), VMA(2), /*int capsule*/ qfalse );
|
||||
#ifndef ELITEFORCE
|
||||
case CG_CM_TEMPCAPSULEMODEL:
|
||||
return CM_TempBoxModel( VMA(1), VMA(2), /*int capsule*/ qtrue );
|
||||
#endif
|
||||
case CG_CM_POINTCONTENTS:
|
||||
return CM_PointContents( VMA(1), args[2] );
|
||||
case CG_CM_TRANSFORMEDPOINTCONTENTS:
|
||||
|
@ -488,15 +504,19 @@ intptr_t CL_CgameSystemCalls( intptr_t *args ) {
|
|||
case CG_CM_BOXTRACE:
|
||||
CM_BoxTrace( VMA(1), VMA(2), VMA(3), VMA(4), VMA(5), args[6], args[7], /*int capsule*/ qfalse );
|
||||
return 0;
|
||||
#ifndef ELITEFORCE
|
||||
case CG_CM_CAPSULETRACE:
|
||||
CM_BoxTrace( VMA(1), VMA(2), VMA(3), VMA(4), VMA(5), args[6], args[7], /*int capsule*/ qtrue );
|
||||
return 0;
|
||||
#endif
|
||||
case CG_CM_TRANSFORMEDBOXTRACE:
|
||||
CM_TransformedBoxTrace( VMA(1), VMA(2), VMA(3), VMA(4), VMA(5), args[6], args[7], VMA(8), VMA(9), /*int capsule*/ qfalse );
|
||||
return 0;
|
||||
#ifndef ELITEFORCE
|
||||
case CG_CM_TRANSFORMEDCAPSULETRACE:
|
||||
CM_TransformedBoxTrace( VMA(1), VMA(2), VMA(3), VMA(4), VMA(5), args[6], args[7], VMA(8), VMA(9), /*int capsule*/ qtrue );
|
||||
return 0;
|
||||
#endif
|
||||
case CG_CM_MARKFRAGMENTS:
|
||||
return re.MarkFragments( args[1], VMA(2), VMA(3), args[4], VMA(5), args[6], VMA(7) );
|
||||
case CG_S_STARTSOUND:
|
||||
|
@ -511,12 +531,14 @@ intptr_t CL_CgameSystemCalls( intptr_t *args ) {
|
|||
case CG_S_ADDLOOPINGSOUND:
|
||||
S_AddLoopingSound( args[1], VMA(2), VMA(3), args[4] );
|
||||
return 0;
|
||||
#ifndef ELITEFORCE
|
||||
case CG_S_ADDREALLOOPINGSOUND:
|
||||
S_AddRealLoopingSound( args[1], VMA(2), VMA(3), args[4] );
|
||||
return 0;
|
||||
case CG_S_STOPLOOPINGSOUND:
|
||||
S_StopLoopingSound( args[1] );
|
||||
return 0;
|
||||
#endif
|
||||
case CG_S_UPDATEENTITYPOSITION:
|
||||
S_UpdateEntityPosition( args[1], VMA(2) );
|
||||
return 0;
|
||||
|
@ -526,7 +548,12 @@ intptr_t CL_CgameSystemCalls( intptr_t *args ) {
|
|||
case CG_S_REGISTERSOUND:
|
||||
return S_RegisterSound( VMA(1), args[2] );
|
||||
case CG_S_STARTBACKGROUNDTRACK:
|
||||
S_StartBackgroundTrack( VMA(1), VMA(2) );
|
||||
#ifdef ELITEFORCE
|
||||
if(!VMA(1) || !*((char *) VMA(1)))
|
||||
S_StopBackgroundTrack();
|
||||
else
|
||||
#endif
|
||||
S_StartBackgroundTrack(VMA(1), VMA(2));
|
||||
return 0;
|
||||
case CG_R_LOADWORLDMAP:
|
||||
re.LoadWorld( VMA(1) );
|
||||
|
@ -539,9 +566,11 @@ intptr_t CL_CgameSystemCalls( intptr_t *args ) {
|
|||
return re.RegisterShader( VMA(1) );
|
||||
case CG_R_REGISTERSHADERNOMIP:
|
||||
return re.RegisterShaderNoMip( VMA(1) );
|
||||
#ifndef ELITEFORCE
|
||||
case CG_R_REGISTERFONT:
|
||||
re.RegisterFont( VMA(1), args[2], VMA(3));
|
||||
return 0;
|
||||
#endif
|
||||
case CG_R_CLEARSCENE:
|
||||
re.ClearScene();
|
||||
return 0;
|
||||
|
@ -551,17 +580,21 @@ intptr_t CL_CgameSystemCalls( intptr_t *args ) {
|
|||
case CG_R_ADDPOLYTOSCENE:
|
||||
re.AddPolyToScene( args[1], args[2], VMA(3), 1 );
|
||||
return 0;
|
||||
#ifndef ELITEFORCE
|
||||
case CG_R_ADDPOLYSTOSCENE:
|
||||
re.AddPolyToScene( args[1], args[2], VMA(3), args[4] );
|
||||
return 0;
|
||||
case CG_R_LIGHTFORPOINT:
|
||||
return re.LightForPoint( VMA(1), VMA(2), VMA(3), VMA(4) );
|
||||
#endif
|
||||
case CG_R_ADDLIGHTTOSCENE:
|
||||
re.AddLightToScene( VMA(1), VMF(2), VMF(3), VMF(4), VMF(5) );
|
||||
return 0;
|
||||
#ifndef ELITEFORCE
|
||||
case CG_R_ADDADDITIVELIGHTTOSCENE:
|
||||
re.AddAdditiveLightToScene( VMA(1), VMF(2), VMF(3), VMF(4), VMF(5) );
|
||||
return 0;
|
||||
#endif
|
||||
case CG_R_RENDERSCENE:
|
||||
re.RenderScene( VMA(1) );
|
||||
return 0;
|
||||
|
@ -598,6 +631,7 @@ intptr_t CL_CgameSystemCalls( intptr_t *args ) {
|
|||
return 0;
|
||||
case CG_MEMORY_REMAINING:
|
||||
return Hunk_MemoryRemaining();
|
||||
#ifndef ELITEFORCE
|
||||
case CG_KEY_ISDOWN:
|
||||
return Key_IsDown( args[1] );
|
||||
case CG_KEY_GETCATCHER:
|
||||
|
@ -608,7 +642,7 @@ intptr_t CL_CgameSystemCalls( intptr_t *args ) {
|
|||
return 0;
|
||||
case CG_KEY_GETKEY:
|
||||
return Key_GetKey( VMA(1) );
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
case CG_MEMSET:
|
||||
|
@ -632,9 +666,9 @@ intptr_t CL_CgameSystemCalls( intptr_t *args ) {
|
|||
return FloatAsInt( floor( VMF(1) ) );
|
||||
case CG_CEIL:
|
||||
return FloatAsInt( ceil( VMF(1) ) );
|
||||
#ifndef ELITEFORCE
|
||||
case CG_ACOS:
|
||||
return FloatAsInt( Q_acos( VMF(1) ) );
|
||||
|
||||
case CG_PC_ADD_GLOBAL_DEFINE:
|
||||
return botlib_export->PC_AddGlobalDefine( VMA(1) );
|
||||
case CG_PC_LOAD_SOURCE:
|
||||
|
@ -692,7 +726,12 @@ intptr_t CL_CgameSystemCalls( intptr_t *args ) {
|
|||
return re.GetEntityToken( VMA(1), args[2] );
|
||||
case CG_R_INPVS:
|
||||
return re.inPVS( VMA(1), VMA(2) );
|
||||
|
||||
#else
|
||||
case CG_R_REGISTERSHADER3D:
|
||||
return re.RegisterShader3D( VMA(1) );
|
||||
case CG_CVAR_SET_NO_MODIFY:
|
||||
return qfalse;
|
||||
#endif
|
||||
default:
|
||||
assert(0);
|
||||
Com_Error( ERR_DROP, "Bad cgame system trap: %ld", (long int) args[0] );
|
||||
|
|
|
@ -602,6 +602,21 @@ void Con_DrawNotify (void)
|
|||
// draw the chat line
|
||||
if ( Key_GetCatcher( ) & KEYCATCH_MESSAGE )
|
||||
{
|
||||
#ifdef ELITEFORCE
|
||||
if (chat_team)
|
||||
{
|
||||
SCR_DrawSmallString (8, v, "say_team:", 1.0f );
|
||||
skip = 11;
|
||||
}
|
||||
else
|
||||
{
|
||||
SCR_DrawSmallString (8, v, "say:", 1.0f );
|
||||
skip = 6;
|
||||
}
|
||||
|
||||
Field_Draw(&chatField, skip * SMALLCHAR_WIDTH, v,
|
||||
SCREEN_WIDTH - ( skip + 1 ) * SMALLCHAR_WIDTH, qtrue, qtrue);
|
||||
#else
|
||||
if (chat_team)
|
||||
{
|
||||
SCR_DrawBigString (8, v, "say_team:", 1.0f, qfalse );
|
||||
|
@ -615,6 +630,7 @@ void Con_DrawNotify (void)
|
|||
|
||||
Field_BigDraw( &chatField, skip * BIGCHAR_WIDTH, v,
|
||||
SCREEN_WIDTH - ( skip + 1 ) * BIGCHAR_WIDTH, qtrue, qtrue );
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -649,10 +665,18 @@ void Con_DrawSolidConsole( float frac ) {
|
|||
|
||||
// draw the background
|
||||
y = frac * SCREEN_HEIGHT;
|
||||
|
||||
if ( y < 1 ) {
|
||||
y = 0;
|
||||
}
|
||||
else {
|
||||
#ifdef ELITEFORCE
|
||||
color[0] = 0;
|
||||
color[1] = 0;
|
||||
color[2] = 0;
|
||||
color[3] = 0.85;
|
||||
re.SetColor(color);
|
||||
#endif
|
||||
SCR_DrawPic( 0, 0, SCREEN_WIDTH, y, cls.consoleShader );
|
||||
}
|
||||
|
||||
|
@ -661,8 +685,6 @@ void Con_DrawSolidConsole( float frac ) {
|
|||
color[2] = 0;
|
||||
color[3] = 1;
|
||||
SCR_FillRect( 0, y, SCREEN_WIDTH, 2, color );
|
||||
|
||||
|
||||
// draw the version number
|
||||
|
||||
re.SetColor( g_color_table[ColorIndex(COLOR_RED)] );
|
||||
|
|
|
@ -362,8 +362,10 @@ CL_MouseEvent
|
|||
void CL_MouseEvent( int dx, int dy, int time ) {
|
||||
if ( Key_GetCatcher( ) & KEYCATCH_UI ) {
|
||||
VM_Call( uivm, UI_MOUSE_EVENT, dx, dy );
|
||||
#ifndef ELITEFORCE
|
||||
} else if (Key_GetCatcher( ) & KEYCATCH_CGAME) {
|
||||
VM_Call (cgvm, CG_MOUSE_EVENT, dx, dy);
|
||||
#endif
|
||||
} else {
|
||||
cl.mouseDx[cl.mouseIndex] += dx;
|
||||
cl.mouseDy[cl.mouseIndex] += dy;
|
||||
|
@ -742,7 +744,10 @@ void CL_WritePacket( void ) {
|
|||
usercmd_t nullcmd;
|
||||
int packetNum;
|
||||
int oldPacketNum;
|
||||
int count, key;
|
||||
int count;
|
||||
#ifndef ELITEFORCE
|
||||
int key;
|
||||
#endif
|
||||
|
||||
// don't send anything if playing back a demo
|
||||
if ( clc.demoplaying || clc.state == CA_CINEMATIC ) {
|
||||
|
@ -752,9 +757,21 @@ void CL_WritePacket( void ) {
|
|||
Com_Memset( &nullcmd, 0, sizeof(nullcmd) );
|
||||
oldcmd = &nullcmd;
|
||||
|
||||
MSG_Init( &buf, data, sizeof(data) );
|
||||
#ifdef ELITEFORCE
|
||||
if(clc.compat)
|
||||
{
|
||||
MSG_InitOOB( &buf, data, sizeof(data) );
|
||||
buf.compat = clc.compat;
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif
|
||||
MSG_Init( &buf, data, sizeof(data) );
|
||||
MSG_Bitstream( &buf );
|
||||
#ifdef ELITEFORCE
|
||||
}
|
||||
#endif
|
||||
|
||||
MSG_Bitstream( &buf );
|
||||
// write the current serverId so the server
|
||||
// can tell if this is from the current gameState
|
||||
MSG_WriteLong( &buf, cl.serverId );
|
||||
|
@ -856,18 +873,24 @@ void CL_WritePacket( void ) {
|
|||
// write the command count
|
||||
MSG_WriteByte( &buf, count );
|
||||
|
||||
#ifndef ELITEFORCE
|
||||
// use the checksum feed in the key
|
||||
key = clc.checksumFeed;
|
||||
// also use the message acknowledge
|
||||
key ^= clc.serverMessageSequence;
|
||||
// also use the last acknowledged server command in the key
|
||||
key ^= MSG_HashKey(clc.serverCommands[ clc.serverCommandSequence & (MAX_RELIABLE_COMMANDS-1) ], 32);
|
||||
#endif
|
||||
|
||||
// write all the commands, including the predicted command
|
||||
for ( i = 0 ; i < count ; i++ ) {
|
||||
j = (cl.cmdNumber - count + i + 1) & CMD_MASK;
|
||||
cmd = &cl.cmds[j];
|
||||
#ifdef ELITEFORCE
|
||||
MSG_WriteDeltaUsercmd (&buf, oldcmd, cmd);
|
||||
#else
|
||||
MSG_WriteDeltaUsercmdKey (&buf, key, oldcmd, cmd);
|
||||
#endif
|
||||
oldcmd = cmd;
|
||||
}
|
||||
}
|
||||
|
@ -964,6 +987,12 @@ void CL_InitInput( void ) {
|
|||
Cmd_AddCommand ("-button3", IN_Button3Up);
|
||||
Cmd_AddCommand ("+button4", IN_Button4Down);
|
||||
Cmd_AddCommand ("-button4", IN_Button4Up);
|
||||
#ifdef ELITEFORCE
|
||||
Cmd_AddCommand ("+altattack", IN_Button5Down);
|
||||
Cmd_AddCommand ("-altattack", IN_Button5Up);
|
||||
Cmd_AddCommand ("+use", IN_Button6Down);
|
||||
Cmd_AddCommand ("-use", IN_Button6Up);
|
||||
#endif
|
||||
Cmd_AddCommand ("+button5", IN_Button5Down);
|
||||
Cmd_AddCommand ("-button5", IN_Button5Up);
|
||||
Cmd_AddCommand ("+button6", IN_Button6Down);
|
||||
|
@ -1041,6 +1070,12 @@ void CL_ShutdownInput(void)
|
|||
Cmd_RemoveCommand("-button3");
|
||||
Cmd_RemoveCommand("+button4");
|
||||
Cmd_RemoveCommand("-button4");
|
||||
#ifdef ELITEFORCE
|
||||
Cmd_RemoveCommand ("+altattack");
|
||||
Cmd_RemoveCommand ("-altattack");
|
||||
Cmd_RemoveCommand ("+use");
|
||||
Cmd_RemoveCommand ("-use");
|
||||
#endif
|
||||
Cmd_RemoveCommand("+button5");
|
||||
Cmd_RemoveCommand("-button5");
|
||||
Cmd_RemoveCommand("+button6");
|
||||
|
|
|
@ -1244,13 +1244,14 @@ void CL_KeyDownEvent( int key, unsigned time )
|
|||
return;
|
||||
}
|
||||
|
||||
#ifndef ELITEFORCE
|
||||
// escape always gets out of CGAME stuff
|
||||
if (Key_GetCatcher( ) & KEYCATCH_CGAME) {
|
||||
Key_SetCatcher( Key_GetCatcher( ) & ~KEYCATCH_CGAME );
|
||||
VM_Call (cgvm, CG_EVENT_HANDLING, CGAME_EVENT_NONE);
|
||||
return;
|
||||
}
|
||||
|
||||
#endif
|
||||
if ( !( Key_GetCatcher( ) & KEYCATCH_UI ) ) {
|
||||
if ( clc.state == CA_ACTIVE && !clc.demoplaying ) {
|
||||
VM_Call( uivm, UI_SET_ACTIVE_MENU, UIMENU_INGAME );
|
||||
|
@ -1262,8 +1263,11 @@ void CL_KeyDownEvent( int key, unsigned time )
|
|||
}
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
VM_Call( uivm, UI_KEY_EVENT, key );
|
||||
#else
|
||||
VM_Call( uivm, UI_KEY_EVENT, key, qtrue );
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1277,10 +1281,12 @@ void CL_KeyDownEvent( int key, unsigned time )
|
|||
if ( uivm ) {
|
||||
VM_Call( uivm, UI_KEY_EVENT, key, qtrue );
|
||||
}
|
||||
#ifndef ELITEFORCE
|
||||
} else if ( Key_GetCatcher( ) & KEYCATCH_CGAME ) {
|
||||
if ( cgvm ) {
|
||||
VM_Call( cgvm, CG_KEY_EVENT, key, qtrue );
|
||||
}
|
||||
#endif
|
||||
} else if ( Key_GetCatcher( ) & KEYCATCH_MESSAGE ) {
|
||||
Message_Key( key );
|
||||
} else if ( clc.state == CA_DISCONNECTED ) {
|
||||
|
@ -1317,11 +1323,13 @@ void CL_KeyUpEvent( int key, unsigned time )
|
|||
//
|
||||
CL_ParseBinding( key, qfalse, time );
|
||||
|
||||
#ifndef ELITEFORCE
|
||||
if ( Key_GetCatcher( ) & KEYCATCH_UI && uivm ) {
|
||||
VM_Call( uivm, UI_KEY_EVENT, key, qfalse );
|
||||
} else if ( Key_GetCatcher( ) & KEYCATCH_CGAME && cgvm ) {
|
||||
VM_Call( cgvm, CG_KEY_EVENT, key, qfalse );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -723,9 +723,14 @@ void CL_Record_f( void ) {
|
|||
if ( Cmd_Argc() == 2 ) {
|
||||
s = Cmd_Argv(1);
|
||||
Q_strncpyz( demoName, s, sizeof( demoName ) );
|
||||
|
||||
#ifdef LEGACY_PROTOCOL
|
||||
if(clc.compat)
|
||||
#ifdef ELITEFORCE
|
||||
Com_sprintf(name, sizeof(name), "demos/%s.efdemo", demoName);
|
||||
#else
|
||||
Com_sprintf(name, sizeof(name), "demos/%s.%s%d", demoName, DEMOEXT, com_legacyprotocol->integer);
|
||||
#endif
|
||||
else
|
||||
#endif
|
||||
Com_sprintf(name, sizeof(name), "demos/%s.%s%d", demoName, DEMOEXT, com_protocol->integer);
|
||||
|
@ -737,7 +742,11 @@ void CL_Record_f( void ) {
|
|||
CL_DemoFilename( number, demoName, sizeof( demoName ) );
|
||||
#ifdef LEGACY_PROTOCOL
|
||||
if(clc.compat)
|
||||
#ifdef ELITEFORCE
|
||||
Com_sprintf(name, sizeof(name), "demos/%s.efdemo", demoName);
|
||||
#else
|
||||
Com_sprintf(name, sizeof(name), "demos/%s.%s%d", demoName, DEMOEXT, com_legacyprotocol->integer);
|
||||
#endif
|
||||
else
|
||||
#endif
|
||||
Com_sprintf(name, sizeof(name), "demos/%s.%s%d", demoName, DEMOEXT, com_protocol->integer);
|
||||
|
@ -768,11 +777,23 @@ void CL_Record_f( void ) {
|
|||
clc.demowaiting = qtrue;
|
||||
|
||||
// write out the gamestate message
|
||||
MSG_Init (&buf, bufData, sizeof(bufData));
|
||||
MSG_Bitstream(&buf);
|
||||
#ifdef ELITEFORCE
|
||||
if(clc.compat)
|
||||
{
|
||||
MSG_InitOOB(&buf, bufData, sizeof(bufData));
|
||||
buf.compat = qtrue;
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif
|
||||
MSG_Init (&buf, bufData, sizeof(bufData));
|
||||
MSG_Bitstream(&buf);
|
||||
|
||||
// NOTE, MRE: all server->client messages now acknowledge
|
||||
MSG_WriteLong( &buf, clc.reliableSequence );
|
||||
// NOTE, MRE: all server->client messages now acknowledge
|
||||
MSG_WriteLong( &buf, clc.reliableSequence );
|
||||
#ifdef ELITEFORCE
|
||||
}
|
||||
#endif
|
||||
|
||||
MSG_WriteByte (&buf, svc_gamestate);
|
||||
MSG_WriteLong (&buf, clc.serverCommandSequence );
|
||||
|
@ -799,17 +820,30 @@ void CL_Record_f( void ) {
|
|||
MSG_WriteDeltaEntity (&buf, &nullstate, ent, qtrue );
|
||||
}
|
||||
|
||||
MSG_WriteByte( &buf, svc_EOF );
|
||||
#ifdef ELITEFORCE
|
||||
if(buf.compat)
|
||||
MSG_WriteByte(&buf, 0);
|
||||
else
|
||||
#endif
|
||||
MSG_WriteByte( &buf, svc_EOF );
|
||||
|
||||
// finished writing the gamestate stuff
|
||||
|
||||
// write the client num
|
||||
MSG_WriteLong(&buf, clc.clientNum);
|
||||
// write the checksum feed
|
||||
MSG_WriteLong(&buf, clc.checksumFeed);
|
||||
#ifdef ELITEFORCE
|
||||
if(!buf.compat)
|
||||
{
|
||||
#endif
|
||||
// write the client num
|
||||
MSG_WriteLong(&buf, clc.clientNum);
|
||||
|
||||
// finished writing the client packet
|
||||
MSG_WriteByte( &buf, svc_EOF );
|
||||
// write the checksum feed
|
||||
MSG_WriteLong(&buf, clc.checksumFeed);
|
||||
|
||||
// finished writing the client packet
|
||||
MSG_WriteByte( &buf, svc_EOF );
|
||||
#ifdef ELITEFORCE
|
||||
}
|
||||
#endif
|
||||
|
||||
// write it to the demo file
|
||||
len = LittleLong( clc.serverMessageSequence - 1 );
|
||||
|
@ -952,7 +986,15 @@ void CL_ReadDemoMessage( void ) {
|
|||
clc.serverMessageSequence = LittleLong( s );
|
||||
|
||||
// init the message
|
||||
MSG_Init( &buf, bufData, sizeof( bufData ) );
|
||||
#ifdef ELITEFORCE
|
||||
if(clc.compat)
|
||||
{
|
||||
MSG_InitOOB(&buf, bufData, sizeof(bufData));
|
||||
buf.compat = qtrue;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
MSG_Init( &buf, bufData, sizeof( bufData ) );
|
||||
|
||||
// get the length
|
||||
r = FS_Read (&buf.cursize, 4, clc.demofile);
|
||||
|
@ -989,11 +1031,15 @@ static int CL_WalkDemoExt(char *arg, char *name, int *demofile)
|
|||
{
|
||||
int i = 0;
|
||||
*demofile = 0;
|
||||
|
||||
|
||||
#ifdef LEGACY_PROTOCOL
|
||||
if(com_legacyprotocol->integer > 0)
|
||||
{
|
||||
#ifdef ELITEFORCE
|
||||
Com_sprintf(name, MAX_OSPATH, "demos/%s.efdemo", arg);
|
||||
#else
|
||||
Com_sprintf(name, MAX_OSPATH, "demos/%s.%s%d", arg, DEMOEXT, com_legacyprotocol->integer);
|
||||
#endif
|
||||
FS_FOpenFileRead(name, demofile, qtrue);
|
||||
|
||||
if (*demofile)
|
||||
|
@ -1084,9 +1130,20 @@ void CL_PlayDemo_f( void ) {
|
|||
|
||||
// open the demo file
|
||||
arg = Cmd_Argv(1);
|
||||
|
||||
CL_Disconnect( qtrue );
|
||||
|
||||
CL_Disconnect( qtrue );
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
ext_test = arg + strlen(arg) - 7;
|
||||
if(!strcmp(ext_test, ".efdemo"))
|
||||
{
|
||||
Com_sprintf (name, sizeof(name), "demos/%s", arg);
|
||||
FS_FOpenFileRead(name, &clc.demofile, qtrue);
|
||||
protocol = com_legacyprotocol->integer;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
// check for an extension .DEMOEXT_?? (?? is protocol)
|
||||
ext_test = strrchr(arg, '.');
|
||||
|
||||
|
@ -1126,6 +1183,7 @@ void CL_PlayDemo_f( void ) {
|
|||
}
|
||||
else
|
||||
protocol = CL_WalkDemoExt(arg, name, &clc.demofile);
|
||||
}
|
||||
|
||||
if (!clc.demofile) {
|
||||
Com_Error( ERR_DROP, "couldn't open %s", name);
|
||||
|
@ -1900,7 +1958,12 @@ void CL_SendPureChecksums( void ) {
|
|||
char cMsg[MAX_INFO_VALUE];
|
||||
|
||||
// if we are pure we need to send back a command with our referenced pk3 checksums
|
||||
Com_sprintf(cMsg, sizeof(cMsg), "cp %d %s", cl.serverId, FS_ReferencedPakPureChecksums());
|
||||
#ifdef ELITEFORCE
|
||||
if(clc.compat)
|
||||
Com_sprintf(cMsg, sizeof(cMsg), "cp %s", FS_ReferencedPakPureChecksums());
|
||||
else
|
||||
#endif
|
||||
Com_sprintf(cMsg, sizeof(cMsg), "cp %d %s", cl.serverId, FS_ReferencedPakPureChecksums());
|
||||
|
||||
CL_AddReliableCommand(cMsg, qfalse);
|
||||
}
|
||||
|
@ -2389,7 +2452,11 @@ void CL_CheckForResend( void ) {
|
|||
Info_SetValueForKey( info, "challenge", va("%i", clc.challenge ) );
|
||||
|
||||
Com_sprintf( data, sizeof(data), "connect \"%s\"", info );
|
||||
NET_OutOfBandData( NS_CLIENT, clc.serverAddress, (byte *) data, strlen ( data ) );
|
||||
#ifdef ELITEFORCE
|
||||
NET_OutOfBandPrint( NS_CLIENT, clc.serverAddress, "%s", data);
|
||||
#else
|
||||
NET_OutOfBandData( NS_CLIENT, clc.serverAddress, (byte *) data, strlen ( data ) );
|
||||
#endif
|
||||
// the most current userinfo has been sent, so watch for any
|
||||
// newer changes to userinfo variables
|
||||
cvar_modifiedFlags &= ~CVAR_USERINFO;
|
||||
|
@ -2467,6 +2534,9 @@ void CL_ServersResponsePacket( const netadr_t* from, msg_t *msg, qboolean extend
|
|||
int numservers;
|
||||
byte* buffptr;
|
||||
byte* buffend;
|
||||
#ifdef ELITEFORCE
|
||||
char strbyte[3] = "FF";
|
||||
#endif
|
||||
|
||||
Com_Printf("CL_ServersResponsePacket\n");
|
||||
|
||||
|
@ -2496,12 +2566,30 @@ void CL_ServersResponsePacket( const netadr_t* from, msg_t *msg, qboolean extend
|
|||
if (*buffptr == '\\')
|
||||
{
|
||||
buffptr++;
|
||||
#ifdef ELITEFORCE
|
||||
if (buffend - buffptr < sizeof(addresses[numservers].ip) * 2 + sizeof(addresses[numservers].port) * 2 + 1)
|
||||
break;
|
||||
|
||||
// EliteForce uses a slightly different format with bytes encoded
|
||||
// in hex values.
|
||||
for(i = 0; i < 6; i++)
|
||||
{
|
||||
strbyte[0] = toupper(*buffptr++);
|
||||
strbyte[1] = toupper(*buffptr++);
|
||||
|
||||
if(i < 4)
|
||||
addresses[numservers].ip[i] = strtoul(strbyte, NULL, 16);
|
||||
else
|
||||
((unsigned char *) &addresses[numservers].port)[i - 4] =
|
||||
strtoul(strbyte, NULL, 16);
|
||||
}
|
||||
#else
|
||||
if (buffend - buffptr < sizeof(addresses[numservers].ip) + sizeof(addresses[numservers].port) + 1)
|
||||
break;
|
||||
|
||||
for(i = 0; i < sizeof(addresses[numservers].ip); i++)
|
||||
addresses[numservers].ip[i] = *buffptr++;
|
||||
#endif
|
||||
|
||||
addresses[numservers].type = NA_IP;
|
||||
}
|
||||
|
@ -2517,17 +2605,24 @@ void CL_ServersResponsePacket( const netadr_t* from, msg_t *msg, qboolean extend
|
|||
addresses[numservers].ip6[i] = *buffptr++;
|
||||
|
||||
addresses[numservers].type = NA_IP6;
|
||||
#ifdef ELITEFORCE
|
||||
// parse out port
|
||||
addresses[numservers].port = (*buffptr++) << 8;
|
||||
addresses[numservers].port += *buffptr++;
|
||||
addresses[numservers].port = BigShort( addresses[numservers].port );
|
||||
#endif
|
||||
addresses[numservers].scope_id = from->scope_id;
|
||||
}
|
||||
else
|
||||
// syntax error!
|
||||
break;
|
||||
|
||||
#ifndef ELITEFORCE
|
||||
// parse out port
|
||||
addresses[numservers].port = (*buffptr++) << 8;
|
||||
addresses[numservers].port += *buffptr++;
|
||||
addresses[numservers].port = BigShort( addresses[numservers].port );
|
||||
|
||||
#endif
|
||||
// syntax check
|
||||
if (*buffptr != '\\' && *buffptr != '/')
|
||||
break;
|
||||
|
@ -2728,6 +2823,9 @@ void CL_ConnectionlessPacket( netadr_t from, msg_t *msg ) {
|
|||
clc.challenge, qfalse);
|
||||
#endif
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
clc.netchan.compat = clc.compat;
|
||||
#endif
|
||||
clc.state = CA_CONNECTED;
|
||||
clc.lastPacketSentTime = -9999; // send first packet immediately
|
||||
return;
|
||||
|
@ -2800,7 +2898,10 @@ void CL_PacketEvent( netadr_t from, msg_t *msg ) {
|
|||
int headerBytes;
|
||||
|
||||
clc.lastPacketTime = cls.realtime;
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
msg->compat = clc.compat;
|
||||
#endif
|
||||
|
||||
if ( msg->cursize >= 4 && *(int *)msg->data == -1 ) {
|
||||
CL_ConnectionlessPacket( from, msg );
|
||||
return;
|
||||
|
@ -3117,7 +3218,11 @@ void CL_InitRenderer( void ) {
|
|||
re.BeginRegistration( &cls.glconfig );
|
||||
|
||||
// load character sets
|
||||
#ifdef ELITEFORCE
|
||||
cls.charSetShader = re.RegisterShaderNoMip( "gfx/2d/charsgrid_med" );
|
||||
#else
|
||||
cls.charSetShader = re.RegisterShader( "gfx/2d/bigchars" );
|
||||
#endif
|
||||
cls.whiteShader = re.RegisterShader( "white" );
|
||||
cls.consoleShader = re.RegisterShader( "console" );
|
||||
g_console_field_width = cls.glconfig.vidWidth / SMALLCHAR_WIDTH - 2;
|
||||
|
@ -3496,6 +3601,8 @@ void CL_Init( void ) {
|
|||
}
|
||||
|
||||
cls.realtime = 0;
|
||||
clc.lastPacketTime = 0;
|
||||
clc.lastPacketSentTime = -9999;
|
||||
|
||||
CL_InitInput ();
|
||||
|
||||
|
@ -3530,7 +3637,11 @@ void CL_Init( void ) {
|
|||
cl_pitchspeed = Cvar_Get ("cl_pitchspeed", "140", CVAR_ARCHIVE);
|
||||
cl_anglespeedkey = Cvar_Get ("cl_anglespeedkey", "1.5", 0);
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
cl_maxpackets = Cvar_Get ("cl_maxpackets", "43", CVAR_ARCHIVE );
|
||||
#else
|
||||
cl_maxpackets = Cvar_Get ("cl_maxpackets", "30", CVAR_ARCHIVE );
|
||||
#endif
|
||||
cl_packetdup = Cvar_Get ("cl_packetdup", "1", CVAR_ARCHIVE );
|
||||
|
||||
cl_run = Cvar_Get ("cl_run", "1", CVAR_ARCHIVE);
|
||||
|
@ -3611,12 +3722,14 @@ void CL_Init( void ) {
|
|||
Cvar_Get ("name", "UnnamedPlayer", CVAR_USERINFO | CVAR_ARCHIVE );
|
||||
cl_rate = Cvar_Get ("rate", "25000", CVAR_USERINFO | CVAR_ARCHIVE );
|
||||
Cvar_Get ("snaps", "20", CVAR_USERINFO | CVAR_ARCHIVE );
|
||||
Cvar_Get ("model", "sarge", CVAR_USERINFO | CVAR_ARCHIVE );
|
||||
Cvar_Get ("headmodel", "sarge", CVAR_USERINFO | CVAR_ARCHIVE );
|
||||
Cvar_Get ("model", "munro/red", CVAR_USERINFO | CVAR_ARCHIVE );
|
||||
#ifndef ELITEFORCE
|
||||
Cvar_Get ("headmodel", "munro", CVAR_USERINFO | CVAR_ARCHIVE );
|
||||
Cvar_Get ("team_model", "james", CVAR_USERINFO | CVAR_ARCHIVE );
|
||||
Cvar_Get ("team_headmodel", "*james", CVAR_USERINFO | CVAR_ARCHIVE );
|
||||
Cvar_Get ("g_redTeam", "Stroggs", CVAR_SERVERINFO | CVAR_ARCHIVE);
|
||||
Cvar_Get ("g_blueTeam", "Pagans", CVAR_SERVERINFO | CVAR_ARCHIVE);
|
||||
#endif
|
||||
Cvar_Get ("color1", "4", CVAR_USERINFO | CVAR_ARCHIVE );
|
||||
Cvar_Get ("color2", "5", CVAR_USERINFO | CVAR_ARCHIVE );
|
||||
Cvar_Get ("handicap", "100", CVAR_USERINFO | CVAR_ARCHIVE );
|
||||
|
@ -3824,6 +3937,19 @@ void CL_ServerInfoPacket( netadr_t from, msg_t *msg ) {
|
|||
char *gamename;
|
||||
qboolean gameMismatch;
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
// eliteforce doesn't send a \n after infoResponse..
|
||||
infoString = strchr((char *) msg->data, '"');
|
||||
if(!infoString)
|
||||
return;
|
||||
msg->readcount = (int) ((byte *) ++infoString - msg->data);
|
||||
msg->bit = msg->readcount << 3;
|
||||
// find the second " character and empty it.
|
||||
infoString = strchr(infoString, '"');
|
||||
if(infoString)
|
||||
*infoString = '\0';
|
||||
#endif
|
||||
|
||||
infoString = MSG_ReadString( msg );
|
||||
|
||||
// if this isn't the correct gamename, ignore it
|
||||
|
@ -3861,6 +3987,10 @@ void CL_ServerInfoPacket( netadr_t from, msg_t *msg ) {
|
|||
{
|
||||
if ( cl_pinglist[i].adr.port && !cl_pinglist[i].time && NET_CompareAdr( from, cl_pinglist[i].adr ) )
|
||||
{
|
||||
#ifdef ELITEFORCE
|
||||
char *str = "";
|
||||
#endif
|
||||
|
||||
// calc ping time
|
||||
cl_pinglist[i].time = Sys_Milliseconds() - cl_pinglist[i].start;
|
||||
Com_DPrintf( "ping time %dms from %s\n", cl_pinglist[i].time, NET_AdrToString( from ) );
|
||||
|
@ -3875,15 +4005,25 @@ void CL_ServerInfoPacket( netadr_t from, msg_t *msg ) {
|
|||
case NA_BROADCAST:
|
||||
case NA_IP:
|
||||
type = 1;
|
||||
#ifdef ELITEFORCE
|
||||
str = "udp";
|
||||
#endif
|
||||
break;
|
||||
case NA_IP6:
|
||||
type = 2;
|
||||
#ifdef ELITEFORCE
|
||||
str = "udp6";
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
type = 0;
|
||||
break;
|
||||
}
|
||||
Info_SetValueForKey( cl_pinglist[i].info, "nettype", va("%d", type) );
|
||||
#ifdef ELITEFORCE
|
||||
Info_SetValueForKey( cl_pinglist[i].info, "nettype", str);
|
||||
#else
|
||||
Info_SetValueForKey( cl_pinglist[i].info, "nettype", va("%d", type));
|
||||
#endif
|
||||
CL_SetServerInfoByAddress(from, infoString, cl_pinglist[i].time);
|
||||
|
||||
return;
|
||||
|
@ -4183,7 +4323,7 @@ void CL_GlobalServers_f( void ) {
|
|||
// -1 is used to distinguish a "no response"
|
||||
|
||||
i = NET_StringToAdr(masteraddress, &to, NA_UNSPEC);
|
||||
|
||||
|
||||
if(!i)
|
||||
{
|
||||
Com_Printf( "CL_GlobalServers_f: Error: could not resolve address of master %s\n", masteraddress);
|
||||
|
@ -4217,8 +4357,13 @@ void CL_GlobalServers_f( void ) {
|
|||
Com_sprintf(command, sizeof(command), "getservers %s",
|
||||
Cmd_Argv(2));
|
||||
else
|
||||
#ifdef ELITEFORCE
|
||||
Com_sprintf(command, sizeof(command), "getservers %s",
|
||||
Cmd_Argv(2));
|
||||
#else
|
||||
Com_sprintf(command, sizeof(command), "getservers %s %s",
|
||||
com_gamename->string, Cmd_Argv(2));
|
||||
#endif
|
||||
|
||||
for (i=3; i < count; i++)
|
||||
{
|
||||
|
|
|
@ -24,6 +24,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
#include "../qcommon/qcommon.h"
|
||||
#include "client.h"
|
||||
|
||||
#ifndef ELITEFORCE
|
||||
#ifdef LEGACY_PROTOCOL
|
||||
/*
|
||||
==============
|
||||
|
@ -36,6 +37,7 @@ CL_Netchan_Encode
|
|||
|
||||
==============
|
||||
*/
|
||||
|
||||
static void CL_Netchan_Encode( msg_t *msg ) {
|
||||
int serverId, messageAcknowledge, reliableAcknowledge;
|
||||
int i, index, srdc, sbit, soob;
|
||||
|
@ -90,6 +92,7 @@ CL_Netchan_Decode
|
|||
|
||||
==============
|
||||
*/
|
||||
|
||||
static void CL_Netchan_Decode( msg_t *msg ) {
|
||||
long reliableAcknowledge, i, index;
|
||||
byte key, *string;
|
||||
|
@ -127,6 +130,7 @@ static void CL_Netchan_Decode( msg_t *msg ) {
|
|||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
=================
|
||||
|
@ -150,11 +154,16 @@ CL_Netchan_Transmit
|
|||
================
|
||||
*/
|
||||
void CL_Netchan_Transmit( netchan_t *chan, msg_t* msg ) {
|
||||
MSG_WriteByte( msg, clc_EOF );
|
||||
#ifdef ELITEFORCE
|
||||
if(!chan->compat)
|
||||
#endif
|
||||
MSG_WriteByte( msg, clc_EOF );
|
||||
|
||||
#ifndef ELITEFORCE
|
||||
#ifdef LEGACY_PROTOCOL
|
||||
if(chan->compat)
|
||||
CL_Netchan_Encode(msg);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
Netchan_Transmit(chan, msg->cursize, msg->data);
|
||||
|
@ -177,10 +186,11 @@ qboolean CL_Netchan_Process( netchan_t *chan, msg_t *msg ) {
|
|||
ret = Netchan_Process( chan, msg );
|
||||
if (!ret)
|
||||
return qfalse;
|
||||
|
||||
#ifndef ELITEFORCE
|
||||
#ifdef LEGACY_PROTOCOL
|
||||
if(chan->compat)
|
||||
CL_Netchan_Decode(msg);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return qtrue;
|
||||
|
|
|
@ -210,7 +210,10 @@ void CL_ParseSnapshot( msg_t *msg ) {
|
|||
|
||||
// get the reliable sequence acknowledge number
|
||||
// NOTE: now sent with all server to client messages
|
||||
//clc.reliableAcknowledge = MSG_ReadLong( msg );
|
||||
#ifdef ELITEFORCE
|
||||
if(msg->compat)
|
||||
clc.reliableAcknowledge = MSG_ReadLong( msg );
|
||||
#endif
|
||||
|
||||
// read in the new snapshot to a temporary buffer
|
||||
// we will only copy to cl.snap if it is valid
|
||||
|
@ -483,9 +486,12 @@ void CL_ParseGamestate( msg_t *msg ) {
|
|||
while ( 1 ) {
|
||||
cmd = MSG_ReadByte( msg );
|
||||
|
||||
if ( cmd == svc_EOF ) {
|
||||
#ifdef ELITEFORCE
|
||||
if((msg->compat && cmd <= 0) || cmd == svc_EOF)
|
||||
#else
|
||||
if ( cmd == svc_EOF )
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
if ( cmd == svc_configstring ) {
|
||||
int len;
|
||||
|
@ -518,9 +524,16 @@ void CL_ParseGamestate( msg_t *msg ) {
|
|||
}
|
||||
}
|
||||
|
||||
clc.clientNum = MSG_ReadLong(msg);
|
||||
#ifdef ELITEFORCE
|
||||
if(!msg->compat)
|
||||
#endif
|
||||
clc.clientNum = MSG_ReadLong(msg);
|
||||
|
||||
// read the checksum feed
|
||||
clc.checksumFeed = MSG_ReadLong( msg );
|
||||
#ifdef ELITEFORCE
|
||||
if(!clc.demoplaying || !msg->compat)
|
||||
#endif
|
||||
clc.checksumFeed = MSG_ReadLong( msg );
|
||||
|
||||
// save old gamedir
|
||||
Cvar_VariableStringBuffer("fs_game", oldGame, sizeof(oldGame));
|
||||
|
@ -864,14 +877,21 @@ void CL_ParseServerMessage( msg_t *msg ) {
|
|||
Com_Printf ("------------------\n");
|
||||
}
|
||||
|
||||
MSG_Bitstream(msg);
|
||||
#ifdef ELITEFORCE
|
||||
if(!msg->compat)
|
||||
{
|
||||
#endif
|
||||
MSG_Bitstream(msg);
|
||||
|
||||
// get the reliable sequence acknowledge number
|
||||
clc.reliableAcknowledge = MSG_ReadLong( msg );
|
||||
//
|
||||
if ( clc.reliableAcknowledge < clc.reliableSequence - MAX_RELIABLE_COMMANDS ) {
|
||||
clc.reliableAcknowledge = clc.reliableSequence;
|
||||
// get the reliable sequence acknowledge number
|
||||
clc.reliableAcknowledge = MSG_ReadLong( msg );
|
||||
//
|
||||
if ( clc.reliableAcknowledge < clc.reliableSequence - MAX_RELIABLE_COMMANDS ) {
|
||||
clc.reliableAcknowledge = clc.reliableSequence;
|
||||
}
|
||||
#ifdef ELITEFORCE
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// parse the message
|
||||
|
@ -884,7 +904,12 @@ void CL_ParseServerMessage( msg_t *msg ) {
|
|||
|
||||
cmd = MSG_ReadByte( msg );
|
||||
|
||||
if (cmd == svc_EOF) {
|
||||
#ifdef ELITEFORCE
|
||||
if(cmd == svc_EOF || (msg->compat && cmd == -1))
|
||||
#else
|
||||
if ( cmd == svc_EOF)
|
||||
#endif
|
||||
{
|
||||
SHOWNET( msg, "END OF MESSAGE" );
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -160,7 +160,7 @@ static void SCR_DrawChar( int x, int y, float size, int ch ) {
|
|||
void SCR_DrawSmallChar( int x, int y, int ch ) {
|
||||
int row, col;
|
||||
float frow, fcol;
|
||||
float size;
|
||||
float vsize, hsize;
|
||||
|
||||
ch &= 255;
|
||||
|
||||
|
@ -177,11 +177,16 @@ void SCR_DrawSmallChar( int x, int y, int ch ) {
|
|||
|
||||
frow = row*0.0625;
|
||||
fcol = col*0.0625;
|
||||
size = 0.0625;
|
||||
vsize = 0.0625;
|
||||
#ifdef ELITEFORCE
|
||||
hsize = 0.03125;
|
||||
#else
|
||||
hsize = 0.0625;
|
||||
#endif
|
||||
|
||||
re.DrawStretchPic( x, y, SMALLCHAR_WIDTH, SMALLCHAR_HEIGHT,
|
||||
fcol, frow,
|
||||
fcol + size, frow + size,
|
||||
fcol + hsize, frow + vsize,
|
||||
cls.charSetShader );
|
||||
}
|
||||
|
||||
|
@ -255,6 +260,16 @@ void SCR_DrawBigStringColor( int x, int y, const char *s, vec4_t color, qboolean
|
|||
SCR_DrawStringExt( x, y, BIGCHAR_WIDTH, s, color, qtrue, noColorEscape );
|
||||
}
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
void SCR_DrawSmallString(int x, int y, const char *s, float alpha)
|
||||
{
|
||||
float color[4];
|
||||
|
||||
color[0] = color[1] = color[2] = 1.0;
|
||||
color[3] = alpha;
|
||||
SCR_DrawSmallStringExt(x, y, s, color, qfalse, qfalse);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
==================
|
||||
|
|
|
@ -84,7 +84,7 @@ void LAN_SaveServersToCache( void ) {
|
|||
FS_FCloseFile(fileOut);
|
||||
}
|
||||
|
||||
|
||||
#ifndef ELITEFORCE
|
||||
/*
|
||||
====================
|
||||
LAN_ResetPings
|
||||
|
@ -204,7 +204,7 @@ static void LAN_RemoveServer(int source, const char *addr) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
====================
|
||||
|
@ -226,7 +226,6 @@ static int LAN_GetServerCount( int source ) {
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
LAN_GetLocalServerAddressString
|
||||
|
@ -257,6 +256,7 @@ static void LAN_GetServerAddressString( int source, int n, char *buf, int buflen
|
|||
buf[0] = '\0';
|
||||
}
|
||||
|
||||
#ifndef ELITEFORCE
|
||||
/*
|
||||
====================
|
||||
LAN_GetServerInfo
|
||||
|
@ -365,7 +365,6 @@ static serverInfo_t *LAN_GetServerPtr( int source, int n ) {
|
|||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
LAN_CompareServers
|
||||
|
@ -435,6 +434,8 @@ static int LAN_CompareServers( int source, int sortKey, int sortDir, int s1, int
|
|||
return res;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
====================
|
||||
LAN_GetPingQueueCount
|
||||
|
@ -471,6 +472,7 @@ static void LAN_GetPingInfo( int n, char *buf, int buflen ) {
|
|||
CL_GetPingInfo( n, buf, buflen );
|
||||
}
|
||||
|
||||
#ifndef ELITEFORCE
|
||||
/*
|
||||
====================
|
||||
LAN_MarkServerVisible
|
||||
|
@ -549,6 +551,8 @@ static int LAN_ServerIsVisible(int source, int n ) {
|
|||
return qfalse;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
=======================
|
||||
LAN_UpdateVisiblePings
|
||||
|
@ -627,6 +631,7 @@ static void Key_GetBindingBuf( int keynum, char *buf, int buflen ) {
|
|||
CLUI_GetCDKey
|
||||
====================
|
||||
*/
|
||||
#ifndef ELITEFORCE
|
||||
static void CLUI_GetCDKey( char *buf, int buflen ) {
|
||||
#ifndef STANDALONE
|
||||
cvar_t *fs;
|
||||
|
@ -642,7 +647,7 @@ static void CLUI_GetCDKey( char *buf, int buflen ) {
|
|||
*buf = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
====================
|
||||
|
@ -659,7 +664,12 @@ static void CLUI_SetCDKey( char *buf ) {
|
|||
// set the flag so the fle will be written at the next opportunity
|
||||
cvar_modifiedFlags |= CVAR_ARCHIVE;
|
||||
} else {
|
||||
#ifdef ELITEFORCE
|
||||
Com_Memcpy(cl_cdkey, buf, 22);
|
||||
cl_cdkey[22] = '\0';
|
||||
#else
|
||||
Com_Memcpy( cl_cdkey, buf, 16 );
|
||||
#endif
|
||||
// set the flag so the fle will be written at the next opportunity
|
||||
cvar_modifiedFlags |= CVAR_ARCHIVE;
|
||||
}
|
||||
|
@ -794,8 +804,10 @@ intptr_t CL_UISystemCalls( intptr_t *args ) {
|
|||
case UI_FS_GETFILELIST:
|
||||
return FS_GetFileList( VMA(1), VMA(2), VMA(3), args[4] );
|
||||
|
||||
#ifndef ELITEFORCE
|
||||
case UI_FS_SEEK:
|
||||
return FS_Seek( args[1], args[2], args[3] );
|
||||
#endif
|
||||
|
||||
case UI_R_REGISTERMODEL:
|
||||
return re.RegisterModel( VMA(1) );
|
||||
|
@ -902,6 +914,7 @@ intptr_t CL_UISystemCalls( intptr_t *args ) {
|
|||
case UI_GETCONFIGSTRING:
|
||||
return GetConfigString( args[1], VMA(2), args[3] );
|
||||
|
||||
#ifndef ELITEFORCE
|
||||
case UI_LAN_LOADCACHEDSERVERS:
|
||||
LAN_LoadCachedServers();
|
||||
return 0;
|
||||
|
@ -916,6 +929,7 @@ intptr_t CL_UISystemCalls( intptr_t *args ) {
|
|||
case UI_LAN_REMOVESERVER:
|
||||
LAN_RemoveServer(args[1], VMA(2));
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
case UI_LAN_GETPINGQUEUECOUNT:
|
||||
return LAN_GetPingQueueCount();
|
||||
|
@ -932,13 +946,26 @@ intptr_t CL_UISystemCalls( intptr_t *args ) {
|
|||
LAN_GetPingInfo( args[1], VMA(2), args[3] );
|
||||
return 0;
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
case UI_LAN_GETLOCALSERVERCOUNT:
|
||||
return LAN_GetServerCount(AS_LOCAL);
|
||||
|
||||
case UI_LAN_GETLOCALSERVERADDRESSSTRING:
|
||||
LAN_GetServerAddressString( AS_LOCAL, args[1], VMA(2), args[3] );
|
||||
return 0;
|
||||
case UI_LAN_GETGLOBALSERVERCOUNT:
|
||||
return LAN_GetServerCount(AS_GLOBAL);
|
||||
|
||||
case UI_LAN_GETGLOBALSERVERADDRESSSTRING:
|
||||
LAN_GetServerAddressString( AS_GLOBAL, args[1], VMA(2), args[3] );
|
||||
return 0;
|
||||
#else
|
||||
case UI_LAN_GETSERVERCOUNT:
|
||||
return LAN_GetServerCount(args[1]);
|
||||
|
||||
case UI_LAN_GETSERVERADDRESSSTRING:
|
||||
LAN_GetServerAddressString( args[1], args[2], VMA(3), args[4] );
|
||||
return 0;
|
||||
|
||||
case UI_LAN_GETSERVERINFO:
|
||||
LAN_GetServerInfo( args[1], args[2], VMA(3), args[4] );
|
||||
return 0;
|
||||
|
@ -965,26 +992,32 @@ intptr_t CL_UISystemCalls( intptr_t *args ) {
|
|||
|
||||
case UI_LAN_COMPARESERVERS:
|
||||
return LAN_CompareServers( args[1], args[2], args[3], args[4], args[5] );
|
||||
#endif
|
||||
|
||||
case UI_MEMORY_REMAINING:
|
||||
return Hunk_MemoryRemaining();
|
||||
|
||||
#ifndef ELITEFORCE
|
||||
case UI_GET_CDKEY:
|
||||
CLUI_GetCDKey( VMA(1), args[2] );
|
||||
return 0;
|
||||
|
||||
#endif
|
||||
case UI_SET_CDKEY:
|
||||
#ifndef STANDALONE
|
||||
CLUI_SetCDKey( VMA(1) );
|
||||
#ifdef ELITEFORCE
|
||||
return qtrue;
|
||||
#endif
|
||||
#endif
|
||||
return 0;
|
||||
|
||||
#ifndef ELITEFORCE
|
||||
case UI_SET_PBCLSTATUS:
|
||||
return 0;
|
||||
|
||||
case UI_R_REGISTERFONT:
|
||||
re.RegisterFont( VMA(1), args[2], VMA(3));
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
case UI_MEMSET:
|
||||
Com_Memset( VMA(1), args[2], args[3] );
|
||||
|
@ -1016,6 +1049,7 @@ intptr_t CL_UISystemCalls( intptr_t *args ) {
|
|||
case UI_CEIL:
|
||||
return FloatAsInt( ceil( VMF(1) ) );
|
||||
|
||||
#ifndef ELITEFORCE
|
||||
case UI_PC_ADD_GLOBAL_DEFINE:
|
||||
return botlib_export->PC_AddGlobalDefine( VMA(1) );
|
||||
case UI_PC_LOAD_SOURCE:
|
||||
|
@ -1061,6 +1095,7 @@ intptr_t CL_UISystemCalls( intptr_t *args ) {
|
|||
|
||||
case UI_VERIFY_CDKEY:
|
||||
return CL_CDKeyValidate(VMA(1), VMA(2));
|
||||
#endif
|
||||
|
||||
default:
|
||||
Com_Error( ERR_DROP, "Bad UI system trap: %ld", (long int) args[0] );
|
||||
|
@ -1117,6 +1152,10 @@ void CL_InitUI( void ) {
|
|||
// Com_Printf(S_COLOR_YELLOW "WARNING: loading old Quake III Arena User Interface version %d\n", v );
|
||||
// init for this gamestate
|
||||
VM_Call( uivm, UI_INIT, (clc.state >= CA_AUTHORIZING && clc.state < CA_ACTIVE));
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
Cvar_SetValue("ui_cdkeychecked2", 1);
|
||||
#endif
|
||||
}
|
||||
else if (v != UI_API_VERSION) {
|
||||
// Free uivm now, so UI_SHUTDOWN doesn't get called later.
|
||||
|
@ -1129,16 +1168,24 @@ void CL_InitUI( void ) {
|
|||
else {
|
||||
// init for this gamestate
|
||||
VM_Call( uivm, UI_INIT, (clc.state >= CA_AUTHORIZING && clc.state < CA_ACTIVE) );
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
Cvar_SetValue("ui_cdkeychecked2", 1);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef STANDALONE
|
||||
qboolean UI_usesUniqueCDKey( void ) {
|
||||
#ifdef ELITEFORCE
|
||||
return qfalse;
|
||||
#else
|
||||
if (uivm) {
|
||||
return (VM_Call( uivm, UI_HASUNIQUECDKEY) == qtrue);
|
||||
} else {
|
||||
return qfalse;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -575,6 +575,9 @@ void SCR_DrawNamedPic( float x, float y, float width, float height, const char *
|
|||
|
||||
void SCR_DrawBigString( int x, int y, const char *s, float alpha, qboolean noColorEscape ); // draws a string with embedded color control characters with fade
|
||||
void SCR_DrawBigStringColor( int x, int y, const char *s, vec4_t color, qboolean noColorEscape ); // ignores embedded color control characters
|
||||
#ifdef ELITEFORCE
|
||||
void SCR_DrawSmallString( int x, int y, const char *s, float alpha ); // draws a string with embedded color control characters with fade
|
||||
#endif
|
||||
void SCR_DrawSmallStringExt( int x, int y, const char *string, float *setColor, qboolean forceColor, qboolean noColorEscape );
|
||||
void SCR_DrawSmallChar( int x, int y, int ch );
|
||||
|
||||
|
|
|
@ -26,6 +26,34 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
|
||||
static snd_codec_t *codecs;
|
||||
|
||||
static void *S_CodecGetSound(const char *filename, snd_info_t *info);
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
int sem = qtrue;
|
||||
#define VOXDIR "sound/voice"
|
||||
|
||||
void *S_MangleNameEF(char *filename, snd_info_t *info)
|
||||
{
|
||||
char localName[MAX_QPATH];
|
||||
|
||||
if(
|
||||
!Q_strncmp(filename, VOXDIR, ARRAY_LEN(VOXDIR) - 1) &&
|
||||
!Q_stricmp(Cvar_VariableString("s_language"), "DEUTSCH")
|
||||
)
|
||||
{
|
||||
Q_strncpyz(localName, filename, MAX_QPATH - 10);
|
||||
|
||||
localName[8] = 'x';
|
||||
localName[9] = '_';
|
||||
localName[10] = 'd';
|
||||
|
||||
return S_CodecGetSound(localName, info);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
=================
|
||||
S_CodecGetSound
|
||||
|
@ -46,6 +74,12 @@ static void *S_CodecGetSound(const char *filename, snd_info_t *info)
|
|||
|
||||
Q_strncpyz(localName, filename, MAX_QPATH);
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
rtn = S_MangleNameEF(localName, info);
|
||||
if(rtn)
|
||||
return rtn;
|
||||
#endif
|
||||
|
||||
ext = COM_GetExtension(localName);
|
||||
|
||||
if( *ext )
|
||||
|
@ -110,7 +144,7 @@ static void *S_CodecGetSound(const char *filename, snd_info_t *info)
|
|||
}
|
||||
}
|
||||
|
||||
Com_Printf(S_COLOR_YELLOW "WARNING: Failed to %s sound %s!\n", info ? "load" : "open", filename);
|
||||
Com_DPrintf(S_COLOR_YELLOW "WARNING: Failed to %s sound %s!\n", info ? "load" : "open", filename);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -131,6 +165,9 @@ void S_CodecInit()
|
|||
#ifdef USE_CODEC_VORBIS
|
||||
S_CodecRegister(&ogg_codec);
|
||||
#endif
|
||||
#if USE_CODEC_MP3
|
||||
S_CodecRegister(&mp3_codec);
|
||||
#endif
|
||||
|
||||
// Register wav codec last so that it is always tried first when a file extension was not found
|
||||
S_CodecRegister(&wav_codec);
|
||||
|
@ -162,6 +199,7 @@ void S_CodecRegister(snd_codec_t *codec)
|
|||
S_CodecLoad
|
||||
=================
|
||||
*/
|
||||
|
||||
void *S_CodecLoad(const char *filename, snd_info_t *info)
|
||||
{
|
||||
return S_CodecGetSound(filename, info);
|
||||
|
|
|
@ -95,6 +95,15 @@ void S_OGG_CodecCloseStream(snd_stream_t *stream);
|
|||
int S_OGG_CodecReadStream(snd_stream_t *stream, int bytes, void *buffer);
|
||||
#endif // USE_CODEC_VORBIS
|
||||
|
||||
// MP3 codec
|
||||
#ifdef USE_CODEC_MP3
|
||||
extern snd_codec_t mp3_codec;
|
||||
void *S_MP3_CodecLoad(const char *filename, snd_info_t *info);
|
||||
snd_stream_t *S_MP3_CodecOpenStream(const char *filename);
|
||||
void S_MP3_CodecCloseStream(snd_stream_t *stream);
|
||||
int S_MP3_CodecReadStream(snd_stream_t *stream, int bytes, void *buffer);
|
||||
#endif // USE_CODEC_MP3
|
||||
|
||||
// Ogg Opus codec
|
||||
#ifdef USE_CODEC_OPUS
|
||||
extern snd_codec_t opus_codec;
|
||||
|
|
716
code/client/snd_codec_mp3.c
Normal file
716
code/client/snd_codec_mp3.c
Normal file
|
@ -0,0 +1,716 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
Copyright (C) 2005 Stuart Dalton (badcdev@gmail.com)
|
||||
Copyright (C) 2005-2006 Joerg Dietrich <dietrich_joerg@gmx.de>
|
||||
Copyright (C) 2006 Thilo Schulz <arny@ats.s.bawue.de>
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Quake III Arena source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
// MP3 support is enabled by this define
|
||||
#if USE_CODEC_MP3
|
||||
|
||||
// includes for the Q3 sound system
|
||||
#include "client.h"
|
||||
#include "snd_codec.h"
|
||||
|
||||
// includes for the MP3 codec
|
||||
#include <mad.h>
|
||||
|
||||
#define MP3_SAMPLE_WIDTH 2
|
||||
#define MP3_PCMSAMPLES_PERSLICE 32
|
||||
|
||||
// buffer size used when reading through the mp3
|
||||
#define MP3_DATA_BUFSIZ 128*1024
|
||||
|
||||
// undefine this if you don't want any dithering.
|
||||
#define MP3_DITHERING
|
||||
|
||||
// Q3 MP3 codec
|
||||
snd_codec_t mp3_codec =
|
||||
{
|
||||
"mp3",
|
||||
S_MP3_CodecLoad,
|
||||
S_MP3_CodecOpenStream,
|
||||
S_MP3_CodecReadStream,
|
||||
S_MP3_CodecCloseStream,
|
||||
NULL
|
||||
};
|
||||
|
||||
// structure used for info purposes
|
||||
struct snd_codec_mp3_info
|
||||
{
|
||||
byte encbuf[MP3_DATA_BUFSIZ]; // left over bytes not consumed
|
||||
// by the decoder.
|
||||
struct mad_stream madstream; // uses encbuf as buffer.
|
||||
struct mad_frame madframe; // control structures for libmad.
|
||||
struct mad_synth madsynth;
|
||||
|
||||
byte *pcmbuf; // buffer for not-used samples.
|
||||
int buflen; // length of buffer data.
|
||||
int pcmbufsize; // amount of allocated memory for
|
||||
// pcmbuf. This should have at least
|
||||
// the size of a decoded mp3 frame.
|
||||
|
||||
byte *dest; // copy decoded data here.
|
||||
int destlen; // amount of already copied data.
|
||||
int destsize; // amount of bytes we must decode.
|
||||
};
|
||||
|
||||
/*************** MP3 utility functions ***************/
|
||||
|
||||
/*
|
||||
=================
|
||||
S_MP3_ReadData
|
||||
=================
|
||||
*/
|
||||
|
||||
// feed libmad with data
|
||||
int S_MP3_ReadData(snd_stream_t *stream, struct mad_stream *madstream, byte *encbuf, int encbufsize)
|
||||
{
|
||||
int retval;
|
||||
int leftover;
|
||||
|
||||
if(!stream)
|
||||
return -1;
|
||||
|
||||
leftover = madstream->bufend - madstream->next_frame;
|
||||
if(leftover > 0)
|
||||
memmove(encbuf, madstream->this_frame, leftover);
|
||||
|
||||
|
||||
// Fill the buffer right to the end
|
||||
|
||||
retval = FS_Read(&encbuf[leftover], encbufsize - leftover, stream->file);
|
||||
|
||||
if(retval <= 0)
|
||||
{
|
||||
// EOF reached, that's ok.
|
||||
return 0;
|
||||
}
|
||||
|
||||
mad_stream_buffer(madstream, encbuf, retval + leftover);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
S_MP3_Scanfile
|
||||
|
||||
to determine the samplecount, we apparently must get *all* headers :(
|
||||
I basically used the xmms-mad plugin source to see how this stuff works.
|
||||
|
||||
returns a value < 0 on error.
|
||||
=================
|
||||
*/
|
||||
|
||||
int S_MP3_Scanfile(snd_stream_t *stream)
|
||||
{
|
||||
struct mad_stream madstream;
|
||||
struct mad_header madheader;
|
||||
int retval;
|
||||
int samplecount;
|
||||
byte encbuf[MP3_DATA_BUFSIZ];
|
||||
|
||||
// error out on invalid input.
|
||||
if(!stream)
|
||||
return -1;
|
||||
|
||||
mad_stream_init(&madstream);
|
||||
mad_header_init(&madheader);
|
||||
|
||||
while(1)
|
||||
{
|
||||
retval = S_MP3_ReadData(stream, &madstream, encbuf, sizeof(encbuf));
|
||||
if(retval < 0)
|
||||
return -1;
|
||||
else if(retval == 0)
|
||||
break;
|
||||
|
||||
// Start decoding the headers.
|
||||
while(1)
|
||||
{
|
||||
if((retval = mad_header_decode(&madheader, &madstream)) < 0)
|
||||
{
|
||||
if(madstream.error == MAD_ERROR_BUFLEN)
|
||||
{
|
||||
// We need to read more data
|
||||
break;
|
||||
}
|
||||
|
||||
if(!MAD_RECOVERABLE (madstream.error))
|
||||
{
|
||||
// unrecoverable error... we must bail out.
|
||||
return retval;
|
||||
}
|
||||
|
||||
mad_stream_skip(&madstream, madstream.skiplen);
|
||||
continue;
|
||||
}
|
||||
|
||||
// we got a valid header.
|
||||
|
||||
if(madheader.layer != MAD_LAYER_III)
|
||||
{
|
||||
// we don't support non-mp3s
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(!stream->info.samples)
|
||||
{
|
||||
// This here is the very first frame. Set initial values now,
|
||||
// that we expect to stay constant throughout the whole mp3.
|
||||
|
||||
stream->info.rate = madheader.samplerate;
|
||||
stream->info.width = MP3_SAMPLE_WIDTH;
|
||||
stream->info.channels = MAD_NCHANNELS(&madheader);
|
||||
stream->info.samples = 0;
|
||||
stream->info.size = 0; // same here.
|
||||
stream->info.dataofs = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Check whether something changed that shouldn't.
|
||||
|
||||
if(stream->info.rate != madheader.samplerate ||
|
||||
stream->info.channels != MAD_NCHANNELS(&madheader))
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Update the counters
|
||||
samplecount = MAD_NSBSAMPLES(&madheader) * MP3_PCMSAMPLES_PERSLICE;
|
||||
stream->info.samples += samplecount;
|
||||
stream->info.size += samplecount * stream->info.channels * stream->info.width;
|
||||
}
|
||||
}
|
||||
|
||||
// Reset the file pointer so we can do the real decoding.
|
||||
FS_Seek(stream->file, 0, FS_SEEK_SET);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/************************ dithering functions ***************************/
|
||||
|
||||
#ifdef MP3_DITHERING
|
||||
|
||||
// All dithering done here is taken from the GPL'ed xmms-mad plugin.
|
||||
|
||||
/* Copyright (C) 1997 Makoto Matsumoto and Takuji Nishimura. */
|
||||
/* Any feedback is very welcome. For any question, comments, */
|
||||
/* see http://www.math.keio.ac.jp/matumoto/emt.html or email */
|
||||
/* matumoto@math.keio.ac.jp */
|
||||
|
||||
/* Period parameters */
|
||||
#define MP3_DITH_N 624
|
||||
#define MP3_DITH_M 397
|
||||
#define MATRIX_A 0x9908b0df /* constant vector a */
|
||||
#define UPPER_MASK 0x80000000 /* most significant w-r bits */
|
||||
#define LOWER_MASK 0x7fffffff /* least significant r bits */
|
||||
|
||||
/* Tempering parameters */
|
||||
#define TEMPERING_MASK_B 0x9d2c5680
|
||||
#define TEMPERING_MASK_C 0xefc60000
|
||||
#define TEMPERING_SHIFT_U(y) (y >> 11)
|
||||
#define TEMPERING_SHIFT_S(y) (y << 7)
|
||||
#define TEMPERING_SHIFT_T(y) (y << 15)
|
||||
#define TEMPERING_SHIFT_L(y) (y >> 18)
|
||||
|
||||
static unsigned long mt[MP3_DITH_N]; /* the array for the state vector */
|
||||
static int mti=MP3_DITH_N+1; /* mti==MP3_DITH_N+1 means mt[MP3_DITH_N] is not initialized */
|
||||
|
||||
/* initializing the array with a NONZERO seed */
|
||||
void sgenrand(unsigned long seed)
|
||||
{
|
||||
/* setting initial seeds to mt[MP3_DITH_N] using */
|
||||
/* the generator Line 25 of Table 1 in */
|
||||
/* [KNUTH 1981, The Art of Computer Programming */
|
||||
/* Vol. 2 (2nd Ed.), pp102] */
|
||||
mt[0]= seed & 0xffffffff;
|
||||
for (mti=1; mti<MP3_DITH_N; mti++)
|
||||
mt[mti] = (69069 * mt[mti-1]) & 0xffffffff;
|
||||
}
|
||||
|
||||
unsigned long genrand(void)
|
||||
{
|
||||
unsigned long y;
|
||||
static unsigned long mag01[2]={0x0, MATRIX_A};
|
||||
/* mag01[x] = x * MATRIX_A for x=0,1 */
|
||||
|
||||
if (mti >= MP3_DITH_N) { /* generate MP3_DITH_N words at one time */
|
||||
int kk;
|
||||
|
||||
if (mti == MP3_DITH_N+1) /* if sgenrand() has not been called, */
|
||||
sgenrand(4357); /* a default initial seed is used */
|
||||
|
||||
for (kk=0;kk<MP3_DITH_N-MP3_DITH_M;kk++) {
|
||||
y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
|
||||
mt[kk] = mt[kk+MP3_DITH_M] ^ (y >> 1) ^ mag01[y & 0x1];
|
||||
}
|
||||
for (;kk<MP3_DITH_N-1;kk++) {
|
||||
y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
|
||||
mt[kk] = mt[kk+(MP3_DITH_M-MP3_DITH_N)] ^ (y >> 1) ^ mag01[y & 0x1];
|
||||
}
|
||||
y = (mt[MP3_DITH_N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK);
|
||||
mt[MP3_DITH_N-1] = mt[MP3_DITH_M-1] ^ (y >> 1) ^ mag01[y & 0x1];
|
||||
|
||||
mti = 0;
|
||||
}
|
||||
|
||||
y = mt[mti++];
|
||||
y ^= TEMPERING_SHIFT_U(y);
|
||||
y ^= TEMPERING_SHIFT_S(y) & TEMPERING_MASK_B;
|
||||
y ^= TEMPERING_SHIFT_T(y) & TEMPERING_MASK_C;
|
||||
y ^= TEMPERING_SHIFT_L(y);
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
long triangular_dither_noise(int nbits) {
|
||||
// parameter nbits : the peak-to-peak amplitude desired (in bits)
|
||||
// use with nbits set to 2 + nber of bits to be trimmed.
|
||||
// (because triangular is made from two uniformly distributed processes,
|
||||
// it starts at 2 bits peak-to-peak amplitude)
|
||||
// see The Theory of Dithered Quantization by Robert Alexander Wannamaker
|
||||
// for complete proof of why that's optimal
|
||||
|
||||
long v = (genrand()/2 - genrand()/2); // in ]-2^31, 2^31[
|
||||
//int signe = (v>0) ? 1 : -1;
|
||||
long P = 1 << (32 - nbits); // the power of 2
|
||||
v /= P;
|
||||
// now v in ]-2^(nbits-1), 2^(nbits-1) [
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
#endif // MP3_DITHERING
|
||||
|
||||
/************************ decoder functions ***************************/
|
||||
|
||||
/*
|
||||
=================
|
||||
S_MP3_Scale
|
||||
|
||||
Converts the signal to 16 bit LE-PCM data and does dithering.
|
||||
|
||||
- borrowed from xmms-mad plugin source.
|
||||
=================
|
||||
*/
|
||||
|
||||
/*
|
||||
* xmms-mad - mp3 plugin for xmms
|
||||
* Copyright (C) 2001-2002 Sam Clegg
|
||||
*/
|
||||
|
||||
signed int S_MP3_Scale(mad_fixed_t sample)
|
||||
{
|
||||
int n_bits_to_loose = MAD_F_FRACBITS + 1 - 16;
|
||||
#ifdef MP3_DITHERING
|
||||
int dither;
|
||||
#endif
|
||||
|
||||
// round
|
||||
sample += (1L << (n_bits_to_loose - 1));
|
||||
|
||||
#ifdef MP3_DITHERING
|
||||
dither = triangular_dither_noise(n_bits_to_loose + 1);
|
||||
sample += dither;
|
||||
#endif
|
||||
|
||||
/* clip */
|
||||
if (sample >= MAD_F_ONE)
|
||||
sample = MAD_F_ONE - 1;
|
||||
else if (sample < -MAD_F_ONE)
|
||||
sample = -MAD_F_ONE;
|
||||
|
||||
/* quantize */
|
||||
return sample >> n_bits_to_loose;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
S_MP3_PCMCopy
|
||||
|
||||
Copy and convert pcm data until bytecount bytes have been written.
|
||||
return the position in pcm->samples.
|
||||
indicate the amount of actually written bytes in wrotecnt.
|
||||
=================
|
||||
*/
|
||||
|
||||
int S_MP3_PCMCopy(byte *buf, struct mad_pcm *pcm, int bufofs,
|
||||
int sampleofs, int bytecount, int *wrotecnt)
|
||||
{
|
||||
int written = 0;
|
||||
signed int sample;
|
||||
int framesize = pcm->channels * MP3_SAMPLE_WIDTH;
|
||||
|
||||
// add new pcm data.
|
||||
while(written < bytecount && sampleofs < pcm->length)
|
||||
{
|
||||
sample = S_MP3_Scale(pcm->samples[0][sampleofs]);
|
||||
|
||||
#ifdef Q3_BIG_ENDIAN
|
||||
// output to 16 bit big endian PCM
|
||||
buf[bufofs++] = (sample >> 8) & 0xff;
|
||||
buf[bufofs++] = sample & 0xff;
|
||||
#else
|
||||
// output to 16 bit little endian PCM
|
||||
buf[bufofs++] = sample & 0xff;
|
||||
buf[bufofs++] = (sample >> 8) & 0xff;
|
||||
#endif
|
||||
|
||||
if(pcm->channels == 2)
|
||||
{
|
||||
sample = S_MP3_Scale(pcm->samples[1][sampleofs]);
|
||||
|
||||
#ifdef Q3_BIG_ENDIAN
|
||||
buf[bufofs++] = (sample >> 8) & 0xff;
|
||||
buf[bufofs++] = sample & 0xff;
|
||||
#else
|
||||
buf[bufofs++] = sample & 0xff;
|
||||
buf[bufofs++] = (sample >> 8) & 0xff;
|
||||
#endif
|
||||
}
|
||||
|
||||
sampleofs++;
|
||||
written += framesize;
|
||||
}
|
||||
|
||||
if(wrotecnt)
|
||||
*wrotecnt = written;
|
||||
|
||||
return sampleofs;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
S_MP3_Decode
|
||||
=================
|
||||
*/
|
||||
|
||||
// gets executed for every decoded frame.
|
||||
int S_MP3_Decode(snd_stream_t *stream)
|
||||
{
|
||||
struct snd_codec_mp3_info *mp3info;
|
||||
struct mad_stream *madstream;
|
||||
struct mad_frame *madframe;
|
||||
struct mad_synth *madsynth;
|
||||
struct mad_pcm *pcm;
|
||||
int cursize;
|
||||
int samplecount;
|
||||
int needcount;
|
||||
int wrote;
|
||||
int retval;
|
||||
|
||||
if(!stream)
|
||||
return -1;
|
||||
|
||||
mp3info = stream->ptr;
|
||||
madstream = &mp3info->madstream;
|
||||
madframe = &mp3info->madframe;
|
||||
|
||||
if(mad_frame_decode(madframe, madstream))
|
||||
{
|
||||
if(madstream->error == MAD_ERROR_BUFLEN)
|
||||
{
|
||||
// we need more data. Read another chunk.
|
||||
retval = S_MP3_ReadData(stream, madstream, mp3info->encbuf, sizeof(mp3info->encbuf));
|
||||
|
||||
// call myself again now that buffer is full.
|
||||
if(retval > 0)
|
||||
retval = S_MP3_Decode(stream);
|
||||
}
|
||||
else if(MAD_RECOVERABLE(madstream->error))
|
||||
{
|
||||
mad_stream_skip(madstream, madstream->skiplen);
|
||||
return S_MP3_Decode(stream);
|
||||
}
|
||||
else
|
||||
retval = -1;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
// check whether this really is an mp3
|
||||
if(madframe->header.layer != MAD_LAYER_III)
|
||||
return -1;
|
||||
|
||||
// generate pcm data
|
||||
madsynth = &mp3info->madsynth;
|
||||
mad_synth_frame(madsynth, madframe);
|
||||
|
||||
pcm = &madsynth->pcm;
|
||||
|
||||
// perform a few checks to see whether something changed that shouldn't.
|
||||
|
||||
if(stream->info.rate != pcm->samplerate ||
|
||||
stream->info.channels != pcm->channels)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
// see whether we have got enough data now.
|
||||
cursize = pcm->length * pcm->channels * stream->info.width;
|
||||
needcount = mp3info->destsize - mp3info->destlen;
|
||||
|
||||
// Copy exactly as many samples as required.
|
||||
samplecount = S_MP3_PCMCopy(mp3info->dest, pcm,
|
||||
mp3info->destlen, 0, needcount, &wrote);
|
||||
mp3info->destlen += wrote;
|
||||
|
||||
if(samplecount < pcm->length)
|
||||
{
|
||||
// Not all samples got copied. Copy the rest into the pcm buffer.
|
||||
samplecount = S_MP3_PCMCopy(mp3info->pcmbuf, pcm,
|
||||
mp3info->buflen,
|
||||
samplecount,
|
||||
mp3info->pcmbufsize - mp3info->buflen,
|
||||
&wrote);
|
||||
mp3info->buflen += wrote;
|
||||
|
||||
|
||||
if(samplecount < pcm->length)
|
||||
{
|
||||
// The pcm buffer was not large enough. Make it bigger.
|
||||
byte *newbuf = Z_Malloc(cursize);
|
||||
|
||||
if(mp3info->pcmbuf)
|
||||
{
|
||||
memcpy(newbuf, mp3info->pcmbuf, mp3info->buflen);
|
||||
Z_Free(mp3info->pcmbuf);
|
||||
}
|
||||
|
||||
mp3info->pcmbuf = newbuf;
|
||||
mp3info->pcmbufsize = cursize;
|
||||
|
||||
samplecount = S_MP3_PCMCopy(mp3info->pcmbuf, pcm,
|
||||
mp3info->buflen,
|
||||
samplecount,
|
||||
mp3info->pcmbufsize - mp3info->buflen,
|
||||
&wrote);
|
||||
mp3info->buflen += wrote;
|
||||
}
|
||||
|
||||
// we're definitely done.
|
||||
retval = 0;
|
||||
}
|
||||
else if(mp3info->destlen >= mp3info->destsize)
|
||||
retval = 0;
|
||||
else
|
||||
retval = 1;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*************** Callback functions for quake3 ***************/
|
||||
|
||||
/*
|
||||
=================
|
||||
S_MP3_CodecOpenStream
|
||||
=================
|
||||
*/
|
||||
|
||||
snd_stream_t *S_MP3_CodecOpenStream(const char *filename)
|
||||
{
|
||||
snd_stream_t *stream;
|
||||
struct snd_codec_mp3_info *mp3info;
|
||||
|
||||
// Open the stream
|
||||
stream = S_CodecUtilOpen(filename, &mp3_codec);
|
||||
if(!stream || stream->length <= 0)
|
||||
return NULL;
|
||||
|
||||
// We have to scan through the MP3 to determine the important mp3 info.
|
||||
if(S_MP3_Scanfile(stream) < 0)
|
||||
{
|
||||
// scanning didn't work out...
|
||||
S_CodecUtilClose(&stream);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Initialize the mp3 info structure we need for streaming
|
||||
mp3info = Z_Malloc(sizeof(*mp3info));
|
||||
if(!mp3info)
|
||||
{
|
||||
S_CodecUtilClose(&stream);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
stream->ptr = mp3info;
|
||||
|
||||
// initialize the libmad control structures.
|
||||
mad_stream_init(&mp3info->madstream);
|
||||
mad_frame_init(&mp3info->madframe);
|
||||
mad_synth_init(&mp3info->madsynth);
|
||||
|
||||
if(S_MP3_ReadData(stream, &mp3info->madstream, mp3info->encbuf, sizeof(mp3info->encbuf)) <= 0)
|
||||
{
|
||||
// we didnt read anything, that's bad.
|
||||
S_MP3_CodecCloseStream(stream);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_MP3_CodecCloseStream
|
||||
=================
|
||||
*/
|
||||
|
||||
// free all memory we allocated.
|
||||
void S_MP3_CodecCloseStream(snd_stream_t *stream)
|
||||
{
|
||||
struct snd_codec_mp3_info *mp3info;
|
||||
|
||||
if(!stream)
|
||||
return;
|
||||
|
||||
// free all data in our mp3info tree
|
||||
|
||||
if(stream->ptr)
|
||||
{
|
||||
mp3info = stream->ptr;
|
||||
|
||||
if(mp3info->pcmbuf)
|
||||
Z_Free(mp3info->pcmbuf);
|
||||
|
||||
mad_synth_finish(&mp3info->madsynth);
|
||||
mad_frame_finish(&mp3info->madframe);
|
||||
mad_stream_finish(&mp3info->madstream);
|
||||
|
||||
Z_Free(stream->ptr);
|
||||
}
|
||||
|
||||
S_CodecUtilClose(&stream);
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_MP3_CodecReadStream
|
||||
=================
|
||||
*/
|
||||
int S_MP3_CodecReadStream(snd_stream_t *stream, int bytes, void *buffer)
|
||||
{
|
||||
struct snd_codec_mp3_info *mp3info;
|
||||
int retval;
|
||||
|
||||
if(!stream)
|
||||
return -1;
|
||||
|
||||
mp3info = stream->ptr;
|
||||
|
||||
// Make sure we get complete frames all the way through.
|
||||
bytes -= bytes % (stream->info.channels * stream->info.width);
|
||||
|
||||
if(mp3info->buflen)
|
||||
{
|
||||
if(bytes < mp3info->buflen)
|
||||
{
|
||||
// we still have enough bytes in our decoded pcm buffer
|
||||
memcpy(buffer, mp3info->pcmbuf, bytes);
|
||||
|
||||
// remove the portion from our buffer.
|
||||
mp3info->buflen -= bytes;
|
||||
memmove(mp3info->pcmbuf, &mp3info->pcmbuf[bytes], mp3info->buflen);
|
||||
return bytes;
|
||||
}
|
||||
else
|
||||
{
|
||||
// copy over the samples we already have.
|
||||
memcpy(buffer, mp3info->pcmbuf, mp3info->buflen);
|
||||
mp3info->destlen = mp3info->buflen;
|
||||
mp3info->buflen = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
mp3info->destlen = 0;
|
||||
|
||||
mp3info->dest = buffer;
|
||||
mp3info->destsize = bytes;
|
||||
|
||||
do
|
||||
{
|
||||
retval = S_MP3_Decode(stream);
|
||||
} while(retval > 0);
|
||||
|
||||
// if there was an error return nothing.
|
||||
if(retval < 0)
|
||||
return 0;
|
||||
|
||||
return mp3info->destlen;
|
||||
}
|
||||
|
||||
/*
|
||||
=====================================================================
|
||||
S_MP3_CodecLoad
|
||||
|
||||
We handle S_MP3_CodecLoad as a special case of the streaming functions
|
||||
where we read the whole stream at once.
|
||||
======================================================================
|
||||
*/
|
||||
void *S_MP3_CodecLoad(const char *filename, snd_info_t *info)
|
||||
{
|
||||
snd_stream_t *stream;
|
||||
byte *pcmbuffer;
|
||||
|
||||
// check if input is valid
|
||||
if(!filename)
|
||||
return NULL;
|
||||
|
||||
stream = S_MP3_CodecOpenStream(filename);
|
||||
|
||||
if(!stream)
|
||||
return NULL;
|
||||
|
||||
// copy over the info
|
||||
info->rate = stream->info.rate;
|
||||
info->width = stream->info.width;
|
||||
info->channels = stream->info.channels;
|
||||
info->samples = stream->info.samples;
|
||||
info->dataofs = stream->info.dataofs;
|
||||
|
||||
// allocate enough buffer for all pcm data
|
||||
pcmbuffer = Hunk_AllocateTempMemory(stream->info.size);
|
||||
if(!pcmbuffer)
|
||||
{
|
||||
S_MP3_CodecCloseStream(stream);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
info->size = S_MP3_CodecReadStream(stream, stream->info.size, pcmbuffer);
|
||||
|
||||
if(info->size <= 0)
|
||||
{
|
||||
// we didn't read anything at all. darn.
|
||||
Hunk_FreeTempMemory(pcmbuffer);
|
||||
pcmbuffer = NULL;
|
||||
}
|
||||
|
||||
S_MP3_CodecCloseStream(stream);
|
||||
|
||||
return pcmbuffer;
|
||||
}
|
||||
|
||||
#endif // USE_CODEC_MP3
|
|
@ -375,10 +375,20 @@ sfxHandle_t S_Base_RegisterSound( const char *name, qboolean compressed ) {
|
|||
sfx->inMemory = qfalse;
|
||||
sfx->soundCompressed = compressed;
|
||||
|
||||
S_memoryLoad(sfx);
|
||||
S_memoryLoad(sfx);
|
||||
|
||||
if ( sfx->defaultSound ) {
|
||||
#ifdef ELITEFORCE
|
||||
int hash = S_HashSFXName(name);
|
||||
// free the slot up.
|
||||
sfx->soundName[0] = '\0';
|
||||
sfx->inMemory = qfalse;
|
||||
sfx->defaultSound = qfalse;
|
||||
// the new entry is head anyways.
|
||||
sfxHash[hash] = sfx->next;
|
||||
#else
|
||||
Com_Printf( S_COLOR_YELLOW "WARNING: could not find %s - using default\n", sfx->soundName );
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -400,7 +410,11 @@ void S_Base_BeginRegistration( void ) {
|
|||
Com_Memset(s_knownSfx, '\0', sizeof(s_knownSfx));
|
||||
Com_Memset(sfxHash, '\0', sizeof(sfx_t *) * LOOP_HASH);
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
S_Base_RegisterSound("sound/null.wav", qfalse); // Eliteforce specific sound.
|
||||
#else
|
||||
S_Base_RegisterSound("sound/feedback/hit.wav", qfalse); // changed to a sound in baseq3
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1399,9 +1413,11 @@ static void S_OpenBackgroundStream( const char *filename ) {
|
|||
return;
|
||||
}
|
||||
|
||||
#ifndef ELITEFORCE
|
||||
if(s_backgroundStream->info.channels != 2 || s_backgroundStream->info.rate != 22050) {
|
||||
Com_Printf(S_COLOR_YELLOW "WARNING: music file %s is not 22k stereo\n", filename );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -376,7 +376,12 @@ static void S_AL_BufferLoad(sfxHandle_t sfx, qboolean cache)
|
|||
data = S_CodecLoad(curSfx->filename, &info);
|
||||
if(!data)
|
||||
{
|
||||
#ifdef ELITEFORCE
|
||||
S_AL_BufferUnload(sfx);
|
||||
*knownSfx[sfx].filename = '\0';
|
||||
#else
|
||||
S_AL_BufferUseDefault(sfx);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -481,7 +486,11 @@ qboolean S_AL_BufferInit( void )
|
|||
numSfx = 0;
|
||||
|
||||
// Load the default sound, and lock it
|
||||
#ifdef ELITEFORCE
|
||||
default_sfx = S_AL_BufferFind("sound/null.wav");
|
||||
#else
|
||||
default_sfx = S_AL_BufferFind("sound/feedback/hit.wav");
|
||||
#endif
|
||||
S_AL_BufferUse(default_sfx);
|
||||
knownSfx[default_sfx].isLocked = qtrue;
|
||||
|
||||
|
@ -529,6 +538,12 @@ sfxHandle_t S_AL_RegisterSound( const char *sample, qboolean compressed )
|
|||
|
||||
if((!knownSfx[sfx].inMemory) && (!knownSfx[sfx].isDefault))
|
||||
S_AL_BufferLoad(sfx, s_alPrecache->integer);
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
if(! *knownSfx[sfx].filename)
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
knownSfx[sfx].lastUsedTime = Com_Milliseconds();
|
||||
|
||||
if (knownSfx[sfx].isDefault) {
|
||||
|
|
|
@ -263,6 +263,11 @@ typedef enum {
|
|||
#define EF_AWARD_DENIED 0x00040000 // denied
|
||||
#define EF_TEAMVOTED 0x00080000 // already cast a team vote
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
#define EF_SHIELD_BOX_X 0x00000800
|
||||
#define EF_SHIELD_BOX_Y 0x00400000
|
||||
#endif
|
||||
|
||||
// NOTE: may not have more than 16
|
||||
typedef enum {
|
||||
PW_NONE,
|
||||
|
|
|
@ -33,9 +33,19 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
|
||||
// TTimo
|
||||
// https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=551
|
||||
#ifdef ELITEFORCE
|
||||
#define SVF_SHIELD_BBOX 0x00000002
|
||||
#define SVF_CLIENTMASK 0x00000004
|
||||
#else
|
||||
#define SVF_CLIENTMASK 0x00000002
|
||||
#endif
|
||||
|
||||
#define SVF_BOT 0x00000008 // set if the entity is a bot
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
#define SVF_ELIMINATED 0x00000010
|
||||
#endif
|
||||
|
||||
#define SVF_BROADCAST 0x00000020 // send to all connected clients
|
||||
#define SVF_PORTAL 0x00000040 // merge a second pvs at origin2 into snapshots
|
||||
#define SVF_USE_CURRENT_ORIGIN 0x00000080 // entity->r.currentOrigin instead of entity->s.origin
|
||||
|
@ -54,8 +64,9 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
|
||||
|
||||
typedef struct {
|
||||
#ifndef ELITEFORCE
|
||||
entityState_t unused; // apparently this field was put here accidentally
|
||||
// (and is kept only for compatibility, as a struct pad)
|
||||
#endif
|
||||
|
||||
qboolean linked; // qfalse if not in any good cluster
|
||||
int linkcount;
|
||||
|
@ -104,6 +115,280 @@ typedef struct {
|
|||
//
|
||||
// system traps provided by the main engine
|
||||
//
|
||||
#ifdef ELITEFORCE
|
||||
typedef enum {
|
||||
//============== general Quake services ==================
|
||||
|
||||
G_PRINT, // ( const char *string );
|
||||
// print message on the local console
|
||||
|
||||
G_ERROR, // ( const char *string );
|
||||
// abort the game
|
||||
|
||||
G_MILLISECONDS, // ( void );
|
||||
// get current time for profiling reasons
|
||||
// this should NOT be used for any game related tasks,
|
||||
// because it is not journaled
|
||||
|
||||
// console variable interaction
|
||||
G_CVAR_REGISTER, // ( vmCvar_t *vmCvar, const char *varName, const char *defaultValue, int flags );
|
||||
G_CVAR_UPDATE, // ( vmCvar_t *vmCvar );
|
||||
G_CVAR_SET, // ( const char *var_name, const char *value );
|
||||
G_CVAR_VARIABLE_INTEGER_VALUE, // ( const char *var_name );
|
||||
|
||||
G_CVAR_VARIABLE_STRING_BUFFER, // ( const char *var_name, char *buffer, int bufsize );
|
||||
|
||||
G_ARGC, // ( void );
|
||||
// ClientCommand and ServerCommand parameter access
|
||||
|
||||
G_ARGV, // ( int n, char *buffer, int bufferLength );
|
||||
|
||||
G_FS_FOPEN_FILE, // ( const char *qpath, fileHandle_t *file, fsMode_t mode );
|
||||
G_FS_READ, // ( void *buffer, int len, fileHandle_t f );
|
||||
G_FS_WRITE, // ( const void *buffer, int len, fileHandle_t f );
|
||||
G_FS_FCLOSE_FILE, // ( fileHandle_t f );
|
||||
|
||||
G_SEND_CONSOLE_COMMAND, // ( const char *text );
|
||||
// add commands to the console as if they were typed in
|
||||
// for map changing, etc
|
||||
|
||||
|
||||
//=========== server specific functionality =============
|
||||
|
||||
G_LOCATE_GAME_DATA, // ( gentity_t *gEnts, int numGEntities, int sizeofGEntity_t,
|
||||
// playerState_t *clients, int sizeofGameClient );
|
||||
// the game needs to let the server system know where and how big the gentities
|
||||
// are, so it can look at them directly without going through an interface
|
||||
|
||||
G_DROP_CLIENT, // ( int clientNum, const char *reason );
|
||||
// kick a client off the server with a message
|
||||
|
||||
G_SEND_SERVER_COMMAND, // ( int clientNum, const char *fmt, ... );
|
||||
// reliably sends a command string to be interpreted by the given
|
||||
// client. If clientNum is -1, it will be sent to all clients
|
||||
|
||||
G_SET_CONFIGSTRING, // ( int num, const char *string );
|
||||
// config strings hold all the index strings, and various other information
|
||||
// that is reliably communicated to all clients
|
||||
// All of the current configstrings are sent to clients when
|
||||
// they connect, and changes are sent to all connected clients.
|
||||
// All confgstrings are cleared at each level start.
|
||||
|
||||
G_GET_CONFIGSTRING, // ( int num, char *buffer, int bufferSize );
|
||||
|
||||
G_GET_USERINFO, // ( int num, char *buffer, int bufferSize );
|
||||
// userinfo strings are maintained by the server system, so they
|
||||
// are persistant across level loads, while all other game visible
|
||||
// data is completely reset
|
||||
|
||||
G_SET_USERINFO, // ( int num, const char *buffer );
|
||||
|
||||
G_GET_SERVERINFO, // ( char *buffer, int bufferSize );
|
||||
// the serverinfo info string has all the cvars visible to server browsers
|
||||
|
||||
G_SET_BRUSH_MODEL, // ( gentity_t *ent, const char *name );
|
||||
// sets mins and maxs based on the brushmodel name
|
||||
|
||||
G_TRACE, // ( trace_t *results, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int passEntityNum,
|
||||
// collision detection against all linked entities
|
||||
|
||||
G_POINT_CONTENTS, // ( const vec3_t point, int passEntityNum );
|
||||
// point contents against all linked entities
|
||||
|
||||
G_IN_PVS, // ( const vec3_t p1, const vec3_t p2 );
|
||||
|
||||
G_IN_PVS_IGNORE_PORTALS, // ( const vec3_t p1, const vec3_t p2 );
|
||||
|
||||
G_ADJUST_AREA_PORTAL_STATE, // ( gentity_t *ent, qboolean open );
|
||||
|
||||
G_AREAS_CONNECTED, // ( int area1, int area2 );
|
||||
|
||||
G_LINKENTITY, // ( gentity_t *ent );
|
||||
// an entity will never be sent to a client or used for collision
|
||||
// if it is not passed to linkentity. If the size, position, or
|
||||
// solidity changes, it must be relinked.
|
||||
|
||||
G_UNLINKENTITY, // ( gentity_t *ent );
|
||||
// call before removing an interactive entity
|
||||
|
||||
G_ENTITIES_IN_BOX, // ( const vec3_t mins, const vec3_t maxs, gentity_t **list, int maxcount );
|
||||
// EntitiesInBox will return brush models based on their bounding box,
|
||||
// so exact determination must still be done with EntityContact
|
||||
|
||||
G_ENTITY_CONTACT, // ( const vec3_t mins, const vec3_t maxs, const gentity_t *ent );
|
||||
// perform an exact check against inline brush models of non-square shape
|
||||
|
||||
// access for bots to get and free a server client (FIXME?)
|
||||
G_BOT_ALLOCATE_CLIENT, // ( void );
|
||||
|
||||
G_BOT_FREE_CLIENT, // ( int clientNum );
|
||||
|
||||
G_GET_USERCMD, // ( int clientNum, usercmd_t *cmd )
|
||||
|
||||
G_GET_ENTITY_TOKEN, // qboolean ( char *buffer, int bufferSize )
|
||||
// Retrieves the next string token from the entity spawn text, returning
|
||||
// false when all tokens have been parsed.
|
||||
// This should only be done at GAME_INIT time.
|
||||
|
||||
G_FS_GETFILELIST,
|
||||
G_DEBUG_POLYGON_CREATE,
|
||||
G_DEBUG_POLYGON_DELETE,
|
||||
|
||||
BOTLIB_SETUP = 200, // ( void );
|
||||
BOTLIB_SHUTDOWN, // ( void );
|
||||
BOTLIB_LIBVAR_SET,
|
||||
BOTLIB_LIBVAR_GET,
|
||||
BOTLIB_DEFINE,
|
||||
BOTLIB_START_FRAME,
|
||||
BOTLIB_LOAD_MAP,
|
||||
BOTLIB_UPDATENTITY,
|
||||
BOTLIB_TEST,
|
||||
|
||||
BOTLIB_GET_SNAPSHOT_ENTITY, // ( int client, int ent );
|
||||
BOTLIB_GET_CONSOLE_MESSAGE, // ( int client, char *message, int size );
|
||||
BOTLIB_USER_COMMAND, // ( int client, usercmd_t *ucmd );
|
||||
|
||||
BOTLIB_AAS_ENTITY_VISIBLE = 300, //FIXME: remove
|
||||
BOTLIB_AAS_IN_FIELD_OF_VISION, //FIXME: remove
|
||||
BOTLIB_AAS_VISIBLE_CLIENTS, //FIXME: remove
|
||||
BOTLIB_AAS_ENTITY_INFO,
|
||||
|
||||
BOTLIB_AAS_INITIALIZED,
|
||||
BOTLIB_AAS_PRESENCE_TYPE_BOUNDING_BOX,
|
||||
BOTLIB_AAS_TIME,
|
||||
|
||||
BOTLIB_AAS_POINT_AREA_NUM,
|
||||
BOTLIB_AAS_TRACE_AREAS,
|
||||
|
||||
BOTLIB_AAS_POINT_CONTENTS,
|
||||
BOTLIB_AAS_NEXT_BSP_ENTITY,
|
||||
BOTLIB_AAS_VALUE_FOR_BSP_EPAIR_KEY,
|
||||
BOTLIB_AAS_VECTOR_FOR_BSP_EPAIR_KEY,
|
||||
BOTLIB_AAS_FLOAT_FOR_BSP_EPAIR_KEY,
|
||||
BOTLIB_AAS_INT_FOR_BSP_EPAIR_KEY,
|
||||
|
||||
BOTLIB_AAS_AREA_REACHABILITY,
|
||||
|
||||
BOTLIB_AAS_AREA_TRAVEL_TIME_TO_GOAL_AREA,
|
||||
|
||||
BOTLIB_AAS_SWIMMING,
|
||||
BOTLIB_AAS_PREDICT_CLIENT_MOVEMENT,
|
||||
|
||||
|
||||
|
||||
BOTLIB_EA_SAY = 400,
|
||||
BOTLIB_EA_SAY_TEAM,
|
||||
BOTLIB_EA_USE_ITEM,
|
||||
BOTLIB_EA_DROP_ITEM,
|
||||
BOTLIB_EA_USE_INV,
|
||||
BOTLIB_EA_DROP_INV,
|
||||
BOTLIB_EA_GESTURE,
|
||||
BOTLIB_EA_COMMAND,
|
||||
|
||||
BOTLIB_EA_SELECT_WEAPON,
|
||||
BOTLIB_EA_TALK,
|
||||
BOTLIB_EA_ATTACK,
|
||||
BOTLIB_EA_USE,
|
||||
BOTLIB_EA_RESPAWN,
|
||||
BOTLIB_EA_JUMP,
|
||||
BOTLIB_EA_DELAYED_JUMP,
|
||||
BOTLIB_EA_CROUCH,
|
||||
BOTLIB_EA_MOVE_UP,
|
||||
BOTLIB_EA_MOVE_DOWN,
|
||||
BOTLIB_EA_MOVE_FORWARD,
|
||||
BOTLIB_EA_MOVE_BACK,
|
||||
BOTLIB_EA_MOVE_LEFT,
|
||||
BOTLIB_EA_MOVE_RIGHT,
|
||||
BOTLIB_EA_MOVE,
|
||||
BOTLIB_EA_VIEW,
|
||||
|
||||
BOTLIB_EA_END_REGULAR,
|
||||
BOTLIB_EA_GET_INPUT,
|
||||
BOTLIB_EA_RESET_INPUT,
|
||||
BOTLIB_EA_ALT_ATTACK,
|
||||
|
||||
|
||||
|
||||
BOTLIB_AI_LOAD_CHARACTER = 500,
|
||||
BOTLIB_AI_FREE_CHARACTER,
|
||||
BOTLIB_AI_CHARACTERISTIC_FLOAT,
|
||||
BOTLIB_AI_CHARACTERISTIC_BFLOAT,
|
||||
BOTLIB_AI_CHARACTERISTIC_INTEGER,
|
||||
BOTLIB_AI_CHARACTERISTIC_BINTEGER,
|
||||
BOTLIB_AI_CHARACTERISTIC_STRING,
|
||||
|
||||
BOTLIB_AI_ALLOC_CHAT_STATE,
|
||||
BOTLIB_AI_FREE_CHAT_STATE,
|
||||
BOTLIB_AI_QUEUE_CONSOLE_MESSAGE,
|
||||
BOTLIB_AI_REMOVE_CONSOLE_MESSAGE,
|
||||
BOTLIB_AI_NEXT_CONSOLE_MESSAGE,
|
||||
BOTLIB_AI_NUM_CONSOLE_MESSAGE,
|
||||
BOTLIB_AI_INITIAL_CHAT,
|
||||
BOTLIB_AI_REPLY_CHAT,
|
||||
BOTLIB_AI_CHAT_LENGTH,
|
||||
BOTLIB_AI_ENTER_CHAT,
|
||||
BOTLIB_AI_STRING_CONTAINS,
|
||||
BOTLIB_AI_FIND_MATCH,
|
||||
BOTLIB_AI_MATCH_VARIABLE,
|
||||
BOTLIB_AI_UNIFY_WHITE_SPACES,
|
||||
BOTLIB_AI_REPLACE_SYNONYMS,
|
||||
BOTLIB_AI_LOAD_CHAT_FILE,
|
||||
BOTLIB_AI_SET_CHAT_GENDER,
|
||||
BOTLIB_AI_SET_CHAT_NAME,
|
||||
|
||||
BOTLIB_AI_RESET_GOAL_STATE,
|
||||
BOTLIB_AI_RESET_AVOID_GOALS,
|
||||
BOTLIB_AI_PUSH_GOAL,
|
||||
BOTLIB_AI_POP_GOAL,
|
||||
BOTLIB_AI_EMPTY_GOAL_STACK,
|
||||
BOTLIB_AI_DUMP_AVOID_GOALS,
|
||||
BOTLIB_AI_DUMP_GOAL_STACK,
|
||||
BOTLIB_AI_GOAL_NAME,
|
||||
BOTLIB_AI_GET_TOP_GOAL,
|
||||
BOTLIB_AI_GET_SECOND_GOAL,
|
||||
BOTLIB_AI_CHOOSE_LTG_ITEM,
|
||||
BOTLIB_AI_CHOOSE_NBG_ITEM,
|
||||
BOTLIB_AI_TOUCHING_GOAL,
|
||||
BOTLIB_AI_ITEM_GOAL_IN_VIS_BUT_NOT_VISIBLE,
|
||||
BOTLIB_AI_GET_LEVEL_ITEM_GOAL,
|
||||
BOTLIB_AI_AVOID_GOAL_TIME,
|
||||
BOTLIB_AI_INIT_LEVEL_ITEMS,
|
||||
BOTLIB_AI_UPDATE_ENTITY_ITEMS,
|
||||
BOTLIB_AI_LOAD_ITEM_WEIGHTS,
|
||||
BOTLIB_AI_FREE_ITEM_WEIGHTS,
|
||||
BOTLIB_AI_SAVE_GOAL_FUZZY_LOGIC,
|
||||
BOTLIB_AI_ALLOC_GOAL_STATE,
|
||||
BOTLIB_AI_FREE_GOAL_STATE,
|
||||
|
||||
BOTLIB_AI_RESET_MOVE_STATE,
|
||||
BOTLIB_AI_MOVE_TO_GOAL,
|
||||
BOTLIB_AI_MOVE_IN_DIRECTION,
|
||||
BOTLIB_AI_RESET_AVOID_REACH,
|
||||
BOTLIB_AI_RESET_LAST_AVOID_REACH,
|
||||
BOTLIB_AI_REACHABILITY_AREA,
|
||||
BOTLIB_AI_MOVEMENT_VIEW_TARGET,
|
||||
BOTLIB_AI_ALLOC_MOVE_STATE,
|
||||
BOTLIB_AI_FREE_MOVE_STATE,
|
||||
BOTLIB_AI_INIT_MOVE_STATE,
|
||||
|
||||
BOTLIB_AI_CHOOSE_BEST_FIGHT_WEAPON,
|
||||
BOTLIB_AI_GET_WEAPON_INFO,
|
||||
BOTLIB_AI_LOAD_WEAPON_WEIGHTS,
|
||||
BOTLIB_AI_ALLOC_WEAPON_STATE,
|
||||
BOTLIB_AI_FREE_WEAPON_STATE,
|
||||
BOTLIB_AI_RESET_WEAPON_STATE,
|
||||
|
||||
BOTLIB_AI_GENETIC_PARENTS_AND_CHILD_SELECTION,
|
||||
BOTLIB_AI_INTERBREED_GOAL_FUZZY_LOGIC,
|
||||
BOTLIB_AI_MUTATE_GOAL_FUZZY_LOGIC,
|
||||
BOTLIB_AI_GET_NEXT_CAMP_SPOT_GOAL,
|
||||
BOTLIB_AI_GET_MAP_LOCATION_GOAL,
|
||||
BOTLIB_AI_NUM_INITIAL_CHATS,
|
||||
BOTLIB_AI_GET_CHAT_MESSAGE,
|
||||
BOTLIB_AI_REMOVE_FROM_AVOID_GOALS,
|
||||
BOTLIB_AI_PREDICT_VISIBLE_POSITION
|
||||
} gameImport_t;
|
||||
#else
|
||||
typedef enum {
|
||||
//============== general Quake services ==================
|
||||
|
||||
|
@ -390,7 +675,7 @@ typedef enum {
|
|||
BOTLIB_PC_SOURCE_FILE_AND_LINE
|
||||
|
||||
} gameImport_t;
|
||||
|
||||
#endif
|
||||
|
||||
//
|
||||
// functions exported by the game subsystem
|
||||
|
|
|
@ -24,10 +24,15 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
#include "qcommon.h"
|
||||
#include "cm_polylib.h"
|
||||
|
||||
#define MAX_SUBMODELS 256
|
||||
#define BOX_MODEL_HANDLE 255
|
||||
#define CAPSULE_MODEL_HANDLE 254
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
#define MAX_SUBMODELS 8192
|
||||
#define BOX_MODEL_HANDLE MAX_SUBMODELS-1
|
||||
#define CAPSULE_MODEL_HANDLE BOX_MODEL_HANDLE-2
|
||||
#else
|
||||
#define MAX_SUBMODELS 256
|
||||
#define BOX_MODEL_HANDLE 255
|
||||
#define CAPSULE_MODEL_HANDLE 254
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
cplane_t *plane;
|
||||
|
|
|
@ -60,8 +60,8 @@ properly.
|
|||
*/
|
||||
|
||||
|
||||
#define MAX_FACETS 1024
|
||||
#define MAX_PATCH_PLANES 2048
|
||||
#define MAX_FACETS 4096
|
||||
#define MAX_PATCH_PLANES 8192
|
||||
|
||||
typedef struct {
|
||||
float plane[4];
|
||||
|
|
|
@ -1161,6 +1161,12 @@ void CM_Trace( trace_t *results, const vec3_t start, const vec3_t end, vec3_t mi
|
|||
// fill in a default trace
|
||||
Com_Memset( &tw, 0, sizeof(tw) );
|
||||
tw.trace.fraction = 1; // assume it goes the entire distance until shown otherwise
|
||||
#ifdef ELITEFORCE
|
||||
// obviously Raven fucked this up. They seem to expect a SURF_NOIMPACT flag if the trace
|
||||
// went through to the end, or the game will crash when firing the dreadnought weapon and
|
||||
// it doesn't hit anything.
|
||||
tw.trace.surfaceFlags = SURF_NOIMPACT;
|
||||
#endif
|
||||
VectorCopy(origin, tw.modelOrigin);
|
||||
|
||||
if (!cm.numNodes) {
|
||||
|
|
|
@ -32,14 +32,22 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
#endif
|
||||
|
||||
int demo_protocols[] =
|
||||
{ 67, 66, 0 };
|
||||
#ifdef ELITEFORCE
|
||||
{ 0 };
|
||||
#else
|
||||
{ 67, 66, 0 };
|
||||
#endif
|
||||
|
||||
#define MAX_NUM_ARGVS 50
|
||||
|
||||
#define MIN_DEDICATED_COMHUNKMEGS 1
|
||||
#define MIN_COMHUNKMEGS 56
|
||||
#define DEF_COMHUNKMEGS 128
|
||||
#ifdef ELITEFORCE
|
||||
#define DEF_COMZONEMEGS 32
|
||||
#else
|
||||
#define DEF_COMZONEMEGS 24
|
||||
#endif
|
||||
#define DEF_COMHUNKMEGS_S XSTRING(DEF_COMHUNKMEGS)
|
||||
#define DEF_COMZONEMEGS_S XSTRING(DEF_COMZONEMEGS)
|
||||
|
||||
|
@ -75,6 +83,7 @@ cvar_t *com_buildScript; // for automated data building scripts
|
|||
#ifdef CINEMATICS_INTRO
|
||||
cvar_t *com_introPlayed;
|
||||
#endif
|
||||
cvar_t *com_novmcompat; // set to 1 to indicate VMs are run by the new engine.
|
||||
cvar_t *cl_paused;
|
||||
cvar_t *sv_paused;
|
||||
cvar_t *cl_packetdelay;
|
||||
|
@ -2448,8 +2457,14 @@ void Com_ReadCDKey( const char *filename ) {
|
|||
fileHandle_t f;
|
||||
char buffer[33];
|
||||
char fbuffer[MAX_OSPATH];
|
||||
#ifdef ELITEFORCE
|
||||
int index = 0;
|
||||
char curchar;
|
||||
|
||||
sprintf(fbuffer, "%s/efq3.key", filename);
|
||||
#else
|
||||
Com_sprintf(fbuffer, sizeof(fbuffer), "%s/q3key", filename);
|
||||
#endif
|
||||
|
||||
FS_SV_FOpenFileRead( fbuffer, &f );
|
||||
if ( !f ) {
|
||||
|
@ -2459,6 +2474,59 @@ void Com_ReadCDKey( const char *filename ) {
|
|||
|
||||
Com_Memset( buffer, 0, sizeof(buffer) );
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
// check for the normal CD key
|
||||
while(index < 16)
|
||||
{
|
||||
if(FS_Read(&curchar, 1, f) != 1)
|
||||
{
|
||||
Q_strncpyz( cl_cdkey, " ", 17 );
|
||||
FS_FCloseFile(f);
|
||||
return;
|
||||
}
|
||||
|
||||
curchar = toupper(curchar);
|
||||
|
||||
if(curchar < '0' || (curchar > '9' && curchar < 'A') || curchar > 'Z')
|
||||
continue;
|
||||
|
||||
buffer[index] = toupper(curchar);
|
||||
|
||||
index++;
|
||||
}
|
||||
FS_FCloseFile(f);
|
||||
|
||||
// check for the expansion pack cd key
|
||||
sprintf(fbuffer, "%s/expefq3.key", filename);
|
||||
FS_SV_FOpenFileRead(fbuffer, &f);
|
||||
|
||||
if(f)
|
||||
{
|
||||
while(index < 32)
|
||||
{
|
||||
// same game
|
||||
|
||||
if(FS_Read(&curchar, 1, f) != 1)
|
||||
{
|
||||
Q_strncpyz( cl_cdkey, " ", 17 );
|
||||
FS_FCloseFile(f);
|
||||
return;
|
||||
}
|
||||
|
||||
curchar = toupper(curchar);
|
||||
|
||||
if(curchar < '0' || (curchar > '9' && curchar < 'A') || curchar > 'Z')
|
||||
continue;
|
||||
|
||||
buffer[index] = toupper(curchar);
|
||||
|
||||
index++;
|
||||
}
|
||||
FS_FCloseFile(f);
|
||||
}
|
||||
|
||||
Q_strncpyz(cl_cdkey, buffer, index+1);
|
||||
#else
|
||||
FS_Read( buffer, 16, f );
|
||||
FS_FCloseFile( f );
|
||||
|
||||
|
@ -2467,6 +2535,7 @@ void Com_ReadCDKey( const char *filename ) {
|
|||
} else {
|
||||
Q_strncpyz( cl_cdkey, " ", 17 );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2508,20 +2577,30 @@ Com_WriteCDKey
|
|||
static void Com_WriteCDKey( const char *filename, const char *ikey ) {
|
||||
fileHandle_t f;
|
||||
char fbuffer[MAX_OSPATH];
|
||||
#ifdef ELITEFORCE
|
||||
char key[23];
|
||||
#else
|
||||
char key[17];
|
||||
#endif
|
||||
#ifndef _WIN32
|
||||
mode_t savedumask;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
sprintf(fbuffer, "%s/efq3.key", filename);
|
||||
#else
|
||||
Com_sprintf(fbuffer, sizeof(fbuffer), "%s/q3key", filename);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
Q_strncpyz( key, ikey, 23 );
|
||||
key[22] = '\0';
|
||||
#else
|
||||
Q_strncpyz( key, ikey, 17 );
|
||||
|
||||
if(!CL_CDKeyValidate(key, NULL) ) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32
|
||||
savedumask = umask(0077);
|
||||
|
@ -2532,7 +2611,11 @@ static void Com_WriteCDKey( const char *filename, const char *ikey ) {
|
|||
goto out;
|
||||
}
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
FS_Write( key, strlen(key), f );
|
||||
#else
|
||||
FS_Write( key, 16, f );
|
||||
#endif
|
||||
|
||||
FS_Printf( f, "\n// generated by quake, do not modify\r\n" );
|
||||
FS_Printf( f, "// Do not give this file to ANYONE.\r\n" );
|
||||
|
@ -2759,6 +2842,7 @@ void Com_Init( char *commandLine ) {
|
|||
#ifdef CINEMATICS_INTRO
|
||||
com_introPlayed = Cvar_Get( "com_introplayed", "0", CVAR_ARCHIVE);
|
||||
#endif
|
||||
com_novmcompat = Cvar_Get( "com_novmcompat", "1", CVAR_ROM);
|
||||
|
||||
s = va("%s %s %s", Q3_VERSION, PLATFORM_STRING, __DATE__ );
|
||||
com_version = Cvar_Get ("version", s, CVAR_ROM | CVAR_SERVERINFO );
|
||||
|
|
|
@ -174,6 +174,15 @@ or configs will never get loaded from disk!
|
|||
|
||||
// every time a new demo pk3 file is built, this checksum must be updated.
|
||||
// the easiest way to get it is to just run the game and see what it spits out
|
||||
#ifdef ELITEFORCE
|
||||
static const unsigned pak_checksums[] =
|
||||
{
|
||||
3376297517u,
|
||||
596947475u,
|
||||
3960871590u,
|
||||
1592359207u,
|
||||
};
|
||||
#else
|
||||
#define DEMO_PAK0_CHECKSUM 2985612116u
|
||||
static const unsigned int pak_checksums[] = {
|
||||
1566731103u,
|
||||
|
@ -186,6 +195,7 @@ static const unsigned int pak_checksums[] = {
|
|||
908855077u,
|
||||
977125798u
|
||||
};
|
||||
#endif
|
||||
|
||||
static const unsigned int missionpak_checksums[] =
|
||||
{
|
||||
|
@ -3110,6 +3120,12 @@ qboolean FS_ComparePaks( char *neededpaks, int len, qboolean dlstring ) {
|
|||
havepak = qfalse;
|
||||
|
||||
// never autodownload any of the id paks
|
||||
#ifdef ELITEFORCE
|
||||
#ifndef STANDALONE
|
||||
if(FS_idPak(fs_serverReferencedPakNames[i], BASEGAME, NUM_ID_PAKS))
|
||||
continue;
|
||||
#endif
|
||||
#else
|
||||
if(FS_idPak(fs_serverReferencedPakNames[i], BASEGAME, NUM_ID_PAKS)
|
||||
#ifndef STANDALONE
|
||||
|| FS_idPak(fs_serverReferencedPakNames[i], BASETA, NUM_TA_PAKS)
|
||||
|
@ -3118,6 +3134,7 @@ qboolean FS_ComparePaks( char *neededpaks, int len, qboolean dlstring ) {
|
|||
{
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Make sure the server cannot make us write to non-quake3 directories.
|
||||
if(FS_CheckDirTraversal(fs_serverReferencedPakNames[i]))
|
||||
|
@ -3398,6 +3415,7 @@ static void FS_Startup( const char *gameName )
|
|||
}
|
||||
|
||||
#ifndef STANDALONE
|
||||
#ifdef ELITEFORCE
|
||||
/*
|
||||
===================
|
||||
FS_CheckPak0
|
||||
|
@ -3410,6 +3428,123 @@ Q3 media pak0.pk3, you'll want to remove this by defining
|
|||
STANDALONE in q_shared.h
|
||||
===================
|
||||
*/
|
||||
|
||||
static void FS_CheckPak0( void )
|
||||
{
|
||||
searchpath_t *path;
|
||||
pack_t *curpack;
|
||||
unsigned int foundPak = 0;
|
||||
|
||||
for( path = fs_searchpaths; path; path = path->next )
|
||||
{
|
||||
const char* pakBasename = path->pack->pakBasename;
|
||||
|
||||
if(!path->pack)
|
||||
continue;
|
||||
|
||||
curpack = path->pack;
|
||||
|
||||
if(!Q_stricmpn( curpack->pakGamename, BASEGAME, MAX_OSPATH )
|
||||
&& strlen(pakBasename) == 4 && !Q_stricmpn( pakBasename, "pak", 3 )
|
||||
&& pakBasename[3] >= '0' && pakBasename[3] <= '0' + NUM_ID_PAKS - 1)
|
||||
{
|
||||
if( curpack->checksum != pak_checksums[pakBasename[3]-'0'] )
|
||||
{
|
||||
if(pakBasename[3] == '0')
|
||||
{
|
||||
|
||||
Com_Printf("\n\n"
|
||||
"**************************************************\n"
|
||||
"WARNING: " BASEGAME "/pak0.pk3 is present but its checksum (%u)\n"
|
||||
"is not correct. Please re-copy pak0.pk3 from your\n"
|
||||
"legitimate EF CDROM.\n"
|
||||
"**************************************************\n\n\n",
|
||||
curpack->checksum );
|
||||
}
|
||||
else
|
||||
{
|
||||
Com_Printf("\n\n"
|
||||
"**************************************************\n"
|
||||
"WARNING: pak%d.pk3 is present but its checksum (%u)\n"
|
||||
"is not correct. Please copy the .pk3 files from\n"
|
||||
"Elite Force patches 1.1 and 1.2 to the baseEF directory.\n"
|
||||
"**************************************************\n\n\n",
|
||||
pakBasename[3]-'0', curpack->checksum );
|
||||
}
|
||||
}
|
||||
|
||||
foundPak |= 1<<(pakBasename[3]-'0');
|
||||
}
|
||||
else
|
||||
{
|
||||
int index;
|
||||
|
||||
// Finally check whether this pak's checksum is listed because the user tried
|
||||
// to trick us by renaming the file, and set foundPak's highest bit to indicate this case.
|
||||
|
||||
for(index = 0; index < ARRAY_LEN(pak_checksums); index++)
|
||||
{
|
||||
if(curpack->checksum == pak_checksums[index])
|
||||
{
|
||||
Com_Printf("\n\n"
|
||||
"**************************************************\n"
|
||||
"WARNING: %s is renamed pak file %s%cpak%d.pk3\n"
|
||||
"Running in standalone mode won't work\n"
|
||||
"Please rename, or remove this file\n"
|
||||
"**************************************************\n\n\n",
|
||||
curpack->pakFilename, BASEGAME, PATH_SEP, index);
|
||||
|
||||
|
||||
foundPak |= 0x80000000;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!foundPak && Q_stricmp(com_basegame->string, BASEGAME))
|
||||
{
|
||||
Cvar_Set("com_standalone", "1");
|
||||
}
|
||||
else
|
||||
Cvar_Set("com_standalone", "0");
|
||||
|
||||
if(!com_standalone->integer && (foundPak & 0x07) != 0x07)
|
||||
{
|
||||
char errorText[MAX_STRING_CHARS] = "";
|
||||
|
||||
if((foundPak & 0x01) != 0x01)
|
||||
{
|
||||
Q_strcat(errorText, sizeof(errorText),
|
||||
"\"pak0.pk3\" is missing. Please copy it "
|
||||
"from your legitimate EliteForce CDROM. ");
|
||||
}
|
||||
if((foundPak & 0x1fe) != 0x1fe)
|
||||
{
|
||||
Q_strcat(errorText, sizeof(errorText),
|
||||
"Patch files are missing. Please\n"
|
||||
"copy the .pk3 files from EliteForce patch 1.2 to baseEF.\n"); }
|
||||
|
||||
Q_strcat(errorText, sizeof(errorText),
|
||||
va("Also check that your EliteForce executable is in "
|
||||
"the correct place and that every file "
|
||||
"in the \"%s\" directory is present and readable", BASEGAME));
|
||||
|
||||
Com_Error(ERR_FATAL, "%s", errorText);
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/*
|
||||
===================
|
||||
FS_CheckPak0
|
||||
|
||||
Checks that pak0.pk3 is present and its checksum is correct
|
||||
Note: If you're building a game that doesn't depend on the
|
||||
Q3 media pak0.pk3, you'll want to remove this function
|
||||
===================
|
||||
*/
|
||||
|
||||
static void FS_CheckPak0( void )
|
||||
{
|
||||
searchpath_t *path;
|
||||
|
@ -3595,6 +3730,7 @@ static void FS_CheckPak0( void )
|
|||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
=====================
|
||||
|
@ -4133,6 +4269,7 @@ void FS_FilenameCompletion( const char *dir, const char *ext,
|
|||
callback( filename );
|
||||
}
|
||||
FS_FreeFileList( filenames );
|
||||
|
||||
}
|
||||
|
||||
const char *FS_GetCurrentGameDir(void)
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -99,6 +99,102 @@ void Netchan_Setup(netsrc_t sock, netchan_t *chan, netadr_t adr, int qport, int
|
|||
#endif
|
||||
}
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
/*
|
||||
==============
|
||||
Netchan_ScramblePacket
|
||||
|
||||
A probably futile attempt to make proxy hacking somewhat
|
||||
more difficult.
|
||||
==============
|
||||
*/
|
||||
#define SCRAMBLE_START 6
|
||||
static void Netchan_ScramblePacket( msg_t *buf ) {
|
||||
unsigned seed;
|
||||
int i, j, c, mask, temp;
|
||||
int seq[MAX_PACKETLEN];
|
||||
|
||||
seed = ( LittleLong( *(unsigned *)buf->data ) * 3 ) ^ ( buf->cursize * 123 ) ^ 0x87243987;
|
||||
c = buf->cursize;
|
||||
if ( c <= SCRAMBLE_START ) {
|
||||
return;
|
||||
}
|
||||
if ( c > MAX_PACKETLEN ) {
|
||||
Com_Error( ERR_DROP, "MAX_PACKETLEN" );
|
||||
}
|
||||
|
||||
// generate a sequence of "random" numbers
|
||||
for (i = 0 ; i < c ; i++) {
|
||||
seed = (69069 * seed + 1);
|
||||
seq[i] = seed;
|
||||
}
|
||||
|
||||
// byte xor the data after the header
|
||||
for (i = SCRAMBLE_START ; i < c ; i++) {
|
||||
buf->data[i] ^= seq[i];
|
||||
}
|
||||
|
||||
// transpose each character
|
||||
for ( mask = 1 ; mask < c-SCRAMBLE_START ; mask = ( mask << 1 ) + 1 ) {
|
||||
}
|
||||
mask >>= 1;
|
||||
for (i = SCRAMBLE_START ; i < c ; i++) {
|
||||
j = SCRAMBLE_START + ( seq[i] & mask );
|
||||
temp = buf->data[j];
|
||||
buf->data[j] = buf->data[i];
|
||||
buf->data[i] = temp;
|
||||
}
|
||||
|
||||
// byte xor the data after the header
|
||||
// for (i = SCRAMBLE_START ; i < c ; i++) {
|
||||
// buf->data[i] ^= seq[i];
|
||||
// }
|
||||
}
|
||||
|
||||
static void Netchan_UnScramblePacket( msg_t *buf ) {
|
||||
unsigned seed;
|
||||
int i, j, c, mask, temp;
|
||||
int seq[MAX_PACKETLEN];
|
||||
|
||||
seed = ( LittleLong( *(unsigned *)buf->data ) * 3 ) ^ ( buf->cursize * 123 ) ^ 0x87243987;
|
||||
c = buf->cursize;
|
||||
if ( c <= SCRAMBLE_START ) {
|
||||
return;
|
||||
}
|
||||
if ( c > MAX_PACKETLEN ) {
|
||||
Com_Error( ERR_DROP, "MAX_PACKETLEN" );
|
||||
}
|
||||
|
||||
// generate a sequence of "random" numbers
|
||||
for (i = 0 ; i < c ; i++) {
|
||||
seed = (69069 * seed + 1);
|
||||
seq[i] = seed;
|
||||
}
|
||||
|
||||
// byte xor the data after the header
|
||||
// for (i = SCRAMBLE_START ; i < c ; i++) {
|
||||
// buf->data[i] ^= seq[i];
|
||||
// }
|
||||
|
||||
// transpose each character in reverse order
|
||||
for ( mask = 1 ; mask < c-SCRAMBLE_START ; mask = ( mask << 1 ) + 1 ) {
|
||||
}
|
||||
mask >>= 1;
|
||||
for (i = c-1 ; i >= SCRAMBLE_START ; i--) {
|
||||
j = SCRAMBLE_START + ( seq[i] & mask );
|
||||
temp = buf->data[j];
|
||||
buf->data[j] = buf->data[i];
|
||||
buf->data[i] = temp;
|
||||
}
|
||||
|
||||
|
||||
// byte xor the data after the header
|
||||
for (i = SCRAMBLE_START ; i < c ; i++) {
|
||||
buf->data[i] ^= seq[i];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
=================
|
||||
Netchan_TransmitNextFragment
|
||||
|
@ -138,6 +234,14 @@ void Netchan_TransmitNextFragment( netchan_t *chan ) {
|
|||
MSG_WriteShort( &send, fragmentLength );
|
||||
MSG_WriteData( &send, chan->unsentBuffer + chan->unsentFragmentStart, fragmentLength );
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
if(chan->compat)
|
||||
{
|
||||
// the original eliteforce uses the old scrambling routines only slightly modified.
|
||||
Netchan_ScramblePacket( &send );
|
||||
}
|
||||
#endif
|
||||
|
||||
// send the datagram
|
||||
NET_SendPacket(chan->sock, send.cursize, send.data, chan->remoteAddress);
|
||||
|
||||
|
@ -213,6 +317,14 @@ void Netchan_Transmit( netchan_t *chan, int length, const byte *data ) {
|
|||
|
||||
MSG_WriteData( &send, data, length );
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
if(chan->compat)
|
||||
{
|
||||
// the original eliteforce uses the old scrambling routines only slightly modified.
|
||||
Netchan_ScramblePacket( &send );
|
||||
}
|
||||
#endif
|
||||
|
||||
// send the datagram
|
||||
NET_SendPacket( chan->sock, send.cursize, send.data, chan->remoteAddress );
|
||||
|
||||
|
@ -247,7 +359,10 @@ qboolean Netchan_Process( netchan_t *chan, msg_t *msg ) {
|
|||
qboolean fragmented;
|
||||
|
||||
// XOR unscramble all data in the packet after the header
|
||||
// Netchan_UnScramblePacket( msg );
|
||||
#ifdef ELITEFORCE
|
||||
if(chan->compat)
|
||||
Netchan_UnScramblePacket( msg );
|
||||
#endif
|
||||
|
||||
// get sequence numbers
|
||||
MSG_BeginReadingOOB( msg );
|
||||
|
@ -394,7 +509,10 @@ qboolean Netchan_Process( netchan_t *chan, msg_t *msg ) {
|
|||
|
||||
// TTimo
|
||||
// clients were not acking fragmented messages
|
||||
chan->incomingSequence = sequence;
|
||||
#ifdef ELITEFORCE
|
||||
if(!chan->compat)
|
||||
#endif
|
||||
chan->incomingSequence = sequence;
|
||||
|
||||
return qtrue;
|
||||
}
|
||||
|
|
|
@ -128,7 +128,11 @@ static struct sockaddr_in6 boundto;
|
|||
#endif
|
||||
|
||||
// use an admin local address per default so that network admins can decide on how to handle quake3 traffic.
|
||||
#ifdef ELITEFORCE
|
||||
#define NET_MULTICAST_IP6 "ff04::696f:6566"
|
||||
#else
|
||||
#define NET_MULTICAST_IP6 "ff04::696f:7175:616b:6533"
|
||||
#endif
|
||||
|
||||
#define MAX_IPS 32
|
||||
|
||||
|
|
|
@ -972,7 +972,11 @@ void PerpendicularVector( vec3_t dst, const vec3_t src )
|
|||
/*
|
||||
** find the smallest magnitude axially aligned vector
|
||||
*/
|
||||
#ifdef ELITEFORCE
|
||||
for ( pos = 0, i = 2; i >= 0; i-- )
|
||||
#else
|
||||
for ( pos = 0, i = 0; i < 3; i++ )
|
||||
#endif
|
||||
{
|
||||
if ( fabs( src[i] ) < minelem )
|
||||
{
|
||||
|
|
|
@ -40,6 +40,19 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
#define CINEMATICS_LOGO "foologo.roq"
|
||||
#define CINEMATICS_INTRO "intro.roq"
|
||||
// #define LEGACY_PROTOCOL // You probably don't need this for your standalone game
|
||||
#else
|
||||
#ifdef ELITEFORCE
|
||||
#define PRODUCT_NAME "ioST:V HM"
|
||||
#define BASEGAME "baseEF"
|
||||
#define CLIENT_WINDOW_TITLE "iostvoyHM"
|
||||
#define CLIENT_WINDOW_MIN_TITLE "iostvoyHM"
|
||||
#define HOMEPATH_NAME_UNIX ".stvef"
|
||||
#define HOMEPATH_NAME_WIN "STVEF"
|
||||
#define HOMEPATH_NAME_MACOSX HOMEPATH_NAME_WIN
|
||||
// #define STEAMPATH_NAME "Star Trek Voyager: Elite Force"
|
||||
// #define STEAMPATH_APPID "2200"
|
||||
#define GAMENAME_FOR_MASTER "EliteForce"
|
||||
#define LEGACY_PROTOCOL
|
||||
#else
|
||||
#define PRODUCT_NAME "ioq3"
|
||||
#define BASEGAME "baseq3"
|
||||
|
@ -55,9 +68,14 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
#define CINEMATICS_INTRO "intro.RoQ"
|
||||
#define LEGACY_PROTOCOL
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Heartbeat for dpmaster protocol. You shouldn't change this unless you know what you're doing
|
||||
#define HEARTBEAT_FOR_MASTER "DarkPlaces"
|
||||
#ifdef ELITEFORCE
|
||||
#define HEARTBEAT_FOR_MASTER "STEF1"
|
||||
#else
|
||||
#define HEARTBEAT_FOR_MASTER "DarkPlaces"
|
||||
#endif
|
||||
|
||||
// When com_gamename is LEGACY_MASTER_GAMENAME, use quake3 master protocol.
|
||||
// You shouldn't change this unless you know what you're doing
|
||||
|
@ -1121,7 +1139,11 @@ typedef struct {
|
|||
#define MAX_POWERUPS 16
|
||||
#define MAX_WEAPONS 16
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
#define MAX_PS_EVENTS 4
|
||||
#else
|
||||
#define MAX_PS_EVENTS 2
|
||||
#endif
|
||||
|
||||
#define PS_PMOVEFRAMECOUNTBITS 6
|
||||
|
||||
|
@ -1145,6 +1167,11 @@ typedef struct playerState_s {
|
|||
vec3_t origin;
|
||||
vec3_t velocity;
|
||||
int weaponTime;
|
||||
#ifdef ELITEFORCE
|
||||
int rechargeTime; // for the phaser
|
||||
short useTime; // use debounce
|
||||
int introTime; // for the holodoor
|
||||
#endif
|
||||
int gravity;
|
||||
int speed;
|
||||
int delta_angles[3]; // add to command angles to get view direction
|
||||
|
@ -1163,7 +1190,9 @@ typedef struct playerState_s {
|
|||
// when at rest, the value will remain unchanged
|
||||
// used to twist the legs during strafing
|
||||
|
||||
#ifndef ELITEFORCE
|
||||
vec3_t grapplePoint; // location of grapple to pull towards if PMF_GRAPPLE_PULL
|
||||
#endif
|
||||
|
||||
int eFlags; // copied to entityState_t->eFlags
|
||||
|
||||
|
@ -1187,20 +1216,27 @@ typedef struct playerState_s {
|
|||
int damageYaw;
|
||||
int damagePitch;
|
||||
int damageCount;
|
||||
#ifdef ELITEFORCE
|
||||
int damageShieldCount;
|
||||
#endif
|
||||
|
||||
int stats[MAX_STATS];
|
||||
int persistant[MAX_PERSISTANT]; // stats that aren't cleared on death
|
||||
int powerups[MAX_POWERUPS]; // level.time that the powerup runs out
|
||||
int ammo[MAX_WEAPONS];
|
||||
|
||||
#ifndef ELITEFORCE
|
||||
int generic1;
|
||||
int loopSound;
|
||||
int jumppad_ent; // jumppad entity hit this frame
|
||||
#endif
|
||||
|
||||
// not communicated over the net at all
|
||||
int ping; // server to game info for scoreboard
|
||||
#ifndef ELITEFORCE
|
||||
int pmove_framecount;
|
||||
int jumppad_frame;
|
||||
#endif
|
||||
int entityEventSequence;
|
||||
} playerState_t;
|
||||
|
||||
|
@ -1235,6 +1271,15 @@ typedef struct playerState_s {
|
|||
// then BUTTON_WALKING should be set
|
||||
|
||||
// usercmd_t is sent to the server each client frame
|
||||
#ifdef ELITEFORCE
|
||||
typedef struct usercmd_s {
|
||||
int serverTime;
|
||||
byte buttons;
|
||||
byte weapon;
|
||||
int angles[3];
|
||||
signed char forwardmove, rightmove, upmove;
|
||||
} usercmd_t;
|
||||
#else
|
||||
typedef struct usercmd_s {
|
||||
int serverTime;
|
||||
int angles[3];
|
||||
|
@ -1242,7 +1287,7 @@ typedef struct usercmd_s {
|
|||
byte weapon; // weapon
|
||||
signed char forwardmove, rightmove, upmove;
|
||||
} usercmd_t;
|
||||
|
||||
#endif
|
||||
//===================================================================
|
||||
|
||||
// if entityState->solid == SOLID_BMODEL, modelindex is an inline model number
|
||||
|
@ -1313,7 +1358,9 @@ typedef struct entityState_s {
|
|||
int legsAnim; // mask off ANIM_TOGGLEBIT
|
||||
int torsoAnim; // mask off ANIM_TOGGLEBIT
|
||||
|
||||
#ifndef ELITEFORCE
|
||||
int generic1;
|
||||
#endif
|
||||
} entityState_t;
|
||||
|
||||
typedef enum {
|
||||
|
|
|
@ -23,6 +23,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
#ifndef _QCOMMON_H_
|
||||
#define _QCOMMON_H_
|
||||
|
||||
#if defined(ELITEFORCE) && defined(MISSIONPACK)
|
||||
#undef MISSIONPACK
|
||||
#endif
|
||||
|
||||
#include "../qcommon/cm_public.h"
|
||||
|
||||
//Ignore __attribute__ on non-gcc platforms
|
||||
|
@ -43,6 +47,9 @@ typedef struct {
|
|||
qboolean allowoverflow; // if false, do a Com_Error
|
||||
qboolean overflowed; // set to true if the buffer size failed (with allowoverflow set)
|
||||
qboolean oob; // set to true if the buffer size failed (with allowoverflow set)
|
||||
#ifdef ELITEFORCE
|
||||
qboolean compat; // Compatibility mode for old EliteForce servers.
|
||||
#endif
|
||||
byte *data;
|
||||
int maxsize;
|
||||
int cursize;
|
||||
|
@ -95,6 +102,11 @@ float MSG_ReadAngle16 (msg_t *sb);
|
|||
void MSG_ReadData (msg_t *sb, void *buffer, int size);
|
||||
int MSG_LookaheadByte (msg_t *msg);
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
void MSG_WriteDeltaUsercmd( msg_t *msg, struct usercmd_s *from, struct usercmd_s *to );
|
||||
void MSG_ReadDeltaUsercmd( msg_t *msg, struct usercmd_s *from, struct usercmd_s *to );
|
||||
#endif
|
||||
|
||||
void MSG_WriteDeltaUsercmdKey( msg_t *msg, int key, usercmd_t *from, usercmd_t *to );
|
||||
void MSG_ReadDeltaUsercmdKey( msg_t *msg, int key, usercmd_t *from, usercmd_t *to );
|
||||
|
||||
|
@ -251,32 +263,63 @@ PROTOCOL
|
|||
==============================================================
|
||||
*/
|
||||
|
||||
#define PROTOCOL_VERSION 71
|
||||
#define PROTOCOL_LEGACY_VERSION 68
|
||||
#ifdef ELITEFORCE
|
||||
#define PROTOCOL_VERSION 26
|
||||
#define PROTOCOL_LEGACY_VERSION 24
|
||||
#else
|
||||
#define PROTOCOL_VERSION 71
|
||||
#define PROTOCOL_LEGACY_VERSION 68
|
||||
#endif
|
||||
// 1.31 - 67
|
||||
|
||||
// maintain a list of compatible protocols for demo playing
|
||||
// NOTE: that stuff only works with two digits protocols
|
||||
extern int demo_protocols[];
|
||||
|
||||
#if !defined UPDATE_SERVER_NAME && !defined STANDALONE
|
||||
#define UPDATE_SERVER_NAME "update.quake3arena.com"
|
||||
#endif
|
||||
// override on command line, config files etc.
|
||||
#ifndef MASTER_SERVER_NAME
|
||||
#define MASTER_SERVER_NAME "master.quake3arena.com"
|
||||
#ifdef ELITEFORCE
|
||||
|
||||
#if !defined UPDATE_SERVER_NAME && !defined STANDALONE
|
||||
#define UPDATE_SERVER_NAME "motd.stef1.ravensoft.com"
|
||||
#endif
|
||||
#ifndef MASTER_SERVER_NAME
|
||||
#define MASTER_SERVER_NAME "master.stef1.ravensoft.com"
|
||||
#endif
|
||||
|
||||
#define PORT_MASTER 27953
|
||||
|
||||
#else
|
||||
|
||||
#if !defined UPDATE_SERVER_NAME && !defined STANDALONE
|
||||
#define UPDATE_SERVER_NAME "update.quake3arena.com"
|
||||
#endif
|
||||
#define UPDATE_SERVER_NAME "update.quake3arena.com"
|
||||
#ifndef MASTER_SERVER_NAME
|
||||
#define MASTER_SERVER_NAME "master.quake3arena.com"
|
||||
#endif
|
||||
|
||||
#define PORT_MASTER 27950
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef STANDALONE
|
||||
#ifndef AUTHORIZE_SERVER_NAME
|
||||
#define AUTHORIZE_SERVER_NAME "authorize.quake3arena.com"
|
||||
#endif
|
||||
#ifndef PORT_AUTHORIZE
|
||||
#define PORT_AUTHORIZE 27952
|
||||
#ifdef ELITEFORCE
|
||||
#ifndef AUTHORIZE_SERVER_NAME
|
||||
#define AUTHORIZE_SERVER_NAME "authenticate.stef1.ravensoft.com"
|
||||
#endif
|
||||
#ifndef PORT_AUTHORIZE
|
||||
#define PORT_AUTHORIZE 27953
|
||||
#endif
|
||||
#else
|
||||
#ifndef AUTHORIZE_SERVER_NAME
|
||||
#define AUTHORIZE_SERVER_NAME "authorize.quake3arena.com"
|
||||
#endif
|
||||
#ifndef PORT_AUTHORIZE
|
||||
#define PORT_AUTHORIZE 27952
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define PORT_MASTER 27950
|
||||
#define PORT_UPDATE 27951
|
||||
#define PORT_SERVER 27960
|
||||
#define NUM_SERVER_PORTS 4 // broadcast scan this many ports after
|
||||
|
@ -594,16 +637,24 @@ issues.
|
|||
#define FS_UI_REF 0x02
|
||||
#define FS_CGAME_REF 0x04
|
||||
// number of id paks that will never be autodownloaded from baseq3/missionpack
|
||||
#ifdef ELITEFORCE
|
||||
#define NUM_ID_PAKS 9
|
||||
#else
|
||||
#define NUM_ID_PAKS 9
|
||||
#define NUM_TA_PAKS 4
|
||||
#endif
|
||||
|
||||
#define MAX_FILE_HANDLES 64
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
#define Q3CONFIG_CFG "hmconfig.cfg"
|
||||
#else
|
||||
#ifdef DEDICATED
|
||||
# define Q3CONFIG_CFG "q3config_server.cfg"
|
||||
#else
|
||||
# define Q3CONFIG_CFG "q3config.cfg"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
qboolean FS_Initialized( void );
|
||||
|
||||
|
|
|
@ -41,6 +41,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
|
||||
#define CONTENTS_PLAYERCLIP 0x10000
|
||||
#define CONTENTS_MONSTERCLIP 0x20000
|
||||
#ifdef ELITEFORCE
|
||||
#define CONTENTS_SHOTCLIP 0x40000
|
||||
#endif
|
||||
|
||||
//bot specific contents types
|
||||
#define CONTENTS_TELEPORTER 0x40000
|
||||
#define CONTENTS_JUMPPAD 0x80000
|
||||
|
|
|
@ -118,6 +118,7 @@ extern cvar_t *r_saveFontData;
|
|||
qboolean R_GetModeInfo( int *width, int *height, float *windowAspect, int mode );
|
||||
|
||||
float R_NoiseGet4f( float x, float y, float z, float t );
|
||||
int R_RandomOn( float t );
|
||||
void R_NoiseInit( void );
|
||||
|
||||
image_t *R_FindImageFile( const char *name, imgType_t type, imgFlags_t flags );
|
||||
|
@ -127,6 +128,9 @@ void R_IssuePendingRenderCommands( void );
|
|||
qhandle_t RE_RegisterShaderLightMap( const char *name, int lightmapIndex );
|
||||
qhandle_t RE_RegisterShader( const char *name );
|
||||
qhandle_t RE_RegisterShaderNoMip( const char *name );
|
||||
#ifdef ELITEFORCE
|
||||
qhandle_t RE_RegisterShader3D( const char *name );
|
||||
#endif
|
||||
qhandle_t RE_RegisterShaderFromImage(const char *name, int lightmapIndex, image_t *image, qboolean mipRawImage);
|
||||
|
||||
// font stuff
|
||||
|
|
|
@ -30,6 +30,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
|
||||
static float s_noise_table[NOISE_SIZE];
|
||||
static int s_noise_perm[NOISE_SIZE];
|
||||
static int s_random[NOISE_SIZE];
|
||||
|
||||
static float GetNoiseValue( int x, int y, int z, int t )
|
||||
{
|
||||
|
@ -46,6 +47,7 @@ void R_NoiseInit( void )
|
|||
{
|
||||
s_noise_table[i] = ( float ) ( ( ( rand() / ( float ) RAND_MAX ) * 2.0 - 1.0 ) );
|
||||
s_noise_perm[i] = ( unsigned char ) ( rand() / ( float ) RAND_MAX * 255 );
|
||||
s_random[i] = rand() & 0x01;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -89,3 +91,10 @@ float R_NoiseGet4f( float x, float y, float z, float t )
|
|||
|
||||
return finalvalue;
|
||||
}
|
||||
|
||||
// used in the shader functions (GF_RANDOM) to implement a quasi random flickering.
|
||||
#define VALR( a ) s_random[ ( a ) & ( NOISE_MASK )]
|
||||
int R_RandomOn(float t)
|
||||
{
|
||||
return VALR((unsigned int) floor(t));
|
||||
}
|
||||
|
|
|
@ -49,6 +49,9 @@ typedef struct {
|
|||
qhandle_t (*RegisterSkin)( const char *name );
|
||||
qhandle_t (*RegisterShader)( const char *name );
|
||||
qhandle_t (*RegisterShaderNoMip)( const char *name );
|
||||
#ifdef ELITEFORCE
|
||||
qhandle_t (*RegisterShader3D)( const char *name );
|
||||
#endif
|
||||
void (*LoadWorld)( const char *name );
|
||||
|
||||
// the vis data is a large enough block of data that we go to the trouble
|
||||
|
|
|
@ -39,10 +39,15 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
#define RF_FIRST_PERSON 0x0004 // only draw through eyes (view weapon, damage blood blob)
|
||||
#define RF_DEPTHHACK 0x0008 // for view weapon Z crunching
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
#define RF_FULLBRIGHT 0x0010
|
||||
#define RF_CROSSHAIR 0x0020
|
||||
#else
|
||||
#define RF_CROSSHAIR 0x0010 // This item is a cross hair and will draw over everything similar to
|
||||
// DEPTHHACK in stereo rendering mode, with the difference that the
|
||||
// projection matrix won't be hacked to reduce the stereo separation as
|
||||
// is done for the gun.
|
||||
#endif
|
||||
|
||||
#define RF_NOSHADOW 0x0040 // don't add stencil shadows
|
||||
|
||||
|
@ -55,6 +60,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
#define RF_WRAP_FRAMES 0x0200 // mod the model frames by the maxframes to allow continuous
|
||||
// animation without needing to know the frame count
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
#define RF_FORCE_ENT_ALPHA 0x0800 // override shader alpha value and take the one from the entity.
|
||||
#endif
|
||||
|
||||
// refdef flags
|
||||
#define RDF_NOWORLDMODEL 0x0001 // used for player configuration screen
|
||||
#define RDF_HYPERSPACE 0x0004 // teleportation effect
|
||||
|
@ -71,6 +80,27 @@ typedef struct poly_s {
|
|||
polyVert_t *verts;
|
||||
} poly_t;
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
typedef enum {
|
||||
RT_MODEL,
|
||||
RT_SPRITE,
|
||||
RT_ORIENTEDSPRITE, // Replaces RT_POLY, which wasn't used. --Pat
|
||||
RT_ALPHAVERTPOLY, // Individual alpha levels on each vertex
|
||||
RT_BEAM,
|
||||
RT_RAIL_CORE,
|
||||
RT_RAIL_RINGS,
|
||||
RT_LIGHTNING,
|
||||
RT_PORTALSURFACE, // doesn't draw anything, just info for portals
|
||||
RT_LINE, // New type for Trek MP --Pat
|
||||
RT_ORIENTEDLINE,
|
||||
RT_LINE2, // New line type for Trek MP, with taper support --Pat
|
||||
RT_BEZIER, // what he said --keith
|
||||
RT_CYLINDER, // Yet another Trek primitive!
|
||||
RT_ELECTRICITY, // Yet another Trek primitive!
|
||||
|
||||
RT_MAX_REF_ENTITY_TYPE
|
||||
} refEntityType_t;
|
||||
#else
|
||||
typedef enum {
|
||||
RT_MODEL,
|
||||
RT_POLY,
|
||||
|
@ -83,6 +113,7 @@ typedef enum {
|
|||
|
||||
RT_MAX_REF_ENTITY_TYPE
|
||||
} refEntityType_t;
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
refEntityType_t reType;
|
||||
|
@ -115,8 +146,49 @@ typedef struct {
|
|||
float shaderTime; // subtracted from refdef time to control effect start times
|
||||
|
||||
// extra sprite information
|
||||
#ifdef ELITEFORCE
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
float rotation;
|
||||
float radius;
|
||||
byte vertRGBA[4][4];
|
||||
} sprite;
|
||||
struct
|
||||
{
|
||||
float width;
|
||||
float width2;
|
||||
float stscale;
|
||||
} line;
|
||||
struct // that whole put-the-opening-brace-on-the-same-line-as-the-beginning-of-the-definition coding style is fecal // I agree.
|
||||
{
|
||||
float width;
|
||||
vec3_t control1;
|
||||
vec3_t control2;
|
||||
} bezier;
|
||||
struct
|
||||
{
|
||||
float width;
|
||||
float width2;
|
||||
float stscale;
|
||||
float height;
|
||||
float bias;
|
||||
qboolean wrap;
|
||||
} cylinder;
|
||||
struct
|
||||
{
|
||||
float width;
|
||||
float deviation;
|
||||
float stscale;
|
||||
qboolean wrap;
|
||||
qboolean taper;
|
||||
} electricity;
|
||||
} data;
|
||||
#else
|
||||
float radius;
|
||||
float rotation;
|
||||
#endif
|
||||
} refEntity_t;
|
||||
|
||||
|
||||
|
@ -137,8 +209,10 @@ typedef struct {
|
|||
// 1 bits will prevent the associated area from rendering at all
|
||||
byte areamask[MAX_MAP_AREA_BYTES];
|
||||
|
||||
#ifndef ELITEFORCE
|
||||
// text messages for deform text shaders
|
||||
char text[MAX_RENDER_STRINGS][MAX_RENDER_STRING_LENGTH];
|
||||
#endif
|
||||
} refdef_t;
|
||||
|
||||
|
||||
|
@ -186,7 +260,11 @@ typedef struct {
|
|||
char renderer_string[MAX_STRING_CHARS];
|
||||
char vendor_string[MAX_STRING_CHARS];
|
||||
char version_string[MAX_STRING_CHARS];
|
||||
#ifdef ELITEFORCE
|
||||
char extensions_string[2*MAX_STRING_CHARS];
|
||||
#else
|
||||
char extensions_string[BIG_INFO_STRING];
|
||||
#endif
|
||||
|
||||
int maxTextureSize; // queried from GL
|
||||
int numTextureUnits; // multitexture ability
|
||||
|
@ -199,6 +277,9 @@ typedef struct {
|
|||
qboolean deviceSupportsGamma;
|
||||
textureCompression_t textureCompression;
|
||||
qboolean textureEnvAddAvailable;
|
||||
#ifdef ELITEFORCE
|
||||
qboolean textureFilterAnisotropicAvailable;
|
||||
#endif
|
||||
|
||||
int vidWidth, vidHeight;
|
||||
// aspect is the screen's physical width / height, which may be different
|
||||
|
|
|
@ -448,10 +448,17 @@ void RB_BeginDrawingView (void) {
|
|||
if ( r_fastsky->integer && !( backEnd.refdef.rdflags & RDF_NOWORLDMODEL ) )
|
||||
{
|
||||
clearBits |= GL_COLOR_BUFFER_BIT; // FIXME: only if sky shaders have been used
|
||||
#ifdef ELITEFORCE
|
||||
if(r_origfastsky->integer)
|
||||
qglClearColor(0.8f, 0.7f, 0.4f, 1.0f);
|
||||
else
|
||||
qglClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
#else
|
||||
#ifdef _DEBUG
|
||||
qglClearColor( 0.8f, 0.7f, 0.4f, 1.0f ); // FIXME: get color of sky
|
||||
#else
|
||||
qglClearColor( 0.0f, 0.0f, 0.0f, 1.0f ); // FIXME: get color of sky
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
qglClear( clearBits );
|
||||
|
|
|
@ -69,6 +69,9 @@ cvar_t *r_measureOverdraw;
|
|||
|
||||
cvar_t *r_inGameVideo;
|
||||
cvar_t *r_fastsky;
|
||||
#ifdef ELITEFORCE
|
||||
cvar_t *r_origfastsky;
|
||||
#endif
|
||||
cvar_t *r_drawSun;
|
||||
cvar_t *r_dynamiclight;
|
||||
cvar_t *r_dlightBacks;
|
||||
|
@ -197,6 +200,10 @@ static void InitOpenGL( void )
|
|||
|
||||
GLimp_Init();
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
glConfig.textureFilterAnisotropicAvailable = textureFilterAnisotropic;
|
||||
#endif
|
||||
|
||||
strcpy( renderer_buffer, glConfig.renderer_string );
|
||||
Q_strlwr( renderer_buffer );
|
||||
|
||||
|
@ -1007,7 +1014,11 @@ void R_Register( void )
|
|||
// latched and archived variables
|
||||
//
|
||||
r_allowExtensions = ri.Cvar_Get( "r_allowExtensions", "1", CVAR_ARCHIVE | CVAR_LATCH );
|
||||
#ifdef ELITEFORCE
|
||||
r_ext_compressed_textures = ri.Cvar_Get( "r_ext_compress_textures", "0", CVAR_ARCHIVE | CVAR_LATCH );
|
||||
#else
|
||||
r_ext_compressed_textures = ri.Cvar_Get( "r_ext_compressed_textures", "0", CVAR_ARCHIVE | CVAR_LATCH );
|
||||
#endif
|
||||
r_ext_multitexture = ri.Cvar_Get( "r_ext_multitexture", "1", CVAR_ARCHIVE | CVAR_LATCH );
|
||||
r_ext_compiled_vertex_array = ri.Cvar_Get( "r_ext_compiled_vertex_array", "1", CVAR_ARCHIVE | CVAR_LATCH);
|
||||
r_ext_texture_env_add = ri.Cvar_Get( "r_ext_texture_env_add", "1", CVAR_ARCHIVE | CVAR_LATCH);
|
||||
|
@ -1050,7 +1061,11 @@ void R_Register( void )
|
|||
r_displayRefresh = ri.Cvar_Get( "r_displayRefresh", "0", CVAR_LATCH );
|
||||
ri.Cvar_CheckRange( r_displayRefresh, 0, 200, qtrue );
|
||||
r_fullbright = ri.Cvar_Get ("r_fullbright", "0", CVAR_LATCH|CVAR_CHEAT );
|
||||
#ifdef ELITEFORCE
|
||||
r_mapOverBrightBits = ri.Cvar_Get ("r_mapOverBrightBits", "1", CVAR_LATCH );
|
||||
#else
|
||||
r_mapOverBrightBits = ri.Cvar_Get ("r_mapOverBrightBits", "2", CVAR_LATCH );
|
||||
#endif
|
||||
r_intensity = ri.Cvar_Get ("r_intensity", "1", CVAR_LATCH );
|
||||
r_singleShader = ri.Cvar_Get ("r_singleShader", "0", CVAR_CHEAT | CVAR_LATCH );
|
||||
|
||||
|
@ -1066,6 +1081,9 @@ void R_Register( void )
|
|||
r_stereoSeparation = ri.Cvar_Get( "r_stereoSeparation", "64", CVAR_ARCHIVE );
|
||||
r_ignoreGLErrors = ri.Cvar_Get( "r_ignoreGLErrors", "1", CVAR_ARCHIVE );
|
||||
r_fastsky = ri.Cvar_Get( "r_fastsky", "0", CVAR_ARCHIVE );
|
||||
#ifdef ELITEFORCE
|
||||
r_origfastsky = ri.Cvar_Get( "r_origfastsky", "0", CVAR_ARCHIVE );
|
||||
#endif
|
||||
r_inGameVideo = ri.Cvar_Get( "r_inGameVideo", "1", CVAR_ARCHIVE );
|
||||
r_drawSun = ri.Cvar_Get( "r_drawSun", "0", CVAR_ARCHIVE );
|
||||
r_dynamiclight = ri.Cvar_Get( "r_dynamiclight", "1", CVAR_ARCHIVE );
|
||||
|
@ -1171,8 +1189,15 @@ void R_Init( void ) {
|
|||
Com_Memset( &backEnd, 0, sizeof( backEnd ) );
|
||||
Com_Memset( &tess, 0, sizeof( tess ) );
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
if(sizeof(glconfig_t) != 5192)
|
||||
{
|
||||
ri.Error( ERR_FATAL, "Mod ABI incompatible: sizeof(glconfig_t) == %u != 5192", (unsigned int) sizeof(glconfig_t));
|
||||
}
|
||||
#else
|
||||
if(sizeof(glconfig_t) != 11332)
|
||||
ri.Error( ERR_FATAL, "Mod ABI incompatible: sizeof(glconfig_t) == %u != 11332", (unsigned int) sizeof(glconfig_t));
|
||||
#endif
|
||||
|
||||
// Swap_Init();
|
||||
|
||||
|
@ -1181,6 +1206,8 @@ void R_Init( void ) {
|
|||
}
|
||||
Com_Memset( tess.constantColor255, 255, sizeof( tess.constantColor255 ) );
|
||||
|
||||
R_NoiseInit();
|
||||
|
||||
//
|
||||
// init function tables
|
||||
//
|
||||
|
@ -1190,6 +1217,7 @@ void R_Init( void ) {
|
|||
tr.squareTable[i] = ( i < FUNCTABLE_SIZE/2 ) ? 1.0f : -1.0f;
|
||||
tr.sawToothTable[i] = (float)i / FUNCTABLE_SIZE;
|
||||
tr.inverseSawToothTable[i] = 1.0f - tr.sawToothTable[i];
|
||||
tr.noiseTable[i] = R_NoiseGet4f(0, 0, 0, i);
|
||||
|
||||
if ( i < FUNCTABLE_SIZE / 2 )
|
||||
{
|
||||
|
@ -1210,8 +1238,6 @@ void R_Init( void ) {
|
|||
|
||||
R_InitFogTable();
|
||||
|
||||
R_NoiseInit();
|
||||
|
||||
R_Register();
|
||||
|
||||
max_polys = r_maxpolys->integer;
|
||||
|
@ -1338,6 +1364,9 @@ refexport_t *GetRefAPI ( int apiVersion, refimport_t *rimp ) {
|
|||
re.RegisterSkin = RE_RegisterSkin;
|
||||
re.RegisterShader = RE_RegisterShader;
|
||||
re.RegisterShaderNoMip = RE_RegisterShaderNoMip;
|
||||
#ifdef ELITEFORCE
|
||||
re.RegisterShader3D = RE_RegisterShader3D;
|
||||
#endif
|
||||
re.LoadWorld = RE_LoadWorldMap;
|
||||
re.SetWorldVisData = RE_SetWorldVisData;
|
||||
re.EndRegistration = RE_EndRegistration;
|
||||
|
|
|
@ -300,6 +300,20 @@ void R_SetupEntityLighting( const trRefdef_t *refdef, trRefEntity_t *ent ) {
|
|||
}
|
||||
ent->lightingCalculated = qtrue;
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
if(ent->e.renderfx & RF_FULLBRIGHT)
|
||||
{
|
||||
// ent->ambientLight[0] = ent->ambientLight[1] = ent->ambientLight[1] = 0xFF;
|
||||
((byte *)&ent->ambientLightInt)[0] = 0x7F;
|
||||
((byte *)&ent->ambientLightInt)[1] = 0x7F;
|
||||
((byte *)&ent->ambientLightInt)[2] = 0x7F;
|
||||
((byte *)&ent->ambientLightInt)[3] = 0xFF;
|
||||
|
||||
ent->lightDir[0] = ent->lightDir[1] = ent->lightDir[2] = 0;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// trace a sample point down to find ambient light
|
||||
//
|
||||
|
|
|
@ -117,7 +117,8 @@ typedef enum {
|
|||
GF_SAWTOOTH,
|
||||
GF_INVERSE_SAWTOOTH,
|
||||
|
||||
GF_NOISE
|
||||
GF_NOISE,
|
||||
GF_RANDOM
|
||||
|
||||
} genFunc_t;
|
||||
|
||||
|
@ -942,6 +943,7 @@ typedef struct {
|
|||
float triangleTable[FUNCTABLE_SIZE];
|
||||
float sawToothTable[FUNCTABLE_SIZE];
|
||||
float inverseSawToothTable[FUNCTABLE_SIZE];
|
||||
float noiseTable[FUNCTABLE_SIZE];
|
||||
float fogTable[FOG_TABLE_SIZE];
|
||||
} trGlobals_t;
|
||||
|
||||
|
@ -982,6 +984,9 @@ extern cvar_t *r_primitives; // "0" = based on compiled vertex array existance
|
|||
|
||||
extern cvar_t *r_inGameVideo; // controls whether in game video should be draw
|
||||
extern cvar_t *r_fastsky; // controls whether sky should be cleared or drawn
|
||||
#ifdef ELITEFORCE
|
||||
extern cvar_t *r_origfastsky; // controls whether fastsky color is like in original EF.
|
||||
#endif
|
||||
extern cvar_t *r_drawSun; // controls drawing of sun quad
|
||||
extern cvar_t *r_dynamiclight; // dynamic lights enabled/disabled
|
||||
extern cvar_t *r_dlightBacks; // dlight non-facing surfaces for continuity
|
||||
|
|
|
@ -1006,6 +1006,7 @@ See if a sprite is inside a fog volume
|
|||
int R_SpriteFogNum( trRefEntity_t *ent ) {
|
||||
int i, j;
|
||||
fog_t *fog;
|
||||
float radius;
|
||||
|
||||
if ( tr.refdef.rdflags & RDF_NOWORLDMODEL ) {
|
||||
return 0;
|
||||
|
@ -1015,13 +1016,19 @@ int R_SpriteFogNum( trRefEntity_t *ent ) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
radius = ent->e.data.sprite.radius;
|
||||
#else
|
||||
radius = ent->e.radius;
|
||||
#endif
|
||||
|
||||
for ( i = 1 ; i < tr.world->numfogs ; i++ ) {
|
||||
fog = &tr.world->fogs[i];
|
||||
for ( j = 0 ; j < 3 ; j++ ) {
|
||||
if ( ent->e.origin[j] - ent->e.radius >= fog->bounds[1][j] ) {
|
||||
if ( ent->e.origin[j] - radius >= fog->bounds[1][j] ) {
|
||||
break;
|
||||
}
|
||||
if ( ent->e.origin[j] + ent->e.radius <= fog->bounds[0][j] ) {
|
||||
if ( ent->e.origin[j] + radius <= fog->bounds[0][j] ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1212,6 +1219,18 @@ void R_AddEntitySurfaces (void) {
|
|||
switch ( ent->e.reType ) {
|
||||
case RT_PORTALSURFACE:
|
||||
break; // don't draw anything
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
case RT_ORIENTEDSPRITE:
|
||||
case RT_ALPHAVERTPOLY:
|
||||
case RT_LINE:
|
||||
case RT_ORIENTEDLINE:
|
||||
case RT_LINE2:
|
||||
case RT_BEZIER:
|
||||
case RT_CYLINDER:
|
||||
case RT_ELECTRICITY:
|
||||
#endif
|
||||
|
||||
case RT_SPRITE:
|
||||
case RT_BEAM:
|
||||
case RT_LIGHTNING:
|
||||
|
|
|
@ -304,7 +304,9 @@ void RE_RenderScene( const refdef_t *fd ) {
|
|||
ri.Error (ERR_DROP, "R_RenderScene: NULL worldmodel");
|
||||
}
|
||||
|
||||
#ifndef ELITEFORCE
|
||||
Com_Memcpy( tr.refdef.text, fd->text, sizeof( tr.refdef.text ) );
|
||||
#endif
|
||||
|
||||
tr.refdef.x = fd->x;
|
||||
tr.refdef.y = fd->y;
|
||||
|
|
|
@ -1109,6 +1109,10 @@ static void ComputeTexCoords( shaderStage_t *pStage ) {
|
|||
static void RB_IterateStagesGeneric( shaderCommands_t *input )
|
||||
{
|
||||
int stage;
|
||||
#ifdef ELITEFORCE
|
||||
qboolean overridealpha;
|
||||
int oldalphaGen = 0;
|
||||
#endif
|
||||
|
||||
for ( stage = 0; stage < MAX_SHADER_STAGES; stage++ )
|
||||
{
|
||||
|
@ -1119,7 +1123,25 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input )
|
|||
break;
|
||||
}
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
// Override the shader alpha channel if requested.
|
||||
if(backEnd.currentEntity->e.renderfx & RF_FORCE_ENT_ALPHA)
|
||||
{
|
||||
overridealpha = qtrue;
|
||||
oldalphaGen = pStage->alphaGen;
|
||||
pStage->alphaGen = AGEN_ENTITY;
|
||||
}
|
||||
else
|
||||
overridealpha = qfalse;
|
||||
#endif
|
||||
|
||||
ComputeColors( pStage );
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
if(overridealpha)
|
||||
pStage->alphaGen = oldalphaGen;
|
||||
#endif
|
||||
|
||||
ComputeTexCoords( pStage );
|
||||
|
||||
if ( !setArraysOnce )
|
||||
|
@ -1147,7 +1169,15 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input )
|
|||
//
|
||||
R_BindAnimatedImage( &pStage->bundle[0] );
|
||||
|
||||
GL_State( pStage->stateBits );
|
||||
#ifdef ELITEFORCE
|
||||
if(overridealpha && backEnd.currentEntity->e.shaderRGBA[3] < 0xFF && !(pStage->stateBits & GLS_ATEST_BITS))
|
||||
{
|
||||
GL_State((pStage->stateBits & ~(GLS_SRCBLEND_BITS | GLS_DSTBLEND_BITS | GLS_ATEST_BITS)) // remove the shader set values.
|
||||
| GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA | GLS_ATEST_GT_0); // Now add the default values.
|
||||
}
|
||||
else
|
||||
#endif
|
||||
GL_State( pStage->stateBits );
|
||||
|
||||
//
|
||||
// draw
|
||||
|
|
|
@ -43,6 +43,8 @@ static float *TableForFunc( genFunc_t func )
|
|||
return tr.sawToothTable;
|
||||
case GF_INVERSE_SAWTOOTH:
|
||||
return tr.inverseSawToothTable;
|
||||
case GF_NOISE:
|
||||
return tr.noiseTable;
|
||||
case GF_NONE:
|
||||
default:
|
||||
break;
|
||||
|
@ -577,7 +579,9 @@ void RB_DeformTessGeometry( void ) {
|
|||
case DEFORM_TEXT5:
|
||||
case DEFORM_TEXT6:
|
||||
case DEFORM_TEXT7:
|
||||
#ifndef ELITEFORCE
|
||||
DeformText( backEnd.refdef.text[ds->deformation - DEFORM_TEXT0] );
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -688,6 +692,8 @@ void RB_CalcWaveColor( const waveForm_t *wf, unsigned char *dstColors )
|
|||
|
||||
if ( wf->func == GF_NOISE ) {
|
||||
glow = wf->base + R_NoiseGet4f( 0, 0, 0, ( tess.shaderTime + wf->phase ) * wf->frequency ) * wf->amplitude;
|
||||
} else if( wf->func == GF_RANDOM ) {
|
||||
glow = wf->base + R_RandomOn( (tess.shaderTime + wf->phase) * wf->frequency ) * wf->amplitude;
|
||||
} else {
|
||||
glow = EvalWaveForm( wf ) * tr.identityLight;
|
||||
}
|
||||
|
|
|
@ -293,6 +293,10 @@ static genFunc_t NameToGenFunc( const char *funcname )
|
|||
{
|
||||
return GF_NOISE;
|
||||
}
|
||||
else if( !Q_stricmp( funcname, "random" ) )
|
||||
{
|
||||
return GF_RANDOM;
|
||||
}
|
||||
|
||||
ri.Printf( PRINT_WARNING, "WARNING: invalid genfunc name '%s' in shader '%s'\n", funcname, shader.name );
|
||||
return GF_SIN;
|
||||
|
@ -768,6 +772,12 @@ static qboolean ParseStage( shaderStage_t *stage, char **text )
|
|||
{
|
||||
depthFuncBits = 0;
|
||||
}
|
||||
#ifdef ELITEFORCE
|
||||
if ( !Q_stricmp( token, "disable" ) )
|
||||
{
|
||||
depthFuncBits = 0;
|
||||
}
|
||||
#endif
|
||||
else if ( !Q_stricmp( token, "equal" ) )
|
||||
{
|
||||
depthFuncBits = GLS_DEPTHFUNC_EQUAL;
|
||||
|
@ -2837,6 +2847,37 @@ qhandle_t RE_RegisterShaderNoMip( const char *name ) {
|
|||
|
||||
return sh->index;
|
||||
}
|
||||
#ifdef ELITEFORCE
|
||||
/*
|
||||
====================
|
||||
RE_RegisterShader3D
|
||||
|
||||
For explicitly defined shaders that need LIGHTMAP_NONE
|
||||
as lightmapIndex.
|
||||
====================
|
||||
*/
|
||||
qhandle_t RE_RegisterShader3D( const char *name ) {
|
||||
shader_t *sh;
|
||||
|
||||
if ( strlen( name ) >= MAX_QPATH ) {
|
||||
Com_Printf( "Shader name exceeds MAX_QPATH\n" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
sh = R_FindShader( name, LIGHTMAP_NONE, qfalse );
|
||||
|
||||
// we want to return 0 if the shader failed to
|
||||
// load for some reason, but R_FindShader should
|
||||
// still keep a name allocated for it, so if
|
||||
// something calls RE_RegisterShader again with
|
||||
// the same name, we don't try looking for it again
|
||||
if ( sh->defaultShader ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return sh->index;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
====================
|
||||
|
|
|
@ -156,17 +156,25 @@ RB_SurfaceSprite
|
|||
static void RB_SurfaceSprite( void ) {
|
||||
vec3_t left, up;
|
||||
float radius;
|
||||
float rotation;
|
||||
|
||||
// calculate the xyz locations for the four corners
|
||||
#ifdef ELITEFORCE
|
||||
radius = backEnd.currentEntity->e.data.sprite.radius;
|
||||
rotation = backEnd.currentEntity->e.data.sprite.rotation;
|
||||
#else
|
||||
radius = backEnd.currentEntity->e.radius;
|
||||
if ( backEnd.currentEntity->e.rotation == 0 ) {
|
||||
rotation = backEnd.currentEntity->e.rotation;
|
||||
#endif
|
||||
|
||||
if ( rotation == 0 ) {
|
||||
VectorScale( backEnd.viewParms.or.axis[1], radius, left );
|
||||
VectorScale( backEnd.viewParms.or.axis[2], radius, up );
|
||||
} else {
|
||||
float s, c;
|
||||
float ang;
|
||||
|
||||
ang = M_PI * backEnd.currentEntity->e.rotation / 180;
|
||||
ang = M_PI * rotation / 180;
|
||||
s = sin( ang );
|
||||
c = cos( ang );
|
||||
|
||||
|
@ -551,6 +559,576 @@ static void RB_SurfaceLightningBolt( void ) {
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
|
||||
/*
|
||||
==============
|
||||
RB_SurfaceOrientedSprite
|
||||
==============
|
||||
*/
|
||||
static void RB_SurfaceOrientedSprite( void )
|
||||
{
|
||||
vec3_t left, up;
|
||||
float radius;
|
||||
float rotation;
|
||||
|
||||
// calculate the xyz locations for the four corners
|
||||
radius = backEnd.currentEntity->e.data.sprite.radius;
|
||||
rotation = backEnd.currentEntity->e.data.sprite.rotation;
|
||||
|
||||
if (rotation == 0)
|
||||
{
|
||||
VectorScale( backEnd.currentEntity->e.axis[1], radius, left );
|
||||
VectorScale( backEnd.currentEntity->e.axis[2], radius, up );
|
||||
}
|
||||
else
|
||||
{
|
||||
float s, c;
|
||||
float ang;
|
||||
|
||||
ang = M_PI * rotation / 180;
|
||||
s = sin( ang );
|
||||
c = cos( ang );
|
||||
|
||||
VectorScale( backEnd.currentEntity->e.axis[1], c * radius, left );
|
||||
VectorMA( left, -s * radius, backEnd.currentEntity->e.axis[2], left );
|
||||
|
||||
VectorScale( backEnd.currentEntity->e.axis[2], c * radius, up );
|
||||
VectorMA( up, s * radius, backEnd.currentEntity->e.axis[1], up );
|
||||
}
|
||||
if ( backEnd.viewParms.isMirror )
|
||||
VectorSubtract( vec3_origin, left, left );
|
||||
|
||||
RB_AddQuadStamp( backEnd.currentEntity->e.origin, left, up, backEnd.currentEntity->e.shaderRGBA );
|
||||
}
|
||||
|
||||
void RB_Line(vec3_t start, vec3_t end, vec3_t linedirection, vec3_t left,
|
||||
vec3_t *corners, float starttex, float endtex, refEntity_t *e)
|
||||
{
|
||||
int ndx, numind;
|
||||
color4ub_t *vertcols;
|
||||
|
||||
RB_CHECKOVERFLOW( 4, 6 );
|
||||
|
||||
// Set up the triangles ..
|
||||
ndx = tess.numVertexes;
|
||||
numind = tess.numIndexes;
|
||||
|
||||
tess.indexes[ numind ] = ndx;
|
||||
tess.indexes[ numind + 1 ] = ndx + 1;
|
||||
tess.indexes[ numind + 2 ] = ndx + 3;
|
||||
|
||||
tess.indexes[ numind + 3 ] = ndx + 3;
|
||||
tess.indexes[ numind + 4 ] = ndx + 1;
|
||||
tess.indexes[ numind + 5 ] = ndx + 2;
|
||||
|
||||
// now create the corner vertices
|
||||
|
||||
if(corners)
|
||||
{
|
||||
// we have the corner points for the start already given.
|
||||
VectorCopy(corners[0], tess.xyz[ndx]);
|
||||
VectorCopy(corners[1], tess.xyz[ndx+1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
// start left corner
|
||||
VectorAdd(start, left, tess.xyz[ndx]);
|
||||
// start right corner
|
||||
VectorSubtract(start, left, tess.xyz[ndx+1]);
|
||||
}
|
||||
// end right corner
|
||||
VectorSubtract(end, left, tess.xyz[ndx+2]);
|
||||
// end left corner
|
||||
VectorAdd(end, left, tess.xyz[ndx+3]);
|
||||
|
||||
if(corners)
|
||||
{
|
||||
// save the end corner points here.
|
||||
VectorCopy(tess.xyz[ndx+3], corners[0]);
|
||||
VectorCopy(tess.xyz[ndx+2], corners[1]);
|
||||
}
|
||||
|
||||
// Texture stuff....
|
||||
tess.texCoords[ndx][0][0] = 0;
|
||||
tess.texCoords[ndx][0][1] = starttex;
|
||||
|
||||
tess.texCoords[ndx+1][0][0] = 1;
|
||||
tess.texCoords[ndx+1][0][1] = starttex;
|
||||
|
||||
tess.texCoords[ndx+2][0][0] = 1;
|
||||
tess.texCoords[ndx+2][0][1] = endtex;
|
||||
|
||||
tess.texCoords[ndx+3][0][0] = 0;
|
||||
tess.texCoords[ndx+3][0][1] = endtex;
|
||||
|
||||
vertcols = tess.vertexColors;
|
||||
|
||||
vertcols[ndx][0] = vertcols[ndx+1][0] = vertcols[ndx+2][0] = vertcols[ndx+3][0] = e->shaderRGBA[0];
|
||||
vertcols[ndx][1] = vertcols[ndx+1][1] = vertcols[ndx+2][1] = vertcols[ndx+3][1] = e->shaderRGBA[1];
|
||||
vertcols[ndx][2] = vertcols[ndx+1][2] = vertcols[ndx+2][2] = vertcols[ndx+3][2] = e->shaderRGBA[2];
|
||||
vertcols[ndx][3] = vertcols[ndx+1][3] = vertcols[ndx+2][3] = vertcols[ndx+3][3] = e->shaderRGBA[3];
|
||||
|
||||
tess.numVertexes += 4;
|
||||
tess.numIndexes += 6;
|
||||
|
||||
|
||||
}
|
||||
|
||||
// Create a normal vector and scale it to the right length
|
||||
void RB_LineNormal(vec3_t vec1, vec3_t vec2, float scale, vec3_t result)
|
||||
{
|
||||
// Create the offset vector for the width of the line
|
||||
CrossProduct(vec1, vec2, result);
|
||||
// Normalize the offset vector first.
|
||||
VectorNormalize(result);
|
||||
// Scale the offset vector to the intended width.
|
||||
VectorScale(result, scale / 2, result);
|
||||
}
|
||||
|
||||
// Let's draw a thick line from A to B and dance happily around a christmas tree!
|
||||
void RB_SurfaceLine( void )
|
||||
{
|
||||
refEntity_t *e;
|
||||
vec3_t left; // I vote the green party...
|
||||
vec3_t start, end, linedirection, start2origin;
|
||||
shader_t *surfshader;
|
||||
|
||||
e = &backEnd.currentEntity->e;
|
||||
|
||||
// Getting up before 1:00 pm to attend HM I lectures finally paid off..
|
||||
|
||||
// Get the start and end point of the line
|
||||
VectorCopy(e->origin, start);
|
||||
VectorCopy(e->oldorigin, end);
|
||||
|
||||
// Direction vector for the line:
|
||||
VectorSubtract(end, start, linedirection);
|
||||
// Direction vector for the start to current point of view
|
||||
VectorSubtract(backEnd.viewParms.or.origin, start, start2origin);
|
||||
|
||||
RB_LineNormal(start2origin, linedirection, e->data.line.width, left);
|
||||
RB_Line(start, end, linedirection, left, NULL, 0, e->data.line.stscale, e);
|
||||
|
||||
// Hack to make the dreadnought lightning bolt work: set the correct cull type...
|
||||
if((surfshader = R_GetShaderByHandle(e->customShader)))
|
||||
surfshader->cullType = CT_TWO_SIDED;
|
||||
}
|
||||
|
||||
void RB_SurfaceOrientedLine(void)
|
||||
{
|
||||
refEntity_t *e;
|
||||
vec3_t left;
|
||||
vec3_t linedirection;
|
||||
shader_t *surfshader;
|
||||
|
||||
e = &backEnd.currentEntity->e;
|
||||
|
||||
VectorSubtract(e->oldorigin, e->origin, linedirection);
|
||||
|
||||
VectorCopy(e->axis[1], left);
|
||||
VectorNormalize(left);
|
||||
VectorScale(left, e->data.line.width / 2, left);
|
||||
|
||||
RB_Line(e->origin, e->oldorigin, linedirection, left, NULL, 0, 1, e);
|
||||
|
||||
surfshader = R_GetShaderByHandle(e->customShader);
|
||||
surfshader->cullType = CT_TWO_SIDED;
|
||||
|
||||
}
|
||||
|
||||
// This time it's not a rectangle but a trapezoid I guess ...
|
||||
void RB_SurfaceLine2( void )
|
||||
{
|
||||
refEntity_t *e;
|
||||
vec3_t startleft, endleft; // I still vote the green party...
|
||||
vec3_t start, end, linedirection, start2origin;
|
||||
color4ub_t *vertcols;
|
||||
int ndx, numind;
|
||||
|
||||
RB_CHECKOVERFLOW( 6, 12 );
|
||||
|
||||
e = &backEnd.currentEntity->e;
|
||||
|
||||
// Set up the triangle ..
|
||||
ndx = tess.numVertexes;
|
||||
numind = tess.numIndexes;
|
||||
|
||||
tess.indexes[ numind ] = ndx;
|
||||
tess.indexes[ numind + 1 ] = ndx + 1;
|
||||
tess.indexes[ numind + 2 ] = ndx + 5;
|
||||
tess.indexes[ numind + 3 ] = ndx + 5;
|
||||
tess.indexes[ numind + 4 ] = ndx + 4;
|
||||
tess.indexes[ numind + 5 ] = ndx + 1;
|
||||
tess.indexes[ numind + 6 ] = ndx + 1;
|
||||
tess.indexes[ numind + 7 ] = ndx + 4;
|
||||
tess.indexes[ numind + 8 ] = ndx + 3;
|
||||
tess.indexes[ numind + 9 ] = ndx + 3;
|
||||
tess.indexes[ numind + 10 ] = ndx + 2;
|
||||
tess.indexes[ numind + 11 ] = ndx + 1;
|
||||
|
||||
|
||||
// Get the start and end point of the line
|
||||
VectorCopy(e->origin, start);
|
||||
VectorCopy(e->oldorigin, end);
|
||||
|
||||
// Direction vector for the line:
|
||||
VectorSubtract(end, start, linedirection);
|
||||
// Direction vector for the start to current point of view
|
||||
VectorSubtract(backEnd.viewParms.or.origin, start, start2origin);
|
||||
|
||||
// Create the offset vector for the width of the line
|
||||
CrossProduct(start2origin, linedirection, startleft);
|
||||
// Normalize the offset vector first.
|
||||
VectorNormalize(startleft);
|
||||
// The normal of the triangle we just thought up:
|
||||
|
||||
|
||||
// Scale the offset vector to the intended width.
|
||||
VectorScale(startleft, e->data.line.width2 / 2, endleft);
|
||||
VectorScale(startleft, e->data.line.width / 2, startleft);
|
||||
|
||||
// now create the corner vertices
|
||||
|
||||
// start left corner
|
||||
VectorAdd(start, startleft, tess.xyz[ndx]);
|
||||
// start point
|
||||
VectorCopy(start, tess.xyz[ndx+1]);
|
||||
// start right corner
|
||||
VectorSubtract(start, startleft, tess.xyz[ndx+2]);
|
||||
// end right corner
|
||||
VectorSubtract(end, endleft, tess.xyz[ndx+3]);
|
||||
// end point
|
||||
VectorCopy(end, tess.xyz[ndx+4]);
|
||||
// end left corner
|
||||
VectorAdd(end, endleft, tess.xyz[ndx+5]);
|
||||
|
||||
// Texture stuff....
|
||||
tess.texCoords[ndx][0][0] = 0;
|
||||
tess.texCoords[ndx][0][1] = 0;
|
||||
|
||||
tess.texCoords[ndx+1][0][0] = 0.5;
|
||||
tess.texCoords[ndx+1][0][1] = 0;
|
||||
|
||||
tess.texCoords[ndx+2][0][0] = 1;
|
||||
tess.texCoords[ndx+2][0][1] = 0;
|
||||
|
||||
tess.texCoords[ndx+3][0][0] = 1;
|
||||
tess.texCoords[ndx+3][0][1] = 1;
|
||||
|
||||
tess.texCoords[ndx+4][0][0] = 0.5;
|
||||
tess.texCoords[ndx+4][0][1] = 1;
|
||||
|
||||
tess.texCoords[ndx+5][0][0] = 0;
|
||||
tess.texCoords[ndx+5][0][1] = 1;
|
||||
|
||||
vertcols = tess.vertexColors;
|
||||
|
||||
vertcols[ndx][0] = vertcols[ndx+1][0] = vertcols[ndx+2][0] =
|
||||
vertcols[ndx+3][0] = vertcols[ndx+4][0] = vertcols[ndx+5][0] = e->shaderRGBA[0];
|
||||
vertcols[ndx][1] = vertcols[ndx+1][1] = vertcols[ndx+2][1] =
|
||||
vertcols[ndx+3][1] = vertcols[ndx+4][1] = vertcols[ndx+5][1] = e->shaderRGBA[1];
|
||||
vertcols[ndx][2] = vertcols[ndx+1][2] = vertcols[ndx+2][2] =
|
||||
vertcols[ndx+3][2] = vertcols[ndx+4][2] = vertcols[ndx+5][2] = e->shaderRGBA[2];
|
||||
vertcols[ndx][3] = vertcols[ndx+1][3] = vertcols[ndx+2][3] =
|
||||
vertcols[ndx+3][3] = vertcols[ndx+4][3] = vertcols[ndx+5][3] = e->shaderRGBA[3];
|
||||
|
||||
tess.numVertexes += 6;
|
||||
tess.numIndexes += 12;
|
||||
}
|
||||
|
||||
// Draw a cubic bezier curve for the imod weapon.
|
||||
#define BEZIER_SEGMENTS 32
|
||||
#define BEZIER_STEPSIZE 1.0 / BEZIER_SEGMENTS
|
||||
|
||||
void RB_SurfaceBezier(void)
|
||||
{
|
||||
refEntity_t *e = &backEnd.currentEntity->e;
|
||||
double tvar = 0, one_tvar; // use double to not lose as much precision on cubing and squaring.
|
||||
float starttc, endtc;
|
||||
vec3_t segstartpos, segendpos, prevend[2];
|
||||
vec3_t linedirection, start2origin, left;
|
||||
int index;
|
||||
|
||||
VectorCopy(e->origin, segstartpos);
|
||||
|
||||
// start of the bezier curve is pointy
|
||||
VectorCopy(segstartpos, prevend[0]);
|
||||
VectorCopy(segstartpos, prevend[1]);
|
||||
|
||||
// iterate through all segments we have to create.
|
||||
while(tvar <= 1.0)
|
||||
{
|
||||
// get the texture position for the rectangular approximating the bezier curve.
|
||||
starttc = tvar / 2.0;
|
||||
tvar += BEZIER_STEPSIZE;
|
||||
endtc = tvar / 2.0;
|
||||
|
||||
one_tvar = 1.0 - tvar;
|
||||
|
||||
// get the endpoint for this segment.
|
||||
|
||||
for(index = 0; index < 3; index++)
|
||||
{
|
||||
// C(t) = P0 (t-1)^3 + 3 P1 t (t-1)^2 + 3 P2 t^2 (t-1) + P3 t^3
|
||||
segendpos[index] =
|
||||
e->origin[index] * one_tvar * one_tvar * one_tvar +
|
||||
3 * e->data.bezier.control1[index] * tvar * one_tvar * one_tvar +
|
||||
3 * e->data.bezier.control2[index] * tvar * tvar * one_tvar +
|
||||
e->oldorigin[index] * tvar * tvar * tvar;
|
||||
}
|
||||
|
||||
// Direction vector for the line:
|
||||
VectorSubtract(segendpos, segstartpos, linedirection);
|
||||
// Direction vector for the start to current point of view
|
||||
VectorSubtract(backEnd.viewParms.or.origin, segstartpos, start2origin);
|
||||
|
||||
RB_LineNormal(start2origin, linedirection, e->data.bezier.width, left);
|
||||
RB_Line(segstartpos, segendpos, linedirection, left, prevend, starttc, endtc, e);
|
||||
|
||||
// Our next segment starts where the old one ends.
|
||||
VectorCopy(segendpos, segstartpos);
|
||||
}
|
||||
}
|
||||
|
||||
// this actually isn't a cylinder but a frustum, but for the sake of naming
|
||||
// conventions we'll keep calling it a cylinder.
|
||||
|
||||
// number of rectangles we'll use to approximate a frustum of a cone.
|
||||
#define CYLINDER_MAXPLANES 64
|
||||
#define LOD_CONSTANT 4.0f
|
||||
|
||||
void RB_SurfaceCylinder(void)
|
||||
{
|
||||
int planes, index = 0; // calculate the number of planes based on the level of detail.
|
||||
vec3_t bottom, top, bottom2top, zerodeg_bottom, zerodeg_top, faxis;
|
||||
vec3_t bottomcorner, topcorner, vieworigin;
|
||||
float anglestep, tcstep = 0, width, width2, height;
|
||||
int ndx, numind;
|
||||
color4ub_t *vertcols;
|
||||
refEntity_t *e = &backEnd.currentEntity->e;
|
||||
// for LOD calculation:
|
||||
vec3_t bottom2origin, top2origin, lodcalc, projection;
|
||||
float maxradius, startdistance, enddistance, distance;
|
||||
|
||||
height = e->data.cylinder.height;
|
||||
width = e->data.cylinder.width;
|
||||
width2 = e->data.cylinder.width2;
|
||||
maxradius = (width > width2) ? width : width2;
|
||||
|
||||
// get the start and end point of the frustum:
|
||||
|
||||
VectorCopy(backEnd.viewParms.or.origin, vieworigin);
|
||||
VectorCopy(e->axis[0], faxis);
|
||||
VectorCopy(e->origin, bottom);
|
||||
VectorScale(faxis, height, bottom2top);
|
||||
VectorAdd(bottom, bottom2top, top);
|
||||
|
||||
// Get distance from frustum:
|
||||
// first distance from endpoints
|
||||
VectorSubtract(vieworigin, bottom, bottom2origin);
|
||||
VectorSubtract(vieworigin, top, top2origin);
|
||||
|
||||
// get projection of view origin on the middle line:
|
||||
distance = DotProduct(bottom2origin, faxis);
|
||||
|
||||
startdistance = VectorLength(bottom2origin);
|
||||
enddistance = VectorLength(top2origin);
|
||||
|
||||
if(distance < 0 || distance > height)
|
||||
{
|
||||
// projected point is not between bottom and top.
|
||||
distance = (startdistance < enddistance) ? startdistance : enddistance;
|
||||
}
|
||||
else
|
||||
{
|
||||
VectorMA(bottom, distance, faxis, projection);
|
||||
VectorSubtract(vieworigin, projection, lodcalc);
|
||||
distance = VectorLength(lodcalc);
|
||||
|
||||
if(startdistance < distance)
|
||||
distance = startdistance;
|
||||
if(enddistance < distance)
|
||||
distance = enddistance;
|
||||
}
|
||||
|
||||
planes = LOD_CONSTANT * maxradius/distance * CYLINDER_MAXPLANES;
|
||||
|
||||
if(planes < 8)
|
||||
planes = 8;
|
||||
else if(planes > CYLINDER_MAXPLANES)
|
||||
planes = CYLINDER_MAXPLANES;
|
||||
|
||||
RB_CHECKOVERFLOW(4 * planes, 6 * planes);
|
||||
|
||||
// create a normalized perpendicular vector to the frustum height.
|
||||
PerpendicularVector(zerodeg_bottom, faxis);
|
||||
|
||||
// This vector gets rotated to create the top ring
|
||||
VectorScale(zerodeg_bottom, width2 / 2.0f, zerodeg_top);
|
||||
// Likewise the vector for the lower ring:
|
||||
VectorScale(zerodeg_bottom, width / 2.0f, zerodeg_bottom);
|
||||
|
||||
anglestep = 360.0f / planes;
|
||||
if(e->data.cylinder.wrap)
|
||||
tcstep = e->data.cylinder.stscale / planes;
|
||||
|
||||
ndx = tess.numVertexes;
|
||||
numind = tess.numIndexes;
|
||||
vertcols = tess.vertexColors;
|
||||
|
||||
// this loop is creating all surface planes.
|
||||
while(index < planes)
|
||||
{
|
||||
index++;
|
||||
|
||||
// Set up the indexes for the new plane:
|
||||
tess.indexes[numind++] = ndx;
|
||||
tess.indexes[numind++] = ndx + 2;
|
||||
tess.indexes[numind++] = ndx + 3;
|
||||
|
||||
tess.indexes[numind++] = ndx;
|
||||
tess.indexes[numind++] = ndx + 3;
|
||||
tess.indexes[numind++] = ndx + 1;
|
||||
|
||||
if(index <= 1)
|
||||
{
|
||||
VectorAdd(bottom, zerodeg_bottom, tess.xyz[ndx]);
|
||||
VectorAdd(top, zerodeg_top, tess.xyz[ndx + 1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
VectorCopy(bottomcorner, tess.xyz[ndx]);
|
||||
VectorCopy(topcorner, tess.xyz[ndx + 1]);
|
||||
}
|
||||
|
||||
// Create on the right side two new vertices, first the bottom, then the top one.
|
||||
if(index >= planes)
|
||||
{
|
||||
VectorAdd(bottom, zerodeg_bottom, bottomcorner);
|
||||
VectorAdd(top, zerodeg_top, topcorner);
|
||||
}
|
||||
else
|
||||
{
|
||||
RotatePointAroundVector(bottomcorner, faxis, zerodeg_bottom, anglestep * index);
|
||||
VectorAdd(bottom, bottomcorner, bottomcorner);
|
||||
RotatePointAroundVector(topcorner, faxis, zerodeg_top, index * anglestep);
|
||||
VectorAdd(top, topcorner, topcorner);
|
||||
}
|
||||
|
||||
VectorCopy(bottomcorner, tess.xyz[ndx + 2]);
|
||||
VectorCopy(topcorner, tess.xyz[ndx + 3]);
|
||||
|
||||
// Take care about the texture stuff
|
||||
if(e->data.cylinder.wrap)
|
||||
{
|
||||
tess.texCoords[ndx][0][0] = tcstep * (index - 1);
|
||||
tess.texCoords[ndx][0][1] = 0;
|
||||
|
||||
tess.texCoords[ndx+1][0][0] = tcstep * (index - 1);
|
||||
tess.texCoords[ndx+1][0][1] = 1;
|
||||
|
||||
tess.texCoords[ndx+2][0][0] = tcstep * index;
|
||||
tess.texCoords[ndx+2][0][1] = 0;
|
||||
|
||||
tess.texCoords[ndx+3][0][0] = tcstep * index;
|
||||
tess.texCoords[ndx+3][0][1] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
tess.texCoords[ndx][0][0] = 0;
|
||||
tess.texCoords[ndx][0][1] = 0;
|
||||
|
||||
tess.texCoords[ndx+1][0][0] = 0;
|
||||
tess.texCoords[ndx+1][0][1] = 1;
|
||||
|
||||
tess.texCoords[ndx+2][0][0] = e->data.cylinder.stscale;
|
||||
tess.texCoords[ndx+2][0][1] = 0;
|
||||
|
||||
tess.texCoords[ndx+3][0][0] = e->data.cylinder.stscale;
|
||||
tess.texCoords[ndx+3][0][1] = 1;
|
||||
}
|
||||
|
||||
vertcols[ndx][0] = vertcols[ndx+1][0] = vertcols[ndx+2][0] = vertcols[ndx+3][0] = e->shaderRGBA[0];
|
||||
vertcols[ndx][1] = vertcols[ndx+1][1] = vertcols[ndx+2][1] = vertcols[ndx+3][1] = e->shaderRGBA[1];
|
||||
vertcols[ndx][2] = vertcols[ndx+1][2] = vertcols[ndx+2][2] = vertcols[ndx+3][2] = e->shaderRGBA[2];
|
||||
vertcols[ndx][3] = vertcols[ndx+1][3] = vertcols[ndx+2][3] = vertcols[ndx+3][3] = 0xff;
|
||||
|
||||
ndx += 4;
|
||||
}
|
||||
|
||||
tess.numVertexes = ndx;
|
||||
tess.numIndexes = numind;
|
||||
}
|
||||
|
||||
// Draws lightning using a multisegment line with jumpy connecting points.
|
||||
#define ELECTRICITY_SEGMENTS 16
|
||||
#define ELECTRICITY_STEPSIZE 1.0 / ELECTRICITY_SEGMENTS
|
||||
|
||||
void RB_SurfaceElectricity(void)
|
||||
{
|
||||
vec3_t start, end, linedirection, segstartpos, segendpos;
|
||||
vec3_t prevend[2], left, start2origin, start2end;
|
||||
refEntity_t *e = &backEnd.currentEntity->e;
|
||||
float width, deviation, veclen;
|
||||
int index;
|
||||
|
||||
VectorCopy(e->origin, start);
|
||||
VectorCopy(e->oldorigin, end);
|
||||
VectorSubtract(end, start, start2end);
|
||||
veclen = VectorLength(start2end);
|
||||
|
||||
width = e->data.electricity.width;
|
||||
deviation = e->data.electricity.deviation;
|
||||
|
||||
VectorCopy(start, segendpos);
|
||||
|
||||
for(index = 0; index < ELECTRICITY_SEGMENTS; index++)
|
||||
{
|
||||
VectorCopy(segendpos, segstartpos);
|
||||
|
||||
if(index > ELECTRICITY_SEGMENTS - 2)
|
||||
{
|
||||
// This is the last segment.
|
||||
VectorCopy(end, segendpos);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(index > ELECTRICITY_SEGMENTS - 3)
|
||||
{
|
||||
// The line should have somewhat deviated by now.
|
||||
// Make the last two segments go to the endpoint
|
||||
|
||||
// get the middle point between startpos and endpos
|
||||
VectorAdd(segstartpos, end, segendpos);
|
||||
VectorScale(segendpos, 0.5f, segendpos);
|
||||
}
|
||||
|
||||
// Slightly misplace the next point on the line.
|
||||
segendpos[PITCH] += (start2end[PITCH] + crandom() * deviation * veclen) * ELECTRICITY_STEPSIZE;
|
||||
segendpos[YAW] += (start2end[YAW] + crandom() * deviation * veclen) * ELECTRICITY_STEPSIZE;
|
||||
segendpos[ROLL] += (start2end[ROLL] + crandom() * deviation * veclen / 2.0) * ELECTRICITY_STEPSIZE;
|
||||
}
|
||||
|
||||
// Direction vector for the line:
|
||||
VectorSubtract(segendpos, segstartpos, linedirection);
|
||||
// Direction vector for the start to current point of view
|
||||
VectorSubtract(backEnd.viewParms.or.origin, segstartpos, start2origin);
|
||||
|
||||
RB_LineNormal(start2origin, linedirection, width, left);
|
||||
|
||||
if(!index)
|
||||
{
|
||||
// this is our first segment, create the starting points
|
||||
VectorAdd(segstartpos, left, prevend[0]);
|
||||
VectorSubtract(segstartpos, left, prevend[1]);
|
||||
}
|
||||
|
||||
RB_Line(segstartpos, segendpos, linedirection, left, prevend, 0, e->data.electricity.stscale, e);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
** VectorArrayNormalize
|
||||
*
|
||||
|
@ -1142,7 +1720,6 @@ static void RB_SurfaceGrid( srfGridMesh_t *cv ) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
|
@ -1187,6 +1764,9 @@ Entities that have a single procedurally generated surface
|
|||
*/
|
||||
static void RB_SurfaceEntity( surfaceType_t *surfType ) {
|
||||
switch( backEnd.currentEntity->e.reType ) {
|
||||
#ifdef ELITEFORCE
|
||||
case RT_ALPHAVERTPOLY:
|
||||
#endif
|
||||
case RT_SPRITE:
|
||||
RB_SurfaceSprite();
|
||||
break;
|
||||
|
@ -1202,6 +1782,29 @@ static void RB_SurfaceEntity( surfaceType_t *surfType ) {
|
|||
case RT_LIGHTNING:
|
||||
RB_SurfaceLightningBolt();
|
||||
break;
|
||||
#ifdef ELITEFORCE
|
||||
case RT_ORIENTEDSPRITE:
|
||||
RB_SurfaceOrientedSprite();
|
||||
break;
|
||||
case RT_LINE:
|
||||
RB_SurfaceLine();
|
||||
break;
|
||||
case RT_ORIENTEDLINE:
|
||||
RB_SurfaceOrientedLine();
|
||||
break;
|
||||
case RT_LINE2:
|
||||
RB_SurfaceLine2();
|
||||
break;
|
||||
case RT_BEZIER:
|
||||
RB_SurfaceBezier();
|
||||
break;
|
||||
case RT_CYLINDER:
|
||||
RB_SurfaceCylinder();
|
||||
break;
|
||||
case RT_ELECTRICITY:
|
||||
RB_SurfaceElectricity();
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
RB_SurfaceAxis();
|
||||
break;
|
||||
|
|
|
@ -71,6 +71,9 @@ cvar_t *r_measureOverdraw;
|
|||
|
||||
cvar_t *r_inGameVideo;
|
||||
cvar_t *r_fastsky;
|
||||
#ifdef ELITEFORCE
|
||||
cvar_t *r_origfastsky;
|
||||
#endif
|
||||
cvar_t *r_drawSun;
|
||||
cvar_t *r_dynamiclight;
|
||||
cvar_t *r_dlightBacks;
|
||||
|
@ -1155,7 +1158,11 @@ void R_Register( void )
|
|||
// latched and archived variables
|
||||
//
|
||||
r_allowExtensions = ri.Cvar_Get( "r_allowExtensions", "1", CVAR_ARCHIVE | CVAR_LATCH );
|
||||
#ifdef ELITEFORCE
|
||||
r_ext_compressed_textures = ri.Cvar_Get( "r_ext_compress_textures", "0", CVAR_ARCHIVE | CVAR_LATCH );
|
||||
#else
|
||||
r_ext_compressed_textures = ri.Cvar_Get( "r_ext_compressed_textures", "0", CVAR_ARCHIVE | CVAR_LATCH );
|
||||
#endif
|
||||
r_ext_multitexture = ri.Cvar_Get( "r_ext_multitexture", "1", CVAR_ARCHIVE | CVAR_LATCH );
|
||||
r_ext_compiled_vertex_array = ri.Cvar_Get( "r_ext_compiled_vertex_array", "1", CVAR_ARCHIVE | CVAR_LATCH);
|
||||
r_ext_texture_env_add = ri.Cvar_Get( "r_ext_texture_env_add", "1", CVAR_ARCHIVE | CVAR_LATCH);
|
||||
|
@ -1284,6 +1291,9 @@ void R_Register( void )
|
|||
r_stereoSeparation = ri.Cvar_Get( "r_stereoSeparation", "64", CVAR_ARCHIVE );
|
||||
r_ignoreGLErrors = ri.Cvar_Get( "r_ignoreGLErrors", "1", CVAR_ARCHIVE );
|
||||
r_fastsky = ri.Cvar_Get( "r_fastsky", "0", CVAR_ARCHIVE );
|
||||
#ifdef ELITEFORCE
|
||||
r_origfastsky = ri.Cvar_Get( "r_origfastsky", "0", CVAR_ARCHIVE );
|
||||
#endif
|
||||
r_inGameVideo = ri.Cvar_Get( "r_inGameVideo", "1", CVAR_ARCHIVE );
|
||||
r_drawSun = ri.Cvar_Get( "r_drawSun", "0", CVAR_ARCHIVE );
|
||||
r_dynamiclight = ri.Cvar_Get( "r_dynamiclight", "1", CVAR_ARCHIVE );
|
||||
|
@ -1409,8 +1419,15 @@ void R_Init( void ) {
|
|||
Com_Memset( &backEnd, 0, sizeof( backEnd ) );
|
||||
Com_Memset( &tess, 0, sizeof( tess ) );
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
if(sizeof(glconfig_t) != 5192)
|
||||
{
|
||||
ri.Error( ERR_FATAL, "Mod ABI incompatible: sizeof(glconfig_t) == %u != 5192", (unsigned int) sizeof(glconfig_t));
|
||||
}
|
||||
#else
|
||||
if(sizeof(glconfig_t) != 11332)
|
||||
ri.Error( ERR_FATAL, "Mod ABI incompatible: sizeof(glconfig_t) == %u != 11332", (unsigned int) sizeof(glconfig_t));
|
||||
#endif
|
||||
|
||||
// Swap_Init();
|
||||
|
||||
|
@ -1428,6 +1445,7 @@ void R_Init( void ) {
|
|||
tr.squareTable[i] = ( i < FUNCTABLE_SIZE/2 ) ? 1.0f : -1.0f;
|
||||
tr.sawToothTable[i] = (float)i / FUNCTABLE_SIZE;
|
||||
tr.inverseSawToothTable[i] = 1.0f - tr.sawToothTable[i];
|
||||
tr.noiseTable[i] = R_NoiseGet4f(0, 0, 0, i);
|
||||
|
||||
if ( i < FUNCTABLE_SIZE / 2 )
|
||||
{
|
||||
|
@ -1448,8 +1466,6 @@ void R_Init( void ) {
|
|||
|
||||
R_InitFogTable();
|
||||
|
||||
R_NoiseInit();
|
||||
|
||||
R_Register();
|
||||
|
||||
max_polys = r_maxpolys->integer;
|
||||
|
@ -1592,6 +1608,9 @@ refexport_t *GetRefAPI ( int apiVersion, refimport_t *rimp ) {
|
|||
re.RegisterSkin = RE_RegisterSkin;
|
||||
re.RegisterShader = RE_RegisterShader;
|
||||
re.RegisterShaderNoMip = RE_RegisterShaderNoMip;
|
||||
#ifdef ELITEFORCE
|
||||
re.RegisterShader3D = RE_RegisterShader3D;
|
||||
#endif
|
||||
re.LoadWorld = RE_LoadWorldMap;
|
||||
re.SetWorldVisData = RE_SetWorldVisData;
|
||||
re.EndRegistration = RE_EndRegistration;
|
||||
|
|
|
@ -332,6 +332,20 @@ void R_SetupEntityLighting( const trRefdef_t *refdef, trRefEntity_t *ent ) {
|
|||
}
|
||||
ent->lightingCalculated = qtrue;
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
if(ent->e.renderfx & RF_FULLBRIGHT)
|
||||
{
|
||||
// ent->ambientLight[0] = ent->ambientLight[1] = ent->ambientLight[1] = 0xFF;
|
||||
((byte *)&ent->ambientLightInt)[0] = 0x7F;
|
||||
((byte *)&ent->ambientLightInt)[1] = 0x7F;
|
||||
((byte *)&ent->ambientLightInt)[2] = 0x7F;
|
||||
((byte *)&ent->ambientLightInt)[3] = 0xFF;
|
||||
|
||||
ent->lightDir[0] = ent->lightDir[1] = ent->lightDir[2] = 0;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// trace a sample point down to find ambient light
|
||||
//
|
||||
|
|
|
@ -178,7 +178,8 @@ typedef enum {
|
|||
GF_SAWTOOTH,
|
||||
GF_INVERSE_SAWTOOTH,
|
||||
|
||||
GF_NOISE
|
||||
GF_NOISE,
|
||||
GF_RANDOM
|
||||
|
||||
} genFunc_t;
|
||||
|
||||
|
@ -1656,6 +1657,7 @@ typedef struct {
|
|||
float triangleTable[FUNCTABLE_SIZE];
|
||||
float sawToothTable[FUNCTABLE_SIZE];
|
||||
float inverseSawToothTable[FUNCTABLE_SIZE];
|
||||
float noiseTable[FUNCTABLE_SIZE];
|
||||
float fogTable[FOG_TABLE_SIZE];
|
||||
} trGlobals_t;
|
||||
|
||||
|
@ -1691,6 +1693,9 @@ extern cvar_t *r_lodscale;
|
|||
|
||||
extern cvar_t *r_inGameVideo; // controls whether in game video should be draw
|
||||
extern cvar_t *r_fastsky; // controls whether sky should be cleared or drawn
|
||||
#ifdef ELITEFORCE
|
||||
extern cvar_t *r_origfastsky; // controls whether fastsky color is like in original EF.
|
||||
#endif
|
||||
extern cvar_t *r_drawSun; // controls drawing of sun quad
|
||||
extern cvar_t *r_dynamiclight; // dynamic lights enabled/disabled
|
||||
extern cvar_t *r_dlightBacks; // dlight non-facing surfaces for continuity
|
||||
|
|
|
@ -43,6 +43,8 @@ static float *TableForFunc( genFunc_t func )
|
|||
return tr.sawToothTable;
|
||||
case GF_INVERSE_SAWTOOTH:
|
||||
return tr.inverseSawToothTable;
|
||||
case GF_NOISE:
|
||||
return tr.noiseTable;
|
||||
case GF_NONE:
|
||||
default:
|
||||
break;
|
||||
|
@ -589,7 +591,9 @@ void RB_DeformTessGeometry( void ) {
|
|||
case DEFORM_TEXT5:
|
||||
case DEFORM_TEXT6:
|
||||
case DEFORM_TEXT7:
|
||||
#ifndef ELITEFORCE
|
||||
DeformText( backEnd.refdef.text[ds->deformation - DEFORM_TEXT0] );
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -305,6 +305,10 @@ static genFunc_t NameToGenFunc( const char *funcname )
|
|||
{
|
||||
return GF_NOISE;
|
||||
}
|
||||
else if( !Q_stricmp( funcname, "random" ) )
|
||||
{
|
||||
return GF_RANDOM;
|
||||
}
|
||||
|
||||
ri.Printf( PRINT_WARNING, "WARNING: invalid genfunc name '%s' in shader '%s'\n", funcname, shader.name );
|
||||
return GF_SIN;
|
||||
|
@ -825,6 +829,12 @@ static qboolean ParseStage( shaderStage_t *stage, char **text )
|
|||
{
|
||||
depthFuncBits = 0;
|
||||
}
|
||||
#ifdef ELITEFORCE
|
||||
if ( !Q_stricmp( token, "disable" ) )
|
||||
{
|
||||
depthFuncBits = 0;
|
||||
}
|
||||
#endif
|
||||
else if ( !Q_stricmp( token, "equal" ) )
|
||||
{
|
||||
depthFuncBits = GLS_DEPTHFUNC_EQUAL;
|
||||
|
@ -3539,6 +3549,37 @@ qhandle_t RE_RegisterShaderNoMip( const char *name ) {
|
|||
|
||||
return sh->index;
|
||||
}
|
||||
#ifdef ELITEFORCE
|
||||
/*
|
||||
====================
|
||||
RE_RegisterShader3D
|
||||
|
||||
For explicitly defined shaders that need LIGHTMAP_NONE
|
||||
as lightmapIndex.
|
||||
====================
|
||||
*/
|
||||
qhandle_t RE_RegisterShader3D( const char *name ) {
|
||||
shader_t *sh;
|
||||
|
||||
if ( strlen( name ) >= MAX_QPATH ) {
|
||||
Com_Printf( "Shader name exceeds MAX_QPATH\n" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
sh = R_FindShader( name, LIGHTMAP_NONE, qfalse );
|
||||
|
||||
// we want to return 0 if the shader failed to
|
||||
// load for some reason, but R_FindShader should
|
||||
// still keep a name allocated for it, so if
|
||||
// something calls RE_RegisterShader again with
|
||||
// the same name, we don't try looking for it again
|
||||
if ( sh->defaultShader ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return sh->index;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
====================
|
||||
|
|
|
@ -1499,7 +1499,6 @@ static void RB_SurfaceGrid( srfBspSurface_t *srf ) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
|
@ -1547,6 +1546,9 @@ Entities that have a single procedurally generated surface
|
|||
*/
|
||||
static void RB_SurfaceEntity( surfaceType_t *surfType ) {
|
||||
switch( backEnd.currentEntity->e.reType ) {
|
||||
#ifdef ELITEFORCE
|
||||
case RT_ALPHAVERTPOLY:
|
||||
#endif
|
||||
case RT_SPRITE:
|
||||
RB_SurfaceSprite();
|
||||
break;
|
||||
|
@ -1562,6 +1564,29 @@ static void RB_SurfaceEntity( surfaceType_t *surfType ) {
|
|||
case RT_LIGHTNING:
|
||||
RB_SurfaceLightningBolt();
|
||||
break;
|
||||
#ifdef ELITEFORCE
|
||||
case RT_ORIENTEDSPRITE:
|
||||
RB_SurfaceOrientedSprite();
|
||||
break;
|
||||
case RT_LINE:
|
||||
RB_SurfaceLine();
|
||||
break;
|
||||
case RT_ORIENTEDLINE:
|
||||
RB_SurfaceOrientedLine();
|
||||
break;
|
||||
case RT_LINE2:
|
||||
RB_SurfaceLine2();
|
||||
break;
|
||||
case RT_BEZIER:
|
||||
RB_SurfaceBezier();
|
||||
break;
|
||||
case RT_CYLINDER:
|
||||
RB_SurfaceCylinder();
|
||||
break;
|
||||
case RT_ELECTRICITY:
|
||||
RB_SurfaceElectricity();
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
RB_SurfaceAxis();
|
||||
break;
|
||||
|
|
|
@ -147,7 +147,11 @@ void SV_GetChallenge(netadr_t from)
|
|||
#ifndef STANDALONE
|
||||
// Drop the authorize stuff if this client is coming in via v6 as the auth server does not support ipv6.
|
||||
// Drop also for addresses coming in on local LAN and for stand-alone games independent from id's assets.
|
||||
#ifdef ELITEFORCE
|
||||
if(challenge->adr.type == NA_IP && !com_standalone->integer && !Sys_IsLANAddress(from))
|
||||
#else
|
||||
if(challenge->adr.type == NA_IP && !com_standalone->integer && !Sys_IsLANAddress(from))
|
||||
#endif
|
||||
{
|
||||
// look up the authorize server's IP
|
||||
if (svs.authorizeAddress.type == NA_BAD)
|
||||
|
@ -175,12 +179,19 @@ void SV_GetChallenge(netadr_t from)
|
|||
Com_DPrintf( "authorize server timed out\n" );
|
||||
else
|
||||
{
|
||||
// otherwise send their ip to the authorize server
|
||||
#ifndef ELITEFORCE
|
||||
cvar_t *fs;
|
||||
char game[1024];
|
||||
#endif
|
||||
|
||||
Com_DPrintf( "sending getIpAuthorize for %s\n", NET_AdrToString( from ));
|
||||
|
||||
|
||||
// otherwise send their ip to the authorize server
|
||||
#ifdef ELITEFORCE
|
||||
NET_OutOfBandPrint( NS_SERVER, svs.authorizeAddress,
|
||||
"getIpAuthorize %i %i.%i.%i.%i ", challenge->challenge,
|
||||
from.ip[0], from.ip[1], from.ip[2], from.ip[3] );
|
||||
#else
|
||||
strcpy(game, BASEGAME);
|
||||
fs = Cvar_Get ("fs_game", "", CVAR_INIT|CVAR_SYSTEMINFO );
|
||||
if (fs && fs->string[0] != 0) {
|
||||
|
@ -192,7 +203,7 @@ void SV_GetChallenge(netadr_t from)
|
|||
NET_OutOfBandPrint( NS_SERVER, svs.authorizeAddress,
|
||||
"getIpAuthorize %i %i.%i.%i.%i %s 0 %s", challenge->challenge,
|
||||
from.ip[0], from.ip[1], from.ip[2], from.ip[3], game, sv_strictAuth->string );
|
||||
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -543,6 +554,7 @@ gotnewcl:
|
|||
ent = SV_GentityNum( clientNum );
|
||||
newcl->gentity = ent;
|
||||
|
||||
|
||||
// save the challenge
|
||||
newcl->challenge = challenge;
|
||||
|
||||
|
@ -669,7 +681,12 @@ void SV_DropClient( client_t *drop, const char *reason ) {
|
|||
VM_Call( gvm, GAME_CLIENT_DISCONNECT, drop - svs.clients );
|
||||
|
||||
// add the disconnect command
|
||||
SV_SendServerCommand( drop, "disconnect \"%s\"", reason);
|
||||
#ifdef ELITEFORCE
|
||||
if(drop->compat)
|
||||
SV_SendServerCommand( drop, "disconnect %s", reason);
|
||||
else
|
||||
#endif
|
||||
SV_SendServerCommand( drop, "disconnect \"%s\"", reason);
|
||||
|
||||
if ( isBot ) {
|
||||
SV_BotFreeClient( drop - svs.clients );
|
||||
|
@ -728,11 +745,23 @@ static void SV_SendClientGameState( client_t *client ) {
|
|||
// gamestate message was not just sent, forcing a retransmit
|
||||
client->gamestateMessageNum = client->netchan.outgoingSequence;
|
||||
|
||||
MSG_Init( &msg, msgBuffer, sizeof( msgBuffer ) );
|
||||
#ifdef ELITEFORCE
|
||||
if(client->compat)
|
||||
MSG_InitOOB(&msg, msgBuffer, sizeof( msgBuffer ) );
|
||||
else
|
||||
#endif
|
||||
MSG_Init( &msg, msgBuffer, sizeof( msgBuffer ) );
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
msg.compat = client->compat;
|
||||
#endif
|
||||
|
||||
// NOTE, MRE: all server->client messages now acknowledge
|
||||
// let the client know which reliable clientCommands we have received
|
||||
MSG_WriteLong( &msg, client->lastClientCommand );
|
||||
#ifdef ELITEFORCE
|
||||
if(!msg.compat)
|
||||
#endif
|
||||
MSG_WriteLong( &msg, client->lastClientCommand );
|
||||
|
||||
// send any server commands waiting to be sent first.
|
||||
// we have to do this cause we send the client->reliableSequence
|
||||
|
@ -764,9 +793,17 @@ static void SV_SendClientGameState( client_t *client ) {
|
|||
MSG_WriteDeltaEntity( &msg, &nullstate, base, qtrue );
|
||||
}
|
||||
|
||||
MSG_WriteByte( &msg, svc_EOF );
|
||||
#ifdef ELITEFORCE
|
||||
if(msg.compat)
|
||||
MSG_WriteByte(&msg, 0);
|
||||
else
|
||||
#endif
|
||||
MSG_WriteByte( &msg, svc_EOF );
|
||||
|
||||
MSG_WriteLong( &msg, client - svs.clients);
|
||||
#ifdef ELITEFORCE
|
||||
if(!msg.compat)
|
||||
#endif
|
||||
MSG_WriteLong( &msg, client - svs.clients);
|
||||
|
||||
// write the checksum feed
|
||||
MSG_WriteLong( &msg, sv.checksumFeed);
|
||||
|
@ -933,6 +970,9 @@ Fill up msg with data, return number of download blocks added
|
|||
int SV_WriteDownloadToClient(client_t *cl, msg_t *msg)
|
||||
{
|
||||
int curindex;
|
||||
#ifndef ELITEFORCE
|
||||
int missionPack = 0;
|
||||
#endif
|
||||
int unreferenced = 1;
|
||||
char errorMessage[1024];
|
||||
char pakbuf[MAX_QPATH], *pakptr;
|
||||
|
@ -944,9 +984,11 @@ int SV_WriteDownloadToClient(client_t *cl, msg_t *msg)
|
|||
if(!cl->download)
|
||||
{
|
||||
qboolean idPack = qfalse;
|
||||
#ifndef ELITEFORCE
|
||||
#ifndef STANDALONE
|
||||
qboolean missionPack = qfalse;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Chop off filename extension.
|
||||
Com_sprintf(pakbuf, sizeof(pakbuf), "%s", cl->downloadName);
|
||||
|
@ -975,8 +1017,12 @@ int SV_WriteDownloadToClient(client_t *cl, msg_t *msg)
|
|||
// now that we know the file is referenced,
|
||||
// check whether it's legal to download it.
|
||||
#ifndef STANDALONE
|
||||
#ifdef ELITEFORCE
|
||||
idPack = FS_idPak(pakbuf, BASEGAME, NUM_ID_PAKS);
|
||||
#else
|
||||
missionPack = FS_idPak(pakbuf, BASETA, NUM_TA_PAKS);
|
||||
idPack = missionPack;
|
||||
#endif
|
||||
#endif
|
||||
idPack = idPack || FS_idPak(pakbuf, BASEGAME, NUM_ID_PAKS);
|
||||
|
||||
|
@ -1000,6 +1046,10 @@ int SV_WriteDownloadToClient(client_t *cl, msg_t *msg)
|
|||
Com_sprintf(errorMessage, sizeof(errorMessage), "File \"%s\" is not referenced and cannot be downloaded.", cl->downloadName);
|
||||
}
|
||||
else if (idPack) {
|
||||
#ifdef ELITEFORCE
|
||||
Com_Printf("clientDownload: %d : \"%s\" cannot download Raven pk3 files\n", (int) (cl - svs.clients), cl->downloadName);
|
||||
Com_sprintf(errorMessage, sizeof(errorMessage), "Cannot autodownload Raven pk3 file \"%s\"", cl->downloadName);
|
||||
#else
|
||||
Com_Printf("clientDownload: %d : \"%s\" cannot download id pk3 files\n", (int) (cl - svs.clients), cl->downloadName);
|
||||
#ifndef STANDALONE
|
||||
if(missionPack)
|
||||
|
@ -1012,6 +1062,7 @@ int SV_WriteDownloadToClient(client_t *cl, msg_t *msg)
|
|||
{
|
||||
Com_sprintf(errorMessage, sizeof(errorMessage), "Cannot autodownload id pk3 file \"%s\"", cl->downloadName);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else if ( !(sv_allowDownload->integer & DLF_ENABLE) ||
|
||||
(sv_allowDownload->integer & DLF_NO_UDP) ) {
|
||||
|
@ -1036,7 +1087,10 @@ int SV_WriteDownloadToClient(client_t *cl, msg_t *msg)
|
|||
MSG_WriteByte( msg, svc_download );
|
||||
MSG_WriteShort( msg, 0 ); // client is expecting block zero
|
||||
MSG_WriteLong( msg, -1 ); // illegal file size
|
||||
MSG_WriteString( msg, errorMessage );
|
||||
#ifdef ELITEFORCE
|
||||
if(!msg->compat)
|
||||
#endif
|
||||
MSG_WriteString( msg, errorMessage );
|
||||
|
||||
*cl->downloadName = 0;
|
||||
|
||||
|
@ -1248,21 +1302,28 @@ static void SV_VerifyPaks_f( client_t *cl ) {
|
|||
// start at arg 2 ( skip serverId cl_paks )
|
||||
nCurArg = 1;
|
||||
|
||||
pArg = Cmd_Argv(nCurArg++);
|
||||
if(!pArg) {
|
||||
bGood = qfalse;
|
||||
}
|
||||
else
|
||||
#ifdef ELITEFORCE
|
||||
if(!cl->compat)
|
||||
{
|
||||
// https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=475
|
||||
// we may get incoming cp sequences from a previous checksumFeed, which we need to ignore
|
||||
// since serverId is a frame count, it always goes up
|
||||
if (atoi(pArg) < sv.checksumFeedServerId)
|
||||
{
|
||||
Com_DPrintf("ignoring outdated cp command from client %s\n", cl->name);
|
||||
return;
|
||||
#endif
|
||||
pArg = Cmd_Argv(nCurArg++);
|
||||
if(!pArg) {
|
||||
bGood = qfalse;
|
||||
}
|
||||
else
|
||||
{
|
||||
// https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=475
|
||||
// we may get incoming cp sequences from a previous checksumFeed, which we need to ignore
|
||||
// since serverId is a frame count, it always goes up
|
||||
if (atoi(pArg) < sv.checksumFeedServerId)
|
||||
{
|
||||
Com_DPrintf("ignoring outdated cp command from client %s\n", cl->name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
#ifdef ELITEFORCE
|
||||
}
|
||||
#endif
|
||||
|
||||
// we basically use this while loop to avoid using 'goto' :)
|
||||
while (bGood) {
|
||||
|
@ -1676,7 +1737,10 @@ each of the backup packets.
|
|||
==================
|
||||
*/
|
||||
static void SV_UserMove( client_t *cl, msg_t *msg, qboolean delta ) {
|
||||
int i, key;
|
||||
int i;
|
||||
#ifndef ELITEFORCE
|
||||
int key;
|
||||
#endif
|
||||
int cmdCount;
|
||||
usercmd_t nullcmd;
|
||||
usercmd_t cmds[MAX_PACKET_USERCMDS];
|
||||
|
@ -1700,6 +1764,7 @@ static void SV_UserMove( client_t *cl, msg_t *msg, qboolean delta ) {
|
|||
return;
|
||||
}
|
||||
|
||||
#ifndef ELITEFORCE
|
||||
// use the checksum feed in the key
|
||||
key = sv.checksumFeed;
|
||||
// also use the message acknowledge
|
||||
|
@ -1707,11 +1772,17 @@ static void SV_UserMove( client_t *cl, msg_t *msg, qboolean delta ) {
|
|||
// also use the last acknowledged server command in the key
|
||||
key ^= MSG_HashKey(cl->reliableCommands[ cl->reliableAcknowledge & (MAX_RELIABLE_COMMANDS-1) ], 32);
|
||||
|
||||
#endif
|
||||
|
||||
Com_Memset( &nullcmd, 0, sizeof(nullcmd) );
|
||||
oldcmd = &nullcmd;
|
||||
for ( i = 0 ; i < cmdCount ; i++ ) {
|
||||
cmd = &cmds[i];
|
||||
#ifdef ELITEFORCE
|
||||
MSG_ReadDeltaUsercmd( msg, oldcmd, cmd );
|
||||
#else
|
||||
MSG_ReadDeltaUsercmdKey( msg, key, oldcmd, cmd );
|
||||
#endif
|
||||
oldcmd = cmd;
|
||||
}
|
||||
|
||||
|
@ -1902,7 +1973,10 @@ void SV_ExecuteClientMessage( client_t *cl, msg_t *msg ) {
|
|||
int c;
|
||||
int serverId;
|
||||
|
||||
MSG_Bitstream(msg);
|
||||
#ifdef ELITEFORCE
|
||||
if(!msg->compat)
|
||||
MSG_Bitstream(msg);
|
||||
#endif
|
||||
|
||||
serverId = MSG_ReadLong( msg );
|
||||
cl->messageAcknowledge = MSG_ReadLong( msg );
|
||||
|
@ -1968,9 +2042,12 @@ void SV_ExecuteClientMessage( client_t *cl, msg_t *msg ) {
|
|||
do {
|
||||
c = MSG_ReadByte( msg );
|
||||
|
||||
if ( c == clc_EOF ) {
|
||||
#ifdef ELITEFORCE
|
||||
if(msg->compat && c == -1)
|
||||
c = clc_EOF;
|
||||
#endif
|
||||
if ( c == clc_EOF )
|
||||
break;
|
||||
}
|
||||
|
||||
if ( c != clc_clientCommand ) {
|
||||
break;
|
||||
|
|
|
@ -335,9 +335,10 @@ intptr_t SV_GameSystemCalls( intptr_t *args ) {
|
|||
return 0;
|
||||
case G_FS_GETFILELIST:
|
||||
return FS_GetFileList( VMA(1), VMA(2), VMA(3), args[4] );
|
||||
#ifndef ELITEFORCE
|
||||
case G_FS_SEEK:
|
||||
return FS_Seek( args[1], args[2], args[3] );
|
||||
|
||||
#endif
|
||||
case G_LOCATE_GAME_DATA:
|
||||
SV_LocateGameData( VMA(1), args[2], args[3], VMA(4), args[5] );
|
||||
return 0;
|
||||
|
@ -357,14 +358,18 @@ intptr_t SV_GameSystemCalls( intptr_t *args ) {
|
|||
return SV_AreaEntities( VMA(1), VMA(2), VMA(3), args[4] );
|
||||
case G_ENTITY_CONTACT:
|
||||
return SV_EntityContact( VMA(1), VMA(2), VMA(3), /*int capsule*/ qfalse );
|
||||
#ifndef ELITEFORCE
|
||||
case G_ENTITY_CONTACTCAPSULE:
|
||||
return SV_EntityContact( VMA(1), VMA(2), VMA(3), /*int capsule*/ qtrue );
|
||||
#endif
|
||||
case G_TRACE:
|
||||
SV_Trace( VMA(1), VMA(2), VMA(3), VMA(4), VMA(5), args[6], args[7], /*int capsule*/ qfalse );
|
||||
return 0;
|
||||
#ifndef ELITEFORCE
|
||||
case G_TRACECAPSULE:
|
||||
SV_Trace( VMA(1), VMA(2), VMA(3), VMA(4), VMA(5), args[6], args[7], /*int capsule*/ qtrue );
|
||||
return 0;
|
||||
#endif
|
||||
case G_POINT_CONTENTS:
|
||||
return SV_PointContents( VMA(1), args[2] );
|
||||
case G_SET_BRUSH_MODEL:
|
||||
|
@ -423,12 +428,13 @@ intptr_t SV_GameSystemCalls( intptr_t *args ) {
|
|||
case G_DEBUG_POLYGON_DELETE:
|
||||
BotImport_DebugPolygonDelete( args[1] );
|
||||
return 0;
|
||||
#ifndef ELITEFORCE
|
||||
case G_REAL_TIME:
|
||||
return Com_RealTime( VMA(1) );
|
||||
case G_SNAPVECTOR:
|
||||
Q_SnapVector(VMA(1));
|
||||
return 0;
|
||||
|
||||
#endif
|
||||
//====================================
|
||||
|
||||
case BOTLIB_SETUP:
|
||||
|
@ -440,6 +446,10 @@ intptr_t SV_GameSystemCalls( intptr_t *args ) {
|
|||
case BOTLIB_LIBVAR_GET:
|
||||
return botlib_export->BotLibVarGet( VMA(1), VMA(2), args[3] );
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
case BOTLIB_DEFINE:
|
||||
return botlib_export->PC_AddGlobalDefine( VMA(1) );
|
||||
#else
|
||||
case BOTLIB_PC_ADD_GLOBAL_DEFINE:
|
||||
return botlib_export->PC_AddGlobalDefine( VMA(1) );
|
||||
case BOTLIB_PC_LOAD_SOURCE:
|
||||
|
@ -450,7 +460,7 @@ intptr_t SV_GameSystemCalls( intptr_t *args ) {
|
|||
return botlib_export->PC_ReadTokenHandle( args[1], VMA(2) );
|
||||
case BOTLIB_PC_SOURCE_FILE_AND_LINE:
|
||||
return botlib_export->PC_SourceFileAndLine( args[1], VMA(2), VMA(3) );
|
||||
|
||||
#endif
|
||||
case BOTLIB_START_FRAME:
|
||||
return botlib_export->BotLibStartFrame( VMF(1) );
|
||||
case BOTLIB_LOAD_MAP:
|
||||
|
@ -467,13 +477,14 @@ intptr_t SV_GameSystemCalls( intptr_t *args ) {
|
|||
case BOTLIB_USER_COMMAND:
|
||||
SV_ClientThink( &svs.clients[args[1]], VMA(2) );
|
||||
return 0;
|
||||
|
||||
#ifndef ELITEFORCE
|
||||
case BOTLIB_AAS_BBOX_AREAS:
|
||||
return botlib_export->aas.AAS_BBoxAreas( VMA(1), VMA(2), VMA(3), args[4] );
|
||||
case BOTLIB_AAS_AREA_INFO:
|
||||
return botlib_export->aas.AAS_AreaInfo( args[1], VMA(2) );
|
||||
case BOTLIB_AAS_ALTERNATIVE_ROUTE_GOAL:
|
||||
return botlib_export->aas.AAS_AlternativeRouteGoals( VMA(1), args[2], VMA(3), args[4], args[5], VMA(6), args[7], args[8] );
|
||||
#endif
|
||||
case BOTLIB_AAS_ENTITY_INFO:
|
||||
botlib_export->aas.AAS_EntityInfo( args[1], VMA(2) );
|
||||
return 0;
|
||||
|
@ -488,8 +499,10 @@ intptr_t SV_GameSystemCalls( intptr_t *args ) {
|
|||
|
||||
case BOTLIB_AAS_POINT_AREA_NUM:
|
||||
return botlib_export->aas.AAS_PointAreaNum( VMA(1) );
|
||||
#ifndef ELITEFORCE
|
||||
case BOTLIB_AAS_POINT_REACHABILITY_AREA_INDEX:
|
||||
return botlib_export->aas.AAS_PointReachabilityAreaIndex( VMA(1) );
|
||||
#endif
|
||||
case BOTLIB_AAS_TRACE_AREAS:
|
||||
return botlib_export->aas.AAS_TraceAreas( VMA(1), VMA(2), VMA(3), VMA(4), args[5] );
|
||||
|
||||
|
@ -511,11 +524,12 @@ intptr_t SV_GameSystemCalls( intptr_t *args ) {
|
|||
|
||||
case BOTLIB_AAS_AREA_TRAVEL_TIME_TO_GOAL_AREA:
|
||||
return botlib_export->aas.AAS_AreaTravelTimeToGoalArea( args[1], VMA(2), args[3], args[4] );
|
||||
#ifndef ELITEFORCE
|
||||
case BOTLIB_AAS_ENABLE_ROUTING_AREA:
|
||||
return botlib_export->aas.AAS_EnableRoutingArea( args[1], args[2] );
|
||||
case BOTLIB_AAS_PREDICT_ROUTE:
|
||||
return botlib_export->aas.AAS_PredictRoute( VMA(1), args[2], VMA(3), args[4], args[5], args[6], args[7], args[8], args[9], args[10], args[11] );
|
||||
|
||||
#endif
|
||||
case BOTLIB_AAS_SWIMMING:
|
||||
return botlib_export->aas.AAS_Swimming( VMA(1) );
|
||||
case BOTLIB_AAS_PREDICT_CLIENT_MOVEMENT:
|
||||
|
@ -532,9 +546,11 @@ intptr_t SV_GameSystemCalls( intptr_t *args ) {
|
|||
botlib_export->ea.EA_Command( args[1], VMA(2) );
|
||||
return 0;
|
||||
|
||||
#ifndef ELITEFORCE
|
||||
case BOTLIB_EA_ACTION:
|
||||
botlib_export->ea.EA_Action( args[1], args[2] );
|
||||
return 0;
|
||||
#endif
|
||||
case BOTLIB_EA_GESTURE:
|
||||
botlib_export->ea.EA_Gesture( args[1] );
|
||||
return 0;
|
||||
|
@ -664,7 +680,11 @@ intptr_t SV_GameSystemCalls( intptr_t *args ) {
|
|||
botlib_export->ai.BotSetChatGender( args[1], args[2] );
|
||||
return 0;
|
||||
case BOTLIB_AI_SET_CHAT_NAME:
|
||||
#ifdef ELITEFORCE
|
||||
botlib_export->ai.BotSetChatName( args[1], VMA(2));
|
||||
#else
|
||||
botlib_export->ai.BotSetChatName( args[1], VMA(2), args[3] );
|
||||
#endif
|
||||
return 0;
|
||||
|
||||
case BOTLIB_AI_RESET_GOAL_STATE:
|
||||
|
@ -714,9 +734,11 @@ intptr_t SV_GameSystemCalls( intptr_t *args ) {
|
|||
return botlib_export->ai.BotGetMapLocationGoal( VMA(1), VMA(2) );
|
||||
case BOTLIB_AI_AVOID_GOAL_TIME:
|
||||
return FloatAsInt( botlib_export->ai.BotAvoidGoalTime( args[1], args[2] ) );
|
||||
#ifndef ELITEFORCE
|
||||
case BOTLIB_AI_SET_AVOID_GOAL_TIME:
|
||||
botlib_export->ai.BotSetAvoidGoalTime( args[1], args[2], VMF(3));
|
||||
return 0;
|
||||
#endif
|
||||
case BOTLIB_AI_INIT_LEVEL_ITEMS:
|
||||
botlib_export->ai.BotInitLevelItems();
|
||||
return 0;
|
||||
|
@ -746,9 +768,11 @@ intptr_t SV_GameSystemCalls( intptr_t *args ) {
|
|||
case BOTLIB_AI_RESET_MOVE_STATE:
|
||||
botlib_export->ai.BotResetMoveState( args[1] );
|
||||
return 0;
|
||||
#ifndef ELITEFORCE
|
||||
case BOTLIB_AI_ADD_AVOID_SPOT:
|
||||
botlib_export->ai.BotAddAvoidSpot( args[1], VMA(2), VMF(3), args[4] );
|
||||
return 0;
|
||||
#endif
|
||||
case BOTLIB_AI_MOVE_TO_GOAL:
|
||||
botlib_export->ai.BotMoveToGoal( VMA(1), args[2], VMA(3), args[4] );
|
||||
return 0;
|
||||
|
@ -836,7 +860,23 @@ intptr_t SV_GameSystemCalls( intptr_t *args ) {
|
|||
case TRAP_CEIL:
|
||||
return FloatAsInt( ceil( VMF(1) ) );
|
||||
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
case BOTLIB_EA_USE_ITEM:
|
||||
botlib_export->ea.EA_UseItem(args[1], VMA(2));
|
||||
return 0;
|
||||
case BOTLIB_EA_DROP_ITEM:
|
||||
botlib_export->ea.EA_DropItem(args[1], VMA(2));
|
||||
return 0;
|
||||
case BOTLIB_EA_USE_INV:
|
||||
botlib_export->ea.EA_UseInv(args[1], VMA(2));
|
||||
return 0;
|
||||
case BOTLIB_EA_DROP_INV:
|
||||
botlib_export->ea.EA_DropInv(args[1], VMA(2));
|
||||
return 0;
|
||||
case BOTLIB_EA_ALT_ATTACK:
|
||||
botlib_export->ea.EA_Attack( args[1] );
|
||||
return 0;
|
||||
#endif
|
||||
default:
|
||||
Com_Error( ERR_DROP, "Bad game system trap: %ld", (long int) args[0] );
|
||||
}
|
||||
|
|
|
@ -668,7 +668,11 @@ void SV_Init (void)
|
|||
// server vars
|
||||
sv_rconPassword = Cvar_Get ("rconPassword", "", CVAR_TEMP );
|
||||
sv_privatePassword = Cvar_Get ("sv_privatePassword", "", CVAR_TEMP );
|
||||
#ifdef ELITEFORCE
|
||||
sv_fps = Cvar_Get ("sv_fps", "20", CVAR_SYSTEMINFO | CVAR_TEMP);
|
||||
#else
|
||||
sv_fps = Cvar_Get ("sv_fps", "20", CVAR_TEMP );
|
||||
#endif
|
||||
sv_timeout = Cvar_Get ("sv_timeout", "200", CVAR_TEMP );
|
||||
sv_zombietime = Cvar_Get ("sv_zombietime", "2", CVAR_TEMP );
|
||||
Cvar_Get ("nextmap", "", CVAR_TEMP );
|
||||
|
@ -677,8 +681,12 @@ void SV_Init (void)
|
|||
Cvar_Get ("sv_dlURL", "", CVAR_SERVERINFO | CVAR_ARCHIVE);
|
||||
|
||||
sv_master[0] = Cvar_Get("sv_master1", MASTER_SERVER_NAME, 0);
|
||||
#ifdef ELITEFORCE
|
||||
sv_master[1] = Cvar_Get("sv_master2", "efmaster.tjps.eu", CVAR_ARCHIVE);
|
||||
#else
|
||||
sv_master[1] = Cvar_Get("sv_master2", "master.ioquake3.org", 0);
|
||||
for(index = 2; index < MAX_MASTER_SERVERS; index++)
|
||||
#endif
|
||||
for(index = 1; index < MAX_MASTER_SERVERS; index++)
|
||||
sv_master[index] = Cvar_Get(va("sv_master%d", index + 1), "", CVAR_ARCHIVE);
|
||||
|
||||
sv_reconnectlimit = Cvar_Get ("sv_reconnectlimit", "3", 0);
|
||||
|
@ -724,7 +732,13 @@ void SV_FinalMessage( char *message ) {
|
|||
// don't send a disconnect to a local client
|
||||
if ( cl->netchan.remoteAddress.type != NA_LOOPBACK ) {
|
||||
SV_SendServerCommand( cl, "print \"%s\n\"\n", message );
|
||||
SV_SendServerCommand( cl, "disconnect \"%s\"", message );
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
if(cl->compat)
|
||||
SV_SendServerCommand(cl, "disconnect Server shutdown: %s", message);
|
||||
else
|
||||
#endif
|
||||
SV_SendServerCommand( cl, "disconnect \"%s\"", message );
|
||||
}
|
||||
// force a snapshot to be sent
|
||||
cl->lastSnapshotTime = 0;
|
||||
|
|
|
@ -321,11 +321,19 @@ void SV_MasterHeartbeat(const char *message)
|
|||
|
||||
// this command should be changed if the server info / status format
|
||||
// ever incompatably changes
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
if(adr[i][0].type != NA_BAD)
|
||||
NET_OutOfBandPrint(NS_SERVER, adr[i][0], "\\heartbeat\\%d\\gamename\\%s\\",
|
||||
Cvar_VariableIntegerValue("net_port"), message);
|
||||
if(adr[i][1].type != NA_BAD)
|
||||
NET_OutOfBandPrint(NS_SERVER, adr[i][1], "\\heartbeat\\%d\\gamename\\%s\\",
|
||||
Cvar_VariableIntegerValue("net_port6"), message);
|
||||
#else
|
||||
if(adr[i][0].type != NA_BAD)
|
||||
NET_OutOfBandPrint( NS_SERVER, adr[i][0], "heartbeat %s\n", message);
|
||||
if(adr[i][1].type != NA_BAD)
|
||||
NET_OutOfBandPrint( NS_SERVER, adr[i][1], "heartbeat %s\n", message);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -682,7 +690,11 @@ void SVC_Info( netadr_t from ) {
|
|||
Info_SetValueForKey( infostring, "game", gamedir );
|
||||
}
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
NET_OutOfBandPrint( NS_SERVER, from, "infoResponse \"%s\"", infostring );
|
||||
#else
|
||||
NET_OutOfBandPrint( NS_SERVER, from, "infoResponse\n%s", infostring );
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -787,9 +799,11 @@ static void SV_ConnectionlessPacket( netadr_t from, msg_t *msg ) {
|
|||
MSG_BeginReadingOOB( msg );
|
||||
MSG_ReadLong( msg ); // skip the -1 marker
|
||||
|
||||
#ifndef ELITEFORCE
|
||||
if (!Q_strncmp("connect", (char *) &msg->data[4], 7)) {
|
||||
Huff_Decompress(msg, 12);
|
||||
}
|
||||
#endif
|
||||
|
||||
s = MSG_ReadStringLine( msg );
|
||||
Cmd_TokenizeString( s );
|
||||
|
@ -867,6 +881,10 @@ void SV_PacketEvent( netadr_t from, msg_t *msg ) {
|
|||
cl->netchan.remoteAddress.port = from.port;
|
||||
}
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
msg->compat = cl->compat;
|
||||
#endif
|
||||
|
||||
// make sure it is a valid, in sequence packet
|
||||
if (SV_Netchan_Process(cl, msg)) {
|
||||
// zombie clients still need to do the Netchan_Process
|
||||
|
|
|
@ -24,6 +24,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
#include "../qcommon/qcommon.h"
|
||||
#include "server.h"
|
||||
|
||||
#ifndef ELITEFORCE
|
||||
#ifdef LEGACY_PROTOCOL
|
||||
/*
|
||||
==============
|
||||
|
@ -130,7 +131,7 @@ static void SV_Netchan_Decode( client_t *client, msg_t *msg ) {
|
|||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
|
@ -164,9 +165,11 @@ void SV_Netchan_TransmitNextInQueue(client_t *client)
|
|||
Com_DPrintf("#462 Netchan_TransmitNextFragment: popping a queued message for transmit\n");
|
||||
netbuf = client->netchan_start_queue;
|
||||
|
||||
#ifndef ELITEFORCE
|
||||
#ifdef LEGACY_PROTOCOL
|
||||
if(client->compat)
|
||||
SV_Netchan_Encode(client, &netbuf->msg, netbuf->clientCommandString);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
Netchan_Transmit(&client->netchan, netbuf->msg.cursize, netbuf->msg.data);
|
||||
|
@ -223,7 +226,11 @@ then buffer them and make sure they get sent in correct order
|
|||
|
||||
void SV_Netchan_Transmit( client_t *client, msg_t *msg)
|
||||
{
|
||||
MSG_WriteByte( msg, svc_EOF );
|
||||
#ifdef ELITEFORCE
|
||||
if(!msg->compat)
|
||||
#endif
|
||||
MSG_WriteByte( msg, svc_EOF );
|
||||
|
||||
|
||||
if(client->netchan.unsentFragments || client->netchan_start_queue)
|
||||
{
|
||||
|
@ -246,9 +253,11 @@ void SV_Netchan_Transmit( client_t *client, msg_t *msg)
|
|||
}
|
||||
else
|
||||
{
|
||||
#ifndef ELITEFORCE
|
||||
#ifdef LEGACY_PROTOCOL
|
||||
if(client->compat)
|
||||
SV_Netchan_Encode(client, msg, client->lastClientCommandString);
|
||||
#endif
|
||||
#endif
|
||||
Netchan_Transmit( &client->netchan, msg->cursize, msg->data );
|
||||
}
|
||||
|
@ -264,12 +273,12 @@ qboolean SV_Netchan_Process( client_t *client, msg_t *msg ) {
|
|||
ret = Netchan_Process( &client->netchan, msg );
|
||||
if (!ret)
|
||||
return qfalse;
|
||||
|
||||
#ifndef ELITEFORCE
|
||||
#ifdef LEGACY_PROTOCOL
|
||||
if(client->compat)
|
||||
SV_Netchan_Decode(client, msg);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
|
|
|
@ -154,6 +154,12 @@ static void SV_WriteSnapshotToClient( client_t *client, msg_t *msg ) {
|
|||
|
||||
MSG_WriteByte (msg, svc_snapshot);
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
if(msg->compat)
|
||||
#endif
|
||||
MSG_WriteLong( msg, client->lastClientCommand );
|
||||
|
||||
|
||||
// NOTE, MRE: now sent at the start of every message from server to client
|
||||
// let the client know which reliable clientCommands we have received
|
||||
//MSG_WriteLong( msg, client->lastClientCommand );
|
||||
|
@ -413,6 +419,7 @@ static void SV_AddEntitiesVisibleFromPoint( vec3_t origin, clientSnapshot_t *fra
|
|||
|
||||
// if it's a portal entity, add everything visible from its camera position
|
||||
if ( ent->r.svFlags & SVF_PORTAL ) {
|
||||
#ifndef ELITEFORCE
|
||||
if ( ent->s.generic1 ) {
|
||||
vec3_t dir;
|
||||
VectorSubtract(ent->s.origin, origin, dir);
|
||||
|
@ -420,6 +427,7 @@ static void SV_AddEntitiesVisibleFromPoint( vec3_t origin, clientSnapshot_t *fra
|
|||
continue;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
SV_AddEntitiesVisibleFromPoint( ent->s.origin2, frame, eNums, qtrue );
|
||||
}
|
||||
|
||||
|
@ -607,12 +615,23 @@ void SV_SendClientSnapshot( client_t *client ) {
|
|||
return;
|
||||
}
|
||||
|
||||
MSG_Init (&msg, msg_buf, sizeof(msg_buf));
|
||||
#ifdef ELITEFORCE
|
||||
if(client->compat)
|
||||
{
|
||||
MSG_InitOOB(&msg, msg_buf, sizeof(msg_buf));
|
||||
msg.compat = qtrue;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
MSG_Init (&msg, msg_buf, sizeof(msg_buf));
|
||||
msg.allowoverflow = qtrue;
|
||||
|
||||
// NOTE, MRE: all server->client messages now acknowledge
|
||||
// let the client know which reliable clientCommands we have received
|
||||
MSG_WriteLong( &msg, client->lastClientCommand );
|
||||
#ifdef ELITEFORCE
|
||||
if(!client->compat)
|
||||
#endif
|
||||
MSG_WriteLong( &msg, client->lastClientCommand );
|
||||
|
||||
// (re)send any reliable server commands
|
||||
SV_UpdateServerCommandsToClient( client, &msg );
|
||||
|
|
|
@ -222,27 +222,87 @@ void SV_LinkEntity( sharedEntity_t *gEnt ) {
|
|||
// encode the size into the entityState_t for client prediction
|
||||
if ( gEnt->r.bmodel ) {
|
||||
gEnt->s.solid = SOLID_BMODEL; // a solid_box will never create this value
|
||||
#ifdef ELITEFORCE
|
||||
} else if ( gEnt->r.contents & ( CONTENTS_SOLID | CONTENTS_BODY | CONTENTS_SHOTCLIP ) ) {
|
||||
if(gEnt->r.svFlags & SVF_SHIELD_BBOX)
|
||||
{
|
||||
if(gEnt->s.time2 & (1 << 24))
|
||||
{
|
||||
i = gEnt->r.maxs[0];
|
||||
if (i<1)
|
||||
i = 1;
|
||||
if (i>255)
|
||||
i = 255;
|
||||
|
||||
// z is not symetric
|
||||
j = -gEnt->r.mins[0];
|
||||
if (j<1)
|
||||
j = 1;
|
||||
if (j>255)
|
||||
j = 255;
|
||||
|
||||
// and z maxs can be negative...
|
||||
k = gEnt->r.maxs[2];
|
||||
if (k<1)
|
||||
k = 1;
|
||||
if (k>255)
|
||||
k = 255;
|
||||
|
||||
gEnt->s.eFlags |= EF_SHIELD_BOX_X;
|
||||
}
|
||||
else
|
||||
{
|
||||
i = gEnt->r.maxs[1];
|
||||
if (i<1)
|
||||
i = 1;
|
||||
if (i>255)
|
||||
i = 255;
|
||||
|
||||
// z is not symetric
|
||||
j = -gEnt->r.mins[1];
|
||||
if (j<1)
|
||||
j = 1;
|
||||
if (j>255)
|
||||
j = 255;
|
||||
|
||||
// and z maxs can be negative...
|
||||
k = gEnt->r.maxs[2];
|
||||
if (k<1)
|
||||
k = 1;
|
||||
if (k>255)
|
||||
k = 255;
|
||||
|
||||
gEnt->s.eFlags |= EF_SHIELD_BOX_Y;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#else
|
||||
} else if ( gEnt->r.contents & ( CONTENTS_SOLID | CONTENTS_BODY ) ) {
|
||||
// assume that x/y are equal and symetric
|
||||
i = gEnt->r.maxs[0];
|
||||
if (i<1)
|
||||
i = 1;
|
||||
if (i>255)
|
||||
i = 255;
|
||||
#endif
|
||||
// assume that x/y are equal and symetric
|
||||
i = gEnt->r.maxs[0];
|
||||
if (i<1)
|
||||
i = 1;
|
||||
if (i>255)
|
||||
i = 255;
|
||||
|
||||
// z is not symetric
|
||||
j = (-gEnt->r.mins[2]);
|
||||
if (j<1)
|
||||
j = 1;
|
||||
if (j>255)
|
||||
j = 255;
|
||||
// z is not symetric
|
||||
j = (-gEnt->r.mins[2]);
|
||||
if (j<1)
|
||||
j = 1;
|
||||
if (j>255)
|
||||
j = 255;
|
||||
|
||||
// and z maxs can be negative...
|
||||
k = (gEnt->r.maxs[2]+32);
|
||||
if (k<1)
|
||||
k = 1;
|
||||
if (k>255)
|
||||
k = 255;
|
||||
// and z maxs can be negative...
|
||||
k = (gEnt->r.maxs[2]+32);
|
||||
if (k<1)
|
||||
k = 1;
|
||||
if (k>255)
|
||||
k = 255;
|
||||
#ifdef ELITEFORCE
|
||||
}
|
||||
#endif
|
||||
|
||||
gEnt->s.solid = (k<<16) | (j<<8) | i;
|
||||
} else {
|
||||
|
|
|
@ -81,6 +81,12 @@ typedef enum {
|
|||
UI_GETGLCONFIG,
|
||||
UI_GETCLIENTSTATE,
|
||||
UI_GETCONFIGSTRING,
|
||||
#ifdef ELITEFORCE
|
||||
UI_LAN_GETLOCALSERVERCOUNT,
|
||||
UI_LAN_GETLOCALSERVERADDRESSSTRING,
|
||||
UI_LAN_GETGLOBALSERVERCOUNT,
|
||||
UI_LAN_GETGLOBALSERVERADDRESSSTRING,
|
||||
#endif
|
||||
UI_LAN_GETPINGQUEUECOUNT,
|
||||
UI_LAN_CLEARPING,
|
||||
UI_LAN_GETPING,
|
||||
|
@ -88,6 +94,10 @@ typedef enum {
|
|||
UI_CVAR_REGISTER,
|
||||
UI_CVAR_UPDATE,
|
||||
UI_MEMORY_REMAINING,
|
||||
#ifdef ELITEFORCE
|
||||
UI_SET_CDKEY,
|
||||
UI_R_MODELBOUNDS,
|
||||
#else
|
||||
UI_GET_CDKEY,
|
||||
UI_SET_CDKEY,
|
||||
UI_R_REGISTERFONT,
|
||||
|
@ -124,6 +134,7 @@ typedef enum {
|
|||
// 1.32
|
||||
UI_FS_SEEK,
|
||||
UI_SET_PBCLSTATUS,
|
||||
#endif
|
||||
|
||||
UI_MEMSET = 100,
|
||||
UI_MEMCPY,
|
||||
|
@ -182,7 +193,9 @@ typedef enum {
|
|||
|
||||
UI_DRAW_CONNECT_SCREEN,
|
||||
// void UI_DrawConnectScreen( qboolean overlay );
|
||||
#ifndef ELITEFORCE
|
||||
UI_HASUNIQUECDKEY
|
||||
#endif
|
||||
// if !overlay, the background will be drawn, otherwise it will be
|
||||
// overlayed over whatever the cgame has drawn.
|
||||
// a GetClientState syscall will be made to get the current strings
|
||||
|
|
Loading…
Reference in a new issue