#include "global.h" #include "main.h" #include "task.h" #include "palette.h" #include "sound.h" #include "constants/songs.h" #include "pokemon.h" #include "text.h" #include "strings.h" #include "string_util.h" #include "menu.h" #include "save.h" #include "constants/species.h" #include "overworld.h" #include "m4a.h" #include "data2.h" #include "decompress.h" #include "random.h" #include "scanline_effect.h" #include "trig.h" #include "hof_pc.h" #include "credits.h" #include "pc_screen_effect.h" #include "ewram.h" static EWRAM_DATA u32 sHofFadePalettes = 0; extern bool8 gHasHallOfFameRecords; // has hall of fame records extern void (*gGameContinueCallback)(void); extern struct MusicPlayerInfo gMPlayInfo_BGM; extern u8 gReservedSpritePaletteCount; extern struct SpriteTemplate gCreatingSpriteTemplate; extern const u8 gContestConfetti_Gfx[]; extern const u8 gContestConfetti_Pal[]; extern const u8 gHallOfFame_Gfx[]; extern const u16 gHallOfFame_Pal[]; struct HallofFameMon { u32 tid; u32 personality; u16 species : 9; u16 lvl : 7; u8 nick[10]; }; struct HallofFameMons { struct HallofFameMon mons[6]; }; #define HALL_OF_FAME_MAX_TEAMS 50 static void sub_8141FF8(u8 taskID); static void sub_81422E8(u8 taskID); static void Task_Hof_InitTeamSaveData(u8 taskID); static void sub_8142274(u8 taskID); static void sub_81422B8(u8 taskID); static void sub_8142320(u8 taskID); static void sub_8142404(u8 taskID); static void sub_8142484(u8 taskID); static void sub_8142570(u8 taskID); static void sub_8142618(u8 taskID); static void sub_81426F8(u8 taskID); static void sub_8142738(u8 taskID); static void sub_8142794(u8 taskID); static void sub_8142818(u8 taskID); static void sub_8142850(u8 taskID); static void sub_81428A0(u8 taskID); static void sub_8142A28(u8 taskID); static void sub_8142FEC(u8 taskID); static void sub_8142B04(u8 taskID); static void sub_8142CC8(u8 taskID); static void sub_8142DF4(u8 taskID); static void sub_8142F78(u8 taskID); static void sub_8142FCC(u8 taskID); static void sub_814302C(u8 taskID); static void sub_81435DC(struct Sprite* sprite); static void sub_814386C(struct Sprite* sprite); static void SpriteCB_HallOfFame_Dummy(struct Sprite* sprite); static void sub_8143068(u8 a0, u8 a1); static void HallOfFame_PrintMonInfo(struct HallofFameMon* currMon, u8 a1, u8 a2); static void HallOfFame_PrintPlayerInfo(u8 a0, u8 a1); static void sub_81433E0(void); static void sub_8143570(void); static void sub_81435B8(void); static u32 HallOfFame_LoadPokemonPic(u16 species, s16 posX, s16 posY, u16 pokeID, u32 tid, u32 pid); static u32 HallOfFame_LoadTrainerPic(u16 trainerPicID, s16 posX, s16 posY, u16 a3); static bool8 sub_81438C4(void); // data and gfx static const struct CompressedSpriteSheet sHallOfFame_ConfettiSpriteSheet = { gContestConfetti_Gfx, 0x220, 1001 }; static const u8 sUnused0[8] = {}; static const struct CompressedSpritePalette sHallOfFame_ConfettiSpritePalette = { gContestConfetti_Pal, 1001 }; static const u8 sUnused1[8] = {}; static const s16 sHallOfFame_MonsFullTeamPositions[6][4] = { {120, 210, 120, 40}, {326, 220, 56, 40}, {-86, 220, 184, 40}, {120, -62, 120, 88}, {-25, -62, 200, 88}, {265, -62, 40, 88} }; static const s16 sHallOfFame_MonsHalfTeamPositions[3][4] = { {120, 214, 120, 64}, {281, 214, 56, 64}, {-41, 214, 184, 64} }; static const struct PCScreenEffectStruct sPCScreenEffectTemplate = { .tileTag = 0x3ea, .paletteTag = 0x3ea }; static const u8 sUnused2[6] = {2, 1, 3, 6, 4, 5}; static const struct OamData sOamData_840B598 = { .y = 0, .affineMode = 0, .objMode = 0, .mosaic = 0, .bpp = 0, .shape = 0, .x = 0, .matrixNum = 0, .size = 3, .tileNum = 0, .priority = 0, .paletteNum = 0, .affineParam = 0, }; void* const gUnknown_0840B5A0[] = { eHofGfxPtr + 0x0000, eHofGfxPtr + 0x2000, eHofGfxPtr + 0x4000, eHofGfxPtr + 0x6000, eHofGfxPtr + 0x8000, eHofGfxPtr + 0xC000, eHofGfxPtr + 0x10000 }; static const struct SpriteFrameImage sSpriteImageTable_840B5BC[] = { {eHofGfxPtr + 0x0000, 0x800}, {eHofGfxPtr + 0x800, 0x800}, {eHofGfxPtr + 0x1000, 0x800}, {eHofGfxPtr + 0x1800, 0x800} }; static const struct SpriteFrameImage sSpriteImageTable_840B5DC[] = { {eHofGfxPtr + 0x2000, 0x800}, {eHofGfxPtr + 0x2800, 0x800}, {eHofGfxPtr + 0x3000, 0x800}, {eHofGfxPtr + 0x3800, 0x800} }; static const struct SpriteFrameImage sSpriteImageTable_840B5FC[] = { {eHofGfxPtr + 0x4000, 0x800}, {eHofGfxPtr + 0x4800, 0x800}, {eHofGfxPtr + 0x5000, 0x800}, {eHofGfxPtr + 0x5800, 0x800} }; static const struct SpriteFrameImage sSpriteImageTable_840B61C[] = { {eHofGfxPtr + 0x6000, 0x800}, {eHofGfxPtr + 0x6800, 0x800}, {eHofGfxPtr + 0x7000, 0x800}, {eHofGfxPtr + 0x7800, 0x800} }; static const struct SpriteFrameImage sSpriteImageTable_840B63C[] = { {eHofGfxPtr + 0x8000, 0x800}, {eHofGfxPtr + 0x8800, 0x800}, {eHofGfxPtr + 0x9000, 0x800}, {eHofGfxPtr + 0x9800, 0x800} }; static const struct SpriteFrameImage sSpriteImageTable_840B65C[] = { {eHofGfxPtr + 0xC000, 0x800}, {eHofGfxPtr + 0xC800, 0x800}, {eHofGfxPtr + 0xD000, 0x800}, {eHofGfxPtr + 0xD800, 0x800} }; static const struct SpriteFrameImage sSpriteImageTable_840B67C[] = { {eHofGfxPtr + 0x10000, 0x800}, {eHofGfxPtr + 0x10800, 0x800}, {eHofGfxPtr + 0x11000, 0x800}, {eHofGfxPtr + 0x11800, 0x800} }; static const struct SpriteFrameImage* const sUnknown_0840B69C[7] = { sSpriteImageTable_840B5BC, sSpriteImageTable_840B5DC, sSpriteImageTable_840B5FC, sSpriteImageTable_840B61C, sSpriteImageTable_840B63C, sSpriteImageTable_840B65C, sSpriteImageTable_840B67C }; static const struct SpriteTemplate sUnknown_0840B6B8 = { .tileTag = -1, .paletteTag = -1, .oam = &sOamData_840B598, .anims = NULL, .images = sSpriteImageTable_840B5BC, .affineAnims = gDummySpriteAffineAnimTable, .callback = SpriteCB_HallOfFame_Dummy }; static const struct OamData sOamData_840B6D0 = { .y = 0, .affineMode = 0, .objMode = 0, .mosaic = 0, .bpp = 0, .shape = 0, .x = 0, .matrixNum = 0, .size = 0, .tileNum = 0, .priority = 0, .paletteNum = 0, .affineParam = 0, }; static const union AnimCmd sSpriteAnim_840B6D8[] = { ANIMCMD_FRAME(0, 30), ANIMCMD_END }; static const union AnimCmd sSpriteAnim_840B6E0[] = { ANIMCMD_FRAME(1, 30), ANIMCMD_END }; static const union AnimCmd sSpriteAnim_840B6E8[] = { ANIMCMD_FRAME(2, 30), ANIMCMD_END }; static const union AnimCmd sSpriteAnim_840B6F0[] = { ANIMCMD_FRAME(3, 30), ANIMCMD_END }; static const union AnimCmd sSpriteAnim_840B6F8[] = { ANIMCMD_FRAME(4, 30), ANIMCMD_END }; static const union AnimCmd sSpriteAnim_840B700[] = { ANIMCMD_FRAME(5, 30), ANIMCMD_END }; static const union AnimCmd sSpriteAnim_840B708[] = { ANIMCMD_FRAME(6, 30), ANIMCMD_END }; static const union AnimCmd sSpriteAnim_840B710[] = { ANIMCMD_FRAME(7, 30), ANIMCMD_END }; static const union AnimCmd sSpriteAnim_840B718[] = { ANIMCMD_FRAME(8, 30), ANIMCMD_END }; static const union AnimCmd sSpriteAnim_840B720[] = { ANIMCMD_FRAME(9, 30), ANIMCMD_END }; static const union AnimCmd sSpriteAnim_840B728[] = { ANIMCMD_FRAME(10, 30), ANIMCMD_END }; static const union AnimCmd sSpriteAnim_840B730[] = { ANIMCMD_FRAME(11, 30), ANIMCMD_END }; static const union AnimCmd sSpriteAnim_840B738[] = { ANIMCMD_FRAME(12, 30), ANIMCMD_END }; static const union AnimCmd sSpriteAnim_840B740[] = { ANIMCMD_FRAME(13, 30), ANIMCMD_END }; static const union AnimCmd sSpriteAnim_840B748[] = { ANIMCMD_FRAME(14, 30), ANIMCMD_END }; static const union AnimCmd sSpriteAnim_840B750[] = { ANIMCMD_FRAME(15, 30), ANIMCMD_END }; static const union AnimCmd sSpriteAnim_840B758[] = { ANIMCMD_FRAME(16, 30), ANIMCMD_END }; static const union AnimCmd* const sSpriteAnimTable_840B760[] = { sSpriteAnim_840B6D8, sSpriteAnim_840B6E0, sSpriteAnim_840B6E8, sSpriteAnim_840B6F0, sSpriteAnim_840B6F8, sSpriteAnim_840B700, sSpriteAnim_840B708, sSpriteAnim_840B710, sSpriteAnim_840B718, sSpriteAnim_840B720, sSpriteAnim_840B728, sSpriteAnim_840B730, sSpriteAnim_840B738, sSpriteAnim_840B740, sSpriteAnim_840B748, sSpriteAnim_840B750, sSpriteAnim_840B758 }; static const struct SpriteTemplate sSpriteTemplate_840B7A4 = { .tileTag = 1001, .paletteTag = 1001, .oam = &sOamData_840B6D0, .anims = sSpriteAnimTable_840B760, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = sub_814386C }; // code #define tDisplayedPoke data[1] #define tPokesNumber data[2] #define tFrameCount data[3] #define tPlayerSpriteID data[4] #define tMonSpriteID(i) data[i + 5] static void VBlankCB_HallOfFame(void) { LoadOam(); ProcessSpriteCopyRequests(); TransferPlttBuffer(); } static void CB2_HallOfFame(void) { RunTasks(); AnimateSprites(); BuildOamBuffer(); UpdatePaletteFade(); } static bool8 sub_8141E64(void) { switch (gMain.state) { case 0: default: SetVBlankCallback(NULL); sub_81433E0(); gMain.state = 1; break; case 1: sub_8143570(); gMain.state++; break; case 2: { u16 saved_IME; BeginNormalPaletteFade(0xFFFFFFFF, 0, 16, 0, RGB(0, 0, 0)); SetVBlankCallback(VBlankCB_HallOfFame); saved_IME = REG_IME; REG_IME = 0; REG_IE |= 1; REG_IME = saved_IME; REG_DISPSTAT |= 8; gMain.state++; } break; case 3: REG_BLDCNT = 0x3F42; REG_BLDALPHA = 0x710; REG_BLDY = 0; sub_81435B8(); gMain.state++; break; case 4: UpdatePaletteFade(); if (!gPaletteFade.active) { SetMainCallback2(CB2_HallOfFame); PlayBGM(MUS_HALL_OF_FAME); return 0; } break; } return 1; } void sub_8141F90(void) { if (sub_8141E64() == 0) { u8 taskID = CreateTask(sub_8141FF8, 0); gTasks[taskID].data[0] = 0; } } static void sub_8141FC4(void) { if (sub_8141E64() == 0) { u8 taskID = CreateTask(sub_8141FF8, 0); gTasks[taskID].data[0] = 1; } } static void sub_8141FF8(u8 taskID) { u16 i, j; struct HallofFameMons* fameMons = eHofMonPtr; gTasks[taskID].tPokesNumber = 0; // valid pokes for (i = 0; i < 6; i++) { u8 nick[12]; if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES)) { fameMons->mons[i].species = GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2); fameMons->mons[i].tid = GetMonData(&gPlayerParty[i], MON_DATA_OT_ID); fameMons->mons[i].personality = GetMonData(&gPlayerParty[i], MON_DATA_PERSONALITY); fameMons->mons[i].lvl = GetMonData(&gPlayerParty[i], MON_DATA_LEVEL); GetMonData(&gPlayerParty[i], MON_DATA_NICKNAME, nick); for (j = 0; j < 10; j++) { fameMons->mons[i].nick[j] = nick[j]; } gTasks[taskID].tPokesNumber++; } else { fameMons->mons[i].species = 0; fameMons->mons[i].tid = 0; fameMons->mons[i].personality = 0; fameMons->mons[i].lvl = 0; fameMons->mons[i].nick[0] = EOS; } } sHofFadePalettes = 0; gTasks[taskID].tDisplayedPoke = 0; gTasks[taskID].data[4] = 0xFF; for (i = 0; i < 6; i++) { gTasks[taskID].tMonSpriteID(i) = 0xFF; } if (gTasks[taskID].data[0]) gTasks[taskID].func = sub_81422E8; else gTasks[taskID].func = Task_Hof_InitTeamSaveData; } static void Task_Hof_InitTeamSaveData(u8 taskID) { u16 i; struct HallofFameMons* fameMons = eHofMonPtr; struct HallofFameMons* lastSavedTeam = (struct HallofFameMons *)gDecompressionBuffer; if (gHasHallOfFameRecords == FALSE) { for (i = 0; i < 0x2000; i++) gSharedMem[0x1E000 + i] = 0; // gDecompressionBuffer[i] = 0; } else Save_LoadGameData(SAVE_HALL_OF_FAME); for (i = 0; i < HALL_OF_FAME_MAX_TEAMS; i++, lastSavedTeam++) { if (lastSavedTeam->mons[0].species == 0) break; } if (i >= HALL_OF_FAME_MAX_TEAMS) { struct HallofFameMons *afterTeam = (struct HallofFameMons *)gDecompressionBuffer; struct HallofFameMons *beforeTeam = (struct HallofFameMons *)gDecompressionBuffer; afterTeam++; for (i = 0; i < HALL_OF_FAME_MAX_TEAMS - 1; i++, beforeTeam++, afterTeam++) { *beforeTeam = *afterTeam; } lastSavedTeam--; } *lastSavedTeam = *fameMons; Menu_DrawStdWindowFrame(2, 14, 27, 19); Menu_PrintText(gMenuText_HOFSaving, 3, 15); gTasks[taskID].func = sub_8142274; } static void sub_8142274(u8 taskID) { gGameContinueCallback = sub_8141FC4; Save_WriteData(3); PlaySE(SE_SAVE); gTasks[taskID].func = sub_81422B8; gTasks[taskID].tFrameCount = 32; } static void sub_81422B8(u8 taskID) { if (gTasks[taskID].tFrameCount) gTasks[taskID].tFrameCount--; else gTasks[taskID].func = sub_81422E8; } static void sub_81422E8(u8 taskID) { Text_LoadWindowTemplate(&gWindowTemplate_81E7198); InitMenuWindow(&gWindowTemplate_81E7198); gTasks[taskID].func = sub_8142320; } static void sub_8142320(u8 taskID) { u8 spriteID; s16 xPos, yPos, field4, field6; struct HallofFameMons* fameMons = eHofMonPtr; u16 currPokeID = gTasks[taskID].tDisplayedPoke; struct HallofFameMon* currMon = &fameMons->mons[currPokeID]; if (gTasks[taskID].tPokesNumber > 3) { xPos = sHallOfFame_MonsFullTeamPositions[currPokeID][0]; yPos = sHallOfFame_MonsFullTeamPositions[currPokeID][1]; field4 = sHallOfFame_MonsFullTeamPositions[currPokeID][2]; field6 = sHallOfFame_MonsFullTeamPositions[currPokeID][3]; } else { xPos = sHallOfFame_MonsHalfTeamPositions[currPokeID][0]; yPos = sHallOfFame_MonsHalfTeamPositions[currPokeID][1]; field4 = sHallOfFame_MonsHalfTeamPositions[currPokeID][2]; field6 = sHallOfFame_MonsHalfTeamPositions[currPokeID][3]; } spriteID = HallOfFame_LoadPokemonPic(currMon->species, xPos, yPos, currPokeID, currMon->tid, currMon->personality); gSprites[spriteID].data[1] = field4; gSprites[spriteID].data[2] = field6; gSprites[spriteID].data[0] = 0; gSprites[spriteID].callback = sub_81435DC; gTasks[taskID].tMonSpriteID(currPokeID) = spriteID; Menu_EraseWindowRect(0, 14, 29, 19); gTasks[taskID].func = sub_8142404; } static void sub_8142404(u8 taskID) { struct HallofFameMons* fameMons = eHofMonPtr; u16 currPokeID = gTasks[taskID].tDisplayedPoke; struct HallofFameMon* currMon = &fameMons->mons[currPokeID]; if (gSprites[gTasks[taskID].tMonSpriteID(currPokeID)].data[0] != 0) { if (currMon->species != SPECIES_EGG) PlayCry1(currMon->species, 0); HallOfFame_PrintMonInfo(currMon, 0, 14); gTasks[taskID].tFrameCount = 120; gTasks[taskID].func = sub_8142484; } } static void sub_8142484(u8 taskID) { struct HallofFameMons* fameMons = eHofMonPtr; u16 currPokeID = gTasks[taskID].tDisplayedPoke; struct HallofFameMon* currMon = &fameMons->mons[currPokeID]; if (gTasks[taskID].tFrameCount != 0) gTasks[taskID].tFrameCount--; else { sHofFadePalettes |= (0x10000 << gSprites[gTasks[taskID].tMonSpriteID(currPokeID)].oam.paletteNum); if (gTasks[taskID].tDisplayedPoke <= 4 && currMon[1].species != 0) // there is another pokemon to display { gTasks[taskID].tDisplayedPoke++; BeginNormalPaletteFade(sHofFadePalettes, 0, 12, 12, RGB(31, 26, 28)); gSprites[gTasks[taskID].tMonSpriteID(currPokeID)].oam.priority = 1; gTasks[taskID].func = sub_8142320; } else gTasks[taskID].func = sub_8142570; } } static void sub_8142570(u8 taskID) { u16 i; BeginNormalPaletteFade(0xFFFF0000, 0, 0, 0, RGB(0, 0, 0)); for (i = 0; i < 6; i++) { if (gTasks[taskID].tMonSpriteID(i) != 0xFF) gSprites[gTasks[taskID].tMonSpriteID(i)].oam.priority = 0; } Menu_EraseWindowRect(0, 14, 29, 19); sub_8143068(0, 15); PlaySE(SE_APPLAUSE); gTasks[taskID].tFrameCount = 400; gTasks[taskID].func = sub_8142618; } static void sub_8142618(u8 taskID) { if (gTasks[taskID].tFrameCount != 0) { gTasks[taskID].tFrameCount--; if ((gTasks[taskID].tFrameCount & 3) == 0 && gTasks[taskID].tFrameCount > 110) sub_81438C4(); } else { u16 i; for (i = 0; i < 6; i++) { if (gTasks[taskID].tMonSpriteID(i) != 0xFF) gSprites[gTasks[taskID].tMonSpriteID(i)].oam.priority = 1; } BeginNormalPaletteFade(sHofFadePalettes, 0, 12, 12, RGB(31, 26, 28)); Menu_EraseWindowRect(0, 14, 29, 19); gTasks[taskID].tFrameCount = 7; gTasks[taskID].func = sub_81426F8; } } static void sub_81426F8(u8 taskID) { if (gTasks[taskID].tFrameCount >= 16) gTasks[taskID].func = sub_8142738; else { gTasks[taskID].tFrameCount++; REG_BLDALPHA = gTasks[taskID].tFrameCount * 256; } } static void sub_8142738(u8 taskID) { REG_DISPCNT = 0x1940; Text_LoadWindowTemplate(&gWindowTemplate_81E71B4); InitMenuWindow(&gWindowTemplate_81E71B4); gTasks[taskID].tPlayerSpriteID = HallOfFame_LoadTrainerPic(gSaveBlock2.playerGender, 120, 72, 6); gTasks[taskID].tFrameCount = 120; gTasks[taskID].func = sub_8142794; } static void sub_8142794(u8 taskID) { if (gTasks[taskID].tFrameCount != 0) gTasks[taskID].tFrameCount--; else { if (gSprites[gTasks[taskID].tPlayerSpriteID].x != 160) gSprites[gTasks[taskID].tPlayerSpriteID].x++; else { Menu_DrawStdWindowFrame(1, 2, 15, 9); HallOfFame_PrintPlayerInfo(1, 2); Menu_DrawStdWindowFrame(2, 14, 27, 19); Menu_PrintText(gMenuText_HOFCongratulations, 4, 15); gTasks[taskID].func = sub_8142818; } } } static void sub_8142818(u8 taskID) { if (gMain.newKeys & A_BUTTON) { FadeOutBGM(4); gTasks[taskID].func = sub_8142850; } } static void sub_8142850(u8 taskID) { CpuSet(gPlttBufferFaded, gPlttBufferUnfaded, 0x200); BeginNormalPaletteFade(0xFFFFFFFF, 8, 0, 16, RGB(0, 0, 0)); gTasks[taskID].func = sub_81428A0; } static void sub_81428A0(u8 taskID) { if (!gPaletteFade.active) { DestroyTask(taskID); SetMainCallback2(CB2_StartCreditsSequence); } } #undef tDisplayedPoke #undef tPokesNumber #undef tFrameCount #undef tPlayerSpriteID #undef tMonSpriteID void sub_81428CC(void) { switch (gMain.state) { case 0: default: SetVBlankCallback(NULL); sub_81433E0(); gMain.state = 1; break; case 1: sub_8143570(); gMain.state++; break; case 2: { u16 savedIme; SetVBlankCallback(VBlankCB_HallOfFame); savedIme = REG_IME; REG_IME = 0; REG_IE |= 1; REG_IME = savedIme; REG_DISPSTAT |= 8; gMain.state++; } break; case 3: REG_BLDCNT = 0; REG_BLDALPHA = 0; REG_BLDY = 0; sub_81435B8(); eHOFPCScreenEffect = sPCScreenEffectTemplate; sub_80C5CD4(&eHOFPCScreenEffect); gMain.state++; break; case 4: AnimateSprites(); BuildOamBuffer(); UpdatePaletteFade(); if (sub_80C5DCC()) gMain.state++; break; case 5: REG_BLDCNT = 0x3F42; REG_BLDALPHA = 0x710; REG_BLDY = 0; CreateTask(sub_8142A28, 0); SetMainCallback2(CB2_HallOfFame); break; } } #define tCurrTeamNo data[0] #define tCurrPageNo data[1] #define tCurrPokeID data[2] #define tPokesNo data[4] #define tMonSpriteID(i) data[i + 5] static void sub_8142A28(u8 taskID) { if (Save_LoadGameData(SAVE_HALL_OF_FAME) != SAVE_STATUS_OK) gTasks[taskID].func = sub_8142FEC; else { u16 *vram1, *vram2; u16 i; struct HallofFameMons* savedTeams = (struct HallofFameMons *)gDecompressionBuffer; for (i = 0; i < HALL_OF_FAME_MAX_TEAMS; i++, savedTeams++) { if (savedTeams->mons[0].species == 0) break; } if (i < HALL_OF_FAME_MAX_TEAMS) gTasks[taskID].tCurrTeamNo = i - 1; else gTasks[taskID].tCurrTeamNo = HALL_OF_FAME_MAX_TEAMS - 1; gTasks[taskID].tCurrPageNo = GetGameStat(10); for (i = 0, vram1 = (u16*)(VRAM + 0x381A), vram2 = (u16*)(VRAM + 0x385A); i <= 16; i++) { *(vram1 + i) = i + 3; *(vram2 + i) = i + 20; } Text_LoadWindowTemplate(&gWindowTemplate_81E7198); InitMenuWindow(&gWindowTemplate_81E7198); gTasks[taskID].func = sub_8142B04; } } static void sub_8142B04(u8 taskID) { struct HallofFameMons* savedTeams = (struct HallofFameMons *)gDecompressionBuffer; struct HallofFameMon* currMon; u16 i; u8* stringPtr; for (i = 0; i < gTasks[taskID].tCurrTeamNo; i++) savedTeams++; currMon = &savedTeams->mons[0]; sHofFadePalettes = 0; gTasks[taskID].tCurrPokeID = 0; gTasks[taskID].tPokesNo = 0; for (i = 0; i < 6; i++, currMon++) { if (currMon->species != 0) gTasks[taskID].tPokesNo++; } currMon = &savedTeams->mons[0]; for (i = 0; i < 6; i++, currMon++) { if (currMon->species != 0) { u16 spriteID; s16 posX, posY; if (gTasks[taskID].tPokesNo > 3) { posX = sHallOfFame_MonsFullTeamPositions[i][2]; posY = sHallOfFame_MonsFullTeamPositions[i][3]; } else { posX = sHallOfFame_MonsHalfTeamPositions[i][2]; posY = sHallOfFame_MonsHalfTeamPositions[i][3]; } spriteID = HallOfFame_LoadPokemonPic(currMon->species, posX, posY, i, currMon->tid, currMon->personality); gSprites[spriteID].oam.priority = 1; gTasks[taskID].tMonSpriteID(i) = spriteID; } else gTasks[taskID].tMonSpriteID(i) = 0xFF; } BlendPalettes(0xFFFF0000, 12, RGB(31, 26, 28)); stringPtr = gStringVar1; stringPtr = StringCopy(stringPtr, gMenuText_HOFNumber); stringPtr[0] = 0xFC; stringPtr[1] = 0x14; stringPtr[2] = 0x6; stringPtr += 3; stringPtr = ConvertIntToDecimalString(stringPtr, gTasks[taskID].tCurrPageNo); stringPtr[0] = 0xFC; stringPtr[1] = 0x13; stringPtr[2] = 0xF0; stringPtr[3] = EOS; Menu_PrintText(gStringVar1, 0, 0); gTasks[taskID].func = sub_8142CC8; } static void sub_8142CC8(u8 taskID) { struct HallofFameMons* savedTeams = (struct HallofFameMons *)gDecompressionBuffer; struct HallofFameMon* currMon; u16 i; u16 currMonID; for (i = 0; i < gTasks[taskID].tCurrTeamNo; i++) savedTeams++; for (i = 0; i < 6; i++) { u16 spriteID = gTasks[taskID].tMonSpriteID(i); if (spriteID != 0xFF) gSprites[spriteID].oam.priority = 1; } currMonID = gTasks[taskID].tMonSpriteID(gTasks[taskID].tCurrPokeID); gSprites[currMonID].oam.priority = 0; sHofFadePalettes = (0x10000 << gSprites[currMonID].oam.paletteNum) ^ 0xFFFF0000; BlendPalettesUnfaded(sHofFadePalettes, 12, RGB(31, 26, 28)); currMon = &savedTeams->mons[gTasks[taskID].tCurrPokeID]; if (currMon->species != SPECIES_EGG) { StopCryAndClearCrySongs(); PlayCry1(currMon->species, 0); } HallOfFame_PrintMonInfo(currMon, 0, 14); gTasks[taskID].func = sub_8142DF4; } static void sub_8142DF4(u8 taskID) { u16 i; if (gMain.newKeys & A_BUTTON) { if (gTasks[taskID].tCurrTeamNo != 0) // prepare another team to view { gTasks[taskID].tCurrTeamNo--; for (i = 0; i < 6; i++) { u8 spriteID = gTasks[taskID].tMonSpriteID(i); if (spriteID != 0xFF) { FreeSpritePaletteByTag(GetSpritePaletteTagByPaletteNum(gSprites[spriteID].oam.paletteNum)); DestroySprite(&gSprites[spriteID]); } } if (gTasks[taskID].tCurrPageNo != 0) gTasks[taskID].tCurrPageNo--; gTasks[taskID].func = sub_8142B04; } else // no more teams to view, turn off hall of fame PC { if (IsCryPlayingOrClearCrySongs()) { StopCryAndClearCrySongs(); m4aMPlayVolumeControl(&gMPlayInfo_BGM, 0xFFFF, 0x100); } gTasks[taskID].func = sub_8142F78; } } else if (gMain.newKeys & B_BUTTON) // turn off hall of fame PC { if (IsCryPlayingOrClearCrySongs()) { StopCryAndClearCrySongs(); m4aMPlayVolumeControl(&gMPlayInfo_BGM, 0xFFFF, 0x100); } gTasks[taskID].func = sub_8142F78; } else if (gMain.newKeys & DPAD_UP && gTasks[taskID].tCurrPokeID != 0) // change poke -1 { gTasks[taskID].tCurrPokeID--; gTasks[taskID].func = sub_8142CC8; } else if (gMain.newKeys & DPAD_DOWN && gTasks[taskID].tCurrPokeID < gTasks[taskID].tPokesNo - 1) // change poke +1 { gTasks[taskID].tCurrPokeID++; gTasks[taskID].func = sub_8142CC8; } } static void sub_8142F78(u8 taskID) { CpuSet(gPlttBufferFaded, gPlttBufferUnfaded, 0x200); eHOFPCScreenEffect = sPCScreenEffectTemplate; sub_80C5E38(&eHOFPCScreenEffect); gTasks[taskID].func = sub_8142FCC; } static void sub_8142FCC(u8 taskID) { if (sub_80C5F98()) { DestroyTask(taskID); ReturnFromHallOfFamePC(); } } static void sub_8142FEC(u8 taskID) { Menu_DrawStdWindowFrame(2, 14, 27, 19); MenuPrintMessage(gMenuText_HOFCorrupt, 3, 15); gTasks[taskID].func = sub_814302C; } static void sub_814302C(u8 taskID) { if (Menu_UpdateWindowText() && gMain.newKeys & A_BUTTON) gTasks[taskID].func = sub_8142F78; } #undef tCurrTeamNo #undef tCurrPageNo #undef tCurrPokeID #undef tPokesNo #undef tMonSpriteID static void sub_8143068(u8 a0, u8 a1) { MenuPrint_Centered(gMenuText_WelcomeToHOFAndDexRating, 0, a1 + 1, 0xF0); } static void HallOfFame_PrintMonInfo(struct HallofFameMon* currMon, u8 a1, u8 a2) { u8* stringPtr; u16 monData; u16 i; stringPtr = gStringVar1; stringPtr[0] = EXT_CTRL_CODE_BEGIN; stringPtr[1] = 0x13; stringPtr[2] = 0x28; stringPtr[3] = EOS; if (currMon->species != SPECIES_EGG) { monData = SpeciesToPokedexNum(currMon->species); if (monData != 0xFFFF) { stringPtr = StringCopy(stringPtr, gOtherText_Number2); ConvertIntToDecimalStringN(stringPtr, monData, 2, 3); } } Menu_PrintText(gStringVar1, a1 + 4, a2 + 1); stringPtr = gStringVar1; for (i = 0; i < 10 && currMon->nick[i] != EOS; stringPtr[i] = currMon->nick[i], i++) {} stringPtr += i; stringPtr[0] = EOS; if (currMon->species == SPECIES_EGG) { stringPtr[0] = EXT_CTRL_CODE_BEGIN; stringPtr[1] = 0x13; stringPtr[2] = 0xA0; stringPtr[3] = EOS; Menu_PrintText(gStringVar1, a1 + 9, a2 + 1); Menu_EraseWindowRect(0, a2 + 3, 29, a2 + 4); } else { stringPtr[0] = EXT_CTRL_CODE_BEGIN; stringPtr[1] = 0x13; stringPtr[2] = 0x3E; stringPtr += 3; stringPtr[0] = CHAR_SLASH; stringPtr++; for (i = 0; i < 10 && gSpeciesNames[currMon->species][i] != EOS; stringPtr[i] = gSpeciesNames[currMon->species][i], i++) {} stringPtr += i; stringPtr[0] = CHAR_SPACE; stringPtr++; if (currMon->species != SPECIES_NIDORAN_M && currMon->species != SPECIES_NIDORAN_F) { switch (GetGenderFromSpeciesAndPersonality(currMon->species, currMon->personality)) { case MON_MALE: stringPtr[0] = CHAR_MALE; stringPtr++; break; case MON_FEMALE: stringPtr[0] = CHAR_FEMALE; stringPtr++; break; } } stringPtr[0] = EXT_CTRL_CODE_BEGIN; stringPtr[1] = 0x13; stringPtr[2] = 0xA0; stringPtr[3] = EOS; Menu_PrintText(gStringVar1, a1 + 9, a2 + 1); monData = currMon->lvl; stringPtr = StringCopy(gStringVar1, gOtherText_Level3); stringPtr[0] = EXT_CTRL_CODE_BEGIN; stringPtr[1] = 0x14; stringPtr[2] = 6; stringPtr += 3; stringPtr = ConvertIntToDecimalStringN(stringPtr, monData, 0, 3); stringPtr[0] = EXT_CTRL_CODE_BEGIN; stringPtr[1] = 0x13; stringPtr[2] = 0x30; stringPtr[3] = EOS; Menu_PrintText(gStringVar1, a1 + 7, a2 + 3); monData = currMon->tid; stringPtr = StringCopy(gStringVar1, gOtherText_IDNumber); ConvertIntToDecimalStringN(stringPtr, monData, 2, 5); Menu_PrintText(gStringVar1, a1 + 13, a2 + 3); } } #define ByteRead16(ptr) ((ptr)[0] | ((ptr)[1] << 8)) static void HallOfFame_PrintPlayerInfo(u8 a0, u8 a1) { u8* stringPtr; u16 visibleTid; Menu_PrintText(gOtherText_Name, a0 + 1, a1 + 1); MenuPrint_RightAligned(gSaveBlock2.playerName, a0 + 14, a1 + 1); Menu_PrintText(gOtherText_IDNumber2, a0 + 1, a1 + 3); visibleTid = ByteRead16(gSaveBlock2.playerTrainerId); ConvertIntToDecimalStringN(gStringVar1, visibleTid, 2, 5); MenuPrint_RightAligned(gStringVar1, a0 + 14, a1 + 3); Menu_PrintText(gMainMenuString_Time, a0 + 1, a1 + 5); stringPtr = ConvertIntToDecimalString(gStringVar1, gSaveBlock2.playTimeHours); stringPtr[0] = CHAR_SPACE; stringPtr[1] = CHAR_COLON; stringPtr[2] = CHAR_SPACE; stringPtr += 3; stringPtr = ConvertIntToDecimalStringN(stringPtr, gSaveBlock2.playTimeMinutes, 2, 2); stringPtr[0] = EOS; MenuPrint_RightAligned(gStringVar1, a0 + 14, a1 + 5); } static void sub_81433E0(void) { u16 i; REG_DISPCNT = 0; REG_BG0CNT = 0; REG_BG0HOFS = 0; REG_BG0VOFS = 0; REG_BG1CNT = 0; REG_BG1HOFS = 0; REG_BG1VOFS = 0; REG_BG2CNT = 0; REG_BG2HOFS = 0; REG_BG2VOFS = 0; REG_BG3CNT = 0; REG_BG3HOFS = 0; REG_BG3VOFS = 0; DmaFill16Large(3, 0, VRAM, 0x18000, 0x1000); DmaFill32Defvars(3, 0, OAM, OAM_SIZE); DmaFill16Defvars(3, 0, PLTT, PLTT_SIZE); LZ77UnCompVram(gHallOfFame_Gfx, (void*)(VRAM)); for (i = 0; i < 64; i++) { *((u16*)(VRAM + 0x3800) + i) = 1; } for (i = 0; i < 192; i++) { *((u16*)(VRAM + 0x3B80) + i) = 1; } for (i = 0; i < 1024; i++) { *((u16*)(VRAM + 0x3000) + i) = 2; } DmaFill16Large(3, 0, gSharedMem, 0x4000, 0x1000); ResetPaletteFade(); LoadPalette(gHallOfFame_Pal, 0, 0x20); } static void sub_8143570(void) { ScanlineEffect_Stop(); ResetTasks(); ResetSpriteData(); FreeAllSpritePalettes(); gReservedSpritePaletteCount = 8; LoadCompressedObjectPic(&sHallOfFame_ConfettiSpriteSheet); LoadCompressedObjectPalette(&sHallOfFame_ConfettiSpritePalette); Text_LoadWindowTemplate(&gWindowTemplate_81E71B4); InitMenuWindow(&gWindowTemplate_81E71B4); } static void sub_81435B8(void) { REG_BG1CNT = 0x700; REG_BG3CNT = 0x603; REG_DISPCNT = 0x1B40; } static void sub_81435DC(struct Sprite* sprite) { if (sprite->x != sprite->data[1] || sprite->y != sprite->data[2]) { if (sprite->x < sprite->data[1]) sprite->x += 15; if (sprite->x > sprite->data[1]) sprite->x -= 15; if (sprite->y < sprite->data[2]) sprite->y += 10; if (sprite->y > sprite->data[2]) sprite->y -= 10; } else { sprite->data[0] = 1; sprite->callback = SpriteCB_HallOfFame_Dummy; } } static void SpriteCB_HallOfFame_Dummy(struct Sprite* sprite) { } void sub_8143648(u16 paletteTag, u8 animID) { gCreatingSpriteTemplate = sUnknown_0840B6B8; gCreatingSpriteTemplate.paletteTag = paletteTag; gCreatingSpriteTemplate.images = sUnknown_0840B69C[animID]; gCreatingSpriteTemplate.anims = gSpriteAnimTable_81E7C64; } void sub_8143680(u16 paletteTag, u8 animID) { gCreatingSpriteTemplate = sUnknown_0840B6B8; gCreatingSpriteTemplate.paletteTag = paletteTag; gCreatingSpriteTemplate.images = sUnknown_0840B69C[animID]; gCreatingSpriteTemplate.anims = gUnknown_081EC2A4[0]; } static u32 HallOfFame_LoadPokemonPic(u16 species, s16 posX, s16 posY, u16 pokeID, u32 tid, u32 pid) { u8 spriteID; const u8* pokePal; LoadSpecialPokePic(&gMonFrontPicTable[species], gMonFrontPicCoords[species].coords, gMonFrontPicCoords[species].y_offset, (void *)EWRAM, gUnknown_0840B5A0[pokeID], species, pid, 1); pokePal = GetMonSpritePalFromOtIdPersonality(species, tid, pid); LoadCompressedPalette(pokePal, 16 * pokeID + 256, 0x20); sub_8143648(pokeID, pokeID); spriteID = CreateSprite(&gCreatingSpriteTemplate, posX, posY, 10 - pokeID); gSprites[spriteID].oam.paletteNum = pokeID; return spriteID; } static u32 HallOfFame_LoadTrainerPic(u16 trainerPicID, s16 posX, s16 posY, u16 a3) { u8 spriteID; DecompressPicFromTable_2(&gTrainerFrontPicTable[trainerPicID], gTrainerFrontPicCoords[trainerPicID].coords, gTrainerFrontPicCoords[trainerPicID].y_offset, (void*)EWRAM, gUnknown_0840B5A0[a3], trainerPicID); LoadCompressedPalette(gTrainerFrontPicPaletteTable[trainerPicID].data, 16 * a3 + 256, 0x20); sub_8143680(a3, a3); spriteID = CreateSprite(&gCreatingSpriteTemplate, posX, posY, 1); gSprites[spriteID].oam.paletteNum = a3; return spriteID; } static void sub_814386C(struct Sprite* sprite) { if (sprite->y2 > 120) DestroySprite(sprite); else { u16 rand; u8 tableID; sprite->y2++; sprite->y2 += sprite->data[1]; tableID = sprite->data[0]; rand = (Random() % 4) + 8; sprite->x2 = rand * gSineTable[tableID] / 256; sprite->data[0] += 4; } } static bool8 sub_81438C4(void) { u8 spriteID; struct Sprite* sprite; s16 posX = Random() % 240; s16 posY = -(Random() % 8); spriteID = CreateSprite(&sSpriteTemplate_840B7A4, posX, posY, 0); sprite = &gSprites[spriteID]; StartSpriteAnim(sprite, Random() % 17); if (Random() & 3) sprite->data[1] = 0; else sprite->data[1] = 1; return 0; }