/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // menu_video.c -- the video options menu #include "client.h" #include "qmenu.h" extern cvar_t *vid_ref; /*extern cvar_t *vid_fullscreen; extern cvar_t *vid_gamma; static cvar_t *gl_mode; static cvar_t *gl_driver; static cvar_t *gl_picmip; static cvar_t *gl_texturemode; static cvar_t *gl_anisotropic; static cvar_t *gl_anisotropic_avail; static cvar_t *gl_ext_texture_compression; static cvar_t *gl_swapinterval; static cvar_t *con_MENU_FONT_SIZE;*/ // Knightmare- cvars for advanced GL options menu cvar_t *intensity; /*cvar_t *gl_modulate; cvar_t *r_overbrightbits; cvar_t *gl_trans_lightmaps; cvar_t *gl_pixel_shader_warp; cvar_t *r_waterwave; cvar_t *gl_particle_overdraw; cvar_t *r_model_shading; cvar_t *gl_shadows; cvar_t *r_shelltype; cvar_t *gl_glass_envmaps; cvar_t *gl_screenshot_jpeg; cvar_t *gl_screenshot_jpeg_quality; cvar_t *r_saveshotsize;*/ // end Knightmare extern void M_ForceMenuOff( void ); void M_PushMenu ( void (*draw) (void), const char *(*key) (int k) ); /* ==================================================================== MENU INTERACTION ==================================================================== */ #define OPENGL_MENU 0 #define OPENGL_ADVANCED_MENU 1 static menuframework_s s_video_menu; static menuframework_s s_video_menu_advanced; // Knightmare added static menuframework_s *s_current_menu; static menulist_s s_mode_list; static menulist_s s_fs_box; static menuslider_s s_brightness_slider; static menulist_s s_texqual_box; static menulist_s s_texfilter_box; static menulist_s s_aniso_box; static menulist_s s_texcompress_box; static menulist_s s_vsync_box; static menuaction_s s_advanced_action; // Knightmare added //Knightmare- replace cancel with apply, thnx to MrG static menuaction_s s_defaults_action; static menuaction_s s_apply_action; static menuaction_s s_backmain_action; // Knightmare- items for advanced video options menu static menuseparator_s s_options_advanced_header; static menuslider_s s_lightmapscale_slider; static menuslider_s s_textureintensity_slider; static menulist_s s_overbrights_box; static menulist_s s_trans_lightmap_box; static menulist_s s_texshader_warp_box; static menuslider_s s_waterwave_slider; static menuslider_s s_particle_comp_slider; static menulist_s s_particle_overdraw_box; static menulist_s s_lightbloom_box; static menuslider_s s_decal_slider; static menulist_s s_modelshading_box; static menulist_s s_glshadows_box; //static menulist_s s_ent_envmap_box; static menulist_s s_ent_shell_box; static menulist_s s_glass_envmap_box; static menulist_s s_screenshotjpeg_box; static menuslider_s s_screenshotjpegquality_slider; static menulist_s s_saveshotsize_box; static menuaction_s s_advanced_apply_action; static menuaction_s s_back_action; // end Knightmare static float ClampCvar( float min, float max, float value ) { if ( value < min ) return min; if ( value > max ) return max; return value; } static void CancelChanges( void *unused ) { extern void M_PopMenu( void ); M_PopMenu(); } /* ======================================================================= ADVANCED VIDEO MENU ======================================================================= */ static void VID_MenuAdvancedSetValues ( void ) { Cvar_SetValue( "gl_modulate", ClampCvar( 1, 2, Cvar_VariableValue("gl_modulate") ) ); s_lightmapscale_slider.curvalue = (Cvar_VariableValue("gl_modulate") -1) * 10; Cvar_SetValue( "intensity", ClampCvar( 1, 2, Cvar_VariableValue("intensity") ) ); s_textureintensity_slider.curvalue = (Cvar_VariableValue("intensity") -1) * 10; Cvar_SetValue( "r_overbrightbits", ClampCvar( 1, 2, Cvar_VariableValue("r_overbrightbits") ) ); if (Cvar_VariableValue("r_overbrightbits") == 1) s_overbrights_box.curvalue = 0; else s_overbrights_box.curvalue = 1; Cvar_SetValue( "gl_trans_lightmaps", ClampCvar( 0, 1, Cvar_VariableValue("gl_trans_lightmaps") ) ); s_trans_lightmap_box.curvalue = Cvar_VariableValue("gl_trans_lightmaps"); Cvar_SetValue( "gl_glass_envmaps", ClampCvar( 0, 1, Cvar_VariableValue("gl_glass_envmaps") ) ); s_glass_envmap_box.curvalue = Cvar_VariableValue("gl_glass_envmaps"); Cvar_SetValue( "gl_pixel_shader_warp", ClampCvar( 0, 1, Cvar_VariableValue("gl_pixel_shader_warp") ) ); s_texshader_warp_box.curvalue = Cvar_VariableValue("gl_pixel_shader_warp"); s_waterwave_slider.curvalue = Cvar_VariableValue("r_waterwave"); Cvar_SetValue( "cl_particle_scale", ClampCvar( 0, 5, Cvar_VariableValue("cl_particle_scale") ) ); s_particle_comp_slider.curvalue = (Cvar_VariableValue("cl_particle_scale") -3)*-1+3; Cvar_SetValue( "gl_particle_overdraw", ClampCvar( 0, 1, Cvar_VariableValue("gl_particle_overdraw") ) ); s_particle_overdraw_box.curvalue = Cvar_VariableValue("gl_particle_overdraw"); Cvar_SetValue( "r_bloom", ClampCvar( 0, 1, Cvar_VariableValue("r_bloom") ) ); s_lightbloom_box.curvalue = Cvar_VariableValue("r_bloom"); Cvar_SetValue( "r_decals", ClampCvar (0, 1000, Cvar_VariableValue("r_decals")) ); s_decal_slider.curvalue = Cvar_VariableValue("r_decals") / 50; Cvar_SetValue( "r_model_shading", ClampCvar( 0, 2, Cvar_VariableValue("r_model_shading") ) ); s_modelshading_box.curvalue = Cvar_VariableValue("r_model_shading"); #ifdef PROJECTION_SHADOWS Cvar_SetValue( "gl_shadows", ClampCvar( 0, 3, Cvar_VariableValue("gl_shadows") ) ); #else Cvar_SetValue( "gl_shadows", ClampCvar( 0, 2, Cvar_VariableValue("gl_shadows") ) ); #endif s_glshadows_box.curvalue = Cvar_VariableValue("gl_shadows"); Cvar_SetValue( "r_shelltype", ClampCvar( 0, 2, Cvar_VariableValue("r_shelltype") ) ); s_ent_shell_box.curvalue = Cvar_VariableValue("r_shelltype"); Cvar_SetValue( "gl_screenshot_jpeg", ClampCvar( 0, 1, Cvar_VariableValue("gl_screenshot_jpeg") ) ); s_screenshotjpeg_box.curvalue = Cvar_VariableValue("gl_screenshot_jpeg"); Cvar_SetValue( "gl_screenshot_jpeg_quality", ClampCvar( 50, 100, Cvar_VariableValue("gl_screenshot_jpeg_quality") ) ); s_screenshotjpegquality_slider.curvalue = (Cvar_VariableValue("gl_screenshot_jpeg_quality") -50) / 5; Cvar_SetValue( "r_saveshotsize", ClampCvar( 0, 1, Cvar_VariableValue("r_saveshotsize") ) ); s_saveshotsize_box.curvalue = Cvar_VariableValue("r_saveshotsize"); } static void LightMapScaleCallback ( void *unused ) { Cvar_SetValue( "gl_modulate", s_lightmapscale_slider.curvalue / 10 + 1); } static void TextureIntensCallback ( void *unused ) { Cvar_SetValue( "intensity", s_textureintensity_slider.curvalue / 10 + 1); } static void OverbrightsCallback ( void *unused ) { Cvar_SetValue( "r_overbrightbits", s_overbrights_box.curvalue + 1); } static void TransFullbrightCallback ( void *unused ) { Cvar_SetValue( "gl_trans_lightmaps", s_trans_lightmap_box.curvalue); } static void GlassEnvmapCallback ( void *unused ) { Cvar_SetValue( "gl_glass_envmaps", s_glass_envmap_box.curvalue); } static void TexShaderWarpCallback ( void *unused ) { Cvar_SetValue( "gl_pixel_shader_warp", s_texshader_warp_box.curvalue); } static void WaterWaveCallback ( void *unused ) { Cvar_SetValue( "r_waterwave", s_waterwave_slider.curvalue); } static void ParticleCompFunc( void *unused ) { Cvar_SetValue( "cl_particle_scale", (s_particle_comp_slider.curvalue-3)*-1+3); } static void ParticleOverdrawCallback( void *unused ) { Cvar_SetValue( "gl_particle_overdraw", s_particle_overdraw_box.curvalue); } static void LightBloomCallback( void *unused ) { Cvar_SetValue( "r_bloom", s_lightbloom_box.curvalue); } // Knightmare- decal option static void DecalFunc( void *unused ) { Cvar_SetValue( "r_decals", s_decal_slider.curvalue * 50); } static void ModelShadingCallback ( void *unused ) { Cvar_SetValue( "r_model_shading", s_modelshading_box.curvalue); } static void GLShadowsCallback ( void *unused ) { Cvar_SetValue( "gl_shadows", s_glshadows_box.curvalue); } static void EntShellCallback ( void *unused ) { Cvar_SetValue( "r_shelltype", s_ent_shell_box.curvalue); } static void JPEGScreenshotCallback ( void *unused ) { Cvar_SetValue( "gl_screenshot_jpeg", s_screenshotjpeg_box.curvalue); } static void JPEGScreenshotQualityCallback ( void *unused ) { Cvar_SetValue( "gl_screenshot_jpeg_quality", (s_screenshotjpegquality_slider.curvalue * 5 + 50)); } static void SaveshotSizeCallback ( void *unused ) { Cvar_SetValue( "r_saveshotsize", s_saveshotsize_box.curvalue); } static void AdvancedMenuApplyChanges ( void *unused ) { // extern void M_PopMenu( void ); // update for modified intensity if ( intensity->modified ) vid_ref->modified = true; // M_PopMenu(); } /* ** VID_MenuAdvancedInit */ void VID_MenuAdvancedInit (void) { static const char *yesno_names[] = { "no", "yes", 0 }; static const char *shading_names[] = { "off", "low", "high", 0 }; #ifdef PROJECTION_SHADOWS static const char *shadow_names[] = { "no", "static planar", "dynamic planar", "projection", 0 }; #else static const char *shadow_names[] = { "no", "static", "dynamic", 0 }; #endif static const char *ifsupported_names[] = { "no", "if supported", 0 }; static const char *shell_names[] = { "solid", "flowing", "envmap", 0 }; int y = 0; intensity = Cvar_Get ("intensity", "1", 0); /*gl_modulate = Cvar_Get( "gl_modulate", "1", CVAR_ARCHIVE ); r_overbrightbits = Cvar_Get ("r_overbrightbits", "2", CVAR_ARCHIVE); gl_trans_lightmaps = Cvar_Get( "gl_trans_lightmaps", "1", CVAR_ARCHIVE ); gl_pixel_shader_warp = Cvar_Get( "gl_pixel_shader_warp", "1", CVAR_ARCHIVE ); r_waterwave = Cvar_Get ("r_waterwave", "0", CVAR_ARCHIVE ); gl_particle_overdraw = Cvar_Get ("gl_particle_overdraw", "0", CVAR_ARCHIVE ); r_model_shading = Cvar_Get ("r_model_shading", "1", CVAR_ARCHIVE ); gl_shadows = Cvar_Get ("gl_shadows", "0", CVAR_ARCHIVE ); r_shelltype = Cvar_Get( "r_shelltype", "1", CVAR_ARCHIVE ); gl_glass_envmaps = Cvar_Get( "gl_glass_envmaps", "1", CVAR_ARCHIVE ); gl_screenshot_jpeg = Cvar_Get( "gl_screenshot_jpeg", "1", CVAR_ARCHIVE ); gl_screenshot_jpeg_quality = Cvar_Get( "gl_screenshot_jpeg_quality", "85", CVAR_ARCHIVE ); // Heffo - JPEG Screenshots r_saveshotsize = Cvar_Get( "r_saveshotsize", "1", CVAR_ARCHIVE );*/ s_video_menu_advanced.x = viddef.width * 0.50; s_video_menu_advanced.y = 0; s_video_menu_advanced.nitems = 0; s_options_advanced_header.generic.type = MTYPE_SEPARATOR; s_options_advanced_header.generic.name = "Advanced Options"; s_options_advanced_header.generic.x = MENU_FONT_SIZE/2 * strlen(s_options_advanced_header.generic.name); s_options_advanced_header.generic.y = y += 2*(MENU_FONT_SIZE+2); s_lightmapscale_slider.generic.type = MTYPE_SLIDER; s_lightmapscale_slider.generic.x = 0; s_lightmapscale_slider.generic.y = y += 3*(MENU_FONT_SIZE+2); //10 s_lightmapscale_slider.generic.name = "lightmap scale"; s_lightmapscale_slider.generic.callback = LightMapScaleCallback; s_lightmapscale_slider.minvalue = 0; s_lightmapscale_slider.maxvalue = 10; s_textureintensity_slider.generic.type = MTYPE_SLIDER; s_textureintensity_slider.generic.x = 0; s_textureintensity_slider.generic.y = y += (MENU_FONT_SIZE+2); //20 s_textureintensity_slider.generic.name = "texture intensity"; s_textureintensity_slider.generic.callback = TextureIntensCallback; s_textureintensity_slider.minvalue = 0; s_textureintensity_slider.maxvalue = 10; s_overbrights_box.generic.type = MTYPE_SPINCONTROL; s_overbrights_box.generic.x = 0; s_overbrights_box.generic.y = y += (MENU_FONT_SIZE+2); //30 s_overbrights_box.generic.name = "overbrights"; s_overbrights_box.generic.callback = OverbrightsCallback; s_overbrights_box.itemnames = yesno_names; s_trans_lightmap_box.generic.type = MTYPE_SPINCONTROL; s_trans_lightmap_box.generic.x = 0; s_trans_lightmap_box.generic.y = y += (MENU_FONT_SIZE+2); //40 s_trans_lightmap_box.generic.name = "translucent lighting"; s_trans_lightmap_box.generic.callback = TransFullbrightCallback; s_trans_lightmap_box.itemnames = yesno_names; s_glass_envmap_box.generic.type = MTYPE_SPINCONTROL; s_glass_envmap_box.generic.x = 0; s_glass_envmap_box.generic.y = y += (MENU_FONT_SIZE+2); //50 s_glass_envmap_box.generic.name = "glass envmaps"; s_glass_envmap_box.generic.callback = GlassEnvmapCallback; s_glass_envmap_box.itemnames = yesno_names; s_glass_envmap_box.generic.statusbar = "enable environment mapping on transparent surfaces"; s_texshader_warp_box.generic.type = MTYPE_SPINCONTROL; s_texshader_warp_box.generic.x = 0; s_texshader_warp_box.generic.y = y += (MENU_FONT_SIZE+2); //60 s_texshader_warp_box.generic.name = "texture shader warp"; s_texshader_warp_box.generic.callback = TexShaderWarpCallback; s_texshader_warp_box.itemnames = ifsupported_names; s_waterwave_slider.generic.type = MTYPE_SLIDER; s_waterwave_slider.generic.x = 0; s_waterwave_slider.generic.y = y += (MENU_FONT_SIZE+2); //70 s_waterwave_slider.generic.name = "water wave size"; s_waterwave_slider.generic.callback = WaterWaveCallback; s_waterwave_slider.minvalue = 0; s_waterwave_slider.maxvalue = 24; s_waterwave_slider.generic.statusbar = "size of waves on flat water surfaces"; s_particle_comp_slider.generic.type = MTYPE_SLIDER; s_particle_comp_slider.generic.x = 0; s_particle_comp_slider.generic.y = y += 2*(MENU_FONT_SIZE+2); //90 s_particle_comp_slider.generic.name = "particle effect complexity"; s_particle_comp_slider.generic.callback = ParticleCompFunc; s_particle_comp_slider.minvalue = 1; s_particle_comp_slider.maxvalue = 5; s_particle_comp_slider.generic.statusbar = "lower = faster performance"; s_particle_overdraw_box.generic.type = MTYPE_SPINCONTROL; s_particle_overdraw_box.generic.x = 0; s_particle_overdraw_box.generic.y = y += (MENU_FONT_SIZE+2); //100 s_particle_overdraw_box.generic.name = "particle overdraw"; s_particle_overdraw_box.generic.callback = ParticleOverdrawCallback; s_particle_overdraw_box.itemnames = yesno_names; s_particle_overdraw_box.generic.statusbar = "redraw particles over trans surfaces"; s_lightbloom_box.generic.type = MTYPE_SPINCONTROL; s_lightbloom_box.generic.x = 0; s_lightbloom_box.generic.y = y += (MENU_FONT_SIZE+2); //110 s_lightbloom_box.generic.name = "light blooms"; s_lightbloom_box.generic.callback = LightBloomCallback; s_lightbloom_box.itemnames = yesno_names; s_decal_slider.generic.type = MTYPE_SLIDER; s_decal_slider.generic.x = 0; s_decal_slider.generic.y = y += (MENU_FONT_SIZE+2); //120 s_decal_slider.generic.name = "decal quantity"; s_decal_slider.generic.callback = DecalFunc; s_decal_slider.minvalue = 0; s_decal_slider.maxvalue = 20; s_decal_slider.generic.statusbar = "how many decals to display at once (max = 1000)"; s_modelshading_box.generic.type = MTYPE_SPINCONTROL; s_modelshading_box.generic.x = 0; s_modelshading_box.generic.y = y += (MENU_FONT_SIZE+2); //130 s_modelshading_box.generic.name = "model shading"; s_modelshading_box.generic.callback = ModelShadingCallback; s_modelshading_box.itemnames = shading_names; s_modelshading_box.generic.statusbar = "level of shading to use on models"; s_glshadows_box.generic.type = MTYPE_SPINCONTROL; s_glshadows_box.generic.x = 0; s_glshadows_box.generic.y = y += (MENU_FONT_SIZE+2); //140 s_glshadows_box.generic.name = "entity shadows"; s_glshadows_box.generic.callback = GLShadowsCallback; s_glshadows_box.itemnames = shadow_names; s_glshadows_box.generic.statusbar = "type of model shadows to draw"; s_ent_shell_box.generic.type = MTYPE_SPINCONTROL; s_ent_shell_box.generic.x = 0; s_ent_shell_box.generic.y = y += (MENU_FONT_SIZE+2); //150 s_ent_shell_box.generic.name = "entity shell type"; s_ent_shell_box.generic.callback = EntShellCallback; s_ent_shell_box.itemnames = shell_names; s_ent_shell_box.generic.statusbar = "envmap effect may cause instability on ATI cards"; s_screenshotjpeg_box.generic.type = MTYPE_SPINCONTROL; s_screenshotjpeg_box.generic.x = 0; s_screenshotjpeg_box.generic.y = y += 2*(MENU_FONT_SIZE+2); //170 s_screenshotjpeg_box.generic.name = "JPEG screenshots"; s_screenshotjpeg_box.generic.callback = JPEGScreenshotCallback; s_screenshotjpeg_box.itemnames = yesno_names; s_screenshotjpeg_box.generic.statusbar = "whether to take JPG screenshots instead of TGA"; s_screenshotjpegquality_slider.generic.type = MTYPE_SLIDER; s_screenshotjpegquality_slider.generic.x = 0; s_screenshotjpegquality_slider.generic.y = y += (MENU_FONT_SIZE+2); //180 s_screenshotjpegquality_slider.generic.name = "JPEG screenshot quality"; s_screenshotjpegquality_slider.generic.callback = JPEGScreenshotQualityCallback; s_screenshotjpegquality_slider.minvalue = 0; s_screenshotjpegquality_slider.maxvalue = 10; s_screenshotjpegquality_slider.generic.statusbar = "quality of JPG screenshots, 50-100%"; s_saveshotsize_box.generic.type = MTYPE_SPINCONTROL; s_saveshotsize_box.generic.x = 0; s_saveshotsize_box.generic.y = y += (MENU_FONT_SIZE+2); //190 s_saveshotsize_box.generic.name = "hi-res saveshots"; s_saveshotsize_box.generic.callback = SaveshotSizeCallback; s_saveshotsize_box.itemnames = yesno_names; s_saveshotsize_box.generic.statusbar = "hi-res saveshots when running at 800x600 or higher"; s_advanced_apply_action.generic.type = MTYPE_ACTION; s_advanced_apply_action.generic.name = "apply changes"; s_advanced_apply_action.generic.x = 0; s_advanced_apply_action.generic.y = y += 2*(MENU_FONT_SIZE+2); //210 s_advanced_apply_action.generic.callback = AdvancedMenuApplyChanges; s_back_action.generic.type = MTYPE_ACTION; s_back_action.generic.name = "back"; s_back_action.generic.x = 0; s_back_action.generic.y = y += 2*(MENU_FONT_SIZE+2); //230 s_back_action.generic.callback = CancelChanges; VID_MenuAdvancedSetValues(); Menu_AddItem( &s_video_menu_advanced, ( void * ) &s_options_advanced_header ); Menu_AddItem( &s_video_menu_advanced, ( void * ) &s_lightmapscale_slider ); Menu_AddItem( &s_video_menu_advanced, ( void * ) &s_textureintensity_slider ); Menu_AddItem( &s_video_menu_advanced, ( void * ) &s_overbrights_box ); Menu_AddItem( &s_video_menu_advanced, ( void * ) &s_trans_lightmap_box ); Menu_AddItem( &s_video_menu_advanced, ( void * ) &s_glass_envmap_box ); Menu_AddItem( &s_video_menu_advanced, ( void * ) &s_texshader_warp_box ); Menu_AddItem( &s_video_menu_advanced, ( void * ) &s_waterwave_slider ); Menu_AddItem( &s_video_menu_advanced, ( void * ) &s_particle_comp_slider ); Menu_AddItem( &s_video_menu_advanced, ( void * ) &s_particle_overdraw_box ); Menu_AddItem( &s_video_menu_advanced, ( void * ) &s_lightbloom_box ); Menu_AddItem( &s_video_menu_advanced, ( void * ) &s_decal_slider ); Menu_AddItem( &s_video_menu_advanced, ( void * ) &s_modelshading_box ); Menu_AddItem( &s_video_menu_advanced, ( void * ) &s_glshadows_box ); Menu_AddItem( &s_video_menu_advanced, ( void * ) &s_ent_shell_box ); Menu_AddItem( &s_video_menu_advanced, ( void * ) &s_screenshotjpeg_box ); Menu_AddItem( &s_video_menu_advanced, ( void * ) &s_screenshotjpegquality_slider ); Menu_AddItem( &s_video_menu_advanced, ( void * ) & s_saveshotsize_box ); Menu_AddItem( &s_video_menu_advanced, ( void * ) &s_advanced_apply_action ); Menu_AddItem( &s_video_menu_advanced, ( void * ) &s_back_action ); Menu_Center( &s_video_menu_advanced ); s_video_menu_advanced.x -= MENU_FONT_SIZE; } // end Knightmare /* ================ VID_MenuAdvancedDraw ================ */ void VID_MenuAdvancedDraw (void) { //int w, h; s_current_menu = &s_video_menu_advanced; // draw the banner //R_DrawGetPicSize( &w, &h, "m_banner_video" ); //R_DrawPic( viddef.width / 2 - w / 2, viddef.height /2 - 110, "m_banner_video" ); M_Banner("m_banner_video"); // move cursor to a reasonable starting position Menu_AdjustCursor( &s_video_menu_advanced, 1 ); // draw the menu Menu_Draw( &s_video_menu_advanced ); } void M_Menu_Video_Advanced_f (void) { VID_MenuAdvancedInit(); M_PushMenu( VID_MenuAdvancedDraw, VID_MenuKey ); } static void AdvancedOptions( void *s ) { M_Menu_Video_Advanced_f (); } /* ======================================================================= VIDEO MENU ======================================================================= */ static void BrightnessCallback( void *s ) { // invert sense so greater = brighter, and scale to a range of 0.5 to 1.3 Cvar_SetValue( "vid_gamma", ( 0.8 - ( s_brightness_slider.curvalue/20.0 - 0.5 ) ) + 0.5 ); // was /10 } static void VsyncCallback ( void *unused ) { Cvar_SetValue( "gl_swapinterval", s_vsync_box.curvalue); } static void ResetDefaults ( void *unused ) { Cvar_SetToDefault ("vid_fullscreen"); Cvar_SetToDefault ("vid_gamma"); Cvar_SetToDefault ("gl_mode"); Cvar_SetToDefault ("gl_texturemode"); Cvar_SetToDefault ("gl_anisotropic"); Cvar_SetToDefault ("gl_picmip"); Cvar_SetToDefault ("gl_ext_texture_compression"); Cvar_SetToDefault ("gl_swapinterval"); Cvar_SetToDefault ("gl_modulate"); Cvar_SetToDefault ("intensity"); Cvar_SetToDefault ("r_overbrightbits"); Cvar_SetToDefault ("gl_trans_lightmaps"); Cvar_SetToDefault ("gl_pixel_shader_warp"); Cvar_SetToDefault ("r_waterwave"); Cvar_SetToDefault ("cl_particle_scale"); Cvar_SetToDefault ("gl_particle_overdraw"); Cvar_SetToDefault ("r_decals"); Cvar_SetToDefault ("r_model_shading"); Cvar_SetToDefault ("gl_shadows"); Cvar_SetToDefault ("r_shelltype"); Cvar_SetToDefault ("gl_glass_envmaps"); Cvar_SetToDefault ("gl_screenshot_jpeg"); Cvar_SetToDefault ("gl_screenshot_jpeg_quality"); Cvar_SetToDefault ("r_saveshotsize"); VID_MenuInit(); } static void prepareVideoRefresh( void ) { //set the right mode for refresh #ifdef _WIN32 Cvar_Set( "vid_ref", "gl" ); Cvar_Set( "gl_driver", "opengl32" ); #else Cvar_Set( "vid_ref", "kmglx" ); /* Backward compatibility with kmquake2 0.16 */ Cvar_Set( "gl_driver", "libGL.so" ); #endif //tell them theyr're modified so they refresh //if ( vid_gamma->modified ) // vid_ref->modified = true; //if ( gl_driver->modified ) // vid_ref->modified = true; } static void ApplyChanges( void *unused ) { if (s_texfilter_box.curvalue == 0) Cvar_Set("gl_texturemode", "GL_LINEAR_MIPMAP_NEAREST"); else if (s_texfilter_box.curvalue == 1) Cvar_Set("gl_texturemode", "GL_LINEAR_MIPMAP_LINEAR"); /*if (s_texfilter_box.curvalue == 0) Cvar_Set("gl_texturemode", "GL_NEAREST"); else if (s_texfilter_box.curvalue == 1) Cvar_Set("gl_texturemode", "GL_NEAREST_MIPMAP_NEAREST"); else if (s_texfilter_box.curvalue == 2) Cvar_Set("gl_texturemode", "GL_LINEAR"); else if (s_texfilter_box.curvalue == 3) Cvar_Set("gl_texturemode", "GL_LINEAR_MIPMAP_NEAREST"); else if (s_texfilter_box.curvalue == 4) Cvar_Set("gl_texturemode", "GL_LINEAR_MIPMAP_LINEAR");*/ Cvar_SetValue( "gl_mode", s_mode_list.curvalue + 3 ); // offset for eliminating < 640x480 modes Cvar_SetValue( "vid_fullscreen", s_fs_box.curvalue ); // invert sense so greater = brighter, and scale to a range of 0.5 to 1.3 Cvar_SetValue( "vid_gamma", ( 0.8 - ( s_brightness_slider.curvalue/20.0 - 0.5 ) ) + 0.5 ); // was /10 Cvar_SetValue( "gl_picmip", 3-s_texqual_box.curvalue ); switch ((int)s_aniso_box.curvalue) { case 1: Cvar_SetValue( "gl_anisotropic", 2.0 ); break; case 2: Cvar_SetValue( "gl_anisotropic", 4.0 ); break; case 3: Cvar_SetValue( "gl_anisotropic", 8.0 ); break; case 4: Cvar_SetValue( "gl_anisotropic", 16.0 ); break; default: case 0: Cvar_SetValue( "gl_anisotropic", 0.0 ); break; } Cvar_SetValue( "gl_ext_texture_compression", s_texcompress_box.curvalue ); Cvar_SetValue( "gl_swapinterval", s_vsync_box.curvalue ); prepareVideoRefresh (); M_ForceMenuOff(); } // Knightmare added int texfilter_box_setval (void) { char *texmode = Cvar_VariableString("gl_texturemode"); if (!Q_strcasecmp(texmode, "GL_LINEAR_MIPMAP_NEAREST")) return 0; else // if (!Q_strcasecmp(texmode, "GL_LINEAR_MIPMAP_LINEAR")) return 1; /*if (!Q_strcasecmp(texmode, "GL_NEAREST")) return 0; else if (!Q_strcasecmp(texmode, "GL_NEAREST_MIPMAP_NEAREST")) return 1; else if (!Q_strcasecmp(texmode, "GL_LINEAR")) return 2; else if (!Q_strcasecmp(texmode, "GL_LINEAR_MIPMAP_NEAREST")) return 3; else // if (!Q_strcasecmp(texmode, "GL_LINEAR_MIPMAP_LINEAR")) return 4;*/ } static const char *aniso0_names[] = { "not supported", 0 }; static const char *aniso2_names[] = { "off", "2x", 0 }; static const char *aniso4_names[] = { "off", "2x", "4x", 0 }; static const char *aniso8_names[] = { "off", "2x", "4x", "8x", 0 }; static const char *aniso16_names[] = { "off", "2x", "4x", "8x", "16x", 0 }; static const char **GetAnisoNames () { float aniso_avail = Cvar_VariableValue("gl_anisotropic_avail"); if (aniso_avail < 2.0) return aniso0_names; else if (aniso_avail < 4.0) return aniso2_names; else if (aniso_avail < 8.0) return aniso4_names; else if (aniso_avail < 16.0) return aniso8_names; else // >= 16.0 return aniso16_names; } float GetAnisoCurValue () { float aniso_avail = Cvar_VariableValue("gl_anisotropic_avail"); float anisoValue = ClampCvar (0, aniso_avail, Cvar_VariableValue("gl_anisotropic")); if (aniso_avail == 0) // not available return 0; if (anisoValue < 2.0) return 0; else if (anisoValue < 4.0) return 1; else if (anisoValue < 8.0) return 2; else if (anisoValue < 16.0) return 3; else // >= 16.0 return 4; } /* ** VID_MenuInit */ void VID_MenuInit (void) { // Knightmare- added 1280x1024, 1400x1050, 856x480, 1024x480 modes, removed 320x240, 400x300, 512x384 modes static const char *resolutions[] = { "[640x480 ]", "[800x600 ]", "[960x720 ]", "[1024x768 ]", "[1152x864 ]", "[1280x960 ]", "[1280x1024]", // Knightmare added "[1400x1050]", // Knightmare added "[1600x1200]", "[1920x1440]", // Knightmare added "[2048x1536]", "[856x480 ]", // Knightmare added "[1024x480 ]", // Knightmare added "[1280x800 ]", // Knightmare added "[1680x1050]", // Knightmare added "[1920x1200]", // Knightmare added 0 }; static const char *yesno_names[] = { "no", "yes", 0 }; static const char *mip_names[] = { //"none", //"nearest", //"linear", "bilinear", "trilinear", 0 }; static const char *lmh_names[] = { "low", "medium", "high", "highest", 0 }; int y; /*if ( !gl_driver ) gl_driver = Cvar_Get( "gl_driver", "opengl32", 0 ); if ( !gl_picmip ) gl_picmip = Cvar_Get( "gl_picmip", "0", 0 ); if ( !gl_mode ) gl_mode = Cvar_Get( "gl_mode", "3", 0 ); // default to 640x480 if ( !gl_swapinterval ) gl_swapinterval = Cvar_Get( "gl_swapinterval", "1", CVAR_ARCHIVE ); if ( !gl_texturemode ) gl_texturemode = Cvar_Get( "gl_texturemode", "GL_LINEAR_MIPMAP_NEAREST", CVAR_ARCHIVE ); if ( !gl_anisotropic ) gl_anisotropic = Cvar_Get( "gl_anisotropic", "0", CVAR_ARCHIVE ); if ( !gl_anisotropic_avail ) gl_anisotropic_avail = Cvar_Get( "gl_anisotropic_avail", "0", 0 ); if ( !gl_ext_texture_compression ) gl_ext_texture_compression = Cvar_Get( "gl_ext_texture_compression", "0", CVAR_ARCHIVE );*/ s_mode_list.curvalue = Cvar_VariableValue("gl_mode") - 3; // offset for getting rid of < 640x480 resolutions if (s_mode_list.curvalue < 0) s_mode_list.curvalue = 0; // clamp to minimum if ( !con_font_size ) con_font_size = Cvar_Get ("con_font_size", "8", CVAR_ARCHIVE); s_video_menu.x = viddef.width * 0.50; s_video_menu.y = 0; s_video_menu.nitems = 0; y = 0; s_mode_list.generic.type = MTYPE_SPINCONTROL; s_mode_list.generic.name = "video mode"; s_mode_list.generic.x = 0; s_mode_list.generic.y = y; s_mode_list.itemnames = resolutions; s_fs_box.generic.type = MTYPE_SPINCONTROL; s_fs_box.generic.x = 0; s_fs_box.generic.y = y += (MENU_FONT_SIZE+2); //10 s_fs_box.generic.name = "fullscreen"; s_fs_box.itemnames = yesno_names; s_fs_box.curvalue = Cvar_VariableValue("vid_fullscreen"); s_brightness_slider.generic.type = MTYPE_SLIDER; s_brightness_slider.generic.x = 0; s_brightness_slider.generic.y = y += (MENU_FONT_SIZE+2); //20 s_brightness_slider.generic.name = "brightness"; s_brightness_slider.generic.callback = BrightnessCallback; s_brightness_slider.minvalue = 10; // was 5 s_brightness_slider.maxvalue = 26; // was 13 s_brightness_slider.curvalue = ( 1.3 - Cvar_VariableValue("vid_gamma") + 0.5 ) * 20; // was * 10 s_texfilter_box.generic.type = MTYPE_SPINCONTROL; s_texfilter_box.generic.x = 0; s_texfilter_box.generic.y = y += 2*(MENU_FONT_SIZE+2); //40 s_texfilter_box.generic.name = "texture filter"; s_texfilter_box.curvalue = texfilter_box_setval(); s_texfilter_box.itemnames = mip_names; s_aniso_box.generic.type = MTYPE_SPINCONTROL; s_aniso_box.generic.x = 0; s_aniso_box.generic.y = y += (MENU_FONT_SIZE+2); //50 s_aniso_box.generic.name = "anisotropic filter"; s_aniso_box.curvalue = GetAnisoCurValue(); s_aniso_box.itemnames = GetAnisoNames(); s_texqual_box.generic.type = MTYPE_SPINCONTROL; s_texqual_box.generic.x = 0; s_texqual_box.generic.y = y += (MENU_FONT_SIZE+2); //60 s_texqual_box.generic.name = "texture quality"; s_texqual_box.curvalue = ClampCvar (0, 3, 3-Cvar_VariableValue("gl_picmip")); s_texqual_box.itemnames = lmh_names; s_texcompress_box.generic.type = MTYPE_SPINCONTROL; s_texcompress_box.generic.x = 0; s_texcompress_box.generic.y = y += (MENU_FONT_SIZE+2); //70 s_texcompress_box.generic.name = "texture compression"; s_texcompress_box.itemnames = yesno_names; s_texcompress_box.curvalue = Cvar_VariableValue("gl_ext_texture_compression"); s_vsync_box.generic.type = MTYPE_SPINCONTROL; s_vsync_box.generic.x = 0; s_vsync_box.generic.y = y += 2*(MENU_FONT_SIZE+2); //90 s_vsync_box.generic.name = "video sync"; s_vsync_box.generic.callback = VsyncCallback; s_vsync_box.curvalue = Cvar_VariableValue("gl_swapinterval"); s_vsync_box.itemnames = yesno_names; s_vsync_box.generic.statusbar = "sync framerate with monitor refresh"; // Knightmare added s_advanced_action.generic.type = MTYPE_ACTION; s_advanced_action.generic.name = "advanced options"; s_advanced_action.generic.x = 0; s_advanced_action.generic.y = y += 3*(MENU_FONT_SIZE+2); //120 s_advanced_action.generic.callback = AdvancedOptions; s_defaults_action.generic.type = MTYPE_ACTION; s_defaults_action.generic.name = "reset to defaults"; s_defaults_action.generic.x = 0; s_defaults_action.generic.y = y += 3*(MENU_FONT_SIZE+2); //150 s_defaults_action.generic.callback = ResetDefaults; s_defaults_action.generic.statusbar = "reset all video settings to internal defaults"; //Knightmare- changed cancel to apply changes, thanx to MrG s_apply_action.generic.type = MTYPE_ACTION; s_apply_action.generic.name = "apply changes"; s_apply_action.generic.x = 0; s_apply_action.generic.y = y += 2*(MENU_FONT_SIZE+2); //170 s_apply_action.generic.callback = ApplyChanges; //end Knightmare s_backmain_action.generic.type = MTYPE_ACTION; s_backmain_action.generic.name = "back to main"; s_backmain_action.generic.x = 0; s_backmain_action.generic.y = y += 2*(MENU_FONT_SIZE+2); //190 s_backmain_action.generic.callback = M_BackMenu; Menu_AddItem( &s_video_menu, ( void * ) &s_mode_list ); Menu_AddItem( &s_video_menu, ( void * ) &s_fs_box ); Menu_AddItem( &s_video_menu, ( void * ) &s_brightness_slider ); Menu_AddItem( &s_video_menu, ( void * ) &s_texfilter_box ); Menu_AddItem( &s_video_menu, ( void * ) &s_aniso_box ); Menu_AddItem( &s_video_menu, ( void * ) &s_texqual_box ); Menu_AddItem( &s_video_menu, ( void * ) &s_texcompress_box ); Menu_AddItem( &s_video_menu, ( void * ) &s_vsync_box ); Menu_AddItem( &s_video_menu, ( void * ) &s_advanced_action ); // Knightmare added Menu_AddItem( &s_video_menu, ( void * ) &s_defaults_action ); //Knightmare- changed cancel to apply changes, thanx to MrG Menu_AddItem( &s_video_menu, ( void * ) &s_apply_action ); Menu_AddItem( &s_video_menu, ( void * ) &s_backmain_action ); Menu_Center( &s_video_menu ); s_video_menu.x -= MENU_FONT_SIZE; } /* ================ VID_MenuDraw ================ */ void M_Banner( char *name ); void VID_MenuDraw (void) { //int w, h; s_current_menu = &s_video_menu; // draw the banner //R_DrawGetPicSize( &w, &h, "m_banner_video" ); //R_DrawPic( viddef.width / 2 - w / 2, viddef.height /2 - 110, "m_banner_video" ); M_Banner("m_banner_video"); // move cursor to a reasonable starting position Menu_AdjustCursor( &s_video_menu, 1 ); // draw the menu Menu_Draw( &s_video_menu ); } /* ================ VID_MenuKey ================ */ const char *VID_MenuKey( int key ) { menuframework_s *m = s_current_menu; char *sound = NULL; switch ( key ) { case K_ESCAPE: //Knightmare- changed to cancel on exit, thanx to MrG //ApplyChanges( 0 ); CancelChanges(NULL); return NULL; case K_KP_UPARROW: case K_UPARROW: m->cursor--; Menu_AdjustCursor( m, -1 ); sound = "misc/menu1.wav"; break; case K_KP_DOWNARROW: case K_DOWNARROW: m->cursor++; Menu_AdjustCursor( m, 1 ); sound = "misc/menu1.wav"; break; case K_KP_LEFTARROW: case K_LEFTARROW: Menu_SlideItem( m, -1 ); sound = "misc/menu1.wav"; break; case K_KP_RIGHTARROW: case K_RIGHTARROW: Menu_SlideItem( m, 1 ); sound = "misc/menu1.wav"; break; case K_KP_ENTER: case K_ENTER: if ( !Menu_SelectItem( m ) ) ApplyChanges( NULL ); //sound = "misc/menu1.wav"; break; } return sound; } void M_Menu_Video_f (void) { VID_MenuInit(); M_PushMenu( VID_MenuDraw, VID_MenuKey ); }