Change up Mempak so it uses CFile class.

Also modify the way mempaks are loaded and written. We only write the bytes that have been changed now, rather then writing the whole file every time the mempak is written to.
This commit is contained in:
Emmet Young 2016-05-16 18:23:31 +10:00
parent a95b35ec2e
commit ff4bd28e3e
3 changed files with 32 additions and 20 deletions

View File

@ -14,8 +14,9 @@ class Mempak
{ {
public: public:
static uint8_t CalculateCrc(uint8_t * DataToCrc); static uint8_t CalculateCrc(uint8_t * DataToCrc);
static void Load(int32_t Control);
static void Format(int32_t Control);
static void ReadFrom(int32_t Control, uint32_t address, uint8_t * data); static void ReadFrom(int32_t Control, uint32_t address, uint8_t * data);
static void WriteTo(int32_t Control, uint32_t address, uint8_t * data); static void WriteTo(int32_t Control, uint32_t address, uint8_t * data);
private:
static void LoadMempak(int32_t Control);
static void Format(int32_t Control);
}; };

View File

@ -15,33 +15,37 @@
#include <Common/path.h> #include <Common/path.h>
uint8_t Mempaks[4][128 * 256]; /* [CONTROLLERS][PAGES][BYTES_PER_PAGE] */ uint8_t Mempaks[4][128 * 256]; /* [CONTROLLERS][PAGES][BYTES_PER_PAGE] */
CPath MempakNames[4]; CFile MempakHandle[4];
void Mempak::Load(int32_t Control) void Mempak::LoadMempak(int32_t Control)
{ {
stdstr MempakName; stdstr MempakName;
MempakName.Format("%s_Cont_%d", g_Settings->LoadStringVal(Game_GameName).c_str(), Control + 1); MempakName.Format("%s_Cont_%d", g_Settings->LoadStringVal(Game_GameName).c_str(), Control + 1);
MempakNames[Control] = CPath(g_Settings->LoadStringVal(Directory_NativeSave).c_str(), stdstr_f("%s.mpk",MempakName.c_str()).c_str()); CPath MempakPath(g_Settings->LoadStringVal(Directory_NativeSave).c_str(), stdstr_f("%s.mpk",MempakName.c_str()).c_str());
if (g_Settings->LoadBool(Setting_UniqueSaveDir)) if (g_Settings->LoadBool(Setting_UniqueSaveDir))
{ {
MempakNames[Control].AppendDirectory(g_Settings->LoadStringVal(Game_UniqueSaveDir).c_str()); MempakPath.AppendDirectory(g_Settings->LoadStringVal(Game_UniqueSaveDir).c_str());
} }
if (!MempakNames[Control].DirectoryExists()) if (!MempakPath.DirectoryExists())
{ {
MempakNames[Control].DirectoryCreate(); MempakPath.DirectoryCreate();
} }
if (MempakNames[Control].Exists()) bool formatMempak = !MempakPath.Exists();
MempakHandle[Control].Open(MempakPath, CFileBase::modeReadWrite | CFileBase::modeNoTruncate | CFileBase::modeCreate);
MempakHandle[Control].SeekToBegin();
if (formatMempak)
{ {
FILE *mempak = fopen(MempakNames[Control], "rb"); Mempak::Format(Control);
fread(Mempaks[Control], 1, 0x8000, mempak); MempakHandle[Control].Write(Mempaks[Control], 0x8000);
fclose(mempak);
} }
else else
{ {
Mempak::Format(Control); MempakHandle[Control].Read(Mempaks[Control], 0x8000);
} }
} }
@ -113,6 +117,11 @@ void Mempak::ReadFrom(int32_t Control, uint32_t address, uint8_t * data)
{ {
if (address < 0x8000) if (address < 0x8000)
{ {
if (!MempakHandle[Control].IsOpen())
{
LoadMempak(Control);
}
memcpy(data, &Mempaks[Control][address], 0x20); memcpy(data, &Mempaks[Control][address], 0x20);
} }
else else
@ -126,11 +135,16 @@ void Mempak::WriteTo(int32_t Control, uint32_t address, uint8_t * data)
{ {
if (address < 0x8000) if (address < 0x8000)
{ {
if (!MempakHandle[Control].IsOpen())
{
LoadMempak(Control);
}
memcpy(&Mempaks[Control][address], data, 0x20); memcpy(&Mempaks[Control][address], data, 0x20);
FILE* mempak = fopen(MempakNames[Control], "wb"); MempakHandle[Control].Seek(address, CFile::begin);
fwrite(Mempaks[Control], 1, 0x8000, mempak); MempakHandle[Control].Write(data, 0x20);
fclose(mempak); MempakHandle[Control].Flush();
} }
else else
{ {

View File

@ -699,9 +699,6 @@ bool CN64System::SetActiveSystem(bool bActive)
case PLUGIN_TANSFER_PAK: case PLUGIN_TANSFER_PAK:
Transferpak::Init(); Transferpak::Init();
break; break;
case PLUGIN_MEMPAK:
Mempak::Load(i);
break;
} }
} }
} }