From b22c0bc75f2b8c49d52754429a6d68d0f1bc0b2f Mon Sep 17 00:00:00 2001 From: Phillip Stephens Date: Fri, 7 Jul 2017 05:23:20 -0700 Subject: [PATCH] Fix CGuiTextSupport crash --- Runtime/GuiSys/CGuiTextSupport.cpp | 2 +- Runtime/GuiSys/CGuiTextSupport.hpp | 2 +- Runtime/GuiSys/CTextParser.cpp | 21 +++++--- Runtime/GuiSys/CTextParser.hpp | 2 +- Runtime/RetroTypes.hpp | 1 + Runtime/World/CScriptColorModulate.cpp | 3 +- Runtime/World/CScriptControllerAction.cpp | 10 ++-- Runtime/World/CScriptCounter.cpp | 64 ++++++++++++++++++++++- Runtime/World/CScriptCounter.hpp | 7 ++- Runtime/World/CScriptSound.cpp | 19 ++++++- Runtime/World/CScriptSound.hpp | 4 +- Runtime/World/CVisorFlare.hpp | 5 ++ Runtime/World/CWorld.cpp | 4 ++ Runtime/World/CWorld.hpp | 3 ++ 14 files changed, 126 insertions(+), 21 deletions(-) diff --git a/Runtime/GuiSys/CGuiTextSupport.cpp b/Runtime/GuiSys/CGuiTextSupport.cpp index 34a314e1b..0c21f8ee2 100644 --- a/Runtime/GuiSys/CGuiTextSupport.cpp +++ b/Runtime/GuiSys/CGuiTextSupport.cpp @@ -144,7 +144,7 @@ void CGuiTextSupport::CheckAndRebuildTextBuffer() g_TextExecuteBuf->AddColor(EColorType::Outline, x28_outlineColor); std::u16string initStr; - if (x5c_fontId != 0xffffffff) + if (x5c_fontId != kInvalidResId) initStr = hecl::Char16Format(L"&font=%08X;", u32(x5c_fontId)); initStr += x0_string; diff --git a/Runtime/GuiSys/CGuiTextSupport.hpp b/Runtime/GuiSys/CGuiTextSupport.hpp index b01de588f..6545697a7 100644 --- a/Runtime/GuiSys/CGuiTextSupport.hpp +++ b/Runtime/GuiSys/CGuiTextSupport.hpp @@ -93,7 +93,7 @@ class CGuiTextSupport bool x50_typeEnable = false; float x54_chFadeTime = 0.1f; float x58_chRate = 10.0f; - ResId x5c_fontId = -1; + ResId x5c_fontId = kInvalidResId; CGuiWidget::EGuiModelDrawFlags m_drawFlags; std::experimental::optional x60_renderBuf; std::vector x2bc_assets; diff --git a/Runtime/GuiSys/CTextParser.cpp b/Runtime/GuiSys/CTextParser.cpp index c9f238a97..37bf9d097 100644 --- a/Runtime/GuiSys/CTextParser.cpp +++ b/Runtime/GuiSys/CTextParser.cpp @@ -240,7 +240,7 @@ CFontImageDef CTextParser::GetImage(const char16_t* str, int len, { AdvanceCommaPos(); texs.push_back(x0_store.GetObj({SBIG('TXTR'), - GetAssetIdFromString(&iterable[tokenPos], txtrMap)})); + GetAssetIdFromString(&iterable[tokenPos], len, txtrMap)})); AdvanceTokenPos(); } while (commaPos != iterable.size()); @@ -267,7 +267,7 @@ CFontImageDef CTextParser::GetImage(const char16_t* str, int len, { AdvanceCommaPos(); texs.push_back(x0_store.GetObj({SBIG('TXTR'), - GetAssetIdFromString(&iterable[tokenPos], txtrMap)})); + GetAssetIdFromString(&iterable[tokenPos], len, txtrMap)})); AdvanceTokenPos(); } while (commaPos != iterable.size()); @@ -286,18 +286,18 @@ CFontImageDef CTextParser::GetImage(const char16_t* str, int len, AdvanceCommaPos(); TToken tex = x0_store.GetObj({SBIG('TXTR'), - GetAssetIdFromString(&iterable[tokenPos], txtrMap)}); + GetAssetIdFromString(&iterable[tokenPos], len, txtrMap)}); AdvanceTokenPos(); return CFontImageDef(tex, zeus::CVector2f(cropX, cropY)); } } - TToken tex = x0_store.GetObj({SBIG('TXTR'), GetAssetIdFromString(str, txtrMap)}); + TToken tex = x0_store.GetObj({SBIG('TXTR'), GetAssetIdFromString(str, len, txtrMap)}); return CFontImageDef(tex, zeus::CVector2f(1.f, 1.f)); } -ResId CTextParser::GetAssetIdFromString(const char16_t* str, +ResId CTextParser::GetAssetIdFromString(const char16_t* str, int len, const std::vector>* txtrMap) { u8 r = GetColorValue(str); @@ -306,6 +306,15 @@ ResId CTextParser::GetAssetIdFromString(const char16_t* str, u8 a = GetColorValue(str + 6); ResId id = ((r << 24) | (g << 16) | (b << 8) | a) & 0xffffffff; + if (len == 16) + { + r = GetColorValue(str + 8); + g = GetColorValue(str + 10); + b = GetColorValue(str + 12); + a = GetColorValue(str + 14); + id = (id << 32) | (((r << 24) | (g << 16) | (b << 8) | a) & 0xffffffff); + } + if (txtrMap) { auto search = std::lower_bound(txtrMap->begin(), txtrMap->end(), id, @@ -319,7 +328,7 @@ ResId CTextParser::GetAssetIdFromString(const char16_t* str, TToken CTextParser::GetFont(const char16_t* str, int len) { - return x0_store.GetObj({SBIG('FONT'), GetAssetIdFromString(str, nullptr)}); + return x0_store.GetObj({SBIG('FONT'), GetAssetIdFromString(str, len, nullptr)}); } void CTextParser::ParseText(CTextExecuteBuffer& out, const char16_t* str, int len, diff --git a/Runtime/GuiSys/CTextParser.hpp b/Runtime/GuiSys/CTextParser.hpp index 9a70462a7..056fb4eab 100644 --- a/Runtime/GuiSys/CTextParser.hpp +++ b/Runtime/GuiSys/CTextParser.hpp @@ -16,7 +16,7 @@ class CTextParser static u8 GetColorValue(const char16_t* str); static u32 FromHex(char16_t ch); static s32 ParseInt(const char16_t* str, int len, bool signVal); - static ResId GetAssetIdFromString(const char16_t* str, + static ResId GetAssetIdFromString(const char16_t* str, int len, const std::vector>* txtrMap); static bool Equals(const char16_t* str, int len, const char16_t* other); static bool BeginsWith(const char16_t* str, int len, const char16_t* other); diff --git a/Runtime/RetroTypes.hpp b/Runtime/RetroTypes.hpp index ade7590d3..a88d1c0e9 100644 --- a/Runtime/RetroTypes.hpp +++ b/Runtime/RetroTypes.hpp @@ -57,6 +57,7 @@ using TAreaId = s32; #define kInvalidEditorId TEditorId() #define kInvalidUniqueId TUniqueId(-1) #define kInvalidAreaId TAreaId(-1) +#define kInvalidResId ResId(-1) } #if 0 diff --git a/Runtime/World/CScriptColorModulate.cpp b/Runtime/World/CScriptColorModulate.cpp index 7c3adce5d..dc7a5e78b 100644 --- a/Runtime/World/CScriptColorModulate.cpp +++ b/Runtime/World/CScriptColorModulate.cpp @@ -50,8 +50,9 @@ void CScriptColorModulate::FadeOutHelper(CStateManager &, TUniqueId, float) { } -void CScriptColorModulate::FadeInHelper(CStateManager &, TUniqueId, float) +void CScriptColorModulate::FadeInHelper(CStateManager& mgr, TUniqueId uid, float f1) { + } void CScriptColorModulate::End(CStateManager& stateMgr) diff --git a/Runtime/World/CScriptControllerAction.cpp b/Runtime/World/CScriptControllerAction.cpp index f1ba79b6a..c61cfad6f 100644 --- a/Runtime/World/CScriptControllerAction.cpp +++ b/Runtime/World/CScriptControllerAction.cpp @@ -8,11 +8,11 @@ namespace urde CScriptControllerAction::CScriptControllerAction(TUniqueId uid, const std::string& name, const CEntityInfo& info, bool active, - ControlMapper::ECommands command, bool b1, u32 w1, bool b2) + ControlMapper::ECommands command, bool mapScreenResponse, u32 w1, bool deactivateOnClose) : CEntity(uid, info, active, name), x34_command(command), x38_mapScreenSubaction(w1) { - x3c_24_mapScreenResponse = b1; - x3c_25_deactivateOnClose = b2; + x3c_24_mapScreenResponse = mapScreenResponse; + x3c_25_deactivateOnClose = deactivateOnClose; } void CScriptControllerAction::Accept(IVisitor& visitor) @@ -22,7 +22,7 @@ void CScriptControllerAction::Accept(IVisitor& visitor) void CScriptControllerAction::Think(float dt, CStateManager& stateMgr) { - bool old26 = x3c_26_pressed; + bool oldPressed = x3c_26_pressed; if (x3c_24_mapScreenResponse) { if (x38_mapScreenSubaction == 0) @@ -33,7 +33,7 @@ void CScriptControllerAction::Think(float dt, CStateManager& stateMgr) x3c_26_pressed = ControlMapper::GetDigitalInput(x34_command, stateMgr.GetFinalInput()); } - if (GetActive() && x3c_26_pressed != old26) + if (GetActive() && x3c_26_pressed != oldPressed) { if (x3c_26_pressed) { diff --git a/Runtime/World/CScriptCounter.cpp b/Runtime/World/CScriptCounter.cpp index 7d1da1a3f..e2a726ade 100644 --- a/Runtime/World/CScriptCounter.cpp +++ b/Runtime/World/CScriptCounter.cpp @@ -1,12 +1,17 @@ #include "CScriptCounter.hpp" +#include "CStateManager.hpp" #include "TCastTo.hpp" namespace urde { CScriptCounter::CScriptCounter(TUniqueId uid, const std::string& name, const CEntityInfo& info, - u32, u32, bool, bool active) + s32 initial, s32 max, bool autoReset, bool active) : CEntity(uid, info, active, name) +, x34_initial(initial) +, x38_current(initial) +, x3c_max(max) +, x40_autoReset(autoReset) { } @@ -15,4 +20,61 @@ void CScriptCounter::Accept(IVisitor& visitor) visitor.Visit(this); } +void CScriptCounter::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId objId, CStateManager& stateMgr) +{ + switch(msg) + { + case EScriptObjectMessage::SetToZero: + if (GetActive()) + { + x38_current = 0; + SendScriptMsgs(EScriptObjectState::Zero, stateMgr, EScriptObjectMessage::None); + + if (x40_autoReset) + x38_current = x34_initial; + } + break; + case EScriptObjectMessage::SetToMax: + if (GetActive()) + { + x38_current = x3c_max; + SendScriptMsgs(EScriptObjectState::MaxReached, stateMgr, EScriptObjectMessage::None); + + if (x40_autoReset) + x38_current = x34_initial; + } + break; + case EScriptObjectMessage::Decrement: + if (GetActive() && x38_current > 0) + { + --x38_current; + if (x38_current == 0) + { + SendScriptMsgs(EScriptObjectState::Zero, stateMgr, EScriptObjectMessage::None); + if (x40_autoReset) + x38_current = x34_initial; + } + } + break; + case EScriptObjectMessage::Increment: + if (GetActive() && x38_current < x3c_max) + { + ++x38_current; + if (x38_current >= x3c_max) + { + SendScriptMsgs(EScriptObjectState::Zero, stateMgr, EScriptObjectMessage::None); + if (x40_autoReset) + x38_current = x34_initial; + } + } + break; + case EScriptObjectMessage::Reset: + if (GetActive()) + x38_current = x34_initial; + break; + } + + CEntity::AcceptScriptMsg(msg, objId, stateMgr); +} + } diff --git a/Runtime/World/CScriptCounter.hpp b/Runtime/World/CScriptCounter.hpp index 7cc622f67..413490416 100644 --- a/Runtime/World/CScriptCounter.hpp +++ b/Runtime/World/CScriptCounter.hpp @@ -8,11 +8,16 @@ namespace urde class CScriptCounter : public CEntity { + s32 x34_initial; + s32 x38_current; + s32 x3c_max; + bool x40_autoReset; public: CScriptCounter(TUniqueId, const std::string& name, const CEntityInfo& info, - u32, u32, bool, bool); + s32, s32, bool, bool); void Accept(IVisitor& visitor); + void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId objId, CStateManager &stateMgr); }; } diff --git a/Runtime/World/CScriptSound.cpp b/Runtime/World/CScriptSound.cpp index e7b69e7e9..497681a17 100644 --- a/Runtime/World/CScriptSound.cpp +++ b/Runtime/World/CScriptSound.cpp @@ -1,6 +1,8 @@ #include "CScriptSound.hpp" #include "Character/CModelData.hpp" #include "Collision/CMaterialList.hpp" +#include "CStateManager.hpp" +#include "CWorld.hpp" #include "CActorParameters.hpp" #include "TCastTo.hpp" @@ -45,7 +47,9 @@ void CScriptSound::PreThink(float dt, CStateManager& mgr) x11d_25_ = false; } -void CScriptSound::Think(float, CStateManager&) {} +void CScriptSound::Think(float dt, CStateManager& mgr) +{ +} void CScriptSound::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) { @@ -83,7 +87,18 @@ void CScriptSound::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CSta void CScriptSound::PlaySound(CStateManager&) {} -void CScriptSound::StopSound() +void CScriptSound::StopSound(CStateManager& mgr) { + x11c_24_playing = false; + if (x11c_30_ && x11c_26_) + { + mgr.WorldNC()->StopSound(x100_soundId); + xec_sfxHandle.reset(); + } + else if (xec_sfxHandle) + { + CSfxManager::RemoveEmitter(xec_sfxHandle); + xec_sfxHandle.reset(); + } } } diff --git a/Runtime/World/CScriptSound.hpp b/Runtime/World/CScriptSound.hpp index cbc6fde22..69bd7d405 100644 --- a/Runtime/World/CScriptSound.hpp +++ b/Runtime/World/CScriptSound.hpp @@ -30,7 +30,7 @@ class CScriptSound : public CActor { struct { - bool x11c_24_ : 1; + bool x11c_24_playing : 1; bool x11c_25_ : 1; bool x11c_26_ : 1; bool x11c_27_ : 1; @@ -55,7 +55,7 @@ public: void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&); void GetOccludedVolumeAmount(const zeus::CVector3f&, const CStateManager&); void PlaySound(CStateManager&); - void StopSound(); + void StopSound(CStateManager&); }; } diff --git a/Runtime/World/CVisorFlare.hpp b/Runtime/World/CVisorFlare.hpp index de83d3bd6..995d495a2 100644 --- a/Runtime/World/CVisorFlare.hpp +++ b/Runtime/World/CVisorFlare.hpp @@ -26,6 +26,11 @@ public: public: CFlareDef(const TToken& tex, float f1, float f2, const zeus::CColor& color) : x0_tex(tex), x8_f1(f1), xc_f2(f2), x10_color(color) { x0_tex.Lock(); } + + TToken GetTexture() const; + zeus::CColor GetColor() { return x10_color; } + float GetScale() const; + float GetPosition() const; }; private: EBlendMode x0_blendMode; diff --git a/Runtime/World/CWorld.cpp b/Runtime/World/CWorld.cpp index 8f870419a..b5e31a2e7 100644 --- a/Runtime/World/CWorld.cpp +++ b/Runtime/World/CWorld.cpp @@ -609,4 +609,8 @@ void CWorld::DrawSky(const zeus::CTransform& xf) const CGraphics::SetDepthRange(0.125f, 1.f); } + +void CWorld::RemoveEmitter(s16) +{ +} } diff --git a/Runtime/World/CWorld.hpp b/Runtime/World/CWorld.hpp index 7bb080c08..8047e5762 100644 --- a/Runtime/World/CWorld.hpp +++ b/Runtime/World/CWorld.hpp @@ -5,6 +5,7 @@ #include "ScriptObjectSupport.hpp" #include "CGameArea.hpp" #include "Graphics/CModel.hpp" +#include "Audio/CSfxManager.hpp" #include "AutoMapper/CMapWorld.hpp" @@ -146,6 +147,7 @@ private: TLockedToken x94_skybox; TLockedToken xa4_skyboxB; TLockedToken xb4_skyboxC; + std::vector xc4_sfxHandles; void LoadSoundGroup(int groupId, ResId agscId, CSoundGroupData& data); void LoadSoundGroups(); @@ -197,6 +199,7 @@ public: void PreRender(); void TouchSky(); void DrawSky(const zeus::CTransform& xf) const; + void RemoveEmitter(s16); }; struct CWorldLayers