diff options
author | sceptillion <33798691+sceptillion@users.noreply.github.com> | 2017-12-17 13:22:46 -0800 |
---|---|---|
committer | sceptillion <33798691+sceptillion@users.noreply.github.com> | 2017-12-17 13:22:46 -0800 |
commit | b849ce93dbafac8e4961b531ab40585c0fdd103a (patch) | |
tree | 1cfd5cf3b7223a8e91dd0a0d4e6e112bd3458d8b /src | |
parent | 3ddda066d91cbbd377584acacaea62a9deba8873 (diff) |
decompile main
Diffstat (limited to 'src')
-rw-r--r-- | src/main.c | 454 |
1 files changed, 454 insertions, 0 deletions
diff --git a/src/main.c b/src/main.c new file mode 100644 index 000000000..72cb976a1 --- /dev/null +++ b/src/main.c @@ -0,0 +1,454 @@ +#include "global.h" +#include "main.h" +#include "m4a.h" +#include "random.h" +#include "dma3.h" +#include "gba/flash_internal.h" +#include "battle.h" + +extern u16 GetGpuReg(u8); +extern void SetGpuReg(u8, u16); +extern void RFUVSync(void); +extern void LinkVSync(void); +extern void sub_80FCF34(void); +extern void LinkVSync(void); +extern void InitGpuRegManager(void); +extern void InitRFU(void); +extern void CheckForFlashMemory(void); +extern void InitMapMusic(void); +extern void ResetBgs(void); +extern void SetDefaultFontsPointer(void); +extern void InitHeap(void *heapStart, u32 heapSize); // malloc.h +extern void rfu_REQ_stopMode(void); +extern void rfu_waitREQComplete(void); +extern bool32 sub_80582E0(void); +extern bool32 sub_8058274(void); +extern void ClearSpriteCopyRequests(void); +extern void PlayTimeCounter_Update(void); +extern void MapMusicMain(void); +extern void EnableInterrupts(u16); +extern void sub_800DD28(void); +extern u16 SetFlashTimerIntr(u8 timerNum, void (**intrFunc)(void)); +extern void remove_some_task(void); +extern void sub_80F50F4(void); +extern bool32 sub_80F5118(void); +extern bool8 sub_813B870(void); + +extern struct SoundInfo gSoundInfo; +extern u32 gFlashMemoryPresent; +extern u32 IntrMain[]; +extern u8 gHeap[]; +extern struct SaveBlock1 gSaveBlock1; +extern struct SaveBlock2 gSaveBlock2; +extern struct PokemonStorage gPokemonStorage; +extern u32 gBattleTypeFlags; +extern u8 gUnknown_03002748; +extern u32 *gUnknown_0203CF5C; + +void Timer3Intr(void); +bool8 HandleLinkConnection(void); +void c2_copyright_1(void); + +static void VBlankIntr(void); +static void HBlankIntr(void); +static void VCountIntr(void); +static void SerialIntr(void); +static void IntrDummy(void); + +const u8 gGameVersion = VERSION_FIRE_RED; + +const u8 gGameLanguage = GAME_LANGUAGE; + +const char BuildDateTime[] = "2004 04 26 11:20"; + +const IntrFunc gIntrTableTemplate[] = +{ + VCountIntr, // V-count interrupt + SerialIntr, // Serial interrupt + Timer3Intr, // Timer 3 interrupt + HBlankIntr, // H-blank interrupt + VBlankIntr, // V-blank interrupt + IntrDummy, // Timer 0 interrupt + IntrDummy, // Timer 1 interrupt + IntrDummy, // Timer 2 interrupt + IntrDummy, // DMA 0 interrupt + IntrDummy, // DMA 1 interrupt + IntrDummy, // DMA 2 interrupt + IntrDummy, // DMA 3 interrupt + IntrDummy, // Key interrupt + IntrDummy, // Game Pak interrupt +}; + +#define INTR_COUNT ((int)(sizeof(gIntrTableTemplate)/sizeof(IntrFunc))) + +extern u16 gKeyRepeatStartDelay; +extern u8 gLinkTransferringData; +extern struct Main gMain; +extern u16 gKeyRepeatContinueDelay; +extern u8 gSoftResetDisabled; +extern IntrFunc gIntrTable[INTR_COUNT]; +extern bool8 gLinkVSyncDisabled; +extern u32 IntrMain_Buffer[0x200]; +extern u8 gPcmDmaCounter; +extern u8 gUnknown_3003578; +extern u8 gUnknown_3003D80; +extern u8 gUnknown_3003D84; + +static IntrFunc * const sTimerIntrFunc = gIntrTable + 0x7; + +extern u16 gTrainerId; +extern bool8 gUnknown_3005ECC; +extern bool8 gUnknown_3003F3C; +extern bool8 gUnknown_3005E88; + +EWRAM_DATA void (**gFlashTimerIntrFunc)(void) = NULL; + +static void UpdateLinkAndCallCallbacks(void); +static void InitMainCallbacks(void); +static void CallCallbacks(void); +static void ReadKeys(void); +void InitIntrHandlers(void); +static void WaitForVBlank(void); +void EnableVCountIntrAtLine150(void); + +#define B_START_SELECT (B_BUTTON | START_BUTTON | SELECT_BUTTON) + +void AgbMain() +{ + RegisterRamReset(RESET_ALL); + *(vu16 *)BG_PLTT = 0x7FFF; + InitGpuRegManager(); + REG_WAITCNT = WAITCNT_PREFETCH_ENABLE | WAITCNT_WS0_S_1 | WAITCNT_WS0_N_3; + InitKeys(); + InitIntrHandlers(); + m4aSoundInit(); + EnableVCountIntrAtLine150(); + InitRFU(); + CheckForFlashMemory(); + InitMainCallbacks(); + InitMapMusic(); + ClearDma3Requests(); + ResetBgs(); + InitHeap(gHeap, 0x1C000); + SetDefaultFontsPointer(); + + gSoftResetDisabled = FALSE; + gUnknown_3005ECC = FALSE; + + sub_80F50F4(); + + AGBPrintInit(); + +#if REVISION == 1 + if (gFlashMemoryPresent != TRUE) + SetMainCallback2(NULL); +#endif + + gLinkTransferringData = FALSE; + + for (;;) + { + ReadKeys(); + + if (gSoftResetDisabled == FALSE + && (gMain.heldKeysRaw & A_BUTTON) + && (gMain.heldKeysRaw & B_START_SELECT) == B_START_SELECT) + { + rfu_REQ_stopMode(); + rfu_waitREQComplete(); + DoSoftReset(); + } + + if (sub_80582E0() == 1) + { + gLinkTransferringData = TRUE; + UpdateLinkAndCallCallbacks(); + gLinkTransferringData = FALSE; + } + else + { + gLinkTransferringData = FALSE; + UpdateLinkAndCallCallbacks(); + + if (sub_8058274() == 1) + { + gMain.newKeys = 0; + ClearSpriteCopyRequests(); + gLinkTransferringData = TRUE; + UpdateLinkAndCallCallbacks(); + gLinkTransferringData = FALSE; + } + } + + PlayTimeCounter_Update(); + MapMusicMain(); + WaitForVBlank(); + } +} + +static void UpdateLinkAndCallCallbacks(void) +{ + if (!HandleLinkConnection()) + CallCallbacks(); +} + +static void InitMainCallbacks(void) +{ + gMain.vblankCounter1 = 0; + gMain.vblankCounter2 = 0; + gMain.callback1 = NULL; + SetMainCallback2(c2_copyright_1); + gSaveBlock2Ptr = &gSaveBlock2; + gSaveBlock1Ptr = &gSaveBlock1; + gSaveBlock2.encryptionKey = 0; + gUnknown_3005E88 = FALSE; +} + +static void CallCallbacks(void) +{ + if (!sub_80F5118() && !sub_813B870()) + { + if (gMain.callback1) + gMain.callback1(); + + if (gMain.callback2) + gMain.callback2(); + } +} + +void SetMainCallback2(MainCallback callback) +{ + gMain.callback2 = callback; + gMain.state = 0; +} + +void StartTimer1(void) +{ + REG_TM1CNT_H = 0x80; +} + +void SeedRngAndSetTrainerId(void) +{ + u16 val = REG_TM1CNT_L; + SeedRng(val); + REG_TM1CNT_H = 0; + gTrainerId = val; +} + +u16 GetGeneratedTrainerIdLower(void) +{ + return gTrainerId; +} + +void EnableVCountIntrAtLine150(void) +{ + u16 gpuReg = (GetGpuReg(REG_OFFSET_DISPSTAT) & 0xFF) | (150 << 8); + SetGpuReg(REG_OFFSET_DISPSTAT, gpuReg | DISPSTAT_VCOUNT_INTR); + EnableInterrupts(INTR_FLAG_VCOUNT); +} + +void InitKeys(void) +{ + gKeyRepeatContinueDelay = 5; + gKeyRepeatStartDelay = 40; + + gMain.heldKeys = 0; + gMain.newKeys = 0; + gMain.newAndRepeatedKeys = 0; + gMain.heldKeysRaw = 0; + gMain.newKeysRaw = 0; +} + +static void ReadKeys(void) +{ + u16 keyInput = REG_KEYINPUT ^ KEYS_MASK; + gMain.newKeysRaw = keyInput & ~gMain.heldKeysRaw; + gMain.newKeys = gMain.newKeysRaw; + gMain.newAndRepeatedKeys = gMain.newKeysRaw; + + // BUG: Key repeat won't work when pressing L using L=A button mode + // because it compares the raw key input with the remapped held keys. + // Note that newAndRepeatedKeys is never remapped either. + + if (keyInput != 0 && gMain.heldKeys == keyInput) + { + gMain.keyRepeatCounter--; + + if (gMain.keyRepeatCounter == 0) + { + gMain.newAndRepeatedKeys = keyInput; + gMain.keyRepeatCounter = gKeyRepeatContinueDelay; + } + } + else + { + // If there is no input or the input has changed, reset the counter. + gMain.keyRepeatCounter = gKeyRepeatStartDelay; + } + + gMain.heldKeysRaw = keyInput; + gMain.heldKeys = gMain.heldKeysRaw; + + // Remap L to A if the L=A option is enabled. + if (gSaveBlock2Ptr->optionsButtonMode == 2) + { + if (gMain.newKeys & L_BUTTON) + gMain.newKeys |= A_BUTTON; + + if (gMain.heldKeys & L_BUTTON) + gMain.heldKeys |= A_BUTTON; + } + + if (gMain.newKeys & gMain.watchedKeysMask) + gMain.watchedKeysPressed = TRUE; +} + +void InitIntrHandlers(void) +{ + int i; + + for (i = 0; i < INTR_COUNT; i++) + gIntrTable[i] = gIntrTableTemplate[i]; + + DmaCopy32(3, IntrMain, IntrMain_Buffer, sizeof(IntrMain_Buffer)); + + INTR_VECTOR = IntrMain_Buffer; + + SetVBlankCallback(NULL); + SetHBlankCallback(NULL); + SetSerialCallback(NULL); + + REG_IME = 1; + + EnableInterrupts(0x1); +} + +void SetVBlankCallback(IntrCallback callback) +{ + gMain.vblankCallback = callback; +} + +void SetHBlankCallback(IntrCallback callback) +{ + gMain.hblankCallback = callback; +} + +void SetVCountCallback(IntrCallback callback) +{ + gMain.vcountCallback = callback; +} + +void SetSerialCallback(IntrCallback callback) +{ + gMain.serialCallback = callback; +} + +extern void CopyBufferedValuesToGpuRegs(void); +extern void ProcessDma3Requests(void); + +static void VBlankIntr(void) +{ + if (gUnknown_3003F3C) + RFUVSync(); + else if (!gLinkVSyncDisabled) + LinkVSync(); + + if (gMain.vblankCounter1) + (*gMain.vblankCounter1)++; + + if (gMain.vblankCallback) + gMain.vblankCallback(); + + gMain.vblankCounter2++; + + CopyBufferedValuesToGpuRegs(); + ProcessDma3Requests(); + + gPcmDmaCounter = gSoundInfo.pcmDmaCounter; + + gUnknown_3003D84 = REG_VCOUNT; + m4aSoundMain(); + gUnknown_3003578 = REG_VCOUNT; + + sub_800DD28(); + Random(); + sub_80FCF34(); + + INTR_CHECK |= INTR_FLAG_VBLANK; + gMain.intrCheck |= INTR_FLAG_VBLANK; +} + +void InitFlashTimer(void) +{ + IntrFunc **func = (IntrFunc **)&sTimerIntrFunc; + SetFlashTimerIntr(2, *func); +} + +static void HBlankIntr(void) +{ + if (gMain.hblankCallback) + gMain.hblankCallback(); + + INTR_CHECK |= INTR_FLAG_HBLANK; + gMain.intrCheck |= INTR_FLAG_HBLANK; +} + +static void VCountIntr(void) +{ + gUnknown_3003D80 = REG_VCOUNT; + m4aSoundVSync(); + INTR_CHECK |= INTR_FLAG_VCOUNT; + gMain.intrCheck |= INTR_FLAG_VCOUNT; +} + +static void SerialIntr(void) +{ + if (gMain.serialCallback) + gMain.serialCallback(); + + INTR_CHECK |= INTR_FLAG_SERIAL; + gMain.intrCheck |= INTR_FLAG_SERIAL; +} + +void RestoreSerialTimer3IntrHandlers(void) +{ + gIntrTable[1] = SerialIntr; + gIntrTable[2] = Timer3Intr; +} + +static void IntrDummy(void) +{} + +static void WaitForVBlank(void) +{ + gMain.intrCheck &= ~INTR_FLAG_VBLANK; + + while (!(gMain.intrCheck & INTR_FLAG_VBLANK)) + ; +} + +void SetVBlankCounter1Ptr(u32 *ptr) +{ + gMain.vblankCounter1 = ptr; +} + +void DisableVBlankCounter1(void) +{ + gMain.vblankCounter1 = NULL; +} + +void DoSoftReset(void) +{ + REG_IME = 0; + m4aSoundVSyncOff(); + remove_some_task(); + DmaStop(1); + DmaStop(2); + DmaStop(3); + SoftReset(RESET_ALL & ~RESET_SIO_REGS); +} + +void ClearPokemonCrySongs(void) +{ + CpuFill16(0, gPokemonCrySongs, MAX_POKEMON_CRIES * sizeof(struct PokemonCrySong)); +} |