summaryrefslogtreecommitdiff
path: root/arm9/lib
diff options
context:
space:
mode:
Diffstat (limited to 'arm9/lib')
-rw-r--r--arm9/lib/include/fx.h10
-rw-r--r--arm9/lib/include/gx.h371
-rw-r--r--arm9/lib/src/GX.c122
-rw-r--r--arm9/lib/src/GX_asm.c16
-rw-r--r--arm9/lib/src/GX_bgcnt.c195
-rw-r--r--arm9/lib/src/GX_g2.c66
-rw-r--r--arm9/lib/src/GX_g3.c36
-rw-r--r--arm9/lib/src/GX_g3_util.c260
-rw-r--r--arm9/lib/src/GX_g3b.c120
-rw-r--r--arm9/lib/src/GX_g3imm.c18
-rw-r--r--arm9/lib/src/GX_g3x.c235
-rw-r--r--arm9/lib/src/GX_load2d.c227
-rw-r--r--arm9/lib/src/GX_load3d.c124
-rw-r--r--arm9/lib/src/GX_state.c26
-rw-r--r--arm9/lib/src/GX_vramcnt.c579
15 files changed, 2402 insertions, 3 deletions
diff --git a/arm9/lib/include/fx.h b/arm9/lib/include/fx.h
index b1c3aa88..e0ba52f3 100644
--- a/arm9/lib/include/fx.h
+++ b/arm9/lib/include/fx.h
@@ -46,10 +46,14 @@ typedef s64 fx64c;
#define FX64C_INT_ABS(x) FX_INT_ABS(FX64C, x)
#define FX64C_FRAC(x) FX_FRAC(FX64C, x)
-#define FX32_MUL(a, b) ((fx32)(((fx64)a * b) >> FX32_INT_SHIFT))
-#define FX32_MUL_ADD_MUL(a, b, c, d) ((fx32)(((fx64)a * b + (fx64)c * d) >> FX32_INT_SHIFT))
+//TODO: clean up these macros
+#define FX32_MUL_NO_ROUND(a, b) ((fx32)(((fx64)(a) * (b)) >> FX32_INT_SHIFT))
+#define FX32_MUL(a, b) ((fx32)((((fx64)(a) * (b) + (1 << (FX32_INT_SHIFT - 1))) >> FX32_INT_SHIFT)))
+#define FX32_MUL_ADD_MUL(a, b, c, d) ((fx32)(((fx64)(a) * (b) + (fx64)c * d) >> FX32_INT_SHIFT))
//the extra term here is for rounding
-#define FX32_MUL_SUB_MUL(a, b, c, d) ((fx32)(((fx64)a * b - (fx64)c * d + (1 << (FX32_INT_SHIFT - 1))) >> FX32_INT_SHIFT))
+#define FX32_MUL_SUB_MUL(a, b, c, d) ((fx32)(((fx64)(a) * (b) - (fx64)c * d + (1 << (FX32_INT_SHIFT - 1))) >> FX32_INT_SHIFT))
+
+#define FX_MUL_FX32_FX64C(a, b) ((fx32)((((a) * (b) + ((fx64)1 << (FX64C_INT_SHIFT - 1))) >> FX64C_INT_SHIFT)))
struct Vecx32
{
diff --git a/arm9/lib/include/gx.h b/arm9/lib/include/gx.h
new file mode 100644
index 00000000..5abc2693
--- /dev/null
+++ b/arm9/lib/include/gx.h
@@ -0,0 +1,371 @@
+#ifndef GUARD_GX_H
+#define GUARD_GX_H
+
+#include "fx.h"
+
+//temporary while other files aren't decompiled
+void MIi_CpuCopy16(void *, void *, u32);
+void GXi_NopClearFifo128_(void *);
+void MI_Copy16B(void *, void *);
+void MI_DmaFill32Async(u32, void *, u32, u32, u32, u32);
+void MI_DmaFill32(u32, void *, u32, u32);
+void MIi_CpuClear32(u32, void *, u32);
+void MI_Copy64B(void *src, void *dst);
+void MI_WaitDma(u32);
+void MI_DmaCopy32Async(u32, void *, void *, u32, void *, void *);
+void MI_DmaCopy16(u32 unk, void *src, void *dst, u32 size);
+void MIi_CpuCopy16(void *src, void *dst, u32 size);
+void MI_DmaCopy32(u32 unk, void *src, void *dst, u32 size);
+void MIi_CpuCopy32(void *src, void *dst, u32 size);
+void OSi_UnlockVram(u16, u16);
+void MIi_CpuClear32(u32, void *, u32);
+
+//Todos before PR
+//TODO: Add defines for GX commands, add structs/unions for HW registers
+
+#define HW_REG_DIV_NUMER 0x04000290
+#define HW_REG_DIV_DENOM 0x04000298
+
+#define HW_REG_MTX_MODE 0x04000440
+#define HW_REG_MTX_LOAD_4x4 0x04000458
+#define HW_REG_MTX_LOAD_4x3 0x0400045C
+#define HW_REG_MTX_MULT_3x3 0x04000468
+
+#define HW_REG_END_VTXS 0x04000504
+#define HW_REG_GXSTAT 0x04000600
+#define HW_REG_DISP3DCNT 0x04000060
+#define HW_REG_BG0HOFS 0x04000010
+#define HW_REG_CLEAR_COLOR 0x04000350
+#define HW_REG_CLEAR_DEPTH 0x04000354
+#define HW_REG_CLRIMAGE_OFFSET 0x04000356
+#define HW_REG_FOG_COLOR 0x04000358
+#define HW_REG_FOG_OFFSET 0x0400035C
+#define HW_REG_BG0CNT 0x04000008
+#define HW_REG_POLYGON_ATTR 0x040004A4
+#define HW_REG_TEXIMAGE_PARAM 0x040004A8
+#define HW_REG_PLTT_BASE 0x040004AC
+
+#define HW_REG_POWCNT1 0x04000304
+
+#define HW_REG_GXFIFO 0x04000400
+#define HW_REG_MTX_IDENTITY 0x04000454
+#define HW_REG_MTX_POP 0x04000448
+#define HW_REG_MTX_MODE 0x04000440
+
+#define HW_REG_CLIPMTX_RESULT 0x04000640
+#define HW_REG_VECMTX_RESULT 0x04000680
+
+#define HW_REG_EDGE_COLOR 0x04000330
+#define HW_REG_FOG_TABLE 0x04000360
+
+#define HW_REG_SHININESS 0x040004D0
+
+#define HW_REG_MASTER_BRIGHT 0x0400006C
+
+#define HW_REG_VRAMCNT_A 0x04000240
+#define HW_REG_VRAMCNT_B 0x04000241
+#define HW_REG_VRAMCNT_C 0x04000242
+#define HW_REG_VRAMCNT_D 0x04000243
+#define HW_REG_VRAMCNT_E 0x04000244
+#define HW_REG_VRAMCNT_F 0x04000245
+#define HW_REG_VRAMCNT_G 0x04000246
+#define HW_REG_WRAMCNT 0x04000247
+#define HW_REG_VRAMCNT_H 0x04000248
+#define HW_REG_VRAMCNT_I 0x04000249
+
+#define HW_REG_DISPCNT 0x04000000
+#define HW_REG_DISPSTAT 0x04000004
+#define HW_REG_DISPCNT_2D 0x04001000
+
+#define HW_REG_DISP3DCNT 0x04000060
+
+#define HW_REG_BG2PA_A 0x04000020
+#define HW_REG_BG2PD_A 0x04000026
+#define HW_REG_BG3PA_A 0x04000030
+#define HW_REG_BG3PD_A 0x04000036
+#define HW_REG_BG2PA_B 0x04001020
+#define HW_REG_BG2PD_B 0x04001026
+#define HW_REG_BG3PA_B 0x04001030
+#define HW_REG_BG3PD_B 0x04001036
+
+#define HW_REG_BG0CNT_A 0x04000008
+#define HW_REG_BG1CNT_A 0x0400000A
+#define HW_REG_BG2CNT_A 0x0400000C
+#define HW_REG_BG3CNT_A 0x0400000E
+
+#define HW_REG_BG0CNT_B 0x04001008
+#define HW_REG_BG1CNT_B 0x0400100A
+#define HW_REG_BG2CNT_B 0x0400100C
+#define HW_REG_BG3CNT_B 0x0400100E
+
+#define HW_REG_DISPCNT_A 0x04000000
+#define HW_REG_DISPCNT_B 0x04001000
+
+//TODO: wait for register commit and replace these
+#define SETREG8(x, y) ((*(vu8 *)x) = y)
+#define SETREG16(x, y) ((*(vu16 *)x) = y)
+#define SETREG32(x, y) ((*(vu32 *)x) = y)
+#define SETREG64(x, y) ((*(vu64 *)x) = y)
+
+#define READREG8(x) (*(vu8 *)x)
+#define READREG16(x) (*(vu16 *)x)
+#define READREG32(x) (*(vu32 *)x)
+#define READREG64(x) (*(vu64 *)x)
+
+static inline void _GX_Load_16(u32 var, void *src, void *dst, u32 size){
+ if (var != -1 && size > 0x1C)
+ {
+ MI_DmaCopy16(var, src, dst, size);
+ }
+ else
+ {
+ MIi_CpuCopy16(src, dst, size);
+ }
+}
+
+static inline void _GX_Load_32(u32 var, void *src, void *dst, u32 size){
+ if (var != -1 && size > 0x30)
+ {
+ MI_DmaCopy32(var, src, dst, size);
+ }
+ else
+ {
+ MIi_CpuCopy32(src, dst, size);
+ }
+}
+
+static inline void _GX_Load_32_Async(u32 var, void *src, void *dst, u32 size, void *func, void *ptr){
+ if (var != -1)
+ {
+ MI_DmaCopy32Async(var, src, dst, size, func, ptr);
+ }
+ else
+ {
+ MIi_CpuCopy32(src, dst, size);
+ }
+}
+
+struct DL
+{
+ u8 *var00; //end pointer
+ u32 *var04; //aligned end pointer, used to write data
+ u8 *var08; //start pointer
+ u32 var0C;
+ u32 var10; //pad end with zero bool
+};
+
+struct VRAM_banks
+{
+ u16 var00; //lcdc
+ u16 var02; //bg
+ u16 var04; //obj
+ u16 var06; //arm7
+ u16 var08; //tex
+ u16 var0A; //texpltt
+ u16 var0C; //clearimage
+ u16 var0E; //bgextpltt
+ u16 var10; //objextpltt
+ u16 var12; //subbg
+ u16 var14; //subobj
+ u16 var16; //subbgextpltt
+ u16 var18; //subobjextpltt
+};
+
+//GX_g3
+void G3_BeginMakeDL(struct DL *displaylist, void *r1, u32 r2);
+s32 G3_EndMakeDL(struct DL *displaylist);
+
+//GX_g3_util
+void G3i_PerspectiveW_(fx32 fovsin, fx32 fovcos, fx32 ratio, fx32 near, fx32 far, fx32 scale, u32 load, struct Mtx44 *mtx);
+void G3i_OrthoW_(fx32 top, fx32 bottom, fx32 left, fx32 right, fx32 near, fx32 far, fx32 scale, u32 load, struct Mtx44 *mtx);
+void G3i_LookAt_(struct Vecx32 *a, struct Vecx32 *b, struct Vecx32 *c, u32 load, struct Mtx44 *mtx);
+void G3_RotX(fx32 sinphi, fx32 cosphi);
+void G3_RotY(fx32 sinphi, fx32 cosphi);
+void G3_RotZ(fx32 sinphi, fx32 cosphi);
+
+//GX_g3x
+void GXi_NopClearFifo128_(void *reg);
+void G3X_Init();
+void G3X_ResetMtxStack();
+void G3X_ClearFifo();
+void G3X_InitMtxStack();
+void G3X_ResetMtxStack_2();
+void G3X_SetFog(u32 enable, u32 alphamode, u32 depth, s32 offset);
+u32 G3X_GetClipMtx(struct Mtx44 *dst);
+u32 G3X_GetVectorMtx(struct Mtx33 *dst);
+void G3X_SetEdgeColorTable(void *tbl_ptr);
+void G3X_SetFogTable(void *tbl_ptr);
+void G3X_SetClearColor(u32 col, u32 alpha, u32 depth, u32 polygon_id, u32 enable_fog);
+void G3X_InitTable();
+u32 G3X_GetMtxStackLevelPV(u32 *level);
+u32 G3X_GetMtxStackLevelPJ(u32 *level);
+u32 G3X_GetBoxTestResult(u32 *result);
+void G3X_SetHOffset(u32 offset);
+
+//GX_g3b
+void G3BS_LoadMtx44(struct DL *displaylist, struct Mtx44 *mtx);
+void G3B_PushMtx(struct DL *displaylist);
+void G3B_PopMtx(struct DL *displaylist, void *mtx);
+void G3B_LoadMtx44(struct DL *displaylist, struct Mtx44 *mtx);
+void G3B_Color(struct DL * displaylist, u32 vtx_col);
+void G3B_Normal(struct DL * displaylist, fx16 x, fx16 y, fx16 z);
+void G3B_Vtx(struct DL * displaylist, fx32 x, fx32 y, fx32 z);
+void G3B_PolygonAttr(struct DL *displaylist, u32 r1, u32 r2, u32 r3, u32 r4, u32 r5, u32 r6);
+void G3B_MaterialColorDiffAmb(struct DL *displaylist, u32 diffuse_col, u32 ambient_col, u32 replace);
+void G3B_MaterialColorSpecEmi(struct DL *displaylist, u32 specular_col, u32 emission_col, u32 shiny_table);
+void G3B_LightVector(struct DL * displaylist, u32 light_num, fx16 x, fx16 y, fx16 z);
+void G3B_LightColor(struct DL * displaylist, u32 light_num, u32 col);
+void G3B_Begin(struct DL * displaylist, u32 type);
+void G3B_End(struct DL * displaylist);
+
+//GX_asm
+void GX_SendFifo48B(void *src, void *dst);
+
+//GX_vramcnt
+//some of the symbols don't match what the function does
+void GX_VRAMCNT_SetLCDC_(u32 mask);
+void GX_SetBankForBG(s32 bg);
+void GX_SetBankForOBJ(s32 obj);
+void GX_SetBankForBGExtPltt(s32 bgextpltt);
+void GX_SetBankForOBJExtPltt(s32 objextpltt);
+void GX_SetBankForTex(s32 tex);
+void GX_SetBankForTexPltt(s32 texpltt);
+void GX_SetBankForClearImage(s32 clearimage);
+void GX_SetBankForARM7(s32 arm7);
+void GX_SetBankForLCDC(s32 lcdc);
+void GX_SetBankForSubBG(s32 subbg);
+void GX_SetBankForSubOBJ(s32 subobj);
+void GX_SetBankForSubBGExtPltt(s32 subbgextpltt);
+void GX_SetBankForSubOBJExtPltt(s32 subobjextpltt);
+u32 FUN_020C6130(u16 *ptr);
+u32 GX_ResetBankForBG();
+u32 GX_ResetBankForOBJ();
+u32 GX_ResetBankForBGExtPltt();
+u32 GX_ResetBankForOBJExtPltt();
+u32 GX_ResetBankForTex();
+u32 GX_ResetBankForTexPltt();
+u32 GX_ResetBankForClearImage();
+u32 GX_ResetBankForSubBG();
+u32 FUN_020C605C();
+u32 FUN_020C6034();
+u32 GX_ResetBankForSubOBJ();
+u32 FUN_020C5F28(u16 *ptr);
+u32 disableBankForX_();
+u32 GX_DisableBankForOBJExtPltt_2();
+u32 GX_DisableBankForBGExtPltt();
+u32 GX_DisableBankForOBJExtPltt();
+u32 GX_DisableBankForTexPltt_2();
+u32 GX_DisableBankForTexPltt();
+u32 GX_DisableBankForClearImage();
+u32 GX_DisableBankForARM7();
+u32 GX_DisableBankForLCDC();
+u32 GX_DisableBankForSubBGExtPltt();
+u32 GX_DisableBankForSubOBJExtPltt_2();
+u32 FUN_020C5E04();
+u32 GX_DisableBankForSubOBJExtPltt();
+u32 GX_GetBankForBGExtPltt_2();
+u32 GX_GetBankForOBJ();
+u32 GX_GetBankForBGExtPltt();
+u32 GX_GetBankForOBJExtPltt();
+u32 FUN_020C5D8C();
+u32 GX_GetBankForTexPltt();
+u32 GX_GetBankForLCDC();
+u32 GX_GetBankForSubBGExtPltt_2();
+u32 GX_GetBankForSubOBJ();
+u32 GX_GetBankForSubBGExtPltt();
+u32 GX_GetBankForSubOBJExtPltt();
+
+//GX_bgcnt
+void *G2_GetBG0ScrPtr();
+void *G2S_GetBG0ScrPtr();
+void *G2_GetBG1ScrPtr();
+void *G2S_GetBG1ScrPtr();
+void *G2_GetBG2ScrPtr();
+void *G2S_GetBG2ScrPtr();
+void *G2_GetBG3ScrPtr();
+void *G2S_GetBG3ScrPtr();
+void *G2_GetBG0CharPtr();
+void *G2S_GetBG0CharPtr();
+void *G2_GetBG1CharPtr();
+void *G2S_GetBG1CharPtr();
+void *G2_GetBG2CharPtr();
+void *G2S_GetBG2CharPtr();
+void *G2_GetBG3CharPtr();
+void *G2S_GetBG3CharPtr();
+
+//GX_load2d
+void GX_LoadBGPltt(void *src, u32 offset, u32 size);
+void GXS_LoadBGPltt(void *src, u32 offset, u32 size);
+void GX_LoadOBJPltt(void *src, u32 offset, u32 size);
+void GXS_LoadOBJPltt(void *src, u32 offset, u32 size);
+void GX_LoadOAM(void *src, u32 offset, u32 size);
+void GXS_LoadOAM(void *src, u32 offset, u32 size);
+void GX_LoadOBJ(void *src, u32 offset, u32 size);
+void GXS_LoadOBJ(void *src, u32 offset, u32 size);
+void GX_LoadBG0Scr(void *src, u32 offset, u32 size);
+void GXS_LoadBG0Scr(void *src, u32 offset, u32 size);
+void GX_LoadBG1Scr(void *src, u32 offset, u32 size);
+void GXS_LoadBG1Scr(void *src, u32 offset, u32 size);
+void GX_LoadBG2Scr(void *src, u32 offset, u32 size);
+void GXS_LoadBG2Scr(void *src, u32 offset, u32 size);
+void GX_LoadBG3Scr(void *src, u32 offset, u32 size);
+void GXS_LoadBG3Scr(void *src, u32 offset, u32 size);
+void GX_LoadBG0Char(void *src, u32 offset, u32 size);
+void GXS_LoadBG0Char(void *src, u32 offset, u32 size);
+void GX_LoadBG1Char(void *src, u32 offset, u32 size);
+void GXS_LoadBG1Char(void *src, u32 offset, u32 size);
+void GX_LoadBG2Char(void *src, u32 offset, u32 size);
+void GXS_LoadBG2Char(void *src, u32 offset, u32 size);
+void GX_LoadBG3Char(void *src, u32 offset, u32 size);
+void GXS_LoadBG3Char(void *src, u32 offset, u32 size);
+void GX_BeginLoadBGExtPltt();
+void GX_LoadBGExtPltt(void *src, u32 offset, u32 size);
+void GX_EndLoadBGExtPltt();
+void GX_BeginLoadOBJExtPltt();
+void GX_LoadOBJExtPltt(void *src, u32 offset, u32 size);
+void GX_EndLoadOBJExtPltt();
+void GXS_BeginLoadBGExtPltt();
+void GXS_LoadBGExtPltt(void *src, u32 offset, u32 size);
+void GXS_EndLoadBGExtPltt();
+void GXS_BeginLoadOBJExtPltt();
+void GXS_LoadOBJExtPltt(void *src, u32 offset, u32 size);
+void GXS_EndLoadOBJExtPltt();
+
+//GX_load3d
+void GX_BeginLoadTex();
+void GX_LoadTex(void *src, u32 offset, u32 size);
+void GX_EndLoadTex();
+void GX_BeginLoadTexPltt();
+void GX_LoadTexPltt(void *src, u32 offset, u32 size);
+void GX_EndLoadTexPltt();
+void GX_BeginLoadClearImage();
+void GX_LoadClearImageColor(void *src, u32 size);
+void GX_LoadClearImageDepth(void *src, u32 size);
+void GX_EndLoadClearImage();
+
+//GX
+void GX_Init();
+u32 GX_HBlankIntr(u32 enable);
+u32 GX_VBlankIntr(u32 enable);
+void GX_DispOff();
+void GX_DispOn();
+void GX_SetGraphicsMode(u32 mode1, u32 mode2, u32 mode3);
+void GXS_SetGraphicsMode(u32 mode);
+void GXx_SetMasterBrightness_(vu16 *dst, s32 brightness);
+
+//GX_g2
+void G2x_SetBGyAffine_(u32 *ptr, struct Mtx22 *mtx, fx32 a, fx32 b, fx32 c, fx32 d);
+void G2x_SetBlendAlpha_(u32 *ptr, fx32 a, fx32 b, fx32 c, fx32 d);
+void G2x_SetBlendBrightness_(u16 *ptr, fx32 a, fx32 brightness);
+void G2x_SetBlendBrightnessExt_(u16 *ptr, fx32 a, fx32 b, fx32 c, fx32 d, fx32 brightness);
+void *G2x_ChangeBlendBrightness_(u16 *ptr, fx32 brightness);
+
+//GX_state
+void GX_InitGXState();
+
+//GX_g3imm
+void G3_LoadMtx43(struct Mtx43 *mtx);
+void G3_MultMtx43(struct Mtx43 *mtx);
+void G3_MultMtx33(struct Mtx33 *mtx);
+
+#endif //GUARD_GX_H
diff --git a/arm9/lib/src/GX.c b/arm9/lib/src/GX.c
new file mode 100644
index 00000000..bae16fca
--- /dev/null
+++ b/arm9/lib/src/GX.c
@@ -0,0 +1,122 @@
+#include "global.h"
+#include "main.h"
+#include "gx.h"
+
+extern u16 gUnk021D33BC;
+extern u16 gUnk021D33C0;
+extern u32 gUnk02106814;
+extern u16 gUnk02106810;
+
+ARM_FUNC void GX_Init(){
+ SETREG16(HW_REG_POWCNT1, READREG16(HW_REG_POWCNT1) | 0x8000);
+ SETREG16(HW_REG_POWCNT1, (READREG16(HW_REG_POWCNT1) & ~0x20E) | 0x20E);
+ SETREG16(HW_REG_POWCNT1, READREG16(HW_REG_POWCNT1) | 0x1);
+ GX_InitGXState();
+ u32 temp;
+ while (gUnk021D33BC == 0)
+ {
+ temp = OS_GetLockID();
+ if (temp == -3)
+ {
+ OS_Terminate();
+ }
+ gUnk021D33BC = temp;
+ }
+ SETREG16(HW_REG_DISPSTAT, 0x0);
+ SETREG32(HW_REG_DISPCNT, 0x0);
+ if (gUnk02106814 != -1)
+ {
+ MI_DmaFill32(gUnk02106814, (void *)HW_REG_BG0CNT_A, 0x0, 0x60);
+ SETREG16(HW_REG_MASTER_BRIGHT, 0x0);
+ MI_DmaFill32(gUnk02106814, (void *)HW_REG_DISPCNT_2D, 0x0, 0x70);
+ }
+ else
+ {
+ MIi_CpuClear32(0x0, (void *)HW_REG_BG0CNT_A, 0x60);
+ SETREG16(HW_REG_MASTER_BRIGHT, 0x0);
+ MIi_CpuClear32(0x0, (void *)HW_REG_DISPCNT_2D, 0x70);
+ }
+ SETREG16(HW_REG_BG2PA_A, 0x100);
+ SETREG16(HW_REG_BG2PD_A, 0x100);
+ SETREG16(HW_REG_BG3PA_A, 0x100);
+ SETREG16(HW_REG_BG3PD_A, 0x100);
+ SETREG16(HW_REG_BG2PA_B, 0x100);
+ SETREG16(HW_REG_BG2PD_B, 0x100);
+ SETREG16(HW_REG_BG3PA_B, 0x100);
+ SETREG16(HW_REG_BG3PD_B, 0x100);
+}
+
+ARM_FUNC u32 GX_HBlankIntr(u32 enable){
+ u32 temp = READREG16(HW_REG_DISPSTAT) & 0x10;
+ if (enable)
+ {
+ SETREG16(HW_REG_DISPSTAT, READREG16(HW_REG_DISPSTAT) | 0x10);
+ }
+ else
+ {
+ SETREG16(HW_REG_DISPSTAT, READREG16(HW_REG_DISPSTAT) & ~0x10);
+ }
+ return temp;
+}
+
+ARM_FUNC u32 GX_VBlankIntr(u32 enable){
+ u32 temp = READREG16(HW_REG_DISPSTAT) & 0x8;
+ if (enable)
+ {
+ SETREG16(HW_REG_DISPSTAT, READREG16(HW_REG_DISPSTAT) | 0x8);
+ }
+ else
+ {
+ SETREG16(HW_REG_DISPSTAT, READREG16(HW_REG_DISPSTAT) & ~0x8);
+ }
+ return temp;
+}
+
+ARM_FUNC void GX_DispOff(){
+ u32 temp = READREG32(HW_REG_DISPCNT);
+ gUnk02106810 = 0x0;
+ gUnk021D33C0 = (temp & 0x30000) >> 0x10;
+ SETREG32(HW_REG_DISPCNT, temp & ~0x30000);
+}
+
+ARM_FUNC void GX_DispOn(){
+ gUnk02106810 = 0x1;
+ if (gUnk021D33C0)
+ {
+ SETREG32(HW_REG_DISPCNT, READREG32(HW_REG_DISPCNT) & ~0x30000 | (gUnk021D33C0 << 0x10));
+
+ }
+ else
+ {
+ SETREG32(HW_REG_DISPCNT, READREG32(HW_REG_DISPCNT) | 0x10000);
+ }
+}
+
+ARM_FUNC void GX_SetGraphicsMode(u32 mode1, u32 mode2, u32 mode3){
+ u32 temp2 = READREG32(HW_REG_DISPCNT);
+ gUnk021D33C0 = mode1;
+ if (!gUnk02106810)
+ mode1 = 0;
+ SETREG32(HW_REG_DISPCNT, (mode2 | ((temp2 & 0xFFF0FFF0) | (mode1 << 0x10))) | (mode3 << 0x3));
+ if (!gUnk021D33C0)
+ gUnk02106810 = 0x0;
+}
+
+ARM_FUNC void GXS_SetGraphicsMode(u32 mode){
+ SETREG32(HW_REG_DISPCNT_2D, READREG32(HW_REG_DISPCNT_2D) & ~0x7 | mode);
+}
+
+ARM_FUNC void GXx_SetMasterBrightness_(vu16 *dst, s32 brightness){
+ if (!brightness)
+ {
+ *dst = 0x0;
+ }
+ else if (brightness > 0)
+ {
+ *dst = 0x4000 | brightness;
+ }
+ else
+ {
+ *dst = 0x8000 | -brightness;
+ }
+}
diff --git a/arm9/lib/src/GX_asm.c b/arm9/lib/src/GX_asm.c
new file mode 100644
index 00000000..1eb0a011
--- /dev/null
+++ b/arm9/lib/src/GX_asm.c
@@ -0,0 +1,16 @@
+#include "global.h"
+#include "main.h"
+#include "gx.h"
+
+//looks like asm and says asm on the tin...
+ARM_FUNC asm void GX_SendFifo48B(void *src, void *dst){
+ ldmia r0!, {r2-r3,r12}
+ stmia r1, {r2-r3,r12}
+ ldmia r0!, {r2-r3,r12}
+ stmia r1, {r2-r3,r12}
+ ldmia r0!, {r2-r3,r12}
+ stmia r1, {r2-r3,r12}
+ ldmia r0!, {r2-r3,r12}
+ stmia r1, {r2-r3,r12}
+ bx lr
+}
diff --git a/arm9/lib/src/GX_bgcnt.c b/arm9/lib/src/GX_bgcnt.c
new file mode 100644
index 00000000..1eeffab6
--- /dev/null
+++ b/arm9/lib/src/GX_bgcnt.c
@@ -0,0 +1,195 @@
+#include "global.h"
+#include "main.h"
+#include "gx.h"
+
+ARM_FUNC void *G2_GetBG0ScrPtr(){
+ u32 temp = (((READREG16(HW_REG_BG0CNT_A) & 0x1F00) >> 0x8) << 0xB);
+ return (void *)(0x6000000 + (((READREG32(HW_REG_DISPCNT_A) & 0x38000000) >> 0x1B) << 0x10) + temp);
+}
+
+ARM_FUNC void *G2S_GetBG0ScrPtr(){
+ return (void *)(0x6200000 + (((READREG16(HW_REG_BG0CNT_B) & 0x1F00) >> 0x8) << 0xB));
+}
+
+ARM_FUNC void *G2_GetBG1ScrPtr(){
+ u32 temp = (((READREG16(HW_REG_BG1CNT_A) & 0x1F00) >> 0x8) << 0xB);
+ return (void *)(0x6000000 + (((READREG32(HW_REG_DISPCNT_A) & 0x38000000) >> 0x1B) << 0x10) + temp);
+}
+
+ARM_FUNC void *G2S_GetBG1ScrPtr(){
+ return (void *)(0x6200000 + (((READREG16(HW_REG_BG1CNT_B) & 0x1F00) >> 0x8) << 0xB));
+}
+
+ARM_FUNC void *G2_GetBG2ScrPtr(){
+ u32 temp12 = (READREG32(HW_REG_DISPCNT_A) & 0x7);
+ u32 temp3 = READREG16(HW_REG_BG2CNT_A);
+ u32 temp2 = (((READREG32(HW_REG_DISPCNT_A) & 0x38000000) >> 0x1B) << 0x10);
+ u32 temp1 = ((temp3 & 0x1F00) >> 0x8);
+ switch (temp12)
+ {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ return (void *)(0x6000000 + temp2 + (temp1 << 0xB));
+ case 5:
+ if (temp3 & 0x80)
+ return (void *)(0x6000000 + (temp1 << 0xE));
+ else
+ return (void *)(0x6000000 + temp2 + (temp1 << 0xB));
+ case 6:
+ return (void *)0x6000000;
+ default:
+ return NULL;
+ }
+}
+
+ARM_FUNC void *G2S_GetBG2ScrPtr(){
+ u32 temp12 = (READREG32(HW_REG_DISPCNT_B) & 0x7);
+ u32 temp3 = READREG16(HW_REG_BG2CNT_B);
+ u32 temp1 = ((temp3 & 0x1F00) >> 0x8);
+ switch (temp12)
+ {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ return (void *)(0x6200000 + (temp1 << 0xB));
+ case 5:
+ if (temp3 & 0x80)
+ return (void *)(0x6200000 + (temp1 << 0xE));
+ else
+ return (void *)(0x6200000 + (temp1 << 0xB));
+ case 6:
+ return NULL;
+ default:
+ return NULL;
+ }
+}
+
+ARM_FUNC void *G2_GetBG3ScrPtr(){
+ u32 temp12 = (READREG32(HW_REG_DISPCNT_A) & 0x7);
+ u32 temp3 = READREG16(HW_REG_BG3CNT_A);
+ u32 temp2 = (((READREG32(HW_REG_DISPCNT_A) & 0x38000000) >> 0x1B) << 0x10);
+ u32 temp1 = ((temp3 & 0x1F00) >> 0x8);
+ switch (temp12)
+ {
+ case 0:
+ case 1:
+ case 2:
+ return (void *)(0x6000000 + temp2 + (temp1 << 0xB));
+ case 3:
+ case 4:
+ case 5:
+ if (temp3 & 0x80)
+ return (void *)(0x6000000 + (temp1 << 0xE));
+ else
+ return (void *)(0x6000000 + temp2 + (temp1 << 0xB));
+ case 6:
+ return NULL;
+ default:
+ return NULL;
+ }
+}
+
+ARM_FUNC void *G2S_GetBG3ScrPtr(){
+ u32 temp12 = (READREG32(HW_REG_DISPCNT_B) & 0x7);
+ u32 temp3 = READREG16(HW_REG_BG3CNT_B);
+ u32 temp1 = ((temp3 & 0x1F00) >> 0x8);
+ switch (temp12)
+ {
+ case 0:
+ case 1:
+ case 2:
+ return (void *)(0x6200000 + (temp1 << 0xB));
+ case 3:
+ case 4:
+ case 5:
+ if (temp3 & 0x80)
+ return (void *)(0x6200000 + (temp1 << 0xE));
+ else
+ return (void *)(0x6200000 + (temp1 << 0xB));
+ case 6:
+ return NULL;
+ default:
+ return NULL;
+ }
+}
+
+ARM_FUNC void *G2_GetBG0CharPtr(){
+ u32 temp = (((READREG16(HW_REG_BG0CNT_A) & 0x3C) >> 0x2) << 0xE);
+ return (void *)(0x6000000 + (((READREG32(HW_REG_DISPCNT_A) & 0x7000000) >> 0x18) << 0x10) + temp);
+}
+
+ARM_FUNC void *G2S_GetBG0CharPtr(){
+ return (void *)(0x6200000 + (((READREG16(HW_REG_BG0CNT_B) & 0x3C) >> 0x2) << 0xE));
+}
+
+ARM_FUNC void *G2_GetBG1CharPtr(){
+ u32 temp = (((READREG16(HW_REG_BG1CNT_A) & 0x3C) >> 0x2) << 0xE);
+ return (void *)(0x6000000 + (((READREG32(HW_REG_DISPCNT_A) & 0x7000000) >> 0x18) << 0x10) + temp);
+}
+
+ARM_FUNC void *G2S_GetBG1CharPtr(){
+ return (void *)(0x6200000 + (((READREG16(HW_REG_BG1CNT_B) & 0x3C) >> 0x2) << 0xE));
+}
+
+ARM_FUNC void *G2_GetBG2CharPtr(){
+ s32 temp1 = (READREG32(HW_REG_DISPCNT_A) & 0x7);
+ u32 temp = READREG16(HW_REG_BG2CNT_A);
+ if (temp1 < 5 || !(temp & 0x80))
+ {
+ u32 temp1 = (((READREG32(HW_REG_DISPCNT_A) & 0x7000000) >> 0x18) << 0x10);
+ u32 temp2 = (temp & 0x3C) >> 2;
+ return (void *)(0x6000000 + temp1 + (temp2 << 0xE));
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+ARM_FUNC void *G2S_GetBG2CharPtr(){
+ s32 temp1 = (READREG32(HW_REG_DISPCNT_B) & 0x7);
+ u32 temp = READREG16(HW_REG_BG2CNT_B);
+ if (temp1 < 5 || !(temp & 0x80))
+ {
+ u32 temp2 = ((temp & 0x3C) >> 2) << 0xE;
+ return (void *)(0x6200000 + temp2);
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+ARM_FUNC void *G2_GetBG3CharPtr(){
+ s32 temp1 = (READREG32(HW_REG_DISPCNT_A) & 0x7);
+ u32 temp = READREG16(HW_REG_BG3CNT_A);
+ if (temp1 < 3 || (temp1 < 6 && !(temp & 0x80)))
+ {
+ u32 temp1 = (((READREG32(HW_REG_DISPCNT_A) & 0x7000000) >> 0x18) << 0x10);
+ u32 temp2 = (temp & 0x3C) >> 2;
+ return (void *)(0x6000000 + temp1 + (temp2 << 0xE));
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+ARM_FUNC void *G2S_GetBG3CharPtr(){
+ s32 temp1 = (READREG32(HW_REG_DISPCNT_B) & 0x7);
+ u32 temp = READREG16(HW_REG_BG3CNT_B);
+ if (temp1 < 3 || (temp1 < 6 && !(temp & 0x80)))
+ {
+ u32 temp2 = ((temp & 0x3C) >> 2) << 0xE;
+ return (void *)(0x6200000 + temp2);
+ }
+ else
+ {
+ return NULL;
+ }
+}
diff --git a/arm9/lib/src/GX_g2.c b/arm9/lib/src/GX_g2.c
new file mode 100644
index 00000000..5bced1ef
--- /dev/null
+++ b/arm9/lib/src/GX_g2.c
@@ -0,0 +1,66 @@
+#include "global.h"
+#include "main.h"
+#include "gx.h"
+
+ARM_FUNC void G2x_SetBGyAffine_(u32 *ptr, struct Mtx22 *mtx, fx32 a, fx32 b, fx32 c, fx32 d){
+ fx32 temp0, temp1, temp2, temp3;
+ ptr[0] = ((u16)(fx16)(mtx->_[0] >> 4) | (u16)(fx16)(mtx->_[1] >> 4)<< 0x10);
+ ptr[1] = ((u16)(fx16)(mtx->_[2] >> 4) | (u16)(fx16)(mtx->_[3] >> 4)<< 0x10);
+ temp0 = c - a;
+ temp1 = d - b;
+ temp2 = mtx->_[0] * temp0 + mtx->_[1] * temp1 + (a << 0xC);
+ temp3 = mtx->_[2] * temp0 + mtx->_[3] * temp1 + (b << 0xC);
+ ptr[2] = temp2 >> 4;
+ ptr[3] = temp3 >> 4;
+}
+
+ARM_FUNC void G2x_SetBlendAlpha_(u32 *ptr, fx32 a, fx32 b, fx32 c, fx32 d){
+ *ptr = ((a | 0x40) | (b << 0x8)) | ((c | (d << 0x8)) << 0x10);
+}
+
+ARM_FUNC void G2x_SetBlendBrightness_(u16 *ptr, fx32 a, fx32 brightness){
+ if (brightness < 0)
+ {
+ ptr[0] = a | 0xC0;
+ ptr[2] = -brightness;
+ }
+ else
+ {
+ ptr[0] = a | 0x80;
+ ptr[2] = brightness;
+ }
+}
+
+ARM_FUNC void G2x_SetBlendBrightnessExt_(u16 *ptr, fx32 a, fx32 b, fx32 c, fx32 d, fx32 brightness){
+ ptr[1] = c | (d << 0x8);
+ if (brightness < 0)
+ {
+ ptr[0] = 0xC0 | a | (b << 0x8);
+ ptr[2] = -brightness;
+ }
+ else
+ {
+ ptr[0] = 0x80 | a | (b << 0x8);
+ ptr[2] = brightness;
+ }
+}
+
+ARM_FUNC void *G2x_ChangeBlendBrightness_(u16 *ptr, fx32 brightness){
+ u32 temp = *ptr;
+ if (brightness < 0)
+ {
+ if ((temp & 0xC0) == 0x80)
+ {
+ ptr[0] = temp & ~0xC0 | 0xC0;
+ }
+ ptr[2] = -brightness;
+ }
+ else
+ {
+ if ((temp & 0xC0) == 0xC0)
+ {
+ ptr[0] = temp & ~0xC0 | 0x80;
+ }
+ ptr[2] = brightness;
+ }
+}
diff --git a/arm9/lib/src/GX_g3.c b/arm9/lib/src/GX_g3.c
new file mode 100644
index 00000000..eb01453d
--- /dev/null
+++ b/arm9/lib/src/GX_g3.c
@@ -0,0 +1,36 @@
+#include "global.h"
+#include "main.h"
+#include "gx.h"
+
+
+ARM_FUNC void G3_BeginMakeDL(struct DL *displaylist, void *r1, u32 r2){
+ displaylist->var0C = r2;
+ displaylist->var08 = r1;
+ displaylist->var00 = r1;
+ displaylist->var04 = (u32 *)r1 + 1;
+ displaylist->var10 = 0x0;
+}
+
+ARM_FUNC s32 G3_EndMakeDL(struct DL *displaylist){
+ if (displaylist->var08 == displaylist->var00)
+ return 0;
+ //pads the buffer with 0 to 4byte alignment if needed
+ switch((u32)displaylist->var00 & 0x3)
+ {
+ case 0:
+ return displaylist->var00 - displaylist->var08;
+ case 1:
+ *displaylist->var00++ = 0x0;
+ case 2:
+ *displaylist->var00++ = 0x0;
+ case 3:
+ *displaylist->var00++ = 0x0;
+ }
+ if (displaylist->var10)
+ {
+ *displaylist->var04++ = 0x0;
+ displaylist->var10 = 0x0;
+ }
+ displaylist->var00 = (u8 *)displaylist->var04;
+ return displaylist->var00 - displaylist->var08;
+}
diff --git a/arm9/lib/src/GX_g3_util.c b/arm9/lib/src/GX_g3_util.c
new file mode 100644
index 00000000..75e18589
--- /dev/null
+++ b/arm9/lib/src/GX_g3_util.c
@@ -0,0 +1,260 @@
+#include "global.h"
+#include "main.h"
+#include "gx.h"
+
+
+ARM_FUNC void G3i_PerspectiveW_(fx32 fovsin, fx32 fovcos, fx32 ratio, fx32 near, fx32 far, fx32 scale, u32 load, struct Mtx44 *mtx){
+ fx32 fovcot, temp1, temp2;
+ fx64c temp0;
+ vu32 *reg_ptr;
+
+ fovcot = FX_Div(fovcos, fovsin);
+ if (scale != 0x1000) //!= 1.0
+ fovcot = (fovcot * scale) / 0x1000;
+ SETREG64(HW_REG_DIV_NUMER, (s64)fovcot << 0x20);
+ SETREG64(HW_REG_DIV_DENOM, (u32)ratio);
+ if (load)
+ {
+ SETREG32(HW_REG_MTX_MODE, 0x0);
+ reg_ptr = (vu32 *)HW_REG_MTX_LOAD_4x4;
+ }
+ if (mtx)
+ {
+ mtx->_[1] = 0x0;
+ mtx->_[2] = 0x0;
+ mtx->_[3] = 0x0;
+ mtx->_[4] = 0x0;
+ mtx->_[6] = 0x0;
+ mtx->_[7] = 0x0;
+ mtx->_[8] = 0x0;
+ mtx->_[9] = 0x0;
+ mtx->_[11] = -scale;
+ mtx->_[12] = 0x0;
+ mtx->_[13] = 0x0;
+ mtx->_[15] = 0x0;
+ }
+ temp1 = FX_GetDivResult();
+ SETREG64(HW_REG_DIV_NUMER, (s64)0x1000 << 0x20);
+ SETREG64(HW_REG_DIV_DENOM, (u32)(near - far));
+ if (load)
+ {
+ *reg_ptr = temp1;
+ *reg_ptr = 0x0;
+ *reg_ptr = 0x0;
+ *reg_ptr = 0x0;
+ *reg_ptr = 0x0;
+ *reg_ptr = fovcot;
+ *reg_ptr = 0x0;
+ *reg_ptr = 0x0;
+ *reg_ptr = 0x0;
+ *reg_ptr = 0x0;
+ }
+ if (mtx)
+ {
+ mtx->_[0] = temp1;
+ mtx->_[5] = fovcot;
+ }
+ temp0 = FX_GetDivResultFx64c();
+ if (scale != 0x1000)
+ temp0 = (temp0 * scale) / 0x1000;
+ temp1 = ((far + near) * temp0 + ((fx64)1 << (FX64C_INT_SHIFT - 1))) >> FX64C_INT_SHIFT;
+ temp2 = (((fx32)(((fx64)(near << 1) * far + (1 << (FX32_INT_SHIFT - 1))) >> FX32_INT_SHIFT)) * temp0 + ((fx64)1 << (FX64C_INT_SHIFT - 1))) >> FX64C_INT_SHIFT;
+ if (load)
+ {
+ *reg_ptr = temp1;
+ *reg_ptr = -scale;
+ *reg_ptr = 0x0;
+ *reg_ptr = 0x0;
+ *reg_ptr = temp2;
+ *reg_ptr = 0x0;
+ }
+ if (mtx)
+ {
+ mtx->_[10] = temp1;
+ mtx->_[14] = temp2;
+ }
+}
+
+ARM_FUNC void G3i_OrthoW_(fx32 top, fx32 bottom, fx32 left, fx32 right, fx32 near, fx32 far, fx32 scale, u32 load, struct Mtx44 *mtx){
+ fx64c temp1, temp2, temp3;
+ fx32 temp0, temp4, temp5;
+ vu32 *reg_ptr;
+
+ FX_InvAsync(right - left);
+ if (load)
+ {
+ SETREG32(HW_REG_MTX_MODE, 0x0);
+ reg_ptr = (vu32 *)HW_REG_MTX_LOAD_4x4;
+ }
+ if (mtx)
+ {
+ mtx->_[1] = 0x0;
+ mtx->_[2] = 0x0;
+ mtx->_[3] = 0x0;
+ mtx->_[4] = 0x0;
+ mtx->_[6] = 0x0;
+ mtx->_[7] = 0x0;
+ mtx->_[8] = 0x0;
+ mtx->_[9] = 0x0;
+ mtx->_[11] = 0x0;
+ mtx->_[15] = scale;
+ }
+ temp1 = FX_GetDivResultFx64c();
+ SETREG64(HW_REG_DIV_NUMER, (s64)0x1000 << 0x20);
+ SETREG64(HW_REG_DIV_DENOM, (u32)(top - bottom));
+ if (scale != 0x1000)
+ temp1 = (temp1 * scale) / 0x1000;
+ temp0 = (0x2000 * temp1 + ((fx64)1 << (FX64C_INT_SHIFT - 1))) >> FX64C_INT_SHIFT;
+ if (load)
+ {
+ *reg_ptr = temp0;
+ *reg_ptr = 0x0;
+ *reg_ptr = 0x0;
+ *reg_ptr = 0x0;
+ *reg_ptr = 0x0;
+ }
+ if (mtx)
+ {
+ mtx->_[0] = temp0;
+ }
+ temp2 = FX_GetDivResultFx64c();
+ SETREG64(HW_REG_DIV_NUMER, (s64)0x1000 << 0x20);
+ SETREG64(HW_REG_DIV_DENOM, (u32)(near - far));
+ if (scale != 0x1000)
+ temp2 = (temp2 * scale) / 0x1000;
+ temp0 = (0x2000 * temp2 + ((fx64)1 << (FX64C_INT_SHIFT - 1))) >> FX64C_INT_SHIFT;
+ if (load)
+ {
+ *reg_ptr = temp0;
+ *reg_ptr = 0x0;
+ *reg_ptr = 0x0;
+ *reg_ptr = 0x0;
+ *reg_ptr = 0x0;
+ }
+ if (mtx)
+ {
+ mtx->_[5] = temp0;
+ }
+ temp3 = FX_GetDivResultFx64c();
+ if (scale != 0x1000)
+ temp3 = (temp3 * scale) / 0x1000;
+ temp0 = (0x2000 * temp3 + ((fx64)1 << (FX64C_INT_SHIFT - 1))) >> FX64C_INT_SHIFT;
+ if (load)
+ {
+ *reg_ptr = temp0;
+ *reg_ptr = 0x0;
+ }
+ if (mtx)
+ {
+ mtx->_[10] = temp0;
+ }
+ temp0 = ((-(right + left)) * temp1 + ((fx64)1 << (FX64C_INT_SHIFT - 1))) >> FX64C_INT_SHIFT;
+ temp4 = ((-(top + bottom)) * temp2 + ((fx64)1 << (FX64C_INT_SHIFT - 1))) >> FX64C_INT_SHIFT;
+ temp5 = ((far + near) * temp3 + ((fx64)1 << (FX64C_INT_SHIFT - 1))) >> FX64C_INT_SHIFT;
+ if (load)
+ {
+ *reg_ptr = temp0;
+ *reg_ptr = temp4;
+ *reg_ptr = temp5;
+ *reg_ptr = scale;
+ }
+ if (mtx)
+ {
+ mtx->_[12] = temp0;
+ mtx->_[13] = temp4;
+ mtx->_[14] = temp5;
+ }
+}
+
+ARM_FUNC void G3i_LookAt_(struct Vecx32 *a, struct Vecx32 *b, struct Vecx32 *c, u32 load, struct Mtx44 *mtx){
+ struct Vecx32 temp, temp1, temp2;
+ fx32 c1, c2, c3;
+ vu32 *reg_ptr;
+ temp.x = a->x - c->x;
+ temp.y = a->y - c->y;
+ temp.z = a->z - c->z;
+ VEC_Normalize(&temp, &temp);
+ VEC_CrossProduct(b, &temp, &temp1);
+ VEC_Normalize(&temp1, &temp1);
+ VEC_CrossProduct(&temp, &temp1, &temp2);
+ if (load)
+ {
+ SETREG32(HW_REG_MTX_MODE, 0x2);
+ reg_ptr = (vu32 *)HW_REG_MTX_LOAD_4x3;
+ *reg_ptr = temp1.x;
+ *reg_ptr = temp2.x;
+ *reg_ptr = temp.x;
+ *reg_ptr = temp1.y;
+ *reg_ptr = temp2.y;
+ *reg_ptr = temp.y;
+ *reg_ptr = temp1.z;
+ *reg_ptr = temp2.z;
+ *reg_ptr = temp.z;
+ }
+ c1 = -VEC_DotProduct(a, &temp1);
+ c2 = -VEC_DotProduct(a, &temp2);
+ c3 = -VEC_DotProduct(a, &temp);
+ if (load)
+ {
+ *reg_ptr = c1;
+ *reg_ptr = c2;
+ *reg_ptr = c3;
+ }
+ if (mtx)
+ {
+ mtx->_[0] = temp1.x;
+ mtx->_[1] = temp2.x;
+ mtx->_[2] = temp.x;
+ mtx->_[3] = temp1.y;
+ mtx->_[4] = temp2.y;
+ mtx->_[5] = temp.y;
+ mtx->_[6] = temp1.z;
+ mtx->_[7] = temp2.z;
+ mtx->_[8] = temp.z;
+ mtx->_[9] = c1;
+ mtx->_[10] = c2;
+ mtx->_[11] = c3;
+ }
+}
+
+ARM_FUNC void G3_RotX(fx32 sinphi, fx32 cosphi){
+ vu32 *reg_ptr;
+ reg_ptr = (vu32 *)HW_REG_MTX_MULT_3x3;
+ *reg_ptr = 0x1000;
+ *reg_ptr = 0x0;
+ *reg_ptr = 0x0;
+ *reg_ptr = 0x0;
+ *reg_ptr = cosphi;
+ *reg_ptr = sinphi;
+ *reg_ptr = 0x0;
+ *reg_ptr = -sinphi;
+ *reg_ptr = cosphi;
+}
+
+ARM_FUNC void G3_RotY(fx32 sinphi, fx32 cosphi){
+ vu32 *reg_ptr;
+ reg_ptr = (vu32 *)HW_REG_MTX_MULT_3x3;
+ *reg_ptr = cosphi;
+ *reg_ptr = 0x0;
+ *reg_ptr = -sinphi;
+ *reg_ptr = 0x0;
+ *reg_ptr = 0x1000;
+ *reg_ptr = 0x0;
+ *reg_ptr = sinphi;
+ *reg_ptr = 0x0;
+ *reg_ptr = cosphi;
+}
+
+ARM_FUNC void G3_RotZ(fx32 sinphi, fx32 cosphi){
+ vu32 *reg_ptr;
+ reg_ptr = (vu32 *)HW_REG_MTX_MULT_3x3;
+ *reg_ptr = cosphi;
+ *reg_ptr = sinphi;
+ *reg_ptr = 0x0;
+ *reg_ptr = -sinphi;
+ *reg_ptr = cosphi;
+ *reg_ptr = 0x0;
+ *reg_ptr = 0x0;
+ *reg_ptr = 0x0;
+ *reg_ptr = 0x1000;
+}
diff --git a/arm9/lib/src/GX_g3b.c b/arm9/lib/src/GX_g3b.c
new file mode 100644
index 00000000..50281ec0
--- /dev/null
+++ b/arm9/lib/src/GX_g3b.c
@@ -0,0 +1,120 @@
+#include "global.h"
+#include "main.h"
+#include "gx.h"
+
+
+ARM_FUNC void G3BS_LoadMtx44(struct DL *displaylist, struct Mtx44 *mtx){
+ *(u32 *)displaylist->var00 = 0x16;
+ MI_Copy64B(mtx, displaylist->var04);
+}
+
+ARM_FUNC void G3B_PushMtx(struct DL *displaylist){
+ *(u32 *)displaylist->var00 = 0x11;
+ displaylist->var00 = (u8 *)displaylist->var04;
+ displaylist->var04 = (u32 *)displaylist->var00 + 1;
+}
+
+ARM_FUNC void G3B_PopMtx(struct DL *displaylist, void *mtx){
+ *(u32 *)displaylist->var00 = 0x12;
+ *displaylist->var04 = (u32)mtx;
+ displaylist->var00 = (u8 *)displaylist->var04 + 0x4;
+ displaylist->var04 = (u32 *)displaylist->var00 + 1;
+}
+
+ARM_FUNC void G3B_LoadMtx44(struct DL *displaylist, struct Mtx44 *mtx){
+ G3BS_LoadMtx44(displaylist, mtx);
+ displaylist->var00 = (u8 *)displaylist->var04 + sizeof(struct Mtx44);
+ displaylist->var04 = (u32 *)displaylist->var00 + 1;
+}
+
+//color format is RGB555, stored in the lower bits
+ARM_FUNC void G3B_Color(struct DL * displaylist, u32 vtx_col){
+ *(u32 *)displaylist->var00 = 0x20;
+ *displaylist->var04 = vtx_col;
+ displaylist->var00 = (u8 *)displaylist->var04 + 0x4;
+ displaylist->var04 = (u32 *)displaylist->var00 + 1;
+}
+
+/*
+Only feed normalized Vectors
+only the fractional part and the sign, which is in the first nonfraction bit
+since the vector is assumed to be normalized, are used
+*/
+ARM_FUNC void G3B_Normal(struct DL * displaylist, fx16 x, fx16 y, fx16 z){
+ *(u32 *)displaylist->var00 = 0x21;
+ *displaylist->var04 = ((x >> 3) & 0x3FF) | (((y >> 3) & 0x3FF) << 0xA) | (((z >> 3) & 0x3FF) << 0x14) ;
+ displaylist->var00 = (u8 *)displaylist->var04 + 0x4;
+ displaylist->var04 = (u32 *)displaylist->var00 + 1;
+}
+
+ARM_FUNC void G3B_Vtx(struct DL * displaylist, fx32 x, fx32 y, fx32 z){
+ *(u32 *)displaylist->var00 = 0x23;
+ displaylist->var04[0] = (u32)(u16)x | (u32)(u16)y << 0x10;
+ displaylist->var04[1] = (u32)(u16)z;
+ displaylist->var00 = (u8 *)displaylist->var04 + 0x8;
+ displaylist->var04 = (u32 *)displaylist->var00 + 1;
+}
+
+//TODO: name arguments
+ARM_FUNC void G3B_PolygonAttr(struct DL *displaylist, u32 r1, u32 r2, u32 r3, u32 r4, u32 r5, u32 r6){
+ *(u32 *)displaylist->var00 = 0x29;
+ *displaylist->var04 = r1 | r2 << 0x4 | r3 << 0x6 | r6 | r4 << 0x18 | r5 << 0x10;
+ displaylist->var00 = (u8 *)displaylist->var04 + 0x4;
+ displaylist->var04 = (u32 *)displaylist->var00 + 1;
+}
+
+ARM_FUNC void G3B_MaterialColorDiffAmb(struct DL *displaylist, u32 diffuse_col, u32 ambient_col, u32 replace){
+ *(u32 *)displaylist->var00 = 0x30;
+ u32 replace_vtx_color_with_diffuse;
+ if (replace)
+ replace_vtx_color_with_diffuse = TRUE;
+ else
+ replace_vtx_color_with_diffuse = FALSE;
+ *displaylist->var04 = diffuse_col | ambient_col << 0x10 | replace_vtx_color_with_diffuse << 0xF;
+ displaylist->var00 = (u8 *)displaylist->var04 + 0x4;
+ displaylist->var04 = (u32 *)displaylist->var00 + 1;
+}
+
+ARM_FUNC void G3B_MaterialColorSpecEmi(struct DL *displaylist, u32 specular_col, u32 emission_col, u32 shiny_table){
+ *(u32 *)displaylist->var00 = 0x31;
+ u32 enable_shininess_table;
+ if (shiny_table)
+ enable_shininess_table = TRUE;
+ else
+ enable_shininess_table = FALSE;
+ *displaylist->var04 = specular_col | emission_col << 0x10 | enable_shininess_table << 0xF;
+ displaylist->var00 = (u8 *)displaylist->var04 + 0x4;
+ displaylist->var04 = (u32 *)displaylist->var00 + 1;
+}
+
+/*
+Only feed normalized Vectors
+only the fractional part and the sign, which is in the first nonfraction bit
+since the vector is assumed to be normalized, are used
+*/
+ARM_FUNC void G3B_LightVector(struct DL * displaylist, u32 light_num, fx16 x, fx16 y, fx16 z){
+ *(u32 *)displaylist->var00 = 0x32;
+ *displaylist->var04 = ((x >> 3) & 0x3FF) | (((y >> 3) & 0x3FF) << 0xA) | (((z >> 3) & 0x3FF) << 0x14) | light_num << 0x1E;
+ displaylist->var00 = (u8 *)displaylist->var04 + 0x4;
+ displaylist->var04 = (u32 *)displaylist->var00 + 1;
+}
+
+ARM_FUNC void G3B_LightColor(struct DL * displaylist, u32 light_num, u32 col){
+ *(u32 *)displaylist->var00 = 0x33;
+ *displaylist->var04 = col | light_num << 0x1E;
+ displaylist->var00 = (u8 *)displaylist->var04 + 0x4;
+ displaylist->var04 = (u32 *)displaylist->var00 + 1;
+}
+
+ARM_FUNC void G3B_Begin(struct DL * displaylist, u32 type){
+ *(u32 *)displaylist->var00 = 0x40;
+ *displaylist->var04 = type;
+ displaylist->var00 = (u8 *)displaylist->var04 + 0x4;
+ displaylist->var04 = (u32 *)displaylist->var00 + 1;
+}
+
+ARM_FUNC void G3B_End(struct DL * displaylist){
+ *(u32 *)displaylist->var00 = 0x41;
+ displaylist->var00 = (u8 *)displaylist->var04;
+ displaylist->var04 = (u32 *)displaylist->var00 + 1;
+}
diff --git a/arm9/lib/src/GX_g3imm.c b/arm9/lib/src/GX_g3imm.c
new file mode 100644
index 00000000..f11e2927
--- /dev/null
+++ b/arm9/lib/src/GX_g3imm.c
@@ -0,0 +1,18 @@
+#include "global.h"
+#include "main.h"
+#include "gx.h"
+
+ARM_FUNC void G3_LoadMtx43(struct Mtx43 *mtx){
+ SETREG32(HW_REG_GXFIFO, 0x17);
+ GX_SendFifo48B(mtx, (void *)HW_REG_GXFIFO);
+}
+
+ARM_FUNC void G3_MultMtx43(struct Mtx43 *mtx){
+ SETREG32(HW_REG_GXFIFO, 0x19);
+ GX_SendFifo48B(mtx, (void *)HW_REG_GXFIFO);
+}
+
+ARM_FUNC void G3_MultMtx33(struct Mtx33 *mtx){
+ SETREG32(HW_REG_GXFIFO, 0x1A);
+ MI_Copy36B(mtx, (void *)HW_REG_GXFIFO);
+}
diff --git a/arm9/lib/src/GX_g3x.c b/arm9/lib/src/GX_g3x.c
new file mode 100644
index 00000000..7ced9de6
--- /dev/null
+++ b/arm9/lib/src/GX_g3x.c
@@ -0,0 +1,235 @@
+#include "global.h"
+#include "main.h"
+#include "gx.h"
+
+extern u32 gUnk02106814;
+
+ARM_FUNC asm void GXi_NopClearFifo128_(void *reg){
+ mov r1, #0x0
+ mov r2, #0x0
+ mov r3, #0x0
+ mov r12, #0x0
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ bx lr
+}
+
+ARM_FUNC void G3X_Init(){
+ G3X_ClearFifo();
+ SETREG32(HW_REG_END_VTXS, 0x0);
+ while (READREG32(HW_REG_GXSTAT) & 0x8000000); //wait for geometry engine to not be busy
+ SETREG16(HW_REG_DISP3DCNT, 0x0);
+ SETREG32(HW_REG_GXSTAT, 0x0);
+ SETREG32(HW_REG_BG0HOFS, 0x0);
+ SETREG16(HW_REG_DISP3DCNT, READREG16(HW_REG_DISP3DCNT) | 0x2000);
+ SETREG16(HW_REG_DISP3DCNT, READREG16(HW_REG_DISP3DCNT) | 0x1000);
+ SETREG16(HW_REG_DISP3DCNT, READREG16(HW_REG_DISP3DCNT) & ~0x3002);
+ SETREG16(HW_REG_DISP3DCNT, READREG16(HW_REG_DISP3DCNT) & ~0x3000 | 0x10);
+ SETREG16(HW_REG_DISP3DCNT, READREG16(HW_REG_DISP3DCNT) & (u16)~0x3004);
+ SETREG32(HW_REG_GXSTAT, READREG32(HW_REG_GXSTAT) | 0x8000);
+ SETREG32(HW_REG_GXSTAT, READREG32(HW_REG_GXSTAT) & ~0xC0000000 | 0x80000000);
+ G3X_InitMtxStack();
+ SETREG32(HW_REG_CLEAR_COLOR, 0x0);
+ SETREG16(HW_REG_CLEAR_DEPTH, 0x7FFF);
+ SETREG16(HW_REG_CLRIMAGE_OFFSET, 0x0);
+ SETREG32(HW_REG_FOG_COLOR, 0x0);
+ SETREG16(HW_REG_FOG_OFFSET, 0x0);
+ SETREG16(HW_REG_BG0CNT, READREG16(HW_REG_BG0CNT) & ~0x3);
+ G3X_InitTable();
+ SETREG32(HW_REG_POLYGON_ATTR, 0x1F0080);
+ SETREG32(HW_REG_TEXIMAGE_PARAM, 0x0);
+ SETREG32(HW_REG_PLTT_BASE, 0x0);
+}
+
+ARM_FUNC void G3X_ResetMtxStack(){
+ while (READREG32(HW_REG_GXSTAT) & 0x8000000);
+ SETREG32(HW_REG_GXSTAT, READREG32(HW_REG_GXSTAT) | 0x8000);
+ SETREG16(HW_REG_DISP3DCNT, READREG16(HW_REG_DISP3DCNT) | 0x2000);
+ SETREG16(HW_REG_DISP3DCNT, READREG16(HW_REG_DISP3DCNT) | 0x1000);
+ G3X_ResetMtxStack_2();
+ SETREG32(HW_REG_POLYGON_ATTR, 0x1F0080);
+ SETREG32(HW_REG_TEXIMAGE_PARAM, 0x0);
+ SETREG32(HW_REG_PLTT_BASE, 0x0);
+}
+
+ARM_FUNC void G3X_ClearFifo(){
+ GXi_NopClearFifo128_((void *)HW_REG_GXFIFO);
+ while (READREG32(HW_REG_GXSTAT) & 0x8000000);
+}
+
+ARM_FUNC void G3X_InitMtxStack(){
+ u32 PV_level, PJ_level;
+ SETREG32(HW_REG_GXSTAT, READREG32(HW_REG_GXSTAT) | 0x8000);
+ while (G3X_GetMtxStackLevelPV(&PV_level));
+ while (G3X_GetMtxStackLevelPJ(&PJ_level));
+ SETREG32(HW_REG_MTX_MODE, 0x3);
+ SETREG32(HW_REG_MTX_IDENTITY, 0x0);
+ SETREG32(HW_REG_MTX_MODE, 0x0);
+ if (PJ_level)
+ {
+ SETREG32(HW_REG_MTX_POP, PJ_level);
+ }
+ SETREG32(HW_REG_MTX_IDENTITY, 0x0);
+ SETREG32(HW_REG_MTX_MODE, 0x2);
+ SETREG32(HW_REG_MTX_POP, PV_level);
+ SETREG32(HW_REG_MTX_IDENTITY, 0x0);
+}
+
+ARM_FUNC void G3X_ResetMtxStack_2(){
+ u32 PV_level, PJ_level;
+ SETREG32(HW_REG_GXSTAT, READREG32(HW_REG_GXSTAT) | 0x8000);
+ while (G3X_GetMtxStackLevelPV(&PV_level));
+ while (G3X_GetMtxStackLevelPJ(&PJ_level));
+ SETREG32(HW_REG_MTX_MODE, 0x3);
+ SETREG32(HW_REG_MTX_IDENTITY, 0x0);
+ SETREG32(HW_REG_MTX_MODE, 0x0);
+ if (PJ_level)
+ {
+ SETREG32(HW_REG_MTX_POP, PJ_level);
+ }
+
+ SETREG32(HW_REG_MTX_MODE, 0x2);
+ SETREG32(HW_REG_MTX_POP, PV_level);
+ SETREG32(HW_REG_MTX_IDENTITY, 0x0);
+
+}
+
+ARM_FUNC void G3X_SetFog(u32 enable, u32 alphamode, u32 depth, s32 offset){
+ if (enable)
+ {
+ SETREG16(HW_REG_FOG_OFFSET, offset);
+ SETREG16(HW_REG_DISP3DCNT, (READREG16(HW_REG_DISP3DCNT) &~0x3f40) | (((depth << 0x8)| (alphamode << 0x6)|0x80 )));
+
+ }
+ else
+ {
+ SETREG16(HW_REG_DISP3DCNT, READREG16(HW_REG_DISP3DCNT) & (u16)~0x3080);
+ }
+}
+
+ARM_FUNC u32 G3X_GetClipMtx(struct Mtx44 *dst){
+ if (READREG32(HW_REG_GXSTAT) & 0x8000000)
+ {
+ return -1;
+ }
+ else
+ {
+ MI_Copy64B((void *)HW_REG_CLIPMTX_RESULT, dst);
+ return 0;
+ }
+}
+
+ARM_FUNC u32 G3X_GetVectorMtx(struct Mtx33 *dst){
+ if (READREG32(HW_REG_GXSTAT) & 0x8000000)
+ {
+ return -1;
+ }
+ else
+ {
+ MI_Copy36B((void *)HW_REG_VECMTX_RESULT, dst);
+ return 0;
+ }
+}
+
+ARM_FUNC void G3X_SetEdgeColorTable(void *tbl_ptr){
+ MIi_CpuCopy16(tbl_ptr, (void *)HW_REG_EDGE_COLOR, 0x10);
+}
+
+ARM_FUNC void G3X_SetFogTable(void *tbl_ptr){
+ MI_Copy16B(tbl_ptr, (void *)HW_REG_FOG_TABLE);
+}
+
+ARM_FUNC void G3X_SetClearColor(u32 col, u32 alpha, u32 depth, u32 polygon_id, u32 enable_fog){
+ u32 temp = col | (alpha << 0x10) | (polygon_id << 0x18);
+ if (enable_fog)
+ temp |= 0x8000;
+ SETREG32(HW_REG_CLEAR_COLOR, temp);
+ SETREG16(HW_REG_CLEAR_DEPTH, depth);
+}
+
+ARM_FUNC void G3X_InitTable(){
+ if (gUnk02106814 != -1)
+ {
+ MI_DmaFill32Async(gUnk02106814, (void *)HW_REG_EDGE_COLOR, 0x0, 0x10, 0x0, 0x0);
+ MI_DmaFill32(gUnk02106814, (void *)HW_REG_FOG_TABLE, 0x0, 0x60);
+ }
+ else
+ {
+ MIi_CpuClear32(0x0, (void *)HW_REG_EDGE_COLOR, 0x10);
+ MIi_CpuClear32(0x0, (void *)HW_REG_FOG_TABLE, 0x60);
+ }
+ for (int i = 0; i < 0x20; i++)
+ {
+ SETREG32(HW_REG_SHININESS, 0x0);
+ }
+}
+
+ARM_FUNC u32 G3X_GetMtxStackLevelPV(u32 *level){
+ if (READREG32(HW_REG_GXSTAT) & 0x4000)
+ {
+ return -1;
+ }
+ else
+ {
+ *level = (READREG32(HW_REG_GXSTAT) & 0x1F00) >> 0x8;
+ return 0;
+ }
+}
+
+ARM_FUNC u32 G3X_GetMtxStackLevelPJ(u32 *level){
+ if (READREG32(HW_REG_GXSTAT) & 0x4000)
+ {
+ return -1;
+ }
+ else
+ {
+ *level = (READREG32(HW_REG_GXSTAT) & 0x2000) >> 0xD;
+ return 0;
+ }
+}
+
+ARM_FUNC u32 G3X_GetBoxTestResult(u32 *result){
+ if (READREG32(HW_REG_GXSTAT) & 0x1)
+ {
+ return -1;
+ }
+ else
+ {
+ *result = (READREG32(HW_REG_GXSTAT) & 0x2);
+ return 0;
+ }
+}
+
+ARM_FUNC void G3X_SetHOffset(u32 offset){
+ SETREG32(HW_REG_BG0HOFS, offset);
+}
diff --git a/arm9/lib/src/GX_load2d.c b/arm9/lib/src/GX_load2d.c
new file mode 100644
index 00000000..972babad
--- /dev/null
+++ b/arm9/lib/src/GX_load2d.c
@@ -0,0 +1,227 @@
+#include "global.h"
+#include "main.h"
+#include "gx.h"
+
+extern u32 gUnk02106814;
+
+extern s32 gUnk021D33F8;
+extern s32 gUnk021D33F4;
+extern u32 gUnk021D33F0;
+extern u32 gUnk021D33EC;
+extern s32 gUnk021D33E8;
+extern u32 gUnk021D33E4;
+extern s32 gUnk021D33E0;
+
+
+static inline void *_GX_OBJ_PTR(){
+ return (void *)0x6400000;
+}
+static inline void *_GXS_OBJ_PTR(){
+ return (void *)0x6600000;
+}
+
+ARM_FUNC void GX_LoadBGPltt(void *src, u32 offset, u32 size){
+ _GX_Load_16(gUnk02106814, src, (void *)(0x5000000 + offset), size);
+}
+
+ARM_FUNC void GXS_LoadBGPltt(void *src, u32 offset, u32 size){
+ _GX_Load_16(gUnk02106814, src, (void *)(0x5000400 + offset), size);
+}
+
+ARM_FUNC void GX_LoadOBJPltt(void *src, u32 offset, u32 size){
+ _GX_Load_16(gUnk02106814, src, (void *)(0x5000200 + offset), size);
+}
+
+ARM_FUNC void GXS_LoadOBJPltt(void *src, u32 offset, u32 size){
+ _GX_Load_16(gUnk02106814, src, (void *)(0x5000600 + offset), size);
+}
+
+ARM_FUNC void GX_LoadOAM(void *src, u32 offset, u32 size){
+ _GX_Load_32(gUnk02106814, src, (void *)(0x7000000 + offset), size);
+}
+
+ARM_FUNC void GXS_LoadOAM(void *src, u32 offset, u32 size){
+ _GX_Load_32(gUnk02106814, src, (void *)(0x7000400 + offset), size);
+}
+
+ARM_FUNC void GX_LoadOBJ(void *src, u32 offset, u32 size){
+ u32 base = (u32)_GX_OBJ_PTR();
+ _GX_Load_32(gUnk02106814, src, (void *)(base + offset), size);
+}
+
+ARM_FUNC void GXS_LoadOBJ(void *src, u32 offset, u32 size){
+ u32 base = (u32)_GXS_OBJ_PTR();
+ _GX_Load_32(gUnk02106814, src, (void *)(base + offset), size);
+}
+
+ARM_FUNC void GX_LoadBG0Scr(void *src, u32 offset, u32 size){
+ u32 base = (u32)G2_GetBG0ScrPtr();
+ _GX_Load_16(gUnk02106814, src, (void *)(base + offset), size);
+}
+
+ARM_FUNC void GXS_LoadBG0Scr(void *src, u32 offset, u32 size){
+ u32 base = (u32)G2S_GetBG0ScrPtr();
+ _GX_Load_16(gUnk02106814, src, (void *)(base + offset), size);
+}
+
+ARM_FUNC void GX_LoadBG1Scr(void *src, u32 offset, u32 size){
+ u32 base = (u32)G2_GetBG1ScrPtr();
+ _GX_Load_16(gUnk02106814, src, (void *)(base + offset), size);
+}
+
+ARM_FUNC void GXS_LoadBG1Scr(void *src, u32 offset, u32 size){
+ u32 base = (u32)G2S_GetBG1ScrPtr();
+ _GX_Load_16(gUnk02106814, src, (void *)(base + offset), size);
+}
+
+ARM_FUNC void GX_LoadBG2Scr(void *src, u32 offset, u32 size){
+ u32 base = (u32)G2_GetBG2ScrPtr();
+ _GX_Load_16(gUnk02106814, src, (void *)(base + offset), size);
+}
+
+ARM_FUNC void GXS_LoadBG2Scr(void *src, u32 offset, u32 size){
+ u32 base = (u32)G2S_GetBG2ScrPtr();
+ _GX_Load_16(gUnk02106814, src, (void *)(base + offset), size);
+}
+
+ARM_FUNC void GX_LoadBG3Scr(void *src, u32 offset, u32 size){
+ u32 base = (u32)G2_GetBG3ScrPtr();
+ _GX_Load_16(gUnk02106814, src, (void *)(base + offset), size);
+}
+
+ARM_FUNC void GXS_LoadBG3Scr(void *src, u32 offset, u32 size){
+ u32 base = (u32)G2S_GetBG3ScrPtr();
+ _GX_Load_16(gUnk02106814, src, (void *)(base + offset), size);
+}
+
+ARM_FUNC void GX_LoadBG0Char(void *src, u32 offset, u32 size){
+ u32 base = (u32)G2_GetBG0CharPtr();
+ _GX_Load_32(gUnk02106814, src, (void *)(base + offset), size);
+}
+
+ARM_FUNC void GXS_LoadBG0Char(void *src, u32 offset, u32 size){
+ u32 base = (u32)G2S_GetBG0CharPtr();
+ _GX_Load_32(gUnk02106814, src, (void *)(base + offset), size);
+}
+
+ARM_FUNC void GX_LoadBG1Char(void *src, u32 offset, u32 size){
+ u32 base = (u32)G2_GetBG1CharPtr();
+ _GX_Load_32(gUnk02106814, src, (void *)(base + offset), size);
+}
+
+ARM_FUNC void GXS_LoadBG1Char(void *src, u32 offset, u32 size){
+ u32 base = (u32)G2S_GetBG1CharPtr();
+ _GX_Load_32(gUnk02106814, src, (void *)(base + offset), size);
+}
+
+ARM_FUNC void GX_LoadBG2Char(void *src, u32 offset, u32 size){
+ u32 base = (u32)G2_GetBG2CharPtr();
+ _GX_Load_32(gUnk02106814, src, (void *)(base + offset), size);
+}
+
+ARM_FUNC void GXS_LoadBG2Char(void *src, u32 offset, u32 size){
+ u32 base = (u32)G2S_GetBG2CharPtr();
+ _GX_Load_32(gUnk02106814, src, (void *)(base + offset), size);
+}
+
+ARM_FUNC void GX_LoadBG3Char(void *src, u32 offset, u32 size){
+ u32 base = (u32)G2_GetBG3CharPtr();
+ _GX_Load_32(gUnk02106814, src, (void *)(base + offset), size);
+}
+
+ARM_FUNC void GXS_LoadBG3Char(void *src, u32 offset, u32 size){
+ u32 base = (u32)G2S_GetBG3CharPtr();
+ _GX_Load_32(gUnk02106814, src, (void *)(base + offset), size);
+}
+
+ARM_FUNC void GX_BeginLoadBGExtPltt(){
+ gUnk021D33F4 = GX_ResetBankForBGExtPltt();
+ switch (gUnk021D33F4)
+ {
+ case 0: //needed to match
+ break;
+ case 0x10:
+ gUnk021D33F0 = 0x06880000;
+ gUnk021D33EC = 0x0;
+ break;
+ case 0x40:
+ gUnk021D33F0 = 0x06894000;
+ gUnk021D33EC = 0x4000;
+ break;
+ case 0x20:
+ case 0x60:
+ gUnk021D33F0 = 0x06890000;
+ gUnk021D33EC = 0x0;
+ break;
+ }
+}
+
+ARM_FUNC void GX_LoadBGExtPltt(void *src, u32 offset, u32 size){
+ _GX_Load_32_Async(gUnk02106814, src, (void *)(gUnk021D33F0 + offset - gUnk021D33EC), size, NULL, NULL);
+}
+
+ARM_FUNC void GX_EndLoadBGExtPltt(){
+ if (gUnk02106814 != -1)
+ MI_WaitDma(gUnk02106814);
+ GX_SetBankForBGExtPltt(gUnk021D33F4);
+ gUnk021D33F4 = 0x0;
+ gUnk021D33F0 = 0x0;
+ gUnk021D33EC = 0x0;
+}
+
+ARM_FUNC void GX_BeginLoadOBJExtPltt(){
+ gUnk021D33E8 = GX_ResetBankForOBJExtPltt();
+ switch (gUnk021D33E8)
+ {
+ case 0: //needed to match
+ break;
+ case 0x40:
+ gUnk021D33E4 = 0x06894000;
+ break;
+ case 0x20:
+ gUnk021D33E4 = 0x06890000;
+ break;
+ }
+}
+
+ARM_FUNC void GX_LoadOBJExtPltt(void *src, u32 offset, u32 size){
+ _GX_Load_32_Async(gUnk02106814, src, (void *)(gUnk021D33E4 + offset), size, NULL, NULL);
+}
+
+ARM_FUNC void GX_EndLoadOBJExtPltt(){
+ if (gUnk02106814 != -1)
+ MI_WaitDma(gUnk02106814);
+ GX_SetBankForOBJExtPltt(gUnk021D33E8);
+ gUnk021D33E8 = 0x0;
+ gUnk021D33E4 = 0x0;
+}
+
+ARM_FUNC void GXS_BeginLoadBGExtPltt(){
+ gUnk021D33E0 = FUN_020C6034();
+}
+
+ARM_FUNC void GXS_LoadBGExtPltt(void *src, u32 offset, u32 size){
+ _GX_Load_32_Async(gUnk02106814, src, (void *)(0x06898000 + offset), size, NULL, NULL);
+}
+
+ARM_FUNC void GXS_EndLoadBGExtPltt(){
+ if (gUnk02106814 != -1)
+ MI_WaitDma(gUnk02106814);
+ GX_SetBankForSubBGExtPltt(gUnk021D33E0);
+ gUnk021D33E0 = 0x0;
+}
+
+ARM_FUNC void GXS_BeginLoadOBJExtPltt(){
+ gUnk021D33F8 = GX_ResetBankForSubOBJ();
+}
+
+ARM_FUNC void GXS_LoadOBJExtPltt(void *src, u32 offset, u32 size){
+ _GX_Load_32_Async(gUnk02106814, src, (void *)(0x068A0000 + offset), size, NULL, NULL);
+}
+
+ARM_FUNC void GXS_EndLoadOBJExtPltt(){
+ if (gUnk02106814 != -1)
+ MI_WaitDma(gUnk02106814);
+ GX_SetBankForSubOBJExtPltt(gUnk021D33F8);
+ gUnk021D33F8 = 0x0;
+}
diff --git a/arm9/lib/src/GX_load3d.c b/arm9/lib/src/GX_load3d.c
new file mode 100644
index 00000000..ee7502db
--- /dev/null
+++ b/arm9/lib/src/GX_load3d.c
@@ -0,0 +1,124 @@
+#include "global.h"
+#include "main.h"
+#include "gx.h"
+
+extern u32 gUnk02106814;
+
+extern u32 gUnk021D3410;
+extern u32 gUnk021D3400;
+extern u32 gUnk021D3414;
+extern u32 gUnk021D3418;
+
+//probably structs of length 0x6
+extern u16 gUnk02103B4C[];
+extern u16 gUnk02103B4E[];
+extern u16 gUnk02103B50[];
+
+extern u32 gUnk021D3408;
+extern u32 gUnk021D3404;
+extern u16 gUnk02103B3C[];
+
+extern s32 gUnk021D33FC;
+extern u32 gUnk021D340C;
+
+ARM_FUNC void GX_BeginLoadTex(){
+ u32 temp = GX_ResetBankForTex();
+ gUnk021D3410 = temp;
+ gUnk021D3400 = gUnk02103B4C[temp * 3] << 0xC;
+ gUnk021D3414 = gUnk02103B4E[temp * 3] << 0xC;
+ gUnk021D3418 = gUnk02103B50[temp * 3] << 0xC;
+}
+
+ARM_FUNC void GX_LoadTex(void *src, u32 offset, u32 size){
+ void *temp;
+ if (!gUnk021D3414)
+ {
+ temp = (void *)(gUnk021D3400 + offset);
+ }
+ else
+ {
+ if ((offset + size) < gUnk021D3418)
+ {
+ temp = (void *)(gUnk021D3400 + offset);
+ }
+ else if (offset >= gUnk021D3418)
+ {
+ temp = (void *)(gUnk021D3414 + offset - gUnk021D3418);
+ }
+ else
+ {
+ void *temp2 = (void *)gUnk021D3414;
+ u32 temp1 = gUnk021D3418 - offset;
+ temp = (void *)(gUnk021D3400 + offset);
+ _GX_Load_32(gUnk02106814, src, temp, temp1);
+ _GX_Load_32_Async(gUnk02106814, (void *)((u8 *)src + temp1), temp2, (size - temp1), NULL, NULL);
+ return;
+ }
+ }
+ _GX_Load_32_Async(gUnk02106814, src, temp, size, NULL, NULL);
+}
+
+ARM_FUNC void GX_EndLoadTex(){
+ if (gUnk02106814 != -1)
+ MI_WaitDma(gUnk02106814);
+ GX_SetBankForTex(gUnk021D3410);
+ gUnk021D3418 = 0x0;
+ gUnk021D3414 = 0x0;
+ gUnk021D3400 = 0x0;
+ gUnk021D3410 = 0x0;
+}
+
+ARM_FUNC void GX_BeginLoadTexPltt(){
+ s32 temp = GX_ResetBankForTexPltt();
+ gUnk021D3408 = temp;
+ gUnk021D3404 = gUnk02103B3C[temp >> 4] << 0xC;
+}
+
+ARM_FUNC void GX_LoadTexPltt(void *src, u32 offset, u32 size){
+ _GX_Load_32_Async(gUnk02106814, src, (void *)(gUnk021D3404 + offset), size, NULL, NULL);
+}
+
+ARM_FUNC void GX_EndLoadTexPltt(){
+ if (gUnk02106814 != -1)
+ MI_WaitDma(gUnk02106814);
+ GX_SetBankForTexPltt(gUnk021D3408);
+ gUnk021D3408 = 0x0;
+ gUnk021D3404 = 0x0;
+}
+
+ARM_FUNC void GX_BeginLoadClearImage(){
+ s32 temp = GX_ResetBankForClearImage();
+ gUnk021D33FC = temp;
+ switch (temp)
+ {
+ case 2:
+ case 3:
+ gUnk021D340C = 0x6800000;
+ return;
+ case 8:
+ case 12:
+ gUnk021D340C = 0x6840000;
+ return;
+ case 1:
+ gUnk021D340C = 0x67E0000;
+ return;
+ case 4:
+ gUnk021D340C = 0x6820000;
+ }
+}
+
+ARM_FUNC void GX_LoadClearImageColor(void *src, u32 size){
+ _GX_Load_32_Async(gUnk02106814, src, (void *)(gUnk021D340C), size, NULL, NULL);
+}
+
+ARM_FUNC void GX_LoadClearImageDepth(void *src, u32 size){
+ _GX_Load_32_Async(gUnk02106814, src, (void *)(gUnk021D340C + 0x20000), size, NULL, NULL);
+}
+
+ARM_FUNC void GX_EndLoadClearImage(){
+ if (gUnk02106814 != -1)
+ MI_WaitDma(gUnk02106814);
+ GX_SetBankForClearImage(gUnk021D33FC);
+ gUnk021D33FC = 0x0;
+ gUnk021D340C = 0x0;
+}
diff --git a/arm9/lib/src/GX_state.c b/arm9/lib/src/GX_state.c
new file mode 100644
index 00000000..38968523
--- /dev/null
+++ b/arm9/lib/src/GX_state.c
@@ -0,0 +1,26 @@
+#include "global.h"
+#include "main.h"
+#include "gx.h"
+
+extern struct VRAM_banks gUnk021D33C4;
+
+ARM_FUNC void GX_InitGXState(){
+ gUnk021D33C4.var00 = 0x0;
+ gUnk021D33C4.var02 = 0x0;
+ gUnk021D33C4.var04 = 0x0;
+ gUnk021D33C4.var06 = 0x0;
+ gUnk021D33C4.var08 = 0x0;
+ gUnk021D33C4.var0A = 0x0;
+ gUnk021D33C4.var0C = 0x0;
+ gUnk021D33C4.var0E = 0x0;
+ gUnk021D33C4.var10 = 0x0;
+ gUnk021D33C4.var12 = 0x0;
+ gUnk021D33C4.var14 = 0x0;
+ gUnk021D33C4.var16 = 0x0;
+ gUnk021D33C4.var18 = 0x0;
+ SETREG32(HW_REG_VRAMCNT_A, 0x0);
+ SETREG8(HW_REG_VRAMCNT_E, 0x0);
+ SETREG8(HW_REG_VRAMCNT_F, 0x0);
+ SETREG8(HW_REG_VRAMCNT_G, 0x0);
+ SETREG16(HW_REG_VRAMCNT_H, 0x0);
+}
diff --git a/arm9/lib/src/GX_vramcnt.c b/arm9/lib/src/GX_vramcnt.c
new file mode 100644
index 00000000..24862470
--- /dev/null
+++ b/arm9/lib/src/GX_vramcnt.c
@@ -0,0 +1,579 @@
+#include "global.h"
+#include "main.h"
+#include "gx.h"
+
+extern u16 gUnk021D33BC;
+extern struct VRAM_banks gUnk021D33C4;
+
+ARM_FUNC void GX_VRAMCNT_SetLCDC_(u32 mask){
+ if (mask & (0x1 << 0))
+ SETREG8(HW_REG_VRAMCNT_A, 0x80);
+ if (mask & (0x1 << 1))
+ SETREG8(HW_REG_VRAMCNT_B, 0x80);
+ if (mask & (0x1 << 2))
+ SETREG8(HW_REG_VRAMCNT_C, 0x80);
+ if (mask & (0x1 << 3))
+ SETREG8(HW_REG_VRAMCNT_D, 0x80);
+ if (mask & (0x1 << 4))
+ SETREG8(HW_REG_VRAMCNT_E, 0x80);
+ if (mask & (0x1 << 5))
+ SETREG8(HW_REG_VRAMCNT_F, 0x80);
+ if (mask & (0x1 << 6))
+ SETREG8(HW_REG_VRAMCNT_G, 0x80);
+ if (mask & (0x1 << 7))
+ SETREG8(HW_REG_VRAMCNT_H, 0x80);
+ if (mask & (0x1 << 8))
+ SETREG8(HW_REG_VRAMCNT_I, 0x80);
+}
+
+ARM_FUNC void GX_SetBankForBG(s32 bg){
+ gUnk021D33C4.var00 = (u16)(~bg & (gUnk021D33C4.var00 | gUnk021D33C4.var02));
+ gUnk021D33C4.var02 = bg;
+ switch (bg)
+ {
+ case 8:
+ SETREG8(HW_REG_VRAMCNT_D, 0x81);
+ break;
+ case 12:
+ SETREG8(HW_REG_VRAMCNT_D, 0x89);
+ case 4:
+ SETREG8(HW_REG_VRAMCNT_C, 0x81);
+ break;
+ case 14:
+ SETREG8(HW_REG_VRAMCNT_D, 0x91);
+ case 6:
+ SETREG8(HW_REG_VRAMCNT_C, 0x89);
+ case 2:
+ SETREG8(HW_REG_VRAMCNT_B, 0x81);
+ break;
+ case 15:
+ SETREG8(HW_REG_VRAMCNT_D, 0x99);
+ case 7:
+ SETREG8(HW_REG_VRAMCNT_C, 0x91);
+ case 3:
+ SETREG8(HW_REG_VRAMCNT_B, 0x89);
+ case 1:
+ SETREG8(HW_REG_VRAMCNT_A, 0x81);
+ break;
+ case 11:
+ SETREG8(HW_REG_VRAMCNT_A, 0x81);
+ SETREG8(HW_REG_VRAMCNT_B, 0x89);
+ SETREG8(HW_REG_VRAMCNT_D, 0x91);
+ break;
+ case 13:
+ SETREG8(HW_REG_VRAMCNT_D, 0x91);
+ case 5:
+ SETREG8(HW_REG_VRAMCNT_A, 0x81);
+ SETREG8(HW_REG_VRAMCNT_C, 0x89);
+ break;
+ case 9:
+ SETREG8(HW_REG_VRAMCNT_A, 0x81);
+ SETREG8(HW_REG_VRAMCNT_D, 0x89);
+ break;
+ case 10:
+ SETREG8(HW_REG_VRAMCNT_B, 0x81);
+ SETREG8(HW_REG_VRAMCNT_D, 0x89);
+ break;
+ case 112:
+ SETREG8(HW_REG_VRAMCNT_G, 0x99);
+ case 48:
+ SETREG8(HW_REG_VRAMCNT_F, 0x91);
+ case 16:
+ SETREG8(HW_REG_VRAMCNT_E, 0x81);
+ break;
+ case 80:
+ SETREG8(HW_REG_VRAMCNT_G, 0x91);
+ SETREG8(HW_REG_VRAMCNT_E, 0x81);
+ break;
+ case 96:
+ SETREG8(HW_REG_VRAMCNT_G, 0x89);
+ case 32:
+ SETREG8(HW_REG_VRAMCNT_F, 0x81);
+ break;
+ case 64:
+ SETREG8(HW_REG_VRAMCNT_G, 0x81);
+ break;
+ default:
+ break;
+ }
+ GX_VRAMCNT_SetLCDC_(gUnk021D33C4.var00);
+}
+
+ARM_FUNC void GX_SetBankForOBJ(s32 obj){
+ gUnk021D33C4.var00 = (u16)(~obj & (gUnk021D33C4.var00 | gUnk021D33C4.var04));
+ gUnk021D33C4.var04 = obj;
+ switch (obj)
+ {
+ case 3:
+ SETREG8(HW_REG_VRAMCNT_B, 0x8A);
+ case 1:
+ SETREG8(HW_REG_VRAMCNT_A, 0x82);
+ case 0: //needed to match
+ break;
+ case 2:
+ SETREG8(HW_REG_VRAMCNT_B, 0x82);
+ break;
+ case 112:
+ SETREG8(HW_REG_VRAMCNT_G, 0x9A);
+ case 48:
+ SETREG8(HW_REG_VRAMCNT_F, 0x92);
+ case 16:
+ SETREG8(HW_REG_VRAMCNT_E, 0x82);
+ break;
+ case 80:
+ SETREG8(HW_REG_VRAMCNT_G, 0x92);
+ SETREG8(HW_REG_VRAMCNT_E, 0x82);
+ break;
+ case 96:
+ SETREG8(HW_REG_VRAMCNT_G, 0x8A);
+ case 32:
+ SETREG8(HW_REG_VRAMCNT_F, 0x82);
+ break;
+ case 64:
+ SETREG8(HW_REG_VRAMCNT_G, 0x82);
+ break;
+ default:
+ break;
+ }
+ GX_VRAMCNT_SetLCDC_(gUnk021D33C4.var00);
+}
+
+ARM_FUNC void GX_SetBankForBGExtPltt(s32 bgextpltt){
+ gUnk021D33C4.var00 = (u16)(~bgextpltt & (gUnk021D33C4.var00 | gUnk021D33C4.var0E));
+ gUnk021D33C4.var0E = bgextpltt;
+ switch (bgextpltt)
+ {
+ case 0x10:
+ SETREG32(HW_REG_DISPCNT, READREG32(HW_REG_DISPCNT) | 0x40000000);
+ SETREG8(HW_REG_VRAMCNT_E, 0x84);
+ break;
+ case 0x40:
+ SETREG32(HW_REG_DISPCNT, READREG32(HW_REG_DISPCNT) | 0x40000000);
+ SETREG8(HW_REG_VRAMCNT_G, 0x8C);
+ break;
+ case 0x60:
+ SETREG8(HW_REG_VRAMCNT_G, 0x8C);
+ case 0x20:
+ SETREG8(HW_REG_VRAMCNT_F, 0x84);
+ SETREG32(HW_REG_DISPCNT, READREG32(HW_REG_DISPCNT) | 0x40000000);
+ break;
+ case 0:
+ SETREG32(HW_REG_DISPCNT, READREG32(HW_REG_DISPCNT) & ~0x40000000);
+ break;
+ }
+ GX_VRAMCNT_SetLCDC_(gUnk021D33C4.var00);
+}
+
+ARM_FUNC void GX_SetBankForOBJExtPltt(s32 objextpltt){
+ gUnk021D33C4.var00 = (u16)(~objextpltt & (gUnk021D33C4.var00 | gUnk021D33C4.var10));
+ gUnk021D33C4.var10 = objextpltt;
+ switch (objextpltt)
+ {
+ case 32:
+ SETREG32(HW_REG_DISPCNT, READREG32(HW_REG_DISPCNT) | 0x80000000);
+ SETREG8(HW_REG_VRAMCNT_F, 0x85);
+ break;
+ case 64:
+ SETREG32(HW_REG_DISPCNT, READREG32(HW_REG_DISPCNT) | 0x80000000);
+ SETREG8(HW_REG_VRAMCNT_G, 0x85);
+ break;
+ case 0:
+ SETREG32(HW_REG_DISPCNT, READREG32(HW_REG_DISPCNT) & ~0x80000000);
+ break;
+ }
+ GX_VRAMCNT_SetLCDC_(gUnk021D33C4.var00);
+}
+
+ARM_FUNC void GX_SetBankForTex(s32 tex){
+ gUnk021D33C4.var00 = (u16)(~tex & (gUnk021D33C4.var00 | gUnk021D33C4.var08));
+ gUnk021D33C4.var08 = tex;
+ if (tex == 0)
+ {
+ SETREG16(HW_REG_DISP3DCNT, READREG16(HW_REG_DISP3DCNT) & 0x0000CFFE);
+ }
+ else
+ {
+ SETREG16(HW_REG_DISP3DCNT, (READREG16(HW_REG_DISP3DCNT) & ~0x3000) | 0x1);
+ switch (tex)
+ {
+ case 5:
+ SETREG8(HW_REG_VRAMCNT_A, 0x83);
+ SETREG8(HW_REG_VRAMCNT_C, 0x8B);
+ break;
+ case 9:
+ SETREG8(HW_REG_VRAMCNT_A, 0x83);
+ SETREG8(HW_REG_VRAMCNT_D, 0x8B);
+ break;
+ case 10:
+ SETREG8(HW_REG_VRAMCNT_B, 0x83);
+ SETREG8(HW_REG_VRAMCNT_D, 0x8B);
+ break;
+ case 11:
+ SETREG8(HW_REG_VRAMCNT_A, 0x83);
+ SETREG8(HW_REG_VRAMCNT_B, 0x8B);
+ SETREG8(HW_REG_VRAMCNT_D, 0x93);
+ break;
+ case 13:
+ SETREG8(HW_REG_VRAMCNT_A, 0x83);
+ SETREG8(HW_REG_VRAMCNT_C, 0x8B);
+ SETREG8(HW_REG_VRAMCNT_D, 0x93);
+ break;
+ case 8:
+ SETREG8(HW_REG_VRAMCNT_D, 0x83);
+ break;
+ case 12:
+ SETREG8(HW_REG_VRAMCNT_D, 0x8B);
+ case 4:
+ SETREG8(HW_REG_VRAMCNT_C, 0x83);
+ break;
+ case 14:
+ SETREG8(HW_REG_VRAMCNT_D, 0x93);
+ case 6:
+ SETREG8(HW_REG_VRAMCNT_C, 0x8B);
+ case 2:
+ SETREG8(HW_REG_VRAMCNT_B, 0x83);
+ break;
+ case 15:
+ SETREG8(HW_REG_VRAMCNT_D, 0x9B);
+ case 7:
+ SETREG8(HW_REG_VRAMCNT_C, 0x93);
+ case 3:
+ SETREG8(HW_REG_VRAMCNT_B, 0x8B);
+ case 1:
+ SETREG8(HW_REG_VRAMCNT_A, 0x83);
+ break;
+ }
+ }
+ GX_VRAMCNT_SetLCDC_(gUnk021D33C4.var00);
+}
+
+ARM_FUNC void GX_SetBankForTexPltt(s32 texpltt){
+ gUnk021D33C4.var00 = (u16)(~texpltt & (gUnk021D33C4.var00 | gUnk021D33C4.var0A));
+ gUnk021D33C4.var0A = texpltt;
+ switch (texpltt)
+ {
+ case 0: //needed to match
+ break;
+ case 96:
+ SETREG8(HW_REG_VRAMCNT_G, 0x8B);
+ case 32:
+ SETREG8(HW_REG_VRAMCNT_F, 0x83);
+ break;
+ case 112:
+ SETREG8(HW_REG_VRAMCNT_G, 0x9B);
+ case 48:
+ SETREG8(HW_REG_VRAMCNT_F, 0x93);
+ case 16:
+ SETREG8(HW_REG_VRAMCNT_E, 0x83);
+ break;
+ case 64:
+ SETREG8(HW_REG_VRAMCNT_G, 0x83);
+ break;
+ }
+ GX_VRAMCNT_SetLCDC_(gUnk021D33C4.var00);
+}
+
+ARM_FUNC void GX_SetBankForClearImage(s32 clearimage){
+ gUnk021D33C4.var00 = (u16)(~clearimage & (gUnk021D33C4.var00 | gUnk021D33C4.var0C));
+ gUnk021D33C4.var0C = clearimage;
+ switch (clearimage)
+ {
+ case 3:
+ SETREG8(HW_REG_VRAMCNT_A, 0x93);
+ case 2:
+ SETREG8(HW_REG_VRAMCNT_B, 0x9B);
+ SETREG16(HW_REG_DISP3DCNT, READREG16(HW_REG_DISP3DCNT) | 0x4000);
+ break;
+ case 12:
+ SETREG8(HW_REG_VRAMCNT_C, 0x93);
+ case 8:
+ SETREG8(HW_REG_VRAMCNT_D, 0x9B);
+ SETREG16(HW_REG_DISP3DCNT, READREG16(HW_REG_DISP3DCNT) | 0x4000);
+ break;
+ case 0:
+ SETREG16(HW_REG_DISP3DCNT, READREG16(HW_REG_DISP3DCNT) & ~0x4000);
+ break;
+ case 1:
+ SETREG8(HW_REG_VRAMCNT_A, 0x9B);
+ SETREG16(HW_REG_DISP3DCNT, READREG16(HW_REG_DISP3DCNT) | 0x4000);
+ break;
+ case 4:
+ SETREG8(HW_REG_VRAMCNT_C, 0x9B);
+ SETREG16(HW_REG_DISP3DCNT, READREG16(HW_REG_DISP3DCNT) | 0x4000);
+ }
+ GX_VRAMCNT_SetLCDC_(gUnk021D33C4.var00);
+}
+
+ARM_FUNC void GX_SetBankForARM7(s32 arm7){
+ gUnk021D33C4.var00 = (u16)(~arm7 & (gUnk021D33C4.var00 | gUnk021D33C4.var06));
+ gUnk021D33C4.var06 = arm7;
+ switch (arm7)
+ {
+ case 0: //needed to match
+ break;
+ case 12:
+ SETREG8(HW_REG_VRAMCNT_D, 0x8A);
+ SETREG8(HW_REG_VRAMCNT_C, 0x82);
+ break;
+ case 4:
+ SETREG8(HW_REG_VRAMCNT_C, 0x82);
+ break;
+ case 8:
+ SETREG8(HW_REG_VRAMCNT_D, 0x82);
+ }
+ GX_VRAMCNT_SetLCDC_(gUnk021D33C4.var00);
+}
+
+ARM_FUNC void GX_SetBankForLCDC(s32 lcdc){
+ gUnk021D33C4.var00 |= lcdc;
+ GX_VRAMCNT_SetLCDC_(lcdc);
+}
+
+ARM_FUNC void GX_SetBankForSubBG(s32 subbg){
+ gUnk021D33C4.var00 = (u16)(~subbg & (gUnk021D33C4.var00 | gUnk021D33C4.var12));
+ gUnk021D33C4.var12 = subbg;
+ switch (subbg)
+ {
+ case 0: //needed to match
+ break;
+ case 4:
+ SETREG8(HW_REG_VRAMCNT_C, 0x84);
+ break;
+ case 384:
+ SETREG8(HW_REG_VRAMCNT_I, 0x81);
+ case 128:
+ SETREG8(HW_REG_VRAMCNT_H, 0x81);
+ }
+ GX_VRAMCNT_SetLCDC_(gUnk021D33C4.var00);
+}
+
+
+ARM_FUNC void GX_SetBankForSubOBJ(s32 subobj){
+ gUnk021D33C4.var00 = (u16)(~subobj & (gUnk021D33C4.var00 | gUnk021D33C4.var14));
+ gUnk021D33C4.var14 = subobj;
+ switch (subobj)
+ {
+ case 8:
+ SETREG8(HW_REG_VRAMCNT_D, 0x84);
+ break;
+ case 256:
+ SETREG8(HW_REG_VRAMCNT_I, 0x82);
+ break;
+ case 0: //needed to match
+ break;
+ }
+ GX_VRAMCNT_SetLCDC_(gUnk021D33C4.var00);
+}
+
+ARM_FUNC void GX_SetBankForSubBGExtPltt(s32 subbgextpltt){
+ gUnk021D33C4.var00 = (u16)(~subbgextpltt & (gUnk021D33C4.var00 | gUnk021D33C4.var16));
+ gUnk021D33C4.var16 = subbgextpltt;
+ switch (subbgextpltt)
+ {
+ case 128:
+ SETREG32(HW_REG_DISPCNT_2D, READREG32(HW_REG_DISPCNT_2D) | 0x40000000);
+ SETREG8(HW_REG_VRAMCNT_H, 0x82);
+ break;
+ case 0:
+ SETREG32(HW_REG_DISPCNT_2D, READREG32(HW_REG_DISPCNT_2D) & ~0x40000000);
+ break;
+ }
+ GX_VRAMCNT_SetLCDC_(gUnk021D33C4.var00);
+}
+
+ARM_FUNC void GX_SetBankForSubOBJExtPltt(s32 subobjextpltt){
+ gUnk021D33C4.var00 = (u16)(~subobjextpltt & (gUnk021D33C4.var00 | gUnk021D33C4.var18));
+ gUnk021D33C4.var18 = subobjextpltt;
+ switch (subobjextpltt)
+ {
+ case 256:
+ SETREG32(HW_REG_DISPCNT_2D, READREG32(HW_REG_DISPCNT_2D) | 0x80000000);
+ SETREG8(HW_REG_VRAMCNT_I, 0x83);
+ break;
+ case 0:
+ SETREG32(HW_REG_DISPCNT_2D, READREG32(HW_REG_DISPCNT_2D) & ~0x80000000);
+ break;
+ }
+ GX_VRAMCNT_SetLCDC_(gUnk021D33C4.var00);
+}
+
+ARM_FUNC u32 FUN_020C6130(u16 *ptr){
+ u16 temp = *ptr;
+ *ptr = 0;
+ gUnk021D33C4.var00 |= temp;
+ GX_VRAMCNT_SetLCDC_(temp);
+ return temp;
+}
+
+ARM_FUNC u32 GX_ResetBankForBG(){
+ return FUN_020C6130(&gUnk021D33C4.var02);
+}
+
+ARM_FUNC u32 GX_ResetBankForOBJ(){
+ return FUN_020C6130(&gUnk021D33C4.var04);
+}
+
+ARM_FUNC u32 GX_ResetBankForBGExtPltt(){
+ SETREG32(HW_REG_DISPCNT, READREG32(HW_REG_DISPCNT) & ~0x40000000);
+ return FUN_020C6130(&gUnk021D33C4.var0E);
+}
+
+ARM_FUNC u32 GX_ResetBankForOBJExtPltt(){
+ SETREG32(HW_REG_DISPCNT, READREG32(HW_REG_DISPCNT) & ~0x80000000);
+ return FUN_020C6130(&gUnk021D33C4.var10);
+}
+
+ARM_FUNC u32 GX_ResetBankForTex(){
+ return FUN_020C6130(&gUnk021D33C4.var08);
+}
+
+ARM_FUNC u32 GX_ResetBankForTexPltt(){
+ return FUN_020C6130(&gUnk021D33C4.var0A);
+}
+
+ARM_FUNC u32 GX_ResetBankForClearImage(){
+ return FUN_020C6130(&gUnk021D33C4.var0C);
+}
+
+ARM_FUNC u32 GX_ResetBankForSubBG(){
+ return FUN_020C6130(&gUnk021D33C4.var12);
+}
+
+ARM_FUNC u32 FUN_020C605C(){
+ return FUN_020C6130(&gUnk021D33C4.var14);
+}
+
+ARM_FUNC u32 FUN_020C6034(){
+ SETREG32(HW_REG_DISPCNT_2D, READREG32(HW_REG_DISPCNT_2D) & ~0x40000000);
+ return FUN_020C6130(&gUnk021D33C4.var16);
+}
+
+ARM_FUNC u32 GX_ResetBankForSubOBJ(){
+ SETREG32(HW_REG_DISPCNT_2D, READREG32(HW_REG_DISPCNT_2D) & ~0x80000000);
+ return FUN_020C6130(&gUnk021D33C4.var18);
+}
+
+ARM_FUNC u32 FUN_020C5F28(u16 *ptr){
+ u32 temp = *ptr;
+ *ptr = 0;
+ if (temp & (0x1 << 0))
+ SETREG8(HW_REG_VRAMCNT_A, 0x0);
+ if (temp & (0x1 << 1))
+ SETREG8(HW_REG_VRAMCNT_B, 0x0);
+ if (temp & (0x1 << 2))
+ SETREG8(HW_REG_VRAMCNT_C, 0x0);
+ if (temp & (0x1 << 3))
+ SETREG8(HW_REG_VRAMCNT_D, 0x0);
+ if (temp & (0x1 << 4))
+ SETREG8(HW_REG_VRAMCNT_E, 0x0);
+ if (temp & (0x1 << 5))
+ SETREG8(HW_REG_VRAMCNT_F, 0x0);
+ if (temp & (0x1 << 6))
+ SETREG8(HW_REG_VRAMCNT_G, 0x0);
+ if (temp & (0x1 << 7))
+ SETREG8(HW_REG_VRAMCNT_H, 0x0);
+ if (temp & (0x1 << 8))
+ SETREG8(HW_REG_VRAMCNT_I, 0x0);
+ OSi_UnlockVram((u16)temp, gUnk021D33BC);
+ return temp;
+}
+
+ARM_FUNC u32 disableBankForX_(){
+ return FUN_020C5F28(&gUnk021D33C4.var02);
+}
+
+ARM_FUNC u32 GX_DisableBankForOBJExtPltt_2(){
+ return FUN_020C5F28(&gUnk021D33C4.var04);
+}
+
+ARM_FUNC u32 GX_DisableBankForBGExtPltt(){
+ SETREG32(HW_REG_DISPCNT, READREG32(HW_REG_DISPCNT) & ~0x40000000);
+ return FUN_020C5F28(&gUnk021D33C4.var0E);
+}
+
+ARM_FUNC u32 GX_DisableBankForOBJExtPltt(){
+ SETREG32(HW_REG_DISPCNT, READREG32(HW_REG_DISPCNT) & ~0x80000000);
+ return FUN_020C5F28(&gUnk021D33C4.var10);
+}
+
+ARM_FUNC u32 GX_DisableBankForTexPltt_2(){
+ return FUN_020C5F28(&gUnk021D33C4.var08);
+}
+
+ARM_FUNC u32 GX_DisableBankForTexPltt(){
+ return FUN_020C5F28(&gUnk021D33C4.var0A);
+}
+
+ARM_FUNC u32 GX_DisableBankForClearImage(){
+ return FUN_020C5F28(&gUnk021D33C4.var0C);
+}
+
+ARM_FUNC u32 GX_DisableBankForARM7(){
+ return FUN_020C5F28(&gUnk021D33C4.var06);
+}
+
+ARM_FUNC u32 GX_DisableBankForLCDC(){
+ return FUN_020C5F28(&gUnk021D33C4.var00);
+}
+
+ARM_FUNC u32 GX_DisableBankForSubBGExtPltt(){
+ return FUN_020C5F28(&gUnk021D33C4.var12);
+}
+
+ARM_FUNC u32 GX_DisableBankForSubOBJExtPltt_2(){
+ return FUN_020C5F28(&gUnk021D33C4.var14);
+}
+
+ARM_FUNC u32 FUN_020C5E04(){
+ SETREG32(HW_REG_DISPCNT_2D, READREG32(HW_REG_DISPCNT_2D) & ~0x40000000);
+ return FUN_020C5F28(&gUnk021D33C4.var16);
+}
+
+ARM_FUNC u32 GX_DisableBankForSubOBJExtPltt(){
+ SETREG32(HW_REG_DISPCNT_2D, READREG32(HW_REG_DISPCNT_2D) & ~0x80000000);
+ return FUN_020C5F28(&gUnk021D33C4.var18);
+}
+
+ARM_FUNC u32 GX_GetBankForBGExtPltt_2(){
+ return gUnk021D33C4.var02;
+}
+
+ARM_FUNC u32 GX_GetBankForOBJ(){
+ return gUnk021D33C4.var04;
+}
+
+ARM_FUNC u32 GX_GetBankForBGExtPltt(){
+ return gUnk021D33C4.var0E;
+}
+
+ARM_FUNC u32 GX_GetBankForOBJExtPltt(){
+ return gUnk021D33C4.var10;
+}
+
+ARM_FUNC u32 FUN_020C5D8C(){
+ return gUnk021D33C4.var08;
+}
+
+ARM_FUNC u32 GX_GetBankForTexPltt(){
+ return gUnk021D33C4.var0A;
+}
+
+ARM_FUNC u32 GX_GetBankForLCDC(){
+ return gUnk021D33C4.var00;
+}
+
+ARM_FUNC u32 GX_GetBankForSubBGExtPltt_2(){
+ return gUnk021D33C4.var12;
+}
+
+ARM_FUNC u32 GX_GetBankForSubOBJ(){
+ return gUnk021D33C4.var14;
+}
+
+ARM_FUNC u32 GX_GetBankForSubBGExtPltt(){
+ return gUnk021D33C4.var16;
+}
+
+ARM_FUNC u32 GX_GetBankForSubOBJExtPltt(){
+ return gUnk021D33C4.var18;
+}