|
|
1.1 root 1: #include "quakedef.h"
2:
3: 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;
4:
5: void M_Menu_Main_f (void);
6: void M_Menu_SinglePlayer_f (void);
7: void M_Menu_Load_f (void);
8: void M_Menu_Save_f (void);
9: void M_Menu_MultiPlayer_f (void);
10: void M_Menu_Setup_f (void);
11: void M_Menu_Net_f (void);
12: void M_Menu_Options_f (void);
13: void M_Menu_Keys_f (void);
14: void M_Menu_Video_f (void);
15: void M_Menu_Help_f (void);
16: void M_Menu_Quit_f (void);
17: void M_Menu_SerialConfig_f (void);
18: void M_Menu_ModemConfig_f (void);
19: void M_Menu_LanConfig_f (void);
20: void M_Menu_GameOptions_f (void);
21: void M_Menu_Search_f (void);
22: void M_Menu_ServerList_f (void);
23:
24: void M_Main_Draw (void);
25: void M_SinglePlayer_Draw (void);
26: void M_Load_Draw (void);
27: void M_Save_Draw (void);
28: void M_MultiPlayer_Draw (void);
29: void M_Setup_Draw (void);
30: void M_Net_Draw (void);
31: void M_Options_Draw (void);
32: void M_Keys_Draw (void);
33: void M_Video_Draw (void);
34: void M_Help_Draw (void);
35: void M_Quit_Draw (void);
36: void M_SerialConfig_Draw (void);
37: void M_ModemConfig_Draw (void);
38: void M_LanConfig_Draw (void);
39: void M_GameOptions_Draw (void);
40: void M_Search_Draw (void);
41: void M_ServerList_Draw (void);
42:
43: void M_Main_Key (int key);
44: void M_SinglePlayer_Key (int key);
45: void M_Load_Key (int key);
46: void M_Save_Key (int key);
47: void M_MultiPlayer_Key (int key);
48: void M_Setup_Key (int key);
49: void M_Net_Key (int key);
50: void M_Options_Key (int key);
51: void M_Keys_Key (int key);
52: void M_Video_Key (int key);
53: void M_Help_Key (int key);
54: void M_Quit_Key (int key);
55: void M_SerialConfig_Key (int key);
56: void M_ModemConfig_Key (int key);
57: void M_LanConfig_Key (int key);
58: void M_GameOptions_Key (int key);
59: void M_Search_Key (int key);
60: void M_ServerList_Key (int key);
61:
62: qboolean m_entersound; // play after drawing a frame, so caching
63: // won't disrupt the sound
64: qboolean m_recursiveDraw;
65:
66: #define StartingGame (m_multiplayer_cursor == 1)
67: #define JoiningGame (m_multiplayer_cursor == 0)
68: #define SerialConfig (m_net_cursor == 0)
69: #define DirectConfig (m_net_cursor == 1)
70: #define IPXConfig (m_net_cursor == 2)
71: #define TCPIPConfig (m_net_cursor == 3)
72:
73: void M_ConfigureNetSubsystem(void);
74:
75: //=============================================================================
76: /* Support Routines */
77:
78: typedef struct cachepic_s
79: {
80: char name[MAX_QPATH];
81: cache_user_t cache;
82: } cachepic_t;
83:
84: #define MAX_CACHED_PICS 128
85: cachepic_t menu_cachepics[MAX_CACHED_PICS];
86: int menu_numcachepics;
87:
88:
89: /*
90: ================
91: M_CachePic
92: ================
93: */
94: qpic_t *M_CachePic (char *path)
95: {
96: cachepic_t *pic;
97: int i;
98: qpic_t *dat;
99:
100: for (pic=menu_cachepics, i=0 ; i<menu_numcachepics ; pic++, i++)
101: if (!strcmp (path, pic->name))
102: break;
103:
104: if (i == menu_numcachepics)
105: {
106: if (menu_numcachepics == MAX_CACHED_PICS)
107: Sys_Error ("menu_numcachepics == MAX_CACHED_PICS");
108: menu_numcachepics++;
109: strcpy (pic->name, path);
110: }
111:
112: dat = Cache_Check (&pic->cache);
113: if (dat)
114: return dat;
115:
116: //
117: // load the pic from disk
118: //
119: COM_LoadCacheFile (path, &pic->cache);
120:
121: dat = (qpic_t *)pic->cache.data;
122: if (!dat)
123: Sys_Error ("M_CachePic: failed to load %s", path);
124:
125: SwapPic (dat);
126:
127: return dat;
128: }
129:
130: /*
131: ================
132: M_DrawCharacter
133:
134: Draws one solid graphics character
135: ================
136: */
137: void M_DrawCharacter (int cx, int line, int num)
138: {
139: Draw_Character ( cx + ((vid.width - 320)>>1), line, num);
140: }
141:
142: void M_Print (int cx, int cy, char *str)
143: {
144: while (*str)
145: {
146: M_DrawCharacter (cx, cy, (*str)+128);
147: str++;
148: cx += 8;
149: }
150: }
151:
152: void M_PrintWhite (int cx, int cy, char *str)
153: {
154: while (*str)
155: {
156: M_DrawCharacter (cx, cy, *str);
157: str++;
158: cx += 8;
159: }
160: }
161:
162: void M_DrawTransPic (int x, int y, qpic_t *pic)
163: {
164: Draw_TransPic (x + ((vid.width - 320)>>1), y, pic);
165: }
166:
167: void M_DrawPic (int x, int y, qpic_t *pic)
168: {
169: Draw_Pic (x + ((vid.width - 320)>>1), y, pic);
170: }
171:
172: byte identityTable[256];
173: byte translationTable[256];
174:
175: void M_BuildTranslationTable(int top, int bottom)
176: {
177: int j;
178: byte *dest, *source;
179:
180: for (j = 0; j < 256; j++)
181: identityTable[j] = j;
182: dest = translationTable;
183: source = identityTable;
184: memcpy (dest, source, 256);
185:
186: if (top < 128) // the artists made some backwards ranges. sigh.
187: memcpy (dest + TOP_RANGE, source + top, 16);
188: else
189: for (j=0 ; j<16 ; j++)
190: dest[TOP_RANGE+j] = source[top+15-j];
191:
192: if (bottom < 128)
193: memcpy (dest + BOTTOM_RANGE, source + bottom, 16);
194: else
195: for (j=0 ; j<16 ; j++)
196: dest[BOTTOM_RANGE+j] = source[bottom+15-j];
197: }
198:
199:
200: void M_DrawTransPicTranslate (int x, int y, qpic_t *pic)
201: {
202: Draw_TransPicTranslate (x + ((vid.width - 320)>>1), y, pic, translationTable);
203: }
204:
205:
206: void M_DrawTextBox (int x, int y, int width, int lines)
207: {
208: qpic_t *p;
209: int cx, cy;
210: int n;
211:
212: // draw left side
213: cx = x;
214: cy = y;
215: p = M_CachePic ("gfx/box_tl.lmp");
216: M_DrawTransPic (cx, cy, p);
217: p = M_CachePic ("gfx/box_ml.lmp");
218: for (n = 0; n < lines; n++)
219: {
220: cy += 8;
221: M_DrawTransPic (cx, cy, p);
222: }
223: p = M_CachePic ("gfx/box_bl.lmp");
224: M_DrawTransPic (cx, cy+8, p);
225:
226: // draw middle
227: cx += 8;
228: while (width > 0)
229: {
230: cy = y;
231: p = M_CachePic ("gfx/box_tm.lmp");
232: M_DrawTransPic (cx, cy, p);
233: p = M_CachePic ("gfx/box_mm.lmp");
234: for (n = 0; n < lines; n++)
235: {
236: cy += 8;
237: if (n == 1)
238: p = M_CachePic ("gfx/box_mm2.lmp");
239: M_DrawTransPic (cx, cy, p);
240: }
241: p = M_CachePic ("gfx/box_bm.lmp");
242: M_DrawTransPic (cx, cy+8, p);
243: width -= 2;
244: cx += 16;
245: }
246:
247: // draw right side
248: cy = y;
249: p = M_CachePic ("gfx/box_tr.lmp");
250: M_DrawTransPic (cx, cy, p);
251: p = M_CachePic ("gfx/box_mr.lmp");
252: for (n = 0; n < lines; n++)
253: {
254: cy += 8;
255: M_DrawTransPic (cx, cy, p);
256: }
257: p = M_CachePic ("gfx/box_br.lmp");
258: M_DrawTransPic (cx, cy+8, p);
259: }
260:
261: //=============================================================================
262:
263: int m_save_demonum;
264:
265: /*
266: ================
267: M_ToggleMenu_f
268: ================
269: */
270: void M_ToggleMenu_f (void)
271: {
272: m_entersound = true;
273:
274: if (key_dest == key_menu)
275: {
276: if (m_state != m_main)
277: {
278: M_Menu_Main_f ();
279: return;
280: }
281: key_dest = key_game;
282: m_state = m_none;
283: return;
284: }
285: if (key_dest == key_console)
286: {
287: Con_ToggleConsole_f ();
288: }
289: else
290: {
291: M_Menu_Main_f ();
292: }
293: }
294:
295:
296: //=============================================================================
297: /* MAIN MENU */
298:
299: int m_main_cursor;
300: #define MAIN_ITEMS 5
301:
302:
303: void M_Menu_Main_f (void)
304: {
305: if (key_dest != key_menu)
306: {
307: m_save_demonum = cls.demonum;
308: cls.demonum = -1;
309: }
310: key_dest = key_menu;
311: m_state = m_main;
312: m_entersound = true;
313: }
314:
315:
316: void M_Main_Draw (void)
317: {
318: int f;
319: qpic_t *p;
320:
321: M_DrawTransPic (16, 4, M_CachePic ("gfx/qplaque.lmp") );
322: p = M_CachePic ("gfx/ttl_main.lmp");
323: M_DrawPic ( (320-p->width)/2, 4, p);
324: M_DrawTransPic (72, 32, M_CachePic ("gfx/mainmenu.lmp") );
325:
326: f = (int)(host_time * 10)%6;
327:
328: M_DrawTransPic (54, 32 + m_main_cursor * 20,M_CachePic( va("gfx/menudot%i.lmp", f+1 ) ) );
329: }
330:
331:
332: void M_Main_Key (int key)
333: {
334: switch (key)
335: {
336: case K_ESCAPE:
337: key_dest = key_game;
338: m_state = m_none;
339: cls.demonum = m_save_demonum;
340: if (cls.demonum != -1 && !cls.demoplayback && cls.state != ca_connected)
341: CL_NextDemo ();
342: break;
343:
344: case K_DOWNARROW:
345: S_LocalSound ("misc/menu1.wav");
346: if (++m_main_cursor >= MAIN_ITEMS)
347: m_main_cursor = 0;
348: break;
349:
350: case K_UPARROW:
351: S_LocalSound ("misc/menu1.wav");
352: if (--m_main_cursor < 0)
353: m_main_cursor = MAIN_ITEMS - 1;
354: break;
355:
356: case K_ENTER:
357: m_entersound = true;
358:
359: switch (m_main_cursor)
360: {
361: case 0:
362: M_Menu_SinglePlayer_f ();
363: break;
364:
365: case 1:
366: M_Menu_MultiPlayer_f ();
367: break;
368:
369: case 2:
370: M_Menu_Options_f ();
371: break;
372:
373: case 3:
374: M_Menu_Help_f ();
375: break;
376:
377: case 4:
378: M_Menu_Quit_f ();
379: break;
380: }
381: }
382: }
383:
384: //=============================================================================
385: /* SINGLE PLAYER MENU */
386:
387: int m_singleplayer_cursor;
388: #define SINGLEPLAYER_ITEMS 3
389:
390:
391: void M_Menu_SinglePlayer_f (void)
392: {
393: key_dest = key_menu;
394: m_state = m_singleplayer;
395: m_entersound = true;
396: }
397:
398:
399: void M_SinglePlayer_Draw (void)
400: {
401: int f;
402: qpic_t *p;
403:
404: M_DrawTransPic (16, 4, M_CachePic ("gfx/qplaque.lmp") );
405: p = M_CachePic ("gfx/ttl_sgl.lmp");
406: M_DrawPic ( (320-p->width)/2, 4, p);
407: M_DrawTransPic (72, 32, M_CachePic ("gfx/sp_menu.lmp") );
408:
409: f = (int)(host_time * 10)%6;
410:
411: M_DrawTransPic (54, 32 + m_singleplayer_cursor * 20,M_CachePic( va("gfx/menudot%i.lmp", f+1 ) ) );
412: }
413:
414:
415: void M_SinglePlayer_Key (int key)
416: {
417: switch (key)
418: {
419: case K_ESCAPE:
420: M_Menu_Main_f ();
421: break;
422:
423: case K_DOWNARROW:
424: S_LocalSound ("misc/menu1.wav");
425: if (++m_singleplayer_cursor >= SINGLEPLAYER_ITEMS)
426: m_singleplayer_cursor = 0;
427: break;
428:
429: case K_UPARROW:
430: S_LocalSound ("misc/menu1.wav");
431: if (--m_singleplayer_cursor < 0)
432: m_singleplayer_cursor = SINGLEPLAYER_ITEMS - 1;
433: break;
434:
435: case K_ENTER:
436: m_entersound = true;
437:
438: switch (m_singleplayer_cursor)
439: {
440: case 0:
441: if (sv.active)
442: if (!SCR_ModalMessage("Are you sure you want to\nstart a new game?\n"))
443: break;
444: key_dest = key_game;
445: if (sv.active)
446: Cbuf_AddText ("disconnect\n");
447: Cbuf_AddText ("maxplayers 1\n");
448: Cbuf_AddText ("map start\n");
449: break;
450:
451: case 1:
452: M_Menu_Load_f ();
453: break;
454:
455: case 2:
456: M_Menu_Save_f ();
457: break;
458: }
459: }
460: }
461:
462: //=============================================================================
463: /* LOAD/SAVE MENU */
464:
465: int load_cursor; // 0 < load_cursor < MAX_SAVEGAMES
466:
467: #define MAX_SAVEGAMES 12
468: char m_filenames[MAX_SAVEGAMES][SAVEGAME_COMMENT_LENGTH+1];
469: int loadable[MAX_SAVEGAMES];
470:
471: void M_ScanSaves (void)
472: {
473: int i, j;
474: char name[MAX_OSPATH];
475: FILE *f;
476: int version;
477:
478: for (i=0 ; i<MAX_SAVEGAMES ; i++)
479: {
480: strcpy (m_filenames[i], "--- UNUSED SLOT ---");
481: loadable[i] = false;
482: sprintf (name, "%s/s%i.sav", com_gamedir, i);
483: f = fopen (name, "r");
484: if (!f)
485: continue;
486: fscanf (f, "%i\n", &version);
487: fscanf (f, "%79s\n", name);
488: strncpy (m_filenames[i], name, sizeof(m_filenames[i])-1);
489:
490: // change _ back to space
491: for (j=0 ; j<SAVEGAME_COMMENT_LENGTH ; j++)
492: if (m_filenames[i][j] == '_')
493: m_filenames[i][j] = ' ';
494: loadable[i] = true;
495: fclose (f);
496: }
497: }
498:
499: void M_Menu_Load_f (void)
500: {
501: m_entersound = true;
502: m_state = m_load;
503: key_dest = key_menu;
504: M_ScanSaves ();
505: }
506:
507:
508: void M_Menu_Save_f (void)
509: {
510: if (!sv.active)
511: return;
512: if (cl.intermission)
513: return;
514: if (svs.maxclients != 1)
515: return;
516: m_entersound = true;
517: m_state = m_save;
518: key_dest = key_menu;
519: M_ScanSaves ();
520: }
521:
522:
523: void M_Load_Draw (void)
524: {
525: int i;
526: qpic_t *p;
527:
528: p = M_CachePic ("gfx/p_load.lmp");
529: M_DrawPic ( (320-p->width)/2, 4, p);
530:
531: for (i=0 ; i< MAX_SAVEGAMES; i++)
532: M_Print (16, 32 + 8*i, m_filenames[i]);
533:
534: // line cursor
535: M_DrawCharacter (8, 32 + load_cursor*8, 12+((int)(realtime*4)&1));
536: }
537:
538:
539: void M_Save_Draw (void)
540: {
541: int i;
542: qpic_t *p;
543:
544: p = M_CachePic ("gfx/p_save.lmp");
545: M_DrawPic ( (320-p->width)/2, 4, p);
546:
547: for (i=0 ; i<MAX_SAVEGAMES ; i++)
548: M_Print (16, 32 + 8*i, m_filenames[i]);
549:
550: // line cursor
551: M_DrawCharacter (8, 32 + load_cursor*8, 12+((int)(realtime*4)&1));
552: }
553:
554:
555: void M_Load_Key (int k)
556: {
557: switch (k)
558: {
559: case K_ESCAPE:
560: M_Menu_SinglePlayer_f ();
561: break;
562:
563: case K_ENTER:
564: S_LocalSound ("misc/menu2.wav");
565: if (!loadable[load_cursor])
566: return;
567: m_state = m_none;
568: key_dest = key_game;
569:
570: // Host_Loadgame_f can't bring up the loading plaque because too much
571: // stack space has been used, so do it now
572: SCR_BeginLoadingPlaque ();
573:
574: // issue the load command
575: Cbuf_AddText (va ("load s%i\n", load_cursor) );
576: return;
577:
578: case K_UPARROW:
579: case K_LEFTARROW:
580: S_LocalSound ("misc/menu1.wav");
581: load_cursor--;
582: if (load_cursor < 0)
583: load_cursor = MAX_SAVEGAMES-1;
584: break;
585:
586: case K_DOWNARROW:
587: case K_RIGHTARROW:
588: S_LocalSound ("misc/menu1.wav");
589: load_cursor++;
590: if (load_cursor >= MAX_SAVEGAMES)
591: load_cursor = 0;
592: break;
593: }
594: }
595:
596:
597: void M_Save_Key (int k)
598: {
599: switch (k)
600: {
601: case K_ESCAPE:
602: M_Menu_SinglePlayer_f ();
603: break;
604:
605: case K_ENTER:
606: m_state = m_none;
607: key_dest = key_game;
608: Cbuf_AddText (va("save s%i\n", load_cursor));
609: return;
610:
611: case K_UPARROW:
612: case K_LEFTARROW:
613: S_LocalSound ("misc/menu1.wav");
614: load_cursor--;
615: if (load_cursor < 0)
616: load_cursor = MAX_SAVEGAMES-1;
617: break;
618:
619: case K_DOWNARROW:
620: case K_RIGHTARROW:
621: S_LocalSound ("misc/menu1.wav");
622: load_cursor++;
623: if (load_cursor >= MAX_SAVEGAMES)
624: load_cursor = 0;
625: break;
626: }
627: }
628:
629: //=============================================================================
630: /* MULTIPLAYER MENU */
631:
632: int m_multiplayer_cursor;
633: #define MULTIPLAYER_ITEMS 3
634:
635:
636: void M_Menu_MultiPlayer_f (void)
637: {
638: key_dest = key_menu;
639: m_state = m_multiplayer;
640: m_entersound = true;
641: }
642:
643:
644: void M_MultiPlayer_Draw (void)
645: {
646: int f;
647: qpic_t *p;
648:
649: M_DrawTransPic (16, 4, M_CachePic ("gfx/qplaque.lmp") );
650: p = M_CachePic ("gfx/p_multi.lmp");
651: M_DrawPic ( (320-p->width)/2, 4, p);
652: M_DrawTransPic (72, 32, M_CachePic ("gfx/mp_menu.lmp") );
653:
654: f = (int)(host_time * 10)%6;
655:
656: M_DrawTransPic (54, 32 + m_multiplayer_cursor * 20,M_CachePic( va("gfx/menudot%i.lmp", f+1 ) ) );
657: }
658:
659:
660: void M_MultiPlayer_Key (int key)
661: {
662: switch (key)
663: {
664: case K_ESCAPE:
665: M_Menu_Main_f ();
666: break;
667:
668: case K_DOWNARROW:
669: S_LocalSound ("misc/menu1.wav");
670: if (++m_multiplayer_cursor >= MULTIPLAYER_ITEMS)
671: m_multiplayer_cursor = 0;
672: break;
673:
674: case K_UPARROW:
675: S_LocalSound ("misc/menu1.wav");
676: if (--m_multiplayer_cursor < 0)
677: m_multiplayer_cursor = MULTIPLAYER_ITEMS - 1;
678: break;
679:
680: case K_ENTER:
681: m_entersound = true;
682: switch (m_multiplayer_cursor)
683: {
684: case 0:
1.1.1.2 ! root 685: M_Menu_Net_f ();
1.1 root 686: break;
687:
688: case 1:
1.1.1.2 ! root 689: M_Menu_Net_f ();
1.1 root 690: break;
691:
692: case 2:
693: M_Menu_Setup_f ();
694: break;
695: }
696: }
697: }
698:
699: //=============================================================================
700: /* SETUP MENU */
701:
702: int setup_cursor = 4;
703: int setup_cursor_table[] = {40, 56, 80, 104, 140};
704:
705: char setup_hostname[16];
706: char setup_myname[16];
707: int setup_oldtop;
708: int setup_oldbottom;
709: int setup_top;
710: int setup_bottom;
711:
712: #define NUM_SETUP_CMDS 5
713:
714: void M_Menu_Setup_f (void)
715: {
716: key_dest = key_menu;
717: m_state = m_setup;
718: m_entersound = true;
719: Q_strcpy(setup_myname, cl_name.string);
720: Q_strcpy(setup_hostname, hostname.string);
721: setup_top = setup_oldtop = ((int)cl_color.value) >> 4;
722: setup_bottom = setup_oldbottom = ((int)cl_color.value) & 15;
723: }
724:
725:
726: void M_Setup_Draw (void)
727: {
728: qpic_t *p;
729:
730: M_DrawTransPic (16, 4, M_CachePic ("gfx/qplaque.lmp") );
731: p = M_CachePic ("gfx/p_multi.lmp");
732: M_DrawPic ( (320-p->width)/2, 4, p);
733:
734: M_Print (64, 40, "Hostname");
735: M_DrawTextBox (160, 32, 16, 1);
736: M_Print (168, 40, setup_hostname);
737:
738: M_Print (64, 56, "Your name");
739: M_DrawTextBox (160, 48, 16, 1);
740: M_Print (168, 56, setup_myname);
741:
742: M_Print (64, 80, "Shirt color");
743: M_Print (64, 104, "Pants color");
744:
745: M_DrawTextBox (64, 140-8, 14, 1);
746: M_Print (72, 140, "Accept Changes");
747:
748: p = M_CachePic ("gfx/bigbox.lmp");
749: M_DrawTransPic (160, 64, p);
750: p = M_CachePic ("gfx/menuplyr.lmp");
751: M_BuildTranslationTable(setup_top*16, setup_bottom*16);
752: M_DrawTransPicTranslate (172, 72, p);
753:
754: M_DrawCharacter (56, setup_cursor_table [setup_cursor], 12+((int)(realtime*4)&1));
755:
756: if (setup_cursor == 0)
757: M_DrawCharacter (168 + 8*strlen(setup_hostname), setup_cursor_table [setup_cursor], 10+((int)(realtime*4)&1));
758:
759: if (setup_cursor == 1)
760: M_DrawCharacter (168 + 8*strlen(setup_myname), setup_cursor_table [setup_cursor], 10+((int)(realtime*4)&1));
761: }
762:
763:
764: void M_Setup_Key (int k)
765: {
766: int l;
767:
768: switch (k)
769: {
770: case K_ESCAPE:
771: M_Menu_MultiPlayer_f ();
772: break;
773:
774: case K_UPARROW:
775: S_LocalSound ("misc/menu1.wav");
776: setup_cursor--;
777: if (setup_cursor < 0)
778: setup_cursor = NUM_SETUP_CMDS-1;
779: break;
780:
781: case K_DOWNARROW:
782: S_LocalSound ("misc/menu1.wav");
783: setup_cursor++;
784: if (setup_cursor >= NUM_SETUP_CMDS)
785: setup_cursor = 0;
786: break;
787:
788: case K_LEFTARROW:
789: if (setup_cursor < 2)
790: return;
791: S_LocalSound ("misc/menu3.wav");
792: if (setup_cursor == 2)
793: setup_top = setup_top - 1;
794: if (setup_cursor == 3)
795: setup_bottom = setup_bottom - 1;
796: break;
797: case K_RIGHTARROW:
798: if (setup_cursor < 2)
799: return;
800: forward:
801: S_LocalSound ("misc/menu3.wav");
802: if (setup_cursor == 2)
803: setup_top = setup_top + 1;
804: if (setup_cursor == 3)
805: setup_bottom = setup_bottom + 1;
806: break;
807:
808: case K_ENTER:
809: if (setup_cursor == 0 || setup_cursor == 1)
810: return;
811:
812: if (setup_cursor == 2 || setup_cursor == 3)
813: goto forward;
814:
815: // setup_cursor == 4 (OK)
816: if (Q_strcmp(cl_name.string, setup_myname) != 0)
817: Cbuf_AddText ( va ("name \"%s\"\n", setup_myname) );
818: if (Q_strcmp(hostname.string, setup_hostname) != 0)
819: Cvar_Set("hostname", setup_hostname);
820: if (setup_top != setup_oldtop || setup_bottom != setup_oldbottom)
821: Cbuf_AddText( va ("color %i %i\n", setup_top, setup_bottom) );
822: m_entersound = true;
823: M_Menu_MultiPlayer_f ();
824: break;
825:
826: case K_BACKSPACE:
827: if (setup_cursor == 0)
828: {
829: if (strlen(setup_hostname))
830: setup_hostname[strlen(setup_hostname)-1] = 0;
831: }
832:
833: if (setup_cursor == 1)
834: {
835: if (strlen(setup_myname))
836: setup_myname[strlen(setup_myname)-1] = 0;
837: }
838: break;
839:
840: default:
841: if (k < 32 || k > 127)
842: break;
843: if (setup_cursor == 0)
844: {
845: l = strlen(setup_hostname);
846: if (l < 15)
847: {
848: setup_hostname[l+1] = 0;
849: setup_hostname[l] = k;
850: }
851: }
852: if (setup_cursor == 1)
853: {
854: l = strlen(setup_myname);
855: if (l < 15)
856: {
857: setup_myname[l+1] = 0;
858: setup_myname[l] = k;
859: }
860: }
861: }
862:
863: if (setup_top > 13)
864: setup_top = 0;
865: if (setup_top < 0)
866: setup_top = 13;
867: if (setup_bottom > 13)
868: setup_bottom = 0;
869: if (setup_bottom < 0)
870: setup_bottom = 13;
871: }
872:
873: //=============================================================================
874: /* NET MENU */
875:
876: int m_net_cursor;
877: int m_net_items;
878: int m_net_saveHeight;
879:
880: char *net_helpMessage [] =
881: {
882: /* .........1.........2.... */
883: " ",
884: " Two computers connected",
885: " through two modems. ",
886: " ",
887:
888: " ",
889: " Two computers connected",
890: " by a null-modem cable. ",
891: " ",
892:
893: " Novell network LANs ",
894: " or Windows 95 DOS-box. ",
895: " ",
896: "(LAN=Local Area Network)",
897:
898: " Commonly used to play ",
899: " over the Internet, but ",
900: " also used on a Local ",
1.1.1.2 ! root 901: " Area Network. ",
! 902:
! 903: " This is a man-option ",
! 904: "for experts only, so get",
! 905: " your sorry ass back up ",
! 906: " to the baby options! "
1.1 root 907: };
908:
909: void M_Menu_Net_f (void)
910: {
911: key_dest = key_menu;
912: m_state = m_net;
913: m_entersound = true;
1.1.1.2 ! root 914: #if 0 // JDC
! 915: if (m_multiplayer_cursor == 2)
! 916: m_net_items = 4;
! 917: else
! 918: m_net_items = 5;
! 919: #endif
! 920: m_net_items = 4;
1.1 root 921:
922: if (m_net_cursor >= m_net_items)
923: m_net_cursor = 0;
924: m_net_cursor--;
925: M_Net_Key (K_DOWNARROW);
926: }
927:
928:
929: void M_Net_Draw (void)
930: {
931: int f;
932: qpic_t *p;
933:
934: M_DrawTransPic (16, 4, M_CachePic ("gfx/qplaque.lmp") );
935: p = M_CachePic ("gfx/p_multi.lmp");
936: M_DrawPic ( (320-p->width)/2, 4, p);
937:
938: f = 32;
939: if (serialAvailable)
940: p = M_CachePic ("gfx/netmen1.lmp");
941: else
942: p = M_CachePic ("gfx/dim_modm.lmp");
943: M_DrawTransPic (72, f, p);
944:
945: f += 19;
946: if (serialAvailable)
947: p = M_CachePic ("gfx/netmen2.lmp");
948: else
949: p = M_CachePic ("gfx/dim_drct.lmp");
950: M_DrawTransPic (72, f, p);
951:
952: f += 19;
953: if (ipxAvailable)
954: p = M_CachePic ("gfx/netmen3.lmp");
955: else
956: p = M_CachePic ("gfx/dim_ipx.lmp");
957: M_DrawTransPic (72, f, p);
958:
959: f += 19;
960: if (tcpipAvailable)
961: p = M_CachePic ("gfx/netmen4.lmp");
962: else
963: p = M_CachePic ("gfx/dim_tcp.lmp");
964: M_DrawTransPic (72, f, p);
965:
966: if (m_net_items == 5) // JDC, could just be removed
967: {
968: f += 19;
969: p = M_CachePic ("gfx/netmen5.lmp");
970: M_DrawTransPic (72, f, p);
971: }
972:
973: f = (320-26*8)/2;
974: M_DrawTextBox (f, 134, 24, 4);
975: f += 8;
976: M_Print (f, 142, net_helpMessage[m_net_cursor*4+0]);
977: M_Print (f, 150, net_helpMessage[m_net_cursor*4+1]);
978: M_Print (f, 158, net_helpMessage[m_net_cursor*4+2]);
979: M_Print (f, 166, net_helpMessage[m_net_cursor*4+3]);
980:
981: f = (int)(host_time * 10)%6;
982: M_DrawTransPic (54, 32 + m_net_cursor * 20,M_CachePic( va("gfx/menudot%i.lmp", f+1 ) ) );
983: }
984:
985:
986: void M_Net_Key (int k)
987: {
988: again:
989: switch (k)
990: {
991: case K_ESCAPE:
992: M_Menu_MultiPlayer_f ();
993: break;
994:
995: case K_DOWNARROW:
996: S_LocalSound ("misc/menu1.wav");
997: if (++m_net_cursor >= m_net_items)
998: m_net_cursor = 0;
999: break;
1000:
1001: case K_UPARROW:
1002: S_LocalSound ("misc/menu1.wav");
1003: if (--m_net_cursor < 0)
1004: m_net_cursor = m_net_items - 1;
1005: break;
1006:
1007: case K_ENTER:
1008: m_entersound = true;
1009:
1010: switch (m_net_cursor)
1011: {
1012: case 0:
1013: M_Menu_SerialConfig_f ();
1014: break;
1015:
1016: case 1:
1017: M_Menu_SerialConfig_f ();
1018: break;
1019:
1020: case 2:
1021: M_Menu_LanConfig_f ();
1022: break;
1023:
1024: case 3:
1025: M_Menu_LanConfig_f ();
1026: break;
1027:
1028: case 4:
1029: // multiprotocol
1030: break;
1031: }
1032: }
1033:
1034: if (m_net_cursor == 0 && !serialAvailable)
1035: goto again;
1036: if (m_net_cursor == 1 && !serialAvailable)
1037: goto again;
1038: if (m_net_cursor == 2 && !ipxAvailable)
1039: goto again;
1040: if (m_net_cursor == 3 && !tcpipAvailable)
1041: goto again;
1042: }
1043:
1044: //=============================================================================
1045: /* OPTIONS MENU */
1046:
1047: #define OPTIONS_ITEMS 13
1048: #define SLIDER_RANGE 10
1049:
1050: int options_cursor;
1051:
1052: void M_Menu_Options_f (void)
1053: {
1054: key_dest = key_menu;
1055: m_state = m_options;
1056: m_entersound = true;
1057: }
1058:
1059:
1060: void M_AdjustSliders (int dir)
1061: {
1062: S_LocalSound ("misc/menu3.wav");
1063:
1064: switch (options_cursor)
1065: {
1066: case 3: // screen size
1067: scr_viewsize.value += dir * 10;
1068: if (scr_viewsize.value < 30)
1069: scr_viewsize.value = 30;
1070: if (scr_viewsize.value > 120)
1071: scr_viewsize.value = 120;
1072: Cvar_SetValue ("viewsize", scr_viewsize.value);
1073: break;
1074: case 4: // gamma
1075: v_gamma.value -= dir * 0.05;
1076: if (v_gamma.value < 0.5)
1077: v_gamma.value = 0.5;
1078: if (v_gamma.value > 1)
1079: v_gamma.value = 1;
1080: Cvar_SetValue ("gamma", v_gamma.value);
1081: break;
1082: case 5: // mouse speed
1083: sensitivity.value += dir * 0.5;
1084: if (sensitivity.value < 1)
1085: sensitivity.value = 1;
1086: if (sensitivity.value > 6)
1087: sensitivity.value = 6;
1088: Cvar_SetValue ("sensitivity", sensitivity.value);
1089: break;
1090: case 6: // music volume
1091: bgmvolume.value += dir * 0.1;
1092: if (bgmvolume.value < 0)
1093: bgmvolume.value = 0;
1094: if (bgmvolume.value > 1)
1095: bgmvolume.value = 1;
1096: Cvar_SetValue ("bgmvolume", bgmvolume.value);
1097: break;
1098: case 7: // sfx volume
1099: volume.value += dir * 0.1;
1100: if (volume.value < 0)
1101: volume.value = 0;
1102: if (volume.value > 1)
1103: volume.value = 1;
1104: Cvar_SetValue ("volume", volume.value);
1105: break;
1106:
1107: case 8: // allways run
1108: if (cl_forwardspeed.value > 200)
1109: {
1110: Cvar_SetValue ("cl_forwardspeed", 200);
1111: Cvar_SetValue ("cl_backspeed", 200);
1112: }
1113: else
1114: {
1115: Cvar_SetValue ("cl_forwardspeed", 400);
1116: Cvar_SetValue ("cl_backspeed", 400);
1117: }
1118: break;
1119:
1120: case 9: // invert mouse
1121: Cvar_SetValue ("m_pitch", -m_pitch.value);
1122: break;
1123:
1124: case 10: // lookspring
1125: Cvar_SetValue ("lookspring", !lookspring.value);
1126: break;
1127:
1128: case 11: // lookstrafe
1129: Cvar_SetValue ("lookstrafe", !lookstrafe.value);
1130: break;
1131: }
1132: }
1133:
1134:
1135: void M_DrawSlider (int x, int y, float range)
1136: {
1137: int i;
1138:
1139: if (range < 0)
1140: range = 0;
1141: if (range > 1)
1142: range = 1;
1143: M_DrawCharacter (x-8, y, 128);
1144: for (i=0 ; i<SLIDER_RANGE ; i++)
1145: M_DrawCharacter (x + i*8, y, 129);
1146: M_DrawCharacter (x+i*8, y, 130);
1147: M_DrawCharacter (x + (SLIDER_RANGE-1)*8 * range, y, 131);
1148: }
1149:
1150: void M_DrawCheckbox (int x, int y, int on)
1151: {
1152: #if 0
1153: if (on)
1154: M_DrawCharacter (x, y, 131);
1155: else
1156: M_DrawCharacter (x, y, 129);
1157: #endif
1158: if (on)
1159: M_Print (x, y, "on");
1160: else
1161: M_Print (x, y, "off");
1162: }
1163:
1164: void M_Options_Draw (void)
1165: {
1166: float r;
1167: qpic_t *p;
1168:
1169: M_DrawTransPic (16, 4, M_CachePic ("gfx/qplaque.lmp") );
1170: p = M_CachePic ("gfx/p_option.lmp");
1171: M_DrawPic ( (320-p->width)/2, 4, p);
1172:
1173: M_Print (16, 32, " Customize controls");
1174: M_Print (16, 40, " Go to console");
1175: M_Print (16, 48, " Reset to defaults");
1176:
1177: M_Print (16, 56, " Screen size");
1178: r = (scr_viewsize.value - 30) / (120 - 30);
1179: M_DrawSlider (220, 56, r);
1180:
1181: M_Print (16, 64, " Brightness");
1182: r = (1.0 - v_gamma.value) / 0.5;
1183: M_DrawSlider (220, 64, r);
1184:
1185: M_Print (16, 72, " Mouse Speed");
1186: r = (sensitivity.value - 1)/5;
1187: M_DrawSlider (220, 72, r);
1188:
1189: M_Print (16, 80, " CD Music Volume");
1190: r = bgmvolume.value;
1191: M_DrawSlider (220, 80, r);
1192:
1193: M_Print (16, 88, " Sound Volume");
1194: r = volume.value;
1195: M_DrawSlider (220, 88, r);
1196:
1197: M_Print (16, 96, " Always Run");
1198: M_DrawCheckbox (220, 96, cl_forwardspeed.value > 200);
1199:
1200: M_Print (16, 104, " Invert Mouse");
1201: M_DrawCheckbox (220, 104, m_pitch.value < 0);
1202:
1203: M_Print (16, 112, " Lookspring");
1204: M_DrawCheckbox (220, 112, lookspring.value);
1205:
1206: M_Print (16, 120, " Lookstrafe");
1207: M_DrawCheckbox (220, 120, lookstrafe.value);
1208:
1209: if (vid_menudrawfn)
1210: M_Print (16, 128, " Video Options");
1211:
1212: // cursor
1213: M_DrawCharacter (200, 32 + options_cursor*8, 12+((int)(realtime*4)&1));
1214: }
1215:
1216:
1217: void M_Options_Key (int k)
1218: {
1219: switch (k)
1220: {
1221: case K_ESCAPE:
1222: M_Menu_Main_f ();
1223: break;
1224:
1225: case K_ENTER:
1226: m_entersound = true;
1227: switch (options_cursor)
1228: {
1229: case 0:
1230: M_Menu_Keys_f ();
1231: break;
1232: case 1:
1233: m_state = m_none;
1234: Con_ToggleConsole_f ();
1235: break;
1236: case 2:
1237: Cbuf_AddText ("exec default.cfg\n");
1238: break;
1239: case 12:
1240: M_Menu_Video_f ();
1241: break;
1242: default:
1243: M_AdjustSliders (1);
1244: break;
1245: }
1246: return;
1247:
1248: case K_UPARROW:
1249: S_LocalSound ("misc/menu1.wav");
1250: options_cursor--;
1251: if (options_cursor < 0)
1252: options_cursor = OPTIONS_ITEMS-1;
1253: break;
1254:
1255: case K_DOWNARROW:
1256: S_LocalSound ("misc/menu1.wav");
1257: options_cursor++;
1258: if (options_cursor >= OPTIONS_ITEMS)
1259: options_cursor = 0;
1260: break;
1261:
1262: case K_LEFTARROW:
1263: M_AdjustSliders (-1);
1264: break;
1265:
1266: case K_RIGHTARROW:
1267: M_AdjustSliders (1);
1268: break;
1269: }
1270:
1271: if (options_cursor == 12 && vid_menudrawfn == NULL)
1272: if (k == K_UPARROW)
1273: options_cursor = 11;
1274: else
1275: options_cursor = 0;
1276: }
1277:
1278: //=============================================================================
1279: /* KEYS MENU */
1280:
1281: char *bindnames[][2] =
1282: {
1283: {"+attack", "attack"},
1284: {"impulse 10", "change weapon"},
1285: {"+jump", "jump / swim up"},
1286: {"+forward", "walk forward"},
1287: {"+back", "backpedal"},
1288: {"+left", "turn left"},
1289: {"+right", "turn right"},
1290: {"+speed", "run"},
1291: {"+moveleft", "step left"},
1292: {"+moveright", "step right"},
1293: {"+strafe", "sidestep"},
1294: {"+lookup", "look up"},
1295: {"+lookdown", "look down"},
1296: {"centerview", "center view"},
1297: {"+mlook", "mouse look"},
1298: {"+klook", "keyboard look"},
1299: {"+moveup", "swim up"},
1300: {"+movedown", "swim down"}
1301: };
1302:
1303: #define NUMCOMMANDS (sizeof(bindnames)/sizeof(bindnames[0]))
1304:
1305: int keys_cursor;
1306: int bind_grab;
1307:
1308: void M_Menu_Keys_f (void)
1309: {
1310: key_dest = key_menu;
1311: m_state = m_keys;
1312: m_entersound = true;
1313: }
1314:
1315:
1316: void M_FindKeysForCommand (char *command, int *twokeys)
1317: {
1318: int count;
1319: int j;
1320: int l;
1321: char *b;
1322:
1323: twokeys[0] = twokeys[1] = -1;
1324: l = strlen(command);
1325: count = 0;
1326:
1327: for (j=0 ; j<256 ; j++)
1328: {
1329: b = keybindings[j];
1330: if (!b)
1331: continue;
1332: if (!strncmp (b, command, l) )
1333: {
1334: twokeys[count] = j;
1335: count++;
1336: if (count == 2)
1337: break;
1338: }
1339: }
1340: }
1341:
1342: void M_UnbindCommand (char *command)
1343: {
1344: int j;
1345: int l;
1346: char *b;
1347:
1348: l = strlen(command);
1349:
1350: for (j=0 ; j<256 ; j++)
1351: {
1352: b = keybindings[j];
1353: if (!b)
1354: continue;
1355: if (!strncmp (b, command, l) )
1356: Key_SetBinding (j, "");
1357: }
1358: }
1359:
1360:
1361: void M_Keys_Draw (void)
1362: {
1363: int i, l;
1364: int keys[2];
1365: char *name;
1366: int x, y;
1367: qpic_t *p;
1368:
1369: p = M_CachePic ("gfx/ttl_cstm.lmp");
1370: M_DrawPic ( (320-p->width)/2, 4, p);
1371:
1372: if (bind_grab)
1373: M_Print (12, 32, "Press a key or button for this action");
1374: else
1375: M_Print (18, 32, "Enter to change, backspace to clear");
1376:
1377: // search for known bindings
1378: for (i=0 ; i<NUMCOMMANDS ; i++)
1379: {
1380: y = 48 + 8*i;
1381:
1382: M_Print (16, y, bindnames[i][1]);
1383:
1384: l = strlen (bindnames[i][0]);
1385:
1386: M_FindKeysForCommand (bindnames[i][0], keys);
1387:
1388: if (keys[0] == -1)
1389: {
1390: M_Print (140, y, "???");
1391: }
1392: else
1393: {
1394: name = Key_KeynumToString (keys[0]);
1395: M_Print (140, y, name);
1396: x = strlen(name) * 8;
1397: if (keys[1] != -1)
1398: {
1399: M_Print (140 + x + 8, y, "or");
1400: M_Print (140 + x + 32, y, Key_KeynumToString (keys[1]));
1401: }
1402: }
1403: }
1404:
1405: if (bind_grab)
1406: M_DrawCharacter (130, 48 + keys_cursor*8, '=');
1407: else
1408: M_DrawCharacter (130, 48 + keys_cursor*8, 12+((int)(realtime*4)&1));
1409: }
1410:
1411:
1412: void M_Keys_Key (int k)
1413: {
1414: char cmd[80];
1415: int keys[2];
1416:
1417: if (bind_grab)
1418: { // defining a key
1419: S_LocalSound ("misc/menu1.wav");
1420: if (k == K_ESCAPE)
1421: {
1422: bind_grab = false;
1423: }
1424: else if (k != '`')
1425: {
1.1.1.2 ! root 1426: sprintf (cmd, "bind %s \"%s\"\n", Key_KeynumToString (k), bindnames[keys_cursor][0]);
1.1 root 1427: Cbuf_InsertText (cmd);
1428: }
1429:
1430: bind_grab = false;
1431: return;
1432: }
1433:
1434: switch (k)
1435: {
1436: case K_ESCAPE:
1437: M_Menu_Options_f ();
1438: break;
1439:
1440: case K_LEFTARROW:
1441: case K_UPARROW:
1442: S_LocalSound ("misc/menu1.wav");
1443: keys_cursor--;
1444: if (keys_cursor < 0)
1445: keys_cursor = NUMCOMMANDS-1;
1446: break;
1447:
1448: case K_DOWNARROW:
1449: case K_RIGHTARROW:
1450: S_LocalSound ("misc/menu1.wav");
1451: keys_cursor++;
1452: if (keys_cursor >= NUMCOMMANDS)
1453: keys_cursor = 0;
1454: break;
1455:
1456: case K_ENTER: // go into bind mode
1457: M_FindKeysForCommand (bindnames[keys_cursor][0], keys);
1458: S_LocalSound ("misc/menu2.wav");
1459: if (keys[1] != -1)
1460: M_UnbindCommand (bindnames[keys_cursor][0]);
1461: bind_grab = true;
1462: break;
1463:
1464: case K_BACKSPACE: // delete bindings
1465: case K_DEL: // delete bindings
1466: S_LocalSound ("misc/menu2.wav");
1467: M_UnbindCommand (bindnames[keys_cursor][0]);
1468: break;
1469: }
1470: }
1471:
1472: //=============================================================================
1473: /* VIDEO MENU */
1474:
1475: void M_Menu_Video_f (void)
1476: {
1477: key_dest = key_menu;
1478: m_state = m_video;
1479: m_entersound = true;
1480: }
1481:
1482:
1483: void M_Video_Draw (void)
1484: {
1485: (*vid_menudrawfn) ();
1486: }
1487:
1488:
1489: void M_Video_Key (int key)
1490: {
1491: (*vid_menukeyfn) (key);
1492: }
1493:
1494: //=============================================================================
1495: /* HELP MENU */
1496:
1497: int help_page;
1498: #define NUM_HELP_PAGES 6
1499:
1500:
1501: void M_Menu_Help_f (void)
1502: {
1503: key_dest = key_menu;
1504: m_state = m_help;
1505: m_entersound = true;
1506: help_page = 0;
1507: }
1508:
1509:
1510:
1511: void M_Help_Draw (void)
1512: {
1513: M_DrawPic (0, 0, M_CachePic ( va("gfx/help%i.lmp", help_page)) );
1514: }
1515:
1516:
1517: void M_Help_Key (int key)
1518: {
1519: switch (key)
1520: {
1521: case K_ESCAPE:
1522: M_Menu_Main_f ();
1523: break;
1524:
1525: case K_UPARROW:
1526: case K_RIGHTARROW:
1527: m_entersound = true;
1528: if (++help_page >= NUM_HELP_PAGES)
1529: help_page = 0;
1530: break;
1531:
1532: case K_DOWNARROW:
1533: case K_LEFTARROW:
1534: m_entersound = true;
1535: if (--help_page < 0)
1536: help_page = NUM_HELP_PAGES-1;
1537: break;
1538: }
1539:
1540: }
1541:
1542: //=============================================================================
1543: /* QUIT MENU */
1544:
1545: int msgNumber;
1546: int m_quit_prevstate;
1547: qboolean wasInMenus;
1548:
1549: char *quitMessage [] =
1550: {
1551: /* .........1.........2.... */
1552: " Are you gonna quit ",
1553: " this game just like ",
1554: " everything else? ",
1555: " ",
1556:
1557: " Milord, methinks that ",
1558: " thou art a lowly ",
1559: " quitter. Is this true? ",
1560: " ",
1561:
1562: " Do I need to bust your ",
1563: " face open for trying ",
1564: " to quit? ",
1565: " ",
1566:
1567: " Man, I oughta smack you",
1568: " for trying to quit! ",
1569: " Press Y to get ",
1570: " smacked out. ",
1571:
1572: " Press Y to quit like a ",
1573: " big loser in life. ",
1574: " Press N to stay proud ",
1575: " and successful! ",
1576:
1577: " If you press Y to ",
1578: " quit, I will summon ",
1579: " Satan all over your ",
1580: " hard drive! ",
1581:
1582: " Um, Asmodeus dislikes ",
1583: " his children trying to ",
1584: " quit. Press Y to return",
1585: " to your Tinkertoys. ",
1586:
1587: " If you quit now, I'll ",
1588: " throw a blanket-party ",
1589: " for you next time! ",
1590: " "
1591: };
1592:
1593: void M_Menu_Quit_f (void)
1594: {
1595: if (m_state == m_quit)
1596: return;
1597: wasInMenus = (key_dest == key_menu);
1598: key_dest = key_menu;
1599: m_quit_prevstate = m_state;
1600: m_state = m_quit;
1601: m_entersound = true;
1602: msgNumber = rand()&7;
1603: }
1604:
1605:
1606: void M_Quit_Key (int key)
1607: {
1608: switch (key)
1609: {
1610: case K_ESCAPE:
1611: case 'n':
1612: case 'N':
1613: if (wasInMenus)
1614: {
1615: m_state = m_quit_prevstate;
1616: m_entersound = true;
1617: }
1618: else
1619: {
1620: key_dest = key_game;
1621: m_state = m_none;
1622: }
1623: break;
1624:
1625: case 'Y':
1626: case 'y':
1627: key_dest = key_console;
1628: Host_Quit_f ();
1629: break;
1630:
1631: default:
1632: break;
1633: }
1634:
1635: }
1636:
1637:
1638: void M_Quit_Draw (void)
1639: {
1640: if (wasInMenus)
1641: {
1642: m_state = m_quit_prevstate;
1643: m_recursiveDraw = true;
1644: M_Draw ();
1645: m_state = m_quit;
1646: }
1647: M_DrawTextBox (56, 76, 24, 4);
1648: M_Print (64, 84, quitMessage[msgNumber*4+0]);
1649: M_Print (64, 92, quitMessage[msgNumber*4+1]);
1650: M_Print (64, 100, quitMessage[msgNumber*4+2]);
1651: M_Print (64, 108, quitMessage[msgNumber*4+3]);
1652: }
1653:
1654: //=============================================================================
1655:
1656: /* SERIAL CONFIG MENU */
1657:
1658: int serialConfig_cursor;
1659: int serialConfig_cursor_table[] = {48, 64, 80, 96, 112, 132};
1660: #define NUM_SERIALCONFIG_CMDS 6
1661:
1662: static int ISA_uarts[] = {0x3f8,0x2f8,0x3e8,0x2e8};
1663: static int ISA_IRQs[] = {4,3,4,3};
1664: int serialConfig_baudrate[] = {9600,14400,19200,28800,38400,57600};
1665:
1666: int serialConfig_comport;
1667: int serialConfig_irq ;
1668: int serialConfig_baud;
1669: char serialConfig_phone[16];
1670:
1671: void M_Menu_SerialConfig_f (void)
1672: {
1673: int n;
1674: int port;
1675: int baudrate;
1676: qboolean useModem;
1677:
1678: key_dest = key_menu;
1679: m_state = m_serialconfig;
1680: m_entersound = true;
1681: if (JoiningGame && SerialConfig)
1682: serialConfig_cursor = 4;
1683: else
1684: serialConfig_cursor = 5;
1685:
1686: (*GetComPortConfig) (0, &port, &serialConfig_irq, &baudrate, &useModem);
1687:
1688: // map uart's port to COMx
1689: for (n = 0; n < 4; n++)
1690: if (ISA_uarts[n] == port)
1691: break;
1692: if (n == 4)
1693: {
1694: n = 0;
1695: serialConfig_irq = 4;
1696: }
1697: serialConfig_comport = n + 1;
1698:
1699: // map baudrate to index
1700: for (n = 0; n < 6; n++)
1701: if (serialConfig_baudrate[n] == baudrate)
1702: break;
1703: if (n == 6)
1704: n = 5;
1705: serialConfig_baud = n;
1706: }
1707:
1708:
1709: void M_SerialConfig_Draw (void)
1710: {
1711: qpic_t *p;
1712: int basex;
1713: char *startJoin;
1714: char *directModem;
1715:
1716: M_DrawTransPic (16, 4, M_CachePic ("gfx/qplaque.lmp") );
1717: p = M_CachePic ("gfx/p_multi.lmp");
1718: basex = (320-p->width)/2;
1719: M_DrawPic (basex, 4, p);
1720:
1721: if (StartingGame)
1722: startJoin = "New Game";
1723: else
1724: startJoin = "Join Game";
1725: if (SerialConfig)
1726: directModem = "Modem";
1727: else
1728: directModem = "Direct Connect";
1729: M_Print (basex, 32, va ("%s - %s", startJoin, directModem));
1730: basex += 8;
1731:
1732: M_Print (basex, serialConfig_cursor_table[0], "Port");
1733: M_DrawTextBox (160, 40, 4, 1);
1734: M_Print (168, serialConfig_cursor_table[0], va("COM%u", serialConfig_comport));
1735:
1736: M_Print (basex, serialConfig_cursor_table[1], "IRQ");
1737: M_DrawTextBox (160, serialConfig_cursor_table[1]-8, 1, 1);
1738: M_Print (168, serialConfig_cursor_table[1], va("%u", serialConfig_irq));
1739:
1740: M_Print (basex, serialConfig_cursor_table[2], "Baud");
1741: M_DrawTextBox (160, serialConfig_cursor_table[2]-8, 5, 1);
1742: M_Print (168, serialConfig_cursor_table[2], va("%u", serialConfig_baudrate[serialConfig_baud]));
1743:
1744: if (SerialConfig)
1745: {
1746: M_Print (basex, serialConfig_cursor_table[3], "Modem Setup...");
1747: if (JoiningGame)
1748: {
1749: M_Print (basex, serialConfig_cursor_table[4], "Phone number");
1750: M_DrawTextBox (160, serialConfig_cursor_table[4]-8, 16, 1);
1751: M_Print (168, serialConfig_cursor_table[4], serialConfig_phone);
1752: }
1753: }
1754:
1755: if (JoiningGame)
1756: {
1757: M_DrawTextBox (basex, serialConfig_cursor_table[5]-8, 7, 1);
1758: M_Print (basex+8, serialConfig_cursor_table[5], "Connect");
1759: }
1760: else
1761: {
1762: M_DrawTextBox (basex, serialConfig_cursor_table[5]-8, 2, 1);
1763: M_Print (basex+8, serialConfig_cursor_table[5], "OK");
1764: }
1765:
1766: M_DrawCharacter (basex-8, serialConfig_cursor_table [serialConfig_cursor], 12+((int)(realtime*4)&1));
1767:
1768: if (serialConfig_cursor == 4)
1769: M_DrawCharacter (168 + 8*strlen(serialConfig_phone), serialConfig_cursor_table [serialConfig_cursor], 10+((int)(realtime*4)&1));
1770: }
1771:
1772:
1773: void M_SerialConfig_Key (int key)
1774: {
1775: int l;
1776:
1777: switch (key)
1778: {
1779: case K_ESCAPE:
1780: M_Menu_Net_f ();
1781: break;
1782:
1783: case K_UPARROW:
1784: S_LocalSound ("misc/menu1.wav");
1785: serialConfig_cursor--;
1786: if (serialConfig_cursor < 0)
1787: serialConfig_cursor = NUM_SERIALCONFIG_CMDS-1;
1788: break;
1789:
1790: case K_DOWNARROW:
1791: S_LocalSound ("misc/menu1.wav");
1792: serialConfig_cursor++;
1793: if (serialConfig_cursor >= NUM_SERIALCONFIG_CMDS)
1794: serialConfig_cursor = 0;
1795: break;
1796:
1797: case K_LEFTARROW:
1798: if (serialConfig_cursor > 2)
1799: break;
1800: S_LocalSound ("misc/menu3.wav");
1801:
1802: if (serialConfig_cursor == 0)
1803: {
1804: serialConfig_comport--;
1805: if (serialConfig_comport == 0)
1806: serialConfig_comport = 4;
1807: serialConfig_irq = ISA_IRQs[serialConfig_comport-1];
1808: }
1809:
1810: if (serialConfig_cursor == 1)
1811: {
1812: serialConfig_irq--;
1813: if (serialConfig_irq == 6)
1814: serialConfig_irq = 5;
1815: if (serialConfig_irq == 1)
1816: serialConfig_irq = 7;
1817: }
1818:
1819: if (serialConfig_cursor == 2)
1820: {
1821: serialConfig_baud--;
1822: if (serialConfig_baud < 0)
1823: serialConfig_baud = 5;
1824: }
1825:
1826: break;
1827:
1828: case K_RIGHTARROW:
1829: if (serialConfig_cursor > 2)
1830: break;
1831: forward:
1832: S_LocalSound ("misc/menu3.wav");
1833:
1834: if (serialConfig_cursor == 0)
1835: {
1836: serialConfig_comport++;
1837: if (serialConfig_comport > 4)
1838: serialConfig_comport = 1;
1839: serialConfig_irq = ISA_IRQs[serialConfig_comport-1];
1840: }
1841:
1842: if (serialConfig_cursor == 1)
1843: {
1844: serialConfig_irq++;
1845: if (serialConfig_irq == 6)
1846: serialConfig_irq = 7;
1847: if (serialConfig_irq == 8)
1848: serialConfig_irq = 2;
1849: }
1850:
1851: if (serialConfig_cursor == 2)
1852: {
1853: serialConfig_baud++;
1854: if (serialConfig_baud > 5)
1855: serialConfig_baud = 0;
1856: }
1857:
1858: break;
1859:
1860: case K_ENTER:
1861: if (serialConfig_cursor < 3)
1862: goto forward;
1863:
1864: m_entersound = true;
1865:
1866: if (serialConfig_cursor == 3)
1867: {
1868: (*SetComPortConfig) (0, ISA_uarts[serialConfig_comport-1], serialConfig_irq, serialConfig_baudrate[serialConfig_baud], SerialConfig);
1869:
1870: M_Menu_ModemConfig_f ();
1871: break;
1872: }
1873:
1874: if (serialConfig_cursor == 4)
1875: {
1876: serialConfig_cursor = 5;
1877: break;
1878: }
1879:
1880: // serialConfig_cursor == 5 (OK/CONNECT)
1881: (*SetComPortConfig) (0, ISA_uarts[serialConfig_comport-1], serialConfig_irq, serialConfig_baudrate[serialConfig_baud], SerialConfig);
1882:
1883: M_ConfigureNetSubsystem ();
1884:
1885: if (StartingGame)
1886: {
1887: M_Menu_GameOptions_f ();
1888: break;
1889: }
1890:
1891: key_dest = key_game;
1892: m_state = m_none;
1893:
1894: if (SerialConfig)
1895: Cbuf_AddText (va ("connect \"%s\"\n", serialConfig_phone));
1896: else
1897: Cbuf_AddText ("connect\n");
1898: break;
1899:
1900: case K_BACKSPACE:
1901: if (serialConfig_cursor == 4)
1902: {
1903: if (strlen(serialConfig_phone))
1904: serialConfig_phone[strlen(serialConfig_phone)-1] = 0;
1905: }
1906: break;
1907:
1908: default:
1909: if (key < 32 || key > 127)
1910: break;
1911: if (serialConfig_cursor == 4)
1912: {
1913: l = strlen(serialConfig_phone);
1914: if (l < 15)
1915: {
1916: serialConfig_phone[l+1] = 0;
1917: serialConfig_phone[l] = key;
1918: }
1919: }
1920: }
1921:
1922: if (DirectConfig && (serialConfig_cursor == 3 || serialConfig_cursor == 4))
1923: if (key == K_UPARROW)
1924: serialConfig_cursor = 2;
1925: else
1926: serialConfig_cursor = 5;
1927:
1928: if (SerialConfig && StartingGame && serialConfig_cursor == 4)
1929: if (key == K_UPARROW)
1930: serialConfig_cursor = 3;
1931: else
1932: serialConfig_cursor = 5;
1933: }
1934:
1935: //=============================================================================
1936: /* MODEM CONFIG MENU */
1937:
1938: int modemConfig_cursor;
1939: int modemConfig_cursor_table [] = {40, 56, 88, 120, 156};
1940: #define NUM_MODEMCONFIG_CMDS 5
1941:
1942: char modemConfig_dialing;
1943: char modemConfig_clear [16];
1944: char modemConfig_init [32];
1945: char modemConfig_hangup [16];
1946:
1947: void M_Menu_ModemConfig_f (void)
1948: {
1949: key_dest = key_menu;
1950: m_state = m_modemconfig;
1951: m_entersound = true;
1952: (*GetModemConfig) (0, &modemConfig_dialing, modemConfig_clear, modemConfig_init, modemConfig_hangup);
1953: }
1954:
1955:
1956: void M_ModemConfig_Draw (void)
1957: {
1958: qpic_t *p;
1959: int basex;
1960:
1961: M_DrawTransPic (16, 4, M_CachePic ("gfx/qplaque.lmp") );
1962: p = M_CachePic ("gfx/p_multi.lmp");
1963: basex = (320-p->width)/2;
1964: M_DrawPic (basex, 4, p);
1965: basex += 8;
1966:
1967: if (modemConfig_dialing == 'P')
1968: M_Print (basex, modemConfig_cursor_table[0], "Pulse Dialing");
1969: else
1970: M_Print (basex, modemConfig_cursor_table[0], "Touch Tone Dialing");
1971:
1972: M_Print (basex, modemConfig_cursor_table[1], "Clear");
1973: M_DrawTextBox (basex, modemConfig_cursor_table[1]+4, 16, 1);
1974: M_Print (basex+8, modemConfig_cursor_table[1]+12, modemConfig_clear);
1975: if (modemConfig_cursor == 1)
1976: M_DrawCharacter (basex+8 + 8*strlen(modemConfig_clear), modemConfig_cursor_table[1]+12, 10+((int)(realtime*4)&1));
1977:
1978: M_Print (basex, modemConfig_cursor_table[2], "Init");
1979: M_DrawTextBox (basex, modemConfig_cursor_table[2]+4, 30, 1);
1980: M_Print (basex+8, modemConfig_cursor_table[2]+12, modemConfig_init);
1981: if (modemConfig_cursor == 2)
1982: M_DrawCharacter (basex+8 + 8*strlen(modemConfig_init), modemConfig_cursor_table[2]+12, 10+((int)(realtime*4)&1));
1983:
1984: M_Print (basex, modemConfig_cursor_table[3], "Hangup");
1985: M_DrawTextBox (basex, modemConfig_cursor_table[3]+4, 16, 1);
1986: M_Print (basex+8, modemConfig_cursor_table[3]+12, modemConfig_hangup);
1987: if (modemConfig_cursor == 3)
1988: M_DrawCharacter (basex+8 + 8*strlen(modemConfig_hangup), modemConfig_cursor_table[3]+12, 10+((int)(realtime*4)&1));
1989:
1990: M_DrawTextBox (basex, modemConfig_cursor_table[4]-8, 2, 1);
1991: M_Print (basex+8, modemConfig_cursor_table[4], "OK");
1992:
1993: M_DrawCharacter (basex-8, modemConfig_cursor_table [modemConfig_cursor], 12+((int)(realtime*4)&1));
1994: }
1995:
1996:
1997: void M_ModemConfig_Key (int key)
1998: {
1999: int l;
2000:
2001: switch (key)
2002: {
2003: case K_ESCAPE:
2004: M_Menu_SerialConfig_f ();
2005: break;
2006:
2007: case K_UPARROW:
2008: S_LocalSound ("misc/menu1.wav");
2009: modemConfig_cursor--;
2010: if (modemConfig_cursor < 0)
2011: modemConfig_cursor = NUM_MODEMCONFIG_CMDS-1;
2012: break;
2013:
2014: case K_DOWNARROW:
2015: S_LocalSound ("misc/menu1.wav");
2016: modemConfig_cursor++;
2017: if (modemConfig_cursor >= NUM_MODEMCONFIG_CMDS)
2018: modemConfig_cursor = 0;
2019: break;
2020:
2021: case K_LEFTARROW:
2022: case K_RIGHTARROW:
2023: if (modemConfig_cursor == 0)
2024: {
2025: if (modemConfig_dialing == 'P')
2026: modemConfig_dialing = 'T';
2027: else
2028: modemConfig_dialing = 'P';
2029: S_LocalSound ("misc/menu1.wav");
2030: }
2031: break;
2032:
2033: case K_ENTER:
2034: if (modemConfig_cursor == 0)
2035: {
2036: if (modemConfig_dialing == 'P')
2037: modemConfig_dialing = 'T';
2038: else
2039: modemConfig_dialing = 'P';
2040: m_entersound = true;
2041: }
2042:
2043: if (modemConfig_cursor == 4)
2044: {
2045: (*SetModemConfig) (0, va ("%c", modemConfig_dialing), modemConfig_clear, modemConfig_init, modemConfig_hangup);
2046: m_entersound = true;
2047: M_Menu_SerialConfig_f ();
2048: }
2049: break;
2050:
2051: case K_BACKSPACE:
2052: if (modemConfig_cursor == 1)
2053: {
2054: if (strlen(modemConfig_clear))
2055: modemConfig_clear[strlen(modemConfig_clear)-1] = 0;
2056: }
2057:
2058: if (modemConfig_cursor == 2)
2059: {
2060: if (strlen(modemConfig_init))
2061: modemConfig_init[strlen(modemConfig_init)-1] = 0;
2062: }
2063:
2064: if (modemConfig_cursor == 3)
2065: {
2066: if (strlen(modemConfig_hangup))
2067: modemConfig_hangup[strlen(modemConfig_hangup)-1] = 0;
2068: }
2069: break;
2070:
2071: default:
2072: if (key < 32 || key > 127)
2073: break;
2074:
2075: if (modemConfig_cursor == 1)
2076: {
2077: l = strlen(modemConfig_clear);
2078: if (l < 15)
2079: {
2080: modemConfig_clear[l+1] = 0;
2081: modemConfig_clear[l] = key;
2082: }
2083: }
2084:
2085: if (modemConfig_cursor == 2)
2086: {
2087: l = strlen(modemConfig_init);
2088: if (l < 29)
2089: {
2090: modemConfig_init[l+1] = 0;
2091: modemConfig_init[l] = key;
2092: }
2093: }
2094:
2095: if (modemConfig_cursor == 3)
2096: {
2097: l = strlen(modemConfig_hangup);
2098: if (l < 15)
2099: {
2100: modemConfig_hangup[l+1] = 0;
2101: modemConfig_hangup[l] = key;
2102: }
2103: }
2104: }
2105: }
2106:
2107: //=============================================================================
2108: /* LAN CONFIG MENU */
2109:
2110: int lanConfig_cursor = -1;
2111: int lanConfig_cursor_table [] = {72, 92, 124};
2112: #define NUM_LANCONFIG_CMDS 3
2113:
2114: int lanConfig_port;
2115: char lanConfig_portname[6];
2116: char lanConfig_joinname[22];
2117:
2118: void M_Menu_LanConfig_f (void)
2119: {
2120: key_dest = key_menu;
2121: m_state = m_lanconfig;
2122: m_entersound = true;
2123: if (lanConfig_cursor == -1)
2124: {
2125: if (JoiningGame && TCPIPConfig)
2126: lanConfig_cursor = 2;
2127: else
2128: lanConfig_cursor = 1;
2129: }
2130: if (StartingGame && lanConfig_cursor == 2)
2131: lanConfig_cursor = 1;
1.1.1.2 ! root 2132: lanConfig_port = 26000;
1.1 root 2133: sprintf(lanConfig_portname, "%u", lanConfig_port);
2134: }
2135:
2136:
2137: void M_LanConfig_Draw (void)
2138: {
2139: qpic_t *p;
2140: int basex;
2141: char *startJoin;
2142: char *protocol;
2143:
2144: M_DrawTransPic (16, 4, M_CachePic ("gfx/qplaque.lmp") );
2145: p = M_CachePic ("gfx/p_multi.lmp");
2146: basex = (320-p->width)/2;
2147: M_DrawPic (basex, 4, p);
2148:
2149: if (StartingGame)
2150: startJoin = "New Game";
2151: else
2152: startJoin = "Join Game";
2153: if (IPXConfig)
2154: protocol = "IPX";
2155: else
2156: protocol = "TCP/IP";
2157: M_Print (basex, 32, va ("%s - %s", startJoin, protocol));
2158: basex += 8;
2159:
2160: M_Print (basex, 52, "Address:");
2161: if (IPXConfig)
2162: M_Print (basex+9*8, 52, my_ipx_address);
2163: else
2164: M_Print (basex+9*8, 52, my_tcpip_address);
2165:
2166: M_Print (basex, lanConfig_cursor_table[0], "Port");
2167: M_DrawTextBox (basex+8*8, lanConfig_cursor_table[0]-8, 6, 1);
2168: M_Print (basex+9*8, lanConfig_cursor_table[0], lanConfig_portname);
2169:
2170: if (JoiningGame)
2171: {
2172: M_Print (basex, lanConfig_cursor_table[1], "Search for local games...");
2173: M_Print (basex, 108, "Join game at:");
2174: M_DrawTextBox (basex+8, lanConfig_cursor_table[2]-8, 22, 1);
2175: M_Print (basex+16, lanConfig_cursor_table[2], lanConfig_joinname);
2176: }
2177: else
2178: {
2179: M_DrawTextBox (basex, lanConfig_cursor_table[1]-8, 2, 1);
2180: M_Print (basex+8, lanConfig_cursor_table[1], "OK");
2181: }
2182:
2183: M_DrawCharacter (basex-8, lanConfig_cursor_table [lanConfig_cursor], 12+((int)(realtime*4)&1));
2184:
2185: if (lanConfig_cursor == 0)
2186: M_DrawCharacter (basex+9*8 + 8*strlen(lanConfig_portname), lanConfig_cursor_table [0], 10+((int)(realtime*4)&1));
2187:
2188: if (lanConfig_cursor == 2)
2189: M_DrawCharacter (basex+16 + 8*strlen(lanConfig_joinname), lanConfig_cursor_table [2], 10+((int)(realtime*4)&1));
2190: }
2191:
2192:
2193: void M_LanConfig_Key (int key)
2194: {
2195: int l;
2196:
2197: switch (key)
2198: {
2199: case K_ESCAPE:
2200: M_Menu_Net_f ();
2201: break;
2202:
2203: case K_UPARROW:
2204: S_LocalSound ("misc/menu1.wav");
2205: lanConfig_cursor--;
2206: if (lanConfig_cursor < 0)
2207: lanConfig_cursor = NUM_LANCONFIG_CMDS-1;
2208: break;
2209:
2210: case K_DOWNARROW:
2211: S_LocalSound ("misc/menu1.wav");
2212: lanConfig_cursor++;
2213: if (lanConfig_cursor >= NUM_LANCONFIG_CMDS)
2214: lanConfig_cursor = 0;
2215: break;
2216:
2217: case K_ENTER:
2218: if (lanConfig_cursor == 0)
2219: break;
2220:
2221: m_entersound = true;
2222:
2223: M_ConfigureNetSubsystem ();
2224:
2225: if (lanConfig_cursor == 1)
2226: {
2227: if (StartingGame)
2228: {
2229: M_Menu_GameOptions_f ();
2230: break;
2231: }
2232: M_Menu_Search_f();
2233: break;
2234: }
2235:
2236: if (lanConfig_cursor == 2)
2237: {
2238: key_dest = key_game;
2239: m_state = m_none;
2240: Cbuf_AddText ( va ("connect \"%s\"\n", lanConfig_joinname) );
2241: break;
2242: }
2243:
2244: break;
2245:
2246: case K_BACKSPACE:
2247: if (lanConfig_cursor == 0)
2248: {
2249: if (strlen(lanConfig_portname))
2250: lanConfig_portname[strlen(lanConfig_portname)-1] = 0;
2251: }
2252:
2253: if (lanConfig_cursor == 2)
2254: {
2255: if (strlen(lanConfig_joinname))
2256: lanConfig_joinname[strlen(lanConfig_joinname)-1] = 0;
2257: }
2258: break;
2259:
2260: default:
2261: if (key < 32 || key > 127)
2262: break;
2263:
2264: if (lanConfig_cursor == 2)
2265: {
2266: l = strlen(lanConfig_joinname);
2267: if (l < 21)
2268: {
2269: lanConfig_joinname[l+1] = 0;
2270: lanConfig_joinname[l] = key;
2271: }
2272: }
2273:
2274: if (key < '0' || key > '9')
2275: break;
2276: if (lanConfig_cursor == 0)
2277: {
2278: l = strlen(lanConfig_portname);
2279: if (l < 5)
2280: {
2281: lanConfig_portname[l+1] = 0;
2282: lanConfig_portname[l] = key;
2283: }
2284: }
2285: }
2286:
2287: if (StartingGame && lanConfig_cursor == 2)
2288: if (key == K_UPARROW)
2289: lanConfig_cursor = 1;
2290: else
2291: lanConfig_cursor = 0;
2292:
2293: l = Q_atoi(lanConfig_portname);
2294: if (l > 65535)
2295: l = lanConfig_port;
2296: else
2297: lanConfig_port = l;
2298: sprintf(lanConfig_portname, "%u", lanConfig_port);
2299: }
2300:
2301: //=============================================================================
2302: /* GAME OPTIONS MENU */
2303:
1.1.1.2 ! root 2304: struct
1.1 root 2305: {
2306: char *name;
2307: char *description;
1.1.1.2 ! root 2308: } levels[] =
1.1 root 2309: {
2310: {"start", "Entrance"}, // 0
2311:
2312: {"e1m1", "Slipgate Complex"}, // 1
2313: {"e1m2", "Castle of the Damned"},
2314: {"e1m3", "The Necropolis"},
2315: {"e1m4", "The Grisly Grotto"},
2316: {"e1m5", "Gloom Keep"},
2317: {"e1m6", "The Door To Chthon"},
2318: {"e1m7", "The House of Chthon"},
2319: {"e1m8", "Ziggurat Vertigo"},
2320:
2321: {"e2m1", "The Installation"}, // 9
2322: {"e2m2", "Ogre Citadel"},
2323: {"e2m3", "Crypt of Decay"},
2324: {"e2m4", "The Ebon Fortress"},
2325: {"e2m5", "The Wizard's Manse"},
2326: {"e2m6", "The Dismal Oubliette"},
2327: {"e2m7", "Underearth"},
2328:
2329: {"e3m1", "Termination Central"}, // 16
2330: {"e3m2", "The Vaults of Zin"},
2331: {"e3m3", "The Tomb of Terror"},
2332: {"e3m4", "Satan's Dark Delight"},
2333: {"e3m5", "Wind Tunnels"},
2334: {"e3m6", "Chambers of Torment"},
2335: {"e3m7", "The Haunted Halls"},
2336:
2337: {"e4m1", "The Sewage System"}, // 23
2338: {"e4m2", "The Tower of Despair"},
2339: {"e4m3", "The Elder God Shrine"},
2340: {"e4m4", "The Palace of Hate"},
2341: {"e4m5", "Hell's Atrium"},
2342: {"e4m6", "The Pain Maze"},
2343: {"e4m7", "Azure Agony"},
2344: {"e4m8", "The Nameless City"},
2345:
2346: {"end", "Shub-Niggurath's Pit"}, // 31
2347:
2348: {"dm1", "Place of Two Deaths"}, // 32
2349: {"dm2", "Claustrophobopolis"},
2350: {"dm3", "The Abandoned Base"},
2351: {"dm4", "The Bad Place"},
2352: {"dm5", "The Cistern"},
2353: {"dm6", "The Dark Zone"}
2354: };
2355:
2356: typedef struct
2357: {
2358: char *description;
2359: int firstLevel;
2360: int levels;
2361: } episode_t;
2362:
2363: episode_t episodes[] =
2364: {
2365: {"Welcome to Quake", 0, 1},
2366: {"Doomed Dimension", 1, 8},
2367: {"Realm of Black Magic", 9, 7},
2368: {"Netherworld", 16, 7},
2369: {"The Elder World", 23, 8},
2370: {"Final Level", 31, 1},
2371: {"Deathmatch Arena", 32, 6}
2372: };
2373:
2374: int startepisode;
2375: int startlevel;
2376: int maxplayers;
2377: qboolean m_serverInfoMessage = false;
2378: double m_serverInfoMessageTime;
2379:
2380: void M_Menu_GameOptions_f (void)
2381: {
2382: key_dest = key_menu;
2383: m_state = m_gameoptions;
2384: m_entersound = true;
2385: if (maxplayers == 0)
2386: maxplayers = svs.maxclients;
2387: if (maxplayers < 2)
2388: maxplayers = svs.maxclientslimit;
2389: }
2390:
2391:
2392: int gameoptions_cursor_table[] = {40, 56, 64, 72, 80, 88, 96, 112, 120};
2393: #define NUM_GAMEOPTIONS 9
2394: int gameoptions_cursor;
2395:
2396: void M_GameOptions_Draw (void)
2397: {
2398: qpic_t *p;
2399: int x;
2400:
2401: M_DrawTransPic (16, 4, M_CachePic ("gfx/qplaque.lmp") );
2402: p = M_CachePic ("gfx/p_multi.lmp");
2403: M_DrawPic ( (320-p->width)/2, 4, p);
2404:
2405: M_DrawTextBox (152, 32, 10, 1);
2406: M_Print (160, 40, "begin game");
2407:
2408: M_Print (0, 56, " Max players");
2409: M_Print (160, 56, va("%i", maxplayers) );
2410:
2411: M_Print (0, 64, " Game Type");
2412: if (coop.value)
2413: M_Print (160, 64, "Cooperative");
2414: else
2415: M_Print (160, 64, "Deathmatch");
2416:
2417: M_Print (0, 72, " Teamplay");
2418: if (teamplay.value)
2419: M_Print (160, 72, "on");
2420: else
2421: M_Print (160, 72, "off");
2422:
2423: M_Print (0, 80, " Skill");
2424: if (skill.value == 0)
2425: M_Print (160, 80, "Easy difficulty");
2426: else if (skill.value == 1)
2427: M_Print (160, 80, "Normal difficulty");
2428: else if (skill.value == 2)
2429: M_Print (160, 80, "Hard difficulty");
2430: else
2431: M_Print (160, 80, "Nightmare difficulty");
2432:
2433: M_Print (0, 88, " Frag Limit");
2434: if (fraglimit.value == 0)
2435: M_Print (160, 88, "none");
2436: else
2437: M_Print (160, 88, va("%i frags", (int)fraglimit.value));
2438:
2439: M_Print (0, 96, " Time Limit");
2440: if (timelimit.value == 0)
2441: M_Print (160, 96, "none");
2442: else
2443: M_Print (160, 96, va("%i minutes", (int)timelimit.value));
2444:
2445: M_Print (0, 112, " Episode");
2446: M_Print (160, 112, episodes[startepisode].description);
2447:
2448: M_Print (0, 120, " Level");
2449: M_Print (160, 120, levels[episodes[startepisode].firstLevel + startlevel].description);
2450: M_Print (160, 128, levels[episodes[startepisode].firstLevel + startlevel].name);
2451:
2452: // line cursor
2453: M_DrawCharacter (144, gameoptions_cursor_table[gameoptions_cursor], 12+((int)(realtime*4)&1));
2454:
2455: if (m_serverInfoMessage)
2456: {
2457: if ((realtime - m_serverInfoMessageTime) < 5.0)
2458: {
2459: x = (320-26*8)/2;
2460: M_DrawTextBox (x, 138, 24, 4);
2461: x += 8;
2462: M_Print (x, 146, " More than 4 players ");
2463: M_Print (x, 154, " requires using command ");
2464: M_Print (x, 162, "line parameters; please ");
2465: M_Print (x, 170, " see techinfo.txt. ");
2466: }
2467: else
2468: {
2469: m_serverInfoMessage = false;
2470: }
2471: }
2472: }
2473:
2474:
2475: void M_NetStart_Change (int dir)
2476: {
2477: int count;
2478:
2479: switch (gameoptions_cursor)
2480: {
2481: case 1:
2482: maxplayers += dir;
2483: if (maxplayers > svs.maxclientslimit)
2484: {
2485: maxplayers = svs.maxclientslimit;
2486: m_serverInfoMessage = true;
2487: m_serverInfoMessageTime = realtime;
2488: }
2489: if (maxplayers < 2)
2490: maxplayers = 2;
2491: break;
2492:
2493: case 2:
2494: Cvar_SetValue ("coop", coop.value ? 0 : 1);
2495: break;
2496:
2497: case 3:
2498: Cvar_SetValue ("teamplay", teamplay.value ? 0 : 1);
2499: break;
2500:
2501: case 4:
2502: Cvar_SetValue ("skill", skill.value + dir);
2503: if (skill.value > 3)
2504: Cvar_SetValue ("skill", 0);
2505: if (skill.value < 0)
2506: Cvar_SetValue ("skill", 3);
2507: break;
2508:
2509: case 5:
2510: Cvar_SetValue ("fraglimit", fraglimit.value + dir*10);
2511: if (fraglimit.value > 100)
2512: Cvar_SetValue ("fraglimit", 0);
2513: if (fraglimit.value < 0)
2514: Cvar_SetValue ("fraglimit", 100);
2515: break;
2516:
2517: case 6:
2518: Cvar_SetValue ("timelimit", timelimit.value + dir*5);
2519: if (timelimit.value > 60)
2520: Cvar_SetValue ("timelimit", 0);
2521: if (timelimit.value < 0)
2522: Cvar_SetValue ("timelimit", 60);
2523: break;
2524:
2525: case 7:
2526: startepisode += dir;
2527: if (registered.value)
2528: count = 7;
2529: else
2530: count = 2;
2531: if (startepisode < 0)
2532: startepisode = count - 1;
2533: if (startepisode >= count)
2534: startepisode = 0;
2535: startlevel = 0;
2536: break;
2537:
2538: case 8:
2539: startlevel += dir;
2540: count = episodes[startepisode].levels;
2541: if (startlevel < 0)
2542: startlevel = count - 1;
2543: if (startlevel >= count)
2544: startlevel = 0;
2545: break;
2546: }
2547: }
2548:
2549: void M_GameOptions_Key (int key)
2550: {
2551: switch (key)
2552: {
2553: case K_ESCAPE:
2554: M_Menu_Net_f ();
2555: break;
2556:
2557: case K_UPARROW:
2558: S_LocalSound ("misc/menu1.wav");
2559: gameoptions_cursor--;
2560: if (gameoptions_cursor < 0)
2561: gameoptions_cursor = NUM_GAMEOPTIONS-1;
2562: break;
2563:
2564: case K_DOWNARROW:
2565: S_LocalSound ("misc/menu1.wav");
2566: gameoptions_cursor++;
2567: if (gameoptions_cursor >= NUM_GAMEOPTIONS)
2568: gameoptions_cursor = 0;
2569: break;
2570:
2571: case K_LEFTARROW:
2572: if (gameoptions_cursor == 0)
2573: break;
2574: S_LocalSound ("misc/menu3.wav");
2575: M_NetStart_Change (-1);
2576: break;
2577:
2578: case K_RIGHTARROW:
2579: if (gameoptions_cursor == 0)
2580: break;
2581: S_LocalSound ("misc/menu3.wav");
2582: M_NetStart_Change (1);
2583: break;
2584:
2585: case K_ENTER:
2586: S_LocalSound ("misc/menu2.wav");
2587: if (gameoptions_cursor == 0)
2588: {
2589: if (sv.active)
2590: Cbuf_AddText ("disconnect\n");
2591: Cbuf_AddText ( va ("maxplayers %u\n", maxplayers) );
2592: SCR_BeginLoadingPlaque ();
2593: Cbuf_AddText ( va ("map %s\n", levels[episodes[startepisode].firstLevel + startlevel].name) );
2594: return;
2595: }
2596:
2597: M_NetStart_Change (1);
2598: break;
2599: }
2600: }
2601:
2602: //=============================================================================
2603: /* SEARCH MENU */
2604:
2605: qboolean searchComplete = false;
2606: double searchCompleteTime;
2607:
2608: void M_Menu_Search_f (void)
2609: {
2610: key_dest = key_menu;
2611: m_state = m_search;
2612: m_entersound = false;
2613: slistSilent = true;
2614: slistLocal = false;
2615: searchComplete = false;
2616: NET_Slist_f();
2617:
2618: }
2619:
2620:
2621: void M_Search_Draw (void)
2622: {
2623: qpic_t *p;
2624:
2625: p = M_CachePic ("gfx/p_multi.lmp");
2626: M_DrawPic ( (320-p->width)/2, 4, p);
1.1.1.2 ! root 2627: M_Print ((320/2) - ((12*8)/2), 40, "Searching...");
1.1 root 2628: if(slistInProgress)
2629: {
2630: NET_Poll();
2631: return;
2632: }
2633:
2634: if (! searchComplete)
2635: {
2636: searchComplete = true;
2637: searchCompleteTime = realtime;
2638: }
2639:
2640: if (hostCacheCount)
2641: {
2642: M_Menu_ServerList_f ();
2643: return;
2644: }
2645:
1.1.1.2 ! root 2646: M_Print ((320/2) - ((22*8)/2), 64, "No Quake servers found");
1.1 root 2647: if ((realtime - searchCompleteTime) < 3.0)
2648: return;
2649:
2650: M_Menu_LanConfig_f ();
2651: }
2652:
2653:
2654: void M_Search_Key (int key)
2655: {
2656: }
2657:
2658: //=============================================================================
2659: /* SLIST MENU */
2660:
2661: int slist_cursor;
2662:
2663: void M_Menu_ServerList_f (void)
2664: {
2665: key_dest = key_menu;
2666: m_state = m_slist;
2667: m_entersound = true;
2668: slist_cursor = 0;
2669: }
2670:
2671:
2672: void M_ServerList_Draw (void)
2673: {
2674: int n;
2675: char string [64];
2676: qpic_t *p;
2677:
2678: p = M_CachePic ("gfx/p_multi.lmp");
2679: M_DrawPic ( (320-p->width)/2, 4, p);
2680: for (n = 0; n < hostCacheCount; n++)
2681: {
2682: if (hostcache[n].maxusers)
2683: sprintf(string, "%-15.15s %-15.15s %2u/%2u\n", hostcache[n].name, hostcache[n].map, hostcache[n].users, hostcache[n].maxusers);
2684: else
2685: sprintf(string, "%-15.15s %-15.15s\n", hostcache[n].name, hostcache[n].map);
2686: M_Print (16, 32 + 8*n, string);
2687: }
2688: M_DrawCharacter (0, 32 + slist_cursor*8, 12+((int)(realtime*4)&1));
2689: }
2690:
2691:
2692: void M_ServerList_Key (int k)
2693: {
2694: switch (k)
2695: {
2696: case K_ESCAPE:
2697: M_Menu_LanConfig_f ();
2698: break;
2699:
2700: case K_UPARROW:
2701: case K_LEFTARROW:
2702: S_LocalSound ("misc/menu1.wav");
2703: slist_cursor--;
2704: if (slist_cursor < 0)
2705: slist_cursor = hostCacheCount - 1;
2706: break;
2707:
2708: case K_DOWNARROW:
2709: case K_RIGHTARROW:
2710: S_LocalSound ("misc/menu1.wav");
2711: slist_cursor++;
2712: if (slist_cursor >= hostCacheCount)
2713: slist_cursor = 0;
2714: break;
2715:
2716: case K_ENTER:
2717: S_LocalSound ("misc/menu2.wav");
2718: key_dest = key_game;
2719: m_state = m_none;
2720: Cbuf_AddText ( va ("connect \"%s\"\n", hostcache[slist_cursor].cname) );
2721: break;
2722:
2723: default:
2724: break;
2725: }
2726:
2727: }
2728:
2729: //=============================================================================
2730: /* Menu Subsystem */
2731:
2732:
2733: void M_Init (void)
2734: {
2735: Cmd_AddCommand ("togglemenu", M_ToggleMenu_f);
2736:
2737: Cmd_AddCommand ("menu_main", M_Menu_Main_f);
2738: Cmd_AddCommand ("menu_singleplayer", M_Menu_SinglePlayer_f);
2739: Cmd_AddCommand ("menu_load", M_Menu_Load_f);
2740: Cmd_AddCommand ("menu_save", M_Menu_Save_f);
2741: Cmd_AddCommand ("menu_multiplayer", M_Menu_MultiPlayer_f);
2742: Cmd_AddCommand ("menu_setup", M_Menu_Setup_f);
2743: Cmd_AddCommand ("menu_options", M_Menu_Options_f);
2744: Cmd_AddCommand ("menu_keys", M_Menu_Keys_f);
2745: Cmd_AddCommand ("menu_video", M_Menu_Video_f);
2746: Cmd_AddCommand ("help", M_Menu_Help_f);
2747: Cmd_AddCommand ("menu_quit", M_Menu_Quit_f);
2748: }
2749:
2750:
2751: void M_Draw (void)
2752: {
2753: if (m_state == m_none || key_dest != key_menu)
2754: return;
2755:
2756: if (!m_recursiveDraw)
2757: {
2758: scr_copyeverything = 1;
2759:
2760: if (scr_con_current)
2761: {
2762: Draw_ConsoleBackground (vid.height);
2763: S_ExtraUpdate ();
2764: }
2765: else
2766: Draw_FadeScreen ();
2767:
2768: scr_fullupdate = 0;
2769: }
2770: else
2771: {
2772: m_recursiveDraw = false;
2773: }
2774:
2775: switch (m_state)
2776: {
2777: case m_none:
2778: break;
2779:
2780: case m_main:
2781: M_Main_Draw ();
2782: break;
2783:
2784: case m_singleplayer:
2785: M_SinglePlayer_Draw ();
2786: break;
2787:
2788: case m_load:
2789: M_Load_Draw ();
2790: break;
2791:
2792: case m_save:
2793: M_Save_Draw ();
2794: break;
2795:
2796: case m_multiplayer:
2797: M_MultiPlayer_Draw ();
2798: break;
2799:
2800: case m_setup:
2801: M_Setup_Draw ();
2802: break;
2803:
2804: case m_net:
2805: M_Net_Draw ();
2806: break;
2807:
2808: case m_options:
2809: M_Options_Draw ();
2810: break;
2811:
2812: case m_keys:
2813: M_Keys_Draw ();
2814: break;
2815:
2816: case m_video:
2817: M_Video_Draw ();
2818: break;
2819:
2820: case m_help:
2821: M_Help_Draw ();
2822: break;
2823:
2824: case m_quit:
2825: M_Quit_Draw ();
2826: break;
2827:
2828: case m_serialconfig:
2829: M_SerialConfig_Draw ();
2830: break;
2831:
2832: case m_modemconfig:
2833: M_ModemConfig_Draw ();
2834: break;
2835:
2836: case m_lanconfig:
2837: M_LanConfig_Draw ();
2838: break;
2839:
2840: case m_gameoptions:
2841: M_GameOptions_Draw ();
2842: break;
2843:
2844: case m_search:
2845: M_Search_Draw ();
2846: break;
2847:
2848: case m_slist:
2849: M_ServerList_Draw ();
2850: break;
2851: }
2852:
2853: if (m_entersound)
2854: {
2855: S_LocalSound ("misc/menu2.wav");
2856: m_entersound = false;
2857: }
2858: S_ExtraUpdate ();
2859: }
2860:
2861:
2862: void M_Keydown (int key)
2863: {
2864: switch (m_state)
2865: {
2866: case m_none:
2867: return;
2868:
2869: case m_main:
2870: M_Main_Key (key);
2871: return;
2872:
2873: case m_singleplayer:
2874: M_SinglePlayer_Key (key);
2875: return;
2876:
2877: case m_load:
2878: M_Load_Key (key);
2879: return;
2880:
2881: case m_save:
2882: M_Save_Key (key);
2883: return;
2884:
2885: case m_multiplayer:
2886: M_MultiPlayer_Key (key);
2887: return;
2888:
2889: case m_setup:
2890: M_Setup_Key (key);
2891: return;
2892:
2893: case m_net:
2894: M_Net_Key (key);
2895: return;
2896:
2897: case m_options:
2898: M_Options_Key (key);
2899: return;
2900:
2901: case m_keys:
2902: M_Keys_Key (key);
2903: return;
2904:
2905: case m_video:
2906: M_Video_Key (key);
2907: return;
2908:
2909: case m_help:
2910: M_Help_Key (key);
2911: return;
2912:
2913: case m_quit:
2914: M_Quit_Key (key);
2915: return;
2916:
2917: case m_serialconfig:
2918: M_SerialConfig_Key (key);
2919: return;
2920:
2921: case m_modemconfig:
2922: M_ModemConfig_Key (key);
2923: return;
2924:
2925: case m_lanconfig:
2926: M_LanConfig_Key (key);
2927: return;
2928:
2929: case m_gameoptions:
2930: M_GameOptions_Key (key);
2931: return;
2932:
2933: case m_search:
2934: M_Search_Key (key);
2935: break;
2936:
2937: case m_slist:
2938: M_ServerList_Key (key);
2939: return;
2940: }
2941: }
2942:
2943:
2944: void M_ConfigureNetSubsystem(void)
2945: {
2946: // enable/disable net systems to match desired config
2947:
2948: Cbuf_AddText ("stopdemo\n");
2949: if (SerialConfig || DirectConfig)
2950: {
2951: Cbuf_AddText ("com1 enable\n");
2952: }
2953: }
2954:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.