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 "view.h"
42 
43 void SaveGame(CGameMenuItemZEditBitmap *, CGameMenuEvent *);
44 
45 void SaveGameProcess(CGameMenuItemChain *);
46 void ShowDifficulties();
47 void SetDifficultyAndStart(CGameMenuItemChain *);
48 void SetDetail(CGameMenuItemSlider *);
49 void SetGamma(CGameMenuItemSlider *);
50 void SetMusicVol(CGameMenuItemSlider *);
51 void SetSoundVol(CGameMenuItemSlider *);
52 void SetCDVol(CGameMenuItemSlider *);
53 void SetDoppler(CGameMenuItemZBool *);
54 void SetCrosshair(CGameMenuItemZBool *);
55 void SetCenterHoriz(CGameMenuItemZBool *);
56 void SetShowPlayerNames(CGameMenuItemZBool *);
57 void SetShowWeapons(CGameMenuItemZCycle *);
58 
59 void SetWeaponsV10X(CGameMenuItemZBool*);
60 
61 void SetSlopeTilting(CGameMenuItemZBool *);
62 void SetViewBobbing(CGameMenuItemZBool *);
63 void SetViewSwaying(CGameMenuItemZBool *);
64 void SetMouseSensitivity(CGameMenuItemSliderFloat *);
65 void SetMouseAimFlipped(CGameMenuItemZBool *);
66 void SetTurnSpeed(CGameMenuItemSlider *);
67 void ResetKeys(CGameMenuItemChain *);
68 void ResetKeysClassic(CGameMenuItemChain *);
69 void SetMessages(CGameMenuItemZBool *);
70 void LoadGame(CGameMenuItemZEditBitmap *, CGameMenuEvent *);
71 void SetupNetLevels(CGameMenuItemZCycle *);
72 void StartNetGame(CGameMenuItemChain *);
73 void SetParentalLock(CGameMenuItemZBool *);
74 void TenProcess(CGameMenuItem7EA1C *);
75 void SetupLevelMenuItem(int);
76 void SetupVideoModeMenu(CGameMenuItemChain *);
77 void SetVideoMode(CGameMenuItemChain *);
78 void SetWidescreen(CGameMenuItemZBool *);
79 void SetFOV(CGameMenuItemSlider *);
80 void UpdateVideoModeMenuFrameLimit(CGameMenuItemZCycle *pItem);
81 void UpdateVideoModeMenuFPSOffset(CGameMenuItemSlider *pItem);
82 void UpdateVideoColorMenu(CGameMenuItemSliderFloat *);
83 void ResetVideoColor(CGameMenuItemChain *);
84 #ifdef USE_OPENGL
85 void SetupVideoPolymostMenu(CGameMenuItemChain *);
86 #endif
87 
88 char strRestoreGameStrings[][16] =
89 {
90     "<Empty>",
91     "<Empty>",
92     "<Empty>",
93     "<Empty>",
94     "<Empty>",
95     "<Empty>",
96     "<Empty>",
97     "<Empty>",
98     "<Empty>",
99     "<Empty>",
100 };
101 
102 char restoreGameDifficulty[] =
103 {
104     2,
105     2,
106     2,
107     2,
108     2,
109     2,
110     2,
111     2,
112     2,
113     2,
114 };
115 
116 const char *zNetGameTypes[] =
117 {
118     "Cooperative",
119     "Bloodbath",
120     "Teams",
121 };
122 
123 const char *zMonsterStrings[] =
124 {
125     "None",
126     "Bring 'em on",
127     "Respawn",
128 };
129 
130 const char *zWeaponStrings[] =
131 {
132     "Do not Respawn",
133     "Are Permanent",
134     "Respawn",
135     "Respawn with Markers",
136 };
137 
138 const char *zItemStrings[] =
139 {
140     "Do not Respawn",
141     "Respawn",
142     "Respawn with Markers",
143 };
144 
145 const char *zRespawnStrings[] =
146 {
147     "At Random Locations",
148     "Close to Weapons",
149     "Away from Enemies",
150 };
151 
152 const char *zDiffStrings[] =
153 {
154     "STILL KICKING",
155     "PINK ON THE INSIDE",
156     "LIGHTLY BROILED",
157     "WELL DONE",
158     "EXTRA CRISPY",
159 };
160 
161 const char *pzShowWeaponStrings[] = {
162     "OFF",
163     "SPRITE",
164     "VOXEL"
165 };
166 
167 char zUserMapName[BMAX_PATH];
168 const char *zEpisodeNames[6];
169 const char *zLevelNames[6][16];
170 
171 static char MenuGameFuncs[NUMGAMEFUNCTIONS][MAXGAMEFUNCLEN];
172 static char const *MenuGameFuncNone = "  -None-";
173 static char const *pzGamefuncsStrings[NUMGAMEFUNCTIONS + 1];
174 static int nGamefuncsValues[NUMGAMEFUNCTIONS + 1];
175 static int nGamefuncsNum;
176 
177 CGameMenu menuMain;
178 CGameMenu menuMainWithSave;
179 CGameMenu menuNetMain;
180 CGameMenu menuNetStart;
181 CGameMenu menuEpisode;
182 CGameMenu menuDifficulty;
183 CGameMenu menuOptionsOld;
184 CGameMenu menuControls;
185 CGameMenu menuMessages;
186 CGameMenu menuKeys;
187 CGameMenu menuSaveGame;
188 CGameMenu menuLoadGame;
189 CGameMenu menuLoading;
190 CGameMenu menuSounds;
191 CGameMenu menuQuit;
192 CGameMenu menuRestart;
193 CGameMenu menuCredits;
194 CGameMenu menuOrder;
195 CGameMenu menuPlayOnline;
196 CGameMenu menuParentalLock;
197 CGameMenu menuSorry;
198 CGameMenu menuSorry2;
199 CGameMenu menuNetwork;
200 CGameMenu menuNetworkHost;
201 CGameMenu menuNetworkJoin;
202 
203 CGameMenuItemQAV itemBloodQAV("", 3, 160, 100, "BDRIP", true);
204 CGameMenuItemQAV itemCreditsQAV("", 3, 160, 100, "CREDITS", false, true);
205 CGameMenuItemQAV itemHelp3QAV("", 3, 160, 100, "HELP3", false, false);
206 CGameMenuItemQAV itemHelp3BQAV("", 3, 160, 100, "HELP3B", false, false);
207 CGameMenuItemQAV itemHelp4QAV("", 3, 160, 100, "HELP4", false, true);
208 CGameMenuItemQAV itemHelp5QAV("", 3, 160, 100, "HELP5", false, true);
209 
210 CGameMenuItemTitle itemMainTitle("BLOOD", 1, 160, 20, 2038);
211 CGameMenuItemChain itemMain1("NEW GAME", 1, 0, 45, 320, 1, &menuEpisode, -1, NULL, 0);
212 //CGameMenuItemChain itemMain2("PLAY ONLINE", 1, 0, 65, 320, 1, &menuPlayOnline, -1, NULL, 0);
213 CGameMenuItemChain itemMain2("MULTIPLAYER", 1, 0, 65, 320, 1, &menuNetwork, -1, NULL, 0);
214 CGameMenuItemChain itemMain3("OPTIONS", 1, 0, 85, 320, 1, &menuOptions, -1, NULL, 0);
215 CGameMenuItemChain itemMain4("LOAD GAME", 1, 0, 105, 320, 1, &menuLoadGame, -1, NULL, 0);
216 CGameMenuItemChain itemMain5("HELP", 1, 0, 125, 320, 1, &menuOrder, -1, NULL, 0);
217 CGameMenuItemChain itemMain6("CREDITS", 1, 0, 145, 320, 1, &menuCredits, -1, NULL, 0);
218 CGameMenuItemChain itemMain7("QUIT", 1, 0, 165, 320, 1, &menuQuit, -1, NULL, 0);
219 
220 CGameMenuItemTitle itemMainSaveTitle("BLOOD", 1, 160, 20, 2038);
221 CGameMenuItemChain itemMainSave1("NEW GAME", 1, 0, 45, 320, 1, &menuEpisode, -1, NULL, 0);
222 //CGameMenuItemChain itemMainSave2("PLAY ONLINE", 1, 0, 60, 320, 1, &menuPlayOnline, -1, NULL, 0);
223 CGameMenuItemChain itemMainSave2("OPTIONS", 1, 0, 60, 320, 1, &menuOptions, -1, NULL, 0);
224 CGameMenuItemChain itemMainSave3("SAVE GAME", 1, 0, 75, 320, 1, &menuSaveGame, -1, SaveGameProcess, 0);
225 CGameMenuItemChain itemMainSave4("LOAD GAME", 1, 0, 90, 320, 1, &menuLoadGame, -1, NULL, 0);
226 CGameMenuItemChain itemMainSave5("HELP", 1, 0, 105, 320, 1, &menuOrder, -1, NULL, 0);
227 CGameMenuItemChain itemMainSave6("CREDITS", 1, 0, 120, 320, 1, &menuCredits, -1, NULL, 0);
228 CGameMenuItemChain itemMainSave7("END GAME", 1, 0, 135, 320, 1, &menuRestart, -1, NULL, 0);
229 CGameMenuItemChain itemMainSave8("QUIT", 1, 0, 150, 320, 1, &menuQuit, -1, NULL, 0);
230 
231 CGameMenuItemTitle itemEpisodesTitle("EPISODES", 1, 160, 20, 2038);
232 CGameMenuItemChain7F2F0 itemEpisodes[kMaxEpisodes-1];
233 
234 CGameMenu menuUserMap;
235 CGameMenuItemChain itemUserMap("USER MAP", 1, 0, 60, 320, 1, &menuUserMap, 0, NULL, 0);
236 CGameMenuItemTitle itemUserMapTitle("USER MAP", 1, 160, 20, 2038);
237 CGameMenuFileSelect itemUserMapList("", 3, 0, 0, 0, "./", "*.map", gGameOptions.szUserMap, ShowDifficulties, 0);
238 
239 CGameMenuItemTitle itemDifficultyTitle("DIFFICULTY", 1, 160, 20, 2038);
240 CGameMenuItemChain itemDifficulty1("STILL KICKING", 1, 0, 60, 320, 1, NULL, -1, SetDifficultyAndStart, 0);
241 CGameMenuItemChain itemDifficulty2("PINK ON THE INSIDE", 1, 0, 80, 320, 1, NULL, -1, SetDifficultyAndStart, 1);
242 CGameMenuItemChain itemDifficulty3("LIGHTLY BROILED", 1, 0, 100, 320, 1, NULL, -1, SetDifficultyAndStart, 2);
243 CGameMenuItemChain itemDifficulty4("WELL DONE", 1, 0, 120, 320, 1, NULL, -1, SetDifficultyAndStart, 3);
244 CGameMenuItemChain itemDifficulty5("EXTRA CRISPY", 1, 0, 140, 320, 1, 0, -1, SetDifficultyAndStart, 4);
245 
246 CGameMenuItemTitle itemOptionsOldTitle("OPTIONS", 1, 160, 20, 2038);
247 CGameMenuItemChain itemOption1("CONTROLS...", 3, 0, 40, 320, 1, &menuControls, -1, NULL, 0);
248 CGameMenuItemSlider sliderDetail("DETAIL:", 3, 66, 50, 180, gDetail, 0, 4, 1, SetDetail, -1, -1);
249 CGameMenuItemSlider sliderGamma("GAMMA:", 3, 66, 60, 180, gGamma, 0, 15, 2, SetGamma, -1, -1);
250 CGameMenuItemSlider sliderMusic("MUSIC:", 3, 66, 70, 180, MusicVolume, 0, 256, 48, SetMusicVol, -1, -1);
251 CGameMenuItemSlider sliderSound("SOUND:", 3, 66, 80, 180, FXVolume, 0, 256, 48, SetSoundVol, -1, -1);
252 CGameMenuItemSlider sliderCDAudio("CD AUDIO:", 3, 66, 90, 180, CDVolume, 0, 256, 48, SetCDVol, -1, -1);
253 CGameMenuItemZBool bool3DAudio("3D AUDIO:", 3, 66, 100, 180, gDoppler, SetDoppler, NULL, NULL);
254 CGameMenuItemZBool boolCrosshair("CROSSHAIR:", 3, 66, 110, 180, gAimReticle, SetCrosshair, NULL, NULL);
255 CGameMenuItemZCycle itemCycleShowWeapons("SHOW WEAPONS:", 3, 66, 120, 180, 0, SetShowWeapons, pzShowWeaponStrings, ARRAY_SSIZE(pzShowWeaponStrings), 0);
256 CGameMenuItemZBool boolSlopeTilting("SLOPE TILTING:", 3, 66, 130, 180, gSlopeTilting, SetSlopeTilting, NULL, NULL);
257 CGameMenuItemZBool boolViewBobbing("VIEW BOBBING:", 3, 66, 140, 180, gViewVBobbing, SetViewBobbing, NULL, NULL);
258 CGameMenuItemZBool boolViewSwaying("VIEW SWAYING:", 3, 66, 150, 180, gViewHBobbing, SetViewSwaying, NULL, NULL);
259 CGameMenuItem7EE34 itemOption2("VIDEO MODE...", 3, 0, 160, 320, 1);
260 CGameMenuItemChain itemChainParentalLock("PARENTAL LOCK", 3, 0, 170, 320, 1, &menuParentalLock, -1, NULL, 0);
261 
262 CGameMenuItemTitle itemControlsTitle("CONTROLS", 1, 160, 20, 2038);
263 CGameMenuItemSliderFloat sliderMouseSpeed("Mouse Sensitivity:", 1, 10, 70, 300, CONTROL_MouseSensitivity, 0.5f, 16.f, 0.5f, SetMouseSensitivity, -1,-1);
264 CGameMenuItemZBool boolMouseFlipped("Invert Mouse Aim:", 1, 10, 90, 300, gMouseAimingFlipped, SetMouseAimFlipped, NULL, NULL);
265 CGameMenuItemSlider sliderTurnSpeed("Key Turn Speed:", 1, 10, 110, 300, gTurnSpeed, 64, 128, 4, SetTurnSpeed, -1, -1);
266 CGameMenuItemChain itemChainKeyList("Configure Keys...", 1, 0, 130, 320, 1, &menuKeys, -1, NULL, 0);
267 CGameMenuItemChain itemChainKeyReset("Reset Keys (default)...", 1, 0, 150, 320, 1, &menuKeys, -1, ResetKeys, 0);
268 CGameMenuItemChain itemChainKeyResetClassic("Reset Keys (classic)...", 1, 0, 170, 320, 1, &menuKeys, -1, ResetKeysClassic, 0);
269 
270 CGameMenuItemTitle itemMessagesTitle("MESSAGES", 1, 160, 20, 2038);
271 CGameMenuItemZBool boolMessages("MESSAGES:", 3, 66, 70, 180, 0, SetMessages, NULL, NULL);
272 CGameMenuItemSlider sliderMsgCount("MESSAGE COUNT:", 3, 66, 80, 180, gMessageCount, 1, 16, 1, NULL, -1, -1);
273 CGameMenuItemSlider sliderMsgTime("MESSAGE TIME:", 3, 66, 90, 180, gMessageTime, 1, 8, 1, NULL, -1, -1);
274 CGameMenuItemZBool boolMsgFont("LARGE FONT:", 3, 66, 100, 180, 0, 0, NULL, NULL);
275 CGameMenuItemZBool boolMsgIncoming("INCOMING:", 3, 66, 110, 180, 0, 0, NULL, NULL);
276 CGameMenuItemZBool boolMsgSelf("SELF PICKUP:", 3, 66, 120, 180, 0, 0, NULL, NULL);
277 CGameMenuItemZBool boolMsgOther("OTHER PICKUP:", 3, 66, 130, 180, 0, 0, NULL, NULL);
278 CGameMenuItemZBool boolMsgRespawn("RESPAWN:", 3, 66, 140, 180, 0, 0, NULL, NULL);
279 
280 CGameMenuItemTitle itemKeysTitle("KEY SETUP", 1, 160, 20, 2038);
281 CGameMenuItemKeyList itemKeyList("", 3, 56, 40, 200, 16, NUMGAMEFUNCTIONS, 0);
282 
283 CGameMenuItemTitle itemSaveTitle("Save Game", 1, 160, 20, 2038);
284 CGameMenuItemZEditBitmap itemSaveGame1(NULL, 3, 20, 60, 320, strRestoreGameStrings[0], 16, 1, SaveGame, 0);
285 CGameMenuItemZEditBitmap itemSaveGame2(NULL, 3, 20, 70, 320, strRestoreGameStrings[1], 16, 1, SaveGame, 1);
286 CGameMenuItemZEditBitmap itemSaveGame3(NULL, 3, 20, 80, 320, strRestoreGameStrings[2], 16, 1, SaveGame, 2);
287 CGameMenuItemZEditBitmap itemSaveGame4(NULL, 3, 20, 90, 320, strRestoreGameStrings[3], 16, 1, SaveGame, 3);
288 CGameMenuItemZEditBitmap itemSaveGame5(NULL, 3, 20, 100, 320, strRestoreGameStrings[4], 16, 1, SaveGame, 4);
289 CGameMenuItemZEditBitmap itemSaveGame6(NULL, 3, 20, 110, 320, strRestoreGameStrings[5], 16, 1, SaveGame, 5);
290 CGameMenuItemZEditBitmap itemSaveGame7(NULL, 3, 20, 120, 320, strRestoreGameStrings[6], 16, 1, SaveGame, 6);
291 CGameMenuItemZEditBitmap itemSaveGame8(NULL, 3, 20, 130, 320, strRestoreGameStrings[7], 16, 1, SaveGame, 7);
292 CGameMenuItemZEditBitmap itemSaveGame9(NULL, 3, 20, 140, 320, strRestoreGameStrings[8], 16, 1, SaveGame, 8);
293 CGameMenuItemZEditBitmap itemSaveGame10(NULL, 3, 20, 150, 320, strRestoreGameStrings[9], 16, 1, SaveGame, 9);
294 CGameMenuItemBitmapLS itemSaveGamePic(NULL, 3, 0, 0, 2050);
295 
296 CGameMenuItemTitle itemLoadTitle("Load Game", 1, 160, 20, 2038);
297 CGameMenuItemZEditBitmap itemLoadGame1(NULL, 3, 20, 60, 320, strRestoreGameStrings[0], 16, 1, LoadGame, 0);
298 CGameMenuItemZEditBitmap itemLoadGame2(NULL, 3, 20, 70, 320, strRestoreGameStrings[1], 16, 1, LoadGame, 1);
299 CGameMenuItemZEditBitmap itemLoadGame3(NULL, 3, 20, 80, 320, strRestoreGameStrings[2], 16, 1, LoadGame, 2);
300 CGameMenuItemZEditBitmap itemLoadGame4(NULL, 3, 20, 90, 320, strRestoreGameStrings[3], 16, 1, LoadGame, 3);
301 CGameMenuItemZEditBitmap itemLoadGame5(NULL, 3, 20, 100, 320, strRestoreGameStrings[4], 16, 1, LoadGame, 4);
302 CGameMenuItemZEditBitmap itemLoadGame6(NULL, 3, 20, 110, 320, strRestoreGameStrings[5], 16, 1, LoadGame, 5);
303 CGameMenuItemZEditBitmap itemLoadGame7(NULL, 3, 20, 120, 320, strRestoreGameStrings[6], 16, 1, LoadGame, 6);
304 CGameMenuItemZEditBitmap itemLoadGame8(NULL, 3, 20, 130, 320, strRestoreGameStrings[7], 16, 1, LoadGame, 7);
305 CGameMenuItemZEditBitmap itemLoadGame9(NULL, 3, 20, 140, 320, strRestoreGameStrings[8], 16, 1, LoadGame, 8);
306 CGameMenuItemZEditBitmap itemLoadGame10(NULL, 3, 20, 150, 320, strRestoreGameStrings[9], 16, 1, LoadGame, 9);
307 CGameMenuItemBitmapLS itemLoadGamePic(NULL, 3, 0, 0, 2518);
308 
309 CGameMenu menuMultiUserMaps;
310 
311 CGameMenuItemTitle itemNetStartUserMapTitle("USER MAP", 1, 160, 20, 2038);
312 CGameMenuFileSelect menuMultiUserMap("", 3, 0, 0, 0, "./", "*.map", zUserMapName);
313 
314 CGameMenuItemTitle itemNetStartTitle("MULTIPLAYER", 1, 160, 20, 2038);
315 CGameMenuItemZCycle itemNetStart1("GAME:", 3, 66, 60, 180, 0, 0, zNetGameTypes, 3, 0);
316 CGameMenuItemZCycle itemNetStart2("EPISODE:", 3, 66, 70, 180, 0, SetupNetLevels, NULL, 0, 0);
317 CGameMenuItemZCycle itemNetStart3("LEVEL:", 3, 66, 80, 180, 0, NULL, NULL, 0, 0);
318 CGameMenuItemZCycle itemNetStart4("DIFFICULTY:", 3, 66, 90, 180, 0, 0, zDiffStrings, 5, 0);
319 CGameMenuItemZCycle itemNetStart5("MONSTERS:", 3, 66, 100, 180, 0, 0, zMonsterStrings, 3, 0);
320 CGameMenuItemZCycle itemNetStart6("WEAPONS:", 3, 66, 110, 180, 0, 0, zWeaponStrings, 4, 0);
321 CGameMenuItemZCycle itemNetStart7("ITEMS:", 3, 66, 120, 180, 0, 0, zItemStrings, 3, 0);
322 CGameMenuItemZBool itemNetStart8("FRIENDLY FIRE:", 3, 66, 130, 180, true, 0, NULL, NULL);
323 CGameMenuItemZBool itemNetStart9("KEEP KEYS ON RESPAWN:", 3, 66, 140, 180, false, 0, NULL, NULL);
324 CGameMenuItemZBool itemNetStart10("V1.0x WEAPONS BALANCE:", 3, 66, 150, 180, false, 0, NULL, NULL);
325 CGameMenuItemChain itemNetStart11("USER MAP", 3, 66, 160, 180, 0, &menuMultiUserMaps, 0, NULL, 0);
326 CGameMenuItemChain itemNetStart12("START GAME", 1, 66, 175, 280, 0, 0, -1, StartNetGame, 0);
327 
328 CGameMenuItemText itemLoadingText("LOADING...", 1, 160, 100, 1);
329 
330 CGameMenuItemTitle itemSoundsTitle("SOUNDS", 1, 160, 20, 2038);
331 CGameMenuItemSlider itemSoundsMusic("MUSIC:", 3, 40, 60, 180, MusicVolume, 0, 256, 48, SetMusicVol, -1, -1);
332 CGameMenuItemSlider itemSoundsSound("SOUND:", 3, 40, 70, 180, FXVolume, 0, 256, 48, SetSoundVol, -1, -1);
333 CGameMenuItemSlider itemSoundsCDAudio("CD AUDIO:", 3, 40, 80, 180, CDVolume, 0, 256, 48, SetCDVol, -1, -1);
334 CGameMenuItemZBool itemSounds3DAudio("3D SOUND:", 3, 40, 90, 180, gDoppler, SetDoppler, NULL, NULL);
335 
336 CGameMenuItemTitle itemQuitTitle("QUIT", 1, 160, 20, 2038);
337 CGameMenuItemText itemQuitText1("Do you really want to quit?", 0, 160, 100, 1);
338 CGameMenuItemYesNoQuit itemQuitYesNo("[Y/N]", 0, 20, 110, 280, 1, 0);
339 
340 CGameMenuItemTitle itemRestartTitle("RESTART GAME", 1, 160, 20, 2038);
341 CGameMenuItemText itemRestartText1("Do you really want to restart game?", 0, 160, 100, 1);
342 CGameMenuItemYesNoQuit itemRestartYesNo("[Y/N]", 0, 20, 110, 280, 1, 1);
343 
344 CGameMenuItemPicCycle itemCreditsPicCycle(0, 0, NULL, NULL, 0, 0);
345 CGameMenuItemPicCycle itemOrderPicCycle(0, 0, NULL, NULL, 0, 0);
346 
347 CGameMenuItemTitle itemParentalLockTitle("PARENTAL LOCK", 1, 160, 20, 2038);
348 CGameMenuItemZBool itemParentalLockToggle("LOCK:", 3, 66, 70, 180, 0, SetParentalLock, NULL, NULL);
349 CGameMenuItemPassword itemParentalLockPassword("SET PASSWORD:", 3, 160, 80);
350 
351 CGameMenuItemPicCycle itemSorryPicCycle(0, 0, NULL, NULL, 0, 0);
352 CGameMenuItemText itemSorryText1("Loading and saving games", 0, 160, 90, 1);
353 CGameMenuItemText itemSorryText2("not supported", 0, 160, 100, 1);
354 CGameMenuItemText itemSorryText3("in this demo version of Blood.", 0, 160, 110, 1);
355 
356 CGameMenuItemText itemSorry2Text1("Buy the complete version of", 0, 160, 90, 1);
357 CGameMenuItemText itemSorry2Text2("Blood for three new episodes", 0, 160, 100, 1);
358 CGameMenuItemText itemSorry2Text3("plus eight BloodBath-only levels!", 0, 160, 110, 1);
359 
360 CGameMenuItemTitle unk_26E06C(" ONLINE ", 1, 160, 20, 2038);
361 CGameMenuItem7EA1C unk_26E090("DWANGO", 1, 0, 45, 320, "matt", "DWANGO", 1, -1, NULL, 0);
362 CGameMenuItem7EA1C unk_26E0E8("RTIME", 1, 0, 65, 320, "matt", "RTIME", 1, -1, NULL, 0);
363 CGameMenuItem7EA1C unk_26E140("HEAT", 1, 0, 85, 320, "matt", "HEAT", 1, -1, NULL, 0);
364 CGameMenuItem7EA1C unk_26E198("KALI", 1, 0, 105, 320, "matt", "KALI", 1, -1, NULL, 0);
365 CGameMenuItem7EA1C unk_26E1F0("MPATH", 1, 0, 125, 320, "matt", "MPATH", 1, -1, NULL, 0);
366 CGameMenuItem7EA1C unk_26E248("TEN", 1, 0, 145, 320, "matt", "TEN", 1, -1, TenProcess, 0);
367 
368 
369 // static int32_t newresolution, newrendermode, newfullscreen, newvsync;
370 
371 enum resflags_t {
372     RES_FS = 0x1,
373     RES_WIN = 0x2,
374 };
375 
376 #define MAXRESOLUTIONSTRINGLENGTH 19
377 
378 struct resolution_t {
379     int32_t xdim, ydim;
380     int32_t flags;
381     int32_t bppmax;
382     char name[MAXRESOLUTIONSTRINGLENGTH];
383 };
384 
385 resolution_t gResolution[MAXVALIDMODES];
386 int gResolutionNum;
387 const char *gResolutionName[MAXVALIDMODES];
388 
389 CGameMenu menuOptions;
390 CGameMenu menuOptionsGame;
391 CGameMenu menuOptionsDisplay;
392 CGameMenu menuOptionsDisplayColor;
393 CGameMenu menuOptionsDisplayMode;
394 #ifdef USE_OPENGL
395 CGameMenu menuOptionsDisplayPolymost;
396 #endif
397 CGameMenu menuOptionsSound;
398 CGameMenu menuOptionsPlayer;
399 CGameMenu menuOptionsControl;
400 
401 void SetupOptionsSound(CGameMenuItemChain *pItem);
402 
403 CGameMenuItemTitle itemOptionsTitle("OPTIONS", 1, 160, 20, 2038);
404 CGameMenuItemChain itemOptionsChainGame("GAME SETUP", 1, 0, 50, 320, 1, &menuOptionsGame, -1, NULL, 0);
405 CGameMenuItemChain itemOptionsChainDisplay("DISPLAY SETUP", 1, 0, 70, 320, 1, &menuOptionsDisplay, -1, NULL, 0);
406 CGameMenuItemChain itemOptionsChainSound("SOUND SETUP", 1, 0, 90, 320, 1, &menuOptionsSound, -1, SetupOptionsSound, 0);
407 CGameMenuItemChain itemOptionsChainPlayer("PLAYER SETUP", 1, 0, 110, 320, 1, &menuOptionsPlayer, -1, NULL, 0);
408 CGameMenuItemChain itemOptionsChainControl("CONTROL SETUP", 1, 0, 130, 320, 1, &menuOptionsControl, -1, NULL, 0);
409 CGameMenuItemChain itemOptionsChainOld("OLD MENU", 1, 0, 170, 320, 1, &menuOptionsOld, -1, NULL, 0);
410 
411 const char *pzAutoAimStrings[] = {
412     "NEVER",
413     "ALWAYS",
414     "HITSCAN ONLY"
415 };
416 
417 const char *pzWeaponSwitchStrings[] = {
418     "NEVER",
419     "IF NEW",
420     "BY RATING"
421 };
422 
423 void SetAutoAim(CGameMenuItemZCycle *);
424 void SetLevelStats(CGameMenuItemZBool *);
425 void SetPowerupDuration(CGameMenuItemZBool *);
426 void SetShowMapTitle(CGameMenuItemZBool*);
427 void SetWeaponSwitch(CGameMenuItemZCycle *pItem);
428 
429 CGameMenuItemTitle itemOptionsGameTitle("GAME SETUP", 1, 160, 20, 2038);
430 
431 ///////////////
432 CGameMenuItemZBool itemOptionsGameBoolWeaponsV10X("V1.0x WEAPONS BALANCE:", 3, 66, 130, 180, gWeaponsV10x, SetWeaponsV10X, NULL, NULL);
433 ///////////////////
434 
435 CGameMenuItemZBool itemOptionsGameBoolShowPlayerNames("SHOW PLAYER NAMES:", 3, 66, 60, 180, gShowPlayerNames, SetShowPlayerNames, NULL, NULL);
436 CGameMenuItemZCycle itemOptionsGameShowWeapons("SHOW WEAPONS:", 3, 66, 70, 180, 0, SetShowWeapons, pzShowWeaponStrings, ARRAY_SSIZE(pzShowWeaponStrings), 0);
437 CGameMenuItemZBool itemOptionsGameBoolSlopeTilting("SLOPE TILTING:", 3, 66, 80, 180, gSlopeTilting, SetSlopeTilting, NULL, NULL);
438 CGameMenuItemZBool itemOptionsGameBoolViewBobbing("VIEW BOBBING:", 3, 66, 90, 180, gViewVBobbing, SetViewBobbing, NULL, NULL);
439 CGameMenuItemZBool itemOptionsGameBoolViewSwaying("VIEW SWAYING:", 3, 66, 100, 180, gViewHBobbing, SetViewSwaying, NULL, NULL);
440 CGameMenuItemZCycle itemOptionsGameBoolAutoAim("AUTO AIM:", 3, 66, 110, 180, 0, SetAutoAim, pzAutoAimStrings, ARRAY_SSIZE(pzAutoAimStrings), 0);
441 CGameMenuItemZCycle itemOptionsGameWeaponSwitch("EQUIP PICKUPS:", 3, 66, 120, 180, 0, SetWeaponSwitch, pzWeaponSwitchStrings, ARRAY_SSIZE(pzWeaponSwitchStrings), 0);
442 CGameMenuItemChain itemOptionsGameChainParentalLock("PARENTAL LOCK", 3, 0, 120, 320, 1, &menuParentalLock, -1, NULL, 0);
443 
444 CGameMenuItemTitle itemOptionsDisplayTitle("DISPLAY SETUP", 1, 160, 20, 2038);
445 CGameMenuItemChain itemOptionsDisplayColor("COLOR CORRECTION", 3, 66, 60, 180, 0, &menuOptionsDisplayColor, -1, NULL, 0);
446 CGameMenuItemChain itemOptionsDisplayMode("VIDEO MODE", 3, 66, 70, 180, 0, &menuOptionsDisplayMode, -1, SetupVideoModeMenu, 0);
447 CGameMenuItemZBool itemOptionsDisplayBoolCrosshair("CROSSHAIR:", 3, 66, 80, 180, gAimReticle, SetCrosshair, NULL, NULL);
448 CGameMenuItemZBool itemOptionsDisplayBoolCenterHoriz("CENTER HORIZON LINE:", 3, 66, 90, 180, gCenterHoriz, SetCenterHoriz, NULL, NULL);
449 CGameMenuItemZBool itemOptionsDisplayBoolLevelStats("LEVEL STATS:", 3, 66, 100, 180, gLevelStats, SetLevelStats, NULL, NULL);
450 CGameMenuItemZBool itemOptionsDisplayBoolPowerupDuration("POWERUP DURATION:", 3, 66, 110, 180, gPowerupDuration, SetPowerupDuration, NULL, NULL);
451 CGameMenuItemZBool itemOptionsDisplayBoolShowMapTitle("MAP TITLE:", 3, 66, 120, 180, gShowMapTitle, SetShowMapTitle, NULL, NULL);
452 CGameMenuItemZBool itemOptionsDisplayBoolMessages("MESSAGES:", 3, 66, 130, 180, gMessageState, SetMessages, NULL, NULL);
453 CGameMenuItemZBool itemOptionsDisplayBoolWidescreen("WIDESCREEN:", 3, 66, 140, 180, r_usenewaspect, SetWidescreen, NULL, NULL);
454 CGameMenuItemSlider itemOptionsDisplayFOV("FOV:", 3, 66, 150, 180, &gFov, 75, 140, 5, SetFOV, -1, -1, kMenuSliderValue);
455 #ifdef USE_OPENGL
456 CGameMenuItemChain itemOptionsDisplayPolymost("POLYMOST SETUP", 3, 66, 160, 180, 0, &menuOptionsDisplayPolymost, -1, SetupVideoPolymostMenu, 0);
457 #endif
458 
459 const char *pzRendererStrings[] = {
460     "CLASSIC",
461     "POLYMOST"
462 };
463 
464 const int nRendererValues[] = {
465     REND_CLASSIC,
466     REND_POLYMOST
467 };
468 
469 const char *pzVSyncStrings[] = {
470     "ADAPTIVE",
471     "OFF",
472     "ON"
473 };
474 
475 const int nVSyncValues[] = {
476     -1,
477     0,
478     1
479 };
480 
481 const char *pzFrameLimitStrings[] = {
482     "30 FPS",
483     "60 FPS",
484     "75 FPS",
485     "100 FPS",
486     "120 FPS",
487     "144 FPS",
488     "165 FPS",
489     "240 FPS"
490 };
491 
492 const int nFrameLimitValues[] = {
493     30,
494     60,
495     75,
496     100,
497     120,
498     144,
499     165,
500     240
501 };
502 
503 
504 void PreDrawVideoModeMenu(CGameMenuItem *);
505 
506 CGameMenuItemTitle itemOptionsDisplayModeTitle("VIDEO MODE", 1, 160, 20, 2038);
507 CGameMenuItemZCycle itemOptionsDisplayModeResolution("RESOLUTION:", 3, 66, 60, 180, 0, NULL, NULL, 0, 0, true);
508 CGameMenuItemZCycle itemOptionsDisplayModeRenderer("RENDERER:", 3, 66, 70, 180, 0, NULL, pzRendererStrings, 2, 0);
509 CGameMenuItemZBool itemOptionsDisplayModeFullscreen("FULLSCREEN:", 3, 66, 80, 180, 0, NULL, NULL, NULL);
510 CGameMenuItemZCycle itemOptionsDisplayModeVSync("VSYNC:", 3, 66, 90, 180, 0, NULL, pzVSyncStrings, 3, 0);
511 CGameMenuItemZCycle itemOptionsDisplayModeFrameLimit("FRAMERATE LIMIT:", 3, 66, 100, 180, 0, UpdateVideoModeMenuFrameLimit, pzFrameLimitStrings, 8, 0);
512 CGameMenuItemSlider itemOptionsDisplayModeFPSOffset("FPS OFFSET:", 3, 66, 110, 180, 0, -10, 10, 1, UpdateVideoModeMenuFPSOffset, -1, -1, kMenuSliderValue);
513 CGameMenuItemChain itemOptionsDisplayModeApply("APPLY CHANGES", 3, 66, 125, 180, 0, NULL, 0, SetVideoMode, 0);
514 
515 void PreDrawDisplayColor(CGameMenuItem *);
516 
517 CGameMenuItemTitle itemOptionsDisplayColorTitle("COLOR CORRECTION", 1, 160, 20, -1);
518 CGameMenuItemSliderFloat itemOptionsDisplayColorGamma("GAMMA:", 3, 66, 140, 180, &g_videoGamma, 0.3f, 4.f, 0.1f, UpdateVideoColorMenu, -1, -1, kMenuSliderValue);
519 CGameMenuItemSliderFloat itemOptionsDisplayColorContrast("CONTRAST:", 3, 66, 150, 180, &g_videoContrast, 0.1f, 2.7f, 0.05f, UpdateVideoColorMenu, -1, -1, kMenuSliderValue);
520 CGameMenuItemSliderFloat itemOptionsDisplayColorBrightness("BRIGHTNESS:", 3, 66, 160, 180, &g_videoBrightness, -0.8f, 0.8f, 0.05f, UpdateVideoColorMenu, -1, -1, kMenuSliderValue);
521 CGameMenuItemSliderFloat itemOptionsDisplayColorVisibility("VISIBILITY:", 3, 66, 170, 180, &r_ambientlight, 0.125f, 4.f, 0.125f, UpdateVideoColorMenu, -1, -1, kMenuSliderValue);
522 CGameMenuItemChain itemOptionsDisplayColorReset("RESET TO DEFAULTS", 3, 66, 180, 180, 0, NULL, 0, ResetVideoColor, 0);
523 
524 const char *pzTextureModeStrings[] = {
525     "CLASSIC",
526     "FILTERED"
527 };
528 
529 #ifdef USE_OPENGL
530 int nTextureModeValues[] = {
531     TEXFILTER_OFF,
532     TEXFILTER_ON
533 };
534 #endif
535 
536 const char *pzAnisotropyStrings[] = {
537     "MAX",
538     "NONE",
539     "2X",
540     "4X",
541     "8X",
542     "16X"
543 };
544 
545 int nAnisotropyValues[] = {
546     0,
547     1,
548     2,
549     4,
550     8,
551     16
552 };
553 
554 const char *pzTexQualityStrings[] = {
555     "FULL",
556     "HALF",
557     "BARF"
558 };
559 
560 const char *pzTexCacheStrings[] = {
561     "OFF",
562     "ON",
563     "COMPRESSED"
564 };
565 
566 void UpdateTextureMode(CGameMenuItemZCycle *pItem);
567 void UpdateAnisotropy(CGameMenuItemZCycle *pItem);
568 void UpdateTrueColorTextures(CGameMenuItemZBool *pItem);
569 void UpdateTexQuality(CGameMenuItemZCycle *pItem);
570 void UpdatePreloadCache(CGameMenuItemZBool *pItem);
571 void UpdateTexCache(CGameMenuItemZCycle *pItem);
572 void UpdateDetailTex(CGameMenuItemZBool *pItem);
573 void UpdateGlowTex(CGameMenuItemZBool *pItem);
574 void Update3DModels(CGameMenuItemZBool *pItem);
575 void UpdateDeliriumBlur(CGameMenuItemZBool *pItem);
576 #ifdef USE_OPENGL
577 void PreDrawDisplayPolymost(CGameMenuItem *pItem);
578 CGameMenuItemTitle itemOptionsDisplayPolymostTitle("POLYMOST SETUP", 1, 160, 20, 2038);
579 CGameMenuItemZCycle itemOptionsDisplayPolymostTextureMode("TEXTURE MODE:", 3, 66, 60, 180, 0, UpdateTextureMode, pzTextureModeStrings, 2, 0);
580 CGameMenuItemZCycle itemOptionsDisplayPolymostAnisotropy("ANISOTROPY:", 3, 66, 70, 180, 0, UpdateAnisotropy, pzAnisotropyStrings, 6, 0);
581 CGameMenuItemZBool itemOptionsDisplayPolymostTrueColorTextures("TRUE COLOR TEXTURES:", 3, 66, 80, 180, 0, UpdateTrueColorTextures, NULL, NULL);
582 CGameMenuItemZCycle itemOptionsDisplayPolymostTexQuality("GL TEXTURE QUALITY:", 3, 66, 90, 180, 0, UpdateTexQuality, pzTexQualityStrings, 3, 0);
583 CGameMenuItemZBool itemOptionsDisplayPolymostPreloadCache("PRE-LOAD MAP TEXTURES:", 3, 66, 100, 180, 0, UpdatePreloadCache, NULL, NULL);
584 CGameMenuItemZCycle itemOptionsDisplayPolymostTexCache("ON-DISK TEXTURE CACHE:", 3, 66, 110, 180, 0, UpdateTexCache, pzTexCacheStrings, 3, 0);
585 CGameMenuItemZBool itemOptionsDisplayPolymostDetailTex("DETAIL TEXTURES:", 3, 66, 120, 180, 0, UpdateDetailTex, NULL, NULL);
586 CGameMenuItemZBool itemOptionsDisplayPolymostGlowTex("GLOW TEXTURES:", 3, 66, 130, 180, 0, UpdateGlowTex, NULL, NULL);
587 CGameMenuItemZBool itemOptionsDisplayPolymost3DModels("3D MODELS:", 3, 66, 140, 180, 0, Update3DModels, NULL, NULL);
588 CGameMenuItemZBool itemOptionsDisplayPolymostDeliriumBlur("DELIRIUM EFFECT BLUR:", 3, 66, 150, 180, 0, UpdateDeliriumBlur, NULL, NULL);
589 #endif
590 
591 void UpdateSoundToggle(CGameMenuItemZBool *pItem);
592 void UpdateMusicToggle(CGameMenuItemZBool *pItem);
593 void Update3DToggle(CGameMenuItemZBool *pItem);
594 void UpdateCDToggle(CGameMenuItemZBool *pItem);
595 void UpdateSoundVolume(CGameMenuItemSlider *pItem);
596 void UpdateMusicVolume(CGameMenuItemSlider *pItem);
597 void UpdateSoundRate(CGameMenuItemZCycle *pItem);
598 void UpdateNumVoices(CGameMenuItemSlider *pItem);
599 void UpdateMusicDevice(CGameMenuItemZCycle *pItem);
600 void SetSound(CGameMenuItemChain *pItem);
601 void PreDrawSound(CGameMenuItem *pItem);
602 const char *pzSoundRateStrings[] = {
603     "22050HZ",
604     "44100HZ",
605     "48000HZ"
606 };
607 
608 int nSoundRateValues[] = {
609     22050,
610     44100,
611     48000
612 };
613 
614 int nMusicDeviceValues[] = {
615     ASS_OPL3,
616 #ifdef _WIN32
617     ASS_WinMM,
618 #endif
619     ASS_SF2,
620 };
621 
622 const char *pzMusicDeviceStrings[] = {
623     "OPL3(SB/ADLIB)",
624 #ifdef _WIN32
625     "SYSTEM MIDI",
626 #endif
627     ".SF2 SYNTH",
628 };
629 static char sf2bankfile[BMAX_PATH];
630 
631 CGameMenu menuOptionsSoundSF2;
632 
633 CGameMenuItemTitle itemOptionsSoundSF2Title("SELECT SF2 BANK", 1, 160, 20, 2038);
634 CGameMenuFileSelect itemOptionsSoundSF2FS("", 3, 0, 0, 0, "./", "*.sf2", sf2bankfile);
635 
636 CGameMenuItemTitle itemOptionsSoundTitle("SOUND SETUP", 1, 160, 20, 2038);
637 CGameMenuItemZBool itemOptionsSoundSoundToggle("SOUND:", 3, 66, 60, 180, false, UpdateSoundToggle, NULL, NULL);
638 CGameMenuItemZBool itemOptionsSoundMusicToggle("MUSIC:", 3, 66, 70, 180, false, UpdateMusicToggle, NULL, NULL);
639 CGameMenuItemZBool itemOptionsSound3DToggle("3D AUDIO:", 3, 66, 80, 180, false, Update3DToggle, NULL, NULL);
640 CGameMenuItemSlider itemOptionsSoundSoundVolume("SOUND VOLUME:", 3, 66, 90, 180, &FXVolume, 0, 256, 48, UpdateSoundVolume, -1, -1, kMenuSliderPercent);
641 CGameMenuItemSlider itemOptionsSoundMusicVolume("MUSIC VOLUME:", 3, 66, 100, 180, &MusicVolume, 0, 256, 48, UpdateMusicVolume, -1, -1, kMenuSliderPercent);
642 CGameMenuItemZCycle itemOptionsSoundSampleRate("SAMPLE RATE:", 3, 66, 110, 180, 0, UpdateSoundRate, pzSoundRateStrings, 3, 0);
643 CGameMenuItemSlider itemOptionsSoundNumVoices("VOICES:", 3, 66, 120, 180, NumVoices, 16, 256, 16, UpdateNumVoices, -1, -1, kMenuSliderValue);
644 CGameMenuItemZBool itemOptionsSoundCDToggle("REDBOOK AUDIO:", 3, 66, 130, 180, false, UpdateCDToggle, NULL, NULL);
645 CGameMenuItemZCycle itemOptionsSoundMusicDevice("MIDI DRIVER:", 3, 66, 140, 180, 0, UpdateMusicDevice, pzMusicDeviceStrings, ARRAY_SIZE(pzMusicDeviceStrings), 0);
646 CGameMenuItemChain itemOptionsSoundSF2Bank("SF2 BANK", 3, 66, 150, 180, 0, &menuOptionsSoundSF2, 0, NULL, 0);
647 CGameMenuItemChain itemOptionsSoundApplyChanges("APPLY CHANGES", 3, 66, 160, 180, 0, NULL, 0, SetSound, 0);
648 
649 
650 void UpdatePlayerName(CGameMenuItemZEdit *pItem, CGameMenuEvent *pEvent);
651 
652 CGameMenuItemTitle itemOptionsPlayerTitle("PLAYER SETUP", 1, 160, 20, 2038);
653 CGameMenuItemZEdit itemOptionsPlayerName("PLAYER NAME:", 3, 66, 60, 180, szPlayerName, MAXPLAYERNAME, 0, UpdatePlayerName, 0);
654 
655 CGameMenu menuOptionsControlKeyboard;
656 CGameMenu menuOptionsControlMouse;
657 CGameMenu menuOptionsControlMouseButtonAssignment;
658 
659 void SetupMouseMenu(CGameMenuItemChain *pItem);
660 
661 CGameMenuItemTitle itemOptionsControlTitle("CONTROL SETUP", 1, 160, 20, 2038);
662 CGameMenuItemChain itemOptionsControlKeyboard("KEYBOARD SETUP", 1, 0, 60, 320, 1, &menuOptionsControlKeyboard, -1, NULL, 0);
663 CGameMenuItemChain itemOptionsControlMouse("MOUSE SETUP", 1, 0, 80, 320, 1, &menuOptionsControlMouse, -1, SetupMouseMenu, 0);
664 
665 CGameMenuItemTitle itemOptionsControlKeyboardTitle("KEYBOARD SETUP", 1, 160, 20, 2038);
666 CGameMenuItemChain itemOptionsControlKeyboardList("Configure Keys...", 1, 0, 60, 320, 1, &menuKeys, -1, NULL, 0);
667 CGameMenuItemChain itemOptionsControlKeyboardReset("Reset Keys (default)...", 1, 0, 80, 320, 1, &menuKeys, -1, ResetKeys, 0);
668 CGameMenuItemChain itemOptionsControlKeyboardResetClassic("Reset Keys (classic)...", 1, 0, 100, 320, 1, &menuKeys, -1, ResetKeysClassic, 0);
669 
670 void SetMouseAimMode(CGameMenuItemZBool *pItem);
671 void SetMouseVerticalAim(CGameMenuItemZBool *pItem);
672 void SetMouseXScale(CGameMenuItemSlider *pItem);
673 void SetMouseYScale(CGameMenuItemSlider *pItem);
674 
675 void PreDrawControlMouse(CGameMenuItem *pItem);
676 
677 void SetupMouseButtonMenu(CGameMenuItemChain *pItem);
678 
679 CGameMenuItemTitle itemOptionsControlMouseTitle("MOUSE SETUP", 1, 160, 20, 2038);
680 CGameMenuItemChain itemOptionsControlMouseButton("BUTTON ASSIGNMENT", 3, 66, 60, 180, 0, &menuOptionsControlMouseButtonAssignment, 0, SetupMouseButtonMenu, 0);
681 CGameMenuItemSliderFloat itemOptionsControlMouseSensitivity("SENSITIVITY:", 3, 66, 70, 180, &CONTROL_MouseSensitivity, 0.5f, 16.f, 0.5f, SetMouseSensitivity, -1, -1, kMenuSliderValue);
682 CGameMenuItemZBool itemOptionsControlMouseAimFlipped("INVERT AIMING:", 3, 66, 80, 180, false, SetMouseAimFlipped, NULL, NULL);
683 CGameMenuItemZBool itemOptionsControlMouseAimMode("AIMING TYPE:", 3, 66, 90, 180, false, SetMouseAimMode, "HOLD", "TOGGLE");
684 CGameMenuItemZBool itemOptionsControlMouseVerticalAim("VERTICAL AIMING:", 3, 66, 100, 180, false, SetMouseVerticalAim, NULL, NULL);
685 CGameMenuItemSlider itemOptionsControlMouseXScale("X-SCALE:", 3, 66, 110, 180, 0, 0, 65536, 1024, SetMouseXScale, -1, -1, kMenuSliderQ16);
686 CGameMenuItemSlider itemOptionsControlMouseYScale("Y-SCALE:", 3, 66, 120, 180, 0, 0, 65536, 1024, SetMouseYScale, -1, -1, kMenuSliderQ16);
687 
688 void SetupNetworkMenu(void);
689 void SetupNetworkHostMenu(CGameMenuItemChain *pItem);
690 void SetupNetworkJoinMenu(CGameMenuItemChain *pItem);
691 void NetworkHostGame(CGameMenuItemChain *pItem);
692 void NetworkJoinGame(CGameMenuItemChain *pItem);
693 
694 char zNetAddressBuffer[16] = "localhost";
695 char zNetPortBuffer[6];
696 
697 CGameMenuItemTitle itemNetworkTitle("MULTIPLAYER", 1, 160, 20, 2038);
698 CGameMenuItemChain itemNetworkHost("HOST A GAME", 1, 0, 80, 320, 1, &menuNetworkHost, -1, SetupNetworkHostMenu, 0);
699 CGameMenuItemChain itemNetworkJoin("JOIN A GAME", 1, 0, 100, 320, 1, &menuNetworkJoin, -1, SetupNetworkJoinMenu, 0);
700 
701 CGameMenuItemTitle itemNetworkHostTitle("HOST A GAME", 1, 160, 20, 2038);
702 CGameMenuItemSlider itemNetworkHostPlayerNum("PLAYER NUMBER:", 3, 66, 70, 180, 1, 2, kMaxPlayers, 1, NULL, -1, -1, kMenuSliderValue);
703 CGameMenuItemZEdit itemNetworkHostPort("NETWORK PORT:", 3, 66, 80, 180, zNetPortBuffer, 6, 0, NULL, 0);
704 CGameMenuItemChain itemNetworkHostHost("HOST A GAME", 3, 66, 100, 180, 1, NULL, -1, NetworkHostGame, 0);
705 
706 CGameMenuItemTitle itemNetworkJoinTitle("JOIN A GAME", 1, 160, 20, 2038);
707 CGameMenuItemZEdit itemNetworkJoinAddress("NETWORK ADDRESS:", 3, 66, 70, 180, zNetAddressBuffer, 16, 0, NULL, 0);
708 CGameMenuItemZEdit itemNetworkJoinPort("NETWORK PORT:", 3, 66, 80, 180, zNetPortBuffer, 6, 0, NULL, 0);
709 CGameMenuItemChain itemNetworkJoinJoin("JOIN A GAME", 3, 66, 100, 180, 1, NULL, -1, NetworkJoinGame, 0);
710 
711 // There is no better way to do this than manually.
712 
713 #define MENUMOUSEFUNCTIONS 12
714 
715 static char const *MenuMouseNames[MENUMOUSEFUNCTIONS] = {
716     "Button 1",
717     "Double Button 1",
718     "Button 2",
719     "Double Button 2",
720     "Button 3",
721     "Double Button 3",
722 
723     "Wheel Up",
724     "Wheel Down",
725 
726     "Button 4",
727     "Double Button 4",
728     "Button 5",
729     "Double Button 5",
730 };
731 
732 static int32_t MenuMouseDataIndex[MENUMOUSEFUNCTIONS][2] = {
733     { 0, 0, },
734     { 0, 1, },
735     { 1, 0, },
736     { 1, 1, },
737     { 2, 0, },
738     { 2, 1, },
739 
740     // note the mouse wheel
741     { 4, 0, },
742     { 5, 0, },
743 
744     { 3, 0, },
745     { 3, 1, },
746     { 6, 0, },
747     { 6, 1, },
748 };
749 
750 void SetMouseButton(CGameMenuItemZCycle *pItem);
751 
752 CGameMenuItemZCycle *pItemOptionsControlMouseButton[MENUMOUSEFUNCTIONS];
753 
SetupLoadingScreen(void)754 void SetupLoadingScreen(void)
755 {
756     menuLoading.Add(&itemLoadingText, true);
757 }
758 
SetupKeyListMenu(void)759 void SetupKeyListMenu(void)
760 {
761     menuKeys.Add(&itemKeysTitle, false);
762     menuKeys.Add(&itemKeyList, true);
763     menuKeys.Add(&itemBloodQAV, false);
764 }
765 
SetupMessagesMenu(void)766 void SetupMessagesMenu(void)
767 {
768     menuMessages.Add(&itemMessagesTitle, false);
769     menuMessages.Add(&boolMessages, true);
770     menuMessages.Add(&sliderMsgCount, false);
771     menuMessages.Add(&sliderMsgTime, false);
772     menuMessages.Add(&boolMsgFont, false);
773     menuMessages.Add(&boolMsgIncoming, false);
774     menuMessages.Add(&boolMsgSelf, false);
775     menuMessages.Add(&boolMsgOther, false);
776     menuMessages.Add(&boolMsgRespawn, false);
777     menuMessages.Add(&itemBloodQAV, false);
778 }
779 
SetupControlsMenu(void)780 void SetupControlsMenu(void)
781 {
782     sliderMouseSpeed.fValue = ClipRangeF(CONTROL_MouseSensitivity, sliderMouseSpeed.fRangeLow, sliderMouseSpeed.fRangeHigh);
783     sliderTurnSpeed.nValue = ClipRange(gTurnSpeed, sliderTurnSpeed.nRangeLow, sliderTurnSpeed.nRangeHigh);
784     boolMouseFlipped.at20 = gMouseAimingFlipped;
785     menuControls.Add(&itemControlsTitle, false);
786     menuControls.Add(&sliderMouseSpeed, true);
787     menuControls.Add(&boolMouseFlipped, false);
788     menuControls.Add(&sliderTurnSpeed, false);
789     menuControls.Add(&itemChainKeyList, false);
790     menuControls.Add(&itemChainKeyReset, false);
791     menuControls.Add(&itemChainKeyResetClassic, false);
792     menuControls.Add(&itemBloodQAV, false);
793 }
794 
SetupOptionsOldMenu(void)795 void SetupOptionsOldMenu(void)
796 {
797     sliderDetail.nValue = ClipRange(gDetail, sliderDetail.nRangeLow, sliderDetail.nRangeHigh);
798     sliderGamma.nValue = ClipRange(gGamma, sliderGamma.nRangeLow, sliderGamma.nRangeHigh);
799     sliderMusic.nValue = ClipRange(MusicVolume, sliderMusic.nRangeLow, sliderMusic.nRangeHigh);
800     sliderSound.nValue = ClipRange(FXVolume, sliderSound.nRangeLow, sliderSound.nRangeHigh);
801     bool3DAudio.at20 = gDoppler;
802     boolCrosshair.at20 = gAimReticle;
803     itemCycleShowWeapons.m_nFocus = gShowWeapon;
804     boolSlopeTilting.at20 = gSlopeTilting;
805     boolViewBobbing.at20 = gViewVBobbing;
806     boolViewSwaying.at20 = gViewHBobbing;
807     boolMessages.at20 = gGameMessageMgr.state;
808     menuOptionsOld.Add(&itemOptionsTitle, false);
809     menuOptionsOld.Add(&itemOption1, true);
810     menuOptionsOld.Add(&sliderDetail, false);
811     menuOptionsOld.Add(&sliderGamma, false);
812     menuOptionsOld.Add(&sliderMusic, false);
813     menuOptionsOld.Add(&sliderSound, false);
814     menuOptionsOld.Add(&sliderCDAudio, false);
815     menuOptionsOld.Add(&bool3DAudio, false);
816     menuOptionsOld.Add(&boolCrosshair, false);
817     menuOptionsOld.Add(&itemCycleShowWeapons, false);
818     menuOptionsOld.Add(&boolSlopeTilting, false);
819     menuOptionsOld.Add(&boolViewBobbing, false);
820     menuOptionsOld.Add(&boolViewSwaying, false);
821     menuOptionsOld.Add(&itemOption2, false);
822     menuOptionsOld.Add(&itemChainParentalLock, false);
823     menuOptionsOld.Add(&itemBloodQAV, false);
824 }
825 
SetupDifficultyMenu(void)826 void SetupDifficultyMenu(void)
827 {
828     menuDifficulty.Add(&itemDifficultyTitle, false);
829     menuDifficulty.Add(&itemDifficulty1, false);
830     menuDifficulty.Add(&itemDifficulty2, false);
831     menuDifficulty.Add(&itemDifficulty3, true);
832     menuDifficulty.Add(&itemDifficulty4, false);
833     menuDifficulty.Add(&itemDifficulty5, false);
834     menuDifficulty.Add(&itemBloodQAV, false);
835 }
836 
SetupEpisodeMenu(void)837 void SetupEpisodeMenu(void)
838 {
839     menuEpisode.Add(&itemEpisodesTitle, false);
840     int height;
841     gMenuTextMgr.GetFontInfo(1, NULL, NULL, &height);
842     int j = 0;
843     for (int i = 0; i < gEpisodeCount; i++)
844     {
845         EPISODEINFO *pEpisode = &gEpisodeInfo[i];
846         if (!pEpisode->bloodbath || gGameOptions.nGameType != 0)
847         {
848             CGameMenuItemChain7F2F0 *pEpisodeItem = &itemEpisodes[j];
849             pEpisodeItem->m_nFont = 1;
850             pEpisodeItem->m_nX = 0;
851             pEpisodeItem->m_nWidth = 320;
852             pEpisodeItem->at20 = 1;
853             pEpisodeItem->m_pzText = pEpisode->title;
854             pEpisodeItem->m_nY = 55+(height+8)*j;
855             pEpisodeItem->at34 = i;
856             pEpisodeItem = &itemEpisodes[j];
857             pEpisodeItem->at24 = &menuDifficulty;
858             pEpisodeItem->at28 = 3;
859             pEpisodeItem = &itemEpisodes[j];
860             pEpisodeItem->bCanSelect = 1;
861             pEpisodeItem->bEnable = 1;
862             bool first = j == 0;
863             menuEpisode.Add(&itemEpisodes[j], first);
864             if (first)
865                 SetupLevelMenuItem(j);
866             j++;
867         }
868     }
869 
870     itemUserMap.m_nY = 55+(height+8)*j;
871     menuEpisode.Add(&itemUserMap, false);
872     menuEpisode.Add(&itemBloodQAV, false);
873 
874     menuUserMap.Add(&itemUserMapTitle, true);
875     menuUserMap.Add(&itemUserMapList, true);
876 }
877 
SetupMainMenu(void)878 void SetupMainMenu(void)
879 {
880     menuMain.Add(&itemMainTitle, false);
881     menuMain.Add(&itemMain1, true);
882     if (gGameOptions.nGameType > 0)
883     {
884         itemMain1.at24 = &menuNetStart;
885         itemMain1.at28 = 2;
886     }
887     else
888     {
889         itemMain1.at24 = &menuEpisode;
890         itemMain1.at28 = -1;
891     }
892     menuMain.Add(&itemMain2, false);
893     menuMain.Add(&itemMain3, false);
894     menuMain.Add(&itemMain4, false);
895     menuMain.Add(&itemMain5, false);
896     menuMain.Add(&itemMain6, false);
897     menuMain.Add(&itemMain7, false);
898     menuMain.Add(&itemBloodQAV, false);
899 }
900 
SetupMainMenuWithSave(void)901 void SetupMainMenuWithSave(void)
902 {
903     menuMainWithSave.Add(&itemMainSaveTitle, false);
904     menuMainWithSave.Add(&itemMainSave1, true);
905     if (gGameOptions.nGameType > 0)
906     {
907         itemMainSave1.at24 = &menuNetStart;
908         itemMainSave1.at28 = 2;
909     }
910     else
911     {
912         itemMainSave1.at24 = &menuEpisode;
913         itemMainSave1.at28 = -1;
914     }
915     menuMainWithSave.Add(&itemMainSave2, false);
916     menuMainWithSave.Add(&itemMainSave3, false);
917     menuMainWithSave.Add(&itemMainSave4, false);
918     menuMainWithSave.Add(&itemMainSave5, false);
919     menuMainWithSave.Add(&itemMainSave6, false);
920     menuMainWithSave.Add(&itemMainSave7, false);
921     menuMainWithSave.Add(&itemMainSave8, false);
922     menuMainWithSave.Add(&itemBloodQAV, false);
923 }
924 
SetupNetStartMenu(void)925 void SetupNetStartMenu(void)
926 {
927     bool oneEpisode = false;
928     menuNetStart.Add(&itemNetStartTitle, false);
929     menuNetStart.Add(&itemNetStart1, false);
930     for (int i = 0; i < (oneEpisode ? 1 : 6); i++)
931     {
932         EPISODEINFO *pEpisode = &gEpisodeInfo[i];
933         if (i < gEpisodeCount)
934             itemNetStart2.Add(pEpisode->title, i == 0);
935     }
936     menuNetStart.Add(&itemNetStart2, false);
937     menuNetStart.Add(&itemNetStart3, false);
938     menuNetStart.Add(&itemNetStart4, false);
939     menuNetStart.Add(&itemNetStart5, false);
940     menuNetStart.Add(&itemNetStart6, false);
941     menuNetStart.Add(&itemNetStart7, false);
942     menuNetStart.Add(&itemNetStart8, false);
943     menuNetStart.Add(&itemNetStart9, false);
944     menuNetStart.Add(&itemNetStart10, false);
945     menuNetStart.Add(&itemNetStart11, false);
946     menuNetStart.Add(&itemNetStart12, false);
947     menuMultiUserMaps.Add(&itemNetStartUserMapTitle, true);
948     menuMultiUserMaps.Add(&menuMultiUserMap, true);
949     itemNetStart1.SetTextIndex(1);
950     itemNetStart4.SetTextIndex(2);
951     itemNetStart5.SetTextIndex(0);
952     itemNetStart6.SetTextIndex(1);
953     itemNetStart7.SetTextIndex(1);
954     menuNetStart.Add(&itemBloodQAV, false);
955 }
956 
SetupSaveGameMenu(void)957 void SetupSaveGameMenu(void)
958 {
959     menuSaveGame.Add(&itemSaveTitle, false);
960     menuSaveGame.Add(&itemSaveGame1, true);
961     menuSaveGame.Add(&itemSaveGame2, false);
962     menuSaveGame.Add(&itemSaveGame3, false);
963     menuSaveGame.Add(&itemSaveGame4, false);
964     menuSaveGame.Add(&itemSaveGame5, false);
965     menuSaveGame.Add(&itemSaveGame6, false);
966     menuSaveGame.Add(&itemSaveGame7, false);
967     menuSaveGame.Add(&itemSaveGame8, false);
968     menuSaveGame.Add(&itemSaveGame9, false);
969     menuSaveGame.Add(&itemSaveGame10, false);
970     menuSaveGame.Add(&itemSaveGamePic, false);
971     menuSaveGame.Add(&itemBloodQAV, false);
972 
973     itemSaveGame1.at2c = &itemSaveGamePic;
974     if (!strcmp(strRestoreGameStrings[0], "<Empty>"))
975         itemSaveGame1.at37 = 1;
976 
977     itemSaveGame2.at2c = &itemSaveGamePic;
978     if (!strcmp(strRestoreGameStrings[1], "<Empty>"))
979         itemSaveGame2.at37 = 1;
980 
981     itemSaveGame3.at2c = &itemSaveGamePic;
982     if (!strcmp(strRestoreGameStrings[2], "<Empty>"))
983         itemSaveGame3.at37 = 1;
984 
985     itemSaveGame4.at2c = &itemSaveGamePic;
986     if (!strcmp(strRestoreGameStrings[3], "<Empty>"))
987         itemSaveGame4.at37 = 1;
988 
989     itemSaveGame5.at2c = &itemSaveGamePic;
990     if (!strcmp(strRestoreGameStrings[4], "<Empty>"))
991         itemSaveGame5.at37 = 1;
992 
993     itemSaveGame6.at2c = &itemSaveGamePic;
994     if (!strcmp(strRestoreGameStrings[5], "<Empty>"))
995         itemSaveGame6.at37 = 1;
996 
997     itemSaveGame7.at2c = &itemSaveGamePic;
998     if (!strcmp(strRestoreGameStrings[6], "<Empty>"))
999         itemSaveGame7.at37 = 1;
1000 
1001     itemSaveGame8.at2c = &itemSaveGamePic;
1002     if (!strcmp(strRestoreGameStrings[7], "<Empty>"))
1003         itemSaveGame8.at37 = 1;
1004 
1005     itemSaveGame9.at2c = &itemSaveGamePic;
1006     if (!strcmp(strRestoreGameStrings[8], "<Empty>"))
1007         itemSaveGame9.at37 = 1;
1008 
1009     itemSaveGame10.at2c = &itemSaveGamePic;
1010     if (!strcmp(strRestoreGameStrings[9], "<Empty>"))
1011         itemSaveGame10.at37 = 1;
1012 }
1013 
SetupLoadGameMenu(void)1014 void SetupLoadGameMenu(void)
1015 {
1016     menuLoadGame.Add(&itemLoadTitle, false);
1017     menuLoadGame.Add(&itemLoadGame1, true);
1018     menuLoadGame.Add(&itemLoadGame2, false);
1019     menuLoadGame.Add(&itemLoadGame3, false);
1020     menuLoadGame.Add(&itemLoadGame4, false);
1021     menuLoadGame.Add(&itemLoadGame5, false);
1022     menuLoadGame.Add(&itemLoadGame6, false);
1023     menuLoadGame.Add(&itemLoadGame7, false);
1024     menuLoadGame.Add(&itemLoadGame8, false);
1025     menuLoadGame.Add(&itemLoadGame9, false);
1026     menuLoadGame.Add(&itemLoadGame10, false);
1027     menuLoadGame.Add(&itemLoadGamePic, false);
1028     itemLoadGame1.at35 = 0;
1029     itemLoadGame2.at35 = 0;
1030     itemLoadGame3.at35 = 0;
1031     itemLoadGame4.at35 = 0;
1032     itemLoadGame5.at35 = 0;
1033     itemLoadGame6.at35 = 0;
1034     itemLoadGame7.at35 = 0;
1035     itemLoadGame8.at35 = 0;
1036     itemLoadGame9.at35 = 0;
1037     itemLoadGame10.at35 = 0;
1038     itemLoadGame1.at2c = &itemLoadGamePic;
1039     itemLoadGame2.at2c = &itemLoadGamePic;
1040     itemLoadGame3.at2c = &itemLoadGamePic;
1041     itemLoadGame4.at2c = &itemLoadGamePic;
1042     itemLoadGame5.at2c = &itemLoadGamePic;
1043     itemLoadGame6.at2c = &itemLoadGamePic;
1044     itemLoadGame7.at2c = &itemLoadGamePic;
1045     itemLoadGame8.at2c = &itemLoadGamePic;
1046     itemLoadGame9.at2c = &itemLoadGamePic;
1047     itemLoadGame10.at2c = &itemLoadGamePic;
1048     menuLoadGame.Add(&itemBloodQAV, false);
1049 }
1050 
SetupSoundsMenu(void)1051 void SetupSoundsMenu(void)
1052 {
1053     itemSoundsMusic.nValue = ClipRange(MusicVolume, itemSoundsMusic.nRangeLow, itemSoundsMusic.nRangeHigh);
1054     itemSoundsSound.nValue = ClipRange(FXVolume, itemSoundsSound.nRangeLow, itemSoundsSound.nRangeHigh);
1055     menuSounds.Add(&itemSoundsTitle, false);
1056     menuSounds.Add(&itemSoundsMusic, true);
1057     menuSounds.Add(&itemSoundsSound, false);
1058     menuSounds.Add(&itemSoundsCDAudio, false);
1059     menuSounds.Add(&itemSounds3DAudio, false);
1060     menuSounds.Add(&itemBloodQAV, false);
1061 }
1062 
SetupQuitMenu(void)1063 void SetupQuitMenu(void)
1064 {
1065     menuQuit.Add(&itemQuitTitle, false);
1066     menuQuit.Add(&itemQuitText1, false);
1067     menuQuit.Add(&itemQuitYesNo, true);
1068     menuQuit.Add(&itemBloodQAV, false);
1069 
1070     menuRestart.Add(&itemRestartTitle, false);
1071     menuRestart.Add(&itemRestartText1, false);
1072     menuRestart.Add(&itemRestartYesNo, true);
1073     menuRestart.Add(&itemBloodQAV, false);
1074 }
1075 
SetupHelpOrderMenu(void)1076 void SetupHelpOrderMenu(void)
1077 {
1078     menuOrder.Add(&itemHelp4QAV, true);
1079     menuOrder.Add(&itemHelp5QAV, false);
1080     menuOrder.Add(&itemHelp3QAV, false);
1081     menuOrder.Add(&itemHelp3BQAV, false);
1082     itemHelp4QAV.bEnable = 1;
1083     itemHelp4QAV.bNoDraw = 1;
1084     itemHelp5QAV.bEnable = 1;
1085     itemHelp5QAV.bNoDraw = 1;
1086     itemHelp3QAV.bEnable = 1;
1087     itemHelp3QAV.bNoDraw = 1;
1088     itemHelp3BQAV.bEnable = 1;
1089     itemHelp3BQAV.bNoDraw = 1;
1090 }
1091 
SetupCreditsMenu(void)1092 void SetupCreditsMenu(void)
1093 {
1094     menuCredits.Add(&itemCreditsQAV, true);
1095     itemCreditsQAV.bEnable = 1;
1096     itemCreditsQAV.bNoDraw = 1;
1097 }
1098 
SetupParentalLockMenu(void)1099 void SetupParentalLockMenu(void)
1100 {
1101     itemParentalLockToggle.at20 = gbAdultContent;
1102     strcpy(itemParentalLockPassword.at20, gzAdultPassword);
1103     menuParentalLock.Add(&itemParentalLockTitle, false);
1104     menuParentalLock.Add(&itemParentalLockToggle, true);
1105     menuParentalLock.Add(&itemParentalLockPassword, false);
1106     menuParentalLock.Add(&itemBloodQAV, false);
1107 }
1108 
SetupSorry3Menu(void)1109 void SetupSorry3Menu(void)
1110 {
1111     menuPlayOnline.Add(&unk_26E06C, false);
1112     menuPlayOnline.Add(&unk_26E090, true);
1113     menuPlayOnline.Add(&unk_26E0E8, false);
1114     menuPlayOnline.Add(&unk_26E140, false);
1115     menuPlayOnline.Add(&unk_26E198, false);
1116     menuPlayOnline.Add(&unk_26E1F0, false);
1117     menuPlayOnline.Add(&unk_26E248, false);
1118     menuPlayOnline.Add(&itemBloodQAV, false);
1119 }
1120 
SetupSorryMenu(void)1121 void SetupSorryMenu(void)
1122 {
1123     menuSorry.Add(&itemSorryPicCycle, true);
1124     menuSorry.Add(&itemSorryText1, false);
1125     menuSorry.Add(&itemSorryText3, false);
1126     menuSorry.Add(&itemBloodQAV, false);
1127 }
1128 
SetupSorry2Menu(void)1129 void SetupSorry2Menu(void)
1130 {
1131     menuSorry2.Add(&itemSorryPicCycle, true);
1132     menuSorry2.Add(&itemSorry2Text1, false);
1133     menuSorry2.Add(&itemSorry2Text2, false);
1134     menuSorry2.Add(&itemSorry2Text3, false);
1135     menuSorry2.Add(&itemBloodQAV, false);
1136 }
1137 
SetupOptionsMenu(void)1138 void SetupOptionsMenu(void)
1139 {
1140     menuOptions.Add(&itemOptionsTitle, false);
1141     menuOptions.Add(&itemOptionsChainGame, true);
1142     menuOptions.Add(&itemOptionsChainDisplay, false);
1143     menuOptions.Add(&itemOptionsChainSound, false);
1144     menuOptions.Add(&itemOptionsChainPlayer, false);
1145     menuOptions.Add(&itemOptionsChainControl, false);
1146     //menuOptions.Add(&itemOptionsChainOld, false);
1147     menuOptions.Add(&itemBloodQAV, false);
1148 
1149     menuOptionsGame.Add(&itemOptionsGameTitle, false);
1150     menuOptionsGame.Add(&itemOptionsGameBoolShowPlayerNames, true);
1151     menuOptionsGame.Add(&itemOptionsGameShowWeapons, false);
1152     menuOptionsGame.Add(&itemOptionsGameBoolSlopeTilting, false);
1153     menuOptionsGame.Add(&itemOptionsGameBoolViewBobbing, false);
1154     menuOptionsGame.Add(&itemOptionsGameBoolViewSwaying, false);
1155     menuOptionsGame.Add(&itemOptionsGameBoolAutoAim, false);
1156     menuOptionsGame.Add(&itemOptionsGameWeaponSwitch, false);
1157 
1158     //////////////////////
1159     if (gGameOptions.nGameType == 0) {
1160         menuOptionsGame.Add(&itemOptionsGameBoolWeaponsV10X, false);
1161     }
1162     /////////////////////
1163 
1164     //menuOptionsGame.Add(&itemOptionsGameChainParentalLock, false);
1165     menuOptionsGame.Add(&itemBloodQAV, false);
1166     itemOptionsGameBoolShowPlayerNames.at20 = gShowPlayerNames;
1167     itemOptionsGameShowWeapons.m_nFocus = gShowWeapon;
1168     itemOptionsGameBoolSlopeTilting.at20 = gSlopeTilting;
1169     itemOptionsGameBoolViewBobbing.at20 = gViewVBobbing;
1170     itemOptionsGameBoolViewSwaying.at20 = gViewHBobbing;
1171     itemOptionsGameBoolAutoAim.m_nFocus = gAutoAim;
1172     itemOptionsGameWeaponSwitch.m_nFocus = (gWeaponSwitch&1) ? ((gWeaponSwitch&2) ? 1 : 2) : 0;
1173 
1174     ///////
1175     itemOptionsGameBoolWeaponsV10X.at20 = gWeaponsV10x;
1176     ///////
1177 
1178     menuOptionsDisplay.Add(&itemOptionsDisplayTitle, false);
1179     menuOptionsDisplay.Add(&itemOptionsDisplayColor, true);
1180     menuOptionsDisplay.Add(&itemOptionsDisplayMode, false);
1181     menuOptionsDisplay.Add(&itemOptionsDisplayBoolCrosshair, false);
1182     menuOptionsDisplay.Add(&itemOptionsDisplayBoolCenterHoriz, false);
1183     menuOptionsDisplay.Add(&itemOptionsDisplayBoolLevelStats, false);
1184     menuOptionsDisplay.Add(&itemOptionsDisplayBoolPowerupDuration, false);
1185     menuOptionsDisplay.Add(&itemOptionsDisplayBoolShowMapTitle, false);
1186     menuOptionsDisplay.Add(&itemOptionsDisplayBoolMessages, false);
1187     menuOptionsDisplay.Add(&itemOptionsDisplayBoolWidescreen, false);
1188     menuOptionsDisplay.Add(&itemOptionsDisplayFOV, false);
1189 #ifdef USE_OPENGL
1190     menuOptionsDisplay.Add(&itemOptionsDisplayPolymost, false);
1191 #endif
1192     menuOptionsDisplay.Add(&itemBloodQAV, false);
1193     itemOptionsDisplayBoolCrosshair.at20 = gAimReticle;
1194     itemOptionsDisplayBoolCenterHoriz.at20 = gCenterHoriz;
1195     itemOptionsDisplayBoolLevelStats.at20 = gLevelStats;
1196     itemOptionsDisplayBoolPowerupDuration.at20 = gPowerupDuration;
1197     itemOptionsDisplayBoolShowMapTitle.at20 = gShowMapTitle;
1198     itemOptionsDisplayBoolMessages.at20 = gMessageState;
1199     itemOptionsDisplayBoolWidescreen.at20 = r_usenewaspect;
1200 
1201     menuOptionsDisplayMode.Add(&itemOptionsDisplayModeTitle, false);
1202     menuOptionsDisplayMode.Add(&itemOptionsDisplayModeResolution, true);
1203     // prepare video setup
1204     for (int i = 0; i < validmodecnt; ++i)
1205     {
1206         int j;
1207         for (j = 0; j < gResolutionNum; ++j)
1208         {
1209             if (validmode[i].xdim == gResolution[j].xdim && validmode[i].ydim == gResolution[j].ydim)
1210             {
1211                 gResolution[j].flags |= validmode[i].fs ? RES_FS : RES_WIN;
1212                 Bsnprintf(gResolution[j].name, MAXRESOLUTIONSTRINGLENGTH, "%d x %d%s", gResolution[j].xdim, gResolution[j].ydim, (gResolution[j].flags & RES_FS) ? "" : "Win");
1213                 gResolutionName[j] = gResolution[j].name;
1214                 if (validmode[i].bpp > gResolution[j].bppmax)
1215                     gResolution[j].bppmax = validmode[i].bpp;
1216                 break;
1217             }
1218         }
1219 
1220         if (j == gResolutionNum) // no match found
1221         {
1222             gResolution[j].xdim = validmode[i].xdim;
1223             gResolution[j].ydim = validmode[i].ydim;
1224             gResolution[j].bppmax = validmode[i].bpp;
1225             gResolution[j].flags = validmode[i].fs ? RES_FS : RES_WIN;
1226             Bsnprintf(gResolution[j].name, MAXRESOLUTIONSTRINGLENGTH, "%d x %d%s", gResolution[j].xdim, gResolution[j].ydim, (gResolution[j].flags & RES_FS) ? "" : "Win");
1227             gResolutionName[j] = gResolution[j].name;
1228             ++gResolutionNum;
1229         }
1230     }
1231     itemOptionsDisplayModeResolution.SetTextArray(gResolutionName, gResolutionNum, 0);
1232 #ifdef USE_OPENGL
1233     menuOptionsDisplayMode.Add(&itemOptionsDisplayModeRenderer, false);
1234 #endif
1235     menuOptionsDisplayMode.Add(&itemOptionsDisplayModeFullscreen, false);
1236 #ifdef USE_OPENGL
1237     menuOptionsDisplayMode.Add(&itemOptionsDisplayModeVSync, false);
1238 #endif
1239     menuOptionsDisplayMode.Add(&itemOptionsDisplayModeFrameLimit, false);
1240     menuOptionsDisplayMode.Add(&itemOptionsDisplayModeFPSOffset, false);
1241     menuOptionsDisplayMode.Add(&itemOptionsDisplayModeApply, false);
1242     menuOptionsDisplayMode.Add(&itemBloodQAV, false);
1243 
1244 #ifdef USE_OPENGL
1245     itemOptionsDisplayModeRenderer.pPreDrawCallback = PreDrawVideoModeMenu;
1246 #endif
1247     itemOptionsDisplayModeFullscreen.pPreDrawCallback = PreDrawVideoModeMenu;
1248     itemOptionsDisplayModeFPSOffset.pPreDrawCallback = PreDrawVideoModeMenu;
1249 
1250     menuOptionsDisplayColor.Add(&itemOptionsDisplayColorTitle, false);
1251     menuOptionsDisplayColor.Add(&itemOptionsDisplayColorGamma, true);
1252     menuOptionsDisplayColor.Add(&itemOptionsDisplayColorContrast, false);
1253     menuOptionsDisplayColor.Add(&itemOptionsDisplayColorBrightness, false);
1254     menuOptionsDisplayColor.Add(&itemOptionsDisplayColorVisibility, false);
1255     menuOptionsDisplayColor.Add(&itemOptionsDisplayColorReset, false);
1256     menuOptionsDisplayColor.Add(&itemBloodQAV, false);
1257 
1258     itemOptionsDisplayColorContrast.pPreDrawCallback = PreDrawDisplayColor;
1259     itemOptionsDisplayColorBrightness.pPreDrawCallback = PreDrawDisplayColor;
1260 
1261 #ifdef USE_OPENGL
1262     menuOptionsDisplayPolymost.Add(&itemOptionsDisplayPolymostTitle, false);
1263     //menuOptionsDisplayPolymost.Add(&itemOptionsDisplayPolymostTextureMode, true);
1264     //menuOptionsDisplayPolymost.Add(&itemOptionsDisplayPolymostAnisotropy, false);
1265     menuOptionsDisplayPolymost.Add(&itemOptionsDisplayPolymostTrueColorTextures, true);
1266     menuOptionsDisplayPolymost.Add(&itemOptionsDisplayPolymostTexQuality, false);
1267     menuOptionsDisplayPolymost.Add(&itemOptionsDisplayPolymostPreloadCache, false);
1268     menuOptionsDisplayPolymost.Add(&itemOptionsDisplayPolymostTexCache, false);
1269     menuOptionsDisplayPolymost.Add(&itemOptionsDisplayPolymostDetailTex, false);
1270     menuOptionsDisplayPolymost.Add(&itemOptionsDisplayPolymostGlowTex, false);
1271     menuOptionsDisplayPolymost.Add(&itemOptionsDisplayPolymost3DModels, false);
1272     menuOptionsDisplayPolymost.Add(&itemOptionsDisplayPolymostDeliriumBlur, false);
1273     menuOptionsDisplayPolymost.Add(&itemBloodQAV, false);
1274 
1275     itemOptionsDisplayPolymostTexQuality.pPreDrawCallback = PreDrawDisplayPolymost;
1276     itemOptionsDisplayPolymostPreloadCache.pPreDrawCallback = PreDrawDisplayPolymost;
1277     itemOptionsDisplayPolymostTexCache.pPreDrawCallback = PreDrawDisplayPolymost;
1278     itemOptionsDisplayPolymostDetailTex.pPreDrawCallback = PreDrawDisplayPolymost;
1279     itemOptionsDisplayPolymostGlowTex.pPreDrawCallback = PreDrawDisplayPolymost;
1280 #endif
1281 
1282     menuOptionsSound.Add(&itemOptionsSoundTitle, false);
1283     menuOptionsSound.Add(&itemOptionsSoundSoundToggle, true);
1284     menuOptionsSound.Add(&itemOptionsSoundMusicToggle, false);
1285     menuOptionsSound.Add(&itemOptionsSound3DToggle, false);
1286     menuOptionsSound.Add(&itemOptionsSoundSoundVolume, false);
1287     menuOptionsSound.Add(&itemOptionsSoundMusicVolume, false);
1288     menuOptionsSound.Add(&itemOptionsSoundSampleRate, false);
1289     menuOptionsSound.Add(&itemOptionsSoundNumVoices, false);
1290     menuOptionsSound.Add(&itemOptionsSoundCDToggle, false);
1291     menuOptionsSound.Add(&itemOptionsSoundMusicDevice, false);
1292     menuOptionsSound.Add(&itemOptionsSoundSF2Bank, false);
1293 
1294     menuOptionsSound.Add(&itemOptionsSoundApplyChanges, false);
1295     menuOptionsSound.Add(&itemBloodQAV, false);
1296 
1297     menuOptionsSoundSF2.Add(&itemOptionsSoundSF2Title, true);
1298     menuOptionsSoundSF2.Add(&itemOptionsSoundSF2FS, true);
1299 
1300     menuOptionsPlayer.Add(&itemOptionsPlayerTitle, false);
1301     menuOptionsPlayer.Add(&itemOptionsPlayerName, true);
1302     menuOptionsPlayer.Add(&itemBloodQAV, false);
1303 
1304     menuOptionsControl.Add(&itemOptionsControlTitle, false);
1305     menuOptionsControl.Add(&itemOptionsControlKeyboard, true);
1306     menuOptionsControl.Add(&itemOptionsControlMouse, false);
1307     menuOptionsControl.Add(&itemBloodQAV, false);
1308 
1309     menuOptionsControlKeyboard.Add(&itemOptionsControlKeyboardTitle, false);
1310     menuOptionsControlKeyboard.Add(&itemOptionsControlKeyboardList, true);
1311     menuOptionsControlKeyboard.Add(&itemOptionsControlKeyboardReset, false);
1312     menuOptionsControlKeyboard.Add(&itemOptionsControlKeyboardResetClassic, false);
1313     menuOptionsControlKeyboard.Add(&itemBloodQAV, false);
1314 
1315     menuOptionsControlMouse.Add(&itemOptionsControlMouseTitle, false);
1316     menuOptionsControlMouse.Add(&itemOptionsControlMouseButton, true);
1317     menuOptionsControlMouse.Add(&itemOptionsControlMouseSensitivity, false);
1318     menuOptionsControlMouse.Add(&itemOptionsControlMouseAimFlipped, false);
1319     menuOptionsControlMouse.Add(&itemOptionsControlMouseAimMode, false);
1320     menuOptionsControlMouse.Add(&itemOptionsControlMouseVerticalAim, false);
1321     menuOptionsControlMouse.Add(&itemOptionsControlMouseXScale, false);
1322     menuOptionsControlMouse.Add(&itemOptionsControlMouseYScale, false);
1323     menuOptionsControlMouse.Add(&itemBloodQAV, false);
1324 
1325     itemOptionsControlMouseVerticalAim.pPreDrawCallback = PreDrawControlMouse;
1326 
1327     menuOptionsControlMouseButtonAssignment.Add(&itemOptionsControlMouseTitle, false);
1328     int y = 60;
1329     for (int i = 0; i < MENUMOUSEFUNCTIONS; i++)
1330     {
1331         pItemOptionsControlMouseButton[i] = new CGameMenuItemZCycle(MenuMouseNames[i], 3, 66, y, 180, 0, SetMouseButton, pzGamefuncsStrings, NUMGAMEFUNCTIONS+1, 0, true);
1332         dassert(pItemOptionsControlMouseButton[i] != NULL);
1333         menuOptionsControlMouseButtonAssignment.Add(pItemOptionsControlMouseButton[i], i == 0);
1334         y += 10;
1335     }
1336     menuOptionsControlMouseButtonAssignment.Add(&itemBloodQAV, false);
1337 }
1338 
SetupMenus(void)1339 void SetupMenus(void)
1340 {
1341     // prepare gamefuncs and keys
1342     pzGamefuncsStrings[0] = MenuGameFuncNone;
1343     nGamefuncsValues[0] = -1;
1344     int k = 1;
1345     for (int i = 0; i < NUMGAMEFUNCTIONS; ++i)
1346     {
1347         Bstrcpy(MenuGameFuncs[i], gamefunctions[i]);
1348 
1349         for (int j = 0; j < MAXGAMEFUNCLEN; ++j)
1350             if (MenuGameFuncs[i][j] == '_')
1351                 MenuGameFuncs[i][j] = ' ';
1352 
1353         if (gamefunctions[i][0] != '\0')
1354         {
1355             pzGamefuncsStrings[k] = MenuGameFuncs[i];
1356             nGamefuncsValues[k] = i;
1357             ++k;
1358         }
1359     }
1360 
1361     nGamefuncsNum = k;
1362 
1363     SetupLoadingScreen();
1364     SetupKeyListMenu();
1365     SetupMessagesMenu();
1366     SetupControlsMenu();
1367     SetupSaveGameMenu();
1368     SetupLoadGameMenu();
1369     SetupOptionsOldMenu();
1370     SetupCreditsMenu();
1371     SetupHelpOrderMenu();
1372     SetupSoundsMenu();
1373     SetupDifficultyMenu();
1374     SetupEpisodeMenu();
1375     SetupMainMenu();
1376     SetupMainMenuWithSave();
1377     SetupNetStartMenu();
1378     SetupQuitMenu();
1379     SetupParentalLockMenu();
1380     SetupSorryMenu();
1381     SetupSorry2Menu();
1382     SetupSorry3Menu();
1383 
1384     SetupOptionsMenu();
1385     SetupNetworkMenu();
1386 }
1387 
UpdateNetworkMenus(void)1388 void UpdateNetworkMenus(void)
1389 {
1390     if (gGameOptions.nGameType > 0)
1391     {
1392         itemMain1.at24 = &menuNetStart;
1393         itemMain1.at28 = 2;
1394     }
1395     else
1396     {
1397         itemMain1.at24 = &menuEpisode;
1398         itemMain1.at28 = -1;
1399     }
1400     if (gGameOptions.nGameType > 0)
1401     {
1402         itemMainSave1.at24 = &menuNetStart;
1403         itemMainSave1.at28 = 2;
1404     }
1405     else
1406     {
1407         itemMainSave1.at24 = &menuEpisode;
1408         itemMainSave1.at28 = -1;
1409     }
1410 }
1411 
SetDoppler(CGameMenuItemZBool * pItem)1412 void SetDoppler(CGameMenuItemZBool *pItem)
1413 {
1414     gDoppler = pItem->at20;
1415 }
1416 
SetCrosshair(CGameMenuItemZBool * pItem)1417 void SetCrosshair(CGameMenuItemZBool *pItem)
1418 {
1419     gAimReticle = pItem->at20;
1420 }
1421 
SetCenterHoriz(CGameMenuItemZBool * pItem)1422 void SetCenterHoriz(CGameMenuItemZBool *pItem)
1423 {
1424     gCenterHoriz = pItem->at20;
1425 }
1426 
ResetKeys(CGameMenuItemChain *)1427 void ResetKeys(CGameMenuItemChain *)
1428 {
1429     CONFIG_SetDefaultKeys(keydefaults);
1430 }
1431 
ResetKeysClassic(CGameMenuItemChain *)1432 void ResetKeysClassic(CGameMenuItemChain *)
1433 {
1434     CONFIG_SetDefaultKeys(oldkeydefaults);
1435 }
1436 
1437 ////
SetWeaponsV10X(CGameMenuItemZBool * pItem)1438 void SetWeaponsV10X(CGameMenuItemZBool* pItem)
1439 {
1440     if (gGameOptions.nGameType == 0) {
1441         gWeaponsV10x = pItem->at20;
1442         gGameOptions.weaponsV10x = pItem->at20;
1443     }
1444 }
1445 ////
1446 
SetShowPlayerNames(CGameMenuItemZBool * pItem)1447 void SetShowPlayerNames(CGameMenuItemZBool *pItem)
1448 {
1449     gShowPlayerNames = pItem->at20;
1450 }
1451 
SetShowWeapons(CGameMenuItemZCycle * pItem)1452 void SetShowWeapons(CGameMenuItemZCycle *pItem)
1453 {
1454     gShowWeapon = pItem->m_nFocus;
1455 }
1456 
SetSlopeTilting(CGameMenuItemZBool * pItem)1457 void SetSlopeTilting(CGameMenuItemZBool *pItem)
1458 {
1459     gSlopeTilting = pItem->at20;
1460 }
1461 
SetViewBobbing(CGameMenuItemZBool * pItem)1462 void SetViewBobbing(CGameMenuItemZBool *pItem)
1463 {
1464     gViewVBobbing = pItem->at20;
1465 }
1466 
SetViewSwaying(CGameMenuItemZBool * pItem)1467 void SetViewSwaying(CGameMenuItemZBool *pItem)
1468 {
1469     gViewHBobbing = pItem->at20;
1470 }
1471 
SetDetail(CGameMenuItemSlider * pItem)1472 void SetDetail(CGameMenuItemSlider *pItem)
1473 {
1474     gDetail = pItem->nValue;
1475 }
1476 
SetGamma(CGameMenuItemSlider * pItem)1477 void SetGamma(CGameMenuItemSlider *pItem)
1478 {
1479     gGamma = pItem->nValue;
1480     scrSetGamma(gGamma);
1481 }
1482 
SetMusicVol(CGameMenuItemSlider * pItem)1483 void SetMusicVol(CGameMenuItemSlider *pItem)
1484 {
1485     sndSetMusicVolume(pItem->nValue);
1486 }
1487 
SetSoundVol(CGameMenuItemSlider * pItem)1488 void SetSoundVol(CGameMenuItemSlider *pItem)
1489 {
1490     sndSetFXVolume(pItem->nValue);
1491 }
1492 
SetCDVol(CGameMenuItemSlider * pItem)1493 void SetCDVol(CGameMenuItemSlider *pItem)
1494 {
1495     UNREFERENCED_PARAMETER(pItem);
1496     // NUKE-TODO:
1497 }
1498 
SetMessages(CGameMenuItemZBool * pItem)1499 void SetMessages(CGameMenuItemZBool *pItem)
1500 {
1501     gMessageState = pItem->at20;
1502     gGameMessageMgr.SetState(gMessageState);
1503 }
1504 
SetMouseSensitivity(CGameMenuItemSliderFloat * pItem)1505 void SetMouseSensitivity(CGameMenuItemSliderFloat *pItem)
1506 {
1507 	CONTROL_MouseSensitivity = pItem->fValue;
1508 }
1509 
SetMouseAimFlipped(CGameMenuItemZBool * pItem)1510 void SetMouseAimFlipped(CGameMenuItemZBool *pItem)
1511 {
1512     gMouseAimingFlipped = pItem->at20;
1513 }
1514 
SetTurnSpeed(CGameMenuItemSlider * pItem)1515 void SetTurnSpeed(CGameMenuItemSlider *pItem)
1516 {
1517     gTurnSpeed = pItem->nValue;
1518 }
1519 
SetAutoAim(CGameMenuItemZCycle * pItem)1520 void SetAutoAim(CGameMenuItemZCycle *pItem)
1521 {
1522     gAutoAim = pItem->m_nFocus;
1523     if (!gDemo.at0 && !gDemo.at1)
1524     {
1525         gProfile[myconnectindex].nAutoAim = gAutoAim;
1526         netBroadcastPlayerInfo(myconnectindex);
1527     }
1528 }
1529 
SetLevelStats(CGameMenuItemZBool * pItem)1530 void SetLevelStats(CGameMenuItemZBool *pItem)
1531 {
1532     gLevelStats = pItem->at20;
1533 }
1534 
SetPowerupDuration(CGameMenuItemZBool * pItem)1535 void SetPowerupDuration(CGameMenuItemZBool* pItem)
1536 {
1537     gPowerupDuration = pItem->at20;
1538 }
1539 
SetShowMapTitle(CGameMenuItemZBool * pItem)1540 void SetShowMapTitle(CGameMenuItemZBool* pItem)
1541 {
1542     gShowMapTitle = pItem->at20;
1543 }
1544 
SetWeaponSwitch(CGameMenuItemZCycle * pItem)1545 void SetWeaponSwitch(CGameMenuItemZCycle *pItem)
1546 {
1547     gWeaponSwitch &= ~(1|2);
1548     switch (pItem->m_nFocus)
1549     {
1550     case 0:
1551         break;
1552     case 1:
1553         gWeaponSwitch |= 2;
1554         fallthrough__;
1555     case 2:
1556     default:
1557         gWeaponSwitch |= 1;
1558         break;
1559     }
1560     if (!gDemo.at0 && !gDemo.at1)
1561     {
1562         gProfile[myconnectindex].nWeaponSwitch = gWeaponSwitch;
1563         netBroadcastPlayerInfo(myconnectindex);
1564     }
1565 }
1566 
1567 extern bool gStartNewGame;
1568 
ShowDifficulties()1569 void ShowDifficulties()
1570 {
1571     gGameMenuMgr.Push(&menuDifficulty, 3);
1572 }
1573 
SetDifficultyAndStart(CGameMenuItemChain * pItem)1574 void SetDifficultyAndStart(CGameMenuItemChain *pItem)
1575 {
1576     gGameOptions.nDifficulty = pItem->at30;
1577     gSkill = pItem->at30;
1578     gGameOptions.nLevel = 0;
1579     if (gDemo.at1)
1580         gDemo.StopPlayback();
1581     gStartNewGame = true;
1582     gCheatMgr.sub_5BCF4();
1583     if (Bstrlen(gGameOptions.szUserMap))
1584     {
1585         levelAddUserMap(gGameOptions.szUserMap);
1586         levelSetupOptions(gGameOptions.nEpisode, gGameOptions.nLevel);
1587         StartLevel(&gGameOptions);
1588         viewResizeView(gViewSize);
1589     }
1590     gGameMenuMgr.Deactivate();
1591 }
1592 
SetVideoModeOld(CGameMenuItemChain * pItem)1593 void SetVideoModeOld(CGameMenuItemChain *pItem)
1594 {
1595     if (pItem->at30 == validmodecnt)
1596     {
1597         gSetup.fullscreen = 0;
1598         gSetup.xdim = 640;
1599         gSetup.ydim = 480;
1600     }
1601     else
1602     {
1603         gSetup.fullscreen = 0;
1604         gSetup.xdim = validmode[pItem->at30].xdim;
1605         gSetup.ydim = validmode[pItem->at30].ydim;
1606     }
1607     scrSetGameMode(gSetup.fullscreen, gSetup.xdim, gSetup.ydim, gSetup.bpp);
1608     scrSetDac();
1609     viewResizeView(gViewSize);
1610 }
1611 
SetVideoMode(CGameMenuItemChain * pItem)1612 void SetVideoMode(CGameMenuItemChain *pItem)
1613 {
1614     UNREFERENCED_PARAMETER(pItem);
1615     resolution_t p = { xres, yres, fullscreen, bpp, 0 };
1616     int32_t prend = videoGetRenderMode();
1617     int32_t pvsync = vsync;
1618 
1619     int32_t nResolution = itemOptionsDisplayModeResolution.m_nFocus;
1620     resolution_t n = { gResolution[nResolution].xdim, gResolution[nResolution].ydim,
1621                        (gResolution[nResolution].flags & RES_FS) ? itemOptionsDisplayModeFullscreen.at20 : 0,
1622                        (nRendererValues[itemOptionsDisplayModeRenderer.m_nFocus] == REND_CLASSIC) ? 8 : gResolution[nResolution].bppmax, 0 };
1623     int32_t UNUSED(nrend) = nRendererValues[itemOptionsDisplayModeRenderer.m_nFocus];
1624     int32_t nvsync = nVSyncValues[itemOptionsDisplayModeVSync.m_nFocus];
1625 
1626     if (videoSetGameMode(n.flags, n.xdim, n.ydim, n.bppmax, upscalefactor) < 0)
1627     {
1628         if (videoSetGameMode(p.flags, p.xdim, p.ydim, p.bppmax, upscalefactor) < 0)
1629         {
1630             videoSetRenderMode(prend);
1631             ThrowError("Failed restoring old video mode.");
1632         }
1633         else
1634         {
1635             onvideomodechange(p.bppmax > 8);
1636             vsync = videoSetVsync(pvsync);
1637         }
1638     }
1639     else onvideomodechange(n.bppmax > 8);
1640 
1641     viewResizeView(gViewSize);
1642     vsync = videoSetVsync(nvsync);
1643     gSetup.fullscreen = fullscreen;
1644     gSetup.xdim = xres;
1645     gSetup.ydim = yres;
1646     gSetup.bpp = bpp;
1647 }
1648 
SetWidescreen(CGameMenuItemZBool * pItem)1649 void SetWidescreen(CGameMenuItemZBool *pItem)
1650 {
1651     r_usenewaspect = pItem->at20;
1652 }
1653 
SetFOV(CGameMenuItemSlider * pItem)1654 void SetFOV(CGameMenuItemSlider *pItem)
1655 {
1656     gFov = pItem->nValue;
1657 }
1658 
SetupVideoModeMenu(CGameMenuItemChain * pItem)1659 void SetupVideoModeMenu(CGameMenuItemChain *pItem)
1660 {
1661     UNREFERENCED_PARAMETER(pItem);
1662     for (int i = 0; i < gResolutionNum; i++)
1663     {
1664         if (gSetup.xdim == gResolution[i].xdim && gSetup.ydim == gResolution[i].ydim)
1665         {
1666             itemOptionsDisplayModeResolution.m_nFocus = i;
1667             break;
1668         }
1669     }
1670     itemOptionsDisplayModeFullscreen.at20 = gSetup.fullscreen;
1671 #ifdef USE_OPENGL
1672     for (int i = 0; i < 2; i++)
1673     {
1674         if (videoGetRenderMode() == nRendererValues[i])
1675         {
1676             itemOptionsDisplayModeRenderer.m_nFocus = i;
1677             break;
1678         }
1679     }
1680 #endif
1681     for (int i = 0; i < 3; i++)
1682     {
1683         if (vsync == nVSyncValues[i])
1684         {
1685             itemOptionsDisplayModeVSync.m_nFocus = i;
1686             break;
1687         }
1688     }
1689     for (int i = 0; i < 8; i++)
1690     {
1691         if (r_maxfps == nFrameLimitValues[i])
1692         {
1693             itemOptionsDisplayModeFrameLimit.m_nFocus = i;
1694             break;
1695         }
1696     }
1697     itemOptionsDisplayModeFPSOffset.nValue = r_maxfpsoffset;
1698 }
1699 
PreDrawVideoModeMenu(CGameMenuItem * pItem)1700 void PreDrawVideoModeMenu(CGameMenuItem *pItem)
1701 {
1702     if (pItem == &itemOptionsDisplayModeFullscreen)
1703         pItem->bEnable = !!(gResolution[itemOptionsDisplayModeResolution.m_nFocus].flags & RES_FS);
1704 #ifdef USE_OPENGL
1705     else if (pItem == &itemOptionsDisplayModeRenderer)
1706         pItem->bEnable = gResolution[itemOptionsDisplayModeResolution.m_nFocus].bppmax > 8;
1707 #endif
1708 }
1709 
UpdateVideoModeMenuFrameLimit(CGameMenuItemZCycle * pItem)1710 void UpdateVideoModeMenuFrameLimit(CGameMenuItemZCycle *pItem)
1711 {
1712     r_maxfps = nFrameLimitValues[pItem->m_nFocus];
1713     g_frameDelay = calcFrameDelay(r_maxfps + r_maxfpsoffset);
1714 }
1715 
UpdateVideoModeMenuFPSOffset(CGameMenuItemSlider * pItem)1716 void UpdateVideoModeMenuFPSOffset(CGameMenuItemSlider *pItem)
1717 {
1718     r_maxfpsoffset = pItem->nValue;
1719     g_frameDelay = calcFrameDelay(r_maxfps + r_maxfpsoffset);
1720 }
1721 
UpdateVideoColorMenu(CGameMenuItemSliderFloat * pItem)1722 void UpdateVideoColorMenu(CGameMenuItemSliderFloat *pItem)
1723 {
1724     UNREFERENCED_PARAMETER(pItem);
1725     g_videoGamma = itemOptionsDisplayColorGamma.fValue;
1726     g_videoContrast = itemOptionsDisplayColorContrast.fValue;
1727     g_videoBrightness = itemOptionsDisplayColorBrightness.fValue;
1728     r_ambientlight = itemOptionsDisplayColorVisibility.fValue;
1729     r_ambientlightrecip = 1.f/r_ambientlight;
1730     gBrightness = GAMMA_CALC<<2;
1731     videoSetPalette(gBrightness>>2, gLastPal, 0);
1732 }
1733 
PreDrawDisplayColor(CGameMenuItem * pItem)1734 void PreDrawDisplayColor(CGameMenuItem *pItem)
1735 {
1736     if (pItem == &itemOptionsDisplayColorContrast)
1737         pItem->bEnable = gammabrightness;
1738     else if (pItem == &itemOptionsDisplayColorBrightness)
1739         pItem->bEnable = gammabrightness;
1740 }
1741 
ResetVideoColor(CGameMenuItemChain * pItem)1742 void ResetVideoColor(CGameMenuItemChain *pItem)
1743 {
1744     UNREFERENCED_PARAMETER(pItem);
1745     g_videoGamma = DEFAULT_GAMMA;
1746     g_videoContrast = DEFAULT_CONTRAST;
1747     g_videoBrightness = DEFAULT_BRIGHTNESS;
1748     gBrightness = 0;
1749     r_ambientlight = r_ambientlightrecip = 1.f;
1750     videoSetPalette(gBrightness>>2, gLastPal, 0);
1751 }
1752 
1753 #ifdef USE_OPENGL
SetupVideoPolymostMenu(CGameMenuItemChain * pItem)1754 void SetupVideoPolymostMenu(CGameMenuItemChain *pItem)
1755 {
1756     UNREFERENCED_PARAMETER(pItem);
1757     itemOptionsDisplayPolymostTextureMode.m_nFocus = 0;
1758     for (int i = 0; i < 2; i++)
1759     {
1760         if (nTextureModeValues[i] == gltexfiltermode)
1761         {
1762             itemOptionsDisplayPolymostTextureMode.m_nFocus = i;
1763             break;
1764         }
1765     }
1766     itemOptionsDisplayPolymostAnisotropy.m_nFocus = 0;
1767     for (int i = 0; i < 6; i++)
1768     {
1769         if (nAnisotropyValues[i] == glanisotropy)
1770         {
1771             itemOptionsDisplayPolymostAnisotropy.m_nFocus = i;
1772             break;
1773         }
1774     }
1775     itemOptionsDisplayPolymostTrueColorTextures.at20 = usehightile;
1776     itemOptionsDisplayPolymostTexQuality.m_nFocus = r_downsize;
1777     itemOptionsDisplayPolymostPreloadCache.at20 = useprecache;
1778     itemOptionsDisplayPolymostTexCache.m_nFocus = glusetexcache;
1779     itemOptionsDisplayPolymostDetailTex.at20 = r_detailmapping;
1780     itemOptionsDisplayPolymostGlowTex.at20 = r_glowmapping;
1781     itemOptionsDisplayPolymost3DModels.at20 = usemodels;
1782     itemOptionsDisplayPolymostDeliriumBlur.at20 = gDeliriumBlur;
1783 }
1784 
UpdateTextureMode(CGameMenuItemZCycle * pItem)1785 void UpdateTextureMode(CGameMenuItemZCycle *pItem)
1786 {
1787     gltexfiltermode = nTextureModeValues[pItem->m_nFocus];
1788     gltexapplyprops();
1789 }
1790 
UpdateAnisotropy(CGameMenuItemZCycle * pItem)1791 void UpdateAnisotropy(CGameMenuItemZCycle *pItem)
1792 {
1793     glanisotropy = nAnisotropyValues[pItem->m_nFocus];
1794     gltexapplyprops();
1795 }
1796 
UpdateTrueColorTextures(CGameMenuItemZBool * pItem)1797 void UpdateTrueColorTextures(CGameMenuItemZBool *pItem)
1798 {
1799     usehightile = pItem->at20;
1800 }
1801 #endif
1802 
DoModeChange(void)1803 void DoModeChange(void)
1804 {
1805     videoResetMode();
1806     if (videoSetGameMode(fullscreen, xres, yres, bpp, upscalefactor))
1807         OSD_Printf("restartvid: Reset failed...\n");
1808     onvideomodechange(gSetup.bpp > 8);
1809 }
1810 
1811 #ifdef USE_OPENGL
UpdateTexQuality(CGameMenuItemZCycle * pItem)1812 void UpdateTexQuality(CGameMenuItemZCycle *pItem)
1813 {
1814     r_downsize = pItem->m_nFocus;
1815     texcache_invalidate();
1816     r_downsizevar = r_downsize;
1817     DoModeChange();
1818 }
1819 
UpdatePreloadCache(CGameMenuItemZBool * pItem)1820 void UpdatePreloadCache(CGameMenuItemZBool *pItem)
1821 {
1822     useprecache = pItem->at20;
1823 }
1824 
UpdateTexCache(CGameMenuItemZCycle * pItem)1825 void UpdateTexCache(CGameMenuItemZCycle *pItem)
1826 {
1827     glusetexcache = pItem->m_nFocus;
1828 }
1829 
UpdateDetailTex(CGameMenuItemZBool * pItem)1830 void UpdateDetailTex(CGameMenuItemZBool *pItem)
1831 {
1832     r_detailmapping = pItem->at20;
1833 }
1834 
UpdateGlowTex(CGameMenuItemZBool * pItem)1835 void UpdateGlowTex(CGameMenuItemZBool *pItem)
1836 {
1837     r_glowmapping = pItem->at20;
1838 }
1839 
Update3DModels(CGameMenuItemZBool * pItem)1840 void Update3DModels(CGameMenuItemZBool *pItem)
1841 {
1842     usemodels = pItem->at20;
1843 }
1844 
UpdateDeliriumBlur(CGameMenuItemZBool * pItem)1845 void UpdateDeliriumBlur(CGameMenuItemZBool *pItem)
1846 {
1847     gDeliriumBlur = pItem->at20;
1848 }
1849 
PreDrawDisplayPolymost(CGameMenuItem * pItem)1850 void PreDrawDisplayPolymost(CGameMenuItem *pItem)
1851 {
1852     if (pItem == &itemOptionsDisplayPolymostTexQuality)
1853         pItem->bEnable = usehightile;
1854     else if (pItem == &itemOptionsDisplayPolymostPreloadCache)
1855         pItem->bEnable = usehightile;
1856     else if (pItem == &itemOptionsDisplayPolymostTexCache)
1857         pItem->bEnable = glusetexcompr && usehightile;
1858     else if (pItem == &itemOptionsDisplayPolymostDetailTex)
1859         pItem->bEnable = usehightile;
1860     else if (pItem == &itemOptionsDisplayPolymostGlowTex)
1861         pItem->bEnable = usehightile;
1862 }
1863 #endif
1864 
UpdateSoundToggle(CGameMenuItemZBool * pItem)1865 void UpdateSoundToggle(CGameMenuItemZBool *pItem)
1866 {
1867     SoundToggle = pItem->at20;
1868     if (!SoundToggle)
1869         FX_StopAllSounds();
1870 }
1871 
UpdateMusicToggle(CGameMenuItemZBool * pItem)1872 void UpdateMusicToggle(CGameMenuItemZBool *pItem)
1873 {
1874     MusicToggle = pItem->at20;
1875     if (!MusicToggle)
1876         sndStopSong();
1877     else
1878     {
1879         if (gGameStarted || gDemo.at1)
1880             sndPlaySong(gGameOptions.zLevelSong, true);
1881     }
1882 }
1883 
Update3DToggle(CGameMenuItemZBool * pItem)1884 void Update3DToggle(CGameMenuItemZBool *pItem)
1885 {
1886     gDoppler = pItem->at20;
1887 }
1888 
UpdateCDToggle(CGameMenuItemZBool * pItem)1889 void UpdateCDToggle(CGameMenuItemZBool *pItem)
1890 {
1891     CDAudioToggle = pItem->at20;
1892     if (gGameStarted || gDemo.at1)
1893         levelTryPlayMusicOrNothing(gGameOptions.nEpisode, gGameOptions.nLevel);
1894 }
1895 
UpdateSoundVolume(CGameMenuItemSlider * pItem)1896 void UpdateSoundVolume(CGameMenuItemSlider *pItem)
1897 {
1898     sndSetFXVolume(pItem->nValue);
1899 }
1900 
UpdateMusicVolume(CGameMenuItemSlider * pItem)1901 void UpdateMusicVolume(CGameMenuItemSlider *pItem)
1902 {
1903     sndSetMusicVolume(pItem->nValue);
1904 }
1905 
UpdateSoundRate(CGameMenuItemZCycle * pItem)1906 void UpdateSoundRate(CGameMenuItemZCycle *pItem)
1907 {
1908     UNREFERENCED_PARAMETER(pItem);
1909 }
1910 
UpdateNumVoices(CGameMenuItemSlider * pItem)1911 void UpdateNumVoices(CGameMenuItemSlider *pItem)
1912 {
1913     UNREFERENCED_PARAMETER(pItem);
1914 }
1915 
UpdateMusicDevice(CGameMenuItemZCycle * pItem)1916 void UpdateMusicDevice(CGameMenuItemZCycle *pItem)
1917 {
1918     itemOptionsSoundSF2Bank.bEnable = 0;
1919     itemOptionsSoundSF2Bank.bNoDraw = 1;
1920     switch (nMusicDeviceValues[itemOptionsSoundMusicDevice.m_nFocus])
1921     {
1922     case ASS_SF2:
1923         itemOptionsSoundSF2Bank.bEnable = 1;
1924         itemOptionsSoundSF2Bank.bNoDraw = 0;
1925         break;
1926     }
1927 }
1928 
SetSound(CGameMenuItemChain * pItem)1929 void SetSound(CGameMenuItemChain *pItem)
1930 {
1931     UNREFERENCED_PARAMETER(pItem);
1932     MixRate = nSoundRateValues[itemOptionsSoundSampleRate.m_nFocus];
1933     NumVoices = itemOptionsSoundNumVoices.nValue;
1934     MusicDevice = nMusicDeviceValues[itemOptionsSoundMusicDevice.m_nFocus];
1935     Bstrcpy(SF2_BankFile, sf2bankfile);
1936     sfxTerm();
1937     sndTerm();
1938 
1939     sndInit();
1940     sfxInit();
1941 
1942     if (MusicToggle && (gGameStarted || gDemo.at1))
1943         sndPlaySong(gGameOptions.zLevelSong, true);
1944 }
1945 
PreDrawSound(CGameMenuItem * pItem)1946 void PreDrawSound(CGameMenuItem *pItem)
1947 {
1948     UNREFERENCED_PARAMETER(pItem);
1949 }
1950 
SetupOptionsSound(CGameMenuItemChain * pItem)1951 void SetupOptionsSound(CGameMenuItemChain *pItem)
1952 {
1953     UNREFERENCED_PARAMETER(pItem);
1954     itemOptionsSoundSoundToggle.at20 = SoundToggle;
1955     itemOptionsSoundMusicToggle.at20 = MusicToggle;
1956     itemOptionsSound3DToggle.at20 = gDoppler;
1957     itemOptionsSoundCDToggle.at20 = CDAudioToggle;
1958     itemOptionsSoundSampleRate.m_nFocus = 0;
1959     for (int i = 0; i < 3; i++)
1960     {
1961         if (nSoundRateValues[i] == MixRate)
1962         {
1963             itemOptionsSoundSampleRate.m_nFocus = i;
1964             break;
1965         }
1966     }
1967     itemOptionsSoundNumVoices.nValue = NumVoices;
1968     itemOptionsSoundMusicDevice.m_nFocus = 0;
1969     for (int i = 0; i < ARRAY_SIZE(nMusicDeviceValues); i++)
1970     {
1971         if (nMusicDeviceValues[i] == MusicDevice)
1972         {
1973             itemOptionsSoundMusicDevice.m_nFocus = i;
1974             break;
1975         }
1976     }
1977 
1978     UpdateMusicDevice(NULL);
1979 }
1980 
UpdatePlayerName(CGameMenuItemZEdit * pItem,CGameMenuEvent * pEvent)1981 void UpdatePlayerName(CGameMenuItemZEdit *pItem, CGameMenuEvent *pEvent)
1982 {
1983     UNREFERENCED_PARAMETER(pItem);
1984     if (pEvent->at0 == kMenuEventEnter)
1985         netBroadcastPlayerInfo(myconnectindex);
1986 }
1987 
SetMouseAimMode(CGameMenuItemZBool * pItem)1988 void SetMouseAimMode(CGameMenuItemZBool *pItem)
1989 {
1990     gMouseAiming = pItem->at20;
1991 }
1992 
SetMouseVerticalAim(CGameMenuItemZBool * pItem)1993 void SetMouseVerticalAim(CGameMenuItemZBool *pItem)
1994 {
1995     gMouseAim = pItem->at20;
1996 }
1997 
SetMouseXScale(CGameMenuItemSlider * pItem)1998 void SetMouseXScale(CGameMenuItemSlider *pItem)
1999 {
2000     CONTROL_SetAnalogAxisScale(0, pItem->nValue, controldevice_mouse);
2001 }
2002 
SetMouseYScale(CGameMenuItemSlider * pItem)2003 void SetMouseYScale(CGameMenuItemSlider *pItem)
2004 {
2005     CONTROL_SetAnalogAxisScale(1, pItem->nValue, controldevice_mouse);
2006 }
2007 
SetupMouseMenu(CGameMenuItemChain * pItem)2008 void SetupMouseMenu(CGameMenuItemChain *pItem)
2009 {
2010     UNREFERENCED_PARAMETER(pItem);
2011     itemOptionsControlMouseAimFlipped.at20 = gMouseAimingFlipped;
2012     itemOptionsControlMouseAimMode.at20 = gMouseAiming;
2013     itemOptionsControlMouseVerticalAim.at20 = gMouseAim;
2014     itemOptionsControlMouseXScale.nValue = CONTROL_MouseAxesScale[0];
2015     itemOptionsControlMouseYScale.nValue = CONTROL_MouseAxesScale[1];
2016 }
2017 
PreDrawControlMouse(CGameMenuItem * pItem)2018 void PreDrawControlMouse(CGameMenuItem *pItem)
2019 {
2020     if (pItem == &itemOptionsControlMouseVerticalAim)
2021         pItem->bEnable = !gMouseAiming;
2022 }
2023 
SetMouseButton(CGameMenuItemZCycle * pItem)2024 void SetMouseButton(CGameMenuItemZCycle *pItem)
2025 {
2026     for (int i = 0; i < MENUMOUSEFUNCTIONS; i++)
2027     {
2028         if (pItem == pItemOptionsControlMouseButton[i])
2029         {
2030             int nFunc = nGamefuncsValues[pItem->m_nFocus];
2031             MouseFunctions[MenuMouseDataIndex[i][0]][MenuMouseDataIndex[i][1]] = nFunc;
2032             CONTROL_MapButton(nFunc, MenuMouseDataIndex[i][0], MenuMouseDataIndex[i][1], controldevice_mouse);
2033             CONTROL_FreeMouseBind(MenuMouseDataIndex[i][0]);
2034             break;
2035         }
2036     }
2037 }
2038 
SetupMouseButtonMenu(CGameMenuItemChain * pItem)2039 void SetupMouseButtonMenu(CGameMenuItemChain *pItem)
2040 {
2041     UNREFERENCED_PARAMETER(pItem);
2042     for (int i = 0; i < MENUMOUSEFUNCTIONS; i++)
2043     {
2044         auto pItem = pItemOptionsControlMouseButton[i];
2045         pItem->m_nFocus = 0;
2046         for (int j = 0; j < NUMGAMEFUNCTIONS+1; j++)
2047         {
2048             if (MouseFunctions[MenuMouseDataIndex[i][0]][MenuMouseDataIndex[i][1]] == nGamefuncsValues[j])
2049             {
2050                 pItem->m_nFocus = j;
2051                 break;
2052             }
2053         }
2054     }
2055 }
2056 
SetupNetworkMenu(void)2057 void SetupNetworkMenu(void)
2058 {
2059     sprintf(zNetPortBuffer, "%d", gNetPort);
2060     if (strlen(gNetAddress) > 0)
2061         strncpy(zNetAddressBuffer, gNetAddress, sizeof(zNetAddressBuffer)-1);
2062 
2063     menuNetwork.Add(&itemNetworkTitle, false);
2064     menuNetwork.Add(&itemNetworkHost, true);
2065     menuNetwork.Add(&itemNetworkJoin, false);
2066     menuNetwork.Add(&itemBloodQAV, false);
2067 
2068     menuNetworkHost.Add(&itemNetworkHostTitle, false);
2069     menuNetworkHost.Add(&itemNetworkHostPlayerNum, true);
2070     menuNetworkHost.Add(&itemNetworkHostPort, false);
2071     menuNetworkHost.Add(&itemNetworkHostHost, false);
2072     menuNetworkHost.Add(&itemBloodQAV, false);
2073 
2074     menuNetworkJoin.Add(&itemNetworkJoinTitle, false);
2075     menuNetworkJoin.Add(&itemNetworkJoinAddress, true);
2076     menuNetworkJoin.Add(&itemNetworkJoinPort, false);
2077     menuNetworkJoin.Add(&itemNetworkJoinJoin, false);
2078     menuNetworkJoin.Add(&itemBloodQAV, false);
2079 }
2080 
SetupNetworkHostMenu(CGameMenuItemChain * pItem)2081 void SetupNetworkHostMenu(CGameMenuItemChain *pItem)
2082 {
2083     UNREFERENCED_PARAMETER(pItem);
2084 }
2085 
SetupNetworkJoinMenu(CGameMenuItemChain * pItem)2086 void SetupNetworkJoinMenu(CGameMenuItemChain *pItem)
2087 {
2088     UNREFERENCED_PARAMETER(pItem);
2089 }
2090 
NetworkHostGame(CGameMenuItemChain * pItem)2091 void NetworkHostGame(CGameMenuItemChain *pItem)
2092 {
2093     UNREFERENCED_PARAMETER(pItem);
2094     sndStopSong();
2095     FX_StopAllSounds();
2096     UpdateDacs(0, true);
2097     gNetPlayers = itemNetworkHostPlayerNum.nValue;
2098     gNetPort = strtoul(zNetPortBuffer, NULL, 10);
2099     if (!gNetPort)
2100         gNetPort = kNetDefaultPort;
2101     gNetMode = NETWORK_SERVER;
2102     netInitialize(false);
2103     gGameMenuMgr.Deactivate();
2104     gQuitGame = gRestartGame = true;
2105 }
2106 
NetworkJoinGame(CGameMenuItemChain * pItem)2107 void NetworkJoinGame(CGameMenuItemChain *pItem)
2108 {
2109     UNREFERENCED_PARAMETER(pItem);
2110     sndStopSong();
2111     FX_StopAllSounds();
2112     UpdateDacs(0, true);
2113     strcpy(gNetAddress, zNetAddressBuffer);
2114     gNetPort = strtoul(zNetPortBuffer, NULL, 10);
2115     if (!gNetPort)
2116         gNetPort = kNetDefaultPort;
2117     gNetMode = NETWORK_CLIENT;
2118     netInitialize(false);
2119     gGameMenuMgr.Deactivate();
2120     gQuitGame = gRestartGame = true;
2121 }
2122 
SaveGameProcess(CGameMenuItemChain * pItem)2123 void SaveGameProcess(CGameMenuItemChain *pItem)
2124 {
2125     UNREFERENCED_PARAMETER(pItem);
2126 }
2127 
TenProcess(CGameMenuItem7EA1C * pItem)2128 void TenProcess(CGameMenuItem7EA1C *pItem)
2129 {
2130     UNREFERENCED_PARAMETER(pItem);
2131 }
2132 
2133 short gQuickLoadSlot = -1;
2134 short gQuickSaveSlot = -1;
2135 
SaveGame(CGameMenuItemZEditBitmap * pItem,CGameMenuEvent * event)2136 void SaveGame(CGameMenuItemZEditBitmap *pItem, CGameMenuEvent *event)
2137 {
2138     char strSaveGameName[BMAX_PATH];
2139     int nSlot = pItem->at28;
2140     if (gGameOptions.nGameType > 0 || !gGameStarted)
2141         return;
2142     if (event->at0 != 6/* || strSaveGameName[0]*/)
2143     {
2144         gGameMenuMgr.Deactivate();
2145         return;
2146     }
2147     G_ModDirSnprintf(strSaveGameName, BMAX_PATH, "game00%02d.sav", nSlot);
2148     strcpy(gGameOptions.szUserGameName, strRestoreGameStrings[nSlot]);
2149     sprintf(gGameOptions.szSaveGameName, "%s", strSaveGameName);
2150     restoreGameDifficulty[nSlot] = gGameOptions.nDifficulty;
2151     gGameOptions.nSaveGameSlot = nSlot;
2152     viewLoadingScreen(2518, "Saving", "Saving Your Game", strRestoreGameStrings[nSlot]);
2153     videoNextPage();
2154     gSaveGameNum = nSlot;
2155     LoadSave::SaveGame(strSaveGameName);
2156     gQuickSaveSlot = nSlot;
2157     gGameMenuMgr.Deactivate();
2158     viewSetMessage("Game saved");
2159 }
2160 
QuickSaveGame(void)2161 void QuickSaveGame(void)
2162 {
2163     char strSaveGameName[BMAX_PATH];
2164     if (gGameOptions.nGameType > 0 || !gGameStarted)
2165         return;
2166     /*if (strSaveGameName[0])
2167     {
2168         gGameMenuMgr.Deactivate();
2169         return;
2170     }*/
2171     G_ModDirSnprintf(strSaveGameName, BMAX_PATH, "game00%02d.sav", gQuickSaveSlot);
2172     strcpy(gGameOptions.szUserGameName, strRestoreGameStrings[gQuickSaveSlot]);
2173     sprintf(gGameOptions.szSaveGameName, "%s", strSaveGameName);
2174     restoreGameDifficulty[gQuickSaveSlot] = gGameOptions.nDifficulty;
2175     gGameOptions.nSaveGameSlot = gQuickSaveSlot;
2176     viewLoadingScreen(2518, "Saving", "Saving Your Game", strRestoreGameStrings[gQuickSaveSlot]);
2177     videoNextPage();
2178     LoadSave::SaveGame(strSaveGameName);
2179     gGameOptions.picEntry = gSavedOffset;
2180     gSaveGameOptions[gQuickSaveSlot] = gGameOptions;
2181     UpdateSavedInfo(gQuickSaveSlot);
2182     gGameMenuMgr.Deactivate();
2183     viewSetMessage("Game saved");
2184 }
2185 
LoadGame(CGameMenuItemZEditBitmap * pItem,CGameMenuEvent * event)2186 void LoadGame(CGameMenuItemZEditBitmap *pItem, CGameMenuEvent *event)
2187 {
2188     UNREFERENCED_PARAMETER(event);
2189     char strLoadGameName[BMAX_PATH];
2190     int nSlot = pItem->at28;
2191     if (gGameOptions.nGameType > 0)
2192         return;
2193     G_ModDirSnprintf(strLoadGameName, BMAX_PATH, "game00%02d.sav", nSlot);
2194     if (!testkopen(strLoadGameName, 0))
2195         return;
2196     viewLoadingScreen(2518, "Loading", "Loading Saved Game", strRestoreGameStrings[nSlot]);
2197     videoNextPage();
2198     LoadSave::LoadGame(strLoadGameName);
2199     gGameMenuMgr.Deactivate();
2200     gQuickLoadSlot = nSlot;
2201 }
2202 
QuickLoadGame(void)2203 void QuickLoadGame(void)
2204 {
2205     char strLoadGameName[BMAX_PATH];
2206     if (gGameOptions.nGameType > 0)
2207         return;
2208     G_ModDirSnprintf(strLoadGameName, BMAX_PATH, "game00%02d.sav", gQuickLoadSlot);
2209     if (!testkopen(strLoadGameName, 0))
2210         return;
2211     viewLoadingScreen(2518, "Loading", "Loading Saved Game", strRestoreGameStrings[gQuickLoadSlot]);
2212     videoNextPage();
2213     LoadSave::LoadGame(strLoadGameName);
2214     gGameMenuMgr.Deactivate();
2215 }
2216 
SetupLevelMenuItem(int nEpisode)2217 void SetupLevelMenuItem(int nEpisode)
2218 {
2219     dassert(nEpisode >= 0 && nEpisode < gEpisodeCount);
2220     itemNetStart3.SetTextArray(zLevelNames[nEpisode], gEpisodeInfo[nEpisode].nLevels, 0);
2221 }
2222 
SetupNetLevels(CGameMenuItemZCycle * pItem)2223 void SetupNetLevels(CGameMenuItemZCycle *pItem)
2224 {
2225     SetupLevelMenuItem(pItem->m_nFocus);
2226 }
2227 
StartNetGame(CGameMenuItemChain * pItem)2228 void StartNetGame(CGameMenuItemChain *pItem)
2229 {
2230     UNREFERENCED_PARAMETER(pItem);
2231     gPacketStartGame.gameType = itemNetStart1.m_nFocus+1;
2232     if (gPacketStartGame.gameType == 0)
2233         gPacketStartGame.gameType = 2;
2234     gPacketStartGame.episodeId = itemNetStart2.m_nFocus;
2235     gPacketStartGame.levelId = itemNetStart3.m_nFocus;
2236     gPacketStartGame.difficulty = itemNetStart4.m_nFocus;
2237     gPacketStartGame.monsterSettings = itemNetStart5.m_nFocus;
2238     gPacketStartGame.weaponSettings = itemNetStart6.m_nFocus;
2239     gPacketStartGame.itemSettings = itemNetStart7.m_nFocus;
2240     gPacketStartGame.respawnSettings = 0;
2241     gPacketStartGame.bFriendlyFire = itemNetStart8.at20;
2242     gPacketStartGame.bKeepKeysOnRespawn = itemNetStart9.at20;
2243     ////
2244     gPacketStartGame.weaponsV10x = itemNetStart10.at20;
2245     ////
2246     gPacketStartGame.unk = 0;
2247     Bstrncpy(gPacketStartGame.userMapName, zUserMapName, Bstrlen(zUserMapName));
2248     gPacketStartGame.userMap = gPacketStartGame.userMapName[0] != 0;
2249 
2250     netBroadcastNewGame();
2251     gStartNewGame = 1;
2252     gGameMenuMgr.Deactivate();
2253 }
2254 
Restart(CGameMenuItemChain * pItem)2255 void Restart(CGameMenuItemChain *pItem)
2256 {
2257     UNREFERENCED_PARAMETER(pItem);
2258     if (gGameOptions.nGameType == 0 || numplayers == 1)
2259     {
2260         gQuitGame = true;
2261         gRestartGame = true;
2262     }
2263     else
2264         gQuitRequest = 2;
2265     gGameMenuMgr.Deactivate();
2266 }
2267 
Quit(CGameMenuItemChain * pItem)2268 void Quit(CGameMenuItemChain *pItem)
2269 {
2270     UNREFERENCED_PARAMETER(pItem);
2271     if (gGameOptions.nGameType == 0 || numplayers == 1)
2272         gQuitGame = true;
2273     else
2274         gQuitRequest = 1;
2275     gGameMenuMgr.Deactivate();
2276 }
2277 
SetParentalLock(CGameMenuItemZBool * pItem)2278 void SetParentalLock(CGameMenuItemZBool *pItem)
2279 {
2280     if (!pItem->at20)
2281     {
2282         pItem->at20 = true;
2283         pItem->Draw();
2284         if (strcmp(itemParentalLockPassword.at20, ""))
2285         {
2286             itemParentalLockPassword.pMenu->FocusNextItem();
2287             itemParentalLockPassword.at32 = 0;
2288             itemParentalLockPassword.at37 = 1;
2289             itemParentalLockPassword.at5f = pItem;
2290             itemParentalLockPassword.at29[0] = 0;
2291             return;
2292         }
2293         else
2294         {
2295             itemParentalLockPassword.at20[0] = 0;
2296             pItem->Draw();
2297             gbAdultContent = false;
2298         }
2299     }
2300     else
2301         gbAdultContent = true;
2302     // NUKE-TODO: CONFIG_WriteAdultMode();
2303 }
2304 
MenuSetupEpisodeInfo(void)2305 void MenuSetupEpisodeInfo(void)
2306 {
2307     memset(zEpisodeNames, 0, sizeof(zEpisodeNames));
2308     memset(zLevelNames, 0, sizeof(zLevelNames));
2309     for (int i = 0; i < 6; i++)
2310     {
2311         if (i < gEpisodeCount)
2312         {
2313             EPISODEINFO *pEpisode = &gEpisodeInfo[i];
2314             zEpisodeNames[i] = pEpisode->title;
2315             for (int j = 0; j < 16; j++)
2316             {
2317                 if (j < pEpisode->nLevels)
2318                 {
2319                     zLevelNames[i][j] = pEpisode->levelsInfo[j].Title;
2320                 }
2321             }
2322         }
2323     }
2324 }
2325 
drawLoadingScreen(void)2326 void drawLoadingScreen(void)
2327 {
2328     char buffer[80];
2329     if (gGameOptions.nGameType == 0)
2330     {
2331         if (gDemo.at1)
2332             sprintf(buffer, "Loading Demo");
2333         else
2334             sprintf(buffer, "Loading Level");
2335     }
2336     else
2337         sprintf(buffer, "%s", zNetGameTypes[gGameOptions.nGameType-1]);
2338     viewLoadingScreen(2049, buffer, levelGetTitle(), NULL);
2339 }
2340