commit b5567fcd
Added config for saving
Changed files
diff --git a/src/ImageSelectState.hpp b/src/ImageSelectState.hpp
index ba402bc..7e5f8b8 100644
--- a/src/ImageSelectState.hpp
+++ b/src/ImageSelectState.hpp
@@ -36,9 +36,9 @@ public:
ImageSelectState();
ImageSelectState(const ImageSelectState& orig) = delete;
virtual ~ImageSelectState();
-
+
bool IsActive() override;
- void ProcessInput(const SDL_Event& event, bool &processed) override;
+ void ProcessInput(const SDL_Event& event, bool& processed) override;
void Draw(SDL_Renderer* target) override;
void Update() override;
void Init();
diff --git a/src/MainGameState.hpp b/src/MainGameState.hpp
index 132764e..2350933 100644
--- a/src/MainGameState.hpp
+++ b/src/MainGameState.hpp
@@ -31,9 +31,9 @@ public:
MainGameState();
MainGameState(const MainGameState& orig) = delete;
virtual ~MainGameState();
-
+
bool IsActive() override;
- void ProcessInput(const SDL_Event& event, bool &processed) override;
+ void ProcessInput(const SDL_Event& event, bool& processed) override;
void Draw(SDL_Renderer* target) override;
void Update() override;
diff --git a/src/PuzzleSingleImageState.cpp b/src/PuzzleSingleImageState.cpp
index 0dfb6e7..f02fc62 100644
--- a/src/PuzzleSingleImageState.cpp
+++ b/src/PuzzleSingleImageState.cpp
@@ -29,9 +29,11 @@ https://github.com/sago007/saland
#include <time.h>
#include "SagoImGui.hpp"
#include "rhash.hpp"
+#include "config.hpp"
PuzzleSingleImageState::PuzzleSingleImageState() {
-
+ std::map<std::string, std::string> config = LoadConfigMap();
+ flipMode = GetConfigBool(config, "flipMode", false);
}
PuzzleSingleImageState::~PuzzleSingleImageState() {
@@ -127,6 +129,10 @@ void PuzzleSingleImageState::Draw(SDL_Renderer* target) {
if (ImGui::BeginMenu("Settings")) {
if (ImGui::MenuItem("Flip Mode", nullptr, flipMode)) {
flipMode = !flipMode;
+ // Save the updated configuration
+ std::map<std::string, std::string> config = LoadConfigMap();
+ SetConfigBool(config, "flipMode", flipMode);
+ SaveConfigMap(config);
Shuffle();
}
ImGui::EndMenu();
diff --git a/src/PuzzleSingleImageState.hpp b/src/PuzzleSingleImageState.hpp
index 6556ac7..7ff97f0 100644
--- a/src/PuzzleSingleImageState.hpp
+++ b/src/PuzzleSingleImageState.hpp
@@ -35,7 +35,7 @@ public:
virtual ~PuzzleSingleImageState();
bool IsActive() override;
- void ProcessInput(const SDL_Event& event, bool &processed) override;
+ void ProcessInput(const SDL_Event& event, bool& processed) override;
void Draw(SDL_Renderer* target) override;
void Update() override;
diff --git a/src/config.cpp b/src/config.cpp
new file mode 100644
index 0000000..490016f
--- /dev/null
+++ b/src/config.cpp
@@ -0,0 +1,109 @@
+/*
+Copyright (c) 2025 Poul Sander
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation files
+(the "Software"), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge,
+publish, distribute, sublicense, and/or sell copies of the Software,
+and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+#include "config.hpp"
+#include "os.hpp"
+#include <fstream>
+
+std::map<std::string, std::string> LoadConfigMap() {
+ std::map<std::string, std::string> config;
+ std::string configPath = getPathToSaveFiles() + "/config.txt";
+ std::ifstream configFile(configPath);
+
+ if (configFile.is_open()) {
+ std::string line;
+ while (std::getline(configFile, line)) {
+ // Skip empty lines and comments
+ if (line.empty() || line[0] == '#') {
+ continue;
+ }
+
+ // Find the '=' separator
+ size_t separatorPos = line.find('=');
+ if (separatorPos != std::string::npos) {
+ std::string key = line.substr(0, separatorPos);
+ std::string value = line.substr(separatorPos + 1);
+ config[key] = value;
+ }
+ }
+ configFile.close();
+ }
+
+ return config;
+}
+
+void SaveConfigMap(const std::map<std::string, std::string>& config) {
+ std::string configPath = getPathToSaveFiles() + "/config.txt";
+ std::ofstream configFile(configPath);
+
+ if (configFile.is_open()) {
+ configFile << "# Sago Multi Scrambler Puzzle II Configuration" << std::endl;
+ for (const auto& pair : config) {
+ configFile << pair.first << "=" << pair.second << std::endl;
+ }
+ configFile.close();
+ }
+}
+
+bool GetConfigBool(const std::map<std::string, std::string>& config, const std::string& key, bool defaultValue) {
+ auto it = config.find(key);
+ if (it != config.end()) {
+ const std::string& value = it->second;
+ return (value == "1" || value == "true");
+ }
+ return defaultValue;
+}
+
+void SetConfigBool(std::map<std::string, std::string>& config, const std::string& key, bool value) {
+ config[key] = value ? "1" : "0";
+}
+
+int GetConfigInt(const std::map<std::string, std::string>& config, const std::string& key, int defaultValue) {
+ auto it = config.find(key);
+ if (it != config.end()) {
+ try {
+ return std::stoi(it->second);
+ }
+ catch (...) {
+ return defaultValue;
+ }
+ }
+ return defaultValue;
+}
+
+void SetConfigInt(std::map<std::string, std::string>& config, const std::string& key, int value) {
+ config[key] = std::to_string(value);
+}
+
+std::string GetConfigString(const std::map<std::string, std::string>& config, const std::string& key, const std::string& defaultValue) {
+ auto it = config.find(key);
+ if (it != config.end()) {
+ return it->second;
+ }
+ return defaultValue;
+}
+
+void SetConfigString(std::map<std::string, std::string>& config, const std::string& key, const std::string& value) {
+ config[key] = value;
+}
diff --git a/src/config.hpp b/src/config.hpp
new file mode 100644
index 0000000..11a41ea
--- /dev/null
+++ b/src/config.hpp
@@ -0,0 +1,94 @@
+/*
+Copyright (c) 2025 Poul Sander
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation files
+(the "Software"), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge,
+publish, distribute, sublicense, and/or sell copies of the Software,
+and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+#ifndef CONFIG_HPP
+#define CONFIG_HPP
+
+#include <string>
+#include <map>
+
+/**
+ * @brief Loads configuration from file into a map
+ * @return Map of configuration key-value pairs
+ */
+std::map<std::string, std::string> LoadConfigMap();
+
+/**
+ * @brief Saves configuration map to file
+ * @param config Map of configuration key-value pairs
+ */
+void SaveConfigMap(const std::map<std::string, std::string>& config);
+
+/**
+ * @brief Gets a boolean value from config map
+ * @param config The configuration map
+ * @param key The configuration key
+ * @param defaultValue Default value if key not found
+ * @return The boolean value
+ */
+bool GetConfigBool(const std::map<std::string, std::string>& config, const std::string& key, bool defaultValue);
+
+/**
+ * @brief Sets a boolean value in config map
+ * @param config The configuration map
+ * @param key The configuration key
+ * @param value The boolean value
+ */
+void SetConfigBool(std::map<std::string, std::string>& config, const std::string& key, bool value);
+
+/**
+ * @brief Gets an integer value from config map
+ * @param config The configuration map
+ * @param key The configuration key
+ * @param defaultValue Default value if key not found
+ * @return The integer value
+ */
+int GetConfigInt(const std::map<std::string, std::string>& config, const std::string& key, int defaultValue);
+
+/**
+ * @brief Sets an integer value in config map
+ * @param config The configuration map
+ * @param key The configuration key
+ * @param value The integer value
+ */
+void SetConfigInt(std::map<std::string, std::string>& config, const std::string& key, int value);
+
+/**
+ * @brief Gets a string value from config map
+ * @param config The configuration map
+ * @param key The configuration key
+ * @param defaultValue Default value if key not found
+ * @return The string value
+ */
+std::string GetConfigString(const std::map<std::string, std::string>& config, const std::string& key, const std::string& defaultValue);
+
+/**
+ * @brief Sets a string value in config map
+ * @param config The configuration map
+ * @param key The configuration key
+ * @param value The string value
+ */
+void SetConfigString(std::map<std::string, std::string>& config, const std::string& key, const std::string& value);
+
+#endif // CONFIG_HPP
diff --git a/src/rhash.hpp b/src/rhash.hpp
index cde203e..8ddd1d7 100644
--- a/src/rhash.hpp
+++ b/src/rhash.hpp
@@ -29,109 +29,109 @@ https://github.com/sago007/saland
class RHash {
public:
- RHash(unsigned hash_mask) {
- hash_ids.push_back(hash_mask);
- }
-
- RHash(std::initializer_list<unsigned> hash_list) : RHash(0) {
- for (unsigned hash_id : hash_list) {
- add_hash(hash_id);
- }
- }
-
- ~RHash() {
- if (ctx_) {
- rhash_free(ctx_);
- ctx_ = nullptr;
- }
- }
-
- void reinit() {
- if (ctx_) {
- rhash_free(ctx_);
- ctx_ = nullptr;
- }
- unsigned hash_mask = 0;
- for (unsigned hash_id : hash_ids) {
- hash_mask |= hash_id;
- }
- ctx_ = rhash_init(hash_mask);
- if (ctx_ == nullptr) {
- throw std::runtime_error("Failed to initialize RHash context");
- }
- done = false;
- }
-
- void add_hash(unsigned hash_id) {
- hash_ids.push_back(hash_id);
- }
-
- void update(const std::string& data) {
- if (!ctx_) {
- reinit();
- }
- if (done) {
- throw std::runtime_error("\"update\" called on a finalized rhash context");
- }
- rhash_update(ctx_, data.c_str(), data.length());
- length += data.length();
- }
-
- void finish() {
- rhash_final(ctx_, nullptr);
- done = true;
- }
-
- std::string hash_as_string(unsigned hash_id, int flags) {
- if (!done) {
- finish();
- }
- size_t length = rhash_get_hash_length(hash_id);
- std::vector<char> buffer(length);
- rhash_print(buffer.data(), ctx_, hash_id, flags);
- return std::string(buffer.data(), buffer.size());
- }
-
- std::string hex(unsigned hash_id) {
- return hash_as_string(hash_id, RHPR_HEX);
- }
-
- std::string HEX(unsigned hash_id) {
- return hash_as_string(hash_id, RHPR_HEX | RHPR_UPPERCASE);
- }
-
- std::string base32(unsigned hash_id) {
- return hash_as_string(hash_id, RHPR_BASE32);
- }
-
- std::string base64(unsigned hash_id) {
- return hash_as_string(hash_id, RHPR_BASE64);
- }
-
- size_t size() {
- return length;
- }
-
- void hash_file(const std::string& filename) {
- FILE* file = fopen(filename.c_str(), "rb");
- if (file == nullptr) {
- throw std::runtime_error("Failed to open file for hashing: " + filename);
- }
- reinit(); //Unconditionally reinit when loading a new file
- char buffer[1024];
- size_t bytes_read;
- while ((bytes_read = fread(buffer, 1, sizeof(buffer), file)) > 0) {
- rhash_update(ctx_, buffer, bytes_read);
- length += bytes_read;
- }
-
- fclose(file);
- rhash_final(ctx_, nullptr);
- }
+ RHash(unsigned hash_mask) {
+ hash_ids.push_back(hash_mask);
+ }
+
+ RHash(std::initializer_list<unsigned> hash_list) : RHash(0) {
+ for (unsigned hash_id : hash_list) {
+ add_hash(hash_id);
+ }
+ }
+
+ ~RHash() {
+ if (ctx_) {
+ rhash_free(ctx_);
+ ctx_ = nullptr;
+ }
+ }
+
+ void reinit() {
+ if (ctx_) {
+ rhash_free(ctx_);
+ ctx_ = nullptr;
+ }
+ unsigned hash_mask = 0;
+ for (unsigned hash_id : hash_ids) {
+ hash_mask |= hash_id;
+ }
+ ctx_ = rhash_init(hash_mask);
+ if (ctx_ == nullptr) {
+ throw std::runtime_error("Failed to initialize RHash context");
+ }
+ done = false;
+ }
+
+ void add_hash(unsigned hash_id) {
+ hash_ids.push_back(hash_id);
+ }
+
+ void update(const std::string& data) {
+ if (!ctx_) {
+ reinit();
+ }
+ if (done) {
+ throw std::runtime_error("\"update\" called on a finalized rhash context");
+ }
+ rhash_update(ctx_, data.c_str(), data.length());
+ length += data.length();
+ }
+
+ void finish() {
+ rhash_final(ctx_, nullptr);
+ done = true;
+ }
+
+ std::string hash_as_string(unsigned hash_id, int flags) {
+ if (!done) {
+ finish();
+ }
+ size_t length = rhash_get_hash_length(hash_id);
+ std::vector<char> buffer(length);
+ rhash_print(buffer.data(), ctx_, hash_id, flags);
+ return std::string(buffer.data(), buffer.size());
+ }
+
+ std::string hex(unsigned hash_id) {
+ return hash_as_string(hash_id, RHPR_HEX);
+ }
+
+ std::string HEX(unsigned hash_id) {
+ return hash_as_string(hash_id, RHPR_HEX | RHPR_UPPERCASE);
+ }
+
+ std::string base32(unsigned hash_id) {
+ return hash_as_string(hash_id, RHPR_BASE32);
+ }
+
+ std::string base64(unsigned hash_id) {
+ return hash_as_string(hash_id, RHPR_BASE64);
+ }
+
+ size_t size() {
+ return length;
+ }
+
+ void hash_file(const std::string& filename) {
+ FILE* file = fopen(filename.c_str(), "rb");
+ if (file == nullptr) {
+ throw std::runtime_error("Failed to open file for hashing: " + filename);
+ }
+ reinit(); //Unconditionally reinit when loading a new file
+ char buffer[1024];
+ size_t bytes_read;
+ while ((bytes_read = fread(buffer, 1, sizeof(buffer), file)) > 0) {
+ rhash_update(ctx_, buffer, bytes_read);
+ length += bytes_read;
+ }
+
+ fclose(file);
+ rhash_final(ctx_, nullptr);
+ }
private:
- struct rhash_context* ctx_ = nullptr;
- std::vector<unsigned> hash_ids;
- size_t length = 0;
- bool done = false;
+ struct rhash_context* ctx_ = nullptr;
+ std::vector<unsigned> hash_ids;
+ size_t length = 0;
+ bool done = false;
};
\ No newline at end of file