diff --git a/Makefile b/Makefile index 94f52f093a..57bdec9ae2 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ include config.mk TARGET = ssnes DEFINES = -OBJ = ssnes.o file.o driver.o +OBJ = ssnes.o file.o driver.o conf/config_file.o settings.o libsnes = -lsnes LIBS = -lsamplerate $(libsnes) diff --git a/general.h b/general.h index 50b071add8..06093dc95a 100644 --- a/general.h +++ b/general.h @@ -21,6 +21,7 @@ #include #include +#include "driver.h" #define SSNES_LOG(msg, args...) do { \ if (verbose) \ @@ -31,8 +32,42 @@ fprintf(stderr, "SSNES [ERROR] :: " msg, ##args); \ } while(0) -extern bool verbose; -extern SRC_STATE *source; -extern bool fullscreen; +#define MAX_PLAYERS 2 +#define MAX_BINDS 14 +struct settings +{ + struct + { + float xscale; + float yscale; + unsigned fullscreen_x; + unsigned fullscreen_y; + bool vsync; + bool smooth; + bool force_aspect; + char cg_shader_path[256]; + char video_filter[64]; + } video; + + struct + { + bool enable; + unsigned out_rate; + unsigned in_rate; + char device[256]; + unsigned latency; + bool sync; + int src_quality; + } audio; + + struct + { + struct snes_keybind binds[MAX_PLAYERS][MAX_BINDS]; + } input; +}; + +void parse_config(void); + +extern struct settings g_settings; #endif diff --git a/settings.c b/settings.c new file mode 100644 index 0000000000..9cbeb7e181 --- /dev/null +++ b/settings.c @@ -0,0 +1,138 @@ +#include "general.h" +#include "conf/config_file.h" +#include "config.h" +#include + +struct settings g_settings; + +static void set_defaults(void) +{ + g_settings.video.xscale = xscale; + g_settings.video.yscale = yscale; + g_settings.video.fullscreen_x = fullscreen_x; + g_settings.video.fullscreen_y = fullscreen_y; + g_settings.video.vsync = vsync; + g_settings.video.smootn = video_smooth; + g_settings.video.force_aspect = force_aspect; + strncpy(g_settings.video.cg_shader_path, cg_shader_path, sizeof(g_settings.video.cg_shader_path) - 1); + strncpy(g_settings.video.video_filter, "foo", sizeof(g_settings.video.video_filter) - 1); + + g_settings.audio.enable = audio_enable; + g_settings.audio.out_rate = out_rate; + g_settings.audio.in_rate = in_rate; + if (audio_device) + strncpy(g_settings.audio.device, audio_device, sizeof(g_settings.audio.device)); + g_settings.audio.latency = out_latency; + g_settings.audio.sync = audio_sync; + g_settings.audio.src_quality = SAMPLERATE_QUALITY; + + assert(sizeof(g_settings.input.binds[0]) >= sizeof(snes_keybinds_1)); + assert(sizeof(g_settings.input.binds[1]) >= sizeof(snes_keybinds_2)); + memcpy(g_settings.input.binds[0], snes_keybinds_1, sizeof(snes_keybinds_1)); + memcpy(g_settings.input.binds[1], snes_keybinds_2, sizeof(snes_keybinds_2)); +} + +void parse_config(void) +{ + memset(&g_settings, 0, sizeof(struct settings)); + config_file_t *conf = NULL; + + const char *xdg = getenv("XDG_CONFIG_HOME"); + if (xdg) + { + char conf_path[strlen(xdg) + strlen("/ssnes ")]; + strcpy(conf_path, xdg); + strcat(conf_path, "/ssnes"); + conf = config_file_new(conf_path); + } + else + { + const char *home = getenv("HOME"); + + if (home) + { + char conf_path[strlen(home) + strlen("/.ssnesrc ")]; + strcpy(conf_path, xdg); + strcat(conf_path, "/.ssnesrc"); + conf = config_file_new(conf_path); + } + } + + set_defaults(); + if (conf == NULL) + return; + + int tmp_int; + double tmp_double; + bool tmp_bool; + char *tmp_str; + + // Video settings. + if (config_get_double(conf, "video_xscale", &tmp_double)) + g_settings.video.xscale = tmp_double; + + if (config_get_double(conf, "video_yscale", &tmp_double)) + g_settings.video.yscale = tmp_double; + + if (config_get_int(conf, "video_fullscreen_x", &tmp_int)) + g_settings.video.fullscreen_x = tmp_int; + + if (config_get_int(conf, "video_fullscreen_y", &tmp_int)) + g_settings.video.fullscreen_y = tmp_int; + + if (config_get_bool(conf, "video_vsync", &tmp_bool)) + g_settings.video.vsync = tmp_bool; + + if (config_get_bool(conf, "video_smooth", &tmp_bool)) + g_settings.video.smooth = tmp_bool; + + if (config_get_bool(conf, "video_force_aspect", &tmp_bool)) + g_settings.video.force_aspect = tmp_bool; + + if (config_get_string(conf, "video_cg_shader_path", &tmp_str)) + { + strncpy(g_settings.video.cg_shader_path, tmp_str, sizeof(g_settings.video.cg_shader_path) - 1); + free(tmp_str); + } + + if (config_get_string(conf, "video_video_filter", &tmp_str)) + { + strncpy(g_settings.video.video_filter, tmp_str, sizeof(g_settings.video.video_filter) - 1); + free(tmp_str); + } + + // Audio settings. + if (config_get_bool(conf, "audio_enable", &tmp_bool)) + g_settings.audio.enable = tmp_bool; + + if (config_get_int(conf, "audio_out_rate", &tmp_int)) + g_settings.audio.out_rate = tmp_int; + + if (config_get_int(conf, "audio_in_rate", &tmp_int)) + g_settings.audio.in_rate = tmp_int; + + if (config_get_string(conf, "audio_device", &tmp_str)) + { + strncpy(g_settings.audio.device, tmp_str, sizeof(g_settings.audio.device) - 1); + free(tmp_str); + } + + if (config_get_int(conf, "audio_latency", &tmp_int)) + g_settings.audio.latency = tmp_int; + + if (config_get_bool(conf, "audio_sync", &tmp_bool)) + g_settings.audio.sync = tmp_bool; + + if (config_get_int(conf, "audio_src_quality", &tmp_int)) + { + int quals[] = {SRC_ZERO_ORDER_HOLD, SRC_LINEAR, SRC_SINC_FASTEST, + SRC_SINC_MEDIUM, SRC_SINC_BEST}; + + if (tmp_int > 0 && tmp_int < 6) + g_settings.audio.src_quality = quals[tmp_int]; + } + + // TODO: Keybinds. + + config_file_free(conf); +}