shithub: candycrisis

Download patch

ref: e646d6d829d50983ec2cba8e230a0b95341f6752
parent: a41d051499b5be820f4eb2a96efb8019bd1fcd53
author: Iliyas Jorio <iliyas@jor.io>
date: Thu Jul 30 17:37:20 EDT 2020

Linux support for prefs

--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,7 +1,7 @@
 cmake_minimum_required(VERSION 3.16)
 project(Candy_Crisis)
 
-set(CMAKE_CXX_STANDARD 14)
+set(CMAKE_CXX_STANDARD 17)
 
 set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/")
 find_package(SDL2 REQUIRED)
--- a/src/prefs.cpp
+++ b/src/prefs.cpp
@@ -4,6 +4,9 @@
 
 #if __APPLE__
 #include <Cocoa/Cocoa.h>
+#else
+#include <filesystem>
+#include <fstream>
 #endif
 
 #include <stdio.h>
@@ -41,9 +44,51 @@
     { PREF_NAME("BestCombo"),      &best,        sizeof(best      ) }
 };
 
+#if !__APPLE__ && !_WIN32
+static std::fstream GetPrefsStream(std::ios::openmode openmode)
+{
+    std::filesystem::path path;
+    const char *home = getenv("XDG_CONFIG_HOME");
+    if (home) {
+        path = std::filesystem::path(home);
+    } else {
+        home = getenv("HOME");
+        if (!home) {
+            throw std::exception();
+        }
+        path = std::filesystem::path(home) / ".config";
+    }
+    path = path.lexically_normal();
+    bool exists = std::filesystem::exists(path);
+    
+    if (!exists) {
+        if (openmode == std::ios::out)
+            std::filesystem::create_directories(path);
+        else
+            throw std::exception();
+    } else if (!std::filesystem::is_directory(path)) {
+        throw;
+    }
+    path /= "CandyCrisis.prefs";
+    
+    if (openmode == std::ios::in && !std::filesystem::is_regular_file(path))
+        throw std::exception();
 
+    return std::fstream(path, std::ios::binary | openmode);
+}
+#endif
+
 void LoadPrefs()
 {
+#if !__APPLE__ && !_WIN32
+    std::fstream stream;
+    try {
+        stream = GetPrefsStream(std::ios::in);
+    } catch (...) {
+        return;
+    }
+#endif
+    
     for (Preference& pref: prefList)
     {
         #if __APPLE__
@@ -52,8 +97,7 @@
             {
                 memcpy(pref.valuePtr, [data bytes], pref.valueLength);
             }
-        #endif
-        #if _WIN32
+        #elif _WIN32
             HKEY hKey;
             if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("SOFTWARE\\CandyCrisis"), 0, KEY_QUERY_VALUE, &hKey))
             {
@@ -69,6 +113,28 @@
                 
                 RegCloseKey(hKey);
             }
+        #else
+            stream.seekg(0, std::ios::beg);
+            while (!stream.eof()) {
+                int keyLength;
+                char key[256];
+                unsigned int contentsLength;
+                
+                keyLength = stream.get();
+                if (stream.eof()) break;
+                stream.read(key, keyLength);
+                key[keyLength] = '\0';
+                stream.read((char*)&contentsLength, sizeof(contentsLength));
+                
+                if (!strncmp(key, pref.keyName, strlen(pref.keyName))) {
+                    if (contentsLength != pref.valueLength)
+                        break;
+                    stream.read((char*) pref.valuePtr, pref.valueLength);
+                    break;
+                } else {
+                    stream.seekg(contentsLength, std::ios::cur);
+                }
+            }
         #endif
     }
 }
@@ -76,6 +142,15 @@
 
 void SavePrefs()
 {
+#if !__APPLE__ && !_WIN32
+    std::fstream stream;
+    try {
+        stream = GetPrefsStream(std::ios::out);
+    } catch (...) {
+        return;
+    }
+#endif
+    
     for (Preference& pref: prefList)
     {
         #if __APPLE__
@@ -82,8 +157,7 @@
             [[NSUserDefaults standardUserDefaults]
                 setObject:[NSData dataWithBytes:pref.valuePtr length:pref.valueLength]
                    forKey:pref.keyName];
-        #endif
-        #if _WIN32
+        #elif _WIN32
             HKEY hKey;
             if (ERROR_SUCCESS == RegCreateKeyEx(HKEY_CURRENT_USER, TEXT("SOFTWARE\\CandyCrisis"), 0, NULL, 0, KEY_WRITE, NULL, &hKey, NULL))
             {
@@ -90,6 +164,11 @@
                 RegSetValueEx(hKey, pref.keyName, 0, REG_BINARY, reinterpret_cast<BYTE*>(pref.valuePtr), pref.valueLength);
                 RegCloseKey(hKey);
             }
+        #else
+            stream.put(strlen(pref.keyName));
+            stream.write(pref.keyName, strlen(pref.keyName));
+            stream.write((const char*)&pref.valueLength, sizeof(pref.valueLength));
+            stream.write((const char*)pref.valuePtr, pref.valueLength);
         #endif
     }