aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSuuperW <SuuperW@gmail.com>2021-02-22 19:46:02 -0600
committerGitHub <noreply@github.com>2021-02-23 02:46:02 +0100
commit94dcc9523eb1dfac0141d76eb148184b8c911781 (patch)
tree720a744993ced7b38c7decb7401f0b3dae5e8d43 /src
parent58dd1ec58063707c7944ae8c5b8c2019102de102 (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.cpp5
-rw-r--r--src/NDSCart_SRAMManager.cpp66
-rw-r--r--src/NDSCart_SRAMManager.h6
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