mirror of https://github.com/PrimeDecomp/prime.git
201 lines
7.1 KiB
C++
201 lines
7.1 KiB
C++
#include "MetroidPrime/CMappableObject.hpp"
|
|
|
|
#include "MetroidPrime/CMapWorldInfo.hpp"
|
|
#include "MetroidPrime/Tweaks/CTweakAutoMapper.hpp"
|
|
#include "MetroidPrime/Tweaks/CTweakPlayerRes.hpp"
|
|
|
|
#include "Kyoto/CSimplePool.hpp"
|
|
#include "Kyoto/Graphics/CGX.hpp"
|
|
#include "Kyoto/Graphics/CGraphics.hpp"
|
|
#include "Kyoto/Graphics/CTexture.hpp"
|
|
#include "Kyoto/SObjectTag.hpp"
|
|
#include "Kyoto/TToken.hpp"
|
|
|
|
#include "rstl/math.hpp"
|
|
|
|
struct SDrawData {
|
|
int x0_;
|
|
int x4_;
|
|
int x8_;
|
|
uchar xc_idxA;
|
|
uchar xd_idxB;
|
|
uchar xe_idxC;
|
|
uchar xf_idxD;
|
|
};
|
|
static const SDrawData sDoorData[6] = {
|
|
{0x00000000, 0x00000000, 0xBF800000, 6, 4, 2, 0},
|
|
{0x00000000, 0x00000000, 0x3F800000, 3, 1, 7, 5},
|
|
{0x00000000, 0xBF800000, 0x3F800000, 1, 0, 5, 4},
|
|
{0x00000000, 0x3F800000, 0x3F800000, 7, 6, 3, 2},
|
|
{0xBF800000, 0x00000000, 0x00000000, 3, 2, 1, 0},
|
|
{0x3F800000, 0x00000000, 0x00000000, 5, 4, 7, 6},
|
|
};
|
|
|
|
CVector3f CMappableObject::skDoorVerts[8] = {
|
|
CVector3f::Zero(), CVector3f::Zero(), CVector3f::Zero(), CVector3f::Zero(),
|
|
CVector3f::Zero(), CVector3f::Zero(), CVector3f::Zero(), CVector3f::Zero(),
|
|
};
|
|
|
|
void CMappableObject::ReadAutomapperTweaks(const CTweakAutoMapper& tweaks) {
|
|
const CVector3f& center = tweaks.GetDoorCenter();
|
|
|
|
// skDoorVerts[0] = CVector3f(-center.GetZ(), -center.GetY(), 0.f);
|
|
// skDoorVerts[1] = CVector3f(-center.GetZ(), skDoorVerts[0].GetY(), center.GetX() * 2.0f);
|
|
// skDoorVerts[2] = CVector3f(-center.GetZ(), center.GetY(), 0.f);
|
|
// skDoorVerts[3] = CVector3f(-center.GetZ(), skDoorVerts[2].GetY(), skDoorVerts[1].GetZ());
|
|
|
|
// skDoorVerts[4] = CVector3f(-center.GetZ() * 0.2f, skDoorVerts[0].GetY(), 0.f);
|
|
// skDoorVerts[5] = CVector3f(skDoorVerts[4].GetX(), skDoorVerts[0].GetY(),
|
|
// skDoorVerts[1].GetZ()); skDoorVerts[6] = CVector3f(skDoorVerts[4].GetX(),
|
|
// skDoorVerts[2].GetY(), 0.f); skDoorVerts[7] = CVector3f(skDoorVerts[4].GetX(),
|
|
// skDoorVerts[2].GetY(), skDoorVerts[1].GetZ());
|
|
|
|
skDoorVerts[0] = CVector3f(-center.GetZ(), -center.GetY(), 0.f);
|
|
skDoorVerts[1] = CVector3f(-center.GetZ(), -center.GetY(), 2.f * center.GetX());
|
|
skDoorVerts[2] = CVector3f(-center.GetZ(), center.GetY(), 0.f);
|
|
skDoorVerts[3] = CVector3f(-center.GetZ(), center.GetY(), 2.f * center.GetX());
|
|
skDoorVerts[4] = CVector3f(.2f * -center.GetZ(), -center.GetY(), 0.f);
|
|
skDoorVerts[5] = CVector3f(.2f * -center.GetZ(), -center.GetY(), 2.f * center.GetX());
|
|
skDoorVerts[6] = CVector3f(.2f * -center.GetZ(), center.GetY(), 0.f);
|
|
skDoorVerts[7] = CVector3f(.2f * -center.GetZ(), center.GetY(), 2.f * center.GetX());
|
|
}
|
|
|
|
rstl::pair< CColor, CColor >
|
|
CMappableObject::GetDoorColors(int curAreaId, const CMapWorldInfo& mwInfo, float alpha) const {
|
|
CColor firstColor(0xff00ffff);
|
|
bool areaNumMatches = x8_objId.AreaNum() == curAreaId;
|
|
bool doorVisited = mwInfo.IsDoorVisited(x8_objId);
|
|
|
|
if (areaNumMatches) {
|
|
if (doorVisited && x0_type == kMOT_ShieldDoor) {
|
|
firstColor = gpTweakAutoMapper->GetDoorColor(0);
|
|
} else {
|
|
int colorIdx = 0;
|
|
switch (x0_type) {
|
|
case kMOT_ShieldDoor:
|
|
colorIdx = 1;
|
|
break;
|
|
case kMOT_IceDoor:
|
|
case kMOT_IceDoorCeiling:
|
|
case kMOT_IceDoorFloor:
|
|
case kMOT_IceDoorFloor2:
|
|
colorIdx = 2;
|
|
break;
|
|
case kMOT_WaveDoor:
|
|
case kMOT_WaveDoorCeiling:
|
|
case kMOT_WaveDoorFloor:
|
|
case kMOT_WaveDoorFloor2:
|
|
colorIdx = 3;
|
|
break;
|
|
case kMOT_PlasmaDoor:
|
|
case kMOT_PlasmaDoorCeiling:
|
|
case kMOT_PlasmaDoorFloor:
|
|
case kMOT_PlasmaDoorFloor2:
|
|
colorIdx = 4;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
firstColor = gpTweakAutoMapper->GetDoorColor(colorIdx);
|
|
}
|
|
|
|
} else if (doorVisited) {
|
|
firstColor = gpTweakAutoMapper->GetOpenDoorColor();
|
|
} else {
|
|
firstColor = CColor(0);
|
|
}
|
|
|
|
firstColor = firstColor.WithAlphaModulatedBy(alpha);
|
|
|
|
float r = rstl::min_val(1.0f, firstColor.GetRed() * 1.4f);
|
|
float g = rstl::min_val(1.0f, firstColor.GetGreen() * 1.4f);
|
|
float b = rstl::min_val(1.0f, firstColor.GetBlue() * 1.4f);
|
|
float a = rstl::min_val(1.0f, firstColor.GetAlpha() * 1.4f);
|
|
return rstl::pair< CColor, CColor >(firstColor, CColor(r, g, b, a));
|
|
}
|
|
|
|
void CMappableObject::PostConstruct(const void*) { x10_transform = AdjustTransformForType(); }
|
|
|
|
void CMappableObject::Draw(int curArea, const CMapWorldInfo& mwInfo, float alpha,
|
|
bool needsVtxLoad) const {
|
|
if (IsDoorType(x0_type) == true) {
|
|
rstl::pair< CColor, CColor > colors = GetDoorColors(curArea, mwInfo, alpha);
|
|
for (int i = 0; i < 6; ++i) {
|
|
if (needsVtxLoad) {
|
|
CGX::SetArray(GX_VA_POS, skDoorVerts, '\f');
|
|
}
|
|
CGX::SetTevKColor(GX_KCOLOR0, colors.first.GetGXColor());
|
|
CGX::Begin(GX_TRIANGLESTRIP, GX_VTXFMT0, 4);
|
|
GXPosition1x8(sDoorData[i].xc_idxA);
|
|
GXPosition1x8(sDoorData[i].xd_idxB);
|
|
GXPosition1x8(sDoorData[i].xe_idxC);
|
|
GXPosition1x8(sDoorData[i].xf_idxD);
|
|
CGX::End();
|
|
|
|
CGX::SetTevKColor(GX_KCOLOR0, colors.second.GetGXColor());
|
|
CGX::Begin(GX_LINESTRIP, GX_VTXFMT0, 5);
|
|
GXPosition1x8(sDoorData[i].xc_idxA);
|
|
GXPosition1x8(sDoorData[i].xd_idxB);
|
|
GXPosition1x8(sDoorData[i].xf_idxD);
|
|
GXPosition1x8(sDoorData[i].xe_idxC);
|
|
GXPosition1x8(sDoorData[i].xc_idxA);
|
|
CGX::End();
|
|
}
|
|
return;
|
|
}
|
|
|
|
CAssetId iconRes = kInvalidAssetId;
|
|
CColor iconColor = CColor(0xffffffff);
|
|
|
|
// TODO
|
|
// switch (x0_type) {
|
|
// case kMOT_DownArrowYellow:
|
|
// iconRes = gpTweakPlayerRes->x10_minesBreakFirstTopIcon;
|
|
// iconColor = CColor(0xffff96ff);
|
|
// break;
|
|
// case kMOT_UpArrowYellow:
|
|
// iconRes = gpTweakPlayerRes->x14_minesBreakFirstBottomIcon;
|
|
// iconColor = CColor(0xffff96ff);
|
|
// break;
|
|
// case kMOT_DownArrowGreen:
|
|
// iconRes = gpTweakPlayerRes->x10_minesBreakFirstTopIcon;
|
|
// iconColor = CColor(0x64ff96ff);
|
|
// break;
|
|
// case kMOT_UpArrowGreen:
|
|
// iconRes = gpTweakPlayerRes->x14_minesBreakFirstBottomIcon;
|
|
// iconColor = CColor(0x64ff96ff);
|
|
// break;
|
|
// case kMOT_DownArrowRed:
|
|
// iconRes = gpTweakPlayerRes->x10_minesBreakFirstTopIcon;
|
|
// iconColor = CColor(0xff6496ff);
|
|
// break;
|
|
// case kMOT_UpArrowRed:
|
|
// iconRes = gpTweakPlayerRes->x14_minesBreakFirstBottomIcon;
|
|
// iconColor = CColor(0xff6496ff);
|
|
// break;
|
|
// case kMOT_SaveStation:
|
|
// iconRes = gpTweakPlayerRes->x4_saveStationIcon;
|
|
// break;
|
|
// case kMOT_MissileStation:
|
|
// iconRes = gpTweakPlayerRes->x8_missileStationIcon;
|
|
// break;
|
|
// default:
|
|
// iconRes = gpTweakPlayerRes->xc_elevatorIcon;
|
|
// break;
|
|
// }
|
|
TLockedToken< CTexture > tex = gpSimplePool->GetObj(SObjectTag('TXTR', iconRes));
|
|
tex->Load(GX_TEXMAP0, CTexture::kCM_Repeat);
|
|
CGraphics::SetTevOp(kTS_Stage0, CGraphics::kEnvModulate);
|
|
CGraphics::StreamBegin(kP_TriangleStrip);
|
|
CGraphics::StreamColor(iconColor.WithAlphaOf(alpha));
|
|
CGraphics::StreamTexcoord(0.0f, 1.0f);
|
|
CGraphics::StreamVertex(-2.6f, 0.0f, 2.6f);
|
|
CGraphics::StreamTexcoord(0.0f, 0.0f);
|
|
CGraphics::StreamVertex(-2.6f, 0.0f, -2.6f);
|
|
CGraphics::StreamTexcoord(1.0f, 1.0f);
|
|
CGraphics::StreamVertex(2.6f, 0.0f, 2.6f);
|
|
CGraphics::StreamTexcoord(1.0f, 0.0f);
|
|
CGraphics::StreamVertex(2.6f, 0.0f, -2.6f);
|
|
CGraphics::StreamEnd();
|
|
}
|