menu.cpp
1 //------------------------------------------------------------------------- 2 /* 3 Copyright (C) 2010-2019 EDuke32 developers and contributors 4 Copyright (C) 2019 Nuke.YKT 5 6 This file is part of NBlood. 7 8 NBlood is free software; you can redistribute it and/or 9 modify it under the terms of the GNU General Public License version 2 10 as published by the Free Software Foundation. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 15 16 See the GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program; if not, write to the Free Software 20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 21 */ 22 //------------------------------------------------------------------------- 23 #include "compat.h" 24 #include "mmulti.h" 25 #include "common_game.h" 26 #include "fx_man.h" 27 #include "music.h" 28 #include "blood.h" 29 #include "demo.h" 30 #include "config.h" 31 #include "gamemenu.h" 32 #include "globals.h" 33 #include "loadsave.h" 34 #include "menu.h" 35 #include "messages.h" 36 #include "network.h" 37 #include "osdcmds.h" 38 #include "sfx.h" 39 #include "screen.h" 40 #include "sound.h" 41 #include "tile.h" 42 #include "view.h" 43 44 void SaveGame(CGameMenuItemZEditBitmap *, CGameMenuEvent *); 45 46 void SaveGameProcess(CGameMenuItemChain *); 47 void ShowDifficulties(); 48 void SetDifficultyAndStart(CGameMenuItemChain *); 49 void SetCustomDifficultyMenu(CGameMenuItemChain *); 50 void SetMonsters(CGameMenuItemZCycle *); 51 void SetCustomDifficultyAndStart(CGameMenuItemChain *); 52 void SetFirstLaunchOptions(CGameMenuItemChain *); 53 void SetMusicVol(CGameMenuItemSlider *); 54 void SetSoundVol(CGameMenuItemSlider *); 55 void SetCDVol(CGameMenuItemSlider *); 56 void SetMonoStereo(CGameMenuItemZBool *); 57 void SetCrosshair(CGameMenuItemZCycle *); 58 59 void SetQuadDamagePowerup(CGameMenuItemZBool*); 60 void SetDamageInvul(CGameMenuItemZCycle*); 61 void SetProjectileBehavior(CGameMenuItemZCycle*); 62 void SetNapalmFalloff(CGameMenuItemZBool*); 63 void SetEnemyBehavior(CGameMenuItemZCycle*); 64 void SetEnemyRandomTNT(CGameMenuItemZBool*); 65 void SetWeaponsVer(CGameMenuItemZCycle*); 66 void SetAmmoScale(CGameMenuItemZCycle*); 67 void SetSectorBehavior(CGameMenuItemZBool*); 68 void SetHitscanProjectiles(CGameMenuItemZCycle*); 69 void SetGoreMode(CGameMenuItemZCycle*); 70 void SetPlayerSpeed(CGameMenuItemZCycle*); 71 void SetRandomizerMode(CGameMenuItemZCycle*); 72 void SetRandomizerSeed(CGameMenuItemZEdit *pItem, CGameMenuEvent *pEvent); 73 74 void SetHudSize(CGameMenuItemSlider *); 75 void SetHudRatio(CGameMenuItemZCycle *); 76 void SetCenterHoriz(CGameMenuItemZBool *); 77 void SetSlopeTilting(CGameMenuItemZBool *); 78 void SetViewBobbing(CGameMenuItemZBool *); 79 void SetViewSwaying(CGameMenuItemZBool *); 80 void SetWeaponSwaying(CGameMenuItemZCycle *); 81 void SetWeaponInterpolate(CGameMenuItemZCycle *); 82 void SetViewInterpolate(CGameMenuItemZBool *); 83 void SetLevelCompleteTime(CGameMenuItemZBool *); 84 void SetMirrorMode(CGameMenuItemZCycle *); 85 void SetSlowRoomFlicker(CGameMenuItemZBool *); 86 void SetMouseSensitivity(CGameMenuItemSliderFloat *); 87 void SetMouseAimFlipped(CGameMenuItemZBool *); 88 void SetTurnSpeed(CGameMenuItemSlider *); 89 void SetTurnAcceleration(CGameMenuItemZCycle *); 90 void SetCenterView(CGameMenuItemZBool *); 91 void SetJoystickTargetAimAssist(CGameMenuItemZBool *); 92 void SetRadialMenuToggle(CGameMenuItemZCycle *); 93 void SetRadialMenuPosition(CGameMenuItemSlider *); 94 void SetRadialMenuDimBackground(CGameMenuItemZBool *); 95 void SetRadialMenuDimHUD(CGameMenuItemZBool *); 96 void SetRadialMenuSlowDown(CGameMenuItemZBool *); 97 void SetRadialMenuSound(CGameMenuItemZCycle *); 98 void SetRadialMenuMouseThreshold(CGameMenuItemSlider *); 99 void SetRadialMenuThreshold(CGameMenuItemSlider *); 100 void SetRadialMenuYaw(CGameMenuItemZCycle *); 101 void SetRadialMenuYawInvert(CGameMenuItemZBool *); 102 void SetRadialMenuPitch(CGameMenuItemZCycle *); 103 void SetRadialMenuPitchInvert(CGameMenuItemZBool *); 104 void SetJoystickRumble(CGameMenuItemZBool *); 105 void SetCrouchToggle(CGameMenuItemZBool *); 106 void SetCrouchAuto(CGameMenuItemZBool *); 107 void ResetKeys(CGameMenuItemChain *); 108 void ResetKeysClassic(CGameMenuItemChain *); 109 void SetMessages(CGameMenuItemZBool *); 110 void LoadGame(CGameMenuItemZEditBitmap *, CGameMenuEvent *); 111 void SetupNetLevels(CGameMenuItemZCycle *); 112 void NetClearUserMap(CGameMenuItemZCycle *); 113 void StartNetGame(CGameMenuItemChain *); 114 void SetupLevelMenuItem(int); 115 void SetupVideoModeMenu(CGameMenuItemChain *); 116 void SetupViewMenu(CGameMenuItemChain *); 117 void SetVideoMode(CGameMenuItemChain *); 118 void SetWidescreen(CGameMenuItemZBool *); 119 void SetWeaponSelectMode(CGameMenuItemZCycle *); 120 void SetDetail(CGameMenuItemSlider *); 121 void SetVoxels(CGameMenuItemZBool *); 122 void SetFOV(CGameMenuItemSlider *); 123 void UpdateVideoModeMenuFrameLimit(CGameMenuItemZCycle *pItem); 124 void UpdateVideoColorMenu(CGameMenuItemSliderFloat *); 125 void UpdateVideoPaletteCycleMenu(CGameMenuItemZCycle *); 126 void UpdateVideoPaletteBoolMenu(CGameMenuItemZBool *); 127 void ResetVideoColor(CGameMenuItemChain *); 128 #ifdef USE_OPENGL 129 void SetupVideoPolymostMenu(CGameMenuItemChain *); 130 #endif 131 132 char strRestoreGameStrings[kMaxLoadSaveSlot][16] = 133 { 134 "<Empty>", 135 "<Empty>", 136 "<Empty>", 137 "<Empty>", 138 "<Empty>", 139 "<Empty>", 140 "<Empty>", 141 "<Empty>", 142 "<Empty>", 143 "<Empty>", 144 145 "<Empty>", 146 147 "<Empty>", 148 "<Empty>", 149 }; 150 151 int restoreGameDifficulty[kMaxLoadSaveSlot] = 152 { 153 -1, 154 -1, 155 -1, 156 -1, 157 -1, 158 -1, 159 -1, 160 -1, 161 -1, 162 -1, 163 164 -1, 165 166 -1, 167 -1, 168 }; 169 170 const char *zNetGameTypes[] = 171 { 172 "Cooperative", 173 "Bloodbath", 174 "Teams", 175 }; 176 177 const char *zMonsterStrings[] = 178 { 179 "None", 180 "Bring 'em on", 181 "Respawn (15 Secs)", 182 "Respawn (30 Secs)", 183 "Respawn (60 Secs)", 184 "Respawn (90 Secs)", 185 "Respawn (120 Secs)", 186 }; 187 188 const char *zWeaponStrings[] = 189 { 190 "Do not Respawn", 191 "Are Permanent", 192 "Respawn", 193 "Respawn with Markers", 194 }; 195 196 const char *zItemStrings[] = 197 { 198 "Do not Respawn", 199 "Respawn", 200 "Respawn with Markers", 201 }; 202 203 const char *zKeyStrings[] = 204 { 205 "LOST ON DEATH", 206 "KEPT ON RESPAWN", 207 "SHARED", 208 }; 209 210 const char *zKeepItemWeaponStrings[] = 211 { 212 "LOST ON DEATH", 213 "KEEP ON DEATH" 214 }; 215 216 const char *zSpawnProtectStrings[] = 217 { 218 "OFF", 219 "1 SEC", 220 "2 SECS", 221 "3 SECS", 222 }; 223 224 const char *zShowWeapon[] = 225 { 226 "ALWAYS SHOW", 227 "HIDE WHEN CLOAKED", 228 "ALWAYS HIDE" 229 }; 230 231 const char *zShowWeaponTeams[] = 232 { 233 "ALWAYS SHOW", 234 "HIDE WHEN CLOAKED", 235 "SHOW TEAMS", 236 "ALWAYS HIDE" 237 }; 238 239 const char *zSpawnWeaponStrings[] = 240 { 241 "Pitchfork", 242 "Flare Pistol", 243 "Sawed-off", 244 "Tommy Gun", 245 "Napalm Launcher", 246 "Dynamite", 247 "Spray Can", 248 "Tesla Cannon", 249 "Life Leech", 250 "Voodoo Doll", 251 "Proximity TNT", 252 "Remote TNT", 253 "Random Weapon", 254 "All Weapons" 255 }; 256 257 const char *zRespawnStrings[] = 258 { 259 "Random", 260 "Smart Random", 261 "Farthest From Enemies", 262 }; 263 264 const char *pzMirrorModeStrings[] = { 265 "OFF", 266 "HORIZONTAL", 267 "VERTICAL", 268 "HORIZONTAL+VERTICAL" 269 }; 270 271 const char *zDiffStrings[] = 272 { 273 "STILL KICKING", 274 "PINK ON THE INSIDE", 275 "LIGHTLY BROILED", 276 "WELL DONE", 277 "EXTRA CRISPY", 278 }; 279 280 const char *pzDamageInvulBehaviorStrings[] = { 281 "Off", 282 "Shortest", 283 "Short", 284 "Medium", 285 "Long", 286 "Longest", 287 }; 288 289 const char *pzProjectileBehaviorStrings[] = { 290 "Original", 291 "NotBlood", 292 "Raze", 293 }; 294 295 const char *pzEnemyBehaviorStrings[] = { 296 "Original", 297 "NBlood", 298 "NotBlood", 299 }; 300 301 const char *pzWeaponsVersionStrings[] = { 302 "Original", 303 "NotBlood", 304 "V1.0x", 305 }; 306 307 const char *pzAmmoScaleStrings[] = { 308 "Original", 309 "125%", 310 "150%", 311 "25%", 312 "50%", 313 "75%", 314 }; 315 316 const char *pzHitscanProjectilesStrings[] = { 317 "Off", 318 "Slow", 319 "Medium", 320 "Fast", 321 }; 322 323 const char *pzGoreStrings[] = { 324 "Original", 325 "Extended", 326 "Excessive", 327 }; 328 329 const char *pzRandomizerModeStrings[] = { 330 "Off", 331 "Enemies", 332 "Pickups", 333 "Enemies+Pickups", 334 }; 335 336 const char *pzEnemySpeeds[] = { 337 "Default", 338 "1.5x", 339 "2.0x", 340 "2.5x", 341 "3.0x", 342 }; 343 344 const char *pzPlayerSpeeds[] = { 345 "Default", 346 "1.25x", 347 "1.50x", 348 "1.75x", 349 "2.00x", 350 }; 351 352 char zUserMapName[BMAX_PATH] = ""; 353 const char *zEpisodeNames[6]; 354 const char *zLevelNames[6][kMaxLevels]; 355 static char szRandomizerSeedMenu[9]; 356 357 static char MenuGameFuncs[NUMGAMEFUNCTIONS][MAXGAMEFUNCLEN]; 358 static char const *MenuGameFuncNone = " -None-"; 359 static char const *pzGamefuncsStrings[NUMGAMEFUNCTIONS + 1]; 360 static int nGamefuncsValues[NUMGAMEFUNCTIONS + 1]; 361 static int nGamefuncsNum; 362 363 CGameMenu menuMain; 364 CGameMenu menuMainWithSave; 365 CGameMenu menuFirstLaunch; 366 CGameMenu menuNetMain; 367 CGameMenu menuNetStart; 368 CGameMenu menuEpisode; 369 CGameMenu menuDifficulty; 370 CGameMenu menuCustomDifficulty; 371 CGameMenu menuBannedMonsters; 372 CGameMenu menuBannedItems; 373 CGameMenu menuControls; 374 CGameMenu menuMessages; 375 CGameMenu menuSaveGame; 376 CGameMenu menuLoadGame; 377 CGameMenu menuLoading; 378 CGameMenu menuQuit; 379 CGameMenu menuRestart; 380 CGameMenu menuCredits; 381 CGameMenu menuHelp; 382 CGameMenu menuNetwork; 383 CGameMenu menuNetworkHost; 384 CGameMenu menuNetworkJoin; 385 CGameMenu menuNetworkGameMode; 386 CGameMenu menuNetworkGameMonsters; 387 CGameMenu menuNetworkGameMutators; 388 389 CGameMenuItemQAV itemBloodQAV("", 3, 160, 100, "BDRIP", true); 390 CGameMenuItemQAV itemCreditsQAV("", 3, 160, 100, "CREDITS", false, true); 391 CGameMenuItemQAV itemHelp3QAV("", 3, 160, 100, "HELP3", false, false); 392 CGameMenuItemQAV itemHelp3BQAV("", 3, 160, 100, "HELP3B", false, false); 393 CGameMenuItemQAV itemHelp4QAV("", 3, 160, 100, "HELP4", false, true); 394 CGameMenuItemQAV itemHelp5QAV("", 3, 160, 100, "HELP5", false, true); 395 396 CGameMenuItemTitle itemMainTitle(gGameTitle, 1, 160, 20, 2038); 397 CGameMenuItemChain itemMain1("NEW GAME", 1, 0, 45, 320, 1, &menuEpisode, -1, NULL, 0); 398 CGameMenuItemChain itemMain2("MULTIPLAYER", 1, 0, 65, 320, 1, &menuNetwork, -1, NULL, 0); 399 CGameMenuItemChain itemMain3("OPTIONS", 1, 0, 85, 320, 1, &menuOptions, -1, NULL, 0); 400 CGameMenuItemChain itemMain4("LOAD GAME", 1, 0, 105, 320, 1, &menuLoadGame, -1, NULL, 0); 401 CGameMenuItemChain itemMain5("HELP", 1, 0, 125, 320, 1, &menuHelp, -1, NULL, 0); 402 CGameMenuItemChain itemMain6("CREDITS", 1, 0, 145, 320, 1, &menuCredits, -1, NULL, 0); 403 CGameMenuItemChain itemMain7("QUIT", 1, 0, 165, 320, 1, &menuQuit, -1, NULL, 0); 404 405 CGameMenuItemTitle itemMainSaveTitle(gGameTitle, 1, 160, 20, 2038); 406 CGameMenuItemChain itemMainSave1("NEW GAME", 1, 0, 45, 320, 1, &menuEpisode, -1, NULL, 0); 407 CGameMenuItemChain itemMainSave2("OPTIONS", 1, 0, 60, 320, 1, &menuOptions, -1, NULL, 0); 408 CGameMenuItemChain itemMainSave3("SAVE GAME", 1, 0, 75, 320, 1, &menuSaveGame, -1, SaveGameProcess, 0); 409 CGameMenuItemChain itemMainSave4("LOAD GAME", 1, 0, 90, 320, 1, &menuLoadGame, -1, NULL, 0); 410 CGameMenuItemChain itemMainSave5("HELP", 1, 0, 105, 320, 1, &menuHelp, -1, NULL, 0); 411 CGameMenuItemChain itemMainSave6("CREDITS", 1, 0, 120, 320, 1, &menuCredits, -1, NULL, 0); 412 CGameMenuItemChain itemMainSave7("END GAME", 1, 0, 135, 320, 1, &menuRestart, -1, NULL, 0); 413 CGameMenuItemChain itemMainSave8("QUIT", 1, 0, 150, 320, 1, &menuQuit, -1, NULL, 0); 414 415 CGameMenuItemTitle itemFirstLaunchInfo1("THIS IS YOUR FIRST TIME LAUNCHING NOTBLOOD", 1, 160, 45, -1); 416 CGameMenuItemTitle itemFirstLaunchInfo2("PLEASE SELECT YOUR PREFERRED EXPERIENCE", 1, 160, 65, -1); 417 CGameMenuItemChain itemFirstLaunchVanilla("DOS BLOOD", 1, 0, 90, 320, 1, NULL, -1, SetFirstLaunchOptions, 0); 418 CGameMenuItemChain itemFirstLaunchNBlood("NBLOOD", 1, 0, 110, 320, 1, NULL, -1, SetFirstLaunchOptions, 0); 419 CGameMenuItemChain itemFirstLaunchNotBlood("NOTBLOOD", 1, 0, 130, 320, 1, NULL, -1, SetFirstLaunchOptions, 0); 420 421 CGameMenuItemTitle itemEpisodesTitle("EPISODES", 1, 160, 20, 2038); 422 CGameMenuItemChain7F2F0 itemEpisodes[kMaxEpisodes-1]; 423 424 CGameMenu menuUserMap; 425 CGameMenuItemChain itemUserMap("< USER MAP >", 1, 0, 60, 320, 1, &menuUserMap, 0, NULL, 0, 8); 426 CGameMenuItemTitle itemUserMapTitle("USER MAP", 1, 160, 20, 2038); 427 CGameMenuFileSelect itemUserMapList("", 3, 0, 0, 0, "./", "*.map", gGameOptions.szUserMap, ShowDifficulties, 0); 428 429 CGameMenuItemTitle itemDifficultyTitle("DIFFICULTY", 1, 160, 20, 2038); 430 CGameMenuItemChain itemDifficulty1("STILL KICKING", 1, 0, 55, 320, 1, NULL, -1, SetDifficultyAndStart, 0); 431 CGameMenuItemChain itemDifficulty2("PINK ON THE INSIDE", 1, 0, 75, 320, 1, NULL, -1, SetDifficultyAndStart, 1); 432 CGameMenuItemChain itemDifficulty3("LIGHTLY BROILED", 1, 0, 95, 320, 1, NULL, -1, SetDifficultyAndStart, 2); 433 CGameMenuItemChain itemDifficulty4("WELL DONE", 1, 0, 115, 320, 1, NULL, -1, SetDifficultyAndStart, 3); 434 CGameMenuItemChain itemDifficulty5("EXTRA CRISPY", 1, 0, 135, 320, 1, 0, -1, SetDifficultyAndStart, 4); 435 CGameMenuItemChain itemDifficulty6("< CUSTOM >", 1, 0, 155, 320, 1, &menuCustomDifficulty, -1, SetCustomDifficultyMenu, 0, 8); 436 437 CGameMenuItemTitle itemCustomDifficultyTitle("CUSTOM", 1, 160, 20, 2038); 438 CGameMenuItemSlider itemCustomDifficultyStartLevel("LEVEL:", 3, 66, 35, 180, 0, 0, kMaxLevels-1, 1, NULL, -1, -1, kMenuSliderValue, 1); 439 CGameMenuItemZCycle itemCustomDifficultyMonsterSettings("MONSTERS:", 3, 66, 45, 180, 0, SetMonsters, zMonsterStrings, ARRAY_SSIZE(zMonsterStrings), 1); 440 CGameMenuItemSlider itemCustomDifficultyEnemyQuantity("ENEMIES QUANTITY:", 3, 66, 55, 180, 2, 0, 4, 1, NULL, -1, -1); 441 CGameMenuItemSlider itemCustomDifficultyEnemyHealth("ENEMIES HEALTH:", 3, 66, 65, 180, 2, 0, 4, 1, NULL, -1, -1); 442 CGameMenuItemSlider itemCustomDifficultyEnemyDifficulty("ENEMIES DIFFICULTY:", 3, 66, 75, 180, 2, 0, 4, 1, NULL, -1, -1); 443 CGameMenuItemSlider itemCustomDifficultyPlayerDamage("PLAYER DAMAGE SCALE:", 3, 66, 85, 180, 2, 0, 4, 1, NULL, -1, -1); 444 CGameMenuItemZCycle itemCustomDifficultyEnemySpeed("ENEMIES SPEED:", 3, 66, 95, 180, 0, 0, pzEnemySpeeds, ARRAY_SSIZE(pzEnemySpeeds), 0); 445 CGameMenuItemZBool itemCustomDifficultyEnemyShuffle("RANDOMIZE ENEMY POSITIONS:", 3, 66, 105, 180, false, NULL, NULL, NULL); 446 CGameMenuItemZBool itemCustomDifficultyPitchfork("PITCHFORK START:", 3, 66, 115, 180, false, NULL, NULL, NULL); 447 CGameMenuItemZBool itemCustomDifficultyPermaDeath("PERMANENT DEATH:", 3, 66, 125, 180, false, NULL, NULL, NULL); 448 CGameMenuItemChain itemCustomDifficultyBannedMonsters("SET MONSTERS", 3, 66, 137, 180, 1, &menuBannedMonsters, -1, NULL, 0); 449 CGameMenuItemChain itemCustomDifficultyBannedItems("SET ITEMS", 3, 66, 148, 180, 1, &menuBannedItems, -1, NULL, 0); 450 CGameMenuItemChain itemCustomDifficultyStart("START GAME", 1, 0, 161, 320, 1, NULL, -1, SetCustomDifficultyAndStart, 0); 451 452 CGameMenuItemTitle itemBannedMonstersTitle("SET MONSTERS", 1, 160, 20, 2038); 453 CGameMenuItemZBool itemBannedMonstersBats("BATS:", 3, 75, 40, 161, false, NULL, "REMOVE", "KEEP"); 454 CGameMenuItemZBool itemBannedMonstersRats("RATS:", 3, 75, 48, 161, false, NULL, "REMOVE", "KEEP"); 455 CGameMenuItemZBool itemBannedMonstersFish("FISH:", 3, 75, 56, 161, false, NULL, "REMOVE", "KEEP"); 456 CGameMenuItemZBool itemBannedMonstersHands("HANDS:", 3, 75, 64, 161, false, NULL, "REMOVE", "KEEP"); 457 CGameMenuItemZBool itemBannedMonstersGhosts("GHOSTS:", 3, 75, 72, 161, false, NULL, "REMOVE", "KEEP"); 458 CGameMenuItemZBool itemBannedMonstersSpiders("SPIDERS:", 3, 75, 80, 161, false, NULL, "REMOVE", "KEEP"); 459 CGameMenuItemZBool itemBannedMonstersTinyCaleb("TINY CALEBS:", 3, 75, 88, 161, false, NULL, "REMOVE", "KEEP"); 460 CGameMenuItemZBool itemBannedMonstersHellHounds("HELL HOUNDS:", 3, 75, 96, 161, false, NULL, "REMOVE", "KEEP"); 461 CGameMenuItemZBool itemBannedMonstersRatsAttack("RAT ATTACK DISTANCE:", 3, 75, 112, 161, false, NULL, "SHORTER", "DEFAULT"); 462 CGameMenuItemZBool itemBannedMonstersMotherSpiderHealth("MOTHER SPIDER HEALTH:", 3, 75, 120, 161, false, NULL, "HALF", "DEFAULT"); 463 CGameMenuItemZBool itemBannedMonstersTchernobogHealth("TCHERNOBOG HEALTH:", 3, 75, 128, 161, false, NULL, "FULL", "DEFAULT"); 464 465 CGameMenuItemTitle itemBannedItemsTitle("SET ITEMS", 1, 160, 20, 2038); 466 CGameMenuItemZBool itemBannedItemsFlare("FLARE PISTOL:", 3, 75, 32, 161, false, NULL, "REMOVE", "KEEP"); 467 CGameMenuItemZBool itemBannedItemsShotgun("SAWED-OFF:", 3, 75, 40, 161, false, NULL, "REMOVE", "KEEP"); 468 CGameMenuItemZBool itemBannedItemsTommyGun("TOMMY GUN:", 3, 75, 48, 161, false, NULL, "REMOVE", "KEEP"); 469 CGameMenuItemZBool itemBannedItemsNapalm("NAPALM LAUNCHER:", 3, 75, 56, 161, false, NULL, "REMOVE", "KEEP"); 470 CGameMenuItemZBool itemBannedItemsTNT("DYNAMITE:", 3, 75, 64, 161, false, NULL, "REMOVE", "KEEP"); 471 CGameMenuItemZBool itemBannedItemsSpray("SPRAY CAN:", 3, 75, 72, 161, false, NULL, "REMOVE", "KEEP"); 472 CGameMenuItemZBool itemBannedItemsTesla("TESLA CANNON:", 3, 75, 80, 161, false, NULL, "REMOVE", "KEEP"); 473 CGameMenuItemZBool itemBannedItemsLifeLeech("LIFE LEECH:", 3, 75, 88, 161, false, NULL, "REMOVE", "KEEP"); 474 CGameMenuItemZBool itemBannedItemsVoodoo("VOODOO DOLL:", 3, 75, 96, 161, false, NULL, "REMOVE", "KEEP"); 475 CGameMenuItemZBool itemBannedItemsProxy("PROXIMITY TNT:", 3, 75, 104, 161, false, NULL, "REMOVE", "KEEP"); 476 CGameMenuItemZBool itemBannedItemsRemote("REMOTE TNT:", 3, 75, 112, 161, false, NULL, "REMOVE", "KEEP"); 477 CGameMenuItemZBool itemBannedItemsMedKit("DOCTOR'S BAG:", 3, 75, 120, 161, false, NULL, "REMOVE", "KEEP"); 478 CGameMenuItemZBool itemBannedItemsLifeEssence("LIFE ESSENCE/MED POUCH:", 3, 75, 128, 161, false, NULL, "REMOVE", "KEEP"); 479 CGameMenuItemZBool itemBannedItemsLifeSeed("LIFE SEED:", 3, 75, 136, 161, false, NULL, "REMOVE", "KEEP"); 480 CGameMenuItemZBool itemBannedItemsSuperArmor("SUPER ARMOR:", 3, 75, 144, 161, false, NULL, "REMOVE", "KEEP"); 481 CGameMenuItemZBool itemBannedItemsCrystalBall("CRYSTAL BALL:", 3, 75, 152, 161, false, NULL, "REMOVE", "KEEP"); 482 CGameMenuItemZBool itemBannedItemsJumpBoots("JUMP BOOTS:", 3, 75, 160, 161, false, NULL, "REMOVE", "KEEP"); 483 CGameMenuItemZBool itemBannedItemsCloak("INVISIBILITY CLOAK:", 3, 75, 168, 161, false, NULL, "REMOVE", "KEEP"); 484 CGameMenuItemZBool itemBannedItemsDeathMask("INVULNERABILITY MASK:", 3, 75, 176, 161, false, NULL, "REMOVE", "KEEP"); 485 CGameMenuItemZBool itemBannedItemsAkimbo("GUNS AKIMBO:", 3, 75, 184, 161, false, NULL, "REMOVE", "KEEP"); 486 CGameMenuItemZBool itemBannedItemsReflect("REFLECTIVE SHOTS:", 3, 75, 192, 161, false, NULL, "REMOVE", "KEEP"); 487 488 CGameMenuItemTitle itemMessagesTitle("MESSAGES", 1, 160, 20, 2038); 489 CGameMenuItemZBool boolMessages("MESSAGES:", 3, 66, 70, 180, 0, SetMessages, NULL, NULL); 490 CGameMenuItemSlider sliderMsgCount("MESSAGE COUNT:", 3, 66, 80, 180, gMessageCount, 1, 16, 1, NULL, -1, -1); 491 CGameMenuItemSlider sliderMsgTime("MESSAGE TIME:", 3, 66, 90, 180, gMessageTime, 1, 8, 1, NULL, -1, -1); 492 CGameMenuItemZBool boolMsgFont("LARGE FONT:", 3, 66, 100, 180, 0, 0, NULL, NULL); 493 CGameMenuItemZBool boolMsgIncoming("INCOMING:", 3, 66, 110, 180, 0, 0, NULL, NULL); 494 CGameMenuItemZBool boolMsgSelf("SELF PICKUP:", 3, 66, 120, 180, 0, 0, NULL, NULL); 495 CGameMenuItemZBool boolMsgOther("OTHER PICKUP:", 3, 66, 130, 180, 0, 0, NULL, NULL); 496 CGameMenuItemZBool boolMsgRespawn("RESPAWN:", 3, 66, 140, 180, 0, 0, NULL, NULL); 497 498 CGameMenuItemTitle itemSaveTitle("Save Game", 1, 160, 20, 2038); 499 CGameMenuItemZEditBitmap itemSaveGame0(NULL, 3, 20, 60, 320, strRestoreGameStrings[kLoadSaveSlot0], 16, 1, SaveGame, kLoadSaveSlot0); 500 CGameMenuItemZEditBitmap itemSaveGame1(NULL, 3, 20, 70, 320, strRestoreGameStrings[kLoadSaveSlot1], 16, 1, SaveGame, kLoadSaveSlot1); 501 CGameMenuItemZEditBitmap itemSaveGame2(NULL, 3, 20, 80, 320, strRestoreGameStrings[kLoadSaveSlot2], 16, 1, SaveGame, kLoadSaveSlot2); 502 CGameMenuItemZEditBitmap itemSaveGame3(NULL, 3, 20, 90, 320, strRestoreGameStrings[kLoadSaveSlot3], 16, 1, SaveGame, kLoadSaveSlot3); 503 CGameMenuItemZEditBitmap itemSaveGame4(NULL, 3, 20, 100, 320, strRestoreGameStrings[kLoadSaveSlot4], 16, 1, SaveGame, kLoadSaveSlot4); 504 CGameMenuItemZEditBitmap itemSaveGame5(NULL, 3, 20, 110, 320, strRestoreGameStrings[kLoadSaveSlot5], 16, 1, SaveGame, kLoadSaveSlot5); 505 CGameMenuItemZEditBitmap itemSaveGame6(NULL, 3, 20, 120, 320, strRestoreGameStrings[kLoadSaveSlot6], 16, 1, SaveGame, kLoadSaveSlot6); 506 CGameMenuItemZEditBitmap itemSaveGame7(NULL, 3, 20, 130, 320, strRestoreGameStrings[kLoadSaveSlot7], 16, 1, SaveGame, kLoadSaveSlot7); 507 CGameMenuItemZEditBitmap itemSaveGame8(NULL, 3, 20, 140, 320, strRestoreGameStrings[kLoadSaveSlot8], 16, 1, SaveGame, kLoadSaveSlot8); 508 CGameMenuItemZEditBitmap itemSaveGame9(NULL, 3, 20, 150, 320, strRestoreGameStrings[kLoadSaveSlot9], 16, 1, SaveGame, kLoadSaveSlot9); 509 CGameMenuItemZEditBitmap itemSaveGameQuick(NULL, 3, 20, 163, 320, strRestoreGameStrings[kLoadSaveSlotQuick], 16, 1, SaveGame, kLoadSaveSlotQuick); 510 CGameMenuItemZEditBitmap itemSaveGameAutosaveStart(NULL, 3, 20, 176, 320, strRestoreGameStrings[kLoadSaveSlotSpawn], 16, 1, SaveGame, kLoadSaveSlotSpawn); 511 CGameMenuItemZEditBitmap itemSaveGameAutosaveKey(NULL, 3, 20, 186, 320, strRestoreGameStrings[kLoadSaveSlotKey], 16, 1, SaveGame, kLoadSaveSlotKey); 512 CGameMenuItemBitmapLS itemSaveGamePic(NULL, 3, 0, 0, 2050); 513 514 CGameMenuItemTitle itemLoadTitle("Load Game", 1, 160, 20, 2038); 515 CGameMenuItemZEditBitmap itemLoadGame0(NULL, 3, 20, 60, 320, strRestoreGameStrings[kLoadSaveSlot0], 16, 1, LoadGame, kLoadSaveSlot0); 516 CGameMenuItemZEditBitmap itemLoadGame1(NULL, 3, 20, 70, 320, strRestoreGameStrings[kLoadSaveSlot1], 16, 1, LoadGame, kLoadSaveSlot1); 517 CGameMenuItemZEditBitmap itemLoadGame2(NULL, 3, 20, 80, 320, strRestoreGameStrings[kLoadSaveSlot2], 16, 1, LoadGame, kLoadSaveSlot2); 518 CGameMenuItemZEditBitmap itemLoadGame3(NULL, 3, 20, 90, 320, strRestoreGameStrings[kLoadSaveSlot3], 16, 1, LoadGame, kLoadSaveSlot3); 519 CGameMenuItemZEditBitmap itemLoadGame4(NULL, 3, 20, 100, 320, strRestoreGameStrings[kLoadSaveSlot4], 16, 1, LoadGame, kLoadSaveSlot4); 520 CGameMenuItemZEditBitmap itemLoadGame5(NULL, 3, 20, 110, 320, strRestoreGameStrings[kLoadSaveSlot5], 16, 1, LoadGame, kLoadSaveSlot5); 521 CGameMenuItemZEditBitmap itemLoadGame6(NULL, 3, 20, 120, 320, strRestoreGameStrings[kLoadSaveSlot6], 16, 1, LoadGame, kLoadSaveSlot6); 522 CGameMenuItemZEditBitmap itemLoadGame7(NULL, 3, 20, 130, 320, strRestoreGameStrings[kLoadSaveSlot7], 16, 1, LoadGame, kLoadSaveSlot7); 523 CGameMenuItemZEditBitmap itemLoadGame8(NULL, 3, 20, 140, 320, strRestoreGameStrings[kLoadSaveSlot8], 16, 1, LoadGame, kLoadSaveSlot8); 524 CGameMenuItemZEditBitmap itemLoadGame9(NULL, 3, 20, 150, 320, strRestoreGameStrings[kLoadSaveSlot9], 16, 1, LoadGame, kLoadSaveSlot9); 525 CGameMenuItemZEditBitmap itemLoadGameQuick(NULL, 3, 20, 163, 320, strRestoreGameStrings[kLoadSaveSlotQuick], 16, 1, LoadGame, kLoadSaveSlotQuick); 526 CGameMenuItemZEditBitmap itemLoadGameAutosaveStart(NULL, 3, 20, 176, 320, strRestoreGameStrings[kLoadSaveSlotSpawn], 16, 1, LoadGame, kLoadSaveSlotSpawn); 527 CGameMenuItemZEditBitmap itemLoadGameAutosaveKey(NULL, 3, 20, 186, 320, strRestoreGameStrings[kLoadSaveSlotKey], 16, 1, LoadGame, kLoadSaveSlotKey); 528 CGameMenuItemBitmapLS itemLoadGamePic(NULL, 3, 0, 0, 2518); 529 530 CGameMenu menuMultiUserMaps; 531 532 CGameMenuItemTitle itemNetStartUserMapTitle("USER MAP", 1, 160, 20, 2038); 533 CGameMenuFileSelect menuMultiUserMap("", 3, 0, 0, 0, "./", "*.map", zUserMapName); 534 535 void SetNetGameMode(CGameMenuItemZCycle *pItem); 536 void SetNetShowWeapon(CGameMenuItemZCycle *pItem); 537 void SetNetMonsterMenu(CGameMenuItemZCycle *pItem); 538 539 CGameMenuItemTitle itemNetStartTitle("MULTIPLAYER", 1, 160, 20, 2038); 540 CGameMenuItemChain itemNetStart1("GAME:", 3, 66, 35, 180, 0, &menuNetworkGameMode, -1, NULL, 0); 541 CGameMenuItemZCycle itemNetStart2("EPISODE:", 3, 66, 45, 180, 0, SetupNetLevels, NULL, 0, 0); 542 CGameMenuItemZCycle itemNetStart3("LEVEL:", 3, 66, 55, 180, 0, NetClearUserMap, NULL, 0, 0); 543 CGameMenuItemZCycle itemNetStart4("DIFFICULTY:", 3, 66, 65, 180, 0, SetNetMonsterMenu, zDiffStrings, ARRAY_SSIZE(zDiffStrings), 0); 544 CGameMenuItemChain itemNetStart5("MONSTER SETTING:", 3, 66, 75, 180, 0, &menuNetworkGameMonsters, -1, NULL, 0); 545 CGameMenuItemZCycle itemNetStart6("WEAPONS:", 3, 66, 85, 180, 0, 0, zWeaponStrings, 4, 0); 546 CGameMenuItemZCycle itemNetStart7("ITEMS:", 3, 66, 95, 180, 0, 0, zItemStrings, 3, 0); 547 CGameMenuItemZBool itemNetStartBoolChaseView("CHASE VIEW:", 3, 66, 105, 180, false, NULL, NULL, NULL); 548 CGameMenuItemZBool itemNetStartBoolHolstering("HOLSTERING:", 3, 66, 115, 180, false, NULL, NULL, NULL); 549 CGameMenuItemZBool itemNetStartBoolSecondWind("SECOND WIND:", 3, 66, 125, 180, true, 0, NULL, NULL); 550 CGameMenuItemZBool itemNetStartBoolSpectatorMode("SPECTATING:", 3, 66, 135, 180, false, 0, NULL, NULL); 551 CGameMenuItemChain itemNetStart8("SET ITEMS", 3, 0, 143, 320, 1, &menuBannedItems, -1, NULL, 0); 552 CGameMenuItemChain itemNetStart9("SET MUTATORS", 3, 0, 153, 320, 1, &menuNetworkGameMutators, -1, NULL, 0); 553 CGameMenuItemChain itemNetStart10("USER MAP", 3, 0, 163, 320, 1, &menuMultiUserMaps, 0, NULL, 0); 554 CGameMenuItemChain itemNetStart11("START GAME", 1, 0, 175, 320, 1, 0, -1, StartNetGame, 0); 555 556 CGameMenuItemTitle itemNetGameTitle("GAME SETTINGS", 1, 160, 20, 2038); 557 CGameMenuItemZCycle itemNetGameMode("GAME:", 3, 66, 35, 180, 0, SetNetGameMode, zNetGameTypes, ARRAY_SSIZE(zNetGameTypes), 0); 558 CGameMenuItemSlider itemNetGameSliderScoreLimit("SCORE LIMIT:", 3, 66, 44, 180, 0, 0, 255, 1, NULL, -1, -1, kMenuSliderValue); 559 CGameMenuItemSlider itemNetGameSliderLivesLimit("LIVES:", 3, 66, 44, 180, 0, 0, 255, 1, NULL, -1, -1, kMenuSliderValue); 560 CGameMenuItemSlider itemNetGameSliderTimeLimit("TIME LIMIT:", 3, 66, 54, 180, 0, 0, 60, 1, NULL, -1, -1, kMenuSliderValue); 561 CGameMenuItemZBool itemNetGameBoolExit("LEVEL EXIT:", 3, 66, 65, 180, true, NULL, NULL, NULL); 562 CGameMenuItemZBool itemNetGameBoolTeleFrag("TELEFRAGS:", 3, 66, 73, 180, true, NULL, NULL, NULL); 563 CGameMenuItemZBool itemNetGameBoolSkillOverride("PLAYER HANDICAP:", 3, 66, 81, 180, true, NULL, "ALLOWED", "OFF"); 564 CGameMenuItemZBool itemNetGameBoolModelOverride("PLAYER MODEL:", 3, 66, 89, 180, true, NULL, "CULTISTS/CALEB", "CALEB ONLY"); 565 CGameMenuItemZBool itemNetGameBoolPlayerColors("PLAYER COLORS:", 3, 66, 97, 180, true, 0, "EXTENDED", "VANILLA"); 566 CGameMenuItemZBool itemNetGameBoolFriendlyFire("FRIENDLY FIRE:", 3, 66, 105, 180, true, 0, NULL, NULL); 567 CGameMenuItemZCycle itemNetGameCycleKey("KEYS SETTING:", 3, 66, 113, 180, 0, 0, zKeyStrings, ARRAY_SSIZE(zKeyStrings), 0); 568 CGameMenuItemZCycle itemNetGameCycleItemWeapon("ITEM/WEAPON SETTING:", 3, 66, 121, 180, 0, SetNetGameMode, zKeepItemWeaponStrings, ARRAY_SSIZE(zKeepItemWeaponStrings), 0); 569 CGameMenuItemZBool itemNetGameBoolTeamColors("TEAM COLORS:", 3, 66, 97, 180, true, 0, NULL, NULL); 570 CGameMenuItemZBool itemNetGameBoolAutoTeams("AUTO TEAMS:", 3, 66, 113, 180, true, 0, NULL, NULL); 571 CGameMenuItemZBool itemNetGameBoolTeamFlags("TEAM FLAGS:", 3, 66, 121, 180, true, 0, NULL, NULL); 572 CGameMenuItemZCycle itemNetGameCycleSpawnLocation("SPAWN AREA:", 3, 66, 129, 180, 0, 0, zRespawnStrings, ARRAY_SSIZE(zRespawnStrings), 0); 573 CGameMenuItemZCycle itemNetGameCycleShowWeaponsOverride("ENEMY WEAPONS:", 3, 66, 137, 180, 0, SetNetShowWeapon, zShowWeapon, ARRAY_SSIZE(zShowWeapon), 0); 574 CGameMenuItemZCycle itemNetGameCycleShowWeaponsOverrideTeams("ENEMY WEAPONS:", 3, 66, 137, 180, 0, SetNetShowWeapon, zShowWeaponTeams, ARRAY_SSIZE(zShowWeaponTeams), 0); 575 CGameMenuItemZCycle itemNetGameCycleSpawnProtection("SPAWN PROTECTION:", 3, 66, 145, 180, 0, 0, zSpawnProtectStrings, ARRAY_SSIZE(zSpawnProtectStrings), 0); 576 CGameMenuItemZCycle itemNetGameCycleSpawnWeapon("SPAWN WITH WEAPON:", 3, 66, 153, 180, 0, SetNetGameMode, zSpawnWeaponStrings, ARRAY_SSIZE(zSpawnWeaponStrings), 0); 577 CGameMenuItemZCycle itemNetGameCycleMirrorModeOverride("MIRROR MODE:", 3, 66, 161, 180, 0, NULL, pzMirrorModeStrings, ARRAY_SSIZE(pzMirrorModeStrings), 0); 578 579 CGameMenuItemTitle itemNetMonsterTitle("MONSTERS", 1, 160, 20, 2038); 580 CGameMenuItemZCycle itemNetMonsterSettings("MONSTERS:", 3, 66, 40, 180, 0, SetNetMonsterMenu, zMonsterStrings, ARRAY_SSIZE(zMonsterStrings), 0); 581 CGameMenuItemSlider itemNetMonsterQuantity("MONSTER QUANTITY:", 3, 66, 50, 180, 2, 0, 4, 1, NULL, -1, -1); 582 CGameMenuItemSlider itemNetMonsterHealth("MONSTER HEALTH:", 3, 66, 60, 180, 2, 0, 4, 1, NULL, -1, -1); 583 CGameMenuItemZCycle itemNetMonsterSpeed("MONSTER SPEED:", 3, 66, 70, 180, 0, 0, pzEnemySpeeds, ARRAY_SSIZE(pzEnemySpeeds), 0); 584 CGameMenuItemZBool itemNetMonsterBats("BATS:", 3, 75, 90, 161, false, NULL, "REMOVE", "KEEP"); 585 CGameMenuItemZBool itemNetMonsterRats("RATS:", 3, 75, 98, 161, false, NULL, "REMOVE", "KEEP"); 586 CGameMenuItemZBool itemNetMonsterFish("FISH:", 3, 75, 106, 161, false, NULL, "REMOVE", "KEEP"); 587 CGameMenuItemZBool itemNetMonsterHands("HANDS:", 3, 75, 114, 161, false, NULL, "REMOVE", "KEEP"); 588 CGameMenuItemZBool itemNetMonsterGhosts("GHOSTS:", 3, 75, 122, 161, false, NULL, "REMOVE", "KEEP"); 589 CGameMenuItemZBool itemNetMonsterSpiders("SPIDERS:", 3, 75, 130, 161, false, NULL, "REMOVE", "KEEP"); 590 CGameMenuItemZBool itemNetMonsterTinyCaleb("TINY CALEBS:", 3, 75, 138, 161, false, NULL, "REMOVE", "KEEP"); 591 CGameMenuItemZBool itemNetMonsterHellHounds("HELL HOUNDS:", 3, 75, 146, 161, false, NULL, "REMOVE", "KEEP"); 592 CGameMenuItemZBool itemNetMonsterRatsAttack("RAT ATTACK DISTANCE:", 3, 75, 162, 161, false, NULL, "SHORTER", "DEFAULT"); 593 CGameMenuItemZBool itemNetMonsterMotherSpiderHealth("MOTHER SPIDER HEALTH:", 3, 75, 170, 161, false, NULL, "HALF", "DEFAULT"); 594 CGameMenuItemZBool itemNetMonsterTchernobogHealth("TCHERNOBOG HEALTH:", 3, 75, 178, 161, false, NULL, "FULL", "DEFAULT"); 595 596 /////////////// 597 CGameMenuItemZBool itemNetMutatorBoolQuadDamagePowerup("REPLACE AKIMBO WITH 4X DAMAGE:", 3, 66, 32, 180, false, NULL, NULL, NULL); 598 CGameMenuItemZCycle itemNetMutatorDamageInvul("INVULNERABILITY DURATION:", 3, 66, 42, 180, 0, NULL, pzDamageInvulBehaviorStrings, ARRAY_SSIZE(pzDamageInvulBehaviorStrings), 0); 599 CGameMenuItemZCycle itemNetMutatorProjectileBehavior("PROJECTILES BEHAVIOR:", 3, 66, 52, 180, 0, NULL, pzProjectileBehaviorStrings, ARRAY_SSIZE(pzProjectileBehaviorStrings), 0); 600 CGameMenuItemZBool itemNetMutatorNapalmFalloff("NAPALM GRAVITY FALLOFF:", 3, 66, 62, 180, false, NULL, NULL, NULL); 601 CGameMenuItemZCycle itemNetMutatorEnemyBehavior("ENEMY BEHAVIOR:", 3, 66, 72, 180, false, NULL, pzEnemyBehaviorStrings, ARRAY_SSIZE(pzEnemyBehaviorStrings), 0); 602 CGameMenuItemZBool itemNetMutatorBoolEnemyRandomTNT("RANDOM CULTIST TNT:", 3, 66, 82, 180, false, NULL, NULL, NULL); 603 CGameMenuItemZCycle itemNetMutatorWeaponsVer("WEAPON BEHAVIOR:", 3, 66, 92, 180, 0, NULL, pzWeaponsVersionStrings, ARRAY_SSIZE(pzWeaponsVersionStrings), 0); 604 CGameMenuItemZCycle itemNetMutatorAmmoScale("AMMO PICKUP SCALE:", 3, 66, 102, 180, 0, NULL, pzAmmoScaleStrings, ARRAY_SSIZE(pzAmmoScaleStrings), 0); 605 CGameMenuItemZBool itemNetMutatorSectorBehavior("SECTOR BEHAVIOR:", 3, 66, 112, 180, false, NULL, "NOTBLOOD", "ORIGINAL"); 606 CGameMenuItemZCycle itemNetMutatorHitscanProjectiles("HITSCAN PROJECTILES:", 3, 66, 122, 180, 0, NULL, pzHitscanProjectilesStrings, ARRAY_SSIZE(pzHitscanProjectilesStrings), 0); 607 CGameMenuItemZCycle itemNetMutatorGoreBehavior("GORE BEHAVIOR:", 3, 66, 132, 180, 0, NULL, pzGoreStrings, ARRAY_SSIZE(pzGoreStrings), 0); 608 CGameMenuItemZCycle itemNetMutatorPlayerSpeed("PLAYER SPEED:", 3, 66, 142, 180, 0, NULL, pzPlayerSpeeds, ARRAY_SSIZE(pzPlayerSpeeds), 0); 609 CGameMenuItemZCycle itemNetMutatorRandomizerMode("RANDOMIZER MODE:", 3, 66, 152, 180, 0, NULL, pzRandomizerModeStrings, ARRAY_SSIZE(pzRandomizerModeStrings), 0); 610 CGameMenuItemZEdit itemNetMutatorRandomizerSeed("RANDOMIZER SEED:", 3, 66, 162, 180, szRandomizerSeedMenu, sizeof(szRandomizerSeedMenu), 0, SetRandomizerSeed, 0); 611 /////////////////// 612 613 CGameMenuItemText itemLoadingText("LOADING...", 1, 160, 100, 1); 614 615 CGameMenuItemTitle itemQuitTitle("QUIT", 1, 160, 20, 2038); 616 CGameMenuItemText itemQuitText1("Do you really want to quit?", 0, 160, 100, 1); 617 CGameMenuItemYesNoQuit itemQuitYesNo("[Y/N]", 0, 20, 110, 280, 1, 0); 618 619 CGameMenuItemTitle itemRestartTitle("RESTART GAME", 1, 160, 20, 2038); 620 CGameMenuItemText itemRestartText1("Do you really want to restart game?", 0, 160, 100, 1); 621 CGameMenuItemYesNoQuit itemRestartYesNo("[Y/N]", 0, 20, 110, 280, 1, 1); 622 623 CGameMenuItemPicCycle itemCreditsPicCycle(0, 0, NULL, NULL, 0, 0); 624 CGameMenuItemPicCycle itemOrderPicCycle(0, 0, NULL, NULL, 0, 0); 625 626 enum resflags_t { 627 RES_FS = 0x1, 628 RES_WIN = 0x2, 629 }; 630 631 #define MAXRESOLUTIONSTRINGLENGTH 19 632 633 struct resolution_t { 634 int32_t xdim, ydim; 635 int32_t flags; 636 int32_t bppmax; 637 char name[MAXRESOLUTIONSTRINGLENGTH]; 638 }; 639 640 resolution_t gResolution[MAXVALIDMODES]; 641 int gResolutionNum; 642 const char *gResolutionName[MAXVALIDMODES]; 643 644 CGameMenu menuOptions; 645 CGameMenu menuOptionsGame; 646 CGameMenu menuOptionsGameMutators; 647 CGameMenu menuOptionsDisplay; 648 CGameMenu menuOptionsDisplayView; 649 CGameMenu menuOptionsDisplayColor; 650 CGameMenu menuOptionsDisplayMode; 651 #ifdef USE_OPENGL 652 CGameMenu menuOptionsDisplayPolymost; 653 #endif 654 CGameMenu menuOptionsSound; 655 CGameMenu menuOptionsPlayer; 656 CGameMenu menuOptionsControl; 657 658 void SetupOptionsSound(CGameMenuItemChain *pItem); 659 void SetupPollJoystick(CGameMenuItemChain *pItem); 660 661 CGameMenuItemTitle itemOptionsTitle("OPTIONS", 1, 160, 20, 2038); 662 CGameMenuItemChain itemOptionsChainGame("GAME SETUP", 1, 0, 50, 320, 1, &menuOptionsGame, -1, NULL, 0); 663 CGameMenuItemChain itemOptionsChainDisplay("DISPLAY SETUP", 1, 0, 70, 320, 1, &menuOptionsDisplay, -1, NULL, 0); 664 CGameMenuItemChain itemOptionsChainSound("SOUND SETUP", 1, 0, 90, 320, 1, &menuOptionsSound, -1, SetupOptionsSound, 0); 665 CGameMenuItemChain itemOptionsChainPlayer("PLAYER SETUP", 1, 0, 110, 320, 1, &menuOptionsPlayer, -1, NULL, 0); 666 CGameMenuItemChain itemOptionsChainControl("CONTROL SETUP", 1, 0, 130, 320, 1, &menuOptionsControl, -1, SetupPollJoystick, 0); 667 CGameMenuItemChain itemOptionsChainMutators("MUTATORS", 1, 0, 150, 320, 1, &menuOptionsGameMutators, -1, NULL, 0); 668 669 const char *pzAutoAimStrings[] = { 670 "NEVER", 671 "ALWAYS", 672 "HITSCAN ONLY", 673 "HITSCAN RATS/EELS ONLY", 674 "PITCHFORK ONLY" 675 }; 676 677 const char *pzWeaponSwitchStrings[] = { 678 "NEVER", 679 "BY RATING", 680 "IF NEW", 681 "IF HOLDING PITCHFORK" 682 }; 683 684 const char *pzAutosaveModeStrings[] = { 685 "OFF", 686 "NEW LEVEL", 687 "KEYS+NEW LEVEL", 688 }; 689 690 const char *pzVanillaModeStrings[] = { 691 "OFF", 692 "ON", 693 "DOS MOUSE+ON", 694 }; 695 696 const char *pzCrosshairStrings[] = { 697 "OFF", 698 "ON", 699 "ON (AUTO AIM)" 700 }; 701 702 const char *pzStatsPowerupRatioStrings[] = { 703 "OFF", 704 "ON", 705 "ON (4:3)", 706 "ON (16:10)", 707 "ON (16:9)", 708 "ON (21:9)", 709 }; 710 711 const char *pzWeaponSelectStrings[] = { 712 "OFF", 713 "BOTTOM", 714 "TOP" 715 }; 716 717 const char *pzHudRatioStrings[] = { 718 "NATIVE", 719 "4:3", 720 "16:10", 721 "16:9", 722 "21:9", 723 }; 724 725 const char *pzWeaponHBobbingStrings[] = { 726 "OFF", 727 "ORIGINAL", 728 "V1.0X", 729 }; 730 731 const char *pzWeaponInterpolateStrings[] = { 732 "OFF", 733 "ONLY SWAYING", 734 "ALL ANIMATION" 735 }; 736 737 const char *pzSecretStyleStrings[] = { 738 "ORIGINAL", 739 "NOTBLOOD", 740 "GZDOOM" 741 }; 742 743 void SetAutoAim(CGameMenuItemZCycle *pItem); 744 void SetAutoAimRange(CGameMenuItemSlider *pItem); 745 void SetAutoRun(CGameMenuItemZBool *pItem); 746 void SetLevelStats(CGameMenuItemZCycle *pItem); 747 void SetLevelStatsOnAutomap(CGameMenuItemZBool *pItem); 748 void SetPowerupDuration(CGameMenuItemZCycle *pItem); 749 void SetPowerupStyle(CGameMenuItemZBool *pItem); 750 void SetSecretStyle(CGameMenuItemZCycle *pItem); 751 void SetShowMapTitle(CGameMenuItemZBool *pItem); 752 void SetWeaponSwitch(CGameMenuItemZCycle *pItem); 753 void SetWeaponFastSwitch(CGameMenuItemZBool *pItem); 754 void SetAutosaveMode(CGameMenuItemZCycle *pItem); 755 void SetLockSaving(CGameMenuItemZBool *pItem); 756 void SetRestoreLastSave(CGameMenuItemZBool *pItem); 757 void SetVanillaMode(CGameMenuItemZCycle *pItem); 758 759 /////////////// 760 CGameMenuItemTitle itemGameMutatorsTitle("MUTATORS", 1, 160, 20, 2038); 761 CGameMenuItemZBool itemMutatorBoolQuadDamagePowerup("REPLACE AKIMBO WITH 4X DAMAGE:", 3, 66, 32, 180, false, SetQuadDamagePowerup, NULL, NULL); 762 CGameMenuItemZCycle itemMutatorDamageInvul("INVULNERABILITY DURATION:", 3, 66, 42, 180, 0, SetDamageInvul, pzDamageInvulBehaviorStrings, ARRAY_SSIZE(pzDamageInvulBehaviorStrings), 0); 763 CGameMenuItemZCycle itemMutatorProjectileBehavior("PROJECTILES BEHAVIOR:", 3, 66, 52, 180, 0, SetProjectileBehavior, pzProjectileBehaviorStrings, ARRAY_SSIZE(pzProjectileBehaviorStrings), 0); 764 CGameMenuItemZBool itemMutatorNapalmFalloff("NAPALM GRAVITY FALLOFF:", 3, 66, 62, 180, false, SetNapalmFalloff, NULL, NULL); 765 CGameMenuItemZCycle itemMutatorEnemyBehavior("ENEMY BEHAVIOR:", 3, 66, 72, 180, 0, SetEnemyBehavior, pzEnemyBehaviorStrings, ARRAY_SSIZE(pzEnemyBehaviorStrings), 0); 766 CGameMenuItemZBool itemMutatorBoolEnemyRandomTNT("RANDOM CULTIST TNT:", 3, 66, 82, 180, false, SetEnemyRandomTNT, NULL, NULL); 767 CGameMenuItemZCycle itemMutatorWeaponsVer("WEAPON BEHAVIOR:", 3, 66, 92, 180, 0, SetWeaponsVer, pzWeaponsVersionStrings, ARRAY_SSIZE(pzWeaponsVersionStrings), 0); 768 CGameMenuItemZCycle itemMutatorAmmoScale("AMMO PICKUP SCALE:", 3, 66, 102, 180, 0, SetAmmoScale, pzAmmoScaleStrings, ARRAY_SSIZE(pzAmmoScaleStrings), 0); 769 CGameMenuItemZBool itemMutatorSectorBehavior("SECTOR BEHAVIOR:", 3, 66, 112, 180, false, SetSectorBehavior, "NOTBLOOD", "ORIGINAL"); 770 CGameMenuItemZCycle itemMutatorHitscanProjectiles("HITSCAN PROJECTILES:", 3, 66, 122, 180, 0, SetHitscanProjectiles, pzHitscanProjectilesStrings, ARRAY_SSIZE(pzHitscanProjectilesStrings), 0); 771 CGameMenuItemZCycle itemMutatorGoreBehavior("GORE BEHAVIOR:", 3, 66, 132, 180, 0, SetGoreMode, pzGoreStrings, ARRAY_SSIZE(pzGoreStrings), 0); 772 CGameMenuItemZCycle itemMutatorPlayerSpeed("PLAYER SPEED:", 3, 66, 142, 180, 0, SetPlayerSpeed, pzPlayerSpeeds, ARRAY_SSIZE(pzPlayerSpeeds), 0); 773 CGameMenuItemZCycle itemMutatorRandomizerMode("RANDOMIZER MODE:", 3, 66, 152, 180, 0, SetRandomizerMode, pzRandomizerModeStrings, ARRAY_SSIZE(pzRandomizerModeStrings), 0); 774 CGameMenuItemZEdit itemMutatorRandomizerSeed("RANDOMIZER SEED:", 3, 66, 162, 180, szRandomizerSeedMenu, sizeof(szRandomizerSeedMenu), 0, SetRandomizerSeed, 0); 775 /////////////////// 776 777 CGameMenuItemTitle itemOptionsGameTitle("GAME SETUP", 1, 160, 20, 2038); 778 CGameMenuItemZCycle itemOptionsGameCycleAutoAim("AUTO AIM:", 3, 66, 60, 180, 0, SetAutoAim, pzAutoAimStrings, ARRAY_SSIZE(pzAutoAimStrings), 0); 779 CGameMenuItemSlider itemOptionsGameSliderAutoAimRange("AUTO AIM RANGE:", 3, 66, 70, 180, &gAutoAimRange, 0, 9, 1, SetAutoAimRange, -1, -1, kMenuSliderPercent, 1, 2); 780 CGameMenuItemZBool itemOptionsGameBoolAutoRun("AUTO RUN:", 3, 66, 80, 180, 0, SetAutoRun, NULL, NULL); 781 CGameMenuItemZCycle itemOptionsGameWeaponSwitch("EQUIP PICKUPS:", 3, 66, 90, 180, 0, SetWeaponSwitch, pzWeaponSwitchStrings, ARRAY_SSIZE(pzWeaponSwitchStrings), 0); 782 CGameMenuItemZBool itemOptionsGameWeaponFastSwitch("FAST WEAPON SWITCH:", 3, 66, 100, 180, 0, SetWeaponFastSwitch, NULL, NULL); 783 CGameMenuItemZCycle itemOptionsGameAutosaveMode("AUTOSAVE TRIGGER:", 3, 66, 120, 180, 0, SetAutosaveMode, pzAutosaveModeStrings, ARRAY_SSIZE(pzAutosaveModeStrings), 0); 784 CGameMenuItemZBool itemOptionsGameLockSaving("LOCK MANUAL SAVING:", 3, 66, 130, 180, 0, SetLockSaving, "AUTOSAVES ONLY", "NEVER"); 785 CGameMenuItemZBool itemOptionsGameRestoreLastSave("ASK TO RESTORE LAST SAVE:", 3, 66, 140, 180, 0, SetRestoreLastSave, NULL, NULL); 786 CGameMenuItemZCycle itemOptionsGameBoolVanillaMode("VANILLA MODE:", 3, 66, 150, 180, 0, SetVanillaMode, pzVanillaModeStrings, ARRAY_SSIZE(pzVanillaModeStrings), 0); 787 788 CGameMenuItemTitle itemOptionsDisplayTitle("DISPLAY SETUP", 1, 160, 20, 2038); 789 CGameMenuItemChain itemOptionsDisplayColor("COLOR CORRECTION", 3, 66, 40, 180, 0, &menuOptionsDisplayColor, -1, NULL, 0); 790 CGameMenuItemChain itemOptionsDisplayMode("VIDEO MODE", 3, 66, 50, 180, 0, &menuOptionsDisplayMode, -1, SetupVideoModeMenu, 0); 791 CGameMenuItemChain itemOptionsDisplayView("VIEW SETUP", 3, 66, 60, 180, 0, &menuOptionsDisplayView, -1, NULL, 0); 792 CGameMenuItemSlider itemOptionsDisplaySliderDetail("DETAIL:", 3, 66, 80, 180, &gDetail, 0, 4, 1, SetDetail, -1, -1); 793 CGameMenuItemZBool itemOptionsDisplayBoolVoxels("VOXELS:", 3, 66, 90, 180, 0, SetVoxels, NULL, NULL); 794 CGameMenuItemZCycle itemOptionsDisplayCrosshair("CROSSHAIR:", 3, 66, 100, 180, 0, SetCrosshair, pzCrosshairStrings, ARRAY_SSIZE(pzCrosshairStrings), 0); 795 CGameMenuItemZCycle itemOptionsDisplayLevelStats("LEVEL STATS:", 3, 66, 110, 180, 0, SetLevelStats, pzStatsPowerupRatioStrings, ARRAY_SSIZE(pzStatsPowerupRatioStrings), 0); 796 CGameMenuItemZBool itemOptionsDisplayLevelStatsOnAutomap("LEVEL STATS ON AUTOMAP ONLY:", 3, 66, 120, 180, gLevelStatsOnlyOnMap, SetLevelStatsOnAutomap, NULL, NULL); 797 CGameMenuItemZCycle itemOptionsDisplayPowerupDuration("POWERUP DURATION:", 3, 66, 130, 180, 0, SetPowerupDuration, pzStatsPowerupRatioStrings, ARRAY_SSIZE(pzStatsPowerupRatioStrings), 0); 798 CGameMenuItemZBool itemOptionsDisplayBoolShowMapTitle("MAP TITLE:", 3, 66, 140, 180, gShowMapTitle, SetShowMapTitle, NULL, NULL); 799 CGameMenuItemZBool itemOptionsDisplayBoolMessages("MESSAGES:", 3, 66, 150, 180, gMessageState, SetMessages, NULL, NULL); 800 CGameMenuItemZBool itemOptionsDisplayBoolWidescreen("WIDESCREEN:", 3, 66, 160, 180, r_usenewaspect, SetWidescreen, NULL, NULL); 801 CGameMenuItemZCycle itemOptionsDisplayWeaponSelect("SHOW WEAPON SELECT:", 3, 66, 170, 180, 0, SetWeaponSelectMode, pzWeaponSelectStrings, ARRAY_SSIZE(pzWeaponSelectStrings), 0); 802 CGameMenuItemSlider itemOptionsDisplayFOV("FOV:", 3, 66, 180, 180, &gFov, 75, 140, 1, SetFOV, -1, -1, kMenuSliderValue); 803 804 const char *pzRendererStrings[] = { 805 "CLASSIC", 806 "POLYMOST" 807 }; 808 809 const int nRendererValues[] = { 810 REND_CLASSIC, 811 REND_POLYMOST 812 }; 813 814 const char *pzVSyncStrings[] = { 815 "ADAPTIVE", 816 "OFF", 817 "ON", 818 #if defined USE_OPENGL && defined _WIN32 && defined RENDERTYPESDL 819 "KMT" 820 #endif 821 }; 822 823 const int nVSyncValues[] = { 824 -1, 825 0, 826 1, 827 #if defined USE_OPENGL && defined _WIN32 && defined RENDERTYPESDL 828 2 829 #endif 830 }; 831 832 const char *pzFrameLimitStrings[] = { 833 "30 FPS", 834 "60 FPS", 835 "75 FPS", 836 "100 FPS", 837 "120 FPS", 838 "144 FPS", 839 "165 FPS", 840 "240 FPS" 841 }; 842 843 const int nFrameLimitValues[] = { 844 30, 845 60, 846 75, 847 100, 848 120, 849 144, 850 165, 851 240 852 }; 853 854 const char *pzInvertPaletteStrings[] = { 855 "OFF", 856 "ON", 857 "INVERT TWICE", 858 }; 859 860 861 void PreDrawVideoModeMenu(CGameMenuItem *); 862 863 CGameMenuItemTitle itemOptionsDisplayModeTitle("VIDEO MODE", 1, 160, 20, 2038); 864 CGameMenuItemZCycle itemOptionsDisplayModeResolution("RESOLUTION:", 3, 66, 60, 180, 0, NULL, NULL, 0, 0, true); 865 CGameMenuItemZCycle itemOptionsDisplayModeRenderer("RENDERER:", 3, 66, 70, 180, 0, NULL, pzRendererStrings, 2, 0); 866 #ifdef USE_OPENGL 867 CGameMenuItemChain itemOptionsDisplayModePolymost("POLYMOST SETUP", 3, 66, 80, 180, 0, &menuOptionsDisplayPolymost, -1, SetupVideoPolymostMenu, 0); 868 #endif 869 CGameMenuItemZBool itemOptionsDisplayModeFullscreen("FULLSCREEN:", 3, 66, 90, 180, 0, NULL, NULL, NULL); 870 CGameMenuItemZCycle itemOptionsDisplayModeVSync("VSYNC:", 3, 66, 100, 180, 0, NULL, pzVSyncStrings, ARRAY_SSIZE(pzVSyncStrings), 0); 871 CGameMenuItemZCycle itemOptionsDisplayModeFrameLimit("FRAMERATE LIMIT:", 3, 66, 110, 180, 0, UpdateVideoModeMenuFrameLimit, pzFrameLimitStrings, 8, 0); 872 CGameMenuItemChain itemOptionsDisplayModeApply("APPLY CHANGES", 3, 66, 125, 180, 0, NULL, 0, SetVideoMode, 0); 873 874 void PreDrawDisplayColor(CGameMenuItem *); 875 876 CGameMenuItemTitle itemOptionsDisplayColorTitle("COLOR CORRECTION", 1, 160, 20, -1); 877 CGameMenuItemZCycle itemOptionsDisplayColorPaletteCustom("PALETTE:", 3, 66, 60, 180, 0, UpdateVideoPaletteCycleMenu, srcCustomPaletteStr, ARRAY_SSIZE(srcCustomPaletteStr), 0); 878 CGameMenuItemZBool itemOptionsDisplayColorPaletteCIEDE2000("CIEDE2000 COMPARE:", 3, 66, 70, 180, 0, UpdateVideoPaletteBoolMenu, NULL, NULL); 879 CGameMenuItemZBool itemOptionsDisplayColorPaletteGrayscale("GRAYSCALE PALETTE:", 3, 66, 80, 180, 0, UpdateVideoPaletteBoolMenu, NULL, NULL); 880 CGameMenuItemZCycle itemOptionsDisplayColorPaletteInvert("INVERT PALETTE:", 3, 66, 90, 180, 0, UpdateVideoPaletteCycleMenu, pzInvertPaletteStrings, ARRAY_SSIZE(pzInvertPaletteStrings), 0); 881 CGameMenuItemSliderFloat itemOptionsDisplayColorGamma("GAMMA:", 3, 66, 100, 180, &g_videoGamma, MIN_GAMMA, MAX_GAMMA, 0.1f, UpdateVideoColorMenu, -1, -1, kMenuSliderValue); 882 CGameMenuItemSliderFloat itemOptionsDisplayColorContrast("CONTRAST:", 3, 66, 110, 180, &g_videoContrast, MIN_CONTRAST, MAX_CONTRAST, 0.05f, UpdateVideoColorMenu, -1, -1, kMenuSliderValue); 883 CGameMenuItemSliderFloat itemOptionsDisplayColorSaturation("SATURATION:", 3, 66, 120, 180, &g_videoSaturation, MIN_SATURATION, MAX_SATURATION, 0.05f, UpdateVideoColorMenu, -1, -1, kMenuSliderValue); 884 CGameMenuItemSliderFloat itemOptionsDisplayColorVisibility("VISIBILITY:", 3, 66, 130, 180, &r_ambientlight, 0.125f, 4.f, 0.125f, UpdateVideoColorMenu, -1, -1, kMenuSliderValue); 885 CGameMenuItemChain itemOptionsDisplayColorReset("RESET TO DEFAULTS", 3, 66, 150, 180, 0, NULL, 0, ResetVideoColor, 0); 886 887 CGameMenuItemTitle itemOptionsDisplayViewTitle("VIEW SETUP", 1, 160, 20, 2038); 888 CGameMenuItemSlider itemOptionsDisplayViewHudSize("HUD SIZE:", 3, 66, 40, 180, &gViewSize, 0, 9, 1, SetHudSize, -1, -1, kMenuSliderValue); 889 CGameMenuItemZCycle itemOptionsDisplayViewHudRatio("HUD ALIGNMENT:", 3, 66, 50, 180, 0, SetHudRatio, pzHudRatioStrings, ARRAY_SSIZE(pzHudRatioStrings), 0); 890 CGameMenuItemZBool itemOptionsDisplayViewBoolCenterHoriz("CENTER HORIZON LINE:", 3, 66, 60, 180, gCenterHoriz, SetCenterHoriz, NULL, NULL); 891 CGameMenuItemZBool itemOptionsDisplayViewBoolSlopeTilting("SLOPE TILTING:", 3, 66, 70, 180, gSlopeTilting, SetSlopeTilting, NULL, NULL); 892 CGameMenuItemZBool itemOptionsDisplayViewBoolViewBobbing("VIEW BOBBING:", 3, 66, 80, 180, gViewVBobbing, SetViewBobbing, NULL, NULL); 893 CGameMenuItemZBool itemOptionsDisplayViewBoolViewSwaying("VIEW SWAYING:", 3, 66, 90, 180, gViewHBobbing, SetViewSwaying, NULL, NULL); 894 CGameMenuItemZCycle itemOptionsDisplayViewWeaponSwaying("WEAPON SWAYING:", 3, 66, 100, 180, 0, SetWeaponSwaying, pzWeaponHBobbingStrings, ARRAY_SSIZE(pzWeaponHBobbingStrings), 0); 895 CGameMenuItemZCycle itemOptionsDisplayViewWeaponInterpolation("WEAPON SMOOTHING:", 3, 66, 110, 180, 0, SetWeaponInterpolate, pzWeaponInterpolateStrings, ARRAY_SSIZE(pzWeaponInterpolateStrings), 0); 896 CGameMenuItemZBool itemOptionsDisplayViewBoolInterpolation("VIEW INTERPOLATE:", 3, 66, 120, 180, gViewInterpolateMethod, SetViewInterpolate, "MODERN", "ORIGINAL"); 897 CGameMenuItemZBool itemOptionsDisplayViewBoolLevelCompleteTime("LEVEL TIME AT INTERMISSION:", 3, 66, 130, 180, gShowCompleteTime, SetLevelCompleteTime, "SHOW", "HIDE"); 898 CGameMenuItemZBool itemOptionsDisplayViewBoolPowerupStyle("POWERUP STYLE:", 3, 66, 140, 180, gPowerupStyle, SetPowerupStyle, "NOTBLOOD", "NBLOOD"); 899 CGameMenuItemZCycle itemOptionsDisplayViewSecretMessageStyle("SECRET MESSAGE STYLE:", 3, 66, 150, 180, 0, SetSecretStyle, pzSecretStyleStrings, ARRAY_SSIZE(pzSecretStyleStrings), 0); 900 CGameMenuItemZCycle itemOptionsDisplayViewMirrorMode("MIRROR MODE:", 3, 66, 160, 180, 0, SetMirrorMode, pzMirrorModeStrings, ARRAY_SSIZE(pzMirrorModeStrings), 0); 901 CGameMenuItemZBool itemOptionsDisplayViewBoolSlowRoomFlicker("SLOW FLICKERING LIGHTS:", 3, 66, 170, 180, gSlowRoomFlicker, SetSlowRoomFlicker, NULL, NULL); 902 903 #ifdef USE_OPENGL 904 const char *pzTextureModeStrings[] = { 905 "CLASSIC", 906 "FILTERED" 907 }; 908 909 int nTextureModeValues[] = { 910 TEXFILTER_OFF, 911 TEXFILTER_ON 912 }; 913 #endif 914 915 const char *pzAnisotropyStrings[] = { 916 "MAX", 917 "NONE", 918 "2X", 919 "4X", 920 "8X", 921 "16X" 922 }; 923 924 int nAnisotropyValues[] = { 925 0, 926 1, 927 2, 928 4, 929 8, 930 16 931 }; 932 933 const char *pzTexQualityStrings[] = { 934 "FULL", 935 "HALF", 936 "BARF" 937 }; 938 939 const char *pzTexCacheStrings[] = { 940 "OFF", 941 "ON", 942 "COMPRESSED" 943 }; 944 945 void UpdateTextureMode(CGameMenuItemZCycle *pItem); 946 void UpdateAnisotropy(CGameMenuItemZCycle *pItem); 947 void UpdateTrueColorTextures(CGameMenuItemZBool *pItem); 948 void UpdateTexQuality(CGameMenuItemZCycle *pItem); 949 void UpdatePreloadCache(CGameMenuItemZBool *pItem); 950 void UpdateTexCache(CGameMenuItemZCycle *pItem); 951 void UpdateDetailTex(CGameMenuItemZBool *pItem); 952 void UpdateGlowTex(CGameMenuItemZBool *pItem); 953 void Update3DModels(CGameMenuItemZBool *pItem); 954 void UpdateDeliriumBlur(CGameMenuItemZBool *pItem); 955 void UpdateTexColorIndex(CGameMenuItemZBool *pItem); 956 void UpdateShadeInterpolation(CGameMenuItemZBool *pItem); 957 void UpdateYShrearing(CGameMenuItemZBool *pItem); 958 void UpdateRollAngle(CGameMenuItemSlider *pItem); 959 #ifdef USE_OPENGL 960 void PreDrawDisplayPolymost(CGameMenuItem *pItem); 961 CGameMenuItemTitle itemOptionsDisplayPolymostTitle("POLYMOST SETUP", 1, 160, 20, 2038); 962 CGameMenuItemZCycle itemOptionsDisplayPolymostTextureMode("TEXTURE MODE:", 3, 66, 40, 180, 0, UpdateTextureMode, pzTextureModeStrings, 2, 0); 963 CGameMenuItemZCycle itemOptionsDisplayPolymostAnisotropy("ANISOTROPY:", 3, 66, 50, 180, 0, UpdateAnisotropy, pzAnisotropyStrings, 6, 0); 964 CGameMenuItemZBool itemOptionsDisplayPolymostTrueColorTextures("TRUE COLOR TEXTURES:", 3, 66, 60, 180, 0, UpdateTrueColorTextures, NULL, NULL); 965 CGameMenuItemZCycle itemOptionsDisplayPolymostTexQuality("GL TEXTURE QUALITY:", 3, 66, 70, 180, 0, UpdateTexQuality, pzTexQualityStrings, 3, 0); 966 CGameMenuItemZBool itemOptionsDisplayPolymostPreloadCache("PRE-LOAD MAP TEXTURES:", 3, 66, 80, 180, 0, UpdatePreloadCache, NULL, NULL); 967 CGameMenuItemZCycle itemOptionsDisplayPolymostTexCache("ON-DISK TEXTURE CACHE:", 3, 66, 90, 180, 0, UpdateTexCache, pzTexCacheStrings, 3, 0); 968 CGameMenuItemZBool itemOptionsDisplayPolymostDetailTex("DETAIL TEXTURES:", 3, 66, 100, 180, 0, UpdateDetailTex, NULL, NULL); 969 CGameMenuItemZBool itemOptionsDisplayPolymostGlowTex("GLOW TEXTURES:", 3, 66, 110, 180, 0, UpdateGlowTex, NULL, NULL); 970 CGameMenuItemZBool itemOptionsDisplayPolymost3DModels("3D MODELS:", 3, 66, 120, 180, 0, Update3DModels, NULL, NULL); 971 CGameMenuItemZBool itemOptionsDisplayPolymostDeliriumBlur("DELIRIUM EFFECT BLUR:", 3, 66, 130, 180, 0, UpdateDeliriumBlur, NULL, NULL); 972 CGameMenuItemZBool itemOptionsDisplayPolymostUseColorIndexedTex("PALETTE EMULATON:", 3, 66, 140, 180, 0, UpdateTexColorIndex, NULL, NULL); 973 CGameMenuItemZBool itemOptionsDisplayPolymostShadeInterpolation("PALETTE INTERPOLATION:", 3, 66, 150, 180, 0, UpdateShadeInterpolation, NULL, NULL); 974 CGameMenuItemZBool itemOptionsDisplayPolymostYShearing("Y-SHEARING:", 3, 66, 160, 180, 0, UpdateYShrearing, NULL, NULL); 975 CGameMenuItemSlider itemOptionsDisplayPolymostRollAngle("VIEW ROLLING:", 3, 66, 170, 180, &gRollAngle, -5, 5, 1, UpdateRollAngle, -1, -1, kMenuSliderValue); 976 #endif 977 978 void UpdateSoundToggle(CGameMenuItemZBool *pItem); 979 void UpdateMusicToggle(CGameMenuItemZBool *pItem); 980 void UpdateCDToggle(CGameMenuItemZBool *pItem); 981 void SetDoppler(CGameMenuItemZBool *pItem); 982 void UpdateSoundVolume(CGameMenuItemSlider *pItem); 983 void UpdateMusicVolume(CGameMenuItemSlider *pItem); 984 void UpdateSoundRate(CGameMenuItemZCycle *pItem); 985 void UpdateNumVoices(CGameMenuItemSlider *pItem); 986 void UpdateSpeakerAngle(CGameMenuItemSlider *pItem); 987 void UpdateCalebTalk(CGameMenuItemZCycle *pItem); 988 void UpdateMusicDevice(CGameMenuItemZCycle *pItem); 989 void SetSound(CGameMenuItemChain *pItem); 990 void PreDrawSound(CGameMenuItem *pItem); 991 const char *pzSoundRateStrings[] = { 992 "22050HZ", 993 "44100HZ", 994 "48000HZ" 995 }; 996 997 int nSoundRateValues[] = { 998 22050, 999 44100, 1000 48000 1001 }; 1002 1003 const char *pzCalebTalkStrings[] = { 1004 "ON", 1005 "NO IDLE TALK", 1006 "NO GIB TALK", 1007 "OFF", 1008 }; 1009 1010 int nMusicDeviceValues[] = { 1011 ASS_OPL3, 1012 #ifdef _WIN32 1013 ASS_WinMM, 1014 #endif 1015 ASS_SF2, 1016 }; 1017 1018 const char *pzMusicDeviceStrings[] = { 1019 "OPL3(SB/ADLIB)", 1020 #ifdef _WIN32 1021 "SYSTEM MIDI", 1022 #endif 1023 ".SF2 SYNTH", 1024 }; 1025 static char sf2bankfile[BMAX_PATH]; 1026 1027 CGameMenu menuOptionsSoundSF2; 1028 1029 CGameMenuItemTitle itemOptionsSoundSF2Title("SELECT SF2 BANK", 1, 160, 20, 2038); 1030 CGameMenuFileSelect itemOptionsSoundSF2FS("", 3, 0, 0, 0, "./", "*.sf2", sf2bankfile); 1031 1032 CGameMenuItemTitle itemOptionsSoundTitle("SOUND SETUP", 1, 160, 20, 2038); 1033 CGameMenuItemZBool itemOptionsSoundSoundToggle("SOUND:", 3, 66, 40, 180, false, UpdateSoundToggle, NULL, NULL); 1034 CGameMenuItemZBool itemOptionsSoundMusicToggle("MUSIC:", 3, 66, 50, 180, false, UpdateMusicToggle, NULL, NULL); 1035 CGameMenuItemZBool itemOptionsSoundMonoStereo("STEREO AUDIO:", 3, 66, 60, 180, false, SetMonoStereo, NULL, NULL); 1036 CGameMenuItemZBool itemOptionsSoundDoppler("DOPPLER EFFECT:", 3, 66, 70, 180, false, SetDoppler, NULL, NULL); 1037 CGameMenuItemSlider itemOptionsSoundSoundVolume("SOUND VOLUME:", 3, 66, 80, 180, &FXVolume, 0, 255, 17, UpdateSoundVolume, -1, -1, kMenuSliderPercent); 1038 CGameMenuItemSlider itemOptionsSoundMusicVolume("MUSIC VOLUME:", 3, 66, 90, 180, &MusicVolume, 0, 255, 17, UpdateMusicVolume, -1, -1, kMenuSliderPercent); 1039 CGameMenuItemZCycle itemOptionsSoundSampleRate("SAMPLE RATE:", 3, 66, 100, 180, 0, UpdateSoundRate, pzSoundRateStrings, ARRAY_SIZE(pzSoundRateStrings), 0); 1040 CGameMenuItemSlider itemOptionsSoundNumVoices("VOICES:", 3, 66, 110, 180, NumVoices, 16, 255, 16, UpdateNumVoices, -1, -1, kMenuSliderValue); 1041 CGameMenuItemSlider itemOptionsSoundSpeakerAngle("SPEAKER ANGLE:", 3, 66, 120, 180, &gSoundEarAng, 15, 90, 5, UpdateSpeakerAngle, -1, -1, kMenuSliderValue); 1042 CGameMenuItemZCycle itemOptionsSoundCalebTalk("CALEB TALK:", 3, 66, 130, 180, 0, UpdateCalebTalk, pzCalebTalkStrings, ARRAY_SIZE(pzCalebTalkStrings), 0); 1043 CGameMenuItemZBool itemOptionsSoundCDToggle("REDBOOK AUDIO:", 3, 66, 140, 180, false, UpdateCDToggle, NULL, NULL); 1044 CGameMenuItemZCycle itemOptionsSoundMusicDevice("MIDI DRIVER:", 3, 66, 150, 180, 0, UpdateMusicDevice, pzMusicDeviceStrings, ARRAY_SIZE(pzMusicDeviceStrings), 0); 1045 CGameMenuItemChain itemOptionsSoundSF2Bank("SF2 BANK", 3, 66, 160, 180, 0, &menuOptionsSoundSF2, 0, NULL, 0); 1046 CGameMenuItemChain itemOptionsSoundApplyChanges("APPLY CHANGES", 3, 66, 170, 180, 0, NULL, 0, SetSound, 0); 1047 1048 1049 void UpdatePlayerName(CGameMenuItemZEdit *pItem, CGameMenuEvent *pEvent); 1050 void UpdatePlayerSkill(CGameMenuItemZCycle *pItem); 1051 void UpdatePlayerTeamPreference(CGameMenuItemZCycle *pItem); 1052 void UpdatePlayerColorPreference(CGameMenuItemZCycle *pItem); 1053 void UpdatePlayerModel(CGameMenuItemZBool *pItem); 1054 void SetShowPlayerNames(CGameMenuItemZBool *); 1055 void SetShowWeapons(CGameMenuItemZCycle *); 1056 void UpdateTeamsScoreDisplay(CGameMenuItemZBool *pItem); 1057 void UpdatePlayerChatMessageSound(CGameMenuItemZBool *pItem); 1058 void UpdatePlayerColorMessages(CGameMenuItemZBool *pItem); 1059 void UpdatePlayerKillObituaryMessages(CGameMenuItemZBool *pItem); 1060 void UpdatePlayerKillMessage(CGameMenuItemZBool *pItem); 1061 void UpdatePlayerMultiKill(CGameMenuItemZCycle *pItem); 1062 1063 const char *pzPlayerMultiKillStrings[] = { 1064 "OFF", 1065 "ON", 1066 "SFX+ON", 1067 }; 1068 1069 const char *pzPlayerSkillStrings[] = { 1070 "-2", 1071 "-1", 1072 "DEFAULT", 1073 "+1", 1074 "+2", 1075 }; 1076 1077 const char *pzPlayerTeamPreferenceStrings[] = { 1078 "NONE", 1079 "BLUE", 1080 "RED" 1081 }; 1082 1083 1084 const char *pzPlayerColorPreferenceStrings[] = { 1085 "NONE", 1086 "BLUE", 1087 "RED", 1088 "TEAL", 1089 "GRAY", 1090 "YELLOW", 1091 "BROWN", 1092 "COPPER", 1093 }; 1094 1095 const char *pzShowWeaponStrings[] = { 1096 "OFF", 1097 "SPRITE", 1098 "VOXEL" 1099 }; 1100 1101 CGameMenuItemTitle itemOptionsPlayerTitle("PLAYER SETUP", 1, 160, 20, 2038); 1102 CGameMenuItemZEdit itemOptionsPlayerName("PLAYER NAME:", 3, 66, 35, 180, szPlayerName, MAXPLAYERNAME, 0, UpdatePlayerName, 0); 1103 CGameMenuItemZCycle itemOptionsPlayerSkill("HEALTH HANDICAP:", 3, 66, 45, 180, 0, UpdatePlayerSkill, pzPlayerSkillStrings, ARRAY_SIZE(pzPlayerSkillStrings), 0); 1104 CGameMenuItemZCycle itemOptionsPlayerTeamPreference("TEAM PREFERENCE:", 3, 66, 55, 180, 0, UpdatePlayerTeamPreference, pzPlayerTeamPreferenceStrings, ARRAY_SIZE(pzPlayerTeamPreferenceStrings), 0); 1105 CGameMenuItemZCycle itemOptionsPlayerColorPreference("COLOR PREFERENCE:", 3, 66, 65, 180, 0, UpdatePlayerColorPreference, pzPlayerColorPreferenceStrings, ARRAY_SIZE(pzPlayerColorPreferenceStrings), 0); 1106 CGameMenuItemZBool itemOptionsPlayerModel("PLAYER MODEL:", 3, 66, 75, 180, false, UpdatePlayerModel, "CULTIST", "CALEB"); 1107 CGameMenuItemZBool itemOptionsPlayerBoolShowPlayerNames("SHOW PLAYER NAMES:", 3, 66, 90, 180, gShowPlayerNames, SetShowPlayerNames, NULL, NULL); 1108 CGameMenuItemZCycle itemOptionsPlayerShowWeapons("SHOW WEAPONS:", 3, 66, 100, 180, 0, SetShowWeapons, pzShowWeaponStrings, ARRAY_SSIZE(pzShowWeaponStrings), 0); 1109 CGameMenuItemZBool itemOptionsPlayerTeamsScoreStyle("TEAMS SCORE STYLE:", 3, 66, 110, 180, true, UpdateTeamsScoreDisplay, "NBLOOD", "ORIGINAL"); 1110 CGameMenuItemZBool itemOptionsPlayerChatSound("MESSAGE BEEP:", 3, 66, 120, 180, true, UpdatePlayerChatMessageSound, NULL, NULL); 1111 CGameMenuItemZBool itemOptionsPlayerColorMsg("COLORED MESSAGES:", 3, 66, 130, 180, true, UpdatePlayerColorMessages, NULL, NULL); 1112 CGameMenuItemZBool itemOptionsPlayerObituaryMsg("USE OBITUARY MESSAGES:", 3, 66, 140, 180, true, UpdatePlayerKillObituaryMessages, NULL, NULL); 1113 CGameMenuItemZBool itemOptionsPlayerKillMsg("SHOW KILLS ON HUD:", 3, 66, 150, 180, true, UpdatePlayerKillMessage, NULL, NULL); 1114 CGameMenuItemZCycle itemOptionsPlayerMultiKill("MULTI KILL MESSAGES:", 3, 66, 160, 180, 0, UpdatePlayerMultiKill, pzPlayerMultiKillStrings, ARRAY_SIZE(pzPlayerMultiKillStrings), 0); 1115 1116 #define JOYSTICKITEMSPERPAGE 16 // this must be an even value, as double tap inputs rely on odd index position 1117 #define MAXJOYSTICKBUTTONPAGES (max(1, (MAXJOYBUTTONSANDHATS*2 / JOYSTICKITEMSPERPAGE))) // we double all buttons/hats so each input can be bind for double tap 1118 1119 CGameMenu menuOptionsControlKeyboard; 1120 CGameMenu menuKeys; 1121 CGameMenu menuOptionsControlMouse; 1122 CGameMenu menuOptionsControlMouseButtonAssignment; 1123 CGameMenu menuOptionsControlRadial; 1124 CGameMenu menuOptionsControlJoystickButtonAssignment[MAXJOYSTICKBUTTONPAGES]; 1125 CGameMenu menuOptionsControlJoystickListAxes; // contains list of editable joystick axes 1126 CGameMenu menuOptionsControlJoystickAxis[MAXJOYAXES]; // options menu for each joystick axis 1127 CGameMenu menuOptionsControlJoystickMisc; 1128 1129 void SetupMouseMenu(CGameMenuItemChain *pItem); 1130 void SetupJoystickButtonsMenu(CGameMenuItemChain *pItem); 1131 void SetupJoystickAxesMenu(CGameMenuItemChain *pItem); 1132 void SetupJoystickAxisHeatmap(CGameMenuItemChain *pItem); 1133 void SetJoystickScale(CGameMenuItemSlider* pItem); 1134 void SetJoystickAnalogue(CGameMenuItemZCycle* pItem); 1135 void SetJoystickAnalogueInvert(CGameMenuItemZBool* pItem); 1136 void SetJoystickDigitalPos(CGameMenuItemZCycle* pItem); 1137 void SetJoystickDigitalNeg(CGameMenuItemZCycle* pItem); 1138 void SetJoystickDeadzone(CGameMenuItemSlider* pItem); 1139 void SetJoystickSaturate(CGameMenuItemSlider* pItem); 1140 void SetJoystickSnapZone(CGameMenuItemSlider* pItem); 1141 1142 const char *pzTurnAccelerationStrings[] = { 1143 "OFF", 1144 "ON RUNNING", 1145 "ALWAYS ON", 1146 }; 1147 1148 const char *zRadialMenuToggle[] = 1149 { 1150 "Button Held", 1151 "Button Toggle", 1152 "Weapon Switch", 1153 }; 1154 1155 const char *pzSoundClickStrings[] = 1156 { 1157 "OFF", 1158 "SHARP", 1159 "MEDIUM", 1160 "SOFT", 1161 }; 1162 1163 const char *zRadialMenuAxes[] = 1164 { 1165 "Strafing", 1166 "Moving", 1167 "Turning", 1168 "Look Up/Down", 1169 }; 1170 1171 CGameMenuItemTitle itemOptionsControlTitle("CONTROL SETUP", 1, 160, 20, 2038); 1172 CGameMenuItemChain itemOptionsControlKeyboard("KEYBOARD SETUP", 1, 0, 50, 320, 1, &menuOptionsControlKeyboard, -1, NULL, 0); 1173 CGameMenuItemChain itemOptionsControlMouse("MOUSE SETUP", 1, 0, 70, 320, 1, &menuOptionsControlMouse, -1, SetupMouseMenu, 0); 1174 CGameMenuItemChain itemOptionsControlRadial("RADIAL MENU SETUP", 1, 0, 90, 320, 1, &menuOptionsControlRadial, -1, NULL, 0); 1175 CGameMenuItemChain itemOptionsControlJoystickButtons("JOYSTICK BUTTONS SETUP", 1, 0, 130, 320, 1, &menuOptionsControlJoystickButtonAssignment[0], -1, SetupJoystickButtonsMenu, 0); 1176 CGameMenuItemChain itemOptionsControlJoystickAxes("JOYSTICK AXES SETUP", 1, 0, 150, 320, 1, &menuOptionsControlJoystickListAxes, -1, SetupJoystickAxesMenu, 0); 1177 CGameMenuItemChain itemOptionsControlJoystickMisc("JOYSTICK MISC SETUP", 1, 0, 170, 320, 1, &menuOptionsControlJoystickMisc, -1, NULL, 0); 1178 1179 CGameMenuItemTitle itemOptionsControlKeyboardTitle("KEYBOARD SETUP", 1, 160, 20, 2038); 1180 CGameMenuItemSlider itemOptionsControlKeyboardSliderTurnSpeed("Key Turn Speed:", 1, 18, 50, 280, &gTurnSpeed, 64, 128, 4, SetTurnSpeed, -1, -1); 1181 CGameMenuItemZCycle itemOptionsControlKeyboardCycleTurnAcceleration("Key Turn Acceleration:", 1, 18, 70, 280, 0, SetTurnAcceleration, pzTurnAccelerationStrings, ARRAY_SIZE(pzTurnAccelerationStrings), 0); 1182 CGameMenuItemZBool itemOptionsControlKeyboardBoolCrouchToggle("Crouch Toggle:", 1, 18, 90, 280, gCrouchToggle, SetCrouchToggle, NULL, NULL); 1183 CGameMenuItemZBool itemOptionsControlKeyboardBoolCrouchAuto("Crouch Auto:", 1, 18, 110, 280, gCrouchAuto, SetCrouchAuto, NULL, NULL); 1184 CGameMenuItemChain itemOptionsControlKeyboardList("Configure Keys...", 1, 0, 130, 320, 1, &menuKeys, -1, NULL, 0); 1185 CGameMenuItemChain itemOptionsControlKeyboardReset("Reset Keys (default)...", 1, 0, 155, 320, 1, &menuKeys, -1, ResetKeys, 0); 1186 CGameMenuItemChain itemOptionsControlKeyboardResetClassic("Reset Keys (classic)...", 1, 0, 175, 320, 1, &menuKeys, -1, ResetKeysClassic, 0); 1187 1188 CGameMenuItemTitle itemKeysTitle("KEY SETUP", 1, 160, 20, 2038); 1189 CGameMenuItemKeyList itemKeyList("", 3, 56, 40, 200, 16, NUMGAMEFUNCTIONS, 0); 1190 1191 void SetMouseAimMode(CGameMenuItemZBool *pItem); 1192 void SetMouseVerticalAim(CGameMenuItemZBool *pItem); 1193 void SetMouseXSensitivity(CGameMenuItemSliderFloat *pItem); 1194 void SetMouseYSensitivity(CGameMenuItemSliderFloat*pItem); 1195 1196 void PreDrawControlMouse(CGameMenuItem *pItem); 1197 void SetMouseButton(CGameMenuItemZCycle *pItem); 1198 void SetJoyButton(CGameMenuItemZCycle *pItem); 1199 1200 void SetupMouseButtonMenu(CGameMenuItemChain *pItem); 1201 1202 CGameMenuItemTitle itemOptionsControlMouseTitle("MOUSE SETUP", 1, 160, 20, 2038); 1203 CGameMenuItemChain itemOptionsControlMouseButton("BUTTON ASSIGNMENT", 3, 66, 60, 180, 0, &menuOptionsControlMouseButtonAssignment, 0, SetupMouseButtonMenu, 0); 1204 CGameMenuItemSliderFloat itemOptionsControlMouseSensitivity("SENSITIVITY:", 3, 66, 70, 180, &CONTROL_MouseSensitivity, 0.f, 100.f, 1.f, SetMouseSensitivity, -1, -1, kMenuSliderValue); 1205 CGameMenuItemZBool itemOptionsControlMouseAimFlipped("INVERT AIMING:", 3, 66, 80, 180, false, SetMouseAimFlipped, NULL, NULL); 1206 CGameMenuItemZBool itemOptionsControlMouseAimMode("AIMING TYPE:", 3, 66, 90, 180, false, SetMouseAimMode, "HOLD", "TOGGLE"); 1207 CGameMenuItemZBool itemOptionsControlMouseVerticalAim("VERTICAL AIMING:", 3, 66, 100, 180, false, SetMouseVerticalAim, NULL, NULL); 1208 CGameMenuItemSliderFloat itemOptionsControlMouseXSensitivity("HORIZ SENS:", 3, 66, 110, 180, &CONTROL_MouseAxesSensitivity[0], 0.f, 100.f, 1.f, SetMouseXSensitivity, -1, -1, kMenuSliderValue); 1209 CGameMenuItemSliderFloat itemOptionsControlMouseYSensitivity("VERT SENS:", 3, 66, 120, 180, &CONTROL_MouseAxesSensitivity[1], 0.f, 100.f, 1.f, SetMouseYSensitivity, -1, -1, kMenuSliderValue); 1210 1211 CGameMenuItemTitle itemOptionsControlRadialTitle("RADIAL SETUP", 1, 160, 20, 2038); 1212 CGameMenuItemZCycle itemOptionsControlRadialToggle("USAGE BEHAVIOR:", 3, 66, 45, 180, 0, SetRadialMenuToggle, zRadialMenuToggle, ARRAY_SIZE(zRadialMenuToggle), 0); 1213 CGameMenuItemSlider itemOptionsControlRadialPosition("POSITION:", 3, 66, 55, 180, &gRadialMenuPosition, 0, 320, 16, SetRadialMenuPosition, -1, -1, kMenuSliderPercent); 1214 CGameMenuItemZBool itemOptionsControlRadialDimBackground("DIM BACKGROUND:", 3, 66, 65, 180, 0, SetRadialMenuDimBackground, NULL, NULL); 1215 CGameMenuItemZBool itemOptionsControlRadialDimHUD("TRANSPARENT RADIAL:", 3, 66, 75, 180, 0, SetRadialMenuDimHUD, NULL, NULL); 1216 CGameMenuItemZBool itemOptionsControlRadialSlowDown("MENU SLOW DOWN:", 3, 66, 85, 180, 0, SetRadialMenuSlowDown, NULL, NULL); 1217 CGameMenuItemZCycle itemOptionsControlRadialSound("SOUND CLICK:", 3, 66, 95, 180, 0, SetRadialMenuSound, pzSoundClickStrings, ARRAY_SIZE(pzSoundClickStrings), 0); 1218 CGameMenuItemSlider itemOptionsControlRadialMouseThreshold("MOUSE THRESHOLD:", 3, 66, 105, 180, &gRadialMenuMouseThreshold, 0, 2048, 128, SetRadialMenuMouseThreshold, -1, -1, kMenuSliderPercent); 1219 CGameMenuItemSlider itemOptionsControlRadialThresholdX("JOY X THRESHOLD:", 3, 66, 115, 180, &gRadialMenuThresholdX, 0, 1024, 128, SetRadialMenuThreshold, -1, -1, kMenuSliderPercent); 1220 CGameMenuItemSlider itemOptionsControlRadialThresholdY("JOY Y THRESHOLD:", 3, 66, 125, 180, &gRadialMenuThresholdY, 0, 1024, 128, SetRadialMenuThreshold, -1, -1, kMenuSliderPercent); 1221 CGameMenuItemZCycle itemOptionsControlRadialYaw("JOY X AXIS:", 3, 66, 135, 180, 0, SetRadialMenuYaw, zRadialMenuAxes, ARRAY_SIZE(zRadialMenuAxes), 0); 1222 CGameMenuItemZBool itemOptionsControlRadialYawInvert("JOY X INVERT:", 3, 66, 145, 180, 0, SetRadialMenuPitchInvert, NULL, NULL); 1223 CGameMenuItemZCycle itemOptionsControlRadialPitch("JOY Y AXIS:", 3, 66, 155, 180, 0, SetRadialMenuPitch, zRadialMenuAxes, ARRAY_SIZE(zRadialMenuAxes), 0); 1224 CGameMenuItemZBool itemOptionsControlRadialPitchInvert("JOY Y INVERT:", 3, 66, 165, 180, 0, SetRadialMenuYawInvert, NULL, NULL); 1225 1226 void SetupNetworkMenu(void); 1227 void SetupNetworkHostMenu(CGameMenuItemChain *pItem); 1228 void SetupNetworkJoinMenu(CGameMenuItemChain *pItem); 1229 void NetworkHostGame(CGameMenuItemChain *pItem); 1230 void NetworkJoinGame(CGameMenuItemChain *pItem); 1231 1232 char zNetAddressBuffer[48] = "localhost"; 1233 char zNetPortBuffer[6] = "23513"; 1234 1235 CGameMenuItemTitle itemNetworkTitle("MULTIPLAYER", 1, 160, 20, 2038); 1236 CGameMenuItemChain itemNetworkHost("HOST A GAME", 1, 0, 70, 320, 1, &menuNetworkHost, -1, SetupNetworkHostMenu, 0); 1237 CGameMenuItemChain itemNetworkJoin("JOIN A GAME", 1, 0, 90, 320, 1, &menuNetworkJoin, -1, SetupNetworkJoinMenu, 0); 1238 CGameMenuItemChain itemNetworkPlayer("PLAYER SETUP", 1, 0, 110, 320, 1, &menuOptionsPlayer, -1, NULL, 0); 1239 1240 CGameMenuItemTitle itemNetworkHostTitle("HOST A GAME", 1, 160, 20, 2038); 1241 CGameMenuItemSlider itemNetworkHostPlayerNum("PLAYER NUMBER:", 3, 66, 70, 180, 1, 2, kMaxPlayers, 1, NULL, -1, -1, kMenuSliderValue); 1242 CGameMenuItemZEdit itemNetworkHostPort("NETWORK PORT:", 3, 66, 80, 180, zNetPortBuffer, 6, 0, NULL, 0); 1243 CGameMenuItemChain itemNetworkHostHost("HOST A GAME", 3, 66, 100, 180, 1, NULL, -1, NetworkHostGame, 0); 1244 1245 CGameMenuItemTitle itemNetworkJoinTitle("JOIN A GAME", 1, 160, 20, 2038); 1246 CGameMenuItemZEdit itemNetworkJoinAddress("NETWORK ADDRESS:", 3, 66, 70, 180, zNetAddressBuffer, 48, 0, NULL, 0); 1247 CGameMenuItemZEdit itemNetworkJoinPort("NETWORK PORT:", 3, 66, 80, 180, zNetPortBuffer, 6, 0, NULL, 0); 1248 CGameMenuItemChain itemNetworkJoinJoin("JOIN A GAME", 3, 66, 100, 180, 1, NULL, -1, NetworkJoinGame, 0); 1249 1250 // There is no better way to do this than manually. 1251 1252 #define MENUMOUSEFUNCTIONS 12 1253 1254 static char const *MenuMouseNames[MENUMOUSEFUNCTIONS] = { 1255 "Button 1", 1256 "Double Button 1", 1257 "Button 2", 1258 "Double Button 2", 1259 "Button 3", 1260 "Double Button 3", 1261 1262 "Wheel Up", 1263 "Wheel Down", 1264 1265 "Button 4", 1266 "Double Button 4", 1267 "Button 5", 1268 "Double Button 5", 1269 }; 1270 1271 static int32_t MenuMouseDataIndex[MENUMOUSEFUNCTIONS][2] = { 1272 { 0, 0, }, 1273 { 0, 1, }, 1274 { 1, 0, }, 1275 { 1, 1, }, 1276 { 2, 0, }, 1277 { 2, 1, }, 1278 1279 // note the mouse wheel 1280 { 4, 0, }, 1281 { 5, 0, }, 1282 1283 { 3, 0, }, 1284 { 3, 1, }, 1285 { 6, 0, }, 1286 { 6, 1, }, 1287 }; 1288 1289 CGameMenuItemZCycle *pItemOptionsControlMouseButton[MENUMOUSEFUNCTIONS]; 1290 1291 char MenuJoyButtonNames[MAXJOYBUTTONSANDHATS*2][64] = {""}; 1292 1293 const char *zJoystickAnalogue[] = 1294 { 1295 "-None-", 1296 "Turning", 1297 "Strafing", 1298 "Moving", 1299 "Look Up/Down", 1300 }; 1301 1302 CGameMenuItemTitle itemJoyButtonsTitle("JOYSTICK SETUP", 1, 160, 20, 2038); 1303 CGameMenuItemZCycle *pItemOptionsControlJoyButton[MAXJOYSTICKBUTTONPAGES][JOYSTICKITEMSPERPAGE]; 1304 CGameMenuItemChain *pItemOptionsControlJoyButtonNextPage[MAXJOYSTICKBUTTONPAGES]; 1305 1306 char MenuJoyAxisNames[MAXJOYAXES][64] = {""}; 1307 1308 CGameMenuItemTitle itemJoyAxesTitle("JOYSTICK AXES", 1, 160, 20, 2038); 1309 CGameMenuItemChain *pItemOptionsControlJoystickAxis[MAXJOYAXES]; // dynamic list for each axis 1310 1311 CGameMenuItemTitle *pItemOptionsControlJoystickAxisName[MAXJOYAXES]; 1312 CGameMenuItemSlider *pItemOptionsControlJoystickAxisScale[MAXJOYAXES]; 1313 CGameMenuItemZCycle *pItemOptionsControlJoystickAxisAnalogue[MAXJOYAXES]; 1314 CGameMenuItemZBool *pItemOptionsControlJoystickAxisAnalogueInvert[MAXJOYAXES]; 1315 CGameMenuItemZCycle *pItemOptionsControlJoystickAxisDigitalPos[MAXJOYAXES]; 1316 CGameMenuItemZCycle *pItemOptionsControlJoystickAxisDigitalNeg[MAXJOYAXES]; 1317 CGameMenuItemSlider *pItemOptionsControlJoystickAxisDeadzone[MAXJOYAXES]; 1318 CGameMenuItemSlider *pItemOptionsControlJoystickAxisSaturate[MAXJOYAXES]; 1319 CGameMenuItemSlider *pItemOptionsControlJoystickAxisSnapZone[MAXJOYAXES]; 1320 CGameMenuItemBitmap ItemOptionsControlJoystickAxisHeatmapPic(NULL, 3, 500, 290, kAxisHeatmapTile); 1321 1322 CGameMenuItemTitle itemOptionsControlJoystickMiscTitle("JOYSTICK MISC", 1, 160, 20, 2038); 1323 CGameMenuItemZBool itemOptionsControlJoystickMiscCrouchToggle("CROUCH TOGGLE:", 1, 18, 60, 280, gCrouchToggle, SetCrouchToggle, NULL, NULL); 1324 CGameMenuItemZBool itemOptionsControlJoystickMiscCrouchAuto("AUTO CROUCH:", 1, 18, 80, 280, gCrouchAuto, SetCrouchAuto, NULL, NULL); 1325 CGameMenuItemZBool itemOptionsControlJoystickMiscCenterView("CENTER VIEW ON DROP:", 1, 18, 100, 280, gCenterViewOnDrop, SetCenterView, NULL, NULL); 1326 CGameMenuItemZBool itemOptionsControlJoystickMiscTargetAimAssist("TARGET AIM ASSIST:", 1, 18, 120, 280, 0, SetJoystickTargetAimAssist, NULL, NULL); 1327 CGameMenuItemZBool itemOptionsControlJoystickMiscRumble("RUMBLE CONTROLLER:", 1, 18, 140, 280, 0, SetJoystickRumble, NULL, NULL); 1328 1329 void SetupLoadingScreen(void) 1330 { 1331 menuLoading.Add(&itemLoadingText, true); 1332 } 1333 1334 void SetupMessagesMenu(void) 1335 { 1336 menuMessages.Add(&itemMessagesTitle, false); 1337 menuMessages.Add(&boolMessages, true); 1338 menuMessages.Add(&sliderMsgCount, false); 1339 menuMessages.Add(&sliderMsgTime, false); 1340 menuMessages.Add(&boolMsgFont, false); 1341 menuMessages.Add(&boolMsgIncoming, false); 1342 menuMessages.Add(&boolMsgSelf, false); 1343 menuMessages.Add(&boolMsgOther, false); 1344 menuMessages.Add(&boolMsgRespawn, false); 1345 menuMessages.Add(&itemBloodQAV, false); 1346 } 1347 1348 void SetupDifficultyMenu(void) 1349 { 1350 menuDifficulty.Add(&itemDifficultyTitle, false); 1351 menuDifficulty.Add(&itemDifficulty1, false); 1352 menuDifficulty.Add(&itemDifficulty2, false); 1353 menuDifficulty.Add(&itemDifficulty3, true); 1354 menuDifficulty.Add(&itemDifficulty4, false); 1355 menuDifficulty.Add(&itemDifficulty5, false); 1356 menuDifficulty.Add(&itemDifficulty6, false); 1357 menuDifficulty.Add(&itemBloodQAV, false); 1358 1359 menuCustomDifficulty.Add(&itemCustomDifficultyTitle, false); 1360 menuCustomDifficulty.Add(&itemCustomDifficultyStartLevel, false); 1361 menuCustomDifficulty.Add(&itemCustomDifficultyMonsterSettings, true); 1362 menuCustomDifficulty.Add(&itemCustomDifficultyEnemyQuantity, false); 1363 menuCustomDifficulty.Add(&itemCustomDifficultyEnemyHealth, false); 1364 menuCustomDifficulty.Add(&itemCustomDifficultyEnemyDifficulty, false); 1365 menuCustomDifficulty.Add(&itemCustomDifficultyPlayerDamage, false); 1366 menuCustomDifficulty.Add(&itemCustomDifficultyEnemySpeed, false); 1367 menuCustomDifficulty.Add(&itemCustomDifficultyEnemyShuffle, false); 1368 menuCustomDifficulty.Add(&itemCustomDifficultyPitchfork, false); 1369 menuCustomDifficulty.Add(&itemCustomDifficultyPermaDeath, false); 1370 menuCustomDifficulty.Add(&itemCustomDifficultyBannedMonsters, false); 1371 menuCustomDifficulty.Add(&itemCustomDifficultyBannedItems, false); 1372 menuCustomDifficulty.Add(&itemCustomDifficultyStart, false); 1373 menuCustomDifficulty.Add(&itemBloodQAV, false); 1374 itemCustomDifficultyStartLevel.tooltip_pzTextUpper = ""; 1375 itemCustomDifficultyStartLevel.tooltip_pzTextLower = "Set the starting level for this episode"; 1376 itemCustomDifficultyEnemyQuantity.tooltip_pzTextUpper = ""; 1377 itemCustomDifficultyEnemyQuantity.tooltip_pzTextLower = "Set how many enemies will spawn in the level"; 1378 itemCustomDifficultyEnemyHealth.tooltip_pzTextUpper = ""; 1379 itemCustomDifficultyEnemyHealth.tooltip_pzTextLower = "Set enemy's starting health"; 1380 itemCustomDifficultyEnemyDifficulty.tooltip_pzTextUpper = ""; 1381 itemCustomDifficultyEnemyDifficulty.tooltip_pzTextLower = "Set enemy's behavior difficulty"; 1382 itemCustomDifficultyPlayerDamage.tooltip_pzTextUpper = ""; 1383 itemCustomDifficultyPlayerDamage.tooltip_pzTextLower = "Set player's damage taken scale"; 1384 itemCustomDifficultyEnemySpeed.tooltip_pzTextUpper = ""; 1385 itemCustomDifficultyEnemySpeed.tooltip_pzTextLower = "Set enemy's movement speed modifier"; 1386 itemCustomDifficultyEnemyShuffle.tooltip_pzTextUpper = ""; 1387 itemCustomDifficultyEnemyShuffle.tooltip_pzTextLower = "Shuffle enemy's spawn position"; 1388 itemCustomDifficultyPitchfork.tooltip_pzTextUpper = ""; 1389 itemCustomDifficultyPitchfork.tooltip_pzTextLower = "Player will lose all items on new level"; 1390 itemCustomDifficultyPermaDeath.tooltip_pzTextUpper = ""; 1391 itemCustomDifficultyPermaDeath.tooltip_pzTextLower = "No saving, and you only live once"; 1392 itemCustomDifficultyBannedMonsters.tooltip_pzTextUpper = ""; 1393 itemCustomDifficultyBannedMonsters.tooltip_pzTextLower = "Set which monsters to spawn"; 1394 itemCustomDifficultyBannedItems.tooltip_pzTextUpper = ""; 1395 itemCustomDifficultyBannedItems.tooltip_pzTextLower = "Set which items to spawn"; 1396 1397 menuBannedMonsters.Add(&itemBannedMonstersTitle, false); 1398 menuBannedMonsters.Add(&itemBannedMonstersBats, true); 1399 menuBannedMonsters.Add(&itemBannedMonstersRats, false); 1400 menuBannedMonsters.Add(&itemBannedMonstersFish, false); 1401 menuBannedMonsters.Add(&itemBannedMonstersHands, false); 1402 menuBannedMonsters.Add(&itemBannedMonstersGhosts, false); 1403 menuBannedMonsters.Add(&itemBannedMonstersSpiders, false); 1404 menuBannedMonsters.Add(&itemBannedMonstersTinyCaleb, false); 1405 menuBannedMonsters.Add(&itemBannedMonstersHellHounds, false); 1406 menuBannedMonsters.Add(&itemBannedMonstersRatsAttack, false); 1407 menuBannedMonsters.Add(&itemBannedMonstersMotherSpiderHealth, false); 1408 menuBannedMonsters.Add(&itemBannedMonstersTchernobogHealth, false); 1409 menuBannedMonsters.Add(&itemBloodQAV, false); 1410 itemBannedMonstersSpiders.tooltip_pzTextUpper = ""; 1411 itemBannedMonstersSpiders.tooltip_pzTextLower = "Mother spiders are not removed to avoid boss softlocks"; 1412 itemBannedMonstersTchernobogHealth.tooltip_pzTextUpper = ""; 1413 itemBannedMonstersTchernobogHealth.tooltip_pzTextLower = "Fix overflow health bug for Tchernobog"; 1414 1415 menuBannedItems.Add(&itemBannedItemsTitle, false); 1416 menuBannedItems.Add(&itemBannedItemsFlare, true); 1417 menuBannedItems.Add(&itemBannedItemsShotgun, false); 1418 menuBannedItems.Add(&itemBannedItemsTommyGun, false); 1419 menuBannedItems.Add(&itemBannedItemsNapalm, false); 1420 menuBannedItems.Add(&itemBannedItemsTNT, false); 1421 menuBannedItems.Add(&itemBannedItemsSpray, false); 1422 menuBannedItems.Add(&itemBannedItemsTesla, false); 1423 menuBannedItems.Add(&itemBannedItemsLifeLeech, false); 1424 menuBannedItems.Add(&itemBannedItemsVoodoo, false); 1425 menuBannedItems.Add(&itemBannedItemsProxy, false); 1426 menuBannedItems.Add(&itemBannedItemsRemote, false); 1427 menuBannedItems.Add(&itemBannedItemsMedKit, false); 1428 menuBannedItems.Add(&itemBannedItemsLifeEssence, false); 1429 menuBannedItems.Add(&itemBannedItemsLifeSeed, false); 1430 menuBannedItems.Add(&itemBannedItemsSuperArmor, false); 1431 menuBannedItems.Add(&itemBannedItemsCrystalBall, false); 1432 menuBannedItems.Add(&itemBannedItemsJumpBoots, false); 1433 menuBannedItems.Add(&itemBannedItemsCloak, false); 1434 menuBannedItems.Add(&itemBannedItemsDeathMask, false); 1435 menuBannedItems.Add(&itemBannedItemsAkimbo, false); 1436 menuBannedItems.Add(&itemBannedItemsReflect, false); 1437 menuBannedItems.Add(&itemBloodQAV, false); 1438 } 1439 1440 void SetupEpisodeMenu(void) 1441 { 1442 menuEpisode.Add(&itemEpisodesTitle, false); 1443 int height; 1444 gMenuTextMgr.GetFontInfo(1, NULL, NULL, &height); 1445 int nOffset = 100; 1446 for (int i = 0; i < gEpisodeCount; i++) 1447 { 1448 EPISODEINFO *pEpisode = &gEpisodeInfo[i]; 1449 if (!pEpisode->bloodbath || gGameOptions.nGameType != kGameTypeSinglePlayer) 1450 nOffset -= 10; 1451 } 1452 nOffset = max(min(nOffset, 55), 35); 1453 int j = 0; 1454 for (int i = 0; i < gEpisodeCount; i++) 1455 { 1456 EPISODEINFO *pEpisode = &gEpisodeInfo[i]; 1457 if (!pEpisode->bloodbath || gGameOptions.nGameType != kGameTypeSinglePlayer) 1458 { 1459 if (j >= ARRAY_SSIZE(itemEpisodes)) 1460 ThrowError("Too many ini episodes to display (max %d).\n", ARRAY_SSIZE(itemEpisodes)); 1461 CGameMenuItemChain7F2F0 *pEpisodeItem = &itemEpisodes[j]; 1462 pEpisodeItem->m_nFont = 1; 1463 pEpisodeItem->m_nX = 0; 1464 pEpisodeItem->m_nWidth = 320; 1465 pEpisodeItem->at20 = 1; 1466 pEpisodeItem->m_pzText = pEpisode->title; 1467 pEpisodeItem->m_nY = nOffset+(height+8)*j; 1468 pEpisodeItem->at34 = i; 1469 pEpisodeItem = &itemEpisodes[j]; 1470 pEpisodeItem->at24 = &menuDifficulty; 1471 pEpisodeItem->at28 = 3; 1472 pEpisodeItem = &itemEpisodes[j]; 1473 pEpisodeItem->bCanSelect = 1; 1474 pEpisodeItem->bEnable = 1; 1475 bool first = j == 0; 1476 menuEpisode.Add(&itemEpisodes[j], first); 1477 if (first) 1478 SetupLevelMenuItem(j); 1479 j++; 1480 } 1481 } 1482 1483 if (j < 5) // if menu slots are not all filled, add space for user maps item 1484 itemUserMap.m_nY = 50+(height+8)*5; 1485 else 1486 itemUserMap.m_nY = nOffset+(height+8)*j; 1487 menuEpisode.Add(&itemUserMap, false); 1488 menuEpisode.Add(&itemBloodQAV, false); 1489 1490 menuUserMap.Add(&itemUserMapTitle, true); 1491 menuUserMap.Add(&itemUserMapList, true); 1492 } 1493 1494 void SetupMainMenu(void) 1495 { 1496 menuMain.Add(&itemMainTitle, false); 1497 menuMain.Add(&itemMain1, true); 1498 if (gGameOptions.nGameType != kGameTypeSinglePlayer) 1499 { 1500 itemMain1.at24 = &menuNetStart; 1501 itemMain1.at28 = 2; 1502 } 1503 else 1504 { 1505 itemMain1.at24 = &menuEpisode; 1506 itemMain1.at28 = -1; 1507 } 1508 menuMain.Add(&itemMain2, false); 1509 menuMain.Add(&itemMain3, false); 1510 menuMain.Add(&itemMain4, false); 1511 menuMain.Add(&itemMain5, false); 1512 menuMain.Add(&itemMain6, false); 1513 menuMain.Add(&itemMain7, false); 1514 menuMain.Add(&itemBloodQAV, false); 1515 1516 #ifdef NETCODE_DISABLE 1517 itemMain2.bEnable = 0; // disable multiplayer menu item for non-netcode build 1518 #endif 1519 } 1520 1521 void SetupMainMenuWithSave(void) 1522 { 1523 menuMainWithSave.Add(&itemMainSaveTitle, false); 1524 menuMainWithSave.Add(&itemMainSave1, true); 1525 if (gGameOptions.nGameType != kGameTypeSinglePlayer) 1526 { 1527 itemMainSave1.at24 = &menuNetStart; 1528 itemMainSave1.at28 = 2; 1529 } 1530 else 1531 { 1532 itemMainSave1.at24 = &menuEpisode; 1533 itemMainSave1.at28 = -1; 1534 } 1535 menuMainWithSave.Add(&itemMainSave2, false); 1536 menuMainWithSave.Add(&itemMainSave3, false); 1537 menuMainWithSave.Add(&itemMainSave4, false); 1538 menuMainWithSave.Add(&itemMainSave5, false); 1539 menuMainWithSave.Add(&itemMainSave6, false); 1540 menuMainWithSave.Add(&itemMainSave7, false); 1541 menuMainWithSave.Add(&itemMainSave8, false); 1542 menuMainWithSave.Add(&itemBloodQAV, false); 1543 1544 itemMainSave3.bDisableForNet = itemMainSave3.bDisableForPermaDeath = 1; 1545 itemMainSave4.bDisableForNet = 1; 1546 itemMainSave5.bDisableForNet = 1; 1547 itemMainSave6.bDisableForNet = 1; 1548 itemMainSave3.bEnable = !gLockManualSaving; // disable save option in main menu if lock saving mode is set 1549 } 1550 1551 void SetupFirstLaunchMenu(void) 1552 { 1553 menuFirstLaunch.Add(&itemFirstLaunchInfo1, false); 1554 menuFirstLaunch.Add(&itemFirstLaunchInfo2, false); 1555 menuFirstLaunch.Add(&itemFirstLaunchVanilla, true); 1556 menuFirstLaunch.Add(&itemFirstLaunchNBlood, false); 1557 menuFirstLaunch.Add(&itemFirstLaunchNotBlood, false); 1558 itemFirstLaunchVanilla.tooltip_pzTextUpper = "Set options to match v1.21 DOS Blood and use vanilla mode"; 1559 itemFirstLaunchNBlood.tooltip_pzTextUpper = "Set options to match NBlood"; 1560 itemFirstLaunchNotBlood.tooltip_pzTextUpper = "Keep default NotBlood options"; 1561 itemFirstLaunchNotBlood.tooltip_pzTextLower = "(pick this one if you're unsure)"; 1562 } 1563 1564 void SetupNetStartMenu(void) 1565 { 1566 bool oneEpisode = false; 1567 menuNetStart.Add(&itemNetStartTitle, false); 1568 menuNetStart.Add(&itemNetStart1, false); 1569 for (int i = 0; i < (oneEpisode ? 1 : 6); i++) 1570 { 1571 EPISODEINFO *pEpisode = &gEpisodeInfo[i]; 1572 if (i < gEpisodeCount) 1573 itemNetStart2.Add(pEpisode->title, i == 0); 1574 } 1575 menuNetStart.Add(&itemNetStart2, false); 1576 menuNetStart.Add(&itemNetStart3, false); 1577 menuNetStart.Add(&itemNetStart4, false); 1578 menuNetStart.Add(&itemNetStart5, false); 1579 menuNetStart.Add(&itemNetStart6, false); 1580 menuNetStart.Add(&itemNetStart7, false); 1581 menuNetStart.Add(&itemNetStartBoolChaseView, false); 1582 menuNetStart.Add(&itemNetStartBoolHolstering, false); 1583 menuNetStart.Add(&itemNetStartBoolSecondWind, false); 1584 menuNetStart.Add(&itemNetStartBoolSpectatorMode, false); 1585 menuNetStart.Add(&itemNetStart8, false); 1586 menuNetStart.Add(&itemNetStart9, false); 1587 menuNetStart.Add(&itemNetStart10, false); 1588 menuNetStart.Add(&itemNetStart11, false); 1589 menuMultiUserMaps.Add(&itemNetStartUserMapTitle, true); 1590 menuMultiUserMaps.Add(&menuMultiUserMap, true); 1591 1592 menuNetworkGameMode.Add(&itemNetGameTitle, false); 1593 menuNetworkGameMode.Add(&itemNetGameMode, true); 1594 menuNetworkGameMode.Add(&itemNetGameSliderScoreLimit, false); 1595 menuNetworkGameMode.Add(&itemNetGameSliderTimeLimit, false); 1596 menuNetworkGameMode.Add(&itemNetGameSliderLivesLimit, false); 1597 menuNetworkGameMode.Add(&itemNetGameBoolExit, false); 1598 menuNetworkGameMode.Add(&itemNetGameBoolTeleFrag, false); 1599 menuNetworkGameMode.Add(&itemNetGameBoolSkillOverride, false); 1600 menuNetworkGameMode.Add(&itemNetGameBoolModelOverride, false); 1601 menuNetworkGameMode.Add(&itemNetGameBoolPlayerColors, false); 1602 menuNetworkGameMode.Add(&itemNetGameBoolTeamColors, false); 1603 menuNetworkGameMode.Add(&itemNetGameBoolFriendlyFire, false); 1604 menuNetworkGameMode.Add(&itemNetGameCycleKey, false); 1605 menuNetworkGameMode.Add(&itemNetGameCycleItemWeapon, false); 1606 menuNetworkGameMode.Add(&itemNetGameBoolAutoTeams, false); 1607 menuNetworkGameMode.Add(&itemNetGameBoolTeamFlags, false); 1608 menuNetworkGameMode.Add(&itemNetGameCycleSpawnLocation, false); 1609 menuNetworkGameMode.Add(&itemNetGameCycleShowWeaponsOverride, false); 1610 menuNetworkGameMode.Add(&itemNetGameCycleShowWeaponsOverrideTeams, false); 1611 menuNetworkGameMode.Add(&itemNetGameCycleSpawnProtection, false); 1612 menuNetworkGameMode.Add(&itemNetGameCycleSpawnWeapon, false); 1613 menuNetworkGameMode.Add(&itemNetGameCycleMirrorModeOverride, false); 1614 menuNetworkGameMode.Add(&itemBloodQAV, false); 1615 itemNetGameSliderScoreLimit.tooltip_pzTextUpper = "Set score limit"; 1616 itemNetGameSliderScoreLimit.tooltip_pzTextLower = "(0 = no limit)"; 1617 itemNetGameSliderTimeLimit.tooltip_pzTextUpper = "Set round limt (in minutes)"; 1618 itemNetGameSliderTimeLimit.tooltip_pzTextLower = "(0 = no limit)"; 1619 itemNetGameSliderLivesLimit.tooltip_pzTextUpper = "Set number of respawns allowed"; 1620 itemNetGameSliderLivesLimit.tooltip_pzTextLower = "(0 = no limit)"; 1621 itemNetGameBoolExit.tooltip_pzTextUpper = "Toggle level exit switch functionality"; 1622 itemNetGameBoolTeleFrag.tooltip_pzTextUpper = "Toggle telefrags kills"; 1623 itemNetGameBoolSkillOverride.tooltip_pzTextUpper = "Toggle player health handicap"; 1624 itemNetGameBoolSkillOverride.tooltip_pzTextLower = "(When off, use difficulty setting)"; 1625 itemNetGameBoolModelOverride.tooltip_pzTextUpper = "Set global setting for player models"; 1626 itemNetGameBoolModelOverride.tooltip_pzTextLower = "(This is applied to all players in round)"; 1627 itemNetGameBoolAutoTeams.tooltip_pzTextUpper = "Automatically sort players into teams"; 1628 itemNetGameBoolPlayerColors.tooltip_pzTextUpper = "Allow non-vanilla player colors"; 1629 itemNetGameBoolTeamColors.tooltip_pzTextUpper = "Highlight players with team colors"; 1630 itemNetGameBoolTeamFlags.tooltip_pzTextUpper = "Toggle team flags for teams mode"; 1631 itemNetGameCycleSpawnLocation.tooltip_pzTextUpper = "Set spawn location behavior"; 1632 itemNetGameCycleShowWeaponsOverride.tooltip_pzTextUpper = "Set global setting for show weapons option"; 1633 itemNetGameCycleShowWeaponsOverride.tooltip_pzTextLower = "(This is applied to all players in round)"; 1634 itemNetGameCycleShowWeaponsOverrideTeams.tooltip_pzTextUpper = "Set global setting for show weapons option"; 1635 itemNetGameCycleShowWeaponsOverrideTeams.tooltip_pzTextLower = "(This is applied to all players in round)"; 1636 itemNetGameCycleSpawnProtection.tooltip_pzTextUpper = "Give players invulnerability on spawn"; 1637 itemNetGameCycleMirrorModeOverride.tooltip_pzTextUpper = "Set global setting for mirror mode"; 1638 itemNetGameCycleMirrorModeOverride.tooltip_pzTextLower = "(This is applied to all players in round)"; 1639 1640 menuNetworkGameMonsters.Add(&itemNetMonsterTitle, false); 1641 menuNetworkGameMonsters.Add(&itemNetMonsterSettings, true); 1642 menuNetworkGameMonsters.Add(&itemNetMonsterQuantity, false); 1643 menuNetworkGameMonsters.Add(&itemNetMonsterHealth, false); 1644 menuNetworkGameMonsters.Add(&itemNetMonsterSpeed, false); 1645 menuNetworkGameMonsters.Add(&itemNetMonsterBats, false); 1646 menuNetworkGameMonsters.Add(&itemNetMonsterRats, false); 1647 menuNetworkGameMonsters.Add(&itemNetMonsterFish, false); 1648 menuNetworkGameMonsters.Add(&itemNetMonsterHands, false); 1649 menuNetworkGameMonsters.Add(&itemNetMonsterGhosts, false); 1650 menuNetworkGameMonsters.Add(&itemNetMonsterSpiders, false); 1651 menuNetworkGameMonsters.Add(&itemNetMonsterTinyCaleb, false); 1652 menuNetworkGameMonsters.Add(&itemNetMonsterHellHounds, false); 1653 menuNetworkGameMonsters.Add(&itemNetMonsterRatsAttack, false); 1654 menuNetworkGameMonsters.Add(&itemNetMonsterMotherSpiderHealth, false); 1655 menuNetworkGameMonsters.Add(&itemNetMonsterTchernobogHealth, false); 1656 menuNetworkGameMonsters.Add(&itemBloodQAV, false); 1657 1658 ////////////////////// 1659 menuNetworkGameMutators.Add(&itemGameMutatorsTitle, false); 1660 menuNetworkGameMutators.Add(&itemNetMutatorBoolQuadDamagePowerup, true); 1661 menuNetworkGameMutators.Add(&itemNetMutatorDamageInvul, false); 1662 menuNetworkGameMutators.Add(&itemNetMutatorProjectileBehavior, false); 1663 menuNetworkGameMutators.Add(&itemNetMutatorNapalmFalloff, false); 1664 menuNetworkGameMutators.Add(&itemNetMutatorEnemyBehavior, false); 1665 menuNetworkGameMutators.Add(&itemNetMutatorBoolEnemyRandomTNT, false); 1666 menuNetworkGameMutators.Add(&itemNetMutatorWeaponsVer, false); 1667 menuNetworkGameMutators.Add(&itemNetMutatorAmmoScale, false); 1668 menuNetworkGameMutators.Add(&itemNetMutatorSectorBehavior, false); 1669 menuNetworkGameMutators.Add(&itemNetMutatorHitscanProjectiles, false); 1670 menuNetworkGameMutators.Add(&itemNetMutatorGoreBehavior, false); 1671 menuNetworkGameMutators.Add(&itemNetMutatorPlayerSpeed, false); 1672 menuNetworkGameMutators.Add(&itemNetMutatorRandomizerMode, false); 1673 menuNetworkGameMutators.Add(&itemNetMutatorRandomizerSeed, false); 1674 menuNetworkGameMutators.Add(&itemBloodQAV, false); 1675 itemNetMutatorBoolQuadDamagePowerup.tooltip_pzTextUpper = "Replaces guns akimbo powerup"; 1676 itemNetMutatorBoolQuadDamagePowerup.tooltip_pzTextLower = "with Quake's quad damage"; 1677 itemNetMutatorDamageInvul.tooltip_pzTextUpper = "Apply a short invulnerability state"; 1678 itemNetMutatorDamageInvul.tooltip_pzTextLower = "on bullet/spirit/tesla damage"; 1679 itemNetMutatorProjectileBehavior.tooltip_pzTextUpper = "Use smaller hitboxes and improve collision"; 1680 itemNetMutatorProjectileBehavior.tooltip_pzTextLower = "accuracy for player projectiles"; 1681 itemNetMutatorNapalmFalloff.tooltip_pzTextUpper = "Set napalm projectiles to"; 1682 itemNetMutatorNapalmFalloff.tooltip_pzTextLower = "be affected by gravity"; 1683 itemNetMutatorEnemyBehavior.tooltip_pzTextUpper = "Fix various original bugs with enemies"; 1684 itemNetMutatorBoolEnemyRandomTNT.tooltip_pzTextUpper = "Set cultist to have a chance of"; 1685 itemNetMutatorBoolEnemyRandomTNT.tooltip_pzTextLower = "throwing random projectiles"; 1686 itemNetMutatorWeaponsVer.tooltip_pzTextUpper = "Check readme.txt for full"; 1687 itemNetMutatorWeaponsVer.tooltip_pzTextLower = "list of weapon changes"; 1688 itemNetMutatorAmmoScale.tooltip_pzTextUpper = "Scale ammo pickup amount"; 1689 itemNetMutatorSectorBehavior.tooltip_pzTextUpper = "Improve room over room sector logic"; 1690 itemNetMutatorHitscanProjectiles.tooltip_pzTextUpper = "Set hitscan enemies to spawn projectiles"; 1691 #ifdef NOONE_EXTENSIONS 1692 itemNetMutatorHitscanProjectiles.tooltip_pzTextLower = "(does not support xmapedit enemies)"; 1693 #endif 1694 itemNetMutatorGoreBehavior.tooltip_pzTextUpper = "Spawns excessive gibs and increases particles"; 1695 itemNetMutatorPlayerSpeed.tooltip_pzTextUpper = "Adjusts the player speed"; 1696 itemNetMutatorRandomizerMode.tooltip_pzTextUpper = "Set the randomizer's mode"; 1697 itemNetMutatorRandomizerSeed.tooltip_pzTextUpper = "Set the randomizer's seed"; 1698 itemNetMutatorRandomizerSeed.tooltip_pzTextLower = "No seed = always use a random seed"; 1699 ////////////////////// 1700 1701 itemNetStart2.SetTextIndex(gMultiEpisodeInit != -1 ? gMultiEpisodeInit : 0); 1702 SetupLevelMenuItem(gMultiEpisodeInit != -1 ? gMultiEpisodeInit : 0); 1703 itemNetStart3.SetTextIndex(gMultiLevelInit != -1 ? gMultiLevelInit : 0); 1704 itemNetStart4.SetTextIndex(gMultiDiffInit != -1 ? gMultiDiffInit : 2); 1705 itemNetStart6.SetTextIndex(gMultiWeapons != -1 ? gMultiWeapons : 1); 1706 itemNetStart7.SetTextIndex(gMultiItems != -1 ? gMultiItems : 1); 1707 if (gMultiChaseView) 1708 itemNetStartBoolChaseView.at20 = 1; 1709 if (gMultiHolstering) 1710 itemNetStartBoolHolstering.at20 = 1; 1711 if (gMultiSecondWind > -1) 1712 itemNetStartBoolSecondWind.at20 = !!gMultiSecondWind; 1713 if (gMultiSpectating) 1714 itemNetStartBoolSpectatorMode.at20 = 1; 1715 1716 itemNetGameMode.SetTextIndex(gMultiModeInit != -1 ? gMultiModeInit : 1); 1717 itemNetGameSliderScoreLimit.nValue = gMultiScoreLimit != -1 ? gMultiScoreLimit : itemNetGameSliderScoreLimit.nValue; 1718 itemNetGameSliderLivesLimit.nValue = gMultiScoreLimit != -1 ? gMultiScoreLimit : itemNetGameSliderLivesLimit.nValue; 1719 itemNetGameSliderTimeLimit.nValue = gMultiTimeLimit != -1 ? gMultiTimeLimit : itemNetGameSliderTimeLimit.nValue; 1720 if (gMultiModeNoExit) 1721 itemNetGameBoolExit.at20 = 0; 1722 itemNetGameBoolAutoTeams.at20 = !gPlayerTeamPreference; 1723 if (gMultiModeNoFlag) 1724 itemNetGameBoolTeamFlags.at20 = 0; 1725 itemNetGameCycleSpawnLocation.SetTextIndex(gMultiSpawnLocation != -1 ? gMultiSpawnLocation : 1); 1726 itemNetGameCycleShowWeaponsOverride.SetTextIndex(1); 1727 itemNetGameCycleShowWeaponsOverrideTeams.SetTextIndex(1); 1728 itemNetGameCycleSpawnProtection.SetTextIndex(gMultiSpawnProtection != -1 ? gMultiSpawnProtection : 0); 1729 SetNetGameMode(&itemNetGameMode); // hide friendly fire/keys menu items depending on game mode 1730 1731 itemNetMonsterSettings.SetTextIndex(gMultiMonsters != -1 ? gMultiMonsters : 0); 1732 SetNetMonsterMenu(NULL); 1733 1734 /////// 1735 itemNetMutatorBoolQuadDamagePowerup.at20 = !!gQuadDamagePowerup; 1736 itemNetMutatorDamageInvul.m_nFocus = gDamageInvul % ARRAY_SSIZE(pzDamageInvulBehaviorStrings); 1737 itemNetMutatorProjectileBehavior.m_nFocus = gProjectileBehavior % ARRAY_SSIZE(pzProjectileBehaviorStrings); 1738 itemNetMutatorNapalmFalloff.at20 = !!gNapalmFalloff; 1739 itemNetMutatorEnemyBehavior.m_nFocus = gEnemyBehavior % ARRAY_SSIZE(pzEnemyBehaviorStrings); 1740 itemNetMutatorBoolEnemyRandomTNT.at20 = !!gEnemyRandomTNT; 1741 itemNetMutatorWeaponsVer.m_nFocus = gWeaponsVer % ARRAY_SSIZE(pzWeaponsVersionStrings); 1742 itemNetMutatorAmmoScale.m_nFocus = gAmmoScale % ARRAY_SSIZE(pzAmmoScaleStrings); 1743 itemNetMutatorSectorBehavior.at20 = !!gSectorBehavior; 1744 itemNetMutatorHitscanProjectiles.m_nFocus = gHitscanProjectiles % ARRAY_SSIZE(pzHitscanProjectilesStrings); 1745 itemNetMutatorGoreBehavior.m_nFocus = gGoreBehavior % ARRAY_SSIZE(pzGoreStrings); 1746 itemNetMutatorPlayerSpeed.m_nFocus = gPlayerModSpeed % ARRAY_SSIZE(pzPlayerSpeeds); 1747 itemNetMutatorRandomizerMode.m_nFocus = gRandomizerMode % ARRAY_SSIZE(pzRandomizerModeStrings); 1748 Bstrncpy(szRandomizerSeedMenu, gzRandomizerSeed, sizeof(gPacketStartGame.szRandomizerSeed)); 1749 /////// 1750 1751 menuNetStart.Add(&itemBloodQAV, false); 1752 } 1753 1754 void SetupSaveGameMenu(void) 1755 { 1756 menuSaveGame.Add(&itemSaveTitle, false); 1757 menuSaveGame.Add(&itemSaveGame0, true); 1758 menuSaveGame.Add(&itemSaveGame1, false); 1759 menuSaveGame.Add(&itemSaveGame2, false); 1760 menuSaveGame.Add(&itemSaveGame3, false); 1761 menuSaveGame.Add(&itemSaveGame4, false); 1762 menuSaveGame.Add(&itemSaveGame5, false); 1763 menuSaveGame.Add(&itemSaveGame6, false); 1764 menuSaveGame.Add(&itemSaveGame7, false); 1765 menuSaveGame.Add(&itemSaveGame8, false); 1766 menuSaveGame.Add(&itemSaveGame9, false); 1767 menuSaveGame.Add(&itemSaveGameQuick, false); 1768 menuSaveGame.Add(&itemSaveGameAutosaveStart, false); 1769 menuSaveGame.Add(&itemSaveGameAutosaveKey, false); 1770 menuSaveGame.Add(&itemSaveGamePic, false); 1771 menuSaveGame.Add(&itemBloodQAV, false); 1772 1773 itemSaveGame0.at2c = &itemSaveGamePic; 1774 if (!strcmp(strRestoreGameStrings[kLoadSaveSlot0], "<Empty>")) 1775 itemSaveGame0.at37 = 1; 1776 1777 itemSaveGame1.at2c = &itemSaveGamePic; 1778 if (!strcmp(strRestoreGameStrings[kLoadSaveSlot1], "<Empty>")) 1779 itemSaveGame1.at37 = 1; 1780 1781 itemSaveGame2.at2c = &itemSaveGamePic; 1782 if (!strcmp(strRestoreGameStrings[kLoadSaveSlot2], "<Empty>")) 1783 itemSaveGame2.at37 = 1; 1784 1785 itemSaveGame3.at2c = &itemSaveGamePic; 1786 if (!strcmp(strRestoreGameStrings[kLoadSaveSlot3], "<Empty>")) 1787 itemSaveGame3.at37 = 1; 1788 1789 itemSaveGame4.at2c = &itemSaveGamePic; 1790 if (!strcmp(strRestoreGameStrings[kLoadSaveSlot4], "<Empty>")) 1791 itemSaveGame4.at37 = 1; 1792 1793 itemSaveGame5.at2c = &itemSaveGamePic; 1794 if (!strcmp(strRestoreGameStrings[kLoadSaveSlot5], "<Empty>")) 1795 itemSaveGame5.at37 = 1; 1796 1797 itemSaveGame6.at2c = &itemSaveGamePic; 1798 if (!strcmp(strRestoreGameStrings[kLoadSaveSlot6], "<Empty>")) 1799 itemSaveGame6.at37 = 1; 1800 1801 itemSaveGame7.at2c = &itemSaveGamePic; 1802 if (!strcmp(strRestoreGameStrings[kLoadSaveSlot7], "<Empty>")) 1803 itemSaveGame7.at37 = 1; 1804 1805 itemSaveGame8.at2c = &itemSaveGamePic; 1806 if (!strcmp(strRestoreGameStrings[kLoadSaveSlot8], "<Empty>")) 1807 itemSaveGame8.at37 = 1; 1808 1809 itemSaveGame9.at2c = &itemSaveGamePic; 1810 if (!strcmp(strRestoreGameStrings[kLoadSaveSlot9], "<Empty>")) 1811 itemSaveGame9.at37 = 1; 1812 1813 itemSaveGameQuick.at2c = &itemSaveGamePic; 1814 itemSaveGameAutosaveStart.at2c = &itemSaveGamePic; 1815 itemSaveGameAutosaveKey.at2c = &itemSaveGamePic; 1816 1817 itemSaveGameQuick.bEnable = 0; // don't let these save slots be selectable 1818 itemSaveGameAutosaveStart.bEnable = 0; 1819 itemSaveGameAutosaveStart.bNoDraw = gAutosave == 0; 1820 itemSaveGameAutosaveKey.bEnable = 0; 1821 itemSaveGameAutosaveKey.bNoDraw = gAutosave != 2; 1822 } 1823 1824 void SetupLoadGameMenu(void) 1825 { 1826 menuLoadGame.Add(&itemLoadTitle, false); 1827 menuLoadGame.Add(&itemLoadGame0, true); 1828 menuLoadGame.Add(&itemLoadGame1, false); 1829 menuLoadGame.Add(&itemLoadGame2, false); 1830 menuLoadGame.Add(&itemLoadGame3, false); 1831 menuLoadGame.Add(&itemLoadGame4, false); 1832 menuLoadGame.Add(&itemLoadGame5, false); 1833 menuLoadGame.Add(&itemLoadGame6, false); 1834 menuLoadGame.Add(&itemLoadGame7, false); 1835 menuLoadGame.Add(&itemLoadGame8, false); 1836 menuLoadGame.Add(&itemLoadGame9, false); 1837 menuLoadGame.Add(&itemLoadGameQuick, false); 1838 menuLoadGame.Add(&itemLoadGameAutosaveStart, false); 1839 menuLoadGame.Add(&itemLoadGameAutosaveKey, false); 1840 menuLoadGame.Add(&itemLoadGamePic, false); 1841 itemLoadGamePic.at28 = gMenuPicnum; 1842 itemLoadGame0.at35 = 0; 1843 itemLoadGame1.at35 = 0; 1844 itemLoadGame2.at35 = 0; 1845 itemLoadGame3.at35 = 0; 1846 itemLoadGame4.at35 = 0; 1847 itemLoadGame5.at35 = 0; 1848 itemLoadGame6.at35 = 0; 1849 itemLoadGame7.at35 = 0; 1850 itemLoadGame8.at35 = 0; 1851 itemLoadGame9.at35 = 0; 1852 itemLoadGameQuick.at35 = 0; 1853 itemLoadGameAutosaveStart.at35 = 0; 1854 itemLoadGameAutosaveKey.at35 = 0; 1855 itemLoadGameAutosaveStart.bEnable = gAutosave != 0; // remove autosave slots if autosaves are disabled 1856 itemLoadGameAutosaveStart.bNoDraw = gAutosave == 0; 1857 itemLoadGameAutosaveKey.bEnable = gAutosave == 2; 1858 itemLoadGameAutosaveKey.bNoDraw = gAutosave != 2; 1859 itemLoadGame0.at2c = &itemLoadGamePic; 1860 itemLoadGame1.at2c = &itemLoadGamePic; 1861 itemLoadGame2.at2c = &itemLoadGamePic; 1862 itemLoadGame3.at2c = &itemLoadGamePic; 1863 itemLoadGame4.at2c = &itemLoadGamePic; 1864 itemLoadGame5.at2c = &itemLoadGamePic; 1865 itemLoadGame6.at2c = &itemLoadGamePic; 1866 itemLoadGame7.at2c = &itemLoadGamePic; 1867 itemLoadGame8.at2c = &itemLoadGamePic; 1868 itemLoadGame9.at2c = &itemLoadGamePic; 1869 itemLoadGameQuick.at2c = &itemLoadGamePic; 1870 itemLoadGameAutosaveStart.at2c = &itemLoadGamePic; 1871 itemLoadGameAutosaveKey.at2c = &itemLoadGamePic; 1872 menuLoadGame.Add(&itemBloodQAV, false); 1873 } 1874 1875 void SetupQuitMenu(void) 1876 { 1877 menuQuit.Add(&itemQuitTitle, false); 1878 menuQuit.Add(&itemQuitText1, false); 1879 menuQuit.Add(&itemQuitYesNo, true); 1880 menuQuit.Add(&itemBloodQAV, false); 1881 1882 menuRestart.Add(&itemRestartTitle, false); 1883 menuRestart.Add(&itemRestartText1, false); 1884 menuRestart.Add(&itemRestartYesNo, true); 1885 menuRestart.Add(&itemBloodQAV, false); 1886 } 1887 1888 void SetupHelpMenu(void) 1889 { 1890 menuHelp.Add(&itemHelp4QAV, true); 1891 menuHelp.Add(&itemHelp5QAV, false); 1892 menuHelp.Add(&itemHelp3QAV, false); 1893 menuHelp.Add(&itemHelp3BQAV, false); 1894 itemHelp4QAV.bEnable = 1; 1895 itemHelp4QAV.bNoDraw = 1; 1896 itemHelp5QAV.bEnable = 1; 1897 itemHelp5QAV.bNoDraw = 1; 1898 itemHelp3QAV.bEnable = 1; 1899 itemHelp3QAV.bNoDraw = 1; 1900 itemHelp3BQAV.bEnable = 1; 1901 itemHelp3BQAV.bNoDraw = 1; 1902 } 1903 1904 void SetupCreditsMenu(void) 1905 { 1906 menuCredits.Add(&itemCreditsQAV, true); 1907 itemCreditsQAV.bEnable = 1; 1908 itemCreditsQAV.bNoDraw = 1; 1909 } 1910 1911 void SetupOptionsMenu(void) 1912 { 1913 menuOptions.Add(&itemOptionsTitle, false); 1914 menuOptions.Add(&itemOptionsChainGame, true); 1915 menuOptions.Add(&itemOptionsChainDisplay, false); 1916 menuOptions.Add(&itemOptionsChainSound, false); 1917 menuOptions.Add(&itemOptionsChainPlayer, false); 1918 menuOptions.Add(&itemOptionsChainControl, false); 1919 menuOptions.Add(&itemOptionsChainMutators, false); 1920 menuOptions.Add(&itemBloodQAV, false); 1921 1922 menuOptionsGame.Add(&itemOptionsGameTitle, false); 1923 menuOptionsGame.Add(&itemOptionsGameCycleAutoAim, true); 1924 menuOptionsGame.Add(&itemOptionsGameSliderAutoAimRange, false); 1925 menuOptionsGame.Add(&itemOptionsGameBoolAutoRun, false); 1926 menuOptionsGame.Add(&itemOptionsGameWeaponSwitch, false); 1927 menuOptionsGame.Add(&itemOptionsGameWeaponFastSwitch, false); 1928 menuOptionsGame.Add(&itemOptionsGameAutosaveMode, false); 1929 menuOptionsGame.Add(&itemOptionsGameLockSaving, false); 1930 menuOptionsGame.Add(&itemOptionsGameRestoreLastSave, false); 1931 menuOptionsGame.Add(&itemOptionsGameBoolVanillaMode, false); 1932 itemOptionsGameSliderAutoAimRange.bDisableForNet = 1; 1933 itemOptionsGameLockSaving.bDisableForNet = 1; 1934 itemOptionsGameBoolVanillaMode.bDisableForNet = 1; 1935 itemOptionsGameSliderAutoAimRange.tooltip_pzTextUpper = "Set autoaim angle modifier"; 1936 itemOptionsGameSliderAutoAimRange.tooltip_pzTextLower = "(single-player only)"; 1937 itemOptionsGameWeaponFastSwitch.tooltip_pzTextUpper = "Allow weapon switching while"; 1938 itemOptionsGameWeaponFastSwitch.tooltip_pzTextLower = "weapon is being lowered/raised"; 1939 itemOptionsGameAutosaveMode.tooltip_pzTextUpper = "Set when autosave will trigger"; 1940 itemOptionsGameLockSaving.tooltip_pzTextUpper = "Disable manual saving/save scumming"; 1941 itemOptionsGameRestoreLastSave.tooltip_pzTextUpper = "Prompt to restore last save game on death"; 1942 itemOptionsGameBoolVanillaMode.tooltip_pzTextUpper = "Disable all non-vanilla features/mutators"; 1943 itemOptionsGameBoolVanillaMode.tooltip_pzTextLower = "(v1.21 DOS compatibility mode)"; 1944 1945 ////////////////////// 1946 menuOptionsGameMutators.Add(&itemGameMutatorsTitle, false); 1947 menuOptionsGameMutators.Add(&itemMutatorBoolQuadDamagePowerup, true); 1948 menuOptionsGameMutators.Add(&itemMutatorDamageInvul, false); 1949 menuOptionsGameMutators.Add(&itemMutatorProjectileBehavior, false); 1950 menuOptionsGameMutators.Add(&itemMutatorNapalmFalloff, false); 1951 menuOptionsGameMutators.Add(&itemMutatorEnemyBehavior, false); 1952 menuOptionsGameMutators.Add(&itemMutatorBoolEnemyRandomTNT, false); 1953 menuOptionsGameMutators.Add(&itemMutatorWeaponsVer, false); 1954 menuOptionsGameMutators.Add(&itemMutatorAmmoScale, false); 1955 menuOptionsGameMutators.Add(&itemMutatorSectorBehavior, false); 1956 menuOptionsGameMutators.Add(&itemMutatorHitscanProjectiles, false); 1957 menuOptionsGameMutators.Add(&itemMutatorGoreBehavior, false); 1958 menuOptionsGameMutators.Add(&itemMutatorPlayerSpeed, false); 1959 menuOptionsGameMutators.Add(&itemMutatorRandomizerMode, false); 1960 menuOptionsGameMutators.Add(&itemMutatorRandomizerSeed, false); 1961 menuOptionsGameMutators.Add(&itemBloodQAV, false); 1962 itemOptionsChainMutators.bDisableForNet = 1; 1963 itemMutatorBoolQuadDamagePowerup.tooltip_pzTextUpper = "Replaces guns akimbo powerup"; 1964 itemMutatorBoolQuadDamagePowerup.tooltip_pzTextLower = "with Quake's quad damage"; 1965 itemMutatorDamageInvul.tooltip_pzTextUpper = "Apply a short invulnerability state"; 1966 itemMutatorDamageInvul.tooltip_pzTextLower = "on bullet/spirit/tesla damage"; 1967 itemMutatorProjectileBehavior.tooltip_pzTextUpper = "Use smaller hitboxes and improve collision"; 1968 itemMutatorProjectileBehavior.tooltip_pzTextLower = "accuracy for player projectiles"; 1969 itemMutatorNapalmFalloff.tooltip_pzTextUpper = "Set napalm projectiles to"; 1970 itemMutatorNapalmFalloff.tooltip_pzTextLower = "be affected by gravity"; 1971 itemMutatorEnemyBehavior.tooltip_pzTextUpper = "Fix various original bugs with enemies"; 1972 itemMutatorBoolEnemyRandomTNT.tooltip_pzTextUpper = "Set cultist to have a chance of"; 1973 itemMutatorBoolEnemyRandomTNT.tooltip_pzTextLower = "throwing random projectiles"; 1974 itemMutatorWeaponsVer.tooltip_pzTextUpper = "Check readme.txt for full"; 1975 itemMutatorWeaponsVer.tooltip_pzTextLower = "list of weapon changes"; 1976 itemMutatorAmmoScale.tooltip_pzTextUpper = "Scale ammo pickup amount"; 1977 itemMutatorSectorBehavior.tooltip_pzTextUpper = "Improve room over room sector logic"; 1978 itemMutatorHitscanProjectiles.tooltip_pzTextUpper = "Set hitscan enemies to spawn projectiles"; 1979 #ifdef NOONE_EXTENSIONS 1980 itemMutatorHitscanProjectiles.tooltip_pzTextLower = "(does not support xmapedit enemies)"; 1981 #endif 1982 itemMutatorGoreBehavior.tooltip_pzTextUpper = "Spawns excessive gibs and increases particles"; 1983 itemMutatorPlayerSpeed.tooltip_pzTextUpper = "Adjusts the player speed"; 1984 itemMutatorRandomizerMode.tooltip_pzTextUpper = "Set the randomizer's mode"; 1985 itemMutatorRandomizerSeed.tooltip_pzTextUpper = "Set the randomizer's seed"; 1986 itemMutatorRandomizerSeed.tooltip_pzTextLower = "No seed = always use a random seed"; 1987 ///////////////////// 1988 1989 menuOptionsGame.Add(&itemBloodQAV, false); 1990 itemOptionsGameCycleAutoAim.m_nFocus = gAutoAim; 1991 itemOptionsGameSliderAutoAimRange.nValue = gAutoAimRange; 1992 itemOptionsGameBoolAutoRun.at20 = !!gAutoRun; 1993 itemOptionsGameWeaponSwitch.m_nFocus = gWeaponSwitch % ARRAY_SSIZE(pzWeaponSwitchStrings); 1994 itemOptionsGameWeaponFastSwitch.at20 = !!gWeaponFastSwitch; 1995 itemOptionsGameAutosaveMode.m_nFocus = gAutosave % ARRAY_SSIZE(pzAutosaveModeStrings); 1996 itemOptionsGameLockSaving.at20 = !!gLockManualSaving; 1997 itemOptionsGameRestoreLastSave.at20 = !!gRestoreLastSave; 1998 itemOptionsGameBoolVanillaMode.m_nFocus = gVanilla % ARRAY_SSIZE(pzVanillaModeStrings); 1999 SetGameVanillaMode(gVanilla); // enable/disable menu items depending on current vanilla mode state 2000 2001 /////// 2002 itemMutatorBoolQuadDamagePowerup.at20 = !!gQuadDamagePowerup; 2003 itemMutatorDamageInvul.m_nFocus = gDamageInvul % ARRAY_SSIZE(pzDamageInvulBehaviorStrings); 2004 itemMutatorProjectileBehavior.m_nFocus = gProjectileBehavior % ARRAY_SSIZE(pzProjectileBehaviorStrings); 2005 itemMutatorNapalmFalloff.at20 = !!gNapalmFalloff; 2006 itemMutatorEnemyBehavior.m_nFocus = gEnemyBehavior % ARRAY_SSIZE(pzEnemyBehaviorStrings); 2007 itemMutatorBoolEnemyRandomTNT.at20 = !!gEnemyRandomTNT; 2008 itemMutatorWeaponsVer.m_nFocus = gWeaponsVer % ARRAY_SSIZE(pzWeaponsVersionStrings); 2009 itemMutatorAmmoScale.m_nFocus = gAmmoScale % ARRAY_SSIZE(pzAmmoScaleStrings); 2010 itemMutatorSectorBehavior.at20 = !!gSectorBehavior; 2011 itemMutatorHitscanProjectiles.m_nFocus = gHitscanProjectiles % ARRAY_SSIZE(pzHitscanProjectilesStrings); 2012 itemMutatorGoreBehavior.m_nFocus = gGoreBehavior % ARRAY_SSIZE(pzGoreStrings); 2013 itemMutatorPlayerSpeed.m_nFocus = gPlayerModSpeed % ARRAY_SSIZE(pzPlayerSpeeds); 2014 itemMutatorRandomizerMode.m_nFocus = gRandomizerMode % ARRAY_SSIZE(pzRandomizerModeStrings); 2015 Bstrncpy(szRandomizerSeedMenu, gzRandomizerSeed, sizeof(szRandomizerSeedMenu)); 2016 /////// 2017 2018 menuOptionsDisplay.Add(&itemOptionsDisplayTitle, false); 2019 menuOptionsDisplay.Add(&itemOptionsDisplayColor, true); 2020 menuOptionsDisplay.Add(&itemOptionsDisplayMode, false); 2021 menuOptionsDisplay.Add(&itemOptionsDisplayView, false); 2022 menuOptionsDisplay.Add(&itemOptionsDisplaySliderDetail, false); 2023 menuOptionsDisplay.Add(&itemOptionsDisplayBoolVoxels, false); 2024 menuOptionsDisplay.Add(&itemOptionsDisplayCrosshair, false); 2025 menuOptionsDisplay.Add(&itemOptionsDisplayLevelStats, false); 2026 menuOptionsDisplay.Add(&itemOptionsDisplayLevelStatsOnAutomap, false); 2027 menuOptionsDisplay.Add(&itemOptionsDisplayPowerupDuration, false); 2028 menuOptionsDisplay.Add(&itemOptionsDisplayBoolShowMapTitle, false); 2029 menuOptionsDisplay.Add(&itemOptionsDisplayBoolMessages, false); 2030 menuOptionsDisplay.Add(&itemOptionsDisplayBoolWidescreen, false); 2031 menuOptionsDisplay.Add(&itemOptionsDisplayWeaponSelect, false); 2032 menuOptionsDisplay.Add(&itemOptionsDisplayFOV, false); 2033 menuOptionsDisplay.Add(&itemBloodQAV, false); 2034 itemOptionsDisplayBoolVoxels.at20 = usevoxels; 2035 itemOptionsDisplayCrosshair.m_nFocus = gAimReticle % ARRAY_SSIZE(pzCrosshairStrings); 2036 itemOptionsDisplayLevelStats.m_nFocus = gLevelStats % ARRAY_SSIZE(pzStatsPowerupRatioStrings); 2037 itemOptionsDisplayLevelStatsOnAutomap.at20 = gLevelStatsOnlyOnMap; 2038 itemOptionsDisplayLevelStatsOnAutomap.bEnable = !!gLevelStats; 2039 itemOptionsDisplayPowerupDuration.m_nFocus = gPowerupDuration % ARRAY_SSIZE(pzStatsPowerupRatioStrings); 2040 itemOptionsDisplayBoolShowMapTitle.at20 = gShowMapTitle; 2041 itemOptionsDisplayBoolMessages.at20 = gMessageState; 2042 itemOptionsDisplayBoolWidescreen.at20 = r_usenewaspect; 2043 itemOptionsDisplayWeaponSelect.m_nFocus = gShowWeaponSelect % ARRAY_SSIZE(pzWeaponSelectStrings); 2044 2045 menuOptionsDisplayMode.Add(&itemOptionsDisplayModeTitle, false); 2046 menuOptionsDisplayMode.Add(&itemOptionsDisplayModeResolution, true); 2047 // prepare video setup 2048 for (int i = 0; i < validmodecnt; ++i) 2049 { 2050 int j; 2051 for (j = 0; j < gResolutionNum; ++j) 2052 { 2053 if (validmode[i].xdim == gResolution[j].xdim && validmode[i].ydim == gResolution[j].ydim) 2054 { 2055 gResolution[j].flags |= validmode[i].fs ? RES_FS : RES_WIN; 2056 Bsnprintf(gResolution[j].name, MAXRESOLUTIONSTRINGLENGTH, "%d x %d%s", gResolution[j].xdim, gResolution[j].ydim, (gResolution[j].flags & RES_FS) ? "" : "Win"); 2057 gResolutionName[j] = gResolution[j].name; 2058 if (validmode[i].bpp > gResolution[j].bppmax) 2059 gResolution[j].bppmax = validmode[i].bpp; 2060 break; 2061 } 2062 } 2063 2064 if (j == gResolutionNum) // no match found 2065 { 2066 gResolution[j].xdim = validmode[i].xdim; 2067 gResolution[j].ydim = validmode[i].ydim; 2068 gResolution[j].bppmax = validmode[i].bpp; 2069 gResolution[j].flags = validmode[i].fs ? RES_FS : RES_WIN; 2070 Bsnprintf(gResolution[j].name, MAXRESOLUTIONSTRINGLENGTH, "%d x %d%s", gResolution[j].xdim, gResolution[j].ydim, (gResolution[j].flags & RES_FS) ? "" : "Win"); 2071 gResolutionName[j] = gResolution[j].name; 2072 ++gResolutionNum; 2073 } 2074 } 2075 SetupVideoModeMenu(NULL); 2076 itemOptionsDisplayModeResolution.SetTextArray(gResolutionName, gResolutionNum, 0); 2077 #ifdef USE_OPENGL 2078 menuOptionsDisplayMode.Add(&itemOptionsDisplayModeRenderer, false); 2079 menuOptionsDisplayMode.Add(&itemOptionsDisplayModePolymost, false); 2080 #endif 2081 menuOptionsDisplayMode.Add(&itemOptionsDisplayModeFullscreen, false); 2082 #ifdef USE_OPENGL 2083 menuOptionsDisplayMode.Add(&itemOptionsDisplayModeVSync, false); 2084 #endif 2085 menuOptionsDisplayMode.Add(&itemOptionsDisplayModeFrameLimit, false); 2086 menuOptionsDisplayMode.Add(&itemOptionsDisplayModeApply, false); 2087 menuOptionsDisplayMode.Add(&itemBloodQAV, false); 2088 2089 #ifdef USE_OPENGL 2090 itemOptionsDisplayModeRenderer.pPreDrawCallback = PreDrawVideoModeMenu; 2091 itemOptionsDisplayModePolymost.bEnable = videoGetRenderMode() == REND_POLYMOST; 2092 #endif 2093 itemOptionsDisplayModeFullscreen.pPreDrawCallback = PreDrawVideoModeMenu; 2094 2095 menuOptionsDisplayColor.Add(&itemOptionsDisplayColorTitle, false); 2096 menuOptionsDisplayColor.Add(&itemOptionsDisplayColorPaletteCustom, true); 2097 menuOptionsDisplayColor.Add(&itemOptionsDisplayColorPaletteCIEDE2000, false); 2098 menuOptionsDisplayColor.Add(&itemOptionsDisplayColorPaletteGrayscale, false); 2099 menuOptionsDisplayColor.Add(&itemOptionsDisplayColorPaletteInvert, false); 2100 menuOptionsDisplayColor.Add(&itemOptionsDisplayColorGamma, false); 2101 menuOptionsDisplayColor.Add(&itemOptionsDisplayColorContrast, false); 2102 menuOptionsDisplayColor.Add(&itemOptionsDisplayColorSaturation, false); 2103 menuOptionsDisplayColor.Add(&itemOptionsDisplayColorVisibility, false); 2104 menuOptionsDisplayColor.Add(&itemOptionsDisplayColorReset, false); 2105 menuOptionsDisplayColor.Add(&itemBloodQAV, false); 2106 2107 itemOptionsDisplayColorPaletteCustom.m_nFocus = gCustomPalette % ARRAY_SSIZE(srcCustomPaletteStr); 2108 itemOptionsDisplayColorPaletteCIEDE2000.at20 = gCustomPaletteCIEDE2000; 2109 itemOptionsDisplayColorPaletteGrayscale.at20 = gCustomPaletteGrayscale; 2110 itemOptionsDisplayColorPaletteInvert.m_nFocus = gCustomPaletteInvert % ARRAY_SSIZE(pzInvertPaletteStrings); 2111 itemOptionsDisplayColorContrast.pPreDrawCallback = PreDrawDisplayColor; 2112 itemOptionsDisplayColorSaturation.pPreDrawCallback = PreDrawDisplayColor; 2113 2114 menuOptionsDisplayView.Add(&itemOptionsDisplayViewTitle, false); 2115 menuOptionsDisplayView.Add(&itemOptionsDisplayViewHudSize, true); 2116 menuOptionsDisplayView.Add(&itemOptionsDisplayViewHudRatio, false); 2117 menuOptionsDisplayView.Add(&itemOptionsDisplayViewBoolCenterHoriz, false); 2118 menuOptionsDisplayView.Add(&itemOptionsDisplayViewBoolSlopeTilting, false); 2119 menuOptionsDisplayView.Add(&itemOptionsDisplayViewBoolViewBobbing, false); 2120 menuOptionsDisplayView.Add(&itemOptionsDisplayViewBoolViewSwaying, false); 2121 menuOptionsDisplayView.Add(&itemOptionsDisplayViewWeaponSwaying, false); 2122 menuOptionsDisplayView.Add(&itemOptionsDisplayViewWeaponInterpolation, false); 2123 menuOptionsDisplayView.Add(&itemOptionsDisplayViewBoolInterpolation, false); 2124 menuOptionsDisplayView.Add(&itemOptionsDisplayViewBoolLevelCompleteTime, false); 2125 menuOptionsDisplayView.Add(&itemOptionsDisplayViewBoolPowerupStyle, false); 2126 menuOptionsDisplayView.Add(&itemOptionsDisplayViewSecretMessageStyle, false); 2127 menuOptionsDisplayView.Add(&itemOptionsDisplayViewMirrorMode, false); 2128 menuOptionsDisplayView.Add(&itemOptionsDisplayViewBoolSlowRoomFlicker, false); 2129 menuOptionsDisplayView.Add(&itemBloodQAV, false); 2130 itemOptionsDisplayViewMirrorMode.bDisableForNet = 1; 2131 itemOptionsDisplayViewBoolSlopeTilting.tooltip_pzTextUpper = ""; 2132 itemOptionsDisplayViewBoolSlopeTilting.tooltip_pzTextLower = "Tilt view when looking towards slope"; 2133 itemOptionsDisplayViewWeaponInterpolation.tooltip_pzTextUpper = ""; 2134 itemOptionsDisplayViewWeaponInterpolation.tooltip_pzTextLower = "Interpolate QAV weapon animations (experimental)"; 2135 itemOptionsDisplayViewWeaponSwaying.tooltip_pzTextUpper = ""; 2136 itemOptionsDisplayViewWeaponSwaying.tooltip_pzTextLower = "Set weapon sway (v1.0x alters tommy cultist behavior)"; 2137 itemOptionsDisplayViewBoolInterpolation.tooltip_pzTextUpper = ""; 2138 itemOptionsDisplayViewBoolInterpolation.tooltip_pzTextLower = "Set interpolation method (original/integer or modern/float)"; 2139 itemOptionsDisplayViewBoolPowerupStyle.tooltip_pzTextUpper = ""; 2140 itemOptionsDisplayViewBoolPowerupStyle.tooltip_pzTextLower = "Set the display style for power-ups"; 2141 itemOptionsDisplayViewSecretMessageStyle.tooltip_pzTextUpper = ""; 2142 itemOptionsDisplayViewSecretMessageStyle.tooltip_pzTextLower = "Set the display style for secrets"; 2143 itemOptionsDisplayViewBoolSlowRoomFlicker.tooltip_pzTextUpper = ""; 2144 itemOptionsDisplayViewBoolSlowRoomFlicker.tooltip_pzTextLower = "Reduce the speed of flickering sectors (e.g: E1M4)"; 2145 2146 itemOptionsDisplayViewHudRatio.m_nFocus = gHudRatio % ARRAY_SSIZE(pzHudRatioStrings); 2147 itemOptionsDisplayViewBoolCenterHoriz.at20 = gCenterHoriz; 2148 itemOptionsDisplayViewBoolSlopeTilting.at20 = gSlopeTilting; 2149 itemOptionsDisplayViewBoolViewBobbing.at20 = gViewVBobbing; 2150 itemOptionsDisplayViewBoolViewSwaying.at20 = gViewHBobbing; 2151 itemOptionsDisplayViewWeaponSwaying.m_nFocus = gWeaponHBobbing % ARRAY_SSIZE(pzWeaponHBobbingStrings); 2152 itemOptionsDisplayViewWeaponInterpolation.m_nFocus = gWeaponInterpolate % ARRAY_SSIZE(pzWeaponInterpolateStrings); 2153 itemOptionsDisplayViewBoolInterpolation.at20 = gViewInterpolateMethod; 2154 itemOptionsDisplayViewBoolLevelCompleteTime.at20 = gShowCompleteTime; 2155 itemOptionsDisplayViewBoolPowerupStyle.at20 = gPowerupStyle; 2156 itemOptionsDisplayViewSecretMessageStyle.m_nFocus = gSecretStyle % ARRAY_SSIZE(pzSecretStyleStrings); 2157 itemOptionsDisplayViewMirrorMode.m_nFocus = r_mirrormode % ARRAY_SSIZE(pzMirrorModeStrings); 2158 itemOptionsDisplayViewBoolSlowRoomFlicker.at20 = gSlowRoomFlicker; 2159 2160 #ifdef USE_OPENGL 2161 menuOptionsDisplayPolymost.Add(&itemOptionsDisplayPolymostTitle, false); 2162 //menuOptionsDisplayPolymost.Add(&itemOptionsDisplayPolymostTextureMode, true); 2163 //menuOptionsDisplayPolymost.Add(&itemOptionsDisplayPolymostAnisotropy, false); 2164 menuOptionsDisplayPolymost.Add(&itemOptionsDisplayPolymostTrueColorTextures, true); 2165 menuOptionsDisplayPolymost.Add(&itemOptionsDisplayPolymostTexQuality, false); 2166 menuOptionsDisplayPolymost.Add(&itemOptionsDisplayPolymostPreloadCache, false); 2167 menuOptionsDisplayPolymost.Add(&itemOptionsDisplayPolymostTexCache, false); 2168 menuOptionsDisplayPolymost.Add(&itemOptionsDisplayPolymostDetailTex, false); 2169 menuOptionsDisplayPolymost.Add(&itemOptionsDisplayPolymostGlowTex, false); 2170 menuOptionsDisplayPolymost.Add(&itemOptionsDisplayPolymost3DModels, false); 2171 menuOptionsDisplayPolymost.Add(&itemOptionsDisplayPolymostDeliriumBlur, false); 2172 menuOptionsDisplayPolymost.Add(&itemOptionsDisplayPolymostUseColorIndexedTex, false); 2173 menuOptionsDisplayPolymost.Add(&itemOptionsDisplayPolymostShadeInterpolation, false); 2174 menuOptionsDisplayPolymost.Add(&itemOptionsDisplayPolymostYShearing, false); 2175 menuOptionsDisplayPolymost.Add(&itemOptionsDisplayPolymostRollAngle, false); 2176 menuOptionsDisplayPolymost.Add(&itemBloodQAV, false); 2177 2178 itemOptionsDisplayPolymostTexQuality.pPreDrawCallback = PreDrawDisplayPolymost; 2179 itemOptionsDisplayPolymostPreloadCache.pPreDrawCallback = PreDrawDisplayPolymost; 2180 itemOptionsDisplayPolymostTexCache.pPreDrawCallback = PreDrawDisplayPolymost; 2181 itemOptionsDisplayPolymostDetailTex.pPreDrawCallback = PreDrawDisplayPolymost; 2182 itemOptionsDisplayPolymostGlowTex.pPreDrawCallback = PreDrawDisplayPolymost; 2183 #endif 2184 2185 menuOptionsSound.Add(&itemOptionsSoundTitle, false); 2186 menuOptionsSound.Add(&itemOptionsSoundSoundToggle, true); 2187 menuOptionsSound.Add(&itemOptionsSoundMusicToggle, false); 2188 menuOptionsSound.Add(&itemOptionsSoundMonoStereo, false); 2189 menuOptionsSound.Add(&itemOptionsSoundDoppler, false); 2190 menuOptionsSound.Add(&itemOptionsSoundSoundVolume, false); 2191 menuOptionsSound.Add(&itemOptionsSoundMusicVolume, false); 2192 menuOptionsSound.Add(&itemOptionsSoundSampleRate, false); 2193 menuOptionsSound.Add(&itemOptionsSoundNumVoices, false); 2194 menuOptionsSound.Add(&itemOptionsSoundSpeakerAngle, false); 2195 menuOptionsSound.Add(&itemOptionsSoundCalebTalk, false); 2196 menuOptionsSound.Add(&itemOptionsSoundCDToggle, false); 2197 menuOptionsSound.Add(&itemOptionsSoundMusicDevice, false); 2198 menuOptionsSound.Add(&itemOptionsSoundSF2Bank, false); 2199 itemOptionsSoundSpeakerAngle.tooltip_pzTextUpper = ""; 2200 itemOptionsSoundSpeakerAngle.tooltip_pzTextLower = "Set left/right speaker offset angle (in degrees)"; 2201 itemOptionsSoundCDToggle.tooltip_pzTextUpper = ""; 2202 itemOptionsSoundCDToggle.tooltip_pzTextLower = "Use blood##.ogg/flac files in base folder as redbook audio"; 2203 #ifdef _WIN32 2204 itemOptionsSoundMusicDevice.tooltip_pzTextUpper = ""; 2205 itemOptionsSoundMusicDevice.tooltip_pzTextLower = "For MIDI, use console cmd mus_mme_device # to choose output"; 2206 #endif 2207 2208 menuOptionsSound.Add(&itemOptionsSoundApplyChanges, false); 2209 menuOptionsSound.Add(&itemBloodQAV, false); 2210 2211 menuOptionsSoundSF2.Add(&itemOptionsSoundSF2Title, true); 2212 menuOptionsSoundSF2.Add(&itemOptionsSoundSF2FS, true); 2213 2214 menuOptionsPlayer.Add(&itemOptionsPlayerTitle, false); 2215 menuOptionsPlayer.Add(&itemOptionsPlayerName, true); 2216 menuOptionsPlayer.Add(&itemOptionsPlayerSkill, false); 2217 menuOptionsPlayer.Add(&itemOptionsPlayerTeamPreference, false); 2218 menuOptionsPlayer.Add(&itemOptionsPlayerColorPreference, false); 2219 menuOptionsPlayer.Add(&itemOptionsPlayerModel, false); 2220 menuOptionsPlayer.Add(&itemOptionsPlayerBoolShowPlayerNames, false); 2221 menuOptionsPlayer.Add(&itemOptionsPlayerShowWeapons, false); 2222 menuOptionsPlayer.Add(&itemOptionsPlayerTeamsScoreStyle, false); 2223 menuOptionsPlayer.Add(&itemOptionsPlayerChatSound, false); 2224 menuOptionsPlayer.Add(&itemOptionsPlayerColorMsg, false); 2225 menuOptionsPlayer.Add(&itemOptionsPlayerObituaryMsg, false); 2226 menuOptionsPlayer.Add(&itemOptionsPlayerKillMsg, false); 2227 menuOptionsPlayer.Add(&itemOptionsPlayerMultiKill, false); 2228 menuOptionsPlayer.Add(&itemBloodQAV, false); 2229 itemOptionsPlayerSkill.tooltip_pzTextUpper = "Set player's damage scale handicap"; 2230 itemOptionsPlayerSkill.tooltip_pzTextLower = "(higher = more damage)"; 2231 itemOptionsPlayerTeamPreference.tooltip_pzTextUpper = "Set player's preferred team"; 2232 itemOptionsPlayerColorPreference.tooltip_pzTextUpper = "Set player's preferred color"; 2233 itemOptionsPlayerColorPreference.tooltip_pzTextLower = "(for bloodbath/co-op mode)"; 2234 itemOptionsPlayerModel.tooltip_pzTextUpper = "Set player's sprite model"; 2235 itemOptionsPlayerBoolShowPlayerNames.tooltip_pzTextUpper = "Display player's name"; 2236 itemOptionsPlayerBoolShowPlayerNames.tooltip_pzTextLower = "over crosshair"; 2237 itemOptionsPlayerShowWeapons.tooltip_pzTextUpper = "Display player's weapon"; 2238 itemOptionsPlayerShowWeapons.tooltip_pzTextLower = "over their head"; 2239 itemOptionsPlayerChatSound.tooltip_pzTextUpper = "Play beep sound for chat messages"; 2240 itemOptionsPlayerColorMsg.tooltip_pzTextUpper = "Color player names for chat messages"; 2241 itemOptionsPlayerObituaryMsg.tooltip_pzTextUpper = "Use random obituary kill messages"; 2242 itemOptionsPlayerKillMsg.tooltip_pzTextUpper = "Show player killed on screen"; 2243 itemOptionsPlayerKillMsg.tooltip_pzTextLower = "(for bloodbath/teams mode)"; 2244 itemOptionsPlayerMultiKill.tooltip_pzTextUpper = "Show multi kill alerts on screen"; 2245 itemOptionsPlayerMultiKill.tooltip_pzTextLower = "(for bloodbath/teams mode)"; 2246 2247 itemOptionsPlayerSkill.m_nFocus = gSkill % ARRAY_SSIZE(pzPlayerSkillStrings); 2248 itemOptionsPlayerTeamPreference.m_nFocus = gPlayerTeamPreference % ARRAY_SSIZE(pzPlayerTeamPreferenceStrings); 2249 itemOptionsPlayerColorPreference.m_nFocus = gPlayerColorPreference % ARRAY_SSIZE(pzPlayerColorPreferenceStrings); 2250 itemOptionsPlayerModel.at20 = gPlayerModel; 2251 itemOptionsPlayerBoolShowPlayerNames.at20 = gShowPlayerNames; 2252 itemOptionsPlayerShowWeapons.m_nFocus = gShowWeapon; 2253 itemOptionsPlayerTeamsScoreStyle.at20 = gTeamsScoreStyle; 2254 itemOptionsPlayerChatSound.at20 = gChatSnd; 2255 itemOptionsPlayerColorMsg.at20 = gColorMsg; 2256 itemOptionsPlayerObituaryMsg.at20 = gKillObituary; 2257 itemOptionsPlayerKillMsg.at20 = gKillMsg; 2258 itemOptionsPlayerMultiKill.m_nFocus = gMultiKill % ARRAY_SSIZE(pzPlayerMultiKillStrings); 2259 } 2260 2261 void SetupControlsMenu(void) 2262 { 2263 menuOptionsControl.Add(&itemOptionsControlTitle, false); 2264 menuOptionsControl.Add(&itemOptionsControlKeyboard, true); 2265 menuOptionsControl.Add(&itemOptionsControlMouse, false); 2266 menuOptionsControl.Add(&itemOptionsControlRadial, false); 2267 menuOptionsControl.Add(&itemOptionsControlJoystickButtons, false); 2268 menuOptionsControl.Add(&itemOptionsControlJoystickAxes, false); 2269 menuOptionsControl.Add(&itemOptionsControlJoystickMisc, false); 2270 menuOptionsControl.Add(&itemBloodQAV, false); 2271 2272 menuOptionsControlKeyboard.Add(&itemOptionsControlKeyboardTitle, false); 2273 menuOptionsControlKeyboard.Add(&itemOptionsControlKeyboardSliderTurnSpeed, true); 2274 menuOptionsControlKeyboard.Add(&itemOptionsControlKeyboardCycleTurnAcceleration, false); 2275 menuOptionsControlKeyboard.Add(&itemOptionsControlKeyboardBoolCrouchToggle, false); 2276 menuOptionsControlKeyboard.Add(&itemOptionsControlKeyboardBoolCrouchAuto, false); 2277 menuOptionsControlKeyboard.Add(&itemOptionsControlKeyboardList, false); 2278 menuOptionsControlKeyboard.Add(&itemOptionsControlKeyboardReset, false); 2279 menuOptionsControlKeyboard.Add(&itemOptionsControlKeyboardResetClassic, false); 2280 menuOptionsControlKeyboard.Add(&itemBloodQAV, false); 2281 2282 itemOptionsControlKeyboardSliderTurnSpeed.nValue = gTurnSpeed; 2283 itemOptionsControlKeyboardCycleTurnAcceleration.m_nFocus = gTurnAcceleration % ARRAY_SSIZE(pzTurnAccelerationStrings); 2284 itemOptionsControlKeyboardBoolCrouchToggle.at20 = gCrouchToggle; 2285 itemOptionsControlKeyboardBoolCrouchAuto.at20 = gCrouchAuto; 2286 2287 menuKeys.Add(&itemKeysTitle, false); 2288 menuKeys.Add(&itemKeyList, true); 2289 menuKeys.Add(&itemBloodQAV, false); 2290 2291 menuOptionsControlMouse.Add(&itemOptionsControlMouseTitle, false); 2292 menuOptionsControlMouse.Add(&itemOptionsControlMouseButton, true); 2293 menuOptionsControlMouse.Add(&itemOptionsControlMouseSensitivity, false); 2294 menuOptionsControlMouse.Add(&itemOptionsControlMouseAimFlipped, false); 2295 menuOptionsControlMouse.Add(&itemOptionsControlMouseAimMode, false); 2296 menuOptionsControlMouse.Add(&itemOptionsControlMouseVerticalAim, false); 2297 menuOptionsControlMouse.Add(&itemOptionsControlMouseXSensitivity, false); 2298 menuOptionsControlMouse.Add(&itemOptionsControlMouseYSensitivity, false); 2299 menuOptionsControlMouse.Add(&itemBloodQAV, false); 2300 2301 itemOptionsControlMouseVerticalAim.pPreDrawCallback = PreDrawControlMouse; 2302 2303 menuOptionsControlMouseButtonAssignment.Add(&itemOptionsControlMouseTitle, false); 2304 for (int i = 0, y = 60; i < MENUMOUSEFUNCTIONS; i++) 2305 { 2306 pItemOptionsControlMouseButton[i] = new CGameMenuItemZCycle(MenuMouseNames[i], 3, 66, y, 180, 0, SetMouseButton, pzGamefuncsStrings, NUMGAMEFUNCTIONS+1, 0, true); 2307 dassert(pItemOptionsControlMouseButton[i] != NULL); 2308 menuOptionsControlMouseButtonAssignment.Add(pItemOptionsControlMouseButton[i], i == 0); 2309 y += 10; 2310 } 2311 menuOptionsControlMouseButtonAssignment.Add(&itemBloodQAV, false); 2312 2313 menuOptionsControlRadial.Add(&itemOptionsControlRadialTitle, false); 2314 menuOptionsControlRadial.Add(&itemOptionsControlRadialToggle, true); 2315 menuOptionsControlRadial.Add(&itemOptionsControlRadialPosition, false); 2316 menuOptionsControlRadial.Add(&itemOptionsControlRadialDimBackground, false); 2317 menuOptionsControlRadial.Add(&itemOptionsControlRadialDimHUD, false); 2318 menuOptionsControlRadial.Add(&itemOptionsControlRadialSlowDown, false); 2319 menuOptionsControlRadial.Add(&itemOptionsControlRadialSound, false); 2320 menuOptionsControlRadial.Add(&itemOptionsControlRadialMouseThreshold, false); 2321 menuOptionsControlRadial.Add(&itemOptionsControlRadialThresholdX, false); 2322 menuOptionsControlRadial.Add(&itemOptionsControlRadialThresholdY, false); 2323 menuOptionsControlRadial.Add(&itemOptionsControlRadialYaw, false); 2324 menuOptionsControlRadial.Add(&itemOptionsControlRadialYawInvert, false); 2325 menuOptionsControlRadial.Add(&itemOptionsControlRadialPitch, false); 2326 menuOptionsControlRadial.Add(&itemOptionsControlRadialPitchInvert, false); 2327 menuOptionsControlRadial.Add(&itemBloodQAV, false); 2328 2329 itemOptionsControlRadialToggle.m_nFocus = gRadialMenuToggle % ARRAY_SSIZE(zRadialMenuToggle); 2330 itemOptionsControlRadialPosition.nValue = gRadialMenuPosition; 2331 itemOptionsControlRadialDimBackground.at20 = gRadialMenuDimBackground; 2332 itemOptionsControlRadialDimHUD.at20 = gRadialMenuDimHud; 2333 itemOptionsControlRadialSlowDown.at20 = gRadialMenuSlowDown; 2334 itemOptionsControlRadialSound.m_nFocus = gRadialMenuSfx % ARRAY_SSIZE(pzSoundClickStrings); 2335 itemOptionsControlRadialMouseThreshold.nValue = gRadialMenuMouseThreshold; 2336 itemOptionsControlRadialThresholdX.nValue = gRadialMenuThresholdX; 2337 itemOptionsControlRadialThresholdY.nValue = gRadialMenuThresholdY; 2338 itemOptionsControlRadialYaw.m_nFocus = gRadialMenuYaw % ARRAY_SSIZE(zRadialMenuAxes); 2339 itemOptionsControlRadialYawInvert.at20 = gRadialMenuYawInvert; 2340 itemOptionsControlRadialPitch.m_nFocus = gRadialMenuPitch % ARRAY_SSIZE(zRadialMenuAxes); 2341 itemOptionsControlRadialPitchInvert.at20 = gRadialMenuPitchInvert; 2342 } 2343 2344 void SetupJoystickMenu(void) 2345 { 2346 if (!CONTROL_JoystickEnabled) // joystick disabled, don't bother populating joystick menus 2347 { 2348 itemOptionsControlJoystickButtons.bEnable = 0; 2349 itemOptionsControlJoystickAxes.bEnable = 0; 2350 itemOptionsControlJoystickMisc.bEnable = 0; 2351 return; 2352 } 2353 2354 menuOptionsControlJoystickMisc.Add(&itemOptionsControlJoystickMiscTitle, false); 2355 menuOptionsControlJoystickMisc.Add(&itemOptionsControlJoystickMiscCrouchToggle, true); 2356 menuOptionsControlJoystickMisc.Add(&itemOptionsControlJoystickMiscCrouchAuto, false); 2357 menuOptionsControlJoystickMisc.Add(&itemOptionsControlJoystickMiscCenterView, false); 2358 menuOptionsControlJoystickMisc.Add(&itemOptionsControlJoystickMiscTargetAimAssist, false); 2359 menuOptionsControlJoystickMisc.Add(&itemOptionsControlJoystickMiscRumble, false); 2360 menuOptionsControlJoystickMisc.Add(&itemBloodQAV, false); 2361 itemOptionsControlJoystickMiscTargetAimAssist.tooltip_pzTextUpper = "Slows camera movement when"; 2362 itemOptionsControlJoystickMiscTargetAimAssist.tooltip_pzTextLower = "crosshair is over an enemy"; 2363 2364 itemOptionsControlJoystickMiscCrouchToggle.at20 = gCrouchToggle; 2365 itemOptionsControlJoystickMiscCrouchAuto.at20 = gCrouchAuto; 2366 itemOptionsControlJoystickMiscCenterView.at20 = gCenterViewOnDrop; 2367 itemOptionsControlJoystickMiscTargetAimAssist.at20 = gTargetAimAssist; 2368 itemOptionsControlJoystickMiscRumble.at20 = gSetup.joystickrumble; 2369 2370 int i = 0, y = 0; 2371 for (int nButton = 0; nButton < joystick.numButtons; nButton++) // store every joystick button/hat name for button list at launch 2372 { 2373 const char *pzButtonName = joyGetName(1, nButton); 2374 if (pzButtonName == NULL) // if we've ran out of button names, store joystick hat names 2375 { 2376 for (int nHats = 0; nHats < (joystick.numHats > 0) * 4; nHats++) 2377 { 2378 const char *pzHatName = joyGetName(2, nHats); 2379 if (pzHatName == NULL) 2380 break; 2381 Bsnprintf(MenuJoyButtonNames[i++], 64, "%s", pzHatName); 2382 Bsnprintf(MenuJoyButtonNames[i++], 64, "Double %s", pzHatName); 2383 } 2384 break; 2385 } 2386 Bsnprintf(MenuJoyButtonNames[i++], 64, "%s", pzButtonName); 2387 Bsnprintf(MenuJoyButtonNames[i++], 64, "Double %s", pzButtonName); 2388 } 2389 const int nMaxJoyButtons = i; 2390 2391 i = 0; 2392 for (int nAxis = 0; nAxis < joystick.numAxes; nAxis++) // store every joystick axes for axes list at launch 2393 { 2394 const char *pzAxisName = joyGetName(0, nAxis); 2395 if (pzAxisName == NULL) // if we've ran out of axes names, stop 2396 break; 2397 Bsnprintf(MenuJoyAxisNames[i++], 64, "%s", pzAxisName); 2398 } 2399 const int nMaxJoyAxes = i; 2400 2401 if (nMaxJoyButtons <= 0) // joystick has no buttons, disable button menu 2402 { 2403 itemOptionsControlJoystickButtons.bEnable = 0; 2404 } 2405 else 2406 { 2407 i = 0; 2408 for (int nPage = 0; nPage < MAXJOYSTICKBUTTONPAGES; nPage++) // create lists of joystick button items 2409 { 2410 y = 35; 2411 menuOptionsControlJoystickButtonAssignment[nPage].Add(&itemJoyButtonsTitle, false); 2412 for (int nButton = 0; nButton < JOYSTICKITEMSPERPAGE; nButton++) // populate button list 2413 { 2414 pItemOptionsControlJoyButton[nPage][nButton] = new CGameMenuItemZCycle(MenuJoyButtonNames[i], 3, 66, y, 180, 0, SetJoyButton, pzGamefuncsStrings, NUMGAMEFUNCTIONS+1, 0, true); 2415 dassert(pItemOptionsControlJoyButton[nPage][nButton] != NULL); 2416 menuOptionsControlJoystickButtonAssignment[nPage].Add(pItemOptionsControlJoyButton[nPage][nButton], nButton == 0); 2417 y += 9; 2418 i++; 2419 if (i >= nMaxJoyButtons) // if we've reached the total number of buttons, stop populating list 2420 break; 2421 } 2422 if (i < nMaxJoyButtons) // if we still have more buttons to list, add next page menu item at bottom of page 2423 { 2424 pItemOptionsControlJoyButtonNextPage[nPage] = new CGameMenuItemChain("NEXT PAGE", 3, 0, 182, 320, 1, &menuOptionsControlJoystickButtonAssignment[nPage+1], -1, NULL, 0); 2425 dassert(pItemOptionsControlJoyButtonNextPage[nPage] != NULL); 2426 menuOptionsControlJoystickButtonAssignment[nPage].Add(pItemOptionsControlJoyButtonNextPage[nPage], false); 2427 } 2428 menuOptionsControlJoystickButtonAssignment[nPage].Add(&itemBloodQAV, false); 2429 } 2430 } 2431 2432 if (nMaxJoyAxes <= 0) // joystick has no axes, disable axis menu 2433 { 2434 itemOptionsControlJoystickAxes.bEnable = 0; 2435 return; 2436 } 2437 2438 for (int nAxis = 0; nAxis < (int)ARRAY_SIZE(pItemOptionsControlJoystickAxis); nAxis++) // set all possible axis items to null (used for button setup) 2439 pItemOptionsControlJoystickAxis[nAxis] = NULL; 2440 2441 y = 40; 2442 const char bUseBigFont = nMaxJoyAxes <= 6; 2443 menuOptionsControlJoystickListAxes.Add(&itemJoyAxesTitle, false); 2444 for (int nAxis = 0; nAxis < nMaxJoyAxes; nAxis++) // create list of axes for joystick axis menu 2445 { 2446 pItemOptionsControlJoystickAxis[nAxis] = new CGameMenuItemChain(MenuJoyAxisNames[nAxis], bUseBigFont ? 1 : 3, 66, y, 180, 0, &menuOptionsControlJoystickAxis[nAxis], -1, SetupJoystickAxisHeatmap, 0); 2447 dassert(pItemOptionsControlJoystickAxis[nAxis] != NULL); 2448 menuOptionsControlJoystickListAxes.Add(pItemOptionsControlJoystickAxis[nAxis], nAxis == 0); 2449 y += bUseBigFont ? 20 : 10; 2450 } 2451 menuOptionsControlJoystickListAxes.Add(&itemBloodQAV, false); 2452 2453 for (int nAxis = 0; nAxis < nMaxJoyAxes; nAxis++) // create settings for each listed joystick axis 2454 { 2455 y = 40; 2456 menuOptionsControlJoystickAxis[nAxis].Add(&itemJoyAxesTitle, false); 2457 pItemOptionsControlJoystickAxisName[nAxis] = new CGameMenuItemTitle(MenuJoyAxisNames[nAxis], 3, 160, y, -1); // get axis name 2458 dassert(pItemOptionsControlJoystickAxisName[nAxis] != NULL); 2459 menuOptionsControlJoystickAxis[nAxis].Add(pItemOptionsControlJoystickAxisName[nAxis], false); 2460 y += 10; 2461 pItemOptionsControlJoystickAxisScale[nAxis] = new CGameMenuItemSlider("AXIS SCALE:", 1, 18, y, 280, &JoystickAnalogueScale[nAxis], fix16_from_int(0), fix16_from_float(2.f), fix16_from_float(0.025f), SetJoystickScale, -1, -1, kMenuSliderQ16); // get axis scale 2462 dassert(pItemOptionsControlJoystickAxisScale[nAxis] != NULL); 2463 menuOptionsControlJoystickAxis[nAxis].Add(pItemOptionsControlJoystickAxisScale[nAxis], true); 2464 y += 22; 2465 pItemOptionsControlJoystickAxisAnalogue[nAxis] = new CGameMenuItemZCycle("ANALOG:", 1, 18, y, 280, 0, SetJoystickAnalogue, zJoystickAnalogue, ARRAY_SSIZE(zJoystickAnalogue), 0); // get analog function 2466 dassert(pItemOptionsControlJoystickAxisAnalogue[nAxis] != NULL); 2467 menuOptionsControlJoystickAxis[nAxis].Add(pItemOptionsControlJoystickAxisAnalogue[nAxis], false); 2468 y += 17; 2469 pItemOptionsControlJoystickAxisAnalogueInvert[nAxis] = new CGameMenuItemZBool("ANALOG INVERT:", 1, 18, y, 280, false, SetJoystickAnalogueInvert, NULL, NULL); // get analog function 2470 dassert(pItemOptionsControlJoystickAxisAnalogueInvert[nAxis] != NULL); 2471 menuOptionsControlJoystickAxis[nAxis].Add(pItemOptionsControlJoystickAxisAnalogueInvert[nAxis], false); 2472 y += 17; 2473 pItemOptionsControlJoystickAxisDigitalPos[nAxis] = new CGameMenuItemZCycle("DIGITAL +:", 1, 18, y, 280, 0, SetJoystickDigitalPos, pzGamefuncsStrings, NUMGAMEFUNCTIONS+1, 0, true); // get digital function 2474 dassert(pItemOptionsControlJoystickAxisDigitalPos[nAxis] != NULL); 2475 menuOptionsControlJoystickAxis[nAxis].Add(pItemOptionsControlJoystickAxisDigitalPos[nAxis], false); 2476 y += 17; 2477 pItemOptionsControlJoystickAxisDigitalNeg[nAxis] = new CGameMenuItemZCycle("DIGITAL -:", 1, 18, y, 280, 0, SetJoystickDigitalNeg, pzGamefuncsStrings, NUMGAMEFUNCTIONS+1, 0, true); // get digital function 2478 dassert(pItemOptionsControlJoystickAxisDigitalNeg[nAxis] != NULL); 2479 menuOptionsControlJoystickAxis[nAxis].Add(pItemOptionsControlJoystickAxisDigitalNeg[nAxis], false); 2480 y += 22; 2481 pItemOptionsControlJoystickAxisDeadzone[nAxis] = new CGameMenuItemSlider("DEAD ZONE:", 1, 18, y, 220, &JoystickAnalogueDead[nAxis], fix16_from_int(0), fix16_from_float(0.5f), fix16_from_float(0.025f), SetJoystickDeadzone, -1, -1, kMenuSliderPercent); // get dead size 2482 dassert(pItemOptionsControlJoystickAxisDeadzone[nAxis] != NULL); 2483 menuOptionsControlJoystickAxis[nAxis].Add(pItemOptionsControlJoystickAxisDeadzone[nAxis], false); 2484 y += 17; 2485 pItemOptionsControlJoystickAxisSaturate[nAxis] = new CGameMenuItemSlider("SATURATE:", 1, 18, y, 220, &JoystickAnalogueSaturate[nAxis], fix16_from_int(0), fix16_from_float(0.5f), fix16_from_float(0.025f), SetJoystickSaturate, -1, -1, kMenuSliderPercent); // get saturate 2486 dassert(pItemOptionsControlJoystickAxisSaturate[nAxis] != NULL); 2487 menuOptionsControlJoystickAxis[nAxis].Add(pItemOptionsControlJoystickAxisSaturate[nAxis], false); 2488 y += 17; 2489 pItemOptionsControlJoystickAxisSnapZone[nAxis] = new CGameMenuItemSlider("SNAP ZONE:", 1, 18, y, 220, &JoystickAnalogueSnap[nAxis], fix16_from_int(0), fix16_from_float(0.5f), fix16_from_float(0.05f), SetJoystickSnapZone, -1, -1, kMenuSliderPercent); // get snap axis zone 2490 dassert(pItemOptionsControlJoystickAxisSnapZone[nAxis] != NULL); 2491 if (CONTROL_GetControllerAxisIsTwinAxisStick(nAxis)) // only add for analog stick axis 2492 menuOptionsControlJoystickAxis[nAxis].Add(pItemOptionsControlJoystickAxisSnapZone[nAxis], false); 2493 menuOptionsControlJoystickAxis[nAxis].Add(&ItemOptionsControlJoystickAxisHeatmapPic, false); 2494 menuOptionsControlJoystickAxis[nAxis].Add(&itemBloodQAV, false); 2495 } 2496 ItemOptionsControlJoystickAxisHeatmapPic.bEnable = 0; 2497 } 2498 2499 void SetupMenus(void) 2500 { 2501 // prepare gamefuncs and keys 2502 pzGamefuncsStrings[0] = MenuGameFuncNone; 2503 nGamefuncsValues[0] = -1; 2504 int k = 1; 2505 for (int i = 0; i < NUMGAMEFUNCTIONS; ++i) 2506 { 2507 Bstrcpy(MenuGameFuncs[i], gamefunctions[i]); 2508 2509 for (int j = 0; j < MAXGAMEFUNCLEN; ++j) 2510 if (MenuGameFuncs[i][j] == '_') 2511 MenuGameFuncs[i][j] = ' '; 2512 2513 if (gamefunctions[i][0] != '\0') 2514 { 2515 pzGamefuncsStrings[k] = MenuGameFuncs[i]; 2516 nGamefuncsValues[k] = i; 2517 ++k; 2518 } 2519 } 2520 2521 nGamefuncsNum = k; 2522 2523 SetupLoadingScreen(); 2524 SetupMessagesMenu(); 2525 SetupSaveGameMenu(); 2526 SetupLoadGameMenu(); 2527 SetupCreditsMenu(); 2528 SetupHelpMenu(); 2529 SetupDifficultyMenu(); 2530 SetupEpisodeMenu(); 2531 SetupMainMenu(); 2532 SetupMainMenuWithSave(); 2533 SetupFirstLaunchMenu(); 2534 SetupNetStartMenu(); 2535 SetupQuitMenu(); 2536 2537 SetupOptionsMenu(); 2538 SetupControlsMenu(); 2539 SetupJoystickMenu(); 2540 SetupNetworkMenu(); 2541 } 2542 2543 void UpdateNetworkMenus(void) 2544 { 2545 if (gGameOptions.nGameType != kGameTypeSinglePlayer) 2546 { 2547 itemMain1.at24 = &menuNetStart; 2548 itemMain1.at28 = 2; 2549 } 2550 else 2551 { 2552 itemMain1.at24 = &menuEpisode; 2553 itemMain1.at28 = -1; 2554 } 2555 if (gGameOptions.nGameType != kGameTypeSinglePlayer) 2556 { 2557 itemMainSave1.at24 = &menuNetStart; 2558 itemMainSave1.at28 = 2; 2559 } 2560 else 2561 { 2562 itemMainSave1.at24 = &menuEpisode; 2563 itemMainSave1.at28 = -1; 2564 } 2565 } 2566 2567 void SetMonoStereo(CGameMenuItemZBool *pItem) 2568 { 2569 gStereo = pItem->at20; 2570 itemOptionsSoundDoppler.bEnable = gStereo; 2571 } 2572 2573 void SetVoxels(CGameMenuItemZBool *pItem) 2574 { 2575 usevoxels = pItem->at20; 2576 } 2577 2578 void SetCrosshair(CGameMenuItemZCycle *pItem) 2579 { 2580 gAimReticle = pItem->m_nFocus % ARRAY_SSIZE(pzCrosshairStrings); 2581 } 2582 2583 void ResetKeys(CGameMenuItemChain *) 2584 { 2585 CONFIG_SetDefaultKeys(keydefaults); 2586 } 2587 2588 void ResetKeysClassic(CGameMenuItemChain *) 2589 { 2590 CONFIG_SetDefaultKeys(oldkeydefaults); 2591 } 2592 2593 //// 2594 void SetQuadDamagePowerup(CGameMenuItemZBool* pItem) 2595 { 2596 if ((gGameOptions.nGameType == kGameTypeSinglePlayer) && (numplayers == 1)) { 2597 gQuadDamagePowerup = pItem->at20; 2598 gGameOptions.bQuadDamagePowerup = gQuadDamagePowerup; 2599 } else { 2600 pItem->at20 = gQuadDamagePowerup; 2601 } 2602 } 2603 2604 void SetDamageInvul(CGameMenuItemZCycle* pItem) 2605 { 2606 if ((gGameOptions.nGameType == kGameTypeSinglePlayer) && (numplayers == 1)) { 2607 gDamageInvul = pItem->m_nFocus % ARRAY_SSIZE(pzDamageInvulBehaviorStrings); 2608 gGameOptions.nDamageInvul = gDamageInvul; 2609 } else { 2610 pItem->m_nFocus = gDamageInvul % ARRAY_SSIZE(pzDamageInvulBehaviorStrings); 2611 } 2612 } 2613 2614 void SetProjectileBehavior(CGameMenuItemZCycle *pItem) 2615 { 2616 if ((gGameOptions.nGameType == kGameTypeSinglePlayer) && (numplayers == 1)) { 2617 gProjectileBehavior = pItem->m_nFocus % ARRAY_SSIZE(pzProjectileBehaviorStrings); 2618 gGameOptions.nProjectileBehavior = gProjectileBehavior; 2619 } else { 2620 pItem->m_nFocus = gProjectileBehavior % ARRAY_SSIZE(pzProjectileBehaviorStrings); 2621 } 2622 } 2623 2624 void SetNapalmFalloff(CGameMenuItemZBool *pItem) 2625 { 2626 if ((gGameOptions.nGameType == kGameTypeSinglePlayer) && (numplayers == 1)) { 2627 gNapalmFalloff = pItem->at20; 2628 gGameOptions.bNapalmFalloff = gNapalmFalloff; 2629 } else { 2630 pItem->at20 = !!gNapalmFalloff; 2631 } 2632 } 2633 2634 void SetEnemyBehavior(CGameMenuItemZCycle *pItem) 2635 { 2636 if ((gGameOptions.nGameType == kGameTypeSinglePlayer) && (numplayers == 1)) { 2637 gEnemyBehavior = pItem->m_nFocus % ARRAY_SSIZE(pzEnemyBehaviorStrings); 2638 gGameOptions.nEnemyBehavior = gEnemyBehavior; 2639 } else { 2640 pItem->m_nFocus = gEnemyBehavior % ARRAY_SSIZE(pzEnemyBehaviorStrings); 2641 } 2642 } 2643 2644 void SetEnemyRandomTNT(CGameMenuItemZBool* pItem) 2645 { 2646 if ((gGameOptions.nGameType == kGameTypeSinglePlayer) && (numplayers == 1)) { 2647 gEnemyRandomTNT = pItem->at20; 2648 gGameOptions.bEnemyRandomTNT = gEnemyRandomTNT; 2649 } else { 2650 pItem->at20 = !!gEnemyRandomTNT; 2651 } 2652 } 2653 2654 void SetWeaponsVer(CGameMenuItemZCycle* pItem) 2655 { 2656 if ((gGameOptions.nGameType == kGameTypeSinglePlayer) && (numplayers == 1)) { 2657 gWeaponsVer = pItem->m_nFocus % ARRAY_SSIZE(pzWeaponsVersionStrings); 2658 gGameOptions.nWeaponsVer = gWeaponsVer; 2659 } else { 2660 pItem->m_nFocus = gWeaponsVer % ARRAY_SSIZE(pzWeaponsVersionStrings); 2661 } 2662 } 2663 2664 void SetAmmoScale(CGameMenuItemZCycle *pItem) 2665 { 2666 if ((gGameOptions.nGameType == kGameTypeSinglePlayer) && (numplayers == 1)) { 2667 gAmmoScale = pItem->m_nFocus % ARRAY_SSIZE(pzAmmoScaleStrings); 2668 gGameOptions.nAmmoScale = gAmmoScale; 2669 } else { 2670 pItem->m_nFocus = gAmmoScale % ARRAY_SSIZE(pzAmmoScaleStrings); 2671 } 2672 } 2673 2674 void SetSectorBehavior(CGameMenuItemZBool *pItem) 2675 { 2676 if ((gGameOptions.nGameType == kGameTypeSinglePlayer) && (numplayers == 1)) { 2677 gSectorBehavior = pItem->at20; 2678 gGameOptions.bSectorBehavior = gSectorBehavior; 2679 } else { 2680 pItem->at20 = !!gSectorBehavior; 2681 } 2682 } 2683 2684 void SetHitscanProjectiles(CGameMenuItemZCycle *pItem) 2685 { 2686 if ((gGameOptions.nGameType == kGameTypeSinglePlayer) && (numplayers == 1)) { 2687 gHitscanProjectiles = pItem->m_nFocus % ARRAY_SSIZE(pzHitscanProjectilesStrings); 2688 gGameOptions.nHitscanProjectiles = gHitscanProjectiles; 2689 } else { 2690 pItem->m_nFocus = gHitscanProjectiles % ARRAY_SSIZE(pzHitscanProjectilesStrings); 2691 } 2692 } 2693 2694 void SetGoreMode(CGameMenuItemZCycle *pItem) 2695 { 2696 if ((gGameOptions.nGameType == kGameTypeSinglePlayer) && (numplayers == 1)) { 2697 gGoreBehavior = pItem->m_nFocus % ARRAY_SSIZE(pzGoreStrings); 2698 gGameOptions.nGoreBehavior = gGoreBehavior; 2699 } else { 2700 pItem->m_nFocus = gGoreBehavior % ARRAY_SSIZE(pzGoreStrings); 2701 } 2702 } 2703 2704 void SetPlayerSpeed(CGameMenuItemZCycle *pItem) 2705 { 2706 if ((gGameOptions.nGameType == kGameTypeSinglePlayer) && (numplayers == 1)) { 2707 gPlayerModSpeed = pItem->m_nFocus % ARRAY_SSIZE(pzPlayerSpeeds); 2708 gGameOptions.nPlayerSpeed = gPlayerModSpeed; 2709 } else { 2710 pItem->m_nFocus = gPlayerModSpeed % ARRAY_SSIZE(pzPlayerSpeeds); 2711 } 2712 } 2713 2714 void SetRandomizerMode(CGameMenuItemZCycle *pItem) 2715 { 2716 if ((gGameOptions.nGameType == kGameTypeSinglePlayer) && (numplayers == 1)) { 2717 gRandomizerMode = pItem->m_nFocus % ARRAY_SSIZE(pzRandomizerModeStrings); 2718 gGameOptions.nRandomizerMode = gRandomizerMode; 2719 } else { 2720 pItem->m_nFocus = gRandomizerMode % ARRAY_SSIZE(pzRandomizerModeStrings); 2721 } 2722 } 2723 2724 void SetRandomizerSeed(CGameMenuItemZEdit *pItem, CGameMenuEvent *pEvent) 2725 { 2726 UNREFERENCED_PARAMETER(pItem); 2727 UNREFERENCED_PARAMETER(pEvent); 2728 Bstrncpy(gzRandomizerSeed, szRandomizerSeedMenu, sizeof(gzRandomizerSeed)); 2729 if ((gGameOptions.nGameType == kGameTypeSinglePlayer) && (numplayers == 1)) 2730 Bstrncpy(gGameOptions.szRandomizerSeed, gzRandomizerSeed, sizeof(gGameOptions.szRandomizerSeed)); 2731 } 2732 //// 2733 2734 void SetHudSize(CGameMenuItemSlider *pItem) 2735 { 2736 gViewSize = pItem->nValue; 2737 viewResizeView(gViewSize); 2738 } 2739 2740 void SetHudRatio(CGameMenuItemZCycle *pItem) 2741 { 2742 gHudRatio = pItem->m_nFocus % ARRAY_SSIZE(pzHudRatioStrings); 2743 viewResizeView(gViewSize); 2744 } 2745 2746 void SetCenterHoriz(CGameMenuItemZBool *pItem) 2747 { 2748 gCenterHoriz = pItem->at20; 2749 } 2750 2751 void SetSlopeTilting(CGameMenuItemZBool *pItem) 2752 { 2753 gSlopeTilting = pItem->at20; 2754 } 2755 2756 void SetViewBobbing(CGameMenuItemZBool *pItem) 2757 { 2758 gViewVBobbing = pItem->at20; 2759 } 2760 2761 void SetViewSwaying(CGameMenuItemZBool *pItem) 2762 { 2763 gViewHBobbing = pItem->at20; 2764 } 2765 2766 void SetWeaponSwaying(CGameMenuItemZCycle *pItem) 2767 { 2768 gWeaponHBobbing = pItem->m_nFocus % ARRAY_SSIZE(pzWeaponHBobbingStrings); 2769 if (!gDemo.bRecording && !gDemo.bPlaying) 2770 { 2771 if ((numplayers > 1) || (gGameOptions.nGameType != kGameTypeSinglePlayer)) // if multiplayer session is active 2772 { 2773 netBroadcastPlayerInfoUpdate(myconnectindex); 2774 return; 2775 } 2776 gProfile[myconnectindex].nWeaponHBobbing = gWeaponHBobbing; 2777 netBroadcastPlayerInfo(myconnectindex); 2778 } 2779 } 2780 2781 void SetWeaponInterpolate(CGameMenuItemZCycle *pItem) 2782 { 2783 gWeaponInterpolate = pItem->m_nFocus % ARRAY_SSIZE(pzWeaponInterpolateStrings); 2784 } 2785 2786 void SetViewInterpolate(CGameMenuItemZBool *pItem) 2787 { 2788 gViewInterpolateMethod = pItem->at20; 2789 } 2790 2791 void SetLevelCompleteTime(CGameMenuItemZBool *pItem) 2792 { 2793 gShowCompleteTime = pItem->at20; 2794 } 2795 2796 void SetMirrorMode(CGameMenuItemZCycle *pItem) 2797 { 2798 r_mirrormode = pItem->m_nFocus % ARRAY_SSIZE(pzMirrorModeStrings); 2799 } 2800 2801 void SetSlowRoomFlicker(CGameMenuItemZBool *pItem) 2802 { 2803 gSlowRoomFlicker = pItem->at20; 2804 } 2805 2806 void SetMusicVol(CGameMenuItemSlider *pItem) 2807 { 2808 sndSetMusicVolume(pItem->nValue); 2809 } 2810 2811 void SetSoundVol(CGameMenuItemSlider *pItem) 2812 { 2813 sndSetFXVolume(pItem->nValue); 2814 } 2815 2816 void SetCDVol(CGameMenuItemSlider *pItem) 2817 { 2818 UNREFERENCED_PARAMETER(pItem); 2819 // NUKE-TODO: 2820 } 2821 2822 void SetMessages(CGameMenuItemZBool *pItem) 2823 { 2824 gMessageState = pItem->at20; 2825 gGameMessageMgr.SetState(gMessageState); 2826 } 2827 2828 void SetMouseSensitivity(CGameMenuItemSliderFloat *pItem) 2829 { 2830 CONTROL_MouseSensitivity = pItem->fValue; 2831 } 2832 2833 void SetMouseAimFlipped(CGameMenuItemZBool *pItem) 2834 { 2835 gMouseAimingFlipped = pItem->at20; 2836 } 2837 2838 void SetTurnSpeed(CGameMenuItemSlider *pItem) 2839 { 2840 gTurnSpeed = pItem->nValue; 2841 } 2842 2843 void SetTurnAcceleration(CGameMenuItemZCycle *pItem) 2844 { 2845 gTurnAcceleration = pItem->m_nFocus % ARRAY_SSIZE(pzTurnAccelerationStrings); 2846 } 2847 2848 void SetCenterView(CGameMenuItemZBool *pItem) 2849 { 2850 gCenterViewOnDrop = pItem->at20; 2851 } 2852 2853 void SetJoystickTargetAimAssist(CGameMenuItemZBool *pItem) 2854 { 2855 gTargetAimAssist = pItem->at20; 2856 } 2857 2858 void SetRadialMenuToggle(CGameMenuItemZCycle *pItem) 2859 { 2860 gRadialMenuToggle = pItem->m_nFocus % ARRAY_SSIZE(zRadialMenuToggle); 2861 } 2862 2863 void SetRadialMenuPosition(CGameMenuItemSlider *pItem) 2864 { 2865 gRadialMenuPosition = pItem->nValue; 2866 } 2867 2868 void SetRadialMenuDimBackground(CGameMenuItemZBool *pItem) 2869 { 2870 gRadialMenuDimBackground = pItem->at20; 2871 } 2872 2873 void SetRadialMenuDimHUD(CGameMenuItemZBool *pItem) 2874 { 2875 gRadialMenuDimHud = pItem->at20; 2876 } 2877 2878 void SetRadialMenuSlowDown(CGameMenuItemZBool *pItem) 2879 { 2880 gRadialMenuSlowDown = pItem->at20; 2881 } 2882 2883 void SetRadialMenuSound(CGameMenuItemZCycle *pItem) 2884 { 2885 gRadialMenuSfx = pItem->m_nFocus % ARRAY_SIZE(pzSoundClickStrings); 2886 } 2887 2888 void SetRadialMenuMouseThreshold(CGameMenuItemSlider *pItem) 2889 { 2890 gRadialMenuMouseThreshold = pItem->nValue; 2891 } 2892 2893 void SetRadialMenuThreshold(CGameMenuItemSlider *pItem) 2894 { 2895 UNREFERENCED_PARAMETER(pItem); 2896 gRadialMenuThresholdX = itemOptionsControlRadialThresholdX.nValue; 2897 gRadialMenuThresholdY = itemOptionsControlRadialThresholdY.nValue; 2898 } 2899 2900 void SetRadialMenuYaw(CGameMenuItemZCycle *pItem) 2901 { 2902 gRadialMenuYaw = pItem->m_nFocus % ARRAY_SIZE(zRadialMenuAxes); 2903 } 2904 2905 void SetRadialMenuYawInvert(CGameMenuItemZBool *pItem) 2906 { 2907 gRadialMenuYawInvert = pItem->at20; 2908 } 2909 2910 void SetRadialMenuPitch(CGameMenuItemZCycle *pItem) 2911 { 2912 gRadialMenuPitch = pItem->m_nFocus % ARRAY_SIZE(zRadialMenuAxes); 2913 } 2914 2915 void SetRadialMenuPitchInvert(CGameMenuItemZBool *pItem) 2916 { 2917 gRadialMenuPitchInvert = pItem->at20; 2918 } 2919 2920 void SetJoystickRumble(CGameMenuItemZBool *pItem) 2921 { 2922 gSetup.joystickrumble = pItem->at20; 2923 } 2924 2925 void SetCrouchToggle(CGameMenuItemZBool *pItem) 2926 { 2927 gCrouchToggle = itemOptionsControlKeyboardBoolCrouchToggle.at20 = itemOptionsControlJoystickMiscCrouchToggle.at20 = pItem->at20; 2928 } 2929 2930 void SetCrouchAuto(CGameMenuItemZBool *pItem) 2931 { 2932 gCrouchAuto = itemOptionsControlKeyboardBoolCrouchAuto.at20 = itemOptionsControlJoystickMiscCrouchAuto.at20 = pItem->at20; 2933 } 2934 2935 void SetAutoAim(CGameMenuItemZCycle *pItem) 2936 { 2937 gAutoAim = pItem->m_nFocus; 2938 if (!gDemo.bRecording && !gDemo.bPlaying) 2939 { 2940 if ((numplayers > 1) || (gGameOptions.nGameType != kGameTypeSinglePlayer)) // if multiplayer session is active 2941 { 2942 netBroadcastPlayerInfoUpdate(myconnectindex); 2943 return; 2944 } 2945 gProfile[myconnectindex].nAutoAim = gAutoAim; 2946 netBroadcastPlayerInfo(myconnectindex); 2947 } 2948 } 2949 2950 void SetAutoAimRange(CGameMenuItemSlider *pItem) 2951 { 2952 gAutoAimRange = pItem->nValue; 2953 } 2954 2955 void SetAutoRun(CGameMenuItemZBool *pItem) 2956 { 2957 gAutoRun = pItem->at20; 2958 } 2959 2960 void SetLevelStats(CGameMenuItemZCycle *pItem) 2961 { 2962 gLevelStats = pItem->m_nFocus % ARRAY_SSIZE(pzStatsPowerupRatioStrings); 2963 itemOptionsDisplayLevelStatsOnAutomap.bEnable = !!gLevelStats; 2964 viewResizeView(gViewSize); 2965 } 2966 2967 void SetLevelStatsOnAutomap(CGameMenuItemZBool *pItem) 2968 { 2969 gLevelStatsOnlyOnMap = pItem->at20; 2970 } 2971 2972 void SetPowerupDuration(CGameMenuItemZCycle* pItem) 2973 { 2974 gPowerupDuration = pItem->m_nFocus % ARRAY_SSIZE(pzStatsPowerupRatioStrings); 2975 viewResizeView(gViewSize); 2976 } 2977 2978 void SetPowerupStyle(CGameMenuItemZBool* pItem) 2979 { 2980 gPowerupStyle = pItem->at20; 2981 } 2982 2983 void SetSecretStyle(CGameMenuItemZCycle *pItem) 2984 { 2985 gSecretStyle = pItem->m_nFocus % ARRAY_SSIZE(pzSecretStyleStrings); 2986 } 2987 2988 void SetShowMapTitle(CGameMenuItemZBool* pItem) 2989 { 2990 gShowMapTitle = pItem->at20; 2991 } 2992 2993 void SetWeaponSwitch(CGameMenuItemZCycle *pItem) 2994 { 2995 gWeaponSwitch = pItem->m_nFocus % ARRAY_SSIZE(pzWeaponSwitchStrings); 2996 if (!gDemo.bRecording && !gDemo.bPlaying) 2997 { 2998 if ((numplayers > 1) || (gGameOptions.nGameType != kGameTypeSinglePlayer)) // if multiplayer session is active 2999 { 3000 netBroadcastPlayerInfoUpdate(myconnectindex); 3001 return; 3002 } 3003 gProfile[myconnectindex].nWeaponSwitch = gWeaponSwitch; 3004 netBroadcastPlayerInfo(myconnectindex); 3005 } 3006 } 3007 3008 void SetWeaponFastSwitch(CGameMenuItemZBool *pItem) 3009 { 3010 gWeaponFastSwitch = pItem->at20; 3011 if (!gDemo.bRecording && !gDemo.bPlaying) 3012 { 3013 if ((numplayers > 1) || (gGameOptions.nGameType != kGameTypeSinglePlayer)) // if multiplayer session is active 3014 { 3015 netBroadcastPlayerInfoUpdate(myconnectindex); 3016 return; 3017 } 3018 gProfile[myconnectindex].bWeaponFastSwitch = gWeaponFastSwitch; 3019 netBroadcastPlayerInfo(myconnectindex); 3020 } 3021 } 3022 3023 void SetAutosaveMode(CGameMenuItemZCycle *pItem) 3024 { 3025 gAutosave = pItem->m_nFocus % ARRAY_SSIZE(pzAutosaveModeStrings); 3026 3027 itemLoadGameAutosaveStart.bEnable = gAutosave != 0; // remove autosave slots if autosaves are disabled 3028 itemLoadGameAutosaveStart.bNoDraw = gAutosave == 0; 3029 itemSaveGameAutosaveStart.bNoDraw = gAutosave == 0; 3030 itemLoadGameAutosaveKey.bEnable = gAutosave == 2; 3031 itemLoadGameAutosaveKey.bNoDraw = gAutosave != 2; 3032 itemSaveGameAutosaveKey.bNoDraw = gAutosave != 2; 3033 } 3034 3035 void SetLockSaving(CGameMenuItemZBool *pItem) 3036 { 3037 gLockManualSaving = pItem->at20; 3038 3039 itemMainSave3.bEnable = !gLockManualSaving; // hide save option in main menu if lock saving mode is set 3040 } 3041 3042 void SetRestoreLastSave(CGameMenuItemZBool *pItem) 3043 { 3044 gRestoreLastSave = pItem->at20; 3045 } 3046 3047 void SetGameVanillaMode(char nState) 3048 { 3049 gVanilla = nState % ARRAY_SSIZE(pzVanillaModeStrings); 3050 itemOptionsGameWeaponFastSwitch.bEnable = !gVanilla; 3051 itemOptionsGameBoolVanillaMode.m_nFocus = gVanilla % ARRAY_SSIZE(pzVanillaModeStrings); 3052 itemOptionsDisplayViewBoolInterpolation.bEnable = !gVanilla; 3053 itemOptionsDisplayViewSecretMessageStyle.bEnable = !gVanilla; 3054 itemOptionsDisplayWeaponSelect.bEnable = !gVanilla; 3055 itemOptionsChainMutators.bEnable = !gVanilla; 3056 VanillaModeUpdate(); 3057 } 3058 3059 void SetVanillaMode(CGameMenuItemZCycle *pItem) 3060 { 3061 if ((gGameOptions.nGameType == kGameTypeSinglePlayer) && (numplayers == 1)) 3062 { 3063 SetGameVanillaMode((char)pItem->m_nFocus); 3064 viewClearInterpolations(); 3065 viewResizeView(gViewSize); 3066 gGameMessageMgr.Clear(); 3067 } 3068 else 3069 { 3070 pItem->m_nFocus = gVanilla % ARRAY_SSIZE(pzVanillaModeStrings); 3071 viewSetMessage("Vanilla mode is disabled for multiplayer"); 3072 } 3073 } 3074 3075 inline unsigned int SetBannedSprites(char bSinglePlayer) 3076 { 3077 unsigned int uSpriteBannedFlags = BANNED_NONE; 3078 3079 if (bSinglePlayer) 3080 { 3081 // monsters 3082 if (itemBannedMonstersBats.at20) 3083 uSpriteBannedFlags |= BANNED_BATS; 3084 if (itemBannedMonstersRats.at20) 3085 uSpriteBannedFlags |= BANNED_RATS; 3086 if (itemBannedMonstersFish.at20) 3087 uSpriteBannedFlags |= BANNED_FISH; 3088 if (itemBannedMonstersHands.at20) 3089 uSpriteBannedFlags |= BANNED_HANDS; 3090 if (itemBannedMonstersGhosts.at20) 3091 uSpriteBannedFlags |= BANNED_GHOSTS; 3092 if (itemBannedMonstersSpiders.at20) 3093 uSpriteBannedFlags |= BANNED_SPIDERS; 3094 if (itemBannedMonstersTinyCaleb.at20) 3095 uSpriteBannedFlags |= BANNED_TCALEBS; 3096 if (itemBannedMonstersHellHounds.at20) 3097 uSpriteBannedFlags |= BANNED_HHOUNDS; 3098 3099 // monster behavior tweaks 3100 if (itemBannedMonstersRatsAttack.at20) 3101 uSpriteBannedFlags |= BANNED_RATS_BITE; 3102 if (itemBannedMonstersMotherSpiderHealth.at20) 3103 uSpriteBannedFlags |= BANNED_MSPIDERS_HP; 3104 if (itemBannedMonstersTchernobogHealth.at20) 3105 uSpriteBannedFlags |= BANNED_TCHERNOBOG_HP; 3106 } 3107 else // load from network monster menu 3108 { 3109 // monsters 3110 if (itemNetMonsterBats.at20) 3111 uSpriteBannedFlags |= BANNED_BATS; 3112 if (itemNetMonsterRats.at20) 3113 uSpriteBannedFlags |= BANNED_RATS; 3114 if (itemNetMonsterFish.at20) 3115 uSpriteBannedFlags |= BANNED_FISH; 3116 if (itemNetMonsterHands.at20) 3117 uSpriteBannedFlags |= BANNED_HANDS; 3118 if (itemNetMonsterGhosts.at20) 3119 uSpriteBannedFlags |= BANNED_GHOSTS; 3120 if (itemNetMonsterSpiders.at20) 3121 uSpriteBannedFlags |= BANNED_SPIDERS; 3122 if (itemNetMonsterTinyCaleb.at20) 3123 uSpriteBannedFlags |= BANNED_TCALEBS; 3124 if (itemNetMonsterHellHounds.at20) 3125 uSpriteBannedFlags |= BANNED_HHOUNDS; 3126 3127 // monster behavior tweaks 3128 if (itemNetMonsterRatsAttack.at20) 3129 uSpriteBannedFlags |= BANNED_RATS_BITE; 3130 if (itemNetMonsterMotherSpiderHealth.at20) 3131 uSpriteBannedFlags |= BANNED_MSPIDERS_HP; 3132 if (itemNetMonsterTchernobogHealth.at20) 3133 uSpriteBannedFlags |= BANNED_TCHERNOBOG_HP; 3134 } 3135 3136 // weapons 3137 if (itemBannedItemsFlare.at20) 3138 uSpriteBannedFlags |= BANNED_FLARE; 3139 if (itemBannedItemsShotgun.at20) 3140 uSpriteBannedFlags |= BANNED_SHOTGUN; 3141 if (itemBannedItemsTommyGun.at20) 3142 uSpriteBannedFlags |= BANNED_TOMMYGUN; 3143 if (itemBannedItemsNapalm.at20) 3144 uSpriteBannedFlags |= BANNED_NAPALM; 3145 if (itemBannedItemsTNT.at20) 3146 uSpriteBannedFlags |= BANNED_TNT; 3147 if (itemBannedItemsSpray.at20) 3148 uSpriteBannedFlags |= BANNED_SPRAYCAN; 3149 if (itemBannedItemsTesla.at20) 3150 uSpriteBannedFlags |= BANNED_TESLA; 3151 if (itemBannedItemsLifeLeech.at20) 3152 uSpriteBannedFlags |= BANNED_LIFELEECH; 3153 if (itemBannedItemsVoodoo.at20) 3154 uSpriteBannedFlags |= BANNED_VOODOO; 3155 if (itemBannedItemsProxy.at20) 3156 uSpriteBannedFlags |= BANNED_PROXY; 3157 if (itemBannedItemsRemote.at20) 3158 uSpriteBannedFlags |= BANNED_REMOTE; 3159 3160 // items 3161 if (itemBannedItemsMedKit.at20) 3162 uSpriteBannedFlags |= BANNED_MEDKIT; 3163 if (itemBannedItemsLifeEssence.at20) 3164 uSpriteBannedFlags |= BANNED_LIFEESSENCE; 3165 if (itemBannedItemsLifeSeed.at20) 3166 uSpriteBannedFlags |= BANNED_LIFESEED; 3167 if (itemBannedItemsSuperArmor.at20) 3168 uSpriteBannedFlags |= BANNED_SUPERARMOR; 3169 if (itemBannedItemsCrystalBall.at20) 3170 uSpriteBannedFlags |= BANNED_CRYSTALBALL; 3171 3172 // powerups 3173 if (itemBannedItemsJumpBoots.at20) 3174 uSpriteBannedFlags |= BANNED_JUMPBOOTS; 3175 if (itemBannedItemsCloak.at20) 3176 uSpriteBannedFlags |= BANNED_CLOAK; 3177 if (itemBannedItemsDeathMask.at20) 3178 uSpriteBannedFlags |= BANNED_DEATHMASK; 3179 if (itemBannedItemsAkimbo.at20) 3180 uSpriteBannedFlags |= BANNED_AKIMBO; 3181 if (itemBannedItemsReflect.at20) 3182 uSpriteBannedFlags |= BANNED_REFLECT; 3183 3184 return uSpriteBannedFlags; 3185 } 3186 3187 short gQuickLoadSlot = kLoadSaveNull; 3188 3189 void ShowDifficulties() 3190 { 3191 gGameMenuMgr.Push(&menuDifficulty, 3); 3192 } 3193 3194 void SetMonsters(CGameMenuItemZCycle *pItem) 3195 { 3196 UNREFERENCED_PARAMETER(pItem); 3197 const char bEnable = itemCustomDifficultyMonsterSettings.m_nFocus > 0; 3198 itemCustomDifficultyEnemyDifficulty.bEnable = bEnable; 3199 itemCustomDifficultyEnemyQuantity.bEnable = bEnable; 3200 itemCustomDifficultyEnemyHealth.bEnable = bEnable; 3201 itemCustomDifficultyEnemySpeed.bEnable = bEnable; 3202 itemCustomDifficultyEnemyShuffle.bEnable = bEnable; 3203 itemCustomDifficultyBannedMonsters.bEnable = bEnable; 3204 } 3205 3206 void SetDifficultyAndStart(CGameMenuItemChain *pItem) 3207 { 3208 gGameOptions.nDifficulty = pItem->at30; 3209 gGameOptions.nMonsterSettings = 1; 3210 gGameOptions.nMonsterRespawnTime = 3600; // default (30 secs) 3211 gGameOptions.nEnemyQuantity = gGameOptions.nDifficulty; 3212 gGameOptions.nEnemyHealth = gGameOptions.nDifficulty; 3213 playerSetSkill(gGameOptions.nDifficulty); // set skill to same value as current difficulty 3214 gGameOptions.nEnemySpeed = 0; 3215 gGameOptions.bEnemyShuffle = false; 3216 gGameOptions.bPitchforkOnly = false; 3217 gGameOptions.bPermaDeath = false; 3218 gGameOptions.uSpriteBannedFlags = BANNED_NONE; 3219 gGameOptions.nLevel = 0; 3220 if (!gVanilla) // don't reset gameflags for vanilla mode 3221 gGameOptions.uGameFlags = kGameFlagNone; 3222 gGameOptions.uNetGameFlags = kNetGameFlagNone; 3223 if (gDemo.bPlaying) 3224 gDemo.StopPlayback(); 3225 else if (gDemo.bRecording) 3226 gDemo.Close(); 3227 gStartNewGame = true; 3228 gAutosaveInCurLevel = false; 3229 gQuickLoadSlot = kLoadSaveNull; 3230 gCheatMgr.ResetCheats(); 3231 if (Bstrlen(gGameOptions.szUserMap)) 3232 { 3233 levelAddUserMap(gGameOptions.szUserMap); 3234 levelSetupOptions(gGameOptions.nEpisode, gGameOptions.nLevel); 3235 StartLevel(&gGameOptions); 3236 viewResizeView(gViewSize); 3237 } 3238 gGameMenuMgr.Deactivate(); 3239 } 3240 3241 void SetCustomDifficultyMenu(CGameMenuItemChain *pItem) 3242 { 3243 UNREFERENCED_PARAMETER(pItem); 3244 itemCustomDifficultyStartLevel.nValue = 0; 3245 if (Bstrlen(gGameOptions.szUserMap)) // custom map selected, disable level select cycle item 3246 { 3247 itemCustomDifficultyStartLevel.bEnable = 0; 3248 } 3249 else 3250 { 3251 dassert(gGameOptions.nEpisode >= 0 && gGameOptions.nEpisode < gEpisodeCount); 3252 EPISODEINFO *pEpisodeInfo = &gEpisodeInfo[gGameOptions.nEpisode]; 3253 if (pEpisodeInfo->nLevels <= 0) 3254 itemCustomDifficultyStartLevel.bEnable = 0; 3255 else 3256 { 3257 itemCustomDifficultyStartLevel.bEnable = 1; 3258 itemCustomDifficultyStartLevel.nRangeHigh = pEpisodeInfo->nLevels-1; 3259 } 3260 } 3261 itemCustomDifficultyStartLevel.bNoDraw = !itemCustomDifficultyStartLevel.bEnable; 3262 } 3263 3264 void SetCustomDifficultyAndStart(CGameMenuItemChain *pItem) 3265 { 3266 UNREFERENCED_PARAMETER(pItem); 3267 gGameOptions.nDifficulty = ClipRange(itemCustomDifficultyEnemyDifficulty.nValue, 0, 4); 3268 gGameOptions.nMonsterSettings = ClipRange(itemCustomDifficultyMonsterSettings.m_nFocus, 0, ARRAY_SSIZE(zMonsterStrings)-1); 3269 if (gGameOptions.nMonsterSettings <= 1) 3270 gGameOptions.nMonsterRespawnTime = 3600; // default (30 secs) 3271 else if (gGameOptions.nMonsterSettings == 2) 3272 gGameOptions.nMonsterRespawnTime = 15 * kTicRate; // 15 secs 3273 else 3274 gGameOptions.nMonsterRespawnTime = (gGameOptions.nMonsterSettings - 2) * 30 * kTicRate, gGameOptions.nMonsterSettings = ClipRange(gGameOptions.nMonsterSettings, 0, 2); 3275 gGameOptions.nEnemyQuantity = ClipRange(itemCustomDifficultyEnemyQuantity.nValue, 0, 4); 3276 gGameOptions.nEnemyHealth = ClipRange(itemCustomDifficultyEnemyHealth.nValue, 0, 4); 3277 playerSetSkill(itemCustomDifficultyPlayerDamage.nValue); 3278 gGameOptions.nEnemySpeed = ClipRange(itemCustomDifficultyEnemySpeed.m_nFocus, 0, 4); 3279 gGameOptions.bEnemyShuffle = !!itemCustomDifficultyEnemyShuffle.at20; 3280 gGameOptions.bPitchforkOnly = !!itemCustomDifficultyPitchfork.at20; 3281 gGameOptions.bPermaDeath = !!itemCustomDifficultyPermaDeath.at20; 3282 gGameOptions.uSpriteBannedFlags = SetBannedSprites(1); 3283 gGameOptions.nLevel = 0; 3284 if (!gVanilla) // don't reset gameflags for vanilla mode 3285 gGameOptions.uGameFlags = kGameFlagNone; 3286 gGameOptions.uNetGameFlags = kNetGameFlagNone; 3287 if (gDemo.bPlaying) 3288 gDemo.StopPlayback(); 3289 else if (gDemo.bRecording) 3290 gDemo.Close(); 3291 gStartNewGame = true; 3292 gAutosaveInCurLevel = false; 3293 gQuickLoadSlot = kLoadSaveNull; 3294 gCheatMgr.ResetCheats(); 3295 if (Bstrlen(gGameOptions.szUserMap)) 3296 { 3297 levelAddUserMap(gGameOptions.szUserMap); 3298 levelSetupOptions(gGameOptions.nEpisode, gGameOptions.nLevel); 3299 StartLevel(&gGameOptions); 3300 viewResizeView(gViewSize); 3301 } 3302 else if (itemCustomDifficultyStartLevel.nValue > 0) 3303 gGameOptions.nLevel = itemCustomDifficultyStartLevel.nValue; 3304 gGameMenuMgr.Deactivate(); 3305 } 3306 3307 void SetFirstLaunchOptions(CGameMenuItemChain *pItem) 3308 { 3309 gSetup.firstlaunch = 0; 3310 if (pItem == &itemFirstLaunchNotBlood) 3311 { 3312 gGameMenuMgr.Pop(); // close menu 3313 return; 3314 } 3315 if (pItem == &itemFirstLaunchVanilla) 3316 { 3317 gSlopeTilting = 1; 3318 gAimReticle = 0; 3319 gAutoAim = 1; 3320 gAutoRun = 0; 3321 gShowWeapon = 0; 3322 gWeaponSwitch = 1; 3323 SetGameVanillaMode(1); 3324 gAutosave = 0; 3325 gRestoreLastSave = 0; 3326 gPowerupDuration = 0; 3327 gPowerupStyle = 0; 3328 gSecretStyle = 0; 3329 gShowCompleteTime = 0; 3330 gHudRatio = 1; 3331 gViewSize = 5; 3332 viewResizeView(gViewSize); 3333 gShowMapTitle = 0; 3334 gWeaponInterpolate = 0; 3335 gCenterHoriz = 0; 3336 } 3337 else if (pItem == &itemFirstLaunchNBlood) 3338 { 3339 gAimReticle = 0; 3340 gAutoAim = 1; 3341 gAutoRun = 0; 3342 gShowWeapon = 0; 3343 gWeaponSwitch = 1; 3344 gAutosave = 0; 3345 gRestoreLastSave = 0; 3346 gPowerupStyle = 0; 3347 gSecretStyle = 0; 3348 gShowCompleteTime = 0; 3349 gHudRatio = 0; 3350 gViewSize = 2; 3351 viewResizeView(gViewSize); 3352 gCenterHoriz = 0; 3353 } 3354 itemOptionsDisplayViewBoolSlopeTilting.at20 = gSlopeTilting; 3355 itemOptionsDisplayCrosshair.m_nFocus = gAimReticle; 3356 itemOptionsGameCycleAutoAim.m_nFocus = gAutoAim; 3357 itemOptionsGameBoolAutoRun.at20 = !!gAutoRun; 3358 itemOptionsGameWeaponSwitch.m_nFocus = gWeaponSwitch; 3359 itemOptionsGameAutosaveMode.m_nFocus = gAutosave; 3360 itemOptionsGameRestoreLastSave.at20 = gRestoreLastSave; 3361 itemOptionsDisplayPowerupDuration.m_nFocus = gPowerupDuration; 3362 itemOptionsDisplayViewBoolPowerupStyle.at20 = gPowerupStyle; 3363 itemOptionsDisplayViewSecretMessageStyle.m_nFocus = gSecretStyle; 3364 itemOptionsDisplayViewBoolLevelCompleteTime.at20 = gShowCompleteTime; 3365 itemOptionsDisplayViewHudRatio.m_nFocus = gHudRatio; 3366 itemOptionsDisplayViewHudSize.nValue = gViewSize; 3367 itemOptionsDisplayBoolShowMapTitle.at20 = gShowMapTitle; 3368 itemOptionsDisplayViewWeaponInterpolation.m_nFocus = gWeaponInterpolate; 3369 itemOptionsDisplayViewBoolCenterHoriz.at20 = gCenterHoriz; 3370 gGameMenuMgr.Pop(); // close menu 3371 } 3372 3373 void SetVideoMode(CGameMenuItemChain *pItem) 3374 { 3375 UNREFERENCED_PARAMETER(pItem); 3376 resolution_t p = { xres, yres, fullscreen, bpp, 0 }; 3377 int32_t prend = videoGetRenderMode(); 3378 int32_t pvsync = vsync; 3379 3380 int32_t nResolution = itemOptionsDisplayModeResolution.m_nFocus; 3381 resolution_t n = { gResolution[nResolution].xdim, gResolution[nResolution].ydim, 3382 (gResolution[nResolution].flags & RES_FS) ? itemOptionsDisplayModeFullscreen.at20 : 0, 3383 (nRendererValues[itemOptionsDisplayModeRenderer.m_nFocus] == REND_CLASSIC) ? 8 : gResolution[nResolution].bppmax, 0 }; 3384 int32_t UNUSED(nrend) = nRendererValues[itemOptionsDisplayModeRenderer.m_nFocus]; 3385 int32_t nvsync = nVSyncValues[itemOptionsDisplayModeVSync.m_nFocus]; 3386 3387 if (videoSetGameMode(n.flags, n.xdim, n.ydim, n.bppmax, upscalefactor) < 0) 3388 { 3389 if (videoSetGameMode(p.flags, p.xdim, p.ydim, p.bppmax, upscalefactor) < 0) 3390 { 3391 videoSetRenderMode(prend); 3392 ThrowError("Failed restoring old video mode."); 3393 } 3394 else 3395 { 3396 onvideomodechange(p.bppmax > 8); 3397 vsync = videoSetVsync(pvsync); 3398 } 3399 } 3400 else onvideomodechange(n.bppmax > 8); 3401 3402 viewResizeView(gViewSize); 3403 vsync = videoSetVsync(nvsync); 3404 gSetup.fullscreen = fullscreen; 3405 gSetup.xdim = xres; 3406 gSetup.ydim = yres; 3407 gSetup.bpp = bpp; 3408 3409 #ifdef USE_OPENGL 3410 itemOptionsDisplayModePolymost.bEnable = videoGetRenderMode() == REND_POLYMOST; 3411 #endif 3412 } 3413 3414 void SetWidescreen(CGameMenuItemZBool *pItem) 3415 { 3416 r_usenewaspect = pItem->at20; 3417 } 3418 3419 void SetWeaponSelectMode(CGameMenuItemZCycle *pItem) 3420 { 3421 gShowWeaponSelect = pItem->m_nFocus % ARRAY_SSIZE(pzRandomizerModeStrings); 3422 } 3423 3424 void SetDetail(CGameMenuItemSlider *pItem) 3425 { 3426 gDetail = pItem->nValue; 3427 } 3428 3429 void SetFOV(CGameMenuItemSlider *pItem) 3430 { 3431 gFov = pItem->nValue; 3432 viewUpdateSkyRatio(); 3433 } 3434 3435 void SetupVideoModeMenu(CGameMenuItemChain *pItem) 3436 { 3437 UNREFERENCED_PARAMETER(pItem); 3438 for (int i = 0; i < gResolutionNum; i++) 3439 { 3440 if (gSetup.xdim == gResolution[i].xdim && gSetup.ydim == gResolution[i].ydim) 3441 { 3442 itemOptionsDisplayModeResolution.m_nFocus = i; 3443 break; 3444 } 3445 } 3446 itemOptionsDisplayModeFullscreen.at20 = gSetup.fullscreen; 3447 #ifdef USE_OPENGL 3448 for (int i = 0; i < 2; i++) 3449 { 3450 if (videoGetRenderMode() == nRendererValues[i]) 3451 { 3452 itemOptionsDisplayModeRenderer.m_nFocus = i; 3453 break; 3454 } 3455 } 3456 #endif 3457 for (int i = 0; i < itemOptionsDisplayModeVSync.m_nItems; i++) 3458 { 3459 if (vsync == nVSyncValues[i]) 3460 { 3461 itemOptionsDisplayModeVSync.m_nFocus = i; 3462 break; 3463 } 3464 } 3465 const int kMaxFps = r_maxfps == -1 ? round(refreshfreq) : r_maxfps; 3466 for (int i = 0; i < 8; i++) 3467 { 3468 if (kMaxFps == nFrameLimitValues[i]) 3469 { 3470 itemOptionsDisplayModeFrameLimit.m_nFocus = i; 3471 break; 3472 } 3473 } 3474 } 3475 3476 void PreDrawVideoModeMenu(CGameMenuItem *pItem) 3477 { 3478 if (pItem == &itemOptionsDisplayModeFullscreen) 3479 pItem->bEnable = !!(gResolution[itemOptionsDisplayModeResolution.m_nFocus].flags & RES_FS); 3480 #ifdef USE_OPENGL 3481 else if (pItem == &itemOptionsDisplayModeRenderer) 3482 pItem->bEnable = gResolution[itemOptionsDisplayModeResolution.m_nFocus].bppmax > 8; 3483 #endif 3484 } 3485 3486 void UpdateVideoModeMenuFrameLimit(CGameMenuItemZCycle *pItem) 3487 { 3488 r_maxfps = nFrameLimitValues[pItem->m_nFocus]; 3489 g_frameDelay = calcFrameDelay(r_maxfps); 3490 } 3491 3492 void UpdateVideoColorMenu(CGameMenuItemSliderFloat *pItem) 3493 { 3494 UNREFERENCED_PARAMETER(pItem); 3495 g_videoGamma = itemOptionsDisplayColorGamma.fValue; 3496 g_videoContrast = itemOptionsDisplayColorContrast.fValue; 3497 g_videoSaturation = itemOptionsDisplayColorSaturation.fValue; 3498 r_ambientlight = itemOptionsDisplayColorVisibility.fValue; 3499 r_ambientlightrecip = 1.f/r_ambientlight; 3500 gBrightness = GAMMA_CALC<<2; 3501 videoSetPalette(gBrightness>>2, gLastPal, 0); 3502 } 3503 3504 void UpdateVideoPalette(void) 3505 { 3506 scrCustomizePalette(gCustomPalette % ARRAY_SSIZE(srcCustomPaletteStr), gCustomPaletteCIEDE2000, gCustomPaletteGrayscale, gCustomPaletteInvert); 3507 videoSetPalette(gBrightness>>2, gLastPal, 0); 3508 #ifdef USE_OPENGL 3509 if (!r_useindexedcolortextures && (videoGetRenderMode() != REND_CLASSIC)) 3510 { 3511 videoResetMode(); 3512 if (videoSetGameMode(fullscreen, xres, yres, bpp, upscalefactor)) 3513 ThrowError("restartvid: Reset failed...\n"); 3514 onvideomodechange(gSetup.bpp>8); 3515 } 3516 #endif 3517 } 3518 3519 void UpdateVideoPaletteCycleMenu(CGameMenuItemZCycle *pItem) 3520 { 3521 UNREFERENCED_PARAMETER(pItem); 3522 gCustomPalette = itemOptionsDisplayColorPaletteCustom.m_nFocus % ARRAY_SSIZE(srcCustomPaletteStr); 3523 gCustomPaletteInvert = itemOptionsDisplayColorPaletteInvert.m_nFocus % ARRAY_SSIZE(pzInvertPaletteStrings); 3524 UpdateVideoPalette(); 3525 } 3526 3527 void UpdateVideoPaletteBoolMenu(CGameMenuItemZBool *pItem) 3528 { 3529 UNREFERENCED_PARAMETER(pItem); 3530 gCustomPaletteCIEDE2000 = itemOptionsDisplayColorPaletteCIEDE2000.at20; 3531 gCustomPaletteGrayscale = itemOptionsDisplayColorPaletteGrayscale.at20; 3532 UpdateVideoPalette(); 3533 } 3534 3535 void PreDrawDisplayColor(CGameMenuItem *pItem) 3536 { 3537 if (pItem == &itemOptionsDisplayColorContrast) 3538 pItem->bEnable = gammabrightness; 3539 else if (pItem == &itemOptionsDisplayColorSaturation) 3540 pItem->bEnable = gammabrightness; 3541 } 3542 3543 void ResetVideoColor(CGameMenuItemChain *pItem) 3544 { 3545 UNREFERENCED_PARAMETER(pItem); 3546 g_videoGamma = DEFAULT_GAMMA; 3547 g_videoContrast = DEFAULT_CONTRAST; 3548 g_videoSaturation = DEFAULT_SATURATION; 3549 gBrightness = 0; 3550 r_ambientlight = r_ambientlightrecip = 1.f; 3551 gCustomPalette = itemOptionsDisplayColorPaletteCustom.m_nFocus = 0; 3552 gCustomPaletteCIEDE2000 = itemOptionsDisplayColorPaletteCIEDE2000.at20 = 0; 3553 gCustomPaletteGrayscale = itemOptionsDisplayColorPaletteGrayscale.at20 = 0; 3554 gCustomPaletteInvert = itemOptionsDisplayColorPaletteInvert.m_nFocus = 0; 3555 scrCustomizePalette(gCustomPalette % ARRAY_SSIZE(srcCustomPaletteStr), gCustomPaletteCIEDE2000, gCustomPaletteGrayscale, gCustomPaletteInvert); 3556 videoSetPalette(gBrightness>>2, gLastPal, 0); 3557 #ifdef USE_OPENGL 3558 if (!r_useindexedcolortextures && (videoGetRenderMode() != REND_CLASSIC)) 3559 { 3560 videoResetMode(); 3561 if (videoSetGameMode(fullscreen, xres, yres, bpp, upscalefactor)) 3562 ThrowError("restartvid: Reset failed...\n"); 3563 onvideomodechange(gSetup.bpp>8); 3564 } 3565 #endif 3566 } 3567 3568 #ifdef USE_OPENGL 3569 void SetupVideoPolymostMenu(CGameMenuItemChain *pItem) 3570 { 3571 UNREFERENCED_PARAMETER(pItem); 3572 itemOptionsDisplayPolymostTextureMode.m_nFocus = 0; 3573 for (int i = 0; i < 2; i++) 3574 { 3575 if (nTextureModeValues[i] == gltexfiltermode) 3576 { 3577 itemOptionsDisplayPolymostTextureMode.m_nFocus = i; 3578 break; 3579 } 3580 } 3581 itemOptionsDisplayPolymostAnisotropy.m_nFocus = 0; 3582 for (int i = 0; i < 6; i++) 3583 { 3584 if (nAnisotropyValues[i] == glanisotropy) 3585 { 3586 itemOptionsDisplayPolymostAnisotropy.m_nFocus = i; 3587 break; 3588 } 3589 } 3590 itemOptionsDisplayPolymostTrueColorTextures.at20 = usehightile; 3591 itemOptionsDisplayPolymostTexQuality.m_nFocus = r_downsize; 3592 itemOptionsDisplayPolymostPreloadCache.at20 = useprecache; 3593 itemOptionsDisplayPolymostTexCache.m_nFocus = glusetexcache; 3594 itemOptionsDisplayPolymostDetailTex.at20 = r_detailmapping; 3595 itemOptionsDisplayPolymostGlowTex.at20 = r_glowmapping; 3596 itemOptionsDisplayPolymost3DModels.at20 = usemodels; 3597 itemOptionsDisplayPolymostDeliriumBlur.at20 = gDeliriumBlur; 3598 itemOptionsDisplayPolymostUseColorIndexedTex.at20 = r_useindexedcolortextures; 3599 itemOptionsDisplayPolymostShadeInterpolation.at20 = r_shadeinterpolate; 3600 itemOptionsDisplayPolymostShadeInterpolation.bEnable = !!r_useindexedcolortextures; 3601 itemOptionsDisplayPolymostYShearing.at20 = r_yshearing; 3602 } 3603 3604 void UpdateTextureMode(CGameMenuItemZCycle *pItem) 3605 { 3606 gltexfiltermode = nTextureModeValues[pItem->m_nFocus]; 3607 gltexapplyprops(); 3608 } 3609 3610 void UpdateAnisotropy(CGameMenuItemZCycle *pItem) 3611 { 3612 glanisotropy = nAnisotropyValues[pItem->m_nFocus]; 3613 gltexapplyprops(); 3614 } 3615 3616 void UpdateTrueColorTextures(CGameMenuItemZBool *pItem) 3617 { 3618 usehightile = pItem->at20; 3619 } 3620 #endif 3621 3622 void DoModeChange(void) 3623 { 3624 videoResetMode(); 3625 if (videoSetGameMode(fullscreen, xres, yres, bpp, upscalefactor)) 3626 OSD_Printf("restartvid: Reset failed...\n"); 3627 onvideomodechange(gSetup.bpp > 8); 3628 } 3629 3630 #ifdef USE_OPENGL 3631 void UpdateTexQuality(CGameMenuItemZCycle *pItem) 3632 { 3633 r_downsize = pItem->m_nFocus; 3634 texcache_invalidate(); 3635 r_downsizevar = r_downsize; 3636 DoModeChange(); 3637 } 3638 3639 void UpdatePreloadCache(CGameMenuItemZBool *pItem) 3640 { 3641 useprecache = pItem->at20; 3642 } 3643 3644 void UpdateTexCache(CGameMenuItemZCycle *pItem) 3645 { 3646 glusetexcache = pItem->m_nFocus; 3647 } 3648 3649 void UpdateDetailTex(CGameMenuItemZBool *pItem) 3650 { 3651 r_detailmapping = pItem->at20; 3652 } 3653 3654 void UpdateGlowTex(CGameMenuItemZBool *pItem) 3655 { 3656 r_glowmapping = pItem->at20; 3657 } 3658 3659 void Update3DModels(CGameMenuItemZBool *pItem) 3660 { 3661 usemodels = pItem->at20; 3662 } 3663 3664 void UpdateDeliriumBlur(CGameMenuItemZBool *pItem) 3665 { 3666 gDeliriumBlur = pItem->at20; 3667 } 3668 3669 void UpdateTexColorIndex(CGameMenuItemZBool *pItem) 3670 { 3671 r_useindexedcolortextures = pItem->at20; 3672 itemOptionsDisplayPolymostShadeInterpolation.bEnable = pItem->at20; 3673 } 3674 3675 void UpdateShadeInterpolation(CGameMenuItemZBool *pItem) 3676 { 3677 r_shadeinterpolate = pItem->at20; 3678 } 3679 3680 void UpdateYShrearing(CGameMenuItemZBool *pItem) 3681 { 3682 r_yshearing = pItem->at20; 3683 } 3684 3685 void UpdateRollAngle(CGameMenuItemSlider *pItem) 3686 { 3687 gRollAngle = pItem->nValue; 3688 } 3689 3690 void PreDrawDisplayPolymost(CGameMenuItem *pItem) 3691 { 3692 if (pItem == &itemOptionsDisplayPolymostTexQuality) 3693 pItem->bEnable = usehightile; 3694 else if (pItem == &itemOptionsDisplayPolymostPreloadCache) 3695 pItem->bEnable = usehightile; 3696 else if (pItem == &itemOptionsDisplayPolymostTexCache) 3697 pItem->bEnable = glusetexcompr && usehightile; 3698 else if (pItem == &itemOptionsDisplayPolymostDetailTex) 3699 pItem->bEnable = usehightile; 3700 else if (pItem == &itemOptionsDisplayPolymostGlowTex) 3701 pItem->bEnable = usehightile; 3702 } 3703 #endif 3704 3705 void SetNetGameMode(CGameMenuItemZCycle *pItem) 3706 { 3707 if ((itemNetGameMode.m_nFocus+1) == kGameTypeCoop) // hide multiplayer game length settings 3708 { 3709 itemNetGameSliderTimeLimit.bEnable = 0; 3710 itemNetGameSliderTimeLimit.bNoDraw = !itemNetGameSliderTimeLimit.bEnable; 3711 itemNetGameSliderScoreLimit.bEnable = 0; 3712 itemNetGameSliderScoreLimit.bNoDraw = !itemNetGameSliderScoreLimit.bEnable; 3713 itemNetGameSliderLivesLimit.bEnable = 1; 3714 itemNetGameSliderLivesLimit.bNoDraw = !itemNetGameSliderLivesLimit.bEnable; 3715 itemNetStartBoolSecondWind.at20 = 0; 3716 } 3717 else // hide co-op game length settings 3718 { 3719 itemNetGameSliderTimeLimit.bEnable = 1; 3720 itemNetGameSliderTimeLimit.bNoDraw = !itemNetGameSliderTimeLimit.bEnable; 3721 itemNetGameSliderScoreLimit.bEnable = 1; 3722 itemNetGameSliderScoreLimit.bNoDraw = !itemNetGameSliderScoreLimit.bEnable; 3723 itemNetGameSliderLivesLimit.bEnable = 0; 3724 itemNetGameSliderLivesLimit.bNoDraw = !itemNetGameSliderLivesLimit.bEnable; 3725 itemNetStartBoolSecondWind.at20 = 1; 3726 } 3727 3728 if (pItem == &itemNetGameMode) 3729 { 3730 const int nGameType = pItem->m_nFocus+1; 3731 itemNetStart1.m_pzText2 = zNetGameTypes[pItem->m_nFocus]; 3732 itemNetGameBoolExit.bEnable = nGameType != kGameTypeCoop; 3733 itemNetGameBoolExit.bNoDraw = !itemNetGameBoolExit.bEnable; 3734 itemNetGameBoolPlayerColors.bEnable = nGameType != kGameTypeTeams; 3735 itemNetGameBoolPlayerColors.bNoDraw = !itemNetGameBoolPlayerColors.bEnable; 3736 itemNetGameBoolFriendlyFire.bEnable = nGameType != kGameTypeBloodBath; 3737 itemNetGameBoolFriendlyFire.bNoDraw = !itemNetGameBoolFriendlyFire.bEnable; 3738 itemNetGameCycleKey.bEnable = nGameType == kGameTypeCoop; 3739 itemNetGameCycleKey.bNoDraw = !itemNetGameCycleKey.bEnable; 3740 itemNetGameCycleItemWeapon.bEnable = nGameType == kGameTypeCoop; 3741 itemNetGameCycleItemWeapon.bNoDraw = !itemNetGameCycleItemWeapon.bEnable; 3742 itemNetGameBoolAutoTeams.bEnable = nGameType == kGameTypeTeams; 3743 itemNetGameBoolAutoTeams.bNoDraw = !itemNetGameBoolAutoTeams.bEnable; 3744 itemNetGameBoolTeamColors.bEnable = nGameType == kGameTypeTeams; 3745 itemNetGameBoolTeamColors.bNoDraw = !itemNetGameBoolTeamColors.bEnable; 3746 itemNetGameBoolTeamFlags.bEnable = nGameType == kGameTypeTeams; 3747 itemNetGameBoolTeamFlags.bNoDraw = !itemNetGameBoolTeamFlags.bEnable; 3748 itemNetGameCycleShowWeaponsOverride.bEnable = nGameType != kGameTypeTeams; 3749 itemNetGameCycleShowWeaponsOverride.bNoDraw = !itemNetGameCycleShowWeaponsOverride.bEnable; 3750 itemNetGameCycleShowWeaponsOverrideTeams.bEnable = nGameType == kGameTypeTeams; 3751 itemNetGameCycleShowWeaponsOverrideTeams.bNoDraw = !itemNetGameCycleShowWeaponsOverrideTeams.bEnable; 3752 itemNetGameCycleSpawnLocation.bEnable = nGameType != kGameTypeCoop; 3753 itemNetGameCycleSpawnLocation.bNoDraw = !itemNetGameCycleSpawnLocation.bEnable; 3754 itemNetStartBoolSpectatorMode.bEnable = nGameType != kGameTypeCoop; 3755 itemNetStartBoolSpectatorMode.bNoDraw = !itemNetStartBoolSpectatorMode.bEnable; 3756 return; 3757 } 3758 3759 if ((pItem == &itemNetGameCycleItemWeapon) && (pItem->m_nFocus > 0)) // if adjusted keep weapon/item settings, set spawn weapon to pitchfork 3760 itemNetGameCycleSpawnWeapon.m_nFocus = 0; 3761 else if ((pItem == &itemNetGameCycleSpawnWeapon) && (pItem->m_nFocus > 0)) // if adjusted spawn with weapon, turn off keep weapon/item settings as it will overwrite any weapon picked up after spawning 3762 itemNetGameCycleItemWeapon.m_nFocus = 0; 3763 } 3764 3765 void SetNetShowWeapon(CGameMenuItemZCycle *pItem) 3766 { 3767 if (pItem != &itemNetGameCycleShowWeaponsOverride) 3768 itemNetGameCycleShowWeaponsOverride.SetTextIndex(ClipHigh(pItem->m_nFocus, ARRAY_SIZE(zShowWeapon)-1)); 3769 if (pItem != &itemNetGameCycleShowWeaponsOverrideTeams) 3770 itemNetGameCycleShowWeaponsOverrideTeams.SetTextIndex(ClipHigh(pItem->m_nFocus, ARRAY_SIZE(zShowWeaponTeams)-1)); 3771 } 3772 3773 void SetNetMonsterMenu(CGameMenuItemZCycle *pItem) 3774 { 3775 itemNetStart5.m_pzText2 = zMonsterStrings[itemNetMonsterSettings.m_nFocus]; 3776 3777 if ((pItem == &itemNetStart4) || !pItem) 3778 { 3779 itemNetMonsterQuantity.nValue = itemNetStart4.m_nFocus; 3780 itemNetMonsterHealth.nValue = itemNetStart4.m_nFocus; 3781 } 3782 3783 for (int i = 0; i < menuNetworkGameMonsters.m_nItems; i++) 3784 { 3785 if (menuNetworkGameMonsters.pItemList[i] == &itemNetMonsterTitle) 3786 continue; 3787 if (menuNetworkGameMonsters.pItemList[i] == &itemNetMonsterSettings) 3788 continue; 3789 if (menuNetworkGameMonsters.pItemList[i] == &itemBloodQAV) 3790 continue; 3791 menuNetworkGameMonsters.pItemList[i]->bEnable = itemNetMonsterSettings.m_nFocus != 0; 3792 } 3793 } 3794 3795 void UpdateSoundToggle(CGameMenuItemZBool *pItem) 3796 { 3797 SoundToggle = pItem->at20; 3798 if (!SoundToggle) 3799 FX_StopAllSounds(); 3800 } 3801 3802 void UpdateMusicToggle(CGameMenuItemZBool *pItem) 3803 { 3804 MusicToggle = pItem->at20; 3805 if (!MusicToggle) 3806 sndStopSong(); 3807 else 3808 { 3809 if (gGameStarted || gDemo.bPlaying) 3810 sndPlaySong(gGameOptions.zLevelSong, true); 3811 } 3812 } 3813 3814 void UpdateCDToggle(CGameMenuItemZBool *pItem) 3815 { 3816 CDAudioToggle = pItem->at20; 3817 if (gGameStarted || gDemo.bPlaying) 3818 levelTryPlayMusicOrNothing(gGameOptions.nEpisode, gGameOptions.nLevel); 3819 } 3820 3821 void SetDoppler(CGameMenuItemZBool *pItem) 3822 { 3823 DopplerToggle = pItem->at20; 3824 } 3825 3826 void UpdateSoundVolume(CGameMenuItemSlider *pItem) 3827 { 3828 sndSetFXVolume(pItem->nValue); 3829 } 3830 3831 void UpdateMusicVolume(CGameMenuItemSlider *pItem) 3832 { 3833 sndSetMusicVolume(pItem->nValue); 3834 } 3835 3836 void UpdateSoundRate(CGameMenuItemZCycle *pItem) 3837 { 3838 UNREFERENCED_PARAMETER(pItem); 3839 } 3840 3841 void UpdateNumVoices(CGameMenuItemSlider *pItem) 3842 { 3843 NumVoices = ClipRange(pItem->nValue, 16, 255); 3844 } 3845 3846 void UpdateSpeakerAngle(CGameMenuItemSlider *pItem) 3847 { 3848 gSoundEarAng = ClipRange(pItem->nValue, 15, 90); 3849 } 3850 3851 void UpdateCalebTalk(CGameMenuItemZCycle *pItem) 3852 { 3853 gCalebTalk = pItem->m_nFocus % ARRAY_SIZE(pzCalebTalkStrings); 3854 } 3855 3856 void UpdateMusicDevice(CGameMenuItemZCycle *pItem) 3857 { 3858 UNREFERENCED_PARAMETER(pItem); 3859 itemOptionsSoundSF2Bank.bEnable = 0; 3860 itemOptionsSoundSF2Bank.bNoDraw = 1; 3861 switch (nMusicDeviceValues[itemOptionsSoundMusicDevice.m_nFocus]) 3862 { 3863 case ASS_SF2: 3864 itemOptionsSoundSF2Bank.bEnable = 1; 3865 itemOptionsSoundSF2Bank.bNoDraw = 0; 3866 break; 3867 } 3868 } 3869 3870 void SetSound(CGameMenuItemChain *pItem) 3871 { 3872 UNREFERENCED_PARAMETER(pItem); 3873 MixRate = nSoundRateValues[itemOptionsSoundSampleRate.m_nFocus]; 3874 NumVoices = itemOptionsSoundNumVoices.nValue; 3875 MusicDevice = nMusicDeviceValues[itemOptionsSoundMusicDevice.m_nFocus]; 3876 Bstrcpy(SF2_BankFile, sf2bankfile); 3877 sfxTerm(); 3878 sndTerm(); 3879 3880 sndInit(); 3881 sfxInit(); 3882 3883 if (MusicToggle && (gGameStarted || gDemo.bPlaying)) 3884 sndPlaySong(gGameOptions.zLevelSong, true); 3885 } 3886 3887 void PreDrawSound(CGameMenuItem *pItem) 3888 { 3889 UNREFERENCED_PARAMETER(pItem); 3890 } 3891 3892 void SetupOptionsSound(CGameMenuItemChain *pItem) 3893 { 3894 UNREFERENCED_PARAMETER(pItem); 3895 itemOptionsSoundSoundToggle.at20 = SoundToggle; 3896 itemOptionsSoundMusicToggle.at20 = MusicToggle; 3897 itemOptionsSoundMonoStereo.at20 = gStereo; 3898 itemOptionsSoundCDToggle.at20 = CDAudioToggle; 3899 itemOptionsSoundDoppler.at20 = DopplerToggle; 3900 itemOptionsSoundDoppler.bEnable = gStereo; 3901 itemOptionsSoundSampleRate.m_nFocus = 0; 3902 for (int i = 0; i < 3; i++) 3903 { 3904 if (nSoundRateValues[i] == MixRate) 3905 { 3906 itemOptionsSoundSampleRate.m_nFocus = i; 3907 break; 3908 } 3909 } 3910 itemOptionsSoundNumVoices.nValue = NumVoices; 3911 itemOptionsSoundSpeakerAngle.nValue = gSoundEarAng; 3912 itemOptionsSoundCalebTalk.m_nFocus = gCalebTalk % ARRAY_SIZE(pzCalebTalkStrings); 3913 itemOptionsSoundMusicDevice.m_nFocus = 0; 3914 for (int i = 0; i < (int)ARRAY_SIZE(nMusicDeviceValues); i++) 3915 { 3916 if (nMusicDeviceValues[i] == MusicDevice) 3917 { 3918 itemOptionsSoundMusicDevice.m_nFocus = i; 3919 break; 3920 } 3921 } 3922 3923 UpdateMusicDevice(NULL); 3924 } 3925 3926 void SetupPollJoystick(CGameMenuItemChain *pItem) 3927 { 3928 UNREFERENCED_PARAMETER(pItem); 3929 if (CONTROL_JoyPresent && CONTROL_JoystickEnabled && !itemOptionsControlJoystickButtons.bEnable) // if joysticks menu was never initialized, and a controller is now detected, setup the menu 3930 { 3931 itemOptionsControlJoystickButtons.bEnable = 1; 3932 itemOptionsControlJoystickAxes.bEnable = 1; 3933 itemOptionsControlJoystickMisc.bEnable = 1; 3934 SetupJoystickMenu(); 3935 } 3936 } 3937 3938 void UpdatePlayerName(CGameMenuItemZEdit *pItem, CGameMenuEvent *pEvent) 3939 { 3940 UNREFERENCED_PARAMETER(pItem); 3941 if (pEvent->at0 == kMenuEventEnter) 3942 netBroadcastPlayerInfoUpdate(myconnectindex); 3943 } 3944 3945 void UpdatePlayerSkill(CGameMenuItemZCycle *pItem) 3946 { 3947 gSkill = pItem->m_nFocus % ARRAY_SIZE(pzPlayerSkillStrings); 3948 if ((numplayers > 1) || (gGameOptions.nGameType != kGameTypeSinglePlayer)) // if multiplayer session is active 3949 netBroadcastPlayerInfoUpdate(myconnectindex); 3950 } 3951 3952 void UpdatePlayerTeamPreference(CGameMenuItemZCycle *pItem) 3953 { 3954 gPlayerTeamPreference = pItem->m_nFocus % ARRAY_SIZE(pzPlayerTeamPreferenceStrings); 3955 if ((numplayers > 1) || (gGameOptions.nGameType != kGameTypeSinglePlayer)) // if multiplayer session is active 3956 { 3957 netBroadcastPlayerInfoUpdate(myconnectindex); 3958 if (gGameOptions.bAutoTeams && (gGameOptions.nGameType == kGameTypeTeams)) 3959 { 3960 viewSetMessage("Auto teams is on, cannot change team.", 8, MESSAGE_PRIORITY_INI); // 8: gold 3961 gNetNotifyProfileUpdate = false; 3962 } 3963 } 3964 } 3965 3966 void UpdatePlayerColorPreference(CGameMenuItemZCycle *pItem) 3967 { 3968 gPlayerColorPreference = pItem->m_nFocus % ARRAY_SIZE(pzPlayerColorPreferenceStrings); 3969 if ((numplayers > 1) || (gGameOptions.nGameType != kGameTypeSinglePlayer)) // if multiplayer session is active 3970 netBroadcastPlayerInfoUpdate(myconnectindex); 3971 } 3972 3973 void UpdatePlayerModel(CGameMenuItemZBool *pItem) 3974 { 3975 gPlayerModel = pItem->at20; 3976 if ((numplayers > 1) || (gGameOptions.nGameType != kGameTypeSinglePlayer)) // if multiplayer session is active 3977 netBroadcastPlayerInfoUpdate(myconnectindex); 3978 } 3979 3980 void SetShowPlayerNames(CGameMenuItemZBool *pItem) 3981 { 3982 gShowPlayerNames = pItem->at20; 3983 } 3984 3985 void SetShowWeapons(CGameMenuItemZCycle *pItem) 3986 { 3987 gShowWeapon = pItem->m_nFocus; 3988 } 3989 3990 void UpdateTeamsScoreDisplay(CGameMenuItemZBool *pItem) 3991 { 3992 gTeamsScoreStyle = pItem->at20; 3993 } 3994 3995 void UpdatePlayerChatMessageSound(CGameMenuItemZBool *pItem) 3996 { 3997 gChatSnd = pItem->at20; 3998 } 3999 4000 void UpdatePlayerColorMessages(CGameMenuItemZBool *pItem) 4001 { 4002 gColorMsg = pItem->at20; 4003 } 4004 4005 void UpdatePlayerKillObituaryMessages(CGameMenuItemZBool *pItem) 4006 { 4007 gKillObituary = pItem->at20; 4008 } 4009 4010 void UpdatePlayerKillMessage(CGameMenuItemZBool *pItem) 4011 { 4012 gKillMsg = pItem->at20; 4013 } 4014 4015 void UpdatePlayerMultiKill(CGameMenuItemZCycle *pItem) 4016 { 4017 gMultiKill = pItem->m_nFocus % ARRAY_SIZE(pzPlayerMultiKillStrings); 4018 } 4019 4020 void SetMouseAimMode(CGameMenuItemZBool *pItem) 4021 { 4022 gMouseAiming = pItem->at20; 4023 } 4024 4025 void SetMouseVerticalAim(CGameMenuItemZBool *pItem) 4026 { 4027 gMouseAim = pItem->at20; 4028 } 4029 4030 void SetMouseXSensitivity(CGameMenuItemSliderFloat *pItem) 4031 { 4032 CONTROL_MouseAxesSensitivity[0] = pItem->fValue; 4033 } 4034 4035 void SetMouseYSensitivity(CGameMenuItemSliderFloat*pItem) 4036 { 4037 CONTROL_MouseAxesSensitivity[1] = pItem->fValue; 4038 } 4039 4040 void SetupMouseMenu(CGameMenuItemChain *pItem) 4041 { 4042 UNREFERENCED_PARAMETER(pItem); 4043 itemOptionsControlMouseAimFlipped.at20 = gMouseAimingFlipped; 4044 itemOptionsControlMouseAimMode.at20 = gMouseAiming; 4045 itemOptionsControlMouseVerticalAim.at20 = gMouseAim; 4046 // itemOptionsControlMouseXScale.nValue = CONTROL_MouseAxesScale[0]; 4047 // itemOptionsControlMouseYScale.nValue = CONTROL_MouseAxesScale[1]; 4048 } 4049 4050 void SetupJoystickButtonsMenu(CGameMenuItemChain *pItem) 4051 { 4052 UNREFERENCED_PARAMETER(pItem); 4053 const int nMaxJoyButtons = (joystick.numButtons * 2) + ((joystick.numHats > 0) * 4); 4054 for (int nPage = 0; nPage < MAXJOYSTICKBUTTONPAGES; nPage++) // go through each axis and setup binds 4055 { 4056 for (int nButton = 0; nButton < JOYSTICKITEMSPERPAGE; nButton++) 4057 { 4058 if (nButton >= nMaxJoyButtons) // reached end of button list 4059 return; 4060 const char bDoubleTap = nButton & 1; 4061 const int nJoyButton = ((nPage * JOYSTICKITEMSPERPAGE)>>1) + (nButton>>1); // we halve the button index because button lists are listed in pairs of single tap/double tap inputs 4062 auto pButton = pItemOptionsControlJoyButton[nPage][nButton]; 4063 if (!pButton) 4064 break; 4065 pButton->m_nFocus = 0; 4066 for (int j = 0; j < NUMGAMEFUNCTIONS+1; j++) 4067 { 4068 if (JoystickFunctions[nJoyButton][bDoubleTap] == nGamefuncsValues[j]) 4069 { 4070 pButton->m_nFocus = j; 4071 break; 4072 } 4073 } 4074 } 4075 } 4076 } 4077 4078 void SetupJoystickAxesMenu(CGameMenuItemChain *pItem) 4079 { 4080 UNREFERENCED_PARAMETER(pItem); 4081 for (int nAxis = 0; nAxis < MAXJOYAXES; nAxis++) // set settings for each listed joystick axis 4082 { 4083 if (pItemOptionsControlJoystickAxis[nAxis] == NULL) // reached end of list, stop 4084 return; 4085 pItemOptionsControlJoystickAxisScale[nAxis]->nValue = JoystickAnalogueScale[nAxis]; 4086 switch (JoystickAnalogueAxes[nAxis]) 4087 { 4088 case analog_lookingupanddown: 4089 pItemOptionsControlJoystickAxisAnalogue[nAxis]->m_nFocus = 4; 4090 break; 4091 case analog_moving: 4092 pItemOptionsControlJoystickAxisAnalogue[nAxis]->m_nFocus = 3; 4093 break; 4094 case analog_strafing: 4095 pItemOptionsControlJoystickAxisAnalogue[nAxis]->m_nFocus = 2; 4096 break; 4097 case analog_turning: 4098 pItemOptionsControlJoystickAxisAnalogue[nAxis]->m_nFocus = 1; 4099 break; 4100 default: // unsupported/none 4101 pItemOptionsControlJoystickAxisAnalogue[nAxis]->m_nFocus = 0; 4102 break; 4103 } 4104 pItemOptionsControlJoystickAxisAnalogueInvert[nAxis]->at20 = JoystickAnalogueInvert[nAxis]; 4105 pItemOptionsControlJoystickAxisDigitalPos[nAxis]->m_nFocus = 0; 4106 for (int j = 0; j < NUMGAMEFUNCTIONS+1; j++) 4107 { 4108 if (JoystickDigitalFunctions[nAxis][0] == nGamefuncsValues[j]) 4109 { 4110 pItemOptionsControlJoystickAxisDigitalPos[nAxis]->m_nFocus = j; 4111 break; 4112 } 4113 } 4114 pItemOptionsControlJoystickAxisDigitalNeg[nAxis]->m_nFocus = 0; 4115 for (int j = 0; j < NUMGAMEFUNCTIONS+1; j++) 4116 { 4117 if (JoystickDigitalFunctions[nAxis][1] == nGamefuncsValues[j]) 4118 { 4119 pItemOptionsControlJoystickAxisDigitalNeg[nAxis]->m_nFocus = j; 4120 break; 4121 } 4122 } 4123 pItemOptionsControlJoystickAxisDeadzone[nAxis]->nValue = JoystickAnalogueDead[nAxis]; 4124 pItemOptionsControlJoystickAxisSaturate[nAxis]->nValue = JoystickAnalogueSaturate[nAxis]; 4125 pItemOptionsControlJoystickAxisSnapZone[nAxis]->nValue = JoystickAnalogueSnap[nAxis]; 4126 } 4127 } 4128 4129 inline void GenerateJoystickAxisHeatmap(const int nAxis) 4130 { 4131 if (!waloff[kAxisHeatmapTile]) 4132 { 4133 tileAllocTile(kAxisHeatmapTile, 48, 48, 0, 0); 4134 tileSetSize(kAxisHeatmapTile, 48, 48); 4135 } 4136 dassert(waloff[kAxisHeatmapTile] != 0); 4137 CONTROL_GetAxisHeatMap(nAxis, (uint8_t*)waloff[kAxisHeatmapTile], 48, 48, 0, 31, true); 4138 tileInvalidate(kAxisHeatmapTile, -1, -1); 4139 } 4140 4141 void SetupJoystickAxisHeatmap(CGameMenuItemChain* pItem) 4142 { 4143 for (int nAxis = 0; nAxis < MAXJOYAXES; nAxis++) 4144 { 4145 if (pItem == pItemOptionsControlJoystickAxis[nAxis]) 4146 { 4147 GenerateJoystickAxisHeatmap(nAxis); 4148 break; 4149 } 4150 } 4151 } 4152 4153 void SetJoystickScale(CGameMenuItemSlider* pItem) 4154 { 4155 for (int nAxis = 0; nAxis < MAXJOYAXES; nAxis++) 4156 { 4157 if (pItem == pItemOptionsControlJoystickAxisScale[nAxis]) 4158 { 4159 JoystickAnalogueScale[nAxis] = pItem->nValue; 4160 CONTROL_SetAnalogAxisScale(nAxis, JoystickAnalogueScale[nAxis], controldevice_joystick); 4161 break; 4162 } 4163 } 4164 } 4165 4166 void SetJoystickAnalogue(CGameMenuItemZCycle* pItem) 4167 { 4168 for (int nAxis = 0; nAxis < MAXJOYAXES; nAxis++) 4169 { 4170 if (pItem == pItemOptionsControlJoystickAxisAnalogue[nAxis]) 4171 { 4172 switch (pItem->m_nFocus) 4173 { 4174 case 4: // looking up/down 4175 JoystickAnalogueAxes[nAxis] = analog_lookingupanddown; 4176 break; 4177 case 3: // moving 4178 JoystickAnalogueAxes[nAxis] = analog_moving; 4179 break; 4180 case 2: // strafing 4181 JoystickAnalogueAxes[nAxis] = analog_strafing; 4182 break; 4183 case 1: // turning 4184 JoystickAnalogueAxes[nAxis] = analog_turning; 4185 break; 4186 case 0: // none 4187 default: 4188 JoystickAnalogueAxes[nAxis] = -1; 4189 break; 4190 } 4191 CONTROL_MapAnalogAxis(nAxis, JoystickAnalogueAxes[nAxis]); 4192 break; 4193 } 4194 } 4195 } 4196 4197 void SetJoystickAnalogueInvert(CGameMenuItemZBool* pItem) 4198 { 4199 for (int nAxis = 0; nAxis < MAXJOYAXES; nAxis++) 4200 { 4201 if (pItem == pItemOptionsControlJoystickAxisAnalogueInvert[nAxis]) 4202 { 4203 JoystickAnalogueInvert[nAxis] = pItem->at20; 4204 CONTROL_SetAnalogAxisInvert(nAxis, JoystickAnalogueInvert[nAxis]); 4205 break; 4206 } 4207 } 4208 } 4209 4210 void SetJoystickDigitalPos(CGameMenuItemZCycle* pItem) 4211 { 4212 for (int nAxis = 0; nAxis < MAXJOYAXES; nAxis++) 4213 { 4214 if (pItem == pItemOptionsControlJoystickAxisDigitalPos[nAxis]) 4215 { 4216 for (int j = 0; j < NUMGAMEFUNCTIONS+1; j++) 4217 { 4218 if (JoystickDigitalFunctions[nAxis][0] == nGamefuncsValues[j]) 4219 { 4220 int nFunc = nGamefuncsValues[pItem->m_nFocus]; 4221 JoystickDigitalFunctions[nAxis][0] = nFunc; 4222 CONTROL_MapDigitalAxis(nAxis, JoystickDigitalFunctions[nAxis][0], 0); 4223 return; 4224 } 4225 } 4226 } 4227 } 4228 } 4229 4230 void SetJoystickDigitalNeg(CGameMenuItemZCycle* pItem) 4231 { 4232 for (int nAxis = 0; nAxis < MAXJOYAXES; nAxis++) 4233 { 4234 if (pItem == pItemOptionsControlJoystickAxisDigitalNeg[nAxis]) 4235 { 4236 for (int j = 0; j < NUMGAMEFUNCTIONS+1; j++) 4237 { 4238 if (JoystickDigitalFunctions[nAxis][1] == nGamefuncsValues[j]) 4239 { 4240 int nFunc = nGamefuncsValues[pItem->m_nFocus]; 4241 JoystickDigitalFunctions[nAxis][1] = nFunc; 4242 CONTROL_MapDigitalAxis(nAxis, JoystickDigitalFunctions[nAxis][1], 1); 4243 return; 4244 } 4245 } 4246 } 4247 } 4248 } 4249 4250 void SetJoystickDeadzone(CGameMenuItemSlider* pItem) 4251 { 4252 for (int nAxis = 0; nAxis < MAXJOYAXES; nAxis++) 4253 { 4254 if (pItem == pItemOptionsControlJoystickAxisDeadzone[nAxis]) 4255 { 4256 JoystickAnalogueDead[nAxis] = pItem->nValue; 4257 JOYSTICK_SetDeadZone(nAxis, JoystickAnalogueDead[nAxis], JoystickAnalogueSaturate[nAxis]); 4258 GenerateJoystickAxisHeatmap(nAxis); 4259 break; 4260 } 4261 } 4262 } 4263 4264 void SetJoystickSaturate(CGameMenuItemSlider* pItem) 4265 { 4266 for (int nAxis = 0; nAxis < MAXJOYAXES; nAxis++) 4267 { 4268 if (pItem == pItemOptionsControlJoystickAxisSaturate[nAxis]) 4269 { 4270 JoystickAnalogueSaturate[nAxis] = pItem->nValue; 4271 JOYSTICK_SetDeadZone(nAxis, JoystickAnalogueDead[nAxis], JoystickAnalogueSaturate[nAxis]); 4272 GenerateJoystickAxisHeatmap(nAxis); 4273 break; 4274 } 4275 } 4276 } 4277 4278 void SetJoystickSnapZone(CGameMenuItemSlider* pItem) 4279 { 4280 for (int nAxis = 0; nAxis < MAXJOYAXES; nAxis++) 4281 { 4282 if (pItem == pItemOptionsControlJoystickAxisSnapZone[nAxis]) 4283 { 4284 JoystickAnalogueSnap[nAxis] = pItem->nValue; 4285 JOYSTICK_SetSnapZone(nAxis, JoystickAnalogueSnap[nAxis]); 4286 GenerateJoystickAxisHeatmap(nAxis); 4287 break; 4288 } 4289 } 4290 } 4291 4292 void PreDrawControlMouse(CGameMenuItem *pItem) 4293 { 4294 if (pItem == &itemOptionsControlMouseVerticalAim) 4295 pItem->bEnable = !gMouseAiming; 4296 } 4297 4298 void SetMouseButton(CGameMenuItemZCycle *pItem) 4299 { 4300 for (int i = 0; i < MENUMOUSEFUNCTIONS; i++) 4301 { 4302 if (pItem == pItemOptionsControlMouseButton[i]) 4303 { 4304 int nFunc = nGamefuncsValues[pItem->m_nFocus]; 4305 MouseFunctions[MenuMouseDataIndex[i][0]][MenuMouseDataIndex[i][1]] = nFunc; 4306 CONTROL_MapButton(nFunc, MenuMouseDataIndex[i][0], MenuMouseDataIndex[i][1], controldevice_mouse); 4307 CONTROL_FreeMouseBind(MenuMouseDataIndex[i][0]); 4308 break; 4309 } 4310 } 4311 } 4312 4313 void SetJoyButton(CGameMenuItemZCycle *pItem) 4314 { 4315 for (int nPage = 0; nPage < MAXJOYSTICKBUTTONPAGES; nPage++) // find selected menu item used for this bind 4316 { 4317 for (int nButton = 0; nButton < JOYSTICKITEMSPERPAGE; nButton++) 4318 { 4319 if (pItem == pItemOptionsControlJoyButton[nPage][nButton]) // found menu item, now bind function to joystick button 4320 { 4321 const char bDoubleTap = nButton & 1; 4322 const int nJoyButton = ((nPage * JOYSTICKITEMSPERPAGE)>>1) + (nButton>>1); // we halve the button index because button lists are listed in pairs of single tap/double tap inputs 4323 int nFunc = nGamefuncsValues[pItem->m_nFocus]; 4324 JoystickFunctions[nJoyButton][bDoubleTap] = nFunc; 4325 CONTROL_MapButton(nFunc, nJoyButton, bDoubleTap, controldevice_joystick); 4326 return; 4327 } 4328 } 4329 } 4330 } 4331 4332 void SetupMouseButtonMenu(CGameMenuItemChain *pItem) 4333 { 4334 UNREFERENCED_PARAMETER(pItem); 4335 for (int i = 0; i < MENUMOUSEFUNCTIONS; i++) 4336 { 4337 auto pItem = pItemOptionsControlMouseButton[i]; 4338 pItem->m_nFocus = 0; 4339 for (int j = 0; j < NUMGAMEFUNCTIONS+1; j++) 4340 { 4341 if (MouseFunctions[MenuMouseDataIndex[i][0]][MenuMouseDataIndex[i][1]] == nGamefuncsValues[j]) 4342 { 4343 pItem->m_nFocus = j; 4344 break; 4345 } 4346 } 4347 } 4348 } 4349 4350 void SetupNetworkMenu(void) 4351 { 4352 if (strlen(gNetAddress) > 0) 4353 strncpy(zNetAddressBuffer, gNetAddress, sizeof(zNetAddressBuffer)-1); 4354 4355 menuNetwork.Add(&itemNetworkTitle, false); 4356 menuNetwork.Add(&itemNetworkHost, true); 4357 menuNetwork.Add(&itemNetworkJoin, false); 4358 menuNetwork.Add(&itemNetworkPlayer, false); 4359 menuNetwork.Add(&itemBloodQAV, false); 4360 4361 menuNetworkHost.Add(&itemNetworkHostTitle, false); 4362 menuNetworkHost.Add(&itemNetworkHostPlayerNum, true); 4363 menuNetworkHost.Add(&itemNetworkHostPort, false); 4364 menuNetworkHost.Add(&itemNetworkHostHost, false); 4365 menuNetworkHost.Add(&itemBloodQAV, false); 4366 4367 menuNetworkJoin.Add(&itemNetworkJoinTitle, false); 4368 menuNetworkJoin.Add(&itemNetworkJoinAddress, true); 4369 menuNetworkJoin.Add(&itemNetworkJoinPort, false); 4370 menuNetworkJoin.Add(&itemNetworkJoinJoin, false); 4371 menuNetworkJoin.Add(&itemBloodQAV, false); 4372 } 4373 4374 void SetupNetworkHostMenu(CGameMenuItemChain *pItem) 4375 { 4376 UNREFERENCED_PARAMETER(pItem); 4377 } 4378 4379 void SetupNetworkJoinMenu(CGameMenuItemChain *pItem) 4380 { 4381 UNREFERENCED_PARAMETER(pItem); 4382 } 4383 4384 void NetworkHostGame(CGameMenuItemChain *pItem) 4385 { 4386 UNREFERENCED_PARAMETER(pItem); 4387 sndStopSong(); 4388 FX_StopAllSounds(); 4389 UpdateDacs(0, true); 4390 gNetPlayers = itemNetworkHostPlayerNum.nValue; 4391 gNetPort = strtoul(zNetPortBuffer, NULL, 10); 4392 if (!gNetPort) 4393 gNetPort = kNetDefaultPort; 4394 gNetMode = NETWORK_SERVER; 4395 netInitialize(false); 4396 gGameMenuMgr.Deactivate(); 4397 gQuitGame = gRestartGame = true; 4398 } 4399 4400 void NetworkJoinGame(CGameMenuItemChain *pItem) 4401 { 4402 UNREFERENCED_PARAMETER(pItem); 4403 sndStopSong(); 4404 FX_StopAllSounds(); 4405 UpdateDacs(0, true); 4406 strcpy(gNetAddress, zNetAddressBuffer); 4407 gNetPort = strtoul(zNetPortBuffer, NULL, 10); 4408 if (!gNetPort) 4409 gNetPort = kNetDefaultPort; 4410 gNetMode = NETWORK_CLIENT; 4411 netInitialize(false); 4412 gGameMenuMgr.Deactivate(); 4413 gQuitGame = gRestartGame = true; 4414 } 4415 4416 void SaveGameProcess(CGameMenuItemChain *pItem) 4417 { 4418 UNREFERENCED_PARAMETER(pItem); 4419 } 4420 4421 inline void UpdateSaveGameItemText(int nSlot) 4422 { 4423 switch (nSlot) // set save slot text flag 4424 { 4425 case kLoadSaveSlot0: 4426 itemSaveGame0.at37 = 0; 4427 break; 4428 case kLoadSaveSlot1: 4429 itemSaveGame1.at37 = 0; 4430 break; 4431 case kLoadSaveSlot2: 4432 itemSaveGame2.at37 = 0; 4433 break; 4434 case kLoadSaveSlot3: 4435 itemSaveGame3.at37 = 0; 4436 break; 4437 case kLoadSaveSlot4: 4438 itemSaveGame4.at37 = 0; 4439 break; 4440 case kLoadSaveSlot5: 4441 itemSaveGame5.at37 = 0; 4442 break; 4443 case kLoadSaveSlot6: 4444 itemSaveGame6.at37 = 0; 4445 break; 4446 case kLoadSaveSlot7: 4447 itemSaveGame7.at37 = 0; 4448 break; 4449 case kLoadSaveSlot8: 4450 itemSaveGame8.at37 = 0; 4451 break; 4452 case kLoadSaveSlot9: 4453 itemSaveGame9.at37 = 0; 4454 break; 4455 default: 4456 break; 4457 } 4458 } 4459 4460 void SaveGame(CGameMenuItemZEditBitmap *pItem, CGameMenuEvent *event) 4461 { 4462 char strSaveGameName[BMAX_PATH]; 4463 int nSlot = pItem->at28; 4464 if (gGameOptions.nGameType != kGameTypeSinglePlayer || !gGameStarted) 4465 return; 4466 if (event->at0 != 6/* || strSaveGameName[0]*/) 4467 { 4468 gGameMenuMgr.Deactivate(); 4469 return; 4470 } 4471 if (G_ModDirSnprintf(strSaveGameName, BMAX_PATH, "game00%02d.sav", nSlot)) 4472 return; 4473 memset(gGameOptions.szUserGameName, 0, sizeof(gGameOptions.szSaveGameName)); 4474 strcpy(gGameOptions.szUserGameName, strRestoreGameStrings[nSlot]); 4475 memset(gGameOptions.szSaveGameName, 0, sizeof(gGameOptions.szSaveGameName)); 4476 sprintf(gGameOptions.szSaveGameName, "%s", strSaveGameName); 4477 gGameOptions.nSaveGameSlot = nSlot; 4478 if (gShowLoadingSavingBackground) 4479 { 4480 viewLoadingScreen(gMenuPicnum, "Saving", "Saving Your Game", strRestoreGameStrings[nSlot]); 4481 videoNextPage(); 4482 } 4483 gSaveGameNum = nSlot; 4484 LoadSave::SaveGame(strSaveGameName); 4485 gGameOptions.picEntry = gSavedOffset; 4486 gSaveGameOptions[nSlot] = gGameOptions; 4487 LoadUpdateSaveGame(nSlot, gProfile[myconnectindex].skill); 4488 UpdateSaveGameItemText(nSlot); 4489 gQuickLoadSlot = nSlot; 4490 gGameMenuMgr.Deactivate(); 4491 viewSetMessage("Game saved"); 4492 } 4493 4494 void QuickSaveGame(void) 4495 { 4496 char strSaveGameName[BMAX_PATH]; 4497 if (gGameOptions.nGameType != kGameTypeSinglePlayer || !gGameStarted) 4498 return; 4499 /*if (strSaveGameName[0]) 4500 { 4501 gGameMenuMgr.Deactivate(); 4502 return; 4503 }*/ 4504 if (G_ModDirSnprintf(strSaveGameName, BMAX_PATH, "game00%02d.sav", kLoadSaveSlotQuick)) 4505 return; 4506 memset(gGameOptions.szUserGameName, 0, sizeof(gGameOptions.szSaveGameName)); 4507 snprintf(gGameOptions.szUserGameName, sizeof(gGameOptions.szUserGameName), "%s quick", gGameOptions.zLevelName); 4508 memset(gGameOptions.szSaveGameName, 0, sizeof(gGameOptions.szSaveGameName)); 4509 sprintf(gGameOptions.szSaveGameName, "%s", strSaveGameName); 4510 gGameOptions.nSaveGameSlot = kLoadSaveSlotQuick; 4511 if (gShowLoadingSavingBackground) 4512 { 4513 viewLoadingScreen(gMenuPicnum, "Saving", "Saving Your Game", strRestoreGameStrings[kLoadSaveSlotQuick]); 4514 videoNextPage(); 4515 } 4516 LoadSave::SaveGame(strSaveGameName); 4517 gGameOptions.picEntry = gSavedOffset; 4518 gSaveGameOptions[kLoadSaveSlotQuick] = gGameOptions; 4519 LoadUpdateSaveGame(kLoadSaveSlotQuick, gProfile[myconnectindex].skill); 4520 UpdateSaveGameItemText(kLoadSaveSlotQuick); 4521 gQuickLoadSlot = kLoadSaveSlotQuick; 4522 gGameMenuMgr.Deactivate(); 4523 viewSetMessage("Game saved"); 4524 } 4525 4526 void AutosaveGame(bool bLevelStartSave) 4527 { 4528 char strSaveGameName[BMAX_PATH]; 4529 int nSlot = bLevelStartSave ? kLoadSaveSlotSpawn : kLoadSaveSlotKey; 4530 if (gGameOptions.nGameType != kGameTypeSinglePlayer || !gGameStarted) 4531 return; 4532 if (G_ModDirSnprintf(strSaveGameName, BMAX_PATH, "gameautosave%1d.sav", nSlot - kLoadSaveSlotSpawn)) 4533 return; 4534 snprintf(gGameOptions.szUserGameName, sizeof(gGameOptions.szUserGameName), "%s %s", gGameOptions.zLevelName, nSlot == kLoadSaveSlotSpawn ? "start": "key"); 4535 snprintf(gGameOptions.szSaveGameName, sizeof(gGameOptions.szSaveGameName), "%s", strSaveGameName); 4536 gGameOptions.nSaveGameSlot = nSlot; 4537 const PLAYER playerTemp = *gMe; // temp player struct while we make autosaving a little more easier (blood is stressful enough already) 4538 if (!bLevelStartSave) // if key save, reset problematic weapon states 4539 { 4540 playerResetWeaponState(gMe, true); 4541 gMe->invulTime = (int)gFrameClock; // in case they get hitscanned right after loading 4542 } 4543 LoadSave::SaveGame(strSaveGameName); 4544 *gMe = playerTemp; // restore current player struct 4545 if (!bLevelStartSave) // don't print message on level start autosaves 4546 viewSetMessage("Autosaved..."); 4547 gGameOptions.picEntry = gSavedOffset; 4548 gSaveGameOptions[nSlot] = gGameOptions; 4549 LoadUpdateSaveGame(nSlot, gProfile[myconnectindex].skill); 4550 gQuickLoadSlot = nSlot; 4551 gAutosaveInCurLevel = true; 4552 } 4553 4554 void LoadGame(CGameMenuItemZEditBitmap *pItem, CGameMenuEvent *event) 4555 { 4556 UNREFERENCED_PARAMETER(event); 4557 char strLoadGameName[BMAX_PATH]; 4558 int nSlot = pItem->at28; 4559 if (gGameOptions.nGameType != kGameTypeSinglePlayer) 4560 return; 4561 if (nSlot <= kLoadSaveSlot10) 4562 { 4563 if (G_ModDirSnprintf(strLoadGameName, BMAX_PATH, "game00%02d.sav", nSlot)) 4564 return; 4565 } 4566 else 4567 { 4568 if (G_ModDirSnprintf(strLoadGameName, BMAX_PATH, "gameautosave%1d.sav", nSlot == kLoadSaveSlotSpawn ? 0 : 1)) 4569 return; 4570 } 4571 int const bakpathsearchmode = pathsearchmode; 4572 pathsearchmode = 1; 4573 if (!testkopen(strLoadGameName, 0)) 4574 { 4575 pathsearchmode = bakpathsearchmode; 4576 return; 4577 } 4578 if (!gGameStarted || LoadSavedInCurrentSession(nSlot)) // if save slot is from a different session, set autosave state to false 4579 gAutosaveInCurLevel = false; 4580 if (gShowLoadingSavingBackground) 4581 { 4582 viewLoadingScreen(gMenuPicnum, "Loading", "Loading Saved Game", strRestoreGameStrings[nSlot]); 4583 videoNextPage(); 4584 } 4585 LoadSave::LoadGame(strLoadGameName); 4586 gGameMenuMgr.Deactivate(); 4587 gQuickLoadSlot = nSlot; 4588 pathsearchmode = bakpathsearchmode; 4589 } 4590 4591 void QuickLoadGame(void) 4592 { 4593 char strLoadGameName[BMAX_PATH]; 4594 if (gGameOptions.nGameType != kGameTypeSinglePlayer) 4595 return; 4596 if (gQuickLoadSlot < kLoadSaveSlotAutosave) 4597 { 4598 if (G_ModDirSnprintf(strLoadGameName, BMAX_PATH, "game00%02d.sav", gQuickLoadSlot)) 4599 return; 4600 } 4601 else 4602 { 4603 if (G_ModDirSnprintf(strLoadGameName, BMAX_PATH, "gameautosave%1d.sav", gQuickLoadSlot == kLoadSaveSlotSpawn ? 0 : 1)) 4604 return; 4605 } 4606 int const bakpathsearchmode = pathsearchmode; 4607 pathsearchmode = 1; 4608 if (!testkopen(strLoadGameName, 0)) 4609 { 4610 pathsearchmode = bakpathsearchmode; 4611 return; 4612 } 4613 if (!LoadSavedInCurrentSession(gQuickLoadSlot)) // if save slot is from a different session, set autosave state to false 4614 gAutosaveInCurLevel = false; 4615 if (gShowLoadingSavingBackground) 4616 { 4617 viewLoadingScreen(gMenuPicnum, "Loading", "Loading Saved Game", strRestoreGameStrings[gQuickLoadSlot]); 4618 videoNextPage(); 4619 } 4620 LoadSave::LoadGame(strLoadGameName); 4621 gGameMenuMgr.Deactivate(); 4622 pathsearchmode = bakpathsearchmode; 4623 } 4624 4625 void SetupLevelMenuItem(int nEpisode) 4626 { 4627 dassert(nEpisode >= 0 && nEpisode < gEpisodeCount); 4628 itemNetStart3.SetTextArray(zLevelNames[nEpisode], gEpisodeInfo[nEpisode].nLevels, 0); 4629 } 4630 4631 void SetupNetLevels(CGameMenuItemZCycle *pItem) 4632 { 4633 SetupLevelMenuItem(pItem->m_nFocus); 4634 NetClearUserMap(pItem); 4635 } 4636 4637 void NetClearUserMap(CGameMenuItemZCycle *pItem) 4638 { 4639 UNREFERENCED_PARAMETER(pItem); 4640 memset(zUserMapName, 0, sizeof(zUserMapName)); 4641 } 4642 4643 void StartNetGame(CGameMenuItemChain *pItem) 4644 { 4645 UNREFERENCED_PARAMETER(pItem); 4646 gPacketStartGame.gameType = itemNetGameMode.m_nFocus+1; 4647 if (gPacketStartGame.gameType == kGameTypeSinglePlayer) 4648 gPacketStartGame.gameType = kGameTypeBloodBath; 4649 gPacketStartGame.uNetGameFlags = kNetGameFlagNone; 4650 if (gPacketStartGame.gameType != kGameTypeCoop) // bloodbath/teams score and time limits 4651 { 4652 if (itemNetGameSliderScoreLimit.nValue > 0) 4653 gPacketStartGame.uNetGameFlags |= (ClipRange(itemNetGameSliderScoreLimit.nValue, 1, 255)<<kNetGameFlagScoresLimitBase)&kNetGameFlagScoresLimitMask; 4654 if (itemNetGameSliderTimeLimit.nValue > 0) 4655 gPacketStartGame.uNetGameFlags |= (ClipRange(itemNetGameSliderTimeLimit.nValue, 1, 63)<<kNetGameFlagTimeLimitBase)&kNetGameFlagTimeLimitMask; 4656 } 4657 else if (itemNetGameSliderLivesLimit.nValue > 0) // co-op lives 4658 gPacketStartGame.uNetGameFlags |= (ClipRange(itemNetGameSliderLivesLimit.nValue, 1, 255)<<kNetGameFlagScoresLimitBase)&kNetGameFlagScoresLimitMask; 4659 if (!itemNetGameBoolExit.at20 && (gPacketStartGame.gameType != kGameTypeCoop)) 4660 gPacketStartGame.uNetGameFlags |= kNetGameFlagNoLevelExit; 4661 if (!itemNetGameBoolTeleFrag.at20) 4662 gPacketStartGame.uNetGameFlags |= kNetGameFlagNoTeleFrag; 4663 if (!itemNetGameBoolSkillOverride.at20) 4664 gPacketStartGame.uNetGameFlags |= kNetGameFlagSkillIssue; 4665 if (!itemNetGameBoolModelOverride.at20) 4666 gPacketStartGame.uNetGameFlags |= kNetGameFlagCalebOnly; 4667 if (!itemNetGameBoolPlayerColors.at20) 4668 gPacketStartGame.uNetGameFlags |= kNetGameFlagVanillaColors; 4669 if (!itemNetGameBoolTeamColors.at20) 4670 gPacketStartGame.uNetGameFlags |= kNetGameFlagNoTeamColors; 4671 if (!itemNetGameBoolTeamFlags.at20) 4672 gPacketStartGame.uNetGameFlags |= kNetGameFlagNoTeamFlags; 4673 if (itemNetGameCycleSpawnLocation.m_nFocus > 0) 4674 gPacketStartGame.uNetGameFlags |= itemNetGameCycleSpawnLocation.m_nFocus == 1 ? kNetGameFlagSpawnSmart : kNetGameFlagSpawnDist; 4675 if (gPacketStartGame.gameType == kGameTypeTeams) 4676 { 4677 if (itemNetGameCycleShowWeaponsOverrideTeams.m_nFocus == 1) 4678 gPacketStartGame.uNetGameFlags |= kNetGameFlagHideWeaponsCloak; 4679 else if (itemNetGameCycleShowWeaponsOverrideTeams.m_nFocus == 2) 4680 gPacketStartGame.uNetGameFlags |= kNetGameFlagHideWeaponsAlways; 4681 else if (itemNetGameCycleShowWeaponsOverrideTeams.m_nFocus == 3) 4682 gPacketStartGame.uNetGameFlags |= kNetGameFlagHideWeaponsTeams; 4683 } 4684 else 4685 { 4686 if (itemNetGameCycleShowWeaponsOverride.m_nFocus == 1) 4687 gPacketStartGame.uNetGameFlags |= kNetGameFlagHideWeaponsCloak; 4688 else if (itemNetGameCycleShowWeaponsOverride.m_nFocus == 2) 4689 gPacketStartGame.uNetGameFlags |= kNetGameFlagHideWeaponsAlways; 4690 } 4691 if (itemNetGameCycleMirrorModeOverride.m_nFocus & 1) 4692 gPacketStartGame.uNetGameFlags |= kNetGameFlagMirrorHoriz; 4693 if (itemNetGameCycleMirrorModeOverride.m_nFocus & 2) 4694 gPacketStartGame.uNetGameFlags |= kNetGameFlagMirrorVert; 4695 if (!itemNetStartBoolChaseView.at20) 4696 gPacketStartGame.uNetGameFlags |= kNetGameFlagNoChaseView; 4697 if (!itemNetStartBoolHolstering.at20) 4698 gPacketStartGame.uNetGameFlags |= kNetGameFlagNoHolstering; 4699 if ((itemNetStartBoolSecondWind.at20 && gPacketStartGame.gameType == kGameTypeCoop) || (!itemNetStartBoolSecondWind.at20 && gPacketStartGame.gameType != kGameTypeCoop)) 4700 gPacketStartGame.uNetGameFlags |= kNetGameFlagSecondWindToggle; 4701 if (itemNetStartBoolSpectatorMode.at20) 4702 gPacketStartGame.uNetGameFlags |= kNetGameFlagSpectatingAllow; 4703 gPacketStartGame.episodeId = itemNetStart2.m_nFocus; 4704 gPacketStartGame.levelId = itemNetStart3.m_nFocus; 4705 gPacketStartGame.difficulty = itemNetStart4.m_nFocus; 4706 gPacketStartGame.weaponSettings = itemNetStart6.m_nFocus; 4707 gPacketStartGame.itemSettings = itemNetStart7.m_nFocus; 4708 gPacketStartGame.respawnSettings = 0; 4709 gPacketStartGame.bFriendlyFire = itemNetGameBoolFriendlyFire.at20; 4710 gPacketStartGame.keySettings = itemNetGameCycleKey.m_nFocus; 4711 gPacketStartGame.itemWeaponSettings = itemNetGameCycleItemWeapon.m_nFocus; 4712 gPacketStartGame.bAutoTeams = itemNetGameBoolAutoTeams.at20; 4713 gPacketStartGame.nSpawnProtection = itemNetGameCycleSpawnProtection.m_nFocus; 4714 gPacketStartGame.nSpawnWeapon = itemNetGameCycleSpawnWeapon.m_nFocus; 4715 4716 gPacketStartGame.monsterSettings = itemNetMonsterSettings.m_nFocus; 4717 gPacketStartGame.monsterQuantity = ClipRange(itemNetMonsterQuantity.nValue, 0, 4); 4718 gPacketStartGame.monsterHealth = ClipRange(itemNetMonsterHealth.nValue, 0, 4); 4719 gPacketStartGame.monsterSpeed = ClipRange(itemNetMonsterSpeed.m_nFocus, 0, 4); 4720 4721 //// 4722 SetGameVanillaMode(0); // turn off vanilla mode for multiplayer so menus don't get bugged 4723 gPacketStartGame.bQuadDamagePowerup = itemNetMutatorBoolQuadDamagePowerup.at20; 4724 gPacketStartGame.nDamageInvul = itemNetMutatorDamageInvul.m_nFocus % ARRAY_SSIZE(pzDamageInvulBehaviorStrings); 4725 gPacketStartGame.nProjectileBehavior = itemNetMutatorProjectileBehavior.m_nFocus % ARRAY_SSIZE(pzProjectileBehaviorStrings); 4726 gPacketStartGame.bNapalmFalloff = itemNetMutatorNapalmFalloff.at20; 4727 gPacketStartGame.nEnemyBehavior = itemNetMutatorEnemyBehavior.m_nFocus % ARRAY_SSIZE(pzEnemyBehaviorStrings); 4728 gPacketStartGame.bEnemyRandomTNT = itemNetMutatorBoolEnemyRandomTNT.at20; 4729 gPacketStartGame.nWeaponsVer = itemNetMutatorWeaponsVer.m_nFocus % ARRAY_SSIZE(pzWeaponsVersionStrings); 4730 gPacketStartGame.nAmmoScale = itemNetMutatorAmmoScale.m_nFocus % ARRAY_SSIZE(pzAmmoScaleStrings); 4731 gPacketStartGame.bSectorBehavior = itemNetMutatorSectorBehavior.at20; 4732 gPacketStartGame.nHitscanProjectiles = itemNetMutatorHitscanProjectiles.m_nFocus % ARRAY_SSIZE(pzHitscanProjectilesStrings); 4733 gPacketStartGame.nGoreBehavior = itemNetMutatorGoreBehavior.m_nFocus % ARRAY_SSIZE(pzGoreStrings); 4734 gPacketStartGame.nPlayerSpeed = itemNetMutatorPlayerSpeed.m_nFocus % ARRAY_SSIZE(pzPlayerSpeeds); 4735 gPacketStartGame.randomizerMode = itemNetMutatorRandomizerMode.m_nFocus % ARRAY_SSIZE(pzRandomizerModeStrings); 4736 Bstrncpy(gPacketStartGame.szRandomizerSeed, szRandomizerSeedMenu, sizeof(gPacketStartGame.szRandomizerSeed)); 4737 if (gPacketStartGame.szRandomizerSeed[0] == '\0') // if no seed entered, generate new one before sending packet 4738 sprintf(gPacketStartGame.szRandomizerSeed, "%08X", QRandom2(gGameMenuMgr.m_mousepos.x*gGameMenuMgr.m_mousepos.y)); 4739 gPacketStartGame.uSpriteBannedFlags = SetBannedSprites(0); 4740 //// 4741 Bstrncpy(gPacketStartGame.userMapName, zUserMapName, sizeof(zUserMapName)); 4742 gPacketStartGame.userMap = gPacketStartGame.userMapName[0] != '\0'; 4743 4744 netBroadcastNewGame(); 4745 gStartNewGame = 1; 4746 gGameMenuMgr.Deactivate(); 4747 } 4748 4749 void Restart(CGameMenuItemChain *pItem) 4750 { 4751 UNREFERENCED_PARAMETER(pItem); 4752 if (gGameOptions.nGameType == kGameTypeSinglePlayer || numplayers == 1) 4753 { 4754 gQuitGame = true; 4755 gRestartGame = true; 4756 } 4757 else 4758 gQuitRequest = 2; 4759 gGameMenuMgr.Deactivate(); 4760 } 4761 4762 void Quit(CGameMenuItemChain *pItem) 4763 { 4764 UNREFERENCED_PARAMETER(pItem); 4765 if (gGameOptions.nGameType == kGameTypeSinglePlayer || numplayers == 1) 4766 gQuitGame = true; 4767 else 4768 gQuitRequest = 1; 4769 gGameMenuMgr.Deactivate(); 4770 } 4771 4772 void MenuSetupEpisodeInfo(void) 4773 { 4774 memset(zEpisodeNames, 0, sizeof(zEpisodeNames)); 4775 memset(zLevelNames, 0, sizeof(zLevelNames)); 4776 for (int i = 0; i < 6; i++) 4777 { 4778 if (i < gEpisodeCount) 4779 { 4780 EPISODEINFO *pEpisode = &gEpisodeInfo[i]; 4781 zEpisodeNames[i] = pEpisode->title; 4782 for (int j = 0; j < kMaxLevels; j++) 4783 { 4784 if (j < pEpisode->nLevels) 4785 { 4786 zLevelNames[i][j] = pEpisode->levelsInfo[j].Title; 4787 } 4788 } 4789 } 4790 } 4791 } 4792 4793 void drawLoadingScreen(int nTile) 4794 { 4795 char buffer[80]; 4796 if (gGameOptions.nGameType == kGameTypeSinglePlayer) 4797 { 4798 if (gDemo.bPlaying) 4799 sprintf(buffer, "Loading Demo"); 4800 else 4801 sprintf(buffer, "Loading Level"); 4802 } 4803 else 4804 sprintf(buffer, "%s", zNetGameTypes[gGameOptions.nGameType-1]); 4805 viewLoadingScreen(nTile, buffer, levelGetTitle(), NULL); 4806 }