diff --git a/configure.py b/configure.py index 0c280ad5..65ddda02 100755 --- a/configure.py +++ b/configure.py @@ -279,7 +279,7 @@ LIBS = [ ["MetroidPrime/Weapons/GunController/CGunController", False], ["MetroidPrime/Weapons/GunController/CGSFreeLook", False], "MetroidPrime/Weapons/GunController/CGSComboFire", - "MetroidPrime/HUD/CHudBallInterface", + ["MetroidPrime/HUD/CHudBallInterface", False], "MetroidPrime/Tweaks/CTweakGuiColors", "MetroidPrime/ScriptObjects/CFishCloud", ["MetroidPrime/CHealthInfo", True], diff --git a/include/GuiSys/CGuiCamera.hpp b/include/GuiSys/CGuiCamera.hpp new file mode 100644 index 00000000..c2892842 --- /dev/null +++ b/include/GuiSys/CGuiCamera.hpp @@ -0,0 +1,9 @@ +#ifndef _CGUICAMERA +#define _CGUICAMERA + +#include "GuiSys/CGuiWidget.hpp" + +class CGuiCamera : public CGuiWidget { +}; + +#endif // _CGUICAMERA diff --git a/include/GuiSys/CGuiCompoundWidget.hpp b/include/GuiSys/CGuiCompoundWidget.hpp new file mode 100644 index 00000000..228d4af1 --- /dev/null +++ b/include/GuiSys/CGuiCompoundWidget.hpp @@ -0,0 +1,16 @@ +#ifndef _CGUICOMPOUNDWIDGET +#define _CGUICOMPOUNDWIDGET + +#include "GuiSys/CGuiWidget.hpp" + +class CGuiCompoundWidget : public CGuiWidget { +public: + FourCC GetWidgetTypeID() const override { return -1; } + + void OnVisibleChange() override; + void OnActiveChange() override; + virtual CGuiWidget* GetWorkerWidget(int id) const; +private: +}; + +#endif // _CGUICOMPOUNDWIDGET diff --git a/include/GuiSys/CGuiFrame.hpp b/include/GuiSys/CGuiFrame.hpp new file mode 100644 index 00000000..ce289885 --- /dev/null +++ b/include/GuiSys/CGuiFrame.hpp @@ -0,0 +1,21 @@ +#ifndef _CGUIFRAME +#define _CGUIFRAME + +#include "rstl/string.hpp" + +class CGuiWidget; +class CGuiCamera; + +class CGuiFrame { +public: + CGuiWidget* FindWidget(const char* name) const; + CGuiWidget* FindWidget(const rstl::string& name) const; + + CGuiCamera* GetFrameCamera() const { return x14_camera; } + +private: + char x0_pad[0x14]; + CGuiCamera* x14_camera; +}; + +#endif // _CGUIFRAME diff --git a/include/GuiSys/CGuiGroup.hpp b/include/GuiSys/CGuiGroup.hpp new file mode 100644 index 00000000..e7aa6de0 --- /dev/null +++ b/include/GuiSys/CGuiGroup.hpp @@ -0,0 +1,22 @@ +#ifndef _CGUIGROUP +#define _CGUIGROUP + +#include "GuiSys/CGuiCompoundWidget.hpp" + +class CGuiGroup : public CGuiCompoundWidget { +public: + FourCC GetWidgetTypeID() const override { return 'GRUP'; } + + void SelectWorkerWidget(int workerId, bool setActive, bool setVisible); + CGuiWidget* GetSelectedWidget(); + const CGuiWidget* GetSelectedWidget() const; + bool AddWorkerWidget(CGuiWidget* worker) override; + void OnActiveChange() override; + +private: + uint xb8_workerCount; + int xbc_selectedWorker; + bool xc0_b; +}; + +#endif // _CGUIGROUP diff --git a/include/GuiSys/CGuiModel.hpp b/include/GuiSys/CGuiModel.hpp new file mode 100644 index 00000000..a2603ed1 --- /dev/null +++ b/include/GuiSys/CGuiModel.hpp @@ -0,0 +1,28 @@ +#ifndef _CGUIMODEL +#define _CGUIMODEL + +#include "GuiSys/CGuiWidget.hpp" + +#include "Kyoto/SObjectTag.hpp" +#include "Kyoto/TToken.hpp" + +class CModel; + +class CGuiModel : public CGuiWidget { +public: + CGuiModel(const CGuiWidgetParms& parms, CSimplePool* sp, CAssetId modelId, uint lightMask, + bool flag); + + const TLockedToken< CModel >& GetModel() const { return xb8_model; } + bool GetIsFinishedLoadingWidgetSpecific() override; + void Touch() override; + void Draw(const CGuiWidgetDrawParms& parms) override; + bool TestCursorHit(const CMatrix4f& vp, const CVector2f& point) const override; + +private: + TLockedToken< CModel > xb8_model; + CAssetId xc8_modelId; + uint xcc_lightMask; +}; + +#endif // _CGUIMODEL diff --git a/include/GuiSys/CGuiObject.hpp b/include/GuiSys/CGuiObject.hpp new file mode 100644 index 00000000..4c39da5f --- /dev/null +++ b/include/GuiSys/CGuiObject.hpp @@ -0,0 +1,35 @@ +#ifndef _CGUIOBJECT +#define _CGUIOBJECT + +#include "Kyoto/Math/CTransform4f.hpp" + +class CGuiWidgetDrawParms; +class CMatrix4f; +class CVector2f; + +class CGuiObject { +public: + virtual ~CGuiObject(); + virtual void Update(float dt); + virtual void Draw(const CGuiWidgetDrawParms& parms); + virtual bool TestCursorHit(const CMatrix4f& vp, const CVector2f& point) const { return false; } + virtual void Initialize() = 0; + + void RecalculateTransforms(); + const CVector3f& GetLocalPosition() const; + + void SetLocalTransform(const CTransform4f& xf) { + x4_localXF = xf; + RecalculateTransforms(); + } + +private: + CTransform4f x4_localXF; + CTransform4f x34_worldXF; + CGuiObject* x64_parent; + CGuiObject* x68_child; + CGuiObject* x6c_nextSibling; +}; +CHECK_SIZEOF(CGuiObject, 0x70) + +#endif // _CGUIOBJECT diff --git a/include/GuiSys/CGuiPane.hpp b/include/GuiSys/CGuiPane.hpp new file mode 100644 index 00000000..a043b1a3 --- /dev/null +++ b/include/GuiSys/CGuiPane.hpp @@ -0,0 +1,24 @@ +#ifndef _CGUIPANE +#define _CGUIPANE + +#include "GuiSys/CGuiWidget.hpp" + +class CGuiPane : public CGuiWidget { +public: + CGuiPane(const CGuiWidgetParms& parms, const CVector2f& dim, const CVector3f& scaleCenter); + + void Draw(const CGuiWidgetDrawParms& parms) override; + virtual void ScaleDimensions(const CVector3f& scale); + virtual void SetDimensions(const CVector2f& dim, bool initVBO); + virtual CVector2f GetDimensions() const; + virtual void InitializeBuffers(); + virtual void WriteData(COutputStream& out, bool flag) const; + +private: + CVector2f xb8_dim; + uchar xc0_pad[8]; + CVector3f xc8_scaleCenter; +}; +CHECK_SIZEOF(CGuiPane, 0xd4) + +#endif // _CGUIPANE diff --git a/include/GuiSys/CGuiTextPane.hpp b/include/GuiSys/CGuiTextPane.hpp new file mode 100644 index 00000000..56018696 --- /dev/null +++ b/include/GuiSys/CGuiTextPane.hpp @@ -0,0 +1,33 @@ +#ifndef _CGUITEXTPANE +#define _CGUITEXTPANE + +#include "GuiSys/CGuiPane.hpp" + +#include "GuiSys/CGuiTextSupport.hpp" + +#include "Kyoto/SObjectTag.hpp" + +class CSimplePool; +class CColor; +class CGuiTextProperties; + +class CGuiTextPane : public CGuiPane { +public: + CGuiTextPane(const CGuiWidgetParms& parms, CSimplePool* sp, const CVector2f& dim, const CVector3f& vec, + CAssetId fontId, const CGuiTextProperties& props, const CColor& col1, const CColor& col2, + int padX, int padY, CAssetId jpFontId, int jpExtentX, int jpExtentY); + + CGuiTextSupport& TextSupport() { return xd4_textSupport; } + const CGuiTextSupport& GetTextSupport() const { return xd4_textSupport; } + void Update(float dt) override; + bool GetIsFinishedLoadingWidgetSpecific() override; + void SetDimensions(const CVector2f& dim, bool initVBO) override; + void ScaleDimensions(const CVector3f& scale) override; + void Draw(const CGuiWidgetDrawParms& parms) override; + bool TestCursorHit(const CMatrix4f& vp, const CVector2f& point) const override; + +private: + CGuiTextSupport xd4_textSupport; +}; + +#endif // _CGUITEXTPANE diff --git a/include/GuiSys/CGuiTextSupport.hpp b/include/GuiSys/CGuiTextSupport.hpp new file mode 100644 index 00000000..762356d0 --- /dev/null +++ b/include/GuiSys/CGuiTextSupport.hpp @@ -0,0 +1,15 @@ +#ifndef _CGUITEXTSUPPORT +#define _CGUITEXTSUPPORT + +#include "rstl/string.hpp" + +class CColor; + +class CGuiTextSupport { +public: + void SetText(const rstl::string&, bool multipage = false); + void SetOutlineColor(const CColor& col); + void SetFontColor(const CColor& col); +}; + +#endif // _CGUITEXTSUPPORT diff --git a/include/GuiSys/CGuiWidget.hpp b/include/GuiSys/CGuiWidget.hpp new file mode 100644 index 00000000..83ebd0d3 --- /dev/null +++ b/include/GuiSys/CGuiWidget.hpp @@ -0,0 +1,59 @@ +#ifndef _CGUIWIDGET +#define _CGUIWIDGET + +#include "GuiSys/CGuiObject.hpp" +#include "Kyoto/SObjectTag.hpp" + +class CColor; +class CFinalInput; + +enum ETraversalMode { kTM_ChildrenAndSiblings = 0, kTM_Children = 1, kTM_Single = 2 }; + +class CGuiWidget : public CGuiObject { +public: + enum EGuiModelDrawFlags { kGMDF_Shadeless = 0, kGMDF_Opaque = 1, kGMDF_Alpha = 2, kGMDF_Additive = 3, kGMDF_AlphaAdditiveOverdraw = 4 }; + class CGuiWidgetParms {}; + + void Update(float dt) override; + void Draw(const CGuiWidgetDrawParms& drawParms) override; + void Initialize() override; + + virtual void Reset(ETraversalMode mode); + virtual void ProcessUserInput(const CFinalInput& input); + virtual void Touch(); + virtual bool GetIsVisible() const; + virtual bool GetIsActive() const; + virtual bool GetMouseActive() const; + virtual FourCC GetWidgetTypeID() const { return 'BWIG'; } + virtual bool AddWorkerWidget(CGuiWidget* worker); + virtual bool GetIsFinishedLoadingWidgetSpecific(); + virtual void OnVisibleChange(); + virtual void OnActiveChange(); + + void SetColor(const CColor& color); + void SetVisibility(bool visible, ETraversalMode mode); + +private: + short x70_selfId; + short x72_parentId; + CTransform4f x74_transform; + CColor xa4_color; + CColor xa8_color2; + EGuiModelDrawFlags xac_drawFlags; + CGuiFrame* xb0_frame; + short xb4_workerId; + bool xb6_24_pg : 1; + bool xb6_25_isVisible : 1; + bool xb6_26_isActive : 1; + bool xb6_27_isSelectable : 1; + bool xb6_28_eventLock : 1; + bool xb6_29_cullFaces : 1; + bool xb6_30_depthGreater : 1; + bool xb6_31_depthTest : 1; + bool xb7_24_depthWrite : 1; + bool xb7_25_ : 1; +}; +CHECK_SIZEOF(CGuiWidget, 0xb8) + + +#endif // _CGUIWIDGET diff --git a/include/MetroidPrime/HUD/CHudBallInterface.hpp b/include/MetroidPrime/HUD/CHudBallInterface.hpp new file mode 100644 index 00000000..c4da60fd --- /dev/null +++ b/include/MetroidPrime/HUD/CHudBallInterface.hpp @@ -0,0 +1,36 @@ +#ifndef _CHUDBALLINTERFACE +#define _CHUDBALLINTERFACE + +#include "Kyoto/Math/CVector3f.hpp" +#include "rstl/reserved_vector.hpp" + +class CGuiCamera; +class CGuiFrame; +class CGuiModel; +class CGuiTextPane; +class CGuiWidget; + +class CHudBallInterface { +public: + CHudBallInterface(CGuiFrame& selHud, int pbAmount, int pbCapacity, int availableBombs, bool hasBombs, bool hasPb); + void SetBombParams(int pbAmount, int pbCapacity, int availableBombs, bool hasBombs, bool hasPb, bool init); + void SetBallModeFactor(float t); + + private: + + CGuiCamera* x0_camera; + CGuiWidget* x4_basewidget_bombstuff; + CGuiWidget* x8_basewidget_bombdeco; + CGuiModel* xc_model_bombicon; + CGuiTextPane* x10_textpane_bombdigits; + rstl::reserved_vector x14_group_bombfilled; + rstl::reserved_vector x24_group_bombempty; + CVector3f x34_camPos; + int x40_pbAmount; + int x44_pbCapacity; + int x48_availableBombs; + bool x4c_hasPb; + void UpdatePowerBombReadoutColors(); +}; + +#endif // _CHUDBALLINTERFACE diff --git a/include/MetroidPrime/Tweaks/CTweakGui.hpp b/include/MetroidPrime/Tweaks/CTweakGui.hpp new file mode 100644 index 00000000..f5cc2362 --- /dev/null +++ b/include/MetroidPrime/Tweaks/CTweakGui.hpp @@ -0,0 +1,324 @@ +#ifndef _CTWEAKGUI +#define _CTWEAKGUI + +#include "MetroidPrime/Tweaks/ITweakObject.hpp" + +#include "Kyoto/Graphics/CColor.hpp" +#include "Kyoto/Math/CVector3f.hpp" + +#include "rstl/reserved_vector.hpp" +#include "rstl/string.hpp" + +class CTweakGui : public ITweakObject { +public: + enum EHudVisMode { kHud_Zero, kHud_One, kHud_Two, kHud_Three }; + + enum EHelmetVisMode { + kHelmet_ReducedUpdate, + kHelmet_NotVisible, + kHelmet_Deco, + kHelmet_HelmetDeco, + kHelmet_GlowHelmetDeco, + kHelmet_HelmetOnly + }; + + float GetMapAlphaInterpolant() const override { return x8_mapAlphaInterp; } + float GetPauseBlurFactor() const override { return xc_pauseBlurFactor; } + float GetRadarXYRadius() const override { return x10_radarXYRadius; } + float GetRadarZRadius() const override { return x24_radarZRadius; } + float GetRadarZCloseRadius() const override { return x28_radarZCloseRadius; } + float GetEnergyBarFilledSpeed() const override { return x34_energyBarFilledSpeed; } + float GetEnergyBarShadowSpeed() const override { return x38_energyBarShadowSpeed; } + float GetEnergyBarDrainDelay() const override { return x3c_energyBarDrainDelay; } + bool GetEnergyBarAlwaysResetDelay() const override { return x40_energyBarAlwaysResetDelay; } + float GetHudDamagePracticalsGainConstant() const override { return x44_hudDamagePracticalsGainConstant; } + float GetHudDamagePracticalsGainLinear() const override { return x48_hudDamagePracticalsGainLinear; } + float GetHudDamagePracticalsInitConstant() const override { return x4c_hudDamagePracticalsInitConstant; } + float GetHudDamagePracticalsInitLinear() const override { return x50_hudDamagePracticalsInitLinear; } + float GetHudDamageLightSpotAngle() const override { return x54_hudDamageLightSpotAngle; } + float GetDamageLightAngleC() const override { return x58_damageLightAngleC; } + float GetDamageLightAngleL() const override { return x5c_damageLightAngleL; } + float GetDamageLightAngleQ() const override { return x60_damageLightAngleQ; } + CVector3f GetDamageLightPreTranslate() const override { return x64_damageLightPreTranslate; } + CVector3f GetDamageLightCenterTranslate() const override { return x70_damageLightCenterTranslate; } + float GetDamageLightXfXAngle() const override { return x7c_damageLightXfXAngle; } + float GetDamageLightXfZAngle() const override { return x80_damageLightXfZAngle; } + float GetHudDecoShakeTranslateVelConstant() const override { return x84_hudDecoShakeTranslateVelConstant; } + float GetHudDecoShakeTranslateVelLinear() const override { return x88_hudDecoShakeTranslateVelLinear; } + float GetMaxDecoDamageShakeTranslate() const override { return x8c_maxDecoDamageShakeTranslate; } + float GetDecoDamageShakeDeceleration() const override { return x90_decoDamageShakeDeceleration; } + float GetDecoShakeGainConstant() const override { return x94_decoShakeGainConstant; } + float GetDecoShakeGainLinear() const override { return x98_decoShakeGainLinear; } + float GetDecoShakeInitConstant() const override { return x9c_decoShakeInitConstant; } + float GetDecoShakeInitLinear() const override { return xa0_decoShakeInitLinear; } + float GetMaxDecoDamageShakeRotate() const override { return xa4_maxDecoDamageShakeRotate; } + uint GetHudCamFovTweak() const override { return xa8_hudCamFovTweak; } + uint GetHudCamYTweak() const override { return xac_hudCamYTweak; } + uint GetHudCamZTweak() const override { return xb0_hudCamZTweak; } + float GetBeamVisorMenuAnimTime() const override { return xc0_beamVisorMenuAnimTime; } + float GetVisorBeamMenuItemActiveScale() const override { return xc4_visorBeamMenuItemActiveScale; } + float GetVisorBeamMenuItemInactiveScale() const override { return xc8_visorBeamMenuItemInactiveScale; } + float GetVisorBeamMenuItemTranslate() const override { return xcc_visorBeamMenuItemTranslate; } + float GetThreatRange() const override { return xe4_threatRange; } + float GetRadarScopeCoordRadius() const override { return xe8_radarScopeCoordRadius; } + float GetRadarPlayerPaintRadius() const override { return xec_radarPlayerPaintRadius; } + float GetRadarEnemyPaintRadius() const override { return xf0_radarEnemyPaintRadius; } + float GetMissileArrowVisTime() const override { return xf4_missileArrowVisTime; } + EHudVisMode GetHudVisMode() const override { return xf8_hudVisMode; } + EHelmetVisMode GetHelmetVisMode() const override { return xfc_helmetVisMode; } + uint GetEnableAutoMapper() const override { return x100_enableAutoMapper; } + uint GetEnableTargetingManager() const override { return x108_enableTargetingManager; } + uint GetEnablePlayerVisor() const override { return x10c_enablePlayerVisor; } + float GetThreatWarningFraction() const override { return x110_threatWarningFraction; } + float GetMissileWarningFraction() const override { return x114_missileWarningFraction; } + float GetFreeLookFadeTime() const override { return x118_freeLookFadeTime; } + float GetFreeLookSfxPitchScale() const override { return x12c_freeLookSfxPitchScale; } + bool GetNoAbsoluteFreeLookSfxPitch() const override { return x130_noAbsoluteFreeLookSfxPitch; } + float GetFaceReflectionOrthoWidth() const override { return x13c_faceReflectionOrthoWidth; } + float GetFaceReflectionOrthoHeight() const override { return x140_faceReflectionOrthoHeight; } + float GetFaceReflectionDistance() const override { return x144_faceReflectionDistance; } + float GetFaceReflectionHeight() const override { return x148_faceReflectionHeight; } + float GetFaceReflectionAspect() const override { return x14c_faceReflectionAspect; } + float GetMissileWarningPulseTime() const override { return x1a0_missileWarningPulseTime; } + float GetExplosionLightFalloffMultConstant() const override { return x1a4_explosionLightFalloffMultConstant; } + float GetExplosionLightFalloffMultLinear() const override { return x1a8_explosionLightFalloffMultLinear; } + float GetExplosionLightFalloffMultQuadratic() const override { return x1ac_explosionLightFalloffMultQuadratic; } + float GetHudDamagePeakFactor() const override { return x1b4_hudDamagePeakFactor; } + float GetHudDamageFilterGainConstant() const override { return x1b8_hudDamageFilterGainConstant; } + float GetHudDamageFilterGainLinear() const override { return x1bc_hudDamageFilterGainLinear; } + float GetHudDamageFilterInitConstant() const override { return x1c0_hudDamageFilterInitConstant; } + float GetHudDamageFilterInitLinear() const override { return x1c4_hudDamageFilterInitLinear; } + float GetEnergyDrainModPeriod() const override { return x1c8_energyDrainModPeriod; } + bool GetEnergyDrainSinusoidalPulse() const override { return x1cc_energyDrainSinusoidalPulse; } + bool GetEnergyDrainFilterAdditive() const override { return x1cd_energyDrainFilterAdditive; } + float GetHudDamagePulseDuration() const override { return x1d0_hudDamagePulseDuration; } + float GetHudDamageColorGain() const override { return x1d4_hudDamageColorGain; } + float GetHudDecoShakeTranslateGain() const override { return x1d8_hudDecoShakeTranslateGain; } + float GetHudLagOffsetScale() const override { return x1dc_hudLagOffsetScale; } + float GetXrayBlurScaleLinear() const override { return x204_xrayBlurScaleLinear; } + float GetXrayBlurScaleQuadratic() const override { return x208_xrayBlurScaleQuadratic; } + float GetScanSidesAngle() const override { return x210_scanSidesAngle; } + float GetScanSidesXScale() const override { return x214_scanSidesXScale; } + float GetScanSidesPositionEnd() const override { return x218_scanSidesPositionEnd; } + float GetScanSidesDuration() const override { return x220_scanSidesDuration; } + float GetScanSidesStartTime() const override { return x224_scanSidesStartTime; } + float GetScanSidesEndTime() const override { return x228_scanSidesEndTime; } + float GetScanDataDotRadius() const override { return x22c_scanDataDotRadius; } + float GetScanDataDotPosRandMagnitude() const override { return x230_scanDataDotPosRandMag; } + float GetScanDataDotSeekDurationMin() const override { return x234_scanDataDotSeekDurationMin; } + float GetScanDataDotSeekDurationMax() const override { return x238_scanDataDotSeekDurationMax; } + float GetScanDataDotHoldDurationMin() const override { return x23c_scanDataDotHoldDurationMin; } + float GetScanDataDotHoldDurationMax() const override { return x240_scanDataDotHoldDurationMax; } + float GetScanAppearanceDuration() const override { return x244_scanAppearanceDuration; } + float GetScanPaneFlashFactor() const override { return x248_scanPaneFlashFactor; } + float GetScanPaneFadeInTime() const override { return x24c_scanPaneFadeInTime; } + float GetScanPaneFadeOutTime() const override { return x250_scanPaneFadeOutTime; } + float GetBallViewportYReduction() const override { return x254_ballViewportYReduction; } + float GetScanWindowIdleWidth() const override { return x258_scanWindowIdleW; } + float GetScanWindowIdleHeight() const override { return x25c_scanWindowIdleH; } + float GetScanWindowActiveWidth() const override { return x260_scanWindowActiveW; } + float GetScanWindowActiveHeight() const override { return x264_scanWindowActiveH; } + float GetScanWindowMagnification() const override { return x268_scanWindowMagnification; } + float GetScanWindowScanningAspect() const override { return x26c_scanWindowScanningAspect; } + float GetScanSidesPositionStart() const override { return x270_scanSidesPositionStart; } + bool GetShowAutomapperInMorphball() const override { return x274_showAutomapperInMorphball; } + bool GetLatchArticleText() const override { return x275_latchArticleText; } + float GetWorldTransManagerCharsPerSfx() const override { return x278_wtMgrCharsPerSfx; } + uint GetXRayFogMode() const override { return x27c_xrayFogMode; } + float GetXRayFogNearZ() const override { return x280_xrayFogNearZ; } + float GetXRayFogFarZ() const override { return x284_xrayFogFarZ; } + const CColor& GetXRayFogColor() const override { return x288_xrayFogColor; } + float GetThermalVisorLevel() const override { return x28c_thermalVisorLevel; } + const CColor& GetThermalVisorColor() const override { return x290_thermalVisorColor; } + const CColor& GetVisorHudLightAdd(int v) const override { return x294_hudLightAddPerVisor[v]; } + const CColor& GetVisorHudLightMultiply(int v) const override { return x2a4_hudLightMultiplyPerVisor[v]; } + const CColor& GetHudReflectivityLightColor() const override { return x2b4_hudReflectivityLightColor; } + float GetHudLightAttMulConstant() const override { return x2b8_hudLightAttMulConstant; } + float GetHudLightAttMulLinear() const override { return x2bc_hudLightAttMulLinear; } + float GetHudLightAttMulQuadratic() const override { return x2c0_hudLightAttMulQuadratic; } + const rstl::string& GetCreditsTable() const override { return x2d0_creditsTable; } + const rstl::string& GetCreditsFont() const override { return x2e0_creditsFont; } + const rstl::string& GetJapaneseCreditsFont() const override { return x2f0_japaneseCreditsFont; } + const CColor& GetCreditsTextFontColor() const override { return x300_; } + const CColor& GetCreditsTextBorderColor() const override { return x304_; } + +private: + bool x4_; + float x8_mapAlphaInterp; + float xc_pauseBlurFactor; + float x10_radarXYRadius; + float x14_; + float x18_; + float x1c_; + float x20_; + float x24_radarZRadius; + float x28_radarZCloseRadius; + uint x2c_; + float x30_; + float x34_energyBarFilledSpeed; + float x38_energyBarShadowSpeed; + float x3c_energyBarDrainDelay; + bool x40_energyBarAlwaysResetDelay; + float x44_hudDamagePracticalsGainConstant; + float x48_hudDamagePracticalsGainLinear; + float x4c_hudDamagePracticalsInitConstant; + float x50_hudDamagePracticalsInitLinear; + float x54_hudDamageLightSpotAngle; + float x58_damageLightAngleC; + float x5c_damageLightAngleL; + float x60_damageLightAngleQ; + CVector3f x64_damageLightPreTranslate; + CVector3f x70_damageLightCenterTranslate; + float x7c_damageLightXfXAngle; + float x80_damageLightXfZAngle; + float x84_hudDecoShakeTranslateVelConstant; + float x88_hudDecoShakeTranslateVelLinear; + float x8c_maxDecoDamageShakeTranslate; + float x90_decoDamageShakeDeceleration; + float x94_decoShakeGainConstant; + float x98_decoShakeGainLinear; + float x9c_decoShakeInitConstant; + float xa0_decoShakeInitLinear; + float xa4_maxDecoDamageShakeRotate; + uint xa8_hudCamFovTweak; + uint xac_hudCamYTweak; + uint xb0_hudCamZTweak; + float xb4_; + float xb8_; + float xbc_; + float xc0_beamVisorMenuAnimTime; + float xc4_visorBeamMenuItemActiveScale; + float xc8_visorBeamMenuItemInactiveScale; + float xcc_visorBeamMenuItemTranslate; + float xd0_; + uint xd4_; + float xd8_; + float xdc_; + float xe0_; + float xe4_threatRange; + float xe8_radarScopeCoordRadius; + float xec_radarPlayerPaintRadius; + float xf0_radarEnemyPaintRadius; + float xf4_missileArrowVisTime; + EHudVisMode xf8_hudVisMode; + EHelmetVisMode xfc_helmetVisMode; + uint x100_enableAutoMapper; + uint x104_; + uint x108_enableTargetingManager; + uint x10c_enablePlayerVisor; + float x110_threatWarningFraction; + float x114_missileWarningFraction; + float x118_freeLookFadeTime; + float x11c_; + float x120_; + float x124_; + float x128_; + float x12c_freeLookSfxPitchScale; + bool x130_noAbsoluteFreeLookSfxPitch; + float x134_; + float x138_; + uint x13c_faceReflectionOrthoWidth; + uint x140_faceReflectionOrthoHeight; + uint x144_faceReflectionDistance; + uint x148_faceReflectionHeight; + uint x14c_faceReflectionAspect; + rstl::string x150_; + rstl::string x160_; + rstl::string x170_; + rstl::string x180_; + rstl::string x190_; + float x1a0_missileWarningPulseTime; + float x1a4_explosionLightFalloffMultConstant; + float x1a8_explosionLightFalloffMultLinear; + float x1ac_explosionLightFalloffMultQuadratic; + float x1b0_; + float x1b4_hudDamagePeakFactor; + float x1b8_hudDamageFilterGainConstant; + float x1bc_hudDamageFilterGainLinear; + float x1c0_hudDamageFilterInitConstant; + float x1c4_hudDamageFilterInitLinear; + float x1c8_energyDrainModPeriod; + bool x1cc_energyDrainSinusoidalPulse; + bool x1cd_energyDrainFilterAdditive; + float x1d0_hudDamagePulseDuration; + float x1d4_hudDamageColorGain; + float x1d8_hudDecoShakeTranslateGain; + float x1dc_hudLagOffsetScale; + float x1e0_; + float x1e4_; + float x1e8_; + float x1ec_; + float x1f0_; + float x1f4_; + float x1f8_; + float x1fc_; + CColor x200_; + float x204_xrayBlurScaleLinear; + float x208_xrayBlurScaleQuadratic; + float x20c_; + float x210_scanSidesAngle; + float x214_scanSidesXScale; + float x218_scanSidesPositionEnd; + float x21c_; + float x220_scanSidesDuration; + float x224_scanSidesStartTime; + float x228_scanSidesEndTime; + float x22c_scanDataDotRadius; + float x230_scanDataDotPosRandMag; + float x234_scanDataDotSeekDurationMin; + float x238_scanDataDotSeekDurationMax; + float x23c_scanDataDotHoldDurationMin; + float x240_scanDataDotHoldDurationMax; + float x244_scanAppearanceDuration; + float x248_scanPaneFlashFactor; + float x24c_scanPaneFadeInTime; + float x250_scanPaneFadeOutTime; + float x254_ballViewportYReduction; + float x258_scanWindowIdleW; + float x25c_scanWindowIdleH; + float x260_scanWindowActiveW; + float x264_scanWindowActiveH; + float x268_scanWindowMagnification; + float x26c_scanWindowScanningAspect; + float x270_scanSidesPositionStart; + bool x274_showAutomapperInMorphball; + bool x275_latchArticleText; + float x278_wtMgrCharsPerSfx; + uint x27c_xrayFogMode; + float x280_xrayFogNearZ; + float x284_xrayFogFarZ; + CColor x288_xrayFogColor; + float x28c_thermalVisorLevel; + CColor x290_thermalVisorColor; + CColor x294_hudLightAddPerVisor[4]; + CColor x2a4_hudLightMultiplyPerVisor[4]; + CColor x2b4_hudReflectivityLightColor; + float x2b8_hudLightAttMulConstant; + float x2bc_hudLightAttMulLinear; + float x2c0_hudLightAttMulQuadratic; + rstl::reserved_vector< float, 2 > x2c4_scanSpeeds; + rstl::string x2d0_creditsTable; + rstl::string x2e0_creditsFont; + rstl::string x2f0_japaneseCreditsFont; + CColor x300_; + CColor x304_; + float x308_; + float x30c_; + float x310_; + rstl::string x314_; + rstl::string x324_; + rstl::string x334_; + CColor x344_; + CColor x348_; + CColor x34c_; + CColor x350_; + CColor x354_; + CColor x358_; + float x35c_; + float x360_; + float x364_; +}; + +extern CTweakGui* gpTweakGui; + +#endif // _CTWEAKGUI diff --git a/include/MetroidPrime/Tweaks/CTweakGuiColors.hpp b/include/MetroidPrime/Tweaks/CTweakGuiColors.hpp new file mode 100644 index 00000000..225a2c3f --- /dev/null +++ b/include/MetroidPrime/Tweaks/CTweakGuiColors.hpp @@ -0,0 +1,207 @@ +#ifndef _CTWEAKGUICOLORS +#define _CTWEAKGUICOLORS + +#include "MetroidPrime/Tweaks/ITweakObject.hpp" + +#include "Kyoto/Graphics/CColor.hpp" + +class CTweakGuiColors : public ITweakObject { +public: + const CColor& GetPauseBlurFilterColor() const override { return x4_pauseBlurFilterColor; } + const CColor& GetRadarStuffColor() const override { return x8_radarStuffColor; } + const CColor& GetRadarPlayerPaintColor() const override { return xc_radarPlayerPaintColor; } + const CColor& GetRadarEnemyPaintColor() const override { return x10_radarEnemyPaintColor; } + const CColor& GetHudMessageFill() const override { return x14_hudMessageFill; } + const CColor& GetHudMessageOutline() const override { return x18_hudMessageOutline; } + const CColor& GetHudFrameColor() const override { return x1c_hudFrameColor; } + const CColor& GetMissileIconColorActive() const override { return x28_missileIconColorActive; } + const CColor& GetVisorBeamMenuItemActive() const override { return x2c_visorBeamMenuItemActive; } + const CColor& GetVisorBeamMenuItemInactive() const override { return x30_visorBeamMenuColorInactive; } + const CColor& GetEnergyBarFilledLowEnergy() const override { return x34_energyBarFilledLowEnergy; } + const CColor& GetEnergyBarShadowLowEnergy() const override { return x38_energyBarShadowLowEnergy; } + const CColor& GetEnergyBarEmptyLowEnergy() const override { return x3c_energyBarEmptyLowEnergy; } + const CColor& GetHudDamageLightColor() const override { return x40_hudDamageLightColor; } + const CColor& GetVisorMenuTextFont() const override { return x4c_visorMenuTextFont; } + const CColor& GetVisorMenuTextOutline() const override { return x50_visorMenuTextOutline; } + const CColor& GetBeamMenuTextFont() const override { return x54_beamMenuTextFont; } + const CColor& GetBeamMenuTextOutline() const override { return x58_beamMenuTextOutline; } + const CColor& GetEnergyWarningFont() const override { return x5c_energyWarningFont; } + const CColor& GetThreatWarningFont() const override { return x60_threatWarningFont; } + const CColor& GetMissileWarningFont() const override { return x64_missileWarningFont; } + const CColor& GetThreatBarFilled() const override { return x68_threatBarFilled; } + const CColor& GetThreatBarShadow() const override { return x6c_threatBarShadow; } + const CColor& GetThreatBarEmpty() const override { return x70_threatBarEmpty; } + const CColor& GetMissileBarFilled() const override { return x74_missileBarFilled; } + const CColor& GetMissileBarShadow() const override { return x78_missileBarShadow; } + const CColor& GetMissileBarEmpty() const override { return x7c_missileBarEmpty; } + const CColor& GetThreatIconColor() const override { return x80_threatIconColor; } + const CColor& GetTickDecoColor() const override { return x88_tickDecoColor; } + const CColor& GetHelmetLightColor() const override { return x8c_helmetLightColor; } + const CColor& GetThreatIconSafeColor() const override { return x90_threatIconSafeColor; } + const CColor& GetMissileIconColorInactive() const override { return x94_missileIconColorInactive; } + const CColor& GetMissileIconColorChargedCanAlt() const override { return x98_missileIconColorChargedCanAlt; } + const CColor& GetMissileIconColorChargedNoAlt() const override { return x9c_missileIconColorChargedNoAlt; } + const CColor& GetMissileIconColorDepleteAlt() const override { return xa0_missileIconColorDepleteAlt; } + const CColor& GetVisorBeamMenuLozColor() const override { return xb0_visorBeamMenuLozColor; } + const CColor& GetEnergyWarningOutline() const override { return xb4_energyWarningOutline; } + const CColor& GetThreatWarningOutline() const override { return xb8_threatWarningOutline; } + const CColor& GetMissileWarningOutline() const override { return xbc_missileWarningOutline; } + const CColor& GetDamageAmbientColor() const override { return xc4_damageAmbientColor; } + const CColor& GetScanFrameInactiveColor() const override { return xc8_scanFrameInactiveColor; } + const CColor& GetScanFrameActiveColor() const override { return xcc_scanFrameActiveColor; } + const CColor& GetScanFrameImpulseColor() const override { return xd0_scanFrameImpulseColor; } + const CColor& GetScanVisorHudLightMultiply() const override { return xd4_scanVisorHudLightMultiply; } + const CColor& GetScanVisorScreenDimColor() const override { return xd8_scanVisorScreenDimColor; } + const CColor& GetThermalVisorHudLightMultiply() const override { return xdc_thermalVisorHudLightMultiply; } + const CColor& GetEnergyDrainFilterColor() const override { return xe0_energyDrainFilterColor; } + const CColor& GetDamageAmbientPulseColor() const override { return xe4_damageAmbientPulseColor; } + const CColor& GetEnergyBarFlashColor() const override { return xe8_energyBarFlashColor; } + const CColor& GetXRayEnergyDecoColor() const override { return x100_xrayEnergyDecoColor; } + const CColor& GetScanDataDotColor() const override { return x138_scanDataDotColor; } + const CColor& GetPowerBombDigitAvailableFont() const override { return x13c_powerBombDigitAvailableFont; } + const CColor& GetPowerBombDigitAvailableOutline() const override { return x140_powerBombDigitAvailableOutline; } + const CColor& GetBallBombFilledColor() const override { return x148_ballBombFilled; } + const CColor& GetBallBombEmptyColor() const override { return x14c_ballBombEmpty; } + const CColor& GetPowerBombIconAvailableColor() const override { return x150_powerBombIconAvailable; } + const CColor& GetBallBombEnergyColor() const override { return x158_ballEnergyDeco; } + const CColor& GetBallBombDecoColor() const override { return x15c_ballBombDeco; } + const CColor& GetPowerBombDigitDelpetedFont() const override { return x160_powerBombDigitDepletedFont; } + const CColor& GetPowerBombDigitDelpetedOutline() const override { return x164_powerBombDigitDepletedOutline; } + const CColor& GetPowerBombIconDepletedColor() const override { return x168_powerBombIconUnavailable; } + const CColor& GetScanDisplayImagePaneColor() const override { return x174_scanDisplayImagePaneColor; } + const CColor& GetThreatIconWarningColor() const override { return x17c_threatIconWarningColor; } + const CColor& GetHudCounterFill() const override { return x180_hudCounterFill; } + const CColor& GetHudCounterOutline() const override { return x184_hudCounterOutline; } + const CColor& GetScanIconCriticalColor() const override { return x188_scanIconCriticalColor; } + const CColor& GetScanIconCriticalDimColor() const override { return x18c_scanIconCriticalDimColor; } + const CColor& GetScanIconNoncriticalColor() const override { return x190_scanIconNoncriticalColor; } + const CColor& GetScanIconNoncriticalDimColor() const override { return x194_scanIconNoncriticalDimColor; } + const CColor& GetScanReticuleColor() const override { return x198_scanReticuleColor; } + const CColor& GetThreatDigitsFont() const override { return x19c_threatDigitsFont; } + const CColor& GetThreatDigitsOutline() const override { return x1a0_threatDigitsOutline; } + const CColor& GetMissileDigitsFont() const override { return x1a4_missileDigitsFont; } + const CColor& GetMissileDigitsOutline() const override { return x1a8_missileDigitsOutline; } + const CColor& GetThermalDecoColor() const override { return x1ac_thermalDecoColor; } + const CColor& GetThermalOutlinesColor() const override { return x1b0_thermalOutlinesColor; } + const CColor& GetThermalLockColor() const override { return x1b8_thermalLockColor; } + const CColor& GetPauseItemAmberColor() const override { return x1bc_pauseItemAmber; } + const CColor& GetPauseItemBlueColor() const override { return x1c0_pauseItemBlue; } + +private: + CColor x4_pauseBlurFilterColor; + CColor x8_radarStuffColor; + CColor xc_radarPlayerPaintColor; + CColor x10_radarEnemyPaintColor; + CColor x14_hudMessageFill; + CColor x18_hudMessageOutline; + CColor x1c_hudFrameColor; + CColor x20_; + CColor x24_; + CColor x28_missileIconColorActive; + CColor x2c_visorBeamMenuItemActive; + CColor x30_visorBeamMenuColorInactive; + CColor x34_energyBarFilledLowEnergy; + CColor x38_energyBarShadowLowEnergy; + CColor x3c_energyBarEmptyLowEnergy; + CColor x40_hudDamageLightColor; + CColor x44_; + CColor x48_; + CColor x4c_visorMenuTextFont; + CColor x50_visorMenuTextOutline; + CColor x54_beamMenuTextFont; + CColor x58_beamMenuTextOutline; + CColor x5c_energyWarningFont; + CColor x60_threatWarningFont; + CColor x64_missileWarningFont; + CColor x68_threatBarFilled; + CColor x6c_threatBarShadow; + CColor x70_threatBarEmpty; + CColor x74_missileBarFilled; + CColor x78_missileBarShadow; + CColor x7c_missileBarEmpty; + CColor x80_threatIconColor; + CColor x84_; + CColor x88_tickDecoColor; + CColor x8c_helmetLightColor; + CColor x90_threatIconSafeColor; + CColor x94_missileIconColorInactive; + CColor x98_missileIconColorChargedCanAlt; + CColor x9c_missileIconColorChargedNoAlt; + CColor xa0_missileIconColorDepleteAlt; + CColor xa4_; + CColor xa8_; + CColor xac_; + CColor xb0_visorBeamMenuLozColor; + CColor xb4_energyWarningOutline; + CColor xb8_threatWarningOutline; + CColor xbc_missileWarningOutline; + CColor xc0_; + CColor xc4_damageAmbientColor; + CColor xc8_scanFrameInactiveColor; + CColor xcc_scanFrameActiveColor; + CColor xd0_scanFrameImpulseColor; + CColor xd4_scanVisorHudLightMultiply; + CColor xd8_scanVisorScreenDimColor; + CColor xdc_thermalVisorHudLightMultiply; + CColor xe0_energyDrainFilterColor; + CColor xe4_damageAmbientPulseColor; + CColor xe8_energyBarFlashColor; + CColor xec_; + CColor xf0_; + CColor xf4_; + CColor xf8_; + CColor xfc_; + CColor x100_xrayEnergyDecoColor; + CColor x104_; + CColor x108_; + CColor x10c_; + CColor x110_; + CColor x114_; + CColor x118_; + CColor x11c_; + CColor x120_; + CColor x124_; + CColor x128_; + CColor x12c_; + CColor x130_; + CColor x134_; + CColor x138_scanDataDotColor; + CColor x13c_powerBombDigitAvailableFont; + CColor x140_powerBombDigitAvailableOutline; + CColor x144_; + CColor x148_ballBombFilled; + CColor x14c_ballBombEmpty; + CColor x150_powerBombIconAvailable; + CColor x154_; + CColor x158_ballEnergyDeco; + CColor x15c_ballBombDeco; + CColor x160_powerBombDigitDepletedFont; + CColor x164_powerBombDigitDepletedOutline; + CColor x168_powerBombIconUnavailable; + CColor x16c_; + CColor x170_; + CColor x174_scanDisplayImagePaneColor; + CColor x178_; + CColor x17c_threatIconWarningColor; + CColor x180_hudCounterFill; + CColor x184_hudCounterOutline; + CColor x188_scanIconCriticalColor; + CColor x18c_scanIconCriticalDimColor; + CColor x190_scanIconNoncriticalColor; + CColor x194_scanIconNoncriticalDimColor; + CColor x198_scanReticuleColor; + CColor x19c_threatDigitsFont; + CColor x1a0_threatDigitsOutline; + CColor x1a4_missileDigitsFont; + CColor x1a8_missileDigitsOutline; + CColor x1ac_thermalDecoColor; + CColor x1b0_thermalOutlinesColor; + CColor x1b4_; + CColor x1b8_thermalLockColor; + CColor x1bc_pauseItemAmber; + CColor x1c0_pauseItemBlue; +}; + +extern CTweakGuiColors* gpTweakGuiColors; + +#endif // _CTWEAKGUICOLORS diff --git a/src/MetroidPrime/HUD/CHudBallInterface.cpp b/src/MetroidPrime/HUD/CHudBallInterface.cpp new file mode 100644 index 00000000..3299542e --- /dev/null +++ b/src/MetroidPrime/HUD/CHudBallInterface.cpp @@ -0,0 +1,135 @@ +#include "MetroidPrime/HUD/CHudBallInterface.hpp" + +#include "MetroidPrime/Tweaks/CTweakGui.hpp" +#include "MetroidPrime/Tweaks/CTweakGuiColors.hpp" + +#include "GuiSys/CGuiCamera.hpp" +#include "GuiSys/CGuiFrame.hpp" +#include "GuiSys/CGuiGroup.hpp" +#include "GuiSys/CGuiModel.hpp" +#include "GuiSys/CGuiTextPane.hpp" +#include "Kyoto/Basics/CBasics.hpp" + +#include "rstl/string.hpp" +#include + +CHudBallInterface::CHudBallInterface(CGuiFrame& selHud, int pbAmount, int pbCapacity, + int availableBombs, bool hasBombs, bool hasPb) +: x34_camPos(CVector3f::Zero()) +, x40_pbAmount(pbAmount) +, x44_pbCapacity(pbCapacity) +, x48_availableBombs(availableBombs) +, x4c_hasPb(hasPb) { + x0_camera = selHud.GetFrameCamera(); + + const char* basewidget_bombstuff = "basewidget_bombstuff"; + const char* basewidget_bombdeco = "basewidget_bombdeco"; + const char* model_bombicon = "model_bombicon"; + const char* textpane_bombdigits = "textpane_bombdigits"; + const char* basewidget_energydeco = "basewidget_energydeco"; + + x4_basewidget_bombstuff = selHud.FindWidget(basewidget_bombstuff); + x8_basewidget_bombdeco = selHud.FindWidget(basewidget_bombdeco); + xc_model_bombicon = static_cast< CGuiModel* >(selHud.FindWidget(model_bombicon)); + x10_textpane_bombdigits = static_cast< CGuiTextPane* >(selHud.FindWidget(textpane_bombdigits)); + + for (int i = 0; i < 3; ++i) { + rstl::string groupName(CBasics::Stringize("%s%d", "group_bombcount", i)); + CGuiGroup* grp = static_cast< CGuiGroup* >(selHud.FindWidget(groupName)); + CGuiWidget* filled = grp->GetWorkerWidget(1); + CGuiWidget* empty = grp->GetWorkerWidget(0); + x14_group_bombfilled.push_back(filled); + x24_group_bombempty.push_back(empty); + if (filled) + filled->SetColor(gpTweakGuiColors->GetBallBombFilledColor()); + if (empty) + empty->SetColor(gpTweakGuiColors->GetBallBombEmptyColor()); + } + + x8_basewidget_bombdeco->SetColor(gpTweakGuiColors->GetBallBombDecoColor()); + x34_camPos = x0_camera->GetLocalPosition(); + + if (CGuiWidget* w = selHud.FindWidget(rstl::string_l(basewidget_energydeco))) { + w->SetColor(gpTweakGuiColors->GetBallBombEnergyColor()); + } + SetBombParams(pbAmount, pbCapacity, availableBombs, hasBombs, hasPb, true); +} + +void CHudBallInterface::SetBombParams(int pbAmount, int pbCapacity, int availableBombs, + bool hasBombs, bool hasPb, bool init) { + + if (pbAmount != x40_pbAmount || init) { + char buffer[4]; + sprintf(buffer, "%02d", pbAmount); + x10_textpane_bombdigits->TextSupport().SetText(rstl::string(buffer)); + x40_pbAmount = pbAmount; + UpdatePowerBombReadoutColors(); + } + + if (pbCapacity != x44_pbCapacity || init) { + x44_pbCapacity = pbCapacity; + UpdatePowerBombReadoutColors(); + } + + if (hasPb != x4c_hasPb) { + x4c_hasPb = hasPb; + UpdatePowerBombReadoutColors(); + } + + for (int i = 0; i < 3; ++i) { + bool lit = i < availableBombs; + x14_group_bombfilled[i]->SetVisibility(lit && hasBombs, kTM_Children); + x24_group_bombempty[i]->SetVisibility(!lit && hasBombs, kTM_Children); + } + + x48_availableBombs = availableBombs; + + x8_basewidget_bombdeco->SetVisibility(hasBombs && x44_pbCapacity > 0, kTM_Children); +} + +void CHudBallInterface::SetBallModeFactor(float t) { + float tmp = gpTweakGui->GetBallViewportYReduction() * 448.0f * 0.5f; + x0_camera->SetLocalTransform(CTransform4f::Translate(CVector3f( + x34_camPos.GetX(), x34_camPos.GetY(), x34_camPos.GetZ() + (t * tmp - tmp) * 0.01f))); +} + +void CHudBallInterface::UpdatePowerBombReadoutColors() { + CColor clear(0); + + bool hasPbsAmount = x40_pbAmount > 0; + bool hasPbsCapacity = x44_pbCapacity > 0; + + const CColor* fontColor = nullptr; + if (hasPbsAmount) { + fontColor = &gpTweakGuiColors->GetPowerBombDigitAvailableFont(); + } else if (hasPbsCapacity) { + fontColor = &gpTweakGuiColors->GetPowerBombDigitDelpetedFont(); + } else { + fontColor = &clear; + } + x10_textpane_bombdigits->TextSupport().SetFontColor(*fontColor); + + const CColor* outlineColor = nullptr; + if (hasPbsAmount) { + outlineColor = &gpTweakGuiColors->GetPowerBombDigitAvailableOutline(); + } else if (hasPbsCapacity) { + outlineColor = &gpTweakGuiColors->GetPowerBombDigitDelpetedOutline(); + } else { + outlineColor = &clear; + } + x10_textpane_bombdigits->TextSupport().SetOutlineColor(*outlineColor); + + const CColor* iconColor = nullptr; + bool hasLastDisplay = false; + if (hasPbsAmount && x4c_hasPb) + hasLastDisplay = true; + + if (hasLastDisplay) + iconColor = &gpTweakGuiColors->GetPowerBombIconAvailableColor(); + else if (hasPbsCapacity) + iconColor = &gpTweakGuiColors->GetPowerBombIconDepletedColor(); + else + iconColor = &clear; + + xc_model_bombicon->SetColor(*iconColor); +}