Merge branch 'master' into master

This commit is contained in:
bearoso 2020-06-30 14:13:50 -05:00 committed by GitHub
commit fd558dbd05
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 426 additions and 418 deletions

View File

@ -3515,11 +3515,17 @@ void S9xControlPreSaveState (struct SControlSnapshot *s)
for (int k = 0; k < 2; k++) for (int k = 0; k < 2; k++)
COPY(mp5[j].pads[k]); COPY(mp5[j].pads[k]);
assert(i == sizeof(s->internal));
#undef COPY
#define COPY(x) { memcpy((char *) s->internal_macs + i, &(x), sizeof(x)); i += sizeof(x); }
i = 0;
COPY(macsrifle.x); COPY(macsrifle.x);
COPY(macsrifle.y); COPY(macsrifle.y);
COPY(macsrifle.buttons); COPY(macsrifle.buttons);
assert(i == sizeof(s->internal) + sizeof(s->internal_macs)); assert(i == sizeof(s->internal_macs));
#undef COPY #undef COPY
@ -3594,11 +3600,15 @@ void S9xControlPostLoadState (struct SControlSnapshot *s)
if (s->ver > 3) if (s->ver > 3)
{ {
#undef COPY
#define COPY(x) { memcpy(&(x), (char *) s->internal_macs + i, sizeof(x)); i += sizeof(x); }
i = 0;
COPY(macsrifle.x); COPY(macsrifle.x);
COPY(macsrifle.y); COPY(macsrifle.y);
COPY(macsrifle.buttons); COPY(macsrifle.buttons);
assert(i == sizeof(s->internal) + sizeof(s->internal_macs)); assert(i == sizeof(s->internal_macs));
} }
#undef COPY #undef COPY

View File

@ -1,7 +1,7 @@
project('snes9x-gtk', project('snes9x-gtk',
['c', 'cpp'], ['c', 'cpp'],
version: '1.60', version: '1.60',
default_options: ['cpp_std=c++11']) default_options: ['cpp_std=c++14'])
args = ['-DSNES9X_GTK', '-DUNZIP_SUPPORT', '-DNETPLAY_SUPPORT', '-DJMA_SUPPORT', '-Wall', '-W', '-Wno-unused-parameter'] args = ['-DSNES9X_GTK', '-DUNZIP_SUPPORT', '-DNETPLAY_SUPPORT', '-DJMA_SUPPORT', '-Wall', '-W', '-Wno-unused-parameter']
srcs = [] srcs = []

View File

@ -1305,11 +1305,13 @@ msgid "Disables output of sound"
msgstr "Desactivar la salida de sonido" msgstr "Desactivar la salida de sonido"
#: src/snes9x.ui:4206 #: src/snes9x.ui:4206
msgid "Mute sound when using turbo" #, fuzzy
msgid "Mute sound when using turbo or rewind"
msgstr "Silenciar el sonido cuando se esté en turbo" msgstr "Silenciar el sonido cuando se esté en turbo"
#: src/snes9x.ui:4210 #: src/snes9x.ui:4210
msgid "Disables output of sound when using turbo" #, fuzzy
msgid "Disables output of sound when using turbo or rewind"
msgstr "Deshabilitar la salida de sonido cuando se esté en turbo" msgstr "Deshabilitar la salida de sonido cuando se esté en turbo"
#: src/snes9x.ui:4233 #: src/snes9x.ui:4233

View File

@ -1288,12 +1288,12 @@ msgstr "Désactiver la sortie audio"
#: src/snes9x.ui:4206 #: src/snes9x.ui:4206
#, fuzzy #, fuzzy
msgid "Mute sound when using turbo" msgid "Mute sound when using turbo or rewind"
msgstr "Sourdine" msgstr "Sourdine"
#: src/snes9x.ui:4210 #: src/snes9x.ui:4210
#, fuzzy #, fuzzy
msgid "Disables output of sound when using turbo" msgid "Disables output of sound when using turbo or rewind"
msgstr "Désactiver la sortie audio" msgstr "Désactiver la sortie audio"
#: src/snes9x.ui:4233 #: src/snes9x.ui:4233

View File

@ -1264,12 +1264,12 @@ msgstr "音声出力を無効にします"
#: src/snes9x.ui:4206 #: src/snes9x.ui:4206
#, fuzzy #, fuzzy
msgid "Mute sound when using turbo" msgid "Mute sound when using turbo or rewind"
msgstr "サウンドをミュートする" msgstr "サウンドをミュートする"
#: src/snes9x.ui:4210 #: src/snes9x.ui:4210
#, fuzzy #, fuzzy
msgid "Disables output of sound when using turbo" msgid "Disables output of sound when using turbo or rewind"
msgstr "音声出力を無効にします" msgstr "音声出力を無効にします"
#: src/snes9x.ui:4233 #: src/snes9x.ui:4233

View File

@ -1316,12 +1316,12 @@ msgstr "Desativar saída de áudio."
#: src/snes9x.ui:4206 #: src/snes9x.ui:4206
#, fuzzy #, fuzzy
msgid "Mute sound when using turbo" msgid "Mute sound when using turbo or rewind"
msgstr "Saída de áudio muda" msgstr "Saída de áudio muda"
#: src/snes9x.ui:4210 #: src/snes9x.ui:4210
#, fuzzy #, fuzzy
msgid "Disables output of sound when using turbo" msgid "Disables output of sound when using turbo or rewind"
msgstr "Desativar saída de áudio." msgstr "Desativar saída de áudio."
#: src/snes9x.ui:4233 #: src/snes9x.ui:4233

View File

@ -1298,12 +1298,12 @@ msgstr "Запрещает вывод звука"
#: src/snes9x.ui:4206 #: src/snes9x.ui:4206
#, fuzzy #, fuzzy
msgid "Mute sound when using turbo" msgid "Mute sound when using turbo or rewind"
msgstr "Отключить звук" msgstr "Отключить звук"
#: src/snes9x.ui:4210 #: src/snes9x.ui:4210
#, fuzzy #, fuzzy
msgid "Disables output of sound when using turbo" msgid "Disables output of sound when using turbo or rewind"
msgstr "Запрещает вывод звука" msgstr "Запрещает вывод звука"
#: src/snes9x.ui:4233 #: src/snes9x.ui:4233

View File

@ -1280,12 +1280,12 @@ msgstr "Isključuje izvor zvuka"
#: src/snes9x.ui:4206 #: src/snes9x.ui:4206
#, fuzzy #, fuzzy
msgid "Mute sound when using turbo" msgid "Mute sound when using turbo or rewind"
msgstr "Priguši izvor zvuka" msgstr "Priguši izvor zvuka"
#: src/snes9x.ui:4210 #: src/snes9x.ui:4210
#, fuzzy #, fuzzy
msgid "Disables output of sound when using turbo" msgid "Disables output of sound when using turbo or rewind"
msgstr "Isključuje izvor zvuka" msgstr "Isključuje izvor zvuka"
#: src/snes9x.ui:4233 #: src/snes9x.ui:4233

View File

@ -81,8 +81,7 @@ Binding &Binding::operator=(const Binding &binding)
return *this; return *this;
} }
bool bool Binding::operator==(const Binding &binding)
Binding::matches (Binding &binding)
{ {
if ((value & ~BINDING_THRESHOLD_MASK) == if ((value & ~BINDING_THRESHOLD_MASK) ==
(binding.value & ~BINDING_THRESHOLD_MASK)) (binding.value & ~BINDING_THRESHOLD_MASK))
@ -228,6 +227,13 @@ Binding::Binding (const char *raw_string)
} }
} }
std::string Binding::as_string()
{
char buf[PATH_MAX];
to_string(buf, false);
return std::string(buf);
}
void void
Binding::to_string (char *str, bool translate) Binding::to_string (char *str, bool translate)
{ {

View File

@ -8,6 +8,7 @@
#define __GTK_BINDING_H #define __GTK_BINDING_H
#include "gtk_2_3_compat.h" #include "gtk_2_3_compat.h"
#include <string>
#define AXIS_POS 1 #define AXIS_POS 1
#define AXIS_NEG 0 #define AXIS_NEG 0
@ -38,14 +39,15 @@ class Binding
Binding (unsigned int device, unsigned int button, unsigned int threshold); Binding (unsigned int device, unsigned int button, unsigned int threshold);
Binding (const Binding &binding); Binding (const Binding &binding);
Binding &operator=(const Binding &binding); Binding &operator=(const Binding &binding);
bool operator==(const Binding &binding);
Binding (GdkEventKey *event); Binding (GdkEventKey *event);
Binding (unsigned int); Binding (unsigned int);
Binding (); Binding ();
Binding (const char *str); Binding (const char *str);
void to_string (char *str, bool translate = true); void to_string (char *str, bool translate = true);
std::string as_string();
unsigned int hex (); unsigned int hex ();
unsigned int base_hex (); unsigned int base_hex ();
bool matches (Binding &binding);
void clear (); void clear ();
bool is_joy (); bool is_joy ();
bool is_key (); bool is_key ();

View File

@ -15,30 +15,30 @@
#include "gtk_display.h" #include "gtk_display.h"
#include "conffile.h" #include "conffile.h"
static bool directory_exists (std::string str) static bool directory_exists(std::string str)
{ {
DIR *dir; DIR *dir;
dir = opendir (str.c_str ()); dir = opendir(str.c_str());
if (dir) if (dir)
{ {
closedir (dir); closedir(dir);
return true; return true;
} }
return false; return false;
} }
std::string get_config_dir () std::string get_config_dir()
{ {
// Find config directory // Find config directory
char *env_home = getenv ("HOME"); char *env_home = getenv("HOME");
char *env_xdg_config_home = getenv ("XDG_CONFIG_HOME"); char *env_xdg_config_home = getenv("XDG_CONFIG_HOME");
if (!env_home && !env_xdg_config_home) if (!env_home && !env_xdg_config_home)
{ {
return std::string (".snes9x"); return std::string(".snes9x");
} }
std::string config; std::string config;
@ -51,30 +51,30 @@ std::string get_config_dir ()
(legacy += env_home) += "/.snes9x"; (legacy += env_home) += "/.snes9x";
} }
else else
config = std::string (env_xdg_config_home) + "/snes9x"; config = std::string(env_xdg_config_home) + "/snes9x";
if (directory_exists (legacy) && !directory_exists(config)) if (directory_exists(legacy) && !directory_exists(config))
return legacy; return legacy;
return config; return config;
} }
std::string get_config_file_name () std::string get_config_file_name()
{ {
return get_config_dir () + "/snes9x.conf"; return get_config_dir() + "/snes9x.conf";
} }
void S9xParsePortConfig (ConfigFile &conf, int pass) void S9xParsePortConfig(ConfigFile &conf, int pass)
{ {
} }
Snes9xConfig::Snes9xConfig () Snes9xConfig::Snes9xConfig()
{ {
joystick = NULL; joystick = NULL;
joystick_threshold = 40; joystick_threshold = 40;
} }
int Snes9xConfig::load_defaults () int Snes9xConfig::load_defaults()
{ {
full_screen_on_open = false; full_screen_on_open = false;
change_display_resolution = false; change_display_resolution = false;
@ -107,8 +107,8 @@ int Snes9xConfig::load_defaults ()
sound_playback_rate = 5; sound_playback_rate = 5;
sound_input_rate = 31950; sound_input_rate = 31950;
auto_input_rate = true; auto_input_rate = true;
last_directory.clear (); last_directory.clear();
last_shader_directory.clear (); last_shader_directory.clear();
window_width = -1; window_width = -1;
window_height = -1; window_height = -1;
preferences_width = -1; preferences_width = -1;
@ -117,11 +117,11 @@ int Snes9xConfig::load_defaults ()
shader_parameters_height = -1; shader_parameters_height = -1;
enable_icons = true; enable_icons = true;
current_display_tab = 0; current_display_tab = 0;
sram_directory.clear (); sram_directory.clear();
export_directory.clear (); export_directory.clear();
savestate_directory.clear (); savestate_directory.clear();
cheat_directory.clear (); cheat_directory.clear();
patch_directory.clear (); patch_directory.clear();
screensaver_needs_reset = false; screensaver_needs_reset = false;
ntsc_setup = snes_ntsc_composite; ntsc_setup = snes_ntsc_composite;
ntsc_scanline_intensity = 1; ntsc_scanline_intensity = 1;
@ -134,12 +134,12 @@ int Snes9xConfig::load_defaults ()
netplay_send_rom = false; netplay_send_rom = false;
netplay_default_port = 6096; netplay_default_port = 6096;
netplay_max_frame_loss = 10; netplay_max_frame_loss = 10;
netplay_last_rom.clear (); netplay_last_rom.clear();
netplay_last_host.clear (); netplay_last_host.clear();
netplay_last_port = 6096; netplay_last_port = 6096;
modal_dialogs = true; modal_dialogs = true;
current_save_slot = 0; current_save_slot = 0;
S9xCheatsEnable (); S9xCheatsEnable();
rewind_granularity = 5; rewind_granularity = 5;
rewind_buffer_size = 0; rewind_buffer_size = 0;
@ -151,7 +151,7 @@ int Snes9xConfig::load_defaults ()
pbo_format = 0; pbo_format = 0;
npot_textures = false; npot_textures = false;
use_shaders = false; use_shaders = false;
shader_filename.clear (); shader_filename.clear();
use_glfinish = false; use_glfinish = false;
use_sync_control = false; use_sync_control = false;
#endif #endif
@ -194,447 +194,440 @@ int Snes9xConfig::load_defaults ()
Settings.TwoClockCycles = 12; Settings.TwoClockCycles = 12;
#endif #endif
memset (pad, 0, sizeof (JoypadBinding) * NUM_JOYPADS); for (auto &joypad : pad)
memset (shortcut, 0, sizeof (Binding) * NUM_EMU_LINKS); {
joypad.data.fill(Binding());
}
shortcut.fill(Binding());
return 0; return 0;
} }
void Snes9xConfig::joystick_register_centers () void Snes9xConfig::joystick_register_centers()
{ {
for (int i = 0; joystick[i] != NULL; i++) for (int i = 0; joystick[i] != NULL; i++)
joystick[i]->register_centers (); joystick[i]->register_centers();
} }
void Snes9xConfig::flush_joysticks () void Snes9xConfig::flush_joysticks()
{ {
int i; for (int i = 0; joystick[i] != NULL; i++)
joystick[i]->flush();
for (i = 0; joystick[i] != NULL; i++)
joystick[i]->flush ();
} }
void Snes9xConfig::set_joystick_mode (int mode) void Snes9xConfig::set_joystick_mode(int mode)
{ {
int i; for (int i = 0; joystick[i] != NULL; i++)
for (i = 0; joystick[i] != NULL; i++)
joystick[i]->mode = mode; joystick[i]->mode = mode;
} }
static inline void outbool (ConfigFile &cf, const char *key, bool value, const char *comment = "") int Snes9xConfig::save_config_file()
{ {
cf.SetBool (key, value, "true", "false", comment);
}
int Snes9xConfig::save_config_file ()
{
char key[PATH_MAX];
char buffer[PATH_MAX];
ConfigFile cf; ConfigFile cf;
std::string section = "";
#undef z auto outbool = [&](std::string name, bool b, std::string comment = "") {
#define z "Display::" cf.SetBool((section + "::" + name).c_str(), b, "true", "false", comment.c_str());
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");
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");
cf.SetInt (z"SoftwareScaleFilter", scale_method, "Build-specific number of filter used for software scaling");
cf.SetInt (z"ScanlineFilterIntensity", scanline_filter_intensity, "0: 0%, 1: 12.5%, 2: 25%, 3: 50%, 4: 100%");
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);
outbool (cf, z"Multithreading", multithreading, "Apply filters using multiple threads");
cf.SetInt (z"NumberOfThreads", num_threads);
cf.SetInt (z"HardwareAcceleration", hw_accel, "0: None, 1: OpenGL, 2: XVideo");
outbool (cf, z"BilinearFilter", Settings.BilinearFilter, "Smoothes scaled image");
cf.SetInt (z"SplashBackground", splash_image, "0: Black, 1: Color bars, 2: Pattern, 3: Blue, 4: Default");
#undef z auto outstring = [&](std::string name, std::string str, std::string comment = "") {
#define z "NTSC::" cf.SetString((section + "::" + name).c_str(), str, comment.c_str());
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)); auto outint = [&](std::string name, int i, std::string comment = "") {
cf.SetString (z"Brightness", std::to_string (ntsc_setup.brightness)); cf.SetInt((section + "::" + name).c_str(), i, comment.c_str());
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)); section = "Display";
cf.SetString (z"Bleed", std::to_string (ntsc_setup.bleed)); outbool("FullscreenOnOpen", full_screen_on_open, "Set the screen resolution after opening a ROM");
cf.SetString (z"Fringing", std::to_string (ntsc_setup.fringing)); outbool("ChangeDisplayResolution", change_display_resolution, "Set the resolution in fullscreen mode");
cf.SetString (z"Resolution", std::to_string (ntsc_setup.resolution)); outbool("ScaleToFit", scale_to_fit, "Scale the image to fit the window size");
outbool (cf, z"MergeFields", ntsc_setup.merge_fields); outbool("ShowOverscanArea", overscan);
cf.SetInt (z"ScanlineIntensity", ntsc_scanline_intensity); outbool("MaintainAspectRatio", maintain_aspect_ratio, "Resize the screen to the proportions set by aspect ratio option");
outbool("Multithreading", multithreading, "Apply filters using multiple threads");
outbool("BilinearFilter", Settings.BilinearFilter, "Smoothes scaled image");
outbool("ForceInvertedByteOrder", force_inverted_byte_order);
outint("VideoMode", xrr_index, "Platform-specific video mode number");
outint("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");
outint("SoftwareScaleFilter", scale_method, "Build-specific number of filter used for software scaling");
outint("ScanlineFilterIntensity", scanline_filter_intensity, "0: 0%, 1: 12.5%, 2: 25%, 3: 50%, 4: 100%");
outint("HiresEffect", hires_effect, "0: Downscale to low-res, 1: Leave as-is, 2: Upscale low-res screens");
outint("NumberOfThreads", num_threads);
outint("HardwareAcceleration", hw_accel, "0: None, 1: OpenGL, 2: XVideo");
outint("SplashBackground", splash_image, "0: Black, 1: Color bars, 2: Pattern, 3: Blue, 4: Default");
section = "NTSC";
outstring("Hue", std::to_string(ntsc_setup.hue));
outstring("Saturation", std::to_string(ntsc_setup.saturation));
outstring("Contrast", std::to_string(ntsc_setup.contrast));
outstring("Brightness", std::to_string(ntsc_setup.brightness));
outstring("Sharpness", std::to_string(ntsc_setup.sharpness));
outstring("Artifacts", std::to_string(ntsc_setup.artifacts));
outstring("Gamma", std::to_string(ntsc_setup.gamma));
outstring("Bleed", std::to_string(ntsc_setup.bleed));
outstring("Fringing", std::to_string(ntsc_setup.fringing));
outstring("Resolution", std::to_string(ntsc_setup.resolution));
outbool("MergeFields", ntsc_setup.merge_fields);
outint("ScanlineIntensity", ntsc_scanline_intensity);
#ifdef USE_OPENGL #ifdef USE_OPENGL
#undef z section = "OpenGL";
#define z "OpenGL::" outbool("VSync", sync_to_vblank);
outbool (cf, z"VSync", sync_to_vblank); outbool("glFinish", use_glfinish);
outbool (cf, z"glFinish", use_glfinish); outbool("SyncControl", use_sync_control);
outbool (cf, z"SyncControl", use_sync_control); outbool("UseNonPowerOfTwoTextures", npot_textures);
outbool (cf, z"UsePixelBufferObjects", use_pbos); outbool("EnableCustomShaders", use_shaders);
cf.SetInt (z"PixelBufferObjectBitDepth", pbo_format); outbool("UsePixelBufferObjects", use_pbos);
outbool (cf, z"UseNonPowerOfTwoTextures", npot_textures); outint("PixelBufferObjectBitDepth", pbo_format);
outbool (cf, z"EnableCustomShaders", use_shaders); outstring("ShaderFile", shader_filename);
cf.SetString (z"ShaderFile", shader_filename);
#endif #endif
#undef z section = "Sound";
#define z "Sound::" outbool("MuteSound", mute_sound);
outbool (cf, z"MuteSound", mute_sound); outbool("MuteSoundDuringTurbo", mute_sound_turbo);
outbool (cf, z"MuteSoundDuringTurbo", mute_sound_turbo); outint("BufferSize", sound_buffer_size, "Buffer size in milliseconds");
cf.SetInt (z"BufferSize", sound_buffer_size, "Buffer size in milliseconds"); outint("Driver", sound_driver);
cf.SetInt (z"Driver", sound_driver); outint("InputRate", sound_input_rate);
cf.SetInt (z"InputRate", sound_input_rate); outbool("DynamicRateControl", Settings.DynamicRateControl);
outbool (cf, z"DynamicRateControl", Settings.DynamicRateControl); outint("DynamicRateControlLimit", Settings.DynamicRateLimit);
cf.SetInt (z"DynamicRateControlLimit", Settings.DynamicRateLimit); outbool("AutomaticInputRate", auto_input_rate, "Guess input rate by asking the monitor what its refresh rate is");
outbool (cf, z"AutomaticInputRate", auto_input_rate, "Guess input rate by asking the monitor what its refresh rate is"); outint("PlaybackRate", gui_config->sound_playback_rate, "1: 8000Hz, 2: 11025Hz, 3: 16000Hz, 4: 22050Hz, 5: 32000Hz, 6: 44100Hz, 7: 48000Hz");
cf.SetInt (z"PlaybackRate", gui_config->sound_playback_rate, "1: 8000Hz, 2: 11025Hz, 3: 16000Hz, 4: 22050Hz, 5: 32000Hz, 6: 44100Hz, 7: 48000Hz");
#undef z section = "Files";
#define z "Files::" outstring("LastDirectory", last_directory);
outstring("LastShaderDirectory", last_shader_directory);
outstring("SRAMDirectory", sram_directory);
outstring("SaveStateDirectory", savestate_directory);
outstring("CheatDirectory", cheat_directory);
outstring("PatchDirectory", patch_directory);
outstring("ExportDirectory", export_directory);
cf.SetString (z"LastDirectory", last_directory); section = "Window State";
cf.SetString (z"LastShaderDirectory", last_shader_directory); outint("MainWidth", window_width);
cf.SetString (z"SRAMDirectory", sram_directory); outint("MainHeight", window_height);
cf.SetString (z"SaveStateDirectory", savestate_directory); outint("PreferencesWidth", preferences_width);
cf.SetString (z"CheatDirectory", cheat_directory); outint("PreferencesHeight", preferences_height);
cf.SetString (z"PatchDirectory", patch_directory); outint("ShaderParametersWidth", shader_parameters_width);
cf.SetString (z"ExportDirectory", export_directory); outint("ShaderParametersHeight", shader_parameters_height);
outint("CurrentDisplayTab", current_display_tab);
#undef z outbool("UIVisible", ui_visible);
#define z "Window State::" outbool("EnableIcons", enable_icons);
cf.SetInt (z"MainWidth", window_width);
cf.SetInt (z"MainHeight", window_height);
cf.SetInt (z"PreferencesWidth", preferences_width);
cf.SetInt (z"PreferencesHeight", preferences_height);
cf.SetInt (z"ShaderParametersWidth", shader_parameters_width);
cf.SetInt (z"ShaderParametersHeight", shader_parameters_height);
cf.SetInt (z"CurrentDisplayTab", current_display_tab);
outbool (cf, z"UIVisible", ui_visible);
outbool (cf, z"EnableIcons", enable_icons);
if (default_esc_behavior != ESC_TOGGLE_MENUBAR) if (default_esc_behavior != ESC_TOGGLE_MENUBAR)
outbool (cf, z"Fullscreen", 0); outbool("Fullscreen", 0);
else else
outbool (cf, z"Fullscreen", fullscreen); outbool("Fullscreen", fullscreen);
#undef z section = "Netplay";
#define z "Netplay::" outbool("ActAsServer", netplay_is_server);
outbool (cf, z"ActAsServer", netplay_is_server); outbool("UseResetToSync", netplay_sync_reset);
outbool (cf, z"UseResetToSync", netplay_sync_reset); outbool("SendROM", netplay_send_rom);
outbool (cf, z"SendROM", netplay_send_rom); outint("DefaultPort", netplay_default_port);
cf.SetInt (z"DefaultPort", netplay_default_port); outint("MaxFrameLoss", netplay_max_frame_loss);
cf.SetInt (z"MaxFrameLoss", netplay_max_frame_loss); outint("LastUsedPort", netplay_last_port);
cf.SetInt (z"LastUsedPort", netplay_last_port); outstring("LastUsedROM", netplay_last_rom);
cf.SetString (z"LastUsedROM", netplay_last_rom); outstring("LastUsedHost", netplay_last_host);
cf.SetString (z"LastUsedHost", netplay_last_host);
#undef z section = "Behavior";
#define z "Behavior::" outbool("PauseEmulationWhenFocusLost", pause_emulation_on_switch);
outbool (cf, z"PauseEmulationWhenFocusLost", pause_emulation_on_switch); outint("DefaultESCKeyBehavior", default_esc_behavior);
cf.SetInt (z"DefaultESCKeyBehavior", default_esc_behavior); outbool("PreventScreensaver", prevent_screensaver);
outbool (cf, z"PreventScreensaver", prevent_screensaver); outbool("UseModalDialogs", modal_dialogs);
outbool (cf, z"UseModalDialogs", modal_dialogs); outint("RewindBufferSize", rewind_buffer_size, "Amount of memory (in MB) to use for rewinding");
cf.SetInt (z"RewindBufferSize", rewind_buffer_size, "Amount of memory (in MB) to use for rewinding"); outint("RewindGranularity", rewind_granularity, "Only save rewind snapshots every N frames");
cf.SetInt (z"RewindGranularity", rewind_granularity, "Only save rewind snapshots every N frames"); outint("CurrentSaveSlot", current_save_slot);
cf.SetInt (z"CurrentSaveSlot", current_save_slot);
#undef z section = "Emulation";
#define z "Emulation::" outbool("EmulateTransparency", Settings.Transparency);
outbool (cf, z"EmulateTransparency", Settings.Transparency); outbool("DisplayTime", Settings.DisplayTime);
outbool (cf, z"DisplayTime", Settings.DisplayTime); outbool("DisplayFrameRate", Settings.DisplayFrameRate);
outbool (cf, z"DisplayFrameRate", Settings.DisplayFrameRate); outbool("DisplayPressedKeys", Settings.DisplayPressedKeys);
outbool (cf, z"DisplayPressedKeys", Settings.DisplayPressedKeys); outint("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");
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"); outint("SaveSRAMEveryNSeconds", Settings.AutoSaveDelay);
cf.SetInt (z"SaveSRAMEveryNSeconds", Settings.AutoSaveDelay); outbool("BlockInvalidVRAMAccess", Settings.BlockInvalidVRAMAccessMaster);
outbool (cf, z"BlockInvalidVRAMAccess", Settings.BlockInvalidVRAMAccessMaster); outbool("AllowDPadContradictions", Settings.UpAndDown, "Allow the D-Pad to press both up + down at the same time, or left + right");
outbool (cf, z"AllowDPadContradictions", Settings.UpAndDown, "Allow the D-Pad to press both up + down at the same time, or left + right");
#undef z section = "Hacks";
#define z "Hacks::" outint("SuperFXClockMultiplier", Settings.SuperFXClockMultiplier);
cf.SetInt (z"SuperFXClockMultiplier", Settings.SuperFXClockMultiplier); outint("SoundInterpolationMethod", Settings.InterpolationMethod, "0: None, 1: Linear, 2: Gaussian (what the hardware uses), 3: Cubic, 4: Sinc");
cf.SetInt (z"SoundInterpolationMethod", Settings.InterpolationMethod, "0: None, 1: Linear, 2: Gaussian (what the hardware uses), 3: Cubic, 4: Sinc"); outbool("RemoveSpriteLimit", Settings.MaxSpriteTilesPerLine == 34 ? 0 : 1);
outbool (cf, z"RemoveSpriteLimit", Settings.MaxSpriteTilesPerLine == 34 ? 0 : 1); outbool("OverclockCPU", Settings.OneClockCycle == 6 ? 0 : 1);
outbool (cf, z"OverclockCPU", Settings.OneClockCycle == 6 ? 0 : 1); outbool("EchoBufferHack", Settings.SeparateEchoBuffer, "Prevents echo buffer from overwriting APU RAM");
outbool (cf, z"EchoBufferHack", Settings.SeparateEchoBuffer, "Prevents echo buffer from overwriting APU RAM");
#undef z section = "Input";
#define z "Input::"
controllers controller = CTL_NONE; controllers controller = CTL_NONE;
int8 id[4]; int8 id[4];
for (int i = 0; i < 2; i++) for (int i = 0; i < 2; i++)
{ {
const char *output_string; std::string name;
snprintf (buffer, PATH_MAX, z"ControllerPort%d", i); std::string value;
S9xGetController (i, &controller, &id[0], &id[1], &id[2], &id[3]);
name = "ControllerPort" + std::to_string(i);
S9xGetController(i, &controller, &id[0], &id[1], &id[2], &id[3]);
switch (controller) switch (controller)
{ {
case CTL_JOYPAD: case CTL_JOYPAD:
output_string = "joypad"; value = "joypad";
break; break;
case CTL_MOUSE: case CTL_MOUSE:
output_string = "mouse"; value = "mouse";
break; break;
case CTL_SUPERSCOPE: case CTL_SUPERSCOPE:
output_string = "superscope"; value = "superscope";
break; break;
case CTL_MP5: case CTL_MP5:
output_string = "multitap"; value = "multitap";
break; break;
case CTL_JUSTIFIER: case CTL_JUSTIFIER:
output_string = "justifier"; value = "justifier";
break; break;
default: default:
output_string = "none"; value = "none";
} }
cf.SetString (buffer, output_string); outstring(name, value);
} }
cf.SetInt (z"JoystickThreshold", joystick_threshold); outint("JoystickThreshold", joystick_threshold);
#undef z
for (int i = 0; i < NUM_JOYPADS; i++) for (int i = 0; i < NUM_JOYPADS; i++)
{ {
Binding *joypad = (Binding *) &pad[i]; auto &joypad = pad[i];
for (int j = 0; j < NUM_JOYPAD_LINKS; j++) for (int j = 0; j < NUM_JOYPAD_LINKS; j++)
{ {
snprintf (key, PATH_MAX, "Joypad %d::%s", i, b_links[j].snes9x_name); section = "Joypad " + std::to_string(i);
joypad[j].to_string (buffer, false); outstring(b_links[j].snes9x_name, joypad.data[j].as_string());
cf.SetString (key, std::string (buffer));
} }
} }
section = "Shortcuts";
for (int i = NUM_JOYPAD_LINKS; b_links[i].snes9x_name; i++) for (int i = NUM_JOYPAD_LINKS; b_links[i].snes9x_name; i++)
{ {
snprintf (key, PATH_MAX, "Shortcuts::%s", b_links[i].snes9x_name); outstring(b_links[i].snes9x_name, shortcut[i - NUM_JOYPAD_LINKS].as_string());
shortcut[i - NUM_JOYPAD_LINKS].to_string (buffer, false);
cf.SetString (key, std::string (buffer));
} }
cf.SetNiceAlignment (true); cf.SetNiceAlignment(true);
cf.SetShowComments (true); cf.SetShowComments(true);
cf.SaveTo (get_config_file_name ().c_str ()); cf.SaveTo(get_config_file_name().c_str());
return 0; return 0;
} }
int Snes9xConfig::load_config_file () int Snes9xConfig::load_config_file()
{ {
struct stat file_info; struct stat file_info;
std::string path;
ConfigFile cf; ConfigFile cf;
char key[PATH_MAX];
load_defaults (); load_defaults();
path = get_config_dir (); std::string path = get_config_dir();
if (stat (path.c_str (), &file_info)) if (stat(path.c_str(), &file_info))
{ {
if (mkdir (path.c_str (), 0755)) if (mkdir(path.c_str(), 0755))
{ {
fprintf (stderr, fprintf(stderr,
_("Couldn't create config directory: %s\n"), _("Couldn't create config directory: %s\n"),
path.c_str ()); path.c_str());
return -1; return -1;
} }
} }
else else
{ {
if (!(file_info.st_mode & 0700)) if (!(file_info.st_mode & 0700))
chmod (path.c_str (), file_info.st_mode | 0700); chmod(path.c_str(), file_info.st_mode | 0700);
} }
path = get_config_file_name (); path = get_config_file_name();
if (stat (path.c_str (), &file_info)) if (stat(path.c_str(), &file_info))
{ {
save_config_file (); save_config_file();
} }
if (!cf.LoadFile (path.c_str ())) if (!cf.LoadFile(path.c_str()))
return -1; return -1;
std::string none; std::string none;
#define inbool(key, var) { if (cf.Exists (key)) var = cf.GetBool (key); } std::string section;
#define inint(key, var) { if (cf.Exists(key)) var = cf.GetInt (key); }
#define infloat(key, var) { if (cf.Exists(key)) var = atof (cf.GetString (key, none).c_str()); }
#define instr(key, var) var = cf.GetString (key, none);
#undef z auto inbool = [&](std::string name, auto &b) {
#define z "Display::" if (cf.Exists((section + "::" + name).c_str()))
inbool (z"FullscreenOnOpen", full_screen_on_open); b = cf.GetBool((section + "::" + name).c_str());
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);
inint (z"SplashBackground", splash_image);
#undef z auto inint = [&](std::string name, auto &i) {
#define z "NTSC::" if (cf.Exists((section + "::" + name).c_str()))
infloat (z"Hue", ntsc_setup.hue); i = cf.GetInt((section + "::" + name).c_str());
infloat (z"Saturation", ntsc_setup.saturation); };
infloat (z"Contrast", ntsc_setup.contrast);
infloat (z"Brightness", ntsc_setup.brightness); auto indouble = [&](std::string name, double &d) {
infloat (z"Sharpness", ntsc_setup.sharpness); if (cf.Exists((section + "::" + name).c_str()))
infloat (z"Artifacts", ntsc_setup.artifacts); d = atof(cf.GetString((section + "::" + name).c_str()));
infloat (z"Gamma", ntsc_setup.gamma); };
infloat (z"Bleed", ntsc_setup.bleed);
infloat (z"Fringing", ntsc_setup.fringing); auto instr = [&](std::string name, std::string &str) {
infloat (z"Resolution", ntsc_setup.resolution); str = cf.GetString((section + "::" + name).c_str(), none);
inbool (z"MergeFields", ntsc_setup.merge_fields); };
inint (z"ScanlineIntensity", ntsc_scanline_intensity);
section = "Display";
inbool("FullscreenOnOpen", full_screen_on_open);
inbool("ChangeDisplayResolution", change_display_resolution);
inint("VideoMode", xrr_index);
inbool("ScaleToFit", scale_to_fit);
inbool("MaintainAspectRatio", maintain_aspect_ratio);
inint("AspectRatio", aspect_ratio);
inint("SoftwareScaleFilter", scale_method);
inint("ScanlineFilterIntensity", scanline_filter_intensity);
inbool("ShowOverscanArea", overscan);
inint("HiresEffect", hires_effect);
inbool("ForceInvertedByteOrder", force_inverted_byte_order);
inbool("Multithreading", multithreading);
inint("NumberOfThreads", num_threads);
inint("HardwareAcceleration", hw_accel);
inbool("BilinearFilter", Settings.BilinearFilter);
inint("SplashBackground", splash_image);
section = "NTSC";
indouble("Hue", ntsc_setup.hue);
indouble("Saturation", ntsc_setup.saturation);
indouble("Contrast", ntsc_setup.contrast);
indouble("Brightness", ntsc_setup.brightness);
indouble("Sharpness", ntsc_setup.sharpness);
indouble("Artifacts", ntsc_setup.artifacts);
indouble("Gamma", ntsc_setup.gamma);
indouble("Bleed", ntsc_setup.bleed);
indouble("Fringing", ntsc_setup.fringing);
indouble("Resolution", ntsc_setup.resolution);
inbool("MergeFields", ntsc_setup.merge_fields);
inint("ScanlineIntensity", ntsc_scanline_intensity);
#ifdef USE_OPENGL #ifdef USE_OPENGL
#undef z section = "OpenGL";
#define z "OpenGL::" inbool("VSync", sync_to_vblank);
inbool (z"VSync", sync_to_vblank); inbool("glFinish", use_glfinish);
inbool (z"glFinish", use_glfinish); inbool("SyncControl", use_sync_control);
inbool (z"SyncControl", use_sync_control); inbool("UsePixelBufferObjects", use_pbos);
inbool (z"UsePixelBufferObjects", use_pbos); inint("PixelBufferObjectBitDepth", pbo_format);
inint (z"PixelBufferObjectBitDepth", pbo_format); inbool("UseNonPowerOfTwoTextures", npot_textures);
inbool (z"UseNonPowerOfTwoTextures", npot_textures); inbool("EnableCustomShaders", use_shaders);
inbool (z"EnableCustomShaders", use_shaders); instr("ShaderFile", shader_filename);
instr (z"ShaderFile", shader_filename);
#endif #endif
#undef z section = "Sound";
#define z "Sound::" inbool("MuteSound", mute_sound);
inbool (z"MuteSound", mute_sound); inbool("MuteSoundDuringTurbo", mute_sound_turbo);
inbool (z"MuteSoundDuringTurbo", mute_sound_turbo); inint("BufferSize", sound_buffer_size);
inint (z"BufferSize", sound_buffer_size); inint("Driver", sound_driver);
inint (z"Driver", sound_driver); inint("InputRate", sound_input_rate);
inint (z"InputRate", sound_input_rate); inbool("DynamicRateControl", Settings.DynamicRateControl);
inbool (z"DynamicRateControl", Settings.DynamicRateControl); inint("DynamicRateControlLimit", Settings.DynamicRateLimit);
inint (z"DynamicRateControlLimit", Settings.DynamicRateLimit); inbool("AutomaticInputRate", auto_input_rate);
inbool (z"AutomaticInputRate", auto_input_rate); inint("PlaybackRate", gui_config->sound_playback_rate);
inint (z"PlaybackRate", gui_config->sound_playback_rate);
#undef z section = "Files";
#define z "Files::" instr("LastDirectory", last_directory);
instr (z"LastDirectory", last_directory); instr("LastShaderDirectory", last_shader_directory);
instr (z"LastShaderDirectory", last_shader_directory); instr("SRAMDirectory", sram_directory);
instr (z"SRAMDirectory", sram_directory); instr("SaveStateDirectory", savestate_directory);
instr (z"SaveStateDirectory", savestate_directory); instr("CheatDirectory", cheat_directory);
instr (z"CheatDirectory", cheat_directory); instr("PatchDirectory", patch_directory);
instr (z"PatchDirectory", patch_directory); instr("ExportDirectory", export_directory);
instr (z"ExportDirectory", export_directory);
#undef z section = "Window State";
#define z "Window State::" inint("MainWidth", window_width);
inint("MainHeight", window_height);
inint("PreferencesWidth", preferences_width);
inint("PreferencesHeight", preferences_height);
inint("ShaderParametersWidth", shader_parameters_width);
inint("ShaderParametersHeight", shader_parameters_height);
inint("CurrentDisplayTab", current_display_tab);
inbool("UIVisible", ui_visible);
inbool("Fullscreen", fullscreen);
inbool("EnableIcons", enable_icons);
inint (z"MainWidth", window_width); section = "Netplay";
inint (z"MainHeight", window_height); inbool("ActAsServer", netplay_is_server);
inint (z"PreferencesWidth", preferences_width); inbool("UseResetToSync", netplay_sync_reset);
inint (z"PreferencesHeight", preferences_height); inbool("SendROM", netplay_send_rom);
inint (z"ShaderParametersWidth", shader_parameters_width); inint("DefaultPort", netplay_default_port);
inint (z"ShaderParametersHeight", shader_parameters_height); inint("MaxFrameLoss", netplay_max_frame_loss);
inint (z"CurrentDisplayTab", current_display_tab); inint("LastUsedPort", netplay_last_port);
inbool (z"UIVisible", ui_visible); instr("LastUsedROM", netplay_last_rom);
inbool (z"Fullscreen", fullscreen); instr("LastUsedHost", netplay_last_host);
inbool (z"EnableIcons", enable_icons);
#undef z section = "Behavior";
#define z "Netplay::" inbool("PauseEmulationWhenFocusLost", pause_emulation_on_switch);
inbool (z"ActAsServer", netplay_is_server); inint("DefaultESCKeyBehavior", default_esc_behavior);
inbool (z"UseResetToSync", netplay_sync_reset); inbool("PreventScreensaver", prevent_screensaver);
inbool (z"SendROM", netplay_send_rom); inbool("UseModalDialogs", modal_dialogs);
inint (z"DefaultPort", netplay_default_port); inint("RewindBufferSize", rewind_buffer_size);
inint (z"MaxFrameLoss", netplay_max_frame_loss); inint("RewindGranularity", rewind_granularity);
inint (z"LastUsedPort", netplay_last_port); inint("CurrentSaveSlot", current_save_slot);
instr (z"LastUsedROM", netplay_last_rom);
instr (z"LastUsedHost", netplay_last_host);
#undef z section = "Emulation";
#define z "Behavior::" inbool("EmulateTransparency", Settings.Transparency);
inbool (z"PauseEmulationWhenFocusLost", pause_emulation_on_switch); inbool("DisplayTime", Settings.DisplayTime);
inint (z"DefaultESCKeyBehavior", default_esc_behavior); inbool("DisplayFrameRate", Settings.DisplayFrameRate);
inbool (z"PreventScreensaver", prevent_screensaver); inbool("DisplayPressedKeys", Settings.DisplayPressedKeys);
inbool (z"UseModalDialogs", modal_dialogs); inint("SpeedControlMethod", Settings.SkipFrames);
inint (z"RewindBufferSize", rewind_buffer_size); inint("SaveSRAMEveryNSeconds", Settings.AutoSaveDelay);
inint (z"RewindGranularity", rewind_granularity); inbool("BlockInvalidVRAMAccess", Settings.BlockInvalidVRAMAccessMaster);
inint (z"CurrentSaveSlot", current_save_slot); inbool("AllowDPadContradictions", Settings.UpAndDown);
#undef z section = "Hacks";
#define z "Emulation::" inint("SuperFXClockMultiplier", Settings.SuperFXClockMultiplier);
inbool (z"EmulateTransparency", Settings.Transparency); inint("SoundInterpolationMethod", Settings.InterpolationMethod);
inbool (z"DisplayTime", Settings.DisplayTime);
inbool (z"DisplayFrameRate", Settings.DisplayFrameRate);
inbool (z"DisplayPressedKeys", Settings.DisplayPressedKeys);
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 = false; bool RemoveSpriteLimit = false;
inbool (z"RemoveSpriteLimit", RemoveSpriteLimit); inbool("RemoveSpriteLimit", RemoveSpriteLimit);
bool OverclockCPU = false; bool OverclockCPU = false;
inbool (z"OverclockCPU", OverclockCPU); inbool("OverclockCPU", OverclockCPU);
inbool (z"EchoBufferHack", Settings.SeparateEchoBuffer); inbool("EchoBufferHack", Settings.SeparateEchoBuffer);
#undef z section = "Input";
#define z "Input::"
for (int i = 0; i < 2; i++) for (int i = 0; i < 2; i++)
{ {
snprintf (key, PATH_MAX, z"ControllerPort%d", i); std::string name = "ControllerPort" + std::to_string(i);
std::string tmp = cf.GetString (key, ""); std::string value;
instr(name, value);
if (tmp.find ("joypad") != std::string::npos) if (value.find("joypad") != std::string::npos)
S9xSetController (i, CTL_JOYPAD, i, 0, 0, 0); S9xSetController(i, CTL_JOYPAD, i, 0, 0, 0);
else if (tmp.find ("multitap") != std::string::npos) else if (value.find("multitap") != std::string::npos)
S9xSetController (i, CTL_MP5, i, i + 1, i + 2, i + 3); S9xSetController(i, CTL_MP5, i, i + 1, i + 2, i + 3);
else if (tmp.find ("superscope") != std::string::npos) else if (value.find("superscope") != std::string::npos)
S9xSetController (i, CTL_SUPERSCOPE, 0, 0, 0, 0); S9xSetController(i, CTL_SUPERSCOPE, 0, 0, 0, 0);
else if (tmp.find ("mouse") != std::string::npos) else if (value.find("mouse") != std::string::npos)
S9xSetController (i, CTL_MOUSE, i, 0, 0, 0); S9xSetController(i, CTL_MOUSE, i, 0, 0, 0);
else if (tmp.find ("none") != std::string::npos) else if (value.find("none") != std::string::npos)
S9xSetController (i, CTL_NONE, 0, 0, 0, 0); S9xSetController(i, CTL_NONE, 0, 0, 0, 0);
} }
inint (z"JoystickThreshold", joystick_threshold); inint("JoystickThreshold", joystick_threshold);
#undef z
std::string buffer; std::string buffer;
for (int i = 0; i < NUM_JOYPADS; i++) for (int i = 0; i < NUM_JOYPADS; i++)
{ {
Binding *joypad = (Binding *) &pad[i]; auto &joypad = pad[i];
section = "Joypad " + std::to_string(i);
for (int j = 0; j < NUM_JOYPAD_LINKS; j++) for (int j = 0; j < NUM_JOYPAD_LINKS; j++)
{ {
snprintf (key, PATH_MAX, "Joypad %d::%s", i, b_links[j].snes9x_name); instr(b_links[j].snes9x_name, buffer);
instr (key, buffer); joypad.data[j] = Binding(buffer.c_str());
joypad[j] = Binding (buffer.c_str ());
} }
} }
section = "Shortcuts";
for (int i = NUM_JOYPAD_LINKS; b_links[i].snes9x_name; i++) for (int i = NUM_JOYPAD_LINKS; b_links[i].snes9x_name; i++)
{ {
snprintf (key, PATH_MAX, "Shortcuts::%s", b_links[i].snes9x_name); instr(b_links[i].snes9x_name, buffer);
instr (key, buffer); shortcut[i - NUM_JOYPAD_LINKS] = Binding(buffer.c_str());
shortcut[i - NUM_JOYPAD_LINKS] = Binding (buffer.c_str ());
} }
/* Validation */ /* Validation */
@ -696,11 +689,11 @@ int Snes9xConfig::load_config_file ()
else else
Settings.SoundSync = false; Settings.SoundSync = false;
hires_effect = CLAMP (hires_effect, 0, 2); hires_effect = CLAMP(hires_effect, 0, 2);
Settings.DynamicRateLimit = CLAMP (Settings.DynamicRateLimit, 1, 1000); Settings.DynamicRateLimit = CLAMP(Settings.DynamicRateLimit, 1, 1000);
Settings.SuperFXClockMultiplier = CLAMP (Settings.SuperFXClockMultiplier, 50, 400); Settings.SuperFXClockMultiplier = CLAMP(Settings.SuperFXClockMultiplier, 50, 400);
ntsc_scanline_intensity = MIN (ntsc_scanline_intensity, 4); ntsc_scanline_intensity = MIN(ntsc_scanline_intensity, 4);
scanline_filter_intensity = MIN (scanline_filter_intensity, 3); scanline_filter_intensity = MIN(scanline_filter_intensity, 3);
return 0; return 0;
} }
@ -714,14 +707,14 @@ void Snes9xConfig::rebind_keys()
for (int joypad_i = 0; joypad_i < NUM_JOYPADS; joypad_i++) for (int joypad_i = 0; joypad_i < NUM_JOYPADS; joypad_i++)
{ {
Binding *bin = (Binding *)&pad[joypad_i]; auto &bin = pad[joypad_i].data;
for (int button_i = 0; button_i < NUM_JOYPAD_LINKS; button_i++) for (int button_i = 0; button_i < NUM_JOYPAD_LINKS; button_i++)
{ {
int dupe; int dupe;
for (dupe = button_i + 1; dupe < NUM_JOYPAD_LINKS; dupe++) for (dupe = button_i + 1; dupe < NUM_JOYPAD_LINKS; dupe++)
{ {
if (bin[button_i].matches(bin[dupe]) && bin[button_i].hex() != 0) if (bin[button_i] == bin[dupe] && bin[button_i].hex() != 0)
break; break;
} }
if (dupe < NUM_JOYPAD_LINKS || bin[button_i].hex() == 0) if (dupe < NUM_JOYPAD_LINKS || bin[button_i].hex() == 0)
@ -733,7 +726,7 @@ void Snes9xConfig::rebind_keys()
bool ismulti = false; bool ismulti = false;
for (dupe = button_i - 1; dupe > 0; dupe--) for (dupe = button_i - 1; dupe > 0; dupe--)
{ {
if (bin[button_i].matches(bin[dupe])) if (bin[button_i] == bin[dupe])
{ {
ismulti = true; ismulti = true;
string += ",Joypad" + std::to_string((joypad_i % 5) + 1) + " "; string += ",Joypad" + std::to_string((joypad_i % 5) + 1) + " ";

View File

@ -10,6 +10,7 @@
#include <X11/Xlib.h> #include <X11/Xlib.h>
#include <X11/extensions/Xrandr.h> #include <X11/extensions/Xrandr.h>
#include <string> #include <string>
#include <array>
#include "gtk_control.h" #include "gtk_control.h"
#include "filter/snes_ntsc.h" #include "filter/snes_ntsc.h"
@ -110,8 +111,8 @@ class Snes9xConfig
std::string last_shader_directory; std::string last_shader_directory;
/* Controls */ /* Controls */
JoypadBinding pad[NUM_JOYPADS]; std::array<JoypadBinding, NUM_JOYPADS> pad;
Binding shortcut[NUM_EMU_LINKS]; std::array<Binding, NUM_EMU_LINKS> shortcut;
/* Netplay */ /* Netplay */
bool netplay_is_server; bool netplay_is_server;

View File

@ -8,6 +8,7 @@
#define __GTK_CONTROL_H #define __GTK_CONTROL_H
#include <queue> #include <queue>
#include <array>
#include "gtk_binding.h" #include "gtk_binding.h"
#include "SDL.h" #include "SDL.h"
@ -73,7 +74,7 @@ const int NUM_EMU_LINKS = 62;
typedef struct JoypadBinding typedef struct JoypadBinding
{ {
Binding data[NUM_JOYPAD_LINKS]; /* Avoid packing issues */ std::array<Binding, NUM_JOYPAD_LINKS> data;
} JoypadBinding; } JoypadBinding;
bool S9xGrabJoysticks (); bool S9xGrabJoysticks ();

View File

@ -140,28 +140,28 @@ S9xGetDirectory (enum s9x_getdirtype dirtype)
switch (dirtype) switch (dirtype)
{ {
case HOME_DIR: case HOME_DIR:
sstrncpy (path, get_config_dir ().c_str (), PATH_MAX + 1); snprintf(path, PATH_MAX + 1, "%s", get_config_dir().c_str());
break; break;
case SNAPSHOT_DIR: case SNAPSHOT_DIR:
sstrncpy (path, gui_config->savestate_directory.c_str (), PATH_MAX + 1); snprintf(path, PATH_MAX + 1, "%s", gui_config->savestate_directory.c_str());
break; break;
case PATCH_DIR: case PATCH_DIR:
sstrncpy (path, gui_config->patch_directory.c_str (), PATH_MAX + 1); snprintf(path, PATH_MAX + 1, "%s", gui_config->patch_directory.c_str());
break; break;
case CHEAT_DIR: case CHEAT_DIR:
sstrncpy (path, gui_config->cheat_directory.c_str (), PATH_MAX + 1); snprintf(path, PATH_MAX + 1, "%s", gui_config->cheat_directory.c_str());
break; break;
case SRAM_DIR: case SRAM_DIR:
sstrncpy (path, gui_config->sram_directory.c_str (), PATH_MAX + 1); snprintf(path, PATH_MAX + 1, "%s", gui_config->sram_directory.c_str());
break; break;
case SCREENSHOT_DIR: case SCREENSHOT_DIR:
case SPC_DIR: case SPC_DIR:
sstrncpy (path, gui_config->export_directory.c_str (), PATH_MAX + 1); snprintf(path, PATH_MAX + 1, "%s", gui_config->export_directory.c_str());
break; break;
default: default:
@ -249,7 +249,7 @@ S9xBasenameNoExt (const char *f)
ext = strrchr (f, '.'); ext = strrchr (f, '.');
if (!ext) if (!ext)
sstrncpy (filename, base, PATH_MAX); snprintf (filename, PATH_MAX, "%s", base);
else else
{ {
int len = ext - base; int len = ext - base;
@ -288,7 +288,7 @@ S9xOpenSnapshotFile (const char *fname, bool8 read_only, STREAM *file)
if (*drive || *dir == '/' || (*dir == '.' && (*(dir + 1) == '/'))) if (*drive || *dir == '/' || (*dir == '.' && (*(dir + 1) == '/')))
{ {
sstrncpy (filename, fname, PATH_MAX + 1); snprintf (filename, PATH_MAX + 1, "%s", fname);
if (!file_exists (filename)) if (!file_exists (filename))
{ {

View File

@ -733,8 +733,8 @@ Snes9xPreferences::move_settings_to_dialog ()
set_spin ("joystick_threshold", config->joystick_threshold); set_spin ("joystick_threshold", config->joystick_threshold);
/* Control bindings */ /* Control bindings */
memcpy (pad, config->pad, (sizeof (JoypadBinding)) * NUM_JOYPADS); pad = config->pad;
memcpy (shortcut, config->shortcut, (sizeof (Binding)) * NUM_EMU_LINKS); shortcut = config->shortcut;
bindings_to_dialog (0); bindings_to_dialog (0);
set_combo ("joypad_to_swap_with", 0); set_combo ("joypad_to_swap_with", 0);
@ -966,8 +966,8 @@ Snes9xPreferences::get_settings_from_dialog ()
config->sram_directory = new_sram_directory; config->sram_directory = new_sram_directory;
} }
memcpy (config->pad, pad, (sizeof (JoypadBinding)) * NUM_JOYPADS); config->pad = pad;
memcpy (config->shortcut, shortcut, (sizeof (Binding)) * NUM_EMU_LINKS); config->shortcut = shortcut;
if (sound_needs_restart) if (sound_needs_restart)
{ {
@ -1266,7 +1266,7 @@ Snes9xPreferences::store_binding (const char *string, Binding binding)
} }
else else
{ {
if (shortcut[i - NUM_JOYPAD_LINKS].matches (binding)) if (shortcut[i - NUM_JOYPAD_LINKS] == binding)
{ {
shortcut[i - NUM_JOYPAD_LINKS].clear (); shortcut[i - NUM_JOYPAD_LINKS].clear ();
} }

View File

@ -38,8 +38,8 @@ class Snes9xPreferences : public GtkBuilderWindow
GtkToggleButton *last_toggled; GtkToggleButton *last_toggled;
bool awaiting_key; bool awaiting_key;
bool polling_joystick; bool polling_joystick;
JoypadBinding pad[NUM_JOYPADS]; std::array<JoypadBinding, NUM_JOYPADS> pad;
Binding shortcut[NUM_EMU_LINKS]; std::array<Binding, NUM_EMU_LINKS> shortcut;
private: private:
void get_settings_from_dialog (); void get_settings_from_dialog ();

View File

@ -273,7 +273,6 @@ static gboolean S9xPauseFunc (gpointer data)
/* Clear joystick queues */ /* Clear joystick queues */
gui_config->flush_joysticks (); gui_config->flush_joysticks ();
S9xSetSoundMute (false);
S9xSoundStart (); S9xSoundStart ();
if (Settings.NetPlay && NetPlay.Connected) if (Settings.NetPlay && NetPlay.Connected)
@ -314,7 +313,6 @@ gboolean S9xIdleFunc (gpointer data)
{ {
if (Settings.Paused && gui_config->rom_loaded) if (Settings.Paused && gui_config->rom_loaded)
{ {
S9xSetSoundMute (gui_config->mute_sound);
S9xSoundStop (); S9xSoundStop ();
gui_config->flush_joysticks (); gui_config->flush_joysticks ();
@ -360,14 +358,14 @@ gboolean S9xIdleFunc (gpointer data)
static int muted_from_turbo = false; static int muted_from_turbo = false;
static int mute_saved_state = false; static int mute_saved_state = false;
if (Settings.TurboMode && !muted_from_turbo && gui_config->mute_sound_turbo) if ((Settings.TurboMode || Settings.Rewinding) && !muted_from_turbo && gui_config->mute_sound_turbo)
{ {
muted_from_turbo = true; muted_from_turbo = true;
mute_saved_state = Settings.Mute; mute_saved_state = Settings.Mute;
S9xSetSoundMute (true); S9xSetSoundMute (true);
} }
if (!Settings.TurboMode && muted_from_turbo) if (!(Settings.TurboMode || Settings.Rewinding) && muted_from_turbo)
{ {
muted_from_turbo = false; muted_from_turbo = false;
Settings.Mute = mute_saved_state; Settings.Mute = mute_saved_state;

View File

@ -4203,11 +4203,11 @@
</child> </child>
<child> <child>
<object class="GtkCheckButton" id="mute_sound_turbo_check"> <object class="GtkCheckButton" id="mute_sound_turbo_check">
<property name="label" translatable="yes">Mute sound when using turbo</property> <property name="label" translatable="yes">Mute sound when using turbo or rewind</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="receives_default">False</property> <property name="receives_default">False</property>
<property name="tooltip_text" translatable="yes">Disables output of sound when using turbo</property> <property name="tooltip_text" translatable="yes">Disables output of sound when using turbo or rewind</property>
<property name="use_underline">True</property> <property name="use_underline">True</property>
<property name="draw_indicator">True</property> <property name="draw_indicator">True</property>
</object> </object>

View File

@ -51,6 +51,7 @@ static NSWindowFrameAutosaveName const kMainWindowIdentifier = @"s9xMainWindow";
window.restorationClass = [self class]; window.restorationClass = [self class];
window.frameAutosaveName = kMainWindowIdentifier; window.frameAutosaveName = kMainWindowIdentifier;
window.releasedWhenClosed = NO; window.releasedWhenClosed = NO;
window.backgroundColor = NSColor.clearColor;
if ( ![window setFrameUsingName:kMainWindowIdentifier] ) if ( ![window setFrameUsingName:kMainWindowIdentifier] )
{ {

View File

@ -2531,7 +2531,7 @@ void CMemory::InitROM (void)
if (Settings.ForcePAL) if (Settings.ForcePAL)
Settings.PAL = TRUE; Settings.PAL = TRUE;
else else
if (!Settings.BS && ((ROMRegion >= 2) && (ROMRegion <= 12) || ROMRegion == 18)) // 18 is used by "Tintin in Tibet (Europe) (En,Es,Sv)" if (!Settings.BS && (((ROMRegion >= 2) && (ROMRegion <= 12)) || ROMRegion == 18)) // 18 is used by "Tintin in Tibet (Europe) (En,Es,Sv)"
Settings.PAL = TRUE; Settings.PAL = TRUE;
else else
Settings.PAL = FALSE; Settings.PAL = FALSE;

View File

@ -434,7 +434,7 @@ static int read_movie_extrarominfo (FILE *fd, SMovie *movie)
ptr += 3; // zero bytes ptr += 3; // zero bytes
movie->ROMCRC32 = Read32(ptr); movie->ROMCRC32 = Read32(ptr);
sstrncpy(movie->ROMName, (char *) ptr, 23); memcpy(movie->ROMName, (char *) ptr, 23);
return (SUCCESS); return (SUCCESS);
} }

6
port.h
View File

@ -151,12 +151,6 @@ void SetInfoDlgColor(unsigned char, unsigned char, unsigned char);
#endif // __LIBRETRO__ #endif // __LIBRETRO__
#endif // __WIN32__ #endif // __WIN32__
inline void sstrncpy(char *dst, const char *src, size_t size)
{
strncpy(dst, src, size - 1);
dst[size - 1] = '\0';
}
#if defined(__DJGPP) || defined(__WIN32__) #if defined(__DJGPP) || defined(__WIN32__)
#define SLASH_STR "\\" #define SLASH_STR "\\"
#define SLASH_CHAR '\\' #define SLASH_CHAR '\\'