mirror of
https://github.com/mitch030504/Wiicompiled_VR_Frame.git
synced 2026-10-06 17:00:32 +02:00
- Implemented DVDReadVrAsset function to read mapped disc paths for VR assets. - Created HeldItem structure and ReadHeldItem function for managing held items in the game. - Developed unit tests for ReadHeldItem to ensure correct functionality and edge case handling. - Added cockpit item data tests to validate model indexing and parsing of archives.
85 lines
3.6 KiB
C++
85 lines
3.6 KiB
C++
#include "vr/mkw_vr_item.h"
|
|
|
|
#include <cstdint>
|
|
#include <iostream>
|
|
#include <stdexcept>
|
|
#include <unordered_map>
|
|
|
|
namespace {
|
|
struct GuestMemory {
|
|
using AccessViolation = std::out_of_range;
|
|
inline static std::unordered_map<uint32_t, uint8_t> bytes;
|
|
inline static uint32_t fault = 0;
|
|
static bool Contains(uint32_t address, uint32_t length) {
|
|
for (uint32_t i = 0; i < length; ++i) if (!bytes.count(address + i)) return false;
|
|
return true;
|
|
}
|
|
static uint8_t Read8(uint32_t address) {
|
|
if (address == fault) throw AccessViolation("fault");
|
|
return bytes.at(address);
|
|
}
|
|
static uint32_t Read32(uint32_t address) {
|
|
uint32_t value = 0;
|
|
for (uint32_t i = 0; i < 4; ++i) value = (value << 8) | Read8(address + i);
|
|
return value;
|
|
}
|
|
static bool TryRead32(uint32_t address, uint32_t& out) {
|
|
try { out = Read32(address); return true; } catch (const AccessViolation&) { return false; }
|
|
}
|
|
static void Write32(uint32_t address, uint32_t value) {
|
|
for (uint32_t i = 0; i < 4; ++i) bytes[address + i] = uint8_t(value >> (24 - i * 8));
|
|
}
|
|
};
|
|
|
|
constexpr uint32_t manager = 0x81000000u, players = 0x82000000u;
|
|
constexpr uint32_t player = players + 7 * 0x248u;
|
|
int failures = 0;
|
|
void Check(bool value, const char* name) {
|
|
if (!value) { ++failures; std::cerr << "FAILED: " << name << '\n'; }
|
|
}
|
|
void Init() {
|
|
GuestMemory::bytes.clear(); GuestMemory::fault = 0;
|
|
GuestMemory::Write32(0x809C3618u, manager);
|
|
GuestMemory::Write32(manager + 0x14u, players);
|
|
for (uint32_t i = 0; i < 0x94u; ++i) GuestMemory::bytes[player + i] = 0;
|
|
GuestMemory::bytes[player + 0x18u] = 7;
|
|
GuestMemory::Write32(player + 0x90u, 1);
|
|
}
|
|
}
|
|
|
|
int main() {
|
|
using mkw::vr::detail::ReadHeldItem;
|
|
for (uint32_t id = 0; id <= 0x12u; ++id) {
|
|
Init(); GuestMemory::Write32(player + 0x8cu, id);
|
|
const auto item = ReadHeldItem<GuestMemory>(7, 19);
|
|
Check(item.valid && item.id == id && item.count == 1 && item.race_generation == 19,
|
|
"all 19 IDs, nonzero racer, generation");
|
|
}
|
|
Init(); GuestMemory::Write32(player + 0x8cu, 0x10); GuestMemory::Write32(player + 0x90u, 3);
|
|
Check(ReadHeldItem<GuestMemory>(7, 1).count == 3, "triple full");
|
|
GuestMemory::Write32(player + 0x90u, 2);
|
|
Check(ReadHeldItem<GuestMemory>(7, 1).count == 2, "triple remaining");
|
|
GuestMemory::Write32(player + 0x90u, 0);
|
|
Check(!ReadHeldItem<GuestMemory>(7, 1).valid, "inventory removed on use or damage");
|
|
GuestMemory::Write32(player + 0x90u, 1);
|
|
GuestMemory::Write32(player + 0x58u, 1);
|
|
Check(!ReadHeldItem<GuestMemory>(7, 1).valid, "roulette spinning");
|
|
GuestMemory::Write32(player + 0x58u, 0);
|
|
for (uint32_t id : {0x13u, 0x14u, 0xffu}) {
|
|
GuestMemory::Write32(player + 0x8cu, id);
|
|
Check(!ReadHeldItem<GuestMemory>(7, 1).valid, "empty or unsupported");
|
|
}
|
|
Init(); GuestMemory::Write32(player + 0x8cu, 0x0au);
|
|
Check(ReadHeldItem<GuestMemory>(7, 1).valid, "golden mushroom held");
|
|
GuestMemory::Write32(player + 0x90u, 0);
|
|
Check(!ReadHeldItem<GuestMemory>(7, 1).valid, "golden mushroom expiry");
|
|
Init(); GuestMemory::fault = player + 0x8cu;
|
|
const auto faulted = ReadHeldItem<GuestMemory>(7, 2);
|
|
Check(!faulted.valid && faulted.race_generation == 2, "read fault preserves generation");
|
|
Init(); GuestMemory::Write32(0x809C3618u, 0);
|
|
Check(!ReadHeldItem<GuestMemory>(7, 1).valid, "invalid manager");
|
|
Init(); GuestMemory::bytes[player + 0x18u] = 0;
|
|
Check(!ReadHeldItem<GuestMemory>(7, 1).valid, "racer identity mismatch");
|
|
return failures ? 1 : 0;
|
|
}
|