diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 000000000..1e13814a0 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,49 @@ +name: Build +on: [push, pull_request] + +jobs: + linux: + name: Linux + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v4 + - name: Install Dependencies + run: | + sudo apt-get update + sudo apt-get install libsdl2-dev + - name: Compile + run: make release + env: + ARCHIVE: 1 + - uses: actions/upload-artifact@v4 + with: + name: Linux + path: build/*.zip + windows: + name: Windows + runs-on: windows-2019 + steps: + - uses: actions/checkout@v4 + - name: Compile + run: | + choco install zip + make release + env: + ARCHIVE: 1 + - uses: actions/upload-artifact@v4 + with: + name: Windows + path: build/*.zip + macos: + name: macOS + runs-on: macos-12 + steps: + - uses: actions/checkout@v4 + - name: Compile + run: make release + env: + ARCHIVE: 1 + - uses: actions/upload-artifact@v4 + with: + name: macOS + path: build/*.zip diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 597519cb0..000000000 --- a/.travis.yml +++ /dev/null @@ -1,34 +0,0 @@ -language: c - -env: - global: - # coverity token - - secure: "THWKfpOxFbQxX8Oyg8qkNaPACdOqx4KljQYytfoSzEpGuWgDLzP5YUTq0jiZLm5BRCY3Vj+GbmYGUectpEJQ7UyccfxUipmuAMEpW1zcwzl5Pdspyz2O1rJVh5pb/qRss7VSmyieh8OJYyl5W//HGxsDU29rDPRP4oW6k2k3Zvs=" - matrix: - # standard builds - - CC=gcc - - CC=clang - # cross-compile using mingw - - CC= PLATFORM="mingw32" ARCH="x86" - - CC= PLATFORM="mingw32" ARCH="x86_64" - -script: ./travis-ci-build.sh - -sudo: false - -addons: - apt: - packages: - - binutils-mingw-w64-i686 - - gcc-mingw-w64-i686 - - binutils-mingw-w64-x86-64 - - gcc-mingw-w64-x86-64 - - gcc-mingw-w64 - - mingw-w64 - coverity_scan: - project: - name: "zturtleman/mint-arena" - notification_email: zturtleman@gmail.com - build_command_prepend: "make clean" - build_command: "make release" - branch_pattern: coverity_scan diff --git a/Makefile b/Makefile index a09aa66c9..f6bfb7f46 100644 --- a/Makefile +++ b/Makefile @@ -20,12 +20,18 @@ endif ifndef BUILD_BASEGAME BUILD_BASEGAME = endif +ifndef USE_BASEGAME_MP_HUD + USE_BASEGAME_MP_HUD = +endif ifndef BUILD_MISSIONPACK BUILD_MISSIONPACK= endif ifndef USE_MISSIONPACK_Q3_UI USE_MISSIONPACK_Q3_UI = endif +ifndef USE_MISSIONPACK_MP_HUD + USE_MISSIONPACK_MP_HUD = 1 +endif ifndef BUILD_FINAL BUILD_FINAL =0 endif @@ -115,6 +121,10 @@ endif ifndef BASEGAME_CFLAGS BASEGAME_CFLAGS= + +ifeq ($(USE_BASEGAME_MP_HUD), 1) +BASEGAME_CFLAGS+=-DMISSIONPACK_HUD +endif endif BASEGAME_CFLAGS+=-DMODDIR=\"$(BASEGAME)\" -DBASETA=\"$(MISSIONPACK)\" @@ -124,10 +134,10 @@ MISSIONPACK=missionpack endif ifndef MISSIONPACK_CFLAGS -ifeq ($(USE_MISSIONPACK_Q3_UI), 1) MISSIONPACK_CFLAGS=-DMISSIONPACK -else -MISSIONPACK_CFLAGS=-DMISSIONPACK -DMISSIONPACK_HUD + +ifeq ($(USE_MISSIONPACK_MP_HUD), 1) +MISSIONPACK_CFLAGS+=-DMISSIONPACK_HUD endif endif @@ -423,7 +433,19 @@ ifdef MINGW ifeq ($(COMPILE_PLATFORM),cygwin) TOOLS_BINEXT=.exe - TOOLS_CC=$(CC) + + # Under cygwin the default of using gcc for TOOLS_CC won't work, so + # we need to figure out the appropriate compiler to use, based on the + # host architecture that we're running under (as tools run on the host) + ifeq ($(COMPILE_ARCH),x86_64) + TOOLS_MINGW_PREFIXES=x86_64-w64-mingw32 amd64-mingw32msvc + endif + ifeq ($(COMPILE_ARCH),x86) + TOOLS_MINGW_PREFIXES=i686-w64-mingw32 i586-mingw32msvc i686-pc-mingw32 + endif + + TOOLS_CC=$(firstword $(strip $(foreach TOOLS_MINGW_PREFIX, $(TOOLS_MINGW_PREFIXES), \ + $(call bin_path, $(TOOLS_MINGW_PREFIX)-gcc)))) endif LIBS= -lws2_32 -lwinmm -lpsapi @@ -442,6 +464,8 @@ else # ifdef MINGW ############################################################################# ifeq ($(PLATFORM),freebsd) + # Use the default C compiler + TOOLS_CC=cc # flags BASE_CFLAGS = \ @@ -648,7 +672,6 @@ endif ifneq ($(HAVE_VM_COMPILED),true) BASE_CFLAGS += -DNO_VM_COMPILED - BUILD_GAME_QVM=0 endif TARGETS = @@ -823,6 +846,9 @@ endif @echo " CFLAGS:" $(call print_wrapped, $(CFLAGS) $(OPTIMIZE)) @echo "" + @echo " TOOLS_CFLAGS:" + $(call print_wrapped, $(TOOLS_CFLAGS)) + @echo "" @echo " LDFLAGS:" $(call print_wrapped, $(LDFLAGS)) @echo "" @@ -849,6 +875,7 @@ makedirs: @$(MKDIR) $(B)/$(BASEGAME)/botlib @$(MKDIR) $(B)/$(BASEGAME)/game @$(MKDIR) $(B)/$(BASEGAME)/ui + @$(MKDIR) $(B)/$(BASEGAME)/mpui @$(MKDIR) $(B)/$(BASEGAME)/qcommon @$(MKDIR) $(B)/$(BASEGAME)/vm @$(MKDIR) $(B)/$(MISSIONPACK)/cgame @@ -1134,6 +1161,11 @@ Q3CGOBJ = \ $(B)/$(BASEGAME)/qcommon/q_shared.o \ $(B)/$(BASEGAME)/qcommon/q_unicode.o +ifeq ($(USE_BASEGAME_MP_HUD), 1) +Q3CGOBJ += \ + $(B)/$(BASEGAME)/mpui/ui_shared.o +endif + Q3CGVMOBJ = $(Q3CGOBJ:%.o=%.asm) $(B)/$(BASEGAME)/$(VM_PREFIX)cgame_$(SHLIBNAME): $(Q3CGOBJ) @@ -1232,6 +1264,11 @@ MPCGOBJ += \ $(B)/$(MISSIONPACK)/q3ui/ui_team.o \ $(B)/$(MISSIONPACK)/q3ui/ui_teamorders.o \ $(B)/$(MISSIONPACK)/q3ui/ui_video.o + +ifeq ($(USE_MISSIONPACK_MP_HUD), 1) +MPCGOBJ += \ + $(B)/$(MISSIONPACK)/ui/ui_shared.o +endif else MPCGOBJ += \ $(B)/$(MISSIONPACK)/ui/ui_main.o \ @@ -1442,6 +1479,9 @@ $(B)/$(BASEGAME)/cgame/%.o: $(CGDIR)/%.c $(B)/$(BASEGAME)/ui/%.o: $(Q3UIDIR)/%.c $(DO_CGAME_CC) +$(B)/$(BASEGAME)/mpui/%.o: $(UIDIR)/%.c + $(DO_CGAME_CC) + $(B)/$(BASEGAME)/cgame/bg_%.asm: $(GDIR)/bg_%.c $(Q3LCC) $(DO_CGAME_Q3LCC) @@ -1451,6 +1491,9 @@ $(B)/$(BASEGAME)/cgame/%.asm: $(CGDIR)/%.c $(Q3LCC) $(B)/$(BASEGAME)/ui/%.asm: $(Q3UIDIR)/%.c $(Q3LCC) $(DO_CGAME_Q3LCC) +$(B)/$(BASEGAME)/mpui/%.asm: $(UIDIR)/%.c $(Q3LCC) + $(DO_CGAME_Q3LCC) + $(B)/$(MISSIONPACK)/cgame/bg_%.o: $(GDIR)/bg_%.c $(DO_CGAME_CC_MISSIONPACK) diff --git a/README.md b/README.md index 21ad5b3f8..1a608c2e5 100644 --- a/README.md +++ b/README.md @@ -14,3 +14,8 @@ If you put both projects in the same directory you can launch the game using; On Linux and OS X you'll need to put `./` before the command and substitute the correct platform and architecture (look in the build directory). +## License + +mint-arena is licensed under a [modified version of the GNU GPLv3](COPYING.txt#L625) (or at your option, any later version). This is due to including code from Return to Castle Wolfenstein and Wolfenstein: Enemy Territory. + +Submitted contributions must be given with permission to use as GPLv**2** (two) and any later version; unless the file is under a license besides the GPL, in which case that license applies. This allows me to potentially change the license to GPLv2 or later in the future. diff --git a/code/botlib/be_aas.h b/code/botlib/be_aas.h index cd0829bf9..e22978c01 100644 --- a/code/botlib/be_aas.h +++ b/code/botlib/be_aas.h @@ -174,5 +174,5 @@ typedef struct aas_predictroute_s int endcontents; //contents at the end of movement prediction int endtravelflags; //end travel flags int numareas; //number of areas predicted ahead - int time; //time predicted ahead (in hundreth of a sec) + int time; //time predicted ahead (in hundredths of a sec) } aas_predictroute_t; diff --git a/code/botlib/be_aas_file.c b/code/botlib/be_aas_file.c index 58d306966..56e02f0dd 100644 --- a/code/botlib/be_aas_file.c +++ b/code/botlib/be_aas_file.c @@ -281,7 +281,7 @@ void AAS_FileInfo(void) aasworld.reachabilitysize * sizeof(aas_reachability_t) + aasworld.numportals * sizeof(aas_portal_t) + aasworld.numclusters * sizeof(aas_cluster_t); - botimport.Print(PRT_MESSAGE, "optimzed size %d KB\n", optimized >> 10); + botimport.Print(PRT_MESSAGE, "optimized size %d KB\n", optimized >> 10); } //end of the function AAS_FileInfo #endif //AASFILEDEBUG //=========================================================================== diff --git a/code/cgame/cg_consolecmds.c b/code/cgame/cg_consolecmds.c index 7f0408975..976a44051 100644 --- a/code/cgame/cg_consolecmds.c +++ b/code/cgame/cg_consolecmds.c @@ -33,7 +33,7 @@ Suite 120, Rockville, Maryland 20850 USA. #include "cg_local.h" #include "../ui/ui_public.h" -#ifdef MISSIONPACK +#if defined MISSIONPACK || defined MISSIONPACK_HUD #include "../ui/ui_shared.h" #endif #ifdef MISSIONPACK_HUD @@ -754,7 +754,9 @@ static void CG_VoiceTellAttacker_f( int localPlayerNum ) { Com_sprintf( command, sizeof( command ), "%s %i %s", Com_LocalPlayerCvarName( localPlayerNum, "vtell" ), playerNum, message ); trap_SendClientCommand( command ); } +#endif +#ifdef MISSIONPACK_HUD static void CG_NextTeamMember_f( int localPlayerNum ) { CG_SelectNextPlayer( localPlayerNum ); } @@ -762,14 +764,19 @@ static void CG_NextTeamMember_f( int localPlayerNum ) { static void CG_PrevTeamMember_f( int localPlayerNum ) { CG_SelectPrevPlayer( localPlayerNum ); } +#endif + +#ifdef MISSIONPACK // ASS U ME's enumeration order as far as task specific orders, OFFENSE is zero, CAMP is last // static void CG_NextOrder_f( int localPlayerNum ) { localPlayer_t *player; +#ifdef MISSIONPACK_HUD playerInfo_t *pi; int playerNum; int team; +#endif player = &cg.localPlayers[ localPlayerNum ]; @@ -777,6 +784,7 @@ static void CG_NextOrder_f( int localPlayerNum ) { return; } +#ifdef MISSIONPACK_HUD playerNum = cg.snap->pss[ localPlayerNum ].playerNum; team = cg.snap->pss[ localPlayerNum ].persistant[PERS_TEAM]; @@ -787,6 +795,7 @@ static void CG_NextOrder_f( int localPlayerNum ) { return; } } +#endif if (player->currentOrder < TEAMTASK_CAMP) { player->currentOrder++; @@ -1574,9 +1583,9 @@ static consoleCommand_t cg_commands[] = { #ifdef MISSIONPACK { "spWin", CG_spWin_f, CMD_INGAME }, { "spLose", CG_spLose_f, CMD_INGAME }, +#endif #ifdef MISSIONPACK_HUD { "loadhud", CG_LoadHud_f, CMD_INGAME }, -#endif #endif { "startOrbit", CG_StartOrbit_f, CMD_INGAME }, //{ "camera", CG_Camera_f, CMD_INGAME }, @@ -1684,8 +1693,12 @@ static playerConsoleCommand_t playerCommands[] = { #ifdef MISSIONPACK { "vtell_target", CG_VoiceTellTarget_f, CMD_INGAME, CG_VoiceSayComplete }, { "vtell_attacker", CG_VoiceTellAttacker_f, CMD_INGAME, CG_VoiceSayComplete }, +#endif +#ifdef MISSIONPACK_HUD { "nextTeamMember", CG_NextTeamMember_f, CMD_INGAME }, { "prevTeamMember", CG_PrevTeamMember_f, CMD_INGAME }, +#endif +#ifdef MISSIONPACK { "nextOrder", CG_NextOrder_f, CMD_INGAME }, { "confirmOrder", CG_ConfirmOrder_f, CMD_INGAME }, { "denyOrder", CG_DenyOrder_f, CMD_INGAME }, diff --git a/code/cgame/cg_draw.c b/code/cgame/cg_draw.c index 740444cc0..11e2c8d3c 100644 --- a/code/cgame/cg_draw.c +++ b/code/cgame/cg_draw.c @@ -2777,6 +2777,7 @@ CG_DrawTimedMenus ================= */ void CG_DrawTimedMenus( qboolean *voiceMenuOpen ) { +#ifdef MISSIONPACK if ( cg.cur_lc->voiceTime && cg.cur_lc->voiceTime >= cg.time && cg.cur_lc->playerNum != cg.cur_lc->currentVoicePlayerNum ) { Menus_OpenByName("voiceMenu"); *voiceMenuOpen = qtrue; @@ -2784,6 +2785,7 @@ void CG_DrawTimedMenus( qboolean *voiceMenuOpen ) { Menus_CloseByName("voiceMenu"); *voiceMenuOpen = qfalse; } +#endif } #endif /* diff --git a/code/cgame/cg_local.h b/code/cgame/cg_local.h index 930563235..2f1e0cdff 100644 --- a/code/cgame/cg_local.h +++ b/code/cgame/cg_local.h @@ -813,7 +813,7 @@ typedef struct { int teamScores[2]; score_t scores[MAX_CLIENTS]; clientList_t readyPlayers; -#ifdef MISSIONPACK +#ifdef MISSIONPACK_HUD char spectatorList[MAX_STRING_CHARS]; // list of names int spectatorTime; // last time offset float spectatorOffset; // current offset from start @@ -1026,7 +1026,6 @@ typedef struct { qhandle_t invulnerabilityJuicedModel; qhandle_t medkitUsageModel; qhandle_t dustPuffShader; - qhandle_t heartShader; qhandle_t invulnerabilityPowerupModel; #endif @@ -1186,17 +1185,22 @@ typedef struct { qhandle_t teamLeaderShader; qhandle_t retrieveShader; qhandle_t escortShader; - qhandle_t flagShaders[3]; sfxHandle_t countPrepareTeamSound; sfxHandle_t ammoregenSound; sfxHandle_t doublerSound; sfxHandle_t guardSound; sfxHandle_t scoutSound; +#endif +#ifdef MISSIONPACK_HUD qhandle_t cursor; qhandle_t selectCursor; qhandle_t sizeCursor; + qhandle_t heartShader; +#endif +#if defined MISSIONPACK || defined MISSIONPACK_HUD + qhandle_t flagShaders[3]; #endif sfxHandle_t regenSound; @@ -1324,6 +1328,7 @@ extern vmCvar_t cg_dedicated; extern vmCvar_t cg_centertime; extern vmCvar_t cg_viewbob; +extern vmCvar_t cg_viewkick; extern vmCvar_t cg_runpitch; extern vmCvar_t cg_runroll; extern vmCvar_t cg_bobup; @@ -1488,7 +1493,7 @@ extern vmCvar_t cg_thirdPersonAngle[MAX_SPLITVIEW]; extern vmCvar_t cg_thirdPersonHeight[MAX_SPLITVIEW]; extern vmCvar_t cg_thirdPersonSmooth[MAX_SPLITVIEW]; -#ifdef MISSIONPACK +#ifdef MISSIONPACK_HUD extern vmCvar_t cg_currentSelectedPlayer[MAX_SPLITVIEW]; extern vmCvar_t cg_currentSelectedPlayerName[MAX_SPLITVIEW]; #endif @@ -1530,7 +1535,9 @@ void CG_JoystickHatEvent( int localPlayerNum, int hat, int value, unsigned time, void CG_EventHandling(int type); void CG_RankRunFrame( void ); score_t *CG_GetSelectedScore( void ); +#ifdef MISSIONPACK_HUD void CG_BuildSpectatorString( void ); +#endif void CG_RemoveNotifyLine( localPlayer_t *player ); void CG_AddNotifyText( int realTime, qboolean restoredText ); @@ -1673,11 +1680,15 @@ void CG_GetTeamColor(vec4_t *color); const char *CG_GetGameStatusText( void ); const char *CG_GetKillerText( void ); void CG_Draw3DModel(float x, float y, float w, float h, qhandle_t model, cgSkin_t *skin, vec3_t origin, vec3_t angles); +#ifdef MISSIONPACK void CG_CheckOrderPending( int localPlayerNum ); +#endif const char *CG_GameTypeString( void ); qboolean CG_YourTeamHasFlag( void ); qboolean CG_OtherTeamHasFlag( void ); +#ifdef MISSIONPACK qhandle_t CG_StatusHandle(int task); +#endif qboolean CG_AnyScoreboardShowing( void ); diff --git a/code/cgame/cg_main.c b/code/cgame/cg_main.c index b8983a0eb..a1bb58354 100644 --- a/code/cgame/cg_main.c +++ b/code/cgame/cg_main.c @@ -160,6 +160,7 @@ vmCvar_t cg_dedicated; vmCvar_t cg_railTrailTime; vmCvar_t cg_centertime; vmCvar_t cg_viewbob; +vmCvar_t cg_viewkick; vmCvar_t cg_runpitch; vmCvar_t cg_runroll; vmCvar_t cg_bobup; @@ -329,7 +330,7 @@ vmCvar_t cg_thirdPersonAngle[MAX_SPLITVIEW]; vmCvar_t cg_thirdPersonHeight[MAX_SPLITVIEW]; vmCvar_t cg_thirdPersonSmooth[MAX_SPLITVIEW]; -#ifdef MISSIONPACK +#ifdef MISSIONPACK_HUD vmCvar_t cg_currentSelectedPlayer[MAX_SPLITVIEW]; vmCvar_t cg_currentSelectedPlayerName[MAX_SPLITVIEW]; #endif @@ -400,6 +401,7 @@ static cvarTable_t cgameCvarTable[] = { { &cg_gun_z, "cg_gunZ", "0", CVAR_CHEAT, RANGE_ALL }, { &cg_centertime, "cg_centertime", "3", CVAR_CHEAT, RANGE_ALL }, { &cg_viewbob, "cg_viewbob", "1", CVAR_ARCHIVE, RANGE_BOOL }, + { &cg_viewkick, "cg_viewkick", "1", CVAR_ARCHIVE, RANGE_BOOL }, { &cg_runpitch, "cg_runpitch", "0.002", CVAR_ARCHIVE, RANGE_ALL }, { &cg_runroll, "cg_runroll", "0.005", CVAR_ARCHIVE, RANGE_ALL }, { &cg_bobup , "cg_bobup", "0.005", CVAR_CHEAT, RANGE_ALL }, @@ -554,7 +556,7 @@ static userCvarTable_t userCvarTable[] = { { cg_thirdPersonHeight, "cg_thirdPersonHeight", "24", 0, RANGE_INT( 0, 32 ) }, { cg_thirdPersonSmooth, "cg_thirdPersonSmooth", "0", 0, RANGE_ALL }, // this cvar exists because it's behavior is too buggy to enable by default -#ifdef MISSIONPACK +#ifdef MISSIONPACK_HUD { cg_currentSelectedPlayer, "cg_currentSelectedPlayer", "0", CVAR_ARCHIVE, RANGE_ALL }, { cg_currentSelectedPlayerName, "cg_currentSelectedPlayerName", "", CVAR_ARCHIVE, RANGE_ALL } #endif @@ -1658,7 +1660,6 @@ static void CG_RegisterGraphics( void ) { cgs.media.invulnerabilityImpactModel = trap_R_RegisterModel( "models/powerups/shield/impact.md3" ); cgs.media.invulnerabilityJuicedModel = trap_R_RegisterModel( "models/powerups/shield/juicer.md3" ); cgs.media.medkitUsageModel = trap_R_RegisterModel( "models/powerups/regen.md3" ); - cgs.media.heartShader = trap_R_RegisterShaderNoMip( "ui/assets/statusbar/selectedhealth.tga" ); cgs.media.invulnerabilityPowerupModel = trap_R_RegisterModel( "models/powerups/shield/shield.md3" ); #endif @@ -1733,13 +1734,20 @@ static void CG_RegisterGraphics( void ) { cgs.media.teamLeaderShader = trap_R_RegisterShaderNoMip("ui/assets/statusbar/team_leader.tga"); cgs.media.retrieveShader = trap_R_RegisterShaderNoMip("ui/assets/statusbar/retrieve.tga"); cgs.media.escortShader = trap_R_RegisterShaderNoMip("ui/assets/statusbar/escort.tga"); +#endif +#ifdef MISSIONPACK_HUD cgs.media.cursor = trap_R_RegisterShaderNoMip( "menu/art/3_cursor2" ); cgs.media.sizeCursor = trap_R_RegisterShaderNoMip( "ui/assets/sizecursor.tga" ); cgs.media.selectCursor = trap_R_RegisterShaderNoMip( "ui/assets/selectcursor.tga" ); + cgs.media.heartShader = trap_R_RegisterShaderNoMip( "ui/assets/statusbar/selectedhealth.tga" ); +#endif +#if defined MISSIONPACK || defined MISSIONPACK_HUD cgs.media.flagShaders[0] = trap_R_RegisterShaderNoMip("ui/assets/statusbar/flag_in_base.tga"); cgs.media.flagShaders[1] = trap_R_RegisterShaderNoMip("ui/assets/statusbar/flag_capture.tga"); cgs.media.flagShaders[2] = trap_R_RegisterShaderNoMip("ui/assets/statusbar/flag_missing.tga"); +#endif +#ifdef MISSIONPACK if ( cgs.gametype >= GT_TEAM || cg_buildScript.integer ) { CG_CachePlayerModels( cg_defaultMaleTeamModel.string, cg_defaultMaleTeamHeadModel.string ); CG_CachePlayerModels( cg_defaultFemaleTeamModel.string, cg_defaultFemaleTeamHeadModel.string ); @@ -1790,7 +1798,7 @@ void CG_LocalPlayerRemoved(int localPlayerNum) { cg.localPlayers[localPlayerNum].playerNum = -1; } -#ifdef MISSIONPACK +#ifdef MISSIONPACK_HUD /* ======================= CG_BuildSpectatorString @@ -1845,7 +1853,7 @@ static void CG_RegisterPlayers( void ) { CG_LoadingPlayer( i ); CG_NewPlayerInfo( i ); } -#ifdef MISSIONPACK +#ifdef MISSIONPACK_HUD CG_BuildSpectatorString(); #endif } @@ -2317,11 +2325,15 @@ static const char *CG_FeederItemText(float feederID, int index, int column, qhan } break; case 1: +#ifdef MISSIONPACK if (team == -1) { return ""; } else { *handle = CG_StatusHandle(info->teamTask); } +#else + return ""; +#endif break; case 2: if ( Com_ClientListContains( &cg.readyPlayers, sp->playerNum ) ) { @@ -2408,10 +2420,18 @@ static int CG_OwnerDrawWidth(int ownerDraw, float scale) { return CG_Text_Width(CG_GetKillerText(), scale, 0); break; case CG_RED_NAME: +#ifdef MISSIONPACK return CG_Text_Width(cg_redTeamName.string, scale, 0); +#else + return CG_Text_Width("Red Team", scale, 0); +#endif break; case CG_BLUE_NAME: +#ifdef MISSIONPACK return CG_Text_Width(cg_blueTeamName.string, scale, 0); +#else + return CG_Text_Width("Blue Team", scale, 0); +#endif break; diff --git a/code/cgame/cg_newdraw.c b/code/cgame/cg_newdraw.c index 22dcdd983..9fe3f7656 100644 --- a/code/cgame/cg_newdraw.c +++ b/code/cgame/cg_newdraw.c @@ -31,7 +31,7 @@ Suite 120, Rockville, Maryland 20850 USA. #include "cg_local.h" #include "../ui/ui_shared.h" -#ifdef MISSIONPACK +#if defined MISSIONPACK || defined MISSIONPACK_HUD #ifdef MISSIONPACK_HUD extern displayContextDef_t cgDC; @@ -146,6 +146,7 @@ void CG_SetPrintString(q3print_t type, const char *p) { } } +#ifdef MISSIONPACK void CG_CheckOrderPending( int localPlayerNum ) { localPlayer_t *localPlayer; @@ -172,7 +173,11 @@ void CG_CheckOrderPending( int localPlayerNum ) { playerNum = cg.snap->pss[localPlayerNum].playerNum; team = cg.snap->pss[localPlayerNum].persistant[PERS_TEAM]; +#ifdef MISSIONPACK_HUD selectedPlayer = cg_currentSelectedPlayer[localPlayerNum].integer; +#else + selectedPlayer = playerNum; +#endif //pi = cgs.playerinfo + sortedTeamPlayers[team][selectedPlayer]; @@ -231,7 +236,9 @@ void CG_CheckOrderPending( int localPlayerNum ) { localPlayer->orderPending = qfalse; } } +#endif +#ifdef MISSIONPACK_HUD static void CG_SetSelectedPlayerName( int localPlayerNum ) { int team; @@ -264,7 +271,9 @@ void CG_SelectNextPlayer( int localPlayerNum ) { team = cg.snap->pss[ localPlayerNum ].persistant[PERS_TEAM]; +#ifdef MISSIONPACK CG_CheckOrderPending( localPlayerNum ); +#endif if (cg_currentSelectedPlayer[ localPlayerNum ].integer >= 0 && cg_currentSelectedPlayer[ localPlayerNum ].integer < numSortedTeamPlayers[team]) { cg_currentSelectedPlayer[ localPlayerNum ].integer++; } else { @@ -278,7 +287,9 @@ void CG_SelectPrevPlayer( int localPlayerNum ) { team = cg.snap->pss[ localPlayerNum ].persistant[PERS_TEAM]; +#ifdef MISSIONPACK CG_CheckOrderPending( localPlayerNum ); +#endif if (cg_currentSelectedPlayer[ localPlayerNum ].integer > 0 && cg_currentSelectedPlayer[ localPlayerNum ].integer <= numSortedTeamPlayers[team]) { cg_currentSelectedPlayer[ localPlayerNum ].integer--; } else { @@ -288,7 +299,6 @@ void CG_SelectPrevPlayer( int localPlayerNum ) { } -#ifdef MISSIONPACK_HUD static void CG_DrawPlayerArmorIcon( rectDef_t *rect, qboolean draw2D ) { vec3_t angles; vec3_t origin; @@ -477,6 +487,7 @@ static void CG_DrawSelectedPlayerArmor( rectDef_t *rect, float scale, vec4_t col } } +#ifdef MISSIONPACK qhandle_t CG_StatusHandle(int task) { qhandle_t h; switch (task) { @@ -538,6 +549,7 @@ static void CG_DrawPlayerStatus( rectDef_t *rect ) { CG_DrawPic( rect->x, rect->y, rect->w, rect->h, h); } } +#endif static void CG_DrawSelectedPlayerName( rectDef_t *rect, float scale, vec4_t color, qboolean voice, int textStyle) { @@ -545,7 +557,16 @@ static void CG_DrawSelectedPlayerName( rectDef_t *rect, float scale, vec4_t colo int team; team = cg.cur_ps->persistant[PERS_TEAM]; - pi = cgs.playerinfo + ((voice) ? cg.cur_lc->currentVoicePlayerNum : sortedTeamPlayers[team][CG_GetSelectedPlayer( cg.cur_localPlayerNum )]); + +#ifdef MISSIONPACK + if ( voice ) { + pi = cgs.playerinfo + cg.cur_lc->currentVoicePlayerNum; + } else +#endif + { + pi = cgs.playerinfo + sortedTeamPlayers[team][CG_GetSelectedPlayer( cg.cur_localPlayerNum )]; + } + if (pi) { CG_Text_Paint(rect->x, rect->y + rect->h, scale, color, pi->name, 0, 0, textStyle); } @@ -674,7 +695,14 @@ static void CG_DrawSelectedPlayerHead( rectDef_t *rect, qboolean draw2D, qboolea vec3_t mins, maxs, angles; team = cg.cur_ps->persistant[PERS_TEAM]; - pi = cgs.playerinfo + ((voice) ? cg.cur_lc->currentVoicePlayerNum : sortedTeamPlayers[team][CG_GetSelectedPlayer( cg.cur_localPlayerNum )]); +#ifdef MISSIONPACK + if ( voice ) { + pi = cgs.playerinfo + cg.cur_lc->currentVoicePlayerNum; + } else +#endif + { + pi = cgs.playerinfo + sortedTeamPlayers[team][CG_GetSelectedPlayer( cg.cur_localPlayerNum )]; + } if (pi) { if ( cg_draw3dIcons.integer ) { @@ -764,11 +792,19 @@ static void CG_DrawBlueScore(rectDef_t *rect, float scale, vec4_t color, qhandle // FIXME: team name support static void CG_DrawRedName(rectDef_t *rect, float scale, vec4_t color, int textStyle ) { +#ifdef MISSIONPACK CG_Text_Paint(rect->x, rect->y + rect->h, scale, color, cg_redTeamName.string , 0, 0, textStyle); +#else + CG_Text_Paint(rect->x, rect->y + rect->h, scale, color, "Red Team", 0, 0, textStyle); +#endif } static void CG_DrawBlueName(rectDef_t *rect, float scale, vec4_t color, int textStyle ) { +#ifdef MISSIONPACK CG_Text_Paint(rect->x, rect->y + rect->h, scale, color, cg_blueTeamName.string, 0, 0, textStyle); +#else + CG_Text_Paint(rect->x, rect->y + rect->h, scale, color, "Blue Team", 0, 0, textStyle); +#endif } static void CG_DrawBlueFlagName(rectDef_t *rect, float scale, vec4_t color, int textStyle ) { @@ -782,6 +818,7 @@ static void CG_DrawBlueFlagName(rectDef_t *rect, float scale, vec4_t color, int } static void CG_DrawBlueFlagStatus(rectDef_t *rect, qhandle_t shader) { +#ifdef MISSIONPACK if (cgs.gametype != GT_CTF && cgs.gametype != GT_1FCTF) { if (cgs.gametype == GT_HARVESTER) { vec4_t color = {0, 0, 1, 1}; @@ -791,6 +828,11 @@ static void CG_DrawBlueFlagStatus(rectDef_t *rect, qhandle_t shader) { } return; } +#else + if (cgs.gametype != GT_CTF) { + return; + } +#endif if (shader) { CG_DrawPic( rect->x, rect->y, rect->w, rect->h, shader ); } else { @@ -832,6 +874,7 @@ static void CG_DrawRedFlagName(rectDef_t *rect, float scale, vec4_t color, int t } static void CG_DrawRedFlagStatus(rectDef_t *rect, qhandle_t shader) { +#ifdef MISSIONPACK if (cgs.gametype != GT_CTF && cgs.gametype != GT_1FCTF) { if (cgs.gametype == GT_HARVESTER) { vec4_t color = {1, 0, 0, 1}; @@ -841,6 +884,11 @@ static void CG_DrawRedFlagStatus(rectDef_t *rect, qhandle_t shader) { } return; } +#else + if (cgs.gametype != GT_CTF) { + return; + } +#endif if (shader) { CG_DrawPic( rect->x, rect->y, rect->w, rect->h, shader ); } else { @@ -871,6 +919,7 @@ static void CG_DrawRedFlagHead(rectDef_t *rect) { } } +#ifdef MISSIONPACK static void CG_HarvesterSkulls(rectDef_t *rect, float scale, vec4_t color, qboolean force2D, int textStyle ) { char num[16]; vec3_t origin, angles; @@ -951,6 +1000,7 @@ static void CG_DrawCTFPowerUp(rectDef_t *rect) { CG_DrawPic( rect->x, rect->y, rect->w, rect->h, cg_items[ value ].icon ); } } +#endif @@ -1090,50 +1140,54 @@ float CG_GetValue(int ownerDraw) { #endif // MISSIONPACK_HUD qboolean CG_OtherTeamHasFlag(void) { - if (cgs.gametype == GT_CTF || cgs.gametype == GT_1FCTF) { + if (cgs.gametype == GT_CTF) { int team = cg.cur_ps->persistant[PERS_TEAM]; - if (cgs.gametype == GT_1FCTF) { - if (team == TEAM_RED && cgs.flagStatus == FLAG_TAKEN_BLUE) { - return qtrue; - } else if (team == TEAM_BLUE && cgs.flagStatus == FLAG_TAKEN_RED) { - return qtrue; - } else { - return qfalse; - } + if (team == TEAM_RED && cgs.redflag == FLAG_TAKEN) { + return qtrue; + } else if (team == TEAM_BLUE && cgs.blueflag == FLAG_TAKEN) { + return qtrue; } else { - if (team == TEAM_RED && cgs.redflag == FLAG_TAKEN) { - return qtrue; - } else if (team == TEAM_BLUE && cgs.blueflag == FLAG_TAKEN) { - return qtrue; - } else { - return qfalse; - } + return qfalse; } } +#ifdef MISSIONPACK + if (cgs.gametype == GT_1FCTF) { + int team = cg.cur_ps->persistant[PERS_TEAM]; + if (team == TEAM_RED && cgs.flagStatus == FLAG_TAKEN_BLUE) { + return qtrue; + } else if (team == TEAM_BLUE && cgs.flagStatus == FLAG_TAKEN_RED) { + return qtrue; + } else { + return qfalse; + } + } +#endif return qfalse; } qboolean CG_YourTeamHasFlag(void) { - if (cgs.gametype == GT_CTF || cgs.gametype == GT_1FCTF) { + if (cgs.gametype == GT_CTF) { int team = cg.cur_ps->persistant[PERS_TEAM]; - if (cgs.gametype == GT_1FCTF) { - if (team == TEAM_RED && cgs.flagStatus == FLAG_TAKEN_RED) { - return qtrue; - } else if (team == TEAM_BLUE && cgs.flagStatus == FLAG_TAKEN_BLUE) { - return qtrue; - } else { - return qfalse; - } + if (team == TEAM_RED && cgs.blueflag == FLAG_TAKEN) { + return qtrue; + } else if (team == TEAM_BLUE && cgs.redflag == FLAG_TAKEN) { + return qtrue; } else { - if (team == TEAM_RED && cgs.blueflag == FLAG_TAKEN) { - return qtrue; - } else if (team == TEAM_BLUE && cgs.redflag == FLAG_TAKEN) { - return qtrue; - } else { - return qfalse; - } + return qfalse; } } +#ifdef MISSIONPACK + if (cgs.gametype == GT_1FCTF) { + int team = cg.cur_ps->persistant[PERS_TEAM]; + if (team == TEAM_RED && cgs.flagStatus == FLAG_TAKEN_RED) { + return qtrue; + } else if (team == TEAM_BLUE && cgs.flagStatus == FLAG_TAKEN_BLUE) { + return qtrue; + } else { + return qfalse; + } + } +#endif return qfalse; } @@ -1180,19 +1234,25 @@ qboolean CG_OwnerDrawVisible(int flags) { } if (flags & CG_SHOW_HARVESTER) { +#ifdef MISSIONPACK if( cgs.gametype == GT_HARVESTER ) { return qtrue; - } else { - return qfalse; - } + } else +#endif + { + return qfalse; + } } if (flags & CG_SHOW_ONEFLAG) { +#ifdef MISSIONPACK if( cgs.gametype == GT_1FCTF ) { return qtrue; - } else { - return qfalse; - } + } else +#endif + { + return qfalse; + } } if (flags & CG_SHOW_CTF) { @@ -1202,11 +1262,14 @@ qboolean CG_OwnerDrawVisible(int flags) { } if (flags & CG_SHOW_OBELISK) { +#ifdef MISSIONPACK if( cgs.gametype == GT_OBELISK ) { return qtrue; - } else { - return qfalse; - } + } else +#endif + { + return qfalse; + } } if (flags & CG_SHOW_HEALTHCRITICAL) { @@ -1237,9 +1300,14 @@ qboolean CG_OwnerDrawVisible(int flags) { } if (flags & CG_SHOW_IF_PLAYER_HAS_FLAG) { - if (cg.cur_ps->powerups[PW_REDFLAG] || cg.cur_ps->powerups[PW_BLUEFLAG] || cg.cur_ps->powerups[PW_NEUTRALFLAG]) { + if (cg.cur_ps->powerups[PW_REDFLAG] || cg.cur_ps->powerups[PW_BLUEFLAG]) { return qtrue; } +#ifdef MISSIONPACK + if (cg.cur_ps->powerups[PW_NEUTRALFLAG]) { + return qtrue; + } +#endif } return qfalse; } @@ -1347,7 +1415,9 @@ void CG_DrawNewTeamInfo(rectDef_t *rect, float text_x, float text_y, float scale float pwidth, lwidth, maxx, leftOver; playerInfo_t *pi; gitem_t *item; +#ifdef MISSIONPACK qhandle_t h; +#endif int team; team = cg.cur_ps->persistant[PERS_TEAM]; @@ -1422,6 +1492,7 @@ void CG_DrawNewTeamInfo(rectDef_t *rect, float text_x, float text_y, float scale #endif trap_R_SetColor(NULL); +#ifdef MISSIONPACK if (cg.cur_lc->orderPending) { // blink the icon if ( cg.time > cg.cur_lc->orderTime - 2500 && (cg.time >> 9 ) & 1 ) { @@ -1436,6 +1507,7 @@ void CG_DrawNewTeamInfo(rectDef_t *rect, float text_x, float text_y, float scale if (h) { CG_DrawPic( xx, y, PIC_WIDTH, PIC_WIDTH, h); } +#endif xx += PIC_WIDTH + 1; @@ -1599,6 +1671,7 @@ void CG_OwnerDraw(float x, float y, float w, float h, float text_x, float text_y case CG_SELECTEDPLAYER_HEAD: CG_DrawSelectedPlayerHead(&rect, ownerDrawFlags & CG_SHOW_2DONLY, qfalse); break; +#ifdef MISSIONPACK case CG_VOICE_HEAD: CG_DrawSelectedPlayerHead(&rect, ownerDrawFlags & CG_SHOW_2DONLY, qtrue); break; @@ -1608,6 +1681,7 @@ void CG_OwnerDraw(float x, float y, float w, float h, float text_x, float text_y case CG_SELECTEDPLAYER_STATUS: CG_DrawSelectedPlayerStatus(&rect); break; +#endif case CG_SELECTEDPLAYER_ARMOR: CG_DrawSelectedPlayerArmor(&rect, scale, color, shader, textStyle); break; @@ -1668,6 +1742,7 @@ void CG_OwnerDraw(float x, float y, float w, float h, float text_x, float text_y case CG_RED_FLAGNAME: CG_DrawRedFlagName(&rect, scale, color, textStyle); break; +#ifdef MISSIONPACK case CG_HARVESTER_SKULLS: CG_HarvesterSkulls(&rect, scale, color, qfalse, textStyle); break; @@ -1677,21 +1752,26 @@ void CG_OwnerDraw(float x, float y, float w, float h, float text_x, float text_y case CG_ONEFLAG_STATUS: CG_OneFlagStatus(&rect); break; +#endif case CG_PLAYER_LOCATION: CG_DrawPlayerLocation(&rect, scale, color, textStyle); break; case CG_TEAM_COLOR: CG_DrawTeamColor(&rect, color); break; +#ifdef MISSIONPACK case CG_CTF_POWERUP: CG_DrawCTFPowerUp(&rect); break; +#endif case CG_AREA_POWERUP: CG_DrawAreaPowerUp(&rect, align, special, scale, color); break; +#ifdef MISSIONPACK case CG_PLAYER_STATUS: CG_DrawPlayerStatus(&rect); break; +#endif case CG_PLAYER_HASFLAG: CG_DrawPlayerHasFlag(&rect, qfalse); break; diff --git a/code/cgame/cg_servercmds.c b/code/cgame/cg_servercmds.c index 8aa1f4ddf..a03ef8457 100644 --- a/code/cgame/cg_servercmds.c +++ b/code/cgame/cg_servercmds.c @@ -383,7 +383,7 @@ static void CG_ConfigStringModified( void ) { } } else if ( num >= CS_PLAYERS && num < CS_PLAYERS+MAX_CLIENTS ) { CG_NewPlayerInfo( num - CS_PLAYERS ); -#ifdef MISSIONPACK +#ifdef MISSIONPACK_HUD CG_BuildSpectatorString(); #endif } else if ( num >= CS_DLIGHTS && num < CS_DLIGHTS + MAX_DLIGHT_CONFIGSTRINGS ) { diff --git a/code/cgame/cg_view.c b/code/cgame/cg_view.c index 5cfec5b06..c5df8d539 100644 --- a/code/cgame/cg_view.c +++ b/code/cgame/cg_view.c @@ -455,7 +455,7 @@ static void CG_OffsetFirstPersonView( void ) { } // add angles based on damage kick - if ( cg.cur_lc->damageTime ) { + if ( cg.cur_lc->damageTime && !cg.cur_lc->renderingThirdPerson && cg_viewkick.integer ) { ratio = cg.time - cg.cur_lc->damageTime; if ( ratio < DAMAGE_DEFLECT_TIME ) { ratio /= DAMAGE_DEFLECT_TIME; diff --git a/code/client/keycodes.h b/code/client/keycodes.h index 81089e67c..79e5ffd56 100644 --- a/code/client/keycodes.h +++ b/code/client/keycodes.h @@ -554,6 +554,51 @@ typedef enum { // Pseudo-key that brings the console down K_CONSOLE, + K_FIRST_JOY_PART2, + + K_JOY_MISC1 = K_FIRST_JOY_PART2, + K_JOY_PADDLE1, + K_JOY_PADDLE2, + K_JOY_PADDLE3, + K_JOY_PADDLE4, + K_JOY_TOUCHPAD, + + // + 16 to reserve space for more keys to avoid needing another section to prevent mod API break. + K_LAST_JOY_PART2 = K_FIRST_JOY_PART2 + 16, + + K_FIRST_2JOY_PART2, + + K_2JOY_MISC1 = K_FIRST_2JOY_PART2, + K_2JOY_PADDLE1, + K_2JOY_PADDLE2, + K_2JOY_PADDLE3, + K_2JOY_PADDLE4, + K_2JOY_TOUCHPAD, + + K_LAST_2JOY_PART2 = K_FIRST_2JOY_PART2 + 16, + + K_FIRST_3JOY_PART2, + + K_3JOY_MISC1 = K_FIRST_3JOY_PART2, + K_3JOY_PADDLE1, + K_3JOY_PADDLE2, + K_3JOY_PADDLE3, + K_3JOY_PADDLE4, + K_3JOY_TOUCHPAD, + + K_LAST_3JOY_PART2 = K_FIRST_3JOY_PART2 + 16, + + K_FIRST_4JOY_PART2, + + K_4JOY_MISC1 = K_FIRST_4JOY_PART2, + K_4JOY_PADDLE1, + K_4JOY_PADDLE2, + K_4JOY_PADDLE3, + K_4JOY_PADDLE4, + K_4JOY_TOUCHPAD, + + K_LAST_4JOY_PART2 = K_FIRST_4JOY_PART2 + 16, + MAX_KEYS } keyNum_t; diff --git a/code/game/ai_dmq3.c b/code/game/ai_dmq3.c index ec7ac5701..4aeb5739c 100644 --- a/code/game/ai_dmq3.c +++ b/code/game/ai_dmq3.c @@ -3911,7 +3911,7 @@ void BotMapScripts(bot_state_t *bs) { shootbutton = qfalse; break; } - else if (bs->enemy == i) { + else if (gametype < GT_CTF || bs->enemy == i) { shootbutton = qtrue; } } diff --git a/code/game/bg_public.h b/code/game/bg_public.h index 9078ac48d..fd14210ff 100644 --- a/code/game/bg_public.h +++ b/code/game/bg_public.h @@ -1238,7 +1238,7 @@ typedef struct int (*pointcontents)( const vec3_t point, int passEntityNum ); } bgGenTracemap_t; -void BG_GenerateTracemap(const char *mapname, vec3_t mapcoordsMins, vec3_t mapcoordsMaxs, bgGenTracemap_t *gen); +void BG_GenerateTracemap(const char *mapname, vec2_t mapcoordsMins, vec2_t mapcoordsMaxs, bgGenTracemap_t *gen); qboolean BG_LoadTraceMap( char *rawmapname, vec2_t world_mins, vec2_t world_maxs ); float BG_GetSkyHeightAtPoint( vec3_t pos ); diff --git a/code/game/bg_tracemap.c b/code/game/bg_tracemap.c index 8b0e754bb..303d492c9 100644 --- a/code/game/bg_tracemap.c +++ b/code/game/bg_tracemap.c @@ -62,7 +62,7 @@ static vec2_t one_over_mapgrid_factor; void etpro_FinalizeTracemapClamp( int *x, int *y ); // Currently only used by CGAME -void BG_GenerateTracemap(const char *mapname, vec3_t mapcoordsMins, vec3_t mapcoordsMaxs, bgGenTracemap_t *gen) { +void BG_GenerateTracemap(const char *mapname, vec2_t mapcoordsMins, vec2_t mapcoordsMaxs, bgGenTracemap_t *gen) { trace_t tr; vec3_t start, end; int i, j; diff --git a/code/game/g_utils.c b/code/game/g_utils.c index be2a7fb35..d6680c563 100644 --- a/code/game/g_utils.c +++ b/code/game/g_utils.c @@ -67,7 +67,7 @@ const char *BuildShaderStateConfig(void) { char out[(MAX_QPATH * 2) + 5]; int i; - memset(buff, 0, MAX_STRING_CHARS); + memset(buff, 0, sizeof(buff)); for (i = 0; i < remapCount; i++) { Com_sprintf(out, (MAX_QPATH * 2) + 5, "%s=%s:%5.2f@", remappedShaders[i].oldShader, remappedShaders[i].newShader, remappedShaders[i].timeOffset); Q_strcat( buff, sizeof( buff ), out); diff --git a/code/q3_ui/ui_controls2.c b/code/q3_ui/ui_controls2.c index 6ef3ca511..ccda0d9ba 100644 --- a/code/q3_ui/ui_controls2.c +++ b/code/q3_ui/ui_controls2.c @@ -81,6 +81,10 @@ typedef struct { enum { // bindable actions ID_SHOWSCORES, +#ifdef MISSIONPACK_HUD + ID_SCORESUP, + ID_SCORESDOWN, +#endif ID_USEITEM, ID_SPEED, ID_FORWARD, @@ -222,6 +226,10 @@ typedef struct menuradiobutton_s smoothmouse; menuradiobutton_s alwaysrun; menuaction_s showscores; +#ifdef MISSIONPACK_HUD + menuaction_s scoresup; + menuaction_s scoresdown; +#endif menuradiobutton_s cyclepastgauntlet; menuradiobutton_s autoswitch; menuaction_s useitem; @@ -261,6 +269,10 @@ static qboolean waitingforkey = qfalse; static bind_t g_bindings[] = { {"+scores", "show scores", ID_SHOWSCORES, ANIM_IDLE, K_TAB, -1, -1, -1}, +#ifdef MISSIONPACK_HUD + {"scoresUp", "scroll scores up", ID_SCORESUP, ANIM_IDLE, K_KP_PGUP, -1, -1, -1}, + {"scoresDown", "scroll scores down",ID_SCORESDOWN, ANIM_IDLE, K_KP_PGDN, -1, -1, -1}, +#endif {"+button2", "use item", ID_USEITEM, ANIM_IDLE, K_ENTER, -1, -1, -1}, {"+speed", "run / walk", ID_SPEED, ANIM_RUN, K_LEFTSHIFT, K_RIGHTSHIFT, -1, -1}, {"+forward", "walk forward", ID_FORWARD, ANIM_WALK, K_UPARROW, -1, -1, -1}, @@ -308,6 +320,10 @@ static bind_t g_bindings[] = static bind_t g_bindings2[] = { MINIBIND(ID_SHOWSCORES, -1, -1), +#ifdef MISSIONPACK_HUD + MINIBIND(ID_SCORESUP, -1, -1), + MINIBIND(ID_SCORESDOWN, -1, -1), +#endif MINIBIND(ID_USEITEM, -1, -1), MINIBIND(ID_SPEED, -1, -1), MINIBIND(ID_FORWARD, -1, -1), @@ -352,6 +368,10 @@ static bind_t g_bindings2[] = static bind_t g_bindings3[] = { MINIBIND(ID_SHOWSCORES, -1, -1), +#ifdef MISSIONPACK_HUD + MINIBIND(ID_SCORESUP, -1, -1), + MINIBIND(ID_SCORESDOWN, -1, -1), +#endif MINIBIND(ID_USEITEM, -1, -1), MINIBIND(ID_SPEED, -1, -1), MINIBIND(ID_FORWARD, -1, -1), @@ -396,6 +416,10 @@ static bind_t g_bindings3[] = static bind_t g_bindings4[] = { MINIBIND(ID_SHOWSCORES, -1, -1), +#ifdef MISSIONPACK_HUD + MINIBIND(ID_SCORESUP, -1, -1), + MINIBIND(ID_SCORESDOWN, -1, -1), +#endif MINIBIND(ID_USEITEM, -1, -1), MINIBIND(ID_SPEED, -1, -1), MINIBIND(ID_FORWARD, -1, -1), @@ -499,6 +523,10 @@ static menucommon_s *g_looking_controls[] = { static menucommon_s *g_misc_controls[] = { (menucommon_s *)&s_controls.showscores, +#ifdef MISSIONPACK_HUD + (menucommon_s *)&s_controls.scoresup, + (menucommon_s *)&s_controls.scoresdown, +#endif (menucommon_s *)&s_controls.useitem, (menucommon_s *)&s_controls.gesture, (menucommon_s *)&s_controls.chat, @@ -535,6 +563,10 @@ static menucommon_s *g_looking_mini_controls[] = { static menucommon_s *g_misc_mini_controls[] = { (menucommon_s *)&s_controls.showscores, +#ifdef MISSIONPACK_HUD + (menucommon_s *)&s_controls.scoresup, + (menucommon_s *)&s_controls.scoresdown, +#endif (menucommon_s *)&s_controls.useitem, (menucommon_s *)&s_controls.gesture, NULL, @@ -1823,6 +1855,20 @@ static void Controls_MenuInit( int localPlayerNum ) s_controls.showscores.generic.ownerdraw = Controls_DrawKeyBinding; s_controls.showscores.generic.id = ID_SHOWSCORES; +#ifdef MISSIONPACK_HUD + s_controls.scoresup.generic.type = MTYPE_ACTION; + s_controls.scoresup.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; + s_controls.scoresup.generic.callback = Controls_ActionEvent; + s_controls.scoresup.generic.ownerdraw = Controls_DrawKeyBinding; + s_controls.scoresup.generic.id = ID_SCORESUP; + + s_controls.scoresdown.generic.type = MTYPE_ACTION; + s_controls.scoresdown.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; + s_controls.scoresdown.generic.callback = Controls_ActionEvent; + s_controls.scoresdown.generic.ownerdraw = Controls_DrawKeyBinding; + s_controls.scoresdown.generic.id = ID_SCORESDOWN; +#endif + s_controls.invertmouse.generic.type = MTYPE_RADIOBUTTON; s_controls.invertmouse.generic.flags = QMF_SMALLFONT; s_controls.invertmouse.generic.x = SCREEN_WIDTH/2; @@ -2003,6 +2049,10 @@ static void Controls_MenuInit( int localPlayerNum ) #endif Menu_AddItem( &s_controls.menu, &s_controls.showscores ); +#ifdef MISSIONPACK_HUD + Menu_AddItem( &s_controls.menu, &s_controls.scoresup ); + Menu_AddItem( &s_controls.menu, &s_controls.scoresdown ); +#endif Menu_AddItem( &s_controls.menu, &s_controls.useitem ); Menu_AddItem( &s_controls.menu, &s_controls.gesture ); Menu_AddItem( &s_controls.menu, &s_controls.chat ); diff --git a/code/q3_ui/ui_main.c b/code/q3_ui/ui_main.c index 233aac51e..3ee9a94e1 100644 --- a/code/q3_ui/ui_main.c +++ b/code/q3_ui/ui_main.c @@ -39,6 +39,10 @@ USER INTERFACE MAIN #include "ui_local.h" +// Called by CG_LoadHud_f() but only matters for missionpack UI. +void UI_Load( void ) { + +} qboolean UI_WantsBindKeys( void ) { return Controls_WantsBindKeys(); diff --git a/code/q3_ui/ui_preferences.c b/code/q3_ui/ui_preferences.c index 13c931a4e..0362702aa 100644 --- a/code/q3_ui/ui_preferences.c +++ b/code/q3_ui/ui_preferences.c @@ -51,6 +51,7 @@ enum { ID_CROSSHAIR, ID_CROSSHAIRHEALTH, ID_VIEWBOB, + ID_VIEWKICK, ID_SIMPLEITEMS, ID_HIGHQUALITYSKY, ID_EJECTINGBRASS, @@ -83,6 +84,7 @@ typedef struct { menulist_s crosshair; menuradiobutton_s crosshairhealth; menuradiobutton_s viewbob; + menuradiobutton_s viewkick; menuradiobutton_s simpleitems; menuradiobutton_s brass; menuradiobutton_s wallmarks; @@ -140,6 +142,7 @@ static void Preferences_SetMenuItems( void ) { s_preferences.crosshair.curvalue = (int)trap_Cvar_VariableValue( "cg_drawCrosshair" ) % NUM_CROSSHAIRS; s_preferences.crosshairhealth.curvalue = trap_Cvar_VariableValue( "cg_crosshairHealth" ) != 0; s_preferences.viewbob.curvalue = trap_Cvar_VariableValue( "cg_viewbob" ) != 0; + s_preferences.viewkick.curvalue = trap_Cvar_VariableValue( "cg_viewkick" ) != 0; s_preferences.simpleitems.curvalue = trap_Cvar_VariableValue( "cg_simpleItems" ) != 0; s_preferences.brass.curvalue = trap_Cvar_VariableValue( "cg_brassTime" ) != 0; s_preferences.wallmarks.curvalue = trap_Cvar_VariableValue( "cg_marks" ) != 0; @@ -183,6 +186,10 @@ static void Preferences_Event( void* ptr, int notification ) { trap_Cvar_SetValue( "cg_viewbob", s_preferences.viewbob.curvalue ); break; + case ID_VIEWKICK: + trap_Cvar_SetValue( "cg_viewkick", s_preferences.viewkick.curvalue ); + break; + case ID_SIMPLEITEMS: trap_Cvar_SetValue( "cg_simpleItems", s_preferences.simpleitems.curvalue ); break; @@ -371,6 +378,15 @@ static void Preferences_MenuInit( void ) { s_preferences.viewbob.generic.x = PREFERENCES_X_POS; s_preferences.viewbob.generic.y = y; + y += BIGCHAR_HEIGHT+2; + s_preferences.viewkick.generic.type = MTYPE_RADIOBUTTON; + s_preferences.viewkick.generic.name = "View Damage Kick:"; + s_preferences.viewkick.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; + s_preferences.viewkick.generic.callback = Preferences_Event; + s_preferences.viewkick.generic.id = ID_VIEWKICK; + s_preferences.viewkick.generic.x = PREFERENCES_X_POS; + s_preferences.viewkick.generic.y = y; + y += BIGCHAR_HEIGHT+2; s_preferences.simpleitems.generic.type = MTYPE_RADIOBUTTON; s_preferences.simpleitems.generic.name = "Simple Items:"; @@ -510,6 +526,7 @@ static void Preferences_MenuInit( void ) { Menu_AddItem( &s_preferences.menu, &s_preferences.crosshair ); Menu_AddItem( &s_preferences.menu, &s_preferences.crosshairhealth ); Menu_AddItem( &s_preferences.menu, &s_preferences.viewbob ); + Menu_AddItem( &s_preferences.menu, &s_preferences.viewkick ); Menu_AddItem( &s_preferences.menu, &s_preferences.simpleitems ); Menu_AddItem( &s_preferences.menu, &s_preferences.wallmarks ); Menu_AddItem( &s_preferences.menu, &s_preferences.brass ); diff --git a/code/q3_ui/ui_startserver.c b/code/q3_ui/ui_startserver.c index b582234db..93e74ef5d 100644 --- a/code/q3_ui/ui_startserver.c +++ b/code/q3_ui/ui_startserver.c @@ -895,6 +895,11 @@ static void ServerOptions_Start( void ) { info = UI_GetArenaInfoByNumber( s_startserver.maplist[ s_startserver.currentmap ]); trap_Cmd_ExecuteText( EXEC_APPEND, va( "wait ; wait ; map %s\n", Info_ValueForKey( info, "map" ))); + // remove bots + if ( trap_Cvar_VariableValue("sv_running") ) { + trap_Cmd_ExecuteText( EXEC_APPEND, "kickbots\n" ); + } + // add bots trap_Cmd_ExecuteText( EXEC_APPEND, "wait 3\n" ); for( n = 1; n < PLAYER_SLOTS; n++ ) { diff --git a/code/q3_ui/ui_video.c b/code/q3_ui/ui_video.c index 65f6e9120..e94b8789b 100644 --- a/code/q3_ui/ui_video.c +++ b/code/q3_ui/ui_video.c @@ -256,6 +256,7 @@ GRAPHICS OPTIONS MENU #define ID_SOUND 108 #define ID_NETWORK 109 #define ID_RATIO 110 +#define ID_FPS 111 typedef struct { menuframework_s menu; @@ -272,6 +273,7 @@ typedef struct { menulist_s list; menulist_s ratio; menulist_s mode; + menulist_s fps; menulist_s driver; menulist_s tq; menulist_s fs; @@ -300,6 +302,7 @@ typedef struct int filter; int multisample; qboolean flares; + int fps; } InitialVideoOptions_s; static InitialVideoOptions_s s_ivo; @@ -309,27 +312,27 @@ static InitialVideoOptions_s s_ivo_templates[] = { // very high { - 6, qtrue, 3, 0, 2, 2, 4, 5, 2, qtrue // Note: If r_availableModes is found, mode is changed to -2. + 6, qtrue, 3, 0, 2, 2, 4, 5, 2, qtrue, 4 // Note: If r_availableModes is found, mode is changed to -2. }, // high { - 6, qtrue, 3, 0, 2, 2, 3, 2, 1, qtrue + 6, qtrue, 3, 0, 2, 2, 3, 2, 1, qtrue, 4 }, // normal { - 6, qtrue, 3, 0, 0, 2, 2, 1, 0, qtrue + 6, qtrue, 3, 0, 0, 2, 2, 1, 0, qtrue, 3 }, // fast { - 4, qtrue, 2, 0, 1, 0, 1, 0, 0, qfalse + 4, qtrue, 2, 0, 1, 0, 1, 0, 0, qfalse, 3 }, // fastest { - 3, qtrue, 1, 1, 1, 0, 0, 0, 0, qfalse + 3, qtrue, 1, 1, 1, 0, 0, 0, 0, qfalse, 3 }, // custom { - 3, qtrue, 1, 0, 0, 0, 1, 0, 0, qfalse + 3, qtrue, 1, 0, 0, 0, 1, 0, 0, qfalse, 3 } }; @@ -373,6 +376,7 @@ static int resToRatio[ MAX_RESOLUTIONS ]; static char resbuf[ MAX_STRING_CHARS ]; static const char* detectedResolutions[ MAX_RESOLUTIONS ]; +static char currentResolution[ 20 ]; static const char** resolutions = builtinResolutions; static qboolean resolutionsDetected = qfalse; @@ -514,6 +518,7 @@ static void GraphicsOptions_GetInitialVideo( void ) s_ivo.colordepth = s_graphicsoptions.colordepth.curvalue; s_ivo.mode = s_graphicsoptions.mode.curvalue; s_ivo.fullscreen = s_graphicsoptions.fs.curvalue; + s_ivo.fps = s_graphicsoptions.fps.curvalue; s_ivo.tq = s_graphicsoptions.tq.curvalue; s_ivo.lighting = s_graphicsoptions.lighting.curvalue; s_ivo.flares = s_graphicsoptions.flares.curvalue; @@ -523,7 +528,7 @@ static void GraphicsOptions_GetInitialVideo( void ) s_ivo.texturebits = s_graphicsoptions.texturebits.curvalue; #if 0 - Com_Printf( "DEBUG: s_ivo = { %d, %d, %d, %d, %d, %d, %d, %d, %d, %s }\n", + Com_Printf( "DEBUG: s_ivo = { %d, %d, %d, %d, %d, %d, %d, %d, %d, %s, %d }\n", s_ivo.mode, s_ivo.fullscreen, s_ivo.tq, @@ -533,7 +538,8 @@ static void GraphicsOptions_GetInitialVideo( void ) s_ivo.geometry, s_ivo.filter, s_ivo.multisample, - s_ivo.flares ? "qtrue" : "qfalse" + s_ivo.flares ? "qtrue" : "qfalse", + s_ivo.fps ); #endif } @@ -545,7 +551,7 @@ GraphicsOptions_GetResolutions */ static void GraphicsOptions_GetResolutions( void ) { - Q_strncpyz(resbuf, CG_Cvar_VariableString("r_availableModes"), sizeof(resbuf)); + trap_Cvar_VariableStringBuffer("r_availableModes", resbuf, sizeof(resbuf)); if(*resbuf) { char* s = resbuf; @@ -568,11 +574,26 @@ static void GraphicsOptions_GetResolutions( void ) } detectedResolutions[ i ] = NULL; - if( i > 0 ) + // add custom resolution if not in mode list + if ( i < ARRAY_LEN(detectedResolutions)-1 ) { - resolutions = detectedResolutions; - resolutionsDetected = qtrue; + Com_sprintf( currentResolution, sizeof ( currentResolution ), "%dx%d", cgs.glconfig.vidWidth, cgs.glconfig.vidHeight ); + + for( i = 0; detectedResolutions[ i ]; i++ ) + { + if ( strcmp( detectedResolutions[ i ], currentResolution ) == 0 ) + break; + } + + if ( detectedResolutions[ i ] == NULL ) + { + detectedResolutions[ i++ ] = currentResolution; + detectedResolutions[ i ] = NULL; + } } + + resolutions = detectedResolutions; + resolutionsDetected = qtrue; } } @@ -591,6 +612,8 @@ static void GraphicsOptions_CheckConfig( void ) continue; if ( GraphicsOptions_FindDetectedResolution(s_ivo_templates[i].mode) != s_graphicsoptions.mode.curvalue ) continue; + if ( s_ivo_templates[i].fps != s_graphicsoptions.fps.curvalue ) + continue; // if ( s_ivo_templates[i].fullscreen != s_graphicsoptions.fs.curvalue ) // continue; if ( s_ivo_templates[i].tq != s_graphicsoptions.tq.curvalue ) @@ -638,6 +661,10 @@ static void GraphicsOptions_UpdateMenuItems( void ) { s_graphicsoptions.apply.generic.flags &= ~(QMF_HIDDEN|QMF_INACTIVE); } + if ( s_ivo.fps != s_graphicsoptions.fps.curvalue ) + { + s_graphicsoptions.apply.generic.flags &= ~(QMF_HIDDEN|QMF_INACTIVE); + } if ( s_ivo.fullscreen != s_graphicsoptions.fs.curvalue ) { s_graphicsoptions.apply.generic.flags &= ~(QMF_HIDDEN|QMF_INACTIVE); @@ -727,6 +754,30 @@ static void GraphicsOptions_ApplyChanges( void *unused, int notification ) else trap_Cvar_SetValue( "r_mode", s_graphicsoptions.mode.curvalue ); + switch ( s_graphicsoptions.fps.curvalue ) + { + case 0: + trap_Cvar_SetValue( "r_swapInterval", 1 ); + trap_Cvar_SetValue( "com_maxfps", 125 ); + break; + case 1: + trap_Cvar_SetValue( "r_swapInterval", 0 ); + trap_Cvar_SetValue( "com_maxfps", 30 ); + break; + case 2: + trap_Cvar_SetValue( "r_swapInterval", 0 ); + trap_Cvar_SetValue( "com_maxfps", 60 ); + break; + case 3: + trap_Cvar_SetValue( "r_swapInterval", 0 ); + trap_Cvar_SetValue( "com_maxfps", 85 ); + break; + case 4: + trap_Cvar_SetValue( "r_swapInterval", 0 ); + trap_Cvar_SetValue( "com_maxfps", 125 ); + break; + } + trap_Cvar_SetValue( "r_fullscreen", s_graphicsoptions.fs.curvalue ); switch ( s_graphicsoptions.colordepth.curvalue ) { @@ -850,6 +901,7 @@ static void GraphicsOptions_Event( void* ptr, int event ) { s_graphicsoptions.mode.curvalue = GraphicsOptions_FindDetectedResolution(ivo->mode); s_graphicsoptions.ratio.curvalue = resToRatio[ s_graphicsoptions.mode.curvalue ]; + s_graphicsoptions.fps.curvalue = ivo->fps; s_graphicsoptions.tq.curvalue = ivo->tq; s_graphicsoptions.lighting.curvalue = ivo->lighting; s_graphicsoptions.colordepth.curvalue = ivo->colordepth; @@ -944,6 +996,29 @@ static void GraphicsOptions_SetMenuItems( void ) } s_graphicsoptions.ratio.curvalue = resToRatio[ s_graphicsoptions.mode.curvalue ]; + + s_graphicsoptions.fps.curvalue = trap_Cvar_VariableValue( "com_maxfps"); + if ( trap_Cvar_VariableValue( "r_swapInterval" ) != 0 ) + { + s_graphicsoptions.fps.curvalue = 0; + } + else if ( s_graphicsoptions.fps.curvalue <= 30 ) + { + s_graphicsoptions.fps.curvalue = 1; + } + else if ( s_graphicsoptions.fps.curvalue <= 60 ) + { + s_graphicsoptions.fps.curvalue = 2; + } + else if ( s_graphicsoptions.fps.curvalue <= 85 ) + { + s_graphicsoptions.fps.curvalue = 3; + } + else //if ( s_graphicsoptions.fps.curvalue <= 125 ) + { + s_graphicsoptions.fps.curvalue = 4; + } + s_graphicsoptions.fs.curvalue = trap_Cvar_VariableValue("r_fullscreen"); s_graphicsoptions.tq.curvalue = 3-trap_Cvar_VariableValue( "r_picmip"); if ( s_graphicsoptions.tq.curvalue < 0 ) @@ -1063,6 +1138,22 @@ static void GraphicsOptions_SetMenuItems( void ) } } +/* +================= +GraphicsOptions_StatusBar +================= +*/ +static void GraphicsOptions_StatusBar( void *ptr ) { + switch( ((menucommon_s*)ptr)->id ) { + case ID_FPS: + UI_DrawString( 320, 410, "The frame rate also affects your player's movement.", UI_CENTER|UI_SMALLFONT, colorWhite ); + UI_DrawString( 320, 430, "125Hz can jump slightly higher than the others.", UI_CENTER|UI_SMALLFONT, colorWhite ); + break; + default: + break; + } +} + /* ================ GraphicsOptions_MenuInit @@ -1089,6 +1180,16 @@ void GraphicsOptions_MenuInit( void ) NULL }; + static const char *fps_names[] = + { + "V-Sync", + "30 Hz", + "60 Hz", + "85 Hz", + "125 Hz", + NULL + }; + static const char *lighting_names[] = { "Lightmap (High)", @@ -1254,6 +1355,18 @@ void GraphicsOptions_MenuInit( void ) s_graphicsoptions.mode.generic.id = ID_MODE; y += BIGCHAR_HEIGHT+2; + // references/modifies "com_maxfps" and "r_swapInterval" + s_graphicsoptions.fps.generic.type = MTYPE_SPINCONTROL; + s_graphicsoptions.fps.generic.name = "Frame Rate:"; + s_graphicsoptions.fps.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; + s_graphicsoptions.fps.generic.x = 400; + s_graphicsoptions.fps.generic.y = y; + s_graphicsoptions.fps.itemnames = fps_names; + s_graphicsoptions.fps.generic.callback = GraphicsOptions_Event; + s_graphicsoptions.fps.generic.id = ID_FPS; + s_graphicsoptions.fps.generic.statusbar = GraphicsOptions_StatusBar; + y += BIGCHAR_HEIGHT+2; + // references "r_colorbits" s_graphicsoptions.colordepth.generic.type = MTYPE_SPINCONTROL; s_graphicsoptions.colordepth.generic.name = "Color Depth:"; @@ -1378,6 +1491,7 @@ void GraphicsOptions_MenuInit( void ) Menu_AddItem( &s_graphicsoptions.menu, ( void * ) &s_graphicsoptions.list ); Menu_AddItem( &s_graphicsoptions.menu, ( void * ) &s_graphicsoptions.ratio ); Menu_AddItem( &s_graphicsoptions.menu, ( void * ) &s_graphicsoptions.mode ); + Menu_AddItem( &s_graphicsoptions.menu, ( void * ) &s_graphicsoptions.fps ); Menu_AddItem( &s_graphicsoptions.menu, ( void * ) &s_graphicsoptions.colordepth ); Menu_AddItem( &s_graphicsoptions.menu, ( void * ) &s_graphicsoptions.fs ); Menu_AddItem( &s_graphicsoptions.menu, ( void * ) &s_graphicsoptions.multisample ); diff --git a/code/tools/lcc/cpp/cpp.c b/code/tools/lcc/cpp/cpp.c index 5c0cfd7b6..13e048505 100644 --- a/code/tools/lcc/cpp/cpp.c +++ b/code/tools/lcc/cpp/cpp.c @@ -19,6 +19,15 @@ int ifdepth; int ifsatisfied[NIF]; int skipping; +time_t reproducible_time() +{ + char *source_date_epoch; + time_t t; + if ((source_date_epoch = getenv("SOURCE_DATE_EPOCH")) == NULL || + (t = (time_t)strtol(source_date_epoch, NULL, 10)) <= 0) + return time(NULL); + return t; +} int main(int argc, char **argv) @@ -28,7 +37,7 @@ main(int argc, char **argv) char ebuf[BUFSIZ]; setbuf(stderr, ebuf); - t = time(NULL); + t = reproducible_time(); curtime = ctime(&t); maketokenrow(3, &tr); expandlex(); diff --git a/code/tools/lcc/etc/bytecode.c b/code/tools/lcc/etc/bytecode.c index a5855de3a..4a2fe4456 100644 --- a/code/tools/lcc/etc/bytecode.c +++ b/code/tools/lcc/etc/bytecode.c @@ -34,9 +34,14 @@ void UpdatePaths( const char *lccBinary ) { char basepath[ 1024 ]; char *p; + size_t basepathsz = sizeof( basepath ) - 1; - strncpy( basepath, lccBinary, 1024 ); - p = strrchr( basepath, PATH_SEP ); + strncpy( basepath, lccBinary, basepathsz ); + basepath[basepathsz] = 0; + p = strrchr( basepath, '/' ); + + if( !p ) + p = strrchr( basepath, '\\' ); if( p ) { diff --git a/code/ui/ui_main.c b/code/ui/ui_main.c index 13fddd6bc..a73f0be62 100644 --- a/code/ui/ui_main.c +++ b/code/ui/ui_main.c @@ -2744,6 +2744,7 @@ static void UI_Update(const char *name) { trap_Cvar_SetValue( "r_stencilbits", 8 ); trap_Cvar_SetValue( "r_picmip", 0 ); trap_Cvar_SetValue( "r_mode", 4 ); + trap_Cvar_Set( "ui_videomode", "800x600" ); trap_Cvar_SetValue( "r_texturebits", 32 ); trap_Cvar_SetValue( "r_fastSky", 0 ); trap_Cvar_SetValue( "r_inGameVideo", 1 ); @@ -2761,6 +2762,7 @@ static void UI_Update(const char *name) { trap_Cvar_Reset( "r_stencilbits" ); trap_Cvar_SetValue( "r_picmip", 1 ); trap_Cvar_SetValue( "r_mode", 3 ); + trap_Cvar_Set( "ui_videomode", "640x480" ); trap_Cvar_SetValue( "r_texturebits", 0 ); trap_Cvar_SetValue( "r_fastSky", 0 ); trap_Cvar_SetValue( "r_inGameVideo", 1 ); @@ -2778,6 +2780,7 @@ static void UI_Update(const char *name) { trap_Cvar_Reset( "r_stencilbits" ); trap_Cvar_SetValue( "r_picmip", 1 ); trap_Cvar_SetValue( "r_mode", 3 ); + trap_Cvar_Set( "ui_videomode", "640x480" ); trap_Cvar_SetValue( "r_texturebits", 0 ); trap_Cvar_SetValue( "cg_shadows", 0 ); trap_Cvar_SetValue( "r_fastSky", 1 ); @@ -2794,6 +2797,7 @@ static void UI_Update(const char *name) { trap_Cvar_SetValue( "r_depthbits", 16 ); trap_Cvar_SetValue( "r_stencilbits", 0 ); trap_Cvar_SetValue( "r_mode", 3 ); + trap_Cvar_Set( "ui_videomode", "640x480" ); trap_Cvar_SetValue( "r_picmip", 2 ); trap_Cvar_SetValue( "r_texturebits", 16 ); trap_Cvar_SetValue( "cg_shadows", 0 ); @@ -4718,6 +4722,11 @@ void UI_Init( qboolean inGameLoad, int maxSplitView ) { UI_RegisterCvars(); UI_InitMemory(); + trap_Cvar_Set("ui_videomode", va( "%dx%d", cgs.glconfig.vidWidth, cgs.glconfig.vidHeight ) ); + + // ### FIXME: Don't commit this. + Com_Printf( "DEBUG: ui_videomode default: '%s'\n", va( "%dx%d", cgs.glconfig.vidWidth, cgs.glconfig.vidHeight ) ); + //UI_Load(); uiInfo.uiDC.registerShaderNoMip = &trap_R_RegisterShaderNoMip; uiInfo.uiDC.setColor = &trap_R_SetColor; @@ -5459,6 +5468,7 @@ static cvarTable_t cvarTable[] = { { NULL, "fraglimit", "20", CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_NORESTART}, { NULL, "capturelimit", "8", CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_NORESTART}, { &ui_serverStatusTimeOut, "ui_serverStatusTimeOut", "7000", CVAR_ARCHIVE}, + { NULL, "ui_videomode", "", CVAR_ROM }, { &ui_defaultMaleTeamModel, "default_male_team_model", DEFAULT_TEAM_MODEL_MALE, CVAR_ARCHIVE}, { &ui_defaultFemaleTeamModel, "default_female_team_model", DEFAULT_TEAM_MODEL_FEMALE, CVAR_ARCHIVE}, { &ui_menuFont, "ui_menuFont", "fonts/LiberationSans-Bold.ttf", CVAR_ARCHIVE | CVAR_LATCH}, diff --git a/code/ui/ui_shared.c b/code/ui/ui_shared.c index 275eb1557..46ff7ec96 100644 --- a/code/ui/ui_shared.c +++ b/code/ui/ui_shared.c @@ -2044,6 +2044,26 @@ qboolean Item_Multi_HandleKey(itemDef_t *item, int key) { } else if ( current >= max ) { current = 0; } + + if (multiPtr->videoMode) { + if (multiPtr->cvarValue[current] != -1) { + DC->setCVar("r_mode", va("%i", (int) multiPtr->cvarValue[current] )); + } else { + int w, h; + char *x; + char str[8]; + + x = strchr( multiPtr->cvarStr[current], 'x' ) + 1; + Q_strncpyz( str, multiPtr->cvarStr[current], MIN( x-multiPtr->cvarStr[current], sizeof( str ) ) ); + w = atoi( str ); + h = atoi( x ); + + DC->setCVar("r_mode", "-1"); + DC->setCVar("r_customwidth", va("%i", w)); + DC->setCVar("r_customheight", va("%i", h)); + } + } + if (multiPtr->strDef) { DC->setCVar(item->cvar, multiPtr->cvarStr[current]); } else { @@ -3252,14 +3272,17 @@ static bind_t g_bindings[] = {"weapon 7", '7', -1, -1, -1}, {"weapon 8", '8', -1, -1, -1}, {"weapon 9", '9', -1, -1, -1}, +#ifdef MISSIONPACK {"weapon 10", '0', -1, -1, -1}, {"weapon 11", -1, -1, -1, -1}, {"weapon 12", -1, -1, -1, -1}, {"weapon 13", -1, -1, -1, -1}, +#endif {"+attack", K_LEFTCTRL, K_RIGHTCTRL, -1, -1}, {"weapprev", '[', -1, -1, -1}, {"weapnext", ']', -1, -1, -1}, {"+button3", K_MOUSE3, -1, -1, -1}, +#ifdef MISSIONPACK {"+button4", K_MOUSE4, -1, -1, -1}, {"prevTeamMember", 'w', -1, -1, -1}, {"nextTeamMember", 'r', -1, -1, -1}, @@ -3280,6 +3303,7 @@ static bind_t g_bindings[] = {"tauntTaunt", K_F3, -1, -1, -1}, {"tauntDeathInsult", K_F4, -1, -1, -1}, {"tauntGauntlet", K_F5, -1, -1, -1}, +#endif {"scoresUp", K_KP_PGUP, -1, -1, -1}, {"scoresDown", K_KP_PGDN, -1, -1, -1}, {"messagemode", -1, -1, -1, -1}, @@ -5019,6 +5043,7 @@ qboolean ItemParse_cvarStrList( itemDef_t *item, int handle ) { multiPtr = (multiDef_t*)item->typeData; multiPtr->count = 0; multiPtr->strDef = qtrue; + multiPtr->videoMode = qfalse; if (!trap_PC_ReadToken(handle, &token)) return qfalse; @@ -5067,6 +5092,7 @@ qboolean ItemParse_cvarFloatList( itemDef_t *item, int handle ) { multiPtr = (multiDef_t*)item->typeData; multiPtr->count = 0; multiPtr->strDef = qfalse; + multiPtr->videoMode = qfalse; if (!trap_PC_ReadToken(handle, &token)) return qfalse; @@ -5243,6 +5269,61 @@ void Item_SetupKeywordHash(void) { } } +static const char *builtinResolutions[ ] = +{ + "320x240", + "400x300", + "512x384", + "640x480", + "800x600", + "960x720", + "1024x768", + "1152x864", + "1280x1024", + "1600x1200", + "2048x1536", + "856x480", + NULL +}; + +static const char *knownRatios[ ][2] = +{ + { "1.25:1", "5:4" }, + { "1.33:1", "4:3" }, + { "1.50:1", "3:2" }, + { "1.56:1", "14:9" }, + { "1.60:1", "16:10" }, + { "1.67:1", "5:3" }, + { "1.78:1", "16:9" }, + { NULL , NULL } +}; + +/* +=============== +UI_ResolutionToAspect +=============== +*/ +static void UI_ResolutionToAspect( const char *resolution, char *aspect, size_t aspectLength ) { + int i, w, h; + char *x; + char str[8]; + + // calculate resolution's aspect ratio + x = strchr( resolution, 'x' ) + 1; + Q_strncpyz( str, resolution, MIN( x-resolution, sizeof( str ) ) ); + w = atoi( str ); + h = atoi( x ); + Com_sprintf( aspect, aspectLength, "%.2f:1", (float)w / (float)h ); + + // rename common ratios ("1.33:1" -> "4:3") + for( i = 0; knownRatios[i][0]; i++ ) { + if( !Q_stricmp( aspect, knownRatios[i][0] ) ) { + Q_strncpyz( aspect, knownRatios[i][1], aspectLength ); + break; + } + } +} + /* =============== Item_ApplyHacks @@ -5277,6 +5358,89 @@ static void Item_ApplyHacks( itemDef_t *item ) { } } + // Replace mode list and use a temporary ui_videomode cvar for handling custom modes + if ( item->type == ITEM_TYPE_MULTI && item->cvar && !Q_stricmp( item->cvar, "r_mode" ) ) { + multiDef_t *multiPtr = (multiDef_t*)item->typeData; + int i, oldCount; + char resbuf[MAX_STRING_CHARS]; + char modeName[32], aspect[8]; + + item->cvar = "ui_videomode"; + multiPtr->strDef = qtrue; + multiPtr->videoMode = qtrue; + + oldCount = multiPtr->count; + multiPtr->count = 0; + + DC->getCVarString( "r_availableModes", resbuf, sizeof( resbuf ) ); + + if ( *resbuf ) { + char *s = resbuf, *mode; + + while ( s && multiPtr->count < MAX_MULTI_CVARS ) { + mode = s; + + s = strchr(s, ' '); + if( s ) + *s++ = '\0'; + + UI_ResolutionToAspect( mode, aspect, sizeof( aspect ) ); + Com_sprintf( modeName, sizeof( modeName ), "%s (%s)", mode, aspect ); + + multiPtr->cvarList[multiPtr->count] = String_Alloc( modeName ); + + for ( i = 0; builtinResolutions[i]; i++ ) { + if( !Q_stricmp( builtinResolutions[i], mode ) ) { + multiPtr->cvarStr[multiPtr->count] = builtinResolutions[i]; + multiPtr->cvarValue[multiPtr->count] = i; + break; + } + } + + if ( builtinResolutions[i] == NULL ) { + multiPtr->cvarStr[multiPtr->count] = String_Alloc( mode ); + multiPtr->cvarValue[multiPtr->count] = -1; + } + + multiPtr->count++; + } + } else { + for ( i = 0; builtinResolutions[i] && multiPtr->count < MAX_MULTI_CVARS; i++ ) { + UI_ResolutionToAspect( builtinResolutions[i], aspect, sizeof( aspect ) ); + Com_sprintf( modeName, sizeof( modeName ), "%s (%s)", builtinResolutions[i], aspect ); + + multiPtr->cvarList[multiPtr->count] = String_Alloc( modeName ); + multiPtr->cvarStr[multiPtr->count] = builtinResolutions[i]; + multiPtr->cvarValue[multiPtr->count] = i; + multiPtr->count++; + } + } + + // Add custom resolution if not in mode list + if ( multiPtr->count < MAX_MULTI_CVARS ) { + char currentResolution[20]; + + Com_sprintf( currentResolution, sizeof ( currentResolution ), "%dx%d", cgs.glconfig.vidWidth, cgs.glconfig.vidHeight ); + for ( i = 0; i < multiPtr->count; i++ ) { + if ( !Q_stricmp( multiPtr->cvarStr[i], currentResolution ) ) { + break; + } + } + + if ( i == multiPtr->count ) { + UI_ResolutionToAspect( currentResolution, aspect, sizeof( aspect ) ); + Com_sprintf( modeName, sizeof( modeName ), "%s (%s)", currentResolution, aspect ); + + multiPtr->cvarList[multiPtr->count] = String_Alloc( modeName ); + multiPtr->cvarStr[multiPtr->count] = String_Alloc( currentResolution ); + multiPtr->cvarValue[multiPtr->count] = -1; + multiPtr->count++; + } + } + + Com_Printf( "Found video mode list with %d modes, replaced list with %d modes\n", oldCount, multiPtr->count ); + } + // Show selected score on the scoreboard if ( item->type == ITEM_TYPE_LISTBOX && item->window.outlineColor[3] == 0 && ( item->special == FEEDER_SCOREBOARD || item->special == FEEDER_REDTEAM_LIST || item->special == FEEDER_BLUETEAM_LIST ) ) { diff --git a/code/ui/ui_shared.h b/code/ui/ui_shared.h index b83fbf3c4..769847585 100644 --- a/code/ui/ui_shared.h +++ b/code/ui/ui_shared.h @@ -37,6 +37,24 @@ Suite 120, Rockville, Maryland 20850 USA. #include "../../ui/menudef.h" + +// Avoid duplicate symbols when using MISSIONPACK_HUD with Q3_UI. +// "static" doesn't make symbols local to the file in QVMs. +#define UI_SHARED_STATIC( sym ) sym##_ui_shared +#define UI_Alloc UI_SHARED_STATIC( UI_Alloc ) +#define UI_InitMemory UI_SHARED_STATIC( UI_InitMemory ) +#define outOfMemory UI_SHARED_STATIC( outOfMemory ) +#define allocPoint UI_SHARED_STATIC( allocPoint ) +#define memoryPool UI_SHARED_STATIC( memoryPool ) +#define builtinResolutions UI_SHARED_STATIC( builtinResolutions ) +#define knownRatios UI_SHARED_STATIC( knownRatios ) +#define Controls_GetKeyAssignment UI_SHARED_STATIC( Controls_GetKeyAssignment ) +#define Controls_GetConfig UI_SHARED_STATIC( Controls_GetConfig ) +#define Controls_SetConfig UI_SHARED_STATIC( Controls_SetConfig ) +#define Controls_SetDefaults UI_SHARED_STATIC( Controls_SetDefaults ) +#define g_bindings UI_SHARED_STATIC( g_bindings ) + + #define MAX_MENUNAME 32 #define MAX_ITEMTEXT 64 #define MAX_ITEMACTION 64 @@ -215,6 +233,7 @@ typedef struct multiDef_s { float cvarValue[MAX_MULTI_CVARS]; int count; qboolean strDef; + qboolean videoMode; } multiDef_t; typedef struct modelDef_s { diff --git a/travis-ci-build.sh b/travis-ci-build.sh deleted file mode 100755 index 008bc7e12..000000000 --- a/travis-ci-build.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -failed=0; - -# Default Build -(make clean release) || failed=1; - -if [ $failed -eq 1 ]; then - echo "Build failure."; -else - echo "Build successful."; -fi - -exit $failed; -