Change up the way Mempaks are meant to work, use the standard file functions. Mempaks are now loaded in when the game launches, and file handles are only opened durring read and writes
This commit is contained in:
parent
72e6928ea8
commit
643a684c77
|
@ -1,20 +1,21 @@
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* *
|
* *
|
||||||
* Project64 - A Nintendo 64 emulator. *
|
* Project64 - A Nintendo 64 emulator. *
|
||||||
* http://www.pj64-emu.com/ *
|
* http://www.pj64-emu.com/ *
|
||||||
* Copyright (C) 2012 Project64. All rights reserved. *
|
* Copyright (C) 2012 Project64. All rights reserved. *
|
||||||
* *
|
* *
|
||||||
* License: *
|
* License: *
|
||||||
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
|
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
|
||||||
* *
|
* *
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
class Mempak
|
class Mempak
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static void Close();
|
static uint8_t CalculateCrc(uint8_t * DataToCrc);
|
||||||
static uint8_t CalculateCrc(uint8_t * DataToCrc);
|
static void Load();
|
||||||
static void ReadFrom(int32_t Control, uint8_t * command);
|
static void Format(int32_t Control);
|
||||||
static void WriteTo(int32_t Control, uint8_t * command);
|
static void ReadFrom(int32_t Control, uint8_t * command);
|
||||||
};
|
static void WriteTo(int32_t Control, uint8_t * command);
|
||||||
|
};
|
|
@ -1,173 +1,143 @@
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* *
|
* *
|
||||||
* Project64 - A Nintendo 64 emulator. *
|
* Project64 - A Nintendo 64 emulator. *
|
||||||
* http://www.pj64-emu.com/ *
|
* http://www.pj64-emu.com/ *
|
||||||
* Copyright (C) 2012 Project64. All rights reserved. *
|
* Copyright (C) 2012 Project64. All rights reserved. *
|
||||||
* *
|
* *
|
||||||
* License: *
|
* License: *
|
||||||
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
|
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
|
||||||
* *
|
* *
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "Mempak.H"
|
#include "Mempak.H"
|
||||||
#include <Common/path.h>
|
#include <Common/path.h>
|
||||||
#include <Windows.h>
|
|
||||||
|
uint8_t Mempaks[4][0x8000];
|
||||||
static uint8_t Mempaks[4][0x8000];
|
CPath MempakNames[4];
|
||||||
void * hMempakFile[4];
|
|
||||||
|
void Mempak::Load()
|
||||||
void Mempak::Close()
|
{
|
||||||
{
|
stdstr MempakName;
|
||||||
for (int32_t i = 0; i < 4; i++)
|
|
||||||
{
|
for (int i = 0; i < 3; i++)
|
||||||
if (hMempakFile[i])
|
{
|
||||||
{
|
MempakName.Format("%s_Cont_%d", g_Settings->LoadStringVal(Game_GameName).c_str(), i + 1);
|
||||||
CloseHandle(hMempakFile[i]);
|
|
||||||
hMempakFile[i] = NULL;
|
MempakNames[i].SetDriveDirectory(g_Settings->LoadStringVal(Directory_NativeSave).c_str());
|
||||||
}
|
MempakNames[i].SetName(MempakName.c_str());
|
||||||
}
|
MempakNames[i].SetExtension("mpk");
|
||||||
}
|
|
||||||
|
if (!MempakNames[i].DirectoryExists())
|
||||||
void LoadMempak(int32_t Control)
|
{
|
||||||
{
|
MempakNames[i].DirectoryCreate();
|
||||||
CPath FileName;
|
}
|
||||||
DWORD dwRead;
|
|
||||||
stdstr MempakName;
|
if (MempakNames[i].Exists())
|
||||||
bool bFormatMempak = false;
|
{
|
||||||
|
FILE *mempak = fopen(MempakNames[i], "rb");
|
||||||
MempakName.Format("%s_Cont_%d", g_Settings->LoadStringVal(Game_GameName).c_str(), Control + 1);
|
fread(Mempaks[i], 1, 0x8000, mempak);
|
||||||
|
fclose(mempak);
|
||||||
FileName.SetDriveDirectory(g_Settings->LoadStringVal(Directory_NativeSave).c_str());
|
}
|
||||||
FileName.SetName(MempakName.c_str());
|
else
|
||||||
FileName.SetExtension("mpk");
|
{
|
||||||
|
Mempak::Format(i);
|
||||||
if (!FileName.Exists())
|
}
|
||||||
{
|
}
|
||||||
bFormatMempak = true;
|
}
|
||||||
|
|
||||||
if (!FileName.DirectoryExists())
|
void Mempak::Format(int32_t Control)
|
||||||
{
|
{
|
||||||
FileName.DirectoryCreate();
|
uint8_t Initialize[] = {
|
||||||
}
|
0x81, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0C, 0x0D, 0x0E, 0x0F,
|
||||||
|
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
|
||||||
uint8_t Initialize[] = {
|
0xFF, 0xFF, 0xFF, 0xFF, 0x05, 0x1A, 0x5F, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x81, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0C, 0x0D, 0x0E, 0x0F,
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0xFF, 0x66, 0x25, 0x99, 0xCD,
|
||||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0x05, 0x1A, 0x5F, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0xFF, 0x66, 0x25, 0x99, 0xCD,
|
0xFF, 0xFF, 0xFF, 0xFF, 0x05, 0x1A, 0x5F, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0xFF, 0x66, 0x25, 0x99, 0xCD,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0xFF, 0xFF, 0xFF, 0xFF, 0x05, 0x1A, 0x5F, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0x05, 0x1A, 0x5F, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0xFF, 0x66, 0x25, 0x99, 0xCD,
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0xFF, 0x66, 0x25, 0x99, 0xCD,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0x05, 0x1A, 0x5F, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0xFF, 0x66, 0x25, 0x99, 0xCD,
|
0xFF, 0xFF, 0xFF, 0xFF, 0x05, 0x1A, 0x5F, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0xFF, 0x66, 0x25, 0x99, 0xCD,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0x05, 0x1A, 0x5F, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0xFF, 0x66, 0x25, 0x99, 0xCD,
|
0x00, 0x71, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
};
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x71, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
|
memcpy(&Mempaks[Control][0], Initialize, 0x110);
|
||||||
};
|
|
||||||
|
for (int32_t count = 0x110; count < 0x8000; count += 2)
|
||||||
memcpy(&Mempaks[Control][0], Initialize, 0x110);
|
{
|
||||||
|
Mempaks[Control][count] = 0x00;
|
||||||
for (int32_t count = 0x110; count < 0x8000; count += 2)
|
Mempaks[Control][count + 1] = 0x03;
|
||||||
{
|
}
|
||||||
Mempaks[Control][count] = 0x00;
|
}
|
||||||
Mempaks[Control][count + 1] = 0x03;
|
|
||||||
}
|
uint8_t Mempak::CalculateCrc(uint8_t * DataToCrc)
|
||||||
}
|
{
|
||||||
|
uint32_t Count;
|
||||||
hMempakFile[Control] = CreateFile(FileName, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, NULL);
|
uint32_t XorTap;
|
||||||
|
|
||||||
if (hMempakFile[Control] == INVALID_HANDLE_VALUE)
|
int32_t Length;
|
||||||
{
|
uint8_t CRC = 0;
|
||||||
WriteTrace(TraceN64System, TraceError, "Failed to open (%s), lastError = %X", (LPCTSTR)FileName, GetLastError());
|
|
||||||
return;
|
for (Count = 0; Count < 0x21; Count++)
|
||||||
}
|
{
|
||||||
|
for (Length = 0x80; Length >= 1; Length >>= 1)
|
||||||
SetFilePointer(hMempakFile[Control], 0, NULL, FILE_BEGIN);
|
{
|
||||||
if (bFormatMempak)
|
XorTap = (CRC & 0x80) ? 0x85 : 0x00;
|
||||||
{
|
CRC <<= 1;
|
||||||
WriteFile(hMempakFile[Control], Mempaks[Control], 0x8000, &dwRead, NULL);
|
if (Count == 0x20)
|
||||||
}
|
{
|
||||||
else
|
CRC &= 0xFF;
|
||||||
{
|
}
|
||||||
ReadFile(hMempakFile[Control], Mempaks[Control], 0x8000, &dwRead, NULL);
|
else
|
||||||
}
|
{
|
||||||
}
|
if ((*DataToCrc & Length) != 0)
|
||||||
|
{
|
||||||
uint8_t Mempak::CalculateCrc(uint8_t * DataToCrc)
|
CRC |= 1;
|
||||||
{
|
}
|
||||||
uint32_t Count;
|
}
|
||||||
uint32_t XorTap;
|
CRC ^= XorTap;
|
||||||
|
}
|
||||||
int32_t Length;
|
DataToCrc++;
|
||||||
uint8_t CRC = 0;
|
}
|
||||||
|
|
||||||
for (Count = 0; Count < 0x21; Count++)
|
return CRC;
|
||||||
{
|
}
|
||||||
for (Length = 0x80; Length >= 1; Length >>= 1)
|
|
||||||
{
|
void Mempak::ReadFrom(int32_t Control, uint8_t * command)
|
||||||
XorTap = (CRC & 0x80) ? 0x85 : 0x00;
|
{
|
||||||
CRC <<= 1;
|
uint32_t address = (command[3] << 8) | (command[4] & 0xE0);
|
||||||
if (Count == 0x20)
|
|
||||||
{
|
if (address < 0x8000)
|
||||||
CRC &= 0xFF;
|
{
|
||||||
}
|
memcpy(&command[5], &Mempaks[Control][address], 0x20);
|
||||||
else
|
}
|
||||||
{
|
else
|
||||||
if ((*DataToCrc & Length) != 0)
|
{
|
||||||
{
|
memset(&command[5], 0x00, 0x20);
|
||||||
CRC |= 1;
|
/* Rumble pack area */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CRC ^= XorTap;
|
|
||||||
}
|
void Mempak::WriteTo(int32_t Control, uint8_t * command)
|
||||||
DataToCrc++;
|
{
|
||||||
}
|
uint32_t address = (command[3] << 8) | (command[4] & 0xE0);
|
||||||
|
|
||||||
return CRC;
|
if (address < 0x8000)
|
||||||
}
|
{
|
||||||
|
memcpy(&Mempaks[Control][address], &command[5], 0x20);
|
||||||
void Mempak::ReadFrom(int32_t Control, uint8_t * command)
|
|
||||||
{
|
FILE* mempak = fopen(MempakNames[Control], "wb");
|
||||||
uint32_t address = (command[3] << 8) | (command[4] & 0xE0);
|
fwrite(Mempaks[Control], 1, 0x8000, mempak);
|
||||||
|
fclose(mempak);
|
||||||
if (address < 0x8000)
|
}
|
||||||
{
|
else
|
||||||
if (hMempakFile[Control] == NULL)
|
{
|
||||||
{
|
/* Rumble pack area */
|
||||||
LoadMempak(Control);
|
}
|
||||||
}
|
|
||||||
memcpy(&command[5], &Mempaks[Control][address], 0x20);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
memset(&command[5], 0x00, 0x20);
|
|
||||||
/* Rumble pack area */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Mempak::WriteTo(int32_t Control, uint8_t * command)
|
|
||||||
{
|
|
||||||
DWORD dwWritten;
|
|
||||||
uint32_t address = (command[3] << 8) | (command[4] & 0xE0);
|
|
||||||
|
|
||||||
if (address < 0x8000)
|
|
||||||
{
|
|
||||||
if (hMempakFile[Control] == NULL)
|
|
||||||
{
|
|
||||||
LoadMempak(Control);
|
|
||||||
}
|
|
||||||
memcpy(&Mempaks[Control][address], &command[5], 0x20);
|
|
||||||
|
|
||||||
SetFilePointer(hMempakFile[Control], 0, NULL, FILE_BEGIN);
|
|
||||||
WriteFile(hMempakFile[Control], &Mempaks[Control][0], 0x8000, &dwWritten, NULL);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Rumble pack area */
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -65,12 +65,12 @@ m_CheatsSlectionChanged(false)
|
||||||
m_Limiter.SetHertz(gameHertz);
|
m_Limiter.SetHertz(gameHertz);
|
||||||
g_Settings->SaveDword(GameRunning_ScreenHertz, gameHertz);
|
g_Settings->SaveDword(GameRunning_ScreenHertz, gameHertz);
|
||||||
m_Cheats.LoadCheats(!g_Settings->LoadDword(Setting_RememberCheats), Plugins);
|
m_Cheats.LoadCheats(!g_Settings->LoadDword(Setting_RememberCheats), Plugins);
|
||||||
|
Mempak::Load();
|
||||||
}
|
}
|
||||||
|
|
||||||
CN64System::~CN64System()
|
CN64System::~CN64System()
|
||||||
{
|
{
|
||||||
SetActiveSystem(false);
|
SetActiveSystem(false);
|
||||||
Mempak::Close();
|
|
||||||
if (m_SyncCPU)
|
if (m_SyncCPU)
|
||||||
{
|
{
|
||||||
m_SyncCPU->CpuStopped();
|
m_SyncCPU->CpuStopped();
|
||||||
|
@ -552,7 +552,6 @@ void CN64System::Reset(bool bInitReg, bool ClearMenory)
|
||||||
RefreshGameSettings();
|
RefreshGameSettings();
|
||||||
m_Audio.Reset();
|
m_Audio.Reset();
|
||||||
m_MMU_VM.Reset(ClearMenory);
|
m_MMU_VM.Reset(ClearMenory);
|
||||||
Mempak::Close();
|
|
||||||
|
|
||||||
m_CyclesToSkip = 0;
|
m_CyclesToSkip = 0;
|
||||||
m_AlistCount = 0;
|
m_AlistCount = 0;
|
||||||
|
|
Loading…
Reference in New Issue