diff options
author | SuuperW <SuuperW@gmail.com> | 2021-02-22 19:46:02 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-02-23 02:46:02 +0100 |
commit | 94dcc9523eb1dfac0141d76eb148184b8c911781 (patch) | |
tree | 720a744993ced7b38c7decb7401f0b3dae5e8d43 /src | |
parent | 58dd1ec58063707c7944ae8c5b8c2019102de102 (diff) |
SRAM things (#970)
* Allow SRAMManager to save to/load from a buffer.
* Don't delete what doesn't exist. Don't create a thread that will do absolutely nothing.
* Update SRAMManager's SecondaryBuffer when loading a savestate.
Diffstat (limited to 'src')
-rw-r--r-- | src/NDSCart.cpp | 5 | ||||
-rw-r--r-- | src/NDSCart_SRAMManager.cpp | 66 | ||||
-rw-r--r-- | src/NDSCart_SRAMManager.h | 6 |
3 files changed, 58 insertions, 19 deletions
diff --git a/src/NDSCart.cpp b/src/NDSCart.cpp index ae051bd..f08e5da 100644 --- a/src/NDSCart.cpp +++ b/src/NDSCart.cpp @@ -111,6 +111,10 @@ void DoSavestate(Savestate* file) file->Var8(&StatusReg); file->Var32(&Addr); + + // SRAMManager might now have an old buffer (or one from the future or alternate timeline!) + if (!file->Saving) + NDSCart_SRAMManager::RequestFlush(); } void LoadSave(const char* path, u32 type) @@ -145,6 +149,7 @@ void LoadSave(const char* path, u32 type) } } + SRAMFileDirty = false; NDSCart_SRAMManager::Setup(path, SRAM, SRAMLength); switch (SRAMLength) diff --git a/src/NDSCart_SRAMManager.cpp b/src/NDSCart_SRAMManager.cpp index 88ff40b..c93db2a 100644 --- a/src/NDSCart_SRAMManager.cpp +++ b/src/NDSCart_SRAMManager.cpp @@ -45,13 +45,9 @@ namespace NDSCart_SRAMManager u32 FlushVersion; void FlushThreadFunc(); - void FlushSecondaryBufferToFile(); bool Init() { - FlushThread = Platform::Thread_Create(FlushThreadFunc); - FlushThreadRunning = true; - SecondaryBufferLock = Platform::Mutex_Create(); return true; @@ -64,10 +60,11 @@ namespace NDSCart_SRAMManager FlushThreadRunning = false; Platform::Thread_Wait(FlushThread); Platform::Thread_Free(FlushThread); - FlushSecondaryBufferToFile(); + FlushSecondaryBuffer(); } - delete SecondaryBuffer; + if (SecondaryBuffer) delete SecondaryBuffer; + SecondaryBuffer = NULL; Platform::Mutex_Free(SecondaryBufferLock); } @@ -75,7 +72,7 @@ namespace NDSCart_SRAMManager void Setup(const char* path, u8* buffer, u32 length) { // Flush SRAM in case there is unflushed data from previous state. - FlushSecondaryBufferToFile(); + FlushSecondaryBuffer(); Platform::Mutex_Lock(SecondaryBufferLock); @@ -85,7 +82,7 @@ namespace NDSCart_SRAMManager Buffer = buffer; Length = length; - delete SecondaryBuffer; // Delete secondary buffer, there might be previous state. + if(SecondaryBuffer) delete SecondaryBuffer; // Delete secondary buffer, there might be previous state. SecondaryBuffer = new u8[length]; SecondaryBufferLength = length; @@ -95,6 +92,12 @@ namespace NDSCart_SRAMManager TimeAtLastFlushRequest = 0; Platform::Mutex_Unlock(SecondaryBufferLock); + + if (path[0] != '\0') + { + FlushThread = Platform::Thread_Create(FlushThreadFunc); + FlushThreadRunning = true; + } } void RequestFlush() @@ -121,27 +124,52 @@ namespace NDSCart_SRAMManager continue; } - FlushSecondaryBufferToFile(); + FlushSecondaryBuffer(); } } - void FlushSecondaryBufferToFile() + void FlushSecondaryBuffer(u8* dst, s32 dstLength) { - if (FlushVersion == PreviousFlushVersion) - { - return; - } + // 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); - FILE* f = Platform::OpenFile(Path, "wb"); - if (f) + if (dst) { - printf("NDS SRAM: Written\n"); - fwrite(SecondaryBuffer, SecondaryBufferLength, 1, f); - fclose(f); + 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; + } } diff --git a/src/NDSCart_SRAMManager.h b/src/NDSCart_SRAMManager.h index 2486af2..7d07d40 100644 --- a/src/NDSCart_SRAMManager.h +++ b/src/NDSCart_SRAMManager.h @@ -23,11 +23,17 @@ namespace NDSCart_SRAMManager { + extern u32 SecondaryBufferLength; + bool Init(); void DeInit(); void Setup(const char* path, u8* buffer, u32 length); void RequestFlush(); + + bool NeedsFlush(); + void FlushSecondaryBuffer(u8* dst = NULL, s32 dstLength = 0); + void UpdateBuffer(u8* src, s32 srcLength); } #endif // NDSCART_SRAMMANAGER_H
\ No newline at end of file |