More CGX matches part 2

This commit is contained in:
Luke Street 2022-08-30 18:48:44 -04:00
parent 6fbaa00f07
commit 4758103774
15 changed files with 378 additions and 109 deletions

View File

@ -1171,8 +1171,8 @@ GXSetTlutRegionCallback:
/* 8037A8A8 00377808 7C 03 03 78 */ mr r3, r0
/* 8037A8AC 0037780C 4E 80 00 20 */ blr
.global GXSetTexCoordCylWrap
GXSetTexCoordCylWrap:
.global GXSetTexCoordScaleManually
GXSetTexCoordScaleManually:
/* 8037A8B0 00377810 81 02 CE 08 */ lwz r8, lbl_805AEB28@sda21(r2)
/* 8037A8B4 00377814 38 00 00 01 */ li r0, 1
/* 8037A8B8 00377818 54 84 06 3F */ clrlwi. r4, r4, 0x18

View File

@ -7,7 +7,7 @@ lbl_ctor:
.section .bss
.balign 8
.lcomm lbl_80479BD0, 0xF0, 4
.lcomm sVtxDescList, 0xF0, 4
.comm sGXState__3CGX, 0x260, 4
.section .sbss2, "", @nobits
@ -275,9 +275,9 @@ SetVtxDescv_Compressed__3CGXFUi:
/* 80307F1C 00304E7C 80 BE 00 48 */ lwz r5, 0x48(r30)
/* 80307F20 00304E80 7C 1F 28 40 */ cmplw r31, r5
/* 80307F24 00304E84 41 82 00 7C */ beq lbl_80307FA0
/* 80307F28 00304E88 3C 60 80 48 */ lis r3, lbl_80479BD0@ha
/* 80307F28 00304E88 3C 60 80 48 */ lis r3, sVtxDescList@ha
/* 80307F2C 00304E8C 38 00 00 0B */ li r0, 0xb
/* 80307F30 00304E90 38 63 9B D0 */ addi r3, r3, lbl_80479BD0@l
/* 80307F30 00304E90 38 63 9B D0 */ addi r3, r3, sVtxDescList@l
/* 80307F34 00304E94 39 00 00 00 */ li r8, 0
/* 80307F38 00304E98 7C 67 1B 78 */ mr r7, r3
/* 80307F3C 00304E9C 38 C0 00 00 */ li r6, 0
@ -300,10 +300,10 @@ lbl_80307F74:
/* 80307F78 00304ED8 39 08 00 01 */ addi r8, r8, 1
/* 80307F7C 00304EDC 42 00 FF CC */ bdnz lbl_80307F48
/* 80307F80 00304EE0 38 00 00 FF */ li r0, 0xff
/* 80307F84 00304EE4 3C 60 80 48 */ lis r3, lbl_80479BD0@ha
/* 80307F84 00304EE4 3C 60 80 48 */ lis r3, sVtxDescList@ha
/* 80307F88 00304EE8 90 07 00 00 */ stw r0, 0(r7)
/* 80307F8C 00304EEC 38 00 00 00 */ li r0, 0
/* 80307F90 00304EF0 38 63 9B D0 */ addi r3, r3, lbl_80479BD0@l
/* 80307F90 00304EF0 38 63 9B D0 */ addi r3, r3, sVtxDescList@l
/* 80307F94 00304EF4 90 07 00 04 */ stw r0, 4(r7)
/* 80307F98 00304EF8 48 06 F2 D1 */ bl GXSetVtxDescv
/* 80307F9C 00304EFC 93 FE 00 48 */ stw r31, 0x48(r30)
@ -395,8 +395,8 @@ lbl_803080B4:
/* 803080CC 0030502C 38 21 00 10 */ addi r1, r1, 0x10
/* 803080D0 00305030 4E 80 00 20 */ blr
.global sub_803080d4
sub_803080d4:
.global ResetGXStatesFull__3CGXFv
ResetGXStatesFull__3CGXFv:
/* 803080D4 00305034 94 21 FF F0 */ stwu r1, -0x10(r1)
/* 803080D8 00305038 7C 08 02 A6 */ mflr r0
/* 803080DC 0030503C 3C 60 80 5A */ lis r3, sGXState__3CGX@ha
@ -506,7 +506,7 @@ lbl_80308254:
/* 80308258 003051B8 38 80 00 00 */ li r4, 0
/* 8030825C 003051BC 38 A0 00 00 */ li r5, 0
/* 80308260 003051C0 38 C0 00 00 */ li r6, 0
/* 80308264 003051C4 48 07 26 4D */ bl GXSetTexCoordCylWrap
/* 80308264 003051C4 48 07 26 4D */ bl GXSetTexCoordScaleManually
/* 80308268 003051C8 3B DE 00 01 */ addi r30, r30, 1
/* 8030826C 003051CC 2C 1E 00 08 */ cmpwi r30, 8
/* 80308270 003051D0 41 80 FF E4 */ blt lbl_80308254

View File

@ -137,8 +137,8 @@ lbl_80293C38:
/* 80293C6C 00290BCC 38 80 00 00 */ li r4, 0
/* 80293C70 00290BD0 38 A0 00 00 */ li r5, 0
/* 80293C74 00290BD4 38 C0 00 00 */ li r6, 0
/* 80293C78 00290BD8 48 0E 6C 39 */ bl GXSetTexCoordCylWrap
/* 80293C7C 00290BDC 48 07 44 59 */ bl sub_803080d4
/* 80293C78 00290BD8 48 0E 6C 39 */ bl GXSetTexCoordScaleManually
/* 80293C7C 00290BDC 48 07 44 59 */ bl ResetGXStatesFull__3CGXFv
/* 80293C80 00290BE0 38 60 00 00 */ li r3, 0
/* 80293C84 00290BE4 48 07 51 CD */ bl SetNumChans__3CGXFUc
/* 80293C88 00290BE8 38 60 00 01 */ li r3, 1

View File

@ -3,7 +3,7 @@
#include "types.h"
#include "gx_struct.h"
#include <dolphin/gx/GXStruct.h>
class COsContext {
public:

View File

@ -4,6 +4,11 @@
#include "types.h"
#include "dolphin/gx.h"
#include <stddef.h>
#ifdef __MWERKS__
#pragma cpp_extensions on
#endif
class CGX {
public:
@ -33,24 +38,29 @@ public:
f32 xc_fogFarZ;
GXColor x10_fogColor;
SFogParams(); /* {
x0_fogStartZ = 0.f;
x4_fogEndZ = 1.f;
x8_fogNearZ = 0.1f;
xc_fogFarZ = 1.f;
}*/
SFogParams() : x0_fogStartZ(0.f), x4_fogEndZ(1.f), x8_fogNearZ(0.1f), xc_fogFarZ(1.f) {
x10_fogColor.a = 0;
x10_fogColor.b = 0;
x10_fogColor.g = 0;
x10_fogColor.r = 0;
}
};
struct SGXState {
void* x0_arrayPtrs[12];
const void* x0_arrayPtrs[12];
u16 x30_prevChanCtrls[2];
u16 x34_chanCtrls[2];
GXColor x38_chanAmbColors[2];
GXColor x40_chanMatColors[2];
u32 x48_descList;
u8 x4c_ : 5;
union {
u8 x4c_flags;
struct {
u8 x4c_unk : 5;
u8 x4c_dirtyChanCtrl : 2;
u8 x4c_numChansDirty : 1;
};
};
u8 x4d_prevNumChans;
u8 x4e_numChans;
u8 x4f_numTexGens;
@ -77,6 +87,7 @@ public:
static void SetNumChans(u8 num);
static void SetNumTexGens(u8 num);
static void SetNumTevStages(u8 num);
static void SetNumIndStages(u8 num);
static void SetChanAmbColor(EChannelId channel, const GXColor& color);
static void SetChanMatColor(EChannelId channel, const GXColor& color);
static void SetChanCtrl(EChannelId channel, GXBool enable, GXColorSrc ambSrc, GXColorSrc matSrc, GXLightID lights, GXDiffuseFn diffFn,
@ -88,6 +99,28 @@ public:
static void SetTevColorOp_Compressed(GXTevStageID stageId, u32 flags);
static void SetTevAlphaOp(GXTevStageID stageId, GXTevOp op, GXTevBias bias, GXTevScale scale, GXBool clamp, GXTevRegID outReg);
static void SetTevAlphaOp_Compressed(GXTevStageID stageId, u32 flags);
static void SetTevKColorSel(GXTevStageID stageId, GXTevKColorSel sel);
static void SetTevKAlphaSel(GXTevStageID stageId, GXTevKAlphaSel sel);
static void SetTevOrder(GXTevStageID stageId, GXTexCoordID texCoord, GXTexMapID texMap, GXChannelID color);
static void SetBlendMode(GXBlendMode mode, GXBlendFactor srcFac, GXBlendFactor dstFac, GXLogicOp op);
static void SetZMode(bool compareEnable, GXCompare func, bool updateEnable);
static void SetAlphaCompare(GXCompare comp0, u8 ref0, GXAlphaOp op, GXCompare comp1, u8 ref1);
static void SetTevIndirect(GXTevStageID stageId, GXIndTexStageID indStage, GXIndTexFormat fmt, GXIndTexBiasSel biasSel,
GXIndTexMtxID mtxSel, GXIndTexWrap wrapS, GXIndTexWrap wrapT, GXBool addPrev, GXBool indLod,
GXIndTexAlphaSel alphaSel);
static void SetTevDirect(GXTevStageID stageId);
static void SetTexCoordGen(GXTexCoordID dstCoord, GXTexGenType fn, GXTexGenSrc src, GXTexMtx mtx, GXBool normalize, GXPTTexMtx postMtx);
static void SetArray(GXAttr attr, const void* data, u8 stride);
static void SetFog(GXFogType type, f32 startZ, f32 endZ, f32 nearZ, f32 farZ, const GXColor& color);
static void SetLineWidth(u8 width, GXTexOffset offset);
static void SetIndTexMtxSTPointFive(GXIndTexMtxID id, s8 scaleExp);
static void SetVtxDescv_Compressed(u32 flags);
static void CallDisplayList(const void* ptr, size_t size);
static void Begin(GXPrimitive prim, GXVtxFmt fmt, u16 numVtx);
static void End();
static void ResetGXStates();
static void ResetGXStatesFull(); // name?
static GXColor GetChanAmbColor(EChannelId channel);
@ -97,9 +130,13 @@ public:
static inline void CopyGXColor(GXColor& dst, const GXColor& src) {
*reinterpret_cast< u32* >(&dst) = *reinterpret_cast< const u32* >(&src);
}
static inline u32 MaskAndShiftLeft(u32 a, u32 b, u32 s) { return (a & b) << s; }
static inline u32 MaskAndShiftLeft(u32 v, u32 m, u32 s) { return (v & m) << s; }
static inline u32 ShiftRightAndMask(u32 v, u32 m, u32 s) { return (v >> s) & m; }
private:
static void FlushState();
static void update_fog(u32 flags);
static SGXState sGXState;
};

View File

@ -1,9 +1,10 @@
#ifndef _CTEVCOMBINERS_HPP
#define _CTEVCOMBINERS_HPP
#include "gx_enum.h"
#include "types.h"
#include <dolphin/gx/GXEnum.h>
class CTevCombiners {
public:
enum EColorSrc {

View File

@ -1,9 +1,10 @@
#ifndef _CTEXTURE_HPP
#define _CTEXTURE_HPP
#include "gx_enum.h"
#include "types.h"
#include <dolphin/gx/GXEnum.h>
class CTexture {
public:
enum EClampMode {
@ -13,6 +14,8 @@ public:
};
void Load(GXTexMapID texMapId, EClampMode clampMode) const;
static void InvalidateTexmap(GXTexMapID id);
};
#endif

View File

@ -1,9 +1,10 @@
#ifndef _CCUBERENDERER_HPP
#define _CCUBERENDERER_HPP
#include "gx_enum.h"
#include "types.h"
#include <dolphin/gx/GXEnum.h>
#include "Kyoto/Graphics/CColor.hpp"
#include "Kyoto/Math/CTransform4f.hpp"
#include "Kyoto/Math/CVector2f.hpp"

View File

@ -15,11 +15,12 @@ void GXSetIndTexMtx(GXIndTexMtxID mtx_sel, const void* offset, s8 scale_exp);
void GXSetIndTexMtx(GXIndTexMtxID mtx_sel, f32 offset[2][3], s8 scale_exp);
#endif
void GXSetIndTexOrder(GXIndTexStageID ind_stage, GXTexCoordID tex_coord, GXTexMapID tex_map);
void GXSetTevIndirect(GXTevStageID tev_stage, GXIndTexStageID ind_stage, GXIndTexFormat format,
GXIndTexBiasSel bias_sel, GXIndTexMtxID matrix_sel, GXIndTexWrap wrap_s, GXIndTexWrap wrap_t,
GXBool add_prev, GXBool ind_lod, GXIndTexAlphaSel alpha_sel);
void GXSetTevIndirect(GXTevStageID tev_stage, GXIndTexStageID ind_stage, GXIndTexFormat format, GXIndTexBiasSel bias_sel,
GXIndTexMtxID matrix_sel, GXIndTexWrap wrap_s, GXIndTexWrap wrap_t, GXBool add_prev, GXBool ind_lod,
GXIndTexAlphaSel alpha_sel);
void GXSetTevIndWarp(GXTevStageID tev_stage, GXIndTexStageID ind_stage, GXBool signed_offsets, GXBool replace_mode,
GXIndTexMtxID matrix_sel);
void GXSetIndTexCoordScale(GXIndTexStageID ind_state, GXIndTexScale scale_s, GXIndTexScale scale_t);
#ifdef __cplusplus
}

View File

@ -122,6 +122,8 @@ typedef enum _GXAttr {
GX_VA_NULL = 0xFF,
} GXAttr;
#define GX_MAX_VTXDESCLIST_SZ (GX_VA_MAX_ATTR + 1)
typedef enum _GXAttrType {
GX_NONE,
GX_DIRECT,

View File

@ -8,19 +8,20 @@
extern "C" {
#endif
void GXInitTexObj(GXTexObj* obj, const void* data, u16 width, u16 height, u32 format, GXTexWrapMode wrapS,
GXTexWrapMode wrapT, GXBool mipmap);
void GXInitTexObjCI(GXTexObj* obj, const void* data, u16 width, u16 height, GXCITexFmt format, GXTexWrapMode wrapS,
GXTexWrapMode wrapT, GXBool mipmap, u32 tlut);
void GXInitTexObj(GXTexObj* obj, const void* data, u16 width, u16 height, u32 format, GXTexWrapMode wrapS, GXTexWrapMode wrapT,
GXBool mipmap);
void GXInitTexObjCI(GXTexObj* obj, const void* data, u16 width, u16 height, GXCITexFmt format, GXTexWrapMode wrapS, GXTexWrapMode wrapT,
GXBool mipmap, u32 tlut);
void GXInitTexObjData(GXTexObj* obj, const void* data);
void GXInitTexObjLOD(GXTexObj* obj, GXTexFilter min_filt, GXTexFilter mag_filt, f32 min_lod, f32 max_lod, f32 lod_bias,
GXBool bias_clamp, GXBool do_edge_lod, GXAnisotropy max_aniso);
void GXInitTexObjLOD(GXTexObj* obj, GXTexFilter min_filt, GXTexFilter mag_filt, f32 min_lod, f32 max_lod, f32 lod_bias, GXBool bias_clamp,
GXBool do_edge_lod, GXAnisotropy max_aniso);
void GXLoadTexObj(GXTexObj* obj, GXTexMapID id);
u32 GXGetTexBufferSize(u16 width, u16 height, u32 format, GXBool mipmap, u8 max_lod);
void GXInvalidateTexAll();
void GXInitTexObjWrapMode(GXTexObj* obj, GXTexWrapMode s, GXTexWrapMode t);
void GXInitTlutObj(GXTlutObj* obj, const void* data, GXTlutFmt format, u16 entries);
void GXLoadTlut(const GXTlutObj* obj, GXTlut idx);
void GXSetTexCoordScaleManually(GXTexCoordID coord, GXBool enable, u16 ss, u16 ts);
#ifdef __cplusplus
}

View File

@ -1,38 +0,0 @@
#ifndef __GX_ENUM_H__
#define __GX_ENUM_H__
#include "types.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef enum _GXTexMapID {
GX_TEXMAP0,
GX_TEXMAP1,
GX_TEXMAP2,
GX_TEXMAP3,
GX_TEXMAP4,
GX_TEXMAP5,
GX_TEXMAP6,
GX_TEXMAP7,
GX_MAX_TEXMAP,
GX_TEXMAP_NULL = 0xFF,
GX_TEX_DISABLE = 0x100,
} GXTexMapID;
typedef enum _GXPrimitive {
GX_QUADS = 0x80,
GX_TRIANGLES = 0x90,
GX_TRIANGLESTRIP = 0x98,
GX_TRIANGLEFAN = 0xA0,
GX_LINES = 0xA8,
GX_LINESTRIP = 0xB0,
GX_POINTS = 0xB8,
} GXPrimitive;
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,30 +0,0 @@
#ifndef __GX_STRUCT_H__
#define __GX_STRUCT_H__
#include "types.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct _GXRenderModeObj {
u32 viTVMode;
u16 fbWidth;
u16 efbHeight;
u16 xfbHeight;
u16 viXOrigin;
u16 viYOrigin;
u16 viWidth;
u16 viHeight;
u32 xfbMode;
u8 field_rendering;
u8 aa;
u8 sample_pattern[12][2];
u8 vfilter[7];
} GXRenderModeObj;
#ifdef __cplusplus
}
#endif
#endif

View File

@ -7,7 +7,7 @@ extern "C" {
#define offsetof(type, member) ((size_t) & (((type*)0)->member))
typedef unsigned int size_t;
typedef __typeof__(sizeof(0)) size_t;
#ifndef NULL
#define NULL 0L

View File

@ -1,7 +1,13 @@
#include "Kyoto/Graphics/CGX.hpp"
#include "Kyoto/Alloc/CMemory.hpp"
#include "Kyoto/Graphics/CTexture.hpp"
#include <limits.h>
CGX::SGXState CGX::sGXState;
static GXVtxDescList sVtxDescList[GX_MAX_VTXDESCLIST_SZ];
void CGX::SetNumChans(u8 num) {
sGXState.x4e_numChans = num;
sGXState.x4c_numChansDirty = sGXState.x4e_numChans != sGXState.x4d_prevNumChans;
@ -36,8 +42,8 @@ void CGX::SetChanCtrl(EChannelId channel, GXBool enable, GXColorSrc ambSrc, GXCo
u16 flags = (lights == GX_LIGHT_NULL ? 0 : enable) & 1 | (ambSrc & 1) << 1 | (matSrc & 1) << 2 | (lights & 0xFF) << 3 |
(diffFn & 3) << 11 | (attnFn & 3) << 13;
sGXState.x34_chanCtrls[channel] = flags;
sGXState.x4c_dirtyChanCtrl = (((sGXState.x34_chanCtrls[channel] != sGXState.x30_prevChanCtrls[channel]) & 1) << channel) &
(sGXState.x4c_dirtyChanCtrl & ~(1 << channel));
// sGXState.x4c_dirtyChanCtrl = (((sGXState.x34_chanCtrls[channel] != sGXState.x30_prevChanCtrls[channel]) & 1) << channel) &
// (sGXState.x4c_dirtyChanCtrl & ~(1 << channel));
// if (channel == Channel0) {
// sGXState.x4c_dirtyChanCtrl0 = (sGXState.x34_chanCtrls[channel] != sGXState.x30_prevChanCtrls[channel]);
// } else {
@ -88,7 +94,13 @@ void CGX::SetTevColorOp(GXTevStageID stageId, GXTevOp op, GXTevBias bias, GXTevS
}
void CGX::SetTevColorOp_Compressed(GXTevStageID stageId, u32 flags) {
// TODO
STevState& state = sGXState.x68_tevStates[stageId];
if (flags != state.x8_colorOps) {
state.x8_colorOps = flags;
GXSetTevColorOp(stageId, static_cast< GXTevOp >(ShiftRightAndMask(flags, 0xF, 0)),
static_cast< GXTevBias >(ShiftRightAndMask(flags, 3, 4)), static_cast< GXTevScale >(ShiftRightAndMask(flags, 3, 6)),
static_cast< GXBool >(ShiftRightAndMask(flags, 1, 8)), static_cast< GXTevRegID >(ShiftRightAndMask(flags, 3, 9)));
}
}
void CGX::SetTevAlphaOp(GXTevStageID stageId, GXTevOp op, GXTevBias bias, GXTevScale scale, GXBool clamp, GXTevRegID outReg) {
@ -102,5 +114,284 @@ void CGX::SetTevAlphaOp(GXTevStageID stageId, GXTevOp op, GXTevBias bias, GXTevS
}
void CGX::SetTevAlphaOp_Compressed(GXTevStageID stageId, u32 flags) {
// TODO
STevState& state = sGXState.x68_tevStates[stageId];
if (flags != state.xc_alphaOps) {
state.xc_alphaOps = flags;
GXSetTevAlphaOp(stageId, static_cast< GXTevOp >(ShiftRightAndMask(flags, 0xF, 0)),
static_cast< GXTevBias >(ShiftRightAndMask(flags, 3, 4)), static_cast< GXTevScale >(ShiftRightAndMask(flags, 3, 6)),
static_cast< GXBool >(ShiftRightAndMask(flags, 1, 8)), static_cast< GXTevRegID >(ShiftRightAndMask(flags, 3, 9)));
}
}
void CGX::SetTevKColorSel(GXTevStageID stageId, GXTevKColorSel sel) {
STevState& state = sGXState.x68_tevStates[stageId];
if (sel != state.x18_kColorSel) {
state.x18_kColorSel = sel;
GXSetTevKColorSel(stageId, sel);
}
}
void CGX::SetTevKAlphaSel(GXTevStageID stageId, GXTevKAlphaSel sel) {
STevState& state = sGXState.x68_tevStates[stageId];
if (sel != state.x19_kAlphaSel) {
state.x19_kAlphaSel = sel;
GXSetTevKAlphaSel(stageId, sel);
}
}
void CGX::SetTevOrder(GXTevStageID stageId, GXTexCoordID texCoord, GXTexMapID texMap, GXChannelID color) {
STevState& state = sGXState.x68_tevStates[stageId];
u32 flags = MaskAndShiftLeft(texCoord, 0xFF, 0) | MaskAndShiftLeft(texMap, 0xFF, 8) | MaskAndShiftLeft(color, 0xFF, 16);
if (state.x14_tevOrderFlags != flags) {
state.x14_tevOrderFlags = flags;
GXSetTevOrder(stageId, texCoord, texMap, color);
}
}
void CGX::SetBlendMode(GXBlendMode mode, GXBlendFactor srcFac, GXBlendFactor dstFac, GXLogicOp op) {
u16 flags = MaskAndShiftLeft(mode, 3, 0) | MaskAndShiftLeft(srcFac, 7, 2) | MaskAndShiftLeft(dstFac, 7, 5) | MaskAndShiftLeft(op, 0xF, 8);
if (flags != sGXState.x56_blendMode) {
update_fog(flags);
sGXState.x56_blendMode = flags;
GXSetBlendMode(mode, srcFac, dstFac, op);
}
}
void CGX::SetZMode(bool compareEnable, GXCompare func, bool updateEnable) {
// ??
u8 flags = compareEnable | MaskAndShiftLeft(updateEnable, 0xFF, 1) | (func & 0xFF) << 2;
if (flags != sGXState.x52_zmode) {
sGXState.x52_zmode = flags;
GXSetZMode(compareEnable, func, updateEnable);
}
}
void CGX::SetAlphaCompare(GXCompare comp0, u8 ref0, GXAlphaOp op, GXCompare comp1, u8 ref1) {
u32 flags = MaskAndShiftLeft(comp0, 7, 0) | MaskAndShiftLeft(ref0, 0xFF, 3) | MaskAndShiftLeft(op, 7, 11) |
MaskAndShiftLeft(comp1, 7, 14) | MaskAndShiftLeft(ref1, 0xFF, 17);
if (sGXState.x248_alphaCompare != flags) {
sGXState.x248_alphaCompare = flags;
GXSetAlphaCompare(comp0, ref0, op, comp1, ref1);
GXSetZCompLoc(comp0 == GX_ALWAYS);
}
}
void CGX::SetTevIndirect(GXTevStageID stageId, GXIndTexStageID indStage, GXIndTexFormat fmt, GXIndTexBiasSel biasSel, GXIndTexMtxID mtxSel,
GXIndTexWrap wrapS, GXIndTexWrap wrapT, GXBool addPrev, GXBool indLod, GXIndTexAlphaSel alphaSel) {
STevState& state = sGXState.x68_tevStates[stageId];
u32 flags = MaskAndShiftLeft(indStage, 3, 0) | MaskAndShiftLeft(fmt, 3, 2) | MaskAndShiftLeft(biasSel, 7, 4) |
MaskAndShiftLeft(mtxSel, 15, 7) | MaskAndShiftLeft(wrapS, 7, 11) | MaskAndShiftLeft(wrapT, 7, 14) |
MaskAndShiftLeft(addPrev, 1, 17) | MaskAndShiftLeft(indLod, 1, 18) | MaskAndShiftLeft(alphaSel, 3, 19);
if (state.x10_indFlags != flags) {
state.x10_indFlags = flags;
GXSetTevIndirect(stageId, indStage, fmt, biasSel, mtxSel, wrapS, wrapT, addPrev, indLod, alphaSel);
}
}
void CGX::SetTevDirect(GXTevStageID stageId) {
STevState& state = sGXState.x68_tevStates[stageId];
if (state.x10_indFlags != 0) {
state.x10_indFlags = 0;
GXSetTevDirect(stageId);
}
}
void CGX::SetTexCoordGen(GXTexCoordID dstCoord, GXTexGenType fn, GXTexGenSrc src, GXTexMtx mtx, GXBool normalize, GXPTTexMtx postMtx) {
STexState& state = sGXState.x228_texStates[dstCoord];
u32 vm = (mtx - GX_TEXMTX0) / 3;
u32 vp = postMtx - GX_PTTEXMTX0;
#ifdef NONMATCHING
// Similarly to GXTexMtx, this should also be divided by 3
vp /= 3;
#endif
u32 flags = MaskAndShiftLeft(fn, 0xF, 0) | MaskAndShiftLeft(src, 0x1F, 4) | MaskAndShiftLeft(vm, 0x1F, 9) |
MaskAndShiftLeft(normalize, 1, 14) | MaskAndShiftLeft(vp, 0x3F, 15);
if (state.x0_coordGen != flags) {
state.x0_coordGen = flags;
GXSetTexCoordGen2(dstCoord, fn, src, mtx, normalize, postMtx);
}
}
void CGX::SetNumIndStages(u8 num) {
if (sGXState.x51_numIndStages != num) {
sGXState.x51_numIndStages = num;
GXSetNumIndStages(num);
}
}
void CGX::SetArray(GXAttr attr, const void* data, u8 stride) {
u32 idx = attr - GX_VA_POS;
if (data == nullptr || sGXState.x0_arrayPtrs[idx] == data) {
return;
}
sGXState.x0_arrayPtrs[idx] = data;
GXSetArray(attr, data, stride);
}
void CGX::CallDisplayList(const void* ptr, size_t size) {
if (sGXState.x4c_flags != 0) {
FlushState();
}
GXCallDisplayList(ptr, size);
}
void CGX::Begin(GXPrimitive prim, GXVtxFmt fmt, u16 numVtx) {
if (sGXState.x4c_flags != 0) {
FlushState();
}
GXBegin(prim, fmt, numVtx);
}
void CGX::End() {}
void CGX::SetFog(GXFogType type, f32 startZ, f32 endZ, f32 nearZ, f32 farZ, const GXColor& color) {
sGXState.x53_fogType = type;
sGXState.x24c_fogParams.x0_fogStartZ = startZ;
sGXState.x24c_fogParams.x4_fogEndZ = endZ;
sGXState.x24c_fogParams.x8_fogNearZ = nearZ;
sGXState.x24c_fogParams.xc_fogFarZ = farZ;
CopyGXColor(sGXState.x24c_fogParams.x10_fogColor, color);
GXSetFog(static_cast< GXFogType >(sGXState.x53_fogType), sGXState.x24c_fogParams.x0_fogStartZ, sGXState.x24c_fogParams.x4_fogEndZ,
sGXState.x24c_fogParams.x8_fogNearZ, sGXState.x24c_fogParams.xc_fogFarZ,
(sGXState.x56_blendMode & 0xE0) == 0x20 ? GXColor() : sGXState.x24c_fogParams.x10_fogColor);
}
void CGX::SetLineWidth(u8 width, GXTexOffset offset) {
u16 flags = width | offset << 8;
if (flags != sGXState.x54_lineWidthAndOffset) {
sGXState.x54_lineWidthAndOffset = flags;
GXSetLineWidth(width, offset);
}
}
CGX::STevState::STevState()
: x0_colorInArgs(0)
, x4_alphaInArgs(0)
, x8_colorOps(0)
, xc_alphaOps(0)
, x10_indFlags(0)
, x14_tevOrderFlags(UINT_MAX)
, x18_kColorSel(UCHAR_MAX)
, x19_kAlphaSel(UCHAR_MAX) {}
CGX::STexState::STexState() : x0_coordGen(0) {}
CGX::SGXState::SGXState()
: x48_descList(0)
, x4d_prevNumChans(2)
, x4e_numChans(0)
, x4f_numTexGens(UCHAR_MAX)
, x50_numTevStages(UCHAR_MAX)
, x51_numIndStages(UCHAR_MAX)
, x52_zmode(UCHAR_MAX)
, x53_fogType(0)
, x54_lineWidthAndOffset(USHRT_MAX)
, x56_blendMode(USHRT_MAX)
, x248_alphaCompare(UINT_MAX) {
const GXColor sGXClear = {0, 0, 0, 0};
const GXColor sGXWhite = {255, 255, 255, 255};
for (s32 i = 0; i < 2; ++i) {
x30_prevChanCtrls[i] = USHRT_MAX;
x34_chanCtrls[i] = USHRT_MAX;
x38_chanAmbColors[i] = sGXClear;
x40_chanMatColors[i] = sGXWhite;
}
for (s32 i = 0; i < 4; ++i) {
x58_kColors[i] = sGXClear;
}
SetChanCtrl(Channel0, false, GX_SRC_REG, GX_SRC_REG, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE);
SetChanCtrl(Channel1, false, GX_SRC_REG, GX_SRC_REG, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE);
}
void CGX::ResetGXStates() {
sGXState.x48_descList = 0;
GXClearVtxDesc();
for (s32 i = 0; i < 12; i++) {
sGXState.x0_arrayPtrs[i] = reinterpret_cast< const void* >(1);
}
for (s32 i = 0; i < 8; i++) {
CTexture::InvalidateTexmap(static_cast< GXTexMapID >(i));
}
for (s32 i = 0; i < 4; i++) {
GXSetTevKColor(static_cast< GXTevKColorID >(i), sGXState.x58_kColors[i]);
}
GXSetTevSwapModeTable(GX_TEV_SWAP1, GX_CH_RED, GX_CH_GREEN, GX_CH_BLUE, GX_CH_RED);
GXSetTevSwapModeTable(GX_TEV_SWAP2, GX_CH_RED, GX_CH_GREEN, GX_CH_BLUE, GX_CH_GREEN);
GXSetTevSwapModeTable(GX_TEV_SWAP3, GX_CH_RED, GX_CH_GREEN, GX_CH_BLUE, GX_CH_BLUE);
SetAlphaCompare(GX_ALWAYS, 0, GX_AOP_AND, GX_ALWAYS, 0);
GXSetCurrentMtx(GX_PNMTX0);
SetNumIndStages(0);
for (s32 i = 0; i < 4; i++) {
GXSetIndTexCoordScale(static_cast< GXIndTexStageID >(i), GX_ITS_1, GX_ITS_1);
}
for (s32 i = 0; i < 16; i++) {
SetTevDirect(static_cast< GXTevStageID >(i));
}
for (s32 i = 0; i < 8; i++) {
GXSetTexCoordScaleManually(static_cast< GXTexCoordID >(i), false, 0, 0);
}
GXSetZTexture(GX_ZT_DISABLE, GX_TF_Z8, 0);
}
void CGX::ResetGXStatesFull() {
new (&sGXState) SGXState();
CGX::ResetGXStates();
}
void CGX::FlushState() {
if (sGXState.x4c_numChansDirty) {
GXSetNumChans(sGXState.x4e_numChans);
sGXState.x4d_prevNumChans = sGXState.x4e_numChans;
}
if (sGXState.x4c_flags & 2) {
u16 flags = sGXState.x34_chanCtrls[0];
GXBool enable = ShiftRightAndMask(flags, 1, 0);
GXColorSrc ambSrc = static_cast< GXColorSrc >(ShiftRightAndMask(flags, 1, 1));
GXColorSrc matSrc = static_cast< GXColorSrc >(ShiftRightAndMask(flags, 1, 2));
u32 lightMask = ShiftRightAndMask(flags, 0xFF, 3);
GXDiffuseFn diffFn = static_cast< GXDiffuseFn >(ShiftRightAndMask(flags, 3, 11));
GXAttnFn attnFn = static_cast< GXAttnFn >(ShiftRightAndMask(flags, 3, 13));
GXSetChanCtrl(GX_COLOR0, enable, ambSrc, matSrc, lightMask, diffFn, attnFn);
sGXState.x30_prevChanCtrls[0] = sGXState.x34_chanCtrls[0];
}
if (sGXState.x4c_flags & 4) {
u16 flags = sGXState.x34_chanCtrls[1];
GXBool enable = ShiftRightAndMask(flags, 1, 0);
GXColorSrc ambSrc = static_cast< GXColorSrc >(ShiftRightAndMask(flags, 1, 1));
GXColorSrc matSrc = static_cast< GXColorSrc >(ShiftRightAndMask(flags, 1, 2));
u32 lightMask = ShiftRightAndMask(flags, 0xFF, 3);
GXDiffuseFn diffFn = static_cast< GXDiffuseFn >(ShiftRightAndMask(flags, 3, 11));
GXAttnFn attnFn = static_cast< GXAttnFn >(ShiftRightAndMask(flags, 3, 13));
GXSetChanCtrl(GX_COLOR1, enable, ambSrc, matSrc, lightMask, diffFn, attnFn);
sGXState.x30_prevChanCtrls[1] = sGXState.x34_chanCtrls[1];
}
sGXState.x4c_flags = 0;
}
void CGX::SetIndTexMtxSTPointFive(GXIndTexMtxID id, s8 scaleExp) {
static const f32 indMtx[2][3] = {
{0.5f, 0.f, 0.f},
{0.f, 0.5f, 0.f},
};
GXSetIndTexMtx(id, const_cast< f32(*)[3] >(indMtx), scaleExp);
}
void CGX::SetVtxDescv_Compressed(u32 flags) {
if (flags == sGXState.x48_descList) {
return;
}
GXVtxDescList* list = sVtxDescList;
for (u32 idx = 0; idx < 11; ++idx) {
u32 shift = idx * 2;
if ((flags & 3 << shift) == (sGXState.x48_descList & 3 << shift)) {
continue;
}
list->attr = static_cast< GXAttr >(GX_VA_POS + idx);
list->type = static_cast< GXAttrType >(flags >> shift & 3);
++list;
}
list->attr = GX_VA_NULL;
list->type = GX_NONE;
GXSetVtxDescv(sVtxDescList);
sGXState.x48_descList = flags;
}