|
|
1.1 root 1: /*
2: Copyright (C) 1996-1997 Id Software, Inc.
3:
4: This program is free software; you can redistribute it and/or
5: modify it under the terms of the GNU General Public License
6: as published by the Free Software Foundation; either version 2
7: of the License, or (at your option) any later version.
8:
9: This program is distributed in the hope that it will be useful,
10: but WITHOUT ANY WARRANTY; without even the implied warranty of
11: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12:
13: See the GNU General Public License for more details.
14:
15: You should have received a copy of the GNU General Public License
16: along with this program; if not, write to the Free Software
17: Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18:
19: */
20: #include "quakedef.h"
21: #include "winquake.h"
22:
23: void (*vid_menudrawfn)(void);
24: void (*vid_menukeyfn)(int key);
25:
26: enum {m_none, m_main, m_singleplayer, m_load, m_save, m_multiplayer, m_setup, m_net, m_options, m_video, m_keys, m_help, m_quit, m_serialconfig, m_modemconfig, m_lanconfig, m_gameoptions, m_search, m_slist} m_state;
27:
28: void M_Menu_Main_f (void);
29: void M_Menu_SinglePlayer_f (void);
30: void M_Menu_Load_f (void);
31: void M_Menu_Save_f (void);
32: void M_Menu_MultiPlayer_f (void);
33: void M_Menu_Setup_f (void);
34: void M_Menu_Net_f (void);
35: void M_Menu_Options_f (void);
36: void M_Menu_Keys_f (void);
37: void M_Menu_Video_f (void);
38: void M_Menu_Help_f (void);
39: void M_Menu_Quit_f (void);
40: void M_Menu_SerialConfig_f (void);
41: void M_Menu_ModemConfig_f (void);
42: void M_Menu_LanConfig_f (void);
43: void M_Menu_GameOptions_f (void);
44: void M_Menu_Search_f (void);
45: void M_Menu_ServerList_f (void);
46:
47: void M_Main_Draw (void);
48: void M_SinglePlayer_Draw (void);
49: void M_Load_Draw (void);
50: void M_Save_Draw (void);
51: void M_MultiPlayer_Draw (void);
52: void M_Setup_Draw (void);
53: void M_Net_Draw (void);
54: void M_Options_Draw (void);
55: void M_Keys_Draw (void);
56: void M_Video_Draw (void);
57: void M_Help_Draw (void);
58: void M_Quit_Draw (void);
59: void M_SerialConfig_Draw (void);
60: void M_ModemConfig_Draw (void);
61: void M_LanConfig_Draw (void);
62: void M_GameOptions_Draw (void);
63: void M_Search_Draw (void);
64: void M_ServerList_Draw (void);
65:
66: void M_Main_Key (int key);
67: void M_SinglePlayer_Key (int key);
68: void M_Load_Key (int key);
69: void M_Save_Key (int key);
70: void M_MultiPlayer_Key (int key);
71: void M_Setup_Key (int key);
72: void M_Net_Key (int key);
73: void M_Options_Key (int key);
74: void M_Keys_Key (int key);
75: void M_Video_Key (int key);
76: void M_Help_Key (int key);
77: void M_Quit_Key (int key);
78: void M_SerialConfig_Key (int key);
79: void M_ModemConfig_Key (int key);
80: void M_LanConfig_Key (int key);
81: void M_GameOptions_Key (int key);
82: void M_Search_Key (int key);
83: void M_ServerList_Key (int key);
84:
85: qboolean m_entersound; // play after drawing a frame, so caching
86: // won't disrupt the sound
87: qboolean m_recursiveDraw;
88:
89: int m_return_state;
90: qboolean m_return_onerror;
91: char m_return_reason [32];
92:
93: #define StartingGame (m_multiplayer_cursor == 1)
94: #define JoiningGame (m_multiplayer_cursor == 0)
95: #define SerialConfig (m_net_cursor == 0)
96: #define DirectConfig (m_net_cursor == 1)
97: #define IPXConfig (m_net_cursor == 2)
98: #define TCPIPConfig (m_net_cursor == 3)
99:
100: void M_ConfigureNetSubsystem(void);
101:
102: //=============================================================================
103: /* Support Routines */
104:
105: /*
106: ================
107: M_DrawCharacter
108:
109: Draws one solid graphics character
110: ================
111: */
112: void M_DrawCharacter (int cx, int line, int num)
113: {
114: Draw_Character ( cx + ((vid.width - 320)>>1), line, num);
115: }
116:
117: void M_Print (int cx, int cy, char *str)
118: {
119: while (*str)
120: {
121: M_DrawCharacter (cx, cy, (*str)+128);
122: str++;
123: cx += 8;
124: }
125: }
126:
127: void M_PrintWhite (int cx, int cy, char *str)
128: {
129: while (*str)
130: {
131: M_DrawCharacter (cx, cy, *str);
132: str++;
133: cx += 8;
134: }
135: }
136:
137: void M_DrawTransPic (int x, int y, qpic_t *pic)
138: {
139: Draw_TransPic (x + ((vid.width - 320)>>1), y, pic);
140: }
141:
142: void M_DrawPic (int x, int y, qpic_t *pic)
143: {
144: Draw_Pic (x + ((vid.width - 320)>>1), y, pic);
145: }
146:
147: byte identityTable[256];
148: byte translationTable[256];
149:
150: void M_BuildTranslationTable(int top, int bottom)
151: {
152: int j;
153: byte *dest, *source;
154:
155: for (j = 0; j < 256; j++)
156: identityTable[j] = j;
157: dest = translationTable;
158: source = identityTable;
159: memcpy (dest, source, 256);
160:
161: if (top < 128) // the artists made some backwards ranges. sigh.
162: memcpy (dest + TOP_RANGE, source + top, 16);
163: else
164: for (j=0 ; j<16 ; j++)
165: dest[TOP_RANGE+j] = source[top+15-j];
166:
167: if (bottom < 128)
168: memcpy (dest + BOTTOM_RANGE, source + bottom, 16);
169: else
170: for (j=0 ; j<16 ; j++)
171: dest[BOTTOM_RANGE+j] = source[bottom+15-j];
172: }
173:
174:
175: void M_DrawTransPicTranslate (int x, int y, qpic_t *pic)
176: {
177: Draw_TransPicTranslate (x + ((vid.width - 320)>>1), y, pic, translationTable);
178: }
179:
180:
181: void M_DrawTextBox (int x, int y, int width, int lines)
182: {
183: qpic_t *p;
184: int cx, cy;
185: int n;
186:
187: // draw left side
188: cx = x;
189: cy = y;
190: p = Draw_CachePic ("gfx/box_tl.lmp");
191: M_DrawTransPic (cx, cy, p);
192: p = Draw_CachePic ("gfx/box_ml.lmp");
193: for (n = 0; n < lines; n++)
194: {
195: cy += 8;
196: M_DrawTransPic (cx, cy, p);
197: }
198: p = Draw_CachePic ("gfx/box_bl.lmp");
199: M_DrawTransPic (cx, cy+8, p);
200:
201: // draw middle
202: cx += 8;
203: while (width > 0)
204: {
205: cy = y;
206: p = Draw_CachePic ("gfx/box_tm.lmp");
207: M_DrawTransPic (cx, cy, p);
208: p = Draw_CachePic ("gfx/box_mm.lmp");
209: for (n = 0; n < lines; n++)
210: {
211: cy += 8;
212: if (n == 1)
213: p = Draw_CachePic ("gfx/box_mm2.lmp");
214: M_DrawTransPic (cx, cy, p);
215: }
216: p = Draw_CachePic ("gfx/box_bm.lmp");
217: M_DrawTransPic (cx, cy+8, p);
218: width -= 2;
219: cx += 16;
220: }
221:
222: // draw right side
223: cy = y;
224: p = Draw_CachePic ("gfx/box_tr.lmp");
225: M_DrawTransPic (cx, cy, p);
226: p = Draw_CachePic ("gfx/box_mr.lmp");
227: for (n = 0; n < lines; n++)
228: {
229: cy += 8;
230: M_DrawTransPic (cx, cy, p);
231: }
232: p = Draw_CachePic ("gfx/box_br.lmp");
233: M_DrawTransPic (cx, cy+8, p);
234: }
235:
236: //=============================================================================
237:
238: int m_save_demonum;
239:
240: /*
241: ================
242: M_ToggleMenu_f
243: ================
244: */
245: void M_ToggleMenu_f (void)
246: {
247: m_entersound = true;
248:
249: if (key_dest == key_menu)
250: {
251: if (m_state != m_main)
252: {
253: M_Menu_Main_f ();
254: return;
255: }
256: key_dest = key_game;
257: m_state = m_none;
258: return;
259: }
260: if (key_dest == key_console)
261: {
262: Con_ToggleConsole_f ();
263: }
264: else
265: {
266: M_Menu_Main_f ();
267: }
268: }
269:
270:
271: //=============================================================================
272: /* MAIN MENU */
273:
274: int m_main_cursor;
275: #define MAIN_ITEMS 5
276:
277:
278: void M_Menu_Main_f (void)
279: {
280: if (key_dest != key_menu)
281: {
282: m_save_demonum = cls.demonum;
283: cls.demonum = -1;
284: }
285: key_dest = key_menu;
286: m_state = m_main;
287: m_entersound = true;
288: }
289:
290:
291: void M_Main_Draw (void)
292: {
293: int f;
294: qpic_t *p;
295:
296: M_DrawTransPic (16, 4, Draw_CachePic ("gfx/qplaque.lmp") );
297: p = Draw_CachePic ("gfx/ttl_main.lmp");
298: M_DrawPic ( (320-p->width)/2, 4, p);
299: M_DrawTransPic (72, 32, Draw_CachePic ("gfx/mainmenu.lmp") );
300:
301: f = (int)(realtime * 10)%6;
302:
303: M_DrawTransPic (54, 32 + m_main_cursor * 20,Draw_CachePic( va("gfx/menudot%i.lmp", f+1 ) ) );
304: }
305:
306:
307: void M_Main_Key (int key)
308: {
309: switch (key)
310: {
311: case K_ESCAPE:
312: key_dest = key_game;
313: m_state = m_none;
314: cls.demonum = m_save_demonum;
315: if (cls.demonum != -1 && !cls.demoplayback && cls.state == ca_disconnected)
316: CL_NextDemo ();
317: break;
318:
319: case K_DOWNARROW:
320: S_LocalSound ("misc/menu1.wav");
321: if (++m_main_cursor >= MAIN_ITEMS)
322: m_main_cursor = 0;
323: break;
324:
325: case K_UPARROW:
326: S_LocalSound ("misc/menu1.wav");
327: if (--m_main_cursor < 0)
328: m_main_cursor = MAIN_ITEMS - 1;
329: break;
330:
331: case K_ENTER:
332: m_entersound = true;
333:
334: switch (m_main_cursor)
335: {
336: case 0:
337: M_Menu_SinglePlayer_f ();
338: break;
339:
340: case 1:
341: M_Menu_MultiPlayer_f ();
342: break;
343:
344: case 2:
345: M_Menu_Options_f ();
346: break;
347:
348: case 3:
349: M_Menu_Help_f ();
350: break;
351:
352: case 4:
353: M_Menu_Quit_f ();
354: break;
355: }
356: }
357: }
358:
359:
360: //=============================================================================
361: /* OPTIONS MENU */
362:
363: #define OPTIONS_ITEMS 16
364:
365: #define SLIDER_RANGE 10
366:
367: int options_cursor;
368:
369: void M_Menu_Options_f (void)
370: {
371: key_dest = key_menu;
372: m_state = m_options;
373: m_entersound = true;
374: }
375:
376:
377: void M_AdjustSliders (int dir)
378: {
379: S_LocalSound ("misc/menu3.wav");
380:
381: switch (options_cursor)
382: {
383: case 3: // screen size
384: scr_viewsize.value += dir * 10;
385: if (scr_viewsize.value < 30)
386: scr_viewsize.value = 30;
387: if (scr_viewsize.value > 120)
388: scr_viewsize.value = 120;
389: Cvar_SetValue ("viewsize", scr_viewsize.value);
390: break;
391: case 4: // gamma
392: v_gamma.value -= dir * 0.05;
393: if (v_gamma.value < 0.5)
394: v_gamma.value = 0.5;
395: if (v_gamma.value > 1)
396: v_gamma.value = 1;
397: Cvar_SetValue ("gamma", v_gamma.value);
398: break;
399: case 5: // mouse speed
400: sensitivity.value += dir * 0.5;
401: if (sensitivity.value < 1)
402: sensitivity.value = 1;
403: if (sensitivity.value > 11)
404: sensitivity.value = 11;
405: Cvar_SetValue ("sensitivity", sensitivity.value);
406: break;
407: case 6: // music volume
408: #ifdef _WIN32
409: bgmvolume.value += dir * 1.0;
410: #else
411: bgmvolume.value += dir * 0.1;
412: #endif
413: if (bgmvolume.value < 0)
414: bgmvolume.value = 0;
415: if (bgmvolume.value > 1)
416: bgmvolume.value = 1;
417: Cvar_SetValue ("bgmvolume", bgmvolume.value);
418: break;
419: case 7: // sfx volume
420: volume.value += dir * 0.1;
421: if (volume.value < 0)
422: volume.value = 0;
423: if (volume.value > 1)
424: volume.value = 1;
425: Cvar_SetValue ("volume", volume.value);
426: break;
427:
428: case 8: // allways run
429: if (cl_forwardspeed.value > 200)
430: {
431: Cvar_SetValue ("cl_forwardspeed", 200);
432: Cvar_SetValue ("cl_backspeed", 200);
433: }
434: else
435: {
436: Cvar_SetValue ("cl_forwardspeed", 400);
437: Cvar_SetValue ("cl_backspeed", 400);
438: }
439: break;
440:
441: case 9: // invert mouse
442: Cvar_SetValue ("m_pitch", -m_pitch.value);
443: break;
444:
445: case 10: // lookspring
446: Cvar_SetValue ("lookspring", !lookspring.value);
447: break;
448:
449: case 11: // lookstrafe
450: Cvar_SetValue ("lookstrafe", !lookstrafe.value);
451: break;
452:
453: case 12:
454: Cvar_SetValue ("cl_sbar", !cl_sbar.value);
455: break;
456:
457: case 13:
458: Cvar_SetValue ("cl_hudswap", !cl_hudswap.value);
459:
460: case 15: // _windowed_mouse
461: Cvar_SetValue ("_windowed_mouse", !_windowed_mouse.value);
462: break;
463: }
464: }
465:
466:
467: void M_DrawSlider (int x, int y, float range)
468: {
469: int i;
470:
471: if (range < 0)
472: range = 0;
473: if (range > 1)
474: range = 1;
475: M_DrawCharacter (x-8, y, 128);
476: for (i=0 ; i<SLIDER_RANGE ; i++)
477: M_DrawCharacter (x + i*8, y, 129);
478: M_DrawCharacter (x+i*8, y, 130);
479: M_DrawCharacter (x + (SLIDER_RANGE-1)*8 * range, y, 131);
480: }
481:
482: void M_DrawCheckbox (int x, int y, int on)
483: {
484: #if 0
485: if (on)
486: M_DrawCharacter (x, y, 131);
487: else
488: M_DrawCharacter (x, y, 129);
489: #endif
490: if (on)
491: M_Print (x, y, "on");
492: else
493: M_Print (x, y, "off");
494: }
495:
496: void M_Options_Draw (void)
497: {
498: float r;
499: qpic_t *p;
500:
501: M_DrawTransPic (16, 4, Draw_CachePic ("gfx/qplaque.lmp") );
502: p = Draw_CachePic ("gfx/p_option.lmp");
503: M_DrawPic ( (320-p->width)/2, 4, p);
504:
505: M_Print (16, 32, " Customize controls");
506: M_Print (16, 40, " Go to console");
507: M_Print (16, 48, " Reset to defaults");
508:
509: M_Print (16, 56, " Screen size");
510: r = (scr_viewsize.value - 30) / (120 - 30);
511: M_DrawSlider (220, 56, r);
512:
513: M_Print (16, 64, " Brightness");
514: r = (1.0 - v_gamma.value) / 0.5;
515: M_DrawSlider (220, 64, r);
516:
517: M_Print (16, 72, " Mouse Speed");
518: r = (sensitivity.value - 1)/10;
519: M_DrawSlider (220, 72, r);
520:
521: M_Print (16, 80, " CD Music Volume");
522: r = bgmvolume.value;
523: M_DrawSlider (220, 80, r);
524:
525: M_Print (16, 88, " Sound Volume");
526: r = volume.value;
527: M_DrawSlider (220, 88, r);
528:
529: M_Print (16, 96, " Always Run");
530: M_DrawCheckbox (220, 96, cl_forwardspeed.value > 200);
531:
532: M_Print (16, 104, " Invert Mouse");
533: M_DrawCheckbox (220, 104, m_pitch.value < 0);
534:
535: M_Print (16, 112, " Lookspring");
536: M_DrawCheckbox (220, 112, lookspring.value);
537:
538: M_Print (16, 120, " Lookstrafe");
539: M_DrawCheckbox (220, 120, lookstrafe.value);
540:
541: M_Print (16, 128, " Use old status bar");
542: M_DrawCheckbox (220, 128, cl_sbar.value);
543:
544: M_Print (16, 136, " HUD on left side");
545: M_DrawCheckbox (220, 136, cl_hudswap.value);
546:
547: if (vid_menudrawfn)
548: M_Print (16, 144, " Video Options");
549:
550: #ifdef _WIN32
551: if (modestate == MS_WINDOWED)
552: {
553: #endif
554: M_Print (16, 152, " Use Mouse");
555: M_DrawCheckbox (220, 152, _windowed_mouse.value);
556: #ifdef _WIN32
557: }
558: #endif
559:
560: // cursor
561: M_DrawCharacter (200, 32 + options_cursor*8, 12+((int)(realtime*4)&1));
562: }
563:
564:
565: void M_Options_Key (int k)
566: {
567: switch (k)
568: {
569: case K_ESCAPE:
570: M_Menu_Main_f ();
571: break;
572:
573: case K_ENTER:
574: m_entersound = true;
575: switch (options_cursor)
576: {
577: case 0:
578: M_Menu_Keys_f ();
579: break;
580: case 1:
581: m_state = m_none;
582: Con_ToggleConsole_f ();
583: break;
584: case 2:
585: Cbuf_AddText ("exec default.cfg\n");
586: break;
587: case 14:
588: M_Menu_Video_f ();
589: break;
590: default:
591: M_AdjustSliders (1);
592: break;
593: }
594: return;
595:
596: case K_UPARROW:
597: S_LocalSound ("misc/menu1.wav");
598: options_cursor--;
599: if (options_cursor < 0)
600: options_cursor = OPTIONS_ITEMS-1;
601: break;
602:
603: case K_DOWNARROW:
604: S_LocalSound ("misc/menu1.wav");
605: options_cursor++;
606: if (options_cursor >= OPTIONS_ITEMS)
607: options_cursor = 0;
608: break;
609:
610: case K_LEFTARROW:
611: M_AdjustSliders (-1);
612: break;
613:
614: case K_RIGHTARROW:
615: M_AdjustSliders (1);
616: break;
617: }
618:
619: if (options_cursor == 14 && vid_menudrawfn == NULL)
620: {
621: if (k == K_UPARROW)
622: options_cursor = 13;
623: else
624: options_cursor = 0;
625: }
626:
627: if ((options_cursor == 15)
628: #ifdef _WIN32
629: && (modestate != MS_WINDOWED)
630: #endif
631: )
632: {
633: if (k == K_UPARROW)
634: options_cursor = 14;
635: else
636: options_cursor = 0;
637: }
638: }
639:
640:
641: //=============================================================================
642: /* KEYS MENU */
643:
644: char *bindnames[][2] =
645: {
646: {"+attack", "attack"},
647: {"impulse 10", "change weapon"},
648: {"+jump", "jump / swim up"},
649: {"+forward", "walk forward"},
650: {"+back", "backpedal"},
651: {"+left", "turn left"},
652: {"+right", "turn right"},
653: {"+speed", "run"},
654: {"+moveleft", "step left"},
655: {"+moveright", "step right"},
656: {"+strafe", "sidestep"},
657: {"+lookup", "look up"},
658: {"+lookdown", "look down"},
659: {"centerview", "center view"},
660: {"+mlook", "mouse look"},
661: {"+klook", "keyboard look"},
662: {"+moveup", "swim up"},
663: {"+movedown", "swim down"}
664: };
665:
666: #define NUMCOMMANDS (sizeof(bindnames)/sizeof(bindnames[0]))
667:
668: int keys_cursor;
669: int bind_grab;
670:
671: void M_Menu_Keys_f (void)
672: {
673: key_dest = key_menu;
674: m_state = m_keys;
675: m_entersound = true;
676: }
677:
678:
679: void M_FindKeysForCommand (char *command, int *twokeys)
680: {
681: int count;
682: int j;
683: int l;
684: char *b;
685:
686: twokeys[0] = twokeys[1] = -1;
687: l = strlen(command);
688: count = 0;
689:
690: for (j=0 ; j<256 ; j++)
691: {
692: b = keybindings[j];
693: if (!b)
694: continue;
695: if (!strncmp (b, command, l) )
696: {
697: twokeys[count] = j;
698: count++;
699: if (count == 2)
700: break;
701: }
702: }
703: }
704:
705: void M_UnbindCommand (char *command)
706: {
707: int j;
708: int l;
709: char *b;
710:
711: l = strlen(command);
712:
713: for (j=0 ; j<256 ; j++)
714: {
715: b = keybindings[j];
716: if (!b)
717: continue;
718: if (!strncmp (b, command, l) )
719: Key_SetBinding (j, "");
720: }
721: }
722:
723:
724: void M_Keys_Draw (void)
725: {
726: int i, l;
727: int keys[2];
728: char *name;
729: int x, y;
730: qpic_t *p;
731:
732: p = Draw_CachePic ("gfx/ttl_cstm.lmp");
733: M_DrawPic ( (320-p->width)/2, 4, p);
734:
735: if (bind_grab)
736: M_Print (12, 32, "Press a key or button for this action");
737: else
738: M_Print (18, 32, "Enter to change, backspace to clear");
739:
740: // search for known bindings
741: for (i=0 ; i<NUMCOMMANDS ; i++)
742: {
743: y = 48 + 8*i;
744:
745: M_Print (16, y, bindnames[i][1]);
746:
747: l = strlen (bindnames[i][0]);
748:
749: M_FindKeysForCommand (bindnames[i][0], keys);
750:
751: if (keys[0] == -1)
752: {
753: M_Print (140, y, "???");
754: }
755: else
756: {
757: name = Key_KeynumToString (keys[0]);
758: M_Print (140, y, name);
759: x = strlen(name) * 8;
760: if (keys[1] != -1)
761: {
762: M_Print (140 + x + 8, y, "or");
763: M_Print (140 + x + 32, y, Key_KeynumToString (keys[1]));
764: }
765: }
766: }
767:
768: if (bind_grab)
769: M_DrawCharacter (130, 48 + keys_cursor*8, '=');
770: else
771: M_DrawCharacter (130, 48 + keys_cursor*8, 12+((int)(realtime*4)&1));
772: }
773:
774:
775: void M_Keys_Key (int k)
776: {
777: char cmd[80];
778: int keys[2];
779:
780: if (bind_grab)
781: { // defining a key
782: S_LocalSound ("misc/menu1.wav");
783: if (k == K_ESCAPE)
784: {
785: bind_grab = false;
786: }
787: else if (k != '`')
788: {
789: sprintf (cmd, "bind %s \"%s\"\n", Key_KeynumToString (k), bindnames[keys_cursor][0]);
790: Cbuf_InsertText (cmd);
791: }
792:
793: bind_grab = false;
794: return;
795: }
796:
797: switch (k)
798: {
799: case K_ESCAPE:
800: M_Menu_Options_f ();
801: break;
802:
803: case K_LEFTARROW:
804: case K_UPARROW:
805: S_LocalSound ("misc/menu1.wav");
806: keys_cursor--;
807: if (keys_cursor < 0)
808: keys_cursor = NUMCOMMANDS-1;
809: break;
810:
811: case K_DOWNARROW:
812: case K_RIGHTARROW:
813: S_LocalSound ("misc/menu1.wav");
814: keys_cursor++;
815: if (keys_cursor >= NUMCOMMANDS)
816: keys_cursor = 0;
817: break;
818:
819: case K_ENTER: // go into bind mode
820: M_FindKeysForCommand (bindnames[keys_cursor][0], keys);
821: S_LocalSound ("misc/menu2.wav");
822: if (keys[1] != -1)
823: M_UnbindCommand (bindnames[keys_cursor][0]);
824: bind_grab = true;
825: break;
826:
827: case K_BACKSPACE: // delete bindings
828: case K_DEL: // delete bindings
829: S_LocalSound ("misc/menu2.wav");
830: M_UnbindCommand (bindnames[keys_cursor][0]);
831: break;
832: }
833: }
834:
835: //=============================================================================
836: /* VIDEO MENU */
837:
838: void M_Menu_Video_f (void)
839: {
840: key_dest = key_menu;
841: m_state = m_video;
842: m_entersound = true;
843: }
844:
845:
846: void M_Video_Draw (void)
847: {
848: (*vid_menudrawfn) ();
849: }
850:
851:
852: void M_Video_Key (int key)
853: {
854: (*vid_menukeyfn) (key);
855: }
856:
857: //=============================================================================
858: /* HELP MENU */
859:
860: int help_page;
861: #define NUM_HELP_PAGES 6
862:
863:
864: void M_Menu_Help_f (void)
865: {
866: key_dest = key_menu;
867: m_state = m_help;
868: m_entersound = true;
869: help_page = 0;
870: }
871:
872:
873:
874: void M_Help_Draw (void)
875: {
876: M_DrawPic (0, 0, Draw_CachePic ( va("gfx/help%i.lmp", help_page)) );
877: }
878:
879:
880: void M_Help_Key (int key)
881: {
882: switch (key)
883: {
884: case K_ESCAPE:
885: M_Menu_Main_f ();
886: break;
887:
888: case K_UPARROW:
889: case K_RIGHTARROW:
890: m_entersound = true;
891: if (++help_page >= NUM_HELP_PAGES)
892: help_page = 0;
893: break;
894:
895: case K_DOWNARROW:
896: case K_LEFTARROW:
897: m_entersound = true;
898: if (--help_page < 0)
899: help_page = NUM_HELP_PAGES-1;
900: break;
901: }
902:
903: }
904:
905: //=============================================================================
906: /* QUIT MENU */
907:
908: int msgNumber;
909: int m_quit_prevstate;
910: qboolean wasInMenus;
911:
912: char *quitMessage [] =
913: {
914: /* .........1.........2.... */
915: " Are you gonna quit ",
916: " this game just like ",
917: " everything else? ",
918: " ",
919:
920: " Milord, methinks that ",
921: " thou art a lowly ",
922: " quitter. Is this true? ",
923: " ",
924:
925: " Do I need to bust your ",
926: " face open for trying ",
927: " to quit? ",
928: " ",
929:
930: " Man, I oughta smack you",
931: " for trying to quit! ",
932: " Press Y to get ",
933: " smacked out. ",
934:
935: " Press Y to quit like a ",
936: " big loser in life. ",
937: " Press N to stay proud ",
938: " and successful! ",
939:
940: " If you press Y to ",
941: " quit, I will summon ",
942: " Satan all over your ",
943: " hard drive! ",
944:
945: " Um, Asmodeus dislikes ",
946: " his children trying to ",
947: " quit. Press Y to return",
948: " to your Tinkertoys. ",
949:
950: " If you quit now, I'll ",
951: " throw a blanket-party ",
952: " for you next time! ",
953: " "
954: };
955:
956: void M_Menu_Quit_f (void)
957: {
958: if (m_state == m_quit)
959: return;
960: wasInMenus = (key_dest == key_menu);
961: key_dest = key_menu;
962: m_quit_prevstate = m_state;
963: m_state = m_quit;
964: m_entersound = true;
965: msgNumber = rand()&7;
966: }
967:
968:
969: void M_Quit_Key (int key)
970: {
971: switch (key)
972: {
973: case K_ESCAPE:
974: case 'n':
975: case 'N':
976: if (wasInMenus)
977: {
978: m_state = m_quit_prevstate;
979: m_entersound = true;
980: }
981: else
982: {
983: key_dest = key_game;
984: m_state = m_none;
985: }
986: break;
987:
988: case 'Y':
989: case 'y':
990: key_dest = key_console;
991: CL_Disconnect ();
992: Sys_Quit ();
993: break;
994:
995: default:
996: break;
997: }
998:
999: }
1000:
1001: void M_Menu_SinglePlayer_f (void) {
1002: m_state = m_singleplayer;
1003: }
1004:
1005: void M_SinglePlayer_Draw (void) {
1006: qpic_t *p;
1007:
1008: M_DrawTransPic (16, 4, Draw_CachePic ("gfx/qplaque.lmp") );
1009: // M_DrawTransPic (16, 4, Draw_CachePic ("gfx/qplaque.lmp") );
1010: p = Draw_CachePic ("gfx/ttl_sgl.lmp");
1011: M_DrawPic ( (320-p->width)/2, 4, p);
1012: // M_DrawTransPic (72, 32, Draw_CachePic ("gfx/sp_menu.lmp") );
1013:
1014: M_DrawTextBox (60, 10*8, 23, 4);
1015: M_PrintWhite (92, 12*8, "QuakeWorld is for");
1016: M_PrintWhite (88, 13*8, "Internet play only");
1017:
1018: }
1019:
1020: void M_SinglePlayer_Key (key) {
1021: if (key == K_ESCAPE || key==K_ENTER)
1022: m_state = m_main;
1023: }
1024:
1025: void M_Menu_MultiPlayer_f (void) {
1026: m_state = m_multiplayer;
1027: }
1028:
1029: void M_MultiPlayer_Draw (void) {
1030: qpic_t *p;
1031:
1032: M_DrawTransPic (16, 4, Draw_CachePic ("gfx/qplaque.lmp") );
1033: // M_DrawTransPic (16, 4, Draw_CachePic ("gfx/qplaque.lmp") );
1034: p = Draw_CachePic ("gfx/p_multi.lmp");
1035: M_DrawPic ( (320-p->width)/2, 4, p);
1036: // M_DrawTransPic (72, 32, Draw_CachePic ("gfx/sp_menu.lmp") );
1037:
1038: M_DrawTextBox (46, 8*8, 27, 9);
1039: M_PrintWhite (72, 10*8, "If you want to find QW ");
1040: M_PrintWhite (72, 11*8, "games, head on over to: ");
1041: M_Print (72, 12*8, " www.quakeworld.net ");
1042: M_PrintWhite (72, 13*8, " or ");
1043: M_Print (72, 14*8, " www.quakespy.com ");
1044: M_PrintWhite (72, 15*8, "For pointers on getting ");
1045: M_PrintWhite (72, 16*8, " started! ");
1046: }
1047:
1048: void M_MultiPlayer_Key (key) {
1049: if (key == K_ESCAPE || key==K_ENTER)
1050: m_state = m_main;
1051: }
1052:
1053: void M_Quit_Draw (void)
1054: {
1055: #define VSTR(x) #x
1056: #define VSTR2(x) VSTR(x)
1057: char *cmsg[] = {
1058: // 0123456789012345678901234567890123456789
1059: "0 QuakeWorld",
1060: "1 version " VSTR2(VERSION) " by id Software",
1061: "0Programming",
1062: "1 John Carmack Michael Abrash",
1063: "1 John Cash Christian Antkow",
1064: "0Additional Programming",
1065: "1 Dave 'Zoid' Kirsch",
1066: "1 Jack 'morbid' Mathews",
1067: "0Id Software is not responsible for",
1068: "0providing technical support for",
1069: "0QUAKEWORLD(tm). (c)1996 Id Software,",
1070: "0Inc. All Rights Reserved.",
1071: "0QUAKEWORLD(tm) is a trademark of Id",
1072: "0Software, Inc.",
1073: "1NOTICE: THE COPYRIGHT AND TRADEMARK",
1074: "1NOTICES APPEARING IN YOUR COPY OF",
1075: "1QUAKE(r) ARE NOT MODIFIED BY THE USE",
1076: "1OF QUAKEWORLD(tm) AND REMAIN IN FULL",
1077: "1FORCE.",
1078: "0NIN(r) is a registered trademark",
1079: "0licensed to Nothing Interactive, Inc.",
1080: "0All rights reserved. Press y to exit",
1081: NULL };
1082: char **p;
1083: int y;
1084:
1085: if (wasInMenus)
1086: {
1087: m_state = m_quit_prevstate;
1088: m_recursiveDraw = true;
1089: M_Draw ();
1090: m_state = m_quit;
1091: }
1092: #if 1
1093: M_DrawTextBox (0, 0, 38, 23);
1094: y = 12;
1095: for (p = cmsg; *p; p++, y += 8) {
1096: if (**p == '0')
1097: M_PrintWhite (16, y, *p + 1);
1098: else
1099: M_Print (16, y, *p + 1);
1100: }
1101: #else
1102: M_DrawTextBox (56, 76, 24, 4);
1103: M_Print (64, 84, quitMessage[msgNumber*4+0]);
1104: M_Print (64, 92, quitMessage[msgNumber*4+1]);
1105: M_Print (64, 100, quitMessage[msgNumber*4+2]);
1106: M_Print (64, 108, quitMessage[msgNumber*4+3]);
1107: #endif
1108: }
1109:
1110:
1111:
1112: //=============================================================================
1113: /* Menu Subsystem */
1114:
1115:
1116: void M_Init (void)
1117: {
1118: Cmd_AddCommand ("togglemenu", M_ToggleMenu_f);
1119:
1120: Cmd_AddCommand ("menu_main", M_Menu_Main_f);
1121: Cmd_AddCommand ("menu_options", M_Menu_Options_f);
1122: Cmd_AddCommand ("menu_keys", M_Menu_Keys_f);
1123: Cmd_AddCommand ("menu_video", M_Menu_Video_f);
1124: Cmd_AddCommand ("help", M_Menu_Help_f);
1125: Cmd_AddCommand ("menu_quit", M_Menu_Quit_f);
1126: }
1127:
1128:
1129: void M_Draw (void)
1130: {
1131: if (m_state == m_none || key_dest != key_menu)
1132: return;
1133:
1134: if (!m_recursiveDraw)
1135: {
1136: scr_copyeverything = 1;
1137:
1138: if (scr_con_current)
1139: {
1140: Draw_ConsoleBackground (vid.height);
1141: VID_UnlockBuffer ();
1142: S_ExtraUpdate ();
1143: VID_LockBuffer ();
1144: }
1145: else
1146: Draw_FadeScreen ();
1147:
1148: scr_fullupdate = 0;
1149: }
1150: else
1151: {
1152: m_recursiveDraw = false;
1153: }
1154:
1155: switch (m_state)
1156: {
1157: case m_none:
1158: break;
1159:
1160: case m_main:
1161: M_Main_Draw ();
1162: break;
1163:
1164: case m_singleplayer:
1165: M_SinglePlayer_Draw ();
1166: break;
1167:
1168: case m_load:
1169: // M_Load_Draw ();
1170: break;
1171:
1172: case m_save:
1173: // M_Save_Draw ();
1174: break;
1175:
1176: case m_multiplayer:
1177: M_MultiPlayer_Draw ();
1178: break;
1179:
1180: case m_setup:
1181: // M_Setup_Draw ();
1182: break;
1183:
1184: case m_net:
1185: // M_Net_Draw ();
1186: break;
1187:
1188: case m_options:
1189: M_Options_Draw ();
1190: break;
1191:
1192: case m_keys:
1193: M_Keys_Draw ();
1194: break;
1195:
1196: case m_video:
1197: M_Video_Draw ();
1198: break;
1199:
1200: case m_help:
1201: M_Help_Draw ();
1202: break;
1203:
1204: case m_quit:
1205: M_Quit_Draw ();
1206: break;
1207:
1208: case m_serialconfig:
1209: // M_SerialConfig_Draw ();
1210: break;
1211:
1212: case m_modemconfig:
1213: // M_ModemConfig_Draw ();
1214: break;
1215:
1216: case m_lanconfig:
1217: // M_LanConfig_Draw ();
1218: break;
1219:
1220: case m_gameoptions:
1221: // M_GameOptions_Draw ();
1222: break;
1223:
1224: case m_search:
1225: // M_Search_Draw ();
1226: break;
1227:
1228: case m_slist:
1229: // M_ServerList_Draw ();
1230: break;
1231: }
1232:
1233: if (m_entersound)
1234: {
1235: S_LocalSound ("misc/menu2.wav");
1236: m_entersound = false;
1237: }
1238:
1239: VID_UnlockBuffer ();
1240: S_ExtraUpdate ();
1241: VID_LockBuffer ();
1242: }
1243:
1244:
1245: void M_Keydown (int key)
1246: {
1247: switch (m_state)
1248: {
1249: case m_none:
1250: return;
1251:
1252: case m_main:
1253: M_Main_Key (key);
1254: return;
1255:
1256: case m_singleplayer:
1257: M_SinglePlayer_Key (key);
1258: return;
1259:
1260: case m_load:
1261: // M_Load_Key (key);
1262: return;
1263:
1264: case m_save:
1265: // M_Save_Key (key);
1266: return;
1267:
1268: case m_multiplayer:
1269: M_MultiPlayer_Key (key);
1270: return;
1271:
1272: case m_setup:
1273: // M_Setup_Key (key);
1274: return;
1275:
1276: case m_net:
1277: // M_Net_Key (key);
1278: return;
1279:
1280: case m_options:
1281: M_Options_Key (key);
1282: return;
1283:
1284: case m_keys:
1285: M_Keys_Key (key);
1286: return;
1287:
1288: case m_video:
1289: M_Video_Key (key);
1290: return;
1291:
1292: case m_help:
1293: M_Help_Key (key);
1294: return;
1295:
1296: case m_quit:
1297: M_Quit_Key (key);
1298: return;
1299:
1300: case m_serialconfig:
1301: // M_SerialConfig_Key (key);
1302: return;
1303:
1304: case m_modemconfig:
1305: // M_ModemConfig_Key (key);
1306: return;
1307:
1308: case m_lanconfig:
1309: // M_LanConfig_Key (key);
1310: return;
1311:
1312: case m_gameoptions:
1313: // M_GameOptions_Key (key);
1314: return;
1315:
1316: case m_search:
1317: // M_Search_Key (key);
1318: break;
1319:
1320: case m_slist:
1321: // M_ServerList_Key (key);
1322: return;
1323: }
1324: }
1325:
1326:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.