mirror of
https://github.com/UberGames/lilium-voyager.git
synced 2024-11-10 06:31:47 +00:00
Port Elite Force iorev2231 patch to latest ioq3
Port Thilo Schulz's Elite Force Holomatch patch to latest ioq3. Patch for ioq3 svn r2231. No support for OpenGL2 renderer yet.
This commit is contained in:
parent
4d666212b2
commit
c6e5f060fe
62 changed files with 3124 additions and 292 deletions
10
Makefile
10
Makefile
|
@ -96,7 +96,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
|
||||
|
@ -267,6 +271,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
|
||||
|
|
|
@ -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;
|
||||
|
@ -736,7 +738,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 ) {
|
||||
|
@ -746,9 +751,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 );
|
||||
|
@ -850,18 +867,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;
|
||||
}
|
||||
}
|
||||
|
@ -958,6 +981,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);
|
||||
|
@ -1035,6 +1064,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
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -733,9 +733,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);
|
||||
|
@ -747,7 +752,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);
|
||||
|
@ -778,11 +787,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 );
|
||||
|
@ -809,17 +830,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 );
|
||||
|
@ -962,7 +996,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);
|
||||
|
@ -1003,7 +1045,11 @@ static int CL_WalkDemoExt(char *arg, char *name, int *demofile)
|
|||
#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)
|
||||
|
@ -1097,6 +1143,17 @@ void CL_PlayDemo_f( void ) {
|
|||
|
||||
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, '.');
|
||||
|
||||
|
@ -1136,6 +1193,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);
|
||||
|
@ -1869,7 +1927,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);
|
||||
}
|
||||
|
@ -2369,7 +2432,11 @@ void CL_CheckForResend( void ) {
|
|||
data[10+i] = 0;
|
||||
|
||||
// NOTE TTimo don't forget to set the right data length!
|
||||
NET_OutOfBandData( NS_CLIENT, clc.serverAddress, (byte *) &data[0], i+10 );
|
||||
#ifdef ELITEFORCE
|
||||
NET_OutOfBandPrint( NS_CLIENT, clc.serverAddress, "%s", data);
|
||||
#else
|
||||
NET_OutOfBandData( NS_CLIENT, clc.serverAddress, (byte *) &data[0], i+10 );
|
||||
#endif
|
||||
// the most current userinfo has been sent, so watch for any
|
||||
// newer changes to userinfo variables
|
||||
cvar_modifiedFlags &= ~CVAR_USERINFO;
|
||||
|
@ -2447,6 +2514,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");
|
||||
|
||||
|
@ -2476,12 +2546,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;
|
||||
}
|
||||
|
@ -2497,17 +2585,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;
|
||||
|
@ -2708,6 +2803,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;
|
||||
|
@ -2780,6 +2878,9 @@ 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 );
|
||||
|
@ -3097,7 +3198,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;
|
||||
|
@ -3426,6 +3531,8 @@ void CL_Init( void ) {
|
|||
}
|
||||
|
||||
cls.realtime = 0;
|
||||
clc.lastPacketTime = 0;
|
||||
clc.lastPacketSentTime = -9999;
|
||||
|
||||
CL_InitInput ();
|
||||
|
||||
|
@ -3460,7 +3567,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);
|
||||
|
@ -3541,12 +3652,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 );
|
||||
|
@ -3750,6 +3863,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
|
||||
|
@ -3787,6 +3913,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 ) );
|
||||
|
@ -3801,15 +3931,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;
|
||||
|
@ -4147,8 +4287,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;
|
||||
|
|
|
@ -209,7 +209,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
|
||||
|
@ -482,9 +485,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;
|
||||
|
@ -517,9 +523,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));
|
||||
|
@ -872,14 +885,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
|
||||
|
@ -892,7 +912,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
|
||||
|
||||
|
|
|
@ -574,6 +574,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;
|
||||
}
|
||||
|
@ -166,6 +200,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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -30,6 +30,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
|
||||
// the "gameversion" client command will print this plus compile date
|
||||
#define GAMEVERSION BASEGAME
|
||||
#endif
|
||||
|
||||
#define BODY_QUEUE_SIZE 8
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -31,15 +31,24 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
#include <winsock.h>
|
||||
#endif
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
int demo_protocols[] =
|
||||
{ 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)
|
||||
|
||||
|
@ -73,6 +82,7 @@ cvar_t *com_version;
|
|||
cvar_t *com_blood;
|
||||
cvar_t *com_buildScript; // for automated data building scripts
|
||||
cvar_t *com_introPlayed;
|
||||
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;
|
||||
|
@ -2446,8 +2456,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 ) {
|
||||
|
@ -2457,6 +2473,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 );
|
||||
|
||||
|
@ -2465,6 +2534,7 @@ void Com_ReadCDKey( const char *filename ) {
|
|||
} else {
|
||||
Q_strncpyz( cl_cdkey, " ", 17 );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2506,20 +2576,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);
|
||||
|
@ -2530,7 +2610,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" );
|
||||
|
@ -2755,6 +2839,7 @@ void Com_Init( char *commandLine ) {
|
|||
Cvar_Get("com_errorMessage", "", CVAR_ROM | CVAR_NORESTART);
|
||||
|
||||
com_introPlayed = Cvar_Get( "com_introplayed", "0", CVAR_ARCHIVE);
|
||||
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 );
|
||||
|
@ -2803,6 +2888,9 @@ void Com_Init( char *commandLine ) {
|
|||
|
||||
// add + commands from command line
|
||||
if ( !Com_AddStartupCommands() ) {
|
||||
#ifdef ELITEFORCE
|
||||
Cvar_Set( com_introPlayed->name, "1" );
|
||||
#else
|
||||
// if the user didn't give any commands, run default action
|
||||
if ( !com_dedicated->integer ) {
|
||||
Cbuf_AddText ("cinematic idlogo.RoQ\n");
|
||||
|
@ -2811,6 +2899,7 @@ void Com_Init( char *commandLine ) {
|
|||
Cvar_Set( "nextmap", "cinematic intro.RoQ" );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// start in full screen ui mode
|
||||
|
|
|
@ -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[] =
|
||||
{
|
||||
|
@ -3078,6 +3088,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)
|
||||
|
@ -3086,6 +3102,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]))
|
||||
|
@ -3356,6 +3373,7 @@ static void FS_Startup( const char *gameName )
|
|||
}
|
||||
|
||||
#ifndef STANDALONE
|
||||
#ifdef ELITEFORCE
|
||||
/*
|
||||
===================
|
||||
FS_CheckPak0
|
||||
|
@ -3368,6 +3386,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;
|
||||
|
@ -3399,6 +3534,7 @@ static void FS_CheckPak0( void )
|
|||
{
|
||||
if(pakBasename[3] == '0')
|
||||
{
|
||||
|
||||
Com_Printf("\n\n"
|
||||
"**************************************************\n"
|
||||
"WARNING: " BASEGAME "/pak0.pk3 is present but its checksum (%u)\n"
|
||||
|
@ -3515,7 +3651,6 @@ static void FS_CheckPak0( void )
|
|||
"\"pak0.pk3\" is missing. Please copy it "
|
||||
"from your legitimate Q3 CDROM. ");
|
||||
}
|
||||
|
||||
if((foundPak & 0x1fe) != 0x1fe)
|
||||
{
|
||||
Q_strcat(errorText, sizeof(errorText),
|
||||
|
@ -3553,6 +3688,7 @@ static void FS_CheckPak0( void )
|
|||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
=====================
|
||||
|
@ -4091,6 +4227,7 @@ void FS_FilenameCompletion( const char *dir, const char *ext,
|
|||
callback( filename );
|
||||
}
|
||||
FS_FreeFileList( filenames );
|
||||
|
||||
}
|
||||
|
||||
const char *FS_GetCurrentGameDir(void)
|
||||
|
|
|
@ -103,6 +103,15 @@ bit functions
|
|||
|
||||
int overflows;
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
// Apparently, eliteforce only sends stuff like strings on 1 byte boundaries.
|
||||
void MSG_RoundBits(msg_t *msg)
|
||||
{
|
||||
if(msg->bit & 0x07)
|
||||
msg->bit = ++msg->readcount << 3;
|
||||
}
|
||||
#endif
|
||||
|
||||
// negative bit values include signs
|
||||
void MSG_WriteBits( msg_t *msg, int value, int bits ) {
|
||||
int i;
|
||||
|
@ -140,28 +149,59 @@ void MSG_WriteBits( msg_t *msg, int value, int bits ) {
|
|||
bits = -bits;
|
||||
}
|
||||
if (msg->oob) {
|
||||
if(bits==8)
|
||||
#ifdef ELITEFORCE
|
||||
if(msg->compat)
|
||||
{
|
||||
msg->data[msg->cursize] = value;
|
||||
msg->cursize += 1;
|
||||
msg->bit += 8;
|
||||
}
|
||||
else if(bits==16)
|
||||
{
|
||||
short temp = value;
|
||||
int write, leftover, nbits = bits, location;
|
||||
|
||||
CopyLittleShort(&msg->data[msg->cursize], &temp);
|
||||
msg->cursize += 2;
|
||||
msg->bit += 16;
|
||||
}
|
||||
else if(bits==32)
|
||||
{
|
||||
CopyLittleLong(&msg->data[msg->cursize], &value);
|
||||
msg->cursize += 4;
|
||||
msg->bit += 32;
|
||||
// make sure to set all non-used space in value to zero.
|
||||
if(bits < 32)
|
||||
value &= ((1 << bits) - 1);
|
||||
|
||||
while(nbits)
|
||||
{
|
||||
leftover = msg->bit & 0x07;
|
||||
write = 8 - leftover;
|
||||
location = msg->bit >> 3;
|
||||
|
||||
if(write > nbits)
|
||||
write = nbits;
|
||||
|
||||
msg->data[location] &= (1 << leftover) - 1;
|
||||
msg->data[location] |= (value & ((1 << write) - 1)) << (leftover);
|
||||
nbits -= write;
|
||||
value >>= write;
|
||||
msg->bit += write;
|
||||
}
|
||||
|
||||
msg->cursize = (msg->bit >> 3) + ((msg->bit & 0x07) ? 1 : 0);
|
||||
}
|
||||
else
|
||||
Com_Error(ERR_DROP, "can't write %d bits", bits);
|
||||
#endif
|
||||
{
|
||||
if(bits==8)
|
||||
{
|
||||
msg->data[msg->cursize] = value;
|
||||
msg->cursize += 1;
|
||||
msg->bit += 8;
|
||||
}
|
||||
else if(bits==16)
|
||||
{
|
||||
short temp = value;
|
||||
|
||||
CopyLittleShort(&msg->data[msg->cursize], &temp);
|
||||
msg->cursize += 2;
|
||||
msg->bit += 16;
|
||||
}
|
||||
else if(bits==32)
|
||||
{
|
||||
CopyLittleLong(&msg->data[msg->cursize], &value);
|
||||
msg->cursize += 4;
|
||||
msg->bit += 32;
|
||||
}
|
||||
else
|
||||
Com_Error(ERR_DROP, "can't write %d bits", bits);
|
||||
}
|
||||
} else {
|
||||
// fp = fopen("c:\\netchan.bin", "a");
|
||||
value &= (0xffffffff>>(32-bits));
|
||||
|
@ -203,29 +243,53 @@ int MSG_ReadBits( msg_t *msg, int bits ) {
|
|||
}
|
||||
|
||||
if (msg->oob) {
|
||||
if(bits==8)
|
||||
#ifdef ELITEFORCE
|
||||
if(msg->compat)
|
||||
{
|
||||
value = msg->data[msg->readcount];
|
||||
msg->readcount += 1;
|
||||
msg->bit += 8;
|
||||
}
|
||||
else if(bits==16)
|
||||
{
|
||||
short temp;
|
||||
nbits = 0;
|
||||
|
||||
CopyLittleShort(&temp, &msg->data[msg->readcount]);
|
||||
value = temp;
|
||||
msg->readcount += 2;
|
||||
msg->bit += 16;
|
||||
}
|
||||
else if(bits==32)
|
||||
{
|
||||
CopyLittleLong(&value, &msg->data[msg->readcount]);
|
||||
msg->readcount += 4;
|
||||
msg->bit += 32;
|
||||
while(nbits < bits)
|
||||
{
|
||||
i = msg->bit & 0x07;
|
||||
get = 8 - i;
|
||||
|
||||
if(get > bits - nbits)
|
||||
get = bits - nbits;
|
||||
|
||||
value |= ((msg->data[msg->bit >> 3] >> i) & ((1 << get) - 1)) << nbits;
|
||||
msg->bit += get;
|
||||
nbits += get;
|
||||
}
|
||||
|
||||
msg->readcount = (msg->bit >> 3) + ((msg->bit & 0x07) ? 1 : 0);
|
||||
}
|
||||
else
|
||||
Com_Error(ERR_DROP, "can't read %d bits", bits);
|
||||
#endif
|
||||
{
|
||||
if(bits==8)
|
||||
{
|
||||
value = msg->data[msg->readcount];
|
||||
msg->readcount += 1;
|
||||
msg->bit += 8;
|
||||
}
|
||||
else if(bits==16)
|
||||
{
|
||||
short temp;
|
||||
|
||||
CopyLittleShort(&temp, &msg->data[msg->readcount]);
|
||||
value = temp;
|
||||
msg->readcount += 2;
|
||||
msg->bit += 16;
|
||||
}
|
||||
else if(bits==32)
|
||||
{
|
||||
CopyLittleLong(&value, &msg->data[msg->readcount]);
|
||||
msg->readcount += 4;
|
||||
msg->bit += 32;
|
||||
}
|
||||
else
|
||||
Com_Error(ERR_DROP, "can't read %d bits", bits);
|
||||
}
|
||||
} else {
|
||||
nbits = 0;
|
||||
if (bits&7) {
|
||||
|
@ -256,7 +320,6 @@ int MSG_ReadBits( msg_t *msg, int bits ) {
|
|||
}
|
||||
|
||||
|
||||
|
||||
//================================================================================
|
||||
|
||||
//
|
||||
|
@ -283,6 +346,16 @@ void MSG_WriteByte( msg_t *sb, int c ) {
|
|||
|
||||
void MSG_WriteData( msg_t *buf, const void *data, int length ) {
|
||||
int i;
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
if(buf->compat)
|
||||
{
|
||||
// Start writing on a whole-byte boundary
|
||||
if(buf->bit & 0x07)
|
||||
buf->bit = ++buf->cursize << 3;
|
||||
}
|
||||
#endif
|
||||
|
||||
for(i=0;i<length;i++) {
|
||||
MSG_WriteByte(buf, ((byte *)data)[i]);
|
||||
}
|
||||
|
@ -311,7 +384,11 @@ void MSG_WriteString( msg_t *sb, const char *s ) {
|
|||
if ( !s ) {
|
||||
MSG_WriteData (sb, "", 1);
|
||||
} else {
|
||||
#ifdef ELITEFORCE
|
||||
int l;
|
||||
#else
|
||||
int l,i;
|
||||
#endif
|
||||
char string[MAX_STRING_CHARS];
|
||||
|
||||
l = strlen( s );
|
||||
|
@ -322,12 +399,14 @@ void MSG_WriteString( msg_t *sb, const char *s ) {
|
|||
}
|
||||
Q_strncpyz( string, s, sizeof( string ) );
|
||||
|
||||
#ifndef ELITEFORCE
|
||||
// get rid of 0x80+ and '%' chars, because old clients don't like them
|
||||
for ( i = 0 ; i < l ; i++ ) {
|
||||
if ( ((byte *)string)[i] > 127 || string[i] == '%' ) {
|
||||
string[i] = '.';
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
MSG_WriteData (sb, string, l+1);
|
||||
}
|
||||
|
@ -337,7 +416,11 @@ void MSG_WriteBigString( msg_t *sb, const char *s ) {
|
|||
if ( !s ) {
|
||||
MSG_WriteData (sb, "", 1);
|
||||
} else {
|
||||
#ifdef ELITEFORCE
|
||||
int l;
|
||||
#else
|
||||
int l,i;
|
||||
#endif
|
||||
char string[BIG_INFO_STRING];
|
||||
|
||||
l = strlen( s );
|
||||
|
@ -348,12 +431,14 @@ void MSG_WriteBigString( msg_t *sb, const char *s ) {
|
|||
}
|
||||
Q_strncpyz( string, s, sizeof( string ) );
|
||||
|
||||
#ifndef ELITEFORCE
|
||||
// get rid of 0x80+ and '%' chars, because old clients don't like them
|
||||
for ( i = 0 ; i < l ; i++ ) {
|
||||
if ( ((byte *)string)[i] > 127 || string[i] == '%' ) {
|
||||
string[i] = '.';
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
MSG_WriteData (sb, string, l+1);
|
||||
}
|
||||
|
@ -444,6 +529,11 @@ char *MSG_ReadString( msg_t *msg ) {
|
|||
static char string[MAX_STRING_CHARS];
|
||||
int l,c;
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
if(msg->compat)
|
||||
MSG_RoundBits(msg);
|
||||
#endif
|
||||
|
||||
l = 0;
|
||||
do {
|
||||
c = MSG_ReadByte(msg); // use ReadByte so -1 is out of bounds
|
||||
|
@ -454,11 +544,12 @@ char *MSG_ReadString( msg_t *msg ) {
|
|||
if ( c == '%' ) {
|
||||
c = '.';
|
||||
}
|
||||
#ifndef ELITEFORCE
|
||||
// don't allow higher ascii values
|
||||
if ( c > 127 ) {
|
||||
c = '.';
|
||||
}
|
||||
|
||||
#endif
|
||||
string[l] = c;
|
||||
l++;
|
||||
} while (l < sizeof(string)-1);
|
||||
|
@ -472,6 +563,12 @@ char *MSG_ReadBigString( msg_t *msg ) {
|
|||
static char string[BIG_INFO_STRING];
|
||||
int l,c;
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
if(msg->compat)
|
||||
MSG_RoundBits(msg);
|
||||
#endif
|
||||
|
||||
|
||||
l = 0;
|
||||
do {
|
||||
c = MSG_ReadByte(msg); // use ReadByte so -1 is out of bounds
|
||||
|
@ -482,10 +579,12 @@ char *MSG_ReadBigString( msg_t *msg ) {
|
|||
if ( c == '%' ) {
|
||||
c = '.';
|
||||
}
|
||||
#ifndef ELITEFORCE
|
||||
// don't allow higher ascii values
|
||||
if ( c > 127 ) {
|
||||
c = '.';
|
||||
}
|
||||
#endif
|
||||
|
||||
string[l] = c;
|
||||
l++;
|
||||
|
@ -500,6 +599,11 @@ char *MSG_ReadStringLine( msg_t *msg ) {
|
|||
static char string[MAX_STRING_CHARS];
|
||||
int l,c;
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
if(msg->compat)
|
||||
MSG_RoundBits(msg);
|
||||
#endif
|
||||
|
||||
l = 0;
|
||||
do {
|
||||
c = MSG_ReadByte(msg); // use ReadByte so -1 is out of bounds
|
||||
|
@ -510,11 +614,12 @@ char *MSG_ReadStringLine( msg_t *msg ) {
|
|||
if ( c == '%' ) {
|
||||
c = '.';
|
||||
}
|
||||
#ifndef ELITEFORCE
|
||||
// don't allow higher ascii values
|
||||
if ( c > 127 ) {
|
||||
c = '.';
|
||||
}
|
||||
|
||||
#endif
|
||||
string[l] = c;
|
||||
l++;
|
||||
} while (l < sizeof(string)-1);
|
||||
|
@ -531,6 +636,11 @@ float MSG_ReadAngle16( msg_t *msg ) {
|
|||
void MSG_ReadData( msg_t *msg, void *data, int len ) {
|
||||
int i;
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
if(msg->compat)
|
||||
MSG_RoundBits(msg);
|
||||
#endif
|
||||
|
||||
for (i=0 ; i<len ; i++) {
|
||||
((byte *)data)[i] = MSG_ReadByte (msg);
|
||||
}
|
||||
|
@ -685,7 +795,11 @@ void MSG_WriteDeltaUsercmd( msg_t *msg, usercmd_t *from, usercmd_t *to ) {
|
|||
MSG_WriteDelta( msg, from->forwardmove, to->forwardmove, 8 );
|
||||
MSG_WriteDelta( msg, from->rightmove, to->rightmove, 8 );
|
||||
MSG_WriteDelta( msg, from->upmove, to->upmove, 8 );
|
||||
#ifdef ELITEFORCE
|
||||
MSG_WriteDelta( msg, from->buttons, to->buttons, 8 );
|
||||
#else
|
||||
MSG_WriteDelta( msg, from->buttons, to->buttons, 16 );
|
||||
#endif
|
||||
MSG_WriteDelta( msg, from->weapon, to->weapon, 8 );
|
||||
}
|
||||
|
||||
|
@ -713,13 +827,22 @@ void MSG_ReadDeltaUsercmd( msg_t *msg, usercmd_t *from, usercmd_t *to ) {
|
|||
to->upmove = MSG_ReadDelta( msg, from->upmove, 8);
|
||||
if( to->upmove == -128 )
|
||||
to->upmove = -127;
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
to->buttons = MSG_ReadDelta( msg, from->buttons, 8);
|
||||
#else
|
||||
to->buttons = MSG_ReadDelta( msg, from->buttons, 16);
|
||||
#endif
|
||||
to->weapon = MSG_ReadDelta( msg, from->weapon, 8);
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
<<<<<<< Updated upstream
|
||||
MSG_WriteDeltaUsercmd
|
||||
=======
|
||||
MSG_WriteDeltaUsercmdKey
|
||||
>>>>>>> Stashed changes
|
||||
=====================
|
||||
*/
|
||||
void MSG_WriteDeltaUsercmdKey( msg_t *msg, int key, usercmd_t *from, usercmd_t *to ) {
|
||||
|
@ -750,7 +873,11 @@ void MSG_WriteDeltaUsercmdKey( msg_t *msg, int key, usercmd_t *from, usercmd_t *
|
|||
MSG_WriteDeltaKey( msg, key, from->forwardmove, to->forwardmove, 8 );
|
||||
MSG_WriteDeltaKey( msg, key, from->rightmove, to->rightmove, 8 );
|
||||
MSG_WriteDeltaKey( msg, key, from->upmove, to->upmove, 8 );
|
||||
#ifdef ELITEFORCE
|
||||
MSG_WriteDeltaKey( msg, key, from->buttons, to->buttons, 8 );
|
||||
#else
|
||||
MSG_WriteDeltaKey( msg, key, from->buttons, to->buttons, 16 );
|
||||
#endif
|
||||
MSG_WriteDeltaKey( msg, key, from->weapon, to->weapon, 8 );
|
||||
}
|
||||
|
||||
|
@ -780,7 +907,12 @@ void MSG_ReadDeltaUsercmdKey( msg_t *msg, int key, usercmd_t *from, usercmd_t *t
|
|||
to->upmove = MSG_ReadDeltaKey( msg, key, from->upmove, 8);
|
||||
if( to->upmove == -128 )
|
||||
to->upmove = -127;
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
to->buttons = MSG_ReadDeltaKey( msg, key, from->buttons, 8);
|
||||
#else
|
||||
to->buttons = MSG_ReadDeltaKey( msg, key, from->buttons, 16);
|
||||
#endif
|
||||
to->weapon = MSG_ReadDeltaKey( msg, key, from->weapon, 8);
|
||||
} else {
|
||||
to->angles[0] = from->angles[0];
|
||||
|
@ -802,6 +934,48 @@ entityState_t communication
|
|||
=============================================================================
|
||||
*/
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
#define PVECTOR_BITS 5 // amount of bits we need to reference all predefined vectors.
|
||||
#define PVECTOR_BYTES 8 // length of predefined vector.
|
||||
#define PVECTOR_NUM (1 << PVECTOR_BITS) - 1 // number of existing predefined vectors.
|
||||
|
||||
byte pVectors[PVECTOR_NUM][PVECTOR_BYTES] =
|
||||
{
|
||||
{0x60, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
{0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
{0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
{0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
{0x20, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
{0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
{0x20, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
{0x40, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
{0x60, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
{0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
{0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
{0x60, 0x80, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00},
|
||||
{0x60, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00},
|
||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00},
|
||||
{0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
{0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
{0x60, 0xc0, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00},
|
||||
{0x60, 0xc0, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00},
|
||||
{0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
{0x60, 0xc0, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00},
|
||||
{0x60, 0xc0, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00},
|
||||
{0x60, 0x80, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00},
|
||||
{0x60, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00},
|
||||
{0xe1, 0x00, 0xc0, 0x01, 0x90, 0x00, 0x00, 0x00},
|
||||
{0xed, 0x07, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00},
|
||||
{0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00},
|
||||
{0x62, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00},
|
||||
{0x02, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00},
|
||||
{0xe0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
{0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
{0x60, 0x80, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00},
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
=================
|
||||
MSG_ReportChangeVectors_f
|
||||
|
@ -827,6 +1001,61 @@ typedef struct {
|
|||
// using the stringizing operator to save typing...
|
||||
#define NETF(x) #x,(size_t)&((entityState_t*)0)->x
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
netField_t entityStateFields[] =
|
||||
{
|
||||
{ NETF(eType), 8 },
|
||||
{ NETF(eFlags), 24 },
|
||||
{ NETF(pos.trType), 8 },
|
||||
{ NETF(pos.trTime), 32 },
|
||||
{ NETF(pos.trDuration), 32 },
|
||||
{ NETF(pos.trBase[0]), 0 },
|
||||
{ NETF(pos.trBase[1]), 0 },
|
||||
{ NETF(pos.trBase[2]), 0 },
|
||||
{ NETF(pos.trDelta[0]), 0 },
|
||||
{ NETF(pos.trDelta[1]), 0 },
|
||||
{ NETF(pos.trDelta[2]), 0 },
|
||||
{ NETF(apos.trType), 8 },
|
||||
{ NETF(apos.trTime), 32 },
|
||||
{ NETF(apos.trDuration), 32 },
|
||||
{ NETF(apos.trBase[0]), 0 },
|
||||
{ NETF(apos.trBase[1]), 0 },
|
||||
{ NETF(apos.trBase[2]), 0 },
|
||||
{ NETF(apos.trDelta[0]), 0 },
|
||||
{ NETF(apos.trDelta[1]), 0 },
|
||||
{ NETF(apos.trDelta[2]), 0 },
|
||||
{ NETF(time), 32 },
|
||||
{ NETF(time2), 32 },
|
||||
{ NETF(origin[0]), 0 },
|
||||
{ NETF(origin[1]), 0 },
|
||||
{ NETF(origin[2]), 0 },
|
||||
{ NETF(origin2[0]), 0 },
|
||||
{ NETF(origin2[1]), 0 },
|
||||
{ NETF(origin2[2]), 0 },
|
||||
{ NETF(angles[0]), 0 },
|
||||
{ NETF(angles[1]), 0 },
|
||||
{ NETF(angles[2]), 0 },
|
||||
{ NETF(angles2[0]), 0 },
|
||||
{ NETF(angles2[1]), 0 },
|
||||
{ NETF(angles2[2]), 0 },
|
||||
{ NETF(otherEntityNum), GENTITYNUM_BITS },
|
||||
{ NETF(otherEntityNum2), GENTITYNUM_BITS },
|
||||
{ NETF(groundEntityNum), GENTITYNUM_BITS },
|
||||
{ NETF(loopSound), 16 },
|
||||
{ NETF(constantLight), 32 },
|
||||
{ NETF(modelindex), 8 },
|
||||
{ NETF(modelindex2), 8 },
|
||||
{ NETF(frame), 16 },
|
||||
{ NETF(clientNum), 8 },
|
||||
{ NETF(solid), 24 },
|
||||
{ NETF(event), 10 },
|
||||
{ NETF(eventParm), 8 },
|
||||
{ NETF(powerups), 16 },
|
||||
{ NETF(weapon), 8 },
|
||||
{ NETF(legsAnim), 8 },
|
||||
{ NETF(torsoAnim), 8 },
|
||||
};
|
||||
#else
|
||||
netField_t entityStateFields[] =
|
||||
{
|
||||
{ NETF(pos.trTime), 32 },
|
||||
|
@ -846,7 +1075,7 @@ netField_t entityStateFields[] =
|
|||
{ NETF(legsAnim), 8 },
|
||||
{ NETF(groundEntityNum), GENTITYNUM_BITS },
|
||||
{ NETF(pos.trType), 8 },
|
||||
{ NETF(eFlags), 19 },
|
||||
{ NETF(eFlags), 27 },
|
||||
{ NETF(otherEntityNum), GENTITYNUM_BITS },
|
||||
{ NETF(weapon), 8 },
|
||||
{ NETF(clientNum), 8 },
|
||||
|
@ -881,7 +1110,7 @@ netField_t entityStateFields[] =
|
|||
{ NETF(constantLight), 32 },
|
||||
{ NETF(frame), 16 }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
// if (int)f == f and (int)f + ( 1<<(FLOAT_INT_BITS-1) ) < ( 1 << FLOAT_INT_BITS )
|
||||
// the float will be sent with FLOAT_INT_BITS, otherwise all 32 bits will be sent
|
||||
|
@ -907,6 +1136,10 @@ void MSG_WriteDeltaEntity( msg_t *msg, struct entityState_s *from, struct entity
|
|||
int trunc;
|
||||
float fullFloat;
|
||||
int *fromF, *toF;
|
||||
#ifdef ELITEFORCE
|
||||
byte vector[PVECTOR_BYTES];
|
||||
int vectorIndex = -1;
|
||||
#endif
|
||||
|
||||
numFields = ARRAY_LEN( entityStateFields );
|
||||
|
||||
|
@ -930,17 +1163,33 @@ void MSG_WriteDeltaEntity( msg_t *msg, struct entityState_s *from, struct entity
|
|||
Com_Error (ERR_FATAL, "MSG_WriteDeltaEntity: Bad entity number: %i", to->number );
|
||||
}
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
if(msg->compat)
|
||||
Com_Memset(vector, 0, sizeof(vector));
|
||||
#endif
|
||||
|
||||
lc = 0;
|
||||
// build the change vector as bytes so it is endien independent
|
||||
for ( i = 0, field = entityStateFields ; i < numFields ; i++, field++ ) {
|
||||
fromF = (int *)( (byte *)from + field->offset );
|
||||
toF = (int *)( (byte *)to + field->offset );
|
||||
if ( *fromF != *toF ) {
|
||||
lc = i+1;
|
||||
#ifdef ELITEFORCE
|
||||
if(msg->compat)
|
||||
vector[i >> 3] |= 1 << (i & 0x07);
|
||||
else
|
||||
#endif
|
||||
lc = i+1;
|
||||
}
|
||||
}
|
||||
|
||||
if ( lc == 0 ) {
|
||||
#ifdef ELITEFORCE
|
||||
if((msg->compat && !((int *) vector)[0] && !((int *) vector)[1]) || (!msg->compat && !lc))
|
||||
{
|
||||
#else
|
||||
if ( lc == 0 )
|
||||
{
|
||||
#endif
|
||||
// nothing at all changed
|
||||
if ( !force ) {
|
||||
return; // nothing at all
|
||||
|
@ -952,35 +1201,87 @@ void MSG_WriteDeltaEntity( msg_t *msg, struct entityState_s *from, struct entity
|
|||
return;
|
||||
}
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
if(msg->compat)
|
||||
{
|
||||
for (i = 0; i < PVECTOR_NUM; i++)
|
||||
{
|
||||
if( ((int *) vector)[0] == ((int *)pVectors[i])[0] &&
|
||||
((int *) vector)[1] == ((int *)pVectors[i])[1]
|
||||
)
|
||||
{
|
||||
vectorIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
MSG_WriteBits( msg, to->number, GENTITYNUM_BITS );
|
||||
MSG_WriteBits( msg, 0, 1 ); // not removed
|
||||
MSG_WriteBits( msg, 1, 1 ); // we have a delta
|
||||
|
||||
MSG_WriteByte( msg, lc ); // # of changes
|
||||
#ifdef ELITEFORCE
|
||||
if(msg->compat)
|
||||
{
|
||||
MSG_WriteBits(msg, vectorIndex, PVECTOR_BITS);
|
||||
|
||||
if (vectorIndex < 0)
|
||||
{
|
||||
for ( i = 0 ; i + 8 <= numFields ; i += 8 )
|
||||
MSG_WriteByte( msg, vector[i >> 3] );
|
||||
if ( numFields & 7 )
|
||||
MSG_WriteBits( msg, vector[i >> 3], numFields & 7 );
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
#endif
|
||||
MSG_WriteByte( msg, lc ); // # of changes
|
||||
|
||||
oldsize += numFields;
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
for ( i = 0, field = entityStateFields ; msg->compat ? (i < numFields) : (i < lc) ; i++, field++ ) {
|
||||
#else
|
||||
for ( i = 0, field = entityStateFields ; i < lc ; i++, field++ ) {
|
||||
#endif
|
||||
fromF = (int *)( (byte *)from + field->offset );
|
||||
toF = (int *)( (byte *)to + field->offset );
|
||||
|
||||
if ( *fromF == *toF ) {
|
||||
MSG_WriteBits( msg, 0, 1 ); // no change
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
if(!msg->compat)
|
||||
#endif
|
||||
MSG_WriteBits( msg, 0, 1 ); // no change
|
||||
continue;
|
||||
}
|
||||
|
||||
MSG_WriteBits( msg, 1, 1 ); // changed
|
||||
#ifdef ELITEFORCE
|
||||
if(!msg->compat)
|
||||
#endif
|
||||
MSG_WriteBits( msg, 1, 1 ); // changed
|
||||
|
||||
if ( field->bits == 0 ) {
|
||||
// float
|
||||
fullFloat = *(float *)toF;
|
||||
trunc = (int)fullFloat;
|
||||
|
||||
if (fullFloat == 0.0f) {
|
||||
MSG_WriteBits( msg, 0, 1 );
|
||||
oldsize += FLOAT_INT_BITS;
|
||||
#ifdef ELITEFORCE
|
||||
if(!msg->compat && fullFloat == 0.0f)
|
||||
#else
|
||||
if (fullFloat == 0.0f)
|
||||
#endif
|
||||
{
|
||||
MSG_WriteBits( msg, 0, 1 );
|
||||
oldsize += FLOAT_INT_BITS;
|
||||
} else {
|
||||
MSG_WriteBits( msg, 1, 1 );
|
||||
#ifdef ELITEFORCE
|
||||
if(!msg->compat)
|
||||
#endif
|
||||
MSG_WriteBits( msg, 1, 1 );
|
||||
|
||||
if ( trunc == fullFloat && trunc + FLOAT_INT_BIAS >= 0 &&
|
||||
trunc + FLOAT_INT_BIAS < ( 1 << FLOAT_INT_BITS ) ) {
|
||||
// send as small integer
|
||||
|
@ -993,13 +1294,23 @@ void MSG_WriteDeltaEntity( msg_t *msg, struct entityState_s *from, struct entity
|
|||
}
|
||||
}
|
||||
} else {
|
||||
if (*toF == 0) {
|
||||
MSG_WriteBits( msg, 0, 1 );
|
||||
} else {
|
||||
MSG_WriteBits( msg, 1, 1 );
|
||||
// integer
|
||||
MSG_WriteBits( msg, *toF, field->bits );
|
||||
#ifdef ELITEFORCE
|
||||
if(msg->compat)
|
||||
MSG_WriteBits(msg, *toF, field->bits);
|
||||
else
|
||||
{
|
||||
#endif
|
||||
if (*toF == 0)
|
||||
MSG_WriteBits( msg, 0, 1 );
|
||||
else
|
||||
{
|
||||
MSG_WriteBits( msg, 1, 1 );
|
||||
// integer
|
||||
MSG_WriteBits( msg, *toF, field->bits );
|
||||
}
|
||||
#ifdef ELITEFORCE
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1018,13 +1329,18 @@ Can go from either a baseline or a previous packet_entity
|
|||
*/
|
||||
void MSG_ReadDeltaEntity( msg_t *msg, entityState_t *from, entityState_t *to,
|
||||
int number) {
|
||||
int i, lc;
|
||||
int i, lc = 0;
|
||||
int numFields;
|
||||
netField_t *field;
|
||||
int *fromF, *toF;
|
||||
int print;
|
||||
int trunc;
|
||||
int startBit, endBit;
|
||||
#ifdef ELITEFORCE
|
||||
int vectorIndex;
|
||||
byte vector_space[PVECTOR_BYTES];
|
||||
byte *vector = vector_space;
|
||||
#endif
|
||||
|
||||
if ( number < 0 || number >= MAX_GENTITIES) {
|
||||
Com_Error( ERR_DROP, "Bad delta entity number: %i", number );
|
||||
|
@ -1054,7 +1370,10 @@ void MSG_ReadDeltaEntity( msg_t *msg, entityState_t *from, entityState_t *to,
|
|||
}
|
||||
|
||||
numFields = ARRAY_LEN( entityStateFields );
|
||||
lc = MSG_ReadByte(msg);
|
||||
#ifdef ELITEFORCE
|
||||
if(!msg->compat)
|
||||
#endif
|
||||
lc = MSG_ReadByte(msg);
|
||||
|
||||
if ( lc > numFields || lc < 0 ) {
|
||||
Com_Error( ERR_DROP, "invalid entityState field count" );
|
||||
|
@ -1071,19 +1390,48 @@ void MSG_ReadDeltaEntity( msg_t *msg, entityState_t *from, entityState_t *to,
|
|||
|
||||
to->number = number;
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
if(msg->compat)
|
||||
{
|
||||
// Read in the vector index and check whether there is a predefined one or not.
|
||||
vectorIndex = MSG_ReadBits( msg, PVECTOR_BITS );
|
||||
|
||||
if (vectorIndex == PVECTOR_NUM)
|
||||
{
|
||||
for (i = 0; i + 8 < numFields; i += 8)
|
||||
vector[i >> 3] = MSG_ReadByte(msg);
|
||||
if (numFields & 7)
|
||||
vector[i>>3] = MSG_ReadBits( msg, numFields & 7 );
|
||||
}
|
||||
else
|
||||
vector = pVectors[vectorIndex];
|
||||
}
|
||||
|
||||
for ( i = 0, field = entityStateFields ; msg->compat ? (i < numFields) : (i < lc) ; i++, field++ ) {
|
||||
#else
|
||||
for ( i = 0, field = entityStateFields ; i < lc ; i++, field++ ) {
|
||||
#endif
|
||||
fromF = (int *)( (byte *)from + field->offset );
|
||||
toF = (int *)( (byte *)to + field->offset );
|
||||
|
||||
if ( ! MSG_ReadBits( msg, 1 ) ) {
|
||||
#ifdef ELITEFORCE
|
||||
if((msg->compat && ! (vector[i >> 3] & (1 << (i & 7)) )) || (!msg->compat && !MSG_ReadBits(msg, 1)))
|
||||
#else
|
||||
if ( ! MSG_ReadBits( msg, 1 ) )
|
||||
#endif
|
||||
{
|
||||
// no change
|
||||
*toF = *fromF;
|
||||
} else {
|
||||
if ( field->bits == 0 ) {
|
||||
// float
|
||||
if ( MSG_ReadBits( msg, 1 ) == 0 ) {
|
||||
#ifdef ELITEFORCE
|
||||
if(!msg->compat && !MSG_ReadBits( msg, 1 ))
|
||||
#else
|
||||
if ( MSG_ReadBits( msg, 1 ) == 0 )
|
||||
#endif
|
||||
*(float *)toF = 0.0f;
|
||||
} else {
|
||||
else {
|
||||
if ( MSG_ReadBits( msg, 1 ) == 0 ) {
|
||||
// integral float
|
||||
trunc = MSG_ReadBits( msg, FLOAT_INT_BITS );
|
||||
|
@ -1102,9 +1450,13 @@ void MSG_ReadDeltaEntity( msg_t *msg, entityState_t *from, entityState_t *to,
|
|||
}
|
||||
}
|
||||
} else {
|
||||
if ( MSG_ReadBits( msg, 1 ) == 0 ) {
|
||||
#ifdef ELITEFORCE
|
||||
if(!msg->compat && !MSG_ReadBits(msg, 1))
|
||||
#else
|
||||
if ( MSG_ReadBits( msg, 1 ) == 0 )
|
||||
#endif
|
||||
*toF = 0;
|
||||
} else {
|
||||
else {
|
||||
// integer
|
||||
*toF = MSG_ReadBits( msg, field->bits );
|
||||
if ( print ) {
|
||||
|
@ -1115,12 +1467,19 @@ void MSG_ReadDeltaEntity( msg_t *msg, entityState_t *from, entityState_t *to,
|
|||
// pcount[i]++;
|
||||
}
|
||||
}
|
||||
for ( i = lc, field = &entityStateFields[lc] ; i < numFields ; i++, field++ ) {
|
||||
fromF = (int *)( (byte *)from + field->offset );
|
||||
toF = (int *)( (byte *)to + field->offset );
|
||||
// no change
|
||||
*toF = *fromF;
|
||||
#ifdef ELITEFORCE
|
||||
if(!msg->compat)
|
||||
{
|
||||
#endif
|
||||
for ( i = lc, field = &entityStateFields[lc] ; i < numFields ; i++, field++ ) {
|
||||
fromF = (int *)( (byte *)from + field->offset );
|
||||
toF = (int *)( (byte *)to + field->offset );
|
||||
// no change
|
||||
*toF = *fromF;
|
||||
}
|
||||
#ifdef ELITEFORCE
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( print ) {
|
||||
if ( msg->bit == 0 ) {
|
||||
|
@ -1144,6 +1503,59 @@ plyer_state_t communication
|
|||
// using the stringizing operator to save typing...
|
||||
#define PSF(x) #x,(size_t)&((playerState_t*)0)->x
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
netField_t playerStateFields[] =
|
||||
{
|
||||
{ PSF(commandTime), 32 },
|
||||
{ PSF(pm_type), 8 },
|
||||
{ PSF(bobCycle), 8 },
|
||||
{ PSF(pm_flags), 16 },
|
||||
{ PSF(pm_time), -16 },
|
||||
{ PSF(origin[0]), 0 },
|
||||
{ PSF(origin[1]), 0 },
|
||||
{ PSF(origin[2]), 0 },
|
||||
{ PSF(velocity[0]), 0 },
|
||||
{ PSF(velocity[1]), 0 },
|
||||
{ PSF(velocity[2]), 0 },
|
||||
{ PSF(weaponTime), -16 },
|
||||
{ PSF(gravity), 16 },
|
||||
{ PSF(speed), 16 },
|
||||
{ PSF(delta_angles[0]), 16 },
|
||||
{ PSF(delta_angles[1]), 16 },
|
||||
{ PSF(delta_angles[2]), 16 },
|
||||
{ PSF(groundEntityNum), GENTITYNUM_BITS },
|
||||
{ PSF(legsTimer), 8 },
|
||||
{ PSF(torsoTimer), 12 },
|
||||
{ PSF(legsAnim), 8 },
|
||||
{ PSF(torsoAnim), 8 },
|
||||
{ PSF(movementDir), 4 },
|
||||
{ PSF(eFlags), 16 },
|
||||
{ PSF(eventSequence), 16 },
|
||||
{ PSF(events[0]), 8 },
|
||||
{ PSF(events[1]), 8 },
|
||||
{ PSF(events[2]), 8 },
|
||||
{ PSF(events[3]), 8 },
|
||||
{ PSF(eventParms[0]), 8 },
|
||||
{ PSF(eventParms[1]), 8 },
|
||||
{ PSF(eventParms[2]), 8 },
|
||||
{ PSF(eventParms[3]), 8 },
|
||||
{ PSF(externalEvent), 10 },
|
||||
{ PSF(externalEventParm), 8 },
|
||||
{ PSF(clientNum), 8 },
|
||||
{ PSF(weapon), 5 },
|
||||
{ PSF(weaponstate), 4 },
|
||||
{ PSF(viewangles[0]), 0 },
|
||||
{ PSF(viewangles[1]), 0 },
|
||||
{ PSF(viewangles[2]), 0 },
|
||||
{ PSF(viewheight), -8 },
|
||||
{ PSF(damageEvent), 8 },
|
||||
{ PSF(damageYaw), 8 },
|
||||
{ PSF(damagePitch), 8 },
|
||||
{ PSF(damageCount), 8 },
|
||||
{ PSF(damageShieldCount), 8 },
|
||||
{ PSF(introTime), 32},
|
||||
};
|
||||
#else
|
||||
netField_t playerStateFields[] =
|
||||
{
|
||||
{ PSF(commandTime), 32 },
|
||||
|
@ -1195,7 +1607,7 @@ netField_t playerStateFields[] =
|
|||
{ PSF(jumppad_ent), GENTITYNUM_BITS },
|
||||
{ PSF(loopSound), 16 }
|
||||
};
|
||||
|
||||
#endif
|
||||
/*
|
||||
=============
|
||||
MSG_WriteDeltaPlayerstate
|
||||
|
@ -1213,7 +1625,7 @@ void MSG_WriteDeltaPlayerstate( msg_t *msg, struct playerState_s *from, struct p
|
|||
netField_t *field;
|
||||
int *fromF, *toF;
|
||||
float fullFloat;
|
||||
int trunc, lc;
|
||||
int trunc, lc = 0;
|
||||
|
||||
if (!from) {
|
||||
from = &dummy;
|
||||
|
@ -1222,20 +1634,33 @@ void MSG_WriteDeltaPlayerstate( msg_t *msg, struct playerState_s *from, struct p
|
|||
|
||||
numFields = ARRAY_LEN( playerStateFields );
|
||||
|
||||
lc = 0;
|
||||
for ( i = 0, field = playerStateFields ; i < numFields ; i++, field++ ) {
|
||||
fromF = (int *)( (byte *)from + field->offset );
|
||||
toF = (int *)( (byte *)to + field->offset );
|
||||
if ( *fromF != *toF ) {
|
||||
lc = i+1;
|
||||
#ifdef ELITEFORCE
|
||||
if(!msg->compat)
|
||||
{
|
||||
#endif
|
||||
lc = 0;
|
||||
for ( i = 0, field = playerStateFields ; i < numFields ; i++, field++ ) {
|
||||
fromF = (int *)( (byte *)from + field->offset );
|
||||
toF = (int *)( (byte *)to + field->offset );
|
||||
if ( *fromF != *toF ) {
|
||||
lc = i+1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MSG_WriteByte( msg, lc ); // # of changes
|
||||
MSG_WriteByte( msg, lc ); // # of changes
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
}
|
||||
#endif
|
||||
|
||||
oldsize += numFields - lc;
|
||||
|
||||
for ( i = 0, field = playerStateFields ; i < lc ; i++, field++ ) {
|
||||
#ifdef ELITEFORCE
|
||||
for ( i = 0, field = playerStateFields ; msg->compat ? (i < numFields) : (i < lc) ; i++, field++ )
|
||||
#else
|
||||
for ( i = 0, field = playerStateFields ; i < lc ; i++, field++ )
|
||||
#endif
|
||||
{
|
||||
fromF = (int *)( (byte *)from + field->offset );
|
||||
toF = (int *)( (byte *)to + field->offset );
|
||||
|
||||
|
@ -1297,12 +1722,21 @@ void MSG_WriteDeltaPlayerstate( msg_t *msg, struct playerState_s *from, struct p
|
|||
}
|
||||
}
|
||||
|
||||
if (!statsbits && !persistantbits && !ammobits && !powerupbits) {
|
||||
#ifdef ELITEFORCE
|
||||
if (!msg->compat && !statsbits && !persistantbits && !ammobits && !powerupbits)
|
||||
#else
|
||||
if (!statsbits && !persistantbits && !ammobits && !powerupbits)
|
||||
#endif
|
||||
{
|
||||
MSG_WriteBits( msg, 0, 1 ); // no change
|
||||
oldsize += 4;
|
||||
return;
|
||||
}
|
||||
MSG_WriteBits( msg, 1, 1 ); // changed
|
||||
|
||||
#ifdef ELITEFORCE
|
||||
if(!msg->compat)
|
||||
#endif
|
||||
MSG_WriteBits( msg, 1, 1 ); // changed
|
||||
|
||||
if ( statsbits ) {
|
||||
MSG_WriteBits( msg, 1, 1 ); // changed
|
||||
|
@ -1355,7 +1789,7 @@ MSG_ReadDeltaPlayerstate
|
|||
===================
|
||||
*/
|
||||
void MSG_ReadDeltaPlayerstate (msg_t *msg, playerState_t *from, playerState_t *to ) {
|
||||
int i, lc;
|
||||
int i, lc = 0;
|
||||
int bits;
|
||||
netField_t *field;
|
||||
int numFields;
|
||||
|
@ -1387,10 +1821,17 @@ void MSG_ReadDeltaPlayerstate (msg_t *msg, playerState_t *from, playerState_t *t
|
|||
}
|
||||
|
||||
numFields = ARRAY_LEN( playerStateFields );
|
||||
lc = MSG_ReadByte(msg);
|
||||
|
||||
if ( lc > numFields || lc < 0 ) {
|
||||
Com_Error( ERR_DROP, "invalid playerState field count" );
|
||||
#ifdef ELITEFORCE
|
||||
if(msg->compat)
|
||||
lc = numFields;
|
||||
else
|
||||
#endif
|
||||
{
|
||||
lc = MSG_ReadByte(msg);
|
||||
|
||||
if(lc > numFields || lc < 0)
|
||||
Com_Error(ERR_DROP, "invalid entityState field count");
|
||||
}
|
||||
|
||||
for ( i = 0, field = playerStateFields ; i < lc ; i++, field++ ) {
|
||||
|
@ -1428,16 +1869,27 @@ void MSG_ReadDeltaPlayerstate (msg_t *msg, playerState_t *from, playerState_t *t
|
|||
}
|
||||
}
|
||||
}
|
||||
for ( i=lc,field = &playerStateFields[lc];i<numFields; i++, field++) {
|
||||
fromF = (int *)( (byte *)from + field->offset );
|
||||
toF = (int *)( (byte *)to + field->offset );
|
||||
// no change
|
||||
*toF = *fromF;
|
||||
#ifdef ELITEFORCE
|
||||
if(!msg->compat)
|
||||
{
|
||||
#endif
|
||||
for ( i=lc,field = &playerStateFields[lc];i<numFields; i++, field++) {
|
||||
fromF = (int *)( (byte *)from + field->offset );
|
||||
toF = (int *)( (byte *)to + field->offset );
|
||||
// no change
|
||||
*toF = *fromF;
|
||||
}
|
||||
#ifdef ELITEFORCE
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// read the arrays
|
||||
if (MSG_ReadBits( msg, 1 ) ) {
|
||||
#ifdef ELITEFORCE
|
||||
if(msg->compat || MSG_ReadBits( msg, 1 ))
|
||||
#else
|
||||
if (MSG_ReadBits( msg, 1 ) )
|
||||
#endif
|
||||
{
|
||||
// parse stats
|
||||
if ( MSG_ReadBits( msg, 1 ) ) {
|
||||
LOG("PS_STATS");
|
||||
|
|
|
@ -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 )
|
||||
{
|
||||
|
|
|
@ -37,19 +37,35 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
#define GAMENAME_FOR_MASTER "foobar" // must NOT contain whitespace
|
||||
// #define LEGACY_PROTOCOL // You probably don't need this for your standalone game
|
||||
#else
|
||||
#define PRODUCT_NAME "ioq3"
|
||||
#define BASEGAME "baseq3"
|
||||
#define CLIENT_WINDOW_TITLE "ioquake3"
|
||||
#define CLIENT_WINDOW_MIN_TITLE "ioq3"
|
||||
#define HOMEPATH_NAME_UNIX ".q3a"
|
||||
#define HOMEPATH_NAME_WIN "Quake3"
|
||||
#define HOMEPATH_NAME_MACOSX HOMEPATH_NAME_WIN
|
||||
#define GAMENAME_FOR_MASTER "Quake3Arena"
|
||||
#define LEGACY_PROTOCOL
|
||||
#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 GAMENAME_FOR_MASTER "EliteForce"
|
||||
#define LEGACY_PROTOCOL
|
||||
#else
|
||||
#define PRODUCT_NAME "ioq3"
|
||||
#define BASEGAME "baseq3"
|
||||
#define CLIENT_WINDOW_TITLE "ioquake3"
|
||||
#define CLIENT_WINDOW_MIN_TITLE "ioq3"
|
||||
#define HOMEPATH_NAME_UNIX ".q3a"
|
||||
#define HOMEPATH_NAME_WIN "Quake3"
|
||||
#define HOMEPATH_NAME_MACOSX HOMEPATH_NAME_WIN
|
||||
#define GAMENAME_FOR_MASTER "Quake3Arena"
|
||||
#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
|
||||
|
@ -1113,7 +1129,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
|
||||
|
||||
|
@ -1137,6 +1157,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
|
||||
|
@ -1155,7 +1180,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
|
||||
|
||||
|
@ -1179,20 +1206,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;
|
||||
|
||||
|
@ -1227,6 +1261,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];
|
||||
|
@ -1234,7 +1277,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
|
||||
|
@ -1305,7 +1348,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;
|
||||
|
@ -254,32 +261,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
|
||||
|
@ -595,15 +633,23 @@ 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 DEDICATED
|
||||
# define Q3CONFIG_CFG "q3config_server.cfg"
|
||||
#ifdef ELITEFORCE
|
||||
#define Q3CONFIG_CFG "hmconfig.cfg"
|
||||
#else
|
||||
# define Q3CONFIG_CFG "q3config.cfg"
|
||||
#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
|
||||
|
|
|
@ -82,6 +82,12 @@ extern qboolean textureFilterAnisotropic;
|
|||
extern int maxAnisotropy;
|
||||
extern float displayAspect;
|
||||
|
||||
// used by shader functions, including noise in renderercommon
|
||||
#define FOG_TABLE_SIZE 256
|
||||
#define FUNCTABLE_SIZE 1024
|
||||
#define FUNCTABLE_SIZE2 10
|
||||
#define FUNCTABLE_MASK (FUNCTABLE_SIZE-1)
|
||||
|
||||
//
|
||||
// cvars
|
||||
//
|
||||
|
@ -118,6 +124,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 +134,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
|
||||
|
|
|
@ -22,7 +22,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
// tr_noise.c
|
||||
#include "tr_common.h"
|
||||
|
||||
#define NOISE_SIZE 256
|
||||
#define NOISE_SIZE FUNCTABLE_SIZE
|
||||
#define NOISE_MASK ( NOISE_SIZE - 1 )
|
||||
|
||||
#define VAL( a ) s_noise_perm[ ( a ) & ( NOISE_MASK )]
|
||||
|
@ -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
|
||||
|
|
|
@ -24,7 +24,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
#define __TR_TYPES_H
|
||||
|
||||
|
||||
#define MAX_DLIGHTS 32 // can't be increased, because bit flags are used on surfaces
|
||||
#define MAX_DLIGHTS 32 // can't be increased, because bit flags are used on surfaces
|
||||
|
||||
#define REFENTITYNUM_BITS 10 // can't be increased without changing drawsurf bit packing
|
||||
#define REFENTITYNUM_MASK ((1<<REFENTITYNUM_BITS) - 1)
|
||||
|
@ -39,25 +39,34 @@ 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
|
||||
|
||||
#define RF_CROSSHAIR 0x0010 // This item is a cross hair and will draw over everything similar to
|
||||
#ifdef ELITEFORCE
|
||||
#define RF_FULLBRIGHT 0x0010
|
||||
#define RF_CROSSHAIR 0x0020 // 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.
|
||||
#else
|
||||
#define RF_CROSSHAIR 0x0010
|
||||
#endif
|
||||
|
||||
#define RF_NOSHADOW 0x0040 // don't add stencil shadows
|
||||
|
||||
#define RF_LIGHTING_ORIGIN 0x0080 // use refEntity->lightingOrigin instead of refEntity->origin
|
||||
// for lighting. This allows entities to sink into the floor
|
||||
// with their origin going solid, and allows all parts of a
|
||||
// player to get the same lighting
|
||||
// for lighting. This allows entities to sink into the floor
|
||||
// with their origin going solid, and allows all parts of a
|
||||
// player to get the same lighting
|
||||
|
||||
#define RF_SHADOW_PLANE 0x0100 // use refEntity->shadowPlane
|
||||
#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
|
||||
#define RDF_NOWORLDMODEL 1 // used for player configuration screen
|
||||
#define RDF_HYPERSPACE 4 // teleportation effect
|
||||
|
||||
typedef struct {
|
||||
vec3_t xyz;
|
||||
|
@ -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;
|
||||
|
|
|
@ -294,6 +294,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;
|
||||
|
||||
|
@ -810,11 +811,6 @@ typedef struct {
|
|||
int c_dlightSurfacesCulled;
|
||||
} frontEndCounters_t;
|
||||
|
||||
#define FOG_TABLE_SIZE 256
|
||||
#define FUNCTABLE_SIZE 1024
|
||||
#define FUNCTABLE_SIZE2 10
|
||||
#define FUNCTABLE_MASK (FUNCTABLE_SIZE-1)
|
||||
|
||||
|
||||
// the renderer front end should never modify glstate_t
|
||||
typedef struct {
|
||||
|
@ -948,6 +944,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;
|
||||
|
||||
|
@ -988,6 +985,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,18 +1006,25 @@ 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;
|
||||
}
|
||||
|
||||
#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;
|
||||
}
|
||||
}
|
||||
|
@ -1215,6 +1222,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;
|
||||
|
@ -2820,6 +2830,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
|
||||
*
|
||||
|
@ -1141,7 +1719,6 @@ static void RB_SurfaceGrid( srfGridMesh_t *cv ) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
|
@ -1186,6 +1763,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;
|
||||
|
@ -1201,6 +1781,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] );
|
||||
}
|
||||
|
|
|
@ -667,7 +667,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 );
|
||||
|
@ -676,8 +680,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);
|
||||
|
@ -723,7 +731,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;
|
||||
|
|
|
@ -320,11 +320,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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -681,7 +689,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
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -786,9 +798,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 );
|
||||
|
@ -866,6 +880,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 {
|
||||
|
|
|
@ -58,7 +58,14 @@ char *Sys_DefaultHomePath(void)
|
|||
if( ( p = getenv( "HOME" ) ) != NULL )
|
||||
{
|
||||
Com_sprintf(homePath, sizeof(homePath), "%s%c", p, PATH_SEP);
|
||||
#ifdef MACOS_X
|
||||
#ifdef ELITEFORCE
|
||||
#ifdef MACOS_X
|
||||
Q_strcat(homePath, sizeof(homePath), "/Library/Application Support/STVEF");
|
||||
#else
|
||||
Q_strcat(homePath, sizeof(homePath), "/.stvef");
|
||||
#endif
|
||||
#else
|
||||
#ifdef MACOS_X
|
||||
Q_strcat(homePath, sizeof(homePath),
|
||||
"Library/Application Support/");
|
||||
|
||||
|
@ -66,11 +73,12 @@ char *Sys_DefaultHomePath(void)
|
|||
Q_strcat(homePath, sizeof(homePath), com_homepath->string);
|
||||
else
|
||||
Q_strcat(homePath, sizeof(homePath), HOMEPATH_NAME_MACOSX);
|
||||
#else
|
||||
#else
|
||||
if(com_homepath->string[0])
|
||||
Q_strcat(homePath, sizeof(homePath), com_homepath->string);
|
||||
else
|
||||
Q_strcat(homePath, sizeof(homePath), HOMEPATH_NAME_UNIX);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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