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()) if (system.IsTriforce())
{ {
auto& memory = system.GetMemory(); auto& memory = system.GetMemory();
const u32 disc_size = volume.GetDataSize();
// Load game into RAM, like on the actual Triforce AMMediaboard::InitDIMM(volume);
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);
// Triforce disc register obfuscation // Triforce disc register obfuscation
AMMediaboard::InitKeys(memory.Read_U32(0), memory.Read_U32(4), memory.Read_U32(8)); 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 <fmt/format.h>
#include "Common/Buffer.h"
#include "Common/CommonTypes.h" #include "Common/CommonTypes.h"
#include "Common/FileUtil.h" #include "Common/FileUtil.h"
#include "Common/IOFile.h" #include "Common/IOFile.h"
@ -37,6 +36,8 @@
#include "Core/Movie.h" #include "Core/Movie.h"
#include "Core/System.h" #include "Core/System.h"
#include "DiscIO/CachedBlob.h"
#if defined(__linux__) or defined(__APPLE__) or defined(__FreeBSD__) or defined(__NetBSD__) or \ #if defined(__linux__) or defined(__APPLE__) or defined(__FreeBSD__) or defined(__NetBSD__) or \
defined(__HAIKU__) defined(__HAIKU__)
@ -142,7 +143,7 @@ static File::IOFile s_extra;
static File::IOFile s_backup; static File::IOFile s_backup;
static File::IOFile s_dimm; 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 u8 s_firmware[2 * 1024 * 1024];
static u32 s_media_buffer_32[192]; static u32 s_media_buffer_32[192];
@ -499,20 +500,10 @@ void Init()
s_test_menu = true; s_test_menu = true;
} }
u8* InitDIMM(u32 size) void InitDIMM(const DiscIO::Volume& volume)
{ {
if (size == 0) // Load game into RAM, like on the actual Triforce.
return nullptr; s_dimm_disc = DiscIO::CreateCachedBlobReader(volume.GetBlobReader().CopyReader());
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();
} }
static int PlatformPoll(std::span<WSAPOLLFD> pfds, std::chrono::milliseconds timeout) 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; 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; return 0;
} }
@ -1996,7 +1987,8 @@ void Shutdown()
s_extra.Close(); s_extra.Close();
s_backup.Close(); s_backup.Close();
s_dimm.Close(); s_dimm.Close();
s_dimm_disc.clear();
s_dimm_disc.reset();
CloseAllSockets(); CloseAllSockets();
} }

View File

@ -11,6 +11,8 @@
#include "Common/ChunkFile.h" #include "Common/ChunkFile.h"
#include "Common/CommonTypes.h" #include "Common/CommonTypes.h"
#include "DiscIO/Volume.h"
enum GameType enum GameType
{ {
FZeroAX = 1, FZeroAX = 1,
@ -230,7 +232,7 @@ enum SocketStatusCodes
void Init(); void Init();
void FirmwareMap(bool on); 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); 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 ExecuteCommand(std::array<u32, 3>& dicmd_buf, u32* diimm_buf, u32 address, u32 length);
u32 GetGameType(); u32 GetGameType();