diff --git a/Runtime/CGameState.hpp b/Runtime/CGameState.hpp index 7cfba220a..f62098e73 100644 --- a/Runtime/CGameState.hpp +++ b/Runtime/CGameState.hpp @@ -116,6 +116,7 @@ public: void ExportPersistentOptions(CPersistentOptions& opts) const; void SetGameOptions(const CGameOptions& opts) { x17c_gameOptions = opts; } void WriteBackupBuf(); + std::vector& BackupBuf() { return x218_backupBuf; } u32 GetFileIdx() const { return x20c_saveFileIdx; } void SetFileIdx(u32 idx) { x20c_saveFileIdx = idx; } void SetCardSerial(u64 serial) { x210_cardSerial = serial; } diff --git a/Runtime/CPakFile.cpp b/Runtime/CPakFile.cpp index 9ef3f59fd..9be1834b0 100644 --- a/Runtime/CPakFile.cpp +++ b/Runtime/CPakFile.cpp @@ -43,6 +43,8 @@ void CPakFile::LoadResourceTable(athena::io::MemoryReader& r) CAssetId id = r.readUint32Big(); u32 size = r.readUint32Big(); u32 offset = r.readUint32Big(); + if (fcc == FOURCC('MLVL')) + m_mlvlId = id; x74_resList.emplace_back(id, fcc, offset, size, flags); if (x28_24_buildDepList) x64_depList.push_back(id); diff --git a/Runtime/CPakFile.hpp b/Runtime/CPakFile.hpp index a926d216b..761a5bfd8 100644 --- a/Runtime/CPakFile.hpp +++ b/Runtime/CPakFile.hpp @@ -63,6 +63,7 @@ private: std::vector x64_depList; std::vector x74_resList; mutable s32 x84_currentSeek = -1; + CAssetId m_mlvlId; void LoadResourceTable(athena::io::MemoryReader& r); void DataLoad(); void InitialHeaderLoad(); @@ -79,6 +80,7 @@ public: bool IsWorldPak() const { return x28_26_worldPak; } u32 GetFakeStaticSize() const { return 0; } void AsyncIdle(); + CAssetId GetMLVLId() const { return m_mlvlId; } }; } diff --git a/Runtime/Graphics/CBooRenderer.cpp b/Runtime/Graphics/CBooRenderer.cpp index b4ce8a0ae..ffbb03ea2 100644 --- a/Runtime/Graphics/CBooRenderer.cpp +++ b/Runtime/Graphics/CBooRenderer.cpp @@ -373,12 +373,12 @@ void CBooRenderer::CalcDrawFogFan(const zeus::CPlane* planes, int numPlanes, con const zeus::CPlane& plane = planes[level]; u32 insidePlaneCount = 0; - bool outsidePlane[4]; + bool outsidePlane[20]; for (int i=0 ; i fanToStrip(m_verts); + fanToStrip.AddVert(vert0); + for (int i = 1; i < numVerts; ++i) + fanToStrip.AddVert(proj * zeus::CVector4f(CGraphics::g_GXModelView * verts[i])); } void CFogVolumePlaneShader::draw(int pass) diff --git a/Runtime/MP1/CFrontEndUI.cpp b/Runtime/MP1/CFrontEndUI.cpp index a23bdfbb5..12d562e94 100644 --- a/Runtime/MP1/CFrontEndUI.cpp +++ b/Runtime/MP1/CFrontEndUI.cpp @@ -2007,7 +2007,6 @@ CFrontEndUI::CFrontEndUI() m->ResetGameState(); g_GameState->SetCurrentWorldId(g_ResFactory->TranslateOriginalToNew(g_DefaultWorldTag.id)); - g_GameState->CurrentWorldState().SetAreaId(7); g_GameState->GameOptions().ResetToDefaults(); g_GameState->WriteBackupBuf(); @@ -2016,8 +2015,6 @@ CFrontEndUI::CFrontEndUI() m_touchBar = NewFrontEndUITouchBar(); m_touchBar->SetPhase(CFrontEndUITouchBar::EPhase::None); - - x14_phase = EPhase::ExitFrontEnd; } void CFrontEndUI::StartSlideShow(CArchitectureQueue& queue) diff --git a/Runtime/MP1/CStateSetterFlow.cpp b/Runtime/MP1/CStateSetterFlow.cpp index b227dafb6..58d97ac8d 100644 --- a/Runtime/MP1/CStateSetterFlow.cpp +++ b/Runtime/MP1/CStateSetterFlow.cpp @@ -1,20 +1,54 @@ #include "CStateSetterFlow.hpp" #include "CArchitectureMessage.hpp" #include "GameGlobalObjects.hpp" +#include "MP1.hpp" namespace urde::MP1 { CStateSetterFlow::CStateSetterFlow() -: CIOWin("") -{ - -} +: CIOWin("") {} CIOWin::EMessageReturn CStateSetterFlow::OnMessage(const CArchitectureMessage& msg, CArchitectureQueue& queue) { if (msg.GetType() == EArchMsgType::TimerTick) { - //g_Main->sub80004590(); + MP1::CMain* m = static_cast(g_Main); + + if (m->m_warpWorldIdx > -1) + { + CResLoader* loader = g_ResFactory->GetResLoader(); + CAssetId worldId; + for (const auto& pak : loader->GetPaks()) + { + if (*(pak->GetPath().end() - 6) == '0' + m->m_warpWorldIdx) + { + worldId = pak->GetMLVLId(); + break; + } + } + + if (worldId.IsValid()) + { + m->ResetGameState(); + + g_GameState->SetCurrentWorldId(worldId); + CWorldLayerState& layers = *g_GameState->StateForWorld(worldId).GetLayerState(); + if (m->m_warpAreaId < layers.GetAreaCount()) + { + g_GameState->StateForWorld(worldId).SetAreaId(m->m_warpAreaId); + if (m->m_warpLayerBits) + { + for (u32 i = 0; i < layers.GetAreaLayerCount(m->m_warpAreaId); ++i) + layers.SetLayerActive(m->m_warpAreaId, i, ((m->m_warpLayerBits >> i) & 1) != 0); + } + } + g_GameState->GameOptions().ResetToDefaults(); + g_GameState->WriteBackupBuf(); + return EMessageReturn::RemoveIOWinAndExit; + } + } + + m->RefreshGameState(); return EMessageReturn::RemoveIOWinAndExit; } return EMessageReturn::Exit; diff --git a/Runtime/MP1/MP1.cpp b/Runtime/MP1/MP1.cpp index 8d58e6b8e..0b964ece3 100644 --- a/Runtime/MP1/MP1.cpp +++ b/Runtime/MP1/MP1.cpp @@ -622,6 +622,22 @@ void CMain::StreamNewGameState(CBitStreamReader& r, u32 idx) g_GameState->HintOptions().SetNextHintTime(); } +void CMain::RefreshGameState() +{ + CPersistentOptions sysOpts = g_GameState->SystemOptions(); + u64 cardSerial = g_GameState->GetCardSerial(); + std::vector saveData = g_GameState->BackupBuf(); + CGameOptions gameOpts = g_GameState->GameOptions(); + CBitStreamReader r(saveData.data(), saveData.size()); + x128_globalObjects.StreamInGameState(r, g_GameState->GetFileIdx()); + g_GameState->SetPersistentOptions(sysOpts); + g_GameState->SetGameOptions(gameOpts); + g_GameState->GameOptions().EnsureSettings(); + g_GameState->SetCardSerial(cardSerial); + g_GameState->GetPlayerState()->SetIsFusionEnabled( + g_GameState->SystemOptions().GetPlayerFusionSuitActive()); +} + static logvisor::Module DiscordLog("Discord"); static const char* DISCORD_APPLICATION_ID = "402571593815031819"; static int64_t DiscordStartTime; @@ -720,6 +736,35 @@ void CMain::Init(const hecl::Runtime::FileStoreManager& storeMgr, m_console->registerCommand("ListWorlds"sv, "Lists loaded worlds"sv, ""sv, std::bind(&CMain::ListWorlds, this, std::placeholders::_1, std::placeholders::_2), hecl::SConsoleCommand::ECommandFlags::Normal); m_console->registerCommand("WarpTo"sv, "Warps to a given area and world"sv, "[worldname] areaId"sv, std::bind(&CMain::WarpTo, this, std::placeholders::_1, std::placeholders::_2), hecl::SConsoleCommand::ECommandFlags::Normal); + const auto& args = boo::APP->getArgs(); + for (auto it = args.begin(); it != args.end(); ++it) + { + if (*it == _SYS_STR("--warp") && args.end() - it >= 3) + { + const hecl::SystemChar* worldIdxStr = (*(it + 1)).c_str(); + const hecl::SystemChar* areaIdxStr = (*(it + 2)).c_str(); + + hecl::SystemChar* endptr; + m_warpWorldIdx = hecl::StrToUl(worldIdxStr, &endptr, 0); + if (endptr == worldIdxStr) + m_warpWorldIdx = 0; + m_warpAreaId = hecl::StrToUl(areaIdxStr, &endptr, 0); + if (endptr == areaIdxStr) + m_warpAreaId = 0; + + if (args.end() - it >= 4) + { + const hecl::SystemChar* layerStr = (*(it + 3)).c_str(); + if (layerStr[0] == _SYS_STR('0') || layerStr[0] == _SYS_STR('1')) + for (const auto* cur = layerStr; *cur != _SYS_STR('\0'); ++cur) + if (*cur == _SYS_STR('1')) + m_warpLayerBits |= 1 << (cur - layerStr); + } + + SetFlowState(EFlowState::StateSetter); + } + } + InitializeSubsystems(); x128_globalObjects.PostInitialize(); x70_tweaks.RegisterTweaks(m_cvarMgr); @@ -730,8 +775,6 @@ void CMain::Init(const hecl::Runtime::FileStoreManager& storeMgr, g_archSupport = x164_archSupport.get(); x164_archSupport->PreloadAudio(); //g_TweakManager->ReadFromMemoryCard("AudioTweaks"); - - //CStreamAudioManager::Start(false, "Audio/rui_samusL.dsp|Audio/rui_samusR.dsp", 0x7f, true, 1.f, 1.f); } static logvisor::Module WarmupLog("ShaderWarmup"); diff --git a/Runtime/MP1/MP1.hpp b/Runtime/MP1/MP1.hpp index 6f1ee975c..00c9ea13f 100644 --- a/Runtime/MP1/MP1.hpp +++ b/Runtime/MP1/MP1.hpp @@ -118,6 +118,12 @@ public: x134_gameState.reset(new CGameState()); g_GameState = x134_gameState.get(); } + + void StreamInGameState(CBitStreamReader& stream, u32 saveIdx) + { + x134_gameState.reset(new CGameState(stream, saveIdx)); + g_GameState = x134_gameState.get(); + } }; #if MP1_USE_BOO @@ -281,6 +287,7 @@ public: void AddWorldPaks(); void ResetGameState(); void StreamNewGameState(CBitStreamReader&, u32 idx); + void RefreshGameState(); void CheckTweakManagerDebugOptions() {} void SetMFGameBuilt(bool b) { x160_25_mfGameBuilt = b; } void SetScreenFading(bool b) { x160_26_screenFading = b; } @@ -336,6 +343,10 @@ public: void ListWorlds(hecl::Console*, const std::vector&); void WarpTo(hecl::Console*, const std::vector&); hecl::Console* Console() const { return m_console.get(); } + + int m_warpWorldIdx = -1; + TAreaId m_warpAreaId = 0; + u64 m_warpLayerBits = 0; }; } diff --git a/Shaders/CFogVolumePlaneShader.shader b/Shaders/CFogVolumePlaneShader.shader index b1988cb17..0757f1fa5 100644 --- a/Shaders/CFogVolumePlaneShader.shader +++ b/Shaders/CFogVolumePlaneShader.shader @@ -6,6 +6,7 @@ #depthtest lequal #depthwrite true #colorwrite false +#alphawrite true #culling frontface #vertex glsl @@ -72,16 +73,19 @@ fragment float4 fmain(VertToFrag vtf [[ stage_in ]]) #depthtest none #depthwrite false #colorwrite false +#alphawrite true #culling frontface #shader CFogVolumePlaneShader2 : CFogVolumePlaneShader0 #depthtest lequal #depthwrite true #colorwrite false +#alphawrite true #culling backface #shader CFogVolumePlaneShader3 : CFogVolumePlaneShader0 #depthtest greater #depthwrite false #colorwrite false +#alphawrite true #culling backface