From 2ca2a4f98c08275a086835018be753de87a34b1d Mon Sep 17 00:00:00 2001 From: Linus Probert Date: Sat, 17 Mar 2018 00:04:26 +0100 Subject: [PATCH] Added persistent settings --- CMakeLists.txt | 3 +- data.db | Bin 0 -> 12288 bytes src/main.c | 3 + src/mixer.c | 23 ++++---- src/settings.c | 149 +++++++++++++++++++++++++++++++++++++++++++++++++ src/settings.h | 38 +++++++++++++ 6 files changed, 205 insertions(+), 11 deletions(-) create mode 100644 data.db create mode 100644 src/settings.c create mode 100644 src/settings.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 52e39d5..d4bedb2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -121,6 +121,7 @@ add_executable(breakhack src/vector2d src/map_room_modifiers src/sqlite3 + src/settings ) # Sqlite has some warnings that I we don't need to see @@ -181,7 +182,7 @@ ENDIF (CHECK_FOUND AND NOT WIN32) # LINT: if (CPPCHECK_FOUND) add_custom_target(lint - COMMAND ${CPPCHECK_EXECUTABLE} --language=c --template=gcc --error-exitcode=1 --quiet --enable=warning,style,performance,portability,information,missingInclude src/ + COMMAND ${CPPCHECK_EXECUTABLE} --force --language=c --template=gcc --error-exitcode=1 --quiet --enable=warning,style,performance,portability,information,missingInclude --suppress=*:src/sqlite3.? -isrc/sqlite3.c src/ WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} COMMENT "Run cppcheck" ) diff --git a/data.db b/data.db new file mode 100644 index 0000000000000000000000000000000000000000..91952a2040778fa59f209182474dd01d310acdb1 GIT binary patch literal 12288 zcmeI$K}&={6bJAbjaprnvD02U41`z^L3HTawhXcC7G)mVy@;(-NUl&s8so19yT8r9yPP7ukTf!104qYBJ5jVFdzT{2tWV=5P$## zAOHafKmY;|=$wFKn_h2K7RfS{S#<~zJC^BLMP6ocU9t67q5tpPuf+>P00Izz00bZa d0SG_<0uX?}zZTeS_4eDQM_UD}s|eYsVCVn< literal 0 HcmV?d00001 diff --git a/src/main.c b/src/main.c index be2454b..46eb92b 100644 --- a/src/main.c +++ b/src/main.c @@ -46,6 +46,7 @@ #include "skillbar.h" #include "texturecache.h" #include "update_data.h" +#include "settings.h" typedef enum Turn_t { PLAYER, @@ -340,6 +341,7 @@ init(void) bool result = true; result = result && initSDL(); result = result && initGame(); + settings_init(); initMainMenu(); gCamera.pos = (Position) { 0, 0 }; @@ -629,6 +631,7 @@ void close(void) timer_destroy(menuTimer); mixer_close(); texturecache_close(); + settings_close(); SDL_DestroyRenderer(gRenderer); SDL_DestroyWindow(gWindow); diff --git a/src/mixer.c b/src/mixer.c index 34f71b4..2f59891 100644 --- a/src/mixer.c +++ b/src/mixer.c @@ -20,6 +20,8 @@ #include "mixer.h" #include "util.h" #include "io_util.h" +#include "settings.h" +#include "random.h" static Mix_Chunk *effects[LAST_EFFECT]; static Mix_Music *current_song = NULL; @@ -32,9 +34,6 @@ static char *music[LAST_MUSIC] = { "Sounds/Music/fantasy-forest-battle.ogg" // MENU_MUSIC }; -static bool sound_enabled = true; -static bool music_enabled = true; - static Mix_Music* load_song(char *path) { @@ -95,27 +94,31 @@ mixer_init(void) bool mixer_toggle_sound(void) { - sound_enabled = !sound_enabled; - return sound_enabled; + Settings *settings = settings_get(); + settings->sound_enabled = !settings->sound_enabled; + return settings->sound_enabled; } bool mixer_toggle_music(void) { - music_enabled = !music_enabled; + Settings *settings = settings_get(); + settings->music_enabled = !settings->music_enabled; - if (Mix_PlayingMusic() && !music_enabled) + if (Mix_PlayingMusic() && !settings->music_enabled) Mix_PauseMusic(); else if (Mix_PausedMusic()) Mix_ResumeMusic(); + else + mixer_play_music(GAME_MUSIC0 + get_random(2)); - return music_enabled; + return settings->music_enabled; } void mixer_play_effect(Fx fx) { - if (!sound_enabled) + if (!settings_get()->sound_enabled) return; if (Mix_PlayChannel( -1, effects[fx], 0) == -1) @@ -125,7 +128,7 @@ mixer_play_effect(Fx fx) void mixer_play_music(Music mus) { - if (!music_enabled) + if (!settings_get()->music_enabled) return; if (mus != loaded_song) { diff --git a/src/settings.c b/src/settings.c new file mode 100644 index 0000000..06993d7 --- /dev/null +++ b/src/settings.c @@ -0,0 +1,149 @@ +/* + * BreakHack - A dungeone crawler RPG + * Copyright (C) 2018 Linus Probert + * + * 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 3 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, see . + */ + +#include +#include +#include "settings.h" +#include "sqlite3.h" +#include "util.h" +#include "defines.h" + +static sqlite3 *db = NULL; +static Settings settings; + +static const char *KEY_MUSIC_ENABLED = "music_enabled"; +static const char *KEY_SOUND_ENABLED = "sound_enabled"; + +static void +set_default_settings(void) +{ + settings.music_enabled = true; + settings.sound_enabled = true; +} + +static void +execute_statement(const char *stmt, + int (*cb)(void*, int, char**, char**), + void *cb_arg) +{ + char *errorMsg; + + set_default_settings(); + if (sqlite3_exec(db, stmt, cb, cb_arg, &errorMsg)) { + error("Faled to execture statement: %s", stmt); + error("Sqlite3: %s", errorMsg); + sqlite3_free(errorMsg); + sqlite3_close(db); + fatal("Exiting"); + } +} + +static void +create_tables(void) +{ + execute_statement("CREATE TABLE IF NOT EXISTS settings_int(key TEXT PRIMARY KEY, value INTEGER)", + NULL, + NULL); +} + +static int +load_settings_cb(void *unused, int count, char **values, char **colNames) +{ + UNUSED(unused); + + int i = 0; + while (i < count) { + if (strcmp("key", colNames[i]) != 0) + continue; + + debug("Loading setting: %s = %s", values[i], values[i+1]); + if (!strcmp(KEY_SOUND_ENABLED, values[i])) { + settings.sound_enabled = (bool) atoi(values[i+1]); + i += 2; + } else if (!strcmp(KEY_MUSIC_ENABLED, values[i])) { + settings.music_enabled = (bool) atoi(values[i+1]); + i += 2; + } + } + return 0; +} + +static void +load_settings(void) +{ + execute_statement("SELECT * FROM settings_int", load_settings_cb, NULL); +} + +void +settings_init(void) +{ + int result = sqlite3_open("data.db", &db); + if (result) { + error("Failed to open settings db: %s", sqlite3_errmsg(db)); + sqlite3_close(db); + fatal("Exiting"); + } + create_tables(); + load_settings(); +} + +static void +save_setting_int(const char *key, int value) +{ + const char *stmtStr = "INSERT OR REPLACE INTO settings_int(key, value) values (?, ?)"; + const char *pzTest; + sqlite3_stmt *stmt; + int result; + + result = sqlite3_prepare_v2(db, stmtStr, (int) strlen(stmtStr), &stmt, &pzTest); + + debug("Saving setting: %s = %d", key, value); + if (result == SQLITE_OK) { + sqlite3_bind_text(stmt, + 1, + key, + (int) strlen(key), + NULL); + + sqlite3_bind_int(stmt, 2, value); + sqlite3_step(stmt); + sqlite3_finalize(stmt); + } else { + error("Failed to prepare storage statement for: %s", key); + } +} + +static void +settings_save(void) +{ + save_setting_int(KEY_SOUND_ENABLED, settings.sound_enabled); + save_setting_int(KEY_MUSIC_ENABLED, settings.music_enabled); +} + +Settings * +settings_get(void) +{ + return &settings; +} + +void +settings_close(void) +{ + settings_save(); + sqlite3_close(db); +} diff --git a/src/settings.h b/src/settings.h new file mode 100644 index 0000000..bb1b387 --- /dev/null +++ b/src/settings.h @@ -0,0 +1,38 @@ +/* + * BreakHack - A dungeone crawler RPG + * Copyright (C) 2018 Linus Probert + * + * 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 3 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, see . + */ + +#ifndef SETTINGS_H_ +#define SETTINGS_H_ + +#include + +typedef struct Settings_t { + bool music_enabled; + bool sound_enabled; +} Settings; + +void +settings_init(void); + +Settings * +settings_get(void); + +void +settings_close(void); + +#endif // SETTINGS_H_