2
0
mirror of https://github.com/AxioDL/metaforce.git synced 2025-05-14 13:11:21 +00:00
metaforce/Runtime/GuiSys/CAuiEnergyBarT01.cpp
Lioncash 40fc3f9dd8 CModelBoo: Remove usages of const_cast
Many functions are modifying internals of CBooModel and const-casting
is performed in order to work around functions being const when they
really shouldn't be.

This amends the function signatures in order to allow these functions to
exist without const_cast, making code much nicer to read.
2020-03-25 02:01:46 -04:00

152 lines
4.9 KiB
C++

#include "Runtime/GuiSys/CAuiEnergyBarT01.hpp"
#include "Runtime/CSimplePool.hpp"
#include "Runtime/GuiSys/CGuiSys.hpp"
#include "Runtime/GuiSys/CGuiWidgetDrawParms.hpp"
namespace urde {
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<zeus::CVector3f, zeus::CVector3f> 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("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<CEnergyBarShader::Vertex>& 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<zeus::CVector3f, zeus::CVector3f> 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<CGuiWidget> CAuiEnergyBarT01::Create(CGuiFrame* frame, CInputStream& in, CSimplePool* sp) {
CGuiWidgetParms parms = ReadWidgetHeader(frame, in);
CAssetId tex = in.readUint32Big();
std::shared_ptr<CGuiWidget> ret = std::make_shared<CAuiEnergyBarT01>(parms, sp, tex);
ret->ParseBaseInfo(frame, in, parms);
return ret;
}
} // namespace urde