From 595e2a92df6536e2bb4be7852d0fe797917d6add Mon Sep 17 00:00:00 2001 From: Cuyler36 Date: Mon, 28 Aug 2023 21:01:23 -0400 Subject: [PATCH] emu64 work and misc improvements --- common.py | 9 +- config/rel.lcf | 3 + configure.py | 3 +- include/dolphin/gx.h | 25 +- include/dolphin/gx/GXBump.h | 32 + include/dolphin/gx/GXCommandList.h | 35 + include/dolphin/gx/GXCull.h | 18 + include/dolphin/gx/GXDispList.h | 18 + include/dolphin/gx/GXDraw.h | 16 + include/dolphin/gx/GXEnum.h | 897 ++++++++++++++++++++++++ include/dolphin/gx/GXExtra.h | 36 + include/dolphin/gx/GXFifo.h | 37 + include/dolphin/gx/GXFrameBuffer.h | 66 ++ include/dolphin/gx/GXGeometry.h | 37 + include/dolphin/gx/GXGet.h | 28 + include/dolphin/gx/GXLighting.h | 32 + include/dolphin/gx/GXManage.h | 24 + include/dolphin/gx/GXMisc.h | 20 + include/dolphin/gx/GXPerf.h | 16 + include/dolphin/gx/GXPixel.h | 29 + include/dolphin/gx/GXPriv.h | 38 + include/dolphin/gx/GXStruct.h | 79 +++ include/dolphin/gx/GXTev.h | 37 + include/dolphin/gx/GXTexture.h | 37 + include/dolphin/gx/GXTransform.h | 33 + include/dolphin/gx/GXVert.h | 152 ++++ include/dolphin/mtx.h | 29 + include/dolphin/os/__ppc_eabi_init.h | 49 ++ include/dolphin/vi.h | 62 ++ include/libforest/emu64/emu64.hpp | 465 ++++++++++++ include/libforest/emu64/texture_cache.h | 84 +++ include/va_args.h | 6 +- rel/m_all_grow_ovl.c | 3 + rel/main.c | 1 + src/libforest/emu64/emu64.cc | 296 ++++++++ 35 files changed, 2746 insertions(+), 6 deletions(-) create mode 100644 include/dolphin/gx/GXBump.h create mode 100644 include/dolphin/gx/GXCommandList.h create mode 100644 include/dolphin/gx/GXCull.h create mode 100644 include/dolphin/gx/GXDispList.h create mode 100644 include/dolphin/gx/GXDraw.h create mode 100644 include/dolphin/gx/GXEnum.h create mode 100644 include/dolphin/gx/GXExtra.h create mode 100644 include/dolphin/gx/GXFifo.h create mode 100644 include/dolphin/gx/GXFrameBuffer.h create mode 100644 include/dolphin/gx/GXGeometry.h create mode 100644 include/dolphin/gx/GXGet.h create mode 100644 include/dolphin/gx/GXLighting.h create mode 100644 include/dolphin/gx/GXManage.h create mode 100644 include/dolphin/gx/GXMisc.h create mode 100644 include/dolphin/gx/GXPerf.h create mode 100644 include/dolphin/gx/GXPixel.h create mode 100644 include/dolphin/gx/GXPriv.h create mode 100644 include/dolphin/gx/GXStruct.h create mode 100644 include/dolphin/gx/GXTev.h create mode 100644 include/dolphin/gx/GXTexture.h create mode 100644 include/dolphin/gx/GXTransform.h create mode 100644 include/dolphin/gx/GXVert.h create mode 100644 include/dolphin/mtx.h create mode 100644 include/libforest/emu64/emu64.hpp create mode 100644 include/libforest/emu64/texture_cache.h create mode 100644 src/libforest/emu64/emu64.cc diff --git a/common.py b/common.py index 8898acda..e161e9f9 100644 --- a/common.py +++ b/common.py @@ -421,11 +421,18 @@ EXTERNAL_DOL_CFLAGS = ' '.join(BASE_DOL_CFLAGS) EXTERNAL_REL_CFLAGS = ' '.join(BASE_REL_CFLAGS) PREPROCESS_CFLAGS = ' '.join(PREPROCESSOR_CFLAGS) -LDFLAGS = ' '.join([ +DOL_LDFLAGS = ' '.join([ "-maxerrors 1", "-mapunused" ]) +LDFLAGS = ' '.join([ + "-maxerrors 1", + "-mapunused", + "-opt_partial", + "-strip_partial" +]) + PPCDIS_ANALYSIS_FLAGS = ' '.join([ f"-o {ANALYSIS_OVERRIDES}", f"-l {EXTERNS}" diff --git a/config/rel.lcf b/config/rel.lcf index bae71cb4..36c87745 100644 --- a/config/rel.lcf +++ b/config/rel.lcf @@ -15,6 +15,9 @@ SECTIONS { } FORCEFILES { } +FORCEACTIVE { + _prolog _epilog _unresolved +} __dummy_str = 0; __dummy_float = 0; diff --git a/configure.py b/configure.py index 3396adb1..5cb73253 100644 --- a/configure.py +++ b/configure.py @@ -776,7 +776,8 @@ n.build( implicit_outputs=c.DOL_MAP, variables={ "map" : c.DOL_MAP, - "lcf" : c.DOL_LCF + "lcf" : c.DOL_LCF, + "ldflags": c.DOL_LDFLAGS } ) diff --git a/include/dolphin/gx.h b/include/dolphin/gx.h index 02157995..76b4e564 100644 --- a/include/dolphin/gx.h +++ b/include/dolphin/gx.h @@ -7,9 +7,28 @@ extern "C" { #endif -#define GX_CLAMP 0 -#define GX_REPEAT 1 -#define GX_MIRROR 2 +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #ifdef __cplusplus } diff --git a/include/dolphin/gx/GXBump.h b/include/dolphin/gx/GXBump.h new file mode 100644 index 00000000..e9a294c0 --- /dev/null +++ b/include/dolphin/gx/GXBump.h @@ -0,0 +1,32 @@ +#ifndef _DOLPHIN_GXBUMP +#define _DOLPHIN_GXBUMP + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void GXSetTevDirect(GXTevStageID tev_stage); +void GXSetNumIndStages(u8 nIndStages); +#ifdef TARGET_PC +void GXSetIndTexMtx(GXIndTexMtxID mtx_sel, const void* offset, s8 scale_exp); +#else +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 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); + +extern void __GXSetIndirectMask(u32 mask); + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_GXBUMP diff --git a/include/dolphin/gx/GXCommandList.h b/include/dolphin/gx/GXCommandList.h new file mode 100644 index 00000000..cf3a5172 --- /dev/null +++ b/include/dolphin/gx/GXCommandList.h @@ -0,0 +1,35 @@ +#ifndef _DOLPHIN_GXCOMMANDLIST +#define _DOLPHIN_GXCOMMANDLIST + +#ifdef __cplusplus +extern "C" { +#endif + +#define GX_NOP 0x00 +#define GX_DRAW_QUADS 0x80 +#define GX_DRAW_TRIANGLES 0x90 +#define GX_DRAW_TRIANGLE_STRIP 0x98 +#define GX_DRAW_TRIANGLE_FAN 0xA0 +#define GX_DRAW_LINES 0xA8 +#define GX_DRAW_LINE_STRIP 0xB0 +#define GX_DRAW_POINTS 0xB8 + +#define GX_LOAD_BP_REG 0x61 +#define GX_LOAD_CP_REG 0x08 +#define GX_LOAD_XF_REG 0x10 +#define GX_LOAD_INDX_A 0x20 +#define GX_LOAD_INDX_B 0x28 +#define GX_LOAD_INDX_C 0x30 +#define GX_LOAD_INDX_D 0x38 + +#define GX_CMD_CALL_DL 0x40 +#define GX_CMD_INVL_VC 0x48 + +#define GX_OPCODE_MASK 0xF8 +#define GX_VAT_MASK 0x07 + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_GXCOMMANDLIST diff --git a/include/dolphin/gx/GXCull.h b/include/dolphin/gx/GXCull.h new file mode 100644 index 00000000..b7bb229a --- /dev/null +++ b/include/dolphin/gx/GXCull.h @@ -0,0 +1,18 @@ +#ifndef _DOLPHIN_GXCULL +#define _DOLPHIN_GXCULL + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void GXSetScissor(u32 left, u32 top, u32 wd, u32 ht); +void GXSetCullMode(GXCullMode mode); +void GXSetCoPlanar(GXBool enable); + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_GXCULL diff --git a/include/dolphin/gx/GXDispList.h b/include/dolphin/gx/GXDispList.h new file mode 100644 index 00000000..9fce67e0 --- /dev/null +++ b/include/dolphin/gx/GXDispList.h @@ -0,0 +1,18 @@ +#ifndef _DOLPHIN_GXDISPLIST +#define _DOLPHIN_GXDISPLIST + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void GXBeginDisplayList(void* list, u32 size); +u32 GXEndDisplayList(void); +void GXCallDisplayList(const void* list, u32 nbytes); + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_GXDISPLIST diff --git a/include/dolphin/gx/GXDraw.h b/include/dolphin/gx/GXDraw.h new file mode 100644 index 00000000..3ec8994f --- /dev/null +++ b/include/dolphin/gx/GXDraw.h @@ -0,0 +1,16 @@ +#ifndef _DOLPHIN_GXDRAW +#define _DOLPHIN_GXDRAW + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void GXDrawSphere(u8 numMajor, u8 numMinor); + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_GXDRAW diff --git a/include/dolphin/gx/GXEnum.h b/include/dolphin/gx/GXEnum.h new file mode 100644 index 00000000..0ac650d0 --- /dev/null +++ b/include/dolphin/gx/GXEnum.h @@ -0,0 +1,897 @@ +#ifndef _DOLPHIN_GXENUM +#define _DOLPHIN_GXENUM + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef TARGET_PC +#include + +typedef bool GXBool; +#else +typedef u8 GXBool; +#endif + +#define GX_FALSE ((GXBool)0) +#define GX_TRUE ((GXBool)1) + +#define GX_ENABLE ((GXBool)1) +#define GX_DISABLE ((GXBool)0) + +typedef enum _GXProjectionType { + GX_PERSPECTIVE, + GX_ORTHOGRAPHIC, +} GXProjectionType; + +typedef enum _GXCompare { + GX_NEVER, + GX_LESS, + GX_EQUAL, + GX_LEQUAL, + GX_GREATER, + GX_NEQUAL, + GX_GEQUAL, + GX_ALWAYS, +} GXCompare; + +typedef enum _GXAlphaOp { + GX_AOP_AND, + GX_AOP_OR, + GX_AOP_XOR, + GX_AOP_XNOR, + GX_MAX_ALPHAOP, +} GXAlphaOp; + +typedef enum _GXFBClamp { + GX_CLAMP_NONE, + GX_CLAMP_TOP, + GX_CLAMP_BOTTOM, +} GXFBClamp; + +typedef enum _GXZFmt16 { + GX_ZC_LINEAR, + GX_ZC_NEAR, + GX_ZC_MID, + GX_ZC_FAR, +} GXZFmt16; + +typedef enum _GXGamma { + GX_GM_1_0, + GX_GM_1_7, + GX_GM_2_2, +} GXGamma; + +typedef enum _GXPixelFmt { + GX_PF_RGB8_Z24, + GX_PF_RGBA6_Z24, + GX_PF_RGB565_Z16, + GX_PF_Z24, + GX_PF_Y8, + GX_PF_U8, + GX_PF_V8, + GX_PF_YUV420, +} GXPixelFmt; + +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; + +typedef enum _GXVtxFmt { + GX_VTXFMT0, + GX_VTXFMT1, + GX_VTXFMT2, + GX_VTXFMT3, + GX_VTXFMT4, + GX_VTXFMT5, + GX_VTXFMT6, + GX_VTXFMT7, + GX_MAX_VTXFMT, +} GXVtxFmt; + +typedef enum _GXAttr { + GX_VA_PNMTXIDX, + GX_VA_TEX0MTXIDX, + GX_VA_TEX1MTXIDX, + GX_VA_TEX2MTXIDX, + GX_VA_TEX3MTXIDX, + GX_VA_TEX4MTXIDX, + GX_VA_TEX5MTXIDX, + GX_VA_TEX6MTXIDX, + GX_VA_TEX7MTXIDX, + GX_VA_POS, + GX_VA_NRM, + GX_VA_CLR0, + GX_VA_CLR1, + GX_VA_TEX0, + GX_VA_TEX1, + GX_VA_TEX2, + GX_VA_TEX3, + GX_VA_TEX4, + GX_VA_TEX5, + GX_VA_TEX6, + GX_VA_TEX7, + GX_POS_MTX_ARRAY, + GX_NRM_MTX_ARRAY, + GX_TEX_MTX_ARRAY, + GX_LIGHT_ARRAY, + GX_VA_NBT, + GX_VA_MAX_ATTR, + GX_VA_NULL = 0xFF, +} GXAttr; + +#define GX_MAX_VTXDESCLIST_SZ (GX_VA_MAX_ATTR + 1) + +typedef enum _GXAttrType { + GX_NONE, + GX_DIRECT, + GX_INDEX8, + GX_INDEX16, +} GXAttrType; + +#define _GX_TF_CTF 0x20 +#define _GX_TF_ZTF 0x10 + +typedef enum _GXTexFmt { + GX_TF_I4 = 0x0, + GX_TF_I8 = 0x1, + GX_TF_IA4 = 0x2, + GX_TF_IA8 = 0x3, + GX_TF_RGB565 = 0x4, + GX_TF_RGB5A3 = 0x5, + GX_TF_RGBA8 = 0x6, + GX_TF_CMPR = 0xE, + + GX_CTF_R4 = 0x0 | _GX_TF_CTF, + GX_CTF_RA4 = 0x2 | _GX_TF_CTF, + GX_CTF_RA8 = 0x3 | _GX_TF_CTF, + GX_CTF_YUVA8 = 0x6 | _GX_TF_CTF, + GX_CTF_A8 = 0x7 | _GX_TF_CTF, + GX_CTF_R8 = 0x8 | _GX_TF_CTF, + GX_CTF_G8 = 0x9 | _GX_TF_CTF, + GX_CTF_B8 = 0xA | _GX_TF_CTF, + GX_CTF_RG8 = 0xB | _GX_TF_CTF, + GX_CTF_GB8 = 0xC | _GX_TF_CTF, + + GX_TF_Z8 = 0x1 | _GX_TF_ZTF, + GX_TF_Z16 = 0x3 | _GX_TF_ZTF, + GX_TF_Z24X8 = 0x6 | _GX_TF_ZTF, + + GX_CTF_Z4 = 0x0 | _GX_TF_ZTF | _GX_TF_CTF, + GX_CTF_Z8M = 0x9 | _GX_TF_ZTF | _GX_TF_CTF, + GX_CTF_Z8L = 0xA | _GX_TF_ZTF | _GX_TF_CTF, + GX_CTF_Z16L = 0xC | _GX_TF_ZTF | _GX_TF_CTF, + + GX_TF_A8 = GX_CTF_A8, +} GXTexFmt; + +typedef enum _GXCITexFmt { + GX_TF_C4 = 0x8, + GX_TF_C8 = 0x9, + GX_TF_C14X2 = 0xa, +} GXCITexFmt; + +typedef enum _GXTexWrapMode { + GX_CLAMP, + GX_REPEAT, + GX_MIRROR, + GX_MAX_TEXWRAPMODE, +} GXTexWrapMode; + +typedef enum _GXTexFilter { + GX_NEAR, + GX_LINEAR, + GX_NEAR_MIP_NEAR, + GX_LIN_MIP_NEAR, + GX_NEAR_MIP_LIN, + GX_LIN_MIP_LIN, +} GXTexFilter; + +typedef enum _GXAnisotropy { + GX_ANISO_1, + GX_ANISO_2, + GX_ANISO_4, + GX_MAX_ANISOTROPY, +} GXAnisotropy; + +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 _GXTexCoordID { + GX_TEXCOORD0, + GX_TEXCOORD1, + GX_TEXCOORD2, + GX_TEXCOORD3, + GX_TEXCOORD4, + GX_TEXCOORD5, + GX_TEXCOORD6, + GX_TEXCOORD7, + GX_MAX_TEXCOORD, + GX_TEXCOORD_NULL = 0xFF, +} GXTexCoordID; + +typedef enum _GXTevStageID { + GX_TEVSTAGE0, + GX_TEVSTAGE1, + GX_TEVSTAGE2, + GX_TEVSTAGE3, + GX_TEVSTAGE4, + GX_TEVSTAGE5, + GX_TEVSTAGE6, + GX_TEVSTAGE7, + GX_TEVSTAGE8, + GX_TEVSTAGE9, + GX_TEVSTAGE10, + GX_TEVSTAGE11, + GX_TEVSTAGE12, + GX_TEVSTAGE13, + GX_TEVSTAGE14, + GX_TEVSTAGE15, + GX_MAX_TEVSTAGE, +} GXTevStageID; + +typedef enum _GXTevMode { + GX_MODULATE, + GX_DECAL, + GX_BLEND, + GX_REPLACE, + GX_PASSCLR, +} GXTevMode; + +typedef enum _GXTexMtxType { + GX_MTX3x4, + GX_MTX2x4, +} GXTexMtxType; + +typedef enum _GXTexGenType { + GX_TG_MTX3x4, + GX_TG_MTX2x4, + GX_TG_BUMP0, + GX_TG_BUMP1, + GX_TG_BUMP2, + GX_TG_BUMP3, + GX_TG_BUMP4, + GX_TG_BUMP5, + GX_TG_BUMP6, + GX_TG_BUMP7, + GX_TG_SRTG, +} GXTexGenType; + +typedef enum _GXPosNrmMtx { + GX_PNMTX0 = 0, + GX_PNMTX1 = 3, + GX_PNMTX2 = 6, + GX_PNMTX3 = 9, + GX_PNMTX4 = 12, + GX_PNMTX5 = 15, + GX_PNMTX6 = 18, + GX_PNMTX7 = 21, + GX_PNMTX8 = 24, + GX_PNMTX9 = 27, +} GXPosNrmMtx; + +typedef enum _GXTexMtx { + GX_TEXMTX0 = 30, + GX_TEXMTX1 = 33, + GX_TEXMTX2 = 36, + GX_TEXMTX3 = 39, + GX_TEXMTX4 = 42, + GX_TEXMTX5 = 45, + GX_TEXMTX6 = 48, + GX_TEXMTX7 = 51, + GX_TEXMTX8 = 54, + GX_TEXMTX9 = 57, + GX_IDENTITY = 60, +} GXTexMtx; + +typedef enum _GXChannelID { + GX_COLOR0, + GX_COLOR1, + GX_ALPHA0, + GX_ALPHA1, + GX_COLOR0A0, + GX_COLOR1A1, + GX_COLOR_ZERO, + GX_ALPHA_BUMP, + GX_ALPHA_BUMPN, + GX_COLOR_NULL = 0xFF, +} GXChannelID; + +typedef enum _GXTexGenSrc { + GX_TG_POS, + GX_TG_NRM, + GX_TG_BINRM, + GX_TG_TANGENT, + GX_TG_TEX0, + GX_TG_TEX1, + GX_TG_TEX2, + GX_TG_TEX3, + GX_TG_TEX4, + GX_TG_TEX5, + GX_TG_TEX6, + GX_TG_TEX7, + GX_TG_TEXCOORD0, + GX_TG_TEXCOORD1, + GX_TG_TEXCOORD2, + GX_TG_TEXCOORD3, + GX_TG_TEXCOORD4, + GX_TG_TEXCOORD5, + GX_TG_TEXCOORD6, + GX_TG_COLOR0, + GX_TG_COLOR1, + GX_MAX_TEXGENSRC, +} GXTexGenSrc; + +typedef enum _GXBlendMode { + GX_BM_NONE, + GX_BM_BLEND, + GX_BM_LOGIC, + GX_BM_SUBTRACT, + GX_MAX_BLENDMODE, +} GXBlendMode; + +typedef enum _GXBlendFactor { + GX_BL_ZERO, + GX_BL_ONE, + GX_BL_SRCCLR, + GX_BL_INVSRCCLR, + GX_BL_SRCALPHA, + GX_BL_INVSRCALPHA, + GX_BL_DSTALPHA, + GX_BL_INVDSTALPHA, + GX_BL_DSTCLR = GX_BL_SRCCLR, + GX_BL_INVDSTCLR = GX_BL_INVSRCCLR, +} GXBlendFactor; + +typedef enum _GXLogicOp { + GX_LO_CLEAR, + GX_LO_AND, + GX_LO_REVAND, + GX_LO_COPY, + GX_LO_INVAND, + GX_LO_NOOP, + GX_LO_XOR, + GX_LO_OR, + GX_LO_NOR, + GX_LO_EQUIV, + GX_LO_INV, + GX_LO_REVOR, + GX_LO_INVCOPY, + GX_LO_INVOR, + GX_LO_NAND, + GX_LO_SET, +} GXLogicOp; + +typedef enum _GXCompCnt { + GX_POS_XY = 0, + GX_POS_XYZ = 1, + GX_NRM_XYZ = 0, + GX_NRM_NBT = 1, + GX_NRM_NBT3 = 2, + GX_CLR_RGB = 0, + GX_CLR_RGBA = 1, + GX_TEX_S = 0, + GX_TEX_ST = 1, +} GXCompCnt; + +typedef enum _GXCompType { + GX_U8 = 0, + GX_S8 = 1, + GX_U16 = 2, + GX_S16 = 3, + GX_F32 = 4, + GX_RGB565 = 0, + GX_RGB8 = 1, + GX_RGBX8 = 2, + GX_RGBA4 = 3, + GX_RGBA6 = 4, + GX_RGBA8 = 5, +} GXCompType; + +typedef enum _GXPTTexMtx { + GX_PTTEXMTX0 = 64, + GX_PTTEXMTX1 = 67, + GX_PTTEXMTX2 = 70, + GX_PTTEXMTX3 = 73, + GX_PTTEXMTX4 = 76, + GX_PTTEXMTX5 = 79, + GX_PTTEXMTX6 = 82, + GX_PTTEXMTX7 = 85, + GX_PTTEXMTX8 = 88, + GX_PTTEXMTX9 = 91, + GX_PTTEXMTX10 = 94, + GX_PTTEXMTX11 = 97, + GX_PTTEXMTX12 = 100, + GX_PTTEXMTX13 = 103, + GX_PTTEXMTX14 = 106, + GX_PTTEXMTX15 = 109, + GX_PTTEXMTX16 = 112, + GX_PTTEXMTX17 = 115, + GX_PTTEXMTX18 = 118, + GX_PTTEXMTX19 = 121, + GX_PTIDENTITY = 125, +} GXPTTexMtx; + +typedef enum _GXTevRegID { + GX_TEVPREV, + GX_TEVREG0, + GX_TEVREG1, + GX_TEVREG2, + GX_MAX_TEVREG, +} GXTevRegID; + +typedef enum _GXDiffuseFn { + GX_DF_NONE, + GX_DF_SIGN, + GX_DF_CLAMP, +} GXDiffuseFn; + +typedef enum _GXColorSrc { + GX_SRC_REG, + GX_SRC_VTX, +} GXColorSrc; + +typedef enum _GXAttnFn { + GX_AF_SPEC, + GX_AF_SPOT, + GX_AF_NONE, +} GXAttnFn; + +typedef enum _GXLightID { + GX_LIGHT0 = 0x001, + GX_LIGHT1 = 0x002, + GX_LIGHT2 = 0x004, + GX_LIGHT3 = 0x008, + GX_LIGHT4 = 0x010, + GX_LIGHT5 = 0x020, + GX_LIGHT6 = 0x040, + GX_LIGHT7 = 0x080, + GX_MAX_LIGHT = 0x100, + GX_LIGHT_NULL = 0, +} GXLightID; + +typedef enum _GXTexOffset { + GX_TO_ZERO, + GX_TO_SIXTEENTH, + GX_TO_EIGHTH, + GX_TO_FOURTH, + GX_TO_HALF, + GX_TO_ONE, + GX_MAX_TEXOFFSET, +} GXTexOffset; + +typedef enum _GXSpotFn { + GX_SP_OFF, + GX_SP_FLAT, + GX_SP_COS, + GX_SP_COS2, + GX_SP_SHARP, + GX_SP_RING1, + GX_SP_RING2, +} GXSpotFn; + +typedef enum _GXDistAttnFn { + GX_DA_OFF, + GX_DA_GENTLE, + GX_DA_MEDIUM, + GX_DA_STEEP, +} GXDistAttnFn; + +typedef enum _GXCullMode { + GX_CULL_NONE, + GX_CULL_FRONT, + GX_CULL_BACK, + GX_CULL_ALL, +} GXCullMode; + +typedef enum _GXTevSwapSel { + GX_TEV_SWAP0 = 0, + GX_TEV_SWAP1, + GX_TEV_SWAP2, + GX_TEV_SWAP3, + GX_MAX_TEVSWAP, +} GXTevSwapSel; + +typedef enum _GXTevColorChan { + GX_CH_RED = 0, + GX_CH_GREEN, + GX_CH_BLUE, + GX_CH_ALPHA, +} GXTevColorChan; + +typedef enum _GXFogType { + GX_FOG_NONE = 0, + GX_FOG_PERSP_LIN = 2, + GX_FOG_PERSP_EXP = 4, + GX_FOG_PERSP_EXP2 = 5, + GX_FOG_PERSP_REVEXP = 6, + GX_FOG_PERSP_REVEXP2 = 7, + GX_FOG_ORTHO_LIN = 10, + GX_FOG_ORTHO_EXP = 12, + GX_FOG_ORTHO_EXP2 = 13, + GX_FOG_ORTHO_REVEXP = 14, + GX_FOG_ORTHO_REVEXP2 = 15, + GX_FOG_LIN = GX_FOG_PERSP_LIN, + GX_FOG_EXP = GX_FOG_PERSP_EXP, + GX_FOG_EXP2 = GX_FOG_PERSP_EXP2, + GX_FOG_REVEXP = GX_FOG_PERSP_REVEXP, + GX_FOG_REVEXP2 = GX_FOG_PERSP_REVEXP2, +} GXFogType; + +typedef enum _GXTevColorArg { + GX_CC_CPREV, + GX_CC_APREV, + GX_CC_C0, + GX_CC_A0, + GX_CC_C1, + GX_CC_A1, + GX_CC_C2, + GX_CC_A2, + GX_CC_TEXC, + GX_CC_TEXA, + GX_CC_RASC, + GX_CC_RASA, + GX_CC_ONE, + GX_CC_HALF, + GX_CC_KONST, + GX_CC_ZERO, +} GXTevColorArg; + +typedef enum _GXTevAlphaArg { + GX_CA_APREV, + GX_CA_A0, + GX_CA_A1, + GX_CA_A2, + GX_CA_TEXA, + GX_CA_RASA, + GX_CA_KONST, + GX_CA_ZERO, +} GXTevAlphaArg; + +typedef enum _GXTevOp { + GX_TEV_ADD = 0, + GX_TEV_SUB = 1, + GX_TEV_COMP_R8_GT = 8, + GX_TEV_COMP_R8_EQ = 9, + GX_TEV_COMP_GR16_GT = 10, + GX_TEV_COMP_GR16_EQ = 11, + GX_TEV_COMP_BGR24_GT = 12, + GX_TEV_COMP_BGR24_EQ = 13, + GX_TEV_COMP_RGB8_GT = 14, + GX_TEV_COMP_RGB8_EQ = 15, + GX_TEV_COMP_A8_GT = GX_TEV_COMP_RGB8_GT, + GX_TEV_COMP_A8_EQ = GX_TEV_COMP_RGB8_EQ, +} GXTevOp; + +typedef enum _GXTevBias { + GX_TB_ZERO, + GX_TB_ADDHALF, + GX_TB_SUBHALF, + GX_MAX_TEVBIAS, +} GXTevBias; + +typedef enum _GXTevScale { + GX_CS_SCALE_1, + GX_CS_SCALE_2, + GX_CS_SCALE_4, + GX_CS_DIVIDE_2, + GX_MAX_TEVSCALE, +} GXTevScale; + +typedef enum _GXTevKColorSel { + GX_TEV_KCSEL_8_8 = 0x00, + GX_TEV_KCSEL_7_8 = 0x01, + GX_TEV_KCSEL_6_8 = 0x02, + GX_TEV_KCSEL_5_8 = 0x03, + GX_TEV_KCSEL_4_8 = 0x04, + GX_TEV_KCSEL_3_8 = 0x05, + GX_TEV_KCSEL_2_8 = 0x06, + GX_TEV_KCSEL_1_8 = 0x07, + GX_TEV_KCSEL_1 = GX_TEV_KCSEL_8_8, + GX_TEV_KCSEL_3_4 = GX_TEV_KCSEL_6_8, + GX_TEV_KCSEL_1_2 = GX_TEV_KCSEL_4_8, + GX_TEV_KCSEL_1_4 = GX_TEV_KCSEL_2_8, + GX_TEV_KCSEL_K0 = 0x0C, + GX_TEV_KCSEL_K1 = 0x0D, + GX_TEV_KCSEL_K2 = 0x0E, + GX_TEV_KCSEL_K3 = 0x0F, + GX_TEV_KCSEL_K0_R = 0x10, + GX_TEV_KCSEL_K1_R = 0x11, + GX_TEV_KCSEL_K2_R = 0x12, + GX_TEV_KCSEL_K3_R = 0x13, + GX_TEV_KCSEL_K0_G = 0x14, + GX_TEV_KCSEL_K1_G = 0x15, + GX_TEV_KCSEL_K2_G = 0x16, + GX_TEV_KCSEL_K3_G = 0x17, + GX_TEV_KCSEL_K0_B = 0x18, + GX_TEV_KCSEL_K1_B = 0x19, + GX_TEV_KCSEL_K2_B = 0x1A, + GX_TEV_KCSEL_K3_B = 0x1B, + GX_TEV_KCSEL_K0_A = 0x1C, + GX_TEV_KCSEL_K1_A = 0x1D, + GX_TEV_KCSEL_K2_A = 0x1E, + GX_TEV_KCSEL_K3_A = 0x1F, +} GXTevKColorSel; + +typedef enum _GXTevKAlphaSel { + GX_TEV_KASEL_8_8 = 0x00, + GX_TEV_KASEL_7_8 = 0x01, + GX_TEV_KASEL_6_8 = 0x02, + GX_TEV_KASEL_5_8 = 0x03, + GX_TEV_KASEL_4_8 = 0x04, + GX_TEV_KASEL_3_8 = 0x05, + GX_TEV_KASEL_2_8 = 0x06, + GX_TEV_KASEL_1_8 = 0x07, + GX_TEV_KASEL_1 = GX_TEV_KASEL_8_8, + GX_TEV_KASEL_3_4 = GX_TEV_KASEL_6_8, + GX_TEV_KASEL_1_2 = GX_TEV_KASEL_4_8, + GX_TEV_KASEL_1_4 = GX_TEV_KASEL_2_8, + GX_TEV_KASEL_K0_R = 0x10, + GX_TEV_KASEL_K1_R = 0x11, + GX_TEV_KASEL_K2_R = 0x12, + GX_TEV_KASEL_K3_R = 0x13, + GX_TEV_KASEL_K0_G = 0x14, + GX_TEV_KASEL_K1_G = 0x15, + GX_TEV_KASEL_K2_G = 0x16, + GX_TEV_KASEL_K3_G = 0x17, + GX_TEV_KASEL_K0_B = 0x18, + GX_TEV_KASEL_K1_B = 0x19, + GX_TEV_KASEL_K2_B = 0x1A, + GX_TEV_KASEL_K3_B = 0x1B, + GX_TEV_KASEL_K0_A = 0x1C, + GX_TEV_KASEL_K1_A = 0x1D, + GX_TEV_KASEL_K2_A = 0x1E, + GX_TEV_KASEL_K3_A = 0x1F, +} GXTevKAlphaSel; + +typedef enum _GXTevKColorID { + GX_KCOLOR0 = 0, + GX_KCOLOR1, + GX_KCOLOR2, + GX_KCOLOR3, + GX_MAX_KCOLOR, +} GXTevKColorID; + +typedef enum _GXZTexOp { + GX_ZT_DISABLE, + GX_ZT_ADD, + GX_ZT_REPLACE, + GX_MAX_ZTEXOP, +} GXZTexOp; + +typedef enum _GXIndTexFormat { + GX_ITF_8, + GX_ITF_5, + GX_ITF_4, + GX_ITF_3, + GX_MAX_ITFORMAT, +} GXIndTexFormat; + +typedef enum _GXIndTexBiasSel { + GX_ITB_NONE, + GX_ITB_S, + GX_ITB_T, + GX_ITB_ST, + GX_ITB_U, + GX_ITB_SU, + GX_ITB_TU, + GX_ITB_STU, + GX_MAX_ITBIAS, +} GXIndTexBiasSel; + +typedef enum _GXIndTexAlphaSel { + GX_ITBA_OFF, + GX_ITBA_S, + GX_ITBA_T, + GX_ITBA_U, + GX_MAX_ITBALPHA, +} GXIndTexAlphaSel; + +typedef enum _GXIndTexMtxID { + GX_ITM_OFF, + GX_ITM_0, + GX_ITM_1, + GX_ITM_2, + GX_ITM_S0 = 5, + GX_ITM_S1, + GX_ITM_S2, + GX_ITM_T0 = 9, + GX_ITM_T1, + GX_ITM_T2, +} GXIndTexMtxID; + +typedef enum _GXIndTexWrap { + GX_ITW_OFF, + GX_ITW_256, + GX_ITW_128, + GX_ITW_64, + GX_ITW_32, + GX_ITW_16, + GX_ITW_0, + GX_MAX_ITWRAP, +} GXIndTexWrap; + +typedef enum _GXIndTexStageID { + GX_INDTEXSTAGE0, + GX_INDTEXSTAGE1, + GX_INDTEXSTAGE2, + GX_INDTEXSTAGE3, + GX_MAX_INDTEXSTAGE, +} GXIndTexStageID; + +typedef enum _GXIndTexScale { + GX_ITS_1, + GX_ITS_2, + GX_ITS_4, + GX_ITS_8, + GX_ITS_16, + GX_ITS_32, + GX_ITS_64, + GX_ITS_128, + GX_ITS_256, + GX_MAX_ITSCALE, +} GXIndTexScale; + +typedef enum _GXClipMode { + GX_CLIP_ENABLE = 0, + GX_CLIP_DISABLE = 1, +} GXClipMode; + +typedef enum _GXTlut { + GX_TLUT0 = 0, + GX_TLUT1 = 1, + GX_TLUT2 = 2, + GX_TLUT3 = 3, + GX_TLUT4 = 4, + GX_TLUT5 = 5, + GX_TLUT6 = 6, + GX_TLUT7 = 7, + GX_TLUT8 = 8, + GX_TLUT9 = 9, + GX_TLUT10 = 10, + GX_TLUT11 = 11, + GX_TLUT12 = 12, + GX_TLUT13 = 13, + GX_TLUT14 = 14, + GX_TLUT15 = 15, + GX_BIGTLUT0 = 16, + GX_BIGTLUT1 = 17, + GX_BIGTLUT2 = 18, + GX_BIGTLUT3 = 19, +} GXTlut; + +typedef enum _GXTlutFmt { + GX_TL_IA8, + GX_TL_RGB565, + GX_TL_RGB5A3, + GX_MAX_TLUTFMT, +} GXTlutFmt; + +typedef enum _GXMiscToken { + GX_MT_NULL = 0, + GX_MT_XF_FLUSH = 1, + GX_MT_DL_SAVE_CONTEXT = 2, + GX_MT_ABORT_WAIT_COPYOUT = 3, +} GXMiscToken; + +typedef enum _GXTexCacheSize { + GX_TEXCACHE_32K, + GX_TEXCACHE_128K, + GX_TEXCACHE_512K, + GX_TEXCACHE_NONE +} GXTexCacheSize; + +typedef enum _GXPerf0 { + GX_PERF0_VERTICES, + GX_PERF0_CLIP_VTX, + GX_PERF0_CLIP_CLKS, + GX_PERF0_XF_WAIT_IN, + GX_PERF0_XF_WAIT_OUT, + GX_PERF0_XF_XFRM_CLKS, + GX_PERF0_XF_LIT_CLKS, + GX_PERF0_XF_BOT_CLKS, + GX_PERF0_XF_REGLD_CLKS, + GX_PERF0_XF_REGRD_CLKS, + GX_PERF0_CLIP_RATIO, + + GX_PERF0_TRIANGLES, + GX_PERF0_TRIANGLES_CULLED, + GX_PERF0_TRIANGLES_PASSED, + GX_PERF0_TRIANGLES_SCISSORED, + GX_PERF0_TRIANGLES_0TEX, + GX_PERF0_TRIANGLES_1TEX, + GX_PERF0_TRIANGLES_2TEX, + GX_PERF0_TRIANGLES_3TEX, + GX_PERF0_TRIANGLES_4TEX, + GX_PERF0_TRIANGLES_5TEX, + GX_PERF0_TRIANGLES_6TEX, + GX_PERF0_TRIANGLES_7TEX, + GX_PERF0_TRIANGLES_8TEX, + GX_PERF0_TRIANGLES_0CLR, + GX_PERF0_TRIANGLES_1CLR, + GX_PERF0_TRIANGLES_2CLR, + + GX_PERF0_QUAD_0CVG, + GX_PERF0_QUAD_NON0CVG, + GX_PERF0_QUAD_1CVG, + GX_PERF0_QUAD_2CVG, + GX_PERF0_QUAD_3CVG, + GX_PERF0_QUAD_4CVG, + GX_PERF0_AVG_QUAD_CNT, + + GX_PERF0_CLOCKS, + GX_PERF0_NONE + +} GXPerf0; + +typedef enum _GXPerf1 { + GX_PERF1_TEXELS, + GX_PERF1_TX_IDLE, + GX_PERF1_TX_REGS, + GX_PERF1_TX_MEMSTALL, + GX_PERF1_TC_CHECK1_2, + GX_PERF1_TC_CHECK3_4, + GX_PERF1_TC_CHECK5_6, + GX_PERF1_TC_CHECK7_8, + GX_PERF1_TC_MISS, + + GX_PERF1_VC_ELEMQ_FULL, + GX_PERF1_VC_MISSQ_FULL, + GX_PERF1_VC_MEMREQ_FULL, + GX_PERF1_VC_STATUS7, + GX_PERF1_VC_MISSREP_FULL, + GX_PERF1_VC_STREAMBUF_LOW, + GX_PERF1_VC_ALL_STALLS, + GX_PERF1_VERTICES, + + GX_PERF1_FIFO_REQ, + GX_PERF1_CALL_REQ, + GX_PERF1_VC_MISS_REQ, + GX_PERF1_CP_ALL_REQ, + + GX_PERF1_CLOCKS, + GX_PERF1_NONE + +} GXPerf1; + +typedef enum _GXVCachePerf { + GX_VC_POS, + GX_VC_NRM, + GX_VC_CLR0, + GX_VC_CLR1, + GX_VC_TEX0, + GX_VC_TEX1, + GX_VC_TEX2, + GX_VC_TEX3, + GX_VC_TEX4, + GX_VC_TEX5, + GX_VC_TEX6, + GX_VC_TEX7, + GX_VC_ALL = 0xf + +} GXVCachePerf; + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_GXENUM diff --git a/include/dolphin/gx/GXExtra.h b/include/dolphin/gx/GXExtra.h new file mode 100644 index 00000000..4cf7e499 --- /dev/null +++ b/include/dolphin/gx/GXExtra.h @@ -0,0 +1,36 @@ +#ifndef _DOLPHIN_GXEXTRA +#define _DOLPHIN_GXEXTRA + +// Extra types for PC +#ifdef TARGET_PC +#include +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + float r; + float g; + float b; + float a; +} GXColorF32; + +typedef enum { + GX_TF_R8_PC = 0x60, + GX_TF_RGBA8_PC = 0x61, +} GXPCTexFmt; + +void GXDestroyTexObj(GXTexObj* obj); +void GXDestroyTlutObj(GXTlutObj* obj); + +void GXColor4f32(float r, float g, float b, float a); + +#ifdef __cplusplus +} +#endif + +#endif // TARGET_PC + +#endif // _DOLPHIN_GXEXTRA diff --git a/include/dolphin/gx/GXFifo.h b/include/dolphin/gx/GXFifo.h new file mode 100644 index 00000000..85d61685 --- /dev/null +++ b/include/dolphin/gx/GXFifo.h @@ -0,0 +1,37 @@ +#ifndef _DOLPHIN_GXFIFO +#define _DOLPHIN_GXFIFO + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + u8 pad[128]; +} GXFifoObj; + +typedef void (*GXBreakPtCallback)(void); + +void GXInitFifoBase(GXFifoObj* fifo, void* base, u32 size); +void GXInitFifoPtrs(GXFifoObj* fifo, void* readPtr, void* writePtr); +void GXGetFifoPtrs(GXFifoObj* fifo, void** readPtr, void** writePtr); +GXFifoObj* GXGetCPUFifo(void); +GXFifoObj* GXGetGPFifo(void); +void GXSetCPUFifo(GXFifoObj* fifo); +void GXSetGPFifo(GXFifoObj* fifo); +void GXSaveCPUFifo(GXFifoObj* fifo); +void GXGetFifoStatus(GXFifoObj* fifo, GXBool* overhi, GXBool* underlow, u32* fifoCount, + GXBool* cpu_write, GXBool* gp_read, GXBool* fifowrap); +void GXGetGPStatus(GXBool* overhi, GXBool* underlow, GXBool* readIdle, GXBool* cmdIdle, + GXBool* brkpt); +void GXInitFifoLimits(GXFifoObj* fifo, u32 hiWaterMark, u32 loWaterMark); +GXBreakPtCallback GXSetBreakPtCallback(GXBreakPtCallback cb); +void GXEnableBreakPt(void* breakPt); +void GXDisableBreakPt(void); + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_GXFIFO diff --git a/include/dolphin/gx/GXFrameBuffer.h b/include/dolphin/gx/GXFrameBuffer.h new file mode 100644 index 00000000..469acbb9 --- /dev/null +++ b/include/dolphin/gx/GXFrameBuffer.h @@ -0,0 +1,66 @@ +#ifndef _DOLPHIN_GXFRAMEBUFFER +#define _DOLPHIN_GXFRAMEBUFFER + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// extern GXRenderModeObj GXNtsc240Ds; +// extern GXRenderModeObj GXNtsc240DsAa; +// extern GXRenderModeObj GXNtsc240Int; +// extern GXRenderModeObj GXNtsc240IntAa; +extern GXRenderModeObj GXNtsc480IntDf; +// extern GXRenderModeObj GXNtsc480Int; +// extern GXRenderModeObj GXNtsc480IntAa; +// extern GXRenderModeObj GXNtsc480Prog; +// extern GXRenderModeObj GXNtsc480ProgSoft; +// extern GXRenderModeObj GXNtsc480ProgAa; +// extern GXRenderModeObj GXMpal240Ds; +// extern GXRenderModeObj GXMpal240DsAa; +// extern GXRenderModeObj GXMpal240Int; +// extern GXRenderModeObj GXMpal240IntAa; +extern GXRenderModeObj GXMpal480IntDf; +// extern GXRenderModeObj GXMpal480Int; +// extern GXRenderModeObj GXMpal480IntAa; +// extern GXRenderModeObj GXPal264Ds; +// extern GXRenderModeObj GXPal264DsAa; +// extern GXRenderModeObj GXPal264Int; +// extern GXRenderModeObj GXPal264IntAa; +extern GXRenderModeObj GXPal528IntDf; +// extern GXRenderModeObj GXPal528Int; +// extern GXRenderModeObj GXPal524IntAa; +// extern GXRenderModeObj GXEurgb60Hz240Ds; +// extern GXRenderModeObj GXEurgb60Hz240DsAa; +// extern GXRenderModeObj GXEurgb60Hz240Int; +// extern GXRenderModeObj GXEurgb60Hz240IntAa; +extern GXRenderModeObj GXEurgb60Hz480IntDf; +// extern GXRenderModeObj GXEurgb60Hz480Int; +// extern GXRenderModeObj GXEurgb60Hz480IntAa; + +#define GX_MAX_Z24 0x00FFFFFF + +void GXSetCopyClear(GXColor clear_clr, u32 clear_z); +void GXAdjustForOverscan(GXRenderModeObj* rmin, GXRenderModeObj* rmout, u16 hor, u16 ver); +void GXCopyDisp(void* dest, GXBool clear); +void GXSetDispCopyGamma(GXGamma gamma); +void GXSetDispCopySrc(u16 left, u16 top, u16 wd, u16 ht); +void GXSetDispCopyDst(u16 wd, u16 ht); +f32 GXGetYScaleFactor(u16 efbHeight, u16 xfbHeight); +u32 GXSetDispCopyYScale(f32 vscale); +u16 GXGetNumXfbLines(u16 efbHeight, f32 yScale); +void GXSetCopyFilter(GXBool aa, u8 sample_pattern[12][2], GXBool vf, u8 vfilter[7]); +void GXSetPixelFmt(GXPixelFmt pix_fmt, GXZFmt16 z_fmt); +void GXSetTexCopySrc(u16 left, u16 top, u16 wd, u16 ht); +void GXSetTexCopyDst(u16 wd, u16 ht, GXTexFmt fmt, GXBool mipmap); +void GXCopyTex(void* dest, GXBool clear); + +void GXSetCopyClamp(GXFBClamp clamp); + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_GXFRAMEBUFFER diff --git a/include/dolphin/gx/GXGeometry.h b/include/dolphin/gx/GXGeometry.h new file mode 100644 index 00000000..632ebc69 --- /dev/null +++ b/include/dolphin/gx/GXGeometry.h @@ -0,0 +1,37 @@ +#ifndef _DOLPHIN_GXGEOMETRY +#define _DOLPHIN_GXGEOMETRY + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void GXSetVtxDesc(GXAttr attr, GXAttrType type); +void GXSetVtxDescv(GXVtxDescList* list); +void GXClearVtxDesc(void); +void GXSetVtxAttrFmt(GXVtxFmt vtxfmt, GXAttr attr, GXCompCnt cnt, GXCompType type, u8 frac); +void GXSetNumTexGens(u8 nTexGens); +void GXBegin(GXPrimitive type, GXVtxFmt vtxfmt, u16 nverts); +void GXSetTexCoordGen2(GXTexCoordID dst_coord, GXTexGenType func, GXTexGenSrc src_param, u32 mtx, + GXBool normalize, u32 postmtx); +void GXSetLineWidth(u8 width, GXTexOffset texOffsets); +void GXSetPointSize(u8 pointSize, GXTexOffset texOffsets); +void GXEnableTexOffsets(GXTexCoordID coord, GXBool line_enable, GXBool point_enable); +#ifdef TARGET_PC +void GXSetArray(GXAttr attr, const void* data, u32 size, u8 stride); +#else +void GXSetArray(GXAttr attr, const void* data, u8 stride); +#endif +void GXInvalidateVtxCache(void); + +static inline void GXSetTexCoordGen(GXTexCoordID dst_coord, GXTexGenType func, + GXTexGenSrc src_param, u32 mtx) { + GXSetTexCoordGen2(dst_coord, func, src_param, mtx, GX_FALSE, GX_PTIDENTITY); +} + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_GXGEOMETRY diff --git a/include/dolphin/gx/GXGet.h b/include/dolphin/gx/GXGet.h new file mode 100644 index 00000000..1eff8eb2 --- /dev/null +++ b/include/dolphin/gx/GXGet.h @@ -0,0 +1,28 @@ +#ifndef _DOLPHIN_GXGET +#define _DOLPHIN_GXGET + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +GXBool GXGetTexObjMipMap(const GXTexObj* obj); +GXTexFmt GXGetTexObjFmt(const GXTexObj* obj); +u16 GXGetTexObjHeight(const GXTexObj* obj); +u16 GXGetTexObjWidth(const GXTexObj* obj); +GXTexWrapMode GXGetTexObjWrapS(const GXTexObj* obj); +GXTexWrapMode GXGetTexObjWrapT(const GXTexObj* obj); +void* GXGetTexObjData(const GXTexObj* obj); +void GXGetProjectionv(f32* p); +void GXGetLightPos(const GXLightObj* lt_obj, f32* x, f32* y, f32* z); +void GXGetLightColor(const GXLightObj* lt_obj, GXColor* color); +void GXGetVtxAttrFmt(GXVtxFmt idx, GXAttr attr, GXCompCnt* compCnt, GXCompType* compType, + u8* shift); + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_GXGET diff --git a/include/dolphin/gx/GXLighting.h b/include/dolphin/gx/GXLighting.h new file mode 100644 index 00000000..a7e0ccc6 --- /dev/null +++ b/include/dolphin/gx/GXLighting.h @@ -0,0 +1,32 @@ +#ifndef _DOLPHIN_GXLIGHTING +#define _DOLPHIN_GXLIGHTING + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void GXSetNumChans(u8 nChans); +void GXSetChanCtrl(GXChannelID chan, GXBool enable, GXColorSrc amb_src, GXColorSrc mat_src, + u32 light_mask, GXDiffuseFn diff_fn, GXAttnFn attn_fn); +void GXSetChanAmbColor(GXChannelID chan, GXColor amb_color); +void GXSetChanMatColor(GXChannelID chan, GXColor mat_color); + +void GXInitLightSpot(GXLightObj* lt_obj, f32 cutoff, GXSpotFn spot_func); +void GXInitLightDistAttn(GXLightObj* lt_obj, f32 ref_distance, f32 ref_brightness, + GXDistAttnFn dist_func); +void GXInitLightPos(GXLightObj* lt_obj, f32 x, f32 y, f32 z); +void GXInitLightDir(GXLightObj* lt_obj, f32 nx, f32 ny, f32 nz); +void GXInitLightColor(GXLightObj* lt_obj, GXColor color); +void GXInitLightAttn(GXLightObj* lt_obj, f32 a0, f32 a1, f32 a2, f32 k0, f32 k1, f32 k2); +void GXInitLightAttnA(GXLightObj* lt_obj, f32 a0, f32 a1, f32 a2); +void GXInitLightAttnK(GXLightObj* lt_obj, f32 k0, f32 k1, f32 k2); +void GXLoadLightObjImm(GXLightObj* lt_obj, GXLightID light); + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_GXLIGHTING diff --git a/include/dolphin/gx/GXManage.h b/include/dolphin/gx/GXManage.h new file mode 100644 index 00000000..ab3a72c8 --- /dev/null +++ b/include/dolphin/gx/GXManage.h @@ -0,0 +1,24 @@ +#ifndef _DOLPHIN_GXMANAGE +#define _DOLPHIN_GXMANAGE + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*GXDrawDoneCallback)(void); + +GXFifoObj* GXInit(void* base, u32 size); +GXDrawDoneCallback GXSetDrawDoneCallback(GXDrawDoneCallback cb); +void GXDrawDone(void); +void GXSetDrawDone(void); +void GXFlush(void); +void GXPixModeSync(void); +void GXSetMisc(GXMiscToken token, u32 val); + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_GXMANAGE diff --git a/include/dolphin/gx/GXMisc.h b/include/dolphin/gx/GXMisc.h new file mode 100644 index 00000000..b95a6bbb --- /dev/null +++ b/include/dolphin/gx/GXMisc.h @@ -0,0 +1,20 @@ +#ifndef RVL_SDK_GX_MISC_H +#define RVL_SDK_GX_MISC_H +#include "types.h" +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +void GXSetMisc(GXMiscToken token, u32 val); +void GXFlush(); +void GXResetWriteGatherPipe(); + +void GXAbortFrame(); + +#ifdef __cplusplus +} +#endif +#endif \ No newline at end of file diff --git a/include/dolphin/gx/GXPerf.h b/include/dolphin/gx/GXPerf.h new file mode 100644 index 00000000..5c1a07b9 --- /dev/null +++ b/include/dolphin/gx/GXPerf.h @@ -0,0 +1,16 @@ +#ifndef _DOLPHIN_GXPERF +#define _DOLPHIN_GXPERF + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void GXReadXfRasMetric(u32* xf_wait_in, u32* xf_wait_out, u32* ras_busy, u32* clocks); + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_GXPERF diff --git a/include/dolphin/gx/GXPixel.h b/include/dolphin/gx/GXPixel.h new file mode 100644 index 00000000..7dfae08f --- /dev/null +++ b/include/dolphin/gx/GXPixel.h @@ -0,0 +1,29 @@ +#ifndef _DOLPHIN_GXPIXEL +#define _DOLPHIN_GXPIXEL + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void GXSetFog(GXFogType type, f32 startz, f32 endz, f32 nearz, f32 farz, GXColor color); +void GXSetFogColor(GXColor color); +// ? GXSetFogRangeAdj(); +void GXSetBlendMode(GXBlendMode type, GXBlendFactor src_factor, GXBlendFactor dst_factor, + GXLogicOp op); +void GXSetColorUpdate(GXBool update_enable); +void GXSetAlphaUpdate(GXBool update_enable); +void GXSetZMode(GXBool compare_enable, GXCompare func, GXBool update_enable); +void GXSetZCompLoc(GXBool before_tex); +void GXSetPixelFmt(GXPixelFmt pix_fmt, GXZFmt16 z_fmt); +void GXSetDither(GXBool dither); +void GXSetDstAlpha(GXBool enable, u8 alpha); +// ? GXSetFieldMask(); +// ? GXSetFieldMode(); + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_GXPIXEL diff --git a/include/dolphin/gx/GXPriv.h b/include/dolphin/gx/GXPriv.h new file mode 100644 index 00000000..db0286b8 --- /dev/null +++ b/include/dolphin/gx/GXPriv.h @@ -0,0 +1,38 @@ +#ifndef _DOLPHIN_GXPRIV +#define _DOLPHIN_GXPRIV + +#include "dolphin/gx/GXVert.h" + +typedef struct GXLightObj_ { + u32 padding[3]; + u32 color; + float a0; + float a1; + float a2; + float k0; + float k1; + float k2; + float px; + float py; + float pz; + float nx; + float ny; + float nz; +} GXLightObj_; + +#define XF_LIGHT_BASE 0x0600 +#define XF_LIGHT_SIZE 0x10 + +#define GX_FIFO_ADDR 0xCC008000 + +#define GX_WRITE_U8(v) (GXWGFifo.u8 = v) +#define GX_WRITE_U32(v) (GXWGFifo.u32 = v) + +typedef struct GXData { + u16 cpSRreg; + u16 cpCRreg; +} GXData; + +extern GXData* __GXData; + +#endif // _DOLPHIN_GXPRIV diff --git a/include/dolphin/gx/GXStruct.h b/include/dolphin/gx/GXStruct.h new file mode 100644 index 00000000..cf106058 --- /dev/null +++ b/include/dolphin/gx/GXStruct.h @@ -0,0 +1,79 @@ +#ifndef _DOLPHIN_GXSTRUCT +#define _DOLPHIN_GXSTRUCT + +#include +#include +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct _GXRenderModeObj { + VITVMode viTVmode; + u16 fbWidth; + u16 efbHeight; + u16 xfbHeight; + u16 viXOrigin; + u16 viYOrigin; + u16 viWidth; + u16 viHeight; + VIXFBMode xFBmode; + u8 field_rendering; + u8 aa; + u8 sample_pattern[12][2]; + u8 vfilter[7]; +} GXRenderModeObj; + +typedef struct _GXColor { + u8 r; + u8 g; + u8 b; + u8 a; +} GXColor; + +typedef struct _GXTexObj { +#ifdef TARGET_PC + u32 dummy[22]; +#else + u32 dummy[8]; +#endif +} GXTexObj; + +typedef struct _GXTlutObj { +#ifdef TARGET_PC + u32 dummy[4]; +#else + u32 dummy[3]; +#endif +} GXTlutObj; + +typedef struct _GXLightObj { + u32 dummy[16]; +} GXLightObj; + +typedef struct _GXVtxDescList { + GXAttr attr; + GXAttrType type; +} GXVtxDescList; + +typedef struct _GXColorS10 { + s16 r; + s16 g; + s16 b; + s16 a; +} GXColorS10; + +typedef struct _GXTexRegion { + u32 dummy[4]; +} GXTexRegion; + +typedef struct _GXTlutRegion { + u32 dummy[4]; +} GXTlutRegion; + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_GXSTRUCT diff --git a/include/dolphin/gx/GXTev.h b/include/dolphin/gx/GXTev.h new file mode 100644 index 00000000..01290a9d --- /dev/null +++ b/include/dolphin/gx/GXTev.h @@ -0,0 +1,37 @@ +#ifndef _DOLPHIN_GXTEV +#define _DOLPHIN_GXTEV + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void GXSetTevOp(GXTevStageID id, GXTevMode mode); +void GXSetTevColorIn(GXTevStageID stage, GXTevColorArg a, GXTevColorArg b, GXTevColorArg c, + GXTevColorArg d); +void GXSetTevAlphaIn(GXTevStageID stage, GXTevAlphaArg a, GXTevAlphaArg b, GXTevAlphaArg c, + GXTevAlphaArg d); +void GXSetTevColorOp(GXTevStageID stage, GXTevOp op, GXTevBias bias, GXTevScale scale, GXBool clamp, + GXTevRegID out_reg); +void GXSetTevAlphaOp(GXTevStageID stage, GXTevOp op, GXTevBias bias, GXTevScale scale, GXBool clamp, + GXTevRegID out_reg); +void GXSetTevColor(GXTevRegID id, GXColor color); +void GXSetTevColorS10(GXTevRegID id, GXColorS10 color); +void GXSetTevKColor(GXTevKColorID id, GXColor color); +void GXSetTevKColorSel(GXTevStageID stage, GXTevKColorSel sel); +void GXSetTevKAlphaSel(GXTevStageID stage, GXTevKAlphaSel sel); +void GXSetTevSwapMode(GXTevStageID stage, GXTevSwapSel ras_sel, GXTevSwapSel tex_sel); +void GXSetTevSwapModeTable(GXTevSwapSel table, GXTevColorChan red, GXTevColorChan green, + GXTevColorChan blue, GXTevColorChan alpha); +void GXSetAlphaCompare(GXCompare comp0, u8 ref0, GXAlphaOp op, GXCompare comp1, u8 ref1); +void GXSetZTexture(GXZTexOp op, GXTexFmt fmt, u32 bias); +void GXSetTevOrder(GXTevStageID stage, GXTexCoordID coord, GXTexMapID map, GXChannelID color); +void GXSetNumTevStages(u8 nStages); + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_GXTEV diff --git a/include/dolphin/gx/GXTexture.h b/include/dolphin/gx/GXTexture.h new file mode 100644 index 00000000..cb9a0051 --- /dev/null +++ b/include/dolphin/gx/GXTexture.h @@ -0,0 +1,37 @@ +#ifndef _DOLPHIN_GXTEXTURE +#define _DOLPHIN_GXTEXTURE + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef GXTexRegion* (*GXTexRegionCallback)(const GXTexObj* obj, GXTexMapID id); + +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 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, u32 idx); +void GXSetTexCoordScaleManually(GXTexCoordID coord, GXBool enable, u16 ss, u16 ts); +void GXInitTexCacheRegion(GXTexRegion* region, GXBool is_32b_mipmap, u32 tmem_even, + GXTexCacheSize size_even, u32 tmem_odd, GXTexCacheSize size_odd); +GXTexRegionCallback GXSetTexRegionCallback(GXTexRegionCallback callback); +void GXInvalidateTexRegion(const GXTexRegion* region); + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_GXTEXTURE diff --git a/include/dolphin/gx/GXTransform.h b/include/dolphin/gx/GXTransform.h new file mode 100644 index 00000000..bc3bf107 --- /dev/null +++ b/include/dolphin/gx/GXTransform.h @@ -0,0 +1,33 @@ +#ifndef _DOLPHIN_GXTRANSFORM +#define _DOLPHIN_GXTRANSFORM + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define GX_PROJECTION_SZ 7 + +#ifdef TARGET_PC +void GXSetProjection(const void* mtx, GXProjectionType type); +void GXLoadPosMtxImm(const void* mtx, u32 id); +void GXLoadNrmMtxImm(const void* mtx, u32 id); +void GXLoadTexMtxImm(const void* mtx, u32 id, GXTexMtxType type); +#else +void GXSetProjection(f32 mtx[4][4], GXProjectionType type); +void GXLoadPosMtxImm(f32 mtx[3][4], u32 id); +void GXLoadNrmMtxImm(f32 mtx[3][4], u32 id); +void GXLoadTexMtxImm(f32 mtx[][4], u32 id, GXTexMtxType type); +#endif +void GXSetViewport(f32 left, f32 top, f32 wd, f32 ht, f32 nearz, f32 farz); +void GXSetCurrentMtx(u32 id); +void GXSetViewportJitter(f32 left, f32 top, f32 wd, f32 ht, f32 nearz, f32 farz, u32 field); +void GXSetScissorBoxOffset(s32 x_off, s32 y_off); +void GXSetClipMode(GXClipMode mode); + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_GXTRANSFORM diff --git a/include/dolphin/gx/GXVert.h b/include/dolphin/gx/GXVert.h new file mode 100644 index 00000000..b5611113 --- /dev/null +++ b/include/dolphin/gx/GXVert.h @@ -0,0 +1,152 @@ +#ifndef _DOLPHIN_GXVERT +#define _DOLPHIN_GXVERT + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define GXFIFO_ADDR 0xCC008000 + +typedef union { + u8 u8; + u16 u16; + u32 u32; + u64 u64; + s8 s8; + s16 s16; + s32 s32; + s64 s64; + f32 f32; + f64 f64; +} PPCWGPipe; + +#ifdef __MWERKS__ +/*volatile*/ PPCWGPipe GXWGFifo : GXFIFO_ADDR; +#else +#define GXWGFifo (*(volatile PPCWGPipe*)GXFIFO_ADDR) +#endif + +#ifdef TARGET_PC + +void GXPosition3f32(f32 x, f32 y, f32 z); +void GXPosition3u16(u16 x, u16 y, u16 z); +void GXPosition3s16(s16 x, s16 y, s16 z); +void GXPosition3u8(u8 x, u8 y, u8 z); +void GXPosition3s8(s8 x, s8 y, s8 z); + +void GXPosition2f32(f32 x, f32 y); +void GXPosition2u16(u16 x, u16 y); +void GXPosition2s16(s16 x, s16 y); +void GXPosition2u8(u8 x, u8 y); +void GXPosition2s8(s8 x, s8 y); + +void GXPosition1x16(u16 index); +void GXPosition1x8(u8 index); + +void GXNormal3f32(f32 x, f32 y, f32 z); +void GXNormal3s16(s16 x, s16 y, s16 z); +void GXNormal3s8(s8 x, s8 y, s8 z); + +void GXNormal1x16(u16 index); +void GXNormal1x8(u8 index); + +void GXColor4u8(u8 r, u8 g, u8 b, u8 a); + +void GXColor3u8(u8 r, u8 g, u8 b); + +void GXColor1u32(u32 clr); +void GXColor1u16(u16 clr); + +void GXColor1x16(u16 index); +void GXColor1x8(u8 index); + +void GXTexCoord2f32(f32 s, f32 t); +void GXTexCoord2u16(u16 s, u16 t); +void GXTexCoord2s16(s16 s, s16 t); +void GXTexCoord2u8(u8 s, u8 t); +void GXTexCoord2s8(s8 s, s8 t); + +void GXTexCoord1f32(f32 s, f32 t); +void GXTexCoord1u16(u16 s, u16 t); +void GXTexCoord1s16(s16 s, s16 t); +void GXTexCoord1u8(u8 s, u8 t); +void GXTexCoord1s8(s8 s, s8 t); + +void GXTexCoord1x16(u16 index); +void GXTexCoord1x8(u8 index); + +extern void GXEnd(void); + +#else + +static inline void GXPosition2f32(f32 x, f32 y) { + GXWGFifo.f32 = x; + GXWGFifo.f32 = y; +} + +static inline void GXPosition3s16(s16 x, s16 y, s16 z) { + GXWGFifo.s16 = x; + GXWGFifo.s16 = y; + GXWGFifo.s16 = z; +} + +static inline void GXPosition3f32(f32 x, f32 y, f32 z) { + GXWGFifo.f32 = x; + GXWGFifo.f32 = y; + GXWGFifo.f32 = z; +} + +static inline void GXNormal3f32(f32 x, f32 y, f32 z) { + GXWGFifo.f32 = x; + GXWGFifo.f32 = y; + GXWGFifo.f32 = z; +} + +static inline void GXColor1u32(u32 v) { + GXWGFifo.u32 = v; +} + +static inline void GXColor4u8(u8 r, u8 g, u8 b, u8 a) { + GXWGFifo.u8 = r; + GXWGFifo.u8 = g; + GXWGFifo.u8 = b; + GXWGFifo.u8 = a; +} + +static inline void GXTexCoord2s16(s16 u, s16 v) { + GXWGFifo.s16 = u; + GXWGFifo.s16 = v; +} + +static inline void GXPosition2u16(u16 x, u16 y) +{ + GXWGFifo.u16 = x; + GXWGFifo.u16 = y; +} + +static inline void GXTexCoord2f32(f32 u, f32 v) { + GXWGFifo.f32 = u; + GXWGFifo.f32 = v; +} + +static inline void GXTexCoord2u8(u8 u, u8 v) +{ + GXWGFifo.u8 = u; + GXWGFifo.u8 = v; +} + +static inline void GXPosition1x8(u8 index) { + GXWGFifo.u8 = index; +} + +static inline void GXEnd(void) {} + +#endif + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_GXVERT diff --git a/include/dolphin/mtx.h b/include/dolphin/mtx.h new file mode 100644 index 00000000..228bb306 --- /dev/null +++ b/include/dolphin/mtx.h @@ -0,0 +1,29 @@ +#ifndef MTX_H +#define MTX_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef float Mtx[3][4]; +typedef float Mtx44[4][4]; + +typedef struct { + f32 x; + f32 y; + f32 z; +} Vec; + +void PSMTXConcat(const Mtx, const Mtx, Mtx); +void PSMTXCopy(const Mtx, Mtx); +void PSMTXIdentity(Mtx); +void PSMTXTranspose(const Mtx, Mtx); +u32 PSMTXInverse(const Mtx, Mtx); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/dolphin/os/__ppc_eabi_init.h b/include/dolphin/os/__ppc_eabi_init.h index 8db568de..41a83654 100644 --- a/include/dolphin/os/__ppc_eabi_init.h +++ b/include/dolphin/os/__ppc_eabi_init.h @@ -9,6 +9,55 @@ typedef void (*voidfunctionptr)(void); // pointer to function returning void __declspec(section ".ctors") extern voidfunctionptr _ctors[]; __declspec(section ".dtors") extern voidfunctionptr _dtors[]; +/** + * Linker Generated Symbols + */ + +// Declare linker symbols for a section in the ROM +#define DECL_ROM_SECTION(x) \ + extern u8 _f##x[]; \ + extern u8 _f##x##_rom[]; \ + extern u8 _e##x[]; + +// Declare linker symbols for a BSS section +#define DECL_BSS_SECTION(x) \ + extern u8 _f##x[]; \ + extern u8 _e##x[]; + +// Debugger stack +extern u8 _db_stack_addr[]; +extern u8 _db_stack_end[]; + +// Program arena +extern u8 __ArenaLo[]; +extern u8 __ArenaHi[]; + +// Program stack +extern u8 _stack_addr[]; +extern u8 _stack_end[]; + +// Small data bases +extern u8 _SDA_BASE_[]; +extern u8 _SDA2_BASE_[]; + +// ROM sections +DECL_ROM_SECTION(_init); +DECL_ROM_SECTION(extab); +DECL_ROM_SECTION(extabindex); +DECL_ROM_SECTION(_text); +DECL_ROM_SECTION(_ctors); +DECL_ROM_SECTION(_dtors); +DECL_ROM_SECTION(_rodata); +DECL_ROM_SECTION(_data); +DECL_ROM_SECTION(_sdata); +DECL_ROM_SECTION(_sdata2); +DECL_ROM_SECTION(_stack); + +// BSS sections +DECL_BSS_SECTION(_bss); +DECL_BSS_SECTION(_sbss); +DECL_BSS_SECTION(_sbss2); + void __init_hardware(void); void __flush_cache(void*, size_t); void __init_user(void); diff --git a/include/dolphin/vi.h b/include/dolphin/vi.h index 645cb5ec..52b1ea4d 100644 --- a/include/dolphin/vi.h +++ b/include/dolphin/vi.h @@ -7,6 +7,68 @@ extern "C" { #endif +#define VI_DISPLAY_PIX_SZ 2 + +#define VI_INTERLACE 0 +#define VI_NON_INTERLACE 1 +#define VI_PROGRESSIVE 2 + +#define VI_NTSC 0 +#define VI_PAL 1 +#define VI_MPAL 2 +#define VI_DEBUG 3 +#define VI_DEBUG_PAL 4 +#define VI_EURGB60 5 + +#define VI_TVMODE(FMT, INT) (((FMT) << 2) + (INT)) + +typedef enum +{ + VI_TVMODE_NTSC_INT = VI_TVMODE(VI_NTSC, VI_INTERLACE), + VI_TVMODE_NTSC_DS = VI_TVMODE(VI_NTSC, VI_NON_INTERLACE), + VI_TVMODE_NTSC_PROG = VI_TVMODE(VI_NTSC, VI_PROGRESSIVE), + + VI_TVMODE_PAL_INT = VI_TVMODE(VI_PAL, VI_INTERLACE), + VI_TVMODE_PAL_DS = VI_TVMODE(VI_PAL, VI_NON_INTERLACE), + + VI_TVMODE_EURGB60_INT = VI_TVMODE(VI_EURGB60, VI_INTERLACE), + VI_TVMODE_EURGB60_DS = VI_TVMODE(VI_EURGB60, VI_NON_INTERLACE), + + VI_TVMODE_MPAL_INT = VI_TVMODE(VI_MPAL, VI_INTERLACE), + VI_TVMODE_MPAL_DS = VI_TVMODE(VI_MPAL, VI_NON_INTERLACE), + + VI_TVMODE_DEBUG_INT = VI_TVMODE(VI_DEBUG, VI_INTERLACE), + + VI_TVMODE_DEBUG_PAL_INT = VI_TVMODE(VI_DEBUG_PAL, VI_INTERLACE), + VI_TVMODE_DEBUG_PAL_DS = VI_TVMODE(VI_DEBUG_PAL, VI_NON_INTERLACE) +} VITVMode; + +typedef enum +{ + VI_XFBMODE_SF = 0, // progressive scan + VI_XFBMODE_DF // interlaced +} VIXFBMode; + +#define VI_FIELD_ABOVE 1 +#define VI_FIELD_BELOW 0 + +// Maximum screen space +#define VI_MAX_WIDTH_NTSC 720 +#define VI_MAX_HEIGHT_NTSC 480 + +#define VI_MAX_WIDTH_PAL 720 +#define VI_MAX_HEIGHT_PAL 574 + +#define VI_MAX_WIDTH_MPAL 720 +#define VI_MAX_HEIGHT_MPAL 480 + +#define VI_MAX_WIDTH_EURGB60 VI_MAX_WIDTH_NTSC +#define VI_MAX_HEIGHT_EURGB60 VI_MAX_HEIGHT_NTSC + +typedef void (*VIRetraceCallback)(u32 retraceCount); + +#define VIPadFrameBufferWidth(width) ((u16)(((u16)(width) + 15) & ~15)) + void VISetBlack(BOOL); void VIWaitForRetrace(); void VIConfigurePan(u16 x_origin, u16 y_origin, u16 width, u16 height); diff --git a/include/libforest/emu64/emu64.hpp b/include/libforest/emu64/emu64.hpp new file mode 100644 index 00000000..5cd0e623 --- /dev/null +++ b/include/libforest/emu64/emu64.hpp @@ -0,0 +1,465 @@ +#ifndef EMU64_H +#define EMU64_H + +#include "types.h" +#include "va_args.h" +#include "MSL_C/printf.h" +#include "libforest/gbi_extensions.h" +#include "libforest/emu64/texture_cache.h" +#include "dolphin/os/__ppc_eabi_init.h" +#include "dolphin/gx.h" +#include "dolphin/mtx.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef EMU64_DEBUG +#define AFLAGS_MAX 100 +#else +#define AFLAGS_MAX 0 +#endif + +#define EMU64_TEX_BLOCK_SIZE_X 4 +#define EMU64_TEX_BLOCK_SIZE_Y 4 + +#define NUM_COMMANDS 64 +#define NUM_SEGMENTS 16 +#define DL_MAX_STACK_LEVEL 18 +#define DL_HISTORY_COUNT 16 +#define NUM_TILES 8 +#define NUM_TLUTS 16 +#define MTX_STACK_SIZE 10 +#define VTX_COUNT 128 +#define NUM_LIGHTS 8 + +#define EMU64_WARNING_COUNT 10 +#define EMU64_WARN_IDX_DL 4 + +#define EMU64_WARN_TIME 600 + +#define NUM_DIRTY_FLAGS 32 + +/* TODO: figure out where this actually belongs */ +namespace std { + typedef struct __va_list_struct __tag_va_List; +} + +typedef union { + GXColor color; + struct { + u8 r; + u8 g; + u8 b; + u8 a; + }; + u32 raw; +} EmuColor; + +typedef struct { + Vec position; + union { + struct { + u16 _pad0:2; + u16 cull_z_greater:1; + u16 cull_z_lesser:1; + u16 cull_y_greater:1; + u16 cull_y_lesser:1; + u16 cull_x_greater:1; + u16 cull_x_lesser:1; + u16 _pad1:7; + u16 nonshared:1; + }; + u16 flag; + }; + struct { + s16 s, t; + } tex_coords; + short pad; + Vec normal; + EmuColor color; +} Vertex; + +typedef struct { + EmuColor color; + Vec position; + + u8 unk[12]; + + struct { + f32 kc, k1, kq; /*kc = k0, kq = k2 */ + } attenuation; +} EmuLight; + +typedef struct { + void* img_addr; /* Texture RAM address */ + u16 width; /* Texture width */ + u16 height; /* Texture height */ + u8 format; /* Texture format */ + u8 size; /* Size in bpp */ + u8 tlut_name; /* Palette/TLUT idx */ + u8 pad; +} emu64_texture_info; + +class aflags_c { +public: + #ifndef EMU64_DEBUG + + int getMaxArray() { return AFLAGS_MAX; } + void set(u32 idx, u8 val) { this->flags[idx] = val; } /* @fabricated */ + int operator[](u32 idx) { return this->flags[idx]; } /* @fabricated */ + + #else + + int getMaxArray() { return AFLAGS_MAX; } + void set(u32 idx, u8 val) { } + int operator[](u32 idx) { return 0; } + + #endif + +private: + int flags[AFLAGS_MAX]; +}; + +class Texture { +public: + /* @weak */ + Texture(void* img_p, u16 w, u16 h, u8 fmt, u8 bpp) { + this->img_p = img_p; + this->width = w; + this->height = h; + this->n64_bpp = bpp; + this->n64_fmt = fmt; + this->blockX_size = EMU64_TEX_BLOCK_SIZE_X; + this->blockY_size = EMU64_TEX_BLOCK_SIZE_Y; + } + + /* @??? (maybe not weak?) */ + ~Texture() { }; + + /* @weak */ + u32 getOffset(int x, int y) { + const int size_x = sizeof(u16) * EMU64_TEX_BLOCK_SIZE_X; + const int size_y = sizeof(u16) * EMU64_TEX_BLOCK_SIZE_Y; + + return ((((u32)x / 8) + ((u32)(((u32)y / 8) * this->width) / 8)) * (size_x * size_y)) + + ((u32)y & 7) * size_x + + ((u32)x & 7); + } + + /* @weak */ + u32 getTexel(int block_x, int block_y) { + int x = (1 << this->blockX_size) - 1; + int y = (1 << this->blockY_size) - 1; + + block_x &= x; + block_y &= y; + + u32 ofs = this->getOffset(block_x, block_y); + + switch (this->n64_bpp) { + case G_IM_SIZ_4b: + { + u8* img_p = ((u8*)this->img_p) + ofs / 2; + if ((block_x & 1) == 0) { + return *img_p >> 4; + } + else { + return *img_p & 0xF; + } + } + + case G_IM_SIZ_8b: + { + return ((u8*)this->img_p)[ofs]; + } + + case G_IM_SIZ_16b: + { + return ((u16*)this->img_p)[ofs]; + } + + default: + { + return ((u32*)this->img_p)[ofs]; + } + } + } + + /* @weak */ + void putTexel(int block_x, int block_y, u32 texel) { + int x = (1 << this->blockX_size) - 1; + int y = (1 << this->blockY_size) - 1; + + block_x &= x; + block_y &= y; + + u32 ofs = this->getOffset(block_x, block_y); + + switch (this->n64_bpp) { + case G_IM_SIZ_4b: + { + u8* img_p = ((u8*)this->img_p) + ofs / 2; + if ((block_x & 1) == 0) { + *img_p = (*img_p & 0x0F) | (texel << 4); + } + else { + *img_p = (*img_p & 0xF0) | (texel & 0xF); + } + } + + case G_IM_SIZ_8b: + { + ((u8*)this->img_p)[ofs] = texel; + } + + case G_IM_SIZ_16b: + { + ((u16*)this->img_p)[ofs] = texel; + } + + case G_IM_SIZ_32b: + { + ((u32*)this->img_p)[ofs] = texel; + } + } + } + + /* Member variables */ + void* img_p; + u16 width; + u16 height; + u8 blockX_size; + u8 blockY_size; + u8 n64_fmt; + u8 n64_bpp; +}; + +#define EMU64_PRINTF_FLAG (1 << 1) +#define EMU64_PRINTF1_FLAG (1 << 2) +#define EMU64_PRINTF2_FLAG (1 << 3) +#define EMU64_PRINTF3_FLAG (1 << 4) + +class emu64_print { +public: + void Printf(const char* fmt, ...) { + va_list list; + + if ((this->print_flags & EMU64_PRINTF_FLAG)) { + va_start(list, fmt); + this->Vprintf(fmt, list); + va_end(list); + } + } + + void Printf0(const char* fmt, ...) { + va_list list; + + va_start(list, fmt); + this->Vprintf(fmt, list); + va_end(list); + } + + void Printf1(const char* fmt, ...) { + va_list list; + + if ((this->print_flags & EMU64_PRINTF1_FLAG)) { + va_start(list, fmt); + this->Vprintf(fmt, list); + va_end(list); + } + } + + void Printf2(const char* fmt, ...) { + va_list list; + + if ((this->print_flags & EMU64_PRINTF2_FLAG)) { + va_start(list, fmt); + this->Vprintf(fmt, list); + va_end(list); + } + } + + void Printf3(const char* fmt, ...) { + va_list list; + + if ((this->print_flags & EMU64_PRINTF3_FLAG)) { + va_start(list, fmt); + this->Vprintf(fmt, list); + va_end(list); + } + } + +protected: + u8 print_flags; + +private: + void Vprintf(const char* fmt, std::__tag_va_List* va_list) { vprintf(fmt, va_list); } +}; + +class emu64 : public emu64_print { +public: + + /* N64 texture format[N64 bit size] -> dol texture format */ + static u16 fmtxtbl[8][4]; + static char* warningString[EMU64_WARNING_COUNT]; + static int warningTime[EMU64_WARNING_COUNT]; + static bool displayWarning; + +private: + /* 0x0000 */ // u8 emu64_print::print_flags; + /* 0x0001 */ u8 print_commands; + /* 0x0002 */ bool disable_polygons; + /* 0x0004 */ u32 err_count; + /* 0x0008 */ u32 cmds_processed; /* ??? */ + /* 0x000C */ u32 total_vertices; + /* 0x0010 */ u32 vtx_load_calls; + /* 0x0014 */ u32 triangles; + /* 0x0018 */ u32 double_triangles; + /* 0x001C */ u32 quads; + /* 0x0020 */ u32 lines; + /* 0x0024 */ u32 load_ucode_calls; + /* 0x0028 */ u32 num_unknown_cmds; + /* 0x002C */ u32 num_unknown_ucodes; + /* 0x0030 */ int polygons; + /* 0x0034 */ u32 cullDL_calls; + /* 0x0038 */ u32 cullDL_outside_obj_count; + /* 0x003C */ u32 cullDL_visible_obj_count; + /* 0x0040 */ Gfx* gfx_p; + /* 0x0048 */ Gfx gfx; + /* 0x0050 */ u8 gfx_cmd; + /* 0x0054 */ void* work_ptr; + /* 0x0058 */ int end_dl; + /* 0x005C */ s8 ucode_len; + /* 0x0060 */ void* ucode_info; + /* 0x0064 */ void* ucode_p; + /* 0x0068 */ int _0068; /* ??? */ + /* 0x006C */ void* segments[NUM_SEGMENTS]; + /* 0x00AC */ Gfx* DL_stack[DL_MAX_STACK_LEVEL]; + /* 0x00F4 */ s8 DL_stack_level; + /* 0x00F8 */ u32 othermode_high; + /* 0x00FC */ u32 othermode_low; + /* 0x0100 */ u32 geometry_mode; + /* 0x0104 */ u32 _0104; + /* 0x0108 */ u32 combiner_high; + /* 0x010C */ u32 combiner_low; + /* 0x0110 */ emu64_texture_info texture_info[NUM_TILES]; + /* 0x0170 */ Gsetimg2 setimg2_cmds[NUM_TILES]; + /* 0x01B0 */ void* tlut_addresses[NUM_TLUTS]; + /* 0x01F0 */ GXTexObj tex_objs[NUM_TILES]; + /* 0x02F0 */ GXTlutObj tlut_objs[NUM_TLUTS]; + /* 0x03B0 */ bool use_dolphin_settile[NUM_TILES]; + /* 0x03B8 */ Gsettile settile_cmds[NUM_TILES]; + /* 0x03F8 */ Gsettile_dolphin settile_dolphin_cmds[NUM_TILES]; + /* 0x0438 */ Gsettilesize_dolphin settilesize_dolphin_cmds[NUM_TILES]; + /* 0x0478 */ Gsetimg_new now_setimg; + /* 0x0480 */ u8 tex_edge_alpha; + + /* 0x0484 */ union { + u32 primdepth; + struct { + u16 primdepth_z; /* Z value */ + u16 primdepth_dz; /* Delta Z */ + }; + }; + + /* 0x0488 */ EmuColor primitive_color; /* GX_TEVREG1 */ + /* 0x048C */ EmuColor environment_color; /* GX_TEVREG2 */ + /* 0x0490 */ EmuColor blend_color; + /* 0x0494 */ EmuColor fog_color; + /* 0x0498 */ s16 fog_zmult; + /* 0x049A */ s16 fog_zoffset; + /* 0x049C */ EmuColor fill_color; + /* 0x04A0 */ EmuColor fill_tev_color; /* GX_TEVREG0 */ + /* 0x04A4 */ bool dirty_flags[NUM_DIRTY_FLAGS]; + /* 0x04C4 */ Mtx original_projection_mtx; + /* 0x04F4 */ Mtx position_mtx; + /* 0x0524 */ Mtx model_view_mtx_stack[MTX_STACK_SIZE]; + /* 0x0704 */ Mtx position_mtx_stack[MTX_STACK_SIZE]; + /* 0x08E4 */ Mtx44 projection_mtx; + /* 0x0924 */ struct { + struct { + s8 x, y, z; + } x; + struct { + s8 x, y, z; + } y; + } lookAt; + /* 0x092C */ f32 near; /* Near clipping plane */ + /* 0x0930 */ f32 far; /* Far clipping plane */ + /* 0x0934 */ Mtx model_view_mtx; + /* 0x0964 */ Mtx _0964; /* UNCONFIRMED TYPE */ + /* 0x0994 */ int mtx_stack_size; + /* 0x0998 */ Gtexture_internal texture_gfx; + /* 0x09A0 */ f32 texture_scale_s; /* x-scale */ + /* 0x09A4 */ f32 texture_scale_t; /* y-scale */ + /* 0x09A8 */ Mtx44 ortho_mtx; + /* 0x09E8 */ GXProjectionType projection_type; + /* 0x09EC */ Mtx perspective_mtx; + /* 0x0A1C */ u32 _0A1C; + /* 0x0A20 */ u32 rdpHalf_1; + /* 0x0A24 */ EmuLight lights[NUM_LIGHTS]; + /* 0x0B64 */ u8 num_lights; + /* 0x0B68 */ u32 lookatx_cnt; + /* 0x0B6C */ u32 lookaty_cnt; + /* 0x0B70 */ u32 _0B70; + /* 0x0B74 */ u32 texconv_cnt; + /* 0x0B78 */ u32 vertex_cnt; + /* 0x0B7C */ u32 texconv_time; + /* 0x0B80 */ u32 rsprdp_time; + /* 0x0B84 */ u32 combine_time; + /* 0x0B88 */ u32 spvertex_time; + /* 0x0B8C */ u32 setup_time; + /* 0x0B90 */ u32 loadblock_time; + /* 0x0B94 */ u32 loadtlut_time; + /* 0x0B98 */ u32 matrix_time; + /* 0x0B9C */ u32 polygons_time; + /* 0x0BA0 */ u32 dirty_check_time; + /* 0x0BA4 */ u32 dirty_lightX_time; + /* 0x0BA8 */ u32 dirty_lightX_cnt + /* 0x0BAC */ u32 dirty_light_time; + /* 0x0BB0 */ u32 dirty_light_cnt; + /* 0x0BB4 */ u32 dirty_tex_time; + /* 0x0BB8 */ u32 dirty_tex_cnt; + /* 0x0BBC */ u32 dirty_tex1_time; + /* 0x0BC0 */ u32 dirty_tex1_cnt; + /* 0x0BC4 */ u32 dirty_tex2_time; + /* 0x0BC8 */ u32 dirty_tex2_cnt; + /* 0x0BCC */ u32 dirty_texmtx_time; + /* 0x0BD0 */ u32 dirty_texmtx_cnt; + /* 0x0BD4 */ u32 dirty_proj_time; + /* 0x0BD8 */ u32 dirty_primcolor_time; + /* 0x0BDC */ u32 dirty_envcolor_time; + /* 0x0BE0 */ u32 dirty_fillcolor_time; + /* 0x0BE4 */ u32 dirty_combine_mode_time; + /* 0x0BE8 */ u32 dirty_othermodeh_time; + /* 0x0BEC */ u32 dirty_othermodel_time; + /* 0x0BF0 */ u32 dirty_geometory_time; /* Yes, the devs misspelt this */ + /* 0x0BF4 */ u32 setuptex_time; + /* 0x0BF8 */ struct { + u32 time; + u32 calls; + } command_info[NUM_COMMANDS]; + /* 0x0DF8 */ u32 texture_cache_select_time; + /* 0x0DFC */ u32 guMtxL2F_time; + /* 0x0E00 */ u32 guMtxL2F_cnt; + /* 0x0E04 */ u32 combine_auto_cnt[5]; + /* 0x0E18 */ bool using_nonshared_mtx; + /* 0x0E1C */ Vertex vertices[VTX_COUNT]; + /* 0x201C */ u8 texture_adjust_mode; + /* 0x2020 */ u32 resolved_addresses; + /* 0x2024 */ u32 _2024; + /* 0x2028 */ u32 _2028; + /* 0x202C */ u32 _202C; + /* 0x2030 */ u32 abnormal_addresses; + /* 0x2034 */ bool rdp_pipe_sync_needed; + /* 0x2035 */ bool segment_set; + /* 0x2038 */ Gfx* dl_history[DL_HISTORY_COUNT]; + /* 0x2078 */ u8 dl_history_start; +}; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/libforest/emu64/texture_cache.h b/include/libforest/emu64/texture_cache.h new file mode 100644 index 00000000..06eb132b --- /dev/null +++ b/include/libforest/emu64/texture_cache.h @@ -0,0 +1,84 @@ +#ifndef TEXTURE_CACHE_H +#define TEXTURE_CACHE_H + +#include "types.h" +#include "libforest/gbi_extensions.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define TEX_CACHE_ALIGNMENT (32-1) /* 32 byte alignment */ +#define NUM_TEXTURE_CACHE_DATA 10 +#define TEXTURE_CACHE_LIST_SIZE 256 +#define TMEM_ENTRIES 128 + +#define TEX_CACHE_ALIGN(n)((n + TEX_CACHE_ALIGNMENT) & ~TEX_CACHE_ALIGNMENT) + +/* These would be initialized by the linker. TODO: Is there a better way to do this? */ +extern void* _data_segment_start; +extern void* _sdata2_segment_end; + +typedef struct { + void* addr; + Gloadblock loadblock; + Gloadtile loadtile; + Gsetimg_new setimg; +} tmem_t; + +typedef struct { + void* start; /* Start RAM address of cache */ + void* end; /* End RAM address of cache */ +} texture_cache_data_entry_t; + +typedef struct { + void* original; /* Original RAM address */ + void* converted; /* Converted RAM address */ +} texture_cache_entry_t; + +typedef struct texture_cache_s texture_cache_t; + +typedef void* (*texture_cache_search_func)(void* addr); +typedef int (*texture_cache_entry_func)(void* original, void* converted); +typedef void* (*texture_cache_alloc_func)(texture_cache_t* cache, u32 size); + +typedef struct { + texture_cache_search_func search; + texture_cache_entry_func entry; + texture_cache_alloc_func alloc; +} texture_cache_funcs; + +typedef struct texture_cache_s { + texture_cache_funcs* funcs; /* Pointer to texture cache funcs */ + u8* buffer_start; /* Start address of cache buffer */ + u8* buffer_end; /* End address of cache buffer */ + u8* buffer_current; /* Current write position of the cache buffer */ + u8* last_alloc_end; /* Points to end address from last cache alloc */ + u8* last_alloc_start; /* Points to the start address from last cache alloc */ + bool is_overflow; /* Set to true when the cache is full */ + u32 buffer_pos; /* Write index into cache buffer */ +} texture_cache_t; + +/* TMEM map */ +//static tmem_t tmem_map[TMEM_ENTRIES]; + + + +/* Shared alloc function */ +void* texture_cache_alloc(texture_cache_t* cache, u32 size); + +/* .data cache functions */ +void* texture_cache_data_search(void* addr); +int texture_cache_data_entry(void* original, void* converted); + +#define TEX_BUFFER_DATA_SIZE 0xC000 +#define TEX_BUFFER_BSS_SIZE 0x1000 + +extern "C" void emu64_texture_cache_data_entry_set(void* begin, void* end); +extern texture_cache_t* texture_cache_select(void* address); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/va_args.h b/include/va_args.h index 8948de6c..37d308cc 100644 --- a/include/va_args.h +++ b/include/va_args.h @@ -3,6 +3,10 @@ #include "types.h" +#if defined(__INTELLISENSE__) && defined(__cplusplus) +#define __builtin_va_info(v) /* definition for IDEs */ +#endif + typedef struct __va_list_struct { char gpr; char fpr; @@ -21,4 +25,4 @@ typedef _va_list_struct __va_list[1]; #define va_list __va_list #define __va_end(list) ((void)0) -#endif \ No newline at end of file +#endif diff --git a/rel/m_all_grow_ovl.c b/rel/m_all_grow_ovl.c index b4ca1b74..6e2d1913 100644 --- a/rel/m_all_grow_ovl.c +++ b/rel/m_all_grow_ovl.c @@ -3186,8 +3186,11 @@ static void mAGrw_SetGrass(lbRTC_time_c* now_time, lbRTC_time_c* grow_time, u16* } } #else +#pragma push +#pragma force_active on extern f64 lbl_806490a8; REL_SYMBOL_AT(lbl_806490a8, 0x806490A8); +#pragma pop static asm void mAGrw_SetGrass(lbRTC_time_c* now_time, lbRTC_time_c* grow_time, u16* cancel) { #include "asm/8051497c.s" diff --git a/rel/main.c b/rel/main.c index e5210541..bacfdf74 100644 --- a/rel/main.c +++ b/rel/main.c @@ -15,6 +15,7 @@ #include "Famicom/famicom.h" #include "m_debug.h" #include "dolphin/os.h" +#include "libforest/osreport.h" //TODO: actually add all the stacks and headers diff --git a/src/libforest/emu64/emu64.cc b/src/libforest/emu64/emu64.cc new file mode 100644 index 00000000..5f0eb4bd --- /dev/null +++ b/src/libforest/emu64/emu64.cc @@ -0,0 +1,296 @@ +#include "libforest/emu64/emu64.hpp" + +static aflags_c aflags; + +static u8 texture_buffer_data[TEX_BUFFER_DATA_SIZE]; +static u8 texture_buffer_bss[TEX_BUFFER_BSS_SIZE]; + +static u32 texture_cache_num; +static texture_cache_entry_t texture_cache_list[TEXTURE_CACHE_LIST_SIZE]; + +/* These are set externally during emu64 initialization */ +static texture_cache_data_entry_t texture_cache_data_entry_tbl[NUM_TEXTURE_CACHE_DATA]; +static int texture_cache_data_entry_num; + +static texture_cache_funcs texture_cache_data_func = { + &texture_cache_data_search, + &texture_cache_data_entry, + &texture_cache_alloc +}; + +static texture_cache_t texture_cache_data = { + &texture_cache_data_func, + &texture_buffer_data[0], + &texture_buffer_data[TEX_BUFFER_DATA_SIZE], + &texture_buffer_data[0], + nullptr, + nullptr, + FALSE, + 0 +}; + +/* .bss cache functions */ +void* texture_cache_bss_search(void* addr); +int texture_cache_bss_entry(void* original, void* converted); + +static texture_cache_funcs texture_cache_bss_func = { + &texture_cache_bss_search, + &texture_cache_bss_entry, + &texture_cache_alloc +}; + +static texture_cache_t texture_cache_bss = { + &texture_cache_bss_func, + &texture_buffer_bss[0], + &texture_buffer_bss[TEX_BUFFER_BSS_SIZE], + &texture_buffer_bss[0], + nullptr, + nullptr, + FALSE, + 0 +}; + +extern void emu64_texture_cache_data_entry_set(void* begin, void* end) { + texture_cache_data_entry_t* entry = &texture_cache_data_entry_tbl[texture_cache_data_entry_num]; + + entry->start = begin; + entry->end = end; + texture_cache_data_entry_num++; +} + +static texture_cache_t* texture_cache_select(void* addr) { + int i; + + if (aflags[5] < 1 && (addr < _f_rodata || addr > _e_data)) { + for (i = 0; i < texture_cache_data_entry_num; i++) { + if (addr >= texture_cache_data_entry_tbl[i].start && addr < texture_cache_data_entry_tbl[i].end) { + return &texture_cache_data; + } + } + + return &texture_cache_bss; + } + + return &texture_cache_data; +} + +static bool texture_cache_is_overflow(texture_cache_t* cache) { + return cache->is_overflow; +} + +static void texture_cache_clear(texture_cache_t* cache) { + cache->is_overflow = false; + cache->buffer_current = cache->buffer_start; +} + +/* @fabricated */ +MATCH_FORCESTRIP static u32 texture_cache_get_max_alloc_size(texture_cache_t* cache) { + return cache->buffer_current - cache->buffer_start; +} + +/* @fabricated */ +MATCH_FORCESTRIP static u32 texture_cache_get_alloc_size(texture_cache_t* cache) { + return cache->buffer_current - cache->last_alloc_start; +} + +/* @fabricated */ +MATCH_FORCESTRIP static u32 texture_cache_get_free_size(texture_cache_t* cache) { + return cache->buffer_end - cache->buffer_current; +} + +/* @fabricated */ +MATCH_FORCESTRIP static u32 texture_cache_get_heap_size(texture_cache_t* cache) { + return cache->buffer_end - cache->buffer_start; +} + +static void* texture_cache_alloc(texture_cache_t* cache, size_t size) { + u32 new_pos; + + cache->last_alloc_start = cache->buffer_current; + cache->last_alloc_end = (u8*)ALIGN_NEXT((u32)cache->buffer_current + size, 32); + + new_pos = cache->last_alloc_end - cache->buffer_start; + if (cache->buffer_pos < new_pos) { + cache->buffer_pos = new_pos; + } + + if (cache->buffer_end < cache->last_alloc_end) { + cache->is_overflow = true; + return nullptr; + } + + cache->buffer_current = cache->last_alloc_end; + return cache->last_alloc_start; +} + +static void* texture_cache_data_search(void* original_addr) { + int i; + + for (i = 0; i < texture_cache_num; i++) { + if (original_addr == texture_cache_list[i].original) { + return texture_cache_list[i].converted; + } + } + + return nullptr; +} + +static int texture_cache_data_entry(void* original_addr, void* converted_addr) { + if (texture_cache_num < TEXTURE_CACHE_LIST_SIZE && original_addr != nullptr && converted_addr != nullptr) { + texture_cache_entry_t* entry = &texture_cache_list[texture_cache_num++]; + + entry->original = original_addr; + entry->converted = converted_addr; + return 0; + } + + texture_cache_data.is_overflow = true; + return -1; +} + +static void* texture_cache_bss_search(void* original_addr) { + return nullptr; +} + +static int texture_cache_bss_entry(void* original_addr, void* converted_addr) { + return -1; +} + +static void texture_cache_list_clear() { + texture_cache_clear(&texture_cache_data); + texture_cache_num = 0; +} + +extern void emu64_refresh() { + texture_cache_list_clear(); +} + +/* Helper function to convert N64 texture format to Dolphin format */ +u16 emu64::fmtxtbl[8][4] = { + { GX_TF_CMPR, -1, GX_TF_RGB5A3, GX_TF_RGBA8 }, /* G_IM_FMT_RGBA */ + { -1, -1, -1, -1 }, /* G_IM_FMT_YUV */ + { GX_TF_C4, GX_TF_C8, 0xA, -1 }, /* G_IM_FMT_CI */ + { -1, GX_TF_IA4, GX_TF_IA8, -1 }, /* G_IM_FMT_IA */ + { GX_TF_I4, GX_TF_I8, GX_TF_RGB565, -1 }, /* G_IM_FMT_I */ + { GX_TF_CMPR, GX_CTF_A8, GX_TF_RGB5A3, -1 }, /* ?? */ + { -1, GX_TF_Z8, GX_TF_Z16, GX_TF_Z24X8 }, /* ?? */ + { -1, -1, -1, -1 } /* ?? */ +}; + +static u16 cvtN64ToDol(int n64_fmt, int n64_bpp) { + u16 dol = emu64::fmtxtbl[n64_fmt][n64_bpp]; + if (dol != 0xFFFF) { + return dol; + } + + return GX_TF_I4; +} + +MATCH_FORCESTRIP static f32 PsendoArcSinConvert(f32 arcsin) { + f32 g = 2.0f * (arcsin - 0.5f); + g = g * 0.4623f * g * g + g * 0.5377f; + + return 0.5f + g * 0.5f; +} + +MATCH_FORCESTRIP static void TextureLinearConvert1(Texture* src, Texture* dst) { + int y; + int x; + + for (y = 0; y < dst->height; y++) { + for (x = 0; x < dst->width; x++) { + f32 arcsin_x = (f32)x / (f32)(dst->width - 1); + f32 arcsin_y = (f32)y / (f32)(dst->height - 1); + + f32 sin_x = PsendoArcSinConvert(arcsin_x); + f32 sin_y = PsendoArcSinConvert(arcsin_y); + + dst->putTexel(x, y, src->getTexel(sin_x * (src->width - 1), sin_y * (src->height - 1))); + } + } +} + +MATCH_FORCESTRIP static void* TextureLinearConvert(void* img_p, unsigned int width, unsigned int height, unsigned int fmt, unsigned int bpp) { + texture_cache_t* tex_cache = texture_cache_select(NULL); + void* conv_img_p = tex_cache->funcs->alloc(tex_cache, 0x1000); + Texture src(img_p, width, height, fmt, bpp); + Texture dst(conv_img_p, width, height, fmt, bpp); + + TextureLinearConvert1(&src, &dst); + + return conv_img_p; +} + +static GXColor black_color = { 0, 0, 0, 0 }; +static GXColor white_color = { 255, 255, 255, 255 }; + +static void emu64_init2(GXRenderModeObj* render_mode) { + Mtx m; + + __GXSetIndirectMask(0); + + GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY); + GXSetTexCoordGen(GX_TEXCOORD1, GX_TG_MTX2x4, GX_TG_TEX1, GX_IDENTITY); + GXSetTexCoordGen(GX_TEXCOORD2, GX_TG_MTX2x4, GX_TG_TEX2, GX_IDENTITY); + GXSetTexCoordGen(GX_TEXCOORD3, GX_TG_MTX2x4, GX_TG_TEX3, GX_IDENTITY); + GXSetTexCoordGen(GX_TEXCOORD4, GX_TG_MTX2x4, GX_TG_TEX4, GX_IDENTITY); + GXSetTexCoordGen(GX_TEXCOORD5, GX_TG_MTX2x4, GX_TG_TEX5, GX_IDENTITY); + GXSetTexCoordGen(GX_TEXCOORD6, GX_TG_MTX2x4, GX_TG_TEX6, GX_IDENTITY); + GXSetTexCoordGen(GX_TEXCOORD7, GX_TG_MTX2x4, GX_TG_TEX7, GX_IDENTITY); + + GXSetNumTexGens(1); + GXClearVtxDesc(); + GXInvalidateVtxCache(); + GXSetLineWidth(6, GX_TO_ZERO); + GXSetPointSize(6, GX_TO_ZERO); + + GXEnableTexOffsets(GX_TEXCOORD0, GX_FALSE, GX_FALSE); + GXEnableTexOffsets(GX_TEXCOORD1, GX_FALSE, GX_FALSE); + GXEnableTexOffsets(GX_TEXCOORD2, GX_FALSE, GX_FALSE); + GXEnableTexOffsets(GX_TEXCOORD3, GX_FALSE, GX_FALSE); + GXEnableTexOffsets(GX_TEXCOORD4, GX_FALSE, GX_FALSE); + GXEnableTexOffsets(GX_TEXCOORD5, GX_FALSE, GX_FALSE); + GXEnableTexOffsets(GX_TEXCOORD6, GX_FALSE, GX_FALSE); + GXEnableTexOffsets(GX_TEXCOORD7, GX_FALSE, GX_FALSE); + + PSMTXIdentity(m); + GXLoadPosMtxImm(m, GX_PNMTX0); + GXLoadNrmMtxImm(m, GX_PNMTX0); + GXSetCurrentMtx(GX_PNMTX0); + GXLoadTexMtxImm(m, GX_IDENTITY, GX_MTX3x4); + + GXSetViewport(0.0f, 0.0f, render_mode->fbWidth, render_mode->xfbHeight, 0.0f, 1.0f); + GXSetCoPlanar(GX_FALSE); + GXSetCullMode(GX_CULL_BACK); + GXSetClipMode(GX_CLIP_ENABLE); + GXSetScissor(0, 0, render_mode->fbWidth, render_mode->efbHeight); + GXSetScissorBoxOffset(0, 0); + GXSetNumChans(0); + + GXSetChanCtrl(GX_COLOR0A0, GX_FALSE, GX_SRC_REG, GX_SRC_VTX, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE); + GXSetChanAmbColor(GX_COLOR0A0, black_color); + GXSetChanMatColor(GX_COLOR0A0, white_color); + + GXSetChanCtrl(GX_COLOR1A1, GX_FALSE, GX_SRC_REG, GX_SRC_VTX, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE); + GXSetChanAmbColor(GX_COLOR1A1, black_color); + GXSetChanMatColor(GX_COLOR1A1, white_color); + + GXInvalidateTexAll(); + + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0); + GXSetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD1, GX_TEXMAP1, GX_COLOR0A0); + GXSetTevOrder(GX_TEVSTAGE2, GX_TEXCOORD2, GX_TEXMAP2, GX_COLOR0A0); + GXSetTevOrder(GX_TEVSTAGE3, GX_TEXCOORD3, GX_TEXMAP3, GX_COLOR0A0); + GXSetTevOrder(GX_TEVSTAGE4, GX_TEXCOORD4, GX_TEXMAP4, GX_COLOR0A0); + GXSetTevOrder(GX_TEVSTAGE5, GX_TEXCOORD5, GX_TEXMAP5, GX_COLOR0A0); + GXSetTevOrder(GX_TEVSTAGE6, GX_TEXCOORD6, GX_TEXMAP6, GX_COLOR0A0); + GXSetTevOrder(GX_TEVSTAGE7, GX_TEXCOORD7, GX_TEXMAP7, GX_COLOR0A0); + GXSetTevOrder(GX_TEVSTAGE8, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL); + GXSetTevOrder(GX_TEVSTAGE9, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL); + GXSetTevOrder(GX_TEVSTAGE10, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL); + GXSetTevOrder(GX_TEVSTAGE11, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL); + GXSetTevOrder(GX_TEVSTAGE12, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL); + GXSetTevOrder(GX_TEVSTAGE13, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL); + GXSetTevOrder(GX_TEVSTAGE14, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL); + GXSetTevOrder(GX_TEVSTAGE15, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL); +}