2010-09-25 17:46:12 +02:00
# include <stdio.h>
# include <string.h>
# include <stdlib.h>
# include <sys/stat.h>
# include "gtk_config.h"
# include "gtk_s9x.h"
# include "gtk_sound.h"
# include "gtk_display.h"
2018-11-02 02:44:06 +01:00
# include "conffile.h"
2010-09-25 17:46:12 +02:00
2018-11-02 02:44:06 +01:00
static int directory_exists ( const char * directory )
2017-05-07 01:39:01 +02:00
{
DIR * dir ;
dir = opendir ( directory ) ;
if ( dir )
{
closedir ( dir ) ;
return TRUE ;
}
return FALSE ;
}
2018-11-02 02:44:06 +01:00
char * get_config_dir ( )
2010-09-25 17:46:12 +02:00
{
2017-05-07 01:39:01 +02:00
char * home_dir = NULL ,
* classic_config_dir = NULL ,
* xdg_config_dir = NULL ,
* xdg_snes9x_dir = NULL ;
2010-09-25 17:46:12 +02:00
/* Find config directory */
2017-05-07 01:39:01 +02:00
home_dir = getenv ( " HOME " ) ;
2017-05-07 01:43:36 +02:00
xdg_config_dir = getenv ( " XDG_CONFIG_HOME " ) ;
2017-05-07 01:39:01 +02:00
if ( ! home_dir & & ! xdg_config_dir )
{
return strdup ( " .snes9x " ) ;
}
if ( ! xdg_config_dir )
{
xdg_snes9x_dir = ( char * ) malloc ( strlen ( home_dir ) + 16 ) ;
sprintf ( xdg_snes9x_dir , " %s/.config/snes9x " , home_dir ) ;
}
else
{
xdg_snes9x_dir = ( char * ) malloc ( strlen ( xdg_config_dir ) + 9 ) ;
sprintf ( xdg_snes9x_dir , " %s/snes9x " , xdg_config_dir ) ;
}
classic_config_dir = ( char * ) malloc ( strlen ( home_dir ) + 9 ) ;
sprintf ( classic_config_dir , " %s/.snes9x " , home_dir ) ;
char * config_dir ;
2010-09-25 17:46:12 +02:00
2017-05-07 01:39:01 +02:00
if ( directory_exists ( classic_config_dir ) & & ! directory_exists ( xdg_snes9x_dir ) )
2010-09-25 17:46:12 +02:00
{
2017-05-07 01:39:01 +02:00
free ( xdg_snes9x_dir ) ;
config_dir = classic_config_dir ;
2010-09-25 17:46:12 +02:00
}
else
{
2017-05-07 01:39:01 +02:00
free ( classic_config_dir ) ;
config_dir = xdg_snes9x_dir ;
2010-09-25 17:46:12 +02:00
}
2017-05-07 01:39:01 +02:00
return config_dir ;
2010-09-25 17:46:12 +02:00
}
2018-11-02 02:44:06 +01:00
char * get_config_file_name ( )
2010-09-25 17:46:12 +02:00
{
char * filename ;
filename = get_config_dir ( ) ;
2018-11-02 02:44:06 +01:00
filename = ( char * ) realloc ( filename , strlen ( filename ) + 16 ) ;
strcat ( filename , " /snes9x.conf " ) ;
2010-09-25 17:46:12 +02:00
return filename ;
}
2018-11-02 02:44:06 +01:00
void S9xParsePortConfig ( ConfigFile & conf , int pass )
2010-09-25 17:46:12 +02:00
{
}
2018-11-02 02:44:06 +01:00
Snes9xConfig : : Snes9xConfig ( )
2010-09-25 17:46:12 +02:00
{
# ifdef USE_JOYSTICK
joystick = NULL ;
2010-10-21 03:55:59 +02:00
joystick_threshold = 40 ;
2010-09-25 17:46:12 +02:00
# endif
# ifdef USE_OPENGL
opengl_activated = FALSE ;
# endif
}
2018-11-02 02:44:06 +01:00
int Snes9xConfig : : load_defaults ( )
2010-09-25 17:46:12 +02:00
{
full_screen_on_open = 0 ;
change_display_resolution = 0 ;
xrr_index = 0 ;
scale_to_fit = 1 ;
2018-11-02 02:44:06 +01:00
maintain_aspect_ratio = 1 ;
aspect_ratio = 2 ;
2010-09-25 17:46:12 +02:00
scale_method = 0 ;
overscan = 0 ;
save_sram_after_secs = 0 ;
rom_loaded = 0 ;
multithreading = 0 ;
hw_accel = 0 ;
allow_opengl = 0 ;
allow_xv = 0 ;
allow_xrandr = 0 ;
force_inverted_byte_order = FALSE ;
2011-01-24 00:07:22 +01:00
hires_effect = HIRES_NORMAL ;
2010-09-25 17:46:12 +02:00
pause_emulation_on_switch = 0 ;
num_threads = 2 ;
mute_sound = FALSE ;
2016-08-02 17:31:05 +02:00
mute_sound_turbo = FALSE ;
2010-09-25 17:46:12 +02:00
fullscreen = FALSE ;
ui_visible = TRUE ;
2010-09-26 11:19:15 +02:00
statusbar_visible = FALSE ;
2010-09-25 17:46:12 +02:00
default_esc_behavior = 1 ;
prevent_screensaver = FALSE ;
sound_driver = 0 ;
2010-09-26 11:19:15 +02:00
sound_buffer_size = 32 ;
2010-09-25 17:46:12 +02:00
sound_playback_rate = 5 ;
sound_input_rate = 31950 ;
2018-05-02 23:53:54 +02:00
auto_input_rate = TRUE ;
2010-09-25 17:46:12 +02:00
last_directory [ 0 ] = ' \0 ' ;
2018-05-12 22:07:07 +02:00
last_shader_directory [ 0 ] = ' \0 ' ;
2010-09-25 17:46:12 +02:00
window_width = - 1 ;
window_height = - 1 ;
preferences_width = - 1 ;
preferences_height = - 1 ;
2010-09-26 11:19:15 +02:00
sram_directory [ 0 ] = ' \0 ' ;
export_directory [ 0 ] = ' \0 ' ;
savestate_directory [ 0 ] = ' \0 ' ;
cheat_directory [ 0 ] = ' \0 ' ;
patch_directory [ 0 ] = ' \0 ' ;
2010-09-25 17:46:12 +02:00
screensaver_needs_reset = FALSE ;
ntsc_setup = snes_ntsc_composite ;
ntsc_scanline_intensity = 1 ;
scanline_filter_intensity = 0 ;
2018-05-14 00:31:25 +02:00
Settings . BilinearFilter = FALSE ;
2010-09-25 17:46:12 +02:00
netplay_activated = FALSE ;
netplay_server_up = FALSE ;
netplay_is_server = FALSE ;
netplay_sync_reset = TRUE ;
netplay_send_rom = FALSE ;
netplay_default_port = 6096 ;
netplay_max_frame_loss = 10 ;
netplay_last_rom [ 0 ] = ' \0 ' ;
netplay_last_host [ 0 ] = ' \0 ' ;
netplay_last_port = 6096 ;
2010-10-30 16:21:26 +02:00
modal_dialogs = 1 ;
2018-11-06 23:30:50 +01:00
current_save_slot = 0 ;
2018-04-26 18:15:20 +02:00
S9xCheatsEnable ( ) ;
2016-10-09 04:33:34 +02:00
rewind_granularity = 5 ;
rewind_buffer_size = 0 ;
2018-05-14 00:31:25 +02:00
Settings . Rewinding = FALSE ;
2010-09-25 17:46:12 +02:00
# ifdef USE_OPENGL
sync_to_vblank = 1 ;
use_pbos = 1 ;
pbo_format = 0 ;
npot_textures = FALSE ;
2010-09-26 11:19:15 +02:00
use_shaders = 0 ;
fragment_shader [ 0 ] = ' \0 ' ;
vertex_shader [ 0 ] = ' \0 ' ;
sync_every_frame = FALSE ;
2010-09-25 17:46:12 +02:00
# endif
/* Snes9X Variables */
Settings . MouseMaster = TRUE ;
Settings . SuperScopeMaster = TRUE ;
Settings . JustifierMaster = TRUE ;
Settings . MultiPlayer5Master = TRUE ;
Settings . UpAndDown = FALSE ;
Settings . AutoSaveDelay = 0 ;
2018-11-02 02:44:06 +01:00
Settings . SkipFrames = 0 ;
2010-09-25 17:46:12 +02:00
Settings . Transparency = TRUE ;
Settings . DisplayFrameRate = FALSE ;
Settings . SixteenBitSound = TRUE ;
Settings . Stereo = TRUE ;
Settings . ReverseStereo = FALSE ;
Settings . SoundPlaybackRate = 32000 ;
Settings . StopEmulation = TRUE ;
Settings . FrameTimeNTSC = 16667 ;
Settings . FrameTimePAL = 20000 ;
Settings . SupportHiRes = true ;
Settings . FrameTime = Settings . FrameTimeNTSC ;
Settings . BlockInvalidVRAMAccessMaster = TRUE ;
2018-10-29 01:46:08 +01:00
Settings . SoundSync = 0 ;
2018-05-03 00:44:22 +02:00
Settings . DynamicRateControl = FALSE ;
2017-11-24 20:03:24 +01:00
Settings . DynamicRateLimit = 5 ;
2018-08-06 19:31:07 +02:00
Settings . InterpolationMethod = DSP_INTERPOLATION_GAUSSIAN ;
2010-09-25 17:46:12 +02:00
Settings . HDMATimingHack = 100 ;
2018-05-08 00:03:06 +02:00
Settings . SuperFXClockMultiplier = 100 ;
2018-08-12 02:19:04 +02:00
# ifdef ALLOW_CPU_OVERCLOCK
Settings . MaxSpriteTilesPerLine = 34 ;
Settings . OneClockCycle = 6 ;
Settings . OneSlowClockCycle = 8 ;
Settings . TwoClockCycles = 12 ;
# endif
2010-09-25 17:46:12 +02:00
# ifdef NETPLAY_SUPPORT
Settings . NetPlay = FALSE ;
NetPlay . Paused = FALSE ;
NetPlay . MaxFrameSkip = 10 ;
# endif
memset ( pad , 0 , sizeof ( JoypadBinding ) * NUM_JOYPADS ) ;
memset ( shortcut , 0 , sizeof ( Binding ) * NUM_EMU_LINKS ) ;
return 0 ;
}
# ifdef USE_JOYSTICK
2018-11-02 02:44:06 +01:00
void Snes9xConfig : : joystick_register_centers ( )
2010-09-25 17:46:12 +02:00
{
for ( int i = 0 ; joystick [ i ] ! = NULL ; i + + )
joystick [ i ] - > register_centers ( ) ;
}
2018-11-02 02:44:06 +01:00
void Snes9xConfig : : flush_joysticks ( )
2010-09-25 17:46:12 +02:00
{
int i ;
for ( i = 0 ; joystick [ i ] ! = NULL ; i + + )
joystick [ i ] - > flush ( ) ;
}
2018-11-02 02:44:06 +01:00
void Snes9xConfig : : set_joystick_mode ( int mode )
2010-09-25 17:46:12 +02:00
{
int i ;
for ( i = 0 ; joystick [ i ] ! = NULL ; i + + )
joystick [ i ] - > mode = mode ;
}
# endif
2018-11-02 02:44:06 +01:00
static inline void outbool ( ConfigFile & cf , const char * key , bool value , const char * comment = " " )
2010-09-25 17:46:12 +02:00
{
2018-11-02 02:44:06 +01:00
cf . SetBool ( key , value , " true " , " false " , comment ) ;
}
2010-09-25 17:46:12 +02:00
2018-11-02 02:44:06 +01:00
int Snes9xConfig : : save_config_file ( )
{
char * filename ;
char key [ PATH_MAX ] ;
char buffer [ PATH_MAX ] ;
ConfigFile cf ;
# undef z
# define z "Display::"
outbool ( cf , z " FullscreenOnOpen " , full_screen_on_open , " Set the screen resolution after opening a ROM " ) ;
outbool ( cf , z " ChangeDisplayResolution " , change_display_resolution , " Set the resolution in fullscreen mode " ) ;
cf . SetInt ( z " VideoMode " , xrr_index , " Platform-specific video mode number " ) ;
outbool ( cf , z " ScaleToFit " , scale_to_fit , " Scale the image to fit the window size " ) ;
outbool ( cf , z " MaintainAspectRatio " , maintain_aspect_ratio , " Resize the screen to the proportions set by aspect ratio option " ) ;
2018-11-06 01:40:16 +01:00
cf . SetInt ( z " AspectRatio " , aspect_ratio , " 0: uncorrected, 1: uncorrected integer scale, 2: 4:3, 3: 4/3 integer scale, 4: NTSC/PAL, 5: NTSC/PAL integer scale " ) ;
2018-11-02 02:44:06 +01:00
cf . SetInt ( z " SoftwareScaleFilter " , scale_method , " Build-specific number of filter used for software scaling " ) ;
2018-11-06 01:40:16 +01:00
cf . SetInt ( z " ScanlineFilterIntensity " , scanline_filter_intensity , " 0: 0%, 1: 12.5%, 2: 25%, 3: 50%, 4: 100% " ) ;
2018-11-02 02:44:06 +01:00
outbool ( cf , z " ShowOverscanArea " , overscan ) ;
cf . SetInt ( z " HiresEffect " , hires_effect , " 0: Downscale to low-res, 1: Leave as-is, 2: Upscale low-res screens " ) ;
cf . SetInt ( z " ForceInvertedByteOrder " , force_inverted_byte_order ) ;
2018-11-06 01:40:16 +01:00
outbool ( cf , z " Multithreading " , multithreading , " Apply filters using multiple threads " ) ;
2018-11-02 02:44:06 +01:00
cf . SetInt ( z " NumberOfThreads " , num_threads ) ;
cf . SetInt ( z " HardwareAcceleration " , hw_accel , " 0: None, 1: OpenGL, 2: XVideo " ) ;
2018-11-06 01:40:16 +01:00
outbool ( cf , z " BilinearFilter " , Settings . BilinearFilter , " Smoothes scaled image " ) ;
2018-11-02 02:44:06 +01:00
# undef z
# define z "NTSC::"
cf . SetString ( z " Hue " , std : : to_string ( ntsc_setup . hue ) ) ;
cf . SetString ( z " Saturation " , std : : to_string ( ntsc_setup . saturation ) ) ;
cf . SetString ( z " Contrast " , std : : to_string ( ntsc_setup . contrast ) ) ;
cf . SetString ( z " Brightness " , std : : to_string ( ntsc_setup . brightness ) ) ;
cf . SetString ( z " Sharpness " , std : : to_string ( ntsc_setup . sharpness ) ) ;
cf . SetString ( z " Artifacts " , std : : to_string ( ntsc_setup . artifacts ) ) ;
cf . SetString ( z " Gamma " , std : : to_string ( ntsc_setup . gamma ) ) ;
cf . SetString ( z " Bleed " , std : : to_string ( ntsc_setup . bleed ) ) ;
cf . SetString ( z " Fringing " , std : : to_string ( ntsc_setup . fringing ) ) ;
cf . SetString ( z " Resolution " , std : : to_string ( ntsc_setup . resolution ) ) ;
2018-11-02 03:10:50 +01:00
outbool ( cf , z " MergeFields " , ntsc_setup . merge_fields ) ;
2018-11-02 02:44:06 +01:00
cf . SetInt ( z " ScanlineIntensity " , ntsc_scanline_intensity ) ;
2016-10-09 04:33:34 +02:00
2010-09-25 17:46:12 +02:00
# ifdef USE_OPENGL
2018-11-02 02:44:06 +01:00
# undef z
# define z "OpenGL::"
outbool ( cf , z " VSync " , sync_to_vblank ) ;
outbool ( cf , z " ReduceInputLag " , sync_every_frame ) ;
outbool ( cf , z " UsePixelBufferObjects " , use_pbos ) ;
cf . SetInt ( z " PixelBufferObjectBitDepth " , pbo_format ) ;
outbool ( cf , z " UseNonPowerOfTwoTextures " , npot_textures ) ;
outbool ( cf , z " EnableCustomShaders " , use_shaders ) ;
cf . SetString ( z " ShaderFile " , fragment_shader ) ;
2010-09-25 17:46:12 +02:00
# endif
2018-11-02 02:44:06 +01:00
# undef z
# define z "Sound::"
outbool ( cf , z " MuteSound " , mute_sound ) ;
outbool ( cf , z " MuteSoundDuringTurbo " , mute_sound_turbo ) ;
2018-11-06 01:40:16 +01:00
cf . SetInt ( z " BufferSize " , sound_buffer_size , " Buffer size in milliseconds " ) ;
2018-11-02 02:44:06 +01:00
cf . SetInt ( z " Driver " , sound_driver ) ;
cf . SetInt ( z " InputRate " , sound_input_rate ) ;
outbool ( cf , z " DynamicRateControl " , Settings . DynamicRateControl ) ;
cf . SetInt ( z " DynamicRateControlLimit " , Settings . DynamicRateLimit ) ;
2018-11-06 01:40:16 +01:00
outbool ( cf , z " AutomaticInputRate " , auto_input_rate , " Guess input rate by asking the monitor what its refresh rate is " ) ;
2018-11-02 02:44:06 +01:00
outbool ( cf , z " 16bit " , Settings . SixteenBitSound ) ;
outbool ( cf , z " Stereo " , Settings . Stereo ) ;
2018-11-06 01:40:16 +01:00
outbool ( cf , z " ReverseStereo " , Settings . ReverseStereo ) ;
cf . SetInt ( z " PlaybackRate " , gui_config - > sound_playback_rate , " 1: 8000Hz, 2: 11025Hz, 3: 16000Hz, 4: 22050Hz, 5: 32000Hz, 6: 44100Hz, 7: 48000Hz " ) ;
2018-11-02 02:44:06 +01:00
# undef z
# define z "Files::"
cf . SetString ( z " LastDirectory " , last_directory ) ;
cf . SetString ( z " LastShaderDirectory " , last_shader_directory ) ;
cf . SetString ( z " SRAMDirectory " , sram_directory ) ;
cf . SetString ( z " SaveStateDirectory " , savestate_directory ) ;
cf . SetString ( z " CheatDirectory " , cheat_directory ) ;
cf . SetString ( z " PatchDirectory " , patch_directory ) ;
cf . SetString ( z " ExportDirectory " , export_directory ) ;
# undef z
# define z "Window State::"
cf . SetInt ( z " MainWidth " , window_width ) ;
cf . SetInt ( z " MainHeight " , window_height ) ;
cf . SetInt ( z " PreferencesWidth " , preferences_width ) ;
cf . SetInt ( z " PreferencesHeight " , preferences_height ) ;
outbool ( cf , z " UIVisible " , ui_visible ) ;
outbool ( cf , z " StatusBarVisible " , statusbar_visible ) ;
if ( default_esc_behavior ! = ESC_TOGGLE_MENUBAR )
outbool ( cf , z " Fullscreen " , 0 ) ;
else
outbool ( cf , z " Fullscreen " , fullscreen ) ;
# undef z
# define z "Netplay::"
outbool ( cf , z " ActAsServer " , netplay_is_server ) ;
outbool ( cf , z " UseResetToSync " , netplay_sync_reset ) ;
outbool ( cf , z " SendROM " , netplay_send_rom ) ;
cf . SetInt ( z " DefaultPort " , netplay_default_port ) ;
cf . SetInt ( z " MaxFrameLoss " , netplay_max_frame_loss ) ;
cf . SetInt ( z " LastUsedPort " , netplay_last_port ) ;
cf . SetString ( z " LastUsedROM " , netplay_last_rom ) ;
cf . SetString ( z " LastUsedHost " , netplay_last_host ) ;
# undef z
# define z "Behavior::"
outbool ( cf , z " PauseEmulationWhenFocusLost " , pause_emulation_on_switch ) ;
cf . SetInt ( z " DefaultESCKeyBehavior " , default_esc_behavior ) ;
outbool ( cf , z " PreventScreensaver " , prevent_screensaver ) ;
outbool ( cf , z " UseModalDialogs " , modal_dialogs ) ;
2018-11-06 01:40:16 +01:00
cf . SetInt ( z " RewindBufferSize " , rewind_buffer_size , " Amount of memory (in MB) to use for rewinding " ) ;
cf . SetInt ( z " RewindGranularity " , rewind_granularity , " Only save rewind snapshots every N frames " ) ;
2018-11-06 23:30:50 +01:00
cf . SetInt ( z " CurrentSaveSlot " , current_save_slot ) ;
2018-11-02 02:44:06 +01:00
# undef z
# define z "Emulation::"
outbool ( cf , z " EmulateTransparency " , Settings . Transparency ) ;
outbool ( cf , z " DisplayFrameRate " , Settings . DisplayFrameRate ) ;
2018-11-06 01:40:16 +01:00
cf . SetInt ( z " SpeedControlMethod " , Settings . SkipFrames , " 0: Time the frames to 50 or 60Hz, 1: Same, but skip frames if too slow, 2: Synchronize to the sound buffer, 3: Unlimited, except potentially by vsync " ) ;
2018-11-02 02:44:06 +01:00
cf . SetInt ( z " SaveSRAMEveryNSeconds " , Settings . AutoSaveDelay ) ;
outbool ( cf , z " BlockInvalidVRAMAccess " , Settings . BlockInvalidVRAMAccessMaster ) ;
2018-11-06 01:40:16 +01:00
outbool ( cf , z " AllowDPadContradictions " , Settings . UpAndDown , " Allow the D-Pad to press both up + down at the same time, or left + right " ) ;
2018-11-02 02:44:06 +01:00
# undef z
# define z "Hacks::"
cf . SetInt ( z " SuperFXClockMultiplier " , Settings . SuperFXClockMultiplier ) ;
2018-11-06 01:40:16 +01:00
cf . SetInt ( z " SoundInterpolationMethod " , Settings . InterpolationMethod , " 0: None, 1: Linear, 2: Gaussian (what the hardware uses), 3: Cubic, 4: Sinc " ) ;
2018-11-02 02:44:06 +01:00
outbool ( cf , z " RemoveSpriteLimit " , Settings . MaxSpriteTilesPerLine = = 34 ? 0 : 1 ) ;
outbool ( cf , z " OverclockCPU " , Settings . OneClockCycle = = 6 ? 0 : 1 ) ;
2010-09-25 17:46:12 +02:00
2018-11-02 02:44:06 +01:00
# undef z
# define z "Input::"
2018-11-08 21:59:24 +01:00
controllers controller = CTL_NONE ;
int8 id [ 4 ] ;
for ( int i = 0 ; i < 2 ; i + + )
{
const char * output_string ;
snprintf ( buffer , PATH_MAX , z " ControllerPort%d " , i ) ;
S9xGetController ( i , & controller , & id [ 0 ] , & id [ 1 ] , & id [ 2 ] , & id [ 3 ] ) ;
switch ( controller )
{
case CTL_JOYPAD :
output_string = " joypad " ;
break ;
case CTL_MOUSE :
output_string = " mouse " ;
break ;
case CTL_SUPERSCOPE :
output_string = " superscope " ;
break ;
case CTL_MP5 :
output_string = " multitap " ;
break ;
case CTL_JUSTIFIER :
output_string = " justifier " ;
break ;
default :
output_string = " none " ;
}
cf . SetString ( buffer , output_string ) ;
}
# ifdef USE_JOYSTICK
2018-11-02 03:10:50 +01:00
cf . SetInt ( z " JoystickThreshold " , joystick_threshold ) ;
2010-09-25 17:46:12 +02:00
# endif
2018-11-02 02:44:06 +01:00
# undef z
2010-09-25 17:46:12 +02:00
for ( int i = 0 ; i < NUM_JOYPADS ; i + + )
{
Binding * joypad = ( Binding * ) & pad [ i ] ;
for ( int j = 0 ; j < NUM_JOYPAD_LINKS ; j + + )
{
2018-11-02 02:44:06 +01:00
snprintf ( key , PATH_MAX , " Joypad %d::%s " , i , b_links [ j ] . snes9x_name ) ;
2018-11-14 21:51:39 +01:00
joypad [ j ] . to_string ( buffer , false ) ;
2018-11-02 02:44:06 +01:00
cf . SetString ( key , std : : string ( buffer ) ) ;
2010-09-25 17:46:12 +02:00
}
}
for ( int i = NUM_JOYPAD_LINKS ; b_links [ i ] . snes9x_name ; i + + )
{
2018-11-02 02:44:06 +01:00
snprintf ( key , PATH_MAX , " Shortcuts::%s " , b_links [ i ] . snes9x_name ) ;
2018-11-14 21:51:39 +01:00
shortcut [ i - NUM_JOYPAD_LINKS ] . to_string ( buffer , false ) ;
2018-11-02 02:44:06 +01:00
cf . SetString ( key , std : : string ( buffer ) ) ;
2010-09-25 17:46:12 +02:00
}
2018-11-02 02:44:06 +01:00
filename = get_config_file_name ( ) ;
2018-11-02 03:10:50 +01:00
cf . SetNiceAlignment ( true ) ;
cf . SetShowComments ( true ) ;
2018-11-02 02:44:06 +01:00
cf . SaveTo ( filename ) ;
free ( filename ) ;
2010-09-25 17:46:12 +02:00
return 0 ;
}
2018-11-02 02:44:06 +01:00
int Snes9xConfig : : load_config_file ( )
2010-09-25 17:46:12 +02:00
{
2018-11-02 02:44:06 +01:00
struct stat file_info ;
char * pathname ;
ConfigFile cf ;
char key [ PATH_MAX ] ;
char buffer [ PATH_MAX ] ;
2010-09-25 17:46:12 +02:00
2018-11-02 02:44:06 +01:00
load_defaults ( ) ;
2010-09-25 17:46:12 +02:00
2018-11-02 02:44:06 +01:00
pathname = get_config_dir ( ) ;
2010-09-25 17:46:12 +02:00
2018-11-02 02:44:06 +01:00
if ( stat ( pathname , & file_info ) )
2010-09-25 17:46:12 +02:00
{
2018-11-02 02:44:06 +01:00
if ( mkdir ( pathname , 0755 ) )
2010-09-25 17:46:12 +02:00
{
2018-11-02 02:44:06 +01:00
fprintf ( stderr ,
_ ( " Couldn't create config directory: %s \n " ) ,
pathname ) ;
return - 1 ;
2010-09-25 17:46:12 +02:00
}
}
else
{
2018-11-02 02:44:06 +01:00
chmod ( pathname , 0755 ) ;
2010-09-25 17:46:12 +02:00
}
2018-11-02 02:44:06 +01:00
free ( pathname ) ;
2010-09-25 17:46:12 +02:00
2018-11-02 02:44:06 +01:00
pathname = get_config_file_name ( ) ;
2010-09-25 17:46:12 +02:00
2018-11-02 02:44:06 +01:00
if ( stat ( pathname , & file_info ) )
2010-09-25 17:46:12 +02:00
{
2018-11-02 02:44:06 +01:00
save_config_file ( ) ;
2010-09-25 17:46:12 +02:00
}
2018-11-02 02:44:06 +01:00
if ( ! cf . LoadFile ( pathname ) )
return - 1 ;
2010-09-25 17:46:12 +02:00
2018-11-02 02:44:06 +01:00
free ( pathname ) ;
2010-09-25 17:46:12 +02:00
2018-11-02 02:44:06 +01:00
std : : string none ;
# define inbool(key, var) var = cf.GetBool (key)
# define inint(key, var) var = cf.GetInt (key)
# define infloat(key, var) var = atof (cf.GetString (key, none).c_str())
# define instr(key, var) strcpy (var, cf.GetString (key, none).c_str())
# undef z
# define z "Display::"
inbool ( z " FullscreenOnOpen " , full_screen_on_open ) ;
inbool ( z " ChangeDisplayResolution " , change_display_resolution ) ;
inint ( z " VideoMode " , xrr_index ) ;
inbool ( z " ScaleToFit " , scale_to_fit ) ;
inbool ( z " MaintainAspectRatio " , maintain_aspect_ratio ) ;
inint ( z " AspectRatio " , aspect_ratio ) ;
inint ( z " SoftwareScaleFilter " , scale_method ) ;
inint ( z " ScanlineFilterIntensity " , scanline_filter_intensity ) ;
inbool ( z " ShowOverscanArea " , overscan ) ;
inint ( z " HiresEffect " , hires_effect ) ;
inint ( z " ForceInvertedByteOrder " , force_inverted_byte_order ) ;
inbool ( z " Multithreading " , multithreading ) ;
inint ( z " NumberOfThreads " , num_threads ) ;
inint ( z " HardwareAcceleration " , hw_accel ) ;
inbool ( z " BilinearFilter " , Settings . BilinearFilter ) ;
# undef z
# define z "NTSC::"
infloat ( z " Hue " , ntsc_setup . hue ) ;
infloat ( z " Saturation " , ntsc_setup . saturation ) ;
infloat ( z " Contrast " , ntsc_setup . contrast ) ;
infloat ( z " Brightness " , ntsc_setup . brightness ) ;
infloat ( z " Sharpness " , ntsc_setup . sharpness ) ;
infloat ( z " Artifacts " , ntsc_setup . artifacts ) ;
infloat ( z " Gamma " , ntsc_setup . gamma ) ;
infloat ( z " Bleed " , ntsc_setup . bleed ) ;
infloat ( z " Fringing " , ntsc_setup . fringing ) ;
infloat ( z " Resolution " , ntsc_setup . resolution ) ;
2018-11-02 03:10:50 +01:00
inbool ( z " MergeFields " , ntsc_setup . merge_fields ) ;
2018-11-02 02:44:06 +01:00
inint ( z " ScanlineIntensity " , ntsc_scanline_intensity ) ;
2010-09-25 17:46:12 +02:00
2018-11-02 02:44:06 +01:00
# ifdef USE_OPENGL
# undef z
# define z "OpenGL::"
inbool ( z " VSync " , sync_to_vblank ) ;
inbool ( z " ReduceInputLag " , sync_every_frame ) ;
inbool ( z " UsePixelBufferObjects " , use_pbos ) ;
inint ( z " PixelBufferObjectBitDepth " , pbo_format ) ;
inbool ( z " UseNonPowerOfTwoTextures " , npot_textures ) ;
inbool ( z " EnableCustomShaders " , use_shaders ) ;
instr ( z " ShaderFile " , fragment_shader ) ;
2010-09-25 17:46:12 +02:00
# endif
2018-11-02 02:44:06 +01:00
# undef z
# define z "Sound::"
inbool ( z " MuteSound " , mute_sound ) ;
inbool ( z " MuteSoundDuringTurbo " , mute_sound_turbo ) ;
inint ( z " BufferSize " , sound_buffer_size ) ;
inint ( z " Driver " , sound_driver ) ;
inint ( z " InputRate " , sound_input_rate ) ;
inbool ( z " DynamicRateControl " , Settings . DynamicRateControl ) ;
inint ( z " DynamicRateControlLimit " , Settings . DynamicRateLimit ) ;
inbool ( z " AutomaticInputRate " , auto_input_rate ) ;
inbool ( z " 16bit " , Settings . SixteenBitSound ) ;
inbool ( z " Stereo " , Settings . Stereo ) ;
2018-11-06 01:40:16 +01:00
inbool ( z " ReverseStereo " , Settings . ReverseStereo ) ;
2018-11-02 02:44:06 +01:00
inint ( z " PlaybackRate " , gui_config - > sound_playback_rate ) ;
# undef z
# define z "Files::"
instr ( z " LastDirectory " , last_directory ) ;
instr ( z " LastShaderDirectory " , last_shader_directory ) ;
instr ( z " SRAMDirectory " , sram_directory ) ;
instr ( z " SaveStateDirectory " , savestate_directory ) ;
instr ( z " CheatDirectory " , cheat_directory ) ;
instr ( z " PatchDirectory " , patch_directory ) ;
instr ( z " ExportDirectory " , export_directory ) ;
# undef z
# define z "Window State::"
inint ( z " MainWidth " , window_width ) ;
inint ( z " MainHeight " , window_height ) ;
inint ( z " PreferencesWidth " , preferences_width ) ;
inint ( z " PreferencesHeight " , preferences_height ) ;
inbool ( z " UIVisible " , ui_visible ) ;
inbool ( z " StatusBarVisible " , statusbar_visible ) ;
inbool ( z " Fullscreen " , fullscreen ) ;
# undef z
# define z "Netplay::"
inbool ( z " ActAsServer " , netplay_is_server ) ;
inbool ( z " UseResetToSync " , netplay_sync_reset ) ;
inbool ( z " SendROM " , netplay_send_rom ) ;
inint ( z " DefaultPort " , netplay_default_port ) ;
inint ( z " MaxFrameLoss " , netplay_max_frame_loss ) ;
inint ( z " LastUsedPort " , netplay_last_port ) ;
instr ( z " LastUsedROM " , netplay_last_rom ) ;
instr ( z " LastUsedHost " , netplay_last_host ) ;
# undef z
# define z "Behavior::"
inbool ( z " PauseEmulationWhenFocusLost " , pause_emulation_on_switch ) ;
inint ( z " DefaultESCKeyBehavior " , default_esc_behavior ) ;
inbool ( z " PreventScreensaver " , prevent_screensaver ) ;
inbool ( z " UseModalDialogs " , modal_dialogs ) ;
2018-11-06 01:40:16 +01:00
inint ( z " RewindBufferSize " , rewind_buffer_size ) ;
inint ( z " RewindGranularity " , rewind_granularity ) ;
2018-11-06 23:30:50 +01:00
inint ( z " CurrentSaveSlot " , current_save_slot ) ;
2018-11-02 02:44:06 +01:00
# undef z
# define z "Emulation::"
inbool ( z " EmulateTransparency " , Settings . Transparency ) ;
inbool ( z " DisplayFrameRate " , Settings . DisplayFrameRate ) ;
inint ( z " SpeedControlMethod " , Settings . SkipFrames ) ;
inint ( z " SaveSRAMEveryNSeconds " , Settings . AutoSaveDelay ) ;
inbool ( z " BlockInvalidVRAMAccess " , Settings . BlockInvalidVRAMAccessMaster ) ;
inbool ( z " AllowDPadContradictions " , Settings . UpAndDown ) ;
# undef z
# define z "Hacks::"
inint ( z " SuperFXClockMultiplier " , Settings . SuperFXClockMultiplier ) ;
inint ( z " SoundInterpolationMethod " , Settings . InterpolationMethod ) ;
bool RemoveSpriteLimit ;
inbool ( z " RemoveSpriteLimit " , RemoveSpriteLimit ) ;
bool OverclockCPU ;
inbool ( z " OverclockCPU " , OverclockCPU ) ;
2010-09-25 17:46:12 +02:00
2018-11-02 02:44:06 +01:00
# undef z
# define z "Input::"
2018-11-08 21:59:24 +01:00
for ( int i = 0 ; i < 2 ; i + + )
{
snprintf ( buffer , PATH_MAX , z " ControllerPort%d " , i ) ;
std : : string tmp = cf . GetString ( buffer , " " ) ;
if ( tmp . find ( " joypad " ) ! = std : : string : : npos )
S9xSetController ( i , CTL_JOYPAD , i , 0 , 0 , 0 ) ;
else if ( tmp . find ( " multitap " ) ! = std : : string : : npos )
S9xSetController ( i , CTL_MP5 , i , i + 1 , i + 2 , i + 3 ) ;
else if ( tmp . find ( " superscope " ) ! = std : : string : : npos )
S9xSetController ( i , CTL_SUPERSCOPE , 0 , 0 , 0 , 0 ) ;
else if ( tmp . find ( " mouse " ) ! = std : : string : : npos )
S9xSetController ( i , CTL_MOUSE , i , 0 , 0 , 0 ) ;
}
# ifdef USE_JOYSTICK
2018-11-02 03:10:50 +01:00
inint ( z " JoystickThreshold " , joystick_threshold ) ;
2010-09-25 17:46:12 +02:00
# endif
2018-11-08 21:59:24 +01:00
# undef z
2010-09-25 17:46:12 +02:00
2018-11-02 02:44:06 +01:00
for ( int i = 0 ; i < NUM_JOYPADS ; i + + )
2010-09-25 17:46:12 +02:00
{
2018-11-02 02:44:06 +01:00
Binding * joypad = ( Binding * ) & pad [ i ] ;
2010-09-25 17:46:12 +02:00
2018-11-02 02:44:06 +01:00
for ( int j = 0 ; j < NUM_JOYPAD_LINKS ; j + + )
2010-09-25 17:46:12 +02:00
{
2018-11-02 02:44:06 +01:00
snprintf ( key , PATH_MAX , " Joypad %d::%s " , i , b_links [ j ] . snes9x_name ) ;
instr ( key , buffer ) ;
joypad [ j ] = Binding ( buffer ) ;
2010-09-25 17:46:12 +02:00
}
}
2018-11-02 02:44:06 +01:00
for ( int i = NUM_JOYPAD_LINKS ; b_links [ i ] . snes9x_name ; i + + )
{
snprintf ( key , PATH_MAX , " Shortcuts::%s " , b_links [ i ] . snes9x_name ) ;
instr ( key , buffer ) ;
shortcut [ i - NUM_JOYPAD_LINKS ] = Binding ( buffer ) ;
}
2010-09-25 17:46:12 +02:00
2018-11-02 02:44:06 +01:00
/* Validation */
2010-09-25 17:46:12 +02:00
2018-11-02 02:44:06 +01:00
if ( RemoveSpriteLimit )
Settings . MaxSpriteTilesPerLine = 128 ;
else
Settings . MaxSpriteTilesPerLine = 34 ;
2010-09-25 17:46:12 +02:00
2018-11-02 02:44:06 +01:00
if ( OverclockCPU )
2010-09-25 17:46:12 +02:00
{
2018-11-02 02:44:06 +01:00
Settings . OneClockCycle = 4 ;
Settings . OneSlowClockCycle = 5 ;
Settings . TwoClockCycles = 6 ;
2010-09-25 17:46:12 +02:00
}
2010-09-26 11:19:15 +02:00
else
{
2018-11-02 02:44:06 +01:00
Settings . OneClockCycle = 6 ;
Settings . OneSlowClockCycle = 8 ;
Settings . TwoClockCycles = 12 ;
2010-09-25 17:46:12 +02:00
}
2018-11-02 02:44:06 +01:00
if ( default_esc_behavior ! = ESC_TOGGLE_MENUBAR )
fullscreen = false ;
2010-09-25 17:46:12 +02:00
2018-11-02 02:44:06 +01:00
# ifdef USE_HQ2X
if ( scale_method > = NUM_FILTERS )
scale_method = 0 ;
# else
if ( scale_method > = NUM_FILTERS - 3 )
scale_method = 0 ;
# endif /* USE_HQ2X */
2010-09-25 17:46:12 +02:00
2018-11-02 02:44:06 +01:00
# ifdef USE_XBRZ
if ( scale_method > = NUM_FILTERS )
scale_method = 0 ;
# else
if ( scale_method > = NUM_FILTERS - 3 )
scale_method = 0 ;
# endif /* USE_XBRZ */
2010-09-25 17:46:12 +02:00
2018-11-02 02:44:06 +01:00
# ifdef USE_OPENGL
if ( pbo_format ! = 32 )
pbo_format = 16 ;
# endif
2010-09-25 17:46:12 +02:00
2018-11-02 02:44:06 +01:00
if ( Settings . SkipFrames = = THROTTLE_SOUND_SYNC )
Settings . SoundSync = 1 ;
else
Settings . SoundSync = 0 ;
2010-09-25 17:46:12 +02:00
2018-11-02 02:44:06 +01:00
hires_effect = CLAMP ( hires_effect , 0 , 2 ) ;
Settings . DynamicRateLimit = CLAMP ( Settings . DynamicRateLimit , 1 , 1000 ) ;
Settings . SuperFXClockMultiplier = CLAMP ( Settings . SuperFXClockMultiplier , 50 , 400 ) ;
ntsc_scanline_intensity = MAX ( ntsc_scanline_intensity , 4 ) ;
scanline_filter_intensity = MAX ( scanline_filter_intensity , 3 ) ;
2010-10-22 04:18:56 +02:00
2010-09-25 17:46:12 +02:00
return 0 ;
}
2018-11-02 02:44:06 +01:00
void Snes9xConfig : : rebind_keys ( )
2010-09-25 17:46:12 +02:00
{
s9xcommand_t cmd ;
char buf [ 256 ] ;
S9xUnmapAllControls ( ) ;
for ( int joypad_i = 0 ; joypad_i < NUM_JOYPADS ; joypad_i + + )
{
Binding * bin = ( Binding * ) & pad [ joypad_i ] ;
for ( int button_i = 0 ; button_i < NUM_JOYPAD_LINKS ; button_i + + )
{
snprintf ( buf ,
256 ,
" Joypad%d %s " ,
( joypad_i % 5 ) + 1 ,
b_links [ button_i ] . snes9x_name ) ;
cmd = S9xGetPortCommandT ( buf ) ;
S9xMapButton ( bin [ button_i ] . base_hex ( ) , cmd , FALSE ) ;
}
}
for ( int i = NUM_JOYPAD_LINKS ; b_links [ i ] . snes9x_name ; i + + )
{
snprintf ( buf , 256 , " %s " , b_links [ i ] . snes9x_name ) ;
cmd = S9xGetPortCommandT ( buf ) ;
S9xMapButton ( shortcut [ i - NUM_JOYPAD_LINKS ] . base_hex ( ) ,
cmd ,
FALSE ) ;
}
cmd = S9xGetPortCommandT ( " Pointer Mouse1+Superscope+Justifier1 " ) ;
S9xMapPointer ( BINDING_MOUSE_POINTER , cmd , TRUE ) ;
cmd = S9xGetPortCommandT ( " {Mouse1 L,Superscope Fire,Justifier1 Trigger} " ) ;
S9xMapButton ( BINDING_MOUSE_BUTTON0 , cmd , FALSE ) ;
cmd = S9xGetPortCommandT ( " {Justifier1 AimOffscreen Trigger,Superscope AimOffscreen} " ) ;
S9xMapButton ( BINDING_MOUSE_BUTTON1 , cmd , FALSE ) ;
cmd = S9xGetPortCommandT ( " {Mouse1 R,Superscope Cursor,Justifier1 Start} " ) ;
S9xMapButton ( BINDING_MOUSE_BUTTON2 , cmd , FALSE ) ;
}
2018-11-02 02:44:06 +01:00
void Snes9xConfig : : reconfigure ( )
2010-09-25 17:46:12 +02:00
{
rebind_keys ( ) ;
}