From 643a684c779dd31773d45459391d3a33b6f00767 Mon Sep 17 00:00:00 2001 From: Emmet Young Date: Thu, 28 Jan 2016 14:02:05 +1100 Subject: [PATCH] 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 --- Source/Project64-core/N64System/Mips/Mempak.H | 41 +-- .../Project64-core/N64System/Mips/Mempak.cpp | 314 ++++++++---------- Source/Project64-core/N64System/N64Class.cpp | 3 +- 3 files changed, 164 insertions(+), 194 deletions(-) diff --git a/Source/Project64-core/N64System/Mips/Mempak.H b/Source/Project64-core/N64System/Mips/Mempak.H index 0cfca48e4..e394a217c 100644 --- a/Source/Project64-core/N64System/Mips/Mempak.H +++ b/Source/Project64-core/N64System/Mips/Mempak.H @@ -1,20 +1,21 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once - -class Mempak -{ -public: - static void Close(); - static uint8_t CalculateCrc(uint8_t * DataToCrc); - static void ReadFrom(int32_t Control, uint8_t * command); - static void WriteTo(int32_t Control, uint8_t * command); -}; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once + +class Mempak +{ +public: + static uint8_t CalculateCrc(uint8_t * DataToCrc); + static void Load(); + static void Format(int32_t Control); + static void ReadFrom(int32_t Control, uint8_t * command); + static void WriteTo(int32_t Control, uint8_t * command); +}; \ No newline at end of file diff --git a/Source/Project64-core/N64System/Mips/Mempak.cpp b/Source/Project64-core/N64System/Mips/Mempak.cpp index f5f69b502..6e6df87b4 100644 --- a/Source/Project64-core/N64System/Mips/Mempak.cpp +++ b/Source/Project64-core/N64System/Mips/Mempak.cpp @@ -1,173 +1,143 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#include "stdafx.h" -#include "Mempak.H" -#include -#include - -static uint8_t Mempaks[4][0x8000]; -void * hMempakFile[4]; - -void Mempak::Close() -{ - for (int32_t i = 0; i < 4; i++) - { - if (hMempakFile[i]) - { - CloseHandle(hMempakFile[i]); - hMempakFile[i] = NULL; - } - } -} - -void LoadMempak(int32_t Control) -{ - CPath FileName; - DWORD dwRead; - stdstr MempakName; - bool bFormatMempak = false; - - MempakName.Format("%s_Cont_%d", g_Settings->LoadStringVal(Game_GameName).c_str(), Control + 1); - - FileName.SetDriveDirectory(g_Settings->LoadStringVal(Directory_NativeSave).c_str()); - FileName.SetName(MempakName.c_str()); - FileName.SetExtension("mpk"); - - if (!FileName.Exists()) - { - bFormatMempak = true; - - if (!FileName.DirectoryExists()) - { - 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, - 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, - 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, - 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, - 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, - 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, - 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) - { - Mempaks[Control][count] = 0x00; - Mempaks[Control][count + 1] = 0x03; - } - } - - hMempakFile[Control] = CreateFile(FileName, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, NULL); - - if (hMempakFile[Control] == INVALID_HANDLE_VALUE) - { - WriteTrace(TraceN64System, TraceError, "Failed to open (%s), lastError = %X", (LPCTSTR)FileName, GetLastError()); - return; - } - - SetFilePointer(hMempakFile[Control], 0, NULL, FILE_BEGIN); - if (bFormatMempak) - { - WriteFile(hMempakFile[Control], Mempaks[Control], 0x8000, &dwRead, NULL); - } - else - { - ReadFile(hMempakFile[Control], Mempaks[Control], 0x8000, &dwRead, NULL); - } -} - -uint8_t Mempak::CalculateCrc(uint8_t * DataToCrc) -{ - uint32_t Count; - uint32_t XorTap; - - int32_t Length; - uint8_t CRC = 0; - - for (Count = 0; Count < 0x21; Count++) - { - for (Length = 0x80; Length >= 1; Length >>= 1) - { - XorTap = (CRC & 0x80) ? 0x85 : 0x00; - CRC <<= 1; - if (Count == 0x20) - { - CRC &= 0xFF; - } - else - { - if ((*DataToCrc & Length) != 0) - { - CRC |= 1; - } - } - CRC ^= XorTap; - } - DataToCrc++; - } - - return CRC; -} - -void Mempak::ReadFrom(int32_t Control, uint8_t * command) -{ - uint32_t address = (command[3] << 8) | (command[4] & 0xE0); - - if (address < 0x8000) - { - if (hMempakFile[Control] == NULL) - { - 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 */ - } +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#include "stdafx.h" +#include "Mempak.H" +#include + +uint8_t Mempaks[4][0x8000]; +CPath MempakNames[4]; + +void Mempak::Load() +{ + stdstr MempakName; + + for (int i = 0; i < 3; i++) + { + MempakName.Format("%s_Cont_%d", g_Settings->LoadStringVal(Game_GameName).c_str(), i + 1); + + MempakNames[i].SetDriveDirectory(g_Settings->LoadStringVal(Directory_NativeSave).c_str()); + MempakNames[i].SetName(MempakName.c_str()); + MempakNames[i].SetExtension("mpk"); + + if (!MempakNames[i].DirectoryExists()) + { + MempakNames[i].DirectoryCreate(); + } + + if (MempakNames[i].Exists()) + { + FILE *mempak = fopen(MempakNames[i], "rb"); + fread(Mempaks[i], 1, 0x8000, mempak); + fclose(mempak); + } + else + { + Mempak::Format(i); + } + } +} + +void Mempak::Format(int32_t Control) +{ + 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, + 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, + 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, + 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, + 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, + 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, + 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) + { + Mempaks[Control][count] = 0x00; + Mempaks[Control][count + 1] = 0x03; + } +} + +uint8_t Mempak::CalculateCrc(uint8_t * DataToCrc) +{ + uint32_t Count; + uint32_t XorTap; + + int32_t Length; + uint8_t CRC = 0; + + for (Count = 0; Count < 0x21; Count++) + { + for (Length = 0x80; Length >= 1; Length >>= 1) + { + XorTap = (CRC & 0x80) ? 0x85 : 0x00; + CRC <<= 1; + if (Count == 0x20) + { + CRC &= 0xFF; + } + else + { + if ((*DataToCrc & Length) != 0) + { + CRC |= 1; + } + } + CRC ^= XorTap; + } + DataToCrc++; + } + + return CRC; +} + +void Mempak::ReadFrom(int32_t Control, uint8_t * command) +{ + uint32_t address = (command[3] << 8) | (command[4] & 0xE0); + + if (address < 0x8000) + { + 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) +{ + uint32_t address = (command[3] << 8) | (command[4] & 0xE0); + + if (address < 0x8000) + { + memcpy(&Mempaks[Control][address], &command[5], 0x20); + + FILE* mempak = fopen(MempakNames[Control], "wb"); + fwrite(Mempaks[Control], 1, 0x8000, mempak); + fclose(mempak); + } + else + { + /* Rumble pack area */ + } } \ No newline at end of file diff --git a/Source/Project64-core/N64System/N64Class.cpp b/Source/Project64-core/N64System/N64Class.cpp index 397775318..a0d13d3fe 100644 --- a/Source/Project64-core/N64System/N64Class.cpp +++ b/Source/Project64-core/N64System/N64Class.cpp @@ -65,12 +65,12 @@ m_CheatsSlectionChanged(false) m_Limiter.SetHertz(gameHertz); g_Settings->SaveDword(GameRunning_ScreenHertz, gameHertz); m_Cheats.LoadCheats(!g_Settings->LoadDword(Setting_RememberCheats), Plugins); + Mempak::Load(); } CN64System::~CN64System() { SetActiveSystem(false); - Mempak::Close(); if (m_SyncCPU) { m_SyncCPU->CpuStopped(); @@ -552,7 +552,6 @@ void CN64System::Reset(bool bInitReg, bool ClearMenory) RefreshGameSettings(); m_Audio.Reset(); m_MMU_VM.Reset(ClearMenory); - Mempak::Close(); m_CyclesToSkip = 0; m_AlistCount = 0;