diff options
Diffstat (limited to 'src/m_menu.c')
-rw-r--r-- | src/m_menu.c | 5559 |
1 files changed, 5559 insertions, 0 deletions
diff --git a/src/m_menu.c b/src/m_menu.c new file mode 100644 index 0000000..16afd60 --- /dev/null +++ b/src/m_menu.c | |||
@@ -0,0 +1,5559 @@ | |||
1 | /* Emacs style mode select -*- C++ -*- | ||
2 | *----------------------------------------------------------------------------- | ||
3 | * | ||
4 | * | ||
5 | * PrBoom: a Doom port merged with LxDoom and LSDLDoom | ||
6 | * based on BOOM, a modified and improved DOOM engine | ||
7 | * Copyright (C) 1999 by | ||
8 | * id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman | ||
9 | * Copyright (C) 1999-2000 by | ||
10 | * Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze | ||
11 | * Copyright 2005, 2006 by | ||
12 | * Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or | ||
15 | * modify it under the terms of the GNU General Public License | ||
16 | * as published by the Free Software Foundation; either version 2 | ||
17 | * of the License, or (at your option) any later version. | ||
18 | * | ||
19 | * This program is distributed in the hope that it will be useful, | ||
20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
22 | * GNU General Public License for more details. | ||
23 | * | ||
24 | * You should have received a copy of the GNU General Public License | ||
25 | * along with this program; if not, write to the Free Software | ||
26 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||
27 | * 02111-1307, USA. | ||
28 | * | ||
29 | * DESCRIPTION: | ||
30 | * DOOM selection menu, options, episode etc. (aka Big Font menus) | ||
31 | * Sliders and icons. Kinda widget stuff. | ||
32 | * Setup Menus. | ||
33 | * Extended HELP screens. | ||
34 | * Dynamic HELP screen. | ||
35 | * | ||
36 | *-----------------------------------------------------------------------------*/ | ||
37 | |||
38 | #include <stdio.h> | ||
39 | #include <fcntl.h> | ||
40 | |||
41 | #include "doomdef.h" | ||
42 | #include "doomstat.h" | ||
43 | #include "dstrings.h" | ||
44 | #include "d_main.h" | ||
45 | #include "v_video.h" | ||
46 | #include "w_wad.h" | ||
47 | #include "r_main.h" | ||
48 | #include "hu_stuff.h" | ||
49 | #include "g_game.h" | ||
50 | #include "s_sound.h" | ||
51 | #include "sounds.h" | ||
52 | #include "m_menu.h" | ||
53 | #include "d_deh.h" | ||
54 | #include "m_misc.h" | ||
55 | #include "lprintf.h" | ||
56 | #include "am_map.h" | ||
57 | #include "i_main.h" | ||
58 | #include "i_system.h" | ||
59 | #include "i_video.h" | ||
60 | #include "i_sound.h" | ||
61 | #include "r_demo.h" | ||
62 | #include "r_fps.h" | ||
63 | |||
64 | extern patchnum_t hu_font[HU_FONTSIZE]; | ||
65 | extern boolean message_dontfuckwithme; | ||
66 | |||
67 | extern boolean chat_on; // in heads-up code | ||
68 | |||
69 | // | ||
70 | // defaulted values | ||
71 | // | ||
72 | |||
73 | int mouseSensitivity_horiz; // has default // killough | ||
74 | int mouseSensitivity_vert; // has default | ||
75 | |||
76 | int showMessages; // Show messages has default, 0 = off, 1 = on | ||
77 | |||
78 | int hide_setup=1; // killough 5/15/98 | ||
79 | |||
80 | // Blocky mode, has default, 0 = high, 1 = normal | ||
81 | //int detailLevel; obsolete -- killough | ||
82 | int screenblocks; // has default | ||
83 | |||
84 | int screenSize; // temp for screenblocks (0-9) | ||
85 | |||
86 | int quickSaveSlot; // -1 = no quicksave slot picked! | ||
87 | |||
88 | int messageToPrint; // 1 = message to be printed | ||
89 | |||
90 | // CPhipps - static const | ||
91 | static const char* messageString; // ...and here is the message string! | ||
92 | |||
93 | // message x & y | ||
94 | int messx; | ||
95 | int messy; | ||
96 | int messageLastMenuActive; | ||
97 | |||
98 | boolean messageNeedsInput; // timed message = no input from user | ||
99 | |||
100 | void (*messageRoutine)(int response); | ||
101 | |||
102 | #define SAVESTRINGSIZE 24 | ||
103 | |||
104 | /* killough 8/15/98: when changes are allowed to sync-critical variables */ | ||
105 | static int allow_changes(void) | ||
106 | { | ||
107 | return !(demoplayback || demorecording || netgame); | ||
108 | } | ||
109 | |||
110 | static void M_UpdateCurrent(default_t* def) | ||
111 | { | ||
112 | /* cph - requires rewrite of m_misc.c */ | ||
113 | if (def->current) { | ||
114 | if (allow_changes()) /* killough 8/15/98 */ | ||
115 | *def->current = *def->location.pi; | ||
116 | else if (*def->current != *def->location.pi) | ||
117 | warn_about_changes(S_LEVWARN); /* killough 8/15/98 */ | ||
118 | } | ||
119 | } | ||
120 | |||
121 | int warning_about_changes, print_warning_about_changes; | ||
122 | |||
123 | /* cphipps - M_DrawBackground renamed and moved to v_video.c */ | ||
124 | #define M_DrawBackground V_DrawBackground | ||
125 | |||
126 | // we are going to be entering a savegame string | ||
127 | |||
128 | int saveStringEnter; | ||
129 | int saveSlot; // which slot to save in | ||
130 | int saveCharIndex; // which char we're editing | ||
131 | // old save description before edit | ||
132 | char saveOldString[SAVESTRINGSIZE]; | ||
133 | |||
134 | boolean inhelpscreens; // indicates we are in or just left a help screen | ||
135 | |||
136 | boolean menuactive; // The menus are up | ||
137 | |||
138 | #define SKULLXOFF -32 | ||
139 | #define LINEHEIGHT 16 | ||
140 | |||
141 | char savegamestrings[10][SAVESTRINGSIZE]; | ||
142 | |||
143 | // | ||
144 | // MENU TYPEDEFS | ||
145 | // | ||
146 | |||
147 | typedef struct | ||
148 | { | ||
149 | short status; // 0 = no cursor here, 1 = ok, 2 = arrows ok | ||
150 | char name[10]; | ||
151 | |||
152 | // choice = menu item #. | ||
153 | // if status = 2, | ||
154 | // choice=0:leftarrow,1:rightarrow | ||
155 | void (*routine)(int choice); | ||
156 | char alphaKey; // hotkey in menu | ||
157 | } menuitem_t; | ||
158 | |||
159 | typedef struct menu_s | ||
160 | { | ||
161 | short numitems; // # of menu items | ||
162 | struct menu_s* prevMenu; // previous menu | ||
163 | menuitem_t* menuitems; // menu items | ||
164 | void (*routine)(); // draw routine | ||
165 | short x; | ||
166 | short y; // x,y of menu | ||
167 | short lastOn; // last item user was on in menu | ||
168 | } menu_t; | ||
169 | |||
170 | short itemOn; // menu item skull is on (for Big Font menus) | ||
171 | short skullAnimCounter; // skull animation counter | ||
172 | short whichSkull; // which skull to draw (he blinks) | ||
173 | |||
174 | // graphic name of skulls | ||
175 | |||
176 | const char skullName[2][/*8*/9] = {"M_SKULL1","M_SKULL2"}; | ||
177 | |||
178 | menu_t* currentMenu; // current menudef | ||
179 | |||
180 | // phares 3/30/98 | ||
181 | // externs added for setup menus | ||
182 | |||
183 | extern int mousebfire; | ||
184 | extern int mousebstrafe; | ||
185 | extern int mousebforward; | ||
186 | // proff 08/17/98: Added backward to mousebuttons | ||
187 | extern int mousebbackward; | ||
188 | extern int joybfire; | ||
189 | extern int joybstrafe; | ||
190 | extern int joybuse; | ||
191 | extern int joybspeed; | ||
192 | int mapcolor_me; // cph | ||
193 | |||
194 | extern int map_point_coordinates; // killough 10/98 | ||
195 | |||
196 | extern char* chat_macros[]; // chat macros | ||
197 | extern const char* shiftxform; | ||
198 | extern default_t defaults[]; | ||
199 | extern int numdefaults; | ||
200 | |||
201 | // end of externs added for setup menus | ||
202 | |||
203 | // | ||
204 | // PROTOTYPES | ||
205 | // | ||
206 | void M_NewGame(int choice); | ||
207 | void M_Episode(int choice); | ||
208 | void M_ChooseSkill(int choice); | ||
209 | void M_LoadGame(int choice); | ||
210 | void M_SaveGame(int choice); | ||
211 | void M_Options(int choice); | ||
212 | void M_EndGame(int choice); | ||
213 | void M_ReadThis(int choice); | ||
214 | void M_ReadThis2(int choice); | ||
215 | void M_QuitDOOM(int choice); | ||
216 | |||
217 | void M_ChangeMessages(int choice); | ||
218 | void M_ChangeSensitivity(int choice); | ||
219 | void M_SfxVol(int choice); | ||
220 | void M_MusicVol(int choice); | ||
221 | /* void M_ChangeDetail(int choice); unused -- killough */ | ||
222 | void M_SizeDisplay(int choice); | ||
223 | void M_StartGame(int choice); | ||
224 | void M_Sound(int choice); | ||
225 | |||
226 | void M_Mouse(int choice, int *sens); /* killough */ | ||
227 | void M_MouseVert(int choice); | ||
228 | void M_MouseHoriz(int choice); | ||
229 | void M_DrawMouse(void); | ||
230 | |||
231 | void M_FinishReadThis(int choice); | ||
232 | void M_FinishHelp(int choice); // killough 10/98 | ||
233 | void M_LoadSelect(int choice); | ||
234 | void M_SaveSelect(int choice); | ||
235 | void M_ReadSaveStrings(void); | ||
236 | void M_QuickSave(void); | ||
237 | void M_QuickLoad(void); | ||
238 | |||
239 | void M_DrawMainMenu(void); | ||
240 | void M_DrawReadThis1(void); | ||
241 | void M_DrawReadThis2(void); | ||
242 | void M_DrawNewGame(void); | ||
243 | void M_DrawEpisode(void); | ||
244 | void M_DrawOptions(void); | ||
245 | void M_DrawSound(void); | ||
246 | void M_DrawLoad(void); | ||
247 | void M_DrawSave(void); | ||
248 | void M_DrawSetup(void); // phares 3/21/98 | ||
249 | void M_DrawHelp (void); // phares 5/04/98 | ||
250 | |||
251 | void M_DrawSaveLoadBorder(int x,int y); | ||
252 | void M_SetupNextMenu(menu_t *menudef); | ||
253 | void M_DrawThermo(int x,int y,int thermWidth,int thermDot); | ||
254 | void M_DrawEmptyCell(menu_t *menu,int item); | ||
255 | void M_DrawSelCell(menu_t *menu,int item); | ||
256 | void M_WriteText(int x, int y, const char *string); | ||
257 | int M_StringWidth(const char *string); | ||
258 | int M_StringHeight(const char *string); | ||
259 | void M_StartMessage(const char *string,void *routine,boolean input); | ||
260 | void M_StopMessage(void); | ||
261 | void M_ClearMenus (void); | ||
262 | |||
263 | // phares 3/30/98 | ||
264 | // prototypes added to support Setup Menus and Extended HELP screens | ||
265 | |||
266 | int M_GetKeyString(int,int); | ||
267 | void M_Setup(int choice); | ||
268 | void M_KeyBindings(int choice); | ||
269 | void M_Weapons(int); | ||
270 | void M_StatusBar(int); | ||
271 | void M_Automap(int); | ||
272 | void M_Enemy(int); | ||
273 | void M_Messages(int); | ||
274 | void M_ChatStrings(int); | ||
275 | void M_InitExtendedHelp(void); | ||
276 | void M_ExtHelpNextScreen(int); | ||
277 | void M_ExtHelp(int); | ||
278 | static int M_GetPixelWidth(const char*); | ||
279 | void M_DrawKeybnd(void); | ||
280 | void M_DrawWeapons(void); | ||
281 | static void M_DrawMenuString(int,int,int); | ||
282 | static void M_DrawStringCentered(int,int,int,const char*); | ||
283 | void M_DrawStatusHUD(void); | ||
284 | void M_DrawExtHelp(void); | ||
285 | void M_DrawAutoMap(void); | ||
286 | void M_DrawEnemy(void); | ||
287 | void M_DrawMessages(void); | ||
288 | void M_DrawChatStrings(void); | ||
289 | void M_Compat(int); // killough 10/98 | ||
290 | void M_ChangeDemoSmoothTurns(void); | ||
291 | void M_General(int); // killough 10/98 | ||
292 | void M_DrawCompat(void); // killough 10/98 | ||
293 | void M_DrawGeneral(void); // killough 10/98 | ||
294 | void M_FullScreen(void); // nathanh 01/01 | ||
295 | |||
296 | menu_t NewDef; // phares 5/04/98 | ||
297 | |||
298 | // end of prototypes added to support Setup Menus and Extended HELP screens | ||
299 | |||
300 | ///////////////////////////////////////////////////////////////////////////// | ||
301 | // | ||
302 | // DOOM MENUS | ||
303 | // | ||
304 | |||
305 | ///////////////////////////// | ||
306 | // | ||
307 | // MAIN MENU | ||
308 | // | ||
309 | |||
310 | // main_e provides numerical values for which Big Font screen you're on | ||
311 | |||
312 | enum | ||
313 | { | ||
314 | newgame = 0, | ||
315 | loadgame, | ||
316 | savegame, | ||
317 | options, | ||
318 | readthis, | ||
319 | quitdoom, | ||
320 | main_end | ||
321 | } main_e; | ||
322 | |||
323 | // | ||
324 | // MainMenu is the definition of what the main menu Screen should look | ||
325 | // like. Each entry shows that the cursor can land on each item (1), the | ||
326 | // built-in graphic lump (i.e. "M_NGAME") that should be displayed, | ||
327 | // the program which takes over when an item is selected, and the hotkey | ||
328 | // associated with the item. | ||
329 | // | ||
330 | |||
331 | menuitem_t MainMenu[]= | ||
332 | { | ||
333 | {1,"M_NGAME", M_NewGame, 'n'}, | ||
334 | {1,"M_OPTION",M_Options, 'o'}, | ||
335 | {1,"M_LOADG", M_LoadGame,'l'}, | ||
336 | {1,"M_SAVEG", M_SaveGame,'s'}, | ||
337 | // Another hickup with Special edition. | ||
338 | {1,"M_RDTHIS",M_ReadThis,'r'}, | ||
339 | {1,"M_QUITG", M_QuitDOOM,'q'} | ||
340 | }; | ||
341 | |||
342 | menu_t MainDef = | ||
343 | { | ||
344 | main_end, // number of menu items | ||
345 | NULL, // previous menu screen | ||
346 | MainMenu, // table that defines menu items | ||
347 | M_DrawMainMenu, // drawing routine | ||
348 | 97,64, // initial cursor position | ||
349 | 0 // last menu item the user was on | ||
350 | }; | ||
351 | |||
352 | // | ||
353 | // M_DrawMainMenu | ||
354 | // | ||
355 | |||
356 | void M_DrawMainMenu(void) | ||
357 | { | ||
358 | // CPhipps - patch drawing updated | ||
359 | V_DrawNamePatch(94, 2, 0, "M_DOOM", CR_DEFAULT, VPT_STRETCH); | ||
360 | } | ||
361 | |||
362 | ///////////////////////////// | ||
363 | // | ||
364 | // Read This! MENU 1 & 2 | ||
365 | // | ||
366 | |||
367 | // There are no menu items on the Read This! screens, so read_e just | ||
368 | // provides a placeholder to maintain structure. | ||
369 | |||
370 | enum | ||
371 | { | ||
372 | rdthsempty1, | ||
373 | read1_end | ||
374 | } read_e; | ||
375 | |||
376 | enum | ||
377 | { | ||
378 | rdthsempty2, | ||
379 | read2_end | ||
380 | } read_e2; | ||
381 | |||
382 | enum // killough 10/98 | ||
383 | { | ||
384 | helpempty, | ||
385 | help_end | ||
386 | } help_e; | ||
387 | |||
388 | |||
389 | // The definitions of the Read This! screens | ||
390 | |||
391 | menuitem_t ReadMenu1[] = | ||
392 | { | ||
393 | {1,"",M_ReadThis2,0} | ||
394 | }; | ||
395 | |||
396 | menuitem_t ReadMenu2[]= | ||
397 | { | ||
398 | {1,"",M_FinishReadThis,0} | ||
399 | }; | ||
400 | |||
401 | menuitem_t HelpMenu[]= // killough 10/98 | ||
402 | { | ||
403 | {1,"",M_FinishHelp,0} | ||
404 | }; | ||
405 | |||
406 | menu_t ReadDef1 = | ||
407 | { | ||
408 | read1_end, | ||
409 | &MainDef, | ||
410 | ReadMenu1, | ||
411 | M_DrawReadThis1, | ||
412 | 330,175, | ||
413 | //280,185, // killough 2/21/98: fix help screens | ||
414 | 0 | ||
415 | }; | ||
416 | |||
417 | menu_t ReadDef2 = | ||
418 | { | ||
419 | read2_end, | ||
420 | &ReadDef1, | ||
421 | ReadMenu2, | ||
422 | M_DrawReadThis2, | ||
423 | 330,175, | ||
424 | 0 | ||
425 | }; | ||
426 | |||
427 | menu_t HelpDef = // killough 10/98 | ||
428 | { | ||
429 | help_end, | ||
430 | &HelpDef, | ||
431 | HelpMenu, | ||
432 | M_DrawHelp, | ||
433 | 330,175, | ||
434 | 0 | ||
435 | }; | ||
436 | |||
437 | // | ||
438 | // M_ReadThis | ||
439 | // | ||
440 | |||
441 | void M_ReadThis(int choice) | ||
442 | { | ||
443 | M_SetupNextMenu(&ReadDef1); | ||
444 | } | ||
445 | |||
446 | void M_ReadThis2(int choice) | ||
447 | { | ||
448 | M_SetupNextMenu(&ReadDef2); | ||
449 | } | ||
450 | |||
451 | void M_FinishReadThis(int choice) | ||
452 | { | ||
453 | M_SetupNextMenu(&MainDef); | ||
454 | } | ||
455 | |||
456 | void M_FinishHelp(int choice) // killough 10/98 | ||
457 | { | ||
458 | M_SetupNextMenu(&MainDef); | ||
459 | } | ||
460 | |||
461 | // | ||
462 | // Read This Menus | ||
463 | // Had a "quick hack to fix romero bug" | ||
464 | // | ||
465 | // killough 10/98: updated with new screens | ||
466 | |||
467 | void M_DrawReadThis1(void) | ||
468 | { | ||
469 | inhelpscreens = true; | ||
470 | if (gamemode == shareware) | ||
471 | V_DrawNamePatch(0, 0, 0, "HELP2", CR_DEFAULT, VPT_STRETCH); | ||
472 | else | ||
473 | M_DrawCredits(); | ||
474 | } | ||
475 | |||
476 | // | ||
477 | // Read This Menus - optional second page. | ||
478 | // | ||
479 | // killough 10/98: updated with new screens | ||
480 | |||
481 | void M_DrawReadThis2(void) | ||
482 | { | ||
483 | inhelpscreens = true; | ||
484 | if (gamemode == shareware) | ||
485 | M_DrawCredits(); | ||
486 | else | ||
487 | V_DrawNamePatch(0, 0, 0, "CREDIT", CR_DEFAULT, VPT_STRETCH); | ||
488 | } | ||
489 | |||
490 | ///////////////////////////// | ||
491 | // | ||
492 | // EPISODE SELECT | ||
493 | // | ||
494 | |||
495 | // | ||
496 | // episodes_e provides numbers for the episode menu items. The default is | ||
497 | // 4, to accomodate Ultimate Doom. If the user is running anything else, | ||
498 | // this is accounted for in the code. | ||
499 | // | ||
500 | |||
501 | enum | ||
502 | { | ||
503 | ep1, | ||
504 | ep2, | ||
505 | ep3, | ||
506 | ep4, | ||
507 | ep_end | ||
508 | } episodes_e; | ||
509 | |||
510 | // The definitions of the Episodes menu | ||
511 | |||
512 | menuitem_t EpisodeMenu[]= | ||
513 | { | ||
514 | {1,"M_EPI1", M_Episode,'k'}, | ||
515 | {1,"M_EPI2", M_Episode,'t'}, | ||
516 | {1,"M_EPI3", M_Episode,'i'}, | ||
517 | {1,"M_EPI4", M_Episode,'t'} | ||
518 | }; | ||
519 | |||
520 | menu_t EpiDef = | ||
521 | { | ||
522 | ep_end, // # of menu items | ||
523 | &MainDef, // previous menu | ||
524 | EpisodeMenu, // menuitem_t -> | ||
525 | M_DrawEpisode, // drawing routine -> | ||
526 | 48,63, // x,y | ||
527 | ep1 // lastOn | ||
528 | }; | ||
529 | |||
530 | // | ||
531 | // M_Episode | ||
532 | // | ||
533 | int epi; | ||
534 | |||
535 | void M_DrawEpisode(void) | ||
536 | { | ||
537 | // CPhipps - patch drawing updated | ||
538 | V_DrawNamePatch(54, 38, 0, "M_EPISOD", CR_DEFAULT, VPT_STRETCH); | ||
539 | } | ||
540 | |||
541 | void M_Episode(int choice) | ||
542 | { | ||
543 | if ( (gamemode == shareware) && choice) { | ||
544 | M_StartMessage(s_SWSTRING,NULL,false); // Ty 03/27/98 - externalized | ||
545 | M_SetupNextMenu(&ReadDef1); | ||
546 | return; | ||
547 | } | ||
548 | |||
549 | // Yet another hack... | ||
550 | if ( (gamemode == registered) && (choice > 2)) | ||
551 | { | ||
552 | lprintf( LO_WARN, | ||
553 | "M_Episode: 4th episode requires UltimateDOOM\n"); | ||
554 | choice = 0; | ||
555 | } | ||
556 | |||
557 | epi = choice; | ||
558 | M_SetupNextMenu(&NewDef); | ||
559 | } | ||
560 | |||
561 | ///////////////////////////// | ||
562 | // | ||
563 | // NEW GAME | ||
564 | // | ||
565 | |||
566 | // numerical values for the New Game menu items | ||
567 | |||
568 | enum | ||
569 | { | ||
570 | killthings, | ||
571 | toorough, | ||
572 | hurtme, | ||
573 | violence, | ||
574 | nightmare, | ||
575 | newg_end | ||
576 | } newgame_e; | ||
577 | |||
578 | // The definitions of the New Game menu | ||
579 | |||
580 | menuitem_t NewGameMenu[]= | ||
581 | { | ||
582 | {1,"M_JKILL", M_ChooseSkill, 'i'}, | ||
583 | {1,"M_ROUGH", M_ChooseSkill, 'h'}, | ||
584 | {1,"M_HURT", M_ChooseSkill, 'h'}, | ||
585 | {1,"M_ULTRA", M_ChooseSkill, 'u'}, | ||
586 | {1,"M_NMARE", M_ChooseSkill, 'n'} | ||
587 | }; | ||
588 | |||
589 | menu_t NewDef = | ||
590 | { | ||
591 | newg_end, // # of menu items | ||
592 | &EpiDef, // previous menu | ||
593 | NewGameMenu, // menuitem_t -> | ||
594 | M_DrawNewGame, // drawing routine -> | ||
595 | 48,63, // x,y | ||
596 | hurtme // lastOn | ||
597 | }; | ||
598 | |||
599 | // | ||
600 | // M_NewGame | ||
601 | // | ||
602 | |||
603 | void M_DrawNewGame(void) | ||
604 | { | ||
605 | // CPhipps - patch drawing updated | ||
606 | V_DrawNamePatch(96, 14, 0, "M_NEWG", CR_DEFAULT, VPT_STRETCH); | ||
607 | V_DrawNamePatch(54, 38, 0, "M_SKILL",CR_DEFAULT, VPT_STRETCH); | ||
608 | } | ||
609 | |||
610 | /* cph - make `New Game' restart the level in a netgame */ | ||
611 | static void M_RestartLevelResponse(int ch) | ||
612 | { | ||
613 | if (ch != 'y') | ||
614 | return; | ||
615 | |||
616 | if (demorecording) | ||
617 | exit(0); | ||
618 | |||
619 | currentMenu->lastOn = itemOn; | ||
620 | M_ClearMenus (); | ||
621 | G_RestartLevel (); | ||
622 | } | ||
623 | |||
624 | void M_NewGame(int choice) | ||
625 | { | ||
626 | if (netgame && !demoplayback) { | ||
627 | if (compatibility_level < lxdoom_1_compatibility) | ||
628 | M_StartMessage(s_NEWGAME,NULL,false); // Ty 03/27/98 - externalized | ||
629 | else // CPhipps - query restarting the level | ||
630 | M_StartMessage(s_RESTARTLEVEL,M_RestartLevelResponse,true); | ||
631 | return; | ||
632 | } | ||
633 | |||
634 | if (demorecording) { /* killough 5/26/98: exclude during demo recordings */ | ||
635 | M_StartMessage("you can't start a new game\n" | ||
636 | "while recording a demo!\n\n"PRESSKEY, | ||
637 | NULL, false); // killough 5/26/98: not externalized | ||
638 | return; | ||
639 | } | ||
640 | |||
641 | if ( gamemode == commercial ) | ||
642 | M_SetupNextMenu(&NewDef); | ||
643 | else | ||
644 | M_SetupNextMenu(&EpiDef); | ||
645 | } | ||
646 | |||
647 | // CPhipps - static | ||
648 | static void M_VerifyNightmare(int ch) | ||
649 | { | ||
650 | if (ch != 'y') | ||
651 | return; | ||
652 | |||
653 | G_DeferedInitNew(nightmare,epi+1,1); | ||
654 | M_ClearMenus (); | ||
655 | } | ||
656 | |||
657 | void M_ChooseSkill(int choice) | ||
658 | { | ||
659 | if (choice == nightmare) | ||
660 | { // Ty 03/27/98 - externalized | ||
661 | M_StartMessage(s_NIGHTMARE,M_VerifyNightmare,true); | ||
662 | return; | ||
663 | } | ||
664 | |||
665 | G_DeferedInitNew(choice,epi+1,1); | ||
666 | M_ClearMenus (); | ||
667 | } | ||
668 | |||
669 | ///////////////////////////// | ||
670 | // | ||
671 | // LOAD GAME MENU | ||
672 | // | ||
673 | |||
674 | // numerical values for the Load Game slots | ||
675 | |||
676 | enum | ||
677 | { | ||
678 | load1, | ||
679 | load2, | ||
680 | load3, | ||
681 | load4, | ||
682 | load5, | ||
683 | load6, | ||
684 | load7, //jff 3/15/98 extend number of slots | ||
685 | load8, | ||
686 | load_end | ||
687 | } load_e; | ||
688 | |||
689 | // The definitions of the Load Game screen | ||
690 | |||
691 | menuitem_t LoadMenue[]= | ||
692 | { | ||
693 | {1,"", M_LoadSelect,'1'}, | ||
694 | {1,"", M_LoadSelect,'2'}, | ||
695 | {1,"", M_LoadSelect,'3'}, | ||
696 | {1,"", M_LoadSelect,'4'}, | ||
697 | {1,"", M_LoadSelect,'5'}, | ||
698 | {1,"", M_LoadSelect,'6'}, | ||
699 | {1,"", M_LoadSelect,'7'}, //jff 3/15/98 extend number of slots | ||
700 | {1,"", M_LoadSelect,'8'}, | ||
701 | }; | ||
702 | |||
703 | menu_t LoadDef = | ||
704 | { | ||
705 | load_end, | ||
706 | &MainDef, | ||
707 | LoadMenue, | ||
708 | M_DrawLoad, | ||
709 | 80,34, //jff 3/15/98 move menu up | ||
710 | 0 | ||
711 | }; | ||
712 | |||
713 | #define LOADGRAPHIC_Y 8 | ||
714 | |||
715 | // | ||
716 | // M_LoadGame & Cie. | ||
717 | // | ||
718 | |||
719 | void M_DrawLoad(void) | ||
720 | { | ||
721 | int i; | ||
722 | |||
723 | //jff 3/15/98 use symbolic load position | ||
724 | // CPhipps - patch drawing updated | ||
725 | V_DrawNamePatch(72 ,LOADGRAPHIC_Y, 0, "M_LOADG", CR_DEFAULT, VPT_STRETCH); | ||
726 | for (i = 0 ; i < load_end ; i++) { | ||
727 | M_DrawSaveLoadBorder(LoadDef.x,LoadDef.y+LINEHEIGHT*i); | ||
728 | M_WriteText(LoadDef.x,LoadDef.y+LINEHEIGHT*i,savegamestrings[i]); | ||
729 | } | ||
730 | } | ||
731 | |||
732 | // | ||
733 | // Draw border for the savegame description | ||
734 | // | ||
735 | |||
736 | void M_DrawSaveLoadBorder(int x,int y) | ||
737 | { | ||
738 | int i; | ||
739 | |||
740 | V_DrawNamePatch(x-8, y+7, 0, "M_LSLEFT", CR_DEFAULT, VPT_STRETCH); | ||
741 | |||
742 | for (i = 0 ; i < 24 ; i++) | ||
743 | { | ||
744 | V_DrawNamePatch(x, y+7, 0, "M_LSCNTR", CR_DEFAULT, VPT_STRETCH); | ||
745 | x += 8; | ||
746 | } | ||
747 | |||
748 | V_DrawNamePatch(x, y+7, 0, "M_LSRGHT", CR_DEFAULT, VPT_STRETCH); | ||
749 | } | ||
750 | |||
751 | // | ||
752 | // User wants to load this game | ||
753 | // | ||
754 | |||
755 | void M_LoadSelect(int choice) | ||
756 | { | ||
757 | // CPhipps - Modified so savegame filename is worked out only internal | ||
758 | // to g_game.c, this only passes the slot. | ||
759 | |||
760 | G_LoadGame(choice, false); // killough 3/16/98, 5/15/98: add slot, cmd | ||
761 | |||
762 | M_ClearMenus (); | ||
763 | } | ||
764 | |||
765 | // | ||
766 | // killough 5/15/98: add forced loadgames | ||
767 | // | ||
768 | |||
769 | static void M_VerifyForcedLoadGame(int ch) | ||
770 | { | ||
771 | if (ch=='y') | ||
772 | G_ForcedLoadGame(); | ||
773 | free((char*)messageString); // free the message strdup()'ed below | ||
774 | M_ClearMenus(); | ||
775 | } | ||
776 | |||
777 | void M_ForcedLoadGame(const char *msg) | ||
778 | { | ||
779 | M_StartMessage(strdup(msg), M_VerifyForcedLoadGame, true); // free()'d above | ||
780 | } | ||
781 | |||
782 | // | ||
783 | // Selected from DOOM menu | ||
784 | // | ||
785 | |||
786 | void M_LoadGame (int choice) | ||
787 | { | ||
788 | /* killough 5/26/98: exclude during demo recordings | ||
789 | * cph - unless a new demo */ | ||
790 | if (demorecording && (compatibility_level < prboom_2_compatibility)) | ||
791 | { | ||
792 | M_StartMessage("you can't load a game\n" | ||
793 | "while recording an old demo!\n\n"PRESSKEY, | ||
794 | NULL, false); // killough 5/26/98: not externalized | ||
795 | return; | ||
796 | } | ||
797 | |||
798 | M_SetupNextMenu(&LoadDef); | ||
799 | M_ReadSaveStrings(); | ||
800 | } | ||
801 | |||
802 | ///////////////////////////// | ||
803 | // | ||
804 | // SAVE GAME MENU | ||
805 | // | ||
806 | |||
807 | // The definitions of the Save Game screen | ||
808 | |||
809 | menuitem_t SaveMenu[]= | ||
810 | { | ||
811 | {1,"", M_SaveSelect,'1'}, | ||
812 | {1,"", M_SaveSelect,'2'}, | ||
813 | {1,"", M_SaveSelect,'3'}, | ||
814 | {1,"", M_SaveSelect,'4'}, | ||
815 | {1,"", M_SaveSelect,'5'}, | ||
816 | {1,"", M_SaveSelect,'6'}, | ||
817 | {1,"", M_SaveSelect,'7'}, //jff 3/15/98 extend number of slots | ||
818 | {1,"", M_SaveSelect,'8'}, | ||
819 | }; | ||
820 | |||
821 | menu_t SaveDef = | ||
822 | { | ||
823 | load_end, // same number of slots as the Load Game screen | ||
824 | &MainDef, | ||
825 | SaveMenu, | ||
826 | M_DrawSave, | ||
827 | 80,34, //jff 3/15/98 move menu up | ||
828 | 0 | ||
829 | }; | ||
830 | |||
831 | // | ||
832 | // M_ReadSaveStrings | ||
833 | // read the strings from the savegame files | ||
834 | // | ||
835 | void M_ReadSaveStrings(void) | ||
836 | { | ||
837 | int i; | ||
838 | |||
839 | for (i = 0 ; i < load_end ; i++) { | ||
840 | char name[PATH_MAX+1]; // killough 3/22/98 | ||
841 | FILE *fp; // killough 11/98: change to use stdio | ||
842 | |||
843 | /* killough 3/22/98 | ||
844 | * cph - add not-demoplayback parameter */ | ||
845 | G_SaveGameName(name,sizeof(name),i,false); | ||
846 | fp = fopen(name,"rb"); | ||
847 | if (!fp) { // Ty 03/27/98 - externalized: | ||
848 | strcpy(&savegamestrings[i][0],s_EMPTYSTRING); | ||
849 | LoadMenue[i].status = 0; | ||
850 | continue; | ||
851 | } | ||
852 | fread(&savegamestrings[i], SAVESTRINGSIZE, 1, fp); | ||
853 | fclose(fp); | ||
854 | LoadMenue[i].status = 1; | ||
855 | } | ||
856 | } | ||
857 | |||
858 | // | ||
859 | // M_SaveGame & Cie. | ||
860 | // | ||
861 | void M_DrawSave(void) | ||
862 | { | ||
863 | int i; | ||
864 | |||
865 | //jff 3/15/98 use symbolic load position | ||
866 | // CPhipps - patch drawing updated | ||
867 | V_DrawNamePatch(72, LOADGRAPHIC_Y, 0, "M_SAVEG", CR_DEFAULT, VPT_STRETCH); | ||
868 | for (i = 0 ; i < load_end ; i++) | ||
869 | { | ||
870 | M_DrawSaveLoadBorder(LoadDef.x,LoadDef.y+LINEHEIGHT*i); | ||
871 | M_WriteText(LoadDef.x,LoadDef.y+LINEHEIGHT*i,savegamestrings[i]); | ||
872 | } | ||
873 | |||
874 | if (saveStringEnter) | ||
875 | { | ||
876 | i = M_StringWidth(savegamestrings[saveSlot]); | ||
877 | M_WriteText(LoadDef.x + i,LoadDef.y+LINEHEIGHT*saveSlot,"_"); | ||
878 | } | ||
879 | } | ||
880 | |||
881 | // | ||
882 | // M_Responder calls this when user is finished | ||
883 | // | ||
884 | static void M_DoSave(int slot) | ||
885 | { | ||
886 | G_SaveGame (slot,savegamestrings[slot]); | ||
887 | M_ClearMenus (); | ||
888 | |||
889 | // PICK QUICKSAVE SLOT YET? | ||
890 | if (quickSaveSlot == -2) | ||
891 | quickSaveSlot = slot; | ||
892 | } | ||
893 | |||
894 | // | ||
895 | // User wants to save. Start string input for M_Responder | ||
896 | // | ||
897 | void M_SaveSelect(int choice) | ||
898 | { | ||
899 | // we are going to be intercepting all chars | ||
900 | saveStringEnter = 1; | ||
901 | |||
902 | saveSlot = choice; | ||
903 | strcpy(saveOldString,savegamestrings[choice]); | ||
904 | if (!strcmp(savegamestrings[choice],s_EMPTYSTRING)) // Ty 03/27/98 - externalized | ||
905 | savegamestrings[choice][0] = 0; | ||
906 | saveCharIndex = strlen(savegamestrings[choice]); | ||
907 | } | ||
908 | |||
909 | // | ||
910 | // Selected from DOOM menu | ||
911 | // | ||
912 | void M_SaveGame (int choice) | ||
913 | { | ||
914 | // killough 10/6/98: allow savegames during single-player demo playback | ||
915 | if (!usergame && (!demoplayback || netgame)) | ||
916 | { | ||
917 | M_StartMessage(s_SAVEDEAD,NULL,false); // Ty 03/27/98 - externalized | ||
918 | return; | ||
919 | } | ||
920 | |||
921 | if (gamestate != GS_LEVEL) | ||
922 | return; | ||
923 | |||
924 | M_SetupNextMenu(&SaveDef); | ||
925 | M_ReadSaveStrings(); | ||
926 | } | ||
927 | |||
928 | ///////////////////////////// | ||
929 | // | ||
930 | // OPTIONS MENU | ||
931 | // | ||
932 | |||
933 | // numerical values for the Options menu items | ||
934 | |||
935 | enum | ||
936 | { | ||
937 | general, // killough 10/98 | ||
938 | // killough 4/6/98: move setup to be a sub-menu of OPTIONs | ||
939 | setup, // phares 3/21/98 | ||
940 | endgame, | ||
941 | messages, | ||
942 | /* detail, obsolete -- killough */ | ||
943 | scrnsize, | ||
944 | option_empty1, | ||
945 | mousesens, | ||
946 | /* option_empty2, submenu now -- killough */ | ||
947 | soundvol, | ||
948 | opt_end | ||
949 | } options_e; | ||
950 | |||
951 | // The definitions of the Options menu | ||
952 | |||
953 | menuitem_t OptionsMenu[]= | ||
954 | { | ||
955 | // killough 4/6/98: move setup to be a sub-menu of OPTIONs | ||
956 | {1,"M_GENERL", M_General, 'g'}, // killough 10/98 | ||
957 | {1,"M_SETUP", M_Setup, 's'}, // phares 3/21/98 | ||
958 | {1,"M_ENDGAM", M_EndGame,'e'}, | ||
959 | {1,"M_MESSG", M_ChangeMessages,'m'}, | ||
960 | /* {1,"M_DETAIL", M_ChangeDetail,'g'}, unused -- killough */ | ||
961 | {2,"M_SCRNSZ", M_SizeDisplay,'s'}, | ||
962 | {-1,"",0}, | ||
963 | {1,"M_MSENS", M_ChangeSensitivity,'m'}, | ||
964 | /* {-1,"",0}, replaced with submenu -- killough */ | ||
965 | {1,"M_SVOL", M_Sound,'s'} | ||
966 | }; | ||
967 | |||
968 | menu_t OptionsDef = | ||
969 | { | ||
970 | opt_end, | ||
971 | &MainDef, | ||
972 | OptionsMenu, | ||
973 | M_DrawOptions, | ||
974 | 60,37, | ||
975 | 0 | ||
976 | }; | ||
977 | |||
978 | // | ||
979 | // M_Options | ||
980 | // | ||
981 | char detailNames[2][9] = {"M_GDHIGH","M_GDLOW"}; | ||
982 | char msgNames[2][9] = {"M_MSGOFF","M_MSGON"}; | ||
983 | |||
984 | |||
985 | void M_DrawOptions(void) | ||
986 | { | ||
987 | // CPhipps - patch drawing updated | ||
988 | // proff/nicolas 09/20/98 -- changed for hi-res | ||
989 | V_DrawNamePatch(108, 15, 0, "M_OPTTTL", CR_DEFAULT, VPT_STRETCH); | ||
990 | |||
991 | V_DrawNamePatch(OptionsDef.x + 120, OptionsDef.y+LINEHEIGHT*messages, 0, | ||
992 | msgNames[showMessages], CR_DEFAULT, VPT_STRETCH); | ||
993 | |||
994 | M_DrawThermo(OptionsDef.x,OptionsDef.y+LINEHEIGHT*(scrnsize+1), | ||
995 | 9,screenSize); | ||
996 | } | ||
997 | |||
998 | void M_Options(int choice) | ||
999 | { | ||
1000 | M_SetupNextMenu(&OptionsDef); | ||
1001 | } | ||
1002 | |||
1003 | ///////////////////////////// | ||
1004 | // | ||
1005 | // M_QuitDOOM | ||
1006 | // | ||
1007 | int quitsounds[8] = | ||
1008 | { | ||
1009 | sfx_pldeth, | ||
1010 | sfx_dmpain, | ||
1011 | sfx_popain, | ||
1012 | sfx_slop, | ||
1013 | sfx_telept, | ||
1014 | sfx_posit1, | ||
1015 | sfx_posit3, | ||
1016 | sfx_sgtatk | ||
1017 | }; | ||
1018 | |||
1019 | int quitsounds2[8] = | ||
1020 | { | ||
1021 | sfx_vilact, | ||
1022 | sfx_getpow, | ||
1023 | sfx_boscub, | ||
1024 | sfx_slop, | ||
1025 | sfx_skeswg, | ||
1026 | sfx_kntdth, | ||
1027 | sfx_bspact, | ||
1028 | sfx_sgtatk | ||
1029 | }; | ||
1030 | |||
1031 | static void M_QuitResponse(int ch) | ||
1032 | { | ||
1033 | if (ch != 'y') | ||
1034 | return; | ||
1035 | if ((!netgame || demoplayback) // killough 12/98 | ||
1036 | && !nosfxparm && snd_card) // avoid delay if no sound card | ||
1037 | { | ||
1038 | int i; | ||
1039 | |||
1040 | if (gamemode == commercial) | ||
1041 | S_StartSound(NULL,quitsounds2[(gametic>>2)&7]); | ||
1042 | else | ||
1043 | S_StartSound(NULL,quitsounds[(gametic>>2)&7]); | ||
1044 | |||
1045 | // wait till all sounds stopped or 3 seconds are over | ||
1046 | i = 30; | ||
1047 | while (i>0) { | ||
1048 | I_uSleep(100000); // CPhipps - don't thrash cpu in this loop | ||
1049 | if (!I_AnySoundStillPlaying()) | ||
1050 | break; | ||
1051 | i--; | ||
1052 | } | ||
1053 | } | ||
1054 | exit(0); // killough | ||
1055 | } | ||
1056 | |||
1057 | void M_QuitDOOM(int choice) | ||
1058 | { | ||
1059 | static char endstring[160]; | ||
1060 | |||
1061 | // We pick index 0 which is language sensitive, | ||
1062 | // or one at random, between 1 and maximum number. | ||
1063 | // Ty 03/27/98 - externalized DOSY as a string s_DOSY that's in the sprintf | ||
1064 | if (language != english) | ||
1065 | sprintf(endstring,"%s\n\n%s",s_DOSY, endmsg[0] ); | ||
1066 | else // killough 1/18/98: fix endgame message calculation: | ||
1067 | sprintf(endstring,"%s\n\n%s", endmsg[gametic%(NUM_QUITMESSAGES-1)+1], s_DOSY); | ||
1068 | |||
1069 | M_StartMessage(endstring,M_QuitResponse,true); | ||
1070 | } | ||
1071 | |||
1072 | ///////////////////////////// | ||
1073 | // | ||
1074 | // SOUND VOLUME MENU | ||
1075 | // | ||
1076 | |||
1077 | // numerical values for the Sound Volume menu items | ||
1078 | // The 'empty' slots are where the sliding scales appear. | ||
1079 | |||
1080 | enum | ||
1081 | { | ||
1082 | sfx_vol, | ||
1083 | sfx_empty1, | ||
1084 | music_vol, | ||
1085 | sfx_empty2, | ||
1086 | sound_end | ||
1087 | } sound_e; | ||
1088 | |||
1089 | // The definitions of the Sound Volume menu | ||
1090 | |||
1091 | menuitem_t SoundMenu[]= | ||
1092 | { | ||
1093 | {2,"M_SFXVOL",M_SfxVol,'s'}, | ||
1094 | {-1,"",0}, | ||
1095 | {2,"M_MUSVOL",M_MusicVol,'m'}, | ||
1096 | {-1,"",0} | ||
1097 | }; | ||
1098 | |||
1099 | menu_t SoundDef = | ||
1100 | { | ||
1101 | sound_end, | ||
1102 | &OptionsDef, | ||
1103 | SoundMenu, | ||
1104 | M_DrawSound, | ||
1105 | 80,64, | ||
1106 | 0 | ||
1107 | }; | ||
1108 | |||
1109 | // | ||
1110 | // Change Sfx & Music volumes | ||
1111 | // | ||
1112 | |||
1113 | void M_DrawSound(void) | ||
1114 | { | ||
1115 | // CPhipps - patch drawing updated | ||
1116 | V_DrawNamePatch(60, 38, 0, "M_SVOL", CR_DEFAULT, VPT_STRETCH); | ||
1117 | |||
1118 | M_DrawThermo(SoundDef.x,SoundDef.y+LINEHEIGHT*(sfx_vol+1),16,snd_SfxVolume); | ||
1119 | |||
1120 | M_DrawThermo(SoundDef.x,SoundDef.y+LINEHEIGHT*(music_vol+1),16,snd_MusicVolume); | ||
1121 | } | ||
1122 | |||
1123 | void M_Sound(int choice) | ||
1124 | { | ||
1125 | M_SetupNextMenu(&SoundDef); | ||
1126 | } | ||
1127 | |||
1128 | void M_SfxVol(int choice) | ||
1129 | { | ||
1130 | switch(choice) | ||
1131 | { | ||
1132 | case 0: | ||
1133 | if (snd_SfxVolume) | ||
1134 | snd_SfxVolume--; | ||
1135 | break; | ||
1136 | case 1: | ||
1137 | if (snd_SfxVolume < 15) | ||
1138 | snd_SfxVolume++; | ||
1139 | break; | ||
1140 | } | ||
1141 | |||
1142 | S_SetSfxVolume(snd_SfxVolume /* *8 */); | ||
1143 | } | ||
1144 | |||
1145 | void M_MusicVol(int choice) | ||
1146 | { | ||
1147 | switch(choice) | ||
1148 | { | ||
1149 | case 0: | ||
1150 | if (snd_MusicVolume) | ||
1151 | snd_MusicVolume--; | ||
1152 | break; | ||
1153 | case 1: | ||
1154 | if (snd_MusicVolume < 15) | ||
1155 | snd_MusicVolume++; | ||
1156 | break; | ||
1157 | } | ||
1158 | |||
1159 | S_SetMusicVolume(snd_MusicVolume /* *8 */); | ||
1160 | } | ||
1161 | |||
1162 | ///////////////////////////// | ||
1163 | // | ||
1164 | // MOUSE SENSITIVITY MENU -- killough | ||
1165 | // | ||
1166 | |||
1167 | // numerical values for the Mouse Sensitivity menu items | ||
1168 | // The 'empty' slots are where the sliding scales appear. | ||
1169 | |||
1170 | enum | ||
1171 | { | ||
1172 | mouse_horiz, | ||
1173 | mouse_empty1, | ||
1174 | mouse_vert, | ||
1175 | mouse_empty2, | ||
1176 | mouse_end | ||
1177 | } mouse_e; | ||
1178 | |||
1179 | // The definitions of the Mouse Sensitivity menu | ||
1180 | |||
1181 | menuitem_t MouseMenu[]= | ||
1182 | { | ||
1183 | {2,"M_HORSEN",M_MouseHoriz,'h'}, | ||
1184 | {-1,"",0}, | ||
1185 | {2,"M_VERSEN",M_MouseVert,'v'}, | ||
1186 | {-1,"",0} | ||
1187 | }; | ||
1188 | |||
1189 | menu_t MouseDef = | ||
1190 | { | ||
1191 | mouse_end, | ||
1192 | &OptionsDef, | ||
1193 | MouseMenu, | ||
1194 | M_DrawMouse, | ||
1195 | 60,64, | ||
1196 | 0 | ||
1197 | }; | ||
1198 | |||
1199 | |||
1200 | // I'm using a scale of 100 since I don't know what's normal -- killough. | ||
1201 | |||
1202 | #define MOUSE_SENS_MAX 100 | ||
1203 | |||
1204 | // | ||
1205 | // Change Mouse Sensitivities -- killough | ||
1206 | // | ||
1207 | |||
1208 | void M_DrawMouse(void) | ||
1209 | { | ||
1210 | int mhmx,mvmx; /* jff 4/3/98 clamp drawn position 99max mead */ | ||
1211 | |||
1212 | // CPhipps - patch drawing updated | ||
1213 | V_DrawNamePatch(60, 38, 0, "M_MSENS", CR_DEFAULT, VPT_STRETCH); | ||
1214 | |||
1215 | //jff 4/3/98 clamp horizontal sensitivity display | ||
1216 | mhmx = mouseSensitivity_horiz>99? 99 : mouseSensitivity_horiz; /*mead*/ | ||
1217 | M_DrawThermo(MouseDef.x,MouseDef.y+LINEHEIGHT*(mouse_horiz+1),100,mhmx); | ||
1218 | //jff 4/3/98 clamp vertical sensitivity display | ||
1219 | mvmx = mouseSensitivity_vert>99? 99 : mouseSensitivity_vert; /*mead*/ | ||
1220 | M_DrawThermo(MouseDef.x,MouseDef.y+LINEHEIGHT*(mouse_vert+1),100,mvmx); | ||
1221 | } | ||
1222 | |||
1223 | void M_ChangeSensitivity(int choice) | ||
1224 | { | ||
1225 | M_SetupNextMenu(&MouseDef); // killough | ||
1226 | |||
1227 | // switch(choice) | ||
1228 | // { | ||
1229 | // case 0: | ||
1230 | // if (mouseSensitivity) | ||
1231 | // mouseSensitivity--; | ||
1232 | // break; | ||
1233 | // case 1: | ||
1234 | // if (mouseSensitivity < 9) | ||
1235 | // mouseSensitivity++; | ||
1236 | // break; | ||
1237 | // } | ||
1238 | } | ||
1239 | |||
1240 | void M_MouseHoriz(int choice) | ||
1241 | { | ||
1242 | M_Mouse(choice, &mouseSensitivity_horiz); | ||
1243 | } | ||
1244 | |||
1245 | void M_MouseVert(int choice) | ||
1246 | { | ||
1247 | M_Mouse(choice, &mouseSensitivity_vert); | ||
1248 | } | ||
1249 | |||
1250 | void M_Mouse(int choice, int *sens) | ||
1251 | { | ||
1252 | switch(choice) | ||
1253 | { | ||
1254 | case 0: | ||
1255 | if (*sens) | ||
1256 | --*sens; | ||
1257 | break; | ||
1258 | case 1: | ||
1259 | if (*sens < 99) | ||
1260 | ++*sens; /*mead*/ | ||
1261 | break; | ||
1262 | } | ||
1263 | } | ||
1264 | |||
1265 | ///////////////////////////// | ||
1266 | // | ||
1267 | // M_QuickSave | ||
1268 | // | ||
1269 | |||
1270 | char tempstring[80]; | ||
1271 | |||
1272 | static void M_QuickSaveResponse(int ch) | ||
1273 | { | ||
1274 | if (ch == 'y') { | ||
1275 | M_DoSave(quickSaveSlot); | ||
1276 | S_StartSound(NULL,sfx_swtchx); | ||
1277 | } | ||
1278 | } | ||
1279 | |||
1280 | void M_QuickSave(void) | ||
1281 | { | ||
1282 | if (!usergame && (!demoplayback || netgame)) { /* killough 10/98 */ | ||
1283 | S_StartSound(NULL,sfx_oof); | ||
1284 | return; | ||
1285 | } | ||
1286 | |||
1287 | if (gamestate != GS_LEVEL) | ||
1288 | return; | ||
1289 | |||
1290 | if (quickSaveSlot < 0) { | ||
1291 | M_StartControlPanel(); | ||
1292 | M_ReadSaveStrings(); | ||
1293 | M_SetupNextMenu(&SaveDef); | ||
1294 | quickSaveSlot = -2; // means to pick a slot now | ||
1295 | return; | ||
1296 | } | ||
1297 | sprintf(tempstring,s_QSPROMPT,savegamestrings[quickSaveSlot]); // Ty 03/27/98 - externalized | ||
1298 | M_StartMessage(tempstring,M_QuickSaveResponse,true); | ||
1299 | } | ||
1300 | |||
1301 | ///////////////////////////// | ||
1302 | // | ||
1303 | // M_QuickLoad | ||
1304 | // | ||
1305 | |||
1306 | static void M_QuickLoadResponse(int ch) | ||
1307 | { | ||
1308 | if (ch == 'y') { | ||
1309 | M_LoadSelect(quickSaveSlot); | ||
1310 | S_StartSound(NULL,sfx_swtchx); | ||
1311 | } | ||
1312 | } | ||
1313 | |||
1314 | void M_QuickLoad(void) | ||
1315 | { | ||
1316 | // cph - removed restriction against quickload in a netgame | ||
1317 | |||
1318 | if (demorecording) { // killough 5/26/98: exclude during demo recordings | ||
1319 | M_StartMessage("you can't quickload\n" | ||
1320 | "while recording a demo!\n\n"PRESSKEY, | ||
1321 | NULL, false); // killough 5/26/98: not externalized | ||
1322 | return; | ||
1323 | } | ||
1324 | |||
1325 | if (quickSaveSlot < 0) { | ||
1326 | M_StartMessage(s_QSAVESPOT,NULL,false); // Ty 03/27/98 - externalized | ||
1327 | return; | ||
1328 | } | ||
1329 | sprintf(tempstring,s_QLPROMPT,savegamestrings[quickSaveSlot]); // Ty 03/27/98 - externalized | ||
1330 | M_StartMessage(tempstring,M_QuickLoadResponse,true); | ||
1331 | } | ||
1332 | |||
1333 | ///////////////////////////// | ||
1334 | // | ||
1335 | // M_EndGame | ||
1336 | // | ||
1337 | |||
1338 | static void M_EndGameResponse(int ch) | ||
1339 | { | ||
1340 | if (ch != 'y') | ||
1341 | return; | ||
1342 | |||
1343 | // killough 5/26/98: make endgame quit if recording or playing back demo | ||
1344 | if (demorecording || singledemo) | ||
1345 | G_CheckDemoStatus(); | ||
1346 | |||
1347 | currentMenu->lastOn = itemOn; | ||
1348 | M_ClearMenus (); | ||
1349 | D_StartTitle (); | ||
1350 | } | ||
1351 | |||
1352 | void M_EndGame(int choice) | ||
1353 | { | ||
1354 | if (netgame) | ||
1355 | { | ||
1356 | M_StartMessage(s_NETEND,NULL,false); // Ty 03/27/98 - externalized | ||
1357 | return; | ||
1358 | } | ||
1359 | M_StartMessage(s_ENDGAME,M_EndGameResponse,true); // Ty 03/27/98 - externalized | ||
1360 | } | ||
1361 | |||
1362 | ///////////////////////////// | ||
1363 | // | ||
1364 | // Toggle messages on/off | ||
1365 | // | ||
1366 | |||
1367 | void M_ChangeMessages(int choice) | ||
1368 | { | ||
1369 | // warning: unused parameter `int choice' | ||
1370 | choice = 0; | ||
1371 | showMessages = 1 - showMessages; | ||
1372 | |||
1373 | if (!showMessages) | ||
1374 | players[consoleplayer].message = s_MSGOFF; // Ty 03/27/98 - externalized | ||
1375 | else | ||
1376 | players[consoleplayer].message = s_MSGON ; // Ty 03/27/98 - externalized | ||
1377 | |||
1378 | message_dontfuckwithme = true; | ||
1379 | } | ||
1380 | |||
1381 | ///////////////////////////// | ||
1382 | // | ||
1383 | // CHANGE DISPLAY SIZE | ||
1384 | // | ||
1385 | // jff 2/23/98 restored to pre-HUD state | ||
1386 | // hud_active controlled soley by F5=key_detail (key_hud) | ||
1387 | // hud_displayed is toggled by + or = in fullscreen | ||
1388 | // hud_displayed is cleared by - | ||
1389 | |||
1390 | void M_SizeDisplay(int choice) | ||
1391 | { | ||
1392 | switch(choice) { | ||
1393 | case 0: | ||
1394 | if (screenSize > 0) { | ||
1395 | screenblocks--; | ||
1396 | screenSize--; | ||
1397 | hud_displayed = 0; | ||
1398 | } | ||
1399 | break; | ||
1400 | case 1: | ||
1401 | if (screenSize < 8) { | ||
1402 | screenblocks++; | ||
1403 | screenSize++; | ||
1404 | } | ||
1405 | else | ||
1406 | hud_displayed = !hud_displayed; | ||
1407 | break; | ||
1408 | } | ||
1409 | R_SetViewSize (screenblocks /*, detailLevel obsolete -- killough */); | ||
1410 | } | ||
1411 | |||
1412 | // | ||
1413 | // End of Original Menus | ||
1414 | // | ||
1415 | ///////////////////////////////////////////////////////////////////////////// | ||
1416 | |||
1417 | ///////////////////////////////////////////////////////////////////////////// | ||
1418 | // | ||
1419 | // SETUP MENU (phares) | ||
1420 | // | ||
1421 | // We've added a set of Setup Screens from which you can configure a number | ||
1422 | // of variables w/o having to restart the game. There are 7 screens: | ||
1423 | // | ||
1424 | // Key Bindings | ||
1425 | // Weapons | ||
1426 | // Status Bar / HUD | ||
1427 | // Automap | ||
1428 | // Enemies | ||
1429 | // Messages | ||
1430 | // Chat Strings | ||
1431 | // | ||
1432 | // killough 10/98: added Compatibility and General menus | ||
1433 | // | ||
1434 | |||
1435 | ///////////////////////////// | ||
1436 | // | ||
1437 | // booleans for setup screens | ||
1438 | // these tell you what state the setup screens are in, and whether any of | ||
1439 | // the overlay screens (automap colors, reset button message) should be | ||
1440 | // displayed | ||
1441 | |||
1442 | boolean setup_active = false; // in one of the setup screens | ||
1443 | boolean set_keybnd_active = false; // in key binding setup screens | ||
1444 | boolean set_weapon_active = false; // in weapons setup screen | ||
1445 | boolean set_status_active = false; // in status bar/hud setup screen | ||
1446 | boolean set_auto_active = false; // in automap setup screen | ||
1447 | boolean set_enemy_active = false; // in enemies setup screen | ||
1448 | boolean set_mess_active = false; // in messages setup screen | ||
1449 | boolean set_chat_active = false; // in chat string setup screen | ||
1450 | boolean setup_select = false; // changing an item | ||
1451 | boolean setup_gather = false; // gathering keys for value | ||
1452 | boolean colorbox_active = false; // color palette being shown | ||
1453 | boolean default_verify = false; // verify reset defaults decision | ||
1454 | boolean set_general_active = false; | ||
1455 | boolean set_compat_active = false; | ||
1456 | |||
1457 | ///////////////////////////// | ||
1458 | // | ||
1459 | // set_menu_itemon is an index that starts at zero, and tells you which | ||
1460 | // item on the current screen the cursor is sitting on. | ||
1461 | // | ||
1462 | // current_setup_menu is a pointer to the current setup menu table. | ||
1463 | |||
1464 | static int set_menu_itemon; // which setup item is selected? // phares 3/98 | ||
1465 | setup_menu_t* current_setup_menu; // points to current setup menu table | ||
1466 | |||
1467 | ///////////////////////////// | ||
1468 | // | ||
1469 | // The menu_buffer is used to construct strings for display on the screen. | ||
1470 | |||
1471 | static char menu_buffer[64]; | ||
1472 | |||
1473 | ///////////////////////////// | ||
1474 | // | ||
1475 | // The setup_e enum is used to provide a unique number for each group of Setup | ||
1476 | // Screens. | ||
1477 | |||
1478 | enum | ||
1479 | { | ||
1480 | set_compat, | ||
1481 | set_key_bindings, | ||
1482 | set_weapons, | ||
1483 | set_statbar, | ||
1484 | set_automap, | ||
1485 | set_enemy, | ||
1486 | set_messages, | ||
1487 | set_chatstrings, | ||
1488 | set_setup_end | ||
1489 | } setup_e; | ||
1490 | |||
1491 | int setup_screen; // the current setup screen. takes values from setup_e | ||
1492 | |||
1493 | ///////////////////////////// | ||
1494 | // | ||
1495 | // SetupMenu is the definition of what the main Setup Screen should look | ||
1496 | // like. Each entry shows that the cursor can land on each item (1), the | ||
1497 | // built-in graphic lump (i.e. "M_KEYBND") that should be displayed, | ||
1498 | // the program which takes over when an item is selected, and the hotkey | ||
1499 | // associated with the item. | ||
1500 | |||
1501 | menuitem_t SetupMenu[]= | ||
1502 | { | ||
1503 | {1,"M_COMPAT",M_Compat, 'p'}, | ||
1504 | {1,"M_KEYBND",M_KeyBindings,'k'}, | ||
1505 | {1,"M_WEAP" ,M_Weapons, 'w'}, | ||
1506 | {1,"M_STAT" ,M_StatusBar, 's'}, | ||
1507 | {1,"M_AUTO" ,M_Automap, 'a'}, | ||
1508 | {1,"M_ENEM" ,M_Enemy, 'e'}, | ||
1509 | {1,"M_MESS" ,M_Messages, 'm'}, | ||
1510 | {1,"M_CHAT" ,M_ChatStrings,'c'}, | ||
1511 | }; | ||
1512 | |||
1513 | ///////////////////////////// | ||
1514 | // | ||
1515 | // M_DoNothing does just that: nothing. Just a placeholder. | ||
1516 | |||
1517 | static void M_DoNothing(int choice) | ||
1518 | { | ||
1519 | } | ||
1520 | |||
1521 | ///////////////////////////// | ||
1522 | // | ||
1523 | // Items needed to satisfy the 'Big Font' menu structures: | ||
1524 | // | ||
1525 | // the generic_setup_e enum mimics the 'Big Font' menu structures, but | ||
1526 | // means nothing to the Setup Menus. | ||
1527 | |||
1528 | enum | ||
1529 | { | ||
1530 | generic_setupempty1, | ||
1531 | generic_setup_end | ||
1532 | } generic_setup_e; | ||
1533 | |||
1534 | // Generic_Setup is a do-nothing definition that the mainstream Menu code | ||
1535 | // can understand, while the Setup Menu code is working. Another placeholder. | ||
1536 | |||
1537 | menuitem_t Generic_Setup[] = | ||
1538 | { | ||
1539 | {1,"",M_DoNothing,0} | ||
1540 | }; | ||
1541 | |||
1542 | ///////////////////////////// | ||
1543 | // | ||
1544 | // SetupDef is the menu definition that the mainstream Menu code understands. | ||
1545 | // This is used by M_Setup (below) to define what is drawn and what is done | ||
1546 | // with the main Setup screen. | ||
1547 | |||
1548 | menu_t SetupDef = | ||
1549 | { | ||
1550 | set_setup_end, // number of Setup Menu items (Key Bindings, etc.) | ||
1551 | &OptionsDef, // menu to return to when BACKSPACE is hit on this menu | ||
1552 | SetupMenu, // definition of items to show on the Setup Screen | ||
1553 | M_DrawSetup, // program that draws the Setup Screen | ||
1554 | 59,37, // x,y position of the skull (modified when the skull is | ||
1555 | // drawn). The skull is parked on the upper-left corner | ||
1556 | // of the Setup screens, since it isn't needed as a cursor | ||
1557 | 0 // last item the user was on for this menu | ||
1558 | }; | ||
1559 | |||
1560 | ///////////////////////////// | ||
1561 | // | ||
1562 | // Here are the definitions of the individual Setup Menu screens. They | ||
1563 | // follow the format of the 'Big Font' menu structures. See the comments | ||
1564 | // for SetupDef (above) to help understand what each of these says. | ||
1565 | |||
1566 | menu_t KeybndDef = | ||
1567 | { | ||
1568 | generic_setup_end, | ||
1569 | &SetupDef, | ||
1570 | Generic_Setup, | ||
1571 | M_DrawKeybnd, | ||
1572 | 34,5, // skull drawn here | ||
1573 | 0 | ||
1574 | }; | ||
1575 | |||
1576 | menu_t WeaponDef = | ||
1577 | { | ||
1578 | generic_setup_end, | ||
1579 | &SetupDef, | ||
1580 | Generic_Setup, | ||
1581 | M_DrawWeapons, | ||
1582 | 34,5, // skull drawn here | ||
1583 | 0 | ||
1584 | }; | ||
1585 | |||
1586 | menu_t StatusHUDDef = | ||
1587 | { | ||
1588 | generic_setup_end, | ||
1589 | &SetupDef, | ||
1590 | Generic_Setup, | ||
1591 | M_DrawStatusHUD, | ||
1592 | 34,5, // skull drawn here | ||
1593 | 0 | ||
1594 | }; | ||
1595 | |||
1596 | menu_t AutoMapDef = | ||
1597 | { | ||
1598 | generic_setup_end, | ||
1599 | &SetupDef, | ||
1600 | Generic_Setup, | ||
1601 | M_DrawAutoMap, | ||
1602 | 34,5, // skull drawn here | ||
1603 | 0 | ||
1604 | }; | ||
1605 | |||
1606 | menu_t EnemyDef = // phares 4/08/98 | ||
1607 | { | ||
1608 | generic_setup_end, | ||
1609 | &SetupDef, | ||
1610 | Generic_Setup, | ||
1611 | M_DrawEnemy, | ||
1612 | 34,5, // skull drawn here | ||
1613 | 0 | ||
1614 | }; | ||
1615 | |||
1616 | menu_t MessageDef = // phares 4/08/98 | ||
1617 | { | ||
1618 | generic_setup_end, | ||
1619 | &SetupDef, | ||
1620 | Generic_Setup, | ||
1621 | M_DrawMessages, | ||
1622 | 34,5, // skull drawn here | ||
1623 | 0 | ||
1624 | }; | ||
1625 | |||
1626 | menu_t ChatStrDef = // phares 4/10/98 | ||
1627 | { | ||
1628 | generic_setup_end, | ||
1629 | &SetupDef, | ||
1630 | Generic_Setup, | ||
1631 | M_DrawChatStrings, | ||
1632 | 34,5, // skull drawn here | ||
1633 | 0 | ||
1634 | }; | ||
1635 | |||
1636 | menu_t GeneralDef = // killough 10/98 | ||
1637 | { | ||
1638 | generic_setup_end, | ||
1639 | &OptionsDef, | ||
1640 | Generic_Setup, | ||
1641 | M_DrawGeneral, | ||
1642 | 34,5, // skull drawn here | ||
1643 | 0 | ||
1644 | }; | ||
1645 | |||
1646 | menu_t CompatDef = // killough 10/98 | ||
1647 | { | ||
1648 | generic_setup_end, | ||
1649 | &SetupDef, | ||
1650 | Generic_Setup, | ||
1651 | M_DrawCompat, | ||
1652 | 34,5, // skull drawn here | ||
1653 | 0 | ||
1654 | }; | ||
1655 | |||
1656 | ///////////////////////////// | ||
1657 | // | ||
1658 | // Draws the Title for the main Setup screen | ||
1659 | |||
1660 | void M_DrawSetup(void) | ||
1661 | { | ||
1662 | // CPhipps - patch drawing updated | ||
1663 | V_DrawNamePatch(124, 15, 0, "M_SETUP", CR_DEFAULT, VPT_STRETCH); | ||
1664 | } | ||
1665 | |||
1666 | ///////////////////////////// | ||
1667 | // | ||
1668 | // Uses the SetupDef structure to draw the menu items for the main | ||
1669 | // Setup screen | ||
1670 | |||
1671 | void M_Setup(int choice) | ||
1672 | { | ||
1673 | M_SetupNextMenu(&SetupDef); | ||
1674 | } | ||
1675 | |||
1676 | ///////////////////////////// | ||
1677 | // | ||
1678 | // Data that's used by the Setup screen code | ||
1679 | // | ||
1680 | // Establish the message colors to be used | ||
1681 | |||
1682 | #define CR_TITLE CR_GOLD | ||
1683 | #define CR_SET CR_GREEN | ||
1684 | #define CR_ITEM CR_RED | ||
1685 | #define CR_HILITE CR_ORANGE | ||
1686 | #define CR_SELECT CR_GRAY | ||
1687 | |||
1688 | // Data used by the Automap color selection code | ||
1689 | |||
1690 | #define CHIP_SIZE 7 // size of color block for colored items | ||
1691 | |||
1692 | #define COLORPALXORIG ((320 - 16*(CHIP_SIZE+1))/2) | ||
1693 | #define COLORPALYORIG ((200 - 16*(CHIP_SIZE+1))/2) | ||
1694 | |||
1695 | #define PAL_BLACK 0 | ||
1696 | #define PAL_WHITE 4 | ||
1697 | |||
1698 | // Data used by the Chat String editing code | ||
1699 | |||
1700 | #define CHAT_STRING_BFR_SIZE 128 | ||
1701 | |||
1702 | // chat strings must fit in this screen space | ||
1703 | // killough 10/98: reduced, for more general uses | ||
1704 | #define MAXCHATWIDTH 272 | ||
1705 | |||
1706 | int chat_index; | ||
1707 | char* chat_string_buffer; // points to new chat strings while editing | ||
1708 | |||
1709 | ///////////////////////////// | ||
1710 | // | ||
1711 | // phares 4/17/98: | ||
1712 | // Added 'Reset to Defaults' Button to Setup Menu screens | ||
1713 | // This is a small button that sits in the upper-right-hand corner of | ||
1714 | // the first screen for each group. It blinks when selected, thus the | ||
1715 | // two patches, which it toggles back and forth. | ||
1716 | |||
1717 | char ResetButtonName[2][8] = {"M_BUTT1","M_BUTT2"}; | ||
1718 | |||
1719 | ///////////////////////////// | ||
1720 | // | ||
1721 | // phares 4/18/98: | ||
1722 | // Consolidate Item drawing code | ||
1723 | // | ||
1724 | // M_DrawItem draws the description of the provided item (the left-hand | ||
1725 | // part). A different color is used for the text depending on whether the | ||
1726 | // item is selected or not, or whether it's about to change. | ||
1727 | |||
1728 | // CPhipps - static, hanging else removed, const parameter | ||
1729 | static void M_DrawItem(const setup_menu_t* s) | ||
1730 | { | ||
1731 | int x = s->m_x; | ||
1732 | int y = s->m_y; | ||
1733 | int flags = s->m_flags; | ||
1734 | if (flags & S_RESET) | ||
1735 | |||
1736 | // This item is the reset button | ||
1737 | // Draw the 'off' version if this isn't the current menu item | ||
1738 | // Draw the blinking version in tune with the blinking skull otherwise | ||
1739 | |||
1740 | // proff/nicolas 09/20/98 -- changed for hi-res | ||
1741 | // CPhipps - Patch drawing updated, reformatted | ||
1742 | |||
1743 | V_DrawNamePatch(x, y, 0, ResetButtonName[(flags & (S_HILITE|S_SELECT)) ? whichSkull : 0], | ||
1744 | CR_DEFAULT, VPT_STRETCH); | ||
1745 | |||
1746 | else { // Draw the item string | ||
1747 | char *p, *t; | ||
1748 | int w = 0; | ||
1749 | int color = | ||
1750 | flags & S_SELECT ? CR_SELECT : | ||
1751 | flags & S_HILITE ? CR_HILITE : | ||
1752 | flags & (S_TITLE|S_NEXT|S_PREV) ? CR_TITLE : CR_ITEM; // killough 10/98 | ||
1753 | |||
1754 | /* killough 10/98: | ||
1755 | * Enhance to support multiline text separated by newlines. | ||
1756 | * This supports multiline items on horizontally-crowded menus. | ||
1757 | */ | ||
1758 | |||
1759 | for (p = t = strdup(s->m_text); (p = strtok(p,"\n")); y += 8, p = NULL) | ||
1760 | { /* killough 10/98: support left-justification: */ | ||
1761 | strcpy(menu_buffer,p); | ||
1762 | if (!(flags & S_LEFTJUST)) | ||
1763 | w = M_GetPixelWidth(menu_buffer) + 4; | ||
1764 | M_DrawMenuString(x - w, y ,color); | ||
1765 | } | ||
1766 | free(t); | ||
1767 | } | ||
1768 | } | ||
1769 | |||
1770 | // If a number item is being changed, allow up to N keystrokes to 'gather' | ||
1771 | // the value. Gather_count tells you how many you have so far. The legality | ||
1772 | // of what is gathered is determined by the low/high settings for the item. | ||
1773 | |||
1774 | #define MAXGATHER 5 | ||
1775 | int gather_count; | ||
1776 | char gather_buffer[MAXGATHER+1]; // killough 10/98: make input character-based | ||
1777 | |||
1778 | ///////////////////////////// | ||
1779 | // | ||
1780 | // phares 4/18/98: | ||
1781 | // Consolidate Item Setting drawing code | ||
1782 | // | ||
1783 | // M_DrawSetting draws the setting of the provided item (the right-hand | ||
1784 | // part. It determines the text color based on whether the item is | ||
1785 | // selected or being changed. Then, depending on the type of item, it | ||
1786 | // displays the appropriate setting value: yes/no, a key binding, a number, | ||
1787 | // a paint chip, etc. | ||
1788 | |||
1789 | static void M_DrawSetting(const setup_menu_t* s) | ||
1790 | { | ||
1791 | int x = s->m_x, y = s->m_y, flags = s->m_flags, color; | ||
1792 | |||
1793 | // Determine color of the text. This may or may not be used later, | ||
1794 | // depending on whether the item is a text string or not. | ||
1795 | |||
1796 | color = flags & S_SELECT ? CR_SELECT : flags & S_HILITE ? CR_HILITE : CR_SET; | ||
1797 | |||
1798 | // Is the item a YES/NO item? | ||
1799 | |||
1800 | if (flags & S_YESNO) { | ||
1801 | strcpy(menu_buffer,*s->var.def->location.pi ? "YES" : "NO"); | ||
1802 | M_DrawMenuString(x,y,color); | ||
1803 | return; | ||
1804 | } | ||
1805 | |||
1806 | // Is the item a simple number? | ||
1807 | |||
1808 | if (flags & S_NUM) { | ||
1809 | // killough 10/98: We must draw differently for items being gathered. | ||
1810 | if (flags & (S_HILITE|S_SELECT) && setup_gather) { | ||
1811 | gather_buffer[gather_count] = 0; | ||
1812 | strcpy(menu_buffer, gather_buffer); | ||
1813 | } | ||
1814 | else | ||
1815 | sprintf(menu_buffer,"%d",*s->var.def->location.pi); | ||
1816 | M_DrawMenuString(x,y,color); | ||
1817 | return; | ||
1818 | } | ||
1819 | |||
1820 | // Is the item a key binding? | ||
1821 | |||
1822 | if (flags & S_KEY) { // Key Binding | ||
1823 | int *key = s->var.m_key; | ||
1824 | |||
1825 | // Draw the key bound to the action | ||
1826 | |||
1827 | if (key) { | ||
1828 | M_GetKeyString(*key,0); // string to display | ||
1829 | if (key == &key_use) { | ||
1830 | // For the 'use' key, you have to build the string | ||
1831 | |||
1832 | if (s->m_mouse) | ||
1833 | sprintf(menu_buffer+strlen(menu_buffer), "/DBL-CLK MB%d",*s->m_mouse+1); | ||
1834 | if (s->m_joy) | ||
1835 | sprintf(menu_buffer+strlen(menu_buffer), "/JSB%d",*s->m_joy+1); | ||
1836 | } | ||
1837 | else if (key == &key_up || key == &key_speed || | ||
1838 | key == &key_fire || key == &key_strafe) | ||
1839 | { | ||
1840 | if (s->m_mouse) | ||
1841 | sprintf(menu_buffer+strlen(menu_buffer), "/MB%d", | ||
1842 | *s->m_mouse+1); | ||
1843 | if (s->m_joy) | ||
1844 | sprintf(menu_buffer+strlen(menu_buffer), "/JSB%d", | ||
1845 | *s->m_joy+1); | ||
1846 | } | ||
1847 | M_DrawMenuString(x,y,color); | ||
1848 | } | ||
1849 | return; | ||
1850 | } | ||
1851 | |||
1852 | // Is the item a weapon number? | ||
1853 | // OR, Is the item a colored text string from the Automap? | ||
1854 | // | ||
1855 | // killough 10/98: removed special code, since the rest of the engine | ||
1856 | // already takes care of it, and this code prevented the user from setting | ||
1857 | // their overall weapons preferences while playing Doom 1. | ||
1858 | // | ||
1859 | // killough 11/98: consolidated weapons code with color range code | ||
1860 | |||
1861 | if (flags & (S_WEAP|S_CRITEM)) // weapon number or color range | ||
1862 | { | ||
1863 | sprintf(menu_buffer,"%d", *s->var.def->location.pi); | ||
1864 | M_DrawMenuString(x,y, flags & S_CRITEM ? *s->var.def->location.pi : color); | ||
1865 | return; | ||
1866 | } | ||
1867 | |||
1868 | // Is the item a paint chip? | ||
1869 | |||
1870 | if (flags & S_COLOR) // Automap paint chip | ||
1871 | { | ||
1872 | int ch; | ||
1873 | |||
1874 | ch = *s->var.def->location.pi; | ||
1875 | // proff 12/6/98: Drawing of colorchips completly changed for hi-res, it now uses a patch | ||
1876 | // draw the paint chip | ||
1877 | V_FillRect(0, x*SCREENWIDTH/320, (y-1)*SCREENHEIGHT/200, | ||
1878 | 8*SCREENWIDTH/320, 8*SCREENHEIGHT/200, | ||
1879 | PAL_BLACK); | ||
1880 | V_FillRect(0, (x+1)*SCREENWIDTH/320, y*SCREENHEIGHT/200, | ||
1881 | 6*SCREENWIDTH/320, 6*SCREENHEIGHT/200, | ||
1882 | (byte)ch); | ||
1883 | |||
1884 | if (!ch) // don't show this item in automap mode | ||
1885 | V_DrawNamePatch(x+1,y,0,"M_PALNO", CR_DEFAULT, VPT_STRETCH); | ||
1886 | return; | ||
1887 | } | ||
1888 | |||
1889 | // Is the item a chat string? | ||
1890 | // killough 10/98: or a filename? | ||
1891 | |||
1892 | if (flags & S_STRING) { | ||
1893 | /* cph - cast to char* as it's really a Z_Strdup'd string (see m_misc.h) */ | ||
1894 | char *text = (char*)*s->var.def->location.ppsz; | ||
1895 | |||
1896 | // Are we editing this string? If so, display a cursor under | ||
1897 | // the correct character. | ||
1898 | |||
1899 | if (setup_select && (s->m_flags & (S_HILITE|S_SELECT))) { | ||
1900 | int cursor_start, char_width; | ||
1901 | char c[2]; | ||
1902 | |||
1903 | // If the string is too wide for the screen, trim it back, | ||
1904 | // one char at a time until it fits. This should only occur | ||
1905 | // while you're editing the string. | ||
1906 | |||
1907 | while (M_GetPixelWidth(text) >= MAXCHATWIDTH) { | ||
1908 | int len = strlen(text); | ||
1909 | text[--len] = 0; | ||
1910 | if (chat_index > len) | ||
1911 | chat_index--; | ||
1912 | } | ||
1913 | |||
1914 | // Find the distance from the beginning of the string to | ||
1915 | // where the cursor should be drawn, plus the width of | ||
1916 | // the char the cursor is under.. | ||
1917 | |||
1918 | *c = text[chat_index]; // hold temporarily | ||
1919 | c[1] = 0; | ||
1920 | char_width = M_GetPixelWidth(c); | ||
1921 | if (char_width == 1) | ||
1922 | char_width = 7; // default for end of line | ||
1923 | text[chat_index] = 0; // NULL to get cursor position | ||
1924 | cursor_start = M_GetPixelWidth(text); | ||
1925 | text[chat_index] = *c; // replace stored char | ||
1926 | |||
1927 | // Now draw the cursor | ||
1928 | // proff 12/6/98: Drawing of cursor changed for hi-res | ||
1929 | V_FillRect(0, ((x+cursor_start-1)*SCREENWIDTH)/320, (y*SCREENHEIGHT)/200, | ||
1930 | (char_width*SCREENWIDTH)/320, 9*SCREENHEIGHT/200, PAL_WHITE); | ||
1931 | } | ||
1932 | |||
1933 | // Draw the setting for the item | ||
1934 | |||
1935 | strcpy(menu_buffer,text); | ||
1936 | M_DrawMenuString(x,y,color); | ||
1937 | return; | ||
1938 | } | ||
1939 | |||
1940 | // Is the item a selection of choices? | ||
1941 | |||
1942 | if (flags & S_CHOICE) { | ||
1943 | if (s->var.def->type == def_int) { | ||
1944 | if (s->selectstrings == NULL) { | ||
1945 | sprintf(menu_buffer,"%d",*s->var.def->location.pi); | ||
1946 | } else { | ||
1947 | strcpy(menu_buffer,s->selectstrings[*s->var.def->location.pi]); | ||
1948 | } | ||
1949 | } | ||
1950 | |||
1951 | if (s->var.def->type == def_str) { | ||
1952 | sprintf(menu_buffer,"%s", *s->var.def->location.ppsz); | ||
1953 | } | ||
1954 | |||
1955 | M_DrawMenuString(x,y,color); | ||
1956 | return; | ||
1957 | } | ||
1958 | } | ||
1959 | |||
1960 | ///////////////////////////// | ||
1961 | // | ||
1962 | // M_DrawScreenItems takes the data for each menu item and gives it to | ||
1963 | // the drawing routines above. | ||
1964 | |||
1965 | // CPhipps - static, const parameter, formatting | ||
1966 | static void M_DrawScreenItems(const setup_menu_t* src) | ||
1967 | { | ||
1968 | if (print_warning_about_changes > 0) { /* killough 8/15/98: print warning */ | ||
1969 | if (warning_about_changes & S_BADVAL) { | ||
1970 | strcpy(menu_buffer, "Value out of Range"); | ||
1971 | M_DrawMenuString(100,176,CR_RED); | ||
1972 | } else if (warning_about_changes & S_PRGWARN) { | ||
1973 | strcpy(menu_buffer, "Warning: Program must be restarted to see changes"); | ||
1974 | M_DrawMenuString(3, 176, CR_RED); | ||
1975 | } else if (warning_about_changes & S_BADVID) { | ||
1976 | strcpy(menu_buffer, "Video mode not supported"); | ||
1977 | M_DrawMenuString(80,176,CR_RED); | ||
1978 | } else { | ||
1979 | strcpy(menu_buffer, "Warning: Changes are pending until next game"); | ||
1980 | M_DrawMenuString(18,184,CR_RED); | ||
1981 | } | ||
1982 | } | ||
1983 | |||
1984 | while (!(src->m_flags & S_END)) { | ||
1985 | |||
1986 | // See if we're to draw the item description (left-hand part) | ||
1987 | |||
1988 | if (src->m_flags & S_SHOWDESC) | ||
1989 | M_DrawItem(src); | ||
1990 | |||
1991 | // See if we're to draw the setting (right-hand part) | ||
1992 | |||
1993 | if (src->m_flags & S_SHOWSET) | ||
1994 | M_DrawSetting(src); | ||
1995 | src++; | ||
1996 | } | ||
1997 | } | ||
1998 | |||
1999 | ///////////////////////////// | ||
2000 | // | ||
2001 | // Data used to draw the "are you sure?" dialogue box when resetting | ||
2002 | // to defaults. | ||
2003 | |||
2004 | #define VERIFYBOXXORG 66 | ||
2005 | #define VERIFYBOXYORG 88 | ||
2006 | #define PAL_GRAY1 91 | ||
2007 | #define PAL_GRAY2 98 | ||
2008 | #define PAL_GRAY3 105 | ||
2009 | |||
2010 | // And the routine to draw it. | ||
2011 | |||
2012 | static void M_DrawDefVerify(void) | ||
2013 | { | ||
2014 | // proff 12/6/98: Drawing of verify box changed for hi-res, it now uses a patch | ||
2015 | V_DrawNamePatch(VERIFYBOXXORG,VERIFYBOXYORG,0,"M_VBOX",CR_DEFAULT,VPT_STRETCH); | ||
2016 | // The blinking messages is keyed off of the blinking of the | ||
2017 | // cursor skull. | ||
2018 | |||
2019 | if (whichSkull) { // blink the text | ||
2020 | strcpy(menu_buffer,"Reset to defaults? (Y or N)"); | ||
2021 | M_DrawMenuString(VERIFYBOXXORG+8,VERIFYBOXYORG+8,CR_RED); | ||
2022 | } | ||
2023 | } | ||
2024 | |||
2025 | |||
2026 | ///////////////////////////// | ||
2027 | // | ||
2028 | // phares 4/18/98: | ||
2029 | // M_DrawInstructions writes the instruction text just below the screen title | ||
2030 | // | ||
2031 | // cph 2006/08/06 - go back to the Boom version, and then clean up by using | ||
2032 | // M_DrawStringCentered (much better than all those magic 'x' valies!) | ||
2033 | |||
2034 | static void M_DrawInstructions(void) | ||
2035 | { | ||
2036 | int flags = current_setup_menu[set_menu_itemon].m_flags; | ||
2037 | |||
2038 | // There are different instruction messages depending on whether you | ||
2039 | // are changing an item or just sitting on it. | ||
2040 | |||
2041 | if (setup_select) { | ||
2042 | switch (flags & (S_KEY | S_YESNO | S_WEAP | S_NUM | S_COLOR | S_CRITEM | S_CHAT | S_RESET | S_FILE | S_CHOICE)) { | ||
2043 | case S_KEY: | ||
2044 | // See if a joystick or mouse button setting is allowed for | ||
2045 | // this item. | ||
2046 | if (current_setup_menu[set_menu_itemon].m_mouse || current_setup_menu[set_menu_itemon].m_joy) | ||
2047 | M_DrawStringCentered(160, 20, CR_SELECT, "Press key or button for this action"); | ||
2048 | else | ||
2049 | M_DrawStringCentered(160, 20, CR_SELECT, "Press key for this action"); | ||
2050 | break; | ||
2051 | |||
2052 | case S_YESNO: | ||
2053 | M_DrawStringCentered(160, 20, CR_SELECT, "Press ENTER key to toggle"); | ||
2054 | break; | ||
2055 | case S_WEAP: | ||
2056 | M_DrawStringCentered(160, 20, CR_SELECT, "Enter weapon number"); | ||
2057 | break; | ||
2058 | case S_NUM: | ||
2059 | M_DrawStringCentered(160, 20, CR_SELECT, "Enter value. Press ENTER when finished."); | ||
2060 | break; | ||
2061 | case S_COLOR: | ||
2062 | M_DrawStringCentered(160, 20, CR_SELECT, "Select color and press enter"); | ||
2063 | break; | ||
2064 | case S_CRITEM: | ||
2065 | M_DrawStringCentered(160, 20, CR_SELECT, "Enter value"); | ||
2066 | break; | ||
2067 | case S_CHAT: | ||
2068 | M_DrawStringCentered(160, 20, CR_SELECT, "Type/edit chat string and Press ENTER"); | ||
2069 | break; | ||
2070 | case S_FILE: | ||
2071 | M_DrawStringCentered(160, 20, CR_SELECT, "Type/edit filename and Press ENTER"); | ||
2072 | break; | ||
2073 | case S_CHOICE: | ||
2074 | M_DrawStringCentered(160, 20, CR_SELECT, "Press left or right to choose"); | ||
2075 | break; | ||
2076 | case S_RESET: | ||
2077 | break; | ||
2078 | #ifdef SIMPLECHECKS | ||
2079 | default: | ||
2080 | lprintf(LO_WARN,"Unrecognised menu item type %d", flags); | ||
2081 | #endif | ||
2082 | } | ||
2083 | } else { | ||
2084 | if (flags & S_RESET) | ||
2085 | M_DrawStringCentered(160, 20, CR_HILITE, "Press ENTER key to reset to defaults"); | ||
2086 | else | ||
2087 | M_DrawStringCentered(160, 20, CR_HILITE, "Press Enter to Change"); | ||
2088 | } | ||
2089 | } | ||
2090 | |||
2091 | |||
2092 | ///////////////////////////// | ||
2093 | // | ||
2094 | // The Key Binding Screen tables. | ||
2095 | |||
2096 | #define KB_X 160 | ||
2097 | #define KB_PREV 57 | ||
2098 | #define KB_NEXT 310 | ||
2099 | #define KB_Y 31 | ||
2100 | |||
2101 | // phares 4/16/98: | ||
2102 | // X,Y position of reset button. This is the same for every screen, and is | ||
2103 | // only defined once here. | ||
2104 | |||
2105 | #define X_BUTTON 301 | ||
2106 | #define Y_BUTTON 3 | ||
2107 | |||
2108 | // Definitions of the (in this case) four key binding screens. | ||
2109 | |||
2110 | setup_menu_t keys_settings1[]; | ||
2111 | setup_menu_t keys_settings2[]; | ||
2112 | setup_menu_t keys_settings3[]; | ||
2113 | setup_menu_t keys_settings4[]; | ||
2114 | |||
2115 | // The table which gets you from one screen table to the next. | ||
2116 | |||
2117 | setup_menu_t* keys_settings[] = | ||
2118 | { | ||
2119 | keys_settings1, | ||
2120 | keys_settings2, | ||
2121 | keys_settings3, | ||
2122 | keys_settings4, | ||
2123 | NULL | ||
2124 | }; | ||
2125 | |||
2126 | int mult_screens_index; // the index of the current screen in a set | ||
2127 | |||
2128 | // Here's an example from this first screen, with explanations. | ||
2129 | // | ||
2130 | // { | ||
2131 | // "STRAFE", // The description of the item ('strafe' key) | ||
2132 | // S_KEY, // This is a key binding item | ||
2133 | // m_scrn, // It belongs to the m_scrn group. Its key cannot be | ||
2134 | // // bound to two items in this group. | ||
2135 | // KB_X, // The X offset of the start of the right-hand side | ||
2136 | // KB_Y+ 8*8, // The Y offset of the start of the right-hand side. | ||
2137 | // // Always given in multiples off a baseline. | ||
2138 | // &key_strafe, // The variable that holds the key value bound to this | ||
2139 | // OR a string that holds the config variable name. | ||
2140 | // OR a pointer to another setup_menu | ||
2141 | // &mousebstrafe, // The variable that holds the mouse button bound to | ||
2142 | // this. If zero, no mouse button can be bound here. | ||
2143 | // &joybstrafe, // The variable that holds the joystick button bound to | ||
2144 | // this. If zero, no mouse button can be bound here. | ||
2145 | // } | ||
2146 | |||
2147 | // The first Key Binding screen table. | ||
2148 | // Note that the Y values are ascending. If you need to add something to | ||
2149 | // this table, (well, this one's not a good example, because it's full) | ||
2150 | // you need to make sure the Y values still make sense so everything gets | ||
2151 | // displayed. | ||
2152 | // | ||
2153 | // Note also that the first screen of each set has a line for the reset | ||
2154 | // button. If there is more than one screen in a set, the others don't get | ||
2155 | // the reset button. | ||
2156 | // | ||
2157 | // Note also that this screen has a "NEXT ->" line. This acts like an | ||
2158 | // item, in that 'activating' it moves you along to the next screen. If | ||
2159 | // there's a "<- PREV" item on a screen, it behaves similarly, moving you | ||
2160 | // to the previous screen. If you leave these off, you can't move from | ||
2161 | // screen to screen. | ||
2162 | |||
2163 | setup_menu_t keys_settings1[] = // Key Binding screen strings | ||
2164 | { | ||
2165 | {"MOVEMENT" ,S_SKIP|S_TITLE,m_null,KB_X,KB_Y}, | ||
2166 | {"FORWARD" ,S_KEY ,m_scrn,KB_X,KB_Y+1*8,{&key_up},&mousebforward}, | ||
2167 | {"BACKWARD" ,S_KEY ,m_scrn,KB_X,KB_Y+2*8,{&key_down}}, | ||
2168 | {"TURN LEFT" ,S_KEY ,m_scrn,KB_X,KB_Y+3*8,{&key_left}}, | ||
2169 | {"TURN RIGHT" ,S_KEY ,m_scrn,KB_X,KB_Y+4*8,{&key_right}}, | ||
2170 | {"RUN" ,S_KEY ,m_scrn,KB_X,KB_Y+5*8,{&key_speed},0,&joybspeed}, | ||
2171 | {"STRAFE LEFT" ,S_KEY ,m_scrn,KB_X,KB_Y+6*8,{&key_strafeleft}}, | ||
2172 | {"STRAFE RIGHT",S_KEY ,m_scrn,KB_X,KB_Y+7*8,{&key_straferight}}, | ||
2173 | {"STRAFE" ,S_KEY ,m_scrn,KB_X,KB_Y+8*8,{&key_strafe},&mousebstrafe,&joybstrafe}, | ||
2174 | {"AUTORUN" ,S_KEY ,m_scrn,KB_X,KB_Y+9*8,{&key_autorun}}, | ||
2175 | {"180 TURN" ,S_KEY ,m_scrn,KB_X,KB_Y+10*8,{&key_reverse}}, | ||
2176 | {"USE" ,S_KEY ,m_scrn,KB_X,KB_Y+11*8,{&key_use},&mousebforward,&joybuse}, | ||
2177 | |||
2178 | {"MENUS" ,S_SKIP|S_TITLE,m_null,KB_X,KB_Y+12*8}, | ||
2179 | {"NEXT ITEM" ,S_KEY ,m_menu,KB_X,KB_Y+13*8,{&key_menu_down}}, | ||
2180 | {"PREV ITEM" ,S_KEY ,m_menu,KB_X,KB_Y+14*8,{&key_menu_up}}, | ||
2181 | {"LEFT" ,S_KEY ,m_menu,KB_X,KB_Y+15*8,{&key_menu_left}}, | ||
2182 | {"RIGHT" ,S_KEY ,m_menu,KB_X,KB_Y+16*8,{&key_menu_right}}, | ||
2183 | {"BACKSPACE" ,S_KEY ,m_menu,KB_X,KB_Y+17*8,{&key_menu_backspace}}, | ||
2184 | {"SELECT ITEM" ,S_KEY ,m_menu,KB_X,KB_Y+18*8,{&key_menu_enter}}, | ||
2185 | {"EXIT" ,S_KEY ,m_menu,KB_X,KB_Y+19*8,{&key_menu_escape}}, | ||
2186 | |||
2187 | // Button for resetting to defaults | ||
2188 | {0,S_RESET,m_null,X_BUTTON,Y_BUTTON}, | ||
2189 | |||
2190 | {"NEXT ->",S_SKIP|S_NEXT,m_null,KB_NEXT,KB_Y+20*8, {keys_settings2}}, | ||
2191 | |||
2192 | // Final entry | ||
2193 | {0,S_SKIP|S_END,m_null} | ||
2194 | |||
2195 | }; | ||
2196 | |||
2197 | setup_menu_t keys_settings2[] = // Key Binding screen strings | ||
2198 | { | ||
2199 | {"SCREEN" ,S_SKIP|S_TITLE,m_null,KB_X,KB_Y}, | ||
2200 | |||
2201 | // phares 4/13/98: | ||
2202 | // key_help and key_escape can no longer be rebound. This keeps the | ||
2203 | // player from getting themselves in a bind where they can't remember how | ||
2204 | // to get to the menus, and can't remember how to get to the help screen | ||
2205 | // to give them a clue as to how to get to the menus. :) | ||
2206 | |||
2207 | // Also, the keys assigned to these functions cannot be bound to other | ||
2208 | // functions. Introduce an S_KEEP flag to show that you cannot swap this | ||
2209 | // key with other keys in the same 'group'. (m_scrn, etc.) | ||
2210 | |||
2211 | {"HELP" ,S_SKIP|S_KEEP ,m_scrn,0 ,0 ,{&key_help}}, | ||
2212 | {"MENU" ,S_SKIP|S_KEEP ,m_scrn,0 ,0 ,{&key_escape}}, | ||
2213 | // killough 10/98: hotkey for entering setup menu: | ||
2214 | {"SETUP" ,S_KEY ,m_scrn,KB_X,KB_Y+ 1*8,{&key_setup}}, | ||
2215 | {"PAUSE" ,S_KEY ,m_scrn,KB_X,KB_Y+ 2*8,{&key_pause}}, | ||
2216 | {"AUTOMAP" ,S_KEY ,m_scrn,KB_X,KB_Y+ 3*8,{&key_map}}, | ||
2217 | {"VOLUME" ,S_KEY ,m_scrn,KB_X,KB_Y+ 4*8,{&key_soundvolume}}, | ||
2218 | {"HUD" ,S_KEY ,m_scrn,KB_X,KB_Y+ 5*8,{&key_hud}}, | ||
2219 | {"MESSAGES" ,S_KEY ,m_scrn,KB_X,KB_Y+ 6*8,{&key_messages}}, | ||
2220 | {"GAMMA FIX" ,S_KEY ,m_scrn,KB_X,KB_Y+ 7*8,{&key_gamma}}, | ||
2221 | {"SPY" ,S_KEY ,m_scrn,KB_X,KB_Y+ 8*8,{&key_spy}}, | ||
2222 | {"LARGER VIEW" ,S_KEY ,m_scrn,KB_X,KB_Y+ 9*8,{&key_zoomin}}, | ||
2223 | {"SMALLER VIEW",S_KEY ,m_scrn,KB_X,KB_Y+10*8,{&key_zoomout}}, | ||
2224 | {"SCREENSHOT" ,S_KEY ,m_scrn,KB_X,KB_Y+11*8,{&key_screenshot}}, | ||
2225 | {"GAME" ,S_SKIP|S_TITLE,m_null,KB_X,KB_Y+12*8}, | ||
2226 | {"SAVE" ,S_KEY ,m_scrn,KB_X,KB_Y+13*8,{&key_savegame}}, | ||
2227 | {"LOAD" ,S_KEY ,m_scrn,KB_X,KB_Y+14*8,{&key_loadgame}}, | ||
2228 | {"QUICKSAVE" ,S_KEY ,m_scrn,KB_X,KB_Y+15*8,{&key_quicksave}}, | ||
2229 | {"QUICKLOAD" ,S_KEY ,m_scrn,KB_X,KB_Y+16*8,{&key_quickload}}, | ||
2230 | {"END GAME" ,S_KEY ,m_scrn,KB_X,KB_Y+17*8,{&key_endgame}}, | ||
2231 | {"QUIT" ,S_KEY ,m_scrn,KB_X,KB_Y+18*8,{&key_quit}}, | ||
2232 | {"<- PREV", S_SKIP|S_PREV,m_null,KB_PREV,KB_Y+20*8, {keys_settings1}}, | ||
2233 | {"NEXT ->", S_SKIP|S_NEXT,m_null,KB_NEXT,KB_Y+20*8, {keys_settings3}}, | ||
2234 | |||
2235 | // Final entry | ||
2236 | |||
2237 | {0,S_SKIP|S_END,m_null} | ||
2238 | }; | ||
2239 | |||
2240 | setup_menu_t keys_settings3[] = // Key Binding screen strings | ||
2241 | { | ||
2242 | {"WEAPONS" ,S_SKIP|S_TITLE,m_null,KB_X,KB_Y}, | ||
2243 | {"FIST" ,S_KEY ,m_scrn,KB_X,KB_Y+ 1*8,{&key_weapon1}}, | ||
2244 | {"PISTOL" ,S_KEY ,m_scrn,KB_X,KB_Y+ 2*8,{&key_weapon2}}, | ||
2245 | {"SHOTGUN" ,S_KEY ,m_scrn,KB_X,KB_Y+ 3*8,{&key_weapon3}}, | ||
2246 | {"CHAINGUN",S_KEY ,m_scrn,KB_X,KB_Y+ 4*8,{&key_weapon4}}, | ||
2247 | {"ROCKET" ,S_KEY ,m_scrn,KB_X,KB_Y+ 5*8,{&key_weapon5}}, | ||
2248 | {"PLASMA" ,S_KEY ,m_scrn,KB_X,KB_Y+ 6*8,{&key_weapon6}}, | ||
2249 | {"BFG", S_KEY ,m_scrn,KB_X,KB_Y+ 7*8,{&key_weapon7}}, | ||
2250 | {"CHAINSAW",S_KEY ,m_scrn,KB_X,KB_Y+ 8*8,{&key_weapon8}}, | ||
2251 | {"SSG" ,S_KEY ,m_scrn,KB_X,KB_Y+ 9*8,{&key_weapon9}}, | ||
2252 | {"BEST" ,S_KEY ,m_scrn,KB_X,KB_Y+10*8,{&key_weapontoggle}}, | ||
2253 | {"FIRE" ,S_KEY ,m_scrn,KB_X,KB_Y+11*8,{&key_fire},&mousebfire,&joybfire}, | ||
2254 | |||
2255 | {"<- PREV",S_SKIP|S_PREV,m_null,KB_PREV,KB_Y+20*8, {keys_settings2}}, | ||
2256 | {"NEXT ->",S_SKIP|S_NEXT,m_null,KB_NEXT,KB_Y+20*8, {keys_settings4}}, | ||
2257 | |||
2258 | // Final entry | ||
2259 | |||
2260 | {0,S_SKIP|S_END,m_null} | ||
2261 | |||
2262 | }; | ||
2263 | |||
2264 | setup_menu_t keys_settings4[] = // Key Binding screen strings | ||
2265 | { | ||
2266 | {"AUTOMAP" ,S_SKIP|S_TITLE,m_null,KB_X,KB_Y}, | ||
2267 | {"FOLLOW" ,S_KEY ,m_map ,KB_X,KB_Y+ 1*8,{&key_map_follow}}, | ||
2268 | {"ZOOM IN" ,S_KEY ,m_map ,KB_X,KB_Y+ 2*8,{&key_map_zoomin}}, | ||
2269 | {"ZOOM OUT" ,S_KEY ,m_map ,KB_X,KB_Y+ 3*8,{&key_map_zoomout}}, | ||
2270 | {"SHIFT UP" ,S_KEY ,m_map ,KB_X,KB_Y+ 4*8,{&key_map_up}}, | ||
2271 | {"SHIFT DOWN" ,S_KEY ,m_map ,KB_X,KB_Y+ 5*8,{&key_map_down}}, | ||
2272 | {"SHIFT LEFT" ,S_KEY ,m_map ,KB_X,KB_Y+ 6*8,{&key_map_left}}, | ||
2273 | {"SHIFT RIGHT",S_KEY ,m_map ,KB_X,KB_Y+ 7*8,{&key_map_right}}, | ||
2274 | {"MARK PLACE" ,S_KEY ,m_map ,KB_X,KB_Y+ 8*8,{&key_map_mark}}, | ||
2275 | {"CLEAR MARKS",S_KEY ,m_map ,KB_X,KB_Y+ 9*8,{&key_map_clear}}, | ||
2276 | {"FULL/ZOOM" ,S_KEY ,m_map ,KB_X,KB_Y+10*8,{&key_map_gobig}}, | ||
2277 | {"GRID" ,S_KEY ,m_map ,KB_X,KB_Y+11*8,{&key_map_grid}}, | ||
2278 | |||
2279 | {"CHATTING" ,S_SKIP|S_TITLE,m_null,KB_X,KB_Y+12*8}, | ||
2280 | {"BEGIN CHAT" ,S_KEY ,m_scrn,KB_X,KB_Y+13*8,{&key_chat}}, | ||
2281 | {"PLAYER 1" ,S_KEY ,m_scrn,KB_X,KB_Y+14*8,{&destination_keys[0]}}, | ||
2282 | {"PLAYER 2" ,S_KEY ,m_scrn,KB_X,KB_Y+15*8,{&destination_keys[1]}}, | ||
2283 | {"PLAYER 3" ,S_KEY ,m_scrn,KB_X,KB_Y+16*8,{&destination_keys[2]}}, | ||
2284 | {"PLAYER 4" ,S_KEY ,m_scrn,KB_X,KB_Y+17*8,{&destination_keys[3]}}, | ||
2285 | {"BACKSPACE" ,S_KEY ,m_scrn,KB_X,KB_Y+18*8,{&key_backspace}}, | ||
2286 | {"ENTER" ,S_KEY ,m_scrn,KB_X,KB_Y+19*8,{&key_enter}}, | ||
2287 | |||
2288 | {"<- PREV" ,S_SKIP|S_PREV,m_null,KB_PREV,KB_Y+20*8, {keys_settings3}}, | ||
2289 | |||
2290 | // Final entry | ||
2291 | |||
2292 | {0,S_SKIP|S_END,m_null} | ||
2293 | |||
2294 | }; | ||
2295 | |||
2296 | // Setting up for the Key Binding screen. Turn on flags, set pointers, | ||
2297 | // locate the first item on the screen where the cursor is allowed to | ||
2298 | // land. | ||
2299 | |||
2300 | void M_KeyBindings(int choice) | ||
2301 | { | ||
2302 | M_SetupNextMenu(&KeybndDef); | ||
2303 | |||
2304 | setup_active = true; | ||
2305 | setup_screen = ss_keys; | ||
2306 | set_keybnd_active = true; | ||
2307 | setup_select = false; | ||
2308 | default_verify = false; | ||
2309 | setup_gather = false; | ||
2310 | mult_screens_index = 0; | ||
2311 | current_setup_menu = keys_settings[0]; | ||
2312 | set_menu_itemon = 0; | ||
2313 | while (current_setup_menu[set_menu_itemon++].m_flags & S_SKIP); | ||
2314 | current_setup_menu[--set_menu_itemon].m_flags |= S_HILITE; | ||
2315 | } | ||
2316 | |||
2317 | // The drawing part of the Key Bindings Setup initialization. Draw the | ||
2318 | // background, title, instruction line, and items. | ||
2319 | |||
2320 | void M_DrawKeybnd(void) | ||
2321 | |||
2322 | { | ||
2323 | inhelpscreens = true; // killough 4/6/98: Force status bar redraw | ||
2324 | |||
2325 | // Set up the Key Binding screen | ||
2326 | |||
2327 | M_DrawBackground("FLOOR4_6", 0); // Draw background | ||
2328 | // proff/nicolas 09/20/98 -- changed for hi-res | ||
2329 | V_DrawNamePatch(84, 2, 0, "M_KEYBND", CR_DEFAULT, VPT_STRETCH); | ||
2330 | M_DrawInstructions(); | ||
2331 | M_DrawScreenItems(current_setup_menu); | ||
2332 | |||
2333 | // If the Reset Button has been selected, an "Are you sure?" message | ||
2334 | // is overlayed across everything else. | ||
2335 | |||
2336 | if (default_verify) | ||
2337 | M_DrawDefVerify(); | ||
2338 | } | ||
2339 | |||
2340 | ///////////////////////////// | ||
2341 | // | ||
2342 | // The Weapon Screen tables. | ||
2343 | |||
2344 | #define WP_X 203 | ||
2345 | #define WP_Y 33 | ||
2346 | |||
2347 | // There's only one weapon settings screen (for now). But since we're | ||
2348 | // trying to fit a common description for screens, it gets a setup_menu_t, | ||
2349 | // which only has one screen definition in it. | ||
2350 | // | ||
2351 | // Note that this screen has no PREV or NEXT items, since there are no | ||
2352 | // neighboring screens. | ||
2353 | |||
2354 | enum { // killough 10/98: enum for y-offset info | ||
2355 | weap_recoil, | ||
2356 | weap_bobbing, | ||
2357 | weap_bfg, | ||
2358 | weap_stub1, | ||
2359 | weap_pref1, | ||
2360 | weap_pref2, | ||
2361 | weap_pref3, | ||
2362 | weap_pref4, | ||
2363 | weap_pref5, | ||
2364 | weap_pref6, | ||
2365 | weap_pref7, | ||
2366 | weap_pref8, | ||
2367 | weap_pref9, | ||
2368 | weap_stub2, | ||
2369 | weap_toggle, | ||
2370 | weap_toggle2, | ||
2371 | }; | ||
2372 | |||
2373 | setup_menu_t weap_settings1[]; | ||
2374 | |||
2375 | setup_menu_t* weap_settings[] = | ||
2376 | { | ||
2377 | weap_settings1, | ||
2378 | NULL | ||
2379 | }; | ||
2380 | |||
2381 | setup_menu_t weap_settings1[] = // Weapons Settings screen | ||
2382 | { | ||
2383 | {"ENABLE RECOIL", S_YESNO,m_null,WP_X, WP_Y+ weap_recoil*8, {"weapon_recoil"}}, | ||
2384 | {"ENABLE BOBBING",S_YESNO,m_null,WP_X, WP_Y+weap_bobbing*8, {"player_bobbing"}}, | ||
2385 | |||
2386 | {"1ST CHOICE WEAPON",S_WEAP,m_null,WP_X,WP_Y+weap_pref1*8, {"weapon_choice_1"}}, | ||
2387 | {"2nd CHOICE WEAPON",S_WEAP,m_null,WP_X,WP_Y+weap_pref2*8, {"weapon_choice_2"}}, | ||
2388 | {"3rd CHOICE WEAPON",S_WEAP,m_null,WP_X,WP_Y+weap_pref3*8, {"weapon_choice_3"}}, | ||
2389 | {"4th CHOICE WEAPON",S_WEAP,m_null,WP_X,WP_Y+weap_pref4*8, {"weapon_choice_4"}}, | ||
2390 | {"5th CHOICE WEAPON",S_WEAP,m_null,WP_X,WP_Y+weap_pref5*8, {"weapon_choice_5"}}, | ||
2391 | {"6th CHOICE WEAPON",S_WEAP,m_null,WP_X,WP_Y+weap_pref6*8, {"weapon_choice_6"}}, | ||
2392 | {"7th CHOICE WEAPON",S_WEAP,m_null,WP_X,WP_Y+weap_pref7*8, {"weapon_choice_7"}}, | ||
2393 | {"8th CHOICE WEAPON",S_WEAP,m_null,WP_X,WP_Y+weap_pref8*8, {"weapon_choice_8"}}, | ||
2394 | {"9th CHOICE WEAPON",S_WEAP,m_null,WP_X,WP_Y+weap_pref9*8, {"weapon_choice_9"}}, | ||
2395 | |||
2396 | {"Enable Fist/Chainsaw\n& SG/SSG toggle", S_YESNO, m_null, WP_X, | ||
2397 | WP_Y+ weap_toggle*8, {"doom_weapon_toggles"}}, | ||
2398 | |||
2399 | // Button for resetting to defaults | ||
2400 | {0,S_RESET,m_null,X_BUTTON,Y_BUTTON}, | ||
2401 | |||
2402 | // Final entry | ||
2403 | {0,S_SKIP|S_END,m_null} | ||
2404 | |||
2405 | }; | ||
2406 | |||
2407 | // Setting up for the Weapons screen. Turn on flags, set pointers, | ||
2408 | // locate the first item on the screen where the cursor is allowed to | ||
2409 | // land. | ||
2410 | |||
2411 | void M_Weapons(int choice) | ||
2412 | { | ||
2413 | M_SetupNextMenu(&WeaponDef); | ||
2414 | |||
2415 | setup_active = true; | ||
2416 | setup_screen = ss_weap; | ||
2417 | set_weapon_active = true; | ||
2418 | setup_select = false; | ||
2419 | default_verify = false; | ||
2420 | setup_gather = false; | ||
2421 | mult_screens_index = 0; | ||
2422 | current_setup_menu = weap_settings[0]; | ||
2423 | set_menu_itemon = 0; | ||
2424 | while (current_setup_menu[set_menu_itemon++].m_flags & S_SKIP); | ||
2425 | current_setup_menu[--set_menu_itemon].m_flags |= S_HILITE; | ||
2426 | } | ||
2427 | |||
2428 | |||
2429 | // The drawing part of the Weapons Setup initialization. Draw the | ||
2430 | // background, title, instruction line, and items. | ||
2431 | |||
2432 | void M_DrawWeapons(void) | ||
2433 | { | ||
2434 | inhelpscreens = true; // killough 4/6/98: Force status bar redraw | ||
2435 | |||
2436 | M_DrawBackground("FLOOR4_6", 0); // Draw background | ||
2437 | // proff/nicolas 09/20/98 -- changed for hi-res | ||
2438 | V_DrawNamePatch(109, 2, 0, "M_WEAP", CR_DEFAULT, VPT_STRETCH); | ||
2439 | M_DrawInstructions(); | ||
2440 | M_DrawScreenItems(current_setup_menu); | ||
2441 | |||
2442 | // If the Reset Button has been selected, an "Are you sure?" message | ||
2443 | // is overlayed across everything else. | ||
2444 | |||
2445 | if (default_verify) | ||
2446 | M_DrawDefVerify(); | ||
2447 | } | ||
2448 | |||
2449 | ///////////////////////////// | ||
2450 | // | ||
2451 | // The Status Bar / HUD tables. | ||
2452 | |||
2453 | #define ST_X 203 | ||
2454 | #define ST_Y 31 | ||
2455 | |||
2456 | // Screen table definitions | ||
2457 | |||
2458 | setup_menu_t stat_settings1[]; | ||
2459 | |||
2460 | setup_menu_t* stat_settings[] = | ||
2461 | { | ||
2462 | stat_settings1, | ||
2463 | NULL | ||
2464 | }; | ||
2465 | |||
2466 | setup_menu_t stat_settings1[] = // Status Bar and HUD Settings screen | ||
2467 | { | ||
2468 | {"STATUS BAR" ,S_SKIP|S_TITLE,m_null,ST_X,ST_Y+ 1*8 }, | ||
2469 | |||
2470 | {"USE RED NUMBERS" ,S_YESNO, m_null,ST_X,ST_Y+ 2*8, {"sts_always_red"}}, | ||
2471 | {"GRAY %" ,S_YESNO, m_null,ST_X,ST_Y+ 3*8, {"sts_pct_always_gray"}}, | ||
2472 | {"SINGLE KEY DISPLAY",S_YESNO, m_null,ST_X,ST_Y+ 4*8, {"sts_traditional_keys"}}, | ||
2473 | |||
2474 | {"HEADS-UP DISPLAY" ,S_SKIP|S_TITLE,m_null,ST_X,ST_Y+ 6*8}, | ||
2475 | |||
2476 | {"HIDE SECRETS" ,S_YESNO ,m_null,ST_X,ST_Y+ 7*8, {"hud_nosecrets"}}, | ||
2477 | {"HEALTH LOW/OK" ,S_NUM ,m_null,ST_X,ST_Y+ 8*8, {"health_red"}}, | ||
2478 | {"HEALTH OK/GOOD" ,S_NUM ,m_null,ST_X,ST_Y+ 9*8, {"health_yellow"}}, | ||
2479 | {"HEALTH GOOD/EXTRA" ,S_NUM ,m_null,ST_X,ST_Y+10*8, {"health_green"}}, | ||
2480 | {"ARMOR LOW/OK" ,S_NUM ,m_null,ST_X,ST_Y+11*8, {"armor_red"}}, | ||
2481 | {"ARMOR OK/GOOD" ,S_NUM ,m_null,ST_X,ST_Y+12*8, {"armor_yellow"}}, | ||
2482 | {"ARMOR GOOD/EXTRA" ,S_NUM ,m_null,ST_X,ST_Y+13*8, {"armor_green"}}, | ||
2483 | {"AMMO LOW/OK" ,S_NUM ,m_null,ST_X,ST_Y+14*8, {"ammo_red"}}, | ||
2484 | {"AMMO OK/GOOD" ,S_NUM ,m_null,ST_X,ST_Y+15*8, {"ammo_yellow"}}, | ||
2485 | |||
2486 | // Button for resetting to defaults | ||
2487 | {0,S_RESET,m_null,X_BUTTON,Y_BUTTON}, | ||
2488 | |||
2489 | // Final entry | ||
2490 | {0,S_SKIP|S_END,m_null} | ||
2491 | }; | ||
2492 | |||
2493 | // Setting up for the Status Bar / HUD screen. Turn on flags, set pointers, | ||
2494 | // locate the first item on the screen where the cursor is allowed to | ||
2495 | // land. | ||
2496 | |||
2497 | void M_StatusBar(int choice) | ||
2498 | { | ||
2499 | M_SetupNextMenu(&StatusHUDDef); | ||
2500 | |||
2501 | setup_active = true; | ||
2502 | setup_screen = ss_stat; | ||
2503 | set_status_active = true; | ||
2504 | setup_select = false; | ||
2505 | default_verify = false; | ||
2506 | setup_gather = false; | ||
2507 | mult_screens_index = 0; | ||
2508 | current_setup_menu = stat_settings[0]; | ||
2509 | set_menu_itemon = 0; | ||
2510 | while (current_setup_menu[set_menu_itemon++].m_flags & S_SKIP); | ||
2511 | current_setup_menu[--set_menu_itemon].m_flags |= S_HILITE; | ||
2512 | } | ||
2513 | |||
2514 | |||
2515 | // The drawing part of the Status Bar / HUD Setup initialization. Draw the | ||
2516 | // background, title, instruction line, and items. | ||
2517 | |||
2518 | void M_DrawStatusHUD(void) | ||
2519 | |||
2520 | { | ||
2521 | inhelpscreens = true; // killough 4/6/98: Force status bar redraw | ||
2522 | |||
2523 | M_DrawBackground("FLOOR4_6", 0); // Draw background | ||
2524 | // proff/nicolas 09/20/98 -- changed for hi-res | ||
2525 | V_DrawNamePatch(59, 2, 0, "M_STAT", CR_DEFAULT, VPT_STRETCH); | ||
2526 | M_DrawInstructions(); | ||
2527 | M_DrawScreenItems(current_setup_menu); | ||
2528 | |||
2529 | // If the Reset Button has been selected, an "Are you sure?" message | ||
2530 | // is overlayed across everything else. | ||
2531 | |||
2532 | if (default_verify) | ||
2533 | M_DrawDefVerify(); | ||
2534 | } | ||
2535 | |||
2536 | |||
2537 | ///////////////////////////// | ||
2538 | // | ||
2539 | // The Automap tables. | ||
2540 | |||
2541 | #define AU_X 250 | ||
2542 | #define AU_Y 31 | ||
2543 | #define AU_PREV KB_PREV | ||
2544 | #define AU_NEXT KB_NEXT | ||
2545 | |||
2546 | setup_menu_t auto_settings1[]; | ||
2547 | setup_menu_t auto_settings2[]; | ||
2548 | |||
2549 | setup_menu_t* auto_settings[] = | ||
2550 | { | ||
2551 | auto_settings1, | ||
2552 | auto_settings2, | ||
2553 | NULL | ||
2554 | }; | ||
2555 | |||
2556 | setup_menu_t auto_settings1[] = // 1st AutoMap Settings screen | ||
2557 | { | ||
2558 | {"background", S_COLOR, m_null, AU_X, AU_Y, {"mapcolor_back"}}, | ||
2559 | {"grid lines", S_COLOR, m_null, AU_X, AU_Y + 1*8, {"mapcolor_grid"}}, | ||
2560 | {"normal 1s wall", S_COLOR, m_null,AU_X,AU_Y+ 2*8, {"mapcolor_wall"}}, | ||
2561 | {"line at floor height change", S_COLOR, m_null, AU_X, AU_Y+ 3*8, {"mapcolor_fchg"}}, | ||
2562 | {"line at ceiling height change" ,S_COLOR,m_null,AU_X,AU_Y+ 4*8, {"mapcolor_cchg"}}, | ||
2563 | {"line at sector with floor = ceiling",S_COLOR,m_null,AU_X,AU_Y+ 5*8, {"mapcolor_clsd"}}, | ||
2564 | {"red key" ,S_COLOR,m_null,AU_X,AU_Y+ 6*8, {"mapcolor_rkey"}}, | ||
2565 | {"blue key" ,S_COLOR,m_null,AU_X,AU_Y+ 7*8, {"mapcolor_bkey"}}, | ||
2566 | {"yellow key" ,S_COLOR,m_null,AU_X,AU_Y+ 8*8, {"mapcolor_ykey"}}, | ||
2567 | {"red door" ,S_COLOR,m_null,AU_X,AU_Y+ 9*8, {"mapcolor_rdor"}}, | ||
2568 | {"blue door" ,S_COLOR,m_null,AU_X,AU_Y+10*8, {"mapcolor_bdor"}}, | ||
2569 | {"yellow door" ,S_COLOR,m_null,AU_X,AU_Y+11*8, {"mapcolor_ydor"}}, | ||
2570 | |||
2571 | {"AUTOMAP LEVEL TITLE COLOR" ,S_CRITEM,m_null,AU_X,AU_Y+13*8, {"hudcolor_titl"}}, | ||
2572 | {"AUTOMAP COORDINATES COLOR" ,S_CRITEM,m_null,AU_X,AU_Y+14*8, {"hudcolor_xyco"}}, | ||
2573 | |||
2574 | {"Show Secrets only after entering",S_YESNO,m_null,AU_X,AU_Y+15*8, {"map_secret_after"}}, | ||
2575 | |||
2576 | {"Show coordinates of automap pointer",S_YESNO,m_null,AU_X,AU_Y+16*8, {"map_point_coord"}}, // killough 10/98 | ||
2577 | |||
2578 | // Button for resetting to defaults | ||
2579 | {0,S_RESET,m_null,X_BUTTON,Y_BUTTON}, | ||
2580 | |||
2581 | {"NEXT ->",S_SKIP|S_NEXT,m_null,AU_NEXT,AU_Y+20*8, {auto_settings2}}, | ||
2582 | |||
2583 | // Final entry | ||
2584 | {0,S_SKIP|S_END,m_null} | ||
2585 | |||
2586 | }; | ||
2587 | |||
2588 | setup_menu_t auto_settings2[] = // 2nd AutoMap Settings screen | ||
2589 | { | ||
2590 | {"teleporter line" ,S_COLOR ,m_null,AU_X,AU_Y, {"mapcolor_tele"}}, | ||
2591 | {"secret sector boundary" ,S_COLOR ,m_null,AU_X,AU_Y+ 1*8, {"mapcolor_secr"}}, | ||
2592 | //jff 4/23/98 add exit line to automap | ||
2593 | {"exit line" ,S_COLOR ,m_null,AU_X,AU_Y+ 2*8, {"mapcolor_exit"}}, | ||
2594 | {"computer map unseen line" ,S_COLOR ,m_null,AU_X,AU_Y+ 3*8, {"mapcolor_unsn"}}, | ||
2595 | {"line w/no floor/ceiling changes",S_COLOR ,m_null,AU_X,AU_Y+ 4*8, {"mapcolor_flat"}}, | ||
2596 | {"general sprite" ,S_COLOR ,m_null,AU_X,AU_Y+ 5*8, {"mapcolor_sprt"}}, | ||
2597 | {"countable enemy sprite" ,S_COLOR ,m_null,AU_X,AU_Y+ 6*8, {"mapcolor_enemy"}}, // cph 2006/06/30 | ||
2598 | {"countable item sprite" ,S_COLOR ,m_null,AU_X,AU_Y+ 7*8, {"mapcolor_item"}}, // mead 3/4/2003 | ||
2599 | {"crosshair" ,S_COLOR ,m_null,AU_X,AU_Y+ 8*8, {"mapcolor_hair"}}, | ||
2600 | {"single player arrow" ,S_COLOR ,m_null,AU_X,AU_Y+ 9*8, {"mapcolor_sngl"}}, | ||
2601 | {"your colour in multiplayer" ,S_COLOR ,m_null,AU_X,AU_Y+10*8, {"mapcolor_me"}}, | ||
2602 | |||
2603 | {"friends" ,S_COLOR ,m_null,AU_X,AU_Y+12*8, {"mapcolor_frnd"}}, // killough 8/8/98 | ||
2604 | |||
2605 | {"<- PREV",S_SKIP|S_PREV,m_null,AU_PREV,AU_Y+20*8, {auto_settings1}}, | ||
2606 | |||
2607 | // Final entry | ||
2608 | |||
2609 | {0,S_SKIP|S_END,m_null} | ||
2610 | |||
2611 | }; | ||
2612 | |||
2613 | |||
2614 | // Setting up for the Automap screen. Turn on flags, set pointers, | ||
2615 | // locate the first item on the screen where the cursor is allowed to | ||
2616 | // land. | ||
2617 | |||
2618 | void M_Automap(int choice) | ||
2619 | { | ||
2620 | M_SetupNextMenu(&AutoMapDef); | ||
2621 | |||
2622 | setup_active = true; | ||
2623 | setup_screen = ss_auto; | ||
2624 | set_auto_active = true; | ||
2625 | setup_select = false; | ||
2626 | colorbox_active = false; | ||
2627 | default_verify = false; | ||
2628 | setup_gather = false; | ||
2629 | set_menu_itemon = 0; | ||
2630 | mult_screens_index = 0; | ||
2631 | current_setup_menu = auto_settings[0]; | ||
2632 | while (current_setup_menu[set_menu_itemon++].m_flags & S_SKIP); | ||
2633 | current_setup_menu[--set_menu_itemon].m_flags |= S_HILITE; | ||
2634 | } | ||
2635 | |||
2636 | // Data used by the color palette that is displayed for the player to | ||
2637 | // select colors. | ||
2638 | |||
2639 | int color_palette_x; // X position of the cursor on the color palette | ||
2640 | int color_palette_y; // Y position of the cursor on the color palette | ||
2641 | byte palette_background[16*(CHIP_SIZE+1)+8]; | ||
2642 | |||
2643 | // M_DrawColPal() draws the color palette when the user needs to select a | ||
2644 | // color. | ||
2645 | |||
2646 | // phares 4/1/98: now uses a single lump for the palette instead of | ||
2647 | // building the image out of individual paint chips. | ||
2648 | |||
2649 | static void M_DrawColPal(void) | ||
2650 | { | ||
2651 | int cpx, cpy; | ||
2652 | |||
2653 | // Draw a background, border, and paint chips | ||
2654 | |||
2655 | // proff/nicolas 09/20/98 -- changed for hi-res | ||
2656 | // CPhipps - patch drawing updated | ||
2657 | V_DrawNamePatch(COLORPALXORIG-5, COLORPALYORIG-5, 0, "M_COLORS", CR_DEFAULT, VPT_STRETCH); | ||
2658 | |||
2659 | // Draw the cursor around the paint chip | ||
2660 | // (cpx,cpy) is the upper left-hand corner of the paint chip | ||
2661 | |||
2662 | cpx = COLORPALXORIG+color_palette_x*(CHIP_SIZE+1)-1; | ||
2663 | cpy = COLORPALYORIG+color_palette_y*(CHIP_SIZE+1)-1; | ||
2664 | // proff 12/6/98: Drawing of colorchips completly changed for hi-res, it now uses a patch | ||
2665 | V_DrawNamePatch(cpx,cpy,0,"M_PALSEL",CR_DEFAULT,VPT_STRETCH); // PROFF_GL_FIX | ||
2666 | } | ||
2667 | |||
2668 | // The drawing part of the Automap Setup initialization. Draw the | ||
2669 | // background, title, instruction line, and items. | ||
2670 | |||
2671 | void M_DrawAutoMap(void) | ||
2672 | |||
2673 | { | ||
2674 | inhelpscreens = true; // killough 4/6/98: Force status bar redraw | ||
2675 | |||
2676 | M_DrawBackground("FLOOR4_6", 0); // Draw background | ||
2677 | // CPhipps - patch drawing updated | ||
2678 | V_DrawNamePatch(109, 2, 0, "M_AUTO", CR_DEFAULT, VPT_STRETCH); | ||
2679 | M_DrawInstructions(); | ||
2680 | M_DrawScreenItems(current_setup_menu); | ||
2681 | |||
2682 | // If a color is being selected, need to show color paint chips | ||
2683 | |||
2684 | if (colorbox_active) | ||
2685 | M_DrawColPal(); | ||
2686 | |||
2687 | // If the Reset Button has been selected, an "Are you sure?" message | ||
2688 | // is overlayed across everything else. | ||
2689 | |||
2690 | else if (default_verify) | ||
2691 | M_DrawDefVerify(); | ||
2692 | } | ||
2693 | |||
2694 | |||
2695 | ///////////////////////////// | ||
2696 | // | ||
2697 | // The Enemies table. | ||
2698 | |||
2699 | #define E_X 250 | ||
2700 | #define E_Y 31 | ||
2701 | |||
2702 | setup_menu_t enem_settings1[]; | ||
2703 | |||
2704 | setup_menu_t* enem_settings[] = | ||
2705 | { | ||
2706 | enem_settings1, | ||
2707 | NULL | ||
2708 | }; | ||
2709 | |||
2710 | enum { | ||
2711 | enem_infighting, | ||
2712 | |||
2713 | enem_remember = 1, | ||
2714 | |||
2715 | enem_backing, | ||
2716 | enem_monkeys, | ||
2717 | enem_avoid_hazards, | ||
2718 | enem_friction, | ||
2719 | enem_help_friends, | ||
2720 | |||
2721 | #ifdef DOGS | ||
2722 | enem_helpers, | ||
2723 | #endif | ||
2724 | |||
2725 | enem_distfriend, | ||
2726 | |||
2727 | #ifdef DOGS | ||
2728 | enem_dog_jumping, | ||
2729 | #endif | ||
2730 | |||
2731 | enem_end | ||
2732 | }; | ||
2733 | |||
2734 | setup_menu_t enem_settings1[] = // Enemy Settings screen | ||
2735 | { | ||
2736 | // killough 7/19/98 | ||
2737 | {"Monster Infighting When Provoked",S_YESNO,m_null,E_X,E_Y+ enem_infighting*8, {"monster_infighting"}}, | ||
2738 | |||
2739 | {"Remember Previous Enemy",S_YESNO,m_null,E_X,E_Y+ enem_remember*8, {"monsters_remember"}}, | ||
2740 | |||
2741 | // killough 9/8/98 | ||
2742 | {"Monster Backing Out",S_YESNO,m_null,E_X,E_Y+ enem_backing*8, {"monster_backing"}}, | ||
2743 | |||
2744 | {"Climb Steep Stairs", S_YESNO,m_null,E_X,E_Y+enem_monkeys*8, {"monkeys"}}, | ||
2745 | |||
2746 | // killough 9/9/98 | ||
2747 | {"Intelligently Avoid Hazards",S_YESNO,m_null,E_X,E_Y+ enem_avoid_hazards*8, {"monster_avoid_hazards"}}, | ||
2748 | |||
2749 | // killough 10/98 | ||
2750 | {"Affected by Friction",S_YESNO,m_null,E_X,E_Y+ enem_friction*8, {"monster_friction"}}, | ||
2751 | |||
2752 | {"Rescue Dying Friends",S_YESNO,m_null,E_X,E_Y+ enem_help_friends*8, {"help_friends"}}, | ||
2753 | |||
2754 | #ifdef DOGS | ||
2755 | // killough 7/19/98 | ||
2756 | {"Number Of Single-Player Helper Dogs",S_NUM|S_LEVWARN,m_null,E_X,E_Y+ enem_helpers*8, {"player_helpers"}}, | ||
2757 | |||
2758 | // killough 8/8/98 | ||
2759 | {"Distance Friends Stay Away",S_NUM,m_null,E_X,E_Y+ enem_distfriend*8, {"friend_distance"}}, | ||
2760 | |||
2761 | {"Allow dogs to jump down",S_YESNO,m_null,E_X,E_Y+ enem_dog_jumping*8, {"dog_jumping"}}, | ||
2762 | #endif | ||
2763 | |||
2764 | // Button for resetting to defaults | ||
2765 | {0,S_RESET,m_null,X_BUTTON,Y_BUTTON}, | ||
2766 | |||
2767 | // Final entry | ||
2768 | {0,S_SKIP|S_END,m_null} | ||
2769 | |||
2770 | }; | ||
2771 | |||
2772 | ///////////////////////////// | ||
2773 | |||
2774 | // Setting up for the Enemies screen. Turn on flags, set pointers, | ||
2775 | // locate the first item on the screen where the cursor is allowed to | ||
2776 | // land. | ||
2777 | |||
2778 | void M_Enemy(int choice) | ||
2779 | { | ||
2780 | M_SetupNextMenu(&EnemyDef); | ||
2781 | |||
2782 | setup_active = true; | ||
2783 | setup_screen = ss_enem; | ||
2784 | set_enemy_active = true; | ||
2785 | setup_select = false; | ||
2786 | default_verify = false; | ||
2787 | setup_gather = false; | ||
2788 | mult_screens_index = 0; | ||
2789 | current_setup_menu = enem_settings[0]; | ||
2790 | set_menu_itemon = 0; | ||
2791 | while (current_setup_menu[set_menu_itemon++].m_flags & S_SKIP); | ||
2792 | current_setup_menu[--set_menu_itemon].m_flags |= S_HILITE; | ||
2793 | } | ||
2794 | |||
2795 | // The drawing part of the Enemies Setup initialization. Draw the | ||
2796 | // background, title, instruction line, and items. | ||
2797 | |||
2798 | void M_DrawEnemy(void) | ||
2799 | |||
2800 | { | ||
2801 | inhelpscreens = true; | ||
2802 | |||
2803 | M_DrawBackground("FLOOR4_6", 0); // Draw background | ||
2804 | // proff/nicolas 09/20/98 -- changed for hi-res | ||
2805 | V_DrawNamePatch(114, 2, 0, "M_ENEM", CR_DEFAULT, VPT_STRETCH); | ||
2806 | M_DrawInstructions(); | ||
2807 | M_DrawScreenItems(current_setup_menu); | ||
2808 | |||
2809 | // If the Reset Button has been selected, an "Are you sure?" message | ||
2810 | // is overlayed across everything else. | ||
2811 | |||
2812 | if (default_verify) | ||
2813 | M_DrawDefVerify(); | ||
2814 | } | ||
2815 | |||
2816 | |||
2817 | ///////////////////////////// | ||
2818 | // | ||
2819 | // The General table. | ||
2820 | // killough 10/10/98 | ||
2821 | |||
2822 | extern int usejoystick, usemouse, default_mus_card, default_snd_card; | ||
2823 | extern int detect_voices, realtic_clock_rate, tran_filter_pct; | ||
2824 | |||
2825 | setup_menu_t gen_settings1[], gen_settings2[], gen_settings3[]; | ||
2826 | |||
2827 | setup_menu_t* gen_settings[] = | ||
2828 | { | ||
2829 | gen_settings1, | ||
2830 | gen_settings2, | ||
2831 | gen_settings3, | ||
2832 | NULL | ||
2833 | }; | ||
2834 | |||
2835 | enum { | ||
2836 | general_trans, | ||
2837 | general_transpct, | ||
2838 | general_fullscreen, | ||
2839 | general_videomode, | ||
2840 | // general_pcx, | ||
2841 | // general_diskicon, | ||
2842 | general_uncapped, | ||
2843 | }; | ||
2844 | |||
2845 | enum { | ||
2846 | general_gl_texfilter, | ||
2847 | general_gl_texformat, | ||
2848 | general_flooroffset, | ||
2849 | }; | ||
2850 | |||
2851 | enum { | ||
2852 | // general_sndcard, | ||
2853 | // general_muscard, | ||
2854 | // general_detvoices, | ||
2855 | general_sndchan, | ||
2856 | general_pitch | ||
2857 | }; | ||
2858 | |||
2859 | #define G_X 250 | ||
2860 | #define G_YA 44 | ||
2861 | #define G_YA2 (G_YA+9*8) | ||
2862 | #define G_YA3 (G_YA2+5*8) | ||
2863 | #define GF_X 76 | ||
2864 | |||
2865 | static const char *videomodes[] = {"8bit","15bit","16bit", | ||
2866 | "32bit","OpenGL", NULL}; | ||
2867 | |||
2868 | static const char *gltexfilters[] = {"GL_NEAREST","GL_LINEAR", | ||
2869 | "GL_LINEAR_MIPMAP_LINEAR", | ||
2870 | NULL}; | ||
2871 | |||
2872 | static const char *gltexformats[] = {"GL_RGBA","GL_RGB5_A1", | ||
2873 | "GL_RGBA4", NULL}; | ||
2874 | |||
2875 | setup_menu_t gen_settings1[] = { // General Settings screen1 | ||
2876 | |||
2877 | {"Video" ,S_SKIP|S_TITLE, m_null, G_X, G_YA - 12}, | ||
2878 | |||
2879 | {"Enable Translucency", S_YESNO, m_null, G_X, | ||
2880 | G_YA + general_trans*8, {"translucency"}, 0, 0, M_Trans}, | ||
2881 | |||
2882 | {"Translucency filter percentage", S_NUM, m_null, G_X, | ||
2883 | G_YA + general_transpct*8, {"tran_filter_pct"}, 0, 0, M_Trans}, | ||
2884 | |||
2885 | {"Fullscreen Video mode", S_YESNO|S_PRGWARN, m_null, G_X, | ||
2886 | G_YA + general_fullscreen*8, {"use_fullscreen"}, 0, 0, NULL}, | ||
2887 | |||
2888 | {"Video mode", S_CHOICE|S_PRGWARN, m_null, G_X, | ||
2889 | G_YA + general_videomode*8, {"videomode"}, 0, 0, NULL, videomodes}, | ||
2890 | |||
2891 | {"Uncapped Framerate", S_YESNO, m_null, G_X, | ||
2892 | G_YA + general_uncapped*8, {"uncapped_framerate"}}, | ||
2893 | |||
2894 | #ifdef GL_DOOM | ||
2895 | {"OpenGL", S_SKIP|S_TITLE, m_null, G_X, G_YA2 - 12}, | ||
2896 | |||
2897 | {"Texture filter", S_CHOICE|S_PRGWARN, m_null, G_X, | ||
2898 | G_YA2 + general_gl_texfilter*8, {"gl_tex_filter_string"}, 0, 0, NULL, gltexfilters}, | ||
2899 | |||
2900 | {"Texture format", S_CHOICE|S_PRGWARN, m_null, G_X, | ||
2901 | G_YA2 + general_gl_texformat*8, {"gl_tex_format_string"}, 0, 0, NULL, gltexformats}, | ||
2902 | |||
2903 | {"Item out of Floor offset", S_NUM, m_null, G_X, | ||
2904 | G_YA2 + general_flooroffset*8, {"gl_sprite_offset"}}, | ||
2905 | #endif | ||
2906 | |||
2907 | #if 0 | ||
2908 | {"PCX instead of BMP for screenshots", S_YESNO, m_null, G_X, | ||
2909 | G_YA + general_pcx*8, {"screenshot_pcx"}}, | ||
2910 | #endif | ||
2911 | |||
2912 | #if 0 // MBF | ||
2913 | {"Flash Icon During Disk IO", S_YESNO, m_null, G_X, | ||
2914 | G_YA + general_diskicon*8, {"disk_icon"}}, | ||
2915 | #endif | ||
2916 | |||
2917 | {"Sound & Music", S_SKIP|S_TITLE, m_null, G_X, G_YA3 - 12}, | ||
2918 | #if 0 // MBF | ||
2919 | {"Sound Card", S_NUM|S_PRGWARN, m_null, G_X, | ||
2920 | G_YA2 + general_sndcard*8, {"sound_card"}}, | ||
2921 | |||
2922 | {"Music Card", S_NUM|S_PRGWARN, m_null, G_X, | ||
2923 | G_YA2 + general_muscard*8, {"music_card"}}, | ||
2924 | |||
2925 | {"Autodetect Number of Voices", S_YESNO|S_PRGWARN, m_null, G_X, | ||
2926 | G_YA2 + general_detvoices*8, {"detect_voices"}}, | ||
2927 | #endif | ||
2928 | |||
2929 | {"Number of Sound Channels", S_NUM|S_PRGWARN, m_null, G_X, | ||
2930 | G_YA3 + general_sndchan*8, {"snd_channels"}}, | ||
2931 | |||
2932 | {"Enable v1.1 Pitch Effects", S_YESNO, m_null, G_X, | ||
2933 | G_YA3 + general_pitch*8, {"pitched_sounds"}}, | ||
2934 | |||
2935 | // Button for resetting to defaults | ||
2936 | {0,S_RESET,m_null,X_BUTTON,Y_BUTTON}, | ||
2937 | |||
2938 | {"NEXT ->",S_SKIP|S_NEXT,m_null,KB_NEXT,KB_Y+20*8, {gen_settings2}}, | ||
2939 | |||
2940 | // Final entry | ||
2941 | {0,S_SKIP|S_END,m_null} | ||
2942 | }; | ||
2943 | |||
2944 | enum { | ||
2945 | general_mouse, | ||
2946 | general_joy, | ||
2947 | general_leds | ||
2948 | }; | ||
2949 | |||
2950 | enum { | ||
2951 | general_wad1, | ||
2952 | general_wad2, | ||
2953 | general_deh1, | ||
2954 | general_deh2 | ||
2955 | }; | ||
2956 | |||
2957 | enum { | ||
2958 | general_corpse, | ||
2959 | general_realtic, | ||
2960 | general_smooth, | ||
2961 | general_smoothfactor, | ||
2962 | general_defskill, | ||
2963 | }; | ||
2964 | |||
2965 | #define G_YB 44 | ||
2966 | #define G_YB1 (G_YB+44) | ||
2967 | #define G_YB2 (G_YB1+52) | ||
2968 | |||
2969 | static const char *gen_skillstrings[] = { | ||
2970 | // Dummy first option because defaultskill is 1-based | ||
2971 | "", "ITYTD", "HNTR", "HMP", "UV", "NM", NULL | ||
2972 | }; | ||
2973 | |||
2974 | setup_menu_t gen_settings2[] = { // General Settings screen2 | ||
2975 | |||
2976 | {"Input Devices" ,S_SKIP|S_TITLE, m_null, G_X, G_YB - 12}, | ||
2977 | |||
2978 | {"Enable Mouse", S_YESNO, m_null, G_X, | ||
2979 | G_YB + general_mouse*8, {"use_mouse"}}, | ||
2980 | |||
2981 | {"Enable Joystick", S_YESNO, m_null, G_X, | ||
2982 | G_YB + general_joy*8, {"use_joystick"}}, | ||
2983 | |||
2984 | {"Files Preloaded at Game Startup",S_SKIP|S_TITLE, m_null, G_X, | ||
2985 | G_YB1 - 12}, | ||
2986 | |||
2987 | {"WAD # 1", S_FILE, m_null, GF_X, G_YB1 + general_wad1*8, {"wadfile_1"}}, | ||
2988 | |||
2989 | {"WAD #2", S_FILE, m_null, GF_X, G_YB1 + general_wad2*8, {"wadfile_2"}}, | ||
2990 | |||
2991 | {"DEH/BEX # 1", S_FILE, m_null, GF_X, G_YB1 + general_deh1*8, {"dehfile_1"}}, | ||
2992 | |||
2993 | {"DEH/BEX #2", S_FILE, m_null, GF_X, G_YB1 + general_deh2*8, {"dehfile_2"}}, | ||
2994 | |||
2995 | {"Miscellaneous" ,S_SKIP|S_TITLE, m_null, G_X, G_YB2 - 12}, | ||
2996 | |||
2997 | {"Maximum number of player corpses", S_NUM|S_PRGWARN, m_null, G_X, | ||
2998 | G_YB2 + general_corpse*8, {"max_player_corpse"}}, | ||
2999 | |||
3000 | {"Game speed, percentage of normal", S_NUM|S_PRGWARN, m_null, G_X, | ||
3001 | G_YB2 + general_realtic*8, {"realtic_clock_rate"}}, | ||
3002 | |||
3003 | {"Smooth Demo Playback", S_YESNO, m_null, G_X, | ||
3004 | G_YB2 + general_smooth*8, {"demo_smoothturns"}, 0, 0, M_ChangeDemoSmoothTurns}, | ||
3005 | |||
3006 | {"Smooth Demo Playback Factor", S_NUM, m_null, G_X, | ||
3007 | G_YB2 + general_smoothfactor*8, {"demo_smoothturnsfactor"}, 0, 0, M_ChangeDemoSmoothTurns}, | ||
3008 | |||
3009 | {"Default skill level", S_CHOICE, m_null, G_X, | ||
3010 | G_YB2 + general_defskill*8, {"default_skill"}, 0, 0, NULL, gen_skillstrings}, | ||
3011 | |||
3012 | {"<- PREV",S_SKIP|S_PREV, m_null, KB_PREV, KB_Y+20*8, {gen_settings1}}, | ||
3013 | |||
3014 | {"NEXT ->",S_SKIP|S_NEXT,m_null,KB_NEXT,KB_Y+20*8, {gen_settings3}}, | ||
3015 | |||
3016 | // Final entry | ||
3017 | |||
3018 | {0,S_SKIP|S_END,m_null} | ||
3019 | }; | ||
3020 | |||
3021 | enum { | ||
3022 | general_filterwall, | ||
3023 | general_filterfloor, | ||
3024 | general_filtersprite, | ||
3025 | general_filterpatch, | ||
3026 | general_filterz, | ||
3027 | general_filter_threshold, | ||
3028 | general_spriteedges, | ||
3029 | general_patchedges, | ||
3030 | general_hom, | ||
3031 | }; | ||
3032 | |||
3033 | #define G_YC 44 | ||
3034 | |||
3035 | static const char *renderfilters[] = {"none", "point", "linear", "rounded"}; | ||
3036 | static const char *edgetypes[] = {"jagged", "sloped"}; | ||
3037 | |||
3038 | setup_menu_t gen_settings3[] = { // General Settings screen2 | ||
3039 | |||
3040 | {"Renderer settings" ,S_SKIP|S_TITLE, m_null, G_X, G_YB - 12}, | ||
3041 | |||
3042 | {"Filter for walls", S_CHOICE, m_null, G_X, | ||
3043 | G_YC + general_filterwall*8, {"filter_wall"}, 0, 0, NULL, renderfilters}, | ||
3044 | |||
3045 | {"Filter for floors/ceilings", S_CHOICE, m_null, G_X, | ||
3046 | G_YC + general_filterfloor*8, {"filter_floor"}, 0, 0, NULL, renderfilters}, | ||
3047 | |||
3048 | {"Filter for sprites", S_CHOICE, m_null, G_X, | ||
3049 | G_YC + general_filtersprite*8, {"filter_sprite"}, 0, 0, NULL, renderfilters}, | ||
3050 | |||
3051 | {"Filter for patches", S_CHOICE, m_null, G_X, | ||
3052 | G_YC + general_filterpatch*8, {"filter_patch"}, 0, 0, NULL, renderfilters}, | ||
3053 | |||
3054 | {"Filter for lighting", S_CHOICE, m_null, G_X, | ||
3055 | G_YC + general_filterz*8, {"filter_z"}, 0, 0, NULL, renderfilters}, | ||
3056 | |||
3057 | {"Drawing of sprite edges", S_CHOICE, m_null, G_X, | ||
3058 | G_YC + general_spriteedges*8, {"sprite_edges"}, 0, 0, NULL, edgetypes}, | ||
3059 | |||
3060 | {"Drawing of patch edges", S_CHOICE, m_null, G_X, | ||
3061 | G_YC + general_patchedges*8, {"patch_edges"}, 0, 0, NULL, edgetypes}, | ||
3062 | |||
3063 | {"Flashing HOM indicator", S_YESNO, m_null, G_X, | ||
3064 | G_YC + general_hom*8, {"flashing_hom"}}, | ||
3065 | |||
3066 | {"<- PREV",S_SKIP|S_PREV, m_null, KB_PREV, KB_Y+20*8, {gen_settings2}}, | ||
3067 | |||
3068 | // Final entry | ||
3069 | |||
3070 | {0,S_SKIP|S_END,m_null} | ||
3071 | }; | ||
3072 | |||
3073 | void M_Trans(void) // To reset translucency after setting it in menu | ||
3074 | { | ||
3075 | general_translucency = default_translucency; //e6y: Fix for "translucency won't change until you restart the engine" | ||
3076 | |||
3077 | if (general_translucency) | ||
3078 | R_InitTranMap(0); | ||
3079 | } | ||
3080 | |||
3081 | void M_FullScreen(void) // To (un)set fullscreen video after menu changes | ||
3082 | { | ||
3083 | I_UpdateVideoMode(); | ||
3084 | V_SetPalette(0); | ||
3085 | } | ||
3086 | |||
3087 | void M_ChangeDemoSmoothTurns(void) | ||
3088 | { | ||
3089 | if (demo_smoothturns) | ||
3090 | gen_settings2[12].m_flags &= ~(S_SKIP|S_SELECT); | ||
3091 | else | ||
3092 | gen_settings2[12].m_flags |= (S_SKIP|S_SELECT); | ||
3093 | |||
3094 | R_SmoothPlaying_Reset(NULL); | ||
3095 | } | ||
3096 | |||
3097 | // Setting up for the General screen. Turn on flags, set pointers, | ||
3098 | // locate the first item on the screen where the cursor is allowed to | ||
3099 | // land. | ||
3100 | |||
3101 | void M_General(int choice) | ||
3102 | { | ||
3103 | M_SetupNextMenu(&GeneralDef); | ||
3104 | |||
3105 | setup_active = true; | ||
3106 | setup_screen = ss_gen; | ||
3107 | set_general_active = true; | ||
3108 | setup_select = false; | ||
3109 | default_verify = false; | ||
3110 | setup_gather = false; | ||
3111 | mult_screens_index = 0; | ||
3112 | current_setup_menu = gen_settings[0]; | ||
3113 | set_menu_itemon = 0; | ||
3114 | while (current_setup_menu[set_menu_itemon++].m_flags & S_SKIP); | ||
3115 | current_setup_menu[--set_menu_itemon].m_flags |= S_HILITE; | ||
3116 | } | ||
3117 | |||
3118 | // The drawing part of the General Setup initialization. Draw the | ||
3119 | // background, title, instruction line, and items. | ||
3120 | |||
3121 | void M_DrawGeneral(void) | ||
3122 | { | ||
3123 | inhelpscreens = true; | ||
3124 | |||
3125 | M_DrawBackground("FLOOR4_6", 0); // Draw background | ||
3126 | // proff/nicolas 09/20/98 -- changed for hi-res | ||
3127 | V_DrawNamePatch(114, 2, 0, "M_GENERL", CR_DEFAULT, VPT_STRETCH); | ||
3128 | M_DrawInstructions(); | ||
3129 | M_DrawScreenItems(current_setup_menu); | ||
3130 | |||
3131 | // If the Reset Button has been selected, an "Are you sure?" message | ||
3132 | // is overlayed across everything else. | ||
3133 | |||
3134 | if (default_verify) | ||
3135 | M_DrawDefVerify(); | ||
3136 | } | ||
3137 | |||
3138 | ///////////////////////////// | ||
3139 | // | ||
3140 | // The Compatibility table. | ||
3141 | // killough 10/10/98 | ||
3142 | |||
3143 | #define C_X 284 | ||
3144 | #define C_Y 32 | ||
3145 | #define COMP_SPC 12 | ||
3146 | #define C_NEXTPREV 131 | ||
3147 | |||
3148 | setup_menu_t comp_settings1[], comp_settings2[], comp_settings3[]; | ||
3149 | |||
3150 | setup_menu_t* comp_settings[] = | ||
3151 | { | ||
3152 | comp_settings1, | ||
3153 | comp_settings2, | ||
3154 | comp_settings3, | ||
3155 | NULL | ||
3156 | }; | ||
3157 | |||
3158 | enum | ||
3159 | { | ||
3160 | compat_telefrag, | ||
3161 | compat_dropoff, | ||
3162 | compat_falloff, | ||
3163 | compat_staylift, | ||
3164 | compat_doorstuck, | ||
3165 | compat_pursuit, | ||
3166 | compat_vile, | ||
3167 | compat_pain, | ||
3168 | compat_skull, | ||
3169 | compat_blazing, | ||
3170 | compat_doorlight = 0, | ||
3171 | compat_god, | ||
3172 | compat_infcheat, | ||
3173 | compat_zombie, | ||
3174 | compat_skymap, | ||
3175 | compat_stairs, | ||
3176 | compat_floors, | ||
3177 | compat_moveblock, | ||
3178 | compat_model, | ||
3179 | compat_zerotags, | ||
3180 | compat_666 = 0, | ||
3181 | compat_soul, | ||
3182 | compat_maskedanim, | ||
3183 | }; | ||
3184 | |||
3185 | setup_menu_t comp_settings1[] = // Compatibility Settings screen #1 | ||
3186 | { | ||
3187 | {"Any monster can telefrag on MAP30", S_YESNO, m_null, C_X, | ||
3188 | C_Y + compat_telefrag * COMP_SPC, {"comp_telefrag"}}, | ||
3189 | |||
3190 | {"Some objects never hang over tall ledges", S_YESNO, m_null, C_X, | ||
3191 | C_Y + compat_dropoff * COMP_SPC, {"comp_dropoff"}}, | ||
3192 | |||
3193 | {"Objects don't fall under their own weight", S_YESNO, m_null, C_X, | ||
3194 | C_Y + compat_falloff * COMP_SPC, {"comp_falloff"}}, | ||
3195 | |||
3196 | {"Monsters randomly walk off of moving lifts", S_YESNO, m_null, C_X, | ||
3197 | C_Y + compat_staylift * COMP_SPC, {"comp_staylift"}}, | ||
3198 | |||
3199 | {"Monsters get stuck on doortracks", S_YESNO, m_null, C_X, | ||
3200 | C_Y + compat_doorstuck * COMP_SPC, {"comp_doorstuck"}}, | ||
3201 | |||
3202 | {"Monsters don't give up pursuit of targets", S_YESNO, m_null, C_X, | ||
3203 | C_Y + compat_pursuit * COMP_SPC, {"comp_pursuit"}}, | ||
3204 | |||
3205 | {"Arch-Vile resurrects invincible ghosts", S_YESNO, m_null, C_X, | ||
3206 | C_Y + compat_vile * COMP_SPC, {"comp_vile"}}, | ||
3207 | |||
3208 | {"Pain Elementals limited to 21 lost souls", S_YESNO, m_null, C_X, | ||
3209 | C_Y + compat_pain * COMP_SPC, {"comp_pain"}}, | ||
3210 | |||
3211 | {"Lost souls get stuck behind walls", S_YESNO, m_null, C_X, | ||
3212 | C_Y + compat_skull * COMP_SPC, {"comp_skull"}}, | ||
3213 | |||
3214 | {"Blazing doors make double closing sounds", S_YESNO, m_null, C_X, | ||
3215 | C_Y + compat_blazing * COMP_SPC, {"comp_blazing"}}, | ||
3216 | |||
3217 | // Button for resetting to defaults | ||
3218 | {0,S_RESET,m_null,X_BUTTON,Y_BUTTON}, | ||
3219 | |||
3220 | {"NEXT ->",S_SKIP|S_NEXT, m_null, KB_NEXT, C_Y+C_NEXTPREV, {comp_settings2}}, | ||
3221 | |||
3222 | // Final entry | ||
3223 | {0,S_SKIP|S_END,m_null} | ||
3224 | }; | ||
3225 | |||
3226 | setup_menu_t comp_settings2[] = // Compatibility Settings screen #2 | ||
3227 | { | ||
3228 | {"Tagged doors don't trigger special lighting", S_YESNO, m_null, C_X, | ||
3229 | C_Y + compat_doorlight * COMP_SPC, {"comp_doorlight"}}, | ||
3230 | |||
3231 | {"God mode isn't absolute", S_YESNO, m_null, C_X, | ||
3232 | C_Y + compat_god * COMP_SPC, {"comp_god"}}, | ||
3233 | |||
3234 | {"Powerup cheats are not infinite duration", S_YESNO, m_null, C_X, | ||
3235 | C_Y + compat_infcheat * COMP_SPC, {"comp_infcheat"}}, | ||
3236 | |||
3237 | {"Zombie players can exit levels", S_YESNO, m_null, C_X, | ||
3238 | C_Y + compat_zombie * COMP_SPC, {"comp_zombie"}}, | ||
3239 | |||
3240 | {"Sky is unaffected by invulnerability", S_YESNO, m_null, C_X, | ||
3241 | C_Y + compat_skymap * COMP_SPC, {"comp_skymap"}}, | ||
3242 | |||
3243 | {"Use exactly Doom's stairbuilding method", S_YESNO, m_null, C_X, | ||
3244 | C_Y + compat_stairs * COMP_SPC, {"comp_stairs"}}, | ||
3245 | |||
3246 | {"Use exactly Doom's floor motion behavior", S_YESNO, m_null, C_X, | ||
3247 | C_Y + compat_floors * COMP_SPC, {"comp_floors"}}, | ||
3248 | |||
3249 | {"Use exactly Doom's movement clipping code", S_YESNO, m_null, C_X, | ||
3250 | C_Y + compat_moveblock * COMP_SPC, {"comp_moveblock"}}, | ||
3251 | |||
3252 | {"Use exactly Doom's linedef trigger model", S_YESNO, m_null, C_X, | ||
3253 | C_Y + compat_model * COMP_SPC, {"comp_model"}}, | ||
3254 | |||
3255 | {"Linedef effects work with sector tag = 0", S_YESNO, m_null, C_X, | ||
3256 | C_Y + compat_zerotags * COMP_SPC, {"comp_zerotags"}}, | ||
3257 | |||
3258 | {"<- PREV", S_SKIP|S_PREV, m_null, KB_PREV, C_Y+C_NEXTPREV,{comp_settings1}}, | ||
3259 | |||
3260 | {"NEXT ->",S_SKIP|S_NEXT, m_null, KB_NEXT, C_Y+C_NEXTPREV, {comp_settings3}}, | ||
3261 | |||
3262 | // Final entry | ||
3263 | |||
3264 | {0,S_SKIP|S_END,m_null} | ||
3265 | }; | ||
3266 | |||
3267 | setup_menu_t comp_settings3[] = // Compatibility Settings screen #2 | ||
3268 | { | ||
3269 | {"All boss types can trigger tag 666 at ExM8", S_YESNO, m_null, C_X, | ||
3270 | C_Y + compat_666 * COMP_SPC, {"comp_666"}}, | ||
3271 | |||
3272 | {"Lost souls don't bounce off flat surfaces", S_YESNO, m_null, C_X, | ||
3273 | C_Y + compat_soul * COMP_SPC, {"comp_soul"}}, | ||
3274 | |||
3275 | {"2S middle textures do not animate", S_YESNO, m_null, C_X, | ||
3276 | C_Y + compat_maskedanim * COMP_SPC, {"comp_maskedanim"}}, | ||
3277 | |||
3278 | {"<- PREV", S_SKIP|S_PREV, m_null, KB_PREV, C_Y+C_NEXTPREV,{comp_settings2}}, | ||
3279 | |||
3280 | // Final entry | ||
3281 | |||
3282 | {0,S_SKIP|S_END,m_null} | ||
3283 | }; | ||
3284 | |||
3285 | // Setting up for the Compatibility screen. Turn on flags, set pointers, | ||
3286 | // locate the first item on the screen where the cursor is allowed to | ||
3287 | // land. | ||
3288 | |||
3289 | void M_Compat(int choice) | ||
3290 | { | ||
3291 | M_SetupNextMenu(&CompatDef); | ||
3292 | |||
3293 | setup_active = true; | ||
3294 | setup_screen = ss_comp; | ||
3295 | set_general_active = true; | ||
3296 | setup_select = false; | ||
3297 | default_verify = false; | ||
3298 | setup_gather = false; | ||
3299 | mult_screens_index = 0; | ||
3300 | current_setup_menu = comp_settings[0]; | ||
3301 | set_menu_itemon = 0; | ||
3302 | while (current_setup_menu[set_menu_itemon++].m_flags & S_SKIP); | ||
3303 | current_setup_menu[--set_menu_itemon].m_flags |= S_HILITE; | ||
3304 | } | ||
3305 | |||
3306 | // The drawing part of the Compatibility Setup initialization. Draw the | ||
3307 | // background, title, instruction line, and items. | ||
3308 | |||
3309 | void M_DrawCompat(void) | ||
3310 | { | ||
3311 | inhelpscreens = true; | ||
3312 | |||
3313 | M_DrawBackground("FLOOR4_6", 0); // Draw background | ||
3314 | V_DrawNamePatch(52,2,0,"M_COMPAT", CR_DEFAULT, VPT_STRETCH); | ||
3315 | M_DrawInstructions(); | ||
3316 | M_DrawScreenItems(current_setup_menu); | ||
3317 | |||
3318 | // If the Reset Button has been selected, an "Are you sure?" message | ||
3319 | // is overlayed across everything else. | ||
3320 | |||
3321 | if (default_verify) | ||
3322 | M_DrawDefVerify(); | ||
3323 | } | ||
3324 | |||
3325 | ///////////////////////////// | ||
3326 | // | ||
3327 | // The Messages table. | ||
3328 | |||
3329 | #define M_X 230 | ||
3330 | #define M_Y 39 | ||
3331 | |||
3332 | // killough 11/98: enumerated | ||
3333 | |||
3334 | enum { | ||
3335 | mess_color_play, | ||
3336 | mess_timer, | ||
3337 | mess_color_chat, | ||
3338 | mess_chat_timer, | ||
3339 | mess_color_review, | ||
3340 | mess_timed, | ||
3341 | mess_hud_timer, | ||
3342 | mess_lines, | ||
3343 | mess_scrollup, | ||
3344 | mess_background, | ||
3345 | }; | ||
3346 | |||
3347 | setup_menu_t mess_settings1[]; | ||
3348 | |||
3349 | setup_menu_t* mess_settings[] = | ||
3350 | { | ||
3351 | mess_settings1, | ||
3352 | NULL | ||
3353 | }; | ||
3354 | |||
3355 | setup_menu_t mess_settings1[] = // Messages screen | ||
3356 | { | ||
3357 | {"Message Color During Play", S_CRITEM, m_null, M_X, | ||
3358 | M_Y + mess_color_play*8, {"hudcolor_mesg"}}, | ||
3359 | |||
3360 | #if 0 | ||
3361 | {"Message Duration During Play (ms)", S_NUM, m_null, M_X, | ||
3362 | M_Y + mess_timer*8, {"message_timer"}}, | ||
3363 | #endif | ||
3364 | |||
3365 | {"Chat Message Color", S_CRITEM, m_null, M_X, | ||
3366 | M_Y + mess_color_chat*8, {"hudcolor_chat"}}, | ||
3367 | |||
3368 | #if 0 | ||
3369 | {"Chat Message Duration (ms)", S_NUM, m_null, M_X, | ||
3370 | M_Y + mess_chat_timer*8, {"chat_msg_timer"}}, | ||
3371 | #endif | ||
3372 | |||
3373 | {"Message Review Color", S_CRITEM, m_null, M_X, | ||
3374 | M_Y + mess_color_review*8, {"hudcolor_list"}}, | ||
3375 | |||
3376 | #if 0 | ||
3377 | {"Message Listing Review is Temporary", S_YESNO, m_null, M_X, | ||
3378 | M_Y + mess_timed*8, {"hud_msg_timed"}}, | ||
3379 | |||
3380 | {"Message Review Duration (ms)", S_NUM, m_null, M_X, | ||
3381 | M_Y + mess_hud_timer*8, {"hud_msg_timer"}}, | ||
3382 | #endif | ||
3383 | |||
3384 | {"Number of Review Message Lines", S_NUM, m_null, M_X, | ||
3385 | M_Y + mess_lines*8, {"hud_msg_lines"}}, | ||
3386 | |||
3387 | #if 0 | ||
3388 | {"Message Listing Scrolls Upwards", S_YESNO, m_null, M_X, | ||
3389 | M_Y + mess_scrollup*8, {"hud_msg_scrollup"}}, | ||
3390 | #endif | ||
3391 | |||
3392 | {"Message Background", S_YESNO, m_null, M_X, | ||
3393 | M_Y + mess_background*8, {"hud_list_bgon"}}, | ||
3394 | |||
3395 | // Button for resetting to defaults | ||
3396 | {0,S_RESET,m_null,X_BUTTON,Y_BUTTON}, | ||
3397 | |||
3398 | // Final entry | ||
3399 | |||
3400 | {0,S_SKIP|S_END,m_null} | ||
3401 | }; | ||
3402 | |||
3403 | |||
3404 | // Setting up for the Messages screen. Turn on flags, set pointers, | ||
3405 | // locate the first item on the screen where the cursor is allowed to | ||
3406 | // land. | ||
3407 | |||
3408 | void M_Messages(int choice) | ||
3409 | { | ||
3410 | M_SetupNextMenu(&MessageDef); | ||
3411 | |||
3412 | setup_active = true; | ||
3413 | setup_screen = ss_mess; | ||
3414 | set_mess_active = true; | ||
3415 | setup_select = false; | ||
3416 | default_verify = false; | ||
3417 | setup_gather = false; | ||
3418 | mult_screens_index = 0; | ||
3419 | current_setup_menu = mess_settings[0]; | ||
3420 | set_menu_itemon = 0; | ||
3421 | while (current_setup_menu[set_menu_itemon++].m_flags & S_SKIP); | ||
3422 | current_setup_menu[--set_menu_itemon].m_flags |= S_HILITE; | ||
3423 | } | ||
3424 | |||
3425 | |||
3426 | // The drawing part of the Messages Setup initialization. Draw the | ||
3427 | // background, title, instruction line, and items. | ||
3428 | |||
3429 | void M_DrawMessages(void) | ||
3430 | |||
3431 | { | ||
3432 | inhelpscreens = true; | ||
3433 | M_DrawBackground("FLOOR4_6", 0); // Draw background | ||
3434 | // CPhipps - patch drawing updated | ||
3435 | V_DrawNamePatch(103, 2, 0, "M_MESS", CR_DEFAULT, VPT_STRETCH); | ||
3436 | M_DrawInstructions(); | ||
3437 | M_DrawScreenItems(current_setup_menu); | ||
3438 | if (default_verify) | ||
3439 | M_DrawDefVerify(); | ||
3440 | } | ||
3441 | |||
3442 | |||
3443 | ///////////////////////////// | ||
3444 | // | ||
3445 | // The Chat Strings table. | ||
3446 | |||
3447 | #define CS_X 20 | ||
3448 | #define CS_Y (31+8) | ||
3449 | |||
3450 | setup_menu_t chat_settings1[]; | ||
3451 | |||
3452 | setup_menu_t* chat_settings[] = | ||
3453 | { | ||
3454 | chat_settings1, | ||
3455 | NULL | ||
3456 | }; | ||
3457 | |||
3458 | setup_menu_t chat_settings1[] = // Chat Strings screen | ||
3459 | { | ||
3460 | {"1",S_CHAT,m_null,CS_X,CS_Y+ 1*8, {"chatmacro1"}}, | ||
3461 | {"2",S_CHAT,m_null,CS_X,CS_Y+ 2*8, {"chatmacro2"}}, | ||
3462 | {"3",S_CHAT,m_null,CS_X,CS_Y+ 3*8, {"chatmacro3"}}, | ||
3463 | {"4",S_CHAT,m_null,CS_X,CS_Y+ 4*8, {"chatmacro4"}}, | ||
3464 | {"5",S_CHAT,m_null,CS_X,CS_Y+ 5*8, {"chatmacro5"}}, | ||
3465 | {"6",S_CHAT,m_null,CS_X,CS_Y+ 6*8, {"chatmacro6"}}, | ||
3466 | {"7",S_CHAT,m_null,CS_X,CS_Y+ 7*8, {"chatmacro7"}}, | ||
3467 | {"8",S_CHAT,m_null,CS_X,CS_Y+ 8*8, {"chatmacro8"}}, | ||
3468 | {"9",S_CHAT,m_null,CS_X,CS_Y+ 9*8, {"chatmacro9"}}, | ||
3469 | {"0",S_CHAT,m_null,CS_X,CS_Y+10*8, {"chatmacro0"}}, | ||
3470 | |||
3471 | // Button for resetting to defaults | ||
3472 | {0,S_RESET,m_null,X_BUTTON,Y_BUTTON}, | ||
3473 | |||
3474 | // Final entry | ||
3475 | {0,S_SKIP|S_END,m_null} | ||
3476 | |||
3477 | }; | ||
3478 | |||
3479 | // Setting up for the Chat Strings screen. Turn on flags, set pointers, | ||
3480 | // locate the first item on the screen where the cursor is allowed to | ||
3481 | // land. | ||
3482 | |||
3483 | void M_ChatStrings(int choice) | ||
3484 | { | ||
3485 | M_SetupNextMenu(&ChatStrDef); | ||
3486 | setup_active = true; | ||
3487 | setup_screen = ss_chat; | ||
3488 | set_chat_active = true; | ||
3489 | setup_select = false; | ||
3490 | default_verify = false; | ||
3491 | setup_gather = false; | ||
3492 | mult_screens_index = 0; | ||
3493 | current_setup_menu = chat_settings[0]; | ||
3494 | set_menu_itemon = 0; | ||
3495 | while (current_setup_menu[set_menu_itemon++].m_flags & S_SKIP); | ||
3496 | current_setup_menu[--set_menu_itemon].m_flags |= S_HILITE; | ||
3497 | } | ||
3498 | |||
3499 | // The drawing part of the Chat Strings Setup initialization. Draw the | ||
3500 | // background, title, instruction line, and items. | ||
3501 | |||
3502 | void M_DrawChatStrings(void) | ||
3503 | |||
3504 | { | ||
3505 | inhelpscreens = true; | ||
3506 | M_DrawBackground("FLOOR4_6", 0); // Draw background | ||
3507 | // CPhipps - patch drawing updated | ||
3508 | V_DrawNamePatch(83, 2, 0, "M_CHAT", CR_DEFAULT, VPT_STRETCH); | ||
3509 | M_DrawInstructions(); | ||
3510 | M_DrawScreenItems(current_setup_menu); | ||
3511 | |||
3512 | // If the Reset Button has been selected, an "Are you sure?" message | ||
3513 | // is overlayed across everything else. | ||
3514 | |||
3515 | if (default_verify) | ||
3516 | M_DrawDefVerify(); | ||
3517 | } | ||
3518 | |||
3519 | ///////////////////////////// | ||
3520 | // | ||
3521 | // General routines used by the Setup screens. | ||
3522 | // | ||
3523 | |||
3524 | static boolean shiftdown = false; // phares 4/10/98: SHIFT key down or not | ||
3525 | |||
3526 | // phares 4/17/98: | ||
3527 | // M_SelectDone() gets called when you have finished entering your | ||
3528 | // Setup Menu item change. | ||
3529 | |||
3530 | static void M_SelectDone(setup_menu_t* ptr) | ||
3531 | { | ||
3532 | ptr->m_flags &= ~S_SELECT; | ||
3533 | ptr->m_flags |= S_HILITE; | ||
3534 | S_StartSound(NULL,sfx_itemup); | ||
3535 | setup_select = false; | ||
3536 | colorbox_active = false; | ||
3537 | if (print_warning_about_changes) // killough 8/15/98 | ||
3538 | print_warning_about_changes--; | ||
3539 | } | ||
3540 | |||
3541 | // phares 4/21/98: | ||
3542 | // Array of setup screens used by M_ResetDefaults() | ||
3543 | |||
3544 | static setup_menu_t **setup_screens[] = | ||
3545 | { | ||
3546 | keys_settings, | ||
3547 | weap_settings, | ||
3548 | stat_settings, | ||
3549 | auto_settings, | ||
3550 | enem_settings, | ||
3551 | mess_settings, | ||
3552 | chat_settings, | ||
3553 | gen_settings, // killough 10/98 | ||
3554 | comp_settings, | ||
3555 | }; | ||
3556 | |||
3557 | // phares 4/19/98: | ||
3558 | // M_ResetDefaults() resets all values for a setup screen to default values | ||
3559 | // | ||
3560 | // killough 10/98: rewritten to fix bugs and warn about pending changes | ||
3561 | |||
3562 | static void M_ResetDefaults(void) | ||
3563 | { | ||
3564 | int i; //e6y | ||
3565 | |||
3566 | default_t *dp; | ||
3567 | int warn = 0; | ||
3568 | |||
3569 | // Look through the defaults table and reset every variable that | ||
3570 | // belongs to the group we're interested in. | ||
3571 | // | ||
3572 | // killough: However, only reset variables whose field in the | ||
3573 | // current setup screen is the same as in the defaults table. | ||
3574 | // i.e. only reset variables really in the current setup screen. | ||
3575 | |||
3576 | // e6y | ||
3577 | // Fixed crash while trying to read data past array end | ||
3578 | // All previous versions of prboom worked only by a lucky accident | ||
3579 | // old code: for (dp = defaults; dp->name; dp++) | ||
3580 | for (i = 0; i < numdefaults ; i++) | ||
3581 | { | ||
3582 | dp = &defaults[i]; | ||
3583 | |||
3584 | if (dp->setupscreen == setup_screen) | ||
3585 | { | ||
3586 | setup_menu_t **l, *p; | ||
3587 | for (l = setup_screens[setup_screen-1]; *l; l++) | ||
3588 | for (p = *l; !(p->m_flags & S_END); p++) | ||
3589 | if (p->m_flags & S_HASDEFPTR ? p->var.def == dp : | ||
3590 | p->var.m_key == dp->location.pi || | ||
3591 | p->m_mouse == dp->location.pi || | ||
3592 | p->m_joy == dp->location.pi) | ||
3593 | { | ||
3594 | if (IS_STRING(*dp)) | ||
3595 | free((char*)*dp->location.ppsz), | ||
3596 | *dp->location.ppsz = strdup(dp->defaultvalue.psz); | ||
3597 | else | ||
3598 | *dp->location.pi = dp->defaultvalue.i; | ||
3599 | |||
3600 | #if 0 | ||
3601 | if (p->m_flags & (S_LEVWARN | S_PRGWARN)) | ||
3602 | warn |= p->m_flags & (S_LEVWARN | S_PRGWARN); | ||
3603 | else | ||
3604 | if (dp->current) | ||
3605 | if (allow_changes()) | ||
3606 | *dp->current = *dp->location.pi; | ||
3607 | else | ||
3608 | warn |= S_LEVWARN; | ||
3609 | #endif | ||
3610 | if (p->action) | ||
3611 | p->action(); | ||
3612 | |||
3613 | goto end; | ||
3614 | } | ||
3615 | end:; | ||
3616 | } | ||
3617 | } | ||
3618 | |||
3619 | if (warn) | ||
3620 | warn_about_changes(warn); | ||
3621 | } | ||
3622 | |||
3623 | // | ||
3624 | // M_InitDefaults() | ||
3625 | // | ||
3626 | // killough 11/98: | ||
3627 | // | ||
3628 | // This function converts all setup menu entries consisting of cfg | ||
3629 | // variable names, into pointers to the corresponding default[] | ||
3630 | // array entry. var.name becomes converted to var.def. | ||
3631 | // | ||
3632 | |||
3633 | static void M_InitDefaults(void) | ||
3634 | { | ||
3635 | setup_menu_t *const *p, *t; | ||
3636 | default_t *dp; | ||
3637 | int i; | ||
3638 | for (i = 0; i < ss_max-1; i++) | ||
3639 | for (p = setup_screens[i]; *p; p++) | ||
3640 | for (t = *p; !(t->m_flags & S_END); t++) | ||
3641 | if (t->m_flags & S_HASDEFPTR) { | ||
3642 | if (!(dp = M_LookupDefault(t->var.name))) | ||
3643 | I_Error("M_InitDefaults: Couldn't find config variable %s", t->var.name); | ||
3644 | else | ||
3645 | (t->var.def = dp)->setup_menu = t; | ||
3646 | } | ||
3647 | } | ||
3648 | |||
3649 | // | ||
3650 | // End of Setup Screens. | ||
3651 | // | ||
3652 | ///////////////////////////////////////////////////////////////////////////// | ||
3653 | |||
3654 | ///////////////////////////////////////////////////////////////////////////// | ||
3655 | // | ||
3656 | // Start of Extended HELP screens // phares 3/30/98 | ||
3657 | // | ||
3658 | // The wad designer can define a set of extended HELP screens for their own | ||
3659 | // information display. These screens should be 320x200 graphic lumps | ||
3660 | // defined in a separate wad. They should be named "HELP01" through "HELP99". | ||
3661 | // "HELP01" is shown after the regular BOOM Dynamic HELP screen, and ENTER | ||
3662 | // and BACKSPACE keys move the player through the HELP set. | ||
3663 | // | ||
3664 | // Rather than define a set of menu definitions for each of the possible | ||
3665 | // HELP screens, one definition is used, and is altered on the fly | ||
3666 | // depending on what HELPnn lumps the game finds. | ||
3667 | |||
3668 | // phares 3/30/98: | ||
3669 | // Extended Help Screen variables | ||
3670 | |||
3671 | int extended_help_count; // number of user-defined help screens found | ||
3672 | int extended_help_index; // index of current extended help screen | ||
3673 | |||
3674 | menuitem_t ExtHelpMenu[] = | ||
3675 | { | ||
3676 | {1,"",M_ExtHelpNextScreen,0} | ||
3677 | }; | ||
3678 | |||
3679 | menu_t ExtHelpDef = | ||
3680 | { | ||
3681 | 1, // # of menu items | ||
3682 | &ReadDef1, // previous menu | ||
3683 | ExtHelpMenu, // menuitem_t -> | ||
3684 | M_DrawExtHelp, // drawing routine -> | ||
3685 | 330,181, // x,y | ||
3686 | 0 // lastOn | ||
3687 | }; | ||
3688 | |||
3689 | // M_ExtHelpNextScreen establishes the number of the next HELP screen in | ||
3690 | // the series. | ||
3691 | |||
3692 | void M_ExtHelpNextScreen(int choice) | ||
3693 | { | ||
3694 | choice = 0; | ||
3695 | if (++extended_help_index > extended_help_count) | ||
3696 | { | ||
3697 | |||
3698 | // when finished with extended help screens, return to Main Menu | ||
3699 | |||
3700 | extended_help_index = 1; | ||
3701 | M_SetupNextMenu(&MainDef); | ||
3702 | } | ||
3703 | } | ||
3704 | |||
3705 | // phares 3/30/98: | ||
3706 | // Routine to look for HELPnn screens and create a menu | ||
3707 | // definition structure that defines extended help screens. | ||
3708 | |||
3709 | void M_InitExtendedHelp(void) | ||
3710 | |||
3711 | { | ||
3712 | int index,i; | ||
3713 | char namebfr[] = { "HELPnn"} ; | ||
3714 | |||
3715 | extended_help_count = 0; | ||
3716 | for (index = 1 ; index < 100 ; index++) { | ||
3717 | namebfr[4] = index/10 + 0x30; | ||
3718 | namebfr[5] = index%10 + 0x30; | ||
3719 | i = W_CheckNumForName(namebfr); | ||
3720 | if (i == -1) { | ||
3721 | if (extended_help_count) { | ||
3722 | if (gamemode == commercial) { | ||
3723 | ExtHelpDef.prevMenu = &ReadDef1; /* previous menu */ | ||
3724 | ReadMenu1[0].routine = M_ExtHelp; | ||
3725 | } else { | ||
3726 | ExtHelpDef.prevMenu = &ReadDef2; /* previous menu */ | ||
3727 | ReadMenu2[0].routine = M_ExtHelp; | ||
3728 | } | ||
3729 | } | ||
3730 | return; | ||
3731 | } | ||
3732 | extended_help_count++; | ||
3733 | } | ||
3734 | |||
3735 | } | ||
3736 | |||
3737 | // Initialization for the extended HELP screens. | ||
3738 | |||
3739 | void M_ExtHelp(int choice) | ||
3740 | { | ||
3741 | choice = 0; | ||
3742 | extended_help_index = 1; // Start with first extended help screen | ||
3743 | M_SetupNextMenu(&ExtHelpDef); | ||
3744 | } | ||
3745 | |||
3746 | // Initialize the drawing part of the extended HELP screens. | ||
3747 | |||
3748 | void M_DrawExtHelp(void) | ||
3749 | { | ||
3750 | char namebfr[10] = { "HELPnn" }; // CPhipps - make it local & writable | ||
3751 | |||
3752 | inhelpscreens = true; // killough 5/1/98 | ||
3753 | namebfr[4] = extended_help_index/10 + 0x30; | ||
3754 | namebfr[5] = extended_help_index%10 + 0x30; | ||
3755 | // CPhipps - patch drawing updated | ||
3756 | V_DrawNamePatch(0, 0, 0, namebfr, CR_DEFAULT, VPT_STRETCH); | ||
3757 | } | ||
3758 | |||
3759 | // | ||
3760 | // End of Extended HELP screens // phares 3/30/98 | ||
3761 | // | ||
3762 | //////////////////////////////////////////////////////////////////////////// | ||
3763 | |||
3764 | //////////////////////////////////////////////////////////////////////////// | ||
3765 | // | ||
3766 | // Dynamic HELP screen // phares 3/2/98 | ||
3767 | // | ||
3768 | // Rather than providing the static HELP screens from DOOM and its versions, | ||
3769 | // BOOM provides the player with a dynamic HELP screen that displays the | ||
3770 | // current settings of major key bindings. | ||
3771 | // | ||
3772 | // The Dynamic HELP screen is defined in a manner similar to that used for | ||
3773 | // the Setup Screens above. | ||
3774 | // | ||
3775 | // M_GetKeyString finds the correct string to represent the key binding | ||
3776 | // for the current item being drawn. | ||
3777 | |||
3778 | int M_GetKeyString(int c,int offset) | ||
3779 | { | ||
3780 | const char* s; | ||
3781 | |||
3782 | if (c >= 33 && c <= 126) { | ||
3783 | |||
3784 | // The '=', ',', and '.' keys originally meant the shifted | ||
3785 | // versions of those keys, but w/o having to shift them in | ||
3786 | // the game. Any actions that are mapped to these keys will | ||
3787 | // still mean their shifted versions. Could be changed later | ||
3788 | // if someone can come up with a better way to deal with them. | ||
3789 | |||
3790 | if (c == '=') // probably means the '+' key? | ||
3791 | c = '+'; | ||
3792 | else if (c == ',') // probably means the '<' key? | ||
3793 | c = '<'; | ||
3794 | else if (c == '.') // probably means the '>' key? | ||
3795 | c = '>'; | ||
3796 | menu_buffer[offset++] = c; // Just insert the ascii key | ||
3797 | menu_buffer[offset] = 0; | ||
3798 | |||
3799 | } else { | ||
3800 | |||
3801 | // Retrieve 4-letter (max) string representing the key | ||
3802 | |||
3803 | // cph - Keypad keys, general code reorganisation to | ||
3804 | // make this smaller and neater. | ||
3805 | if ((0x100 <= c) && (c < 0x200)) { | ||
3806 | if (c == KEYD_KEYPADENTER) | ||
3807 | s = "PADE"; | ||
3808 | else { | ||
3809 | strcpy(&menu_buffer[offset], "PAD"); | ||
3810 | offset+=4; | ||
3811 | menu_buffer[offset-1] = c & 0xff; | ||
3812 | menu_buffer[offset] = 0; | ||
3813 | } | ||
3814 | } else if ((KEYD_F1 <= c) && (c < KEYD_F10)) { | ||
3815 | menu_buffer[offset++] = 'F'; | ||
3816 | menu_buffer[offset++] = '1' + c - KEYD_F1; | ||
3817 | menu_buffer[offset] = 0; | ||
3818 | } else { | ||
3819 | switch(c) { | ||
3820 | case KEYD_TAB: s = "TAB"; break; | ||
3821 | case KEYD_ENTER: s = "ENTR"; break; | ||
3822 | case KEYD_ESCAPE: s = "ESC"; break; | ||
3823 | case KEYD_SPACEBAR: s = "SPAC"; break; | ||
3824 | case KEYD_BACKSPACE: s = "BACK"; break; | ||
3825 | case KEYD_RCTRL: s = "CTRL"; break; | ||
3826 | case KEYD_LEFTARROW: s = "LARR"; break; | ||
3827 | case KEYD_UPARROW: s = "UARR"; break; | ||
3828 | case KEYD_RIGHTARROW: s = "RARR"; break; | ||
3829 | case KEYD_DOWNARROW: s = "DARR"; break; | ||
3830 | case KEYD_RSHIFT: s = "SHFT"; break; | ||
3831 | case KEYD_RALT: s = "ALT"; break; | ||
3832 | case KEYD_CAPSLOCK: s = "CAPS"; break; | ||
3833 | case KEYD_SCROLLLOCK: s = "SCRL"; break; | ||
3834 | case KEYD_HOME: s = "HOME"; break; | ||
3835 | case KEYD_PAGEUP: s = "PGUP"; break; | ||
3836 | case KEYD_END: s = "END"; break; | ||
3837 | case KEYD_PAGEDOWN: s = "PGDN"; break; | ||
3838 | case KEYD_INSERT: s = "INST"; break; | ||
3839 | case KEYD_DEL: s = "DEL"; break; | ||
3840 | case KEYD_F10: s = "F10"; break; | ||
3841 | case KEYD_F11: s = "F11"; break; | ||
3842 | case KEYD_F12: s = "F12"; break; | ||
3843 | case KEYD_PAUSE: s = "PAUS"; break; | ||
3844 | default: s = "JUNK"; break; | ||
3845 | } | ||
3846 | |||
3847 | if (s) { // cph - Slight code change | ||
3848 | strcpy(&menu_buffer[offset],s); // string to display | ||
3849 | offset += strlen(s); | ||
3850 | } | ||
3851 | } | ||
3852 | } | ||
3853 | return offset; | ||
3854 | } | ||
3855 | |||
3856 | // | ||
3857 | // The Dynamic HELP screen table. | ||
3858 | |||
3859 | #define KT_X1 283 | ||
3860 | #define KT_X2 172 | ||
3861 | #define KT_X3 87 | ||
3862 | |||
3863 | #define KT_Y1 2 | ||
3864 | #define KT_Y2 118 | ||
3865 | #define KT_Y3 102 | ||
3866 | |||
3867 | setup_menu_t helpstrings[] = // HELP screen strings | ||
3868 | { | ||
3869 | {"SCREEN" ,S_SKIP|S_TITLE,m_null,KT_X1,KT_Y1}, | ||
3870 | {"HELP" ,S_SKIP|S_KEY,m_null,KT_X1,KT_Y1+ 1*8,{&key_help}}, | ||
3871 | {"MENU" ,S_SKIP|S_KEY,m_null,KT_X1,KT_Y1+ 2*8,{&key_escape}}, | ||
3872 | {"SETUP" ,S_SKIP|S_KEY,m_null,KT_X1,KT_Y1+ 3*8,{&key_setup}}, | ||
3873 | {"PAUSE" ,S_SKIP|S_KEY,m_null,KT_X1,KT_Y1+ 4*8,{&key_pause}}, | ||
3874 | {"AUTOMAP" ,S_SKIP|S_KEY,m_null,KT_X1,KT_Y1+ 5*8,{&key_map}}, | ||
3875 | {"SOUND VOLUME",S_SKIP|S_KEY,m_null,KT_X1,KT_Y1+ 6*8,{&key_soundvolume}}, | ||
3876 | {"HUD" ,S_SKIP|S_KEY,m_null,KT_X1,KT_Y1+ 7*8,{&key_hud}}, | ||
3877 | {"MESSAGES" ,S_SKIP|S_KEY,m_null,KT_X1,KT_Y1+ 8*8,{&key_messages}}, | ||
3878 | {"GAMMA FIX" ,S_SKIP|S_KEY,m_null,KT_X1,KT_Y1+ 9*8,{&key_gamma}}, | ||
3879 | {"SPY" ,S_SKIP|S_KEY,m_null,KT_X1,KT_Y1+10*8,{&key_spy}}, | ||
3880 | {"LARGER VIEW" ,S_SKIP|S_KEY,m_null,KT_X1,KT_Y1+11*8,{&key_zoomin}}, | ||
3881 | {"SMALLER VIEW",S_SKIP|S_KEY,m_null,KT_X1,KT_Y1+12*8,{&key_zoomout}}, | ||
3882 | {"SCREENSHOT" ,S_SKIP|S_KEY,m_null,KT_X1,KT_Y1+13*8,{&key_screenshot}}, | ||
3883 | |||
3884 | {"AUTOMAP" ,S_SKIP|S_TITLE,m_null,KT_X1,KT_Y2}, | ||
3885 | {"FOLLOW MODE" ,S_SKIP|S_KEY,m_null,KT_X1,KT_Y2+ 1*8,{&key_map_follow}}, | ||
3886 | {"ZOOM IN" ,S_SKIP|S_KEY,m_null,KT_X1,KT_Y2+ 2*8,{&key_map_zoomin}}, | ||
3887 | {"ZOOM OUT" ,S_SKIP|S_KEY,m_null,KT_X1,KT_Y2+ 3*8,{&key_map_zoomout}}, | ||
3888 | {"MARK PLACE" ,S_SKIP|S_KEY,m_null,KT_X1,KT_Y2+ 4*8,{&key_map_mark}}, | ||
3889 | {"CLEAR MARKS" ,S_SKIP|S_KEY,m_null,KT_X1,KT_Y2+ 5*8,{&key_map_clear}}, | ||
3890 | {"FULL/ZOOM" ,S_SKIP|S_KEY,m_null,KT_X1,KT_Y2+ 6*8,{&key_map_gobig}}, | ||
3891 | {"GRID" ,S_SKIP|S_KEY,m_null,KT_X1,KT_Y2+ 7*8,{&key_map_grid}}, | ||
3892 | |||
3893 | {"WEAPONS" ,S_SKIP|S_TITLE,m_null,KT_X3,KT_Y1}, | ||
3894 | {"FIST" ,S_SKIP|S_KEY,m_null,KT_X3,KT_Y1+ 1*8,{&key_weapon1}}, | ||
3895 | {"PISTOL" ,S_SKIP|S_KEY,m_null,KT_X3,KT_Y1+ 2*8,{&key_weapon2}}, | ||
3896 | {"SHOTGUN" ,S_SKIP|S_KEY,m_null,KT_X3,KT_Y1+ 3*8,{&key_weapon3}}, | ||
3897 | {"CHAINGUN" ,S_SKIP|S_KEY,m_null,KT_X3,KT_Y1+ 4*8,{&key_weapon4}}, | ||
3898 | {"ROCKET" ,S_SKIP|S_KEY,m_null,KT_X3,KT_Y1+ 5*8,{&key_weapon5}}, | ||
3899 | {"PLASMA" ,S_SKIP|S_KEY,m_null,KT_X3,KT_Y1+ 6*8,{&key_weapon6}}, | ||
3900 | {"BFG 9000" ,S_SKIP|S_KEY,m_null,KT_X3,KT_Y1+ 7*8,{&key_weapon7}}, | ||
3901 | {"CHAINSAW" ,S_SKIP|S_KEY,m_null,KT_X3,KT_Y1+ 8*8,{&key_weapon8}}, | ||
3902 | {"SSG" ,S_SKIP|S_KEY,m_null,KT_X3,KT_Y1+ 9*8,{&key_weapon9}}, | ||
3903 | {"BEST" ,S_SKIP|S_KEY,m_null,KT_X3,KT_Y1+10*8,{&key_weapontoggle}}, | ||
3904 | {"FIRE" ,S_SKIP|S_KEY,m_null,KT_X3,KT_Y1+11*8,{&key_fire},&mousebfire,&joybfire}, | ||
3905 | |||
3906 | {"MOVEMENT" ,S_SKIP|S_TITLE,m_null,KT_X3,KT_Y3}, | ||
3907 | {"FORWARD" ,S_SKIP|S_KEY,m_null,KT_X3,KT_Y3+ 1*8,{&key_up},&mousebforward}, | ||
3908 | {"BACKWARD" ,S_SKIP|S_KEY,m_null,KT_X3,KT_Y3+ 2*8,{&key_down}}, | ||
3909 | {"TURN LEFT" ,S_SKIP|S_KEY,m_null,KT_X3,KT_Y3+ 3*8,{&key_left}}, | ||
3910 | {"TURN RIGHT" ,S_SKIP|S_KEY,m_null,KT_X3,KT_Y3+ 4*8,{&key_right}}, | ||
3911 | {"RUN" ,S_SKIP|S_KEY,m_null,KT_X3,KT_Y3+ 5*8,{&key_speed},0,&joybspeed}, | ||
3912 | {"STRAFE LEFT" ,S_SKIP|S_KEY,m_null,KT_X3,KT_Y3+ 6*8,{&key_strafeleft}}, | ||
3913 | {"STRAFE RIGHT",S_SKIP|S_KEY,m_null,KT_X3,KT_Y3+ 7*8,{&key_straferight}}, | ||
3914 | {"STRAFE" ,S_SKIP|S_KEY,m_null,KT_X3,KT_Y3+ 8*8,{&key_strafe},&mousebstrafe,&joybstrafe}, | ||
3915 | {"AUTORUN" ,S_SKIP|S_KEY,m_null,KT_X3,KT_Y3+ 9*8,{&key_autorun}}, | ||
3916 | {"180 TURN" ,S_SKIP|S_KEY,m_null,KT_X3,KT_Y3+10*8,{&key_reverse}}, | ||
3917 | {"USE" ,S_SKIP|S_KEY,m_null,KT_X3,KT_Y3+11*8,{&key_use},&mousebforward,&joybuse}, | ||
3918 | |||
3919 | {"GAME" ,S_SKIP|S_TITLE,m_null,KT_X2,KT_Y1}, | ||
3920 | {"SAVE" ,S_SKIP|S_KEY,m_null,KT_X2,KT_Y1+ 1*8,{&key_savegame}}, | ||
3921 | {"LOAD" ,S_SKIP|S_KEY,m_null,KT_X2,KT_Y1+ 2*8,{&key_loadgame}}, | ||
3922 | {"QUICKSAVE" ,S_SKIP|S_KEY,m_null,KT_X2,KT_Y1+ 3*8,{&key_quicksave}}, | ||
3923 | {"END GAME" ,S_SKIP|S_KEY,m_null,KT_X2,KT_Y1+ 4*8,{&key_endgame}}, | ||
3924 | {"QUICKLOAD" ,S_SKIP|S_KEY,m_null,KT_X2,KT_Y1+ 5*8,{&key_quickload}}, | ||
3925 | {"QUIT" ,S_SKIP|S_KEY,m_null,KT_X2,KT_Y1+ 6*8,{&key_quit}}, | ||
3926 | |||
3927 | // Final entry | ||
3928 | |||
3929 | {0,S_SKIP|S_END,m_null} | ||
3930 | }; | ||
3931 | |||
3932 | #define SPACEWIDTH 4 | ||
3933 | |||
3934 | /* cph 2006/08/06 | ||
3935 | * M_DrawString() is the old M_DrawMenuString, except that it is not tied to | ||
3936 | * menu_buffer - no reason to force all the callers to write into one array! */ | ||
3937 | |||
3938 | static void M_DrawString(int cx, int cy, int color, const char* ch) | ||
3939 | { | ||
3940 | int w; | ||
3941 | int c; | ||
3942 | |||
3943 | while (*ch) { | ||
3944 | c = *ch++; // get next char | ||
3945 | c = toupper(c) - HU_FONTSTART; | ||
3946 | if (c < 0 || c> HU_FONTSIZE) | ||
3947 | { | ||
3948 | cx += SPACEWIDTH; // space | ||
3949 | continue; | ||
3950 | } | ||
3951 | w = hu_font[c].width; | ||
3952 | if (cx + w > 320) | ||
3953 | break; | ||
3954 | |||
3955 | // V_DrawpatchTranslated() will draw the string in the | ||
3956 | // desired color, colrngs[color] | ||
3957 | |||
3958 | // CPhipps - patch drawing updated | ||
3959 | V_DrawNumPatch(cx, cy, 0, hu_font[c].lumpnum, color, VPT_STRETCH | VPT_TRANS); | ||
3960 | // The screen is cramped, so trim one unit from each | ||
3961 | // character so they butt up against each other. | ||
3962 | cx += w - 1; | ||
3963 | } | ||
3964 | } | ||
3965 | |||
3966 | // M_DrawMenuString() draws the string in menu_buffer[] | ||
3967 | |||
3968 | static void M_DrawMenuString(int cx, int cy, int color) | ||
3969 | { | ||
3970 | M_DrawString(cx, cy, color, menu_buffer); | ||
3971 | } | ||
3972 | |||
3973 | // M_GetPixelWidth() returns the number of pixels in the width of | ||
3974 | // the string, NOT the number of chars in the string. | ||
3975 | |||
3976 | static int M_GetPixelWidth(const char* ch) | ||
3977 | { | ||
3978 | int len = 0; | ||
3979 | int c; | ||
3980 | |||
3981 | while (*ch) { | ||
3982 | c = *ch++; // pick up next char | ||
3983 | c = toupper(c) - HU_FONTSTART; | ||
3984 | if (c < 0 || c > HU_FONTSIZE) | ||
3985 | { | ||
3986 | len += SPACEWIDTH; // space | ||
3987 | continue; | ||
3988 | } | ||
3989 | len += hu_font[c].width; | ||
3990 | len--; // adjust so everything fits | ||
3991 | } | ||
3992 | len++; // replace what you took away on the last char only | ||
3993 | return len; | ||
3994 | } | ||
3995 | |||
3996 | static void M_DrawStringCentered(int cx, int cy, int color, const char* ch) | ||
3997 | { | ||
3998 | M_DrawString(cx - M_GetPixelWidth(ch)/2, cy, color, ch); | ||
3999 | } | ||
4000 | |||
4001 | // | ||
4002 | // M_DrawHelp | ||
4003 | // | ||
4004 | // This displays the help screen | ||
4005 | |||
4006 | void M_DrawHelp (void) | ||
4007 | { | ||
4008 | inhelpscreens = true; // killough 10/98 | ||
4009 | M_DrawBackground("FLOOR4_6", 0); | ||
4010 | |||
4011 | M_DrawScreenItems(helpstrings); | ||
4012 | } | ||
4013 | |||
4014 | // | ||
4015 | // End of Dynamic HELP screen // phares 3/2/98 | ||
4016 | // | ||
4017 | //////////////////////////////////////////////////////////////////////////// | ||
4018 | |||
4019 | enum { | ||
4020 | prog, | ||
4021 | prog_stub, | ||
4022 | prog_stub1, | ||
4023 | prog_stub2, | ||
4024 | adcr | ||
4025 | }; | ||
4026 | |||
4027 | enum { | ||
4028 | cr_prog=0, | ||
4029 | cr_adcr=2, | ||
4030 | }; | ||
4031 | |||
4032 | #define CR_S 9 | ||
4033 | #define CR_X 20 | ||
4034 | #define CR_X2 50 | ||
4035 | #define CR_Y 32 | ||
4036 | #define CR_SH 9 | ||
4037 | |||
4038 | setup_menu_t cred_settings[]={ | ||
4039 | |||
4040 | {"Programmers",S_SKIP|S_CREDIT|S_LEFTJUST,m_null, CR_X, CR_Y + CR_S*prog + CR_SH*cr_prog}, | ||
4041 | {"Florian 'Proff' Schulze",S_SKIP|S_CREDIT|S_LEFTJUST,m_null, CR_X2, CR_Y + CR_S*(prog+1) + CR_SH*cr_prog}, | ||
4042 | {"Colin Phipps",S_SKIP|S_CREDIT|S_LEFTJUST,m_null, CR_X2, CR_Y + CR_S*(prog+2) + CR_SH*cr_prog}, | ||
4043 | {"Neil Stevens",S_SKIP|S_CREDIT|S_LEFTJUST,m_null, CR_X2, CR_Y + CR_S*(prog+3) + CR_SH*cr_prog}, | ||
4044 | {"Andrey Budko",S_SKIP|S_CREDIT|S_LEFTJUST,m_null, CR_X2, CR_Y + CR_S*(prog+4) + CR_SH*cr_prog}, | ||
4045 | |||
4046 | {"Additional Credit To",S_SKIP|S_CREDIT|S_LEFTJUST,m_null, CR_X, CR_Y + CR_S*adcr + CR_SH*cr_adcr}, | ||
4047 | {"id Software for DOOM",S_SKIP|S_CREDIT|S_LEFTJUST,m_null, CR_X2, CR_Y + CR_S*(adcr+1)+CR_SH*cr_adcr}, | ||
4048 | {"TeamTNT for BOOM",S_SKIP|S_CREDIT|S_LEFTJUST,m_null, CR_X2, CR_Y + CR_S*(adcr+2)+CR_SH*cr_adcr}, | ||
4049 | {"Lee Killough for MBF",S_SKIP|S_CREDIT|S_LEFTJUST,m_null, CR_X2, CR_Y + CR_S*(adcr+3)+CR_SH*cr_adcr}, | ||
4050 | {"The DOSDoom-Team for DOSDOOM",S_SKIP|S_CREDIT|S_LEFTJUST,m_null, CR_X2, CR_Y + CR_S*(adcr+4)+CR_SH*cr_adcr}, | ||
4051 | {"Randy Heit for ZDOOM",S_SKIP|S_CREDIT|S_LEFTJUST,m_null, CR_X2, CR_Y + CR_S*(adcr+5)+CR_SH*cr_adcr}, | ||
4052 | {"Michael 'Kodak' Ryssen for DOOMGL",S_SKIP|S_CREDIT|S_LEFTJUST,m_null, CR_X2, CR_Y + CR_S*(adcr+6)+CR_SH*cr_adcr}, | ||
4053 | {"Jess Haas for lSDLDoom",S_SKIP|S_CREDIT|S_LEFTJUST,m_null, CR_X2, CR_Y + CR_S*(adcr+7) + CR_SH*cr_adcr}, | ||
4054 | {"all others who helped (see AUTHORS file)",S_SKIP|S_CREDIT|S_LEFTJUST,m_null, CR_X2, CR_Y + CR_S*(adcr+8)+CR_SH*cr_adcr}, | ||
4055 | |||
4056 | {0,S_SKIP|S_END,m_null} | ||
4057 | }; | ||
4058 | |||
4059 | void M_DrawCredits(void) // killough 10/98: credit screen | ||
4060 | { | ||
4061 | inhelpscreens = true; | ||
4062 | M_DrawBackground(gamemode==shareware ? "CEIL5_1" : "MFLR8_4", 0); | ||
4063 | V_DrawNamePatch(115,9,0, "PRBOOM",CR_GOLD, VPT_TRANS | VPT_STRETCH); | ||
4064 | M_DrawScreenItems(cred_settings); | ||
4065 | } | ||
4066 | |||
4067 | static int M_IndexInChoices(const char *str, const char **choices) { | ||
4068 | int i = 0; | ||
4069 | |||
4070 | while (*choices != NULL) { | ||
4071 | if (!strcmp(str, *choices)) | ||
4072 | return i; | ||
4073 | i++; | ||
4074 | choices++; | ||
4075 | } | ||
4076 | return 0; | ||
4077 | } | ||
4078 | |||
4079 | ///////////////////////////////////////////////////////////////////////////// | ||
4080 | // | ||
4081 | // M_Responder | ||
4082 | // | ||
4083 | // Examines incoming keystrokes and button pushes and determines some | ||
4084 | // action based on the state of the system. | ||
4085 | // | ||
4086 | |||
4087 | boolean M_Responder (event_t* ev) { | ||
4088 | int ch; | ||
4089 | int i; | ||
4090 | static int joywait = 0; | ||
4091 | static int mousewait = 0; | ||
4092 | static int mousey = 0; | ||
4093 | static int lasty = 0; | ||
4094 | static int mousex = 0; | ||
4095 | static int lastx = 0; | ||
4096 | |||
4097 | ch = -1; // will be changed to a legit char if we're going to use it here | ||
4098 | |||
4099 | // Process joystick input | ||
4100 | |||
4101 | if (ev->type == ev_joystick && joywait < I_GetTime()) { | ||
4102 | if (ev->data3 == -1) | ||
4103 | { | ||
4104 | ch = key_menu_up; // phares 3/7/98 | ||
4105 | joywait = I_GetTime() + 5; | ||
4106 | } | ||
4107 | else if (ev->data3 == 1) | ||
4108 | { | ||
4109 | ch = key_menu_down; // phares 3/7/98 | ||
4110 | joywait = I_GetTime() + 5; | ||
4111 | } | ||
4112 | |||
4113 | if (ev->data2 == -1) | ||
4114 | { | ||
4115 | ch = key_menu_left; // phares 3/7/98 | ||
4116 | joywait = I_GetTime() + 2; | ||
4117 | } | ||
4118 | else if (ev->data2 == 1) | ||
4119 | { | ||
4120 | ch = key_menu_right; // phares 3/7/98 | ||
4121 | joywait = I_GetTime() + 2; | ||
4122 | } | ||
4123 | |||
4124 | if (ev->data1&1) | ||
4125 | { | ||
4126 | ch = key_menu_enter; // phares 3/7/98 | ||
4127 | joywait = I_GetTime() + 5; | ||
4128 | } | ||
4129 | |||
4130 | if (ev->data1&2) | ||
4131 | { | ||
4132 | ch = key_menu_backspace; // phares 3/7/98 | ||
4133 | joywait = I_GetTime() + 5; | ||
4134 | } | ||
4135 | |||
4136 | // phares 4/4/98: | ||
4137 | // Handle joystick buttons 3 and 4, and allow them to pass down | ||
4138 | // to where key binding can eat them. | ||
4139 | |||
4140 | if (setup_active && set_keybnd_active) { | ||
4141 | if (ev->data1&4) { | ||
4142 | ch = 0; // meaningless, just to get you past the check for -1 | ||
4143 | joywait = I_GetTime() + 5; | ||
4144 | } | ||
4145 | if (ev->data1&8) { | ||
4146 | ch = 0; // meaningless, just to get you past the check for -1 | ||
4147 | joywait = I_GetTime() + 5; | ||
4148 | } | ||
4149 | } | ||
4150 | |||
4151 | } else { | ||
4152 | // Mouse input processing removed | ||
4153 | |||
4154 | // Process keyboard input | ||
4155 | |||
4156 | if (ev->type == ev_keydown) | ||
4157 | { | ||
4158 | ch = ev->data1; // phares 4/11/98: | ||
4159 | if (ch == KEYD_RSHIFT) // For chat string processing, need | ||
4160 | shiftdown = true; // to know when shift key is up or | ||
4161 | } // down so you can get at the !,#, | ||
4162 | else if (ev->type == ev_keyup) // etc. keys. Keydowns are allowed | ||
4163 | if (ev->data1 == KEYD_RSHIFT) // past this point, but keyups aren't | ||
4164 | shiftdown = false; // so we need to note the difference | ||
4165 | } // here using the 'shiftdown' boolean. | ||
4166 | |||
4167 | if (ch == -1) | ||
4168 | return false; // we can't use the event here | ||
4169 | |||
4170 | // Save Game string input | ||
4171 | |||
4172 | if (saveStringEnter) { | ||
4173 | if (ch == key_menu_backspace) // phares 3/7/98 | ||
4174 | { | ||
4175 | if (saveCharIndex > 0) | ||
4176 | { | ||
4177 | saveCharIndex--; | ||
4178 | savegamestrings[saveSlot][saveCharIndex] = 0; | ||
4179 | } | ||
4180 | } | ||
4181 | |||
4182 | else if (ch == key_menu_escape) // phares 3/7/98 | ||
4183 | { | ||
4184 | saveStringEnter = 0; | ||
4185 | strcpy(&savegamestrings[saveSlot][0],saveOldString); | ||
4186 | } | ||
4187 | |||
4188 | else if (ch == key_menu_enter) // phares 3/7/98 | ||
4189 | { | ||
4190 | saveStringEnter = 0; | ||
4191 | if (savegamestrings[saveSlot][0]) | ||
4192 | M_DoSave(saveSlot); | ||
4193 | } | ||
4194 | |||
4195 | else | ||
4196 | { | ||
4197 | ch = toupper(ch); | ||
4198 | if (ch >= 32 && ch <= 127 && | ||
4199 | saveCharIndex < SAVESTRINGSIZE-1 && | ||
4200 | M_StringWidth(savegamestrings[saveSlot]) < (SAVESTRINGSIZE-2)*8) | ||
4201 | { | ||
4202 | savegamestrings[saveSlot][saveCharIndex++] = ch; | ||
4203 | savegamestrings[saveSlot][saveCharIndex] = 0; | ||
4204 | } | ||
4205 | } | ||
4206 | return true; | ||
4207 | } | ||
4208 | |||
4209 | // Take care of any messages that need input | ||
4210 | |||
4211 | if (messageToPrint) { | ||
4212 | if (messageNeedsInput == true && | ||
4213 | !(ch == ' ' || ch == 'n' || ch == 'y' || ch == key_escape)) // phares | ||
4214 | return false; | ||
4215 | |||
4216 | menuactive = messageLastMenuActive; | ||
4217 | messageToPrint = 0; | ||
4218 | if (messageRoutine) | ||
4219 | messageRoutine(ch); | ||
4220 | |||
4221 | menuactive = false; | ||
4222 | S_StartSound(NULL,sfx_swtchx); | ||
4223 | return true; | ||
4224 | } | ||
4225 | |||
4226 | /* killough 2/22/98: add support for screenshot key: | ||
4227 | * cph 2001/02/04: no need for this to be a gameaction, just do it | ||
4228 | */ | ||
4229 | if (ch == key_screenshot) | ||
4230 | { | ||
4231 | M_ScreenShot (); | ||
4232 | // Don't eat the keypress in this case. See sf bug #1843280. | ||
4233 | } | ||
4234 | |||
4235 | // If there is no active menu displayed... | ||
4236 | |||
4237 | if (!menuactive) { // phares | ||
4238 | if (ch == key_autorun) // Autorun // V | ||
4239 | { | ||
4240 | autorun = !autorun; | ||
4241 | return true; | ||
4242 | } | ||
4243 | |||
4244 | if (ch == key_help) // Help key | ||
4245 | { | ||
4246 | M_StartControlPanel (); | ||
4247 | |||
4248 | currentMenu = &HelpDef; // killough 10/98: new help screen | ||
4249 | |||
4250 | itemOn = 0; | ||
4251 | S_StartSound(NULL,sfx_swtchn); | ||
4252 | return true; | ||
4253 | } | ||
4254 | |||
4255 | if (ch == key_savegame) // Save Game | ||
4256 | { | ||
4257 | M_StartControlPanel(); | ||
4258 | S_StartSound(NULL,sfx_swtchn); | ||
4259 | M_SaveGame(0); | ||
4260 | return true; | ||
4261 | } | ||
4262 | |||
4263 | if (ch == key_loadgame) // Load Game | ||
4264 | { | ||
4265 | M_StartControlPanel(); | ||
4266 | S_StartSound(NULL,sfx_swtchn); | ||
4267 | M_LoadGame(0); | ||
4268 | return true; | ||
4269 | } | ||
4270 | |||
4271 | if (ch == key_soundvolume) // Sound Volume | ||
4272 | { | ||
4273 | M_StartControlPanel (); | ||
4274 | currentMenu = &SoundDef; | ||
4275 | itemOn = sfx_vol; | ||
4276 | S_StartSound(NULL,sfx_swtchn); | ||
4277 | return true; | ||
4278 | } | ||
4279 | |||
4280 | if (ch == key_quicksave) // Quicksave | ||
4281 | { | ||
4282 | S_StartSound(NULL,sfx_swtchn); | ||
4283 | M_QuickSave(); | ||
4284 | return true; | ||
4285 | } | ||
4286 | |||
4287 | if (ch == key_endgame) // End game | ||
4288 | { | ||
4289 | S_StartSound(NULL,sfx_swtchn); | ||
4290 | M_EndGame(0); | ||
4291 | return true; | ||
4292 | } | ||
4293 | |||
4294 | if (ch == key_messages) // Toggle messages | ||
4295 | { | ||
4296 | M_ChangeMessages(0); | ||
4297 | S_StartSound(NULL,sfx_swtchn); | ||
4298 | return true; | ||
4299 | } | ||
4300 | |||
4301 | if (ch == key_quickload) // Quickload | ||
4302 | { | ||
4303 | S_StartSound(NULL,sfx_swtchn); | ||
4304 | M_QuickLoad(); | ||
4305 | return true; | ||
4306 | } | ||
4307 | |||
4308 | if (ch == key_quit) // Quit DOOM | ||
4309 | { | ||
4310 | S_StartSound(NULL,sfx_swtchn); | ||
4311 | M_QuitDOOM(0); | ||
4312 | return true; | ||
4313 | } | ||
4314 | |||
4315 | if (ch == key_gamma) // gamma toggle | ||
4316 | { | ||
4317 | usegamma++; | ||
4318 | if (usegamma > 4) | ||
4319 | usegamma = 0; | ||
4320 | players[consoleplayer].message = | ||
4321 | usegamma == 0 ? s_GAMMALVL0 : | ||
4322 | usegamma == 1 ? s_GAMMALVL1 : | ||
4323 | usegamma == 2 ? s_GAMMALVL2 : | ||
4324 | usegamma == 3 ? s_GAMMALVL3 : | ||
4325 | s_GAMMALVL4; | ||
4326 | V_SetPalette(0); | ||
4327 | return true; | ||
4328 | } | ||
4329 | |||
4330 | |||
4331 | if (ch == key_zoomout) // zoom out | ||
4332 | { | ||
4333 | if ((automapmode & am_active) || chat_on) | ||
4334 | return false; | ||
4335 | M_SizeDisplay(0); | ||
4336 | S_StartSound(NULL,sfx_stnmov); | ||
4337 | return true; | ||
4338 | } | ||
4339 | |||
4340 | if (ch == key_zoomin) // zoom in | ||
4341 | { // jff 2/23/98 | ||
4342 | if ((automapmode & am_active) || chat_on) // allow | ||
4343 | return false; // key_hud==key_zoomin | ||
4344 | M_SizeDisplay(1); // ^ | ||
4345 | S_StartSound(NULL,sfx_stnmov); // | | ||
4346 | return true; // phares | ||
4347 | } | ||
4348 | |||
4349 | if (ch == key_hud) // heads-up mode | ||
4350 | { | ||
4351 | if ((automapmode & am_active) || chat_on) // jff 2/22/98 | ||
4352 | return false; // HUD mode control | ||
4353 | if (screenSize<8) // function on default F5 | ||
4354 | while (screenSize<8 || !hud_displayed) // make hud visible | ||
4355 | M_SizeDisplay(1); // when configuring it | ||
4356 | else | ||
4357 | { | ||
4358 | hud_displayed = 1; //jff 3/3/98 turn hud on | ||
4359 | hud_active = (hud_active+1)%3; // cycle hud_active | ||
4360 | if (!hud_active) //jff 3/4/98 add distributed | ||
4361 | { | ||
4362 | hud_distributed = !hud_distributed; // to cycle | ||
4363 | HU_MoveHud(); //jff 3/9/98 move it now to avoid glitch | ||
4364 | } | ||
4365 | } | ||
4366 | return true; | ||
4367 | } | ||
4368 | |||
4369 | /* killough 10/98: allow key shortcut into Setup menu */ | ||
4370 | if (ch == key_setup) { | ||
4371 | M_StartControlPanel(); | ||
4372 | S_StartSound(NULL,sfx_swtchn); | ||
4373 | M_SetupNextMenu(&SetupDef); | ||
4374 | return true; | ||
4375 | } | ||
4376 | } | ||
4377 | // Pop-up Main menu? | ||
4378 | |||
4379 | if (!menuactive) | ||
4380 | { | ||
4381 | if (ch == key_escape) // phares | ||
4382 | { | ||
4383 | M_StartControlPanel (); | ||
4384 | S_StartSound(NULL,sfx_swtchn); | ||
4385 | return true; | ||
4386 | } | ||
4387 | return false; | ||
4388 | } | ||
4389 | |||
4390 | // phares 3/26/98 - 4/11/98: | ||
4391 | // Setup screen key processing | ||
4392 | |||
4393 | if (setup_active) { | ||
4394 | setup_menu_t* ptr1= current_setup_menu + set_menu_itemon; | ||
4395 | setup_menu_t* ptr2 = NULL; | ||
4396 | |||
4397 | // phares 4/19/98: | ||
4398 | // Catch the response to the 'reset to default?' verification | ||
4399 | // screen | ||
4400 | |||
4401 | if (default_verify) | ||
4402 | { | ||
4403 | if (toupper(ch) == 'Y') { | ||
4404 | M_ResetDefaults(); | ||
4405 | default_verify = false; | ||
4406 | M_SelectDone(ptr1); | ||
4407 | } | ||
4408 | else if (toupper(ch) == 'N') { | ||
4409 | default_verify = false; | ||
4410 | M_SelectDone(ptr1); | ||
4411 | } | ||
4412 | return true; | ||
4413 | } | ||
4414 | |||
4415 | // Common processing for some items | ||
4416 | |||
4417 | if (setup_select) { // changing an entry | ||
4418 | if (ch == key_menu_escape) // Exit key = no change | ||
4419 | { | ||
4420 | M_SelectDone(ptr1); // phares 4/17/98 | ||
4421 | setup_gather = false; // finished gathering keys, if any | ||
4422 | return true; | ||
4423 | } | ||
4424 | |||
4425 | if (ptr1->m_flags & S_YESNO) // yes or no setting? | ||
4426 | { | ||
4427 | if (ch == key_menu_enter) { | ||
4428 | *ptr1->var.def->location.pi = !*ptr1->var.def->location.pi; // killough 8/15/98 | ||
4429 | |||
4430 | // phares 4/14/98: | ||
4431 | // If not in demoplayback, demorecording, or netgame, | ||
4432 | // and there's a second variable in var2, set that | ||
4433 | // as well | ||
4434 | |||
4435 | // killough 8/15/98: add warning messages | ||
4436 | |||
4437 | if (ptr1->m_flags & (S_LEVWARN | S_PRGWARN)) | ||
4438 | warn_about_changes(ptr1->m_flags & // killough 10/98 | ||
4439 | (S_LEVWARN | S_PRGWARN)); | ||
4440 | else | ||
4441 | M_UpdateCurrent(ptr1->var.def); | ||
4442 | |||
4443 | if (ptr1->action) // killough 10/98 | ||
4444 | ptr1->action(); | ||
4445 | } | ||
4446 | M_SelectDone(ptr1); // phares 4/17/98 | ||
4447 | return true; | ||
4448 | } | ||
4449 | |||
4450 | if (ptr1->m_flags & S_CRITEM) | ||
4451 | { | ||
4452 | if (ch != key_menu_enter) | ||
4453 | { | ||
4454 | ch -= 0x30; // out of ascii | ||
4455 | if (ch < 0 || ch > 9) | ||
4456 | return true; // ignore | ||
4457 | *ptr1->var.def->location.pi = ch; | ||
4458 | } | ||
4459 | if (ptr1->action) // killough 10/98 | ||
4460 | ptr1->action(); | ||
4461 | M_SelectDone(ptr1); // phares 4/17/98 | ||
4462 | return true; | ||
4463 | } | ||
4464 | |||
4465 | if (ptr1->m_flags & S_NUM) // number? | ||
4466 | { | ||
4467 | if (setup_gather) { // gathering keys for a value? | ||
4468 | /* killough 10/98: Allow negatives, and use a more | ||
4469 | * friendly input method (e.g. don't clear value early, | ||
4470 | * allow backspace, and return to original value if bad | ||
4471 | * value is entered). | ||
4472 | */ | ||
4473 | if (ch == key_menu_enter) { | ||
4474 | if (gather_count) { // Any input? | ||
4475 | int value; | ||
4476 | |||
4477 | gather_buffer[gather_count] = 0; | ||
4478 | value = atoi(gather_buffer); // Integer value | ||
4479 | |||
4480 | if ((ptr1->var.def->minvalue != UL && | ||
4481 | value < ptr1->var.def->minvalue) || | ||
4482 | (ptr1->var.def->maxvalue != UL && | ||
4483 | value > ptr1->var.def->maxvalue)) | ||
4484 | warn_about_changes(S_BADVAL); | ||
4485 | else { | ||
4486 | *ptr1->var.def->location.pi = value; | ||
4487 | |||
4488 | /* killough 8/9/98: fix numeric vars | ||
4489 | * killough 8/15/98: add warning message | ||
4490 | */ | ||
4491 | if (ptr1->m_flags & (S_LEVWARN | S_PRGWARN)) | ||
4492 | warn_about_changes(ptr1->m_flags & | ||
4493 | (S_LEVWARN | S_PRGWARN)); | ||
4494 | else | ||
4495 | M_UpdateCurrent(ptr1->var.def); | ||
4496 | |||
4497 | if (ptr1->action) // killough 10/98 | ||
4498 | ptr1->action(); | ||
4499 | } | ||
4500 | } | ||
4501 | M_SelectDone(ptr1); // phares 4/17/98 | ||
4502 | setup_gather = false; // finished gathering keys | ||
4503 | return true; | ||
4504 | } | ||
4505 | |||
4506 | if (ch == key_menu_backspace && gather_count) { | ||
4507 | gather_count--; | ||
4508 | return true; | ||
4509 | } | ||
4510 | |||
4511 | if (gather_count >= MAXGATHER) | ||
4512 | return true; | ||
4513 | |||
4514 | if (!isdigit(ch) && ch != '-') | ||
4515 | return true; // ignore | ||
4516 | |||
4517 | /* killough 10/98: character-based numerical input */ | ||
4518 | gather_buffer[gather_count++] = ch; | ||
4519 | } | ||
4520 | return true; | ||
4521 | } | ||
4522 | |||
4523 | if (ptr1->m_flags & S_CHOICE) // selection of choices? | ||
4524 | { | ||
4525 | if (ch == key_menu_left) { | ||
4526 | if (ptr1->var.def->type == def_int) { | ||
4527 | int value = *ptr1->var.def->location.pi; | ||
4528 | |||
4529 | value = value - 1; | ||
4530 | if ((ptr1->var.def->minvalue != UL && | ||
4531 | value < ptr1->var.def->minvalue)) | ||
4532 | value = ptr1->var.def->minvalue; | ||
4533 | if ((ptr1->var.def->maxvalue != UL && | ||
4534 | value > ptr1->var.def->maxvalue)) | ||
4535 | value = ptr1->var.def->maxvalue; | ||
4536 | if (*ptr1->var.def->location.pi != value) | ||
4537 | S_StartSound(NULL,sfx_pstop); | ||
4538 | *ptr1->var.def->location.pi = value; | ||
4539 | } | ||
4540 | if (ptr1->var.def->type == def_str) { | ||
4541 | int old_value, value; | ||
4542 | |||
4543 | old_value = M_IndexInChoices(*ptr1->var.def->location.ppsz, | ||
4544 | ptr1->selectstrings); | ||
4545 | value = old_value - 1; | ||
4546 | if (value < 0) | ||
4547 | value = 0; | ||
4548 | if (old_value != value) | ||
4549 | S_StartSound(NULL,sfx_pstop); | ||
4550 | *ptr1->var.def->location.ppsz = ptr1->selectstrings[value]; | ||
4551 | } | ||
4552 | } | ||
4553 | if (ch == key_menu_right) { | ||
4554 | if (ptr1->var.def->type == def_int) { | ||
4555 | int value = *ptr1->var.def->location.pi; | ||
4556 | |||
4557 | value = value + 1; | ||
4558 | if ((ptr1->var.def->minvalue != UL && | ||
4559 | value < ptr1->var.def->minvalue)) | ||
4560 | value = ptr1->var.def->minvalue; | ||
4561 | if ((ptr1->var.def->maxvalue != UL && | ||
4562 | value > ptr1->var.def->maxvalue)) | ||
4563 | value = ptr1->var.def->maxvalue; | ||
4564 | if (*ptr1->var.def->location.pi != value) | ||
4565 | S_StartSound(NULL,sfx_pstop); | ||
4566 | *ptr1->var.def->location.pi = value; | ||
4567 | } | ||
4568 | if (ptr1->var.def->type == def_str) { | ||
4569 | int old_value, value; | ||
4570 | |||
4571 | old_value = M_IndexInChoices(*ptr1->var.def->location.ppsz, | ||
4572 | ptr1->selectstrings); | ||
4573 | value = old_value + 1; | ||
4574 | if (ptr1->selectstrings[value] == NULL) | ||
4575 | value = old_value; | ||
4576 | if (old_value != value) | ||
4577 | S_StartSound(NULL,sfx_pstop); | ||
4578 | *ptr1->var.def->location.ppsz = ptr1->selectstrings[value]; | ||
4579 | } | ||
4580 | } | ||
4581 | if (ch == key_menu_enter) { | ||
4582 | // phares 4/14/98: | ||
4583 | // If not in demoplayback, demorecording, or netgame, | ||
4584 | // and there's a second variable in var2, set that | ||
4585 | // as well | ||
4586 | |||
4587 | // killough 8/15/98: add warning messages | ||
4588 | |||
4589 | if (ptr1->m_flags & (S_LEVWARN | S_PRGWARN)) | ||
4590 | warn_about_changes(ptr1->m_flags & // killough 10/98 | ||
4591 | (S_LEVWARN | S_PRGWARN)); | ||
4592 | else | ||
4593 | M_UpdateCurrent(ptr1->var.def); | ||
4594 | |||
4595 | if (ptr1->action) // killough 10/98 | ||
4596 | ptr1->action(); | ||
4597 | M_SelectDone(ptr1); // phares 4/17/98 | ||
4598 | } | ||
4599 | return true; | ||
4600 | } | ||
4601 | |||
4602 | } | ||
4603 | |||
4604 | // Key Bindings | ||
4605 | |||
4606 | if (set_keybnd_active) // on a key binding setup screen | ||
4607 | if (setup_select) // incoming key or button gets bound | ||
4608 | { | ||
4609 | if (ev->type == ev_joystick) | ||
4610 | { | ||
4611 | int oldbutton,group; | ||
4612 | boolean search = true; | ||
4613 | |||
4614 | if (!ptr1->m_joy) | ||
4615 | return true; // not a legal action here (yet) | ||
4616 | |||
4617 | // see if the button is already bound elsewhere. if so, you | ||
4618 | // have to swap bindings so the action where it's currently | ||
4619 | // bound doesn't go dead. Since there is more than one | ||
4620 | // keybinding screen, you have to search all of them for | ||
4621 | // any duplicates. You're only interested in the items | ||
4622 | // that belong to the same group as the one you're changing. | ||
4623 | |||
4624 | oldbutton = *ptr1->m_joy; | ||
4625 | group = ptr1->m_group; | ||
4626 | if (ev->data1 & 1) | ||
4627 | ch = 0; | ||
4628 | else if (ev->data1 & 2) | ||
4629 | ch = 1; | ||
4630 | else if (ev->data1 & 4) | ||
4631 | ch = 2; | ||
4632 | else if (ev->data1 & 8) | ||
4633 | ch = 3; | ||
4634 | else | ||
4635 | return true; | ||
4636 | for (i = 0 ; keys_settings[i] && search ; i++) | ||
4637 | for (ptr2 = keys_settings[i] ; !(ptr2->m_flags & S_END) ; ptr2++) | ||
4638 | if (ptr2->m_group == group && ptr1 != ptr2) | ||
4639 | if (ptr2->m_flags & S_KEY && ptr2->m_joy) | ||
4640 | if (*ptr2->m_joy == ch) | ||
4641 | { | ||
4642 | *ptr2->m_joy = oldbutton; | ||
4643 | search = false; | ||
4644 | break; | ||
4645 | } | ||
4646 | *ptr1->m_joy = ch; | ||
4647 | } | ||
4648 | else if (ev->type == ev_mouse) | ||
4649 | { | ||
4650 | int i,oldbutton,group; | ||
4651 | boolean search = true; | ||
4652 | |||
4653 | if (!ptr1->m_mouse) | ||
4654 | return true; // not a legal action here (yet) | ||
4655 | |||
4656 | // see if the button is already bound elsewhere. if so, you | ||
4657 | // have to swap bindings so the action where it's currently | ||
4658 | // bound doesn't go dead. Since there is more than one | ||
4659 | // keybinding screen, you have to search all of them for | ||
4660 | // any duplicates. You're only interested in the items | ||
4661 | // that belong to the same group as the one you're changing. | ||
4662 | |||
4663 | oldbutton = *ptr1->m_mouse; | ||
4664 | group = ptr1->m_group; | ||
4665 | if (ev->data1 & 1) | ||
4666 | ch = 0; | ||
4667 | else if (ev->data1 & 2) | ||
4668 | ch = 1; | ||
4669 | else if (ev->data1 & 4) | ||
4670 | ch = 2; | ||
4671 | else | ||
4672 | return true; | ||
4673 | for (i = 0 ; keys_settings[i] && search ; i++) | ||
4674 | for (ptr2 = keys_settings[i] ; !(ptr2->m_flags & S_END) ; ptr2++) | ||
4675 | if (ptr2->m_group == group && ptr1 != ptr2) | ||
4676 | if (ptr2->m_flags & S_KEY && ptr2->m_mouse) | ||
4677 | if (*ptr2->m_mouse == ch) | ||
4678 | { | ||
4679 | *ptr2->m_mouse = oldbutton; | ||
4680 | search = false; | ||
4681 | break; | ||
4682 | } | ||
4683 | *ptr1->m_mouse = ch; | ||
4684 | } | ||
4685 | else // keyboard key | ||
4686 | { | ||
4687 | int i,oldkey,group; | ||
4688 | boolean search = true; | ||
4689 | |||
4690 | // see if 'ch' is already bound elsewhere. if so, you have | ||
4691 | // to swap bindings so the action where it's currently | ||
4692 | // bound doesn't go dead. Since there is more than one | ||
4693 | // keybinding screen, you have to search all of them for | ||
4694 | // any duplicates. You're only interested in the items | ||
4695 | // that belong to the same group as the one you're changing. | ||
4696 | |||
4697 | // if you find that you're trying to swap with an action | ||
4698 | // that has S_KEEP set, you can't bind ch; it's already | ||
4699 | // bound to that S_KEEP action, and that action has to | ||
4700 | // keep that key. | ||
4701 | |||
4702 | oldkey = *ptr1->var.m_key; | ||
4703 | group = ptr1->m_group; | ||
4704 | for (i = 0 ; keys_settings[i] && search ; i++) | ||
4705 | for (ptr2 = keys_settings[i] ; !(ptr2->m_flags & S_END) ; ptr2++) | ||
4706 | if (ptr2->m_flags & (S_KEY|S_KEEP) && | ||
4707 | ptr2->m_group == group && | ||
4708 | ptr1 != ptr2) | ||
4709 | if (*ptr2->var.m_key == ch) | ||
4710 | { | ||
4711 | if (ptr2->m_flags & S_KEEP) | ||
4712 | return true; // can't have it! | ||
4713 | *ptr2->var.m_key = oldkey; | ||
4714 | search = false; | ||
4715 | break; | ||
4716 | } | ||
4717 | *ptr1->var.m_key = ch; | ||
4718 | } | ||
4719 | |||
4720 | M_SelectDone(ptr1); // phares 4/17/98 | ||
4721 | return true; | ||
4722 | } | ||
4723 | |||
4724 | // Weapons | ||
4725 | |||
4726 | if (set_weapon_active) // on the weapons setup screen | ||
4727 | if (setup_select) // changing an entry | ||
4728 | { | ||
4729 | if (ch != key_menu_enter) | ||
4730 | { | ||
4731 | ch -= '0'; // out of ascii | ||
4732 | if (ch < 1 || ch > 9) | ||
4733 | return true; // ignore | ||
4734 | |||
4735 | // Plasma and BFG don't exist in shareware | ||
4736 | // killough 10/98: allow it anyway, since this | ||
4737 | // isn't the game itself, just setting preferences | ||
4738 | |||
4739 | // see if 'ch' is already assigned elsewhere. if so, | ||
4740 | // you have to swap assignments. | ||
4741 | |||
4742 | // killough 11/98: simplified | ||
4743 | |||
4744 | for (i = 0; (ptr2 = weap_settings[i]); i++) | ||
4745 | for (; !(ptr2->m_flags & S_END); ptr2++) | ||
4746 | if (ptr2->m_flags & S_WEAP && | ||
4747 | *ptr2->var.def->location.pi == ch && ptr1 != ptr2) | ||
4748 | { | ||
4749 | *ptr2->var.def->location.pi = *ptr1->var.def->location.pi; | ||
4750 | goto end; | ||
4751 | } | ||
4752 | end: | ||
4753 | *ptr1->var.def->location.pi = ch; | ||
4754 | } | ||
4755 | |||
4756 | M_SelectDone(ptr1); // phares 4/17/98 | ||
4757 | return true; | ||
4758 | } | ||
4759 | |||
4760 | // Automap | ||
4761 | |||
4762 | if (set_auto_active) // on the automap setup screen | ||
4763 | if (setup_select) // incoming key | ||
4764 | { | ||
4765 | if (ch == key_menu_down) | ||
4766 | { | ||
4767 | if (++color_palette_y == 16) | ||
4768 | color_palette_y = 0; | ||
4769 | S_StartSound(NULL,sfx_itemup); | ||
4770 | return true; | ||
4771 | } | ||
4772 | |||
4773 | if (ch == key_menu_up) | ||
4774 | { | ||
4775 | if (--color_palette_y < 0) | ||
4776 | color_palette_y = 15; | ||
4777 | S_StartSound(NULL,sfx_itemup); | ||
4778 | return true; | ||
4779 | } | ||
4780 | |||
4781 | if (ch == key_menu_left) | ||
4782 | { | ||
4783 | if (--color_palette_x < 0) | ||
4784 | color_palette_x = 15; | ||
4785 | S_StartSound(NULL,sfx_itemup); | ||
4786 | return true; | ||
4787 | } | ||
4788 | |||
4789 | if (ch == key_menu_right) | ||
4790 | { | ||
4791 | if (++color_palette_x == 16) | ||
4792 | color_palette_x = 0; | ||
4793 | S_StartSound(NULL,sfx_itemup); | ||
4794 | return true; | ||
4795 | } | ||
4796 | |||
4797 | if (ch == key_menu_enter) | ||
4798 | { | ||
4799 | *ptr1->var.def->location.pi = color_palette_x + 16*color_palette_y; | ||
4800 | M_SelectDone(ptr1); // phares 4/17/98 | ||
4801 | colorbox_active = false; | ||
4802 | return true; | ||
4803 | } | ||
4804 | } | ||
4805 | |||
4806 | // killough 10/98: consolidate handling into one place: | ||
4807 | if (setup_select && | ||
4808 | set_enemy_active | set_general_active | set_chat_active | | ||
4809 | set_mess_active | set_status_active | set_compat_active) | ||
4810 | { | ||
4811 | if (ptr1->m_flags & S_STRING) // creating/editing a string? | ||
4812 | { | ||
4813 | if (ch == key_menu_backspace) // backspace and DEL | ||
4814 | { | ||
4815 | if (chat_string_buffer[chat_index] == 0) | ||
4816 | { | ||
4817 | if (chat_index > 0) | ||
4818 | chat_string_buffer[--chat_index] = 0; | ||
4819 | } | ||
4820 | // shift the remainder of the text one char left | ||
4821 | else | ||
4822 | strcpy(&chat_string_buffer[chat_index], | ||
4823 | &chat_string_buffer[chat_index+1]); | ||
4824 | } | ||
4825 | else if (ch == key_menu_left) // move cursor left | ||
4826 | { | ||
4827 | if (chat_index > 0) | ||
4828 | chat_index--; | ||
4829 | } | ||
4830 | else if (ch == key_menu_right) // move cursor right | ||
4831 | { | ||
4832 | if (chat_string_buffer[chat_index] != 0) | ||
4833 | chat_index++; | ||
4834 | } | ||
4835 | else if ((ch == key_menu_enter) || | ||
4836 | (ch == key_menu_escape)) | ||
4837 | { | ||
4838 | *ptr1->var.def->location.ppsz = chat_string_buffer; | ||
4839 | M_SelectDone(ptr1); // phares 4/17/98 | ||
4840 | } | ||
4841 | |||
4842 | // Adding a char to the text. Has to be a printable | ||
4843 | // char, and you can't overrun the buffer. If the | ||
4844 | // chat string gets larger than what the screen can hold, | ||
4845 | // it is dealt with when the string is drawn (above). | ||
4846 | |||
4847 | else if ((ch >= 32) && (ch <= 126)) | ||
4848 | if ((chat_index+1) < CHAT_STRING_BFR_SIZE) | ||
4849 | { | ||
4850 | if (shiftdown) | ||
4851 | ch = shiftxform[ch]; | ||
4852 | if (chat_string_buffer[chat_index] == 0) | ||
4853 | { | ||
4854 | chat_string_buffer[chat_index++] = ch; | ||
4855 | chat_string_buffer[chat_index] = 0; | ||
4856 | } | ||
4857 | else | ||
4858 | chat_string_buffer[chat_index++] = ch; | ||
4859 | } | ||
4860 | return true; | ||
4861 | } | ||
4862 | |||
4863 | M_SelectDone(ptr1); // phares 4/17/98 | ||
4864 | return true; | ||
4865 | } | ||
4866 | |||
4867 | // Not changing any items on the Setup screens. See if we're | ||
4868 | // navigating the Setup menus or selecting an item to change. | ||
4869 | |||
4870 | if (ch == key_menu_down) | ||
4871 | { | ||
4872 | ptr1->m_flags &= ~S_HILITE; // phares 4/17/98 | ||
4873 | do | ||
4874 | if (ptr1->m_flags & S_END) | ||
4875 | { | ||
4876 | set_menu_itemon = 0; | ||
4877 | ptr1 = current_setup_menu; | ||
4878 | } | ||
4879 | else | ||
4880 | { | ||
4881 | set_menu_itemon++; | ||
4882 | ptr1++; | ||
4883 | } | ||
4884 | while (ptr1->m_flags & S_SKIP); | ||
4885 | M_SelectDone(ptr1); // phares 4/17/98 | ||
4886 | return true; | ||
4887 | } | ||
4888 | |||
4889 | if (ch == key_menu_up) | ||
4890 | { | ||
4891 | ptr1->m_flags &= ~S_HILITE; // phares 4/17/98 | ||
4892 | do | ||
4893 | { | ||
4894 | if (set_menu_itemon == 0) | ||
4895 | do | ||
4896 | set_menu_itemon++; | ||
4897 | while(!((current_setup_menu + set_menu_itemon)->m_flags & S_END)); | ||
4898 | set_menu_itemon--; | ||
4899 | } | ||
4900 | while((current_setup_menu + set_menu_itemon)->m_flags & S_SKIP); | ||
4901 | M_SelectDone(current_setup_menu + set_menu_itemon); // phares 4/17/98 | ||
4902 | return true; | ||
4903 | } | ||
4904 | |||
4905 | if (ch == key_menu_enter) | ||
4906 | { | ||
4907 | int flags = ptr1->m_flags; | ||
4908 | |||
4909 | // You've selected an item to change. Highlight it, post a new | ||
4910 | // message about what to do, and get ready to process the | ||
4911 | // change. | ||
4912 | // | ||
4913 | // killough 10/98: use friendlier char-based input buffer | ||
4914 | |||
4915 | if (flags & S_NUM) | ||
4916 | { | ||
4917 | setup_gather = true; | ||
4918 | print_warning_about_changes = false; | ||
4919 | gather_count = 0; | ||
4920 | } | ||
4921 | else if (flags & S_COLOR) | ||
4922 | { | ||
4923 | int color = *ptr1->var.def->location.pi; | ||
4924 | |||
4925 | if (color < 0 || color > 255) // range check the value | ||
4926 | color = 0; // 'no show' if invalid | ||
4927 | |||
4928 | color_palette_x = *ptr1->var.def->location.pi & 15; | ||
4929 | color_palette_y = *ptr1->var.def->location.pi >> 4; | ||
4930 | colorbox_active = true; | ||
4931 | } | ||
4932 | else if (flags & S_STRING) | ||
4933 | { | ||
4934 | // copy chat string into working buffer; trim if needed. | ||
4935 | // free the old chat string memory and replace it with | ||
4936 | // the (possibly larger) new memory for editing purposes | ||
4937 | // | ||
4938 | // killough 10/98: fix bugs, simplify | ||
4939 | |||
4940 | chat_string_buffer = malloc(CHAT_STRING_BFR_SIZE); | ||
4941 | strncpy(chat_string_buffer, | ||
4942 | *ptr1->var.def->location.ppsz, CHAT_STRING_BFR_SIZE); | ||
4943 | |||
4944 | // guarantee null delimiter | ||
4945 | chat_string_buffer[CHAT_STRING_BFR_SIZE-1] = 0; | ||
4946 | |||
4947 | // set chat table pointer to working buffer | ||
4948 | // and free old string's memory. | ||
4949 | |||
4950 | free((char*)*ptr1->var.def->location.ppsz); | ||
4951 | *ptr1->var.def->location.ppsz = chat_string_buffer; | ||
4952 | chat_index = 0; // current cursor position in chat_string_buffer | ||
4953 | } | ||
4954 | else if (flags & S_RESET) | ||
4955 | default_verify = true; | ||
4956 | |||
4957 | ptr1->m_flags |= S_SELECT; | ||
4958 | setup_select = true; | ||
4959 | S_StartSound(NULL,sfx_itemup); | ||
4960 | return true; | ||
4961 | } | ||
4962 | |||
4963 | if ((ch == key_menu_escape) || (ch == key_menu_backspace)) | ||
4964 | { | ||
4965 | if (ch == key_menu_escape) // Clear all menus | ||
4966 | M_ClearMenus(); | ||
4967 | else // key_menu_backspace = return to Setup Menu | ||
4968 | if (currentMenu->prevMenu) | ||
4969 | { | ||
4970 | currentMenu = currentMenu->prevMenu; | ||
4971 | itemOn = currentMenu->lastOn; | ||
4972 | S_StartSound(NULL,sfx_swtchn); | ||
4973 | } | ||
4974 | ptr1->m_flags &= ~(S_HILITE|S_SELECT);// phares 4/19/98 | ||
4975 | setup_active = false; | ||
4976 | set_keybnd_active = false; | ||
4977 | set_weapon_active = false; | ||
4978 | set_status_active = false; | ||
4979 | set_auto_active = false; | ||
4980 | set_enemy_active = false; | ||
4981 | set_mess_active = false; | ||
4982 | set_chat_active = false; | ||
4983 | colorbox_active = false; | ||
4984 | default_verify = false; // phares 4/19/98 | ||
4985 | set_general_active = false; // killough 10/98 | ||
4986 | set_compat_active = false; // killough 10/98 | ||
4987 | HU_Start(); // catch any message changes // phares 4/19/98 | ||
4988 | S_StartSound(NULL,sfx_swtchx); | ||
4989 | return true; | ||
4990 | } | ||
4991 | |||
4992 | // Some setup screens may have multiple screens. | ||
4993 | // When there are multiple screens, m_prev and m_next items need to | ||
4994 | // be placed on the appropriate screen tables so the user can | ||
4995 | // move among the screens using the left and right arrow keys. | ||
4996 | // The m_var1 field contains a pointer to the appropriate screen | ||
4997 | // to move to. | ||
4998 | |||
4999 | if (ch == key_menu_left) | ||
5000 | { | ||
5001 | ptr2 = ptr1; | ||
5002 | do | ||
5003 | { | ||
5004 | ptr2++; | ||
5005 | if (ptr2->m_flags & S_PREV) | ||
5006 | { | ||
5007 | ptr1->m_flags &= ~S_HILITE; | ||
5008 | mult_screens_index--; | ||
5009 | current_setup_menu = ptr2->var.menu; | ||
5010 | set_menu_itemon = 0; | ||
5011 | print_warning_about_changes = false; // killough 10/98 | ||
5012 | while (current_setup_menu[set_menu_itemon++].m_flags&S_SKIP); | ||
5013 | current_setup_menu[--set_menu_itemon].m_flags |= S_HILITE; | ||
5014 | S_StartSound(NULL,sfx_pstop); // killough 10/98 | ||
5015 | return true; | ||
5016 | } | ||
5017 | } | ||
5018 | while (!(ptr2->m_flags & S_END)); | ||
5019 | } | ||
5020 | |||
5021 | if (ch == key_menu_right) | ||
5022 | { | ||
5023 | ptr2 = ptr1; | ||
5024 | do | ||
5025 | { | ||
5026 | ptr2++; | ||
5027 | if (ptr2->m_flags & S_NEXT) | ||
5028 | { | ||
5029 | ptr1->m_flags &= ~S_HILITE; | ||
5030 | mult_screens_index++; | ||
5031 | current_setup_menu = ptr2->var.menu; | ||
5032 | set_menu_itemon = 0; | ||
5033 | print_warning_about_changes = false; // killough 10/98 | ||
5034 | while (current_setup_menu[set_menu_itemon++].m_flags&S_SKIP); | ||
5035 | current_setup_menu[--set_menu_itemon].m_flags |= S_HILITE; | ||
5036 | S_StartSound(NULL,sfx_pstop); // killough 10/98 | ||
5037 | return true; | ||
5038 | } | ||
5039 | } | ||
5040 | while (!(ptr2->m_flags & S_END)); | ||
5041 | } | ||
5042 | |||
5043 | } // End of Setup Screen processing | ||
5044 | |||
5045 | // From here on, these navigation keys are used on the BIG FONT menus | ||
5046 | // like the Main Menu. | ||
5047 | |||
5048 | if (ch == key_menu_down) // phares 3/7/98 | ||
5049 | { | ||
5050 | do | ||
5051 | { | ||
5052 | if (itemOn+1 > currentMenu->numitems-1) | ||
5053 | itemOn = 0; | ||
5054 | else | ||
5055 | itemOn++; | ||
5056 | S_StartSound(NULL,sfx_pstop); | ||
5057 | } | ||
5058 | while(currentMenu->menuitems[itemOn].status==-1); | ||
5059 | return true; | ||
5060 | } | ||
5061 | |||
5062 | if (ch == key_menu_up) // phares 3/7/98 | ||
5063 | { | ||
5064 | do | ||
5065 | { | ||
5066 | if (!itemOn) | ||
5067 | itemOn = currentMenu->numitems-1; | ||
5068 | else | ||
5069 | itemOn--; | ||
5070 | S_StartSound(NULL,sfx_pstop); | ||
5071 | } | ||
5072 | while(currentMenu->menuitems[itemOn].status==-1); | ||
5073 | return true; | ||
5074 | } | ||
5075 | |||
5076 | if (ch == key_menu_left) // phares 3/7/98 | ||
5077 | { | ||
5078 | if (currentMenu->menuitems[itemOn].routine && | ||
5079 | currentMenu->menuitems[itemOn].status == 2) | ||
5080 | { | ||
5081 | S_StartSound(NULL,sfx_stnmov); | ||
5082 | currentMenu->menuitems[itemOn].routine(0); | ||
5083 | } | ||
5084 | return true; | ||
5085 | } | ||
5086 | |||
5087 | if (ch == key_menu_right) // phares 3/7/98 | ||
5088 | { | ||
5089 | if (currentMenu->menuitems[itemOn].routine && | ||
5090 | currentMenu->menuitems[itemOn].status == 2) | ||
5091 | { | ||
5092 | S_StartSound(NULL,sfx_stnmov); | ||
5093 | currentMenu->menuitems[itemOn].routine(1); | ||
5094 | } | ||
5095 | return true; | ||
5096 | } | ||
5097 | |||
5098 | if (ch == key_menu_enter) // phares 3/7/98 | ||
5099 | { | ||
5100 | if (currentMenu->menuitems[itemOn].routine && | ||
5101 | currentMenu->menuitems[itemOn].status) | ||
5102 | { | ||
5103 | currentMenu->lastOn = itemOn; | ||
5104 | if (currentMenu->menuitems[itemOn].status == 2) | ||
5105 | { | ||
5106 | currentMenu->menuitems[itemOn].routine(1); // right arrow | ||
5107 | S_StartSound(NULL,sfx_stnmov); | ||
5108 | } | ||
5109 | else | ||
5110 | { | ||
5111 | currentMenu->menuitems[itemOn].routine(itemOn); | ||
5112 | S_StartSound(NULL,sfx_pistol); | ||
5113 | } | ||
5114 | } | ||
5115 | //jff 3/24/98 remember last skill selected | ||
5116 | // killough 10/98 moved to skill-specific functions | ||
5117 | return true; | ||
5118 | } | ||
5119 | |||
5120 | if (ch == key_menu_escape) // phares 3/7/98 | ||
5121 | { | ||
5122 | currentMenu->lastOn = itemOn; | ||
5123 | M_ClearMenus (); | ||
5124 | S_StartSound(NULL,sfx_swtchx); | ||
5125 | return true; | ||
5126 | } | ||
5127 | |||
5128 | if (ch == key_menu_backspace) // phares 3/7/98 | ||
5129 | { | ||
5130 | currentMenu->lastOn = itemOn; | ||
5131 | |||
5132 | // phares 3/30/98: | ||
5133 | // add checks to see if you're in the extended help screens | ||
5134 | // if so, stay with the same menu definition, but bump the | ||
5135 | // index back one. if the index bumps back far enough ( == 0) | ||
5136 | // then you can return to the Read_Thisn menu definitions | ||
5137 | |||
5138 | if (currentMenu->prevMenu) | ||
5139 | { | ||
5140 | if (currentMenu == &ExtHelpDef) | ||
5141 | { | ||
5142 | if (--extended_help_index == 0) | ||
5143 | { | ||
5144 | currentMenu = currentMenu->prevMenu; | ||
5145 | extended_help_index = 1; // reset | ||
5146 | } | ||
5147 | } | ||
5148 | else | ||
5149 | currentMenu = currentMenu->prevMenu; | ||
5150 | itemOn = currentMenu->lastOn; | ||
5151 | S_StartSound(NULL,sfx_swtchn); | ||
5152 | } | ||
5153 | return true; | ||
5154 | } | ||
5155 | |||
5156 | else | ||
5157 | { | ||
5158 | for (i = itemOn+1;i < currentMenu->numitems;i++) | ||
5159 | if (currentMenu->menuitems[i].alphaKey == ch) | ||
5160 | { | ||
5161 | itemOn = i; | ||
5162 | S_StartSound(NULL,sfx_pstop); | ||
5163 | return true; | ||
5164 | } | ||
5165 | for (i = 0;i <= itemOn;i++) | ||
5166 | if (currentMenu->menuitems[i].alphaKey == ch) | ||
5167 | { | ||
5168 | itemOn = i; | ||
5169 | S_StartSound(NULL,sfx_pstop); | ||
5170 | return true; | ||
5171 | } | ||
5172 | } | ||
5173 | return false; | ||
5174 | } | ||
5175 | |||
5176 | // | ||
5177 | // End of M_Responder | ||
5178 | // | ||
5179 | ///////////////////////////////////////////////////////////////////////////// | ||
5180 | |||
5181 | ///////////////////////////////////////////////////////////////////////////// | ||
5182 | // | ||
5183 | // General Routines | ||
5184 | // | ||
5185 | // This displays the Main menu and gets the menu screens rolling. | ||
5186 | // Plus a variety of routines that control the Big Font menu display. | ||
5187 | // Plus some initialization for game-dependant situations. | ||
5188 | |||
5189 | void M_StartControlPanel (void) | ||
5190 | { | ||
5191 | // intro might call this repeatedly | ||
5192 | |||
5193 | if (menuactive) | ||
5194 | return; | ||
5195 | |||
5196 | //jff 3/24/98 make default skill menu choice follow -skill or defaultskill | ||
5197 | //from command line or config file | ||
5198 | // | ||
5199 | // killough 10/98: | ||
5200 | // Fix to make "always floating" with menu selections, and to always follow | ||
5201 | // defaultskill, instead of -skill. | ||
5202 | |||
5203 | NewDef.lastOn = defaultskill - 1; | ||
5204 | |||
5205 | default_verify = 0; // killough 10/98 | ||
5206 | menuactive = 1; | ||
5207 | currentMenu = &MainDef; // JDC | ||
5208 | itemOn = currentMenu->lastOn; // JDC | ||
5209 | print_warning_about_changes = false; // killough 11/98 | ||
5210 | } | ||
5211 | |||
5212 | // | ||
5213 | // M_Drawer | ||
5214 | // Called after the view has been rendered, | ||
5215 | // but before it has been blitted. | ||
5216 | // | ||
5217 | // killough 9/29/98: Significantly reformatted source | ||
5218 | // | ||
5219 | |||
5220 | void M_Drawer (void) | ||
5221 | { | ||
5222 | inhelpscreens = false; | ||
5223 | |||
5224 | // Horiz. & Vertically center string and print it. | ||
5225 | // killough 9/29/98: simplified code, removed 40-character width limit | ||
5226 | if (messageToPrint) | ||
5227 | { | ||
5228 | /* cph - strdup string to writable memory */ | ||
5229 | char *ms = strdup(messageString); | ||
5230 | char *p = ms; | ||
5231 | |||
5232 | int y = 100 - M_StringHeight(messageString)/2; | ||
5233 | while (*p) | ||
5234 | { | ||
5235 | char *string = p, c; | ||
5236 | while ((c = *p) && *p != '\n') | ||
5237 | p++; | ||
5238 | *p = 0; | ||
5239 | M_WriteText(160 - M_StringWidth(string)/2, y, string); | ||
5240 | y += hu_font[0].height; | ||
5241 | if ((*p = c)) | ||
5242 | p++; | ||
5243 | } | ||
5244 | free(ms); | ||
5245 | } | ||
5246 | else | ||
5247 | if (menuactive) | ||
5248 | { | ||
5249 | int x,y,max,i; | ||
5250 | |||
5251 | if (currentMenu->routine) | ||
5252 | currentMenu->routine(); // call Draw routine | ||
5253 | |||
5254 | // DRAW MENU | ||
5255 | |||
5256 | x = currentMenu->x; | ||
5257 | y = currentMenu->y; | ||
5258 | max = currentMenu->numitems; | ||
5259 | |||
5260 | for (i=0;i<max;i++) | ||
5261 | { | ||
5262 | if (currentMenu->menuitems[i].name[0]) | ||
5263 | V_DrawNamePatch(x,y,0,currentMenu->menuitems[i].name, | ||
5264 | CR_DEFAULT, VPT_STRETCH); | ||
5265 | y += LINEHEIGHT; | ||
5266 | } | ||
5267 | |||
5268 | // DRAW SKULL | ||
5269 | |||
5270 | // CPhipps - patch drawing updated | ||
5271 | V_DrawNamePatch(x + SKULLXOFF, currentMenu->y - 5 + itemOn*LINEHEIGHT,0, | ||
5272 | skullName[whichSkull], CR_DEFAULT, VPT_STRETCH); | ||
5273 | } | ||
5274 | } | ||
5275 | |||
5276 | // | ||
5277 | // M_ClearMenus | ||
5278 | // | ||
5279 | // Called when leaving the menu screens for the real world | ||
5280 | |||
5281 | void M_ClearMenus (void) | ||
5282 | { | ||
5283 | menuactive = 0; | ||
5284 | print_warning_about_changes = 0; // killough 8/15/98 | ||
5285 | default_verify = 0; // killough 10/98 | ||
5286 | |||
5287 | // if (!netgame && usergame && paused) | ||
5288 | // sendpause = true; | ||
5289 | } | ||
5290 | |||
5291 | // | ||
5292 | // M_SetupNextMenu | ||
5293 | // | ||
5294 | void M_SetupNextMenu(menu_t *menudef) | ||
5295 | { | ||
5296 | currentMenu = menudef; | ||
5297 | itemOn = currentMenu->lastOn; | ||
5298 | } | ||
5299 | |||
5300 | ///////////////////////////// | ||
5301 | // | ||
5302 | // M_Ticker | ||
5303 | // | ||
5304 | void M_Ticker (void) | ||
5305 | { | ||
5306 | if (--skullAnimCounter <= 0) | ||
5307 | { | ||
5308 | whichSkull ^= 1; | ||
5309 | skullAnimCounter = 8; | ||
5310 | } | ||
5311 | } | ||
5312 | |||
5313 | ///////////////////////////// | ||
5314 | // | ||
5315 | // Message Routines | ||
5316 | // | ||
5317 | |||
5318 | void M_StartMessage (const char* string,void* routine,boolean input) | ||
5319 | { | ||
5320 | messageLastMenuActive = menuactive; | ||
5321 | messageToPrint = 1; | ||
5322 | messageString = string; | ||
5323 | messageRoutine = routine; | ||
5324 | messageNeedsInput = input; | ||
5325 | menuactive = true; | ||
5326 | return; | ||
5327 | } | ||
5328 | |||
5329 | void M_StopMessage(void) | ||
5330 | { | ||
5331 | menuactive = messageLastMenuActive; | ||
5332 | messageToPrint = 0; | ||
5333 | } | ||
5334 | |||
5335 | ///////////////////////////// | ||
5336 | // | ||
5337 | // Thermometer Routines | ||
5338 | // | ||
5339 | |||
5340 | // | ||
5341 | // M_DrawThermo draws the thermometer graphic for Mouse Sensitivity, | ||
5342 | // Sound Volume, etc. | ||
5343 | // | ||
5344 | // proff/nicolas 09/20/98 -- changed for hi-res | ||
5345 | // CPhipps - patch drawing updated | ||
5346 | // | ||
5347 | void M_DrawThermo(int x,int y,int thermWidth,int thermDot ) | ||
5348 | { | ||
5349 | int xx; | ||
5350 | int i; | ||
5351 | /* | ||
5352 | * Modification By Barry Mead to allow the Thermometer to have vastly | ||
5353 | * larger ranges. (the thermWidth parameter can now have a value as | ||
5354 | * large as 200. Modified 1-9-2000 Originally I used it to make | ||
5355 | * the sensitivity range for the mouse better. It could however also | ||
5356 | * be used to improve the dynamic range of music and sound affect | ||
5357 | * volume controls for example. | ||
5358 | */ | ||
5359 | int horizScaler; //Used to allow more thermo range for mouse sensitivity. | ||
5360 | thermWidth = (thermWidth > 200) ? 200 : thermWidth; //Clamp to 200 max | ||
5361 | horizScaler = (thermWidth > 23) ? (200 / thermWidth) : 8; //Dynamic range | ||
5362 | xx = x; | ||
5363 | V_DrawNamePatch(xx, y, 0, "M_THERML", CR_DEFAULT, VPT_STRETCH); | ||
5364 | xx += 8; | ||
5365 | for (i=0;i<thermWidth;i++) | ||
5366 | { | ||
5367 | V_DrawNamePatch(xx, y, 0, "M_THERMM", CR_DEFAULT, VPT_STRETCH); | ||
5368 | xx += horizScaler; | ||
5369 | } | ||
5370 | |||
5371 | xx += (8 - horizScaler); /* make the right end look even */ | ||
5372 | |||
5373 | V_DrawNamePatch(xx, y, 0, "M_THERMR", CR_DEFAULT, VPT_STRETCH); | ||
5374 | V_DrawNamePatch((x+8)+thermDot*horizScaler,y,0,"M_THERMO",CR_DEFAULT,VPT_STRETCH); | ||
5375 | } | ||
5376 | |||
5377 | // | ||
5378 | // Draw an empty cell in the thermometer | ||
5379 | // | ||
5380 | |||
5381 | void M_DrawEmptyCell (menu_t* menu,int item) | ||
5382 | { | ||
5383 | // CPhipps - patch drawing updated | ||
5384 | V_DrawNamePatch(menu->x - 10, menu->y+item*LINEHEIGHT - 1, 0, | ||
5385 | "M_CELL1", CR_DEFAULT, VPT_STRETCH); | ||
5386 | } | ||
5387 | |||
5388 | // | ||
5389 | // Draw a full cell in the thermometer | ||
5390 | // | ||
5391 | |||
5392 | void M_DrawSelCell (menu_t* menu,int item) | ||
5393 | { | ||
5394 | // CPhipps - patch drawing updated | ||
5395 | V_DrawNamePatch(menu->x - 10, menu->y+item*LINEHEIGHT - 1, 0, | ||
5396 | "M_CELL2", CR_DEFAULT, VPT_STRETCH); | ||
5397 | } | ||
5398 | |||
5399 | ///////////////////////////// | ||
5400 | // | ||
5401 | // String-drawing Routines | ||
5402 | // | ||
5403 | |||
5404 | // | ||
5405 | // Find string width from hu_font chars | ||
5406 | // | ||
5407 | |||
5408 | int M_StringWidth(const char* string) | ||
5409 | { | ||
5410 | int i, c, w = 0; | ||
5411 | for (i = 0;(size_t)i < strlen(string);i++) | ||
5412 | w += (c = toupper(string[i]) - HU_FONTSTART) < 0 || c >= HU_FONTSIZE ? | ||
5413 | 4 : hu_font[c].width; | ||
5414 | return w; | ||
5415 | } | ||
5416 | |||
5417 | // | ||
5418 | // Find string height from hu_font chars | ||
5419 | // | ||
5420 | |||
5421 | int M_StringHeight(const char* string) | ||
5422 | { | ||
5423 | int i, h, height = h = hu_font[0].height; | ||
5424 | for (i = 0;string[i];i++) // killough 1/31/98 | ||
5425 | if (string[i] == '\n') | ||
5426 | h += height; | ||
5427 | return h; | ||
5428 | } | ||
5429 | |||
5430 | // | ||
5431 | // Write a string using the hu_font | ||
5432 | // | ||
5433 | void M_WriteText (int x,int y,const char* string) | ||
5434 | { | ||
5435 | int w; | ||
5436 | const char* ch; | ||
5437 | int c; | ||
5438 | int cx; | ||
5439 | int cy; | ||
5440 | |||
5441 | ch = string; | ||
5442 | cx = x; | ||
5443 | cy = y; | ||
5444 | |||
5445 | while(1) { | ||
5446 | c = *ch++; | ||
5447 | if (!c) | ||
5448 | break; | ||
5449 | if (c == '\n') { | ||
5450 | cx = x; | ||
5451 | cy += 12; | ||
5452 | continue; | ||
5453 | } | ||
5454 | |||
5455 | c = toupper(c) - HU_FONTSTART; | ||
5456 | if (c < 0 || c>= HU_FONTSIZE) { | ||
5457 | cx += 4; | ||
5458 | continue; | ||
5459 | } | ||
5460 | |||
5461 | w = hu_font[c].width; | ||
5462 | if (cx+w > SCREENWIDTH) | ||
5463 | break; | ||
5464 | // proff/nicolas 09/20/98 -- changed for hi-res | ||
5465 | // CPhipps - patch drawing updated | ||
5466 | V_DrawNumPatch(cx, cy, 0, hu_font[c].lumpnum, CR_DEFAULT, VPT_STRETCH); | ||
5467 | cx+=w; | ||
5468 | } | ||
5469 | } | ||
5470 | |||
5471 | ///////////////////////////// | ||
5472 | // | ||
5473 | // Initialization Routines to take care of one-time setup | ||
5474 | // | ||
5475 | |||
5476 | // phares 4/08/98: | ||
5477 | // M_InitHelpScreen() clears the weapons from the HELP | ||
5478 | // screen that don't exist in this version of the game. | ||
5479 | |||
5480 | void M_InitHelpScreen(void) | ||
5481 | { | ||
5482 | setup_menu_t* src; | ||
5483 | |||
5484 | src = helpstrings; | ||
5485 | while (!(src->m_flags & S_END)) { | ||
5486 | |||
5487 | if ((strncmp(src->m_text,"PLASMA",6) == 0) && (gamemode == shareware)) | ||
5488 | src->m_flags = S_SKIP; // Don't show setting or item | ||
5489 | if ((strncmp(src->m_text,"BFG",3) == 0) && (gamemode == shareware)) | ||
5490 | src->m_flags = S_SKIP; // Don't show setting or item | ||
5491 | if ((strncmp(src->m_text,"SSG",3) == 0) && (gamemode != commercial)) | ||
5492 | src->m_flags = S_SKIP; // Don't show setting or item | ||
5493 | src++; | ||
5494 | } | ||
5495 | } | ||
5496 | |||
5497 | // | ||
5498 | // M_Init | ||
5499 | // | ||
5500 | void M_Init(void) | ||
5501 | { | ||
5502 | M_InitDefaults(); // killough 11/98 | ||
5503 | currentMenu = &MainDef; | ||
5504 | menuactive = 0; | ||
5505 | itemOn = currentMenu->lastOn; | ||
5506 | whichSkull = 0; | ||
5507 | skullAnimCounter = 10; | ||
5508 | screenSize = screenblocks - 3; | ||
5509 | messageToPrint = 0; | ||
5510 | messageString = NULL; | ||
5511 | messageLastMenuActive = menuactive; | ||
5512 | quickSaveSlot = -1; | ||
5513 | |||
5514 | // Here we could catch other version dependencies, | ||
5515 | // like HELP1/2, and four episodes. | ||
5516 | |||
5517 | switch(gamemode) | ||
5518 | { | ||
5519 | case commercial: | ||
5520 | // This is used because DOOM 2 had only one HELP | ||
5521 | // page. I use CREDIT as second page now, but | ||
5522 | // kept this hack for educational purposes. | ||
5523 | MainMenu[readthis] = MainMenu[quitdoom]; | ||
5524 | MainDef.numitems--; | ||
5525 | MainDef.y += 8; | ||
5526 | NewDef.prevMenu = &MainDef; | ||
5527 | ReadDef1.routine = M_DrawReadThis1; | ||
5528 | ReadDef1.x = 330; | ||
5529 | ReadDef1.y = 165; | ||
5530 | ReadMenu1[0].routine = M_FinishReadThis; | ||
5531 | break; | ||
5532 | case registered: | ||
5533 | // Episode 2 and 3 are handled, | ||
5534 | // branching to an ad screen. | ||
5535 | |||
5536 | // killough 2/21/98: Fix registered Doom help screen | ||
5537 | // killough 10/98: moved to second screen, moved up to the top | ||
5538 | ReadDef2.y = 15; | ||
5539 | |||
5540 | case shareware: | ||
5541 | // We need to remove the fourth episode. | ||
5542 | EpiDef.numitems--; | ||
5543 | break; | ||
5544 | case retail: | ||
5545 | // We are fine. | ||
5546 | default: | ||
5547 | break; | ||
5548 | } | ||
5549 | |||
5550 | M_InitHelpScreen(); // init the help screen // phares 4/08/98 | ||
5551 | M_InitExtendedHelp(); // init extended help screens // phares 3/30/98 | ||
5552 | |||
5553 | M_ChangeDemoSmoothTurns(); | ||
5554 | } | ||
5555 | |||
5556 | // | ||
5557 | // End of General Routines | ||
5558 | // | ||
5559 | ///////////////////////////////////////////////////////////////////////////// | ||