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_state_t {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, const 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, const 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, "%79s\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 861const char *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 ((int) (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, (int) lookspring.value); 1219 1220 M_Print (16, 120, " Lookstrafe"); 1221 M_DrawCheckbox (220, 120, (int) 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 1315const char *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; 1341 1342void M_Menu_Keys_f (void) 1343{ 1344 key_dest = key_menu; 1345 m_state = m_keys; 1346 m_entersound = true; 1347} 1348 1349 1350void M_FindKeysForCommand (const char *command, int *twokeys) 1351{ 1352 int count; 1353 int j; 1354 int l; 1355 char *b; 1356 1357 twokeys[0] = twokeys[1] = -1; 1358 l = strlen(command); 1359 count = 0; 1360 1361 for (j=0 ; j<256 ; j++) 1362 { 1363 b = keybindings[j]; 1364 if (!b) 1365 continue; 1366 if (!strncmp (b, command, l) ) 1367 { 1368 twokeys[count] = j; 1369 count++; 1370 if (count == 2) 1371 break; 1372 } 1373 } 1374} 1375 1376void M_UnbindCommand (const char *command) 1377{ 1378 int j; 1379 int l; 1380 char *b; 1381 1382 l = strlen(command); 1383 1384 for (j=0 ; j<256 ; j++) 1385 { 1386 b = keybindings[j]; 1387 if (!b) 1388 continue; 1389 if (!strncmp (b, command, l) ) 1390 Key_SetBinding (j, ""); 1391 } 1392} 1393 1394 1395void M_Keys_Draw (void) 1396{ 1397 int i, l; 1398 int keys[2]; 1399 const char *name; 1400 int x, y; 1401 qpic_t *p; 1402 1403 p = Draw_CachePic ("gfx/ttl_cstm.lmp"); 1404 M_DrawPic ( (320-p->width)/2, 4, p); 1405 1406 if (bind_grab) 1407 M_Print (12, 32, "Press a key or button for this action"); 1408 else 1409 M_Print (18, 32, "Enter to change, backspace to clear"); 1410 1411// search for known bindings 1412 for (i=0 ; i< (int) (NUMCOMMANDS) ; i++) 1413 { 1414 y = 48 + 8*i; 1415 1416 M_Print (16, y, bindnames[i][1]); 1417 1418 l = strlen (bindnames[i][0]); 1419 1420 M_FindKeysForCommand (bindnames[i][0], keys); 1421 1422 if (keys[0] == -1) 1423 { 1424 M_Print (140, y, "???"); 1425 } 1426 else 1427 { 1428 name = Key_KeynumToString (keys[0]); 1429 M_Print (140, y, name); 1430 x = strlen(name) * 8; 1431 if (keys[1] != -1) 1432 { 1433 M_Print (140 + x + 8, y, "or"); 1434 M_Print (140 + x + 32, y, Key_KeynumToString (keys[1])); 1435 } 1436 } 1437 } 1438 1439 if (bind_grab) 1440 M_DrawCharacter (130, 48 + keys_cursor*8, '='); 1441 else 1442 M_DrawCharacter (130, 48 + keys_cursor*8, 12+((int)(realtime*4)&1)); 1443} 1444 1445 1446void M_Keys_Key (int k) 1447{ 1448 char cmd[80]; 1449 int keys[2]; 1450 1451 if (bind_grab) 1452 { // defining a key 1453 S_LocalSound ("misc/menu1.wav"); 1454 if (k == K_ESCAPE) 1455 { 1456 bind_grab = false; 1457 } 1458 else if (k != '`') 1459 { 1460 sprintf (cmd, "bind \"%s\" \"%s\"\n", Key_KeynumToString (k), bindnames[keys_cursor][0]); 1461 Cbuf_InsertText (cmd); 1462 } 1463 1464 bind_grab = false; 1465 return; 1466 } 1467 1468 switch (k) 1469 { 1470 case K_ESCAPE: 1471 M_Menu_Options_f (); 1472 break; 1473 1474 case K_LEFTARROW: 1475 case K_UPARROW: 1476 S_LocalSound ("misc/menu1.wav"); 1477 keys_cursor--; 1478 if (keys_cursor < 0) 1479 keys_cursor = NUMCOMMANDS-1; 1480 break; 1481 1482 case K_DOWNARROW: 1483 case K_RIGHTARROW: 1484 S_LocalSound ("misc/menu1.wav"); 1485 keys_cursor++; 1486 if (keys_cursor >= (int)(NUMCOMMANDS)) 1487 keys_cursor = 0; 1488 break; 1489 1490 case K_ENTER: // go into bind mode 1491 M_FindKeysForCommand (bindnames[keys_cursor][0], keys); 1492 S_LocalSound ("misc/menu2.wav"); 1493 if (keys[1] != -1) 1494 M_UnbindCommand (bindnames[keys_cursor][0]); 1495 bind_grab = true; 1496 break; 1497 1498 case K_BACKSPACE: // delete bindings 1499 case K_DEL: // delete bindings 1500 S_LocalSound ("misc/menu2.wav"); 1501 M_UnbindCommand (bindnames[keys_cursor][0]); 1502 break; 1503 } 1504} 1505 1506//============================================================================= 1507/* VIDEO MENU */ 1508 1509void M_Menu_Video_f (void) 1510{ 1511 key_dest = key_menu; 1512 m_state = m_video; 1513 m_entersound = true; 1514} 1515 1516 1517void M_Video_Draw (void) 1518{ 1519 (*vid_menudrawfn) (); 1520} 1521 1522 1523void M_Video_Key (int key) 1524{ 1525 (*vid_menukeyfn) (key); 1526} 1527 1528//============================================================================= 1529/* HELP MENU */ 1530 1531int help_page; 1532#define NUM_HELP_PAGES 6 1533 1534 1535void M_Menu_Help_f (void) 1536{ 1537#if 1 // Hijack menu for timedemo 1538 key_dest = key_menu; 1539 m_state = m_none; 1540 char buf[50]; 1541 strcpy(buf, "timedemo demo1"); 1542 Cmd_TokenizeString(buf); 1543 CL_TimeDemo_f(); 1544#else 1545 key_dest = key_menu; 1546 m_state = m_help; 1547 m_entersound = true; 1548 help_page = 0; 1549#endif 1550} 1551 1552 1553 1554void M_Help_Draw (void) 1555{ 1556 M_DrawPic (0, 0, Draw_CachePic ( va("gfx/help%i.lmp", help_page)) ); 1557} 1558 1559 1560void M_Help_Key (int key) 1561{ 1562 switch (key) 1563 { 1564 case K_ESCAPE: 1565 M_Menu_Main_f (); 1566 break; 1567 1568 case K_UPARROW: 1569 case K_RIGHTARROW: 1570 m_entersound = true; 1571 if (++help_page >= NUM_HELP_PAGES) 1572 help_page = 0; 1573 break; 1574 1575 case K_DOWNARROW: 1576 case K_LEFTARROW: 1577 m_entersound = true; 1578 if (--help_page < 0) 1579 help_page = NUM_HELP_PAGES-1; 1580 break; 1581 } 1582 1583} 1584 1585//============================================================================= 1586/* QUIT MENU */ 1587 1588int msgNumber; 1589int m_quit_prevstate; 1590qboolean wasInMenus; 1591 1592#ifndef _WIN32 1593const char *quitMessage [] = 1594{ 1595/* .........1.........2.... */ 1596 " Are you gonna quit ", 1597 " this game just like ", 1598 " everything else? ", 1599 " ", 1600 1601 " Milord, methinks that ", 1602 " thou art a lowly ", 1603 " quitter. Is this true? ", 1604 " ", 1605 1606 " Do I need to bust your ", 1607 " face open for trying ", 1608 " to quit? ", 1609 " ", 1610 1611 " Man, I oughta smack you", 1612 " for trying to quit! ", 1613 " Press Y to get ", 1614 " smacked out. ", 1615 1616 " Press Y to quit like a ", 1617 " big loser in life. ", 1618 " Press N to stay proud ", 1619 " and successful! ", 1620 1621 " If you press Y to ", 1622 " quit, I will summon ", 1623 " Satan all over your ", 1624 " hard drive! ", 1625 1626 " Um, Asmodeus dislikes ", 1627 " his children trying to ", 1628 " quit. Press Y to return", 1629 " to your Tinkertoys. ", 1630 1631 " If you quit now, I'll ", 1632 " throw a blanket-party ", 1633 " for you next time! ", 1634 " " 1635}; 1636#endif 1637 1638void M_Menu_Quit_f (void) 1639{ 1640 if (m_state == m_quit) 1641 return; 1642 wasInMenus = (key_dest == key_menu); 1643 key_dest = key_menu; 1644 m_quit_prevstate = m_state; 1645 m_state = m_quit; 1646 m_entersound = true; 1647 msgNumber = rand()&7; 1648} 1649 1650 1651void M_Quit_Key (int key) 1652{ 1653 switch (key) 1654 { 1655 case K_ESCAPE: 1656 case 'n': 1657 case 'N': 1658 if (wasInMenus) 1659 { 1660 m_state = (m_state_t) m_quit_prevstate; 1661 m_entersound = true; 1662 } 1663 else 1664 { 1665 key_dest = key_game; 1666 m_state = (m_state_t) m_none; 1667 } 1668 break; 1669 1670 case 'Y': 1671 case 'y': 1672 case K_ENTER: 1673 key_dest = key_console; 1674 Host_Quit_f (); 1675 break; 1676 1677 default: 1678 break; 1679 } 1680 1681} 1682 1683 1684void M_Quit_Draw (void) 1685{ 1686 if (wasInMenus) 1687 { 1688 m_state = (m_state_t) m_quit_prevstate; 1689 m_recursiveDraw = true; 1690 M_Draw (); 1691 m_state = m_quit; 1692 } 1693 1694#ifdef _WIN32 1695 M_DrawTextBox (0, 0, 38, 23); 1696 M_PrintWhite (16, 12, " Quake version 1.09 by id Software\n\n"); 1697 M_PrintWhite (16, 28, "Programming Art \n"); 1698 M_Print (16, 36, " John Carmack Adrian Carmack\n"); 1699 M_Print (16, 44, " Michael Abrash Kevin Cloud\n"); 1700 M_Print (16, 52, " John Cash Paul Steed\n"); 1701 M_Print (16, 60, " Dave 'Zoid' Kirsch\n"); 1702 M_PrintWhite (16, 68, "Design Biz\n"); 1703 M_Print (16, 76, " John Romero Jay Wilbur\n"); 1704 M_Print (16, 84, " Sandy Petersen Mike Wilson\n"); 1705 M_Print (16, 92, " American McGee Donna Jackson\n"); 1706 M_Print (16, 100, " Tim Willits Todd Hollenshead\n"); 1707 M_PrintWhite (16, 108, "Support Projects\n"); 1708 M_Print (16, 116, " Barrett Alexander Shawn Green\n"); 1709 M_PrintWhite (16, 124, "Sound Effects\n"); 1710 M_Print (16, 132, " Trent Reznor and Nine Inch Nails\n\n"); 1711 M_PrintWhite (16, 140, "Quake is a trademark of Id Software,\n"); 1712 M_PrintWhite (16, 148, "inc., (c)1996 Id Software, inc. All\n"); 1713 M_PrintWhite (16, 156, "rights reserved. NIN logo is a\n"); 1714 M_PrintWhite (16, 164, "registered trademark licensed to\n"); 1715 M_PrintWhite (16, 172, "Nothing Interactive, Inc. All rights\n"); 1716 M_PrintWhite (16, 180, "reserved. Press y to exit\n"); 1717#else 1718 M_DrawTextBox (56, 76, 24, 4); 1719#if 0 1720 M_Print (64, 84, quitMessage[msgNumber*4+0]); 1721 M_Print (64, 92, quitMessage[msgNumber*4+1]); 1722 M_Print (64, 100, quitMessage[msgNumber*4+2]); 1723 M_Print (64, 108, quitMessage[msgNumber*4+3]); 1724#else 1725 M_PrintWhite(64, 92, "Click Trackball to Quit"); 1726#endif 1727#endif 1728} 1729 1730//============================================================================= 1731 1732/* SERIAL CONFIG MENU */ 1733 1734int serialConfig_cursor; 1735int serialConfig_cursor_table[] = {48, 64, 80, 96, 112, 132}; 1736#define NUM_SERIALCONFIG_CMDS 6 1737 1738static int ISA_uarts[] = {0x3f8,0x2f8,0x3e8,0x2e8}; 1739static int ISA_IRQs[] = {4,3,4,3}; 1740int serialConfig_baudrate[] = {9600,14400,19200,28800,38400,57600}; 1741 1742int serialConfig_comport; 1743int serialConfig_irq ; 1744int serialConfig_baud; 1745char serialConfig_phone[16]; 1746 1747void M_Menu_SerialConfig_f (void) 1748{ 1749 int n; 1750 int port; 1751 int baudrate; 1752 qboolean useModem; 1753 1754 key_dest = key_menu; 1755 m_state = m_serialconfig; 1756 m_entersound = true; 1757 if (JoiningGame && SerialConfig) 1758 serialConfig_cursor = 4; 1759 else 1760 serialConfig_cursor = 5; 1761 1762 (*GetComPortConfig) (0, &port, &serialConfig_irq, &baudrate, &useModem); 1763 1764 // map uart's port to COMx 1765 for (n = 0; n < 4; n++) 1766 if (ISA_uarts[n] == port) 1767 break; 1768 if (n == 4) 1769 { 1770 n = 0; 1771 serialConfig_irq = 4; 1772 } 1773 serialConfig_comport = n + 1; 1774 1775 // map baudrate to index 1776 for (n = 0; n < 6; n++) 1777 if (serialConfig_baudrate[n] == baudrate) 1778 break; 1779 if (n == 6) 1780 n = 5; 1781 serialConfig_baud = n; 1782 1783 m_return_onerror = false; 1784 m_return_reason[0] = 0; 1785} 1786 1787 1788void M_SerialConfig_Draw (void) 1789{ 1790 qpic_t *p; 1791 int basex; 1792 const char *startJoin; 1793 const char *directModem; 1794 1795 M_DrawTransPic (16, 4, Draw_CachePic ("gfx/qplaque.lmp") ); 1796 p = Draw_CachePic ("gfx/p_multi.lmp"); 1797 basex = (320-p->width)/2; 1798 M_DrawPic (basex, 4, p); 1799 1800 if (StartingGame) 1801 startJoin = "New Game"; 1802 else 1803 startJoin = "Join Game"; 1804 if (SerialConfig) 1805 directModem = "Modem"; 1806 else 1807 directModem = "Direct Connect"; 1808 M_Print (basex, 32, va ("%s - %s", startJoin, directModem)); 1809 basex += 8; 1810 1811 M_Print (basex, serialConfig_cursor_table[0], "Port"); 1812 M_DrawTextBox (160, 40, 4, 1); 1813 M_Print (168, serialConfig_cursor_table[0], va("COM%u", serialConfig_comport)); 1814 1815 M_Print (basex, serialConfig_cursor_table[1], "IRQ"); 1816 M_DrawTextBox (160, serialConfig_cursor_table[1]-8, 1, 1); 1817 M_Print (168, serialConfig_cursor_table[1], va("%u", serialConfig_irq)); 1818 1819 M_Print (basex, serialConfig_cursor_table[2], "Baud"); 1820 M_DrawTextBox (160, serialConfig_cursor_table[2]-8, 5, 1); 1821 M_Print (168, serialConfig_cursor_table[2], va("%u", serialConfig_baudrate[serialConfig_baud])); 1822 1823 if (SerialConfig) 1824 { 1825 M_Print (basex, serialConfig_cursor_table[3], "Modem Setup..."); 1826 if (JoiningGame) 1827 { 1828 M_Print (basex, serialConfig_cursor_table[4], "Phone number"); 1829 M_DrawTextBox (160, serialConfig_cursor_table[4]-8, 16, 1); 1830 M_Print (168, serialConfig_cursor_table[4], serialConfig_phone); 1831 } 1832 } 1833 1834 if (JoiningGame) 1835 { 1836 M_DrawTextBox (basex, serialConfig_cursor_table[5]-8, 7, 1); 1837 M_Print (basex+8, serialConfig_cursor_table[5], "Connect"); 1838 } 1839 else 1840 { 1841 M_DrawTextBox (basex, serialConfig_cursor_table[5]-8, 2, 1); 1842 M_Print (basex+8, serialConfig_cursor_table[5], "OK"); 1843 } 1844 1845 M_DrawCharacter (basex-8, serialConfig_cursor_table [serialConfig_cursor], 12+((int)(realtime*4)&1)); 1846 1847 if (serialConfig_cursor == 4) 1848 M_DrawCharacter (168 + 8*strlen(serialConfig_phone), serialConfig_cursor_table [serialConfig_cursor], 10+((int)(realtime*4)&1)); 1849 1850 if (*m_return_reason) 1851 M_PrintWhite (basex, 148, m_return_reason); 1852} 1853 1854 1855void M_SerialConfig_Key (int key) 1856{ 1857 int l; 1858 1859 switch (key) 1860 { 1861 case K_ESCAPE: 1862 M_Menu_Net_f (); 1863 break; 1864 1865 case K_UPARROW: 1866 S_LocalSound ("misc/menu1.wav"); 1867 serialConfig_cursor--; 1868 if (serialConfig_cursor < 0) 1869 serialConfig_cursor = NUM_SERIALCONFIG_CMDS-1; 1870 break; 1871 1872 case K_DOWNARROW: 1873 S_LocalSound ("misc/menu1.wav"); 1874 serialConfig_cursor++; 1875 if (serialConfig_cursor >= NUM_SERIALCONFIG_CMDS) 1876 serialConfig_cursor = 0; 1877 break; 1878 1879 case K_LEFTARROW: 1880 if (serialConfig_cursor > 2) 1881 break; 1882 S_LocalSound ("misc/menu3.wav"); 1883 1884 if (serialConfig_cursor == 0) 1885 { 1886 serialConfig_comport--; 1887 if (serialConfig_comport == 0) 1888 serialConfig_comport = 4; 1889 serialConfig_irq = ISA_IRQs[serialConfig_comport-1]; 1890 } 1891 1892 if (serialConfig_cursor == 1) 1893 { 1894 serialConfig_irq--; 1895 if (serialConfig_irq == 6) 1896 serialConfig_irq = 5; 1897 if (serialConfig_irq == 1) 1898 serialConfig_irq = 7; 1899 } 1900 1901 if (serialConfig_cursor == 2) 1902 { 1903 serialConfig_baud--; 1904 if (serialConfig_baud < 0) 1905 serialConfig_baud = 5; 1906 } 1907 1908 break; 1909 1910 case K_RIGHTARROW: 1911 if (serialConfig_cursor > 2) 1912 break; 1913forward: 1914 S_LocalSound ("misc/menu3.wav"); 1915 1916 if (serialConfig_cursor == 0) 1917 { 1918 serialConfig_comport++; 1919 if (serialConfig_comport > 4) 1920 serialConfig_comport = 1; 1921 serialConfig_irq = ISA_IRQs[serialConfig_comport-1]; 1922 } 1923 1924 if (serialConfig_cursor == 1) 1925 { 1926 serialConfig_irq++; 1927 if (serialConfig_irq == 6) 1928 serialConfig_irq = 7; 1929 if (serialConfig_irq == 8) 1930 serialConfig_irq = 2; 1931 } 1932 1933 if (serialConfig_cursor == 2) 1934 { 1935 serialConfig_baud++; 1936 if (serialConfig_baud > 5) 1937 serialConfig_baud = 0; 1938 } 1939 1940 break; 1941 1942 case K_ENTER: 1943 if (serialConfig_cursor < 3) 1944 goto forward; 1945 1946 m_entersound = true; 1947 1948 if (serialConfig_cursor == 3) 1949 { 1950 (*SetComPortConfig) (0, ISA_uarts[serialConfig_comport-1], serialConfig_irq, serialConfig_baudrate[serialConfig_baud], SerialConfig); 1951 1952 M_Menu_ModemConfig_f (); 1953 break; 1954 } 1955 1956 if (serialConfig_cursor == 4) 1957 { 1958 serialConfig_cursor = 5; 1959 break; 1960 } 1961 1962 // serialConfig_cursor == 5 (OK/CONNECT) 1963 (*SetComPortConfig) (0, ISA_uarts[serialConfig_comport-1], serialConfig_irq, serialConfig_baudrate[serialConfig_baud], SerialConfig); 1964 1965 M_ConfigureNetSubsystem (); 1966 1967 if (StartingGame) 1968 { 1969 M_Menu_GameOptions_f (); 1970 break; 1971 } 1972 1973 m_return_state = m_state; 1974 m_return_onerror = true; 1975 key_dest = key_game; 1976 m_state = m_none; 1977 1978 if (SerialConfig) 1979 Cbuf_AddText (va ("connect \"%s\"\n", serialConfig_phone)); 1980 else 1981 Cbuf_AddText ("connect\n"); 1982 break; 1983 1984 case K_BACKSPACE: 1985 if (serialConfig_cursor == 4) 1986 { 1987 if (strlen(serialConfig_phone)) 1988 serialConfig_phone[strlen(serialConfig_phone)-1] = 0; 1989 } 1990 break; 1991 1992 default: 1993 if (key < 32 || key > 127) 1994 break; 1995 if (serialConfig_cursor == 4) 1996 { 1997 l = strlen(serialConfig_phone); 1998 if (l < 15) 1999 { 2000 serialConfig_phone[l+1] = 0; 2001 serialConfig_phone[l] = key; 2002 } 2003 } 2004 } 2005 2006 if (DirectConfig && (serialConfig_cursor == 3 || serialConfig_cursor == 4)) 2007 { 2008 if (key == K_UPARROW) 2009 serialConfig_cursor = 2; 2010 else 2011 serialConfig_cursor = 5; 2012 } 2013 if (SerialConfig && StartingGame && serialConfig_cursor == 4) 2014 { 2015 if (key == K_UPARROW) 2016 serialConfig_cursor = 3; 2017 else 2018 serialConfig_cursor = 5; 2019 } 2020} 2021 2022//============================================================================= 2023/* MODEM CONFIG MENU */ 2024 2025int modemConfig_cursor; 2026int modemConfig_cursor_table [] = {40, 56, 88, 120, 156}; 2027#define NUM_MODEMCONFIG_CMDS 5 2028 2029char modemConfig_dialing; 2030char modemConfig_clear [16]; 2031char modemConfig_init [32]; 2032char modemConfig_hangup [16]; 2033 2034void M_Menu_ModemConfig_f (void) 2035{ 2036 key_dest = key_menu; 2037 m_state = m_modemconfig; 2038 m_entersound = true; 2039 (*GetModemConfig) (0, &modemConfig_dialing, modemConfig_clear, modemConfig_init, modemConfig_hangup); 2040} 2041 2042 2043void M_ModemConfig_Draw (void) 2044{ 2045 qpic_t *p; 2046 int basex; 2047 2048 M_DrawTransPic (16, 4, Draw_CachePic ("gfx/qplaque.lmp") ); 2049 p = Draw_CachePic ("gfx/p_multi.lmp"); 2050 basex = (320-p->width)/2; 2051 M_DrawPic (basex, 4, p); 2052 basex += 8; 2053 2054 if (modemConfig_dialing == 'P') 2055 M_Print (basex, modemConfig_cursor_table[0], "Pulse Dialing"); 2056 else 2057 M_Print (basex, modemConfig_cursor_table[0], "Touch Tone Dialing"); 2058 2059 M_Print (basex, modemConfig_cursor_table[1], "Clear"); 2060 M_DrawTextBox (basex, modemConfig_cursor_table[1]+4, 16, 1); 2061 M_Print (basex+8, modemConfig_cursor_table[1]+12, modemConfig_clear); 2062 if (modemConfig_cursor == 1) 2063 M_DrawCharacter (basex+8 + 8*strlen(modemConfig_clear), modemConfig_cursor_table[1]+12, 10+((int)(realtime*4)&1)); 2064 2065 M_Print (basex, modemConfig_cursor_table[2], "Init"); 2066 M_DrawTextBox (basex, modemConfig_cursor_table[2]+4, 30, 1); 2067 M_Print (basex+8, modemConfig_cursor_table[2]+12, modemConfig_init); 2068 if (modemConfig_cursor == 2) 2069 M_DrawCharacter (basex+8 + 8*strlen(modemConfig_init), modemConfig_cursor_table[2]+12, 10+((int)(realtime*4)&1)); 2070 2071 M_Print (basex, modemConfig_cursor_table[3], "Hangup"); 2072 M_DrawTextBox (basex, modemConfig_cursor_table[3]+4, 16, 1); 2073 M_Print (basex+8, modemConfig_cursor_table[3]+12, modemConfig_hangup); 2074 if (modemConfig_cursor == 3) 2075 M_DrawCharacter (basex+8 + 8*strlen(modemConfig_hangup), modemConfig_cursor_table[3]+12, 10+((int)(realtime*4)&1)); 2076 2077 M_DrawTextBox (basex, modemConfig_cursor_table[4]-8, 2, 1); 2078 M_Print (basex+8, modemConfig_cursor_table[4], "OK"); 2079 2080 M_DrawCharacter (basex-8, modemConfig_cursor_table [modemConfig_cursor], 12+((int)(realtime*4)&1)); 2081} 2082 2083 2084void M_ModemConfig_Key (int key) 2085{ 2086 int l; 2087 2088 switch (key) 2089 { 2090 case K_ESCAPE: 2091 M_Menu_SerialConfig_f (); 2092 break; 2093 2094 case K_UPARROW: 2095 S_LocalSound ("misc/menu1.wav"); 2096 modemConfig_cursor--; 2097 if (modemConfig_cursor < 0) 2098 modemConfig_cursor = NUM_MODEMCONFIG_CMDS-1; 2099 break; 2100 2101 case K_DOWNARROW: 2102 S_LocalSound ("misc/menu1.wav"); 2103 modemConfig_cursor++; 2104 if (modemConfig_cursor >= NUM_MODEMCONFIG_CMDS) 2105 modemConfig_cursor = 0; 2106 break; 2107 2108 case K_LEFTARROW: 2109 case K_RIGHTARROW: 2110 if (modemConfig_cursor == 0) 2111 { 2112 if (modemConfig_dialing == 'P') 2113 modemConfig_dialing = 'T'; 2114 else 2115 modemConfig_dialing = 'P'; 2116 S_LocalSound ("misc/menu1.wav"); 2117 } 2118 break; 2119 2120 case K_ENTER: 2121 if (modemConfig_cursor == 0) 2122 { 2123 if (modemConfig_dialing == 'P') 2124 modemConfig_dialing = 'T'; 2125 else 2126 modemConfig_dialing = 'P'; 2127 m_entersound = true; 2128 } 2129 2130 if (modemConfig_cursor == 4) 2131 { 2132 (*SetModemConfig) (0, va ("%c", modemConfig_dialing), modemConfig_clear, modemConfig_init, modemConfig_hangup); 2133 m_entersound = true; 2134 M_Menu_SerialConfig_f (); 2135 } 2136 break; 2137 2138 case K_BACKSPACE: 2139 if (modemConfig_cursor == 1) 2140 { 2141 if (strlen(modemConfig_clear)) 2142 modemConfig_clear[strlen(modemConfig_clear)-1] = 0; 2143 } 2144 2145 if (modemConfig_cursor == 2) 2146 { 2147 if (strlen(modemConfig_init)) 2148 modemConfig_init[strlen(modemConfig_init)-1] = 0; 2149 } 2150 2151 if (modemConfig_cursor == 3) 2152 { 2153 if (strlen(modemConfig_hangup)) 2154 modemConfig_hangup[strlen(modemConfig_hangup)-1] = 0; 2155 } 2156 break; 2157 2158 default: 2159 if (key < 32 || key > 127) 2160 break; 2161 2162 if (modemConfig_cursor == 1) 2163 { 2164 l = strlen(modemConfig_clear); 2165 if (l < 15) 2166 { 2167 modemConfig_clear[l+1] = 0; 2168 modemConfig_clear[l] = key; 2169 } 2170 } 2171 2172 if (modemConfig_cursor == 2) 2173 { 2174 l = strlen(modemConfig_init); 2175 if (l < 29) 2176 { 2177 modemConfig_init[l+1] = 0; 2178 modemConfig_init[l] = key; 2179 } 2180 } 2181 2182 if (modemConfig_cursor == 3) 2183 { 2184 l = strlen(modemConfig_hangup); 2185 if (l < 15) 2186 { 2187 modemConfig_hangup[l+1] = 0; 2188 modemConfig_hangup[l] = key; 2189 } 2190 } 2191 } 2192} 2193 2194//============================================================================= 2195/* LAN CONFIG MENU */ 2196 2197int lanConfig_cursor = -1; 2198int lanConfig_cursor_table [] = {72, 92, 124}; 2199#define NUM_LANCONFIG_CMDS 3 2200 2201int lanConfig_port; 2202char lanConfig_portname[6]; 2203char lanConfig_joinname[22]; 2204 2205void M_Menu_LanConfig_f (void) 2206{ 2207 key_dest = key_menu; 2208 m_state = m_lanconfig; 2209 m_entersound = true; 2210 if (lanConfig_cursor == -1) 2211 { 2212 if (JoiningGame && TCPIPConfig) 2213 lanConfig_cursor = 2; 2214 else 2215 lanConfig_cursor = 1; 2216 } 2217 if (StartingGame && lanConfig_cursor == 2) 2218 lanConfig_cursor = 1; 2219 lanConfig_port = DEFAULTnet_hostport; 2220 sprintf(lanConfig_portname, "%u", lanConfig_port); 2221 2222 m_return_onerror = false; 2223 m_return_reason[0] = 0; 2224} 2225 2226 2227void M_LanConfig_Draw (void) 2228{ 2229 qpic_t *p; 2230 int basex; 2231 const char *startJoin; 2232 const char *protocol; 2233 2234 M_DrawTransPic (16, 4, Draw_CachePic ("gfx/qplaque.lmp") ); 2235 p = Draw_CachePic ("gfx/p_multi.lmp"); 2236 basex = (320-p->width)/2; 2237 M_DrawPic (basex, 4, p); 2238 2239 if (StartingGame) 2240 startJoin = "New Game"; 2241 else 2242 startJoin = "Join Game"; 2243 if (IPXConfig) 2244 protocol = "IPX"; 2245 else 2246 protocol = "TCP/IP"; 2247 M_Print (basex, 32, va ("%s - %s", startJoin, protocol)); 2248 basex += 8; 2249 2250 M_Print (basex, 52, "Address:"); 2251 if (IPXConfig) 2252 M_Print (basex+9*8, 52, my_ipx_address); 2253 else 2254 M_Print (basex+9*8, 52, my_tcpip_address); 2255 2256 M_Print (basex, lanConfig_cursor_table[0], "Port"); 2257 M_DrawTextBox (basex+8*8, lanConfig_cursor_table[0]-8, 6, 1); 2258 M_Print (basex+9*8, lanConfig_cursor_table[0], lanConfig_portname); 2259 2260 if (JoiningGame) 2261 { 2262 M_Print (basex, lanConfig_cursor_table[1], "Search for local games..."); 2263 M_Print (basex, 108, "Join game at:"); 2264 M_DrawTextBox (basex+8, lanConfig_cursor_table[2]-8, 22, 1); 2265 M_Print (basex+16, lanConfig_cursor_table[2], lanConfig_joinname); 2266 } 2267 else 2268 { 2269 M_DrawTextBox (basex, lanConfig_cursor_table[1]-8, 2, 1); 2270 M_Print (basex+8, lanConfig_cursor_table[1], "OK"); 2271 } 2272 2273 M_DrawCharacter (basex-8, lanConfig_cursor_table [lanConfig_cursor], 12+((int)(realtime*4)&1)); 2274 2275 if (lanConfig_cursor == 0) 2276 M_DrawCharacter (basex+9*8 + 8*strlen(lanConfig_portname), lanConfig_cursor_table [0], 10+((int)(realtime*4)&1)); 2277 2278 if (lanConfig_cursor == 2) 2279 M_DrawCharacter (basex+16 + 8*strlen(lanConfig_joinname), lanConfig_cursor_table [2], 10+((int)(realtime*4)&1)); 2280 2281 if (*m_return_reason) 2282 M_PrintWhite (basex, 148, m_return_reason); 2283} 2284 2285 2286void M_LanConfig_Key (int key) 2287{ 2288 int l; 2289 2290 switch (key) 2291 { 2292 case K_ESCAPE: 2293 M_Menu_Net_f (); 2294 break; 2295 2296 case K_UPARROW: 2297 S_LocalSound ("misc/menu1.wav"); 2298 lanConfig_cursor--; 2299 if (lanConfig_cursor < 0) 2300 lanConfig_cursor = NUM_LANCONFIG_CMDS-1; 2301 break; 2302 2303 case K_DOWNARROW: 2304 S_LocalSound ("misc/menu1.wav"); 2305 lanConfig_cursor++; 2306 if (lanConfig_cursor >= NUM_LANCONFIG_CMDS) 2307 lanConfig_cursor = 0; 2308 break; 2309 2310 case K_ENTER: 2311 if (lanConfig_cursor == 0) 2312 break; 2313 2314 m_entersound = true; 2315 2316 M_ConfigureNetSubsystem (); 2317 2318 if (lanConfig_cursor == 1) 2319 { 2320 if (StartingGame) 2321 { 2322 M_Menu_GameOptions_f (); 2323 break; 2324 } 2325 M_Menu_Search_f(); 2326 break; 2327 } 2328 2329 if (lanConfig_cursor == 2) 2330 { 2331 m_return_state = m_state; 2332 m_return_onerror = true; 2333 key_dest = key_game; 2334 m_state = m_none; 2335 Cbuf_AddText ( va ("connect \"%s\"\n", lanConfig_joinname) ); 2336 break; 2337 } 2338 2339 break; 2340 2341 case K_BACKSPACE: 2342 if (lanConfig_cursor == 0) 2343 { 2344 if (strlen(lanConfig_portname)) 2345 lanConfig_portname[strlen(lanConfig_portname)-1] = 0; 2346 } 2347 2348 if (lanConfig_cursor == 2) 2349 { 2350 if (strlen(lanConfig_joinname)) 2351 lanConfig_joinname[strlen(lanConfig_joinname)-1] = 0; 2352 } 2353 break; 2354 2355 default: 2356 if (key < 32 || key > 127) 2357 break; 2358 2359 if (lanConfig_cursor == 2) 2360 { 2361 l = strlen(lanConfig_joinname); 2362 if (l < 21) 2363 { 2364 lanConfig_joinname[l+1] = 0; 2365 lanConfig_joinname[l] = key; 2366 } 2367 } 2368 2369 if (key < '0' || key > '9') 2370 break; 2371 if (lanConfig_cursor == 0) 2372 { 2373 l = strlen(lanConfig_portname); 2374 if (l < 5) 2375 { 2376 lanConfig_portname[l+1] = 0; 2377 lanConfig_portname[l] = key; 2378 } 2379 } 2380 } 2381 2382 if (StartingGame && lanConfig_cursor == 2) 2383 { 2384 if (key == K_UPARROW) 2385 lanConfig_cursor = 1; 2386 else 2387 lanConfig_cursor = 0; 2388 } 2389 2390 l = Q_atoi(lanConfig_portname); 2391 if (l > 65535) 2392 l = lanConfig_port; 2393 else 2394 lanConfig_port = l; 2395 sprintf(lanConfig_portname, "%u", lanConfig_port); 2396} 2397 2398//============================================================================= 2399/* GAME OPTIONS MENU */ 2400 2401typedef struct 2402{ 2403 const char *name; 2404 const char *description; 2405} level_t; 2406 2407level_t levels[] = 2408{ 2409 {"start", "Entrance"}, // 0 2410 2411 {"e1m1", "Slipgate Complex"}, // 1 2412 {"e1m2", "Castle of the Damned"}, 2413 {"e1m3", "The Necropolis"}, 2414 {"e1m4", "The Grisly Grotto"}, 2415 {"e1m5", "Gloom Keep"}, 2416 {"e1m6", "The Door To Chthon"}, 2417 {"e1m7", "The House of Chthon"}, 2418 {"e1m8", "Ziggurat Vertigo"}, 2419 2420 {"e2m1", "The Installation"}, // 9 2421 {"e2m2", "Ogre Citadel"}, 2422 {"e2m3", "Crypt of Decay"}, 2423 {"e2m4", "The Ebon Fortress"}, 2424 {"e2m5", "The Wizard's Manse"}, 2425 {"e2m6", "The Dismal Oubliette"}, 2426 {"e2m7", "Underearth"}, 2427 2428 {"e3m1", "Termination Central"}, // 16 2429 {"e3m2", "The Vaults of Zin"}, 2430 {"e3m3", "The Tomb of Terror"}, 2431 {"e3m4", "Satan's Dark Delight"}, 2432 {"e3m5", "Wind Tunnels"}, 2433 {"e3m6", "Chambers of Torment"}, 2434 {"e3m7", "The Haunted Halls"}, 2435 2436 {"e4m1", "The Sewage System"}, // 23 2437 {"e4m2", "The Tower of Despair"}, 2438 {"e4m3", "The Elder God Shrine"}, 2439 {"e4m4", "The Palace of Hate"}, 2440 {"e4m5", "Hell's Atrium"}, 2441 {"e4m6", "The Pain Maze"}, 2442 {"e4m7", "Azure Agony"}, 2443 {"e4m8", "The Nameless City"}, 2444 2445 {"end", "Shub-Niggurath's Pit"}, // 31 2446 2447 {"dm1", "Place of Two Deaths"}, // 32 2448 {"dm2", "Claustrophobopolis"}, 2449 {"dm3", "The Abandoned Base"}, 2450 {"dm4", "The Bad Place"}, 2451 {"dm5", "The Cistern"}, 2452 {"dm6", "The Dark Zone"} 2453}; 2454 2455//MED 01/06/97 added hipnotic levels 2456level_t hipnoticlevels[] = 2457{ 2458 {"start", "Command HQ"}, // 0 2459 2460 {"hip1m1", "The Pumping Station"}, // 1 2461 {"hip1m2", "Storage Facility"}, 2462 {"hip1m3", "The Lost Mine"}, 2463 {"hip1m4", "Research Facility"}, 2464 {"hip1m5", "Military Complex"}, 2465 2466 {"hip2m1", "Ancient Realms"}, // 6 2467 {"hip2m2", "The Black Cathedral"}, 2468 {"hip2m3", "The Catacombs"}, 2469 {"hip2m4", "The Crypt"}, 2470 {"hip2m5", "Mortum's Keep"}, 2471 {"hip2m6", "The Gremlin's Domain"}, 2472 2473 {"hip3m1", "Tur Torment"}, // 12 2474 {"hip3m2", "Pandemonium"}, 2475 {"hip3m3", "Limbo"}, 2476 {"hip3m4", "The Gauntlet"}, 2477 2478 {"hipend", "Armagon's Lair"}, // 16 2479 2480 {"hipdm1", "The Edge of Oblivion"} // 17 2481}; 2482 2483//PGM 01/07/97 added rogue levels 2484//PGM 03/02/97 added dmatch level 2485level_t roguelevels[] = 2486{ 2487 {"start", "Split Decision"}, 2488 {"r1m1", "Deviant's Domain"}, 2489 {"r1m2", "Dread Portal"}, 2490 {"r1m3", "Judgement Call"}, 2491 {"r1m4", "Cave of Death"}, 2492 {"r1m5", "Towers of Wrath"}, 2493 {"r1m6", "Temple of Pain"}, 2494 {"r1m7", "Tomb of the Overlord"}, 2495 {"r2m1", "Tempus Fugit"}, 2496 {"r2m2", "Elemental Fury I"}, 2497 {"r2m3", "Elemental Fury II"}, 2498 {"r2m4", "Curse of Osiris"}, 2499 {"r2m5", "Wizard's Keep"}, 2500 {"r2m6", "Blood Sacrifice"}, 2501 {"r2m7", "Last Bastion"}, 2502 {"r2m8", "Source of Evil"}, 2503 {"ctf1", "Division of Change"} 2504}; 2505 2506typedef struct 2507{ 2508 const char *description; 2509 int firstLevel; 2510 int levels; 2511} episode_t; 2512 2513episode_t episodes[] = 2514{ 2515 {"Welcome to Quake", 0, 1}, 2516 {"Doomed Dimension", 1, 8}, 2517 {"Realm of Black Magic", 9, 7}, 2518 {"Netherworld", 16, 7}, 2519 {"The Elder World", 23, 8}, 2520 {"Final Level", 31, 1}, 2521 {"Deathmatch Arena", 32, 6} 2522}; 2523 2524//MED 01/06/97 added hipnotic episodes 2525episode_t hipnoticepisodes[] = 2526{ 2527 {"Scourge of Armagon", 0, 1}, 2528 {"Fortress of the Dead", 1, 5}, 2529 {"Dominion of Darkness", 6, 6}, 2530 {"The Rift", 12, 4}, 2531 {"Final Level", 16, 1}, 2532 {"Deathmatch Arena", 17, 1} 2533}; 2534 2535//PGM 01/07/97 added rogue episodes 2536//PGM 03/02/97 added dmatch episode 2537episode_t rogueepisodes[] = 2538{ 2539 {"Introduction", 0, 1}, 2540 {"Hell's Fortress", 1, 7}, 2541 {"Corridors of Time", 8, 8}, 2542 {"Deathmatch Arena", 16, 1} 2543}; 2544 2545int startepisode; 2546int startlevel; 2547int maxplayers; 2548qboolean m_serverInfoMessage = false; 2549double m_serverInfoMessageTime; 2550 2551void M_Menu_GameOptions_f (void) 2552{ 2553 key_dest = key_menu; 2554 m_state = m_gameoptions; 2555 m_entersound = true; 2556 if (maxplayers == 0) 2557 maxplayers = svs.maxclients; 2558 if (maxplayers < 2) 2559 maxplayers = svs.maxclientslimit; 2560} 2561 2562 2563int gameoptions_cursor_table[] = {40, 56, 64, 72, 80, 88, 96, 112, 120}; 2564#define NUM_GAMEOPTIONS 9 2565int gameoptions_cursor; 2566 2567void M_GameOptions_Draw (void) 2568{ 2569 qpic_t *p; 2570 int x; 2571 2572 M_DrawTransPic (16, 4, Draw_CachePic ("gfx/qplaque.lmp") ); 2573 p = Draw_CachePic ("gfx/p_multi.lmp"); 2574 M_DrawPic ( (320-p->width)/2, 4, p); 2575 2576 M_DrawTextBox (152, 32, 10, 1); 2577 M_Print (160, 40, "begin game"); 2578 2579 M_Print (0, 56, " Max players"); 2580 M_Print (160, 56, va("%i", maxplayers) ); 2581 2582 M_Print (0, 64, " Game Type"); 2583 if (coop.value) 2584 M_Print (160, 64, "Cooperative"); 2585 else 2586 M_Print (160, 64, "Deathmatch"); 2587 2588 M_Print (0, 72, " Teamplay"); 2589 if (rogue) 2590 { 2591 const 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 case 3: msg = "Tag"; break; 2598 case 4: msg = "Capture the Flag"; break; 2599 case 5: msg = "One Flag CTF"; break; 2600 case 6: msg = "Three Team CTF"; break; 2601 default: msg = "Off"; break; 2602 } 2603 M_Print (160, 72, msg); 2604 } 2605 else 2606 { 2607 const char *msg; 2608 2609 switch((int)teamplay.value) 2610 { 2611 case 1: msg = "No Friendly Fire"; break; 2612 case 2: msg = "Friendly Fire"; break; 2613 default: msg = "Off"; break; 2614 } 2615 M_Print (160, 72, msg); 2616 } 2617 2618 M_Print (0, 80, " Skill"); 2619 if (skill.value == 0) 2620 M_Print (160, 80, "Easy difficulty"); 2621 else if (skill.value == 1) 2622 M_Print (160, 80, "Normal difficulty"); 2623 else if (skill.value == 2) 2624 M_Print (160, 80, "Hard difficulty"); 2625 else 2626 M_Print (160, 80, "Nightmare difficulty"); 2627 2628 M_Print (0, 88, " Frag Limit"); 2629 if (fraglimit.value == 0) 2630 M_Print (160, 88, "none"); 2631 else 2632 M_Print (160, 88, va("%i frags", (int)fraglimit.value)); 2633 2634 M_Print (0, 96, " Time Limit"); 2635 if (timelimit.value == 0) 2636 M_Print (160, 96, "none"); 2637 else 2638 M_Print (160, 96, va("%i minutes", (int)timelimit.value)); 2639 2640 M_Print (0, 112, " Episode"); 2641 //MED 01/06/97 added hipnotic episodes 2642 if (hipnotic) 2643 M_Print (160, 112, hipnoticepisodes[startepisode].description); 2644 //PGM 01/07/97 added rogue episodes 2645 else if (rogue) 2646 M_Print (160, 112, rogueepisodes[startepisode].description); 2647 else 2648 M_Print (160, 112, episodes[startepisode].description); 2649 2650 M_Print (0, 120, " Level"); 2651 //MED 01/06/97 added hipnotic episodes 2652 if (hipnotic) 2653 { 2654 M_Print (160, 120, hipnoticlevels[hipnoticepisodes[startepisode].firstLevel + startlevel].description); 2655 M_Print (160, 128, hipnoticlevels[hipnoticepisodes[startepisode].firstLevel + startlevel].name); 2656 } 2657 //PGM 01/07/97 added rogue episodes 2658 else if (rogue) 2659 { 2660 M_Print (160, 120, roguelevels[rogueepisodes[startepisode].firstLevel + startlevel].description); 2661 M_Print (160, 128, roguelevels[rogueepisodes[startepisode].firstLevel + startlevel].name); 2662 } 2663 else 2664 { 2665 M_Print (160, 120, levels[episodes[startepisode].firstLevel + startlevel].description); 2666 M_Print (160, 128, levels[episodes[startepisode].firstLevel + startlevel].name); 2667 } 2668 2669// line cursor 2670 M_DrawCharacter (144, gameoptions_cursor_table[gameoptions_cursor], 12+((int)(realtime*4)&1)); 2671 2672 if (m_serverInfoMessage) 2673 { 2674 if ((realtime - m_serverInfoMessageTime) < 5.0) 2675 { 2676 x = (320-26*8)/2; 2677 M_DrawTextBox (x, 138, 24, 4); 2678 x += 8; 2679 M_Print (x, 146, " More than 4 players "); 2680 M_Print (x, 154, " requires using command "); 2681 M_Print (x, 162, "line parameters; please "); 2682 M_Print (x, 170, " see techinfo.txt. "); 2683 } 2684 else 2685 { 2686 m_serverInfoMessage = false; 2687 } 2688 } 2689} 2690 2691 2692void M_NetStart_Change (int dir) 2693{ 2694 int count; 2695 2696 switch (gameoptions_cursor) 2697 { 2698 case 1: 2699 maxplayers += dir; 2700 if (maxplayers > svs.maxclientslimit) 2701 { 2702 maxplayers = svs.maxclientslimit; 2703 m_serverInfoMessage = true; 2704 m_serverInfoMessageTime = realtime; 2705 } 2706 if (maxplayers < 2) 2707 maxplayers = 2; 2708 break; 2709 2710 case 2: 2711 Cvar_SetValue ("coop", coop.value ? 0 : 1); 2712 break; 2713 2714 case 3: 2715 if (rogue) 2716 count = 6; 2717 else 2718 count = 2; 2719 2720 Cvar_SetValue ("teamplay", teamplay.value + dir); 2721 if (teamplay.value > count) 2722 Cvar_SetValue ("teamplay", 0); 2723 else if (teamplay.value < 0) 2724 Cvar_SetValue ("teamplay", count); 2725 break; 2726 2727 case 4: 2728 Cvar_SetValue ("skill", skill.value + dir); 2729 if (skill.value > 3) 2730 Cvar_SetValue ("skill", 0); 2731 if (skill.value < 0) 2732 Cvar_SetValue ("skill", 3); 2733 break; 2734 2735 case 5: 2736 Cvar_SetValue ("fraglimit", fraglimit.value + dir*10); 2737 if (fraglimit.value > 100) 2738 Cvar_SetValue ("fraglimit", 0); 2739 if (fraglimit.value < 0) 2740 Cvar_SetValue ("fraglimit", 100); 2741 break; 2742 2743 case 6: 2744 Cvar_SetValue ("timelimit", timelimit.value + dir*5); 2745 if (timelimit.value > 60) 2746 Cvar_SetValue ("timelimit", 0); 2747 if (timelimit.value < 0) 2748 Cvar_SetValue ("timelimit", 60); 2749 break; 2750 2751 case 7: 2752 startepisode += dir; 2753 //MED 01/06/97 added hipnotic count 2754 if (hipnotic) 2755 count = 6; 2756 //PGM 01/07/97 added rogue count 2757 //PGM 03/02/97 added 1 for dmatch episode 2758 else if (rogue) 2759 count = 4; 2760 else if (registered.value) 2761 count = 7; 2762 else 2763 count = 2; 2764 2765 if (startepisode < 0) 2766 startepisode = count - 1; 2767 2768 if (startepisode >= count) 2769 startepisode = 0; 2770 2771 startlevel = 0; 2772 break; 2773 2774 case 8: 2775 startlevel += dir; 2776 //MED 01/06/97 added hipnotic episodes 2777 if (hipnotic) 2778 count = hipnoticepisodes[startepisode].levels; 2779 //PGM 01/06/97 added hipnotic episodes 2780 else if (rogue) 2781 count = rogueepisodes[startepisode].levels; 2782 else 2783 count = episodes[startepisode].levels; 2784 2785 if (startlevel < 0) 2786 startlevel = count - 1; 2787 2788 if (startlevel >= count) 2789 startlevel = 0; 2790 break; 2791 } 2792} 2793 2794void M_GameOptions_Key (int key) 2795{ 2796 switch (key) 2797 { 2798 case K_ESCAPE: 2799 M_Menu_Net_f (); 2800 break; 2801 2802 case K_UPARROW: 2803 S_LocalSound ("misc/menu1.wav"); 2804 gameoptions_cursor--; 2805 if (gameoptions_cursor < 0) 2806 gameoptions_cursor = NUM_GAMEOPTIONS-1; 2807 break; 2808 2809 case K_DOWNARROW: 2810 S_LocalSound ("misc/menu1.wav"); 2811 gameoptions_cursor++; 2812 if (gameoptions_cursor >= NUM_GAMEOPTIONS) 2813 gameoptions_cursor = 0; 2814 break; 2815 2816 case K_LEFTARROW: 2817 if (gameoptions_cursor == 0) 2818 break; 2819 S_LocalSound ("misc/menu3.wav"); 2820 M_NetStart_Change (-1); 2821 break; 2822 2823 case K_RIGHTARROW: 2824 if (gameoptions_cursor == 0) 2825 break; 2826 S_LocalSound ("misc/menu3.wav"); 2827 M_NetStart_Change (1); 2828 break; 2829 2830 case K_ENTER: 2831 S_LocalSound ("misc/menu2.wav"); 2832 if (gameoptions_cursor == 0) 2833 { 2834 if (sv.active) 2835 Cbuf_AddText ("disconnect\n"); 2836 Cbuf_AddText ("listen 0\n"); // so host_netport will be re-examined 2837 Cbuf_AddText ( va ("maxplayers %u\n", maxplayers) ); 2838 SCR_BeginLoadingPlaque (); 2839 2840 if (hipnotic) 2841 Cbuf_AddText ( va ("map %s\n", hipnoticlevels[hipnoticepisodes[startepisode].firstLevel + startlevel].name) ); 2842 else if (rogue) 2843 Cbuf_AddText ( va ("map %s\n", roguelevels[rogueepisodes[startepisode].firstLevel + startlevel].name) ); 2844 else 2845 Cbuf_AddText ( va ("map %s\n", levels[episodes[startepisode].firstLevel + startlevel].name) ); 2846 2847 return; 2848 } 2849 2850 M_NetStart_Change (1); 2851 break; 2852 } 2853} 2854 2855//============================================================================= 2856/* SEARCH MENU */ 2857 2858qboolean searchComplete = false; 2859double searchCompleteTime; 2860 2861void M_Menu_Search_f (void) 2862{ 2863 key_dest = key_menu; 2864 m_state = m_search; 2865 m_entersound = false; 2866 slistSilent = true; 2867 slistLocal = false; 2868 searchComplete = false; 2869 NET_Slist_f(); 2870 2871} 2872 2873 2874void M_Search_Draw (void) 2875{ 2876 qpic_t *p; 2877 int x; 2878 2879 p = Draw_CachePic ("gfx/p_multi.lmp"); 2880 M_DrawPic ( (320-p->width)/2, 4, p); 2881 x = (320/2) - ((12*8)/2) + 4; 2882 M_DrawTextBox (x-8, 32, 12, 1); 2883 M_Print (x, 40, "Searching..."); 2884 2885 if(slistInProgress) 2886 { 2887 NET_Poll(); 2888 return; 2889 } 2890 2891 if (! searchComplete) 2892 { 2893 searchComplete = true; 2894 searchCompleteTime = realtime; 2895 } 2896 2897 if (hostCacheCount) 2898 { 2899 M_Menu_ServerList_f (); 2900 return; 2901 } 2902 2903 M_PrintWhite ((320/2) - ((22*8)/2), 64, "No Quake servers found"); 2904 if ((realtime - searchCompleteTime) < 3.0) 2905 return; 2906 2907 M_Menu_LanConfig_f (); 2908} 2909 2910 2911void M_Search_Key (int key) 2912{ 2913} 2914 2915//============================================================================= 2916/* SLIST MENU */ 2917 2918int slist_cursor; 2919qboolean slist_sorted; 2920 2921void M_Menu_ServerList_f (void) 2922{ 2923 key_dest = key_menu; 2924 m_state = m_slist; 2925 m_entersound = true; 2926 slist_cursor = 0; 2927 m_return_onerror = false; 2928 m_return_reason[0] = 0; 2929 slist_sorted = false; 2930} 2931 2932 2933void M_ServerList_Draw (void) 2934{ 2935 int n; 2936 char string [64]; 2937 qpic_t *p; 2938 2939 if (!slist_sorted) 2940 { 2941 if (hostCacheCount > 1) 2942 { 2943 int i,j; 2944 hostcache_t temp; 2945 for (i = 0; i < hostCacheCount; i++) 2946 for (j = i+1; j < hostCacheCount; j++) 2947 if (strcmp(hostcache[j].name, hostcache[i].name) < 0) 2948 { 2949 Q_memcpy(&temp, &hostcache[j], sizeof(hostcache_t)); 2950 Q_memcpy(&hostcache[j], &hostcache[i], sizeof(hostcache_t)); 2951 Q_memcpy(&hostcache[i], &temp, sizeof(hostcache_t)); 2952 } 2953 } 2954 slist_sorted = true; 2955 } 2956 2957 p = Draw_CachePic ("gfx/p_multi.lmp"); 2958 M_DrawPic ( (320-p->width)/2, 4, p); 2959 for (n = 0; n < hostCacheCount; n++) 2960 { 2961 if (hostcache[n].maxusers) 2962 sprintf(string, "%-15.15s %-15.15s %2u/%2u\n", hostcache[n].name, hostcache[n].map, hostcache[n].users, hostcache[n].maxusers); 2963 else 2964 sprintf(string, "%-15.15s %-15.15s\n", hostcache[n].name, hostcache[n].map); 2965 M_Print (16, 32 + 8*n, string); 2966 } 2967 M_DrawCharacter (0, 32 + slist_cursor*8, 12+((int)(realtime*4)&1)); 2968 2969 if (*m_return_reason) 2970 M_PrintWhite (16, 148, m_return_reason); 2971} 2972 2973 2974void M_ServerList_Key (int k) 2975{ 2976 switch (k) 2977 { 2978 case K_ESCAPE: 2979 M_Menu_LanConfig_f (); 2980 break; 2981 2982 case K_SPACE: 2983 M_Menu_Search_f (); 2984 break; 2985 2986 case K_UPARROW: 2987 case K_LEFTARROW: 2988 S_LocalSound ("misc/menu1.wav"); 2989 slist_cursor--; 2990 if (slist_cursor < 0) 2991 slist_cursor = hostCacheCount - 1; 2992 break; 2993 2994 case K_DOWNARROW: 2995 case K_RIGHTARROW: 2996 S_LocalSound ("misc/menu1.wav"); 2997 slist_cursor++; 2998 if (slist_cursor >= hostCacheCount) 2999 slist_cursor = 0; 3000 break; 3001 3002 case K_ENTER: 3003 S_LocalSound ("misc/menu2.wav"); 3004 m_return_state = m_state; 3005 m_return_onerror = true; 3006 slist_sorted = false; 3007 key_dest = key_game; 3008 m_state = m_none; 3009 Cbuf_AddText ( va ("connect \"%s\"\n", hostcache[slist_cursor].cname) ); 3010 break; 3011 3012 default: 3013 break; 3014 } 3015 3016} 3017 3018//============================================================================= 3019/* Menu Subsystem */ 3020 3021 3022void M_Init (void) 3023{ 3024 Cmd_AddCommand ("togglemenu", M_ToggleMenu_f); 3025 3026 Cmd_AddCommand ("menu_main", M_Menu_Main_f); 3027 Cmd_AddCommand ("menu_singleplayer", M_Menu_SinglePlayer_f); 3028 Cmd_AddCommand ("menu_load", M_Menu_Load_f); 3029 Cmd_AddCommand ("menu_save", M_Menu_Save_f); 3030 Cmd_AddCommand ("menu_multiplayer", M_Menu_MultiPlayer_f); 3031 Cmd_AddCommand ("menu_setup", M_Menu_Setup_f); 3032 Cmd_AddCommand ("menu_options", M_Menu_Options_f); 3033 Cmd_AddCommand ("menu_keys", M_Menu_Keys_f); 3034 Cmd_AddCommand ("menu_video", M_Menu_Video_f); 3035 Cmd_AddCommand ("help", M_Menu_Help_f); 3036 Cmd_AddCommand ("menu_quit", M_Menu_Quit_f); 3037} 3038 3039 3040void M_Draw (void) 3041{ 3042 if (m_state == m_none || key_dest != key_menu) 3043 return; 3044 3045 if (!m_recursiveDraw) 3046 { 3047 scr_copyeverything = 1; 3048 3049 if (scr_con_current) 3050 { 3051 Draw_ConsoleBackground (vid.height); 3052 VID_UnlockBuffer (); 3053 S_ExtraUpdate (); 3054 VID_LockBuffer (); 3055 } 3056 else 3057 Draw_FadeScreen (); 3058 3059 scr_fullupdate = 0; 3060 } 3061 else 3062 { 3063 m_recursiveDraw = false; 3064 } 3065 3066 switch (m_state) 3067 { 3068 case m_none: 3069 break; 3070 3071 case m_main: 3072 M_Main_Draw (); 3073 break; 3074 3075 case m_singleplayer: 3076 M_SinglePlayer_Draw (); 3077 break; 3078 3079 case m_load: 3080 M_Load_Draw (); 3081 break; 3082 3083 case m_save: 3084 M_Save_Draw (); 3085 break; 3086 3087 case m_multiplayer: 3088 M_MultiPlayer_Draw (); 3089 break; 3090 3091 case m_setup: 3092 M_Setup_Draw (); 3093 break; 3094 3095 case m_net: 3096 M_Net_Draw (); 3097 break; 3098 3099 case m_options: 3100 M_Options_Draw (); 3101 break; 3102 3103 case m_keys: 3104 M_Keys_Draw (); 3105 break; 3106 3107 case m_video: 3108 M_Video_Draw (); 3109 break; 3110 3111 case m_help: 3112 M_Help_Draw (); 3113 break; 3114 3115 case m_quit: 3116 M_Quit_Draw (); 3117 break; 3118 3119 case m_serialconfig: 3120 M_SerialConfig_Draw (); 3121 break; 3122 3123 case m_modemconfig: 3124 M_ModemConfig_Draw (); 3125 break; 3126 3127 case m_lanconfig: 3128 M_LanConfig_Draw (); 3129 break; 3130 3131 case m_gameoptions: 3132 M_GameOptions_Draw (); 3133 break; 3134 3135 case m_search: 3136 M_Search_Draw (); 3137 break; 3138 3139 case m_slist: 3140 M_ServerList_Draw (); 3141 break; 3142 } 3143 3144 if (m_entersound) 3145 { 3146 S_LocalSound ("misc/menu2.wav"); 3147 m_entersound = false; 3148 } 3149 3150 VID_UnlockBuffer (); 3151 S_ExtraUpdate (); 3152 VID_LockBuffer (); 3153} 3154 3155 3156void M_Keydown (int key) 3157{ 3158 switch (m_state) 3159 { 3160 case m_none: 3161 return; 3162 3163 case m_main: 3164 M_Main_Key (key); 3165 return; 3166 3167 case m_singleplayer: 3168 M_SinglePlayer_Key (key); 3169 return; 3170 3171 case m_load: 3172 M_Load_Key (key); 3173 return; 3174 3175 case m_save: 3176 M_Save_Key (key); 3177 return; 3178 3179 case m_multiplayer: 3180 M_MultiPlayer_Key (key); 3181 return; 3182 3183 case m_setup: 3184 M_Setup_Key (key); 3185 return; 3186 3187 case m_net: 3188 M_Net_Key (key); 3189 return; 3190 3191 case m_options: 3192 M_Options_Key (key); 3193 return; 3194 3195 case m_keys: 3196 M_Keys_Key (key); 3197 return; 3198 3199 case m_video: 3200 M_Video_Key (key); 3201 return; 3202 3203 case m_help: 3204 M_Help_Key (key); 3205 return; 3206 3207 case m_quit: 3208 M_Quit_Key (key); 3209 return; 3210 3211 case m_serialconfig: 3212 M_SerialConfig_Key (key); 3213 return; 3214 3215 case m_modemconfig: 3216 M_ModemConfig_Key (key); 3217 return; 3218 3219 case m_lanconfig: 3220 M_LanConfig_Key (key); 3221 return; 3222 3223 case m_gameoptions: 3224 M_GameOptions_Key (key); 3225 return; 3226 3227 case m_search: 3228 M_Search_Key (key); 3229 break; 3230 3231 case m_slist: 3232 M_ServerList_Key (key); 3233 return; 3234 } 3235} 3236 3237 3238void M_ConfigureNetSubsystem(void) 3239{ 3240// enable/disable net systems to match desired config 3241 3242 Cbuf_AddText ("stopdemo\n"); 3243 if (SerialConfig || DirectConfig) 3244 { 3245 Cbuf_AddText ("com1 enable\n"); 3246 } 3247 3248 if (IPXConfig || TCPIPConfig) 3249 net_hostport = lanConfig_port; 3250} 3251