mirror of
https://github.com/AxioDL/metaforce.git
synced 2025-05-14 13:11:21 +00:00
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.
152 lines
4.9 KiB
C++
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
|