From 6abd9109b2544c1612aebaf64f3b1b49c0f67c58 Mon Sep 17 00:00:00 2001 From: sowens99 Date: Wed, 17 Jan 2024 19:50:00 -0500 Subject: [PATCH] Add BSP reading --- source/game/kart/KartParam.cc | 46 ++++++++++++++++++++++-- source/game/kart/KartParam.hh | 42 +++++++++++++++++++++- source/game/kart/KartParamFileManager.cc | 20 ++++++++--- source/game/kart/KartParamFileManager.hh | 1 + source/game/system/ResourceManager.cc | 7 ++-- source/game/system/ResourceManager.hh | 2 +- 6 files changed, 106 insertions(+), 12 deletions(-) diff --git a/source/game/kart/KartParam.cc b/source/game/kart/KartParam.cc index 8c8aa58f..ba4bfd5b 100644 --- a/source/game/kart/KartParam.cc +++ b/source/game/kart/KartParam.cc @@ -21,9 +21,11 @@ void KartParam::initStats(Character character, Vehicle vehicle) { m_stats.applyCharacterBonus(driverStream); } -// TODO: Add BSP parsing void KartParam::initHitboxes(Vehicle vehicle) { - (void)vehicle; + auto *fileManager = KartParamFileManager::Instance(); + + auto hitboxStream = fileManager->getHitboxStream(vehicle); + m_bsp = BSP(hitboxStream); } KartParam::Stats::Stats() = default; @@ -116,4 +118,44 @@ void KartParam::Stats::applyCharacterBonus(EGG::RamStream &stream) { } } +KartParam::BSP::BSP() = default; + +KartParam::BSP::BSP(EGG::RamStream &stream) { + read(stream); +} + +void KartParam::BSP::read(EGG::RamStream &stream) { + m_initialYPos = stream.read_f32(); + + for (auto &hitbox : m_hitboxes) { + hitbox.m_enable = stream.read_u16(); + stream.skip(2); + hitbox.m_position.read(stream); + hitbox.m_radius = stream.read_f32(); + hitbox.m_wallsOnly = stream.read_u16(); + hitbox.m_tireCollisionIdx = stream.read_u16(); + } + + m_cuboids[0].read(stream); + m_cuboids[1].read(stream); + m_angVel0Factor = stream.read_f32(); + _1a0 = stream.read_f32(); + + for (auto &wheel : m_wheels) { + wheel.m_enable = stream.read_u16(); + stream.skip(2); + wheel.m_springStiffness = stream.read_f32(); + wheel.m_dampingFactor = stream.read_f32(); + wheel.m_maxTravel = stream.read_f32(); + wheel.m_relPosition.read(stream); + wheel.m_xRot = stream.read_f32(); + wheel.m_wheelRadius = stream.read_f32(); + wheel.m_sphereRadius = stream.read_f32(); + wheel._28 = stream.read_u32(); + } + + m_rumbleHeight = stream.read_f32(); + m_rumbleSpeed = stream.read_f32(); +} + } // namespace Kart diff --git a/source/game/kart/KartParam.hh b/source/game/kart/KartParam.hh index abe922a5..0609ce63 100644 --- a/source/game/kart/KartParam.hh +++ b/source/game/kart/KartParam.hh @@ -1,6 +1,6 @@ #pragma once -#include +#include namespace Kart { @@ -66,6 +66,45 @@ public: }; static_assert(sizeof(Stats) == 0x18c); + struct BSP { + struct Hitbox { + u16 m_enable; + EGG::Vector3f m_position; + f32 m_radius; + u16 m_wallsOnly; + u16 m_tireCollisionIdx; + }; + static_assert(sizeof(Hitbox) == 0x18); + + struct Wheel { + u16 m_enable; + f32 m_springStiffness; + f32 m_dampingFactor; + f32 m_maxTravel; + EGG::Vector3f m_relPosition; + f32 m_xRot; + f32 m_wheelRadius; + f32 m_sphereRadius; + u32 _28; + }; + static_assert(sizeof(Wheel) == 0x2c); + + BSP(); + BSP(EGG::RamStream &stream); + + void read(EGG::RamStream &stream); + + f32 m_initialYPos; + std::array m_hitboxes; + EGG::Vector3f m_cuboids[2]; + f32 m_angVel0Factor; + f32 _1a0; + std::array m_wheels; + f32 m_rumbleHeight; + f32 m_rumbleSpeed; + }; + static_assert(sizeof(BSP) == 0x25c); + KartParam(Character character, Vehicle vehicle); ~KartParam(); @@ -74,6 +113,7 @@ private: void initHitboxes(Vehicle vehicle); Stats m_stats; + BSP m_bsp; }; } // namespace Kart diff --git a/source/game/kart/KartParamFileManager.cc b/source/game/kart/KartParamFileManager.cc index eb30d93d..7b34c490 100644 --- a/source/game/kart/KartParamFileManager.cc +++ b/source/game/kart/KartParamFileManager.cc @@ -76,6 +76,20 @@ EGG::RamStream KartParamFileManager::getVehicleStream(Vehicle vehicle) const { return EGG::RamStream(reinterpret_cast(offset), size); } +EGG::RamStream KartParamFileManager::getHitboxStream(Vehicle vehicle) const { + if (vehicle >= Vehicle::Max) { + K_PANIC("Uh oh."); + } + + auto *resourceManager = System::ResourceManager::Instance(); + size_t size; + + auto *file = resourceManager->getBsp(vehicle, &size); + assert(file); + assert(size == sizeof(KartParam::BSP)); + return EGG::RamStream(reinterpret_cast(file), size); +} + KartParamFileManager *KartParamFileManager::CreateInstance() { assert(!s_instance); s_instance = new KartParamFileManager; @@ -105,8 +119,7 @@ bool KartParamFileManager::validate() const { } auto *file = reinterpret_cast(m_kartParam.m_file); - if (m_kartParam.m_size != - parse(file->m_count) * sizeof(KartParam::Stats) + 4) { + if (m_kartParam.m_size != parse(file->m_count) * sizeof(KartParam::Stats) + 4) { return false; } @@ -116,8 +129,7 @@ bool KartParamFileManager::validate() const { } file = reinterpret_cast(m_driverParam.m_file); - if (m_driverParam.m_size != - parse(file->m_count) * sizeof(KartParam::Stats) + 4) { + if (m_driverParam.m_size != parse(file->m_count) * sizeof(KartParam::Stats) + 4) { return false; } diff --git a/source/game/kart/KartParamFileManager.hh b/source/game/kart/KartParamFileManager.hh index 1c56a53d..e2bb59f5 100644 --- a/source/game/kart/KartParamFileManager.hh +++ b/source/game/kart/KartParamFileManager.hh @@ -10,6 +10,7 @@ public: void init(); EGG::RamStream getDriverStream(Character character) const; EGG::RamStream getVehicleStream(Vehicle vehicle) const; + EGG::RamStream getHitboxStream(Vehicle vehicle) const; static KartParamFileManager *CreateInstance(); static void DestroyInstance(); diff --git a/source/game/system/ResourceManager.cc b/source/game/system/ResourceManager.cc index becc843c..cfc17fe9 100644 --- a/source/game/system/ResourceManager.cc +++ b/source/game/system/ResourceManager.cc @@ -15,12 +15,11 @@ void *ResourceManager::getFile(const char *filename, size_t *size, s32 idx) { return m_archives[idx]->isLoaded() ? m_archives[idx]->getFile(filename, size) : nullptr; } -void *ResourceManager::getBsp(u8 playerIdx, size_t *size) { +void *ResourceManager::getBsp(Vehicle vehicle, size_t *size) { char buffer[32]; - auto *raceConfig = RaceConfig::Instance(); - const char *vehicle = GetVehicleName(raceConfig->raceScenario().m_players[playerIdx].m_vehicle); - snprintf(buffer, sizeof(buffer), "bsp/%s.bsp", vehicle); + const char *name = GetVehicleName(vehicle); + snprintf(buffer, sizeof(buffer), "/bsp/%s.bsp", name); return m_archives[0]->isLoaded() ? m_archives[0]->getFile(buffer, size) : nullptr; } diff --git a/source/game/system/ResourceManager.hh b/source/game/system/ResourceManager.hh index d4c8a82f..9f963c69 100644 --- a/source/game/system/ResourceManager.hh +++ b/source/game/system/ResourceManager.hh @@ -7,7 +7,7 @@ namespace System { class ResourceManager { public: void *getFile(const char *filename, size_t *size, s32 idx); - void *getBsp(u8 playerIdx, size_t *size); + void *getBsp(Vehicle vehicle, size_t *size); MultiDvdArchive *load(Course courseId); MultiDvdArchive *load(s32 idx, const char *filename);