CMappableObject, CMapArea equivalent

This commit is contained in:
Luke Street 2025-04-09 22:39:18 -06:00
parent b20a2b1eac
commit feddcf83c0
16 changed files with 286 additions and 179 deletions

1
.gitignore vendored
View File

@ -24,6 +24,7 @@ ctx.*
# Generated configs
objdiff.json
compile_commands.json
report*.json
# Miscellaneous
/*.txt

View File

@ -1912,8 +1912,8 @@ FMapAreaFactory__FRC10SObjectTagR12CInputStreamRC15CVParamTransfer = .text:0x800
__dt__35TObjOwnerDerivedFromIObj<8CMapArea>Fv = .text:0x800802A4; // type:function size:0x90 scope:global
GetIObjObjectFor__17TToken<8CMapArea>FRCQ24rstl19auto_ptr<8CMapArea> = .text:0x80080334; // type:function size:0x2C scope:global
GetNewDerivedObject__35TObjOwnerDerivedFromIObj<8CMapArea>FRCQ24rstl19auto_ptr<8CMapArea> = .text:0x80080360; // type:function size:0x9C scope:global
GetAreaPostTranslate__8CMapAreaFRC6IWorld7TAreaId = .text:0x800803FC; // type:function size:0x6C scope:global
GetAreaPostTransform__8CMapAreaFRC6CWorld7TAreaId = .text:0x80080468; // type:function size:0x108 scope:global
GetAreaPostTranslate__8CMapAreaFRC6IWorldi = .text:0x800803FC; // type:function size:0x6C scope:global
GetAreaPostTransform__8CMapAreaFRC6IWorldi = .text:0x80080468; // type:function size:0x108 scope:global
SetupGXMaterial__Q28CMapArea15CMapAreaSurfaceFv = .text:0x80080570; // type:function size:0x104 scope:global
Draw__Q28CMapArea15CMapAreaSurfaceCFPC9CVector3fRC6CColorRC6CColorf = .text:0x80080674; // type:function size:0x384 scope:global
PostConstruct__Q28CMapArea15CMapAreaSurfaceFPCv = .text:0x800809F8; // type:function size:0x304 scope:global

View File

@ -1912,8 +1912,8 @@ FMapAreaFactory__FRC10SObjectTagR12CInputStreamRC15CVParamTransfer = .text:0x800
__dt__35TObjOwnerDerivedFromIObj<8CMapArea>Fv = .text:0x80080320; // type:function size:0x90 scope:global
GetIObjObjectFor__17TToken<8CMapArea>FRCQ24rstl19auto_ptr<8CMapArea> = .text:0x800803B0; // type:function size:0x2C scope:global
GetNewDerivedObject__35TObjOwnerDerivedFromIObj<8CMapArea>FRCQ24rstl19auto_ptr<8CMapArea> = .text:0x800803DC; // type:function size:0x9C scope:global
GetAreaPostTranslate__8CMapAreaFRC6IWorld7TAreaId = .text:0x80080478; // type:function size:0x6C scope:global
GetAreaPostTransform__8CMapAreaFRC6CWorld7TAreaId = .text:0x800804E4; // type:function size:0x108 scope:global
GetAreaPostTranslate__8CMapAreaFRC6IWorldi = .text:0x80080478; // type:function size:0x6C scope:global
GetAreaPostTransform__8CMapAreaFRC6IWorldi = .text:0x800804E4; // type:function size:0x108 scope:global
SetupGXMaterial__Q28CMapArea15CMapAreaSurfaceFv = .text:0x800805EC; // type:function size:0x104 scope:global
Draw__Q28CMapArea15CMapAreaSurfaceCFPC9CVector3fRC6CColorRC6CColorf = .text:0x800806F0; // type:function size:0x384 scope:global
PostConstruct__Q28CMapArea15CMapAreaSurfaceFPCv = .text:0x80080A74; // type:function size:0x304 scope:global

View File

@ -446,7 +446,7 @@ config.libs = [
Object(NonMatching, "MetroidPrime/Enemies/CPatterned.cpp"),
Object(NonMatching, "MetroidPrime/ScriptObjects/CScriptDoor.cpp"),
Object(NonMatching, "MetroidPrime/Enemies/CStateMachine.cpp"),
Object(NonMatching, "MetroidPrime/CMapArea.cpp"),
Object(Equivalent, "MetroidPrime/CMapArea.cpp"),
Object(NonMatching, "MetroidPrime/Cameras/CBallCamera.cpp"),
Object(NonMatching, "MetroidPrime/ScriptObjects/CScriptEffect.cpp"),
Object(NonMatching, "MetroidPrime/Weapons/CBomb.cpp"),
@ -493,7 +493,7 @@ config.libs = [
Object(NonMatching, "MetroidPrime/Enemies/CBeetle.cpp"),
Object(MatchingFor("GM8E01_00", "GM8E01_01"), "MetroidPrime/HUD/CHUDMemoParms.cpp"),
Object(MatchingFor("GM8E01_00", "GM8E01_01"), "MetroidPrime/ScriptObjects/CScriptHUDMemo.cpp"),
Object(NonMatching, "MetroidPrime/CMappableObject.cpp"),
Object(Equivalent, "MetroidPrime/CMappableObject.cpp"),
Object(NonMatching, "MetroidPrime/Player/CPlayerCameraBob.cpp"),
Object(
MatchingFor("GM8E01_00", "GM8E01_01"), "MetroidPrime/ScriptObjects/CScriptCameraFilterKeyframe.cpp"

View File

@ -6,13 +6,19 @@
namespace CBasics {
bool Init();
char* Stringize(const char* fmt, ...);
inline uint SwapBytes(uint x) {
inline const int SwapBytes(int x) {
#if 0
x = ((x << 24) | ((x << 8) & 0x00FF0000) | ((x >> 8) & 0x0000FF00) | (x >> 24));
#endif
return x;
}
inline float SwapBytes(float x) {
inline const uint SwapBytes(uint x) {
#if 0
x = ((x << 24) | ((x << 8) & 0x00FF0000) | ((x >> 8) & 0x0000FF00) | (x >> 24));
#endif
return x;
}
inline const float SwapBytes(float x) {
union {
float f;
uint u;

View File

@ -32,8 +32,8 @@ public:
, m1(xf.GetRow(kDY))
, m2(xf.GetRow(kDZ)) {}*/
void RotateY(const CRelAngle& angle);
void RotateZ(const CRelAngle& angle);
static CMatrix3f RotateY(const CRelAngle& angle);
static CMatrix3f RotateZ(const CRelAngle& angle);
const CMatrix3f& operator=(const CMatrix3f& other);
const CVector3f operator*(const CVector3f&) const;
const CMatrix3f operator*(const CMatrix3f&) const;

View File

@ -11,9 +11,7 @@
#include "rstl/single_ptr.hpp"
#include "rstl/vector.hpp"
class IWorld;
class CWorld;
class CMapArea {
public:
@ -25,13 +23,11 @@ public:
const int* x1c_outlineOffset;
public:
explicit CMapAreaSurface(const void* surfBuf);
void PostConstruct(const void* buf);
void Draw(const CVector3f* verts, const CColor& surfColor, const CColor& lineColor,
float lineWidth) const;
void SetupGXMaterial();
static void SetupGXMaterial();
const CVector3f& GetNormal() const { return x0_normal; }
const CVector3f& GetCenterPosition() const { return xc_centroid; }
@ -44,8 +40,8 @@ public:
void PostConstruct();
bool GetIsVisibleToAutoMapper(bool worldVis, bool areaVis) const;
CVector3f GetAreaCenterPoint() const;
CTransform4f GetAreaPostTransform(const CWorld&, TAreaId);
const CVector3f& GetAreaPostTranslate(const IWorld&, TAreaId);
CTransform4f GetAreaPostTransform(const IWorld&, int);
static const CVector3f& GetAreaPostTranslate(const IWorld&, int);
private:
uint x0_magic;
@ -60,7 +56,7 @@ private:
CMappableObject* x38_moStart;
CVector3f* x3c_vertexStart;
CMapAreaSurface* x40_surfaceStart;
rstl::single_ptr< u8 > x44_buf;
rstl::single_ptr< uchar > x44_buf;
static int gUsedMemory;
};

View File

@ -1,9 +1,12 @@
#ifndef _CMAPWORLD
#define _CMAPWORLD
#include "Kyoto/Graphics/CColor.hpp"
#include "MetroidPrime/CMapArea.hpp"
#include "Kyoto/Graphics/CColor.hpp"
#include "rstl/reserved_vector.hpp"
class CStateManager;
class CMapWorld {

View File

@ -1,8 +1,11 @@
#ifndef _CMAPWORLDINFO
#define _CMAPWORLDINFO
#include "MetroidPrime/TGameTypes.hpp"
class CMapWorldInfo {
public:
bool IsAreaVisible(TAreaId areaId) const;
bool IsDoorVisited(TEditorId eid) const;
};

View File

@ -8,6 +8,8 @@
#include "rstl/pair.hpp"
#include "CMapWorldInfo.hpp"
class CTweakAutoMapper;
class CMapWorldInfo;
@ -45,14 +47,23 @@ public:
void PostConstruct(const void*);
rstl::pair< CColor, CColor > GetDoorColors(int idx, const CMapWorldInfo&, float alpha) const;
void Draw(int, const CMapWorldInfo&, float, bool) const;
void Draw(int curAreaId, const CMapWorldInfo& mwInfo, float alpha, bool needsVtxLoad) const;
void DrawDoorSurface(int curAreaId, const CMapWorldInfo& mwInfo, float alpha, int surfaceIdx,
bool needsVtxLoad) const;
CVector3f BuildSurfaceCenterPoint(int surfaceIdx) const;
bool GetIsVisibleToAutoMapper(bool worldVis, const CMapWorldInfo& mwInfo) const;
CTransform4f AdjustTransformForType() const;
EMappableObjectType GetType() const { return x0_type; }
TEditorId GetObjId() const { return x8_objId; }
const CTransform4f& GetTransform() const { return x10_transform; }
static bool IsDoorType(EMappableObjectType type) {
return type >= kMOT_BlueDoor && type <= kMOT_PlasmaDoorFloor2;
}
static void ReadAutomapperTweaks(const CTweakAutoMapper&);
private:
EMappableObjectType x0_type;
EVisMode x4_visibilityMode;
@ -62,8 +73,6 @@ private:
uchar x40_pad[0x10];
CTransform4f AdjustTransformForType();
static CVector3f skDoorVerts[8];
};
CHECK_SIZEOF(CMappableObject, 0x50)

View File

@ -16,13 +16,6 @@ public:
~CTweakAutoMapper();
CTweakAutoMapper(CInputStream&);
const CColor& GetDoorColor(int idx) const { return x100_doorColors[idx]; }
const CColor& GetOpenDoorColor() const { return x11c_openDoorColor; }
const CVector3f& GetDoorCenter() const {
return CVector3f(xa4_doorCenterA, xa8_doorCenterB, xac_doorCenterC);
}
private:
bool x4_24_showOneMiniMapArea : 1;
bool x4_25_ : 1;
bool x4_26_scaleMoveSpeedWithCamDist : 1;

View File

@ -5,21 +5,23 @@
#include "MetroidPrime/Tweaks/ITweakObject.hpp"
#include "Kyoto/SObjectTag.hpp"
#include "Kyoto/TOneStatic.hpp"
#include "types.h"
struct CTweakPlayerRes : public ITweakObject, public TOneStatic< CTweakPlayerRes > {
public:
/*
CAssetId x4_saveStationIcon;
CAssetId x8_missileStationIcon;
CAssetId xc_elevatorIcon;
CAssetId x10_minesBreakFirstTopIcon;
CAssetId x14_minesBreakFirstBottomIcon;
*/
char cls[0xf0];
char cls[0xdc];
CTweakPlayerRes(CInputStream& in);
CAssetId GetBallTransitionBeamResId(CPlayerState::EBeamId id) const;
};
CHECK_SIZEOF(CTweakPlayerRes, 0xf4);
extern CTweakPlayerRes* gpTweakPlayerRes;

View File

@ -41,32 +41,16 @@ CMatrix3f::CMatrix3f(CInputStream& in) {
m22 = in.ReadFloat();
}
void CMatrix3f::RotateY(const CRelAngle& angle) {
CMatrix3f CMatrix3f::RotateY(const CRelAngle& angle) {
const float dVar1 = sin(angle.AsRadians());
const float dVar2 = cos(angle.AsRadians());
m00 = dVar2;
m01 = 0.f;
m02 = dVar1;
m10 = 0.f;
m11 = 1.f;
m12 = 0.f;
m20 = -dVar1;
m21 = 0.f;
m22 = dVar2;
return CMatrix3f(dVar2, 0.f, dVar1, 0.f, 1.f, 0.f, -dVar1, 0.f, dVar2);
}
void CMatrix3f::RotateZ(const CRelAngle& angle) {
CMatrix3f CMatrix3f::RotateZ(const CRelAngle& angle) {
const float dVar1 = sin(angle.AsRadians());
const float dVar2 = cos(angle.AsRadians());
m00 = dVar2;
m01 = -dVar1;
m02 = 0.f;
m10 = dVar1;
m11 = dVar2;
m12 = 0.f;
m20 = 0.f;
m21 = 0.f;
m22 = 1.f;
return CMatrix3f(dVar2, -dVar1, 0.f, dVar1, dVar2, 0.f, 0.f, 0.f, 1.f);
}
CMatrix3f CMatrix3f::Orthonormalized() const {

View File

@ -1,5 +1,6 @@
#include "MetroidPrime/CMapArea.hpp"
#include "MetroidPrime/CMappableObject.hpp"
#include "MetroidPrime/CWorld.hpp"
#include "MetroidPrime/Tweaks/CTweakAutoMapper.hpp"
@ -8,12 +9,13 @@
#include "Kyoto/CResFactory.hpp"
#include "Kyoto/Graphics/CGX.hpp"
#include "Kyoto/Graphics/CGraphics.hpp"
#include "Kyoto/Math/CVector3f.hpp"
#include "Kyoto/Streams/CInputStream.hpp"
#include "Kyoto/Streams/CMemoryInStream.hpp"
#include "dolphin/os.h"
#include "limits.h"
#include "stdint.h"
#include <dolphin/gx/GXEnum.h>
#include <dolphin/os.h>
#include <stdint.h>
static const CVector3f MinesPostTransforms[3] = {
CVector3f(0.f, 0.f, 200.f),
@ -72,13 +74,13 @@ CMapArea::CMapArea(CInputStream& in, uint size)
: x0_magic(in.ReadLong())
, x4_version(in.ReadLong())
, x8_(in.ReadLong())
, xc_visibilityMode(EVisMode(in.ReadLong()))
, xc_visibilityMode(static_cast<EVisMode>(in.ReadLong()))
, x10_box(in)
, x28_mappableObjCount(in.ReadLong())
, x2c_vertexCount(in.ReadLong())
, x30_surfaceCount(in.ReadLong())
, x34_size(size - 52) {
x44_buf = rs_new u8[x34_size];
, x30_surfaceCount(in.ReadLong()) {
x34_size = size - 52;
x44_buf = rs_new uchar[x34_size];
in.Get(x44_buf.get(), x34_size);
PostConstruct();
@ -92,16 +94,17 @@ CMapArea::~CMapArea() {
}
void CMapArea::PostConstruct() {
x38_moStart = (CMappableObject*)(x44_buf.get());
void* vertexStart = x38_moStart + x28_mappableObjCount;
x3c_vertexStart = (CVector3f*)(vertexStart);
x40_surfaceStart = (CMapAreaSurface*)((CVector3f*)(vertexStart) + x2c_vertexCount);
CMappableObject* moStart = x38_moStart = reinterpret_cast< CMappableObject* >(x44_buf.get());
CVector3f* vertexStart = x3c_vertexStart =
reinterpret_cast< CVector3f* >(moStart + x28_mappableObjCount);
x40_surfaceStart = reinterpret_cast< CMapAreaSurface* >(vertexStart + x2c_vertexCount);
for (int i = 0; i < x28_mappableObjCount; ++i) {
x38_moStart[i].PostConstruct(x44_buf.get());
}
float* floatStart = reinterpret_cast< float* >(x3c_vertexStart);
for (int i = 0; i < x2c_vertexCount * 3; ++i) {
// Somehow this empty loop generates a lot worse code than it should...
floatStart[i] = floatStart[i]; // no-op, stripped out, possible byteswapping?
}
for (int i = 0; i < x30_surfaceCount; ++i) {
x40_surfaceStart[i].PostConstruct(x44_buf.get());
@ -126,18 +129,24 @@ bool CMapArea::GetIsVisibleToAutoMapper(bool worldVis, bool areaVis) const {
CVector3f CMapArea::GetAreaCenterPoint() const { return x10_box.GetCenterPoint(); }
void CMapArea::CMapAreaSurface::PostConstruct(const void* buf) {
x18_surfOffset = (const int*)((const uchar*)buf + reinterpret_cast< uintptr_t >(x18_surfOffset));
x1c_outlineOffset =
(const int*)((const uchar*)buf + reinterpret_cast< uintptr_t >(x1c_outlineOffset));
x18_surfOffset = reinterpret_cast< const int* >(static_cast< const uchar* >(buf) +
reinterpret_cast< uintptr_t >(x18_surfOffset));
x1c_outlineOffset = reinterpret_cast< const int* >(
static_cast< const uchar* >(buf) + reinterpret_cast< uintptr_t >(x1c_outlineOffset));
int numSurfaces = *x18_surfOffset;
const int* surfOffset = x18_surfOffset + 1;
for (int i = 0; i < numSurfaces; ++i) {
// Nothing?
int numVertices = *++surfOffset;
surfOffset++; // skip primitive type
surfOffset += ((numVertices + 3) & ~3) / 4;
}
int numOutlines = *x1c_outlineOffset;
const int* outlineOffset = x1c_outlineOffset + 1;
for (int i = 0; i < numOutlines; ++i) {
// Nothing?
int numVertices = *outlineOffset++;
outlineOffset += ((numVertices + 3) & ~3) / 4;
}
}
@ -159,10 +168,10 @@ void CMapArea::CMapAreaSurface::Draw(const CVector3f* verts, const CColor& surfC
CGX::SetTevKColor(GX_KCOLOR0, surfColor.GetGXColor());
const int* surface = &x18_surfOffset[1];
for (int i = 0; i < numSurfaces; ++i) {
GXPrimitive primType = GXPrimitive(*surface++);
GXPrimitive primType = static_cast< GXPrimitive >(*surface++);
int numVertices = *surface++;
const u8* data = reinterpret_cast< const u8* >(surface);
surface += (numVertices + 3) / 4;
const uchar* data = reinterpret_cast< const uchar* >(surface);
surface += ((numVertices + 3) & ~3) / 4;
CGX::Begin(primType, GX_VTXFMT0, numVertices);
for (int v = 0; v < numVertices; ++v) {
@ -172,20 +181,20 @@ void CMapArea::CMapAreaSurface::Draw(const CVector3f* verts, const CColor& surfC
}
}
if (hasLineAlpha) {
bool thickLine = 1.0f < lineWidth;
for (int j = 0; j < 1 + !!thickLine; ++j) {
bool thickLine = lineWidth > 1.f;
for (int j = 0; j < (thickLine ? 1 : 0) + 1; ++j) {
const int* outline = &x1c_outlineOffset[1];
if (thickLine) {
CGraphics::SetLineWidth(lineWidth - j, ERglTexOffset(5));
CGraphics::SetLineWidth(lineWidth - j, kTO_One);
}
CGX::SetTevKColor(GX_KCOLOR0,
lineColor.WithAlphaModulatedBy(thickLine ? 0.5f : 1.0f).GetGXColor());
for (int i = 0; i < numOutlines; ++i) {
int numVertices = *outline++;
const u8* data = reinterpret_cast< const u8* >(outline);
outline += (numVertices + 3) / 4;
const uchar* data = reinterpret_cast< const uchar* >(outline);
outline += ((numVertices + 3) & ~3) / 4;
CGX::Begin(GX_LINESTRIP, GX_VTXFMT0, numVertices);
for (int v = 0; v < numVertices; ++v) {
@ -216,21 +225,20 @@ void CMapArea::CMapAreaSurface::SetupGXMaterial() {
CGX::SetTevKAlphaSel(GX_TEVSTAGE0, GX_TEV_KASEL_K0_A);
}
CTransform4f CMapArea::GetAreaPostTransform(const CWorld& world, TAreaId aid) {
CTransform4f CMapArea::GetAreaPostTransform(const IWorld& world, int aid) {
if (world.IGetWorldAssetId() == 0xB1AC4D65) // Phazon Mines
{
const CTransform4f& areaXf = world.IGetAreaAlways(aid)->IGetTM();
const CVector3f& postVec = MinesPostTransforms[MinesPostTransformIndices[aid.value]];
return CTransform4f::Translate(postVec) * areaXf;
return CTransform4f::Translate(MinesPostTransforms[MinesPostTransformIndices[aid]]) *
world.IGetAreaAlways(aid)->IGetTM();
} else {
return world.IGetAreaAlways(aid)->IGetTM();
}
}
const CVector3f& CMapArea::GetAreaPostTranslate(const IWorld& world, TAreaId aid) {
const CVector3f& CMapArea::GetAreaPostTranslate(const IWorld& world, int aid) {
if (world.IGetWorldAssetId() == 0xB1AC4D65) // Phazon Mines
{
return MinesPostTransforms[MinesPostTransformIndices[aid.Value()]];
return MinesPostTransforms[MinesPostTransformIndices[aid]];
} else {
return CVector3f::Zero();
}

View File

@ -1,74 +1,75 @@
#include "MetroidPrime/CMappableObject.hpp"
#include "Kyoto/Basics/CBasics.hpp"
#include "MetroidPrime/CMapWorldInfo.hpp"
#include "MetroidPrime/Tweaks/CTweakAutoMapper.hpp"
#include "MetroidPrime/Tweaks/CTweakPlayerRes.hpp"
#include "Kyoto/CSimplePool.hpp"
#include "Kyoto/Graphics/CColor.hpp"
#include "Kyoto/Graphics/CGX.hpp"
#include "Kyoto/Graphics/CGraphics.hpp"
#include "Kyoto/Graphics/CTexture.hpp"
#include "Kyoto/Math/CMatrix3f.hpp"
#include "Kyoto/Math/CRelAngle.hpp"
#include "Kyoto/Math/CTransform4f.hpp"
#include "Kyoto/Math/CVector3f.hpp"
#include "Kyoto/SObjectTag.hpp"
#include "Kyoto/TToken.hpp"
#include "dolphin/gx/GXEnum.h"
#include "rstl/math.hpp"
struct SDrawData {
float x0_;
float x4_;
float x8_;
float x0_x;
float x4_y;
float x8_z;
uchar xc_idxA;
uchar xd_idxB;
uchar xe_idxC;
uchar xf_idxD;
};
static const SDrawData sDoorData[6] = {
{0.f, 0.f, -1, 6, 4, 2, 0},
{0.f, 0.f, 1.f, 3, 1, 7, 5},
{0.f, -1.f, 1.f, 1, 0, 5, 4},
{0.f, 1.f, 1.f, 7, 6, 3, 2},
static const SDrawData sDrawData[6] = {
// clang-format off
{ 0.f, 0.f, -1.f, 6, 4, 2, 0},
{ 0.f, 0.f, 1.f, 3, 1, 7, 5},
{ 0.f, -1.f, 1.f, 1, 0, 5, 4},
{ 0.f, 1.f, 1.f, 7, 6, 3, 2},
{-1.f, 0.f, 0.f, 3, 2, 1, 0},
{1.f, 0.f, 0.f, 5, 4, 7, 6},
{ 1.f, 0.f, 0.f, 5, 4, 7, 6},
// clang-format on
};
CVector3f CMappableObject::skDoorVerts[8] = {
static CVector3f 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());
const float x = tweaks.xac_doorCenterC;
const float y = tweaks.xa8_doorCenterB;
const float z = tweaks.xa4_doorCenterA;
skDoorVerts[0] = CVector3f(-x, -y, 0.f);
skDoorVerts[1] = CVector3f(-x, -y, z * 2.f);
skDoorVerts[2] = CVector3f(-x, y, 0.f);
skDoorVerts[3] = CVector3f(-x, y, z * 2.f);
skDoorVerts[4] = CVector3f(-x * .2f, -y, 0.f);
skDoorVerts[5] = CVector3f(-x * .2f, -y, z * 2.f);
skDoorVerts[6] = CVector3f(-x * .2f, y, 0.f);
skDoorVerts[7] = CVector3f(-x * .2f, y, z * 2.f);
}
rstl::pair< CColor, CColor >
CMappableObject::GetDoorColors(int curAreaId, const CMapWorldInfo& mwInfo, float alpha) const {
CColor firstColor(0xff00ffff);
CColor firstColor((uchar)0xff, 0x00, 0xff, 0xff);
bool areaNumMatches = x8_objId.AreaNum() == curAreaId;
bool doorVisited = mwInfo.IsDoorVisited(x8_objId);
if (areaNumMatches) {
if (doorVisited && x0_type == kMOT_ShieldDoor) {
firstColor = gpTweakAutoMapper->GetDoorColor(0);
firstColor = gpTweakAutoMapper->x100_doorColors[0];
} else {
int colorIdx = 0;
switch (x0_type) {
@ -96,25 +97,28 @@ CMappableObject::GetDoorColors(int curAreaId, const CMapWorldInfo& mwInfo, float
default:
break;
}
firstColor = gpTweakAutoMapper->GetDoorColor(colorIdx);
firstColor = gpTweakAutoMapper->x100_doorColors[colorIdx];
}
} else if (doorVisited) {
firstColor = gpTweakAutoMapper->GetOpenDoorColor();
firstColor = gpTweakAutoMapper->x11c_openDoorColor;
} 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));
const CColor secondColor(rstl::min_val(1.0f, firstColor.GetRed() * 0.5f),
rstl::min_val(1.0f, firstColor.GetGreen() * 0.5f),
rstl::min_val(1.0f, firstColor.GetBlue() * 0.5f),
rstl::min_val(1.0f, firstColor.GetAlpha() * 0.5f));
return rstl::pair< CColor, CColor >(firstColor, secondColor);
}
void CMappableObject::PostConstruct(const void*) { x10_transform = AdjustTransformForType(); }
void CMappableObject::PostConstruct(const void*) {
for (int i = 0; i < offsetof(CMappableObject, x40_pad) / sizeof(int); ++i) {
reinterpret_cast< int* >(this)[i] = CBasics::SwapBytes(reinterpret_cast< int* >(this)[i]);
}
x10_transform = AdjustTransformForType();
}
void CMappableObject::Draw(int curArea, const CMapWorldInfo& mwInfo, float alpha,
bool needsVtxLoad) const {
@ -122,23 +126,23 @@ void CMappableObject::Draw(int curArea, const CMapWorldInfo& mwInfo, float alpha
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::SetArray(GX_VA_POS, skDoorVerts, sizeof(skDoorVerts[0]));
}
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);
GXPosition1x8(sDrawData[i].xc_idxA);
GXPosition1x8(sDrawData[i].xd_idxB);
GXPosition1x8(sDrawData[i].xe_idxC);
GXPosition1x8(sDrawData[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);
GXPosition1x8(sDrawData[i].xc_idxA);
GXPosition1x8(sDrawData[i].xd_idxB);
GXPosition1x8(sDrawData[i].xf_idxD);
GXPosition1x8(sDrawData[i].xe_idxC);
GXPosition1x8(sDrawData[i].xc_idxA);
CGX::End();
}
return;
@ -146,43 +150,42 @@ void CMappableObject::Draw(int curArea, const CMapWorldInfo& mwInfo, float alpha
CAssetId iconRes = kInvalidAssetId;
CColor iconColor = CColor(0xffffffff);
switch (x0_type) {
case kMOT_DownArrowYellow:
iconColor = CColor((uchar)0xff, 0xff, 0x96, 0xff);
iconRes = gpTweakPlayerRes->x10_minesBreakFirstTopIcon;
break;
case kMOT_UpArrowYellow:
iconColor = CColor((uchar)0xff, 0xff, 0x96, 0xff);
iconRes = gpTweakPlayerRes->x14_minesBreakFirstBottomIcon;
break;
case kMOT_DownArrowGreen:
iconColor = CColor((uchar)0x64, 0xff, 0x96, 0xff);
iconRes = gpTweakPlayerRes->x10_minesBreakFirstTopIcon;
break;
case kMOT_UpArrowGreen:
iconColor = CColor((uchar)0x64, 0xff, 0x96, 0xff);
iconRes = gpTweakPlayerRes->x14_minesBreakFirstBottomIcon;
break;
case kMOT_DownArrowRed:
iconColor = CColor((uchar)0xff, 0x64, 0x96, 0xff);
iconRes = gpTweakPlayerRes->x10_minesBreakFirstTopIcon;
break;
case kMOT_UpArrowRed:
iconColor = CColor((uchar)0xff, 0x64, 0x96, 0xff);
iconRes = gpTweakPlayerRes->x14_minesBreakFirstBottomIcon;
break;
case kMOT_SaveStation:
iconRes = gpTweakPlayerRes->x4_saveStationIcon;
break;
case kMOT_MissileStation:
iconRes = gpTweakPlayerRes->x8_missileStationIcon;
break;
default:
iconRes = gpTweakPlayerRes->xc_elevatorIcon;
break;
}
// 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);
@ -198,3 +201,101 @@ void CMappableObject::Draw(int curArea, const CMapWorldInfo& mwInfo, float alpha
CGraphics::StreamVertex(2.6f, 0.0f, -2.6f);
CGraphics::StreamEnd();
}
void CMappableObject::DrawDoorSurface(int curAreaId, const CMapWorldInfo& mwInfo, float alpha,
int surfaceIdx, bool needsVtxLoad) const {
rstl::pair< CColor, CColor > colors = GetDoorColors(curAreaId, mwInfo, alpha);
const SDrawData& drawData = sDrawData[surfaceIdx];
if (needsVtxLoad) {
CGX::SetArray(GX_VA_POS, skDoorVerts, 12);
}
CGX::SetTevKColor(GX_KCOLOR0, colors.first.GetGXColor());
CGX::Begin(GX_TRIANGLESTRIP, GX_VTXFMT0, 4);
GXPosition1x8(drawData.xc_idxA);
GXPosition1x8(drawData.xd_idxB);
GXPosition1x8(drawData.xe_idxC);
GXPosition1x8(drawData.xf_idxD);
CGX::End();
CGX::SetTevKColor(GX_KCOLOR0, colors.second.GetGXColor());
CGX::Begin(GX_LINESTRIP, GX_VTXFMT0, 5);
GXPosition1x8(drawData.xc_idxA);
GXPosition1x8(drawData.xd_idxB);
GXPosition1x8(drawData.xf_idxD);
GXPosition1x8(drawData.xe_idxC);
GXPosition1x8(drawData.xc_idxA);
CGX::End();
}
CVector3f CMappableObject::BuildSurfaceCenterPoint(int surfaceIdx) const {
const float x = gpTweakAutoMapper->xac_doorCenterC;
const float y = gpTweakAutoMapper->xa8_doorCenterB;
const float z = gpTweakAutoMapper->xa4_doorCenterA;
switch (surfaceIdx) {
case 0:
return x10_transform * CVector3f::Zero();
case 1:
return x10_transform * CVector3f(0.f, 0.f, 2.f * z);
case 2:
return x10_transform * CVector3f(0.f, -y, 0.f);
case 3:
return x10_transform * CVector3f(0.f, y, 0.f);
case 4:
return x10_transform * CVector3f(-x, 0.f, 0.f);
case 5:
return x10_transform * CVector3f(x, 0.f, 0.f);
default:
return CVector3f::Zero();
}
}
bool CMappableObject::GetIsVisibleToAutoMapper(bool worldVis, const CMapWorldInfo& mwInfo) const {
bool areaVis = mwInfo.IsAreaVisible(x8_objId.AreaNum());
switch (x4_visibilityMode) {
case kVM_Always:
return true;
case kVM_MapStationOrVisit:
case kVM_MapStationOrVisit2:
return worldVis || areaVis;
case kVM_Visit:
if (IsDoorType(x0_type)) {
return mwInfo.IsDoorVisited(x8_objId);
}
return areaVis;
case kVM_Never:
return false;
default:
return true;
}
}
CTransform4f CMappableObject::AdjustTransformForType() const {
const float doorCenterX = gpTweakAutoMapper->xa4_doorCenterA;
const float doorCenterZ = gpTweakAutoMapper->xac_doorCenterC;
if (x0_type == kMOT_BigDoor1) {
return (GetTransform() * CTransform4f(CMatrix3f::RotateZ(CRelAngle::FromDegrees(90.f)),
CVector3f(0.f, 0.f, doorCenterX * -1.4f))) *
CTransform4f::Scale(1.5f);
} else if (x0_type == kMOT_BigDoor2) {
return (GetTransform() *
CTransform4f(CMatrix3f::RotateZ(CRelAngle::FromDegrees(-90.f)),
CVector3f(0.f, doorCenterZ * -2.f, doorCenterX * -1.4f))) *
CTransform4f::Scale(1.5f);
} else if (x0_type == kMOT_IceDoorCeiling || x0_type == kMOT_WaveDoorCeiling ||
x0_type == kMOT_PlasmaDoorCeiling) {
return GetTransform() * CTransform4f(CMatrix3f::RotateY(CRelAngle::FromDegrees(90.f)),
CVector3f(doorCenterX * -1.65f, 0.f, doorCenterZ * -1.f));
} else if (x0_type == kMOT_IceDoorFloor || x0_type == kMOT_WaveDoorFloor ||
x0_type == kMOT_PlasmaDoorFloor) {
return GetTransform() * CTransform4f(CMatrix3f::RotateY(CRelAngle::FromDegrees(90.f)),
CVector3f(doorCenterX * -1.65f, 0.f, doorCenterZ * -1.f));
} else if ((u32(x0_type) - u32(kMOT_IceDoorFloor2)) <= u32(kMOT_ShieldDoor) ||
x0_type == kMOT_PlasmaDoorFloor2) {
return GetTransform() * CTransform4f(CMatrix3f::RotateY(CRelAngle::FromDegrees(90.f)),
CVector3f(doorCenterX * -0.49f, 0.f, doorCenterZ * -1.f));
} else if (IsDoorType(x0_type)) {
return GetTransform();
}
return CTransform4f::Translate(GetTransform().GetTranslation());
}

View File

@ -108,6 +108,7 @@ _LITERAL_REPLACEMENTS = [
("ERglBlendMode::", "kBM_"),
("ERglBlendFactor::", "kBF_"),
("ERglLogicOp::", "kLO_"),
("EVisMode", "kVM_"),
# CActor
("x34_transform.origin", "GetTranslation()"),