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