diff options
Diffstat (limited to 'src/NDSCart_SRAMManager.cpp')
-rw-r--r-- | src/NDSCart_SRAMManager.cpp | 184 |
1 files changed, 0 insertions, 184 deletions
diff --git a/src/NDSCart_SRAMManager.cpp b/src/NDSCart_SRAMManager.cpp deleted file mode 100644 index addd122..0000000 --- a/src/NDSCart_SRAMManager.cpp +++ /dev/null @@ -1,184 +0,0 @@ -/* - Copyright 2016-2021 Arisotura - - This file is part of melonDS. - - melonDS 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. - - melonDS 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 melonDS. If not, see http://www.gnu.org/licenses/. -*/ - -#include <stdio.h> -#include <string.h> -#include <unistd.h> -#include <time.h> -#include <atomic> -#include "NDSCart_SRAMManager.h" -#include "Platform.h" - -namespace NDSCart_SRAMManager -{ - -Platform::Thread* FlushThread; -std::atomic_bool FlushThreadRunning; -Platform::Mutex* SecondaryBufferLock; - -char Path[1024]; - -u8* Buffer; -u32 Length; - -u8* SecondaryBuffer; -u32 SecondaryBufferLength; - -time_t TimeAtLastFlushRequest; - -// We keep versions in case the user closes the application before -// a flush cycle is finished. -u32 PreviousFlushVersion; -u32 FlushVersion; - -void FlushThreadFunc(); - -bool Init() -{ - SecondaryBufferLock = Platform::Mutex_Create(); - - return true; -} - -void DeInit() -{ - if (FlushThreadRunning) - { - FlushThreadRunning = false; - Platform::Thread_Wait(FlushThread); - Platform::Thread_Free(FlushThread); - FlushSecondaryBuffer(); - } - - if (SecondaryBuffer) delete[] SecondaryBuffer; - SecondaryBuffer = NULL; - - Platform::Mutex_Free(SecondaryBufferLock); -} - -void Setup(const char* path, u8* buffer, u32 length) -{ - // Flush SRAM in case there is unflushed data from previous state. - FlushSecondaryBuffer(); - - Platform::Mutex_Lock(SecondaryBufferLock); - - strncpy(Path, path, 1023); - Path[1023] = '\0'; - - Buffer = buffer; - Length = length; - - if(SecondaryBuffer) delete[] SecondaryBuffer; // Delete secondary buffer, there might be previous state. - - SecondaryBuffer = new u8[length]; - SecondaryBufferLength = length; - - FlushVersion = 0; - PreviousFlushVersion = 0; - TimeAtLastFlushRequest = 0; - - Platform::Mutex_Unlock(SecondaryBufferLock); - - if (path[0] != '\0' && !FlushThreadRunning) - { - FlushThread = Platform::Thread_Create(FlushThreadFunc); - FlushThreadRunning = true; - } - else if (path[0] == '\0' && FlushThreadRunning) - { - FlushThreadRunning = false; - Platform::Thread_Wait(FlushThread); - Platform::Thread_Free(FlushThread); - } -} - -void RequestFlush() -{ - Platform::Mutex_Lock(SecondaryBufferLock); - printf("NDS SRAM: Flush requested\n"); - memcpy(SecondaryBuffer, Buffer, Length); - FlushVersion++; - TimeAtLastFlushRequest = time(NULL); - Platform::Mutex_Unlock(SecondaryBufferLock); -} - -void FlushThreadFunc() -{ - for (;;) - { - Platform::Sleep(100 * 1000); // 100ms - - if (!FlushThreadRunning) return; - - // We debounce for two seconds after last flush request to ensure that writing has finished. - if (TimeAtLastFlushRequest == 0 || difftime(time(NULL), TimeAtLastFlushRequest) < 2) - { - continue; - } - - FlushSecondaryBuffer(); - } -} - -void FlushSecondaryBuffer(u8* dst, s32 dstLength) -{ - // When flushing to a file, there's no point in re-writing the exact same data. - if (!dst && !NeedsFlush()) return; - // When flushing to memory, we don't know if dst already has any data so we only check that we CAN flush. - if (dst && dstLength < SecondaryBufferLength) return; - - Platform::Mutex_Lock(SecondaryBufferLock); - if (dst) - { - memcpy(dst, SecondaryBuffer, SecondaryBufferLength); - } - else - { - FILE* f = Platform::OpenFile(Path, "wb"); - if (f) - { - printf("NDS SRAM: Written\n"); - fwrite(SecondaryBuffer, SecondaryBufferLength, 1, f); - fclose(f); - } - } - PreviousFlushVersion = FlushVersion; - TimeAtLastFlushRequest = 0; - Platform::Mutex_Unlock(SecondaryBufferLock); -} - -bool NeedsFlush() -{ - return FlushVersion != PreviousFlushVersion; -} - -void UpdateBuffer(u8* src, s32 srcLength) -{ - if (!src || srcLength != Length) return; - - // should we create a lock for the primary buffer? this method is not intended to be called from a secondary thread in the way Flush is - memcpy(Buffer, src, srcLength); - Platform::Mutex_Lock(SecondaryBufferLock); - memcpy(SecondaryBuffer, src, srcLength); - Platform::Mutex_Unlock(SecondaryBufferLock); - - PreviousFlushVersion = FlushVersion; -} - -} |