2022-02-25 07:45:25 +00:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include "CToken.hpp"
|
|
|
|
#include "GCNTypes.hpp"
|
|
|
|
#include "Graphics/CTexture.hpp"
|
2022-03-06 00:26:52 +00:00
|
|
|
#include "Graphics/CModel.hpp"
|
2022-02-25 07:45:25 +00:00
|
|
|
#include "IObjectStore.hpp"
|
|
|
|
|
|
|
|
namespace metaforce {
|
2022-02-26 07:05:59 +00:00
|
|
|
class CCubeModel;
|
|
|
|
class CCubeSurface;
|
|
|
|
|
|
|
|
enum class CCubeMaterialFlagBits : u32 {
|
|
|
|
fKonstValues = 0x8,
|
|
|
|
fDepthSorting = 0x10,
|
|
|
|
fAlphaTest = 0x20,
|
|
|
|
fSamusReflection = 0x40,
|
|
|
|
fDepthWrite = 0x80,
|
|
|
|
fSamusReflectionSurfaceEye = 0x100,
|
|
|
|
fShadowOccluderMesh = 0x200,
|
|
|
|
fSamusReflectionIndirectTexture = 0x400,
|
|
|
|
fLightmap = 0x800,
|
|
|
|
fLightmapUvArray = 0x2000,
|
|
|
|
fTextureSlotMask = 0xffff0000
|
|
|
|
};
|
|
|
|
using CCubeMaterialFlags = Flags<CCubeMaterialFlagBits>;
|
|
|
|
|
2022-02-25 07:45:25 +00:00
|
|
|
class CCubeMaterial {
|
|
|
|
const u8* x0_data;
|
|
|
|
|
|
|
|
public:
|
|
|
|
explicit CCubeMaterial(const u8* data) : x0_data(data) {}
|
|
|
|
|
2022-02-26 07:05:59 +00:00
|
|
|
void SetCurrent(const CModelFlags& flags, const CCubeSurface& surface, CCubeModel& model);
|
2022-02-25 07:45:25 +00:00
|
|
|
|
|
|
|
[[nodiscard]] u32 GetCompressedBlend() {
|
2022-02-26 07:05:59 +00:00
|
|
|
const u32* ptr = reinterpret_cast<const u32*>(x0_data + (GetTextureCount() * 4) + 16);
|
|
|
|
if (GetFlags() & CCubeMaterialFlagBits::fKonstValues) {
|
2022-02-25 07:45:25 +00:00
|
|
|
ptr += SBig(*ptr) + 1;
|
|
|
|
}
|
|
|
|
return SBig(*ptr);
|
|
|
|
}
|
2022-02-26 07:05:59 +00:00
|
|
|
[[nodiscard]] CCubeMaterialFlags GetFlags() const {
|
|
|
|
return CCubeMaterialFlags(SBig(*reinterpret_cast<const u32*>(x0_data)));
|
|
|
|
}
|
2022-05-13 23:40:19 +00:00
|
|
|
[[nodiscard]] u32 GetVatFlags() const {
|
2022-02-26 07:05:59 +00:00
|
|
|
return SBig(*reinterpret_cast<const u32*>(x0_data + 8 + (GetTextureCount() * 4)));
|
|
|
|
}
|
2022-02-25 07:45:25 +00:00
|
|
|
[[nodiscard]] u32 GetUsedTextureSlots() const { return static_cast<u32>(GetFlags()) >> 16; }
|
2022-02-26 07:05:59 +00:00
|
|
|
[[nodiscard]] u32 GetTextureCount() const { return SBig(*reinterpret_cast<const u32*>(x0_data + 4)); }
|
2022-02-25 07:45:25 +00:00
|
|
|
[[nodiscard]] u32 GetVertexDesc() const {
|
2022-02-27 17:08:24 +00:00
|
|
|
return SBig(*reinterpret_cast<const u32*>(x0_data + (GetTextureCount() * 4) + 8));
|
2022-02-25 07:45:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void ResetCachedMaterials();
|
2022-02-26 07:05:59 +00:00
|
|
|
static void EnsureViewDepStateCached(const CCubeSurface* surface);
|
|
|
|
static void KillCachedViewDepState();
|
2022-03-06 04:50:54 +00:00
|
|
|
static void EnsureTevsDirect();
|
2022-02-26 07:05:59 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
void SetCurrentBlack();
|
|
|
|
|
|
|
|
static void SetupBlendMode(u32 blendFactors, const CModelFlags& flags, bool alphaTest);
|
2022-03-06 00:26:52 +00:00
|
|
|
static void HandleDepth(CModelFlagsFlags modelFlags, CCubeMaterialFlags matFlags);
|
2022-02-26 07:05:59 +00:00
|
|
|
static u32 HandleColorChannels(u32 chanCount, u32 firstChan);
|
2022-03-06 07:46:42 +00:00
|
|
|
static void HandleTev(u32 tevCur, const u32* materialDataCur, const u32* texMapTexCoordFlags, bool shadowMapsEnabled);
|
2022-03-14 22:00:03 +00:00
|
|
|
static u32 HandleAnimatedUV(const u32* uvAnim, GX::TexMtx texMtx, GX::PTTexMtx pttTexMtx);
|
2022-02-26 07:05:59 +00:00
|
|
|
static void HandleTransparency(u32& finalTevCount, u32& finalKColorCount, const CModelFlags& modelFlags,
|
|
|
|
u32 blendFactors, u32& finalCCFlags, u32& finalACFlags);
|
|
|
|
static u32 HandleReflection(bool usesTevReg2, u32 indTexSlot, u32 r5, u32 finalTevCount, u32 texCount, u32 tcgCount,
|
|
|
|
u32 finalKColorCount, u32& finalCCFlags, u32& finalACFlags);
|
|
|
|
static void DoPassthru(u32 finalTevCount);
|
|
|
|
static void DoModelShadow(u32 texCount, u32 tcgCount);
|
2022-02-25 07:45:25 +00:00
|
|
|
};
|
|
|
|
} // namespace metaforce
|