mirror of https://github.com/zeldaret/tmc.git
307 lines
7.1 KiB
C
307 lines
7.1 KiB
C
#include "sound.h"
|
|
#include "functions.h"
|
|
#include "main.h"
|
|
#include "screen.h"
|
|
#include "common.h"
|
|
#include "save.h"
|
|
#include "message.h"
|
|
#include "interrupts.h"
|
|
|
|
extern u32 gRand;
|
|
|
|
extern void TitleTask(void);
|
|
extern void FileSelectTask(void);
|
|
extern void DemoTask(void);
|
|
extern void GameTask(void);
|
|
extern void GameOverTask(void);
|
|
extern void StaffrollTask(void);
|
|
extern void DebugTask(void);
|
|
|
|
static void InitOverlays(void);
|
|
static bool32 SoftResetKeysPressed(void);
|
|
static u32 CheckHeaderValid(void);
|
|
|
|
void (*const sTaskHandlers[])(void) = {
|
|
[TASK_TITLE] = TitleTask,
|
|
#ifdef DEMO_USA
|
|
[TASK_FILE_SELECT] = DemoTask,
|
|
#else
|
|
[TASK_FILE_SELECT] = FileSelectTask,
|
|
#endif
|
|
|
|
[TASK_GAME] = GameTask, [TASK_GAMEOVER] = GameOverTask,
|
|
[TASK_STAFFROLL] = StaffrollTask, [TASK_DEBUG] = DebugTask,
|
|
};
|
|
|
|
static void sub_080560B8(void);
|
|
|
|
void AgbMain(void) {
|
|
InitOverlays();
|
|
InitSound();
|
|
InitDMA();
|
|
InitSaveData();
|
|
sub_080560B8();
|
|
sub_08056208();
|
|
gUnk_02000010.field_0x4 = 193;
|
|
InitFade();
|
|
DmaCopy32(3, BG_PLTT, gPaletteBuffer, BG_PLTT_SIZE);
|
|
SetBrightness(1);
|
|
MessageInitialize();
|
|
ResetPalettes();
|
|
gRand = 0x1234567;
|
|
MemClear(&gMain, sizeof(gMain));
|
|
SetTask(TASK_TITLE);
|
|
while (1) {
|
|
ReadKeyInput();
|
|
if (SoftResetKeysPressed()) {
|
|
DoSoftReset();
|
|
}
|
|
|
|
switch (gMain.sleepStatus) {
|
|
case SLEEP:
|
|
SetSleepMode();
|
|
break;
|
|
case DEFAULT:
|
|
default:
|
|
if (gMain.pauseFrames != 0) {
|
|
do {
|
|
VBlankIntrWait();
|
|
} while (--gMain.pauseFrames);
|
|
}
|
|
|
|
if (gMain.pauseCount != 0) {
|
|
int cnt;
|
|
gMain.pauseCount--;
|
|
cnt = gMain.pauseInterval;
|
|
while (cnt-- > 0) {
|
|
VBlankIntrWait();
|
|
}
|
|
}
|
|
|
|
gMain.ticks.HWORD++;
|
|
sTaskHandlers[gMain.task]();
|
|
MessageMain();
|
|
FadeMain();
|
|
AudioMain();
|
|
break;
|
|
}
|
|
WaitForNextFrame();
|
|
}
|
|
}
|
|
|
|
// Interrupt handlers that are loaded into RAM.
|
|
extern u8 sub_080B197C[];
|
|
extern u8 gUnk_030056F0[];
|
|
extern u8 gUnk_02038560[];
|
|
extern u8 gUnk_080B2CD8[];
|
|
extern u8 gUnk_080B2CD8_2[];
|
|
extern u8 gUnk_080B2CD8_3[];
|
|
extern u8 gUnk_02000030[];
|
|
|
|
static void InitOverlays(void) {
|
|
u32 size;
|
|
|
|
DisableInterruptsAndDMA();
|
|
RegisterRamReset(RESET_ALL & ~RESET_EWRAM);
|
|
*(vu16*)BG_PLTT = 0x7FFF;
|
|
REG_WAITCNT = WAITCNT_PREFETCH_ENABLE | WAITCNT_WS0_S_1 | WAITCNT_WS0_N_3;
|
|
size = 0x3FFD0;
|
|
MemClear(gUnk_02000030, size);
|
|
size = (u32)gUnk_080B2CD8 - (u32)sub_080B197C;
|
|
if (size != 0) {
|
|
MemCopy(sub_080B197C, gUnk_030056F0, size);
|
|
}
|
|
|
|
size = (u32)gUnk_080B2CD8_2 - (u32)gUnk_080B2CD8_3;
|
|
if (size != 0) {
|
|
MemCopy(gUnk_080B2CD8_3, gUnk_02038560, size);
|
|
}
|
|
|
|
DispReset(0);
|
|
EnableVBlankIntr();
|
|
}
|
|
|
|
#define SOFT_RESET_KEYS (A_BUTTON | B_BUTTON | SELECT_BUTTON | START_BUTTON)
|
|
|
|
static bool32 SoftResetKeysPressed(void) {
|
|
return (gInput.heldKeys & SOFT_RESET_KEYS) == SOFT_RESET_KEYS;
|
|
}
|
|
|
|
void SetTask(u32 task) {
|
|
gMain.task = task;
|
|
gMain.state = 0;
|
|
gMain.substate = 0;
|
|
}
|
|
|
|
void DisableInterruptsAndDMA(void) {
|
|
REG_IME = 0;
|
|
REG_IE = 0;
|
|
REG_DISPSTAT = 0;
|
|
REG_IF = 0;
|
|
REG_IME = 0;
|
|
|
|
DmaStop(0);
|
|
DmaStop(1);
|
|
DmaStop(2);
|
|
DmaStop(3);
|
|
}
|
|
|
|
void DoSoftReset(void) {
|
|
DisableInterruptsAndDMA();
|
|
SoftReset(RESET_ALL & ~(RESET_EWRAM | RESET_SIO_REGS));
|
|
}
|
|
|
|
typedef struct {
|
|
int signature;
|
|
u8 saveFileId;
|
|
u8 msg_speed;
|
|
u8 brightness;
|
|
u8 language;
|
|
u8 name[6];
|
|
u8 invalid;
|
|
u8 initialized;
|
|
} Defaults;
|
|
|
|
const Defaults sDefaultSettings = {
|
|
.signature = SIGNATURE,
|
|
.saveFileId = 0,
|
|
.msg_speed = 1,
|
|
.brightness = 1,
|
|
#ifdef EU
|
|
.language = 2, // TODO in EU 2 is english?
|
|
#else
|
|
.language = GAME_LANGUAGE,
|
|
#endif
|
|
.name = "LINK",
|
|
.invalid = 0,
|
|
.initialized = 0,
|
|
};
|
|
|
|
// single misplaced ldr
|
|
NONMATCH("asm/non_matching/sub_080560B8.inc", static void sub_080560B8(void)) {
|
|
u32 temp;
|
|
u32 b;
|
|
|
|
if (!CheckHeaderValid()) {
|
|
switch ((s32)Read_02000000(gSaveHeader)) {
|
|
case 1:
|
|
if (CheckHeaderValid())
|
|
break;
|
|
case 0:
|
|
case -1:
|
|
default:
|
|
MemCopy(&sDefaultSettings, gSaveHeader, sizeof *gSaveHeader);
|
|
Write_02000000(gSaveHeader);
|
|
break;
|
|
}
|
|
}
|
|
|
|
temp = gUnk_02000010.signature ^ SIGNATURE;
|
|
b = BOOLCAST(temp);
|
|
|
|
if ((gUnk_02000010.field_0x4 != 0) && (gUnk_02000010.field_0x4 != 0xc1)) {
|
|
b = TRUE;
|
|
}
|
|
if (b) {
|
|
MemClear(&gUnk_02000010, sizeof gUnk_02000010);
|
|
gUnk_02000010.signature = SIGNATURE;
|
|
}
|
|
}
|
|
END_NONMATCH
|
|
|
|
static u32 CheckHeaderValid(void) {
|
|
if ((gSaveHeader->signature != SIGNATURE) || (gSaveHeader->saveFileId >= NUM_SAVE_SLOTS) ||
|
|
(gSaveHeader->msg_speed >= MAX_MSG_SPEED) || (gSaveHeader->brightness >= MAX_BRIGHTNESS)
|
|
#ifdef EU
|
|
|| (gSaveHeader->language <= GAME_LANGUAGE) || (gSaveHeader->language > NUM_LANGUAGES)
|
|
#else
|
|
|| (gSaveHeader->language != GAME_LANGUAGE)
|
|
#endif
|
|
|| (gSaveHeader->invalid))
|
|
return FALSE;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void InitDMA(void) {
|
|
SoundReq(SONG_VSYNC_OFF);
|
|
gScreen._6d = gScreen._6c;
|
|
gScreen._6c = 0;
|
|
|
|
DmaStop(0);
|
|
|
|
DmaWait(0);
|
|
DmaWait(1);
|
|
DmaWait(2);
|
|
DmaWait(3);
|
|
}
|
|
|
|
void sub_08056208(void) {
|
|
SoundReq(SONG_VSYNC_ON);
|
|
gScreen._6c = gScreen._6d;
|
|
gScreen._6d = 0;
|
|
}
|
|
|
|
void sub_0805622C(void* a1, u32 a2, u32 a3) {
|
|
gScreen._70 = a1;
|
|
gScreen._74 = a2;
|
|
gScreen._78 = a3;
|
|
gScreen._6c = 1;
|
|
gUnk_03003DE4 ^= 1;
|
|
}
|
|
|
|
void sub_08056250(void) {
|
|
gScreen._6c = 0;
|
|
}
|
|
|
|
void SetSleepMode(void) {
|
|
u32 restore;
|
|
Main* m;
|
|
|
|
REG_DISPCNT = DISPCNT_FORCED_BLANK;
|
|
REG_KEYCNT = KEY_AND_INTR | L_BUTTON | R_BUTTON | SELECT_BUTTON;
|
|
REG_IME = 0;
|
|
restore = REG_IE;
|
|
REG_IE = INTR_FLAG_KEYPAD | INTR_FLAG_GAMEPAK;
|
|
REG_IME = 1;
|
|
Stop();
|
|
REG_IME = 0;
|
|
REG_IE = restore;
|
|
REG_IME = 1;
|
|
m = &gMain;
|
|
*(vu8*)&m->sleepStatus; // force a read
|
|
m->sleepStatus = 0;
|
|
}
|
|
|
|
// Convert AABB to screen coordinates and check if it's within the viewport
|
|
u32 CheckRegionOnScreen(u32 x0, u32 y0, u32 x1, u32 y1) {
|
|
u32 result;
|
|
u32 x = ((gRoomControls.scroll_x - gRoomControls.origin_x) - x0 + DISPLAY_WIDTH);
|
|
u32 y = ((gRoomControls.scroll_y - gRoomControls.origin_y) - y0 + DISPLAY_HEIGHT);
|
|
u32 a = x1 + DISPLAY_WIDTH;
|
|
u32 b = y1 + DISPLAY_HEIGHT;
|
|
if ((x < a) && (y < b))
|
|
result = TRUE;
|
|
else
|
|
result = FALSE;
|
|
return result;
|
|
}
|
|
|
|
// Iterate over array of AABBs and check if any fit on screen
|
|
u16 CheckRegionsOnScreen(u16* arr) {
|
|
u16* i;
|
|
for (i = arr; *i != 0xff; i += 5) {
|
|
if (CheckRegionOnScreen(i[1], i[2], i[3], i[4]))
|
|
return *i;
|
|
}
|
|
return 0xff;
|
|
}
|
|
|
|
void PlayerItemNulled2(void) {
|
|
DeleteThisEntity();
|
|
}
|
|
|
|
void PlayerItemNulled(void) {
|
|
DeleteThisEntity();
|
|
}
|