decompile main
This commit is contained in:
+454
@@ -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));
|
||||
}
|
||||
Reference in New Issue
Block a user