diff --git a/asm/Kyoto/Graphics/CGX.s b/asm/Kyoto/Graphics/CGX.s index b1777f28..61125ac9 100644 --- a/asm/Kyoto/Graphics/CGX.s +++ b/asm/Kyoto/Graphics/CGX.s @@ -19,8 +19,8 @@ lbl_805AF4A0: .section .text, "ax" -.global sub_80307bbc -sub_80307bbc: +.global GetFog__3CGXFP10_GXFogTypePfPfPfPfP8_GXColor +GetFog__3CGXFP10_GXFogTypePfPfPfPfP8_GXColor: /* 80307BBC 00304B1C 28 03 00 00 */ cmplwi r3, 0 /* 80307BC0 00304B20 41 82 00 14 */ beq lbl_80307BD4 /* 80307BC4 00304B24 3D 20 80 5A */ lis r9, sGXState__3CGX@ha @@ -223,8 +223,8 @@ lbl_80307E58: /* 80307E74 00304DD4 38 21 00 10 */ addi r1, r1, 0x10 /* 80307E78 00304DD8 4E 80 00 20 */ blr -.global SetIndexedPositionVtxFmt__14CFluidPlaneCPUFv -SetIndexedPositionVtxFmt__14CFluidPlaneCPUFv: +.global ResetVtxDescv__3CGXFv +ResetVtxDescv__3CGXFv: /* 80307E7C 00304DDC 94 21 FF F0 */ stwu r1, -0x10(r1) /* 80307E80 00304DE0 7C 08 02 A6 */ mflr r0 /* 80307E84 00304DE4 3C 60 80 3D */ lis r3, lbl_803D73B8@ha @@ -236,8 +236,8 @@ SetIndexedPositionVtxFmt__14CFluidPlaneCPUFv: /* 80307E9C 00304DFC 38 21 00 10 */ addi r1, r1, 0x10 /* 80307EA0 00304E00 4E 80 00 20 */ blr -.global SetAttrFmt__11CFluidPlaneF6GXAttr10GXAttrType -SetAttrFmt__11CFluidPlaneF6GXAttr10GXAttrType: +.global SetVtxDesc__3CGXF7_GXAttr11_GXAttrType +SetVtxDesc__3CGXF7_GXAttr11_GXAttrType: /* 80307EA4 00304E04 94 21 FF F0 */ stwu r1, -0x10(r1) /* 80307EA8 00304E08 7C 08 02 A6 */ mflr r0 /* 80307EAC 00304E0C 3C A0 80 5A */ lis r5, sGXState__3CGX@ha diff --git a/asm/MetaRender/CCubeRenderer.s b/asm/MetaRender/CCubeRenderer.s index f60bed01..58fb96d8 100644 --- a/asm/MetaRender/CCubeRenderer.s +++ b/asm/MetaRender/CCubeRenderer.s @@ -6947,7 +6947,7 @@ lbl_802BBEB8: /* 802BBEC4 002B8E24 38 C1 00 18 */ addi r6, r1, 0x18 /* 802BBEC8 002B8E28 38 E1 00 14 */ addi r7, r1, 0x14 /* 802BBECC 002B8E2C 39 01 00 10 */ addi r8, r1, 0x10 -/* 802BBED0 002B8E30 48 04 BC ED */ bl sub_80307bbc +/* 802BBED0 002B8E30 48 04 BC ED */ bl GetFog__3CGXFP10_GXFogTypePfPfPfPfP8_GXColor /* 802BBED4 002B8E34 C0 21 00 20 */ lfs f1, 0x20(r1) /* 802BBED8 002B8E38 38 81 00 10 */ addi r4, r1, 0x10 /* 802BBEDC 002B8E3C C0 41 00 1C */ lfs f2, 0x1c(r1) diff --git a/asm/MetroidPrime/CFluidPlaneCPU.s b/asm/MetroidPrime/CFluidPlaneCPU.s index dd1cc047..be6e52a7 100644 --- a/asm/MetroidPrime/CFluidPlaneCPU.s +++ b/asm/MetroidPrime/CFluidPlaneCPU.s @@ -128,7 +128,7 @@ RenderCleanup__14CFluidPlaneCPUCFv: /* 80199984 001968E4 48 16 ED C1 */ bl SetTevDirect__3CGXF13_GXTevStageID /* 80199988 001968E8 38 60 00 00 */ li r3, 0 /* 8019998C 001968EC 48 16 ED 05 */ bl SetNumIndStages__3CGXFUc -/* 80199990 001968F0 48 16 E4 ED */ bl SetIndexedPositionVtxFmt__14CFluidPlaneCPUFv +/* 80199990 001968F0 48 16 E4 ED */ bl ResetVtxDescv__3CGXFv /* 80199994 001968F4 3C 80 80 5A */ lis r4, mViewMatrix__9CGraphics@ha /* 80199998 001968F8 38 61 00 08 */ addi r3, r1, 8 /* 8019999C 001968FC 38 84 61 D4 */ addi r4, r4, mViewMatrix__9CGraphics@l @@ -255,7 +255,7 @@ lbl_80199A58: /* 80199B70 00196AD0 48 00 08 C1 */ bl RenderSetup__14CFluidPlaneCPUCFRC13CStateManagerfRC12CTransform4fRC12CTransform4fRC6CAABoxP12CScriptWater /* 80199B74 00196AD4 80 78 08 7C */ lwz r3, 0x87c(r24) /* 80199B78 00196AD8 C3 63 01 1C */ lfs f27, 0x11c(r3) -/* 80199B7C 00196ADC 48 16 E3 01 */ bl SetIndexedPositionVtxFmt__14CFluidPlaneCPUFv +/* 80199B7C 00196ADC 48 16 E3 01 */ bl ResetVtxDescv__3CGXFv /* 80199B80 00196AE0 88 0F 00 BC */ lbz r0, 0xbc(r15) /* 80199B84 00196AE4 28 00 00 00 */ cmplwi r0, 0 /* 80199B88 00196AE8 41 82 00 18 */ beq lbl_80199BA0 @@ -274,10 +274,10 @@ lbl_80199BB0: lbl_80199BB4: /* 80199BB4 00196B14 38 60 00 09 */ li r3, 9 /* 80199BB8 00196B18 38 80 00 01 */ li r4, 1 -/* 80199BBC 00196B1C 48 16 E2 E9 */ bl SetAttrFmt__11CFluidPlaneF6GXAttr10GXAttrType +/* 80199BBC 00196B1C 48 16 E2 E9 */ bl SetVtxDesc__3CGXF7_GXAttr11_GXAttrType /* 80199BC0 00196B20 38 60 00 0B */ li r3, 0xb /* 80199BC4 00196B24 38 80 00 01 */ li r4, 1 -/* 80199BC8 00196B28 48 16 E2 DD */ bl SetAttrFmt__11CFluidPlaneF6GXAttr10GXAttrType +/* 80199BC8 00196B28 48 16 E2 DD */ bl SetVtxDesc__3CGXF7_GXAttr11_GXAttrType /* 80199BCC 00196B2C 2C 19 00 03 */ cmpwi r25, 3 /* 80199BD0 00196B30 41 82 00 14 */ beq lbl_80199BE4 /* 80199BD4 00196B34 40 80 00 5C */ bge lbl_80199C30 @@ -304,7 +304,7 @@ lbl_80199C0C: /* 80199C20 00196B80 48 1D DB 6D */ bl GXSetVtxAttrFmt /* 80199C24 00196B84 38 60 00 0A */ li r3, 0xa /* 80199C28 00196B88 38 80 00 01 */ li r4, 1 -/* 80199C2C 00196B8C 48 16 E2 79 */ bl SetAttrFmt__11CFluidPlaneF6GXAttr10GXAttrType +/* 80199C2C 00196B8C 48 16 E2 79 */ bl SetVtxDesc__3CGXF7_GXAttr11_GXAttrType lbl_80199C30: /* 80199C30 00196B90 80 CF 01 04 */ lwz r6, 0x104(r15) /* 80199C34 00196B94 38 00 00 2A */ li r0, 0x2a diff --git a/asm/MetroidPrime/CFluidPlaneDoor.s b/asm/MetroidPrime/CFluidPlaneDoor.s index ebf5f829..dfe85d46 100644 --- a/asm/MetroidPrime/CFluidPlaneDoor.s +++ b/asm/MetroidPrime/CFluidPlaneDoor.s @@ -109,10 +109,10 @@ Render__15CFluidPlaneDoorCFRC13CStateManagerRC6CAABoxRC14CFrustumPlanesRC14CRipp /* 8019D4A8 0019A408 7F 86 E3 78 */ mr r6, r28 /* 8019D4AC 0019A40C 7D 07 43 78 */ mr r7, r8 /* 8019D4B0 0019A410 48 00 03 5D */ bl RenderSetup__15CFluidPlaneDoorCFRC13CStateManagerfRC12CTransform4fRC6CAABox -/* 8019D4B4 0019A414 48 16 A9 C9 */ bl SetIndexedPositionVtxFmt__14CFluidPlaneCPUFv +/* 8019D4B4 0019A414 48 16 A9 C9 */ bl ResetVtxDescv__3CGXFv /* 8019D4B8 0019A418 38 60 00 09 */ li r3, 9 /* 8019D4BC 0019A41C 38 80 00 01 */ li r4, 1 -/* 8019D4C0 0019A420 48 16 A9 E5 */ bl SetAttrFmt__11CFluidPlaneF6GXAttr10GXAttrType +/* 8019D4C0 0019A420 48 16 A9 E5 */ bl SetVtxDesc__3CGXF7_GXAttr11_GXAttrType /* 8019D4C4 0019A424 80 DD 00 A4 */ lwz r6, 0xa4(r29) /* 8019D4C8 0019A428 38 00 00 2A */ li r0, 0x2a /* 8019D4CC 0019A42C C3 DD 00 A8 */ lfs f30, 0xa8(r29) diff --git a/include/Kyoto/Graphics/CGX.hpp b/include/Kyoto/Graphics/CGX.hpp index f386f29e..d2220cec 100644 --- a/include/Kyoto/Graphics/CGX.hpp +++ b/include/Kyoto/Graphics/CGX.hpp @@ -115,6 +115,11 @@ public: static void SetLineWidth(u8 width, GXTexOffset offset); static void SetIndTexMtxSTPointFive(GXIndTexMtxID id, s8 scaleExp); static void SetVtxDescv_Compressed(u32 flags); + static void SetVtxDesc(GXAttr attr, GXAttrType type); // name? + static void ResetVtxDescv(); // name? + static void SetVtxDescv(const GXVtxDescList* list); + static void SetStandardDirectTev_Compressed(GXTevStageID stageId, u32 colorArgs, u32 alphaArgs, u32 colorOps, u32 alphaOps); + static void SetStandardTevColorAlphaOp(GXTevStageID stageId); static void CallDisplayList(const void* ptr, size_t size); static void Begin(GXPrimitive prim, GXVtxFmt fmt, u16 numVtx); @@ -123,6 +128,7 @@ public: static void ResetGXStatesFull(); // name? static GXColor GetChanAmbColor(EChannelId channel); + static void GetFog(GXFogType* fogType, f32* fogStartZ, f32* fogEndZ, f32* fogNearZ, f32* fogFarZ, GXColor* fogColor); static inline bool CompareGXColors(const GXColor& lhs, const GXColor& rhs) { return *reinterpret_cast< const u32* >(&lhs) == *reinterpret_cast< const u32* >(&rhs); diff --git a/src/Kyoto/Graphics/CGX.cpp b/src/Kyoto/Graphics/CGX.cpp index 68e9dba4..4a98513e 100644 --- a/src/Kyoto/Graphics/CGX.cpp +++ b/src/Kyoto/Graphics/CGX.cpp @@ -36,19 +36,18 @@ void CGX::SetChanMatColor(EChannelId channel, const GXColor& color) { } } -// TODO non-matching +// TODO https://decomp.me/scratch/09nam void CGX::SetChanCtrl(EChannelId channel, GXBool enable, GXColorSrc ambSrc, GXColorSrc matSrc, GXLightID lights, GXDiffuseFn diffFn, GXAttnFn attnFn) { - u16 flags = (lights == GX_LIGHT_NULL ? 0 : enable) & 1 | (ambSrc & 1) << 1 | (matSrc & 1) << 2 | (lights & 0xFF) << 3 | - (diffFn & 3) << 11 | (attnFn & 3) << 13; + u16 prevFlags = sGXState.x30_prevChanCtrls[channel]; + u32 flags = enable; + if (lights == GX_LIGHT_NULL) { + flags = 0; + } + flags = MaskAndShiftLeft(flags, 1, 0) | MaskAndShiftLeft(ambSrc, 1, 1) | MaskAndShiftLeft(matSrc, 1, 2) | + MaskAndShiftLeft(lights, 0xFF, 3) | MaskAndShiftLeft(diffFn, 3, 11) | MaskAndShiftLeft(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)); - // if (channel == Channel0) { - // sGXState.x4c_dirtyChanCtrl0 = (sGXState.x34_chanCtrls[channel] != sGXState.x30_prevChanCtrls[channel]); - // } else { - // sGXState.x4c_dirtyChanCtrl1 = (sGXState.x34_chanCtrls[channel] != sGXState.x30_prevChanCtrls[channel]); - // } + sGXState.x4c_flags = ((flags != prevFlags) << (channel + 1)) | (sGXState.x4c_flags & ~(1 << (channel + 1))); } void CGX::SetNumTevStages(u8 num) { @@ -58,6 +57,7 @@ void CGX::SetNumTevStages(u8 num) { } } +// TODO https://decomp.me/scratch/V2iVD void CGX::SetTevKColor(GXTevKColorID id, const GXColor& color) { if (!CompareGXColors(sGXState.x58_kColors[id], color)) { CopyGXColor(sGXState.x58_kColors[id], color); @@ -148,6 +148,7 @@ void CGX::SetTevOrder(GXTevStageID stageId, GXTexCoordID texCoord, GXTexMapID te } } +// TODO https://decomp.me/scratch/YWJTk 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) { @@ -395,3 +396,92 @@ void CGX::SetVtxDescv_Compressed(u32 flags) { GXSetVtxDescv(sVtxDescList); sGXState.x48_descList = flags; } + +void CGX::SetVtxDesc(GXAttr attr, GXAttrType type) { + u32 lshift = (attr - GX_VA_POS) * 2; + u32 rshift = 3 << lshift; + u32 flags = type << lshift; + if (flags != (sGXState.x48_descList & rshift)) { + sGXState.x48_descList = flags | (sGXState.x48_descList & ~rshift); + GXSetVtxDesc(attr, type); + } +} + +void CGX::ResetVtxDescv() { + static const GXVtxDescList vtxDescList[2] = { + {GX_VA_POS, GX_INDEX16}, + {GX_VA_NULL, GX_NONE}, + }; + SetVtxDescv(vtxDescList); +} + +void CGX::SetVtxDescv(const GXVtxDescList* list) { + u32 flags = 0; + for (; list->attr != GX_VA_NULL; ++list) { + flags |= (list->type & 3) << (list->attr - GX_VA_POS) * 2; + } + SetVtxDescv_Compressed(flags); +} + +void CGX::SetStandardDirectTev_Compressed(GXTevStageID stageId, u32 colorArgs, u32 alphaArgs, u32 colorOps, u32 alphaOps) { + STevState& state = sGXState.x68_tevStates[stageId]; + if (state.x10_indFlags != 0) { + state.x10_indFlags = 0; + GXSetTevDirect(stageId); + } + if (state.x0_colorInArgs != colorArgs) { + state.x0_colorInArgs = colorArgs; + GXSetTevColorIn(stageId, static_cast< GXTevColorArg >(ShiftRightAndMask(colorArgs, 31, 0)), + static_cast< GXTevColorArg >(ShiftRightAndMask(colorArgs, 31, 5)), + static_cast< GXTevColorArg >(ShiftRightAndMask(colorArgs, 31, 10)), + static_cast< GXTevColorArg >(ShiftRightAndMask(colorArgs, 31, 15))); + } + if (state.x4_alphaInArgs != alphaArgs) { + state.x4_alphaInArgs = alphaArgs; + GXSetTevAlphaIn(stageId, static_cast< GXTevAlphaArg >(ShiftRightAndMask(alphaArgs, 31, 0)), + static_cast< GXTevAlphaArg >(ShiftRightAndMask(alphaArgs, 31, 5)), + static_cast< GXTevAlphaArg >(ShiftRightAndMask(alphaArgs, 31, 10)), + static_cast< GXTevAlphaArg >(ShiftRightAndMask(alphaArgs, 31, 15))); + } + if (colorOps != alphaOps || (colorOps & 0x1FF) != 0x100) { + SetTevColorOp_Compressed(stageId, colorOps); + SetTevAlphaOp_Compressed(stageId, alphaOps); + } else if (colorOps != state.x8_colorOps || colorOps != state.xc_alphaOps) { + state.xc_alphaOps = colorOps; + state.x8_colorOps = colorOps; + GXTevRegID outReg = static_cast< GXTevRegID >(ShiftRightAndMask(colorOps, 3, 9)); + GXSetTevColorOp(stageId, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, outReg); + GXSetTevAlphaOp(stageId, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, outReg); + } +} + +void CGX::SetStandardTevColorAlphaOp(GXTevStageID stageId) { + STevState& state = sGXState.x68_tevStates[stageId]; + if (state.x8_colorOps != 0x100 || state.xc_alphaOps != 0x100) { + state.xc_alphaOps = 0x100; + state.x8_colorOps = 0x100; + GXSetTevColorOp(stageId, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVPREV); + GXSetTevAlphaOp(stageId, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVPREV); + } +} + +void CGX::GetFog(GXFogType* fogType, f32* fogStartZ, f32* fogEndZ, f32* fogNearZ, f32* fogFarZ, GXColor* fogColor) { + if (fogType != nullptr) { + *fogType = static_cast< GXFogType >(sGXState.x53_fogType); + } + if (fogStartZ != nullptr) { + *fogStartZ = sGXState.x24c_fogParams.x0_fogStartZ; + } + if (fogEndZ != nullptr) { + *fogEndZ = sGXState.x24c_fogParams.x4_fogEndZ; + } + if (fogNearZ != nullptr) { + *fogNearZ = sGXState.x24c_fogParams.x8_fogNearZ; + } + if (fogFarZ != nullptr) { + *fogFarZ = sGXState.x24c_fogParams.xc_fogFarZ; + } + if (fogColor != nullptr) { + CopyGXColor(*fogColor, sGXState.x24c_fogParams.x10_fogColor); + } +}