diff --git a/Runtime/MP1/CArtifactDoll.cpp b/Runtime/MP1/CArtifactDoll.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/Runtime/MP1/CArtifactDoll.hpp b/Runtime/MP1/CArtifactDoll.hpp new file mode 100644 index 000000000..738076703 --- /dev/null +++ b/Runtime/MP1/CArtifactDoll.hpp @@ -0,0 +1,35 @@ +#ifndef __URDE_CARTIFACTDOLL_HPP__ +#define __URDE_CARTIFACTDOLL_HPP__ + +#include "RetroTypes.hpp" +#include "Character/CActorLights.hpp" +#include "CToken.hpp" + +namespace urde +{ +class CModel; +namespace MP1 +{ + +class CArtifactDoll +{ + std::vector> x0_models; + std::vector x10_lights; + std::unique_ptr x20_actorLights; + float x24_fader = 0.f; + bool x28_24_loaded : 1; + void UpdateActorLights(); +public: + CGameCubeDoll(); + void Update(float dt); + void Draw(float alpha); + void Touch(); + bool CheckLoadComplete(); + bool IsLoaded() const { return x20_24_loaded; } + +}; + +} +} + +#endif // __URDE_CARTIFACTDOLL_HPP__ diff --git a/Runtime/MP1/CGameCubeDoll.cpp b/Runtime/MP1/CGameCubeDoll.cpp new file mode 100644 index 000000000..c54e88d0c --- /dev/null +++ b/Runtime/MP1/CGameCubeDoll.cpp @@ -0,0 +1,69 @@ +#include "CGameCubeDoll.hpp" +#include "GameGlobalObjects.hpp" +#include "CSimplePool.hpp" +#include "Graphics/CBooRenderer.hpp" + +namespace urde +{ +namespace MP1 +{ + +CGameCubeDoll::CGameCubeDoll() +{ + x0_model = g_SimplePool->GetObj("CMDL_GameCube"); + x8_lights.push_back(CLight::BuildDirectional(zeus::CVector3f::skForward, zeus::CColor::skWhite)); + x18_actorLights = std::make_unique(8, zeus::CVector3f::skZero, 4, 4, false, false, false, 0.1f); + x20_24_loaded = false; +} + +void CGameCubeDoll::UpdateActorLights() +{ + x8_lights[0] = CLight::BuildDirectional( + (zeus::CVector3f::skForward + zeus::CVector3f::skRight * 0.25f + zeus::CVector3f::skDown * 0.1f).normalized(), + zeus::CColor::skWhite); + x18_actorLights->BuildFakeLightList(x8_lights, zeus::CColor(0.25f, 1.f)); +} + +void CGameCubeDoll::Update(float dt) +{ + if (!CheckLoadComplete()) + return; + x1c_fader = std::min(2.f * dt + x1c_fader, 1.f); + UpdateActorLights(); +} + +void CGameCubeDoll::Draw(float alpha) +{ + if (!IsLoaded()) + return; + + g_Renderer->SetPerspective(55.f, g_Viewport.x8_width, g_Viewport.xc_height, 0.2f, 4096.f); + CGraphics::SetViewPointMatrix(zeus::CTransform::Translate(0.f, -2.f, 0.f)); + x18_actorLights->ActivateLights(x0_model->GetInstance()); + CGraphics::SetModelMatrix(zeus::CTransform::RotateZ(zeus::degToRad(360.f * CGraphics::GetSecondsMod900() * -0.25f)) * + zeus::CTransform::Scale(0.2f)); + CModelFlags flags(5, 0, 3, zeus::CColor(1.f, alpha * x1c_fader)); + x0_model->Draw(flags); +} + +void CGameCubeDoll::Touch() +{ + if (!CheckLoadComplete()) + return; + x0_model->Touch(0); +} + +bool CGameCubeDoll::CheckLoadComplete() +{ + if (IsLoaded()) + return true; + if (x0_model.IsLoaded()) + { + x20_24_loaded = true; + return true; + } + return false; +} + +} +} diff --git a/Runtime/MP1/CGameCubeDoll.hpp b/Runtime/MP1/CGameCubeDoll.hpp new file mode 100644 index 000000000..63fcf1876 --- /dev/null +++ b/Runtime/MP1/CGameCubeDoll.hpp @@ -0,0 +1,35 @@ +#ifndef __URDE_CGAMECUBEDOLL_HPP__ +#define __URDE_CGAMECUBEDOLL_HPP__ + +#include "RetroTypes.hpp" +#include "Character/CActorLights.hpp" +#include "CToken.hpp" + +namespace urde +{ +class CModel; +namespace MP1 +{ + +class CGameCubeDoll +{ + TLockedToken x0_model; + std::vector x8_lights; + std::unique_ptr x18_actorLights; + float x1c_fader = 0.f; + bool x20_24_loaded : 1; + void UpdateActorLights(); +public: + CGameCubeDoll(); + void Update(float dt); + void Draw(float alpha); + void Touch(); + bool CheckLoadComplete(); + bool IsLoaded() const { return x20_24_loaded; } + +}; + +} +} + +#endif // __URDE_CGAMECUBEDOLL_HPP__ diff --git a/Runtime/MP1/CInventoryScreen.cpp b/Runtime/MP1/CInventoryScreen.cpp index 2e8819828..319fc77cf 100644 --- a/Runtime/MP1/CInventoryScreen.cpp +++ b/Runtime/MP1/CInventoryScreen.cpp @@ -251,7 +251,7 @@ bool CInventoryScreen::HasLeftInventoryItem(int idx) const } } -void CInventoryScreen::VActivate() const +void CInventoryScreen::VActivate() { for (int i=0 ; i<5 ; ++i) { diff --git a/Runtime/MP1/CInventoryScreen.hpp b/Runtime/MP1/CInventoryScreen.hpp index cceca37ea..62712a3d5 100644 --- a/Runtime/MP1/CInventoryScreen.hpp +++ b/Runtime/MP1/CInventoryScreen.hpp @@ -38,7 +38,7 @@ public: void Draw(float transInterp, float totalAlpha, float yOff); float GetCameraYBias() const; bool VReady() const; - void VActivate() const; + void VActivate(); void RightTableSelectionChanged(int selBegin, int selEnd); void ChangedMode(); void UpdateRightTable(); diff --git a/Runtime/MP1/CLogBookScreen.cpp b/Runtime/MP1/CLogBookScreen.cpp index 0b7d79b81..6c8d7b705 100644 --- a/Runtime/MP1/CLogBookScreen.cpp +++ b/Runtime/MP1/CLogBookScreen.cpp @@ -17,7 +17,7 @@ bool CLogBookScreen::VReady() const return true; } -void CLogBookScreen::VActivate() const +void CLogBookScreen::VActivate() { } diff --git a/Runtime/MP1/CLogBookScreen.hpp b/Runtime/MP1/CLogBookScreen.hpp index d42249b30..01396736c 100644 --- a/Runtime/MP1/CLogBookScreen.hpp +++ b/Runtime/MP1/CLogBookScreen.hpp @@ -15,7 +15,7 @@ public: CLogBookScreen(const CStateManager& mgr, CGuiFrame& frame, const CStringTable& pauseStrg); bool VReady() const; - void VActivate() const; + void VActivate(); u32 GetRightTableCount() const; }; diff --git a/Runtime/MP1/CMakeLists.txt b/Runtime/MP1/CMakeLists.txt index b80cc6a52..f5f6adbd1 100644 --- a/Runtime/MP1/CMakeLists.txt +++ b/Runtime/MP1/CMakeLists.txt @@ -40,6 +40,8 @@ set(MP1_SOURCES CLogBookScreen.hpp CLogBookScreen.cpp COptionsScreen.hpp COptionsScreen.cpp CSamusDoll.hpp CSamusDoll.cpp + CGameCubeDoll.hpp CGameCubeDoll.cpp + CArtifactDoll.hpp CArtifactDoll.cpp MP1.hpp MP1.cpp ${MP1_PLAT_SOURCES} ${MP1_WORLD_SOURCES}) diff --git a/Runtime/MP1/COptionsScreen.cpp b/Runtime/MP1/COptionsScreen.cpp index d948b9600..0c06d903a 100644 --- a/Runtime/MP1/COptionsScreen.cpp +++ b/Runtime/MP1/COptionsScreen.cpp @@ -1,4 +1,9 @@ #include "COptionsScreen.hpp" +#include "GuiSys/CGuiTableGroup.hpp" +#include "GuiSys/CGuiTextPane.hpp" +#include "GuiSys/CGuiSliderGroup.hpp" +#include "Input/RumbleFxTable.hpp" +#include "CArchitectureQueue.hpp" namespace urde { @@ -9,7 +14,179 @@ COptionsScreen::COptionsScreen(const CStateManager& mgr, CGuiFrame& frame, const CStringTable& pauseStrg) : CPauseScreenBase(mgr, frame, pauseStrg) { + x1a0_gameCube = std::unique_ptr(); + x2a0_24_inOptionBody = false; +} +COptionsScreen::~COptionsScreen() +{ + CSfxManager::SfxStop(x1a4_sliderSfx); +} + +void COptionsScreen::UpdateOptionView() +{ + ResetOptionWidgetVisibility(); + + const std::pair& category = + GameOptionsRegistry[x70_tablegroup_leftlog->GetUserSelection()]; + if (category.first == 0) + return; + + float zOff = x38_hightlightPitch * x1c_rightSel; + const SGameOption& opt = category.second[x1c_rightSel]; + switch (opt.type) + { + case EOptionType::Float: + x18c_slidergroup_slider->SetIsActive(true); + x18c_slidergroup_slider->SetVisibility(true, ETraversalMode::Children); + x18c_slidergroup_slider->SetMinVal(opt.minVal); + x18c_slidergroup_slider->SetMaxVal(opt.maxVal); + x18c_slidergroup_slider->SetIncrement(opt.increment); + x18c_slidergroup_slider->SetCurVal(CGameOptions::GetOption(opt.option)); + x18c_slidergroup_slider->SetLocalPosition(x3c_sliderStart + zeus::CVector3f(0.f, 0.f, zOff)); + break; + case EOptionType::DoubleEnum: + x190_tablegroup_double->SetUserSelection(CGameOptions::GetOption(opt.option)); + x190_tablegroup_double->SetIsVisible(true); + x190_tablegroup_double->SetIsActive(true); + UpdateSideTable(x190_tablegroup_double); + x190_tablegroup_double->SetLocalPosition(x48_tableDoubleStart + zeus::CVector3f(0.f, 0.f, zOff)); + break; + case EOptionType::TripleEnum: + x194_tablegroup_triple->SetUserSelection(CGameOptions::GetOption(opt.option)); + x194_tablegroup_triple->SetIsVisible(true); + x194_tablegroup_triple->SetIsActive(true); + UpdateSideTable(x194_tablegroup_triple); + x194_tablegroup_triple->SetLocalPosition(x54_tableTripleStart + zeus::CVector3f(0.f, 0.f, zOff)); + break; + default: break; + } +} + +void COptionsScreen::ResetOptionWidgetVisibility() +{ + x18c_slidergroup_slider->SetIsActive(false); + x18c_slidergroup_slider->SetVisibility(false, ETraversalMode::Children); + x190_tablegroup_double->SetIsVisible(false); + x190_tablegroup_double->SetIsActive(false); + x194_tablegroup_triple->SetIsActive(false); + x194_tablegroup_triple->SetIsVisible(false); +} + +void COptionsScreen::OnSliderChanged(CGuiSliderGroup* caller, float val) +{ + if (x10_mode != EMode::RightTable) + return; + + EGameOption opt = GameOptionsRegistry[x70_tablegroup_leftlog->GetUserSelection()].second[x1c_rightSel].option; + CGameOptions::SetOption(opt, caller->GetGurVal()); +} + +void COptionsScreen::OnEnumChanged(CGuiTableGroup* caller, int sel) +{ + if (x10_mode != EMode::RightTable) + return; + + EGameOption opt = GameOptionsRegistry[x70_tablegroup_leftlog->GetUserSelection()].second[x1c_rightSel].option; + CGameOptions::SetOption(opt, caller->GetUserSelection()); + + if (opt == EGameOption::Rumble && caller->GetUserSelection() > 0) + { + x1a8_rumble.HardStopAll(); + x1a8_rumble.Rumble(RumbleFxTable[11], 1.f, ERumblePriority::One, EIOPort::Zero); + } + + CPauseScreenBase::UpdateSideTable(caller); + CSfxManager::SfxStart(1437, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId); +} + +bool COptionsScreen::InputDisabled() const +{ + return x19c_quitGame.operator bool(); +} + +void COptionsScreen::Update(float dt, CRandom16& rand, CArchitectureQueue& archQueue) +{ + x1a8_rumble.Update(dt); + CPauseScreenBase::Update(dt, rand, archQueue); + + if (x1a4_sliderSfx.operator bool() != + (x18c_slidergroup_slider->GetState() != CGuiSliderGroup::EState::None)) + { + if (x18c_slidergroup_slider->GetState() != CGuiSliderGroup::EState::None) + x1a4_sliderSfx = CSfxManager::SfxStart(1451, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId); + else + CSfxManager::SfxStop(x1a4_sliderSfx); + } + + if (x2a0_24_inOptionBody) + x29c_optionAlpha = std::min(x29c_optionAlpha + 4.f * dt, 1.f); + else + x29c_optionAlpha = std::max(x29c_optionAlpha - 4.f * dt, 0.f); + + if (std::fabs(x29c_optionAlpha) < 0.00001f) + { + ResetOptionWidgetVisibility(); + x174_textpane_body->SetIsVisible(false); + } + + zeus::CColor color = g_tweakGuiColors->GetPauseItemAmberColor(); + color.a = x29c_optionAlpha; + x18c_slidergroup_slider->SetColor(color); + x190_tablegroup_double->SetColor(color); + x194_tablegroup_triple->SetColor(color); + + if (x19c_quitGame) + { + EQuitAction action = x19c_quitGame->Update(dt); + if (action == EQuitAction::Yes) + { + archQueue.Push(MakeMsg::CreateQuitGameplay(EArchMsgTarget::Game)); + CSfxManager::SetChannel(CSfxManager::ESfxChannels::Default); + CSfxManager::SfxStart(1422, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId); + } + else if (action == EQuitAction::No) + { + CSfxManager::SfxStart(1423, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId); + x19c_quitGame.reset(); + } + } + + x1a0_gameCube->Update(dt); +} + +void COptionsScreen::Touch() +{ + CPauseScreenBase::Touch(); + x1a0_gameCube->Touch(); +} + +void COptionsScreen::ProcessControllerInput(const CFinalInput& input) +{ + if (!x19c_quitGame) + { + CPauseScreenBase::ProcessControllerInput(input); + CGameOptions::TryRestoreDefaults(input, x70_tablegroup_leftlog->GetUserSelection(), + x1c_rightSel, false, false); + if (x70_tablegroup_leftlog->GetUserSelection() == 4 && input.PA()) + x19c_quitGame = std::make_unique(EQuitType::QuitGame); + } + else + { + x19c_quitGame->ProcessUserInput(input); + } +} + +void COptionsScreen::Draw(float transInterp, float totalAlpha, float yOff) +{ + CPauseScreenBase::Draw(transInterp, totalAlpha, yOff); + x1a0_gameCube->Draw(transInterp * (1.f - x29c_optionAlpha)); + if (x19c_quitGame) + { + CGraphics::SetDepthRange(0.f, 0.001f); + x19c_quitGame->Draw(); + CGraphics::SetDepthRange(0.f, 1.f); + } } bool COptionsScreen::VReady() const @@ -17,14 +194,85 @@ bool COptionsScreen::VReady() const return true; } -void COptionsScreen::VActivate() const +void COptionsScreen::VActivate() { + for (int i=0 ; i<5 ; ++i) + xa8_textpane_categories[i]->TextSupport()->SetText(xc_pauseStrg.GetString(i + 16)); + x178_textpane_title->TextSupport()->SetText(xc_pauseStrg.GetString(15)); + + for (int i=0 ; i<5 ; ++i) + x70_tablegroup_leftlog->GetWorkerWidget(i)->SetIsSelectable(false); + + x174_textpane_body->TextSupport()->SetJustification(EJustification::Center); + x174_textpane_body->TextSupport()->SetVerticalJustification(EVerticalJustification::Bottom); + + static_cast(x190_tablegroup_double->GetWorkerWidget(0))-> + TextSupport()->SetText(xc_pauseStrg.GetString(95)); + static_cast(x190_tablegroup_double->GetWorkerWidget(1))-> + TextSupport()->SetText(xc_pauseStrg.GetString(94)); + + static_cast(x194_tablegroup_triple->GetWorkerWidget(0))-> + TextSupport()->SetText(xc_pauseStrg.GetString(96)); + static_cast(x194_tablegroup_triple->GetWorkerWidget(1))-> + TextSupport()->SetText(xc_pauseStrg.GetString(97)); + static_cast(x194_tablegroup_triple->GetWorkerWidget(2))-> + TextSupport()->SetText(xc_pauseStrg.GetString(98)); + + x18c_slidergroup_slider->SetSelectionChangedCallback( + std::bind(&COptionsScreen::OnSliderChanged, this, std::placeholders::_1, std::placeholders::_2)); + x190_tablegroup_double->SetMenuSelectionChangeCallback( + std::bind(&COptionsScreen::OnEnumChanged, this, std::placeholders::_1, std::placeholders::_2)); + x194_tablegroup_triple->SetMenuSelectionChangeCallback( + std::bind(&COptionsScreen::OnEnumChanged, this, std::placeholders::_1, std::placeholders::_2)); +} + +void COptionsScreen::RightTableSelectionChanged(int selBegin, int selEnd) +{ + UpdateOptionView(); +} + +void COptionsScreen::ChangedMode() +{ + if (x10_mode == EMode::RightTable) + { + x174_textpane_body->SetIsVisible(true); + UpdateOptionView(); + x2a0_24_inOptionBody = true; + } + else + { + x2a0_24_inOptionBody = false; + } +} + +void COptionsScreen::UpdateRightTable() +{ + CPauseScreenBase::UpdateRightTable(); + const std::pair& category = + GameOptionsRegistry[x70_tablegroup_leftlog->GetUserSelection()]; + for (int i=0 ; i<5 ; ++i) + { + if (i < category.first) + xd8_textpane_titles[i]->TextSupport()->SetText(xc_pauseStrg.GetString(category.second[i].stringId)); + else + xd8_textpane_titles[i]->TextSupport()->SetText(u""); + } +} + +bool COptionsScreen::ShouldLeftTableAdvance() const +{ + return x70_tablegroup_leftlog->GetUserSelection() != 4; +} + +bool COptionsScreen::ShouldRightTableAdvance() const +{ + return false; } u32 COptionsScreen::GetRightTableCount() const { - return 0; + return GameOptionsRegistry[x70_tablegroup_leftlog->GetUserSelection()].first; } } diff --git a/Runtime/MP1/COptionsScreen.hpp b/Runtime/MP1/COptionsScreen.hpp index 28ba09d36..459fdf06d 100644 --- a/Runtime/MP1/COptionsScreen.hpp +++ b/Runtime/MP1/COptionsScreen.hpp @@ -3,6 +3,8 @@ #include "CInGameGuiManager.hpp" #include "CPauseScreenBase.hpp" +#include "CGameCubeDoll.hpp" +#include "CQuitGameScreen.hpp" namespace urde { @@ -11,11 +13,34 @@ namespace MP1 class COptionsScreen : public CPauseScreenBase { + std::unique_ptr x19c_quitGame; + std::unique_ptr x1a0_gameCube; + CSfxHandle x1a4_sliderSfx; + CRumbleGenerator x1a8_rumble; + float x29c_optionAlpha = 0.f; + bool x2a0_24_inOptionBody : 1; + + void UpdateOptionView(); + void ResetOptionWidgetVisibility(); + void OnSliderChanged(CGuiSliderGroup* caller, float val); + void OnEnumChanged(CGuiTableGroup* caller, int sel); + public: COptionsScreen(const CStateManager& mgr, CGuiFrame& frame, const CStringTable& pauseStrg); + ~COptionsScreen(); + bool InputDisabled() const; + void Update(float dt, CRandom16& rand, CArchitectureQueue& archQueue); + void Touch(); + void ProcessControllerInput(const CFinalInput& input); + void Draw(float transInterp, float totalAlpha, float yOff); bool VReady() const; - void VActivate() const; + void VActivate(); + void RightTableSelectionChanged(int selBegin, int selEnd); + void ChangedMode(); + void UpdateRightTable(); + bool ShouldLeftTableAdvance() const; + bool ShouldRightTableAdvance() const; u32 GetRightTableCount() const; }; diff --git a/Runtime/MP1/CPauseScreenBase.hpp b/Runtime/MP1/CPauseScreenBase.hpp index 0814b5496..107a67ff2 100644 --- a/Runtime/MP1/CPauseScreenBase.hpp +++ b/Runtime/MP1/CPauseScreenBase.hpp @@ -120,7 +120,7 @@ public: virtual void Draw(float transInterp, float totalAlpha, float yOff); virtual float GetCameraYBias() const { return 0.f; } virtual bool VReady() const=0; - virtual void VActivate() const=0; + virtual void VActivate()=0; virtual void RightTableSelectionChanged(int selBegin, int selEnd) {} virtual void ChangedMode() {} virtual void UpdateRightTable();