Add CMapArea

This commit is contained in:
Henrique Gemignani Passos Lima 2022-12-05 17:43:31 +02:00
parent cd31ecff2e
commit 920fe2cbd9
No known key found for this signature in database
GPG Key ID: E224F951761145F8
11 changed files with 402 additions and 27 deletions

View File

@ -7,8 +7,8 @@ lbl_ctor:
.section .data
.balign 8
.global lbl_803DAB80
lbl_803DAB80:
.global "__vt__35TObjOwnerDerivedFromIObj<8CMapArea>"
"__vt__35TObjOwnerDerivedFromIObj<8CMapArea>":
# ROM: 0x3D7B80
.4byte 0
.4byte 0
@ -18,8 +18,8 @@ lbl_803DAB80:
.section .sdata
.balign 8
.global lbl_805A7010
lbl_805A7010:
.global gHackAssetId
gHackAssetId:
# ROM: 0x3F49B0
.4byte 0xFFFFFFFF
.4byte 0
@ -27,7 +27,7 @@ lbl_805A7010:
.section .bss
.balign 8
.lcomm lbl_8046C3E0, 0x28, 4
.lcomm MinesPostTransforms, 0x28, 4
.section .sdata2, "a"
.balign 8
@ -92,7 +92,7 @@ FMapAreaFactory__FRC10SObjectTagR12CInputStreamRC15CVParamTransfer:
/* 800801C0 0007D120 3C 80 80 3D */ lis r4, lbl_803CD66C@ha
/* 800801C4 0007D124 80 1C 00 04 */ lwz r0, 4(r28)
/* 800801C8 0007D128 38 84 D6 6C */ addi r4, r4, lbl_803CD66C@l
/* 800801CC 0007D12C 90 0D 84 50 */ stw r0, lbl_805A7010@sda21(r13)
/* 800801CC 0007D12C 90 0D 84 50 */ stw r0, gHackAssetId@sda21(r13)
/* 800801D0 0007D130 48 29 56 9D */ bl __nw__FUlPCcPCc
/* 800801D4 0007D134 7C 7E 1B 79 */ or. r30, r3, r3
/* 800801D8 0007D138 41 82 00 28 */ beq lbl_80080200
@ -160,8 +160,8 @@ lbl_80080284:
/* 800802B8 0007D218 93 C1 00 08 */ stw r30, 8(r1)
/* 800802BC 0007D21C 7C 7E 1B 79 */ or. r30, r3, r3
/* 800802C0 0007D220 41 82 00 58 */ beq lbl_80080318
/* 800802C4 0007D224 3C 60 80 3E */ lis r3, lbl_803DAB80@ha
/* 800802C8 0007D228 38 03 AB 80 */ addi r0, r3, lbl_803DAB80@l
/* 800802C4 0007D224 3C 60 80 3E */ lis r3, "__vt__35TObjOwnerDerivedFromIObj<8CMapArea>"@ha
/* 800802C8 0007D228 38 03 AB 80 */ addi r0, r3, "__vt__35TObjOwnerDerivedFromIObj<8CMapArea>"@l
/* 800802CC 0007D22C 90 1E 00 00 */ stw r0, 0(r30)
/* 800802D0 0007D230 80 7E 00 04 */ lwz r3, 4(r30)
/* 800802D4 0007D234 28 03 00 00 */ cmplwi r3, 0
@ -226,11 +226,11 @@ lbl_80080318:
/* 8008039C 0007D2FC 3C 80 80 3E */ lis r4, __vt__4IObj@ha
/* 800803A0 0007D300 3C A0 80 3E */ lis r5, __vt__31CObjOwnerDerivedFromIObjUntyped@ha
/* 800803A4 0007D304 38 04 8D 6C */ addi r0, r4, __vt__4IObj@l
/* 800803A8 0007D308 3C 80 80 3E */ lis r4, lbl_803DAB80@ha
/* 800803A8 0007D308 3C 80 80 3E */ lis r4, "__vt__35TObjOwnerDerivedFromIObj<8CMapArea>"@ha
/* 800803AC 0007D30C 90 03 00 00 */ stw r0, 0(r3)
/* 800803B0 0007D310 38 C5 8D 78 */ addi r6, r5, __vt__31CObjOwnerDerivedFromIObjUntyped@l
/* 800803B4 0007D314 38 A0 00 00 */ li r5, 0
/* 800803B8 0007D318 38 04 AB 80 */ addi r0, r4, lbl_803DAB80@l
/* 800803B8 0007D318 38 04 AB 80 */ addi r0, r4, "__vt__35TObjOwnerDerivedFromIObj<8CMapArea>"@l
/* 800803BC 0007D31C 90 C3 00 00 */ stw r6, 0(r3)
/* 800803C0 0007D320 98 BF 00 00 */ stb r5, 0(r31)
/* 800803C4 0007D324 80 9F 00 04 */ lwz r4, 4(r31)
@ -263,11 +263,11 @@ GetAreaPostTranslate__8CMapAreaFRC6IWorld7TAreaId:
/* 80080420 0007D380 3C 03 4E 54 */ addis r0, r3, 0x4e54
/* 80080424 0007D384 28 00 4D 65 */ cmplwi r0, 0x4d65
/* 80080428 0007D388 40 82 00 24 */ bne lbl_8008044C
/* 8008042C 0007D38C 3C 80 80 3D */ lis r4, lbl_803CD640@ha
/* 80080430 0007D390 3C 60 80 47 */ lis r3, lbl_8046C3E0@ha
/* 80080434 0007D394 38 84 D6 40 */ addi r4, r4, lbl_803CD640@l
/* 8008042C 0007D38C 3C 80 80 3D */ lis r4, MinesPostTransformIndices@ha
/* 80080430 0007D390 3C 60 80 47 */ lis r3, MinesPostTransforms@ha
/* 80080434 0007D394 38 84 D6 40 */ addi r4, r4, MinesPostTransformIndices@l
/* 80080438 0007D398 7C 84 F8 AE */ lbzx r4, r4, r31
/* 8008043C 0007D39C 38 03 C3 E0 */ addi r0, r3, lbl_8046C3E0@l
/* 8008043C 0007D39C 38 03 C3 E0 */ addi r0, r3, MinesPostTransforms@l
/* 80080440 0007D3A0 1C 64 00 0C */ mulli r3, r4, 0xc
/* 80080444 0007D3A4 7C 60 1A 14 */ add r3, r0, r3
/* 80080448 0007D3A8 48 00 00 0C */ b lbl_80080454
@ -312,12 +312,12 @@ GetAreaPostTransform__8CMapAreaFRC6CWorld7TAreaId:
/* 800804D0 0007D430 81 8C 00 0C */ lwz r12, 0xc(r12)
/* 800804D4 0007D434 7D 89 03 A6 */ mtctr r12
/* 800804D8 0007D438 4E 80 04 21 */ bctrl
/* 800804DC 0007D43C 3C A0 80 3D */ lis r5, lbl_803CD640@ha
/* 800804E0 0007D440 3C 80 80 47 */ lis r4, lbl_8046C3E0@ha
/* 800804E4 0007D444 38 A5 D6 40 */ addi r5, r5, lbl_803CD640@l
/* 800804DC 0007D43C 3C A0 80 3D */ lis r5, MinesPostTransformIndices@ha
/* 800804E0 0007D440 3C 80 80 47 */ lis r4, MinesPostTransforms@ha
/* 800804E4 0007D444 38 A5 D6 40 */ addi r5, r5, MinesPostTransformIndices@l
/* 800804E8 0007D448 7C 7F 1B 78 */ mr r31, r3
/* 800804EC 0007D44C 7C A5 F0 AE */ lbzx r5, r5, r30
/* 800804F0 0007D450 38 04 C3 E0 */ addi r0, r4, lbl_8046C3E0@l
/* 800804F0 0007D450 38 04 C3 E0 */ addi r0, r4, MinesPostTransforms@l
/* 800804F4 0007D454 38 61 00 18 */ addi r3, r1, 0x18
/* 800804F8 0007D458 1C 85 00 0C */ mulli r4, r5, 0xc
/* 800804FC 0007D45C 7C 80 22 14 */ add r4, r0, r4
@ -1101,9 +1101,9 @@ __ct__8CMapAreaFR12CInputStreamUi:
.global __sinit_CMapArea_cpp
__sinit_CMapArea_cpp:
/* 80081010 0007DF70 C0 42 89 8C */ lfs f2, lbl_805AA6AC@sda21(r2)
/* 80081014 0007DF74 3C 60 80 47 */ lis r3, lbl_8046C3E0@ha
/* 80081014 0007DF74 3C 60 80 47 */ lis r3, MinesPostTransforms@ha
/* 80081018 0007DF78 C0 22 89 A8 */ lfs f1, lbl_805AA6C8@sda21(r2)
/* 8008101C 0007DF7C D4 43 C3 E0 */ stfsu f2, lbl_8046C3E0@l(r3)
/* 8008101C 0007DF7C D4 43 C3 E0 */ stfsu f2, MinesPostTransforms@l(r3)
/* 80081020 0007DF80 C0 02 89 AC */ lfs f0, lbl_805AA6CC@sda21(r2)
/* 80081024 0007DF84 D0 43 00 04 */ stfs f2, 4(r3)
/* 80081028 0007DF88 D0 23 00 08 */ stfs f1, 8(r3)
@ -1125,8 +1125,8 @@ lbl_803CD630:
.4byte 0x000000FF
.4byte 0
.global lbl_803CD640
lbl_803CD640:
.global MinesPostTransformIndices
MinesPostTransformIndices:
# ROM: 0x3CA640
.4byte 0
.4byte 0

View File

@ -71,7 +71,7 @@ LIBS = [
"MetroidPrime/Enemies/CPatterned",
"MetroidPrime/ScriptObjects/CScriptDoor",
["MetroidPrime/Enemies/CStateMachine", False],
"MetroidPrime/CMapArea",
["MetroidPrime/CMapArea", False],
["MetroidPrime/Cameras/CBallCamera", False],
"MetroidPrime/ScriptObjects/CScriptEffect",
"MetroidPrime/Weapons/CBomb",

View File

@ -16,9 +16,8 @@ private:
class CFactoryFnReturn {
public:
template < typename T >
CFactoryFnReturn(T* ptr);
// TODO this forces inlining, were they really manually specialized?
// : obj(TToken< T >::GetIObjObjectFor(ptr).release()) {}
CFactoryFnReturn(T* ptr)
: obj(TToken< T >::GetIObjObjectFor(ptr).release()) {}
private:
rstl::auto_ptr< CObjOwnerDerivedFromIObjUntyped > obj;

View File

@ -31,6 +31,8 @@ public:
void CancelBuild(const SObjectTag&) override;
bool CanBuild(const SObjectTag&) override;
const SObjectTag* GetResourceIdByName(const char* name) const override;
uint ResourceSize(const SObjectTag& tag) const { return x4_resLoader.ResourceSize(tag); }
void AsyncIdle(uint time);

View File

@ -27,6 +27,7 @@ public:
bool AreAllPaksLoaded() const;
CInputStream* LoadNewResourceSync(const SObjectTag& tag, char* extBuf);
FourCC GetResourceTypeById(CAssetId) const;
uint ResourceSize(const SObjectTag& tag) const;
private:
rstl::list< unkptr > x0_aramList;

View File

@ -0,0 +1,70 @@
#ifndef _CMAPAREA
#define _CMAPAREA
#include "MetroidPrime/CMappableObject.hpp"
#include "Kyoto/CFactoryMgr.hpp"
#include "Kyoto/Graphics/CColor.hpp"
#include "Kyoto/Math/CAABox.hpp"
#include "Kyoto/Math/CVector3f.hpp"
#include "rstl/single_ptr.hpp"
#include "rstl/vector.hpp"
class IWorld;
class CWorld;
class CMapArea {
public:
class CMapAreaSurface {
friend class CMapArea;
CVector3f x0_normal;
CVector3f xc_centroid;
const int* x18_surfOffset;
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();
const CVector3f& GetNormal() const { return x0_normal; }
const CVector3f& GetCenterPosition() const { return xc_centroid; }
};
enum EVisMode { kVM_Always, kVM_MapStationOrVisit, kVM_Visit, kVM_Never };
CMapArea(CInputStream& in, uint size);
~CMapArea();
void PostConstruct();
bool GetIsVisibleToAutoMapper(bool worldVis, bool areaVis) const;
CVector3f GetAreaCenterPoint() const;
CTransform4f GetAreaPostTransform(const CWorld&, TAreaId);
const CVector3f& GetAreaPostTranslate(const IWorld&, TAreaId);
private:
uint x0_magic;
uint x4_version;
uint x8_;
EVisMode xc_visibilityMode;
CAABox x10_box;
int x28_mappableObjCount;
int x2c_vertexCount;
int x30_surfaceCount;
uint x34_size;
CMappableObject* x38_moStart;
CVector3f* x3c_vertexStart;
CMapAreaSurface* x40_surfaceStart;
rstl::single_ptr< u8 > x44_buf;
static int gUsedMemory;
};
CFactoryFnReturn FMapAreaFactory(const SObjectTag& objTag, CInputStream& in,
const CVParamTransfer&);
#endif // _CMAPAREA

View File

@ -0,0 +1,51 @@
#ifndef _CMAPPABLEOBJECT
#define _CMAPPABLEOBJECT
#include "MetroidPrime/TGameTypes.hpp"
#include "Kyoto/Math/CTransform4f.hpp"
class CMappableObject {
public:
enum EMappableObjectType {
kMOT_BlueDoor = 0,
kMOT_ShieldDoor = 1,
kMOT_IceDoor = 2,
kMOT_WaveDoor = 3,
kMOT_PlasmaDoor = 4,
kMOT_BigDoor1 = 5,
kMOT_BigDoor2 = 6,
kMOT_IceDoorCeiling = 7,
kMOT_IceDoorFloor = 8,
kMOT_WaveDoorCeiling = 9,
kMOT_WaveDoorFloor = 10,
kMOT_PlasmaDoorCeiling = 11,
kMOT_PlasmaDoorFloor = 12,
kMOT_IceDoorFloor2 = 13,
kMOT_WaveDoorFloor2 = 14,
kMOT_PlasmaDoorFloor2 = 15,
kMOT_DownArrowYellow = 27, /* Maintenance Tunnel */
kMOT_UpArrowYellow = 28, /* Phazon Processing Center */
kMOT_DownArrowGreen = 29, /* Elevator A */
kMOT_UpArrowGreen = 30, /* Elite Control Access */
kMOT_DownArrowRed = 31, /* Elevator B */
kMOT_UpArrowRed = 32, /* Fungal Hall Access */
kMOT_TransportLift = 33,
kMOT_SaveStation = 34,
kMOT_MissileStation = 37
};
enum EVisMode { kVM_Always, kVM_MapStationOrVisit, kVM_Visit, kVM_Never, kVM_MapStationOrVisit2 };
void PostConstruct(const void*);
private:
EMappableObjectType x0_type;
EVisMode x4_visibilityMode;
TEditorId x8_objId;
uint xc_;
CTransform4f x10_transform;
uchar x40_pad[0x10];
};
CHECK_SIZEOF(CMappableObject, 0x50)
#endif // _CMAPPABLEOBJECT

View File

@ -8,8 +8,10 @@
#include "Kyoto/Audio/CSfxHandle.hpp"
#include "Kyoto/IObjectStore.hpp"
#include "Kyoto/TToken.hpp"
#include "rstl/string.hpp"
#include "rstl/reserved_vector.hpp"
class CMapWorld;
class CModel;
@ -89,7 +91,9 @@ public:
static void PropogateAreaChain(CGameArea::EOcclusionState occlusionState, CGameArea* area,
CWorld* world);
CGameArea::CConstChainIterator GetChainHead(EChain chain) const { return CGameArea::CConstChainIterator(x4c_chainHeads[size_t(chain)]); }
CGameArea::CConstChainIterator GetChainHead(EChain chain) const {
return CGameArea::CConstChainIterator(x4c_chainHeads[size_t(chain)]);
}
static CGameArea::CConstChainIterator GetAliveAreasEnd();
private:

View File

@ -88,5 +88,6 @@ private:
CHECK_SIZEOF(CTweakAutoMapper, 0x120)
extern CTweakAutoMapper* gpTweakAutoMapper;
extern "C" int lbl_805A8EB0;
#endif // _CTWEAKAUTOMAPPER

View File

@ -125,6 +125,11 @@ static inline void GXTexCoord2f32(const f32 u, const f32 v) {
GXWGFifo.f32 = v;
}
static inline void GXPosition1x8(u8 index) {
GXWGFifo.u8 = index;
}
static inline void GXEnd(void) {}
#endif

View File

@ -0,0 +1,242 @@
#include "MetroidPrime/CMapArea.hpp"
#include "MetroidPrime/CWorld.hpp"
#include "MetroidPrime/Tweaks/CTweakAutoMapper.hpp"
#include "Kyoto/Alloc/CMemory.hpp"
#include "Kyoto/CFrameDelayedKiller.hpp"
#include "Kyoto/CResFactory.hpp"
#include "Kyoto/Graphics/CGX.hpp"
#include "Kyoto/Graphics/CGraphics.hpp"
#include "Kyoto/Streams/CInputStream.hpp"
#include "Kyoto/Streams/CMemoryInStream.hpp"
#include "dolphin/os.h"
#include "limits.h"
static const CVector3f MinesPostTransforms[3] = {
CVector3f(0.f, 0.f, 200.f),
CVector3f(0.f, 0.f, 0.f),
CVector3f(0.f, 0.f, -200.f),
};
static const uchar MinesPostTransformIndices[42] = {
0, // 00 Transport to Tallon Overworld South
0, // 01 Quarry Access
0, // 02 Main Quarry
0, // 03 Waste Disposal
0, // 04 Save Station Mines A
0, // 05 Security Access A
0, // 06 Ore Processing
0, // 07 Mine Security Station
0, // 08 Research Access
0, // 09 Storage Depot B
0, // 10 Elevator Access A
0, // 11 Security Access B
0, // 12 Storage Depot A
0, // 13 Elite Research
0, // 14 Elevator A
1, // 15 Elite Control Access
1, // 16 Elite Control
1, // 17 Maintenance Tunnel
1, // 18 Ventilation Shaft
2, // 19 Phazon Processing Center
1, // 20 Omega Research
2, // 21 Transport Access
2, // 22 Processing Center Access
1, // 23 Map Station Mines
1, // 24 Dynamo Access
2, // 25 Transport to Magmoor Caverns South
2, // 26 Elite Quarters
1, // 27 Central Dynamo
2, // 28 Elite Quarters Access
1, // 29 Quarantine Access A
1, // 30 Save Station Mines B
2, // 31 Metroid Quarantine B
1, // 32 Metroid Quarantine A
2, // 33 Quarantine Access B
2, // 34 Save Station Mines C
1, // 35 Elevator Access B
2, // 36 Fungal Hall B
1, // 37 Elevator B
2, // 38 Missile Station Mines
2, // 39 Phazon Mining Tunnel
2, // 40 Fungal Hall Access
2, // 41 Fungal Hall A
};
static CAssetId gHackAssetId = kInvalidAssetId;
CMapArea::CMapArea(CInputStream& in, uint size)
: x0_magic(in.ReadLong())
, x4_version(in.ReadLong())
, x8_(in.ReadLong())
, xc_visibilityMode(EVisMode(in.ReadLong()))
, x10_box(in)
, x28_mappableObjCount(in.ReadLong())
, x2c_vertexCount(in.ReadLong())
, x30_surfaceCount(in.ReadLong())
, x34_size(size - 52) {
x44_buf = NEW u8[x34_size];
in.Get(x44_buf.get(), x34_size);
PostConstruct();
DCFlushRange(x3c_vertexStart, x2c_vertexCount * 0xc);
lbl_805A8EB0 += x34_size + sizeof(*this);
}
CMapArea::~CMapArea() {
lbl_805A8EB0 -= x34_size + sizeof(*this);
CFrameDelayedKiller::sub_8036cc1c(true, x44_buf.release());
}
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);
for (int i = 0; i < x28_mappableObjCount; ++i) {
x38_moStart[i].PostConstruct(x44_buf.get());
}
for (int i = 0; i < x2c_vertexCount * 3; ++i) {
// Somehow this empty loop generates a lot worse code than it should...
}
for (int i = 0; i < x30_surfaceCount; ++i) {
x40_surfaceStart[i].PostConstruct(x44_buf.get());
}
}
bool CMapArea::GetIsVisibleToAutoMapper(bool worldVis, bool areaVis) const {
switch (xc_visibilityMode) {
case kVM_Always:
return true;
case kVM_MapStationOrVisit:
return worldVis || areaVis;
case kVM_Visit:
return areaVis;
case kVM_Never:
return false;
default:
return true;
}
}
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));
int numSurfaces = *x18_surfOffset;
for (int i = 0; i < numSurfaces; ++i) {
// Nothing?
}
int numOutlines = *x1c_outlineOffset;
for (int i = 0; i < numOutlines; ++i) {
// Nothing?
}
}
struct Surface {
GXPrimitive primitive;
int numVertices;
};
void CMapArea::CMapAreaSurface::Draw(const CVector3f* verts, const CColor& surfColor,
const CColor& lineColor, float lineWidth) const {
bool hasSurfAlpha = surfColor.GetAlpha() > 0.0f;
bool hasLineAlpha = lineColor.GetAlpha() > 0.0f;
int numSurfaces = *x18_surfOffset;
int numOutlines = *x1c_outlineOffset;
if (verts) {
CGX::SetArray(GX_VA_POS, verts, '\f');
}
if (hasSurfAlpha) {
CGX::SetTevKColor(GX_KCOLOR0, surfColor.GetGXColor());
const int* surface = &x18_surfOffset[1];
for (int i = 0; i < numSurfaces; ++i) {
GXPrimitive primType = GXPrimitive(*surface++);
int numVertices = *surface++;
const u8* data = reinterpret_cast< const u8* >(surface);
surface += (numVertices + 3) / 4;
CGX::Begin(primType, GX_VTXFMT0, numVertices);
for (int v = 0; v < numVertices; ++v) {
GXPosition1x8(data[v]);
}
CGX::End();
}
}
if (hasLineAlpha) {
bool thickLine = 1.0f < lineWidth;
for (int j = 0; j < 1 + !!thickLine; ++j) {
const int* outline = &x1c_outlineOffset[1];
if (thickLine) {
CGraphics::SetLineWidth(lineWidth - j, ERglTexOffset(5));
}
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;
CGX::Begin(GX_LINESTRIP, GX_VTXFMT0, numVertices);
for (int v = 0; v < numVertices; ++v) {
GXPosition1x8(data[v]);
}
CGX::End();
}
}
}
}
void CMapArea::CMapAreaSurface::SetupGXMaterial() {
const GXVtxDescList list[2] = {
{GX_VA_POS, GX_INDEX8},
{GX_VA_NULL, GX_NONE},
};
CGX::SetVtxDescv(list);
CGX::SetNumChans(1);
CGX::SetNumTexGens(0);
CGX::SetNumTevStages(1);
CGX::SetChanCtrl(CGX::Channel0, false, GX_SRC_REG, GX_SRC_VTX, GX_LIGHT_NULL, GX_DF_NONE,
GX_AF_NONE);
CGX::SetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_KONST);
CGX::SetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_KONST);
CGX::SetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVPREV);
CGX::SetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVPREV);
CGX::SetTevKColorSel(GX_TEVSTAGE0, GX_TEV_KCSEL_K0);
CGX::SetTevKAlphaSel(GX_TEVSTAGE0, GX_TEV_KASEL_K0_A);
}
CTransform4f CMapArea::GetAreaPostTransform(const CWorld& world, TAreaId 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;
} else {
return world.IGetAreaAlways(aid)->IGetTM();
}
}
const CVector3f& CMapArea::GetAreaPostTranslate(const IWorld& world, TAreaId aid) {
if (world.IGetWorldAssetId() == 0xB1AC4D65) // Phazon Mines
{
return MinesPostTransforms[MinesPostTransformIndices[aid.Value()]];
} else {
return CVector3f::Zero();
}
}
CFactoryFnReturn FMapAreaFactory(const SObjectTag& objTag, CInputStream& in,
const CVParamTransfer&) {
gHackAssetId = objTag.id;
return CFactoryFnReturn(new CMapArea(in, gpResourceFactory->ResourceSize(objTag)));
}