#include "Runtime/GuiSys/CAuiEnergyBarT01.hpp" #include "Runtime/CSimplePool.hpp" #include "Runtime/GuiSys/CGuiSys.hpp" #include "Runtime/GuiSys/CGuiWidgetDrawParms.hpp" namespace metaforce { CAuiEnergyBarT01::CAuiEnergyBarT01(const CGuiWidgetParms& parms, CSimplePool* sp, CAssetId txtrId) : CGuiWidget(parms), xb8_txtrId(txtrId) { if (g_GuiSys->GetUsageMode() != CGuiSys::EUsageMode::Two) xbc_tex = sp->GetObj(SObjectTag{FOURCC('TXTR'), xb8_txtrId}); } std::pair CAuiEnergyBarT01::DownloadBarCoordFunc(float t) { const float x = 12.5f * t - 6.25f; return {zeus::CVector3f{x, 0.f, -0.2f}, zeus::CVector3f{x, 0.f, 0.2f}}; } void CAuiEnergyBarT01::Update(float dt) { if (x100_shadowDrainDelayTimer > 0.f) x100_shadowDrainDelayTimer = std::max(x100_shadowDrainDelayTimer - dt, 0.f); if (xf8_filledEnergy < xf4_setEnergy) { if (xf1_wrapping) { xf8_filledEnergy -= dt * xe4_filledSpeed; if (xf8_filledEnergy < 0.f) { xf8_filledEnergy = std::max(xf4_setEnergy, xf8_filledEnergy + xe0_maxEnergy); xf1_wrapping = false; xfc_shadowEnergy = xe0_maxEnergy; } } else { xf8_filledEnergy = std::min(xf4_setEnergy, xf8_filledEnergy + dt * xe4_filledSpeed); } } else if (xf8_filledEnergy > xf4_setEnergy) { if (xf1_wrapping) { xf8_filledEnergy += dt * xe4_filledSpeed; if (xf8_filledEnergy > xe0_maxEnergy) { xf8_filledEnergy = std::min(xf4_setEnergy, xf8_filledEnergy - xe0_maxEnergy); xf1_wrapping = false; xfc_shadowEnergy = xf8_filledEnergy; } } else { xf8_filledEnergy = std::max(xf4_setEnergy, xf8_filledEnergy - dt * xe4_filledSpeed); } } if (xfc_shadowEnergy < xf8_filledEnergy) xfc_shadowEnergy = xf8_filledEnergy; else if (xfc_shadowEnergy > xf8_filledEnergy && x100_shadowDrainDelayTimer == 0.f) xfc_shadowEnergy = std::max(xf8_filledEnergy, xfc_shadowEnergy - dt * xe8_shadowSpeed); CGuiWidget::Update(dt); } void CAuiEnergyBarT01::Draw(const CGuiWidgetDrawParms& drawParms) { if (!xbc_tex || !xbc_tex.IsLoaded() || !xd8_coordFunc) { return; } SCOPED_GRAPHICS_DEBUG_GROUP(fmt::format(FMT_STRING("CAuiEnergyBarT01::Draw {}"), m_name).c_str(), zeus::skCyan); CGraphics::SetModelMatrix(x34_worldXF); m_energyBarShader.updateModelMatrix(); const float filledT = xe0_maxEnergy > 0.f ? xf8_filledEnergy / xe0_maxEnergy : 0.f; const float shadowT = xe0_maxEnergy > 0.f ? xfc_shadowEnergy / xe0_maxEnergy : 0.f; zeus::CColor filledColor = xd0_filledColor; filledColor.a() *= drawParms.x0_alphaMod; filledColor *= xa8_color2; zeus::CColor shadowColor = xd4_shadowColor; shadowColor.a() *= drawParms.x0_alphaMod; shadowColor *= xa8_color2; zeus::CColor emptyColor = xcc_emptyColor; emptyColor.a() *= drawParms.x0_alphaMod; emptyColor *= xa8_color2; for (size_t i = 0; i < m_verts.size(); ++i) { std::vector& verts = m_verts[i]; verts.clear(); float start; float end; switch (i) { case 0: default: start = 0.f; end = filledT; break; case 1: start = filledT; end = shadowT; break; case 2: start = shadowT; end = 1.f; break; } if (start == end) { continue; } std::pair coords = xd8_coordFunc(start); while (start < end) { verts.push_back({coords.first, zeus::CVector2f(start, 0.f)}); verts.push_back({coords.second, zeus::CVector2f(start, 1.f)}); start += xdc_tesselation; if (start >= end) { coords = xd8_coordFunc(end); verts.push_back({coords.first, zeus::CVector2f(end, 0.f)}); verts.push_back({coords.second, zeus::CVector2f(end, 1.f)}); } else { coords = xd8_coordFunc(start); } } } m_energyBarShader.draw(filledColor, m_verts[0], shadowColor, m_verts[1], emptyColor, m_verts[2], xbc_tex.GetObj()); } void CAuiEnergyBarT01::SetCurrEnergy(float e, ESetMode mode) { e = zeus::clamp(0.f, e, xe0_maxEnergy); if (e == xf4_setEnergy) return; if (xf0_alwaysResetDelayTimer || xf8_filledEnergy == xfc_shadowEnergy) x100_shadowDrainDelayTimer = xec_shadowDrainDelay; xf1_wrapping = mode == ESetMode::Wrapped; xf4_setEnergy = e; if (mode == ESetMode::Insta) xf8_filledEnergy = xf4_setEnergy; } void CAuiEnergyBarT01::SetMaxEnergy(float maxEnergy) { xe0_maxEnergy = maxEnergy; xf4_setEnergy = std::min(xe0_maxEnergy, xf4_setEnergy); xf8_filledEnergy = std::min(xe0_maxEnergy, xf8_filledEnergy); xfc_shadowEnergy = std::min(xe0_maxEnergy, xfc_shadowEnergy); } std::shared_ptr CAuiEnergyBarT01::Create(CGuiFrame* frame, CInputStream& in, CSimplePool* sp) { CGuiWidgetParms parms = ReadWidgetHeader(frame, in); CAssetId tex = in.Get(); std::shared_ptr ret = std::make_shared(parms, sp, tex); ret->ParseBaseInfo(frame, in, parms); return ret; } } // namespace metaforce