From 7f9b5787c110523be877539243b1e3e393a620f3 Mon Sep 17 00:00:00 2001 From: GenesiaW <74142392+GenesiaW@users.noreply.github.com> Date: Wed, 28 Jan 2026 19:57:19 +0800 Subject: [PATCH] feat: add automatic bootloop recovery --- src/CrossPointState.cpp | 7 ++++++- src/CrossPointState.h | 1 + src/activities/reader/EpubReaderActivity.cpp | 2 ++ src/activities/reader/TxtReaderActivity.cpp | 2 ++ src/activities/reader/XtcReaderActivity.cpp | 2 ++ src/main.cpp | 5 ++++- 6 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/CrossPointState.cpp b/src/CrossPointState.cpp index 91aa2536..d578945c 100644 --- a/src/CrossPointState.cpp +++ b/src/CrossPointState.cpp @@ -5,7 +5,7 @@ #include namespace { -constexpr uint8_t STATE_FILE_VERSION = 2; +constexpr uint8_t STATE_FILE_VERSION = 3; constexpr char STATE_FILE[] = "/.crosspoint/state.bin"; } // namespace @@ -20,6 +20,7 @@ bool CrossPointState::saveToFile() const { serialization::writePod(outputFile, STATE_FILE_VERSION); serialization::writeString(outputFile, openEpubPath); serialization::writePod(outputFile, lastSleepImage); + serialization::writePod(outputFile, readerActivityLoadCount); outputFile.close(); return true; } @@ -45,6 +46,10 @@ bool CrossPointState::loadFromFile() { lastSleepImage = 0; } + if (version >= 3) { + serialization::readPod(inputFile, readerActivityLoadCount); + } + inputFile.close(); return true; } diff --git a/src/CrossPointState.h b/src/CrossPointState.h index 87ce4e96..e8c65c10 100644 --- a/src/CrossPointState.h +++ b/src/CrossPointState.h @@ -9,6 +9,7 @@ class CrossPointState { public: std::string openEpubPath; uint8_t lastSleepImage; + uint8_t readerActivityLoadCount = 0; ~CrossPointState() = default; // Get singleton instance diff --git a/src/activities/reader/EpubReaderActivity.cpp b/src/activities/reader/EpubReaderActivity.cpp index 58668c68..9cfc1e0b 100644 --- a/src/activities/reader/EpubReaderActivity.cpp +++ b/src/activities/reader/EpubReaderActivity.cpp @@ -112,6 +112,8 @@ void EpubReaderActivity::onExit() { } vSemaphoreDelete(renderingMutex); renderingMutex = nullptr; + APP_STATE.readerActivityLoadCount = 0; + APP_STATE.saveToFile(); section.reset(); epub.reset(); } diff --git a/src/activities/reader/TxtReaderActivity.cpp b/src/activities/reader/TxtReaderActivity.cpp index e9303de3..8cfd6eed 100644 --- a/src/activities/reader/TxtReaderActivity.cpp +++ b/src/activities/reader/TxtReaderActivity.cpp @@ -89,6 +89,8 @@ void TxtReaderActivity::onExit() { renderingMutex = nullptr; pageOffsets.clear(); currentPageLines.clear(); + APP_STATE.readerActivityLoadCount = 0; + APP_STATE.saveToFile(); txt.reset(); } diff --git a/src/activities/reader/XtcReaderActivity.cpp b/src/activities/reader/XtcReaderActivity.cpp index f579abcd..5aef68c5 100644 --- a/src/activities/reader/XtcReaderActivity.cpp +++ b/src/activities/reader/XtcReaderActivity.cpp @@ -69,6 +69,8 @@ void XtcReaderActivity::onExit() { } vSemaphoreDelete(renderingMutex); renderingMutex = nullptr; + APP_STATE.readerActivityLoadCount = 0; + APP_STATE.saveToFile(); xtc.reset(); } diff --git a/src/main.cpp b/src/main.cpp index 2456f96e..c1ac6b1d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -311,13 +311,16 @@ void setup() { APP_STATE.loadFromFile(); RECENT_BOOKS.loadFromFile(); - if (APP_STATE.openEpubPath.empty() || mappedInputManager.isPressed(MappedInputManager::Button::Back)) { + // Boot to home screen directly when back button is held or when reader activity crashes 3 times + if (APP_STATE.openEpubPath.empty() || mappedInputManager.isPressed(MappedInputManager::Button::Back) || + APP_STATE.readerActivityLoadCount > 2) { onGoHome(); } else { // Clear app state to avoid getting into a boot loop if the epub doesn't load const auto path = APP_STATE.openEpubPath; APP_STATE.openEpubPath = ""; APP_STATE.lastSleepImage = 0; + APP_STATE.readerActivityLoadCount++; APP_STATE.saveToFile(); onGoToReader(path, MyLibraryActivity::Tab::Recent); }