summaryrefslogtreecommitdiff
path: root/arm9/src/game_init.c
diff options
context:
space:
mode:
Diffstat (limited to 'arm9/src/game_init.c')
-rw-r--r--arm9/src/game_init.c532
1 files changed, 532 insertions, 0 deletions
diff --git a/arm9/src/game_init.c b/arm9/src/game_init.c
new file mode 100644
index 00000000..327c66c6
--- /dev/null
+++ b/arm9/src/game_init.c
@@ -0,0 +1,532 @@
+#include "global.h"
+#include "gx.h"
+#include "math.h"
+#include "main.h"
+#include "FS_rom.h"
+#include "PAD_pad.h"
+#include "heap.h"
+#include "MWC_string.h"
+#include "tp.h"
+#include "unk_0201B4E8.h"
+#include "game_init.h"
+#include "registers.h"
+
+#pragma thumb on
+
+extern void FUN_020166C8(const u32 (*)[2], int, int, int);
+extern void FUN_02022450(void);
+
+typedef volatile struct
+{
+ u8 sys_and_irq_stack[0x3F80];
+ u8 svc_stack[0x40];
+ u8 reserved[0x38];
+ u32 intr_check;
+ void * intr_vector;
+}
+OS_DTCM;
+
+#define DTCM (*(OS_DTCM *)HW_DTCM)
+
+static struct {
+ void * contents;
+ u32 name_hash;
+} UNK_021C4928[128];
+
+struct Main gMain;
+
+void Main_HBlankIntr(BOOL);
+void FUN_0201B5CC(void *);
+
+void FUN_02015EA0(void)
+{
+ DTCM.intr_check |= 1;
+ MI_WaitDma(3);
+ FUN_0201B5CC(gMain.unk1C);
+ gMain.unk30++;
+}
+
+void FUN_02015ED4(void)
+{
+ DTCM.intr_check |= 1;
+ MI_WaitDma(3);
+}
+
+void FUN_02015EF4(void)
+{
+ OS_DisableIrqMask(1);
+ OS_SetIrqFunction(1, FUN_02015ED4);
+ OS_EnableIrqMask(1);
+}
+
+void Main_SetVBlankIntrCB(void (*a0)(void *), void * a1)
+{
+ gMain.vBlankIntr = a0;
+ gMain.vBlankIntrArg = a1;
+}
+
+void FUN_02015F1C(void)
+{
+ Main_HBlankIntr(FALSE);
+ gMain.hBlankIntr = NULL;
+ gMain.hBlankIntrArg = NULL;
+}
+
+BOOL FUN_02015F34(void (*a0)(void *), void * a1)
+{
+ if (a0 == 0)
+ {
+ Main_HBlankIntr(FALSE);
+ gMain.hBlankIntr = NULL;
+ gMain.hBlankIntrArg = NULL;
+ return TRUE;
+ }
+ else if (gMain.hBlankIntr == NULL)
+ {
+ gMain.hBlankIntrArg = a1;
+ gMain.hBlankIntr = a0;
+ Main_HBlankIntr(TRUE);
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
+void FUN_02015F6C(void)
+{
+ if (gMain.hBlankIntr != NULL)
+ gMain.hBlankIntr(gMain.hBlankIntrArg);
+}
+
+void Main_HBlankIntr(BOOL a0)
+{
+ (void)OS_DisableIrq();
+ if (!a0)
+ {
+ (void)OS_GetIrqMask();
+ OS_DisableIrqMask(2);
+ GX_HBlankIntr(FALSE);
+ }
+ else
+ {
+ (void)OS_GetIrqMask();
+ OS_SetIrqFunction(2, FUN_02015F6C);
+ OS_EnableIrqMask(2);
+ GX_HBlankIntr(TRUE);
+ }
+ (void)OS_EnableIrq();
+}
+
+const u32 UNK_020EDB10[][2] = {
+ { 0x0000D000, 0x00000000 },
+ { 0x00021000, 0x00000000 },
+ { 0x00001000, 0x00000000 },
+ { 0x0010D800, 0x00000000 }
+};
+
+void FUN_02015FC8(void)
+{
+ u32 data[8];
+ u8 digest[16];
+ OS_GetLowEntropyData(data);
+ MATH_CalcMD5(digest, data, 32);
+ u32 csum = 0, i;
+ for (i = 0; i < sizeof(digest); i++)
+ {
+ csum += digest[i];
+ }
+ csum = (csum << 24) >> 24;
+ while (csum & 3)
+ {
+ csum++;
+ }
+ FUN_020166C8(UNK_020EDB10, 4, 92, (int)csum);
+}
+
+void InitSystemForTheGame(void)
+{
+ OS_Init();
+ FX_Init();
+ reg_GX_POWCNT = (REGType16v)((reg_GX_POWCNT & ~(REG_GX_POWCNT_GE_MASK | REG_GX_POWCNT_RE_MASK | REG_GX_POWCNT_E2DG_MASK | REG_GX_POWCNT_E2DGB_MASK)) | (REG_GX_POWCNT_GE_MASK | REG_GX_POWCNT_RE_MASK | REG_GX_POWCNT_E2DG_MASK | REG_GX_POWCNT_E2DGB_MASK));
+ GX_Init();
+ OS_InitTick();
+ FUN_02015FC8();
+ gMain.unk18 = FUN_0201B580(0xa0, OS_AllocFromArenaLo(OS_ARENA_MAIN, FUN_0201B578(0xa0), 4));
+ gMain.unk1C = FUN_0201B580(0x10, OS_AllocFromArenaLo(OS_ARENA_MAIN, FUN_0201B578(0x10), 4));
+ gMain.unk20 = FUN_0201B580(0x20, OS_AllocFromArenaLo(OS_ARENA_MAIN, FUN_0201B578(0x20), 4));
+ gMain.unk24 = FUN_0201B580(0x04, OS_AllocFromArenaLo(OS_ARENA_MAIN, FUN_0201B578(0x04), 4));
+ GX_DispOff();
+ reg_GXS_DB_DISPCNT &= ~0x10000;
+ reg_GX_POWCNT |= REG_GX_POWCNT_DSEL_MASK;
+ OS_SetIrqFunction(1, FUN_02015EA0);
+ OS_EnableIrqMask(1);
+ OS_EnableIrqMask(0x40000);
+ (void)OS_EnableIrq();
+ GX_VBlankIntr(TRUE);
+ FS_Init(1);
+ FUN_02022450();
+ u32 size = FS_TryLoadTable(NULL, 0);
+ void * table = OS_AllocFromArenaLo(OS_ARENA_MAIN, size, 4);
+ GF_ASSERT(table != NULL);
+ FS_TryLoadTable(table, size);
+ gMain.vBlankIntr = NULL;
+ gMain.hBlankIntr = NULL;
+ gMain.unk10 = 0;
+ gMain.unk14 = 0;
+ gMain.unk2C = 0;
+ gMain.unk65 = 0;
+}
+
+void InitGraphicMemory(void)
+{
+ GX_SetBankForLCDC(0x1FF);
+ MIi_CpuClearFast(0, (void *)HW_LCDC_VRAM, HW_LCDC_VRAM_SIZE);
+ GX_DisableBankForLCDC();
+ MIi_CpuClearFast(0xC0, (void *)HW_OAM, HW_OAM_SIZE);
+ MIi_CpuClearFast(0xC0, (void *)HW_DB_OAM, HW_DB_OAM_SIZE);
+ MIi_CpuClearFast(0, (void *)HW_PLTT, HW_PLTT_SIZE);
+ MIi_CpuClearFast(0, (void *)HW_DB_PLTT, HW_DB_PLTT_SIZE);
+}
+
+void * FUN_020161A4(u32 heap_id, const char * path)
+{
+ void * ret;
+
+ FSFile file;
+ FS_InitFile(&file);
+ if (FS_OpenFile(&file, path))
+ {
+ u32 size = file.prop.file.bottom - file.prop.file.top;
+ ret = AllocFromHeap(heap_id, size);
+ if (ret != NULL)
+ {
+ if (size != FS_ReadFile(&file, ret, (s32)size))
+ {
+ FUN_02016A8C(heap_id, ret);
+ ret = NULL;
+ }
+ }
+ FS_CloseFile(&file);
+ }
+ else
+ ret = NULL;
+ return ret;
+}
+
+void FUN_020161F8(const char * path, void ** ptr)
+{
+ FSFile file;
+ FS_InitFile(&file);
+ if (FS_OpenFile(&file, path))
+ {
+ u32 size = file.prop.file.bottom - file.prop.file.top;
+ if (*ptr != NULL)
+ FS_ReadFile(&file, *ptr, (s32)size);
+ FS_CloseFile(&file);
+ }
+}
+
+u32 FUN_02016230(const s8 * str)
+{
+ u16 len = (u16)strlen(str);
+ u16 sp4;
+ if ((len % 4) != 0)
+ sp4 = (u16)((len / 4) + 1);
+ else
+ sp4 = (u16)(len / 4);
+ u32 r7 = 0;
+ s32 i, j;
+ for (i = 0; i < sp4; i++)
+ {
+ u32 r1 = 0;
+ for (j = 0; j < 4; j++)
+ {
+ int r5 = str[4 * i + j];
+ if (r5 == 0)
+ break;
+ r1 |= r5 << (8 * j);
+ }
+ r7 ^= r1;
+ }
+ return r7;
+}
+
+int FUN_020162A0(u32 a0)
+{
+ for (int i = 0; i < 128; i++)
+ {
+ if (UNK_021C4928[i].name_hash == a0 && UNK_021C4928[i].contents != NULL)
+ return i;
+ }
+ return -1;
+}
+
+int FUN_020162C8(void * a0, u32 a1)
+{
+ for (int i = 0; i < 128; i++)
+ {
+ if (UNK_021C4928[i].contents == NULL)
+ {
+ UNK_021C4928[i].contents = a0;
+ UNK_021C4928[i].name_hash = a1;
+ return i;
+ }
+ }
+ return -1;
+}
+
+void FUN_020162FC(void)
+{
+ for (int i = 127; i > -1; i--)
+ {
+ if (UNK_021C4928[i].contents != NULL)
+ {
+ FreeToHeap(UNK_021C4928[i].contents);
+ UNK_021C4928[i].contents = NULL;
+ UNK_021C4928[i].name_hash = 0;
+ }
+ }
+}
+
+void * FUN_02016324(const s8 * str, u32 heap_id)
+{
+ s8 sp0[32];
+ FSFile file;
+ void * ret;
+ int r5 = 0;
+
+ if (str[0] == '!')
+ {
+ strcpy(sp0, str + 1);
+ r5 = 1;
+ }
+ else
+ {
+ strcpy(sp0, str);
+ }
+ u32 r7 = FUN_02016230(sp0);
+ s32 r0 = FUN_020162A0(r7);
+ if (r0 >= 0 && r5 == 0)
+ {
+ ret = UNK_021C4928[r0].contents;
+ }
+ else
+ {
+ FS_InitFile(&file);
+ if (FS_OpenFile(&file, (const char *)sp0))
+ {
+ u32 size = file.prop.file.bottom - file.prop.file.top;
+ ret = AllocFromHeap(heap_id, size);
+ if (ret != NULL)
+ {
+ if (size != FS_ReadFile(&file, ret, (s32)size))
+ {
+ FreeToHeap(ret);
+ ret = NULL;
+ }
+ }
+ FS_CloseFile(&file);
+ if (r5 == 0)
+ FUN_020162C8(ret, r7);
+ }
+ else
+ ret = NULL;
+ }
+ return ret;
+}
+
+void FUN_020163BC(void)
+{
+ TPCalibrateParam tp;
+ gMain.unk34 = 0;
+ gMain.unk38 = 0;
+ gMain.unk3C = 0;
+ gMain.unk40 = 0;
+ gMain.unk44 = 0;
+ gMain.unk48 = 0;
+ gMain.unk4C = 0;
+ gMain.unk50 = 0;
+ gMain.unk54 = 8;
+ gMain.unk58 = 15;
+ gMain.unk5C = 0;
+ gMain.unk5E = 0;
+ gMain.unk60 = 0;
+ gMain.unk62 = 0;
+ gMain.unk64 = 0;
+ TP_Init();
+ if (TP_GetUserInfo(&tp) == TRUE)
+ TP_SetCalibrateParam(&tp);
+ else
+ {
+ tp.x0 = 686;
+ tp.y0 = 1420;
+ tp.xDotSize = 3621;
+ tp.yDotSize = 4616;
+ TP_SetCalibrateParam(&tp);
+ }
+}
+
+void FUN_02016438(u8 a0)
+{
+ gMain.unk66 = a0;
+}
+
+void FUN_02016444(u8 a0)
+{
+ gMain.unk67 |= a0;
+}
+
+void FUN_02016454(u8 a0)
+{
+ gMain.unk67 &= ~a0;
+}
+
+void FUN_02016464(void)
+{
+ TPData raw, calib;
+ if (PAD_DetectFold())
+ {
+ gMain.unk48 = 0;
+ gMain.unk44 = 0;
+ gMain.unk4C = 0;
+ gMain.unk60 = 0;
+ gMain.unk62 = 0;
+ return;
+ }
+ u32 r0 = PAD_Read();
+ gMain.unk40 = gMain.unk3C = (r0 ^ gMain.unk38) & r0;
+ if (r0 != 0 && gMain.unk38 == r0)
+ {
+ if (--gMain.unk50 == 0)
+ {
+ gMain.unk40 = r0;
+ gMain.unk50 = gMain.unk54;
+ }
+ }
+ else
+ {
+ gMain.unk50 = gMain.unk58;
+ }
+ gMain.unk38 = r0;
+ gMain.unk48 = gMain.unk3C;
+ gMain.unk44 = r0;
+ gMain.unk4C = gMain.unk40;
+ FUN_02016568();
+ if (gMain.unk64 == 0)
+ {
+ while (TP_RequestRawSampling(&raw))
+ ;
+ }
+ else
+ TP_GetLatestRawPointInAuto(&raw);
+ TP_GetCalibratedPoint(&calib, &raw);
+ if (calib.validity == 0)
+ {
+ gMain.unk5C = calib.x;
+ gMain.unk5E = calib.y;
+ }
+ else if (gMain.unk62)
+ {
+ switch (calib.validity)
+ {
+ case 1:
+ gMain.unk5E = calib.y;
+ break;
+ case 2:
+ gMain.unk5C = calib.x;
+ break;
+ case 3:
+ break;
+ }
+ }
+ else
+ calib.touch = 0;
+ gMain.unk60 = (u16)((gMain.unk62 ^ calib.touch) & calib.touch);
+ gMain.unk62 = calib.touch;
+}
+
+void FUN_02016568(void)
+{
+ switch (gMain.unk34)
+ {
+ case 0: // Normal
+ break;
+ case 1: // Start = X
+ if (gMain.unk48 & PAD_BUTTON_START)
+ gMain.unk48 |= PAD_BUTTON_X;
+ if (gMain.unk44 & PAD_BUTTON_START)
+ gMain.unk44 |= PAD_BUTTON_X;
+ if (gMain.unk4C & PAD_BUTTON_START)
+ gMain.unk4C |= PAD_BUTTON_X;
+ break;
+ case 2: // Swap X and Y; unused in the retail game
+ {
+ u32 r1 = 0;
+ if (gMain.unk48 & PAD_BUTTON_X)
+ {
+ r1 |= PAD_BUTTON_Y;
+ }
+ if (gMain.unk48 & PAD_BUTTON_Y)
+ {
+ r1 |= PAD_BUTTON_X;
+ }
+ gMain.unk48 &= 0xF3FF;
+ gMain.unk48 |= r1;
+ }
+ {
+ u32 r1 = 0;
+ if (gMain.unk44 & PAD_BUTTON_X)
+ {
+ r1 |= PAD_BUTTON_Y;
+ }
+ if (gMain.unk44 & PAD_BUTTON_Y)
+ {
+ r1 |= PAD_BUTTON_X;
+ }
+ gMain.unk44 &= 0xF3FF;
+ gMain.unk44 |= r1;
+ }
+ {
+ u32 r1 = 0;
+ if (gMain.unk4C & PAD_BUTTON_X)
+ {
+ r1 |= PAD_BUTTON_Y;
+ }
+ if (gMain.unk4C & PAD_BUTTON_Y)
+ {
+ r1 |= PAD_BUTTON_X;
+ }
+ gMain.unk4C &= 0xF3FF;
+ gMain.unk4C |= r1;
+ }
+ break;
+ case 3: // L = A
+ if (gMain.unk48 & PAD_BUTTON_L)
+ gMain.unk48 |= PAD_BUTTON_A;
+ if (gMain.unk44 & PAD_BUTTON_L)
+ gMain.unk44 |= PAD_BUTTON_A;
+ if (gMain.unk4C & PAD_BUTTON_L)
+ gMain.unk4C |= PAD_BUTTON_A;
+ gMain.unk48 &= 0xFCFF;
+ gMain.unk44 &= 0xFCFF;
+ gMain.unk4C &= 0xFCFF;
+ }
+}
+
+void FUN_0201669C(int x, int y)
+{
+ gMain.unk54 = x;
+ gMain.unk58 = y;
+}
+
+void FUN_020166A8(u8 a0)
+{
+ gMain.unk68 |= a0;
+}
+
+void FUN_020166B8(u8 a0)
+{
+ gMain.unk68 &= ~a0;
+}