GCMemcard: Remove dependency on g_SRAM and force the caller to provide the relevant values instead.
This commit is contained in:
parent
1f505870a9
commit
07bd200596
|
@ -64,14 +64,16 @@ GCMemcard::GCMemcard()
|
|||
{
|
||||
}
|
||||
|
||||
std::optional<GCMemcard> GCMemcard::Create(std::string filename, u16 size_mbits, bool shift_jis)
|
||||
std::optional<GCMemcard> GCMemcard::Create(std::string filename, const CardFlashId& flash_id,
|
||||
u16 size_mbits, bool shift_jis, u32 rtc_bias,
|
||||
u32 sram_language, u64 format_time)
|
||||
{
|
||||
GCMemcard card;
|
||||
card.m_filename = std::move(filename);
|
||||
|
||||
// TODO: Format() not only formats the card but also writes it to disk at m_filename.
|
||||
// Those tasks should probably be separated.
|
||||
if (!card.Format(shift_jis, size_mbits))
|
||||
if (!card.Format(flash_id, size_mbits, shift_jis, rtc_bias, sram_language, format_time))
|
||||
return std::nullopt;
|
||||
|
||||
return std::move(card);
|
||||
|
@ -1367,29 +1369,32 @@ std::optional<std::vector<GCMemcardAnimationFrameRGBA8>> GCMemcard::ReadAnimRGBA
|
|||
return output;
|
||||
}
|
||||
|
||||
bool GCMemcard::Format(u8* card_data, bool shift_jis, u16 SizeMb)
|
||||
bool GCMemcard::Format(u8* card_data, const CardFlashId& flash_id, u16 size_mbits, bool shift_jis,
|
||||
u32 rtc_bias, u32 sram_language, u64 format_time)
|
||||
{
|
||||
if (!card_data)
|
||||
return false;
|
||||
memset(card_data, 0xFF, BLOCK_SIZE * 3);
|
||||
memset(card_data + BLOCK_SIZE * 3, 0, BLOCK_SIZE * 2);
|
||||
|
||||
*((Header*)card_data) = Header(SLOT_A, SizeMb, shift_jis);
|
||||
*((Header*)card_data) =
|
||||
Header(flash_id, size_mbits, shift_jis, rtc_bias, sram_language, format_time);
|
||||
|
||||
*((Directory*)(card_data + BLOCK_SIZE)) = Directory();
|
||||
*((Directory*)(card_data + BLOCK_SIZE * 2)) = Directory();
|
||||
*((BlockAlloc*)(card_data + BLOCK_SIZE * 3)) = BlockAlloc(SizeMb);
|
||||
*((BlockAlloc*)(card_data + BLOCK_SIZE * 4)) = BlockAlloc(SizeMb);
|
||||
*((BlockAlloc*)(card_data + BLOCK_SIZE * 3)) = BlockAlloc(size_mbits);
|
||||
*((BlockAlloc*)(card_data + BLOCK_SIZE * 4)) = BlockAlloc(size_mbits);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GCMemcard::Format(bool shift_jis, u16 SizeMb)
|
||||
bool GCMemcard::Format(const CardFlashId& flash_id, u16 size_mbits, bool shift_jis, u32 rtc_bias,
|
||||
u32 sram_language, u64 format_time)
|
||||
{
|
||||
m_header_block = Header(SLOT_A, SizeMb, shift_jis);
|
||||
m_header_block = Header(flash_id, size_mbits, shift_jis, rtc_bias, sram_language, format_time);
|
||||
m_directory_blocks[0] = m_directory_blocks[1] = Directory();
|
||||
m_bat_blocks[0] = m_bat_blocks[1] = BlockAlloc(SizeMb);
|
||||
m_bat_blocks[0] = m_bat_blocks[1] = BlockAlloc(size_mbits);
|
||||
|
||||
m_size_mb = SizeMb;
|
||||
m_size_mb = size_mbits;
|
||||
m_size_blocks = (u32)m_size_mb * MBIT_TO_BLOCKS;
|
||||
m_data_blocks.clear();
|
||||
m_data_blocks.resize(m_size_blocks - MC_FST_BLOCKS);
|
||||
|
@ -1538,25 +1543,33 @@ void GCMBlock::Erase()
|
|||
memset(m_block.data(), 0xFF, m_block.size());
|
||||
}
|
||||
|
||||
Header::Header(int slot, u16 size_mbits, bool shift_jis)
|
||||
Header::Header()
|
||||
{
|
||||
static_assert(std::is_trivially_copyable_v<Header>);
|
||||
std::memset(this, 0xFF, BLOCK_SIZE);
|
||||
}
|
||||
|
||||
Header::Header(const CardFlashId& flash_id, u16 size_mbits, bool shift_jis, u32 rtc_bias,
|
||||
u32 sram_language, u64 format_time)
|
||||
{
|
||||
// Nintendo format algorithm.
|
||||
// Constants are fixed by the GC SDK
|
||||
// Changing the constants will break memory card support
|
||||
memset(this, 0xFF, BLOCK_SIZE);
|
||||
static_assert(std::is_trivially_copyable_v<Header>);
|
||||
std::memset(this, 0xFF, BLOCK_SIZE);
|
||||
m_size_mb = size_mbits;
|
||||
m_encoding = shift_jis ? 1 : 0;
|
||||
u64 rand = Common::Timer::GetLocalTimeSinceJan1970() - ExpansionInterface::CEXIIPL::GC_EPOCH;
|
||||
m_format_time = rand;
|
||||
m_format_time = format_time;
|
||||
u64 rand = format_time;
|
||||
for (int i = 0; i < 12; i++)
|
||||
{
|
||||
rand = (((rand * (u64)0x0000000041c64e6dULL) + (u64)0x0000000000003039ULL) >> 16);
|
||||
m_serial[i] = (u8)(g_SRAM.settings_ex.flash_id[slot][i] + (u32)rand);
|
||||
m_serial[i] = (u8)(flash_id[i] + (u32)rand);
|
||||
rand = (((rand * (u64)0x0000000041c64e6dULL) + (u64)0x0000000000003039ULL) >> 16);
|
||||
rand &= (u64)0x0000000000007fffULL;
|
||||
}
|
||||
m_sram_bias = g_SRAM.settings.rtc_bias;
|
||||
m_sram_language = static_cast<u32>(g_SRAM.settings.language);
|
||||
m_sram_bias = rtc_bias;
|
||||
m_sram_language = sram_language;
|
||||
// TODO: determine the purpose of m_unknown_2
|
||||
// 1 works for slot A, 0 works for both slot A and slot B
|
||||
memset(m_unknown_2.data(), 0,
|
||||
|
|
|
@ -213,8 +213,12 @@ struct Header
|
|||
// 0x1e00 bytes at 0x0200: Unused (0xff)
|
||||
std::array<u8, 7680> m_unused_2;
|
||||
|
||||
explicit Header(int slot = 0, u16 size_mbits = MBIT_SIZE_MEMORY_CARD_2043,
|
||||
bool shift_jis = false);
|
||||
// initialize an unformatted header block
|
||||
explicit Header();
|
||||
|
||||
// initialize a formatted header block
|
||||
explicit Header(const CardFlashId& flash_id, u16 size_mbits, bool shift_jis, u32 rtc_bias,
|
||||
u32 sram_language, u64 format_time);
|
||||
|
||||
// Calculates the card serial numbers used for encrypting some save files.
|
||||
std::pair<u32, u32> CalculateSerial() const;
|
||||
|
@ -401,7 +405,9 @@ private:
|
|||
void UpdateBat(const BlockAlloc& bat);
|
||||
|
||||
public:
|
||||
static std::optional<GCMemcard> Create(std::string filename, u16 size_mbits, bool shift_jis);
|
||||
static std::optional<GCMemcard> Create(std::string filename, const CardFlashId& flash_id,
|
||||
u16 size_mbits, bool shift_jis, u32 rtc_bias,
|
||||
u32 sram_language, u64 format_time);
|
||||
|
||||
static std::pair<GCMemcardErrorCode, std::optional<GCMemcard>> Open(std::string filename);
|
||||
|
||||
|
@ -413,9 +419,10 @@ public:
|
|||
bool IsValid() const { return m_valid; }
|
||||
bool IsShiftJIS() const;
|
||||
bool Save();
|
||||
bool Format(bool shift_jis = false, u16 SizeMb = MBIT_SIZE_MEMORY_CARD_2043);
|
||||
static bool Format(u8* card_data, bool shift_jis = false,
|
||||
u16 SizeMb = MBIT_SIZE_MEMORY_CARD_2043);
|
||||
bool Format(const CardFlashId& flash_id, u16 size_mbits, bool shift_jis, u32 rtc_bias,
|
||||
u32 sram_language, u64 format_time);
|
||||
static bool Format(u8* card_data, const CardFlashId& flash_id, u16 size_mbits, bool shift_jis,
|
||||
u32 rtc_bias, u32 sram_language, u64 format_time);
|
||||
static s32 FZEROGX_MakeSaveGameValid(const Header& cardheader, const DEntry& direntry,
|
||||
std::vector<GCMBlock>& FileBuffer);
|
||||
static s32 PSO_MakeSaveGameValid(const Header& cardheader, const DEntry& direntry,
|
||||
|
|
|
@ -26,9 +26,13 @@
|
|||
#include "Common/MsgHandler.h"
|
||||
#include "Common/StringUtil.h"
|
||||
#include "Common/Thread.h"
|
||||
#include "Common/Timer.h"
|
||||
|
||||
#include "Core/Config/MainSettings.h"
|
||||
#include "Core/ConfigManager.h"
|
||||
#include "Core/Core.h"
|
||||
#include "Core/HW/EXI/EXI_DeviceIPL.h"
|
||||
#include "Core/HW/Sram.h"
|
||||
#include "Core/NetPlayProto.h"
|
||||
|
||||
static const char* MC_HDR = "MC_SYSTEM_AREA";
|
||||
|
@ -148,8 +152,10 @@ std::vector<std::string> GCMemcardDirectory::GetFileNamesForGameID(const std::st
|
|||
GCMemcardDirectory::GCMemcardDirectory(const std::string& directory, int slot, u16 size_mbits,
|
||||
bool shift_jis, int game_id)
|
||||
: MemoryCardBase(slot, size_mbits), m_game_id(game_id), m_last_block(-1),
|
||||
m_hdr(slot, size_mbits, shift_jis), m_bat1(size_mbits), m_saves(0),
|
||||
m_save_directory(directory), m_exiting(false)
|
||||
m_hdr(g_SRAM.settings_ex.flash_id[slot], size_mbits, shift_jis, g_SRAM.settings.rtc_bias,
|
||||
static_cast<u32>(g_SRAM.settings.language),
|
||||
Common::Timer::GetLocalTimeSinceJan1970() - ExpansionInterface::CEXIIPL::GC_EPOCH),
|
||||
m_bat1(size_mbits), m_saves(0), m_save_directory(directory), m_exiting(false)
|
||||
{
|
||||
// Use existing header data if available
|
||||
{
|
||||
|
|
|
@ -22,9 +22,13 @@
|
|||
#include "Common/MsgHandler.h"
|
||||
#include "Common/StringUtil.h"
|
||||
#include "Common/Thread.h"
|
||||
#include "Common/Timer.h"
|
||||
|
||||
#include "Core/ConfigManager.h"
|
||||
#include "Core/Core.h"
|
||||
#include "Core/HW/EXI/EXI_DeviceIPL.h"
|
||||
#include "Core/HW/GCMemcard/GCMemcard.h"
|
||||
#include "Core/HW/Sram.h"
|
||||
|
||||
#define SIZE_TO_Mb (1024 * 8 * 16)
|
||||
#define MC_HDR_SIZE 0xA000
|
||||
|
@ -51,9 +55,18 @@ MemoryCard::MemoryCard(const std::string& filename, int card_index, u16 size_mbi
|
|||
m_memory_card_size = size_mbits * SIZE_TO_Mb;
|
||||
|
||||
m_memcard_data = std::make_unique<u8[]>(m_memory_card_size);
|
||||
// Fills in MC_HDR_SIZE bytes
|
||||
Memcard::GCMemcard::Format(&m_memcard_data[0], m_filename.find(".JAP.raw") != std::string::npos,
|
||||
size_mbits);
|
||||
|
||||
// Fills in the first 5 blocks (MC_HDR_SIZE bytes)
|
||||
const CardFlashId& flash_id = g_SRAM.settings_ex.flash_id[Memcard::SLOT_A];
|
||||
const bool shift_jis = m_filename.find(".JAP.raw") != std::string::npos;
|
||||
const u32 rtc_bias = g_SRAM.settings.rtc_bias;
|
||||
const u32 sram_language = static_cast<u32>(g_SRAM.settings.language);
|
||||
const u64 format_time =
|
||||
Common::Timer::GetLocalTimeSinceJan1970() - ExpansionInterface::CEXIIPL::GC_EPOCH;
|
||||
Memcard::GCMemcard::Format(&m_memcard_data[0], flash_id, size_mbits, shift_jis, rtc_bias,
|
||||
sram_language, format_time);
|
||||
|
||||
// Fills in the remaining blocks
|
||||
memset(&m_memcard_data[MC_HDR_SIZE], 0xFF, m_memory_card_size - MC_HDR_SIZE);
|
||||
|
||||
INFO_LOG(EXPANSIONINTERFACE, "No memory card found. A new one was created instead.");
|
||||
|
|
|
@ -14,8 +14,11 @@
|
|||
|
||||
#include "Common/FileUtil.h"
|
||||
#include "Common/MsgHandler.h"
|
||||
#include "Common/Timer.h"
|
||||
|
||||
#include "Core/HW/EXI/EXI_DeviceIPL.h"
|
||||
#include "Core/HW/GCMemcard/GCMemcard.h"
|
||||
#include "Core/HW/Sram.h"
|
||||
|
||||
GCMemcardCreateNewDialog::GCMemcardCreateNewDialog(QWidget* parent) : QDialog(parent)
|
||||
{
|
||||
|
@ -74,8 +77,16 @@ bool GCMemcardCreateNewDialog::CreateCard()
|
|||
if (path.isEmpty())
|
||||
return false;
|
||||
|
||||
// TODO: The dependency on g_SRAM here is sketchy. We should instead use sensible default values.
|
||||
const CardFlashId& flash_id = g_SRAM.settings_ex.flash_id[Memcard::SLOT_A];
|
||||
const u32 rtc_bias = g_SRAM.settings.rtc_bias;
|
||||
const u32 sram_language = static_cast<u32>(g_SRAM.settings.language);
|
||||
const u64 format_time =
|
||||
Common::Timer::GetLocalTimeSinceJan1970() - ExpansionInterface::CEXIIPL::GC_EPOCH;
|
||||
|
||||
const std::string p = path.toStdString();
|
||||
auto memcard = Memcard::GCMemcard::Create(p, size, is_shift_jis);
|
||||
auto memcard = Memcard::GCMemcard::Create(p, flash_id, size, is_shift_jis, rtc_bias,
|
||||
sram_language, format_time);
|
||||
if (memcard && memcard->Save())
|
||||
{
|
||||
m_card_path = p;
|
||||
|
|
Loading…
Reference in New Issue