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