diff options
Diffstat (limited to 'arm9/src/game_init.c')
-rw-r--r-- | arm9/src/game_init.c | 532 |
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; +} |