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