DarkPlaces
Game engine based on the Quake 1 engine by id Software, developed by LadyHavoc
 
menu.c
Go to the documentation of this file.
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#include "cdaudio.h"
22#include "image.h"
23#include "progsvm.h"
24
25#include "mprogdefs.h"
26
27#define TYPE_DEMO 1
28#define TYPE_GAME 2
29#define TYPE_BOTH 3
30
31static cvar_t forceqmenu = {CF_CLIENT, "forceqmenu", "0", "enables the quake menu instead of the quakec menu.dat (if present)"};
32static cvar_t menu_progs = {CF_CLIENT, "menu_progs", "menu.dat", "name of quakec menu.dat file"};
33
34static int NehGameType;
35
37
60
61static void M_Main_Draw (void);
62 static void M_SinglePlayer_Draw (void);
63 static void M_Transfusion_Episode_Draw (void);
64 static void M_Transfusion_Skill_Draw (void);
65 static void M_Load_Draw (void);
66 static void M_Save_Draw (void);
67 static void M_MultiPlayer_Draw (void);
68 static void M_Setup_Draw (void);
69 static void M_Options_Draw (void);
70 static void M_Options_Effects_Draw (void);
71 static void M_Options_Graphics_Draw (void);
72 static void M_Options_ColorControl_Draw (void);
73 static void M_Keys_Draw (void);
74 static void M_Reset_Draw (void);
75 static void M_Video_Draw (void);
76 static void M_Help_Draw (void);
77 static void M_Credits_Draw (void);
78 static void M_Quit_Draw (void);
79static void M_LanConfig_Draw (void);
80static void M_GameOptions_Draw (void);
81static void M_ServerList_Draw (void);
82static void M_ModList_Draw (void);
83
84
85static void M_Main_Key(cmd_state_t *cmd, int key, int ascii);
86 static void M_SinglePlayer_Key(cmd_state_t *cmd, int key, int ascii);
87 static void M_Transfusion_Episode_Key(cmd_state_t *cmd, int key, int ascii);
88 static void M_Transfusion_Skill_Key(cmd_state_t *cmd, int key, int ascii);
89 static void M_Load_Key(cmd_state_t *cmd, int key, int ascii);
90 static void M_Save_Key(cmd_state_t *cmd, int key, int ascii);
91 static void M_MultiPlayer_Key(cmd_state_t *cmd, int key, int ascii);
92 static void M_Setup_Key(cmd_state_t *cmd, int key, int ascii);
93 static void M_Options_Key(cmd_state_t *cmd, int key, int ascii);
94 static void M_Options_Effects_Key(cmd_state_t *cmd, int key, int ascii);
95 static void M_Options_Graphics_Key(cmd_state_t *cmd, int key, int ascii);
96 static void M_Options_ColorControl_Key(cmd_state_t *cmd, int key, int ascii);
97 static void M_Keys_Key(cmd_state_t *cmd, int key, int ascii);
98 static void M_Reset_Key(cmd_state_t *cmd, int key, int ascii);
99 static void M_Video_Key(cmd_state_t *cmd, int key, int ascii);
100 static void M_Help_Key(cmd_state_t *cmd, int key, int ascii);
101 static void M_Credits_Key(cmd_state_t *cmd, int key, int ascii);
102 static void M_Quit_Key(cmd_state_t *cmd, int key, int ascii);
103static void M_LanConfig_Key(cmd_state_t *cmd, int key, int ascii);
104static void M_GameOptions_Key(cmd_state_t *cmd, int key, int ascii);
105static void M_ServerList_Key(cmd_state_t *cmd, int key, int ascii);
106static void M_ModList_Key(cmd_state_t *cmd, int key, int ascii);
107
109
110#define StartingGame (m_multiplayer_cursor == 1)
111#define JoiningGame (m_multiplayer_cursor == 0)
112
113// Nehahra
114#define NumberOfNehahraDemos 34
115typedef struct nehahrademonames_s
116{
117 const char *name;
118 const char *desc;
120
122{
123 {"intro", "Prologue"},
124 {"genf", "The Beginning"},
125 {"genlab", "A Doomed Project"},
126 {"nehcre", "The New Recruits"},
127 {"maxneh", "Breakthrough"},
128 {"maxchar", "Renewal and Duty"},
129 {"crisis", "Worlds Collide"},
130 {"postcris", "Darkening Skies"},
131 {"hearing", "The Hearing"},
132 {"getjack", "On a Mexican Radio"},
133 {"prelude", "Honor and Justice"},
134 {"abase", "A Message Sent"},
135 {"effect", "The Other Side"},
136 {"uhoh", "Missing in Action"},
137 {"prepare", "The Response"},
138 {"vision", "Farsighted Eyes"},
139 {"maxturns", "Enter the Immortal"},
140 {"backlot", "Separate Ways"},
141 {"maxside", "The Ancient Runes"},
142 {"counter", "The New Initiative"},
143 {"warprep", "Ghosts to the World"},
144 {"counter1", "A Fate Worse Than Death"},
145 {"counter2", "Friendly Fire"},
146 {"counter3", "Minor Setback"},
147 {"madmax", "Scores to Settle"},
148 {"quake", "One Man"},
149 {"cthmm", "Shattered Masks"},
150 {"shades", "Deal with the Dead"},
151 {"gophil", "An Unlikely Hero"},
152 {"cstrike", "War in Hell"},
153 {"shubset", "The Conspiracy"},
154 {"shubdie", "Even Death May Die"},
155 {"newranks", "An Empty Throne"},
156 {"seal", "The Seal is Broken"}
157};
158
160
161static void M_Background(int width, int height)
162{
163 menu_width = bound(1.0f, (float)width, vid_conwidth.value);
164 menu_height = bound(1.0f, (float)height, vid_conheight.value);
167 //DrawQ_Fill(menu_x, menu_y, menu_width, menu_height, 0, 0, 0, 0.5, 0);
168 DrawQ_Fill(0, 0, vid_conwidth.integer, vid_conheight.integer, 0, 0, 0, 0.5, 0);
169}
170
171/*
172================
173M_DrawCharacter
174
175Draws one solid graphics character
176================
177*/
178static void M_DrawCharacter (float cx, float cy, int num)
179{
180 char temp[2];
181 temp[0] = num;
182 temp[1] = 0;
183 DrawQ_String(menu_x + cx, menu_y + cy, temp, 1, 8, 8, 1, 1, 1, 1, 0, NULL, true, FONT_MENU);
184}
185
186static void M_PrintColored(float cx, float cy, const char *str)
187{
188 DrawQ_String(menu_x + cx, menu_y + cy, str, 0, 8, 8, 1, 1, 1, 1, 0, NULL, false, FONT_MENU);
189}
190
191static void M_Print(float cx, float cy, const char *str)
192{
193 DrawQ_String(menu_x + cx, menu_y + cy, str, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true, FONT_MENU);
194}
195
196static void M_PrintRed(float cx, float cy, const char *str)
197{
198 DrawQ_String(menu_x + cx, menu_y + cy, str, 0, 8, 8, 1, 0, 0, 1, 0, NULL, true, FONT_MENU);
199}
200
201static void M_ItemPrint(float cx, float cy, const char *str, int unghosted)
202{
203 if (unghosted)
204 DrawQ_String(menu_x + cx, menu_y + cy, str, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true, FONT_MENU);
205 else
206 DrawQ_String(menu_x + cx, menu_y + cy, str, 0, 8, 8, 0.4, 0.4, 0.4, 1, 0, NULL, true, FONT_MENU);
207}
208
209static void M_DrawPic(float cx, float cy, const char *picname)
210{
211 DrawQ_Pic(menu_x + cx, menu_y + cy, Draw_CachePic (picname), 0, 0, 1, 1, 1, 1, 0);
212}
213
214static void M_DrawTextBox(float x, float y, float width, float height)
215{
216 int n;
217 float cx, cy;
218
219 // draw left side
220 cx = x;
221 cy = y;
222 M_DrawPic (cx, cy, "gfx/box_tl");
223 for (n = 0; n < height; n++)
224 {
225 cy += 8;
226 M_DrawPic (cx, cy, "gfx/box_ml");
227 }
228 M_DrawPic (cx, cy+8, "gfx/box_bl");
229
230 // draw middle
231 cx += 8;
232 while (width > 0)
233 {
234 cy = y;
235 M_DrawPic (cx, cy, "gfx/box_tm");
236 for (n = 0; n < height; n++)
237 {
238 cy += 8;
239 if (n >= 1)
240 M_DrawPic (cx, cy, "gfx/box_mm2");
241 else
242 M_DrawPic (cx, cy, "gfx/box_mm");
243 }
244 M_DrawPic (cx, cy+8, "gfx/box_bm");
245 width -= 2;
246 cx += 16;
247 }
248
249 // draw right side
250 cy = y;
251 M_DrawPic (cx, cy, "gfx/box_tr");
252 for (n = 0; n < height; n++)
253 {
254 cy += 8;
255 M_DrawPic (cx, cy, "gfx/box_mr");
256 }
257 M_DrawPic (cx, cy+8, "gfx/box_br");
258}
259
260//=============================================================================
261
262//int m_save_demonum;
263
264/*
265================
266M_ToggleMenu
267================
268*/
269static void M_ToggleMenu(int mode)
270{
271 m_entersound = true;
272
274 {
275 if(mode == 0)
276 return; // the menu is off, and we want it off
278 }
279 else
280 {
281 if(mode == 1)
282 return; // the menu is on, and we want it on
284 m_state = m_none;
285 }
286}
287
288
289static int demo_cursor;
290static void M_Demo_Draw (void)
291{
292 int i;
293
294 M_Background(320, 200);
295
296 for (i = 0;i < NumberOfNehahraDemos;i++)
297 M_Print(16, 16 + 8*i, NehahraDemos[i].desc);
298
299 // line cursor
300 M_DrawCharacter (8, 16 + demo_cursor*8, 12+((int)(host.realtime*4)&1));
301}
302
303
305{
307 m_state = m_demo;
308 m_entersound = true;
309}
310
311
312static void M_Demo_Key (cmd_state_t *cmd, int k, int ascii)
313{
314 char vabuf[1024];
315 switch (k)
316 {
317 case K_ESCAPE:
319 break;
320
321 case K_ENTER:
322 S_LocalSound ("sound/misc/menu2.wav");
323 m_state = m_none;
325 Cbuf_AddText (cmd, va(vabuf, sizeof(vabuf), "playdemo %s\n", NehahraDemos[demo_cursor].name));
326 return;
327
328 case K_UPARROW:
329 case K_LEFTARROW:
330 S_LocalSound ("sound/misc/menu1.wav");
331 demo_cursor--;
332 if (demo_cursor < 0)
334 break;
335
336 case K_DOWNARROW:
337 case K_RIGHTARROW:
338 S_LocalSound ("sound/misc/menu1.wav");
339 demo_cursor++;
341 demo_cursor = 0;
342 break;
343 }
344}
345
346//=============================================================================
347/* MAIN MENU */
348
349static int m_main_cursor;
350static qbool m_missingdata = false;
351
352static int MAIN_ITEMS = 4; // Nehahra: Menu Disable
353
354
356{
357 const char *s;
358 s = "gfx/mainmenu";
359
360 if (gamemode == GAME_NEHAHRA)
361 {
362 if (FS_FileExists("maps/neh1m4.bsp"))
363 {
364 if (FS_FileExists("hearing.dem"))
365 {
366 Con_DPrint("Main menu: Nehahra movie and game detected.\n");
368 }
369 else
370 {
371 Con_DPrint("Nehahra game detected.\n");
373 }
374 }
375 else
376 {
377 if (FS_FileExists("hearing.dem"))
378 {
379 Con_DPrint("Nehahra movie detected.\n");
381 }
382 else
383 {
384 Con_DPrint("Nehahra not found.\n");
385 NehGameType = TYPE_GAME; // could just complain, but...
386 }
387 }
388 if (NehGameType == TYPE_DEMO)
389 MAIN_ITEMS = 4;
390 else if (NehGameType == TYPE_GAME)
391 MAIN_ITEMS = 5;
392 else
393 MAIN_ITEMS = 6;
394 }
395 else if (gamemode == GAME_TRANSFUSION)
396 {
397 s = "gfx/menu/mainmenu1";
399 MAIN_ITEMS = 8;
400 else
401 MAIN_ITEMS = 7;
402 }
403 else
404 MAIN_ITEMS = 5;
405
406 // check if the game data is missing and use a different main menu if so
408 if (m_missingdata)
409 MAIN_ITEMS = 2;
410
411 /*
412 if (key_dest != key_menu)
413 {
414 m_save_demonum = cls.demonum;
415 cls.demonum = -1;
416 }
417 */
419 m_state = m_main;
420 m_entersound = true;
421}
422
423
424static bool mp_failed;
425static void M_Main_Draw (void)
426{
427 int f;
428 cachepic_t *p;
429 char vabuf[1024];
430
431 if (m_missingdata)
432 {
433 float y;
434 const char *s;
435 M_Background(640, 480); //fall back is always to 640x480, this makes it most readable at that.
436 y = 480/3-16;
437 if (mp_failed)
438 {
439 s = "The menu QC program has failed.";M_PrintRed ((640-strlen(s)*8)*0.5, y, s);y+=8;
440 y+=8;
441 s = "You should find the specific error(s) in the console.";M_Print ((640-strlen(s)*8)*0.5, y, s);y+=8;
442 }
443 else
444 {
445 s = "The required files were not found.";M_PrintRed ((640-strlen(s)*8)*0.5, y, s);y+=8;
446 y+=8;
447 s = "You may consider adding";M_Print ((640-strlen(s)*8)*0.5, y, s);y+=8;
448 s = "-basedir /path/to/game";M_Print ((640-strlen(s)*8)*0.5, y, s);y+=8;
449 s = "to your launch commandline.";M_Print ((640-strlen(s)*8)*0.5, y, s);y+=8;
450 }
451 M_Print (640/2 - 48, 480/2, "Open Console"); //The console usually better shows errors (failures)
452 M_Print (640/2 - 48, 480/2 + 8, "Quit");
453 M_DrawCharacter(640/2 - 56, 480/2 + (8 * m_main_cursor), 12+((int)(host.realtime*4)&1));
454 return;
455 }
456
457 if (gamemode == GAME_TRANSFUSION) {
458 int y1, y2, y3;
459 M_Background(640, 480);
460 p = Draw_CachePic ("gfx/menu/tb-transfusion");
461 M_DrawPic (640/2 - Draw_GetPicWidth(p)/2, 40, "gfx/menu/tb-transfusion");
462 y2 = 120;
463 // 8 rather than MAIN_ITEMS to skip a number and not miss the last option
464 for (y1 = 1; y1 <= 8; y1++)
465 {
466 if (MAIN_ITEMS == 7 && y1 == 4)
467 y1++;
468 M_DrawPic (0, y2, va(vabuf, sizeof(vabuf), "gfx/menu/mainmenu%i", y1));
469 y2 += 40;
470 }
471 if (MAIN_ITEMS == 7 && m_main_cursor > 2)
472 y3 = m_main_cursor + 2;
473 else
474 y3 = m_main_cursor + 1;
475 M_DrawPic (0, 120 + m_main_cursor * 40, va(vabuf, sizeof(vabuf), "gfx/menu/mainmenu%iselected", y3));
476 return;
477 }
478
479 M_Background(320, 200);
480 M_DrawPic (16, 4, "gfx/qplaque");
481 p = Draw_CachePic ("gfx/ttl_main");
482 M_DrawPic ( (320-Draw_GetPicWidth(p))/2, 4, "gfx/ttl_main");
483// Nehahra
484 if (gamemode == GAME_NEHAHRA)
485 {
486 if (NehGameType == TYPE_BOTH)
487 M_DrawPic (72, 32, "gfx/mainmenu");
488 else if (NehGameType == TYPE_GAME)
489 M_DrawPic (72, 32, "gfx/gamemenu");
490 else
491 M_DrawPic (72, 32, "gfx/demomenu");
492 }
493 else
494 M_DrawPic (72, 32, "gfx/mainmenu");
495
496 f = (int)(host.realtime * 10)%6;
497
498 M_DrawPic (54, 32 + m_main_cursor * 20, va(vabuf, sizeof(vabuf), "gfx/menudot%i", f+1));
499}
500
501
502static void M_Main_Key(cmd_state_t *cmd, int key, int ascii)
503{
504 switch (key)
505 {
506 case K_ESCAPE:
508 m_state = m_none;
509 //cls.demonum = m_save_demonum;
510 //if(!cl_startdemos.integer)
511 // break;
512 //if (cls.demonum != -1 && !cls.demoplayback && cls.state != ca_connected)
513 // CL_NextDemo ();
514 break;
515
516 case K_DOWNARROW:
517 S_LocalSound ("sound/misc/menu1.wav");
518 if (++m_main_cursor >= MAIN_ITEMS)
519 m_main_cursor = 0;
520 break;
521
522 case K_UPARROW:
523 S_LocalSound ("sound/misc/menu1.wav");
524 if (--m_main_cursor < 0)
526 break;
527
528 case K_ENTER:
529 m_entersound = true;
530
531 if (m_missingdata)
532 {
533 switch (m_main_cursor)
534 {
535 case 0:
536 if (cls.state == ca_connected)
537 {
538 m_state = m_none;
540 }
542 break;
543 case 1:
545 break;
546 }
547 }
548 else if (gamemode == GAME_NEHAHRA)
549 {
550 switch (NehGameType)
551 {
552 case TYPE_BOTH:
553 switch (m_main_cursor)
554 {
555 case 0:
557 break;
558
559 case 1:
561 break;
562
563 case 2:
565 break;
566
567 case 3:
569 break;
570
571 case 4:
573 if (sv.active)
574 Cbuf_AddText (cmd, "disconnect\n");
575 Cbuf_AddText (cmd, "playdemo endcred\n");
576 break;
577
578 case 5:
580 break;
581 }
582 break;
583 case TYPE_GAME:
584 switch (m_main_cursor)
585 {
586 case 0:
588 break;
589
590 case 1:
592 break;
593
594 case 2:
596 break;
597
598 case 3:
600 if (sv.active)
601 Cbuf_AddText (cmd, "disconnect\n");
602 Cbuf_AddText (cmd, "playdemo endcred\n");
603 break;
604
605 case 4:
607 break;
608 }
609 break;
610 case TYPE_DEMO:
611 switch (m_main_cursor)
612 {
613 case 0:
615 break;
616
617 case 1:
619 if (sv.active)
620 Cbuf_AddText (cmd, "disconnect\n");
621 Cbuf_AddText (cmd, "playdemo endcred\n");
622 break;
623
624 case 2:
626 break;
627
628 case 3:
630 break;
631 }
632 break;
633 }
634 }
635 else if (gamemode == GAME_TRANSFUSION) {
636 if (MAIN_ITEMS == 7)
637 {
638 switch (m_main_cursor)
639 {
640 case 0:
642 break;
643
644 case 1:
646 break;
647
648 case 2:
650 break;
651
652 case 3:
654 break;
655
656 case 4:
658 break;
659
660 case 5:
662 break;
663
664 case 6:
666 break;
667 }
668 }
669 else
670 {
671 switch (m_main_cursor)
672 {
673 case 0:
675 break;
676
677 case 1:
679 break;
680
681 case 2:
683 break;
684
685 case 3:
687 break;
688
689 case 4:
691 break;
692
693 case 5:
695 break;
696
697 case 6:
699 break;
700
701 case 7:
703 break;
704 }
705 }
706 }
707 else
708 {
709 switch (m_main_cursor)
710 {
711 case 0:
713 break;
714
715 case 1:
717 break;
718
719 case 2:
721 break;
722
723 case 3:
725 break;
726
727 case 4:
729 break;
730 }
731 }
732 }
733}
734
735//=============================================================================
736/* SINGLE PLAYER MENU */
737
739#define SINGLEPLAYER_ITEMS 3
740
741
748
749
750static void M_SinglePlayer_Draw (void)
751{
752 cachepic_t *p;
753 char vabuf[1024];
754
755 M_Background(320, 200);
756
757 M_DrawPic (16, 4, "gfx/qplaque");
758 p = Draw_CachePic ("gfx/ttl_sgl");
759
760 // Some mods don't have a single player mode
762 {
763 M_DrawPic ((320 - Draw_GetPicWidth(p)) / 2, 4, "gfx/ttl_sgl");
764
765 M_DrawTextBox (60, 8 * 8, 23, 4);
767 M_Print(95, 10 * 8, "Good Vs Bad 2 is for");
768 else // if (gamemode == GAME_BATTLEMECH)
769 M_Print(95, 10 * 8, "Battlemech is for");
770 M_Print(83, 11 * 8, "multiplayer play only");
771 }
772 else
773 {
774 int f;
775
776 M_DrawPic ( (320-Draw_GetPicWidth(p))/2, 4, "gfx/ttl_sgl");
777 M_DrawPic (72, 32, "gfx/sp_menu");
778
779 f = (int)(host.realtime * 10)%6;
780
781 M_DrawPic (54, 32 + m_singleplayer_cursor * 20, va(vabuf, sizeof(vabuf), "gfx/menudot%i", f+1));
782 }
783}
784
785
786static void M_SinglePlayer_Key(cmd_state_t *cmd, int key, int ascii)
787{
789 {
790 if (key == K_ESCAPE || key == K_ENTER)
791 m_state = m_main;
792 return;
793 }
794
795 switch (key)
796 {
797 case K_ESCAPE:
799 break;
800
801 case K_DOWNARROW:
802 S_LocalSound ("sound/misc/menu1.wav");
805 break;
806
807 case K_UPARROW:
808 S_LocalSound ("sound/misc/menu1.wav");
809 if (--m_singleplayer_cursor < 0)
811 break;
812
813 case K_ENTER:
814 m_entersound = true;
815
816 switch (m_singleplayer_cursor)
817 {
818 case 0:
820 if (sv.active)
821 Cbuf_AddText(cmd, "disconnect\n");
822 Cbuf_AddText(cmd, "maxplayers 1\n");
823 Cbuf_AddText(cmd, "deathmatch 0\n");
824 Cbuf_AddText(cmd, "coop 0\n");
826 {
829 break;
830 }
831 Cbuf_AddText(cmd, "startmap_sp\n");
832 break;
833
834 case 1:
836 break;
837
838 case 2:
840 break;
841 }
842 }
843}
844
845//=============================================================================
846/* LOAD/SAVE MENU */
847
848static int load_cursor;
849
852
853static void M_ScanSaves (void)
854{
855 int i, j;
856 size_t len;
857 char name[MAX_OSPATH];
858 char buf[SAVEGAME_COMMENT_LENGTH + 256];
859 const char *t;
860 qfile_t *f;
861// int version;
862
863 for (i=0 ; i<MAX_SAVEGAMES ; i++)
864 {
865 dp_strlcpy (m_filenames[i], "--- UNUSED SLOT ---", sizeof(m_filenames[i]));
866 loadable[i] = false;
867 dpsnprintf (name, sizeof(name), "s%i.sav", (int)i);
868 f = FS_OpenRealFile (name, "rb", false);
869 if (!f)
870 continue;
871 // read enough to get the comment
872 len = FS_Read(f, buf, sizeof(buf) - 1);
873 len = min(len, sizeof(buf)-1);
874 buf[len] = 0;
875 t = buf;
876 // version
877 COM_ParseToken_Simple(&t, false, false, true);
878 //version = atoi(com_token);
879 // description
880 COM_ParseToken_Simple(&t, false, false, true);
882
883 // change _ back to space
884 for (j=0 ; j<SAVEGAME_COMMENT_LENGTH ; j++)
885 if (m_filenames[i][j] == '_')
886 m_filenames[i][j] = ' ';
887 loadable[i] = true;
888 FS_Close (f);
889 }
890}
891
893{
894 m_entersound = true;
895 m_state = m_load;
897 M_ScanSaves ();
898}
899
900
902{
903 if (!sv.active)
904 return;
905#if 1
906 // LadyHavoc: allow saving multiplayer games
908 return;
909#else
910 if (cl.intermission)
911 return;
912 if (!cl.islocalgame)
913 return;
914#endif
915 m_entersound = true;
916 m_state = m_save;
918 M_ScanSaves ();
919}
920
921
922static void M_Load_Draw (void)
923{
924 int i;
925 cachepic_t *p;
926
927 M_Background(320, 200);
928
929 p = Draw_CachePic ("gfx/p_load");
930 M_DrawPic ( (320-Draw_GetPicWidth(p))/2, 4, "gfx/p_load" );
931
932 for (i=0 ; i< MAX_SAVEGAMES; i++)
933 M_Print(16, 32 + 8*i, m_filenames[i]);
934
935// line cursor
936 M_DrawCharacter (8, 32 + load_cursor*8, 12+((int)(host.realtime*4)&1));
937}
938
939
940static void M_Save_Draw (void)
941{
942 int i;
943 cachepic_t *p;
944
945 M_Background(320, 200);
946
947 p = Draw_CachePic ("gfx/p_save");
948 M_DrawPic ( (320-Draw_GetPicWidth(p))/2, 4, "gfx/p_save");
949
950 for (i=0 ; i<MAX_SAVEGAMES ; i++)
951 M_Print(16, 32 + 8*i, m_filenames[i]);
952
953// line cursor
954 M_DrawCharacter (8, 32 + load_cursor*8, 12+((int)(host.realtime*4)&1));
955}
956
957
958static void M_Load_Key(cmd_state_t *cmd, int k, int ascii)
959{
960 char vabuf[1024];
961 switch (k)
962 {
963 case K_ESCAPE:
966 else
968 break;
969
970 case K_ENTER:
971 S_LocalSound ("sound/misc/menu2.wav");
972 if (!loadable[load_cursor])
973 return;
974 m_state = m_none;
976
977 // issue the load command
978 Cbuf_AddText (cmd, va(vabuf, sizeof(vabuf), "load s%i\n", load_cursor) );
979 return;
980
981 case K_UPARROW:
982 case K_LEFTARROW:
983 S_LocalSound ("sound/misc/menu1.wav");
984 load_cursor--;
985 if (load_cursor < 0)
987 break;
988
989 case K_DOWNARROW:
990 case K_RIGHTARROW:
991 S_LocalSound ("sound/misc/menu1.wav");
992 load_cursor++;
994 load_cursor = 0;
995 break;
996 }
997}
998
999
1000static void M_Save_Key(cmd_state_t *cmd, int k, int ascii)
1001{
1002 char vabuf[1024];
1003 switch (k)
1004 {
1005 case K_ESCAPE:
1008 else
1010 break;
1011
1012 case K_ENTER:
1013 m_state = m_none;
1015 Cbuf_AddText(cmd, va(vabuf, sizeof(vabuf), "save s%i\n", load_cursor));
1016 return;
1017
1018 case K_UPARROW:
1019 case K_LEFTARROW:
1020 S_LocalSound ("sound/misc/menu1.wav");
1021 load_cursor--;
1022 if (load_cursor < 0)
1024 break;
1025
1026 case K_DOWNARROW:
1027 case K_RIGHTARROW:
1028 S_LocalSound ("sound/misc/menu1.wav");
1029 load_cursor++;
1031 load_cursor = 0;
1032 break;
1033 }
1034}
1035
1036//=============================================================================
1037/* Transfusion Single Player Episode Menu */
1038
1040#define EPISODE_ITEMS 6
1041
1048
1050{
1051 int y;
1052 cachepic_t *p;
1053 char vabuf[1024];
1054 M_Background(640, 480);
1055
1056 p = Draw_CachePic ("gfx/menu/tb-episodes");
1057 M_DrawPic (640/2 - Draw_GetPicWidth(p)/2, 40, "gfx/menu/tb-episodes");
1058 for (y = 0; y < EPISODE_ITEMS; y++){
1059 M_DrawPic (0, 160 + y * 40, va(vabuf, sizeof(vabuf), "gfx/menu/episode%i", y+1));
1060 }
1061
1062 M_DrawPic (0, 120 + (m_episode_cursor + 1) * 40, va(vabuf, sizeof(vabuf), "gfx/menu/episode%iselected", m_episode_cursor + 1));
1063}
1064
1065static void M_Transfusion_Episode_Key(cmd_state_t *cmd, int key, int ascii)
1066{
1067 switch (key)
1068 {
1069 case K_ESCAPE:
1071 break;
1072
1073 case K_DOWNARROW:
1074 S_LocalSound ("sound/misc/menu1.wav");
1077 m_episode_cursor = 0;
1078 break;
1079
1080 case K_UPARROW:
1081 S_LocalSound ("sound/misc/menu1.wav");
1083 if (m_episode_cursor < 0)
1085 break;
1086
1087 case K_ENTER:
1088 Cbuf_AddText(cmd, "deathmatch 0\n");
1089 m_entersound = true;
1091 }
1092}
1093
1094//=============================================================================
1095/* Transfusion Single Player Skill Menu */
1096
1097static int m_skill_cursor = 2;
1098#define SKILL_ITEMS 5
1099
1106
1108{
1109 int y;
1110 cachepic_t *p;
1111 char vabuf[1024];
1112 M_Background(640, 480);
1113
1114 p = Draw_CachePic ("gfx/menu/tb-difficulty");
1115 M_DrawPic(640/2 - Draw_GetPicWidth(p)/2, 40, "gfx/menu/tb-difficulty");
1116
1117 for (y = 0; y < SKILL_ITEMS; y++)
1118 {
1119 M_DrawPic (0, 180 + y * 40, va(vabuf, sizeof(vabuf), "gfx/menu/difficulty%i", y+1));
1120 }
1121 M_DrawPic (0, 140 + (m_skill_cursor + 1) *40, va(vabuf, sizeof(vabuf), "gfx/menu/difficulty%iselected", m_skill_cursor + 1));
1122}
1123
1124static void M_Transfusion_Skill_Key(cmd_state_t *cmd, int key, int ascii)
1125{
1126 switch (key)
1127 {
1128 case K_ESCAPE:
1130 break;
1131
1132 case K_DOWNARROW:
1133 S_LocalSound ("sound/misc/menu1.wav");
1136 m_skill_cursor = 0;
1137 break;
1138
1139 case K_UPARROW:
1140 S_LocalSound ("sound/misc/menu1.wav");
1142 if (m_skill_cursor < 0)
1144 break;
1145
1146 case K_ENTER:
1147 m_entersound = true;
1148 switch (m_skill_cursor)
1149 {
1150 case 0:
1151 Cbuf_AddText(cmd, "skill 1\n");
1152 break;
1153 case 1:
1154 Cbuf_AddText(cmd, "skill 2\n");
1155 break;
1156 case 2:
1157 Cbuf_AddText(cmd, "skill 3\n");
1158 break;
1159 case 3:
1160 Cbuf_AddText(cmd, "skill 4\n");
1161 break;
1162 case 4:
1163 Cbuf_AddText(cmd, "skill 5\n");
1164 break;
1165 }
1167 if (sv.active)
1168 Cbuf_AddText(cmd, "disconnect\n");
1169 Cbuf_AddText(cmd, "maxplayers 1\n");
1170 Cbuf_AddText(cmd, "deathmatch 0\n");
1171 Cbuf_AddText(cmd, "coop 0\n");
1172 switch (m_episode_cursor)
1173 {
1174 case 0:
1175 Cbuf_AddText(cmd, "map e1m1\n");
1176 break;
1177 case 1:
1178 Cbuf_AddText(cmd, "map e2m1\n");
1179 break;
1180 case 2:
1181 Cbuf_AddText(cmd, "map e3m1\n");
1182 break;
1183 case 3:
1184 Cbuf_AddText(cmd, "map e4m1\n");
1185 break;
1186 case 4:
1187 Cbuf_AddText(cmd, "map e6m1\n");
1188 break;
1189 case 5:
1190 Cbuf_AddText(cmd, "map cp01\n");
1191 break;
1192 }
1193 }
1194}
1195//=============================================================================
1196/* MULTIPLAYER MENU */
1197
1199#define MULTIPLAYER_ITEMS 3
1200
1201
1208
1209
1210static void M_MultiPlayer_Draw (void)
1211{
1212 int f;
1213 cachepic_t *p;
1214 char vabuf[1024];
1215
1217 {
1218 M_Background(640, 480);
1219 p = Draw_CachePic ("gfx/menu/tb-online");
1220 M_DrawPic (640/2 - Draw_GetPicWidth(p)/2, 140, "gfx/menu/tb-online");
1221 for (f = 1; f <= MULTIPLAYER_ITEMS; f++)
1222 M_DrawPic (0, 180 + f*40, va(vabuf, sizeof(vabuf), "gfx/menu/online%i", f));
1223 M_DrawPic (0, 220 + m_multiplayer_cursor * 40, va(vabuf, sizeof(vabuf), "gfx/menu/online%iselected", m_multiplayer_cursor + 1));
1224 return;
1225 }
1226 M_Background(320, 200);
1227
1228 M_DrawPic (16, 4, "gfx/qplaque");
1229 p = Draw_CachePic ("gfx/p_multi");
1230 M_DrawPic ( (320-Draw_GetPicWidth(p))/2, 4, "gfx/p_multi");
1231 M_DrawPic (72, 32, "gfx/mp_menu");
1232
1233 f = (int)(host.realtime * 10)%6;
1234
1235 M_DrawPic (54, 32 + m_multiplayer_cursor * 20, va(vabuf, sizeof(vabuf), "gfx/menudot%i", f+1));
1236}
1237
1238
1239static void M_MultiPlayer_Key(cmd_state_t *cmd, int key, int ascii)
1240{
1241 switch (key)
1242 {
1243 case K_ESCAPE:
1245 break;
1246
1247 case K_DOWNARROW:
1248 S_LocalSound ("sound/misc/menu1.wav");
1251 break;
1252
1253 case K_UPARROW:
1254 S_LocalSound ("sound/misc/menu1.wav");
1255 if (--m_multiplayer_cursor < 0)
1257 break;
1258
1259 case K_ENTER:
1260 m_entersound = true;
1261 switch (m_multiplayer_cursor)
1262 {
1263 case 0:
1264 case 1:
1266 break;
1267
1268 case 2:
1270 break;
1271 }
1272 }
1273}
1274
1275//=============================================================================
1276/* SETUP MENU */
1277
1278static int setup_cursor = 4;
1279static int setup_cursor_table[] = {40, 64, 88, 124, 140};
1280
1282static int setup_oldtop;
1284static int setup_top;
1285static int setup_bottom;
1286static int setup_rate;
1287static int setup_oldrate;
1288
1289#define NUM_SETUP_CMDS 5
1290
1291extern cvar_t cl_topcolor;
1292extern cvar_t cl_bottomcolor;
1293
1304
1306static unsigned char *menuplyr_pixels;
1307static unsigned int *menuplyr_translated;
1308
1309typedef struct ratetable_s
1310{
1311 int rate;
1312 const char *name;
1313}
1315
1316#define RATES ((int)(sizeof(setup_ratetable)/sizeof(setup_ratetable[0])))
1318{
1319 {1000, "28.8 bad"},
1320 {1500, "28.8 mediocre"},
1321 {2000, "28.8 good"},
1322 {2500, "33.6 mediocre"},
1323 {3000, "33.6 good"},
1324 {3500, "56k bad"},
1325 {4000, "56k mediocre"},
1326 {4500, "56k adequate"},
1327 {5000, "56k good"},
1328 {7000, "64k ISDN"},
1329 {15000, "128k ISDN"},
1330 {25000, "broadband"}
1331};
1332
1333static int setup_rateindex(int rate)
1334{
1335 int i;
1336 for (i = 0;i < RATES;i++)
1337 if (setup_ratetable[i].rate > setup_rate)
1338 break;
1339 return bound(1, i, RATES) - 1;
1340}
1341
1342static void M_Setup_Draw (void)
1343{
1344 int i, j;
1345 cachepic_t *p;
1346 char vabuf[1024];
1347
1348 M_Background(320, 200);
1349
1350 M_DrawPic (16, 4, "gfx/qplaque");
1351 p = Draw_CachePic ("gfx/p_multi");
1352 M_DrawPic ( (320-Draw_GetPicWidth(p))/2, 4, "gfx/p_multi");
1353
1354 M_Print(64, 40, "Your name");
1355 M_DrawTextBox (160, 32, 16, 1);
1356 M_PrintColored(168, 40, setup_myname);
1357
1359 {
1360 M_Print(64, 64, "Shirt color");
1361 M_Print(64, 88, "Pants color");
1362 }
1363
1364 M_Print(64, 124-8, "Network speed limit");
1365 M_Print(168, 124, va(vabuf, sizeof(vabuf), "%i (%s)", setup_rate, setup_ratetable[setup_rateindex(setup_rate)].name));
1366
1367 M_DrawTextBox (64, 140-8, 14, 1);
1368 M_Print(72, 140, "Accept Changes");
1369
1370 // LadyHavoc: rewrote this code greatly
1371 if (menuplyr_load)
1372 {
1373 unsigned char *f;
1374 fs_offset_t filesize;
1375 menuplyr_load = false;
1376 menuplyr_top = -1;
1377 menuplyr_bottom = -1;
1378 f = FS_LoadFile("gfx/menuplyr.lmp", tempmempool, true, &filesize);
1379 if (f && filesize >= 9)
1380 {
1381 int width, height;
1382 width = f[0] + f[1] * 256 + f[2] * 65536 + f[3] * 16777216;
1383 height = f[4] + f[5] * 256 + f[6] * 65536 + f[7] * 16777216;
1384 if (filesize >= 8 + width * height)
1385 {
1390 memcpy(menuplyr_pixels, f + 8, width * height);
1391 }
1392 }
1393 if (f)
1394 Mem_Free(f);
1395 }
1396
1397 if (menuplyr_pixels)
1398 {
1400 {
1403
1404 for (i = 0;i < menuplyr_width * menuplyr_height;i++)
1405 {
1406 j = menuplyr_pixels[i];
1407 if (j >= TOP_RANGE && j < TOP_RANGE + 16)
1408 {
1409 if (menuplyr_top < 8 || menuplyr_top == 14)
1410 j = menuplyr_top * 16 + (j - TOP_RANGE);
1411 else
1412 j = menuplyr_top * 16 + 15-(j - TOP_RANGE);
1413 }
1414 else if (j >= BOTTOM_RANGE && j < BOTTOM_RANGE + 16)
1415 {
1416 if (menuplyr_bottom < 8 || menuplyr_bottom == 14)
1417 j = menuplyr_bottom * 16 + (j - BOTTOM_RANGE);
1418 else
1419 j = menuplyr_bottom * 16 + 15-(j - BOTTOM_RANGE);
1420 }
1422 }
1424 }
1425 M_DrawPic(160, 48, "gfx/bigbox");
1426 M_DrawPic(172, 56, "gfx/menuplyr");
1427 }
1428
1429 if (setup_cursor == 0)
1431 else
1433}
1434
1435
1436static void M_Setup_Key(cmd_state_t *cmd, int k, int ascii)
1437{
1438 int l;
1439 char vabuf[1024];
1440
1441 switch (k)
1442 {
1443 case K_ESCAPE:
1445 break;
1446
1447 case K_UPARROW:
1448 S_LocalSound ("sound/misc/menu1.wav");
1449 setup_cursor--;
1450 if (setup_cursor < 0)
1452 break;
1453
1454 case K_DOWNARROW:
1455 S_LocalSound ("sound/misc/menu1.wav");
1456 setup_cursor++;
1458 setup_cursor = 0;
1459 break;
1460
1461 case K_LEFTARROW:
1462 if (setup_cursor < 1)
1463 return;
1464 S_LocalSound ("sound/misc/menu3.wav");
1465 if (setup_cursor == 1)
1466 setup_top = setup_top - 1;
1467 if (setup_cursor == 2)
1469 if (setup_cursor == 3)
1470 {
1471 l = setup_rateindex(setup_rate) - 1;
1472 if (l < 0)
1473 l = RATES - 1;
1475 }
1476 break;
1477 case K_RIGHTARROW:
1478 if (setup_cursor < 1)
1479 return;
1480forward:
1481 S_LocalSound ("sound/misc/menu3.wav");
1482 if (setup_cursor == 1)
1483 setup_top = setup_top + 1;
1484 if (setup_cursor == 2)
1486 if (setup_cursor == 3)
1487 {
1488 l = setup_rateindex(setup_rate) + 1;
1489 if (l >= RATES)
1490 l = 0;
1492 }
1493 break;
1494
1495 case K_ENTER:
1496 if (setup_cursor == 0)
1497 return;
1498
1499 if (setup_cursor == 1 || setup_cursor == 2 || setup_cursor == 3)
1500 goto forward;
1501
1502 // setup_cursor == 4 (Accept changes)
1503 if (strcmp(cl_name.string, setup_myname) != 0)
1504 Cbuf_AddText(cmd, va(vabuf, sizeof(vabuf), "name \"%s\"\n", setup_myname) );
1506 Cbuf_AddText(cmd, va(vabuf, sizeof(vabuf), "color %i %i\n", setup_top, setup_bottom) );
1508 Cbuf_AddText(cmd, va(vabuf, sizeof(vabuf), "rate %i\n", setup_rate));
1509
1510 m_entersound = true;
1512 break;
1513
1514 case K_BACKSPACE:
1515 if (setup_cursor == 0)
1516 {
1517 if (strlen(setup_myname))
1519 }
1520 break;
1521
1522 default:
1523 if (ascii < 32)
1524 break;
1525 if (setup_cursor == 0)
1526 {
1527 l = (int)strlen(setup_myname);
1528 if (l < 15)
1529 {
1530 setup_myname[l+1] = 0;
1531 setup_myname[l] = ascii;
1532 }
1533 }
1534 }
1535
1536 if (setup_top > 15)
1537 setup_top = 0;
1538 if (setup_top < 0)
1539 setup_top = 15;
1540 if (setup_bottom > 15)
1541 setup_bottom = 0;
1542 if (setup_bottom < 0)
1543 setup_bottom = 15;
1544}
1545
1546//=============================================================================
1547/* OPTIONS MENU */
1548
1549#define SLIDER_RANGE 10
1550
1551static void M_DrawSlider (int x, int y, float num, float rangemin, float rangemax)
1552{
1553 char text[16];
1554 int i;
1555 float range;
1556 range = bound(0, (num - rangemin) / (rangemax - rangemin), 1);
1557 M_DrawCharacter (x-8, y, 128);
1558 for (i = 0;i < SLIDER_RANGE;i++)
1559 M_DrawCharacter (x + i*8, y, 129);
1560 M_DrawCharacter (x+i*8, y, 130);
1561 M_DrawCharacter (x + (SLIDER_RANGE-1)*8 * range, y, 131);
1562 if (fabs((int)num - num) < 0.01)
1563 dpsnprintf(text, sizeof(text), "%i", (int)num);
1564 else
1565 dpsnprintf(text, sizeof(text), "%.3f", num);
1566 M_Print(x + (SLIDER_RANGE+2) * 8, y, text);
1567}
1568
1569static void M_DrawCheckbox (int x, int y, int on)
1570{
1571 if (on)
1572 M_Print(x, y, "on");
1573 else
1574 M_Print(x, y, "off");
1575}
1576
1577
1578//#define OPTIONS_ITEMS 25 aule was here
1579#define OPTIONS_ITEMS 27
1580
1581
1583
1585{
1588 m_entersound = true;
1589}
1590
1591extern cvar_t host_timescale;
1592extern dllhandle_t jpeg_dll;
1594extern cvar_t r_textshadow;
1596
1598{
1599 int optnum;
1600 double f;
1601 S_LocalSound ("sound/misc/menu3.wav");
1602
1603 optnum = 0;
1604 if (options_cursor == optnum++) ;
1605 else if (options_cursor == optnum++) ;
1606 else if (options_cursor == optnum++) ;
1607 else if (options_cursor == optnum++) ;
1608 else if (options_cursor == optnum++) Cvar_SetValueQuick(&crosshair, bound(0, crosshair.integer + dir, 7));
1609 else if (options_cursor == optnum++) Cvar_SetValueQuick(&sensitivity, bound(1, sensitivity.value + dir * 0.5, 50));
1610 else if (options_cursor == optnum++) Cvar_SetValueQuick(&m_pitch, -m_pitch.value);
1611 else if (options_cursor == optnum++) Cvar_SetValueQuick(&scr_fov, bound(1, scr_fov.integer + dir * 1, 170));
1612 else if (options_cursor == optnum++)
1613 {
1614 if (cl_forwardspeed.value > 200)
1615 {
1618 }
1619 else
1620 {
1623 }
1624 }
1627 else if (options_cursor == optnum++) ;
1629 else if (options_cursor == optnum++) Cvar_SetValueQuick(&v_contrast, bound(1, v_contrast.value + dir * 0.0625, 4));
1630 else if (options_cursor == optnum++) Cvar_SetValueQuick(&v_gamma, bound(0.5, v_gamma.value + dir * 0.0625, 3));
1631 else if (options_cursor == optnum++) Cvar_SetValueQuick(&volume, bound(0, volume.value + dir * 0.0625, 1));
1632 else if (options_cursor == optnum++) Cvar_SetValueQuick(&bgmvolume, bound(0, bgmvolume.value + dir * 0.0625, 1));
1633}
1634
1635static int m_optnum;
1636static int m_opty;
1637static int m_optcursor;
1638
1639static void M_Options_PrintCommand(const char *s, int enabled)
1640{
1641 if (m_opty >= 32)
1642 {
1643 if (m_optnum == m_optcursor)
1644 DrawQ_Fill(menu_x + 48, menu_y + m_opty, 320, 8, m_optnum == m_optcursor ? (0.5 + 0.2 * sin(host.realtime * M_PI)) : 0, 0, 0, 0.5, 0);
1645 M_ItemPrint(0 + 48, m_opty, s, enabled);
1646 }
1647 m_opty += 8;
1648 m_optnum++;
1649}
1650
1651static void M_Options_PrintCheckbox(const char *s, int enabled, int yes)
1652{
1653 if (m_opty >= 32)
1654 {
1655 if (m_optnum == m_optcursor)
1656 DrawQ_Fill(menu_x + 48, menu_y + m_opty, 320, 8, m_optnum == m_optcursor ? (0.5 + 0.2 * sin(host.realtime * M_PI)) : 0, 0, 0, 0.5, 0);
1657 M_ItemPrint(0 + 48, m_opty, s, enabled);
1658 M_DrawCheckbox(0 + 48 + (int)strlen(s) * 8 + 8, m_opty, yes);
1659 }
1660 m_opty += 8;
1661 m_optnum++;
1662}
1663
1664static void M_Options_PrintSlider(const char *s, int enabled, float value, float minvalue, float maxvalue)
1665{
1666 if (m_opty >= 32)
1667 {
1668 if (m_optnum == m_optcursor)
1669 DrawQ_Fill(menu_x + 48, menu_y + m_opty, 320, 8, m_optnum == m_optcursor ? (0.5 + 0.2 * sin(host.realtime * M_PI)) : 0, 0, 0, 0.5, 0);
1670 M_ItemPrint(0 + 48, m_opty, s, enabled);
1671 M_DrawSlider(0 + 48 + (int)strlen(s) * 8 + 8, m_opty, value, minvalue, maxvalue);
1672 }
1673 m_opty += 8;
1674 m_optnum++;
1675}
1676
1677static void M_Options_Draw (void)
1678{
1679 int visible;
1680 cachepic_t *p;
1681
1683
1684 M_DrawPic(16, 4, "gfx/qplaque");
1685 p = Draw_CachePic ("gfx/p_option");
1686 M_DrawPic((320-Draw_GetPicWidth(p))/2, 4, "gfx/p_option");
1687
1688 m_optnum = 0;
1690 visible = (int)((menu_height - 32) / 8);
1691 m_opty = 32 - bound(0, m_optcursor - (visible >> 1), max(0, OPTIONS_ITEMS - visible)) * 8;
1692
1693 M_Options_PrintCommand( " Customize controls", true);
1694 M_Options_PrintCommand( " Go to console", true);
1695 M_Options_PrintCommand( " Reset to defaults", true);
1696 M_Options_PrintCommand( " Change Video Mode", true);
1697 M_Options_PrintSlider( " Crosshair", true, crosshair.value, 0, 7);
1698 M_Options_PrintSlider( " Mouse Speed", true, sensitivity.value, 1, 50);
1699 M_Options_PrintCheckbox(" Invert Mouse", true, m_pitch.value < 0);
1700 M_Options_PrintSlider( " Field of View", true, scr_fov.integer, 1, 170);
1701 M_Options_PrintCheckbox(" Always Run", true, cl_forwardspeed.value > 200);
1702 M_Options_PrintCheckbox(" Show Framerate", true, cl_showfps.integer);
1703 M_Options_PrintCheckbox(" Show Date and Time", true, cl_showdate.integer && cl_showtime.integer);
1704 M_Options_PrintCommand( " Custom Brightness", true);
1705 M_Options_PrintSlider( " Game Brightness", true, r_hdr_scenebrightness.value, 1, 4);
1706 M_Options_PrintSlider( " Brightness", true, v_contrast.value, 1, 2);
1707 M_Options_PrintSlider( " Gamma", true, v_gamma.value, 0.5, 3);
1708 M_Options_PrintSlider( " Sound Volume", snd_initialized.integer, volume.value, 0, 1);
1710 M_Options_PrintCommand( " Customize Effects", true);
1711 M_Options_PrintCommand( " Effects: Quake", true);
1712 M_Options_PrintCommand( " Effects: Normal", true);
1713 M_Options_PrintCommand( " Effects: High", true);
1714 M_Options_PrintCommand( " Customize Lighting", true);
1715 M_Options_PrintCommand( " Lighting: Flares", true);
1716 M_Options_PrintCommand( " Lighting: Normal", true);
1717 M_Options_PrintCommand( " Lighting: High", true);
1718 M_Options_PrintCommand( " Lighting: Full", true);
1719 M_Options_PrintCommand( " Browse Mods", true);
1720}
1721
1722
1723static void M_Options_Key(cmd_state_t *cmd, int k, int ascii)
1724{
1725 switch (k)
1726 {
1727 case K_ESCAPE:
1729 break;
1730
1731 case K_ENTER:
1732 m_entersound = true;
1733 switch (options_cursor)
1734 {
1735 case 0:
1737 break;
1738 case 1:
1739 m_state = m_none;
1742 break;
1743 case 2:
1745 break;
1746 case 3:
1748 break;
1749 case 11:
1751 break;
1752 case 17: // Customize Effects
1754 break;
1755 case 18: // Effects: Quake
1756 Cbuf_AddText(cmd, "cl_particles 1;cl_particles_quake 1;cl_particles_quality 1;cl_particles_explosions_shell 0;r_explosionclip 1;cl_stainmaps 0;cl_stainmaps_clearonload 1;cl_decals 0;cl_particles_bulletimpacts 1;cl_particles_smoke 1;cl_particles_sparks 1;cl_particles_bubbles 1;cl_particles_blood 1;cl_particles_blood_alpha 1;cl_particles_blood_bloodhack 0;cl_beams_polygons 0;cl_beams_instantaimhack 0;cl_beams_quakepositionhack 1;cl_beams_lightatend 0;r_lerpmodels 1;r_lerpsprites 1;r_lerplightstyles 0;gl_polyblend 1;r_skyscroll1 1;r_skyscroll2 2;r_waterwarp 1;r_wateralpha 1;r_waterscroll 1\n");
1757 break;
1758 case 19: // Effects: Normal
1759 Cbuf_AddText(cmd, "cl_particles 1;cl_particles_quake 0;cl_particles_quality 1;cl_particles_explosions_shell 0;r_explosionclip 1;cl_stainmaps 0;cl_stainmaps_clearonload 1;cl_decals 1;cl_particles_bulletimpacts 1;cl_particles_smoke 1;cl_particles_sparks 1;cl_particles_bubbles 1;cl_particles_blood 1;cl_particles_blood_alpha 1;cl_particles_blood_bloodhack 1;cl_beams_polygons 1;cl_beams_instantaimhack 0;cl_beams_quakepositionhack 1;cl_beams_lightatend 0;r_lerpmodels 1;r_lerpsprites 1;r_lerplightstyles 0;gl_polyblend 1;r_skyscroll1 1;r_skyscroll2 2;r_waterwarp 1;r_wateralpha 1;r_waterscroll 1\n");
1760 break;
1761 case 20: // Effects: High
1762 Cbuf_AddText(cmd, "cl_particles 1;cl_particles_quake 0;cl_particles_quality 2;cl_particles_explosions_shell 0;r_explosionclip 1;cl_stainmaps 1;cl_stainmaps_clearonload 1;cl_decals 1;cl_particles_bulletimpacts 1;cl_particles_smoke 1;cl_particles_sparks 1;cl_particles_bubbles 1;cl_particles_blood 1;cl_particles_blood_alpha 1;cl_particles_blood_bloodhack 1;cl_beams_polygons 1;cl_beams_instantaimhack 0;cl_beams_quakepositionhack 1;cl_beams_lightatend 0;r_lerpmodels 1;r_lerpsprites 1;r_lerplightstyles 0;gl_polyblend 1;r_skyscroll1 1;r_skyscroll2 2;r_waterwarp 1;r_wateralpha 1;r_waterscroll 1\n");
1763 break;
1764 case 21:
1766 break;
1767 case 22: // Lighting: Flares
1768 Cbuf_AddText(cmd, "r_coronas 1;gl_flashblend 1;r_shadow_gloss 0;r_shadow_realtime_dlight 0;r_shadow_realtime_dlight_shadows 0;r_shadow_realtime_world 0;r_shadow_realtime_world_lightmaps 0;r_shadow_realtime_world_shadows 1;r_bloom 0");
1769 break;
1770 case 23: // Lighting: Normal
1771 Cbuf_AddText(cmd, "r_coronas 1;gl_flashblend 0;r_shadow_gloss 1;r_shadow_realtime_dlight 1;r_shadow_realtime_dlight_shadows 0;r_shadow_realtime_world 0;r_shadow_realtime_world_lightmaps 0;r_shadow_realtime_world_shadows 1;r_bloom 0");
1772 break;
1773 case 24: // Lighting: High
1774 Cbuf_AddText(cmd, "r_coronas 1;gl_flashblend 0;r_shadow_gloss 1;r_shadow_realtime_dlight 1;r_shadow_realtime_dlight_shadows 1;r_shadow_realtime_world 0;r_shadow_realtime_world_lightmaps 0;r_shadow_realtime_world_shadows 1;r_bloom 1");
1775 break;
1776 case 25: // Lighting: Full
1777 Cbuf_AddText(cmd, "r_coronas 1;gl_flashblend 0;r_shadow_gloss 1;r_shadow_realtime_dlight 1;r_shadow_realtime_dlight_shadows 1;r_shadow_realtime_world 1;r_shadow_realtime_world_lightmaps 0;r_shadow_realtime_world_shadows 1;r_bloom 1");
1778 break;
1779 case 26:
1781 break;
1782 default:
1784 break;
1785 }
1786 return;
1787
1788 case K_UPARROW:
1789 S_LocalSound ("sound/misc/menu1.wav");
1791 if (options_cursor < 0)
1793 break;
1794
1795 case K_DOWNARROW:
1796 S_LocalSound ("sound/misc/menu1.wav");
1799 options_cursor = 0;
1800 break;
1801
1802 case K_LEFTARROW:
1804 break;
1805
1806 case K_RIGHTARROW:
1808 break;
1809 }
1810}
1811
1812#define OPTIONS_EFFECTS_ITEMS 35
1813
1815
1822
1823
1824extern cvar_t cl_stainmaps;
1826extern cvar_t r_explosionclip;
1827extern cvar_t r_coronas;
1828extern cvar_t gl_flashblend;
1840
1842{
1843 int optnum;
1844 S_LocalSound ("sound/misc/menu3.wav");
1845
1846 optnum = 0;
1876 else if (options_effects_cursor == optnum++) Cvar_SetValueQuick (&gl_polyblend, bound(0, gl_polyblend.value + dir * 0.1, 1));
1877 else if (options_effects_cursor == optnum++) Cvar_SetValueQuick (&r_skyscroll1, bound(-8, r_skyscroll1.value + dir * 0.1, 8));
1878 else if (options_effects_cursor == optnum++) Cvar_SetValueQuick (&r_skyscroll2, bound(-8, r_skyscroll2.value + dir * 0.1, 8));
1879 else if (options_effects_cursor == optnum++) Cvar_SetValueQuick (&r_waterwarp, bound(0, r_waterwarp.value + dir * 0.1, 1));
1880 else if (options_effects_cursor == optnum++) Cvar_SetValueQuick (&r_wateralpha, bound(0, r_wateralpha.value + dir * 0.1, 1));
1881 else if (options_effects_cursor == optnum++) Cvar_SetValueQuick (&r_waterscroll, bound(0, r_waterscroll.value + dir * 0.5, 10));
1882}
1883
1884static void M_Options_Effects_Draw (void)
1885{
1886 int visible;
1887 cachepic_t *p;
1888
1890
1891 M_DrawPic(16, 4, "gfx/qplaque");
1892 p = Draw_CachePic ("gfx/p_option");
1893 M_DrawPic((320-Draw_GetPicWidth(p))/2, 4, "gfx/p_option");
1894
1896 m_optnum = 0;
1897 visible = (int)((menu_height - 32) / 8);
1898 m_opty = 32 - bound(0, m_optcursor - (visible >> 1), max(0, OPTIONS_EFFECTS_ITEMS - visible)) * 8;
1899
1900 M_Options_PrintCheckbox(" Particles", true, cl_particles.integer);
1901 M_Options_PrintCheckbox(" Quake-style Particles", true, cl_particles_quake.integer);
1902 M_Options_PrintSlider( " Particles Quality", true, cl_particles_quality.value, 1, 4);
1904 M_Options_PrintCheckbox(" Explosion Shell Clip", true, r_explosionclip.integer);
1905 M_Options_PrintCheckbox(" Stainmaps", true, cl_stainmaps.integer);
1906 M_Options_PrintCheckbox("Onload Clear Stainmaps", true, cl_stainmaps_clearonload.integer);
1907 M_Options_PrintCheckbox(" Decals", true, cl_decals.integer);
1913 M_Options_PrintSlider( " Blood Opacity", true, cl_particles_blood_alpha.value, 0.2, 1);
1914 M_Options_PrintCheckbox("Force New Blood Effect", true, cl_particles_blood_bloodhack.integer);
1915 M_Options_PrintCheckbox(" Polygon Lightning", true, cl_beams_polygons.integer);
1916 M_Options_PrintCheckbox("Smooth Sweep Lightning", true, cl_beams_instantaimhack.integer);
1917 M_Options_PrintCheckbox(" Waist-level Lightning", true, cl_beams_quakepositionhack.integer);
1918 M_Options_PrintCheckbox(" Lightning End Light", true, cl_beams_lightatend.integer);
1926 M_Options_PrintCheckbox(" Model Interpolation", true, r_lerpmodels.integer);
1927 M_Options_PrintCheckbox(" Sprite Interpolation", true, r_lerpsprites.integer);
1928 M_Options_PrintCheckbox(" Flicker Interpolation", true, r_lerplightstyles.integer);
1929 M_Options_PrintSlider( " View Blend", true, gl_polyblend.value, 0, 1);
1930 M_Options_PrintSlider( "Upper Sky Scroll Speed", true, r_skyscroll1.value, -8, 8);
1931 M_Options_PrintSlider( "Lower Sky Scroll Speed", true, r_skyscroll2.value, -8, 8);
1932 M_Options_PrintSlider( " Underwater View Warp", true, r_waterwarp.value, 0, 1);
1933 M_Options_PrintSlider( " Water Alpha (opacity)", true, r_wateralpha.value, 0, 1);
1934 M_Options_PrintSlider( " Water Movement", true, r_waterscroll.value, 0, 10);
1935}
1936
1937
1938static void M_Options_Effects_Key(cmd_state_t *cmd, int k, int ascii)
1939{
1940 switch (k)
1941 {
1942 case K_ESCAPE:
1944 break;
1945
1946 case K_ENTER:
1948 break;
1949
1950 case K_UPARROW:
1951 S_LocalSound ("sound/misc/menu1.wav");
1953 if (options_effects_cursor < 0)
1955 break;
1956
1957 case K_DOWNARROW:
1958 S_LocalSound ("sound/misc/menu1.wav");
1962 break;
1963
1964 case K_LEFTARROW:
1966 break;
1967
1968 case K_RIGHTARROW:
1970 break;
1971 }
1972}
1973
1974
1975#define OPTIONS_GRAPHICS_ITEMS 20
1976
1978
1985
1986extern cvar_t r_shadow_gloss;
1992extern cvar_t r_bloom;
1996extern cvar_t r_bloom_blur;
2001extern cvar_t gl_picmip;
2002
2004{
2005 int optnum;
2006 S_LocalSound ("sound/misc/menu3.wav");
2007
2008 optnum = 0;
2009
2010 if (options_graphics_cursor == optnum++) Cvar_SetValueQuick (&r_coronas, bound(0, r_coronas.value + dir * 0.125, 4));
2021 else if (options_graphics_cursor == optnum++) Cvar_SetValueQuick (&r_bloom_colorscale, bound(0.0625, r_bloom_colorscale.value + dir * 0.0625, 1));
2022 else if (options_graphics_cursor == optnum++) Cvar_SetValueQuick (&r_bloom_colorsubtract, bound(0, r_bloom_colorsubtract.value + dir * 0.0625, 1-0.0625));
2023 else if (options_graphics_cursor == optnum++) Cvar_SetValueQuick (&r_bloom_colorexponent, bound(1, r_bloom_colorexponent.value * (dir > 0 ? 2.0 : 0.5), 8));
2025 else if (options_graphics_cursor == optnum++) Cvar_SetValueQuick (&r_bloom_blur, bound(1, r_bloom_blur.value + dir * 1, 16));
2027 else if (options_graphics_cursor == optnum++) Cbuf_AddText(cmd, "r_restart\n");
2028}
2029
2030
2031static void M_Options_Graphics_Draw (void)
2032{
2033 int visible;
2034 cachepic_t *p;
2035
2037
2038 M_DrawPic(16, 4, "gfx/qplaque");
2039 p = Draw_CachePic ("gfx/p_option");
2040 M_DrawPic((320-Draw_GetPicWidth(p))/2, 4, "gfx/p_option");
2041
2043 m_optnum = 0;
2044 visible = (int)((menu_height - 32) / 8);
2045 m_opty = 32 - bound(0, m_optcursor - (visible >> 1), max(0, OPTIONS_GRAPHICS_ITEMS - visible)) * 8;
2046
2047 M_Options_PrintSlider( " Corona Intensity", true, r_coronas.value, 0, 4);
2048 M_Options_PrintCheckbox(" Use Only Coronas", true, gl_flashblend.integer);
2049 M_Options_PrintSlider( " Gloss Mode", true, r_shadow_gloss.integer, 0, 2);
2053 M_Options_PrintSlider( " RT World Lightmaps", true, r_shadow_realtime_world_lightmaps.value, 0, 1);
2055 M_Options_PrintCheckbox(" Bloom Effect", true, r_bloom.integer);
2056 M_Options_PrintSlider( " Scene Brightness", true, r_hdr_scenebrightness.value, 0.25, 4);
2057 M_Options_PrintSlider( " Glow Brightness", true, r_hdr_glowintensity.value, 0, 4);
2058 M_Options_PrintSlider( " Bloom Color Scale", r_bloom.integer, r_bloom_colorscale.value, 0.0625, 1);
2059 M_Options_PrintSlider( " Bloom Color Subtract", r_bloom.integer, r_bloom_colorsubtract.value, 0, 1-0.0625);
2060 M_Options_PrintSlider( " Bloom Color Exponent", r_bloom.integer, r_bloom_colorexponent.value, 1, 8);
2061 M_Options_PrintSlider( " Bloom Intensity", r_bloom.integer, r_bloom_brighten.value, 1, 4);
2062 M_Options_PrintSlider( " Bloom Blur", r_bloom.integer, r_bloom_blur.value, 1, 16);
2063 M_Options_PrintSlider( " Bloom Resolution", r_bloom.integer, r_bloom_resolution.value, 64, 2048);
2064 M_Options_PrintCommand( " Restart Renderer", true);
2065}
2066
2067
2068static void M_Options_Graphics_Key (cmd_state_t *cmd, int k, int ascii)
2069{
2070 switch (k)
2071 {
2072 case K_ESCAPE:
2074 break;
2075
2076 case K_ENTER:
2078 break;
2079
2080 case K_UPARROW:
2081 S_LocalSound ("sound/misc/menu1.wav");
2085 break;
2086
2087 case K_DOWNARROW:
2088 S_LocalSound ("sound/misc/menu1.wav");
2092 break;
2093
2094 case K_LEFTARROW:
2096 break;
2097
2098 case K_RIGHTARROW:
2100 break;
2101 }
2102}
2103
2104
2105#define OPTIONS_COLORCONTROL_ITEMS 18
2106
2108
2109// intensity value to match up to 50% dither to 'correct' quake
2110static cvar_t menu_options_colorcontrol_correctionvalue = {CF_CLIENT, "menu_options_colorcontrol_correctionvalue", "0.5", "intensity value that matches up to white/black dither pattern, should be 0.5 for linear color"};
2111
2118
2119
2121{
2122 int optnum;
2123 float f;
2124 S_LocalSound ("sound/misc/menu3.wav");
2125
2126 optnum = 1;
2127 if (options_colorcontrol_cursor == optnum++)
2128 {
2130 Cvar_SetValueQuick (&v_gamma, bound(1, v_gamma.value + dir * 0.125, 5));
2131 }
2132 else if (options_colorcontrol_cursor == optnum++)
2133 {
2136 }
2137 else if (options_colorcontrol_cursor == optnum++)
2138 {
2141 }
2142 else if (options_colorcontrol_cursor == optnum++)
2143 {
2145 }
2146 else if (options_colorcontrol_cursor == optnum++)
2147 {
2150 }
2151 else if (options_colorcontrol_cursor == optnum++)
2152 {
2155 }
2156 else if (options_colorcontrol_cursor == optnum++)
2157 {
2160 }
2161 else if (options_colorcontrol_cursor == optnum++)
2162 {
2164 f = bound(0, (v_color_black_r.value + v_color_black_g.value + v_color_black_b.value) / 3 + dir * 0.0125, 0.8);
2168 }
2169 else if (options_colorcontrol_cursor == optnum++)
2170 {
2173 }
2174 else if (options_colorcontrol_cursor == optnum++)
2175 {
2178 }
2179 else if (options_colorcontrol_cursor == optnum++)
2180 {
2183 }
2184 else if (options_colorcontrol_cursor == optnum++)
2185 {
2187 f = bound(0, (v_color_grey_r.value + v_color_grey_g.value + v_color_grey_b.value) / 3 + dir * 0.0125, 0.95);
2191 }
2192 else if (options_colorcontrol_cursor == optnum++)
2193 {
2196 }
2197 else if (options_colorcontrol_cursor == optnum++)
2198 {
2201 }
2202 else if (options_colorcontrol_cursor == optnum++)
2203 {
2206 }
2207 else if (options_colorcontrol_cursor == optnum++)
2208 {
2214 }
2215}
2216
2218{
2219 int visible;
2220 float x, s, t, u, v;
2221 float c[3];
2222 cachepic_t *p, *dither;
2223
2224 dither = Draw_CachePic_Flags ("gfx/colorcontrol/ditherpattern", CACHEPICFLAG_NOCLAMP);
2225
2226 M_Background(320, 256);
2227
2228 M_DrawPic(16, 4, "gfx/qplaque");
2229 p = Draw_CachePic ("gfx/p_option");
2230 M_DrawPic((320-Draw_GetPicWidth(p))/2, 4, "gfx/p_option");
2231
2233 m_optnum = 0;
2234 visible = (int)((menu_height - 32) / 8);
2235 m_opty = 32 - bound(0, m_optcursor - (visible >> 1), max(0, OPTIONS_COLORCONTROL_ITEMS - visible)) * 8;
2236
2237 M_Options_PrintCommand( " Reset to defaults", true);
2241 M_Options_PrintCheckbox(" Color Level Controls", true, v_color_enable.integer);
2254
2255 m_opty += 4;
2256 DrawQ_Fill(menu_x, menu_y + m_opty, 320, 4 + 64 + 8 + 64 + 4, 0, 0, 0, 1, 0);m_opty += 4;
2257 s = (float) 312 / 2 * vid.mode.width / vid_conwidth.integer;
2258 t = (float) 4 / 2 * vid.mode.height / vid_conheight.integer;
2259 DrawQ_SuperPic(menu_x + 4, menu_y + m_opty, dither, 312, 4, 0,0, 1,0,0,1, s,0, 1,0,0,1, 0,t, 1,0,0,1, s,t, 1,0,0,1, 0);m_opty += 4;
2260 DrawQ_SuperPic(menu_x + 4, menu_y + m_opty, NULL , 312, 4, 0,0, 0,0,0,1, 1,0, 1,0,0,1, 0,1, 0,0,0,1, 1,1, 1,0,0,1, 0);m_opty += 4;
2261 DrawQ_SuperPic(menu_x + 4, menu_y + m_opty, dither, 312, 4, 0,0, 0,1,0,1, s,0, 0,1,0,1, 0,t, 0,1,0,1, s,t, 0,1,0,1, 0);m_opty += 4;
2262 DrawQ_SuperPic(menu_x + 4, menu_y + m_opty, NULL , 312, 4, 0,0, 0,0,0,1, 1,0, 0,1,0,1, 0,1, 0,0,0,1, 1,1, 0,1,0,1, 0);m_opty += 4;
2263 DrawQ_SuperPic(menu_x + 4, menu_y + m_opty, dither, 312, 4, 0,0, 0,0,1,1, s,0, 0,0,1,1, 0,t, 0,0,1,1, s,t, 0,0,1,1, 0);m_opty += 4;
2264 DrawQ_SuperPic(menu_x + 4, menu_y + m_opty, NULL , 312, 4, 0,0, 0,0,0,1, 1,0, 0,0,1,1, 0,1, 0,0,0,1, 1,1, 0,0,1,1, 0);m_opty += 4;
2265 DrawQ_SuperPic(menu_x + 4, menu_y + m_opty, dither, 312, 4, 0,0, 1,1,1,1, s,0, 1,1,1,1, 0,t, 1,1,1,1, s,t, 1,1,1,1, 0);m_opty += 4;
2266 DrawQ_SuperPic(menu_x + 4, menu_y + m_opty, NULL , 312, 4, 0,0, 0,0,0,1, 1,0, 1,1,1,1, 0,1, 0,0,0,1, 1,1, 1,1,1,1, 0);m_opty += 4;
2267
2268 c[0] = menu_options_colorcontrol_correctionvalue.value; // intensity value that should be matched up to a 50% dither to 'correct' quake
2269 c[1] = c[0];
2270 c[2] = c[1];
2272 s = (float) 48 / 2 * vid.mode.width / vid_conwidth.integer;
2273 t = (float) 48 / 2 * vid.mode.height / vid_conheight.integer;
2274 u = s * 0.5;
2275 v = t * 0.5;
2276 m_opty += 8;
2277 x = 4;
2278 DrawQ_Fill(menu_x + x, menu_y + m_opty, 64, 48, c[0], 0, 0, 1, 0);
2279 DrawQ_SuperPic(menu_x + x + 16, menu_y + m_opty + 16, dither, 16, 16, 0,0, 1,0,0,1, s,0, 1,0,0,1, 0,t, 1,0,0,1, s,t, 1,0,0,1, 0);
2280 DrawQ_SuperPic(menu_x + x + 32, menu_y + m_opty + 16, dither, 16, 16, 0,0, 1,0,0,1, u,0, 1,0,0,1, 0,v, 1,0,0,1, u,v, 1,0,0,1, 0);
2281 x += 80;
2282 DrawQ_Fill(menu_x + x, menu_y + m_opty, 64, 48, 0, c[1], 0, 1, 0);
2283 DrawQ_SuperPic(menu_x + x + 16, menu_y + m_opty + 16, dither, 16, 16, 0,0, 0,1,0,1, s,0, 0,1,0,1, 0,t, 0,1,0,1, s,t, 0,1,0,1, 0);
2284 DrawQ_SuperPic(menu_x + x + 32, menu_y + m_opty + 16, dither, 16, 16, 0,0, 0,1,0,1, u,0, 0,1,0,1, 0,v, 0,1,0,1, u,v, 0,1,0,1, 0);
2285 x += 80;
2286 DrawQ_Fill(menu_x + x, menu_y + m_opty, 64, 48, 0, 0, c[2], 1, 0);
2287 DrawQ_SuperPic(menu_x + x + 16, menu_y + m_opty + 16, dither, 16, 16, 0,0, 0,0,1,1, s,0, 0,0,1,1, 0,t, 0,0,1,1, s,t, 0,0,1,1, 0);
2288 DrawQ_SuperPic(menu_x + x + 32, menu_y + m_opty + 16, dither, 16, 16, 0,0, 0,0,1,1, u,0, 0,0,1,1, 0,v, 0,0,1,1, u,v, 0,0,1,1, 0);
2289 x += 80;
2290 DrawQ_Fill(menu_x + x, menu_y + m_opty, 64, 48, c[0], c[1], c[2], 1, 0);
2291 DrawQ_SuperPic(menu_x + x + 16, menu_y + m_opty + 16, dither, 16, 16, 0,0, 1,1,1,1, s,0, 1,1,1,1, 0,t, 1,1,1,1, s,t, 1,1,1,1, 0);
2292 DrawQ_SuperPic(menu_x + x + 32, menu_y + m_opty + 16, dither, 16, 16, 0,0, 1,1,1,1, u,0, 1,1,1,1, 0,v, 1,1,1,1, u,v, 1,1,1,1, 0);
2293}
2294
2295
2296static void M_Options_ColorControl_Key(cmd_state_t *cmd, int k, int ascii)
2297{
2298 switch (k)
2299 {
2300 case K_ESCAPE:
2302 break;
2303
2304 case K_ENTER:
2305 m_entersound = true;
2307 {
2308 case 0:
2322 break;
2323 default:
2325 break;
2326 }
2327 return;
2328
2329 case K_UPARROW:
2330 S_LocalSound ("sound/misc/menu1.wav");
2334 break;
2335
2336 case K_DOWNARROW:
2337 S_LocalSound ("sound/misc/menu1.wav");
2341 break;
2342
2343 case K_LEFTARROW:
2345 break;
2346
2347 case K_RIGHTARROW:
2349 break;
2350 }
2351}
2352
2353
2354//=============================================================================
2355/* KEYS MENU */
2356
2357static const char *quakebindnames[][2] =
2358{
2359{"+attack", "attack"},
2360{"impulse 10", "next weapon"},
2361{"impulse 12", "previous weapon"},
2362{"+jump", "jump / swim up"},
2363{"+forward", "walk forward"},
2364{"+back", "backpedal"},
2365{"+left", "turn left"},
2366{"+right", "turn right"},
2367{"+speed", "run"},
2368{"+moveleft", "step left"},
2369{"+moveright", "step right"},
2370{"+strafe", "sidestep"},
2371{"+lookup", "look up"},
2372{"+lookdown", "look down"},
2373{"centerview", "center view"},
2374{"+mlook", "mouse look"},
2375{"+klook", "keyboard look"},
2376{"+moveup", "swim up"},
2377{"+movedown", "swim down"}
2378};
2379
2380static const char *transfusionbindnames[][2] =
2381{
2382{"", "Movement"}, // Movement commands
2383{"+forward", "walk forward"},
2384{"+back", "backpedal"},
2385{"+left", "turn left"},
2386{"+right", "turn right"},
2387{"+moveleft", "step left"},
2388{"+moveright", "step right"},
2389{"+jump", "jump / swim up"},
2390{"+movedown", "swim down"},
2391{"", "Combat"}, // Combat commands
2392{"impulse 1", "Pitch Fork"},
2393{"impulse 2", "Flare Gun"},
2394{"impulse 3", "Shotgun"},
2395{"impulse 4", "Machine Gun"},
2396{"impulse 5", "Incinerator"},
2397{"impulse 6", "Bombs (TNT)"},
2398{"impulse 35", "Proximity Bomb"},
2399{"impulse 36", "Remote Detonator"},
2400{"impulse 7", "Aerosol Can"},
2401{"impulse 8", "Tesla Cannon"},
2402{"impulse 9", "Life Leech"},
2403{"impulse 10", "Voodoo Doll"},
2404{"impulse 21", "next weapon"},
2405{"impulse 22", "previous weapon"},
2406{"+attack", "attack"},
2407{"+button3", "altfire"},
2408{"", "Inventory"}, // Inventory commands
2409{"impulse 40", "Dr.'s Bag"},
2410{"impulse 41", "Crystal Ball"},
2411{"impulse 42", "Beast Vision"},
2412{"impulse 43", "Jump Boots"},
2413{"impulse 23", "next item"},
2414{"impulse 24", "previous item"},
2415{"impulse 25", "use item"},
2416{"", "Misc"}, // Misc commands
2417{"+button4", "use"},
2418{"impulse 50", "add bot (red)"},
2419{"impulse 51", "add bot (blue)"},
2420{"impulse 52", "kick a bot"},
2421{"impulse 26", "next armor type"},
2422{"impulse 27", "identify player"},
2423{"impulse 55", "voting menu"},
2424{"impulse 56", "observer mode"},
2425{"", "Taunts"}, // Taunts
2426{"impulse 70", "taunt 0"},
2427{"impulse 71", "taunt 1"},
2428{"impulse 72", "taunt 2"},
2429{"impulse 73", "taunt 3"},
2430{"impulse 74", "taunt 4"},
2431{"impulse 75", "taunt 5"},
2432{"impulse 76", "taunt 6"},
2433{"impulse 77", "taunt 7"},
2434{"impulse 78", "taunt 8"},
2435{"impulse 79", "taunt 9"}
2436};
2437
2438static const char *goodvsbad2bindnames[][2] =
2439{
2440{"impulse 69", "Power 1"},
2441{"impulse 70", "Power 2"},
2442{"impulse 71", "Power 3"},
2443{"+jump", "jump / swim up"},
2444{"+forward", "walk forward"},
2445{"+back", "backpedal"},
2446{"+left", "turn left"},
2447{"+right", "turn right"},
2448{"+speed", "run"},
2449{"+moveleft", "step left"},
2450{"+moveright", "step right"},
2451{"+strafe", "sidestep"},
2452{"+lookup", "look up"},
2453{"+lookdown", "look down"},
2454{"centerview", "center view"},
2455{"+mlook", "mouse look"},
2456{"kill", "kill yourself"},
2457{"+moveup", "swim up"},
2458{"+movedown", "swim down"}
2459};
2460
2461static int numcommands;
2462static const char *(*bindnames)[2];
2463
2464/*
2465typedef struct binditem_s
2466{
2467 char *command, *description;
2468 struct binditem_s *next;
2469}
2470binditem_t;
2471
2472typedef struct bindcategory_s
2473{
2474 char *name;
2475 binditem_t *binds;
2476 struct bindcategory_s *next;
2477}
2478bindcategory_t;
2479
2480static bindcategory_t *bindcategories = NULL;
2481
2482static void M_ClearBinds (void)
2483{
2484 for (c = bindcategories;c;c = cnext)
2485 {
2486 cnext = c->next;
2487 for (b = c->binds;b;b = bnext)
2488 {
2489 bnext = b->next;
2490 Z_Free(b);
2491 }
2492 Z_Free(c);
2493 }
2494 bindcategories = NULL;
2495}
2496
2497static void M_AddBindToCategory(bindcategory_t *c, char *command, char *description)
2498{
2499 for (b = &c->binds;*b;*b = &(*b)->next);
2500 *b = Z_Alloc(sizeof(binditem_t) + strlen(command) + 1 + strlen(description) + 1);
2501 *b->command = (char *)((*b) + 1);
2502 *b->description = *b->command + strlen(command) + 1;
2503 strlcpy(*b->command, command, strlen(command) + 1);
2504 strlcpy(*b->description, description, strlen(description) + 1);
2505}
2506
2507static void M_AddBind (char *category, char *command, char *description)
2508{
2509 for (c = &bindcategories;*c;c = &(*c)->next)
2510 {
2511 if (!strcmp(category, (*c)->name))
2512 {
2513 M_AddBindToCategory(*c, command, description);
2514 return;
2515 }
2516 }
2517 *c = Z_Alloc(sizeof(bindcategory_t));
2518 M_AddBindToCategory(*c, command, description);
2519}
2520
2521static void M_DefaultBinds (void)
2522{
2523 M_ClearBinds();
2524 M_AddBind("movement", "+jump", "jump / swim up");
2525 M_AddBind("movement", "+forward", "walk forward");
2526 M_AddBind("movement", "+back", "backpedal");
2527 M_AddBind("movement", "+left", "turn left");
2528 M_AddBind("movement", "+right", "turn right");
2529 M_AddBind("movement", "+speed", "run");
2530 M_AddBind("movement", "+moveleft", "step left");
2531 M_AddBind("movement", "+moveright", "step right");
2532 M_AddBind("movement", "+strafe", "sidestep");
2533 M_AddBind("movement", "+lookup", "look up");
2534 M_AddBind("movement", "+lookdown", "look down");
2535 M_AddBind("movement", "centerview", "center view");
2536 M_AddBind("movement", "+mlook", "mouse look");
2537 M_AddBind("movement", "+klook", "keyboard look");
2538 M_AddBind("movement", "+moveup", "swim up");
2539 M_AddBind("movement", "+movedown", "swim down");
2540 M_AddBind("weapons", "+attack", "attack");
2541 M_AddBind("weapons", "impulse 10", "next weapon");
2542 M_AddBind("weapons", "impulse 12", "previous weapon");
2543 M_AddBind("weapons", "impulse 1", "select weapon 1 (axe)");
2544 M_AddBind("weapons", "impulse 2", "select weapon 2 (shotgun)");
2545 M_AddBind("weapons", "impulse 3", "select weapon 3 (super )");
2546 M_AddBind("weapons", "impulse 4", "select weapon 4 (nailgun)");
2547 M_AddBind("weapons", "impulse 5", "select weapon 5 (super nailgun)");
2548 M_AddBind("weapons", "impulse 6", "select weapon 6 (grenade launcher)");
2549 M_AddBind("weapons", "impulse 7", "select weapon 7 (rocket launcher)");
2550 M_AddBind("weapons", "impulse 8", "select weapon 8 (lightning gun)");
2551}
2552*/
2553
2554
2555static int keys_cursor;
2556static int bind_grab;
2557
2559{
2561 m_state = m_keys;
2562 m_entersound = true;
2563
2565 {
2568 }
2569 else if (gamemode == GAME_GOODVSBAD2)
2570 {
2573 }
2574 else
2575 {
2576 numcommands = sizeof(quakebindnames) / sizeof(quakebindnames[0]);
2578 }
2579
2580 // Make sure "keys_cursor" doesn't start on a section in the binding list
2581 keys_cursor = 0;
2582 while (bindnames[keys_cursor][0][0] == '\0')
2583 {
2584 keys_cursor++;
2585
2586 // Only sections? There may be a problem somewhere...
2587 if (keys_cursor >= numcommands)
2588 Sys_Error ("M_Init: The key binding list only contains sections");
2589 }
2590}
2591
2592#define NUMKEYS 5
2593
2594static void M_UnbindCommand (const char *command)
2595{
2596 int j;
2597 const char *b;
2598
2599 for (j = 0; j < (int)sizeof (keybindings[0]) / (int)sizeof (keybindings[0][0]); j++)
2600 {
2601 b = keybindings[0][j];
2602 if (!b)
2603 continue;
2604 if (!strcmp (b, command))
2605 Key_SetBinding (j, 0, "");
2606 }
2607}
2608
2609
2610static void M_Keys_Draw (void)
2611{
2612 int i, j;
2613 int keys[NUMKEYS];
2614 int y;
2615 cachepic_t *p;
2616 char keystring[MAX_INPUTLINE];
2617
2618 M_Background(320, 48 + 8 * numcommands);
2619
2620 p = Draw_CachePic ("gfx/ttl_cstm");
2621 M_DrawPic ( (320-Draw_GetPicWidth(p))/2, 4, "gfx/ttl_cstm");
2622
2623 if (bind_grab)
2624 M_Print(12, 32, "Press a key or button for this action");
2625 else
2626 M_Print(18, 32, "Enter to change, backspace to clear");
2627
2628// search for known bindings
2629 for (i=0 ; i<numcommands ; i++)
2630 {
2631 y = 48 + 8*i;
2632
2633 // If there's no command, it's just a section
2634 if (bindnames[i][0][0] == '\0')
2635 {
2636 M_PrintRed (4, y, "\x0D"); // #13 is the little arrow pointing to the right
2637 M_PrintRed (16, y, bindnames[i][1]);
2638 continue;
2639 }
2640 else
2641 M_Print(16, y, bindnames[i][1]);
2642
2643 Key_FindKeysForCommand (bindnames[i][0], keys, NUMKEYS, 0);
2644
2645 // LadyHavoc: redesigned to print more than 2 keys, inspired by Tomaz's MiniRacer
2646 if (keys[0] == -1)
2647 dp_strlcpy(keystring, "???", sizeof(keystring));
2648 else
2649 {
2650 char tinystr[TINYSTR_LEN];
2651 keystring[0] = 0;
2652 for (j = 0;j < NUMKEYS;j++)
2653 {
2654 if (keys[j] != -1)
2655 {
2656 if (j > 0)
2657 dp_strlcat(keystring, " or ", sizeof(keystring));
2658 dp_strlcat(keystring, Key_KeynumToString (keys[j], tinystr, TINYSTR_LEN), sizeof(keystring));
2659 }
2660 }
2661 }
2662 M_Print(150, y, keystring);
2663 }
2664
2665 if (bind_grab)
2666 M_DrawCharacter (140, 48 + keys_cursor*8, '=');
2667 else
2668 M_DrawCharacter (140, 48 + keys_cursor*8, 12+((int)(host.realtime*4)&1));
2669}
2670
2671
2672static void M_Keys_Key(cmd_state_t *cmd, int k, int ascii)
2673{
2674 char line[80];
2675 int keys[NUMKEYS];
2676 char tinystr[TINYSTR_LEN];
2677
2678 if (bind_grab)
2679 { // defining a key
2680 S_LocalSound ("sound/misc/menu1.wav");
2681 if (k == K_ESCAPE)
2682 {
2683 bind_grab = false;
2684 }
2685 else //if (k != '`')
2686 {
2687 dpsnprintf(line, sizeof(line), "bind \"%s\" \"%s\"\n", Key_KeynumToString(k, tinystr, TINYSTR_LEN), bindnames[keys_cursor][0]);
2688 Cbuf_InsertText (cmd, line);
2689 }
2690
2691 bind_grab = false;
2692 return;
2693 }
2694
2695 switch (k)
2696 {
2697 case K_ESCAPE:
2699 break;
2700
2701 case K_LEFTARROW:
2702 case K_UPARROW:
2703 S_LocalSound ("sound/misc/menu1.wav");
2704 do
2705 {
2706 keys_cursor--;
2707 if (keys_cursor < 0)
2709 }
2710 while (bindnames[keys_cursor][0][0] == '\0'); // skip sections
2711 break;
2712
2713 case K_DOWNARROW:
2714 case K_RIGHTARROW:
2715 S_LocalSound ("sound/misc/menu1.wav");
2716 do
2717 {
2718 keys_cursor++;
2719 if (keys_cursor >= numcommands)
2720 keys_cursor = 0;
2721 }
2722 while (bindnames[keys_cursor][0][0] == '\0'); // skip sections
2723 break;
2724
2725 case K_ENTER: // go into bind mode
2727 S_LocalSound ("sound/misc/menu2.wav");
2728 if (keys[NUMKEYS - 1] != -1)
2730 bind_grab = true;
2731 break;
2732
2733 case K_BACKSPACE: // delete bindings
2734 case K_DEL: // delete bindings
2735 S_LocalSound ("sound/misc/menu2.wav");
2737 break;
2738 }
2739}
2740
2742{
2744 m_state = m_reset;
2745 m_entersound = true;
2746}
2747
2748
2749static void M_Reset_Key(cmd_state_t *cmd, int key, int ascii)
2750{
2751 switch (key)
2752 {
2753 case 'Y':
2754 case 'y':
2755 Cbuf_AddText(cmd, "cvar_resettodefaults_all;exec default.cfg\n");
2756 // no break here since we also exit the menu
2757
2758 case K_ESCAPE:
2759 case 'n':
2760 case 'N':
2762 m_entersound = true;
2763 break;
2764
2765 default:
2766 break;
2767 }
2768}
2769
2770static void M_Reset_Draw (void)
2771{
2772 int lines = 2, linelength = 20;
2773 M_Background(linelength * 8 + 16, lines * 8 + 16);
2774 M_DrawTextBox(0, 0, linelength, lines);
2775 M_Print(8 + 4 * (linelength - 19), 8, "Really wanna reset?");
2776 M_Print(8 + 4 * (linelength - 11), 16, "Press y / n");
2777}
2778
2779//=============================================================================
2780/* VIDEO MENU */
2781
2783{
2784{"Standard 4x3" , 320, 240, 320, 240, 1 },
2785{"Standard 4x3" , 400, 300, 400, 300, 1 },
2786{"Standard 4x3" , 512, 384, 512, 384, 1 },
2787{"Standard 4x3" , 640, 480, 640, 480, 1 },
2788{"Standard 4x3" , 800, 600, 640, 480, 1 },
2789{"Standard 4x3" , 1024, 768, 640, 480, 1 },
2790{"Standard 4x3" , 1152, 864, 640, 480, 1 },
2791{"Standard 4x3" , 1280, 960, 640, 480, 1 },
2792{"Standard 4x3" , 1400,1050, 640, 480, 1 },
2793{"Standard 4x3" , 1600,1200, 640, 480, 1 },
2794{"Standard 4x3" , 1792,1344, 640, 480, 1 },
2795{"Standard 4x3" , 1856,1392, 640, 480, 1 },
2796{"Standard 4x3" , 1920,1440, 640, 480, 1 },
2797{"Standard 4x3" , 2048,1536, 640, 480, 1 },
2798{"Short Pixel (CRT) 5x4" , 320, 256, 320, 256, 0.9375},
2799{"Short Pixel (CRT) 5x4" , 640, 512, 640, 512, 0.9375},
2800{"Short Pixel (CRT) 5x4" , 1280,1024, 640, 512, 0.9375},
2801{"Tall Pixel (CRT) 8x5" , 320, 200, 320, 200, 1.2 },
2802{"Tall Pixel (CRT) 8x5" , 640, 400, 640, 400, 1.2 },
2803{"Tall Pixel (CRT) 8x5" , 840, 525, 640, 400, 1.2 },
2804{"Tall Pixel (CRT) 8x5" , 960, 600, 640, 400, 1.2 },
2805{"Tall Pixel (CRT) 8x5" , 1680,1050, 640, 400, 1.2 },
2806{"Tall Pixel (CRT) 8x5" , 1920,1200, 640, 400, 1.2 },
2807{"Square Pixel (LCD) 5x4" , 320, 256, 320, 256, 1 },
2808{"Square Pixel (LCD) 5x4" , 640, 512, 640, 512, 1 },
2809{"Square Pixel (LCD) 5x4" , 1280,1024, 640, 512, 1 },
2810{"WideScreen 5x3" , 640, 384, 640, 384, 1 },
2811{"WideScreen 5x3" , 1280, 768, 640, 384, 1 },
2812{"WideScreen 8x5" , 320, 200, 320, 200, 1 },
2813{"WideScreen 8x5" , 640, 400, 640, 400, 1 },
2814{"WideScreen 8x5" , 720, 450, 720, 450, 1 },
2815{"WideScreen 8x5" , 840, 525, 640, 400, 1 },
2816{"WideScreen 8x5" , 960, 600, 640, 400, 1 },
2817{"WideScreen 8x5" , 1280, 800, 640, 400, 1 },
2818{"WideScreen 8x5" , 1440, 900, 720, 450, 1 },
2819{"WideScreen 8x5" , 1680,1050, 640, 400, 1 },
2820{"WideScreen 8x5" , 1920,1200, 640, 400, 1 },
2821{"WideScreen 8x5" , 2560,1600, 640, 400, 1 },
2822{"WideScreen 8x5" , 3840,2400, 640, 400, 1 },
2823{"WideScreen 14x9" , 840, 540, 640, 400, 1 },
2824{"WideScreen 14x9" , 1680,1080, 640, 400, 1 },
2825{"WideScreen 16x9" , 640, 360, 640, 360, 1 },
2826{"WideScreen 16x9" , 683, 384, 683, 384, 1 },
2827{"WideScreen 16x9" , 960, 540, 640, 360, 1 },
2828{"WideScreen 16x9" , 1280, 720, 640, 360, 1 },
2829{"WideScreen 16x9" , 1360, 768, 680, 384, 1 },
2830{"WideScreen 16x9" , 1366, 768, 683, 384, 1 },
2831{"WideScreen 16x9" , 1600, 900, 640, 360, 1 },
2832{"WideScreen 16x9" , 1920,1080, 640, 360, 1 },
2833{"WideScreen 16x9" , 2560,1440, 640, 360, 1 },
2834{"WideScreen 16x9" , 3840,2160, 640, 360, 1 },
2835{"NTSC 3x2" , 360, 240, 360, 240, 1.125 },
2836{"NTSC 3x2" , 720, 480, 720, 480, 1.125 },
2837{"PAL 14x11" , 360, 283, 360, 283, 0.9545},
2838{"PAL 14x11" , 720, 566, 720, 566, 0.9545},
2839{"NES 8x7" , 256, 224, 256, 224, 1.1667},
2840{"SNES 8x7" , 512, 448, 512, 448, 1.1667},
2841{NULL, 0, 0, 0, 0, 0}
2842};
2843// this is the number of the default mode (640x480) in the list above
2845
2846#define VIDEO_ITEMS 11
2847static int video_cursor = 0;
2848static int video_cursor_table[VIDEO_ITEMS] = {68, 88, 96, 104, 112, 120, 128, 136, 144, 152, 160};
2850
2853
2857
2858static void M_Menu_Video_FindResolution(int w, int h, float a)
2859{
2860 int i;
2861
2863 {
2866 }
2867 else
2868 {
2871 }
2872
2873 // Look for the closest match to the current resolution
2875 for (i = 1;i < menu_video_resolutions_count;i++)
2876 {
2877 // if the new mode would be a worse match in width, skip it
2879 continue;
2880 // if it is equal in width, check height
2882 {
2883 // if the new mode would be a worse match in height, skip it
2885 continue;
2886 // if it is equal in width and height, check pixel aspect
2888 {
2889 // if the new mode would be a worse match in pixel aspect, skip it
2890 if (fabs(menu_video_resolutions[i].pixelheight - a) > fabs(menu_video_resolutions[menu_video_resolution].pixelheight - a))
2891 continue;
2892 // if it is equal in everything, skip it (prefer earlier modes)
2893 if (menu_video_resolutions[i].pixelheight == a && menu_video_resolutions[menu_video_resolution].pixelheight == a)
2894 continue;
2895 // better match for width, height, and pixel aspect
2897 }
2898 else // better match for width and height
2900 }
2901 else // better match for width
2903 }
2904}
2905
2914
2915
2916static void M_Video_Draw (void)
2917{
2918 int t;
2919 cachepic_t *p;
2920 char vabuf[1024];
2921
2923 {
2927 }
2928
2929 M_Background(320, 200);
2930
2931 M_DrawPic(16, 4, "gfx/qplaque");
2932 p = Draw_CachePic ("gfx/vidmodes");
2933 M_DrawPic((320-Draw_GetPicWidth(p))/2, 4, "gfx/vidmodes");
2934
2935 t = 0;
2936
2937 // Current and Proposed Resolution
2938 M_Print(16, video_cursor_table[t] - 12, " Current Resolution");
2940 M_Print(220, video_cursor_table[t] - 12, va(vabuf, sizeof(vabuf), "%dx%d %.2fhz", vid.mode.width, vid.mode.height, vid.mode.refreshrate));
2941 else
2942 M_Print(220, video_cursor_table[t] - 12, va(vabuf, sizeof(vabuf), "%dx%d", vid.mode.width, vid.mode.height));
2943 M_Print(16, video_cursor_table[t], " New Resolution");
2945 M_Print(96, video_cursor_table[t] + 8, va(vabuf, sizeof(vabuf), "Type: %s", menu_video_resolutions[menu_video_resolution].type));
2946 t++;
2947
2948 // Antialiasing
2949 M_Print(16, video_cursor_table[t], " Antialiasing");
2951 t++;
2952
2953 // Refresh Rate
2956 t++;
2957
2958 // Fullscreen
2959 M_Print(16, video_cursor_table[t], " Fullscreen");
2961 t++;
2962
2963 // Desktop Fullscreen
2964 M_ItemPrint(16, video_cursor_table[t], " Desktop Fullscreen", vid_fullscreen.integer);
2966 t++;
2967
2968 // Display selection (multi-monitor)
2969 M_ItemPrint(16, video_cursor_table[t], " Display/Monitor", vid_info_displaycount.integer > 1);
2971 t++;
2972
2973 // Vertical Sync
2974 M_ItemPrint(16, video_cursor_table[t], " Vertical Sync", true);
2976 t++;
2977
2980 t++;
2981
2982 M_ItemPrint(16, video_cursor_table[t], " Texture Quality", true);
2984 t++;
2985
2986 M_ItemPrint(16, video_cursor_table[t], " Texture Compression", true);
2988 t++;
2989
2990 // "Apply" button
2991 M_Print(220, video_cursor_table[t], "Apply");
2992 t++;
2993
2994 // Cursor
2996}
2997
2998
3000{
3001 int t;
3002
3003 S_LocalSound ("sound/misc/menu3.wav");
3004
3005 t = 0;
3006 if (video_cursor == t++)
3007 {
3008 // Resolution
3009 int r;
3010 for(r = 0;r < menu_video_resolutions_count;r++)
3011 {
3015 if (menu_video_resolution < 0)
3018 break;
3019 }
3020 }
3021 else if (video_cursor == t++)
3022 Cvar_SetValueQuick (&vid_samples, bound(1, vid_samples.value * (dir > 0 ? 2 : 0.5), 32));
3023 else if (video_cursor == t++) // allow jumping from the minimum refreshrate to 0 (auto)
3025 else if (video_cursor == t++)
3027 else if (video_cursor == t++)
3029 else if (video_cursor == t++)
3031 else if (video_cursor == t++)
3033 else if (video_cursor == t++)
3035 else if (video_cursor == t++)
3037 else if (video_cursor == t++)
3039}
3040
3041
3042static void M_Video_Key(cmd_state_t *cmd, int key, int ascii)
3043{
3044 switch (key)
3045 {
3046 case K_ESCAPE:
3047 // vid_shared.c has a copy of the current video config. We restore it
3054
3055 S_LocalSound ("sound/misc/menu1.wav");
3057 break;
3058
3059 case K_ENTER:
3060 m_entersound = true;
3061 switch (video_cursor)
3062 {
3063 case (VIDEO_ITEMS - 1):
3069 Cbuf_AddText(cmd, "vid_restart\n");
3071 break;
3072 default:
3074 }
3075 break;
3076
3077 case K_UPARROW:
3078 S_LocalSound ("sound/misc/menu1.wav");
3079 video_cursor--;
3080 if (video_cursor < 0)
3082 break;
3083
3084 case K_DOWNARROW:
3085 S_LocalSound ("sound/misc/menu1.wav");
3086 video_cursor++;
3088 video_cursor = 0;
3089 break;
3090
3091 case K_LEFTARROW:
3093 break;
3094
3095 case K_RIGHTARROW:
3097 break;
3098 }
3099}
3100
3101//=============================================================================
3102/* HELP MENU */
3103
3104static int help_page;
3105#define NUM_HELP_PAGES 6
3106
3107
3109{
3111 m_state = m_help;
3112 m_entersound = true;
3113 help_page = 0;
3114}
3115
3116
3117
3118static void M_Help_Draw (void)
3119{
3120 char vabuf[1024];
3121 M_Background(320, 200);
3122 M_DrawPic (0, 0, va(vabuf, sizeof(vabuf), "gfx/help%i", help_page));
3123}
3124
3125
3126static void M_Help_Key(cmd_state_t *cmd, int key, int ascii)
3127{
3128 switch (key)
3129 {
3130 case K_ESCAPE:
3132 break;
3133
3134 case K_UPARROW:
3135 case K_RIGHTARROW:
3136 m_entersound = true;
3137 if (++help_page >= NUM_HELP_PAGES)
3138 help_page = 0;
3139 break;
3140
3141 case K_DOWNARROW:
3142 case K_LEFTARROW:
3143 m_entersound = true;
3144 if (--help_page < 0)
3146 break;
3147 }
3148
3149}
3150
3151//=============================================================================
3152/* CEDITS MENU */
3153
3155{
3158 m_entersound = true;
3159}
3160
3161
3162
3163static void M_Credits_Draw (void)
3164{
3165 M_Background(640, 480);
3166 M_DrawPic (0, 0, "gfx/creditsmiddle");
3167 M_Print (640/2 - 14/2*8, 236, "Coming soon...");
3168 M_DrawPic (0, 0, "gfx/creditstop");
3169 M_DrawPic (0, 433, "gfx/creditsbottom");
3170}
3171
3172
3173static void M_Credits_Key(cmd_state_t *cmd, int key, int ascii)
3174{
3176}
3177
3178//=============================================================================
3179/* QUIT MENU */
3180
3181static const char *m_quit_message[9];
3184
3185
3186static int M_QuitMessage(const char *line1, const char *line2, const char *line3, const char *line4, const char *line5, const char *line6, const char *line7, const char *line8)
3187{
3188 m_quit_message[0] = line1;
3189 m_quit_message[1] = line2;
3190 m_quit_message[2] = line3;
3191 m_quit_message[3] = line4;
3192 m_quit_message[4] = line5;
3193 m_quit_message[5] = line6;
3194 m_quit_message[6] = line7;
3195 m_quit_message[7] = line8;
3196 m_quit_message[8] = NULL;
3197 return 1;
3198}
3199
3200static int M_ChooseQuitMessage(int request)
3201{
3202 if (m_missingdata)
3203 {
3204 // frag related quit messages are pointless for a fallback menu, so use something generic
3205 if (request-- == 0) return M_QuitMessage("Are you sure you want to quit?","Press Y to quit, N to stay",NULL,NULL,NULL,NULL,NULL,NULL);
3206 return 0;
3207 }
3208 switch (gamemode)
3209 {
3210 case GAME_NORMAL:
3211 case GAME_HIPNOTIC:
3212 case GAME_ROGUE:
3213 case GAME_QUOTH:
3214 case GAME_NEHAHRA:
3216 if (request-- == 0) return M_QuitMessage("Are you gonna quit","this game just like","everything else?",NULL,NULL,NULL,NULL,NULL);
3217 if (request-- == 0) return M_QuitMessage("Milord, methinks that","thou art a lowly","quitter. Is this true?",NULL,NULL,NULL,NULL,NULL);
3218 if (request-- == 0) return M_QuitMessage("Do I need to bust your","face open for trying","to quit?",NULL,NULL,NULL,NULL,NULL);
3219 if (request-- == 0) return M_QuitMessage("Man, I oughta smack you","for trying to quit!","Press Y to get","smacked out.",NULL,NULL,NULL,NULL);
3220 if (request-- == 0) return M_QuitMessage("Press Y to quit like a","big loser in life.","Press N to stay proud","and successful!",NULL,NULL,NULL,NULL);
3221 if (request-- == 0) return M_QuitMessage("If you press Y to","quit, I will summon","Satan all over your","hard drive!",NULL,NULL,NULL,NULL);
3222 if (request-- == 0) return M_QuitMessage("Um, Asmodeus dislikes","his children trying to","quit. Press Y to return","to your Tinkertoys.",NULL,NULL,NULL,NULL);
3223 if (request-- == 0) return M_QuitMessage("If you quit now, I'll","throw a blanket-party","for you next time!",NULL,NULL,NULL,NULL,NULL);
3224 break;
3225 case GAME_GOODVSBAD2:
3226 if (request-- == 0) return M_QuitMessage("Press Yes To Quit","...","Yes",NULL,NULL,NULL,NULL,NULL);
3227 if (request-- == 0) return M_QuitMessage("Do you really want to","Quit?","Play Good vs bad 3!",NULL,NULL,NULL,NULL,NULL);
3228 if (request-- == 0) return M_QuitMessage("All your quit are","belong to long duck","dong",NULL,NULL,NULL,NULL,NULL);
3229 if (request-- == 0) return M_QuitMessage("Press Y to quit","","But are you too legit?",NULL,NULL,NULL,NULL,NULL);
3230 if (request-- == 0) return M_QuitMessage("This game was made by","e@chip-web.com","It is by far the best","game ever made.",NULL,NULL,NULL,NULL);
3231 if (request-- == 0) return M_QuitMessage("Even I really dont","know of a game better","Press Y to quit","like rougue chedder",NULL,NULL,NULL,NULL);
3232 if (request-- == 0) return M_QuitMessage("After you stop playing","tell the guys who made","counterstrike to just","kill themselves now",NULL,NULL,NULL,NULL);
3233 if (request-- == 0) return M_QuitMessage("Press Y to exit to DOS","","SSH login as user Y","to exit to Linux",NULL,NULL,NULL,NULL);
3234 if (request-- == 0) return M_QuitMessage("Press Y like you","were waanderers","from Ys'",NULL,NULL,NULL,NULL,NULL);
3235 if (request-- == 0) return M_QuitMessage("This game was made in","Nippon like the SS","announcer's saying ipon",NULL,NULL,NULL,NULL,NULL);
3236 if (request-- == 0) return M_QuitMessage("you","want to quit?",NULL,NULL,NULL,NULL,NULL,NULL);
3237 if (request-- == 0) return M_QuitMessage("Please stop playing","this stupid game",NULL,NULL,NULL,NULL,NULL,NULL);
3238 break;
3239 case GAME_BATTLEMECH:
3240 if (request-- == 0) return M_QuitMessage("? WHY ?","Press Y to quit, N to keep fraggin'",NULL,NULL,NULL,NULL,NULL,NULL);
3241 if (request-- == 0) return M_QuitMessage("Leave now and your mech is scrap!","Press Y to quit, N to keep fraggin'",NULL,NULL,NULL,NULL,NULL,NULL);
3242 if (request-- == 0) return M_QuitMessage("Accept Defeat?","Press Y to quit, N to keep fraggin'",NULL,NULL,NULL,NULL,NULL,NULL);
3243 if (request-- == 0) return M_QuitMessage("Wait! There are more mechs to destroy!","Press Y to quit, N to keep fraggin'",NULL,NULL,NULL,NULL,NULL,NULL);
3244 if (request-- == 0) return M_QuitMessage("Where's your bloodlust?","Press Y to quit, N to keep fraggin'",NULL,NULL,NULL,NULL,NULL,NULL);
3245 if (request-- == 0) return M_QuitMessage("Your mech here is way more impressive","than your car out there...","Press Y to quit, N to keep fraggin'",NULL,NULL,NULL,NULL,NULL);
3246 if (request-- == 0) return M_QuitMessage("Quitting won't reduce your debt","Press Y to quit, N to keep fraggin'",NULL,NULL,NULL,NULL,NULL,NULL);
3247 break;
3248 case GAME_OPENQUARTZ:
3249 if (request-- == 0) return M_QuitMessage("There is nothing like free beer!","Press Y to quit, N to stay",NULL,NULL,NULL,NULL,NULL,NULL);
3250 if (request-- == 0) return M_QuitMessage("GNU is not Unix!","Press Y to quit, N to stay",NULL,NULL,NULL,NULL,NULL,NULL);
3251 if (request-- == 0) return M_QuitMessage("You prefer free beer over free speech?","Press Y to quit, N to stay",NULL,NULL,NULL,NULL,NULL,NULL);
3252 if (request-- == 0) return M_QuitMessage("Is OpenQuartz Propaganda?","Press Y to quit, N to stay",NULL,NULL,NULL,NULL,NULL,NULL);
3253 break;
3254 default:
3255 if (request-- == 0) return M_QuitMessage("Tired of fragging already?",NULL,NULL,NULL,NULL,NULL,NULL,NULL);
3256 if (request-- == 0) return M_QuitMessage("Quit now and forfeit your bodycount?",NULL,NULL,NULL,NULL,NULL,NULL,NULL);
3257 if (request-- == 0) return M_QuitMessage("Are you sure you want to quit?",NULL,NULL,NULL,NULL,NULL,NULL,NULL);
3258 if (request-- == 0) return M_QuitMessage("Off to do something constructive?",NULL,NULL,NULL,NULL,NULL,NULL,NULL);
3259 break;
3260 }
3261 return 0;
3262}
3263
3265{
3266 int n;
3267 if (m_state == m_quit)
3268 return;
3272 m_state = m_quit;
3273 m_entersound = true;
3274 // count how many there are
3275 for (n = 1;M_ChooseQuitMessage(n);n++);
3276 // choose one
3277 M_ChooseQuitMessage(rand() % n);
3278}
3279
3280
3281static void M_Quit_Key(cmd_state_t *cmd, int key, int ascii)
3282{
3283 switch (key)
3284 {
3285 case K_ESCAPE:
3286 case 'n':
3287 case 'N':
3288 if (wasInMenus)
3289 {
3291 m_entersound = true;
3292 }
3293 else
3294 {
3296 m_state = m_none;
3297 }
3298 break;
3299
3300 case 'Y':
3301 case 'y':
3303 break;
3304
3305 default:
3306 break;
3307 }
3308}
3309
3310static void M_Quit_Draw (void)
3311{
3312 int i, l, linelength, firstline, lastline, lines;
3313 for (i = 0, linelength = 0, firstline = 9999, lastline = -1;m_quit_message[i];i++)
3314 {
3315 if ((l = (int)strlen(m_quit_message[i])))
3316 {
3317 if (firstline > i)
3318 firstline = i;
3319 if (lastline < i)
3320 lastline = i;
3321 if (linelength < l)
3322 linelength = l;
3323 }
3324 }
3325 lines = (lastline - firstline) + 1;
3326 M_Background(linelength * 8 + 16, lines * 8 + 16);
3327 if (!m_missingdata) //since this is a fallback menu for missing data, it is very hard to read with the box
3328 M_DrawTextBox(0, 0, linelength, lines); //this is less obtrusive than hacking up the M_DrawTextBox function
3329 for (i = 0, l = firstline;i < lines;i++, l++)
3330 M_Print(8 + 4 * (linelength - strlen(m_quit_message[l])), 8 + 8 * i, m_quit_message[l]);
3331}
3332
3333//=============================================================================
3334/* LAN CONFIG MENU */
3335
3336static int lanConfig_cursor = -1;
3337static int lanConfig_cursor_table [] = {56, 76, 84, 120};
3338#define NUM_LANCONFIG_CMDS 4
3339
3341static char lanConfig_portname[6];
3342static char lanConfig_joinname[40];
3343
3345{
3348 m_entersound = true;
3349 if (lanConfig_cursor == -1)
3350 {
3351 if (JoiningGame)
3352 lanConfig_cursor = 1;
3353 }
3354 if (StartingGame)
3355 lanConfig_cursor = 1;
3356 lanConfig_port = 26000;
3357 dpsnprintf(lanConfig_portname, sizeof(lanConfig_portname), "%u", (unsigned int) lanConfig_port);
3358
3359 cl_connect_status[0] = '\0';
3360}
3361
3362
3363static void M_LanConfig_Draw (void)
3364{
3365 cachepic_t *p;
3366 int basex;
3367 const char *startJoin;
3368 const char *protocol;
3369 char vabuf[1024];
3370
3371 M_Background(320, 200);
3372
3373 M_DrawPic (16, 4, "gfx/qplaque");
3374 p = Draw_CachePic ("gfx/p_multi");
3375 basex = (320-Draw_GetPicWidth(p))/2;
3376 M_DrawPic (basex, 4, "gfx/p_multi");
3377
3378 if (StartingGame)
3379 startJoin = "New Game";
3380 else
3381 startJoin = "Join Game";
3382 protocol = "TCP/IP";
3383 M_Print(basex, 32, va(vabuf, sizeof(vabuf), "%s - %s", startJoin, protocol));
3384 basex += 8;
3385
3386 M_Print(basex, lanConfig_cursor_table[0], "Port");
3387 M_DrawTextBox (basex+8*8, lanConfig_cursor_table[0]-8, sizeof(lanConfig_portname), 1);
3389
3390 if (JoiningGame)
3391 {
3392 M_Print(basex, lanConfig_cursor_table[1], "Search for DarkPlaces games...");
3393 M_Print(basex, lanConfig_cursor_table[2], "Search for QuakeWorld games...");
3394 M_Print(basex, lanConfig_cursor_table[3]-16, "Join game at:");
3395 M_DrawTextBox (basex+8, lanConfig_cursor_table[3]-8, sizeof(lanConfig_joinname), 1);
3397 }
3398 else
3399 {
3400 M_DrawTextBox (basex, lanConfig_cursor_table[1]-8, 2, 1);
3401 M_Print(basex+8, lanConfig_cursor_table[1], "OK");
3402 }
3403
3405
3406 if (lanConfig_cursor == 0)
3408
3409 if (lanConfig_cursor == 3)
3411
3412 if (*cl_connect_status)
3413 M_Print(basex, 168, cl_connect_status);
3414}
3415
3416
3417static void M_LanConfig_Key(cmd_state_t *cmd, int key, int ascii)
3418{
3419 int l;
3420 char vabuf[1024];
3421
3422 switch (key)
3423 {
3424 case K_ESCAPE:
3426 break;
3427
3428 case K_UPARROW:
3429 S_LocalSound ("sound/misc/menu1.wav");
3431 if (lanConfig_cursor < 0)
3433 // when in start game menu, skip the unused search qw servers item
3434 if (StartingGame && lanConfig_cursor == 2)
3435 lanConfig_cursor = 1;
3436 break;
3437
3438 case K_DOWNARROW:
3439 S_LocalSound ("sound/misc/menu1.wav");
3442 lanConfig_cursor = 0;
3443 // when in start game menu, skip the unused search qw servers item
3444 if (StartingGame && lanConfig_cursor == 1)
3445 lanConfig_cursor = 2;
3446 break;
3447
3448 case K_ENTER:
3449 if (lanConfig_cursor == 0)
3450 break;
3451
3452 m_entersound = true;
3453
3454 Cbuf_AddText(cmd, "stopdemo\n");
3455
3457
3458 if (lanConfig_cursor == 1 || lanConfig_cursor == 2)
3459 {
3460 if (StartingGame)
3461 {
3463 break;
3464 }
3466 break;
3467 }
3468
3469 if (lanConfig_cursor == 3)
3470 Cbuf_AddText(cmd, va(vabuf, sizeof(vabuf), "connect \"%s\"\n", lanConfig_joinname) );
3471 break;
3472
3473 case K_BACKSPACE:
3474 if (lanConfig_cursor == 0)
3475 {
3478 }
3479
3480 if (lanConfig_cursor == 3)
3481 {
3484 }
3485 break;
3486
3487 default:
3488 if (ascii < 32)
3489 break;
3490
3491 if (lanConfig_cursor == 3)
3492 {
3494 if (l < (int)sizeof(lanConfig_joinname) - 1)
3495 {
3496 lanConfig_joinname[l+1] = 0;
3497 lanConfig_joinname[l] = ascii;
3498 }
3499 }
3500
3501 if (ascii < '0' || ascii > '9')
3502 break;
3503 if (lanConfig_cursor == 0)
3504 {
3506 if (l < (int)sizeof(lanConfig_portname) - 1)
3507 {
3508 lanConfig_portname[l+1] = 0;
3509 lanConfig_portname[l] = ascii;
3510 }
3511 }
3512 }
3513
3514 if (StartingGame && lanConfig_cursor == 3)
3515 {
3516 if (key == K_UPARROW)
3517 lanConfig_cursor = 1;
3518 else
3519 lanConfig_cursor = 0;
3520 }
3521
3522 l = atoi(lanConfig_portname);
3523 if (l <= 65535)
3524 lanConfig_port = l;
3525 dpsnprintf(lanConfig_portname, sizeof(lanConfig_portname), "%u", (unsigned int) lanConfig_port);
3526}
3527
3528//=============================================================================
3529/* GAME OPTIONS MENU */
3530
3531typedef struct level_s
3532{
3533 const char *name;
3534 const char *description;
3535} level_t;
3536
3537typedef struct episode_s
3538{
3539 const char *description;
3542} episode_t;
3543
3544typedef struct gamelevels_s
3545{
3546 const char *gamename;
3550}
3552
3554{
3555 {"start", "Entrance"}, // 0
3556
3557 {"e1m1", "Slipgate Complex"}, // 1
3558 {"e1m2", "Castle of the Damned"},
3559 {"e1m3", "The Necropolis"},
3560 {"e1m4", "The Grisly Grotto"},
3561 {"e1m5", "Gloom Keep"},
3562 {"e1m6", "The Door To Chthon"},
3563 {"e1m7", "The House of Chthon"},
3564 {"e1m8", "Ziggurat Vertigo"},
3565
3566 {"e2m1", "The Installation"}, // 9
3567 {"e2m2", "Ogre Citadel"},
3568 {"e2m3", "Crypt of Decay"},
3569 {"e2m4", "The Ebon Fortress"},
3570 {"e2m5", "The Wizard's Manse"},
3571 {"e2m6", "The Dismal Oubliette"},
3572 {"e2m7", "Underearth"},
3573
3574 {"e3m1", "Termination Central"}, // 16
3575 {"e3m2", "The Vaults of Zin"},
3576 {"e3m3", "The Tomb of Terror"},
3577 {"e3m4", "Satan's Dark Delight"},
3578 {"e3m5", "Wind Tunnels"},
3579 {"e3m6", "Chambers of Torment"},
3580 {"e3m7", "The Haunted Halls"},
3581
3582 {"e4m1", "The Sewage System"}, // 23
3583 {"e4m2", "The Tower of Despair"},
3584 {"e4m3", "The Elder God Shrine"},
3585 {"e4m4", "The Palace of Hate"},
3586 {"e4m5", "Hell's Atrium"},
3587 {"e4m6", "The Pain Maze"},
3588 {"e4m7", "Azure Agony"},
3589 {"e4m8", "The Nameless City"},
3590
3591 {"end", "Shub-Niggurath's Pit"}, // 31
3592
3593 {"dm1", "Place of Two Deaths"}, // 32
3594 {"dm2", "Claustrophobopolis"},
3595 {"dm3", "The Abandoned Base"},
3596 {"dm4", "The Bad Place"},
3597 {"dm5", "The Cistern"},
3598 {"dm6", "The Dark Zone"}
3599};
3600
3602{
3603 {"Welcome to Quake", 0, 1},
3604 {"Doomed Dimension", 1, 8},
3605 {"Realm of Black Magic", 9, 7},
3606 {"Netherworld", 16, 7},
3607 {"The Elder World", 23, 8},
3608 {"Final Level", 31, 1},
3609 {"Deathmatch Arena", 32, 6}
3610};
3611
3612 //MED 01/06/97 added hipnotic levels
3614{
3615 {"start", "Command HQ"}, // 0
3616
3617 {"hip1m1", "The Pumping Station"}, // 1
3618 {"hip1m2", "Storage Facility"},
3619 {"hip1m3", "The Lost Mine"},
3620 {"hip1m4", "Research Facility"},
3621 {"hip1m5", "Military Complex"},
3622
3623 {"hip2m1", "Ancient Realms"}, // 6
3624 {"hip2m2", "The Black Cathedral"},
3625 {"hip2m3", "The Catacombs"},
3626 {"hip2m4", "The Crypt"},
3627 {"hip2m5", "Mortum's Keep"},
3628 {"hip2m6", "The Gremlin's Domain"},
3629
3630 {"hip3m1", "Tur Torment"}, // 12
3631 {"hip3m2", "Pandemonium"},
3632 {"hip3m3", "Limbo"},
3633 {"hip3m4", "The Gauntlet"},
3634
3635 {"hipend", "Armagon's Lair"}, // 16
3636
3637 {"hipdm1", "The Edge of Oblivion"} // 17
3638};
3639
3640//MED 01/06/97 added hipnotic episodes
3642{
3643 {"Scourge of Armagon", 0, 1},
3644 {"Fortress of the Dead", 1, 5},
3645 {"Dominion of Darkness", 6, 6},
3646 {"The Rift", 12, 4},
3647 {"Final Level", 16, 1},
3648 {"Deathmatch Arena", 17, 1}
3649};
3650
3651//PGM 01/07/97 added rogue levels
3652//PGM 03/02/97 added dmatch level
3654{
3655 {"start", "Split Decision"},
3656 {"r1m1", "Deviant's Domain"},
3657 {"r1m2", "Dread Portal"},
3658 {"r1m3", "Judgement Call"},
3659 {"r1m4", "Cave of Death"},
3660 {"r1m5", "Towers of Wrath"},
3661 {"r1m6", "Temple of Pain"},
3662 {"r1m7", "Tomb of the Overlord"},
3663 {"r2m1", "Tempus Fugit"},
3664 {"r2m2", "Elemental Fury I"},
3665 {"r2m3", "Elemental Fury II"},
3666 {"r2m4", "Curse of Osiris"},
3667 {"r2m5", "Wizard's Keep"},
3668 {"r2m6", "Blood Sacrifice"},
3669 {"r2m7", "Last Bastion"},
3670 {"r2m8", "Source of Evil"},
3671 {"ctf1", "Division of Change"}
3672};
3673
3674//PGM 01/07/97 added rogue episodes
3675//PGM 03/02/97 added dmatch episode
3677{
3678 {"Introduction", 0, 1},
3679 {"Hell's Fortress", 1, 7},
3680 {"Corridors of Time", 8, 8},
3681 {"Deathmatch Arena", 16, 1}
3682};
3683
3685{
3686 {"nehstart", "Welcome to Nehahra"},
3687 {"neh1m1", "Forge City1: Slipgates"},
3688 {"neh1m2", "Forge City2: Boiler"},
3689 {"neh1m3", "Forge City3: Escape"},
3690 {"neh1m4", "Grind Core"},
3691 {"neh1m5", "Industrial Silence"},
3692 {"neh1m6", "Locked-Up Anger"},
3693 {"neh1m7", "Wanderer of the Wastes"},
3694 {"neh1m8", "Artemis System Net"},
3695 {"neh1m9", "To the Death"},
3696 {"neh2m1", "The Gates of Ghoro"},
3697 {"neh2m2", "Sacred Trinity"},
3698 {"neh2m3", "Realm of the Ancients"},
3699 {"neh2m4", "Temple of the Ancients"},
3700 {"neh2m5", "Dreams Made Flesh"},
3701 {"neh2m6", "Your Last Cup of Sorrow"},
3702 {"nehsec", "Ogre's Bane"},
3703 {"nehahra", "Nehahra's Den"},
3704 {"nehend", "Quintessence"}
3705};
3706
3708{
3709 {"Welcome to Nehahra", 0, 1},
3710 {"The Fall of Forge", 1, 9},
3711 {"The Outlands", 10, 7},
3712 {"Dimension of the Lost", 17, 2}
3713};
3714
3715// Map list for Transfusion
3717{
3718 {"e1m1", "Cradle to Grave"},
3719 {"e1m2", "Wrong Side of the Tracks"},
3720 {"e1m3", "Phantom Express"},
3721 {"e1m4", "Dark Carnival"},
3722 {"e1m5", "Hallowed Grounds"},
3723 {"e1m6", "The Great Temple"},
3724 {"e1m7", "Altar of Stone"},
3725 {"e1m8", "House of Horrors"},
3726
3727 {"e2m1", "Shipwrecked"},
3728 {"e2m2", "The Lumber Mill"},
3729 {"e2m3", "Rest for the Wicked"},
3730 {"e2m4", "The Overlooked Hotel"},
3731 {"e2m5", "The Haunting"},
3732 {"e2m6", "The Cold Rush"},
3733 {"e2m7", "Bowels of the Earth"},
3734 {"e2m8", "The Lair of Shial"},
3735 {"e2m9", "Thin Ice"},
3736
3737 {"e3m1", "Ghost Town"},
3738 {"e3m2", "The Siege"},
3739 {"e3m3", "Raw Sewage"},
3740 {"e3m4", "The Sick Ward"},
3741 {"e3m5", "Spare Parts"},
3742 {"e3m6", "Monster Bait"},
3743 {"e3m7", "The Pit of Cerberus"},
3744 {"e3m8", "Catacombs"},
3745
3746 {"e4m1", "Butchery Loves Company"},
3747 {"e4m2", "Breeding Grounds"},
3748 {"e4m3", "Charnel House"},
3749 {"e4m4", "Crystal Lake"},
3750 {"e4m5", "Fire and Brimstone"},
3751 {"e4m6", "The Ganglion Depths"},
3752 {"e4m7", "In the Flesh"},
3753 {"e4m8", "The Hall of the Epiphany"},
3754 {"e4m9", "Mall of the Dead"},
3755
3756 {"bb1", "The Stronghold"},
3757 {"bb2", "Winter Wonderland"},
3758 {"bb3", "Bodies"},
3759 {"bb4", "The Tower"},
3760 {"bb5", "Click!"},
3761 {"bb6", "Twin Fortress"},
3762 {"bb7", "Midgard"},
3763 {"bb8", "Fun With Heads"},
3764 {"dm1", "Monolith Building 11"},
3765 {"dm2", "Power!"},
3766 {"dm3", "Area 15"},
3767
3768 {"e6m1", "Welcome to Your Life"},
3769 {"e6m2", "They Are Here"},
3770 {"e6m3", "Public Storage"},
3771 {"e6m4", "Aqueducts"},
3772 {"e6m5", "The Ruined Temple"},
3773 {"e6m6", "Forbidden Rituals"},
3774 {"e6m7", "The Dungeon"},
3775 {"e6m8", "Beauty and the Beast"},
3776 {"e6m9", "Forgotten Catacombs"},
3777
3778 {"cp01", "Boat Docks"},
3779 {"cp02", "Old Opera House"},
3780 {"cp03", "Gothic Library"},
3781 {"cp04", "Lost Monastery"},
3782 {"cp05", "Steamboat"},
3783 {"cp06", "Graveyard"},
3784 {"cp07", "Mountain Pass"},
3785 {"cp08", "Abysmal Mine"},
3786 {"cp09", "Castle"},
3787 {"cps1", "Boggy Creek"},
3788
3789 {"cpbb01", "Crypt of Despair"},
3790 {"cpbb02", "Pits of Blood"},
3791 {"cpbb03", "Unholy Cathedral"},
3792 {"cpbb04", "Deadly Inspirations"},
3793
3794 {"b2a15", "Area 15 (B2)"},
3795 {"b2bodies", "BB_Bodies (B2)"},
3796 {"b2cabana", "BB_Cabana"},
3797 {"b2power", "BB_Power"},
3798 {"barena", "Blood Arena"},
3799 {"bkeep", "Blood Keep"},
3800 {"bstar", "Brown Star"},
3801 {"crypt", "The Crypt"},
3802
3803 {"bb3_2k1", "Bodies Infusion"},
3804 {"captasao", "Captasao"},
3805 {"curandero", "Curandero"},
3806 {"dcamp", "DeathCamp"},
3807 {"highnoon", "HighNoon"},
3808 {"qbb1", "The Confluence"},
3809 {"qbb2", "KathartiK"},
3810 {"qbb3", "Caleb's Woodland Retreat"},
3811 {"zoo", "Zoo"},
3812
3813 {"dranzbb6", "Black Coffee"},
3814 {"fragm", "Frag'M"},
3815 {"maim", "Maim"},
3816 {"qe1m7", "The House of Chthon"},
3817 {"qdm1", "Place of Two Deaths"},
3818 {"qdm4", "The Bad Place"},
3819 {"qdm5", "The Cistern"},
3820 {"qmorbias", "DM-Morbias"},
3821 {"simple", "Dead Simple"}
3822};
3823
3825{
3826 {"The Way of All Flesh", 0, 8},
3827 {"Even Death May Die", 8, 9},
3828 {"Farewell to Arms", 17, 8},
3829 {"Dead Reckoning", 25, 9},
3830 {"BloodBath", 34, 11},
3831 {"Post Mortem", 45, 9},
3832 {"Cryptic Passage", 54, 10},
3833 {"Cryptic BloodBath", 64, 4},
3834 {"Blood 2", 68, 8},
3835 {"Transfusion", 76, 9},
3836 {"Conversions", 85, 9}
3837};
3838
3840{
3841 {"rts", "Many Paths"}, // 0
3842 {"chess", "Chess, Scott Hess"}, // 1
3843 {"dot", "Big Wall"},
3844 {"city2", "The Big City"},
3845 {"bwall", "0 G like Psychic TV"},
3846 {"snow", "Wireframed"},
3847 {"telep", "Infinite Falling"},
3848 {"faces", "Facing Bases"},
3849 {"island", "Adventure Islands"},
3850};
3851
3853{
3854 {"Levels? Bevels!", 0, 8},
3855};
3856
3858{
3859 {"start", "Parking Level"},
3860 {"dm1", "Hot Dump"}, // 1
3861 {"dm2", "The Pits"},
3862 {"dm3", "Dimber Died"},
3863 {"dm4", "Fire in the Hole"},
3864 {"dm5", "Clubhouses"},
3865 {"dm6", "Army go Underground"},
3866};
3867
3869{
3870 {"Time for Battle", 0, 7},
3871};
3872
3874{
3875 {"start", "Welcome to Openquartz"},
3876
3877 {"void1", "The center of nowhere"}, // 1
3878 {"void2", "The place with no name"},
3879 {"void3", "The lost supply base"},
3880 {"void4", "Past the outer limits"},
3881 {"void5", "Into the nonexistance"},
3882 {"void6", "Void walk"},
3883
3884 {"vtest", "Warp Central"},
3885 {"box", "The deathmatch box"},
3886 {"bunkers", "Void command"},
3887 {"house", "House of chaos"},
3888 {"office", "Overnight office kill"},
3889 {"am1", "The nameless chambers"},
3890};
3891
3893{
3894 {"Single Player", 0, 1},
3895 {"Void Deathmatch", 1, 6},
3896 {"Contrib", 7, 6},
3897};
3898
3900{
3901 {"atac3", "River Crossing"},
3902 {"atac4", "Canyon Chaos"},
3903 {"atac7", "Desert Stormer"},
3904};
3905
3907{
3908 {"ATAC Campaign", 0, 3},
3909};
3910
3912{
3913 {"curig2", "Capel Curig"}, // 0
3914
3915 {"tdastart", "Gateway"}, // 1
3916};
3917
3919{
3920 {"Prydon Gate", 0, 1},
3921 {"The Dark Age", 1, 1}
3922};
3923
3926static gamelevels_t hipnoticgame = {"Scourge of Armagon", hipnoticlevels, hipnoticepisodes, 6};
3927static gamelevels_t roguegame = {"Dissolution of Eternity", roguelevels, rogueepisodes, 4};
3935
3943
3958
3960
3961static int startepisode;
3962static int startlevel;
3963static int maxplayers;
3966
3968{
3969 int i;
3972 m_entersound = true;
3973 if (maxplayers == 0)
3975 if (maxplayers < 2)
3977 // pick game level list based on gamemode (use GAME_NORMAL if no matches)
3979 for (i = 0;i < (int)(sizeof(gamelist)/sizeof(gamelist[0]));i++)
3980 if (gamelist[i].gameid == gamemode)
3982}
3983
3984
3985static int gameoptions_cursor_table[] = {40, 56, 64, 72, 80, 88, 96, 104, 112, 140, 160, 168};
3986#define NUM_GAMEOPTIONS 12
3988
3990{
3991 cachepic_t *p;
3992 int x;
3993 char vabuf[1024];
3994
3995 M_Background(320, 200);
3996
3997 M_DrawPic (16, 4, "gfx/qplaque");
3998 p = Draw_CachePic ("gfx/p_multi");
3999 M_DrawPic ( (320-Draw_GetPicWidth(p))/2, 4, "gfx/p_multi");
4000
4001 M_DrawTextBox (152, 32, 10, 1);
4002 M_Print(160, 40, "begin game");
4003
4004 M_Print(0, 56, " Max players");
4005 M_Print(160, 56, va(vabuf, sizeof(vabuf), "%i", maxplayers) );
4006
4008 {
4009 M_Print(0, 64, " Game Type");
4011 {
4012 if (!coop.integer && !deathmatch.integer)
4014 if (deathmatch.integer == 0)
4015 M_Print(160, 64, "Cooperative");
4016 else if (deathmatch.integer == 2)
4017 M_Print(160, 64, "Capture the Flag");
4018 else
4019 M_Print(160, 64, "Blood Bath");
4020 }
4021 else if (gamemode == GAME_BATTLEMECH)
4022 {
4023 if (!deathmatch.integer)
4025 if (deathmatch.integer == 2)
4026 M_Print(160, 64, "Rambo Match");
4027 else
4028 M_Print(160, 64, "Deathmatch");
4029 }
4030 else
4031 {
4032 if (!coop.integer && !deathmatch.integer)
4034 if (coop.integer)
4035 M_Print(160, 64, "Cooperative");
4036 else
4037 M_Print(160, 64, "Deathmatch");
4038 }
4039
4040 M_Print(0, 72, " Teamplay");
4041 if (gamemode == GAME_ROGUE)
4042 {
4043 const char *msg;
4044
4045 switch((int)teamplay.integer)
4046 {
4047 case 1: msg = "No Friendly Fire"; break;
4048 case 2: msg = "Friendly Fire"; break;
4049 case 3: msg = "Tag"; break;
4050 case 4: msg = "Capture the Flag"; break;
4051 case 5: msg = "One Flag CTF"; break;
4052 case 6: msg = "Three Team CTF"; break;
4053 default: msg = "Off"; break;
4054 }
4055 M_Print(160, 72, msg);
4056 }
4057 else
4058 {
4059 const char *msg;
4060
4061 switch (teamplay.integer)
4062 {
4063 case 0: msg = "Off"; break;
4064 case 2: msg = "Friendly Fire"; break;
4065 default: msg = "No Friendly Fire"; break;
4066 }
4067 M_Print(160, 72, msg);
4068 }
4069 M_Print(0, 80, " Skill");
4071 {
4072 if (skill.integer == 1)
4073 M_Print(160, 80, "Still Kicking");
4074 else if (skill.integer == 2)
4075 M_Print(160, 80, "Pink On The Inside");
4076 else if (skill.integer == 3)
4077 M_Print(160, 80, "Lightly Broiled");
4078 else if (skill.integer == 4)
4079 M_Print(160, 80, "Well Done");
4080 else
4081 M_Print(160, 80, "Extra Crispy");
4082 }
4083 else
4084 {
4085 if (skill.integer == 0)
4086 M_Print(160, 80, "Easy difficulty");
4087 else if (skill.integer == 1)
4088 M_Print(160, 80, "Normal difficulty");
4089 else if (skill.integer == 2)
4090 M_Print(160, 80, "Hard difficulty");
4091 else
4092 M_Print(160, 80, "Nightmare difficulty");
4093 }
4094 M_Print(0, 88, " Frag Limit");
4095 if (fraglimit.integer == 0)
4096 M_Print(160, 88, "none");
4097 else
4098 M_Print(160, 88, va(vabuf, sizeof(vabuf), "%i frags", fraglimit.integer));
4099
4100 M_Print(0, 96, " Time Limit");
4101 if (timelimit.integer == 0)
4102 M_Print(160, 96, "none");
4103 else
4104 M_Print(160, 96, va(vabuf, sizeof(vabuf), "%i minutes", timelimit.integer));
4105 }
4106
4107 M_Print(0, 104, " Public server");
4108 M_Print(160, 104, (sv_public.integer == 0) ? "no" : "yes");
4109
4110 M_Print(0, 112, " Server maxrate");
4111 M_Print(160, 112, va(vabuf, sizeof(vabuf), "%i", sv_maxrate.integer));
4112
4113 M_Print(0, 128, " Server name");
4114 M_DrawTextBox (0, 132, 38, 1);
4115 M_Print(8, 140, hostname.string);
4116
4118 {
4119 M_Print(0, 160, " Episode");
4121 }
4122
4123 M_Print(0, 168, " Level");
4126
4127// line cursor
4128 if (gameoptions_cursor == 9)
4130 else
4132
4134 {
4136 {
4137 x = (320-26*8)/2;
4138 M_DrawTextBox (x, 138, 24, 4);
4139 x += 8;
4140 M_Print(x, 146, " More than 255 players??");
4141 M_Print(x, 154, " First, question your ");
4142 M_Print(x, 162, " sanity, then email ");
4143 M_Print(x, 170, "darkplacesengine@gmail.com");
4144 }
4145 else
4146 m_serverInfoMessage = false;
4147 }
4148}
4149
4150
4151static void M_NetStart_Change (int dir)
4152{
4153 int count;
4154
4155 switch (gameoptions_cursor)
4156 {
4157 case 1:
4158 maxplayers += dir;
4160 {
4162 m_serverInfoMessage = true;
4164 }
4165 if (maxplayers < 2)
4166 maxplayers = 2;
4167 break;
4168
4169 case 2:
4171 break;
4173 {
4174 switch (deathmatch.integer)
4175 {
4176 // From Cooperative to BloodBath
4177 case 0:
4180 break;
4181
4182 // From BloodBath to CTF
4183 case 1:
4186 break;
4187
4188 // From CTF to Cooperative
4189 //case 2:
4190 default:
4193 }
4194 }
4195 else if (gamemode == GAME_BATTLEMECH)
4196 {
4197 if (deathmatch.integer == 2) // changing from Rambo to Deathmatch
4199 else // changing from Deathmatch to Rambo
4201 }
4202 else
4203 {
4204 if (deathmatch.integer) // changing from deathmatch to coop
4205 {
4208 }
4209 else // changing from coop to deathmatch
4210 {
4213 }
4214 }
4215 break;
4216
4217 case 3:
4219 break;
4220 if (gamemode == GAME_ROGUE)
4221 count = 6;
4222 else
4223 count = 2;
4224
4226 if (teamplay.integer > count)
4228 else if (teamplay.integer < 0)
4230 break;
4231
4232 case 4:
4234 break;
4237 {
4238 if (skill.integer > 5)
4240 if (skill.integer < 1)
4242 }
4243 else
4244 {
4245 if (skill.integer > 3)
4247 if (skill.integer < 0)
4249 }
4250 break;
4251
4252 case 5:
4254 break;
4256 if (fraglimit.integer > 100)
4258 if (fraglimit.integer < 0)
4260 break;
4261
4262 case 6:
4264 break;
4266 if (timelimit.value > 60)
4268 if (timelimit.value < 0)
4270 break;
4271
4272 case 7:
4274 break;
4275
4276 case 8:
4280 break;
4281
4282 case 9:
4283 break;
4284
4285 case 10:
4287 break;
4288 startepisode += dir;
4289
4290 if (startepisode < 0)
4292
4294 startepisode = 0;
4295
4296 startlevel = 0;
4297 break;
4298
4299 case 11:
4300 startlevel += dir;
4301
4302 if (startlevel < 0)
4304
4306 startlevel = 0;
4307 break;
4308 }
4309}
4310
4311static void M_GameOptions_Key(cmd_state_t *cmd, int key, int ascii)
4312{
4313 int l;
4314 char hostnamebuf[128];
4315 char vabuf[1024];
4316
4317 switch (key)
4318 {
4319 case K_ESCAPE:
4321 break;
4322
4323 case K_UPARROW:
4324 S_LocalSound ("sound/misc/menu1.wav");
4326 if (gameoptions_cursor < 0)
4328 break;
4329
4330 case K_DOWNARROW:
4331 S_LocalSound ("sound/misc/menu1.wav");
4335 break;
4336
4337 case K_LEFTARROW:
4338 if (gameoptions_cursor == 0)
4339 break;
4340 S_LocalSound ("sound/misc/menu3.wav");
4341 M_NetStart_Change (-1);
4342 break;
4343
4344 case K_RIGHTARROW:
4345 if (gameoptions_cursor == 0)
4346 break;
4347 S_LocalSound ("sound/misc/menu3.wav");
4349 break;
4350
4351 case K_ENTER:
4352 S_LocalSound ("sound/misc/menu2.wav");
4353 if (gameoptions_cursor == 0)
4354 {
4355 if (sv.active)
4356 Cbuf_AddText(cmd, "disconnect\n");
4357 Cbuf_AddText(cmd, va(vabuf, sizeof(vabuf), "maxplayers %u\n", maxplayers) );
4358
4360 return;
4361 }
4362
4364 break;
4365
4366 case K_BACKSPACE:
4367 if (gameoptions_cursor == 9)
4368 {
4369 l = (int)strlen(hostname.string);
4370 if (l)
4371 {
4372 l = min(l - 1, 37);
4373 memcpy(hostnamebuf, hostname.string, l);
4374 hostnamebuf[l] = 0;
4375 Cvar_SetQuick(&hostname, hostnamebuf);
4376 }
4377 }
4378 break;
4379
4380 default:
4381 if (ascii < 32)
4382 break;
4383 if (gameoptions_cursor == 9)
4384 {
4385 l = (int)strlen(hostname.string);
4386 if (l < 37)
4387 {
4388 memcpy(hostnamebuf, hostname.string, l);
4389 hostnamebuf[l] = ascii;
4390 hostnamebuf[l+1] = 0;
4391 Cvar_SetQuick(&hostname, hostnamebuf);
4392 }
4393 }
4394 }
4395}
4396
4397//=============================================================================
4398/* SLIST MENU */
4399
4400static unsigned slist_cursor;
4401static unsigned slist_visible;
4402
4404{
4406 m_state = m_slist;
4407 m_entersound = true;
4408 slist_cursor = 0;
4409 cl_connect_status[0] = '\0';
4410 if (lanConfig_cursor == 2)
4411 Net_SlistQW_f(cmd);
4412 else
4413 Net_Slist_f(cmd);
4414}
4415
4416
4417static void M_ServerList_Draw (void)
4418{
4419 unsigned n, y, start, end, statnumplayers, statmaxplayers;
4420 cachepic_t *p;
4421 const char *s;
4422 char vabuf[1024];
4423
4424 // use as much vertical space as available
4427 else
4429 // scroll the list as the cursor moves
4430 ServerList_GetPlayerStatistics(&statnumplayers, &statmaxplayers);
4431 s = va(vabuf, sizeof(vabuf), "%u/%u masters %u/%u servers %u/%u players", masterreplycount, masterquerycount, serverreplycount, serverquerycount, statnumplayers, statmaxplayers);
4432 M_PrintRed((640 - strlen(s) * 8) / 2, 32, s);
4433 if (*cl_connect_status)
4435 y = 48;
4436 slist_visible = (menu_height - 16 - y) / 8 / 2;
4437 start = min(slist_cursor - min(slist_cursor, slist_visible >> 1), serverlist_viewcount - min(serverlist_viewcount, slist_visible));
4438 end = min(start + slist_visible, serverlist_viewcount);
4439
4440 p = Draw_CachePic ("gfx/p_multi");
4441 M_DrawPic((640 - Draw_GetPicWidth(p)) / 2, 4, "gfx/p_multi");
4442 if (end > start)
4443 {
4444 for (n = start;n < end;n++)
4445 {
4446 serverlist_entry_t *entry = ServerList_GetViewEntry(n);
4447 DrawQ_Fill(menu_x, menu_y + y, 640, 16, n == slist_cursor ? (0.5 + 0.2 * sin(host.realtime * M_PI)) : 0, 0, 0, 0.5, 0);
4448 M_PrintColored(0, y, entry->line1);y += 8;
4449 M_PrintColored(0, y, entry->line2);y += 8;
4450 }
4451 }
4452 else if (host.realtime - masterquerytime > 10)
4453 {
4454 if (masterquerycount)
4455 M_Print(0, y, "No servers found");
4456 else
4457 M_Print(0, y, "No master servers found (network problem?)");
4458 }
4459 else
4460 {
4461 if (serverquerycount)
4462 M_Print(0, y, "Querying servers");
4463 else
4464 M_Print(0, y, "Querying master servers");
4465 }
4466}
4467
4468
4469static void M_ServerList_Key(cmd_state_t *cmd, int k, int ascii)
4470{
4471 char vabuf[1024];
4472 switch (k)
4473 {
4474 case K_ESCAPE:
4476 break;
4477
4478 case K_SPACE:
4479 if (lanConfig_cursor == 2)
4480 Net_SlistQW_f(cmd);
4481 else
4482 Net_Slist_f(cmd);
4483 break;
4484
4485 case K_PGUP:
4487 case K_UPARROW:
4488 case K_LEFTARROW:
4489 S_LocalSound ("sound/misc/menu1.wav");
4490 slist_cursor--;
4491 if (slist_cursor >= serverlist_viewcount)
4492 slist_cursor = serverlist_viewcount - 1;
4493 break;
4494
4495 case K_PGDN:
4497 case K_DOWNARROW:
4498 case K_RIGHTARROW:
4499 S_LocalSound ("sound/misc/menu1.wav");
4500 slist_cursor++;
4501 if (slist_cursor >= serverlist_viewcount)
4502 slist_cursor = 0;
4503 break;
4504
4505 case K_HOME:
4506 S_LocalSound ("sound/misc/menu1.wav");
4507 slist_cursor = 0;
4508 break;
4509
4510 case K_END:
4511 S_LocalSound ("sound/misc/menu1.wav");
4512 slist_cursor = serverlist_viewcount - 1;
4513 break;
4514
4515 case K_ENTER:
4516 S_LocalSound ("sound/misc/menu2.wav");
4517 if (serverlist_viewcount)
4518 Cbuf_AddText(cmd, va(vabuf, sizeof(vabuf), "connect \"%s\"\n", ServerList_GetViewEntry(slist_cursor)->info.cname));
4519 break;
4520
4521 default:
4522 break;
4523 }
4524
4525}
4526
4527//=============================================================================
4528/* MODLIST MENU */
4529// same limit of mod dirs as in fs.c (allowing that one is used by gamedirname1)
4530#define MODLIST_MAXDIRS MAX_GAMEDIRS - 1
4531static int modlist_numenabled; //number of enabled (or in process to be..) mods
4532
4533typedef struct modlist_entry_s
4534{
4535 qbool loaded; // used to determine whether this entry is loaded and running
4536
4537 // name of the modification, this is displayed on the menu entry
4538 char name[128];
4539 // directory where we will find it
4542
4544//static int modlist_viewcount;
4545
4546static int modlist_count = 0;
4548
4549static void ModList_RebuildList(void)
4550{
4551 int i,j;
4552 stringlist_t list;
4553 const char *description;
4554 int desc_len;
4555
4556 stringlistinit(&list);
4557 listdirectory(&list, fs_basedir, "");
4558 stringlistsort(&list, true);
4559 modlist_count = 0;
4561 for (i = 0;i < list.numstrings && modlist_count < MODLIST_TOTALSIZE;i++)
4562 {
4563 // reject any dirs that are part of the base game
4564 if (gamedirname1 && !strcasecmp(gamedirname1, list.strings[i])) continue;
4565 //if (gamedirname2 && !strcasecmp(gamedirname2, list.strings[i])) continue;
4566
4567 // check if we can get a description of the gamedir (from modinfo.txt),
4568 // or if the directory is valid but has no description (fs_checkgamedir_missing)
4569 // otherwise this isn't a valid gamedir
4570 description = FS_CheckGameDir(list.strings[i]);
4571 if (description == NULL || description == fs_checkgamedir_missing) continue;
4572
4573 desc_len = min(strlen(description), sizeof(modlist[modlist_count].name));
4574 for (j = 0; j < desc_len; ++j)
4575 if (!ISWHITESPACE(description[j]))
4576 {
4578 break;
4579 }
4580
4582
4583 // check if this mod is currently loaded
4584 modlist[modlist_count].loaded = false;
4585 for (j = 0; j < fs_numgamedirs; j++)
4586 if (!strcasecmp(fs_gamedirs[j], modlist[modlist_count].dir))
4587 {
4590 break;
4591 }
4592
4593 modlist_count ++;
4594 }
4596}
4597
4598static void ModList_Enable (void)
4599{
4600 int i;
4601 int numgamedirs;
4602 const char *gamedirs[MODLIST_MAXDIRS];
4603
4604 // this part is basically the same as the FS_GameDir_f function
4605 if ((cls.state == ca_connected && !cls.demoplayback) || sv.active)
4606 {
4607 // actually, changing during game would work fine, but would be stupid
4608 Con_Printf("Can not change gamedir while client is connected or server is running!\n");
4609 return;
4610 }
4611
4612 // copy our mod list into an array for FS_ChangeGameDirs
4613 for (i = 0, numgamedirs = 0; i < modlist_count && numgamedirs < MODLIST_MAXDIRS; i++)
4614 if (modlist[i].loaded)
4615 gamedirs[numgamedirs++] = modlist[i].dir;
4616 // allow disabling all active mods using the menu
4617 if (numgamedirs == 0)
4618 {
4619 numgamedirs = 1;
4620 gamedirs[0] = gamedirname1;
4621 }
4622
4623 FS_ChangeGameDirs(numgamedirs, gamedirs, true);
4624}
4625
4627{
4630 m_entersound = true;
4631 modlist_cursor = 0;
4632 cl_connect_status[0] = '\0';
4634}
4635
4637{
4638 S_LocalSound ("sound/misc/menu3.wav");
4639
4640 // stop adding mods, we reach the limit
4641 if (!modlist[modlist_cursor].loaded && (modlist_numenabled == MODLIST_MAXDIRS)) return;
4642
4645}
4646
4647static void M_ModList_Draw (void)
4648{
4649 int n, y, visible, start, end;
4650 cachepic_t *p;
4651 const char *s_available = "Available Mods";
4652 const char *s_enabled = "Enabled Mods";
4653
4654 // use as much vertical space as available
4657 else
4659
4660 M_PrintRed(48 + 32, 32, s_available);
4661 M_PrintRed(432, 32, s_enabled);
4662 // Draw a list box with all enabled mods
4663 DrawQ_Pic(menu_x + 432, menu_y + 48, NULL, 172, 8 * modlist_numenabled, 0, 0, 0, 0.5, 0);
4664 for (n = 0, y = 48; n < modlist_count; n++)
4665 if (modlist[n].loaded)
4666 {
4667 M_PrintRed(432, y, modlist[n].dir);
4668 y += 8;
4669 }
4670
4671 if (*cl_connect_status)
4673 // scroll the list as the cursor moves
4674 y = 48;
4675 visible = (int)((menu_height - 16 - y) / 8 / 2);
4676 start = bound(0, modlist_cursor - (visible >> 1), modlist_count - visible);
4677 end = min(start + visible, modlist_count);
4678
4679 p = Draw_CachePic ("gfx/p_option");
4680 M_DrawPic((640 - Draw_GetPicWidth(p)) / 2, 4, "gfx/p_option");
4681 if (end > start)
4682 {
4683 for (n = start;n < end;n++)
4684 {
4685 const char *item_label = (modlist[n].name[0] != '\0') ? modlist[n].name : modlist[n].dir;
4686
4687 DrawQ_Pic(menu_x + 40, menu_y + y, NULL, 360, 8, n == modlist_cursor ? (0.5 + 0.2 * sin(host.realtime * M_PI)) : 0, 0, 0, 0.5, 0);
4688 M_ItemPrint(80, y, item_label, true);
4689 M_DrawCheckbox(48, y, modlist[n].loaded);
4690 y +=8;
4691 }
4692 }
4693 else
4694 {
4695 M_Print(80, y, "No Mods found");
4696 }
4697}
4698
4699static void M_ModList_Key(cmd_state_t *cmd, int k, int ascii)
4700{
4701 switch (k)
4702 {
4703 case K_ESCAPE:
4704 ModList_Enable ();
4706 break;
4707
4708 case K_SPACE:
4709 S_LocalSound ("sound/misc/menu2.wav");
4711 break;
4712
4713 case K_UPARROW:
4714 S_LocalSound ("sound/misc/menu1.wav");
4716 if (modlist_cursor < 0)
4718 break;
4719
4720 case K_LEFTARROW:
4722 break;
4723
4724 case K_DOWNARROW:
4725 S_LocalSound ("sound/misc/menu1.wav");
4728 modlist_cursor = 0;
4729 break;
4730
4731 case K_RIGHTARROW:
4733 break;
4734
4735 case K_ENTER:
4736 S_LocalSound ("sound/misc/menu2.wav");
4737 ModList_Enable ();
4738 break;
4739
4740 default:
4741 break;
4742 }
4743
4744}
4745
4746//=============================================================================
4747/* Menu Subsystem */
4748
4749static void M_KeyEvent(int key, int ascii, qbool downevent);
4750static void M_Draw(void);
4751void M_ToggleMenu(int mode);
4752static void M_Shutdown(void);
4753
4754static void M_Init (void)
4755{
4756 menuplyr_load = true;
4758
4759 Cmd_AddCommand(CF_CLIENT, "menu_main", M_Menu_Main_f, "open the main menu");
4760 Cmd_AddCommand(CF_CLIENT, "menu_singleplayer", M_Menu_SinglePlayer_f, "open the singleplayer menu");
4761 Cmd_AddCommand(CF_CLIENT, "menu_load", M_Menu_Load_f, "open the loadgame menu");
4762 Cmd_AddCommand(CF_CLIENT, "menu_save", M_Menu_Save_f, "open the savegame menu");
4763 Cmd_AddCommand(CF_CLIENT, "menu_multiplayer", M_Menu_MultiPlayer_f, "open the multiplayer menu");
4764 Cmd_AddCommand(CF_CLIENT, "menu_setup", M_Menu_Setup_f, "open the player setup menu");
4765 Cmd_AddCommand(CF_CLIENT, "menu_options", M_Menu_Options_f, "open the options menu");
4766 Cmd_AddCommand(CF_CLIENT, "menu_options_effects", M_Menu_Options_Effects_f, "open the effects options menu");
4767 Cmd_AddCommand(CF_CLIENT, "menu_options_graphics", M_Menu_Options_Graphics_f, "open the graphics options menu");
4768 Cmd_AddCommand(CF_CLIENT, "menu_options_colorcontrol", M_Menu_Options_ColorControl_f, "open the color control menu");
4769 Cmd_AddCommand(CF_CLIENT, "menu_keys", M_Menu_Keys_f, "open the key binding menu");
4770 Cmd_AddCommand(CF_CLIENT, "menu_video", M_Menu_Video_f, "open the video options menu");
4771 Cmd_AddCommand(CF_CLIENT, "menu_reset", M_Menu_Reset_f, "open the reset to defaults menu");
4772 Cmd_AddCommand(CF_CLIENT, "menu_mods", M_Menu_ModList_f, "open the mods browser menu");
4773 Cmd_AddCommand(CF_CLIENT, "help", M_Menu_Help_f, "open the help menu");
4774 Cmd_AddCommand(CF_CLIENT, "menu_quit", M_Menu_Quit_f, "open the quit menu");
4775 Cmd_AddCommand(CF_CLIENT, "menu_transfusion_episode", M_Menu_Transfusion_Episode_f, "open the transfusion episode select menu");
4776 Cmd_AddCommand(CF_CLIENT, "menu_transfusion_skill", M_Menu_Transfusion_Skill_f, "open the transfusion skill select menu");
4777 Cmd_AddCommand(CF_CLIENT, "menu_credits", M_Menu_Credits_f, "open the credits menu");
4778}
4779
4780void M_Draw (void)
4781{
4782 char vabuf[1024];
4784 m_state = m_none;
4785
4786 if (m_state == m_none)
4787 return;
4788
4789 switch (m_state)
4790 {
4791 case m_none:
4792 break;
4793
4794 case m_main:
4795 M_Main_Draw ();
4796 break;
4797
4798 case m_demo:
4799 M_Demo_Draw ();
4800 break;
4801
4802 case m_singleplayer:
4804 break;
4805
4808 break;
4809
4812 break;
4813
4814 case m_load:
4815 M_Load_Draw ();
4816 break;
4817
4818 case m_save:
4819 M_Save_Draw ();
4820 break;
4821
4822 case m_multiplayer:
4824 break;
4825
4826 case m_setup:
4827 M_Setup_Draw ();
4828 break;
4829
4830 case m_options:
4831 M_Options_Draw ();
4832 break;
4833
4834 case m_options_effects:
4836 break;
4837
4838 case m_options_graphics:
4840 break;
4841
4844 break;
4845
4846 case m_keys:
4847 M_Keys_Draw ();
4848 break;
4849
4850 case m_reset:
4851 M_Reset_Draw ();
4852 break;
4853
4854 case m_video:
4855 M_Video_Draw ();
4856 break;
4857
4858 case m_help:
4859 M_Help_Draw ();
4860 break;
4861
4862 case m_credits:
4863 M_Credits_Draw ();
4864 break;
4865
4866 case m_quit:
4867 M_Quit_Draw ();
4868 break;
4869
4870 case m_lanconfig:
4872 break;
4873
4874 case m_gameoptions:
4876 break;
4877
4878 case m_slist:
4880 break;
4881
4882 case m_modlist:
4883 M_ModList_Draw ();
4884 break;
4885 }
4886
4888 if (m_state != m_credits) {
4889 cachepic_t *p, *drop1, *drop2, *drop3;
4890 int g, scale_x, scale_y, scale_y_repeat, top_offset;
4891 float scale_y_rate;
4892 scale_y_repeat = vid_conheight.integer * 2;
4893 g = (int)(host.realtime * 64)%96;
4894 scale_y_rate = (float)(g+1) / 96;
4895 top_offset = (g+12)/12;
4896 p = Draw_CachePic (va(vabuf, sizeof(vabuf), "gfx/menu/blooddrip%i", top_offset));
4897 drop1 = Draw_CachePic ("gfx/menu/blooddrop1");
4898 drop2 = Draw_CachePic ("gfx/menu/blooddrop2");
4899 drop3 = Draw_CachePic ("gfx/menu/blooddrop3");
4900 for (scale_x = 0; scale_x <= vid_conwidth.integer; scale_x += Draw_GetPicWidth(p)) {
4901 for (scale_y = -scale_y_repeat; scale_y <= vid_conheight.integer; scale_y += scale_y_repeat) {
4902 DrawQ_Pic (scale_x + 21, scale_y_repeat * .5 + scale_y + scale_y_rate * scale_y_repeat, drop3, 0, 0, 1, 1, 1, 1, 0);
4903 DrawQ_Pic (scale_x + 116, scale_y_repeat + scale_y + scale_y_rate * scale_y_repeat, drop1, 0, 0, 1, 1, 1, 1, 0);
4904 DrawQ_Pic (scale_x + 180, scale_y_repeat * .275 + scale_y + scale_y_rate * scale_y_repeat, drop3, 0, 0, 1, 1, 1, 1, 0);
4905 DrawQ_Pic (scale_x + 242, scale_y_repeat * .75 + scale_y + scale_y_rate * scale_y_repeat, drop3, 0, 0, 1, 1, 1, 1, 0);
4906 DrawQ_Pic (scale_x + 304, scale_y_repeat * .25 + scale_y + scale_y_rate * scale_y_repeat, drop3, 0, 0, 1, 1, 1, 1, 0);
4907 DrawQ_Pic (scale_x + 362, scale_y_repeat * .46125 + scale_y + scale_y_rate * scale_y_repeat, drop3, 0, 0, 1, 1, 1, 1, 0);
4908 DrawQ_Pic (scale_x + 402, scale_y_repeat * .1725 + scale_y + scale_y_rate * scale_y_repeat, drop3, 0, 0, 1, 1, 1, 1, 0);
4909 DrawQ_Pic (scale_x + 438, scale_y_repeat * .9 + scale_y + scale_y_rate * scale_y_repeat, drop1, 0, 0, 1, 1, 1, 1, 0);
4910 DrawQ_Pic (scale_x + 484, scale_y_repeat * .5 + scale_y + scale_y_rate * scale_y_repeat, drop3, 0, 0, 1, 1, 1, 1, 0);
4911 DrawQ_Pic (scale_x + 557, scale_y_repeat * .9425 + scale_y + scale_y_rate * scale_y_repeat, drop1, 0, 0, 1, 1, 1, 1, 0);
4912 DrawQ_Pic (scale_x + 606, scale_y_repeat * .5 + scale_y + scale_y_rate * scale_y_repeat, drop2, 0, 0, 1, 1, 1, 1, 0);
4913 }
4914 DrawQ_Pic (scale_x, -1, Draw_CachePic (va(vabuf, sizeof(vabuf), "gfx/menu/blooddrip%i", top_offset)), 0, 0, 1, 1, 1, 1, 0);
4915 }
4916 }
4917 }
4918
4919 if (m_entersound)
4920 {
4921 S_LocalSound ("sound/misc/menu2.wav");
4922 m_entersound = false;
4923 }
4924}
4925
4926
4927void M_KeyEvent (int key, int ascii, qbool downevent)
4928{
4930 if (!downevent)
4931 return;
4932 switch (m_state)
4933 {
4934 case m_none:
4935 return;
4936
4937 case m_main:
4938 M_Main_Key(cmd, key, ascii);
4939 return;
4940
4941 case m_demo:
4942 M_Demo_Key(cmd, key, ascii);
4943 return;
4944
4945 case m_singleplayer:
4946 M_SinglePlayer_Key(cmd, key, ascii);
4947 return;
4948
4950 M_Transfusion_Episode_Key(cmd, key, ascii);
4951 return;
4952
4954 M_Transfusion_Skill_Key(cmd, key, ascii);
4955 return;
4956
4957 case m_load:
4958 M_Load_Key(cmd, key, ascii);
4959 return;
4960
4961 case m_save:
4962 M_Save_Key(cmd, key, ascii);
4963 return;
4964
4965 case m_multiplayer:
4966 M_MultiPlayer_Key(cmd, key, ascii);
4967 return;
4968
4969 case m_setup:
4970 M_Setup_Key(cmd, key, ascii);
4971 return;
4972
4973 case m_options:
4974 M_Options_Key(cmd, key, ascii);
4975 return;
4976
4977 case m_options_effects:
4978 M_Options_Effects_Key(cmd, key, ascii);
4979 return;
4980
4981 case m_options_graphics:
4982 M_Options_Graphics_Key(cmd, key, ascii);
4983 return;
4984
4986 M_Options_ColorControl_Key(cmd, key, ascii);
4987 return;
4988
4989 case m_keys:
4990 M_Keys_Key(cmd, key, ascii);
4991 return;
4992
4993 case m_reset:
4994 M_Reset_Key(cmd, key, ascii);
4995 return;
4996
4997 case m_video:
4998 M_Video_Key(cmd, key, ascii);
4999 return;
5000
5001 case m_help:
5002 M_Help_Key(cmd, key, ascii);
5003 return;
5004
5005 case m_credits:
5006 M_Credits_Key(cmd, key, ascii);
5007 return;
5008
5009 case m_quit:
5010 M_Quit_Key(cmd, key, ascii);
5011 return;
5012
5013 case m_lanconfig:
5014 M_LanConfig_Key(cmd, key, ascii);
5015 return;
5016
5017 case m_gameoptions:
5018 M_GameOptions_Key(cmd, key, ascii);
5019 return;
5020
5021 case m_slist:
5022 M_ServerList_Key(cmd, key, ascii);
5023 return;
5024
5025 case m_modlist:
5026 M_ModList_Key(cmd, key, ascii);
5027 return;
5028 }
5029
5030}
5031
5032static void M_NewMap(void)
5033{
5034}
5035
5036static int M_GetServerListEntryCategory(const serverlist_entry_t *entry)
5037{
5038 return 0;
5039}
5040
5041void M_Shutdown(void)
5042{
5043 // reset key_dest
5045}
5046
5047//============================================================================
5048// Menu prog handling
5049
5050static void MP_CheckRequiredFuncs(prvm_prog_t *prog, const char *filename)
5051{
5052 int i;
5053 const char *m_required_func[] = {
5054 "m_init",
5055 "m_keydown",
5056 "m_draw",
5057 "m_toggle",
5058 "m_shutdown",
5059 };
5060 int m_numrequiredfunc = sizeof(m_required_func) / sizeof(char*);
5061
5062 for(i = 0; i < m_numrequiredfunc; ++i)
5063 if(PRVM_ED_FindFunction(prog, m_required_func[i]) == 0)
5064 prog->error_cmd("%s: %s not found in %s",prog->name, m_required_func[i], filename);
5065}
5066
5068{
5069#define PRVM_DECLARE_serverglobalfloat(x)
5070#define PRVM_DECLARE_serverglobalvector(x)
5071#define PRVM_DECLARE_serverglobalstring(x)
5072#define PRVM_DECLARE_serverglobaledict(x)
5073#define PRVM_DECLARE_serverglobalfunction(x)
5074#define PRVM_DECLARE_clientglobalfloat(x)
5075#define PRVM_DECLARE_clientglobalvector(x)
5076#define PRVM_DECLARE_clientglobalstring(x)
5077#define PRVM_DECLARE_clientglobaledict(x)
5078#define PRVM_DECLARE_clientglobalfunction(x)
5079#define PRVM_DECLARE_menuglobalfloat(x)
5080#define PRVM_DECLARE_menuglobalvector(x)
5081#define PRVM_DECLARE_menuglobalstring(x)
5082#define PRVM_DECLARE_menuglobaledict(x)
5083#define PRVM_DECLARE_menuglobalfunction(x)
5084#define PRVM_DECLARE_serverfieldfloat(x)
5085#define PRVM_DECLARE_serverfieldvector(x)
5086#define PRVM_DECLARE_serverfieldstring(x)
5087#define PRVM_DECLARE_serverfieldedict(x)
5088#define PRVM_DECLARE_serverfieldfunction(x)
5089#define PRVM_DECLARE_clientfieldfloat(x)
5090#define PRVM_DECLARE_clientfieldvector(x)
5091#define PRVM_DECLARE_clientfieldstring(x)
5092#define PRVM_DECLARE_clientfieldedict(x)
5093#define PRVM_DECLARE_clientfieldfunction(x)
5094#define PRVM_DECLARE_menufieldfloat(x) {ev_float, #x},
5095#define PRVM_DECLARE_menufieldvector(x) {ev_vector, #x},
5096#define PRVM_DECLARE_menufieldstring(x) {ev_string, #x},
5097#define PRVM_DECLARE_menufieldedict(x) {ev_entity, #x},
5098#define PRVM_DECLARE_menufieldfunction(x) {ev_function, #x},
5099#define PRVM_DECLARE_serverfunction(x)
5100#define PRVM_DECLARE_clientfunction(x)
5101#define PRVM_DECLARE_menufunction(x)
5102#define PRVM_DECLARE_field(x)
5103#define PRVM_DECLARE_global(x)
5104#define PRVM_DECLARE_function(x)
5105#include "prvm_offsets.h"
5106#undef PRVM_DECLARE_serverglobalfloat
5107#undef PRVM_DECLARE_serverglobalvector
5108#undef PRVM_DECLARE_serverglobalstring
5109#undef PRVM_DECLARE_serverglobaledict
5110#undef PRVM_DECLARE_serverglobalfunction
5111#undef PRVM_DECLARE_clientglobalfloat
5112#undef PRVM_DECLARE_clientglobalvector
5113#undef PRVM_DECLARE_clientglobalstring
5114#undef PRVM_DECLARE_clientglobaledict
5115#undef PRVM_DECLARE_clientglobalfunction
5116#undef PRVM_DECLARE_menuglobalfloat
5117#undef PRVM_DECLARE_menuglobalvector
5118#undef PRVM_DECLARE_menuglobalstring
5119#undef PRVM_DECLARE_menuglobaledict
5120#undef PRVM_DECLARE_menuglobalfunction
5121#undef PRVM_DECLARE_serverfieldfloat
5122#undef PRVM_DECLARE_serverfieldvector
5123#undef PRVM_DECLARE_serverfieldstring
5124#undef PRVM_DECLARE_serverfieldedict
5125#undef PRVM_DECLARE_serverfieldfunction
5126#undef PRVM_DECLARE_clientfieldfloat
5127#undef PRVM_DECLARE_clientfieldvector
5128#undef PRVM_DECLARE_clientfieldstring
5129#undef PRVM_DECLARE_clientfieldedict
5130#undef PRVM_DECLARE_clientfieldfunction
5131#undef PRVM_DECLARE_menufieldfloat
5132#undef PRVM_DECLARE_menufieldvector
5133#undef PRVM_DECLARE_menufieldstring
5134#undef PRVM_DECLARE_menufieldedict
5135#undef PRVM_DECLARE_menufieldfunction
5136#undef PRVM_DECLARE_serverfunction
5137#undef PRVM_DECLARE_clientfunction
5138#undef PRVM_DECLARE_menufunction
5139#undef PRVM_DECLARE_field
5140#undef PRVM_DECLARE_global
5141#undef PRVM_DECLARE_function
5142};
5143
5145
5147{
5148#define PRVM_DECLARE_serverglobalfloat(x)
5149#define PRVM_DECLARE_serverglobalvector(x)
5150#define PRVM_DECLARE_serverglobalstring(x)
5151#define PRVM_DECLARE_serverglobaledict(x)
5152#define PRVM_DECLARE_serverglobalfunction(x)
5153#define PRVM_DECLARE_clientglobalfloat(x)
5154#define PRVM_DECLARE_clientglobalvector(x)
5155#define PRVM_DECLARE_clientglobalstring(x)
5156#define PRVM_DECLARE_clientglobaledict(x)
5157#define PRVM_DECLARE_clientglobalfunction(x)
5158#define PRVM_DECLARE_menuglobalfloat(x) {ev_float, #x},
5159#define PRVM_DECLARE_menuglobalvector(x) {ev_vector, #x},
5160#define PRVM_DECLARE_menuglobalstring(x) {ev_string, #x},
5161#define PRVM_DECLARE_menuglobaledict(x) {ev_entity, #x},
5162#define PRVM_DECLARE_menuglobalfunction(x) {ev_function, #x},
5163#define PRVM_DECLARE_serverfieldfloat(x)
5164#define PRVM_DECLARE_serverfieldvector(x)
5165#define PRVM_DECLARE_serverfieldstring(x)
5166#define PRVM_DECLARE_serverfieldedict(x)
5167#define PRVM_DECLARE_serverfieldfunction(x)
5168#define PRVM_DECLARE_clientfieldfloat(x)
5169#define PRVM_DECLARE_clientfieldvector(x)
5170#define PRVM_DECLARE_clientfieldstring(x)
5171#define PRVM_DECLARE_clientfieldedict(x)
5172#define PRVM_DECLARE_clientfieldfunction(x)
5173#define PRVM_DECLARE_menufieldfloat(x)
5174#define PRVM_DECLARE_menufieldvector(x)
5175#define PRVM_DECLARE_menufieldstring(x)
5176#define PRVM_DECLARE_menufieldedict(x)
5177#define PRVM_DECLARE_menufieldfunction(x)
5178#define PRVM_DECLARE_serverfunction(x)
5179#define PRVM_DECLARE_clientfunction(x)
5180#define PRVM_DECLARE_menufunction(x)
5181#define PRVM_DECLARE_field(x)
5182#define PRVM_DECLARE_global(x)
5183#define PRVM_DECLARE_function(x)
5184#include "prvm_offsets.h"
5185#undef PRVM_DECLARE_serverglobalfloat
5186#undef PRVM_DECLARE_serverglobalvector
5187#undef PRVM_DECLARE_serverglobalstring
5188#undef PRVM_DECLARE_serverglobaledict
5189#undef PRVM_DECLARE_serverglobalfunction
5190#undef PRVM_DECLARE_clientglobalfloat
5191#undef PRVM_DECLARE_clientglobalvector
5192#undef PRVM_DECLARE_clientglobalstring
5193#undef PRVM_DECLARE_clientglobaledict
5194#undef PRVM_DECLARE_clientglobalfunction
5195#undef PRVM_DECLARE_menuglobalfloat
5196#undef PRVM_DECLARE_menuglobalvector
5197#undef PRVM_DECLARE_menuglobalstring
5198#undef PRVM_DECLARE_menuglobaledict
5199#undef PRVM_DECLARE_menuglobalfunction
5200#undef PRVM_DECLARE_serverfieldfloat
5201#undef PRVM_DECLARE_serverfieldvector
5202#undef PRVM_DECLARE_serverfieldstring
5203#undef PRVM_DECLARE_serverfieldedict
5204#undef PRVM_DECLARE_serverfieldfunction
5205#undef PRVM_DECLARE_clientfieldfloat
5206#undef PRVM_DECLARE_clientfieldvector
5207#undef PRVM_DECLARE_clientfieldstring
5208#undef PRVM_DECLARE_clientfieldedict
5209#undef PRVM_DECLARE_clientfieldfunction
5210#undef PRVM_DECLARE_menufieldfloat
5211#undef PRVM_DECLARE_menufieldvector
5212#undef PRVM_DECLARE_menufieldstring
5213#undef PRVM_DECLARE_menufieldedict
5214#undef PRVM_DECLARE_menufieldfunction
5215#undef PRVM_DECLARE_serverfunction
5216#undef PRVM_DECLARE_clientfunction
5217#undef PRVM_DECLARE_menufunction
5218#undef PRVM_DECLARE_field
5219#undef PRVM_DECLARE_global
5220#undef PRVM_DECLARE_function
5221};
5222
5224
5225void MR_SetRouting (qbool forceold);
5226
5227jmp_buf mp_abort;
5228static void MVM_error_cmd(const char *format, ...) DP_FUNC_PRINTF(1) DP_FUNC_NORETURN;
5229static void MVM_error_cmd(const char *format, ...)
5230{
5231 static qbool processingError = false;
5232 char errorstring[MAX_INPUTLINE];
5233 va_list argptr;
5234 int outfd = sys.outfd;
5235
5236 // set output to stderr
5237 sys.outfd = fileno(stderr);
5238
5239 va_start (argptr, format);
5240 dpvsnprintf (errorstring, sizeof(errorstring), format, argptr);
5241 va_end (argptr);
5242
5243 Con_Printf(CON_ERROR "Menu_Error: %s\n", errorstring);
5244
5245 if(!processingError)
5246 {
5247 processingError = true;
5248 PRVM_Crash();
5249 processingError = false;
5250 }
5251 else
5252 Sys_Error("Menu_Error: Recursive call to MVM_error_cmd (from PRVM_Crash)!");
5253
5254 Con_Print("Falling back to engine menu\n");
5256 MR_SetRouting (true);
5257 mp_failed = true;
5258 if (cls.state != ca_connected || key_dest != key_game) // if not disrupting a game
5259 MR_ToggleMenu(1); // ensure error screen appears, eg for: menu_progs ""; menu_restart
5260
5261 // reset the active scene, too (to be on the safe side ;))
5263
5264 // prevent an endless loop if the error was triggered by a command
5266
5267 // restore configured outfd
5268 sys.outfd = outfd;
5269
5270 // no frame abort: menu failure shouldn't interfere with more important VMs
5271 longjmp(mp_abort, 1);
5272}
5273
5275{
5276}
5277
5279{
5280}
5281
5282static void MVM_init_edict(prvm_prog_t *prog, prvm_edict_t *edict)
5283{
5284}
5285
5287{
5288}
5289
5291{
5292 int i;
5293 prvm_edict_t *ent;
5294 int active;
5295
5296 active = 0;
5297 for (i=0 ; i<prog->num_edicts ; i++)
5298 {
5299 ent = PRVM_EDICT_NUM(i);
5300 if (ent->free)
5301 continue;
5302 active++;
5303 }
5304
5305 Con_Printf("num_edicts:%3i\n", prog->num_edicts);
5306 Con_Printf("active :%3i\n", active);
5307}
5308
5310{
5311 return true;
5312}
5313
5314static void MP_KeyEvent (int key, int ascii, qbool downevent)
5315{
5316 prvm_prog_t *prog = MVM_prog;
5317
5318 if (setjmp(mp_abort))
5319 return;
5320
5321 // pass key
5322 prog->globals.fp[OFS_PARM0] = (prvm_vec_t) key;
5323 prog->globals.fp[OFS_PARM1] = (prvm_vec_t) ascii;
5324 if (downevent)
5325 prog->ExecuteProgram(prog, PRVM_menufunction(m_keydown),"m_keydown(float key, float ascii) required");
5326 else if (PRVM_menufunction(m_keyup))
5327 prog->ExecuteProgram(prog, PRVM_menufunction(m_keyup),"m_keyup(float key, float ascii) required");
5328}
5329
5330static void MP_Draw (void)
5331{
5332 prvm_prog_t *prog = MVM_prog;
5333 float oldquality;
5334
5335 // don't crash if we draw a frame between prog shutdown and restart, see Host_LoadConfig_f
5336 if (!prog->loaded)
5337 return;
5338
5339 if (setjmp(mp_abort))
5340 return;
5341
5343
5344 // reset the temp entities each frame
5346
5347 // menu scenes do not use reduced rendering quality
5348 oldquality = r_refdef.view.quality;
5349 r_refdef.view.quality = 1;
5350 // TODO: this needs to be exposed to R_SetView (or something similar) ASAP [2/5/2008 Andreas]
5352
5353 // free memory for resources that are no longer referenced
5355
5356 // FIXME: this really shouldnt error out lest we have a very broken refdef state...?
5357 // or does it kill the server too?
5360 prog->ExecuteProgram(prog, PRVM_menufunction(m_draw),"m_draw() required");
5361
5362 // TODO: imo this should be moved into scene, too [1/27/2008 Andreas]
5363 r_refdef.view.quality = oldquality;
5364
5366}
5367
5368static void MP_ToggleMenu(int mode)
5369{
5370 prvm_prog_t *prog = MVM_prog;
5371
5372 if (setjmp(mp_abort))
5373 return;
5374
5375 prog->globals.fp[OFS_PARM0] = (prvm_vec_t) mode;
5376 prog->ExecuteProgram(prog, PRVM_menufunction(m_toggle),"m_toggle(float mode) required");
5377}
5378
5379static void MP_NewMap(void)
5380{
5381 prvm_prog_t *prog = MVM_prog;
5382
5383 if (setjmp(mp_abort))
5384 return;
5385
5386 if (PRVM_menufunction(m_newmap))
5387 prog->ExecuteProgram(prog, PRVM_menufunction(m_newmap),"m_newmap() required");
5388}
5389
5390const serverlist_entry_t *serverlist_callbackentry = NULL;
5391static int MP_GetServerListEntryCategory(const serverlist_entry_t *entry)
5392{
5393 prvm_prog_t *prog = MVM_prog;
5394
5395 if (setjmp(mp_abort))
5396 return 0;
5397
5399 if (PRVM_menufunction(m_gethostcachecategory))
5400 {
5401 prog->globals.fp[OFS_PARM0] = (prvm_vec_t) -1;
5402 prog->ExecuteProgram(prog, PRVM_menufunction(m_gethostcachecategory),"m_gethostcachecategory(float entry) required");
5404 return prog->globals.fp[OFS_RETURN];
5405 }
5406 else
5407 {
5408 return 0;
5409 }
5410}
5411
5412static void MP_Shutdown (void)
5413{
5414 prvm_prog_t *prog = MVM_prog;
5415
5416 if (setjmp(mp_abort))
5417 return;
5418
5419 if (prog->loaded)
5420 prog->ExecuteProgram(prog, PRVM_menufunction(m_shutdown),"m_shutdown() required");
5421
5422 // reset key_dest
5424
5425 // AK not using this cause Im not sure whether this is useful at all instead :
5426 PRVM_Prog_Reset(prog);
5427}
5428
5429static void MP_Init (void)
5430{
5431 prvm_prog_t *prog = MVM_prog;
5432
5433 if (setjmp(mp_abort))
5434 return;
5435
5437
5438 prog->edictprivate_size = 0; // no private struct used
5439 prog->name = "menu";
5440 prog->num_edicts = 1;
5441 prog->limit_edicts = M_MAX_EDICTS;
5443 prog->builtins = vm_m_builtins;
5445
5446 // all callbacks must be defined (pointers are not checked before calling)
5449 prog->init_edict = MVM_init_edict;
5450 prog->free_edict = MVM_free_edict;
5452 prog->load_edict = MVM_load_edict;
5453 prog->init_cmd = MVM_init_cmd;
5454 prog->reset_cmd = MVM_reset_cmd;
5455 prog->error_cmd = MVM_error_cmd;
5456 prog->ExecuteProgram = MVM_ExecuteProgram;
5457
5458 // allocate the mempools
5460
5462
5463 // note: OP_STATE is not supported by menu qc, we don't even try to detect
5464 // it here
5465
5466 in_client_mouse = true;
5467
5468 // call the prog init
5469 prog->ExecuteProgram(prog, PRVM_menufunction(m_init),"m_init() required");
5470
5471 // Once m_init was called, we consider menuqc code fully initialized.
5472 prog->inittime = host.realtime;
5473}
5474
5475//============================================================================
5476// Menu router
5477
5478void (*MR_KeyEvent) (int key, int ascii, qbool downevent);
5483int (*MR_GetServerListEntryCategory) (const serverlist_entry_t *entry);
5484
5485void MR_SetRouting(qbool forceold)
5486{
5487 // if the menu prog isnt available or forceqmenu ist set, use the old menu
5488 if(!FS_FileExists(menu_progs.string) || forceqmenu.integer || forceold)
5489 {
5490 // set menu router function pointers
5492 MR_Draw = M_Draw;
5497 M_Init();
5498 }
5499 else
5500 {
5501 // set menu router function pointers
5503 MR_Draw = MP_Draw;
5508 MP_Init();
5509 }
5510}
5511
5512void MR_Restart(void)
5513{
5514 if(MR_Shutdown)
5515 MR_Shutdown ();
5516 MR_Init();
5517}
5518
5520{
5521 MR_Restart();
5522}
5523
5525{
5526 int m;
5527 m = ((Cmd_Argc(cmd) < 2) ? -1 : atoi(Cmd_Argv(cmd, 1)));
5528 CL_StartVideo();
5529 if(MR_ToggleMenu)
5530 MR_ToggleMenu(m);
5531}
5532
5534{
5535 // set router console commands
5539 Cmd_AddCommand(CF_CLIENT, "menu_restart", MR_Restart_f, "restart menu system (reloads menu.dat)");
5540 Cmd_AddCommand(CF_CLIENT, "togglemenu", Call_MR_ToggleMenu_f, "opens or closes menu");
5541}
5542
5543void MR_Init(void)
5544{
5545 vid_mode_t res[1024];
5546 size_t res_count, i;
5547
5548 res_count = VID_ListModes(res, sizeof(res) / sizeof(*res));
5549 res_count = VID_SortModes(res, res_count, false, false, true);
5550 if(res_count)
5551 {
5552 video_resolutions_count = (int)res_count;
5555 for(i = 0; i < res_count; ++i)
5556 {
5557 int n, d, t;
5558 video_resolutions[i].type = "Detected mode"; // FIXME make this more dynamic
5561 video_resolutions[i].pixelheight = res[i].pixelheight_num / (double) res[i].pixelheight_denom;
5564 while(d)
5565 {
5566 t = n;
5567 n = d;
5568 d = t % d;
5569 }
5570 d = (res[i].pixelheight_num * video_resolutions[i].height) / n;
5572 switch(n * 0x10000 | d)
5573 {
5574 case 0x00040003:
5577 video_resolutions[i].type = "Standard 4x3";
5578 break;
5579 case 0x00050004:
5582 if(res[i].pixelheight_denom == res[i].pixelheight_num)
5583 video_resolutions[i].type = "Square Pixel (LCD) 5x4";
5584 else
5585 video_resolutions[i].type = "Short Pixel (CRT) 5x4";
5586 break;
5587 case 0x00080005:
5590 if(res[i].pixelheight_denom == res[i].pixelheight_num)
5591 video_resolutions[i].type = "Widescreen 8x5";
5592 else
5593 video_resolutions[i].type = "Tall Pixel (CRT) 8x5";
5594
5595 break;
5596 case 0x00050003:
5599 video_resolutions[i].type = "Widescreen 5x3";
5600 break;
5601 case 0x000D0009:
5604 video_resolutions[i].type = "Widescreen 14x9";
5605 break;
5606 case 0x00100009:
5609 video_resolutions[i].type = "Widescreen 16x9";
5610 break;
5611 case 0x00030002:
5614 video_resolutions[i].type = "NTSC 3x2";
5615 break;
5616 case 0x000D000B:
5619 video_resolutions[i].type = "PAL 14x11";
5620 break;
5621 case 0x00080007:
5622 if(video_resolutions[i].width >= 512)
5623 {
5626 video_resolutions[i].type = "SNES 8x7";
5627 }
5628 else
5629 {
5632 video_resolutions[i].type = "NES 8x7";
5633 }
5634 break;
5635 default:
5637 video_resolutions[i].conheight = 640 * d / n;
5638 video_resolutions[i].type = "Detected mode";
5639 break;
5640 }
5642 {
5643 int f1, f2;
5646 if(f1 > f2)
5647 {
5650 }
5651 else
5652 {
5655 }
5656 }
5657 }
5658 }
5659 else
5660 {
5663 }
5664
5667
5668 // use -forceqmenu to use always the normal quake menu (it sets forceqmenu to 1)
5669// COMMANDLINEOPTION: Client: -forceqmenu disables menu.dat (same as +forceqmenu 1)
5670 if(Sys_CheckParm("-forceqmenu"))
5672 // use -useqmenu for debugging proposes, cause it starts
5673 // the normal quake menu only the first time
5674// COMMANDLINEOPTION: Client: -useqmenu causes the first time you open the menu to use the quake menu, then reverts to menu.dat (if forceqmenu is 0)
5675 if(Sys_CheckParm("-useqmenu"))
5676 MR_SetRouting (true);
5677 else
5678 MR_SetRouting (false);
5679}
cvar_t cdaudioinitialized
Definition cd_shared.c:28
static qbool enabled
Definition cd_shared.c:90
cvar_t cl_rate
Definition cl_cmd.c:33
cvar_t cl_name
User-visible names of these CF_USERINFO cvars must be matched in CL_SetInfo()!
Definition cl_cmd.c:32
cvar_t cl_backspeed
Definition cl_input.c:366
cvar_t cl_forwardspeed
Definition cl_input.c:365
void CL_StartVideo(void)
Definition cl_main.c:2786
client_state_t cl
Definition cl_main.c:117
cvar_t sensitivity
Definition cl_main.c:53
client_static_t cls
Definition cl_main.c:116
cvar_t m_pitch
Definition cl_main.c:55
cvar_t cl_particles_blood_bloodhack
cvar_t cl_decals
cvar_t cl_particles_blood_alpha
cvar_t cl_particles_sparks
cvar_t cl_particles
cvar_t cl_particles_explosions_shell
cvar_t cl_particles_quake
cvar_t cl_particles_blood
cvar_t cl_particles_bulletimpacts
cvar_t cl_particles_smoke
cvar_t cl_particles_quality
cvar_t cl_particles_bubbles
cvar_t scr_fov
Definition cl_screen.c:20
cvar_t vid_pixelheight
Definition cl_screen.c:58
cvar_t vid_conheight
Definition cl_screen.c:57
char cl_connect_status[MAX_QPATH]
User-friendly connection status for the menu and/or loading screen, colours and not supported.
Definition cl_screen.c:1573
cvar_t vid_conwidth
Definition cl_screen.c:56
@ ca_connected
Definition client.h:532
void Cbuf_Clear(cmd_buf_t *cbuf)
Clears all command buffers.
Definition cmd.c:436
void Cbuf_InsertText(cmd_state_t *cmd, const char *text)
Definition cmd.c:292
void Cbuf_AddText(cmd_state_t *cmd, const char *text)
Definition cmd.c:264
void Cmd_AddCommand(unsigned flags, const char *cmd_name, xcommand_t function, const char *description)
called by the init functions of other parts of the program to register commands and functions to call...
Definition cmd.c:1661
cmd_state_t * cmd_local
command interpreter for local commands injected by SVQC, CSQC, MQC, server or client engine code uses...
Definition cmd.c:25
static int Cmd_Argc(cmd_state_t *cmd)
Definition cmd.h:249
static const char * Cmd_Argv(cmd_state_t *cmd, int arg)
Cmd_Argv(cmd, ) will return an empty string (not a NULL) if arg > argc, so string operations are alwa...
Definition cmd.h:254
#define CF_CLIENT
cvar/command that only the client can change/execute
Definition cmd.h:48
gamemode_t gamemode
Definition com_game.c:26
const char * gamedirname1
Definition com_game.c:29
gamemode_t
Definition com_game.h:27
@ GAME_BATTLEMECH
Definition com_game.h:38
@ GAME_QUOTH
Definition com_game.h:31
@ GAME_ROGUE
Definition com_game.h:30
@ GAME_TRANSFUSION
Definition com_game.h:35
@ GAME_OPENQUARTZ
this game sucks
Definition com_game.h:43
@ GAME_GOODVSBAD2
Definition com_game.h:36
@ GAME_NEHAHRA
Definition com_game.h:32
@ GAME_NORMAL
Definition com_game.h:28
@ GAME_PRYDON
Definition com_game.h:44
@ GAME_HIPNOTIC
Definition com_game.h:29
@ GAME_DEFEATINDETAIL2
Definition com_game.h:47
int dpvsnprintf(char *buffer, size_t buffersize, const char *format, va_list args)
Returns the number of printed characters, excluding the final '\0' or returns -1 if the buffer isn't ...
Definition common.c:1010
char com_token[MAX_INPUTLINE]
Definition common.c:39
char * va(char *buf, size_t buflen, const char *format,...)
Definition common.c:972
cvar_t registered
Definition common.c:32
qbool COM_ParseToken_Simple(const char **datapointer, qbool returnnewline, qbool parsebackslash, qbool parsecomments)
Definition common.c:463
int dpsnprintf(char *buffer, size_t buffersize, const char *format,...)
Returns the number of printed characters, excluding the final '\0' or returns -1 if the buffer isn't ...
Definition common.c:997
#define dp_strlcat(dst, src, dsize)
Definition common.h:304
#define dp_strlcpy(dst, src, dsize)
Definition common.h:303
void Con_Print(const char *msg)
Prints to all appropriate console targets, and adds timestamps.
Definition console.c:1504
void Con_Printf(const char *fmt,...)
Prints to all appropriate console targets.
Definition console.c:1514
void Con_DPrint(const char *msg)
A Con_Print that only shows up if the "developer" cvar is set.
Definition console.c:1531
void Con_ToggleConsole_f(cmd_state_t *cmd)
Definition console.c:686
#define CON_ERROR
Definition console.h:102
void() predraw
void Cvar_SetValueQuick(cvar_t *var, float value)
Definition cvar.c:473
void Cvar_SetQuick(cvar_t *var, const char *value)
Definition cvar.c:436
void Cvar_RegisterVariable(cvar_t *variable)
registers a cvar that already has the name, string, and optionally the archive elements set.
Definition cvar.c:599
cachepic_t * Draw_CachePic(const char *path)
Definition gl_draw.c:185
@ CACHEPICFLAG_FAILONMISSING
Definition draw.h:44
@ CACHEPICFLAG_NOCLAMP
Definition draw.h:39
void DrawQ_Fill(float x, float y, float width, float height, float red, float green, float blue, float alpha, int flags)
Definition gl_draw.c:847
void DrawQ_Pic(float x, float y, cachepic_t *pic, float width, float height, float red, float green, float blue, float alpha, int flags)
Definition gl_draw.c:797
void DrawQ_SuperPic(float x, float y, cachepic_t *pic, float width, float height, float s1, float t1, float r1, float g1, float b1, float a1, float s2, float t2, float r2, float g2, float b2, float a2, float s3, float t3, float r3, float g3, float b3, float a3, float s4, float t4, float r4, float g4, float b4, float a4, int flags)
Definition gl_draw.c:1380
cachepic_t * Draw_NewPic(const char *picname, int width, int height, unsigned char *pixels, textype_t textype, int texflags)
Definition gl_draw.c:256
float DrawQ_String(float x, float y, const char *text, size_t maxlen, float scalex, float scaley, float basered, float basegreen, float baseblue, float basealpha, int flags, int *outcolor, qbool ignorecolorcodes, const dp_font_t *fnt)
Definition gl_draw.c:1320
cachepic_t * Draw_CachePic_Flags(const char *path, unsigned int cachepicflags)
Definition gl_draw.c:86
int Draw_GetPicWidth(cachepic_t *pic)
Definition gl_draw.c:197
#define FONT_MENU
Definition draw.h:135
qbool Draw_IsPicLoaded(cachepic_t *pic)
Definition gl_draw.c:211
void stringlistfreecontents(stringlist_t *list)
Definition filematch.c:87
void stringlistinit(stringlist_t *list)
Definition filematch.c:82
void stringlistsort(stringlist_t *list, qbool uniq)
Definition filematch.c:129
void listdirectory(stringlist_t *list, const char *basepath, const char *path)
Definition filematch.c:198
#define n(x, y)
fs_offset_t FS_Read(qfile_t *file, void *buffer, size_t buffersize)
Definition fs.c:3066
char fs_gamedirs[MAX_GAMEDIRS][MAX_QPATH]
Definition fs.c:449
const char * FS_CheckGameDir(const char *gamedir)
Definition fs.c:1824
qbool FS_ChangeGameDirs(int numgamedirs, const char *gamedirs[], qbool failmissing)
Definition fs.c:1719
unsigned char * FS_LoadFile(const char *path, mempool_t *pool, qbool quiet, fs_offset_t *filesizepointer)
Definition fs.c:3540
qfile_t * FS_OpenRealFile(const char *filepath, const char *mode, qbool quiet)
Definition fs.c:2901
static int(ZEXPORT *qz_inflate)(z_stream *strm
int FS_Close(qfile_t *file)
Definition fs.c:2970
const char *const fs_checkgamedir_missing
Definition fs.c:438
char fs_basedir[MAX_OSPATH]
Definition fs.c:444
int fs_numgamedirs
Definition fs.c:448
const char * FS_FileExists(const char *filename)
Look for a file in the packages and in the filesystem Returns its canonical name (same case as used i...
Definition fs.c:3693
int64_t fs_offset_t
Definition fs.h:37
cvar_t gl_polyblend
Definition gl_backend.c:17
cvar_t r_waterwarp
Definition gl_backend.c:13
cvar_t r_waterscroll
Definition gl_rmain.c:206
void R_SelectScene(r_refdef_scene_type_t scenetype)
Definition gl_rmain.c:5573
cvar_t r_wateralpha
Definition gl_rmain.c:120
cvar_t r_lerpsprites
Definition gl_rmain.c:202
r_refdef_t r_refdef
Definition gl_rmain.c:57
cvar_t r_lerplightstyles
Definition gl_rmain.c:205
cvar_t r_lerpmodels
Definition gl_rmain.c:203
cvar_t gl_texturecompression
Definition gl_textures.c:37
GLenum GLsizei width
Definition glquake.h:622
GLenum GLsizei GLsizei height
Definition glquake.h:622
GLubyte GLubyte GLubyte GLubyte w
Definition glquake.h:782
GLenum mode
Definition glquake.h:718
GLsizei const GLfloat * value
Definition glquake.h:740
const GLdouble * v
Definition glquake.h:762
GLenum GLenum GLsizei count
Definition glquake.h:656
GLint GLint GLint GLsizei GLsizei GLenum format
Definition glquake.h:649
GLint GLenum GLint GLint y
Definition glquake.h:651
GLint GLenum GLint x
Definition glquake.h:651
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition glquake.h:657
const GLchar * name
Definition glquake.h:601
GLenum type
Definition glquake.h:656
host_static_t host
Definition host.c:41
@ host_shutdown
states >= host_shutdown cause graceful shutdown, see Sys_HandleCrash() comments
Definition host.h:27
qbool in_client_mouse
Definition vid_shared.c:67
float K_UPARROW
Definition keycodes.qc:15
float K_PGDN
Definition keycodes.qc:39
float K_BACKSPACE
Definition keycodes.qc:14
float K_DOWNARROW
Definition keycodes.qc:16
float K_RIGHTARROW
Definition keycodes.qc:18
float K_DEL
Definition keycodes.qc:38
float K_PGUP
Definition keycodes.qc:40
float K_SPACE
Definition keycodes.qc:10
float K_ENTER
Definition keycodes.qc:8
float K_LEFTARROW
Definition keycodes.qc:17
float K_HOME
Definition keycodes.qc:41
float K_END
Definition keycodes.qc:42
float K_ESCAPE
Definition keycodes.qc:9
void Key_FindKeysForCommand(const char *command, int *keys, int numkeys, int bindmap)
Definition keys.c:1760
qbool Key_SetBinding(int keynum, int bindmap, const char *binding)
Definition keys.c:1409
char * keybindings[MAX_BINDMAPS][MAX_KEYS]
Definition keys.c:39
const char * Key_KeynumToString(int keynum, char *tinystr, size_t tinystrlength)
Definition keys.c:1383
keydest_t key_dest
Definition keys.c:37
#define TINYSTR_LEN
Definition keys.h:46
@ key_menu
Definition keys.h:372
@ key_game
Definition keys.h:372
@ key_menu_grabbed
Definition keys.h:372
#define max(A, B)
Definition mathlib.h:38
#define min(A, B)
Definition mathlib.h:37
#define bound(min, num, max)
Definition mathlib.h:34
#define M_PI
Definition mathlib.h:28
static int menuplyr_top
Definition menu.c:1305
static int m_opty
Definition menu.c:1636
static void M_Options_ColorControl_Key(cmd_state_t *cmd, int key, int ascii)
Definition menu.c:2296
video_resolution_t * video_resolutions
Definition menu.c:2851
static void M_Menu_Demos_f(cmd_state_t *cmd)
Definition menu.c:304
cvar_t r_lightningbeam_scroll
Definition r_lightning.c:6
static level_t battlemechlevels[]
Definition menu.c:3857
static int m_skill_cursor
Definition menu.c:1097
static int m_numrequiredglobals
Definition menu.c:5223
static int video_cursor
Definition menu.c:2847
#define NUM_HELP_PAGES
Definition menu.c:3105
static gamelevels_t defeatindetail2game
Definition menu.c:3933
static gamelevels_t prydongame
Definition menu.c:3934
static episode_t hipnoticepisodes[]
Definition menu.c:3641
static int modlist_numenabled
Definition menu.c:4531
static void M_NewMap(void)
Definition menu.c:5032
cvar_t r_lightningbeam_repeatdistance
Definition r_lightning.c:7
static void MVM_count_edicts(prvm_prog_t *prog)
Definition menu.c:5290
static gamelevels_t sharewarequakegame
Definition menu.c:3924
static int m_numrequiredfields
Definition menu.c:5144
#define RATES
Definition menu.c:1316
static int m_optnum
Definition menu.c:1635
static cvar_t menu_options_colorcontrol_correctionvalue
Definition menu.c:2110
static void M_Main_Draw(void)
Definition menu.c:425
static qbool m_serverInfoMessage
Definition menu.c:3964
static void M_Menu_Options_AdjustSliders(int dir)
Definition menu.c:1597
static void Call_MR_ToggleMenu_f(cmd_state_t *cmd)
Definition menu.c:5524
static const char * m_quit_message[9]
Definition menu.c:3181
static void M_Background(int width, int height)
Definition menu.c:161
static void M_MultiPlayer_Key(cmd_state_t *cmd, int key, int ascii)
Definition menu.c:1239
static void M_GameOptions_Draw(void)
Definition menu.c:3989
static void M_Options_Draw(void)
Definition menu.c:1677
static void MVM_begin_increase_edicts(prvm_prog_t *prog)
Definition menu.c:5274
static void M_Options_PrintCommand(const char *s, int enabled)
Definition menu.c:1639
#define SINGLEPLAYER_ITEMS
Definition menu.c:739
void M_Menu_Options_ColorControl_f(cmd_state_t *cmd)
Definition menu.c:2112
static int NehGameType
Definition menu.c:34
#define StartingGame
Definition menu.c:110
void M_Menu_Help_f(cmd_state_t *cmd)
Definition menu.c:3108
cvar_t r_lightningbeam_color_red
Definition r_lightning.c:8
static void M_Options_PrintCheckbox(const char *s, int enabled, int yes)
Definition menu.c:1651
static int MP_GetServerListEntryCategory(const serverlist_entry_t *entry)
Definition menu.c:5391
#define MULTIPLAYER_ITEMS
Definition menu.c:1199
cvar_t r_bloom_colorsubtract
Definition gl_rmain.c:215
static int keys_cursor
Definition menu.c:2555
cvar_t r_shadow_realtime_dlight
Definition r_shadow.c:159
static void M_Credits_Key(cmd_state_t *cmd, int key, int ascii)
Definition menu.c:3173
static float menu_width
Definition menu.c:159
void M_Menu_Options_Effects_f(cmd_state_t *cmd)
Definition menu.c:1816
static void M_NetStart_Change(int dir)
Definition menu.c:4151
static int menuplyr_width
Definition menu.c:1305
static int maxplayers
Definition menu.c:3963
static qbool m_missingdata
Definition menu.c:350
cvar_t r_bloom_colorexponent
Definition gl_rmain.c:214
#define MODLIST_MAXDIRS
Definition menu.c:4530
static void M_Menu_Options_Graphics_AdjustSliders(cmd_state_t *cmd, int dir)
Definition menu.c:2003
static int menu_video_resolution
Definition menu.c:2849
static void M_GameOptions_Key(cmd_state_t *cmd, int key, int ascii)
Definition menu.c:4311
#define JoiningGame
Definition menu.c:111
static video_resolution_t * menu_video_resolutions
Definition menu.c:2854
void M_Menu_Transfusion_Episode_f(cmd_state_t *cmd)
Definition menu.c:1042
video_resolution_t video_resolutions_hardcoded[]
Definition menu.c:2782
enum m_state_e m_state
Definition menu.c:36
void(* MR_ToggleMenu)(int mode)
Definition menu.c:5480
#define NUM_GAMEOPTIONS
Definition menu.c:3986
static const char * quakebindnames[][2]
Definition menu.c:2357
static void M_LanConfig_Draw(void)
Definition menu.c:3363
static void M_SinglePlayer_Key(cmd_state_t *cmd, int key, int ascii)
Definition menu.c:786
static int lanConfig_port
Definition menu.c:3340
cvar_t r_bloom
Definition gl_rmain.c:208
static level_t transfusionlevels[]
Definition menu.c:3716
static void M_UnbindCommand(const char *command)
Definition menu.c:2594
cvar_t r_shadow_realtime_world_shadows
Definition r_shadow.c:166
static void M_Init(void)
Definition menu.c:4754
static float menu_height
Definition menu.c:159
static void M_ItemPrint(float cx, float cy, const char *str, int unghosted)
Definition menu.c:201
static int setup_rate
Definition menu.c:1286
cvar_t cl_stainmaps_clearonload
Definition cl_main.c:76
static int setup_oldbottom
Definition menu.c:1283
static int setup_bottom
Definition menu.c:1285
static int options_colorcontrol_cursor
Definition menu.c:2107
static void M_Quit_Draw(void)
Definition menu.c:3310
static void M_Save_Draw(void)
Definition menu.c:940
static void M_Menu_Video_FindResolution(int w, int h, float a)
Definition menu.c:2858
cvar_t r_shadow_realtime_world
Definition r_shadow.c:163
static int M_GetServerListEntryCategory(const serverlist_entry_t *entry)
Definition menu.c:5036
static double m_serverInfoMessageTime
Definition menu.c:3965
static cvar_t menu_progs
Definition menu.c:32
void(* MR_NewMap)(void)
Definition menu.c:5482
static unsigned char * menuplyr_pixels
Definition menu.c:1306
static int setup_cursor_table[]
Definition menu.c:1279
static void MVM_error_cmd(const char *format,...) DP_FUNC_PRINTF(1) DP_FUNC_NORETURN
Definition menu.c:5229
static void M_PrintColored(float cx, float cy, const char *str)
Definition menu.c:186
static void M_ServerList_Key(cmd_state_t *cmd, int key, int ascii)
Definition menu.c:4469
static int lanConfig_cursor
Definition menu.c:3336
static int m_episode_cursor
Definition menu.c:1039
static int setup_top
Definition menu.c:1284
static void M_DrawCharacter(float cx, float cy, int num)
Definition menu.c:178
static void M_ToggleMenu(int mode)
Definition menu.c:269
static int MAIN_ITEMS
Definition menu.c:352
static void M_LanConfig_Key(cmd_state_t *cmd, int key, int ascii)
Definition menu.c:3417
static unsigned slist_cursor
Definition menu.c:4400
static void M_PrintRed(float cx, float cy, const char *str)
Definition menu.c:196
static episode_t quakeepisodes[]
Definition menu.c:3601
cvar_t r_coronas
Definition r_shadow.c:233
static const char * goodvsbad2bindnames[][2]
Definition menu.c:2438
static int help_page
Definition menu.c:3104
static gamelevels_t hipnoticgame
Definition menu.c:3926
static void M_DrawSlider(int x, int y, float num, float rangemin, float rangemax)
Definition menu.c:1551
cvar_t gl_picmip
Definition gl_textures.c:29
const serverlist_entry_t * serverlist_callbackentry
Definition menu.c:5390
#define TYPE_BOTH
Definition menu.c:29
void(* MR_Draw)(void)
Definition menu.c:5479
static int m_quit_prevstate
Definition menu.c:3182
static void M_KeyEvent(int key, int ascii, qbool downevent)
Definition menu.c:4927
static level_t defeatindetail2levels[]
Definition menu.c:3899
static void M_Credits_Draw(void)
Definition menu.c:3163
static void M_Keys_Draw(void)
Definition menu.c:2610
static gamelevels_t openquartzgame
Definition menu.c:3932
void MR_Restart(void)
Definition menu.c:5512
int(* MR_GetServerListEntryCategory)(const serverlist_entry_t *entry)
Definition menu.c:5483
cvar_t r_lightningbeam_color_blue
Definition r_lightning.c:10
static level_t goodvsbad2levels[]
Definition menu.c:3839
void M_Menu_Transfusion_Skill_f(cmd_state_t *cmd)
Definition menu.c:1100
static int bind_grab
Definition menu.c:2556
static gamelevels_t battlemechgame
Definition menu.c:3931
static gamelevels_t registeredquakegame
Definition menu.c:3925
static void M_ModList_Key(cmd_state_t *cmd, int key, int ascii)
Definition menu.c:4699
static level_t openquartzlevels[]
Definition menu.c:3873
void(* MR_Shutdown)(void)
Definition menu.c:5481
static int demo_cursor
Definition menu.c:289
static level_t prydonlevels[]
Definition menu.c:3911
static void M_Menu_Options_ColorControl_AdjustSliders(int dir)
Definition menu.c:2120
static bool mp_failed
Definition menu.c:424
static void M_ServerList_Draw(void)
Definition menu.c:4417
static float menu_y
Definition menu.c:159
static int m_multiplayer_cursor
Definition menu.c:1198
static void M_Quit_Key(cmd_state_t *cmd, int key, int ascii)
Definition menu.c:3281
static int options_graphics_cursor
Definition menu.c:1977
static const char *(* bindnames)[2]
Definition menu.c:2462
void M_Menu_ModList_f(cmd_state_t *cmd)
Definition menu.c:4626
void M_Menu_Video_f(cmd_state_t *cmd)
Definition menu.c:2906
#define NUM_SETUP_CMDS
Definition menu.c:1289
cvar_t cl_bottomcolor
Definition cl_cmd.c:36
static char lanConfig_joinname[40]
Definition menu.c:3342
static int modlist_count
Definition menu.c:4546
static int menuplyr_load
Definition menu.c:1305
static gamelevels_t nehahragame
Definition menu.c:3928
static int setup_cursor
Definition menu.c:1278
static int M_ChooseQuitMessage(int request)
Definition menu.c:3200
static qbool menu_video_resolutions_forfullscreen
Definition menu.c:2856
#define OPTIONS_COLORCONTROL_ITEMS
Definition menu.c:2105
void M_Menu_Keys_f(cmd_state_t *cmd)
Definition menu.c:2558
static void M_DrawCheckbox(int x, int y, int on)
Definition menu.c:1569
static void MP_KeyEvent(int key, int ascii, qbool downevent)
Definition menu.c:5314
static void M_Reset_Draw(void)
Definition menu.c:2770
dllhandle_t jpeg_dll
Definition jpeg.c:457
cvar_t r_bloom_colorscale
Definition gl_rmain.c:209
static void M_Demo_Key(cmd_state_t *cmd, int k, int ascii)
Definition menu.c:312
#define EPISODE_ITEMS
Definition menu.c:1040
void M_Menu_Load_f(cmd_state_t *cmd)
Definition menu.c:892
static modlist_entry_t modlist[MODLIST_TOTALSIZE]
Definition menu.c:4547
void M_Menu_Quit_f(cmd_state_t *cmd)
Definition menu.c:3264
static int options_cursor
Definition menu.c:1582
static void M_ScanSaves(void)
Definition menu.c:853
void M_Menu_Options_f(cmd_state_t *cmd)
Definition menu.c:1584
static void MP_Init(void)
Definition menu.c:5429
static int startlevel
Definition menu.c:3962
cvar_t cl_stainmaps
Definition cl_main.c:75
static void M_Demo_Draw(void)
Definition menu.c:290
void M_Menu_Reset_f(cmd_state_t *cmd)
Definition menu.c:2741
static int m_optcursor
Definition menu.c:1637
static int video_cursor_table[VIDEO_ITEMS]
Definition menu.c:2848
static int options_effects_cursor
Definition menu.c:1814
static prvm_required_field_t m_required_fields[]
Definition menu.c:5067
static void M_Print(float cx, float cy, const char *str)
Definition menu.c:191
cvar_t r_bloom_resolution
Definition gl_rmain.c:213
static void MP_ToggleMenu(int mode)
Definition menu.c:5368
static void MP_NewMap(void)
Definition menu.c:5379
cvar_t r_textshadow
Definition gl_draw.c:53
static char setup_myname[MAX_SCOREBOARDNAME]
Definition menu.c:1281
int video_resolutions_count
Definition menu.c:2852
void M_Menu_Credits_f(cmd_state_t *cmd)
Definition menu.c:3154
static void M_Main_Key(cmd_state_t *cmd, int key, int ascii)
Definition menu.c:502
static int gameoptions_cursor
Definition menu.c:3987
static episode_t prydonepisodes[]
Definition menu.c:3918
static void M_Transfusion_Episode_Key(cmd_state_t *cmd, int key, int ascii)
Definition menu.c:1065
cvar_t r_lightningbeam_color_green
Definition r_lightning.c:9
cvar_t r_bloom_brighten
Definition gl_rmain.c:211
cvar_t r_shadow_gloss
Definition r_shadow.c:147
void M_Menu_GameOptions_f(cmd_state_t *cmd)
Definition menu.c:3967
static void M_Load_Draw(void)
Definition menu.c:922
static episode_t goodvsbad2episodes[]
Definition menu.c:3852
static void M_Save_Key(cmd_state_t *cmd, int key, int ascii)
Definition menu.c:1000
cvar_t r_explosionclip
Definition r_explosion.c:58
static level_t roguelevels[]
Definition menu.c:3653
static level_t hipnoticlevels[]
Definition menu.c:3613
#define OPTIONS_ITEMS
Definition menu.c:1579
static void MVM_init_edict(prvm_prog_t *prog, prvm_edict_t *edict)
Definition menu.c:5282
cvar_t r_hdr_scenebrightness
Definition menu.c:1999
static void M_Setup_Draw(void)
Definition menu.c:1342
static void M_Options_Key(cmd_state_t *cmd, int key, int ascii)
Definition menu.c:1723
static void MVM_free_edict(prvm_prog_t *prog, prvm_edict_t *ed)
Definition menu.c:5286
static void M_Options_PrintSlider(const char *s, int enabled, float value, float minvalue, float maxvalue)
Definition menu.c:1664
static void M_SinglePlayer_Draw(void)
Definition menu.c:750
static ratetable_t setup_ratetable[]
Definition menu.c:1317
static episode_t nehahraepisodes[]
Definition menu.c:3707
#define NUMKEYS
Definition menu.c:2592
static level_t nehahralevels[]
Definition menu.c:3684
void M_Menu_Setup_f(cmd_state_t *cmd)
Definition menu.c:1294
static void M_Video_Draw(void)
Definition menu.c:2916
static int setup_rateindex(int rate)
Definition menu.c:1333
static void M_Reset_Key(cmd_state_t *cmd, int key, int ascii)
Definition menu.c:2749
static qbool m_entersound
play after drawing a frame, so caching won't disrupt the sound
Definition menu.c:108
static level_t quakelevels[]
Definition menu.c:3553
static void MP_Draw(void)
Definition menu.c:5330
static gamelevels_t * gameoptions_levels
Definition menu.c:3959
#define NUM_LANCONFIG_CMDS
Definition menu.c:3338
static int M_QuitMessage(const char *line1, const char *line2, const char *line3, const char *line4, const char *line5, const char *line6, const char *line7, const char *line8)
Definition menu.c:3186
static void M_Transfusion_Episode_Draw(void)
Definition menu.c:1049
static int gameoptions_cursor_table[]
Definition menu.c:3985
static void M_DrawTextBox(float x, float y, float width, float height)
Definition menu.c:214
static void MR_Restart_f(cmd_state_t *cmd)
Definition menu.c:5519
cvar_t cl_beams_instantaimhack
Definition cl_main.c:80
static int modlist_cursor
Definition menu.c:4543
static nehahrademonames_t NehahraDemos[NumberOfNehahraDemos]
Definition menu.c:121
jmp_buf mp_abort
Definition menu.c:5227
void(* MR_KeyEvent)(int key, int ascii, qbool downevent)
Definition menu.c:5478
static void M_Transfusion_Skill_Key(cmd_state_t *cmd, int key, int ascii)
Definition menu.c:1124
static int m_singleplayer_cursor
Definition menu.c:738
void MR_Init(void)
Definition menu.c:5543
static int load_cursor
0 < load_cursor < MAX_SAVEGAMES
Definition menu.c:848
static void MP_Shutdown(void)
Definition menu.c:5412
static void ModList_RebuildList(void)
Definition menu.c:4549
static void M_Video_Key(cmd_state_t *cmd, int key, int ascii)
Definition menu.c:3042
#define SKILL_ITEMS
Definition menu.c:1098
static int startepisode
Definition menu.c:3961
static void M_Draw(void)
Definition menu.c:4780
cvar_t cl_beams_polygons
Definition cl_main.c:78
cvar_t r_lightningbeam_thickness
Definition r_lightning.c:5
#define VIDEO_ITEMS
Definition menu.c:2846
static gameinfo_t gamelist[]
Definition menu.c:3944
static char m_filenames[MAX_SAVEGAMES][SAVEGAME_COMMENT_LENGTH+1]
Definition menu.c:850
cvar_t r_bloom_blur
Definition gl_rmain.c:212
void M_Menu_LanConfig_f(cmd_state_t *cmd)
Definition menu.c:3344
cvar_t host_timescale
Definition sv_main.c:53
cvar_t r_lightningbeam_qmbtexture
Definition r_lightning.c:11
static void M_Menu_Options_Effects_AdjustSliders(int dir)
Definition menu.c:1841
static qbool MVM_load_edict(prvm_prog_t *prog, prvm_edict_t *ent)
Definition menu.c:5309
static episode_t transfusionepisodes[]
Definition menu.c:3824
static void M_Transfusion_Skill_Draw(void)
Definition menu.c:1107
cvar_t gl_texture_anisotropy
Definition gl_textures.c:36
static void M_Help_Key(cmd_state_t *cmd, int key, int ascii)
Definition menu.c:3126
static const char * transfusionbindnames[][2]
Definition menu.c:2380
cvar_t r_shadow_realtime_dlight_shadows
Definition r_shadow.c:160
void M_Menu_MultiPlayer_f(cmd_state_t *cmd)
Definition menu.c:1202
static qbool wasInMenus
Definition menu.c:3183
cvar_t cl_topcolor
Definition cl_cmd.c:35
static void M_Options_Graphics_Draw(void)
Definition menu.c:2031
static episode_t rogueepisodes[]
Definition menu.c:3676
static void M_Shutdown(void)
Definition menu.c:5041
static void M_Help_Draw(void)
Definition menu.c:3118
#define TYPE_GAME
Definition menu.c:28
static void M_MultiPlayer_Draw(void)
Definition menu.c:1210
void M_Menu_Options_Graphics_f(cmd_state_t *cmd)
Definition menu.c:1979
void M_Menu_ServerList_f(cmd_state_t *cmd)
Definition menu.c:4403
static int numcommands
Definition menu.c:2461
int video_resolutions_hardcoded_count
Definition menu.c:2844
static unsigned int * menuplyr_translated
Definition menu.c:1307
void M_Menu_Main_f(cmd_state_t *cmd)
Definition menu.c:355
static void MP_CheckRequiredFuncs(prvm_prog_t *prog, const char *filename)
Definition menu.c:5050
static int menuplyr_bottom
Definition menu.c:1305
static int setup_oldrate
Definition menu.c:1287
static float menu_x
Definition menu.c:159
static void M_Setup_Key(cmd_state_t *cmd, int key, int ascii)
Definition menu.c:1436
static episode_t defeatindetail2episodes[]
Definition menu.c:3906
cvar_t cl_beams_lightatend
Definition cl_main.c:81
static gamelevels_t transfusiongame
Definition menu.c:3929
#define TYPE_DEMO
Definition menu.c:27
static void MVM_end_increase_edicts(prvm_prog_t *prog)
Definition menu.c:5278
static void M_Options_Effects_Draw(void)
Definition menu.c:1884
static int menuplyr_height
Definition menu.c:1305
#define SLIDER_RANGE
Definition menu.c:1549
static gamelevels_t roguegame
Definition menu.c:3927
#define OPTIONS_GRAPHICS_ITEMS
Definition menu.c:1975
static unsigned slist_visible
Definition menu.c:4401
#define NumberOfNehahraDemos
Definition menu.c:114
static void M_Menu_Video_AdjustSliders(int dir)
Definition menu.c:2999
void M_Menu_SinglePlayer_f(cmd_state_t *cmd)
Definition menu.c:742
static void M_DrawPic(float cx, float cy, const char *picname)
Definition menu.c:209
static cvar_t forceqmenu
Definition menu.c:31
static void M_Menu_ModList_AdjustSliders(int dir)
Definition menu.c:4636
void M_Menu_Save_f(cmd_state_t *cmd)
Definition menu.c:901
static int menu_video_resolutions_count
Definition menu.c:2855
cvar_t r_shadow_realtime_world_lightmaps
Definition r_shadow.c:165
static int lanConfig_cursor_table[]
Definition menu.c:3337
cvar_t cl_beams_quakepositionhack
Definition cl_main.c:79
static gamelevels_t goodvsbad2game
Definition menu.c:3930
static void M_Load_Key(cmd_state_t *cmd, int key, int ascii)
Definition menu.c:958
cvar_t r_hdr_glowintensity
Definition gl_rmain.c:219
static int loadable[MAX_SAVEGAMES]
Definition menu.c:851
static void M_Options_Effects_Key(cmd_state_t *cmd, int key, int ascii)
Definition menu.c:1938
#define OPTIONS_EFFECTS_ITEMS
Definition menu.c:1812
void MR_SetRouting(qbool forceold)
Definition menu.c:5485
static prvm_required_field_t m_required_globals[]
Definition menu.c:5146
static void M_ModList_Draw(void)
Definition menu.c:4647
static int m_main_cursor
Definition menu.c:349
static void M_Keys_Key(cmd_state_t *cmd, int key, int ascii)
Definition menu.c:2672
static int setup_oldtop
Definition menu.c:1282
static episode_t openquartzepisodes[]
Definition menu.c:3892
static void M_Options_ColorControl_Draw(void)
Definition menu.c:2217
static void M_Options_Graphics_Key(cmd_state_t *cmd, int key, int ascii)
Definition menu.c:2068
static episode_t battlemechepisodes[]
Definition menu.c:3868
cvar_t gl_flashblend
Definition r_shadow.c:236
void MR_Init_Commands(void)
Definition menu.c:5533
static char lanConfig_portname[6]
Definition menu.c:3341
static void ModList_Enable(void)
Definition menu.c:4598
m_state_e
Definition menu.h:27
@ m_credits
Definition menu.h:42
@ m_transfusion_skill
Definition menu.h:33
@ m_transfusion_episode
Definition menu.h:32
@ m_lanconfig
Definition menu.h:44
@ m_save
Definition menu.h:35
@ m_gameoptions
Definition menu.h:45
@ m_options_effects
Definition menu.h:47
@ m_multiplayer
Definition menu.h:36
@ m_quit
Definition menu.h:43
@ m_keys
Definition menu.h:40
@ m_slist
Definition menu.h:46
@ m_video
Definition menu.h:39
@ m_singleplayer
Definition menu.h:31
@ m_demo
Definition menu.h:30
@ m_options_graphics
Definition menu.h:48
@ m_modlist
Definition menu.h:51
@ m_setup
Definition menu.h:37
@ m_options_colorcontrol
Definition menu.h:49
@ m_reset
Definition menu.h:50
@ m_help
Definition menu.h:41
@ m_none
Definition menu.h:28
@ m_main
Definition menu.h:29
@ m_load
Definition menu.h:34
@ m_options
Definition menu.h:38
float strlen(string s)
void cmd(string command,...)
float sin(float f)
float fabs(float f)
const int vm_m_numbuiltins
Definition mvm_cmds.c:1745
prvm_builtin_t vm_m_builtins[]
Definition mvm_cmds.c:1070
void MVM_init_cmd(prvm_prog_t *prog)
Definition mvm_cmds.c:1747
void MVM_reset_cmd(prvm_prog_t *prog)
Definition mvm_cmds.c:1769
const char * vm_m_extensions[]
Definition mvm_cmds.c:13
cvar_t sv_public
Definition netconn.c:36
double masterquerytime
Definition netconn.c:117
unsigned serverquerycount
Definition netconn.c:120
unsigned masterquerycount
Definition netconn.c:118
unsigned serverreplycount
Definition netconn.c:121
unsigned masterreplycount
Definition netconn.c:119
cvar_t hostname
Definition netconn.c:88
cvar_t sv_netport
Definition netconn.c:156
unsigned int palette_bgra_transparent[256]
Definition palette.c:24
#define OFS_RETURN
Definition pr_comp.h:33
#define OFS_PARM0
Definition pr_comp.h:34
#define OFS_PARM1
Definition pr_comp.h:35
float deathmatch
Definition progsdefs.qc:29
float coop
Definition progsdefs.qc:30
float teamplay
Definition progsdefs.qc:31
void PRVM_Crash(void)
Definition prvm_exec.c:750
void PRVM_Prog_Load(prvm_prog_t *prog, const char *filename, unsigned char *data, fs_offset_t size, void CheckRequiredFuncs(prvm_prog_t *prog, const char *filename), int numrequiredfields, prvm_required_field_t *required_field, int numrequiredglobals, prvm_required_field_t *required_global)
void PRVM_Prog_Init(prvm_prog_t *prog, struct cmd_state_s *cmd)
Initializing a vm: Call InitProg with the num Set up the fields marked with [INIT] in the prog struct...
mfunction_t * PRVM_ED_FindFunction(prvm_prog_t *prog, const char *name)
Definition prvm_edict.c:425
#define PRVM_EDICT_NUM(n)
Definition progsvm.h:867
void PRVM_Prog_Reset(prvm_prog_t *prog)
void PRVM_GarbageCollection(prvm_prog_t *prog)
#define PRVM_menufunction(funcname)
Definition progsvm.h:206
#define PRVM_G_FLOAT(o)
Definition progsvm.h:882
int i
#define M_MAX_EDICTS
max objects in menu vm
Definition qdefs.h:117
#define MAX_INPUTLINE
maximum size of console commandline, QuakeC strings, and many other text processing buffers
Definition qdefs.h:94
#define SAVEGAME_COMMENT_LENGTH
max comment length of savegame in menu
Definition qdefs.h:121
#define MAX_OSPATH
max length of a filesystem pathname
Definition qdefs.h:175
#define ISWHITESPACE(ch)
Definition qdefs.h:184
#define NET_MINRATE
limits "rate" and "sv_maxrate" cvars
Definition qdefs.h:180
#define DP_FUNC_PRINTF(n)
Definition qdefs.h:14
#define MAX_SAVEGAMES
max savegames listed in savegame menu
Definition qdefs.h:120
#define MODLIST_TOTALSIZE
Definition qdefs.h:148
#define MAX_SCOREBOARDNAME
max length of player name in game
Definition qdefs.h:111
#define MAX_QPATH
max length of a quake game pathname
Definition qdefs.h:169
#define MAX_SCOREBOARD
max number of players in game at once (255 protocol limit)
Definition qdefs.h:110
#define DP_FUNC_NORETURN
Definition qdefs.h:16
#define NULL
Definition qtypes.h:12
bool qbool
Definition qtypes.h:9
float prvm_vec_t
Definition qtypes.h:55
cvar_t r_skyscroll1
Definition r_sky.c:7
cvar_t r_skyscroll2
Definition r_sky.c:8
@ TEXTYPE_BGRA
Definition r_textures.h:53
#define TEXF_CLAMP
Definition r_textures.h:15
#define BOTTOM_RANGE
Definition render.h:183
@ RST_CLIENT
Definition render.h:223
@ RST_MENU
Definition render.h:224
#define TOP_RANGE
Definition render.h:182
cvar_t cl_showfps
Definition sbar.c:88
cvar_t cl_showtime
Definition sbar.c:94
cvar_t cl_showdate
Definition sbar.c:96
struct cvar_s crosshair
Definition view.c:121
server_t sv
local server
Definition sv_main.c:223
cvar_t timelimit
Definition sv_main.c:173
cvar_t sv_maxrate
Definition sv_main.c:141
server_static_t svs
persistant server info
Definition sv_main.c:224
cvar_t fraglimit
Definition sv_main.c:45
cvar_t skill
Definition sv_main.c:52
dp_FragColor r
vec2 dir
dp_FragColor g
precision highp float
Definition shader_glsl.h:53
float f
vec3 y2
dp_FragColor b
ret a
qbool S_LocalSound(const char *sound)
Definition snd_main.c:2246
cvar_t bgmvolume
Definition snd_main.c:165
cvar_t snd_initialized
Definition snd_main.c:167
cvar_t volume
Definition snd_main.c:166
int intermission
Definition client.h:856
int islocalgame
Definition client.h:746
qbool demoplayback
Definition client.h:587
mempool_t * permanentmempool
Definition client.h:572
cactive_t state
Definition client.h:568
command interpreter state - the tokenizing and execution of commands, as well as pointers to which cv...
Definition cmd.h:127
cmd_buf_t * cbuf
Definition cmd.h:137
Definition cvar.h:66
float value
Definition cvar.h:74
int integer
Definition cvar.h:73
const char * string
Definition cvar.h:71
int firstLevel
Definition menu.c:3540
const char * description
Definition menu.c:3539
int levels
Definition menu.c:3541
gamemode_t gameid
Definition menu.c:3938
gamelevels_t * registered
Definition menu.c:3940
gamelevels_t * notregistered
Definition menu.c:3939
level_t * levels
Definition menu.c:3547
episode_t * episodes
Definition menu.c:3548
const char * gamename
Definition menu.c:3546
int numepisodes
Definition menu.c:3549
int state
Definition host.h:44
double realtime
the accumulated mainloop time since application started (with filtering), without any slowmo or clamp...
Definition host.h:46
const char * description
Definition menu.c:3534
const char * name
Definition menu.c:3533
Definition menu.c:4534
char name[128]
Definition menu.c:4538
char dir[MAX_QPATH]
Definition menu.c:4540
qbool loaded
Definition menu.c:4535
const char * name
Definition menu.c:117
const char * desc
Definition menu.c:118
qbool free
true if this edict is unused
Definition progsvm.h:93
void(* reset_cmd)(struct prvm_prog_s *prog)
[INIT] used by PRVM_ResetProg
Definition progsvm.h:745
int numbuiltins
Definition progsvm.h:605
prvm_builtin_t * builtins
Definition progsvm.h:604
qbool loaded
used to indicate whether a prog is loaded
Definition progsvm.h:710
int edictprivate_size
size of the engine private struct
Definition progsvm.h:689
const char * name
name of the prog, e.g. "Server", "Client" or "Menu" (used for text output)
Definition progsvm.h:700
void(* begin_increase_edicts)(struct prvm_prog_s *prog)
[INIT] used by PRVM_MEM_Increase_Edicts
Definition progsvm.h:734
void(* free_edict)(struct prvm_prog_s *prog, prvm_edict_t *ed)
[INIT] used by PRVM_ED_Free
Definition progsvm.h:738
prvm_vec_t * fp
Definition progsvm.h:580
void(* error_cmd)(const char *format,...) DP_FUNC_PRINTF(1) DP_FUNC_NORETURN
[INIT]
Definition progsvm.h:747
int num_edicts
copies of some vars that were former read from sv
Definition progsvm.h:671
void(* count_edicts)(struct prvm_prog_s *prog)
[INIT] used by PRVM_ED_Count_f
Definition progsvm.h:740
double inittime
system time when QC initialization code finished (any entity created before is not a leak)
Definition progsvm.h:539
int limit_edicts
used instead of the constant MAX_EDICTS
Definition progsvm.h:675
void(* init_edict)(struct prvm_prog_s *prog, prvm_edict_t *edict)
[INIT] used by PRVM_ED_ClearEdict
Definition progsvm.h:737
mempool_t * progs_mempool
all memory allocations related to this vm_prog (code, edicts, strings)
Definition progsvm.h:602
void(* ExecuteProgram)(struct prvm_prog_s *prog, func_t fnum, const char *errormessage)
pointer to one of the *VM_ExecuteProgram functions
Definition progsvm.h:749
qbool(* load_edict)(struct prvm_prog_s *prog, prvm_edict_t *ent)
[INIT] used by PRVM_ED_LoadFromFile
Definition progsvm.h:742
void(* init_cmd)(struct prvm_prog_s *prog)
[INIT] used by PRVM_InitProg
Definition progsvm.h:744
union prvm_prog_t::@31 globals
const char ** extensionstring
Definition progsvm.h:705
void(* end_increase_edicts)(struct prvm_prog_s *prog)
[INIT]
Definition progsvm.h:735
int numtempentities
Definition render.h:367
double time
(client gameworld) time for rendering time based effects
Definition render.h:352
r_refdef_view_t view
Definition render.h:406
r_refdef_scene_t scene
Definition render.h:418
float quality
render quality (0 to 1) - affects r_drawparticles_drawdistance and others
Definition render.h:321
const char * name
Definition menu.c:1312
int rate
Definition menu.c:1311
int maxclients
number of svs.clients slots (updated by maxplayers command)
Definition server.h:28
qbool active
false if only a net client
Definition server.h:66
char ** strings
Definition filematch.h:31
int outfd
Definition sys.h:149
int pixelheight_denom
Definition vid.h:244
int pixelheight_num
Definition vid.h:244
int width
Definition vid.h:243
int height
Definition vid.h:243
int samples
Definition vid.h:65
qbool desktopfullscreen
whether the display hardware mode can be changed
Definition vid.h:59
float refreshrate
Definition vid.h:63
int width
Definition vid.h:60
int height
Definition vid.h:61
qbool fullscreen
Definition vid.h:58
int bitsperpixel
Definition vid.h:62
int display
Definition vid.h:57
qbool ext_texture_filter_anisotropic
Definition vid.h:49
unsigned int max_anisotropy
Definition vid.h:86
viddef_support_t support
Definition vid.h:89
viddef_mode_t mode
currently active video mode
Definition vid.h:73
double pixelheight
pixel aspect
Definition menu.h:98
const char * type
Definition menu.h:95
static vec3_t forward
Definition sv_user.c:305
void Sys_Error(const char *error,...) DP_FUNC_PRINTF(1) DP_FUNC_NORETURN
Causes the entire program to exit ASAP.
Definition sys_shared.c:724
void * dllhandle_t
Definition sys.h:169
sys_t sys
Definition sys_shared.c:42
int Sys_CheckParm(const char *parm)
Definition sys_shared.c:327
cvar_t vid_refreshrate
Definition vid_shared.c:140
cvar_t v_color_enable
Definition vid_shared.c:176
cvar_t vid_width
Definition vid_shared.c:136
cvar_t v_color_white_b
Definition vid_shared.c:185
cvar_t vid_minwidth
Definition vid_shared.c:154
void VID_ApplyGammaToColor(const float *rgb, float *out)
applies current gamma settings to a color (0-1 range)
cvar_t vid_display
Definition vid_shared.c:166
cvar_t vid_height
Definition vid_shared.c:137
cvar_t vid_vsync
Definition vid_shared.c:149
cvar_t v_color_grey_b
Definition vid_shared.c:182
cvar_t v_gamma
Definition vid_shared.c:172
size_t VID_ListModes(vid_mode_t *modes, size_t maxcount)
Definition vid_null.c:62
cvar_t vid_info_displaycount
Definition vid_shared.c:167
cvar_t v_color_white_g
Definition vid_shared.c:184
cvar_t v_color_black_r
Definition vid_shared.c:177
cvar_t v_color_black_b
Definition vid_shared.c:179
cvar_t v_color_black_g
Definition vid_shared.c:178
viddef_t vid
global video state
Definition vid_shared.c:64
cvar_t v_color_grey_g
Definition vid_shared.c:181
cvar_t vid_samples
Definition vid_shared.c:139
cvar_t vid_desktopfullscreen
Definition vid_shared.c:165
cvar_t v_brightness
Definition vid_shared.c:174
cvar_t v_color_white_r
Definition vid_shared.c:183
size_t VID_SortModes(vid_mode_t *modes, size_t count, qbool usebpp, qbool userefreshrate, qbool useaspect)
cvar_t v_color_grey_r
Definition vid_shared.c:180
cvar_t vid_bitsperpixel
Definition vid_shared.c:138
cvar_t vid_minheight
Definition vid_shared.c:155
cvar_t v_contrast
Definition vid_shared.c:173
cvar_t vid_fullscreen
Definition vid_shared.c:134
mempool_t * tempmempool
Definition zone.c:794
#define Mem_Free(mem)
Definition zone.h:96
#define Mem_Alloc(pool, size)
Definition zone.h:92
#define Mem_AllocPool(name, flags, parent)
Definition zone.h:104