Triforce: Lazily load the game into memory using CachedBlobReader.

This commit is contained in:
Jordan Woyak 2026-02-07 23:08:37 -06:00
parent 3681cade41
commit a4fd5f8343
3 changed files with 18 additions and 33 deletions

View File

@ -233,17 +233,8 @@ bool CBoot::RunApploader(Core::System& system, const Core::CPUThreadGuard& guard
if (system.IsTriforce())
{
auto& memory = system.GetMemory();
const u32 disc_size = volume.GetDataSize();
// Load game into RAM, like on the actual Triforce
u8* dimm = AMMediaboard::InitDIMM(disc_size);
if (!dimm)
{
ERROR_LOG_FMT(BOOT, "AMMediaboard::InitDIMM failed");
return false;
}
volume.Read(0, disc_size, dimm, DiscIO::PARTITION_NONE);
AMMediaboard::InitDIMM(volume);
// Triforce disc register obfuscation
AMMediaboard::InitKeys(memory.Read_U32(0), memory.Read_U32(4), memory.Read_U32(8));

View File

@ -11,7 +11,6 @@
#include <fmt/format.h>
#include "Common/Buffer.h"
#include "Common/CommonTypes.h"
#include "Common/FileUtil.h"
#include "Common/IOFile.h"
@ -37,6 +36,8 @@
#include "Core/Movie.h"
#include "Core/System.h"
#include "DiscIO/CachedBlob.h"
#if defined(__linux__) or defined(__APPLE__) or defined(__FreeBSD__) or defined(__NetBSD__) or \
defined(__HAIKU__)
@ -142,7 +143,7 @@ static File::IOFile s_extra;
static File::IOFile s_backup;
static File::IOFile s_dimm;
static Common::UniqueBuffer<u8> s_dimm_disc;
static std::unique_ptr<DiscIO::BlobReader> s_dimm_disc;
static u8 s_firmware[2 * 1024 * 1024];
static u32 s_media_buffer_32[192];
@ -499,20 +500,10 @@ void Init()
s_test_menu = true;
}
u8* InitDIMM(u32 size)
void InitDIMM(const DiscIO::Volume& volume)
{
if (size == 0)
return nullptr;
s_dimm_disc.reset(size);
if (s_dimm_disc.empty())
{
PanicAlertFmt("Failed to allocate DIMM memory.");
return nullptr;
}
s_firmware_map = false;
return s_dimm_disc.data();
// Load game into RAM, like on the actual Triforce.
s_dimm_disc = DiscIO::CreateCachedBlobReader(volume.GetBlobReader().CopyReader());
}
static int PlatformPoll(std::span<WSAPOLLFD> pfds, std::chrono::milliseconds timeout)
@ -1556,13 +1547,13 @@ u32 ExecuteCommand(std::array<u32, 3>& dicmd_buf, u32* diimm_buf, u32 address, u
return 0;
}
if (s_dimm_disc.size())
if (const auto span = memory.GetSpanForAddress(address); span.size() < length)
{
ERROR_LOG_FMT(AMMEDIABOARD, "GC-AM: Invalid DIMM Disc read from: offset={}, length={}",
offset, length);
}
else if (s_dimm_disc->Read(offset, length, span.data()))
{
if (!SafeCopyToEmu(memory, address, s_dimm_disc.data(), s_dimm_disc.size(), offset, length))
{
ERROR_LOG_FMT(AMMEDIABOARD, "GC-AM: Invalid DIMM Disc read from: offset={}, length={}",
offset, length);
}
return 0;
}
@ -1996,7 +1987,8 @@ void Shutdown()
s_extra.Close();
s_backup.Close();
s_dimm.Close();
s_dimm_disc.clear();
s_dimm_disc.reset();
CloseAllSockets();
}

View File

@ -11,6 +11,8 @@
#include "Common/ChunkFile.h"
#include "Common/CommonTypes.h"
#include "DiscIO/Volume.h"
enum GameType
{
FZeroAX = 1,
@ -230,7 +232,7 @@ enum SocketStatusCodes
void Init();
void FirmwareMap(bool on);
u8* InitDIMM(u32 size);
void InitDIMM(const DiscIO::Volume& volume);
void InitKeys(u32 key_a, u32 key_b, u32 key_c);
u32 ExecuteCommand(std::array<u32, 3>& dicmd_buf, u32* diimm_buf, u32 address, u32 length);
u32 GetGameType();