//read menu.h #include "quakedef.h" #include "winquake.h" //these are awkward/strange qboolean M_Options_AlwaysRun (menucheck_t *option, struct menu_s *menu, chk_set_t set) { if (set == CHK_CHECKED) return cl_forwardspeed.value > 200; else if (cl_forwardspeed.value > 200) { Cvar_SetValue (&cl_forwardspeed, 200); Cvar_SetValue (&cl_backspeed, 200); return false; } else { Cvar_SetValue (&cl_forwardspeed, 400); Cvar_SetValue (&cl_backspeed, 400); return true; } } qboolean M_Options_InvertMouse (menucheck_t *option, struct menu_s *menu, chk_set_t set) { if (set == CHK_CHECKED) return m_pitch.value < 0; else { Cvar_SetValue (&m_pitch, -m_pitch.value); return m_pitch.value < 0; } } //options menu. void M_Menu_Options_f (void) { int mgt; extern cvar_t cl_standardchat; extern cvar_t cl_standardmsg, crosshair; #ifdef _WIN32 extern qboolean vid_isfullscreen; #endif menu_t *menu; int y = 32; key_dest = key_menu; m_state = m_complex; menu = M_CreateMenu(0); mgt = M_GameType(); if (mgt == MGT_QUAKE2) { //q2... MC_AddCenterPicture(menu, 4, 24, "pics/m_banner_options"); y += 32; } else if (mgt == MGT_HEXEN2) { //h2 MC_AddPicture(menu, 16, 0, 35, 176, "gfx/menu/hplaque.lmp"); MC_AddCenterPicture(menu, 0, 60, "gfx/menu/title3.lmp"); y+=32; } else { //q1 MC_AddPicture(menu, 16, 4, 32, 144, "gfx/qplaque.lmp"); MC_AddCenterPicture(menu, 4, 24, "gfx/p_option.lmp"); } menu->selecteditem = (union menuoption_s *) MC_AddConsoleCommand(menu, 16, y, " Customize controls", "menu_keys\n"); y+=8; MC_AddConsoleCommand(menu, 16, y, " Go to console", "toggleconsole\nplay misc/menu2.wav\n"); y+=8; MC_AddConsoleCommand(menu, 16, y, " Reset to defaults", "exec default.cfg\nplay misc/menu2.wav\n"); y+=8; MC_AddSlider(menu, 16, y, " Mouse Speed", &sensitivity, 1, 10, 0.5); y+=8; MC_AddSlider(menu, 16, y, " Crosshair", &crosshair, 0, 22, 1); y+=8; MC_AddCheckBox(menu, 16, y, " Always Run", NULL,0)->func = M_Options_AlwaysRun; y+=8; MC_AddCheckBox(menu, 16, y, " Invert Mouse", NULL,0)->func = M_Options_InvertMouse; y+=8; MC_AddCheckBox(menu, 16, y, " Lookspring", &lookspring,0); y+=8; MC_AddCheckBox(menu, 16, y, " Lookstrafe", &lookstrafe,0); y+=8; MC_AddCheckBox(menu, 16, y, " Use old status bar", &cl_sbar,0); y+=8; MC_AddCheckBox(menu, 16, y, " HUD on left side", &cl_hudswap,0); y+=8; MC_AddCheckBox(menu, 16, y, " Old-style chatting", &cl_standardchat,0);y+=8; MC_AddCheckBox(menu, 16, y, " Old-style messages", &cl_standardmsg,0);y+=8; y+=4;MC_AddEditCvar(menu, 16, y," Imitate FPS", "cl_netfps"); y+=8+4; y+=4;MC_AddEditCvar(menu, 16, y," Auto status format", "tp_autostatus"); y+=8+4; MC_AddConsoleCommand(menu, 16, y, " Video Options", "menu_video\n"); y+=8; MC_AddConsoleCommand(menu, 16, y, " FPS Options", "menu_fps\n"); y+=8; MC_AddConsoleCommand(menu, 16, y, " Audio Options", "menu_audio\n"); y+=8; MC_AddConsoleCommand(menu, 16, y, " Downloads", "menu_download\n"); y+=8; #ifdef _WIN32 if (!vid_isfullscreen) #endif { MC_AddCheckBox(menu, 16, y, " Use Mouse", &_windowed_mouse,0); y+=8; } menu->cursoritem = (menuoption_t*)MC_AddWhiteText(menu, 200, 32, NULL, false); } #ifndef __CYGWIN__ typedef struct { int cursorpos; menuoption_t *cursoritem; menutext_t *speaker[6]; menutext_t *testsoundsource; soundcardinfo_t *card; } audiomenuinfo_t; qboolean M_Audio_Key (int key, struct menu_s *menu) { int i, x, y; audiomenuinfo_t *info = menu->data; soundcardinfo_t *sc; for (sc = sndcardinfo; sc; sc = sc->next) { if (sc == info->card) break; } if (!sc) { M_RemoveMenu(menu); return true; } if (key == K_DOWNARROW) { info->testsoundsource->common.posy+=10; } if (key == K_UPARROW) { info->testsoundsource->common.posy-=10; } if (key == K_RIGHTARROW) { info->testsoundsource->common.posx+=10; } if (key == K_LEFTARROW) { info->testsoundsource->common.posx-=10; } if (key >= '0' && key <= '5') { i = key - '0'; x = info->testsoundsource->common.posx - 320/2; y = info->testsoundsource->common.posy - 200/2; sc->yaw[i] = (-atan2 (y,x)*180/M_PI) - 90; sc->dist[i] = 50/sqrt(x*x+y*y); } menu->selecteditem = NULL; return false; } void M_Audio_StartSound (struct menu_s *menu) { int i; vec3_t org; audiomenuinfo_t *info = menu->data; soundcardinfo_t *sc; vec3_t mat[4]; static float lasttime; for (sc = sndcardinfo; sc; sc = sc->next) { if (sc == info->card) break; } if (!sc) { M_RemoveMenu(menu); return; } for (i = 0; i < sc->sn.numchannels; i++) { info->speaker[i]->common.posx = 320/2 - sin(sc->yaw[i]*M_PI/180) * 50/sc->dist[i]; info->speaker[i]->common.posy = 200/2 - cos(sc->yaw[i]*M_PI/180) * 50/sc->dist[i]; } for (; i < 6; i++) info->speaker[i]->common.posy = -100; if (lasttime+0.5 < Sys_DoubleTime()) { S_GetListenerInfo(mat[0], mat[1], mat[2], mat[3]); lasttime = Sys_DoubleTime(); org[0] = mat[0][0] + 2*(mat[1][0]*(info->testsoundsource->common.posx-320/2) + mat[1][0]*(info->testsoundsource->common.posy-200/2)); org[1] = mat[0][1] + 2*(mat[1][1]*(info->testsoundsource->common.posx-320/2) + mat[1][1]*(info->testsoundsource->common.posy-200/2)); org[2] = mat[0][2] + 2*(mat[1][2]*(info->testsoundsource->common.posx-320/2) + mat[1][2]*(info->testsoundsource->common.posy-200/2)); S_StartSound(-2, 0, S_PrecacheSound("player/pain3.wav"), org, 1, 4); } } void M_Menu_Audio_Speakers_f (void) { int i; audiomenuinfo_t *info; menu_t *menu; key_dest = key_menu; m_state = m_complex; menu = M_CreateMenu(sizeof(audiomenuinfo_t)); info = menu->data; menu->key = M_Audio_Key; menu->event = M_Audio_StartSound; for (i = 0; i < 6; i++) info->speaker[i] = MC_AddBufferedText(menu, 0, 0, va("%i", i), false, true); info->testsoundsource = MC_AddBufferedText(menu, 0, 0, "X", false, true); info->card = sndcardinfo; menu->selecteditem = NULL; } menucombo_t *MC_AddCvarCombo(menu_t *menu, int x, int y, const char *caption, cvar_t *cvar, const char **ops, const char **values); void M_Menu_Audio_f (void) { int y = 32; menu_t *menu; int mgt; extern cvar_t nosound, precache, snd_leftisright, snd_khz, snd_eax, snd_speakers, ambient_level; static const char *soundqualityoptions[] = { "11025 Hz", "22050 Hz", "44100 Hz", NULL }; static const char *soundqualityvalues[] = { "11.025", "22.050", "44.100", NULL }; static const char *speakeroptions[] = { "Mono", "Stereo", "Quad", "5.1 surround", NULL }; static const char *speakervalues[] = { "1", "2", "4", "6", NULL }; key_dest = key_menu; m_state = m_complex; menu = M_CreateMenu(0); mgt = M_GameType(); if (mgt == MGT_QUAKE2) { MC_AddCenterPicture(menu, 4, 24, "pics/m_banner_options"); y += 32; } else if (mgt == MGT_HEXEN2) { } else { MC_AddPicture(menu, 16, 4, 32, 144, "gfx/qplaque.lmp"); MC_AddCenterPicture(menu, 4, 24, "gfx/p_option.lmp"); } menu->selecteditem = (union menuoption_s *) MC_AddSlider(menu, 16, y, " CD Music Volume", &bgmvolume, 0, 1, 0.1);y+=8; MC_AddSlider(menu, 16, y, " Sound Volume", &volume, 0, 1, 0.1);y+=8; MC_AddSlider(menu, 16, y, " Ambient Volume", &ambient_level, 0, 1, 0.1);y+=8; MC_AddCheckBox(menu, 16, y, " no sound", &nosound,0);y+=8; MC_AddCheckBox(menu, 16, y, " precache", &precache,0);y+=8; MC_AddCheckBox(menu, 16, y, " Low Quality Sound", &loadas8bit,0);y+=8; MC_AddCheckBox(menu, 16, y, " Flip Sound", &snd_leftisright,0);y+=8; MC_AddCheckBox(menu, 16, y, " Experimental EAX 2", &snd_eax,0);y+=8; MC_AddCvarCombo(menu, 16, y, " Speaker setup", &snd_speakers, speakeroptions, speakervalues);y+=8; MC_AddCvarCombo(menu, 16, y, " Sound speed", &snd_khz, soundqualityoptions, soundqualityvalues);y+=8; MC_AddConsoleCommand(menu, 16, y, " Restart sound", "snd_restart\n");y+=8; menu->cursoritem = (menuoption_t*)MC_AddWhiteText(menu, 200, 32, NULL, false); } #else void M_Menu_Audio_f (void) { Con_Printf("No sound in cygwin\n"); } #endif void M_Menu_Particles_f (void) { int y = 32; menu_t *menu; int mgt; extern cvar_t r_bouncysparks, r_part_rain, gl_part_flame, r_particlesystem; char *psystemopts[] = { "fixed/classic(faster)", "scripted", NULL }; char *psystemvals[] = { "classic", "script", NULL }; key_dest = key_menu; m_state = m_complex; menu = M_CreateMenu(0); mgt = M_GameType(); if (mgt == MGT_QUAKE2) { MC_AddCenterPicture(menu, 4, 24, "pics/m_banner_options"); y += 32; } else if (mgt == MGT_HEXEN2) { } else { MC_AddPicture(menu, 16, 4, 32, 144, "gfx/qplaque.lmp"); MC_AddCenterPicture(menu, 4, 24, "gfx/p_option.lmp"); } menu->selecteditem = (union menuoption_s *) MC_AddCvarCombo(menu, 16, y, " particle system", &r_particlesystem, psystemopts, psystemvals);y+=8; //fixme: hide the rest of the options if r_particlesystem==classic MC_AddConsoleCommand(menu, 16, y, " Choose particle set", "menu_particlesets");y+=8; MC_AddCheckBox(menu, 16, y, " sparks bounce", &r_bouncysparks,0);y+=8; // MC_AddSlider(menu, 16, y, " exp spark count", &r_particles_in_explosion, 16, 1024);y+=8; MC_AddCheckBox(menu, 16, y, " texture emittance", &r_part_rain, 0);y+=8; MC_AddCheckBox(menu, 16, y, " model emitters", &gl_part_flame, 0);y+=8; menu->cursoritem = (menuoption_t*)MC_AddWhiteText(menu, 200, 32, NULL, false); } enum { PRESET_286, PRESET_FAST, PRESET_DEFAULT, PRESET_NICE, PRESET_REALTIME, PRESET_MAX }; typedef struct { char *cvarname; char *value[PRESET_MAX]; } presetinfo_t; presetinfo_t preset[] = { //default is a reasonable nice look for single player //fast is for competetive deathmatch games (equivelent to the default settings of other quakrworld engines) //286 is an attempt to get the very vest fps possible, if you're crazy {"r_presetname", {"286", "fast", "default", "nice", "realtime"}}, {"gl_texturemode", {"nn", "ln", "ln", "ll", "ll"}}, {"r_particlesdesc", {"none", "highfps", "spikeset tsshaft", "spikeset tsshaft", "spikeset tsshaft"}}, {"r_particlesystem", {"none", "classic", "script", "script", "script"}}, {"r_stains", {"0", "0", "0.75", "0.75", "0.75"}}, {"r_drawflat", {"1", "0", "0", "0", "0"}}, {"gl_miptexLevel", {"3", "0", "0", "0", "0"}}, {"r_nolerp", {"1", "0", "0", "0", "0"}}, {"r_nolightdir", {"1", "1", "0", "0", "0"}}, {"r_dynamic", {"0", "0", "1", "0", "0"}}, {"r_bloom", {"0", "0", "0", "0", "1"}}, {"gl_flashblend", {"0", "1", "0", "1", "2"}}, {"gl_bump", {"0", "0", "0", "1", "1"}}, {"r_skin_overlays", {"0", "0", "1", "1", "1"}}, {"gl_specular", {"0", "0", "0", "1", "1"}}, {"r_loadlit", {"0", "1", "1", "2", "2"}}, {"r_fastsky", {"1", "0", "0", "-1", "-1"}}, {"r_waterlayers", {"0", "2", "", "4", "4"}}, {"r_shadows", {"0", "0", "0", "1", "1"}}, {"r_shadow_realtime_world",{"0", "0", "0", "0", "1"}}, {"r_shadow_realtime_dlight",{"0", "0", "0", "1", "1"}}, {"gl_detail", {"0", "0", "0", "1", "1"}}, {"gl_load24bit", {"0", "0", "1", "1", "1"}}, {"r_replacemodels", {"", "", "md3 md2", "md3 md2", "md3 md2"}}, {"r_waterwarp", {"0", "-1", "1", "1", "1"}}, {"r_lightstylesmooth", {"0", "0", "0", "1", "1"}}, {NULL} }; static void ApplyPreset (int presetnum) { int i; for (i = 1; preset[i].cvarname; i++) { Cbuf_AddText(preset[i].cvarname, Cmd_ExecLevel); Cbuf_AddText(" ", Cmd_ExecLevel); Cbuf_AddText(preset[i].value[presetnum], Cmd_ExecLevel); Cbuf_AddText("\n", Cmd_ExecLevel); } } void FPS_Preset_f (void) { char *arg = Cmd_Argv(1); int i; for (i = 0; i < PRESET_MAX; i++) { if (!strcmp(preset[0].value[i], arg)) { ApplyPreset(i); return; } } Con_Printf("Preset %s not recognised\n", arg); Con_Printf("Valid presests:\n"); for (i = 0; i < PRESET_MAX; i++) Con_Printf("%s\n", preset[0].value[i]); } void M_Menu_FPS_f (void) { char *loadlitoptions[] = {" off", " load", " generate", NULL}; char *numbervalues[] = {"0", "1", "2"}; int y = 32; menu_t *menu; int mgt; int i, len; #ifdef GLQUAKE extern cvar_t gl_compress, gl_detail, gl_bump, gl_specular, r_flashblend, r_shadow_realtime_world, r_shadow_realtime_dlight, gl_motionblur, r_nolightdir; #endif extern cvar_t r_stains, r_bloodstains, r_loadlits, r_dynamic, v_contentblend, show_fps; key_dest = key_menu; m_state = m_complex; menu = M_CreateMenu(0); mgt = M_GameType(); if (mgt == MGT_QUAKE2) { MC_AddCenterPicture(menu, 4, 24, "pics/m_banner_options"); y += 32; } else if (mgt == MGT_HEXEN2) { } else { MC_AddPicture(menu, 16, 4, 32, 144, "gfx/qplaque.lmp"); MC_AddCenterPicture(menu, 4, 24, "gfx/p_option.lmp"); } menu->selecteditem = (union menuoption_s *) MC_AddConsoleCommand(menu, 48, y, " Particle Options", "menu_particles\n"); y+=8; for (i = 0; i < PRESET_MAX; i++) { len = strlen(preset[0].value[i]); MC_AddConsoleCommand(menu, 48+8*(9-len), y, va("(preset) %s", preset[0].value[i]), va("fps_preset %s\n", preset[0].value[i])); y+=8; } MC_AddCheckBox(menu, 48, y, " Show FPS", &show_fps,0);y+=8; MC_AddCheckBox(menu, 48, y, " Content blend", &v_contentblend,0);y+=8; y+=4;MC_AddEditCvar(menu, 48, y, " Skybox", "r_skybox");y+=8;y+=4; switch(qrenderer) { #ifdef GLQUAKE case QR_OPENGL: MC_AddCvarCombo(menu, 48, y, " Coloured lighting", &r_loadlits, loadlitoptions, numbervalues);y+=8; MC_AddCheckBox(menu, 48, y, " 32 bit textures", &gl_load24bit,0);y+=8; MC_AddCheckBox(menu, 48, y, " Detail Texturing", &gl_detail,0);y+=8; MC_AddCheckBox(menu, 48, y, " Bumpmaps", &gl_bump,0);y+=8; MC_AddCheckBox(menu, 48, y, " Specular Textures", &gl_specular,0);y+=8; MC_AddCheckBox(menu, 48, y, " Tex Compression", &gl_compress,0);y+=8; MC_AddCheckBox(menu, 48, y, " Stainmaps", &r_stains,0);y+=8; MC_AddCheckBox(menu, 48, y, " Blood stains", &r_bloodstains,0);y+=8; MC_AddCheckBox(menu, 48, y, " Flat mdl Lighting", &r_nolightdir,0);y+=8; MC_AddCheckBox(menu, 48, y, "Old Dynamic lights", &r_dynamic,0);y+=8; MC_AddCheckBox(menu, 48, y, " Flashblending", &r_flashblend,0);y+=8; MC_AddCheckBox(menu, 48, y, " Realtime DLights", &r_shadow_realtime_dlight,0);y+=8; MC_AddCheckBox(menu, 48, y, " DLights Shadows", &r_shadow_realtime_dlight_shadows,0);y+=8; MC_AddCheckBox(menu, 48, y, " Realtime WLights", &r_shadow_realtime_world,0);y+=8; MC_AddCheckBox(menu, 48, y, " World Shadows", &r_shadow_realtime_world_shadows,0);y+=8; MC_AddCheckBox(menu, 48, y, " Waterwarp", &r_waterwarp,0);y+=8; MC_AddSlider(menu, 48, y, " Motion blur", &gl_motionblur, 0, 0.99, 0);y+=8; break; #endif default: break; } menu->cursoritem = (menuoption_t*)MC_AddWhiteText(menu, 200, 32, NULL, false); }