diff --git a/config/GM8E01_00/symbols.txt b/config/GM8E01_00/symbols.txt index 5fc682af..c8908a28 100644 --- a/config/GM8E01_00/symbols.txt +++ b/config/GM8E01_00/symbols.txt @@ -12287,7 +12287,7 @@ Update__16CAuiEnergyBarT01Ff = .text:0x802CB664; // type:function size:0x264 sco SetCurrEnergy__16CAuiEnergyBarT01Ffb = .text:0x802CB8C8; // type:function size:0xA0 scope:global SetMaxEnergy__16CAuiEnergyBarT01Ff = .text:0x802CB968; // type:function size:0x74 scope:global __dt__16CAuiEnergyBarT01Fv = .text:0x802CB9DC; // type:function size:0x98 scope:global -__ct__16CAuiEnergyBarT01FRCQ210CGuiWidget15CGuiWidgetParmsUi = .text:0x802CBA74; // type:function size:0x184 scope:global +__ct__16CAuiEnergyBarT01FRCQ210CGuiWidget15CGuiWidgetParmsP12IObjectStoreUi = .text:0x802CBA74; // type:function size:0x184 scope:global Create__16CAuiEnergyBarT01FP9CGuiFrameR12CInputStreamb = .text:0x802CBBF8; // type:function size:0xF0 scope:global __dt__13CAuiImagePaneFv = .text:0x802CBCE8; // type:function size:0x150 scope:global GetWidgetTypeID__13CAuiImagePaneCFv = .text:0x802CBE38; // type:function size:0xC scope:global diff --git a/config/GM8E01_01/symbols.txt b/config/GM8E01_01/symbols.txt index 9baf6bad..ca24ac76 100644 --- a/config/GM8E01_01/symbols.txt +++ b/config/GM8E01_01/symbols.txt @@ -12287,7 +12287,7 @@ Update__16CAuiEnergyBarT01Ff = .text:0x802CB710; // type:function size:0x264 sco SetCurrEnergy__16CAuiEnergyBarT01Ffb = .text:0x802CB974; // type:function size:0xA0 scope:global SetMaxEnergy__16CAuiEnergyBarT01Ff = .text:0x802CBA14; // type:function size:0x74 scope:global __dt__16CAuiEnergyBarT01Fv = .text:0x802CBA88; // type:function size:0x98 scope:global -__ct__16CAuiEnergyBarT01FRCQ210CGuiWidget15CGuiWidgetParmsUi = .text:0x802CBB20; // type:function size:0x184 scope:global +__ct__16CAuiEnergyBarT01FRCQ210CGuiWidget15CGuiWidgetParmsP12IObjectStoreUi = .text:0x802CBB20; // type:function size:0x184 scope:global Create__16CAuiEnergyBarT01FP9CGuiFrameR12CInputStreamb = .text:0x802CBCA4; // type:function size:0xF0 scope:global __dt__13CAuiImagePaneFv = .text:0x802CBD94; // type:function size:0x150 scope:global GetWidgetTypeID__13CAuiImagePaneCFv = .text:0x802CBEE4; // type:function size:0xC scope:global diff --git a/configure.py b/configure.py index 9b0da49f..60d406cb 100755 --- a/configure.py +++ b/configure.py @@ -1160,8 +1160,8 @@ config.libs = [ { "lib": "mtx", "mw_version": "GC/1.2.5n", - #"cflags": ["-nodefaults","-proc gekko","-align powerpc","-fp hardware","-g","-sym on","-maxerrors 1","-nosyspath","-i include","-i libc", "-D_DEBUG=1", "-inline off", "-Cpp_exceptions off"], - "cflags": [*cflags_base, "-fp_contract off"], + "cflags": ["-nodefaults","-proc gekko","-align powerpc","-fp hardware","-g","-sym on","-maxerrors 1","-nosyspath","-i include","-i libc", "-D_DEBUG=1", "-inline off", "-Cpp_exceptions off"], + #"cflags": [*cflags_base, "-fp_contract off"], "host": False, "progress_category": "sdk", "shift_jis": True, diff --git a/include/GuiSys/CAuiEnergyBarT01.hpp b/include/GuiSys/CAuiEnergyBarT01.hpp new file mode 100644 index 00000000..ed1ea333 --- /dev/null +++ b/include/GuiSys/CAuiEnergyBarT01.hpp @@ -0,0 +1,55 @@ +#ifndef _CAUIENERGYBART01 +#define _CAUIENERGYBART01 + +#include "GuiSys/CGuiWidget.hpp" +#include "Kyoto/SObjectTag.hpp" + +#include +#include +#include + +class IObjectStore; +class CAuiEnergyBarT01 : public CGuiWidget { +public: + enum ESetMode { + kSM_Normal, + kSM_Wrapped, + kSM_Instant, + }; + + typedef rstl::pair< CVector3f, CVector3f > (*FCoordFunc)(float t); + + static CAuiEnergyBarT01* Create(CGuiFrame* frame, CInputStream& in, IObjectStore* sp); + CAuiEnergyBarT01(const CGuiWidgetParms& parms, IObjectStore* sp, CAssetId textureId); + + void SetMaxEnergy(float maxEnergy); + void SetCurrEnergy(float energy, ESetMode mode); + void Update(float dt) override; + void Draw(const CGuiWidgetDrawParms& parms) const override; + + float GetActualFraction() const; + FourCC GetWidgetTypeID() const override; + +private: + static rstl::pair< CVector3f, CVector3f > DownloadBarCoordFunc(float t); + + CAssetId mTextureId; // 0xb8 + rstl::optional_object< TCachedToken< CTexture > > mTexture; // 0xbc + CColor mEmptyColor; // 0xcc + CColor mFilledColor; // 0xd0 + CColor mShadowColor; // 0xd4 + FCoordFunc mCoordFunc; // 0xd8 + float mTesselation; // 0xdc + float mMaxEnergy; // 0xe0 + float mFilledSpeed; // 0xe4 + float mShadowSpeed; // 0xe8 + float mShadowDrainDelay; // 0xec + bool mAlwaysResetDelayTimer; // 0xf0 + bool mWrapping; // 0xf1 + float mSetEnergy; // 0xf4 + float mFilledEnergy; // 0xf8 + float mShadowEnergy; // 0xfc + float mShadowDrainDelayTimer; // 0x100 +}; + +#endif // _CAUIENERGYBART01 diff --git a/include/GuiSys/CGuiSys.hpp b/include/GuiSys/CGuiSys.hpp index 02012aa2..175f7598 100644 --- a/include/GuiSys/CGuiSys.hpp +++ b/include/GuiSys/CGuiSys.hpp @@ -33,10 +33,14 @@ public: gGuiSystem = ptr; spGuiSys = ptr; } + + static CGuiSys* GetGlobalGuiSys() { return spGuiSys; } static CGuiWidget* CreateWidgetInGame(uint type, CInputStream& in, CGuiFrame* parent); void AddFactories(EUsageMode mode); + EUsageMode GetUsageMode() const { return x8_mode; } + private: IFactory* x0_resFactory; CSimplePool* x4_resStore; diff --git a/src/Dolphin/mtx/mtx44vec.c b/src/Dolphin/mtx/mtx44vec.c index 94110cfa..0d52f294 100644 --- a/src/Dolphin/mtx/mtx44vec.c +++ b/src/Dolphin/mtx/mtx44vec.c @@ -1 +1,3 @@ #include "dolphin/mtx.h" + +void C_MTX44MultVec(const Mtx44 m, const Vec* src, Vec* dst) {} diff --git a/src/GuiSys/CAuiEnergyBarT01.cpp b/src/GuiSys/CAuiEnergyBarT01.cpp new file mode 100644 index 00000000..79f94c70 --- /dev/null +++ b/src/GuiSys/CAuiEnergyBarT01.cpp @@ -0,0 +1,146 @@ +#include "GuiSys/CAuiEnergyBarT01.hpp" +#include "GuiSys/CGuiSys.hpp" +#include "GuiSys/CGuiWidget.hpp" +#include "Kyoto/Graphics/CGraphics.hpp" +#include "Kyoto/IObjectStore.hpp" +#include "Kyoto/SObjectTag.hpp" +#include "Kyoto/Streams/CInputStream.hpp" +#include "rstl/math.hpp" +#include "rstl/pair.hpp" + +static const char* UnusedString = "TextureId"; +CAuiEnergyBarT01* CAuiEnergyBarT01::Create(CGuiFrame* frame, CInputStream& in, IObjectStore* sp) { + CGuiWidgetParms parms = ReadWidgetHeader(frame, in); + CAssetId tex = in.Get< CAssetId >(); + + CAuiEnergyBarT01* ret = rs_new CAuiEnergyBarT01(parms, sp, tex); + ret->ParseBaseInfo(frame, in, parms); + return ret; +} + +CAuiEnergyBarT01::CAuiEnergyBarT01(const CGuiWidgetParms& parms, IObjectStore* sp, + CAssetId textureId) +: CGuiWidget(parms) +, mTextureId(textureId) +, mEmptyColor(CColor::White()) +, mFilledColor(CColor::White()) +, mShadowColor(CColor::White()) +, mCoordFunc(nullptr) +, mTesselation(1.f) +, mMaxEnergy(0.f) +, mFilledSpeed(1000.f) +, mShadowSpeed(1000.f) +, mShadowDrainDelay(0.f) +, mAlwaysResetDelayTimer(false) +, mWrapping(false) +, mSetEnergy(0.f) +, mFilledEnergy(0.f) +, mShadowEnergy(0.f) +, mShadowDrainDelayTimer(0.f) { + if (CGuiSys::GetGlobalGuiSys()->GetUsageMode() != CGuiSys::kUM_Two) { + mTexture = sp->GetObj(SObjectTag('TXTR', mTextureId)); + mTexture->Lock(); + } +} + +void CAuiEnergyBarT01::SetMaxEnergy(const float maxEnergy) { + mMaxEnergy = maxEnergy; + mSetEnergy = rstl::min_val(mSetEnergy, mMaxEnergy); + mFilledEnergy = rstl::min_val(mFilledEnergy, mMaxEnergy); + mShadowEnergy = rstl::min_val(mShadowEnergy, mMaxEnergy); +} + +void CAuiEnergyBarT01::SetCurrEnergy(const float energy, const ESetMode mode) { + float e = CMath::Clamp(0.f, energy, mMaxEnergy); + + if (e == mSetEnergy) { + return; + } + + if (mAlwaysResetDelayTimer || mFilledEnergy == mShadowEnergy) { + mShadowDrainDelayTimer = mShadowDrainDelay; + } + + mWrapping = mode == kSM_Wrapped; + mSetEnergy = e; + if (mode == kSM_Instant) { + mFilledEnergy = mSetEnergy; + } +} + +void CAuiEnergyBarT01::Update(const float dt) { + + if (mShadowDrainDelayTimer > 0.f) { + mShadowDrainDelayTimer = rstl::max_val(mShadowDrainDelayTimer - dt, 0.f); + } + + if (mFilledEnergy < mSetEnergy) { + if (mWrapping) { + mFilledEnergy -= dt * mFilledSpeed; + if (mFilledEnergy < 0.f) { + mFilledEnergy = rstl::max_val(mSetEnergy, mFilledEnergy + mMaxEnergy); + mWrapping = false; + mShadowEnergy = mMaxEnergy; + } + } else { + mFilledEnergy = rstl::min_val(mSetEnergy, mFilledEnergy + dt * mFilledSpeed); + } + } else if (mFilledEnergy > mSetEnergy) { + if (mWrapping) { + mFilledEnergy += dt * mFilledSpeed; + if (mFilledEnergy > mMaxEnergy) { + mFilledEnergy = rstl::min_val(mSetEnergy, mFilledEnergy - mMaxEnergy); + mWrapping = false; + mShadowEnergy = mFilledEnergy; + } + } else { + mFilledEnergy = rstl::max_val(mSetEnergy, mFilledEnergy - dt * mFilledSpeed); + } + } + + if (mShadowEnergy < mFilledEnergy) { + mShadowEnergy = mFilledEnergy; + } else if (mShadowEnergy > mFilledEnergy && mShadowDrainDelayTimer == 0.f) { + mShadowEnergy = rstl::max_val(mFilledEnergy, mShadowEnergy - dt * mShadowSpeed); + } + + if (mTexture) { + mTexture->TryCache(); + } + CGuiWidget::Update(dt); +} + +rstl::pair< CVector3f, CVector3f > CAuiEnergyBarT01::DownloadBarCoordFunc(float t) { + const float x = 12.5f * t - 6.25f; + + return rstl::pair< CVector3f, CVector3f >(CVector3f(x, 0.f, -0.2f), CVector3f(x, 0.f, 0.2f)); +} + +void CAuiEnergyBarT01::Draw(const CGuiWidgetDrawParms& parms) const { + CGraphics::SetModelMatrix(GetWorldTransform()); + if (!mTexture) { + return; + } + + if (!mTexture->IsLoaded() || mCoordFunc == nullptr) { + return; + } + CTexture* tex = mTexture->GetObject(); + if (!tex) { + return; + } + + CGraphics::SetDepthWriteMode(true, kE_LEqual, false); + + CGraphics::SetAmbientColor(CColor::White()); + CGraphics::SetBlendMode(kBM_Blend, kBF_SrcAlpha, kBF_One, kLO_Clear); + + CGraphics::SetDepthWriteMode(true, kE_LEqual, true); +} + +float CAuiEnergyBarT01::GetActualFraction() const { + + return mMaxEnergy == 0.f ? 0.f : mSetEnergy / mMaxEnergy; +} + +FourCC CAuiEnergyBarT01::GetWidgetTypeID() const { return 'ENRG'; }