diff options
Diffstat (limited to 'apps/plugins/doom/m_menu.c')
-rw-r--r-- | apps/plugins/doom/m_menu.c | 1848 |
1 files changed, 1848 insertions, 0 deletions
diff --git a/apps/plugins/doom/m_menu.c b/apps/plugins/doom/m_menu.c new file mode 100644 index 0000000000..34f3e22ce2 --- /dev/null +++ b/apps/plugins/doom/m_menu.c | |||
@@ -0,0 +1,1848 @@ | |||
1 | // Emacs style mode select -*- C++ -*- | ||
2 | //----------------------------------------------------------------------------- | ||
3 | // | ||
4 | // $Id$ | ||
5 | // | ||
6 | // Copyright (C) 1993-1996 by id Software, Inc. | ||
7 | // | ||
8 | // This program is free software; you can redistribute it and/or | ||
9 | // modify it under the terms of the GNU General Public License | ||
10 | // as published by the Free Software Foundation; either version 2 | ||
11 | // of the License, or (at your option) any later version. | ||
12 | // | ||
13 | // This program is distributed in the hope that it will be useful, | ||
14 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | // GNU General Public License for more details. | ||
17 | // | ||
18 | // $Log$ | ||
19 | // Revision 1.1 2006/03/28 15:44:01 dave | ||
20 | // Patch #2969 - Doom! Currently only working on the H300. | ||
21 | // | ||
22 | // | ||
23 | // DESCRIPTION: | ||
24 | // DOOM selection menu, options, episode etc. | ||
25 | // Sliders and icons. Kinda widget stuff. | ||
26 | // | ||
27 | //----------------------------------------------------------------------------- | ||
28 | |||
29 | #include "doomdef.h" | ||
30 | #include "dstrings.h" | ||
31 | |||
32 | #include "d_main.h" | ||
33 | |||
34 | #include "i_system.h" | ||
35 | #include "i_video.h" | ||
36 | #include "z_zone.h" | ||
37 | #include "v_video.h" | ||
38 | #include "w_wad.h" | ||
39 | |||
40 | #include "r_main.h" | ||
41 | |||
42 | #include "hu_stuff.h" | ||
43 | |||
44 | #include "g_game.h" | ||
45 | |||
46 | #include "m_argv.h" | ||
47 | #include "m_swap.h" | ||
48 | #include "s_sound.h" | ||
49 | |||
50 | #include "doomstat.h" | ||
51 | |||
52 | // Data. | ||
53 | #include "sounds.h" | ||
54 | |||
55 | #include "m_menu.h" | ||
56 | #include "rockmacros.h" | ||
57 | |||
58 | |||
59 | extern patchnum_t hu_font[HU_FONTSIZE]; | ||
60 | extern boolean message_dontfuckwithme; | ||
61 | |||
62 | extern boolean chat_on; // in heads-up code | ||
63 | |||
64 | // | ||
65 | // defaulted values | ||
66 | // | ||
67 | int mouseSensitivity; // has default | ||
68 | |||
69 | // Show messages has default, 0 = off, 1 = on | ||
70 | int showMessages; | ||
71 | |||
72 | // Blocky mode, has default, 0 = high, 1 = normal | ||
73 | int screenblocks; // has default | ||
74 | |||
75 | // temp for screenblocks (0-9) | ||
76 | int screenSize; | ||
77 | |||
78 | // -1 = no quicksave slot picked! | ||
79 | int quickSaveSlot; | ||
80 | |||
81 | // 1 = message to be printed | ||
82 | int messageToPrint; | ||
83 | // ...and here is the message string! | ||
84 | char* messageString; | ||
85 | |||
86 | // message x & y | ||
87 | int messx; | ||
88 | int messy; | ||
89 | int messageLastMenuActive; | ||
90 | |||
91 | // timed message = no input from user | ||
92 | boolean messageNeedsInput; | ||
93 | |||
94 | void (*messageRoutine)(int response); | ||
95 | |||
96 | #define SAVESTRINGSIZE 24 | ||
97 | |||
98 | char gammamsg[5][26] = | ||
99 | { | ||
100 | GAMMALVL0, | ||
101 | GAMMALVL1, | ||
102 | GAMMALVL2, | ||
103 | GAMMALVL3, | ||
104 | GAMMALVL4 | ||
105 | }; | ||
106 | |||
107 | // we are going to be entering a savegame string | ||
108 | int saveStringEnter; | ||
109 | int saveSlot; // which slot to save in | ||
110 | int saveCharIndex; // which char we're editing | ||
111 | // old save description before edit | ||
112 | char saveOldString[SAVESTRINGSIZE]; | ||
113 | |||
114 | boolean inhelpscreens; | ||
115 | boolean menuactive; | ||
116 | |||
117 | #define SKULLXOFF -32 | ||
118 | #define LINEHEIGHT 16 | ||
119 | |||
120 | extern boolean sendpause; | ||
121 | char savegamestrings[10][SAVESTRINGSIZE]; | ||
122 | |||
123 | char endstring[170]; | ||
124 | |||
125 | |||
126 | // | ||
127 | // MENU TYPEDEFS | ||
128 | // | ||
129 | typedef struct | ||
130 | { | ||
131 | // 0 = no cursor here, 1 = ok, 2 = arrows ok | ||
132 | short status; | ||
133 | |||
134 | char name[10]; | ||
135 | |||
136 | // choice = menu item #. | ||
137 | // if status = 2, | ||
138 | // choice=0:leftarrow,1:rightarrow | ||
139 | void (*routine)(int choice); | ||
140 | |||
141 | // hotkey in menu | ||
142 | char alphaKey; | ||
143 | } | ||
144 | menuitem_t; | ||
145 | |||
146 | |||
147 | |||
148 | typedef struct menu_s | ||
149 | { | ||
150 | short numitems; // # of menu items | ||
151 | struct menu_s* prevMenu; // previous menu | ||
152 | menuitem_t* menuitems; // menu items | ||
153 | void (*routine)(void); // draw routine ROCKBOX | ||
154 | short x; | ||
155 | short y; // x,y of menu | ||
156 | short lastOn; // last item user was on in menu | ||
157 | } | ||
158 | menu_t; | ||
159 | |||
160 | short itemOn; // menu item skull is on | ||
161 | short skullAnimCounter; // skull animation counter | ||
162 | short whichSkull; // which skull to draw | ||
163 | int systemvol; | ||
164 | |||
165 | // graphic name of skulls | ||
166 | // warning: initializer-string for array of chars is too long | ||
167 | char skullName[2][/*8*/9] = {"M_SKULL1","M_SKULL2"}; | ||
168 | |||
169 | // current menudef | ||
170 | menu_t* currentMenu; | ||
171 | |||
172 | // | ||
173 | // PROTOTYPES | ||
174 | // | ||
175 | void M_NewGame(int choice); | ||
176 | void M_Episode(int choice); | ||
177 | void M_ChooseSkill(int choice); | ||
178 | void M_LoadGame(int choice); | ||
179 | void M_SaveGame(int choice); | ||
180 | void M_Options(int choice); | ||
181 | void M_EndGame(int choice); | ||
182 | void M_ReadThis(int choice); | ||
183 | void M_ReadThis2(int choice); | ||
184 | void M_QuitDOOM(int choice); | ||
185 | |||
186 | void M_ChangeMessages(int choice); | ||
187 | void M_ChangeSensitivity(int choice); | ||
188 | void M_SfxVol(int choice); | ||
189 | void M_MusicVol(int choice); | ||
190 | void M_SystemVol(int choice); | ||
191 | void M_SizeDisplay(int choice); | ||
192 | void M_StartGame(int choice); | ||
193 | void M_Sound(int choice); | ||
194 | |||
195 | void M_FinishReadThis(int choice); | ||
196 | void M_LoadSelect(int choice); | ||
197 | void M_SaveSelect(int choice); | ||
198 | void M_ReadSaveStrings(void); | ||
199 | void M_QuickSave(void); | ||
200 | void M_QuickLoad(void); | ||
201 | |||
202 | void M_DrawMainMenu(void); | ||
203 | void M_DrawReadThis1(void); | ||
204 | void M_DrawReadThis2(void); | ||
205 | void M_DrawNewGame(void); | ||
206 | void M_DrawEpisode(void); | ||
207 | void M_DrawOptions(void); | ||
208 | void M_DrawSound(void); | ||
209 | void M_DrawLoad(void); | ||
210 | void M_DrawSave(void); | ||
211 | |||
212 | void M_DrawSaveLoadBorder(int x,int y); | ||
213 | void M_SetupNextMenu(menu_t *menudef); | ||
214 | void M_DrawThermo(int x,int y,int thermWidth,int thermDot); | ||
215 | void M_DrawEmptyCell(menu_t *menu,int item); | ||
216 | void M_DrawSelCell(menu_t *menu,int item); | ||
217 | void M_WriteText(int x, int y, char *string); | ||
218 | int M_StringWidth(const char* string); | ||
219 | int M_StringHeight(const char* string); | ||
220 | void M_StartControlPanel(void); | ||
221 | void M_StartMessage(char *string,void *routine,boolean input); | ||
222 | void M_StopMessage(void); | ||
223 | void M_ClearMenus (void); | ||
224 | |||
225 | |||
226 | |||
227 | |||
228 | // | ||
229 | // DOOM MENU | ||
230 | // | ||
231 | enum | ||
232 | { | ||
233 | newgame = 0, | ||
234 | options, | ||
235 | loadgame, | ||
236 | savegame, | ||
237 | readthis, | ||
238 | quitdoom, | ||
239 | main_end | ||
240 | } main_e; | ||
241 | |||
242 | menuitem_t MainMenu[]= | ||
243 | { | ||
244 | {1,"M_NGAME",M_NewGame,'n'}, | ||
245 | {1,"M_OPTION",M_Options,'o'}, | ||
246 | {1,"M_LOADG",M_LoadGame,'l'}, | ||
247 | {1,"M_SAVEG",M_SaveGame,'s'}, | ||
248 | // Another hickup with Special edition. | ||
249 | {1,"M_RDTHIS",M_ReadThis,'r'}, | ||
250 | {1,"M_QUITG",M_QuitDOOM,'q'} | ||
251 | }; | ||
252 | |||
253 | menu_t MainDef = | ||
254 | { | ||
255 | main_end, | ||
256 | NULL, | ||
257 | MainMenu, | ||
258 | M_DrawMainMenu, | ||
259 | 97,64, | ||
260 | 0 | ||
261 | }; | ||
262 | |||
263 | |||
264 | // | ||
265 | // EPISODE SELECT | ||
266 | // | ||
267 | enum | ||
268 | { | ||
269 | ep1, | ||
270 | ep2, | ||
271 | ep3, | ||
272 | ep4, | ||
273 | ep_end | ||
274 | } episodes_e; | ||
275 | |||
276 | menuitem_t EpisodeMenu[]= | ||
277 | { | ||
278 | {1,"M_EPI1", M_Episode,'k'}, | ||
279 | {1,"M_EPI2", M_Episode,'t'}, | ||
280 | {1,"M_EPI3", M_Episode,'i'}, | ||
281 | {1,"M_EPI4", M_Episode,'t'} | ||
282 | }; | ||
283 | |||
284 | menu_t EpiDef = | ||
285 | { | ||
286 | ep_end, // # of menu items | ||
287 | &MainDef, // previous menu | ||
288 | EpisodeMenu, // menuitem_t -> | ||
289 | M_DrawEpisode, // drawing routine -> | ||
290 | 48,63, // x,y | ||
291 | ep1 // lastOn | ||
292 | }; | ||
293 | |||
294 | // | ||
295 | // NEW GAME | ||
296 | // | ||
297 | enum | ||
298 | { | ||
299 | killthings, | ||
300 | toorough, | ||
301 | hurtme, | ||
302 | violence, | ||
303 | nightmare, | ||
304 | newg_end | ||
305 | } newgame_e; | ||
306 | |||
307 | menuitem_t NewGameMenu[]= | ||
308 | { | ||
309 | {1,"M_JKILL", M_ChooseSkill, 'i'}, | ||
310 | {1,"M_ROUGH", M_ChooseSkill, 'h'}, | ||
311 | {1,"M_HURT", M_ChooseSkill, 'h'}, | ||
312 | {1,"M_ULTRA", M_ChooseSkill, 'u'}, | ||
313 | {1,"M_NMARE", M_ChooseSkill, 'n'} | ||
314 | }; | ||
315 | |||
316 | menu_t NewDef = | ||
317 | { | ||
318 | newg_end, // # of menu items | ||
319 | &EpiDef, // previous menu | ||
320 | NewGameMenu, // menuitem_t -> | ||
321 | M_DrawNewGame, // drawing routine -> | ||
322 | 48,63, // x,y | ||
323 | hurtme // lastOn | ||
324 | }; | ||
325 | |||
326 | |||
327 | |||
328 | // | ||
329 | // OPTIONS MENU | ||
330 | // | ||
331 | enum | ||
332 | { | ||
333 | endgame, | ||
334 | messages, | ||
335 | scrnsize, | ||
336 | option_empty1, | ||
337 | gamasens, | ||
338 | option_empty2, | ||
339 | soundvol, | ||
340 | opt_end | ||
341 | } options_e; | ||
342 | |||
343 | menuitem_t OptionsMenu[]= | ||
344 | { | ||
345 | {1,"M_ENDGAM", M_EndGame,'e'}, | ||
346 | {1,"M_MESSG", M_ChangeMessages,'m'}, | ||
347 | {2,"M_SCRNSZ", M_SizeDisplay,'s'}, | ||
348 | {-1,"",0,0}, | ||
349 | {2,"M_MSENS", M_ChangeSensitivity,'m'}, | ||
350 | {-1,"",0,0}, | ||
351 | {1,"M_SVOL", M_Sound,'s'} | ||
352 | }; | ||
353 | |||
354 | menu_t OptionsDef = | ||
355 | { | ||
356 | opt_end, | ||
357 | &MainDef, | ||
358 | OptionsMenu, | ||
359 | M_DrawOptions, | ||
360 | 60,37, | ||
361 | 0 | ||
362 | }; | ||
363 | |||
364 | // | ||
365 | // Read This! MENU 1 & 2 | ||
366 | // | ||
367 | enum | ||
368 | { | ||
369 | rdthsempty1, | ||
370 | read1_end | ||
371 | } read_e; | ||
372 | |||
373 | menuitem_t ReadMenu1[] = | ||
374 | { | ||
375 | {1,"",M_ReadThis2,0} | ||
376 | }; | ||
377 | |||
378 | menu_t ReadDef1 = | ||
379 | { | ||
380 | read1_end, | ||
381 | &MainDef, | ||
382 | ReadMenu1, | ||
383 | M_DrawReadThis1, | ||
384 | 280,185, | ||
385 | 0 | ||
386 | }; | ||
387 | |||
388 | enum | ||
389 | { | ||
390 | rdthsempty2, | ||
391 | read2_end | ||
392 | } read_e2; | ||
393 | |||
394 | menuitem_t ReadMenu2[]= | ||
395 | { | ||
396 | {1,"",M_FinishReadThis,0} | ||
397 | }; | ||
398 | |||
399 | menu_t ReadDef2 = | ||
400 | { | ||
401 | read2_end, | ||
402 | &ReadDef1, | ||
403 | ReadMenu2, | ||
404 | M_DrawReadThis2, | ||
405 | 330,175, | ||
406 | 0 | ||
407 | }; | ||
408 | |||
409 | // | ||
410 | // SOUND VOLUME MENU | ||
411 | // | ||
412 | enum | ||
413 | { | ||
414 | sfx_vol, | ||
415 | sfx_empty1, | ||
416 | music_vol, | ||
417 | sfx_empty2, | ||
418 | system_vol, | ||
419 | sfx_empty3, | ||
420 | sound_end | ||
421 | } sound_e; | ||
422 | |||
423 | menuitem_t SoundMenu[]= | ||
424 | { | ||
425 | {2,"M_SFXVOL",M_SfxVol,'s'}, | ||
426 | {-1,"",0,0}, //ROCKBOX | ||
427 | {2,"M_MUSVOL",M_MusicVol,'m'}, | ||
428 | {-1,"",0,0}, //ROCKBOX | ||
429 | {2,"M_MUSVOL",M_SystemVol,'z'}, | ||
430 | {-1,"",0,0} //ROCKBOX | ||
431 | }; | ||
432 | |||
433 | menu_t SoundDef = | ||
434 | { | ||
435 | sound_end, | ||
436 | &OptionsDef, | ||
437 | SoundMenu, | ||
438 | M_DrawSound, | ||
439 | 80,64, | ||
440 | 0 | ||
441 | }; | ||
442 | |||
443 | // | ||
444 | // LOAD GAME MENU | ||
445 | // | ||
446 | enum | ||
447 | { | ||
448 | load1, | ||
449 | load2, | ||
450 | load3, | ||
451 | load4, | ||
452 | load5, | ||
453 | load6, | ||
454 | load_end | ||
455 | } load_e; | ||
456 | |||
457 | menuitem_t LoadMenu[]= | ||
458 | { | ||
459 | {1,"", M_LoadSelect,'1'}, | ||
460 | {1,"", M_LoadSelect,'2'}, | ||
461 | {1,"", M_LoadSelect,'3'}, | ||
462 | {1,"", M_LoadSelect,'4'}, | ||
463 | {1,"", M_LoadSelect,'5'}, | ||
464 | {1,"", M_LoadSelect,'6'} | ||
465 | }; | ||
466 | |||
467 | menu_t LoadDef = | ||
468 | { | ||
469 | load_end, | ||
470 | &MainDef, | ||
471 | LoadMenu, | ||
472 | M_DrawLoad, | ||
473 | 80,54, | ||
474 | 0 | ||
475 | }; | ||
476 | |||
477 | // | ||
478 | // SAVE GAME MENU | ||
479 | // | ||
480 | menuitem_t SaveMenu[]= | ||
481 | { | ||
482 | {1,"", M_SaveSelect,'1'}, | ||
483 | {1,"", M_SaveSelect,'2'}, | ||
484 | {1,"", M_SaveSelect,'3'}, | ||
485 | {1,"", M_SaveSelect,'4'}, | ||
486 | {1,"", M_SaveSelect,'5'}, | ||
487 | {1,"", M_SaveSelect,'6'} | ||
488 | }; | ||
489 | |||
490 | menu_t SaveDef = | ||
491 | { | ||
492 | load_end, | ||
493 | &MainDef, | ||
494 | SaveMenu, | ||
495 | M_DrawSave, | ||
496 | 80,54, | ||
497 | 0 | ||
498 | }; | ||
499 | |||
500 | |||
501 | // | ||
502 | // M_ReadSaveStrings | ||
503 | // read the strings from the savegame files | ||
504 | // | ||
505 | void M_ReadSaveStrings(void) | ||
506 | { | ||
507 | int handle; | ||
508 | int count; | ||
509 | int i; | ||
510 | char name[256]; | ||
511 | |||
512 | for (i = 0;i < load_end;i++) | ||
513 | { | ||
514 | if (M_CheckParm("-cdrom")) | ||
515 | snprintf(name,sizeof(name),"c:\\doomdata\\"SAVEGAMENAME"%d.dsg",i); | ||
516 | else | ||
517 | snprintf(name,sizeof(name),SAVEGAMENAME"%d.dsg",i); | ||
518 | |||
519 | handle = open (name, O_RDONLY | 0); | ||
520 | if (handle == -1) | ||
521 | { | ||
522 | strcpy(&savegamestrings[i][0],EMPTYSTRING); | ||
523 | LoadMenu[i].status = 0; | ||
524 | continue; | ||
525 | } | ||
526 | count = read (handle, &savegamestrings[i], SAVESTRINGSIZE); | ||
527 | close (handle); | ||
528 | LoadMenu[i].status = 1; | ||
529 | } | ||
530 | } | ||
531 | |||
532 | #define LOADGRAPHIC_Y 8 | ||
533 | // | ||
534 | // M_LoadGame & Cie. | ||
535 | // | ||
536 | void M_DrawLoad(void) | ||
537 | { | ||
538 | int i; | ||
539 | |||
540 | V_DrawNamePatch(72 ,LOADGRAPHIC_Y, 0, "M_LOADG", CR_DEFAULT, VPT_STRETCH); | ||
541 | for (i = 0;i < load_end; i++) | ||
542 | { | ||
543 | M_DrawSaveLoadBorder(LoadDef.x,LoadDef.y+LINEHEIGHT*i); | ||
544 | M_WriteText(LoadDef.x,LoadDef.y+LINEHEIGHT*i,savegamestrings[i]); | ||
545 | } | ||
546 | } | ||
547 | |||
548 | |||
549 | |||
550 | // | ||
551 | // Draw border for the savegame description | ||
552 | // | ||
553 | void M_DrawSaveLoadBorder(int x,int y) | ||
554 | { | ||
555 | int i; | ||
556 | |||
557 | V_DrawNamePatch(x-8, y+7, 0, "M_LSLEFT", CR_DEFAULT, VPT_STRETCH); | ||
558 | for (i = 0;i < 24;i++) | ||
559 | { | ||
560 | V_DrawNamePatch(x, y+7, 0, "M_LSCNTR", CR_DEFAULT, VPT_STRETCH); | ||
561 | x += 8; | ||
562 | } | ||
563 | V_DrawNamePatch(x, y+7, 0, "M_LSRGHT", CR_DEFAULT, VPT_STRETCH); | ||
564 | } | ||
565 | |||
566 | |||
567 | |||
568 | // | ||
569 | // User wants to load this game | ||
570 | // | ||
571 | void M_LoadSelect(int choice) | ||
572 | { | ||
573 | char name[256]; | ||
574 | |||
575 | if (M_CheckParm("-cdrom")) | ||
576 | snprintf(name,sizeof(name),"c:\\doomdata\\"SAVEGAMENAME"%d.dsg",choice); | ||
577 | else | ||
578 | snprintf(name,sizeof(name),SAVEGAMENAME"%d.dsg",choice); | ||
579 | G_LoadGame (choice, false); | ||
580 | M_ClearMenus (); | ||
581 | } | ||
582 | |||
583 | // | ||
584 | // Selected from DOOM menu | ||
585 | // | ||
586 | void M_LoadGame (int choice) | ||
587 | { | ||
588 | (void)choice; | ||
589 | if (netgame) | ||
590 | { | ||
591 | M_StartMessage(LOADNET,NULL,false); | ||
592 | return; | ||
593 | } | ||
594 | |||
595 | M_SetupNextMenu(&LoadDef); | ||
596 | M_ReadSaveStrings(); | ||
597 | } | ||
598 | |||
599 | |||
600 | // | ||
601 | // M_SaveGame & Cie. | ||
602 | // | ||
603 | void M_DrawSave(void) | ||
604 | { | ||
605 | int i; | ||
606 | |||
607 | V_DrawNamePatch(72, LOADGRAPHIC_Y, 0, "M_SAVEG", CR_DEFAULT, VPT_STRETCH); | ||
608 | for (i = 0;i < load_end; i++) | ||
609 | { | ||
610 | M_DrawSaveLoadBorder(LoadDef.x,LoadDef.y+LINEHEIGHT*i); | ||
611 | M_WriteText(LoadDef.x,LoadDef.y+LINEHEIGHT*i,savegamestrings[i]); | ||
612 | } | ||
613 | |||
614 | if (saveStringEnter) | ||
615 | { | ||
616 | i = M_StringWidth(savegamestrings[saveSlot]); | ||
617 | M_WriteText(LoadDef.x + i,LoadDef.y+LINEHEIGHT*saveSlot,"_"); | ||
618 | } | ||
619 | } | ||
620 | |||
621 | // | ||
622 | // M_Responder calls this when user is finished | ||
623 | // | ||
624 | void M_DoSave(int slot) | ||
625 | { | ||
626 | G_SaveGame (slot,savegamestrings[slot]); | ||
627 | M_ClearMenus (); | ||
628 | |||
629 | // PICK QUICKSAVE SLOT YET? | ||
630 | if (quickSaveSlot == -2) | ||
631 | quickSaveSlot = slot; | ||
632 | } | ||
633 | |||
634 | // | ||
635 | // User wants to save. Start string input for M_Responder | ||
636 | // | ||
637 | void M_SaveSelect(int choice) | ||
638 | { | ||
639 | // we are going to be intercepting all chars | ||
640 | saveStringEnter = 1; | ||
641 | |||
642 | saveSlot = choice; | ||
643 | snprintf(savegamestrings[choice], sizeof(savegamestrings[choice]), "Mysave%d", choice); | ||
644 | // strcpy(saveOldString,savegamestrings[choice]); | ||
645 | if (!strcmp(savegamestrings[choice],EMPTYSTRING)) | ||
646 | savegamestrings[choice][0] = 0; | ||
647 | saveCharIndex = strlen(savegamestrings[choice]); | ||
648 | } | ||
649 | |||
650 | // | ||
651 | // Selected from DOOM menu | ||
652 | // | ||
653 | void M_SaveGame (int choice) | ||
654 | { | ||
655 | (void)choice; | ||
656 | if (!usergame) | ||
657 | { | ||
658 | M_StartMessage(SAVEDEAD,NULL,false); | ||
659 | return; | ||
660 | } | ||
661 | |||
662 | if (gamestate != GS_LEVEL) | ||
663 | return; | ||
664 | |||
665 | M_SetupNextMenu(&SaveDef); | ||
666 | M_ReadSaveStrings(); | ||
667 | } | ||
668 | |||
669 | |||
670 | |||
671 | // | ||
672 | // M_QuickSave | ||
673 | // | ||
674 | char tempstring[80]; | ||
675 | |||
676 | void M_QuickSaveResponse(int ch) | ||
677 | { | ||
678 | if (ch == 'y') | ||
679 | { | ||
680 | M_DoSave(quickSaveSlot); | ||
681 | |||
682 | S_StartSound(NULL,sfx_swtchx); | ||
683 | |||
684 | } | ||
685 | } | ||
686 | |||
687 | void M_QuickSave(void) | ||
688 | { | ||
689 | if (!usergame) | ||
690 | { | ||
691 | S_StartSound(NULL,sfx_oof); | ||
692 | return; | ||
693 | } | ||
694 | |||
695 | if (gamestate != GS_LEVEL) | ||
696 | return; | ||
697 | |||
698 | if (quickSaveSlot < 0) | ||
699 | { | ||
700 | M_StartControlPanel(); | ||
701 | M_ReadSaveStrings(); | ||
702 | M_SetupNextMenu(&SaveDef); | ||
703 | quickSaveSlot = -2; // means to pick a slot now | ||
704 | return; | ||
705 | } | ||
706 | snprintf(tempstring,sizeof(tempstring),QSPROMPT,savegamestrings[quickSaveSlot]); | ||
707 | M_StartMessage(tempstring,M_QuickSaveResponse,true); | ||
708 | } | ||
709 | |||
710 | |||
711 | |||
712 | // | ||
713 | // M_QuickLoad | ||
714 | // | ||
715 | void M_QuickLoadResponse(int ch) | ||
716 | { | ||
717 | if (ch == 'y') | ||
718 | { | ||
719 | M_LoadSelect(quickSaveSlot); | ||
720 | S_StartSound(NULL,sfx_swtchx); | ||
721 | } | ||
722 | } | ||
723 | |||
724 | |||
725 | void M_QuickLoad(void) | ||
726 | { | ||
727 | if (netgame) | ||
728 | { | ||
729 | M_StartMessage(QLOADNET,NULL,false); | ||
730 | return; | ||
731 | } | ||
732 | |||
733 | if (quickSaveSlot < 0) | ||
734 | { | ||
735 | M_StartMessage(QSAVESPOT,NULL,false); | ||
736 | return; | ||
737 | } | ||
738 | snprintf(tempstring, sizeof(tempstring), QLPROMPT,savegamestrings[quickSaveSlot]); | ||
739 | M_StartMessage(tempstring,M_QuickLoadResponse,true); | ||
740 | } | ||
741 | |||
742 | |||
743 | |||
744 | |||
745 | // | ||
746 | // Read This Menus | ||
747 | // Had a "quick hack to fix romero bug" | ||
748 | // | ||
749 | void M_DrawReadThis1(void) | ||
750 | { | ||
751 | inhelpscreens = true; | ||
752 | switch ( gamemode ) | ||
753 | { | ||
754 | case commercial: | ||
755 | V_DrawNamePatch(0, 0, 0, "HELP", CR_DEFAULT, VPT_STRETCH); | ||
756 | break; | ||
757 | case shareware: | ||
758 | case registered: | ||
759 | case retail: | ||
760 | V_DrawNamePatch(0, 0, 0, "HELP1", CR_DEFAULT, VPT_STRETCH); | ||
761 | break; | ||
762 | default: | ||
763 | break; | ||
764 | } | ||
765 | return; | ||
766 | } | ||
767 | |||
768 | |||
769 | |||
770 | // | ||
771 | // Read This Menus - optional second page. | ||
772 | // | ||
773 | void M_DrawReadThis2(void) | ||
774 | { | ||
775 | inhelpscreens = true; | ||
776 | switch ( gamemode ) | ||
777 | { | ||
778 | case retail: | ||
779 | case commercial: | ||
780 | // This hack keeps us from having to change menus. | ||
781 | V_DrawNamePatch(0, 0, 0, "CREDIT", CR_DEFAULT, VPT_STRETCH); | ||
782 | break; | ||
783 | case shareware: | ||
784 | case registered: | ||
785 | V_DrawNamePatch(0, 0, 0, "HELP2", CR_DEFAULT, VPT_STRETCH); | ||
786 | break; | ||
787 | default: | ||
788 | break; | ||
789 | } | ||
790 | return; | ||
791 | } | ||
792 | |||
793 | |||
794 | // | ||
795 | // Change Sfx & Music volumes | ||
796 | // | ||
797 | void M_DrawSound(void) | ||
798 | { | ||
799 | int sysmax=(rb->sound_max(SOUND_VOLUME)-rb->sound_min(SOUND_VOLUME)); | ||
800 | V_DrawNamePatch(60, 38, 0, "M_SVOL", CR_DEFAULT, VPT_STRETCH); | ||
801 | |||
802 | M_DrawThermo(SoundDef.x,SoundDef.y+LINEHEIGHT*(sfx_vol+1), | ||
803 | 16,snd_SfxVolume); | ||
804 | |||
805 | M_DrawThermo(SoundDef.x,SoundDef.y+LINEHEIGHT*(music_vol+1), | ||
806 | 16,snd_MusicVolume); | ||
807 | |||
808 | M_DrawThermo(SoundDef.x,SoundDef.y+LINEHEIGHT*(system_vol+1), | ||
809 | 16,(sysmax+systemvol)/5); | ||
810 | } | ||
811 | |||
812 | void M_Sound(int choice) | ||
813 | { | ||
814 | (void) choice; | ||
815 | M_SetupNextMenu(&SoundDef); | ||
816 | } | ||
817 | |||
818 | void M_SfxVol(int choice) | ||
819 | { | ||
820 | switch(choice) | ||
821 | { | ||
822 | case 0: | ||
823 | if (snd_SfxVolume) | ||
824 | snd_SfxVolume--; | ||
825 | break; | ||
826 | case 1: | ||
827 | if (snd_SfxVolume < 15) | ||
828 | snd_SfxVolume++; | ||
829 | break; | ||
830 | } | ||
831 | |||
832 | S_SetSfxVolume(snd_SfxVolume /* *8 */); | ||
833 | } | ||
834 | |||
835 | void M_MusicVol(int choice) | ||
836 | { | ||
837 | switch(choice) | ||
838 | { | ||
839 | case 0: | ||
840 | if (snd_MusicVolume) | ||
841 | snd_MusicVolume--; | ||
842 | break; | ||
843 | case 1: | ||
844 | if (snd_MusicVolume < 15) | ||
845 | snd_MusicVolume++; | ||
846 | break; | ||
847 | } | ||
848 | |||
849 | S_SetMusicVolume(snd_MusicVolume /* *8 */); | ||
850 | } | ||
851 | |||
852 | void M_SystemVol(int choice) | ||
853 | { | ||
854 | switch(choice) | ||
855 | { | ||
856 | case 0: | ||
857 | if (systemvol-5>rb->sound_min(SOUND_VOLUME)) | ||
858 | { | ||
859 | systemvol-=5; | ||
860 | rb->sound_set(SOUND_VOLUME, systemvol); | ||
861 | rb->global_settings->volume = systemvol; | ||
862 | } | ||
863 | break; | ||
864 | case 1: | ||
865 | if (systemvol+5<rb->sound_max(SOUND_VOLUME)) | ||
866 | { | ||
867 | systemvol+=5; | ||
868 | rb->sound_set(SOUND_VOLUME, systemvol); | ||
869 | rb->global_settings->volume = systemvol; | ||
870 | } | ||
871 | break; | ||
872 | } | ||
873 | } | ||
874 | |||
875 | // | ||
876 | // M_DrawMainMenu | ||
877 | // | ||
878 | void M_DrawMainMenu(void) | ||
879 | { | ||
880 | V_DrawNamePatch(94, 2, 0, "M_DOOM", CR_DEFAULT, VPT_STRETCH); | ||
881 | } | ||
882 | |||
883 | |||
884 | |||
885 | |||
886 | // | ||
887 | // M_NewGame | ||
888 | // | ||
889 | void M_DrawNewGame(void) | ||
890 | { | ||
891 | // CPhipps - patch drawing updated | ||
892 | V_DrawNamePatch(96, 14, 0, "M_NEWG", CR_DEFAULT, VPT_STRETCH); | ||
893 | V_DrawNamePatch(54, 38, 0, "M_SKILL",CR_DEFAULT, VPT_STRETCH); | ||
894 | } | ||
895 | |||
896 | void M_NewGame(int choice) | ||
897 | { | ||
898 | (void) choice; | ||
899 | if (netgame && !demoplayback) | ||
900 | { | ||
901 | M_StartMessage(NEWGAME,NULL,false); | ||
902 | return; | ||
903 | } | ||
904 | |||
905 | if ( gamemode == commercial ) | ||
906 | M_SetupNextMenu(&NewDef); | ||
907 | else | ||
908 | M_SetupNextMenu(&EpiDef); | ||
909 | } | ||
910 | |||
911 | |||
912 | // | ||
913 | // M_Episode | ||
914 | // | ||
915 | int epi; | ||
916 | |||
917 | void M_DrawEpisode(void) | ||
918 | { | ||
919 | // CPhipps - patch drawing updated | ||
920 | V_DrawNamePatch(54, 38, 0, "M_EPISOD", CR_DEFAULT, VPT_STRETCH); | ||
921 | } | ||
922 | |||
923 | void M_VerifyNightmare(int ch) | ||
924 | { | ||
925 | if (ch != KEY_ENTER) | ||
926 | return; | ||
927 | |||
928 | G_DeferedInitNew(nightmare,epi+1,1); | ||
929 | M_ClearMenus (); | ||
930 | } | ||
931 | |||
932 | void M_ChooseSkill(int choice) | ||
933 | { | ||
934 | if (choice == nightmare) | ||
935 | { | ||
936 | M_StartMessage(NIGHTMARE,M_VerifyNightmare,true); | ||
937 | return; | ||
938 | } | ||
939 | |||
940 | //jff 3/24/98 remember last skill selected | ||
941 | // killough 10/98 moved to here | ||
942 | defaultskill = choice+1; | ||
943 | |||
944 | G_DeferedInitNew(choice,epi+1,1); | ||
945 | M_ClearMenus (); | ||
946 | } | ||
947 | |||
948 | void M_Episode(int choice) | ||
949 | { | ||
950 | if ( (gamemode == shareware) | ||
951 | && choice) | ||
952 | { | ||
953 | M_StartMessage(SWSTRING,NULL,false); | ||
954 | M_SetupNextMenu(&ReadDef1); | ||
955 | return; | ||
956 | } | ||
957 | |||
958 | // Yet another hack... | ||
959 | if ( (gamemode == registered) | ||
960 | && (choice > 2)) | ||
961 | { | ||
962 | /* Digita */ | ||
963 | // fprintf( stderr, | ||
964 | // "M_Episode: 4th episode requires UltimateDOOM\n"); | ||
965 | choice = 0; | ||
966 | } | ||
967 | |||
968 | epi = choice; | ||
969 | M_SetupNextMenu(&NewDef); | ||
970 | } | ||
971 | |||
972 | |||
973 | |||
974 | // | ||
975 | // M_Options | ||
976 | // | ||
977 | char detailNames[2][9] = {"M_GDHIGH","M_GDLOW"}; | ||
978 | char msgNames[2][9] = {"M_MSGOFF","M_MSGON"}; | ||
979 | |||
980 | |||
981 | void M_DrawOptions(void) | ||
982 | { | ||
983 | // CPhipps - patch drawing updated | ||
984 | V_DrawNamePatch(108, 15, 0, "M_OPTTTL", CR_DEFAULT, VPT_STRETCH); | ||
985 | |||
986 | V_DrawNamePatch(OptionsDef.x + 120, OptionsDef.y+LINEHEIGHT*messages, 0, | ||
987 | msgNames[showMessages], CR_DEFAULT, VPT_STRETCH); | ||
988 | |||
989 | M_DrawThermo(OptionsDef.x,OptionsDef.y+LINEHEIGHT*(gamasens+1), | ||
990 | 4,usegamma); | ||
991 | |||
992 | M_DrawThermo(OptionsDef.x,OptionsDef.y+LINEHEIGHT*(scrnsize+1), | ||
993 | 9,screenSize); | ||
994 | } | ||
995 | |||
996 | void M_Options(int choice) | ||
997 | { | ||
998 | (void)choice; | ||
999 | M_SetupNextMenu(&OptionsDef); | ||
1000 | } | ||
1001 | |||
1002 | |||
1003 | |||
1004 | // | ||
1005 | // Toggle messages on/off | ||
1006 | // | ||
1007 | void M_ChangeMessages(int choice) | ||
1008 | { | ||
1009 | // warning: unused parameter `int choice' | ||
1010 | choice = 0; | ||
1011 | showMessages = 1 - showMessages; | ||
1012 | |||
1013 | if (!showMessages) | ||
1014 | players[consoleplayer].message = MSGOFF; | ||
1015 | else | ||
1016 | players[consoleplayer].message = MSGON ; | ||
1017 | |||
1018 | message_dontfuckwithme = true; | ||
1019 | } | ||
1020 | |||
1021 | |||
1022 | // | ||
1023 | // M_EndGame | ||
1024 | // | ||
1025 | void M_EndGameResponse(int ch) | ||
1026 | { | ||
1027 | if (ch != KEY_ENTER) | ||
1028 | return; | ||
1029 | |||
1030 | // killough 5/26/98: make endgame quit if recording or playing back demo | ||
1031 | if (demorecording || singledemo) | ||
1032 | G_CheckDemoStatus(); | ||
1033 | |||
1034 | currentMenu->lastOn = itemOn; | ||
1035 | M_ClearMenus (); | ||
1036 | D_StartTitle (); | ||
1037 | } | ||
1038 | |||
1039 | void M_EndGame(int choice) | ||
1040 | { | ||
1041 | choice = 0; | ||
1042 | if (!usergame) | ||
1043 | { | ||
1044 | S_StartSound(NULL,sfx_oof); | ||
1045 | return; | ||
1046 | } | ||
1047 | |||
1048 | if (netgame) | ||
1049 | { | ||
1050 | M_StartMessage(NETEND,NULL,false); | ||
1051 | return; | ||
1052 | } | ||
1053 | |||
1054 | M_StartMessage(ENDGAME,M_EndGameResponse,true); | ||
1055 | } | ||
1056 | |||
1057 | |||
1058 | |||
1059 | |||
1060 | // | ||
1061 | // M_ReadThis | ||
1062 | // | ||
1063 | void M_ReadThis(int choice) | ||
1064 | { | ||
1065 | choice = 0; | ||
1066 | M_SetupNextMenu(&ReadDef1); | ||
1067 | } | ||
1068 | |||
1069 | void M_ReadThis2(int choice) | ||
1070 | { | ||
1071 | choice = 0; | ||
1072 | M_SetupNextMenu(&ReadDef2); | ||
1073 | } | ||
1074 | |||
1075 | void M_FinishReadThis(int choice) | ||
1076 | { | ||
1077 | choice = 0; | ||
1078 | M_SetupNextMenu(&MainDef); | ||
1079 | } | ||
1080 | |||
1081 | |||
1082 | |||
1083 | |||
1084 | // | ||
1085 | // M_QuitDOOM | ||
1086 | // | ||
1087 | int quitsounds[8] = | ||
1088 | { | ||
1089 | sfx_pldeth, | ||
1090 | sfx_dmpain, | ||
1091 | sfx_popain, | ||
1092 | sfx_slop, | ||
1093 | sfx_telept, | ||
1094 | sfx_posit1, | ||
1095 | sfx_posit3, | ||
1096 | sfx_sgtatk | ||
1097 | }; | ||
1098 | |||
1099 | int quitsounds2[8] = | ||
1100 | { | ||
1101 | sfx_vilact, | ||
1102 | sfx_getpow, | ||
1103 | sfx_boscub, | ||
1104 | sfx_slop, | ||
1105 | sfx_skeswg, | ||
1106 | sfx_kntdth, | ||
1107 | sfx_bspact, | ||
1108 | sfx_sgtatk | ||
1109 | }; | ||
1110 | |||
1111 | |||
1112 | |||
1113 | void M_QuitResponse(int ch) | ||
1114 | { | ||
1115 | if (ch != KEY_ENTER) | ||
1116 | return; | ||
1117 | if (!netgame) | ||
1118 | { | ||
1119 | if (gamemode == commercial) | ||
1120 | S_StartSound(NULL,quitsounds2[(gametic>>2)&7]); | ||
1121 | else | ||
1122 | S_StartSound(NULL,quitsounds[(gametic>>2)&7]); | ||
1123 | I_WaitVBL(105); | ||
1124 | } | ||
1125 | I_Quit (); | ||
1126 | } | ||
1127 | |||
1128 | |||
1129 | |||
1130 | |||
1131 | void M_QuitDOOM(int choice) | ||
1132 | { | ||
1133 | (void)choice; | ||
1134 | // We pick index 0 which is language sensitive, | ||
1135 | // or one at random, between 1 and maximum number. | ||
1136 | if (language != english ) | ||
1137 | snprintf(endstring,sizeof(endstring),"%s\n\n"DOSY, endmsg[0] ); | ||
1138 | else | ||
1139 | snprintf(endstring,sizeof(endstring),"%s\n\n%s", endmsg[gametic%(NUM_QUITMESSAGES-1)+1], DOSY); | ||
1140 | |||
1141 | M_StartMessage(endstring,M_QuitResponse,true); | ||
1142 | } | ||
1143 | |||
1144 | |||
1145 | |||
1146 | |||
1147 | void M_ChangeSensitivity(int choice) | ||
1148 | { | ||
1149 | switch(choice) | ||
1150 | { | ||
1151 | case 0: | ||
1152 | if (usegamma) | ||
1153 | usegamma--; | ||
1154 | break; | ||
1155 | case 1: | ||
1156 | if (usegamma < 4) | ||
1157 | usegamma++; | ||
1158 | break; | ||
1159 | } | ||
1160 | V_SetPalette (0); | ||
1161 | } | ||
1162 | |||
1163 | void M_SizeDisplay(int choice) | ||
1164 | { | ||
1165 | switch(choice) | ||
1166 | { | ||
1167 | case 0: | ||
1168 | if (screenSize > 0) | ||
1169 | { | ||
1170 | screenblocks--; | ||
1171 | screenSize--; | ||
1172 | } | ||
1173 | break; | ||
1174 | case 1: | ||
1175 | if (screenSize < 8) | ||
1176 | { | ||
1177 | screenblocks++; | ||
1178 | screenSize++; | ||
1179 | } | ||
1180 | break; | ||
1181 | } | ||
1182 | |||
1183 | |||
1184 | R_SetViewSize (screenblocks); | ||
1185 | } | ||
1186 | |||
1187 | |||
1188 | |||
1189 | |||
1190 | // | ||
1191 | // Menu Functions | ||
1192 | // | ||
1193 | void | ||
1194 | M_DrawThermo | ||
1195 | ( int x, | ||
1196 | int y, | ||
1197 | int thermWidth, | ||
1198 | int thermDot ) | ||
1199 | { | ||
1200 | int xx; | ||
1201 | int i; | ||
1202 | |||
1203 | xx = x; | ||
1204 | V_DrawNamePatch(xx, y, 0, "M_THERML", CR_DEFAULT, VPT_STRETCH); | ||
1205 | xx += 8; | ||
1206 | for (i=0;i<thermWidth;i++) | ||
1207 | { | ||
1208 | V_DrawNamePatch(xx, y, 0, "M_THERMM", CR_DEFAULT, VPT_STRETCH); | ||
1209 | xx += 8; | ||
1210 | } | ||
1211 | V_DrawNamePatch(xx, y, 0, "M_THERMR", CR_DEFAULT, VPT_STRETCH); | ||
1212 | V_DrawNamePatch((x+8)+thermDot*8,y,0,"M_THERMO",CR_DEFAULT,VPT_STRETCH); | ||
1213 | } | ||
1214 | |||
1215 | |||
1216 | |||
1217 | void | ||
1218 | M_DrawEmptyCell | ||
1219 | ( menu_t* menu, | ||
1220 | int item ) | ||
1221 | { | ||
1222 | // CPhipps - patch drawing updated | ||
1223 | V_DrawNamePatch(menu->x - 10, menu->y+item*LINEHEIGHT - 1, 0, | ||
1224 | "M_CELL1", CR_DEFAULT, VPT_STRETCH); | ||
1225 | } | ||
1226 | |||
1227 | void | ||
1228 | M_DrawSelCell | ||
1229 | ( menu_t* menu, | ||
1230 | int item ) | ||
1231 | { | ||
1232 | // CPhipps - patch drawing updated | ||
1233 | V_DrawNamePatch(menu->x - 10, menu->y+item*LINEHEIGHT - 1, 0, | ||
1234 | "M_CELL2", CR_DEFAULT, VPT_STRETCH); | ||
1235 | } | ||
1236 | |||
1237 | |||
1238 | void | ||
1239 | M_StartMessage | ||
1240 | ( char* string, | ||
1241 | void* routine, | ||
1242 | boolean input ) | ||
1243 | { | ||
1244 | messageLastMenuActive = menuactive; | ||
1245 | messageToPrint = 1; | ||
1246 | messageString = string; | ||
1247 | messageRoutine = routine; | ||
1248 | messageNeedsInput = input; | ||
1249 | menuactive = true; | ||
1250 | return; | ||
1251 | } | ||
1252 | |||
1253 | |||
1254 | |||
1255 | void M_StopMessage(void) | ||
1256 | { | ||
1257 | menuactive = messageLastMenuActive; | ||
1258 | messageToPrint = 0; | ||
1259 | } | ||
1260 | |||
1261 | |||
1262 | |||
1263 | // | ||
1264 | // Find string width from hu_font chars | ||
1265 | // | ||
1266 | int M_StringWidth(const char* string) | ||
1267 | { | ||
1268 | int i, c, w = 0; | ||
1269 | for (i = 0;(size_t)i < strlen(string);i++) | ||
1270 | w += (c = toupper(string[i]) - HU_FONTSTART) < 0 || c >= HU_FONTSIZE ? | ||
1271 | 4 : SHORT(hu_font[c].width); | ||
1272 | return w; | ||
1273 | } | ||
1274 | |||
1275 | // | ||
1276 | // Find string height from hu_font chars | ||
1277 | // | ||
1278 | |||
1279 | int M_StringHeight(const char* string) | ||
1280 | { | ||
1281 | int i, h, height = h = SHORT(hu_font[0].height); | ||
1282 | for (i = 0;string[i];i++) // killough 1/31/98 | ||
1283 | if (string[i] == '\n') | ||
1284 | h += height; | ||
1285 | return h; | ||
1286 | } | ||
1287 | |||
1288 | |||
1289 | // | ||
1290 | // Write a string using the hu_font | ||
1291 | // | ||
1292 | void | ||
1293 | M_WriteText | ||
1294 | ( int x, | ||
1295 | int y, | ||
1296 | char* string) | ||
1297 | { | ||
1298 | int w; | ||
1299 | char* ch; | ||
1300 | int c; | ||
1301 | int cx; | ||
1302 | int cy; | ||
1303 | |||
1304 | |||
1305 | ch = string; | ||
1306 | cx = x; | ||
1307 | cy = y; | ||
1308 | |||
1309 | while(1) | ||
1310 | { | ||
1311 | c = *ch++; | ||
1312 | if (!c) | ||
1313 | break; | ||
1314 | if (c == '\n') | ||
1315 | { | ||
1316 | cx = x; | ||
1317 | cy += 12; | ||
1318 | continue; | ||
1319 | } | ||
1320 | |||
1321 | c = toupper(c) - HU_FONTSTART; | ||
1322 | if (c < 0 || c>= HU_FONTSIZE) | ||
1323 | { | ||
1324 | cx += 4; | ||
1325 | continue; | ||
1326 | } | ||
1327 | |||
1328 | w = SHORT (hu_font[c].width); | ||
1329 | if (cx+w > SCREENWIDTH) | ||
1330 | break; | ||
1331 | // proff/nicolas 09/20/98 -- changed for hi-res | ||
1332 | // CPhipps - patch drawing updated | ||
1333 | V_DrawNumPatch(cx, cy, 0, hu_font[c].lumpnum, CR_DEFAULT, VPT_STRETCH); | ||
1334 | cx+=w; | ||
1335 | } | ||
1336 | } | ||
1337 | |||
1338 | |||
1339 | |||
1340 | // | ||
1341 | // CONTROL PANEL | ||
1342 | // | ||
1343 | |||
1344 | // | ||
1345 | // M_Responder | ||
1346 | // | ||
1347 | boolean M_Responder (event_t* ev) | ||
1348 | { | ||
1349 | int ch; | ||
1350 | int i; | ||
1351 | // static int joywait = 0; | ||
1352 | // static int mousewait = 0; | ||
1353 | // static int mousey = 0; | ||
1354 | // static int lasty = 0; | ||
1355 | // static int mousex = 0; | ||
1356 | // static int lastx = 0; | ||
1357 | |||
1358 | ch = -1; | ||
1359 | |||
1360 | // Process joystick input | ||
1361 | |||
1362 | /* if (ev->type == ev_joystick && joywait < I_GetTime()) | ||
1363 | { | ||
1364 | if (ev->data3 == -1) | ||
1365 | { | ||
1366 | ch = KEY_UPARROW; | ||
1367 | joywait = I_GetTime() + 5; | ||
1368 | } | ||
1369 | else if (ev->data3 == 1) | ||
1370 | { | ||
1371 | ch = KEY_DOWNARROW; | ||
1372 | joywait = I_GetTime() + 5; | ||
1373 | } | ||
1374 | |||
1375 | if (ev->data2 == -1) | ||
1376 | { | ||
1377 | ch = KEY_LEFTARROW; | ||
1378 | joywait = I_GetTime() + 2; | ||
1379 | } | ||
1380 | else if (ev->data2 == 1) | ||
1381 | { | ||
1382 | ch = KEY_RIGHTARROW; | ||
1383 | joywait = I_GetTime() + 2; | ||
1384 | } | ||
1385 | |||
1386 | if (ev->data1&1) | ||
1387 | { | ||
1388 | ch = KEY_ENTER; | ||
1389 | joywait = I_GetTime() + 5; | ||
1390 | } | ||
1391 | if (ev->data1&2) | ||
1392 | { | ||
1393 | ch = KEY_BACKSPACE; | ||
1394 | joywait = I_GetTime() + 5; | ||
1395 | } | ||
1396 | } | ||
1397 | else | ||
1398 | { | ||
1399 | // Process mouse input | ||
1400 | if (ev->type == ev_mouse && mousewait < I_GetTime()) | ||
1401 | { | ||
1402 | mousey += ev->data3; | ||
1403 | if (mousey < lasty-30) | ||
1404 | { | ||
1405 | ch = KEY_DOWNARROW; | ||
1406 | mousewait = I_GetTime() + 5; | ||
1407 | mousey = lasty -= 30; | ||
1408 | } | ||
1409 | else if (mousey > lasty+30) | ||
1410 | { | ||
1411 | ch = KEY_UPARROW; | ||
1412 | mousewait = I_GetTime() + 5; | ||
1413 | mousey = lasty += 30; | ||
1414 | } | ||
1415 | |||
1416 | mousex += ev->data2; | ||
1417 | if (mousex < lastx-30) | ||
1418 | { | ||
1419 | ch = KEY_LEFTARROW; | ||
1420 | mousewait = I_GetTime() + 5; | ||
1421 | mousex = lastx -= 30; | ||
1422 | } | ||
1423 | else if (mousex > lastx+30) | ||
1424 | { | ||
1425 | ch = KEY_RIGHTARROW; | ||
1426 | mousewait = I_GetTime() + 5; | ||
1427 | mousex = lastx += 30; | ||
1428 | } | ||
1429 | |||
1430 | if (ev->data1&1) | ||
1431 | { | ||
1432 | ch = KEY_ENTER; | ||
1433 | mousewait = I_GetTime() + 15; | ||
1434 | } | ||
1435 | |||
1436 | if (ev->data1&2) | ||
1437 | { | ||
1438 | ch = KEY_BACKSPACE; | ||
1439 | mousewait = I_GetTime() + 15; | ||
1440 | } | ||
1441 | } | ||
1442 | else */if (ev->type == ev_keydown) | ||
1443 | { | ||
1444 | ch = ev->data1; | ||
1445 | } | ||
1446 | // } | ||
1447 | |||
1448 | if (ch == -1) | ||
1449 | return false; | ||
1450 | |||
1451 | |||
1452 | // Save Game string input | ||
1453 | if (saveStringEnter) | ||
1454 | { | ||
1455 | switch(ch) | ||
1456 | { | ||
1457 | case KEY_BACKSPACE: | ||
1458 | if (saveCharIndex > 0) | ||
1459 | { | ||
1460 | saveCharIndex--; | ||
1461 | savegamestrings[saveSlot][saveCharIndex] = 0; | ||
1462 | } | ||
1463 | break; | ||
1464 | |||
1465 | case KEY_ESCAPE: | ||
1466 | saveStringEnter = 0; | ||
1467 | strcpy(&savegamestrings[saveSlot][0],saveOldString); | ||
1468 | break; | ||
1469 | |||
1470 | case KEY_ENTER: | ||
1471 | saveStringEnter = 0; | ||
1472 | if (savegamestrings[saveSlot][0]) | ||
1473 | M_DoSave(saveSlot); | ||
1474 | break; | ||
1475 | |||
1476 | default: | ||
1477 | ch = toupper(ch); | ||
1478 | if (ch != 32) | ||
1479 | if (ch-HU_FONTSTART < 0 || ch-HU_FONTSTART >= HU_FONTSIZE) | ||
1480 | break; | ||
1481 | if (ch >= 32 && ch <= 127 && | ||
1482 | saveCharIndex < SAVESTRINGSIZE-1 && | ||
1483 | M_StringWidth(savegamestrings[saveSlot]) < | ||
1484 | (SAVESTRINGSIZE-2)*8) | ||
1485 | { | ||
1486 | savegamestrings[saveSlot][saveCharIndex++] = ch; | ||
1487 | savegamestrings[saveSlot][saveCharIndex] = 0; | ||
1488 | } | ||
1489 | break; | ||
1490 | } | ||
1491 | return true; | ||
1492 | } | ||
1493 | |||
1494 | // Take care of any messages that need input | ||
1495 | if (messageToPrint) | ||
1496 | { | ||
1497 | if (messageNeedsInput == true && | ||
1498 | !(ch == ' ' || ch == 'n' || ch == KEY_ENTER || ch == KEY_ESCAPE)) | ||
1499 | return false; | ||
1500 | |||
1501 | menuactive = messageLastMenuActive; | ||
1502 | messageToPrint = 0; | ||
1503 | if (messageRoutine) | ||
1504 | messageRoutine(ch); | ||
1505 | |||
1506 | menuactive = false; | ||
1507 | S_StartSound(NULL,sfx_swtchx); | ||
1508 | return true; | ||
1509 | } | ||
1510 | /* | ||
1511 | if (ch == KEY_F1) // devparm && | ||
1512 | { | ||
1513 | G_ScreenShot (); | ||
1514 | return true; | ||
1515 | } | ||
1516 | */ | ||
1517 | // F-Keys | ||
1518 | if (!menuactive) | ||
1519 | switch(ch) | ||
1520 | { | ||
1521 | case KEY_MINUS: // Screen size down | ||
1522 | if ((automapmode & am_active) || chat_on) | ||
1523 | return false; | ||
1524 | M_SizeDisplay(0); | ||
1525 | S_StartSound(NULL,sfx_stnmov); | ||
1526 | return true; | ||
1527 | |||
1528 | case KEY_EQUALS: // Screen size up | ||
1529 | if ((automapmode & am_active) || chat_on) | ||
1530 | return false; | ||
1531 | M_SizeDisplay(1); | ||
1532 | S_StartSound(NULL,sfx_stnmov); | ||
1533 | return true; | ||
1534 | /* | ||
1535 | case KEY_F1: // Help key | ||
1536 | M_StartControlPanel (); | ||
1537 | |||
1538 | if ( gamemode == retail ) | ||
1539 | currentMenu = &ReadDef2; | ||
1540 | else | ||
1541 | currentMenu = &ReadDef1; | ||
1542 | |||
1543 | itemOn = 0; | ||
1544 | S_StartSound(NULL,sfx_swtchn); | ||
1545 | return true; | ||
1546 | |||
1547 | case KEY_F6: // Quicksave | ||
1548 | S_StartSound(NULL,sfx_swtchn); | ||
1549 | M_QuickSave(); | ||
1550 | return true; | ||
1551 | |||
1552 | case KEY_F9: // Quickload | ||
1553 | S_StartSound(NULL,sfx_swtchn); | ||
1554 | M_QuickLoad(); | ||
1555 | return true; | ||
1556 | */ | ||
1557 | } | ||
1558 | |||
1559 | |||
1560 | // Pop-up menu? | ||
1561 | if (!menuactive) | ||
1562 | { | ||
1563 | if (ch == KEY_ESCAPE) | ||
1564 | { | ||
1565 | M_StartControlPanel (); | ||
1566 | S_StartSound(NULL,sfx_swtchn); | ||
1567 | return true; | ||
1568 | } | ||
1569 | return false; | ||
1570 | } | ||
1571 | |||
1572 | |||
1573 | // Keys usable within menu | ||
1574 | switch (ch) | ||
1575 | { | ||
1576 | case KEY_DOWNARROW: | ||
1577 | do | ||
1578 | { | ||
1579 | if (itemOn+1 > currentMenu->numitems-1) | ||
1580 | itemOn = 0; | ||
1581 | else | ||
1582 | itemOn++; | ||
1583 | S_StartSound(NULL,sfx_pstop); | ||
1584 | } | ||
1585 | while(currentMenu->menuitems[itemOn].status==-1); | ||
1586 | return true; | ||
1587 | |||
1588 | case KEY_UPARROW: | ||
1589 | do | ||
1590 | { | ||
1591 | if (!itemOn) | ||
1592 | itemOn = currentMenu->numitems-1; | ||
1593 | else | ||
1594 | itemOn--; | ||
1595 | S_StartSound(NULL,sfx_pstop); | ||
1596 | } | ||
1597 | while(currentMenu->menuitems[itemOn].status==-1); | ||
1598 | return true; | ||
1599 | |||
1600 | case KEY_LEFTARROW: | ||
1601 | if (currentMenu->menuitems[itemOn].routine && | ||
1602 | currentMenu->menuitems[itemOn].status == 2) | ||
1603 | { | ||
1604 | S_StartSound(NULL,sfx_stnmov); | ||
1605 | currentMenu->menuitems[itemOn].routine(0); | ||
1606 | } | ||
1607 | return true; | ||
1608 | |||
1609 | case KEY_RIGHTARROW: | ||
1610 | if (currentMenu->menuitems[itemOn].routine && | ||
1611 | currentMenu->menuitems[itemOn].status == 2) | ||
1612 | { | ||
1613 | S_StartSound(NULL,sfx_stnmov); | ||
1614 | currentMenu->menuitems[itemOn].routine(1); | ||
1615 | } | ||
1616 | return true; | ||
1617 | |||
1618 | case KEY_ENTER: | ||
1619 | if (currentMenu->menuitems[itemOn].routine && | ||
1620 | currentMenu->menuitems[itemOn].status) | ||
1621 | { | ||
1622 | currentMenu->lastOn = itemOn; | ||
1623 | if (currentMenu->menuitems[itemOn].status == 2) | ||
1624 | { | ||
1625 | currentMenu->menuitems[itemOn].routine(1); // right arrow | ||
1626 | S_StartSound(NULL,sfx_stnmov); | ||
1627 | } | ||
1628 | else | ||
1629 | { | ||
1630 | currentMenu->menuitems[itemOn].routine(itemOn); | ||
1631 | S_StartSound(NULL,sfx_pistol); | ||
1632 | } | ||
1633 | } | ||
1634 | return true; | ||
1635 | |||
1636 | case KEY_ESCAPE: | ||
1637 | currentMenu->lastOn = itemOn; | ||
1638 | M_ClearMenus (); | ||
1639 | S_StartSound(NULL,sfx_swtchx); | ||
1640 | return true; | ||
1641 | |||
1642 | case KEY_BACKSPACE: | ||
1643 | currentMenu->lastOn = itemOn; | ||
1644 | if (currentMenu->prevMenu) | ||
1645 | { | ||
1646 | currentMenu = currentMenu->prevMenu; | ||
1647 | itemOn = currentMenu->lastOn; | ||
1648 | S_StartSound(NULL,sfx_swtchn); | ||
1649 | } | ||
1650 | return true; | ||
1651 | |||
1652 | default: | ||
1653 | for (i = itemOn+1;i < currentMenu->numitems;i++) | ||
1654 | if (currentMenu->menuitems[i].alphaKey == ch) | ||
1655 | { | ||
1656 | itemOn = i; | ||
1657 | S_StartSound(NULL,sfx_pstop); | ||
1658 | return true; | ||
1659 | } | ||
1660 | for (i = 0;i <= itemOn;i++) | ||
1661 | if (currentMenu->menuitems[i].alphaKey == ch) | ||
1662 | { | ||
1663 | itemOn = i; | ||
1664 | S_StartSound(NULL,sfx_pstop); | ||
1665 | return true; | ||
1666 | } | ||
1667 | break; | ||
1668 | |||
1669 | } | ||
1670 | |||
1671 | return false; | ||
1672 | } | ||
1673 | |||
1674 | |||
1675 | |||
1676 | // | ||
1677 | // M_StartControlPanel | ||
1678 | // | ||
1679 | void M_StartControlPanel (void) | ||
1680 | { | ||
1681 | // intro might call this repeatedly | ||
1682 | if (menuactive) | ||
1683 | return; | ||
1684 | |||
1685 | menuactive = 1; | ||
1686 | currentMenu = &MainDef; // JDC | ||
1687 | itemOn = currentMenu->lastOn; // JDC | ||
1688 | } | ||
1689 | |||
1690 | |||
1691 | // | ||
1692 | // M_Drawer | ||
1693 | // Called after the view has been rendered, | ||
1694 | // but before it has been blitted. | ||
1695 | // | ||
1696 | void M_Drawer (void) | ||
1697 | { | ||
1698 | static short x; | ||
1699 | static short y; | ||
1700 | unsigned short i; | ||
1701 | short max; | ||
1702 | char string[40]; | ||
1703 | int start; | ||
1704 | |||
1705 | inhelpscreens = false; | ||
1706 | |||
1707 | |||
1708 | // Horiz. & Vertically center string and print it. | ||
1709 | if (messageToPrint) | ||
1710 | { | ||
1711 | start = 0; | ||
1712 | y = 100 - M_StringHeight(messageString)/2; | ||
1713 | while(*(messageString+start)) | ||
1714 | { | ||
1715 | for (i = 0;i < strlen(messageString+start);i++) | ||
1716 | if (*(messageString+start+i) == '\n') | ||
1717 | { | ||
1718 | memset(string,0,40); | ||
1719 | strncpy(string,messageString+start,i); | ||
1720 | start += i+1; | ||
1721 | break; | ||
1722 | } | ||
1723 | if (i == strlen(messageString+start)) | ||
1724 | { | ||
1725 | strcpy(string,messageString+start); | ||
1726 | start += i; | ||
1727 | } | ||
1728 | |||
1729 | x = 160 - M_StringWidth(string)/2; | ||
1730 | M_WriteText(x,y,string); | ||
1731 | y += SHORT(hu_font[0].height); | ||
1732 | } | ||
1733 | return; | ||
1734 | } | ||
1735 | |||
1736 | if (!menuactive) | ||
1737 | return; | ||
1738 | |||
1739 | if (currentMenu->routine) | ||
1740 | currentMenu->routine(); // call Draw routine | ||
1741 | |||
1742 | // DRAW MENU | ||
1743 | x = currentMenu->x; | ||
1744 | y = currentMenu->y; | ||
1745 | max = currentMenu->numitems; | ||
1746 | |||
1747 | for (i=0;i<max;i++) | ||
1748 | { | ||
1749 | if (currentMenu->menuitems[i].name[0]) | ||
1750 | V_DrawNamePatch(x,y,0,currentMenu->menuitems[i].name, | ||
1751 | CR_DEFAULT, VPT_STRETCH); | ||
1752 | y += LINEHEIGHT; | ||
1753 | } | ||
1754 | |||
1755 | // DRAW SKULL | ||
1756 | // CPhipps - patch drawing updated | ||
1757 | V_DrawNamePatch(x + SKULLXOFF, currentMenu->y - 5 + itemOn*LINEHEIGHT,0, | ||
1758 | skullName[whichSkull], CR_DEFAULT, VPT_STRETCH); | ||
1759 | |||
1760 | } | ||
1761 | |||
1762 | |||
1763 | // | ||
1764 | // M_ClearMenus | ||
1765 | // | ||
1766 | void M_ClearMenus (void) | ||
1767 | { | ||
1768 | menuactive = 0; | ||
1769 | // if (!netgame && usergame && paused) | ||
1770 | // sendpause = true; | ||
1771 | } | ||
1772 | |||
1773 | |||
1774 | |||
1775 | |||
1776 | // | ||
1777 | // M_SetupNextMenu | ||
1778 | // | ||
1779 | void M_SetupNextMenu(menu_t *menudef) | ||
1780 | { | ||
1781 | currentMenu = menudef; | ||
1782 | itemOn = currentMenu->lastOn; | ||
1783 | } | ||
1784 | |||
1785 | |||
1786 | // | ||
1787 | // M_Ticker | ||
1788 | // | ||
1789 | void M_Ticker (void) | ||
1790 | { | ||
1791 | if (--skullAnimCounter <= 0) | ||
1792 | { | ||
1793 | whichSkull ^= 1; | ||
1794 | skullAnimCounter = 8; | ||
1795 | } | ||
1796 | } | ||
1797 | |||
1798 | |||
1799 | // | ||
1800 | // M_Init | ||
1801 | // | ||
1802 | void M_Init (void) | ||
1803 | { | ||
1804 | currentMenu = &MainDef; | ||
1805 | menuactive = 0; | ||
1806 | itemOn = currentMenu->lastOn; | ||
1807 | whichSkull = 0; | ||
1808 | skullAnimCounter = 10; | ||
1809 | screenSize = screenblocks - 3; | ||
1810 | messageToPrint = 0; | ||
1811 | messageString = NULL; | ||
1812 | messageLastMenuActive = menuactive; | ||
1813 | quickSaveSlot = -1; | ||
1814 | |||
1815 | // Here we could catch other version dependencies, | ||
1816 | // like HELP1/2, and four episodes. | ||
1817 | |||
1818 | |||
1819 | switch ( gamemode ) | ||
1820 | { | ||
1821 | case commercial: | ||
1822 | // This is used because DOOM 2 had only one HELP | ||
1823 | // page. I use CREDIT as second page now, but | ||
1824 | // kept this hack for educational purposes. | ||
1825 | MainMenu[readthis] = MainMenu[quitdoom]; | ||
1826 | MainDef.numitems--; | ||
1827 | MainDef.y += 8; | ||
1828 | NewDef.prevMenu = &MainDef; | ||
1829 | ReadDef1.routine = M_DrawReadThis1; | ||
1830 | ReadDef1.x = 330; | ||
1831 | ReadDef1.y = 165; | ||
1832 | ReadMenu1[0].routine = M_FinishReadThis; | ||
1833 | break; | ||
1834 | case shareware: | ||
1835 | // Episode 2 and 3 are handled, | ||
1836 | // branching to an ad screen. | ||
1837 | case registered: | ||
1838 | // We need to remove the fourth episode. | ||
1839 | EpiDef.numitems--; | ||
1840 | break; | ||
1841 | case retail: | ||
1842 | // We are fine. | ||
1843 | default: | ||
1844 | break; | ||
1845 | } | ||
1846 | |||
1847 | } | ||
1848 | |||