diff --git a/src/CrossPointSettings.cpp b/src/CrossPointSettings.cpp new file mode 100644 index 0000000..edc2fc8 --- /dev/null +++ b/src/CrossPointSettings.cpp @@ -0,0 +1,46 @@ +#include "CrossPointSettings.h" + +#include +#include +#include + +#include + +constexpr uint8_t SETTINGS_FILE_VERSION = 1; +constexpr char SETTINGS_FILE[] = "/sd/.crosspoint/settings.bin"; + +bool CrossPointSettings::saveToFile() const { + // Make sure the directory exists + SD.mkdir("/.crosspoint"); + + std::ofstream outputFile(SETTINGS_FILE); + serialization::writePod(outputFile, SETTINGS_FILE_VERSION); + serialization::writePod(outputFile, whiteSleepScreen); + outputFile.close(); + + Serial.printf("[%lu] [CPS] Settings saved to file\n", millis()); + return true; +} + +bool CrossPointSettings::loadFromFile() { + if (!SD.exists(SETTINGS_FILE + 3)) { // +3 to skip "/sd" prefix + Serial.printf("[%lu] [CPS] Settings file does not exist, using defaults\n", millis()); + return false; + } + + std::ifstream inputFile(SETTINGS_FILE); + + uint8_t version; + serialization::readPod(inputFile, version); + if (version != SETTINGS_FILE_VERSION) { + Serial.printf("[%lu] [CPS] Deserialization failed: Unknown version %u\n", millis(), version); + inputFile.close(); + return false; + } + + serialization::readPod(inputFile, whiteSleepScreen); + + inputFile.close(); + Serial.printf("[%lu] [CPS] Settings loaded from file\n", millis()); + return true; +} \ No newline at end of file diff --git a/src/CrossPointSettings.h b/src/CrossPointSettings.h new file mode 100644 index 0000000..01fc100 --- /dev/null +++ b/src/CrossPointSettings.h @@ -0,0 +1,13 @@ +#pragma once +#include + +class CrossPointSettings { + public: + // Sleep screen settings + bool whiteSleepScreen = false; + + ~CrossPointSettings() = default; + + bool saveToFile() const; + bool loadFromFile(); +}; \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 248e061..bfb311f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -14,6 +14,7 @@ #include #include "Battery.h" +#include "CrossPointSettings.h" #include "CrossPointState.h" #include "config.h" #include "screens/BootLogoScreen.h" @@ -41,6 +42,7 @@ InputManager inputManager; GfxRenderer renderer(einkDisplay); Screen* currentScreen; CrossPointState appState; +CrossPointSettings appSettings; // Fonts EpdFont bookerlyFont(&bookerly_2b); @@ -131,7 +133,8 @@ void waitForPowerRelease() { // Enter deep sleep mode void enterDeepSleep() { exitScreen(); - enterNewScreen(new SleepScreen(renderer, inputManager)); + appSettings.saveToFile(); + enterNewScreen(new SleepScreen(renderer, inputManager, appSettings)); Serial.printf("[%lu] [ ] Power button released after a long press. Entering deep sleep.\n", millis()); delay(1000); // Allow Serial buffer to empty and display to update @@ -199,6 +202,7 @@ void setup() { // SD Card Initialization SD.begin(SD_SPI_CS, SPI, SPI_FQ); + appSettings.loadFromFile(); appState.loadFromFile(); if (!appState.openEpubPath.empty()) { auto epub = loadEpub(appState.openEpubPath); diff --git a/src/screens/SleepScreen.cpp b/src/screens/SleepScreen.cpp index ec2c08d..a64f500 100644 --- a/src/screens/SleepScreen.cpp +++ b/src/screens/SleepScreen.cpp @@ -4,6 +4,7 @@ #include "config.h" #include "images/CrossLarge.h" +#include "CrossPointSettings.h" void SleepScreen::onEnter() { const auto pageWidth = GfxRenderer::getScreenWidth(); @@ -13,6 +14,11 @@ void SleepScreen::onEnter() { renderer.drawImage(CrossLarge, (pageWidth - 128) / 2, (pageHeight - 128) / 2, 128, 128); renderer.drawCenteredText(UI_FONT_ID, pageHeight / 2 + 70, "CrossPoint", true, BOLD); renderer.drawCenteredText(SMALL_FONT_ID, pageHeight / 2 + 95, "SLEEPING"); - // renderer.invertScreen(); + + // Apply white screen if enabled in settings + if (!settings.whiteSleepScreen) { + renderer.invertScreen(); + } + renderer.displayBuffer(EInkDisplay::HALF_REFRESH); } diff --git a/src/screens/SleepScreen.h b/src/screens/SleepScreen.h index b280087..f0dea52 100644 --- a/src/screens/SleepScreen.h +++ b/src/screens/SleepScreen.h @@ -1,8 +1,14 @@ #pragma once #include "Screen.h" +class CrossPointSettings; + class SleepScreen final : public Screen { public: - explicit SleepScreen(GfxRenderer& renderer, InputManager& inputManager) : Screen(renderer, inputManager) {} + explicit SleepScreen(GfxRenderer& renderer, InputManager& inputManager, const CrossPointSettings& settings) + : Screen(renderer, inputManager), settings(settings) {} void onEnter() override; + + private: + const CrossPointSettings& settings; };