#include "global.h" #include "alloc.h" #include "decompress.h" #include "ereader_helpers.h" #include "link.h" #include "main.h" #include "mystery_gift.h" #include "save.h" #include "sound.h" #include "sprite.h" #include "task.h" #include "strings.h" #include "util.h" #include "constants/songs.h" struct Unk81D5014 { u16 unk0; u16 unk2; u16 unk4; u16 unk6; u8 unk8; u8 unk9; u8 unkA; u8 unkB; u8 unkC; u8 unkD; u8 unkE; u8 *unk10; }; struct Unk03006370 { u16 unk0; u32 unk4; u32 *unk8; }; static void sub_81D5084(u8); struct Unk03006370 gUnknown_03006370; extern const u8 gUnknown_089A3470[]; extern const u8 gMultiBootProgram_BerryGlitchFix_Start[]; static void sub_81D4D50(struct Unk03006370 *arg0, int arg1, u32 *arg2) { volatile u16 backupIME = REG_IME; REG_IME = 0; gIntrTable[1] = sub_81D3FAC; gIntrTable[2] = sub_81D3F9C; EReaderHelper_SaveRegsState(); sub_81D4238(); REG_IE |= INTR_FLAG_VCOUNT; REG_IME = backupIME; arg0->unk0 = 0; arg0->unk4 = arg1; arg0->unk8 = arg2; } static void sub_81D4DB8(struct Unk03006370 *arg0) { volatile u16 backupIME = REG_IME; REG_IME = 0; sub_81D4238(); EReaderHelper_RestoreRegsState(); RestoreSerialTimer3IntrHandlers(); REG_IME = backupIME; } static u8 sub_81D4DE8(struct Unk03006370 *arg0) { u8 var0 = 0; arg0->unk0 = EReaderHandleTransfer(1, arg0->unk4, arg0->unk8, NULL); if ((arg0->unk0 & 0x13) == 0x10) var0 = 1; if (arg0->unk0 & 0x8) var0 = 2; if (arg0->unk0 & 0x4) var0 = 3; gShouldAdvanceLinkState = 0; return var0; } static void sub_81D4E30(void) { memset(gDecompressionBuffer, 0, 0x2000); gLinkType = 0x5503; OpenLink(); SetSuppressLinkErrorMessage(TRUE); } static bool32 sub_81D4E60(void) { volatile u16 backupIME; u16 sp4[4]; backupIME = REG_IME; REG_IME = 0; *(u64 *)sp4 = *(u64 *)gLink.tempRecvBuffer; REG_IME = backupIME; if (sp4[0] == 0xB9A0 && sp4[1] == 0xCCD0 && sp4[2] == 0xFFFF && sp4[3] == 0xFFFF) { return TRUE; } return FALSE; } static bool32 sub_81D4EC0(void) { if (IsLinkMaster() && GetLinkPlayerCount_2() == 2) return TRUE; return FALSE; } static u32 sub_81D4EE4(u8 *arg0, u16 *arg1) { u8 var0; var0 = *arg0 - 3; if (var0 < 3 && HasLinkErrorOccurred()) { *arg0 = 0; return 3; } switch (*arg0) { case 0: if (IsLinkMaster() && GetLinkPlayerCount_2() > 1) { *arg0 = 1; } else if (gMain.newKeys & B_BUTTON) { *arg0 = 0; return 1; } break; case 1: if (++(*arg1) > 5) { *arg1 = 0; *arg0 = 2; } break; case 2: if (GetLinkPlayerCount_2() == 2) { PlaySE(SE_PINPON); CheckShouldAdvanceLinkState(); *arg1 = 0; *arg0 = 3; } else if (gMain.newKeys & B_BUTTON) { *arg0 = 0; return 1; } break; case 3: if (++(*arg1) > 30) { *arg0 = 0; return 5; } if (IsLinkConnectionEstablished()) { if (gReceivedRemoteLinkPlayers) { if (IsLinkPlayerDataExchangeComplete()) { *arg0 = 0; return 2; } else { *arg0 = 4; } } else { *arg0 = 3; } } break; case 4: sub_800ABF4(0); *arg0 = 5; break; case 5: if (!gReceivedRemoteLinkPlayers) { *arg0 = 0; return 4; } break; default: return 0; } return 0; } void task_add_00_ereader(void) { int value; struct Unk81D5014 *data; u8 taskId = CreateTask(sub_81D5084, 0); data = (struct Unk81D5014 *)gTasks[taskId].data; data->unk8 = 0; data->unk9 = 0; data->unkA = 0; data->unkB = 0; data->unkC = 0; data->unkD = 0; data->unk0 = 0; data->unk2 = 0; data->unk4 = 0; data->unk6 = 0; data->unkE = 0; data->unk10 = AllocZeroed(0x40); } static void sub_81D505C(u16 *arg0) { *arg0 = 0; } static bool32 sub_81D5064(u16 *arg0, u16 arg1) { if (++(*arg0) > arg1) { *arg0 = 0; return TRUE; } return FALSE; } static void sub_81D5084(u8 taskId) { struct Unk81D5014 *data = (struct Unk81D5014 *)gTasks[taskId].data; switch (data->unk8) { case 0: if (MG_PrintTextOnWindow1AndWaitButton(&data->unk9, gUnknown_085EDFD6)) data->unk8 = 1; break; case 1: sub_81D4E30(); sub_81D505C(&data->unk0); data->unk8 = 2; break; case 2: if (sub_81D5064(&data->unk0, 10)) data->unk8 = 3; break; case 3: if (!sub_81D4EC0()) { CloseLink(); data->unk8 = 4; } else { data->unk8 = 13; } break; case 4: if (MG_PrintTextOnWindow1AndWaitButton(&data->unk9, gUnknown_085EDFF5)) { AddTextPrinterToWindow1(gUnknown_085EE014); sub_81D505C(&data->unk0); data->unk8 = 5; } break; case 5: if (sub_81D5064(&data->unk0, 90)) { sub_81D4E30(); data->unk8 = 6; } else if (gMain.newKeys & B_BUTTON) { sub_81D505C(&data->unk0); PlaySE(SE_SELECT); data->unk8 = 23; } break; case 6: if (gMain.newKeys & B_BUTTON) { PlaySE(SE_SELECT); CloseLink(); sub_81D505C(&data->unk0); data->unk8 = 23; } else if (GetLinkPlayerCount_2() > 1) { sub_81D505C(&data->unk0); CloseLink(); data->unk8 = 7; } else if (sub_81D4E60()) { PlaySE(SE_SELECT); CloseLink(); sub_81D505C(&data->unk0); data->unk8 = 8; } else if (sub_81D5064(&data->unk0, 10)) { CloseLink(); sub_81D4E30(); sub_81D505C(&data->unk0); } break; case 7: if (MG_PrintTextOnWindow1AndWaitButton(&data->unk9, gUnknown_085EE05C)) data->unk8 = 4; break; case 8: AddTextPrinterToWindow1(gUnknown_085EE097); // XXX: This (u32*) cast is discarding the const qualifier from gUnknown_089A3470 sub_81D4D50(&gUnknown_03006370, gMultiBootProgram_BerryGlitchFix_Start - gUnknown_089A3470, (u32*)gUnknown_089A3470); data->unk8 = 9; break; case 9: data->unkE = sub_81D4DE8(&gUnknown_03006370); if (data->unkE) data->unk8 = 10; break; case 10: sub_81D4DB8(&gUnknown_03006370); if (data->unkE == 3) { data->unk8 = 20; } else if (data->unkE == 1) { sub_81D505C(&data->unk0); AddTextPrinterToWindow1(gUnknown_085EE120); data->unk8 = 11; } else { data->unk8 = 0; } break; case 11: if (sub_81D5064(&data->unk0, 840)) data->unk8 = 12; break; case 12: sub_81D4E30(); AddTextPrinterToWindow1(gUnknown_085EE0DC); data->unk8 = 13; break; case 13: switch (sub_81D4EE4(&data->unk9, &data->unk0)) { case 0: break; case 2: AddTextPrinterToWindow1(gUnknown_085EE097); data->unk8 = 14; break; case 1: PlaySE(SE_SELECT); CloseLink(); data->unk8 = 23; break; case 5: CloseLink(); data->unk8 = 21; break; case 3: case 4: CloseLink(); data->unk8 = 20; break; } break; case 14: if (HasLinkErrorOccurred()) { CloseLink(); data->unk8 = 20; } else if (GetBlockReceivedStatus()) { ResetBlockReceivedFlags(); data->unk8 = 15; } break; case 15: data->unkE = EReader_IsReceivedDataValid((struct EReaderTrainerHillSet *)gDecompressionBuffer); sub_800ABF4(data->unkE); data->unk8 = 16; break; case 16: if (!gReceivedRemoteLinkPlayers) { if (data->unkE == 1) data->unk8 = 17; else data->unk8 = 20; } break; case 17: if (TryWriteTrainerHill((struct EReaderTrainerHillSet *)&gDecompressionBuffer)) { AddTextPrinterToWindow1(gUnknown_085EE0FA); sub_81D505C(&data->unk0); data->unk8 = 18; } else { data->unk8 = 22; } break; case 18: if (sub_81D5064(&data->unk0, 120)) { AddTextPrinterToWindow1(gUnknown_085EE107); PlayFanfare(MUS_FANFA4); data->unk8 = 19; } break; case 19: if (IsFanfareTaskInactive() && (gMain.newKeys & (A_BUTTON | B_BUTTON))) data->unk8 = 26; break; case 23: if (MG_PrintTextOnWindow1AndWaitButton(&data->unk9,gUnknown_085EE06B)) data->unk8 = 26; break; case 20: if (MG_PrintTextOnWindow1AndWaitButton(&data->unk9, gUnknown_085EE0A3)) data->unk8 = 0; break; case 21: if (MG_PrintTextOnWindow1AndWaitButton(&data->unk9, gUnknown_085EE0BF)) data->unk8 = 0; break; case 22: if (MG_PrintTextOnWindow1AndWaitButton(&data->unk9, gUnknown_085EE12D)) data->unk8 = 0; break; case 26: Free(data->unk10); DestroyTask(taskId); SetMainCallback2(MainCB_FreeAllBuffersAndReturnToInitTitleScreen); break; } }