diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/berry_blender.c | 585 | ||||
-rw-r--r-- | src/hall_of_fame.c | 1552 | ||||
-rw-r--r-- | src/mail.c | 2 | ||||
-rw-r--r-- | src/starter_choose.c | 391 | ||||
-rw-r--r-- | src/text_window.c | 4 |
5 files changed, 2528 insertions, 6 deletions
diff --git a/src/berry_blender.c b/src/berry_blender.c index db50fe4c4..8e5a51845 100644 --- a/src/berry_blender.c +++ b/src/berry_blender.c @@ -1,6 +1,8 @@ - -// Includes #include "global.h" +#include "bg.h" +#include "window.h" +#include "task.h" +#include "sprite.h" // Static type declarations @@ -11,8 +13,585 @@ IWRAM_DATA s16 gUnknown_03000DF8[6]; IWRAM_DATA s16 gUnknown_03000E04; IWRAM_DATA s16 gUnknown_03000E06; -// Static ROM declarations +// graphics +extern const u8 gBerryBlenderArrowTiles[]; +extern const u8 gBerryBlenderStartTiles[]; +extern const u8 gBerryBlenderMarubatsuTiles[]; +extern const u8 gBerryBlenderParticlesTiles[]; +extern const u8 gBerryBlenderCountdownNumbersTiles[]; +extern const u16 gBerryBlenderMiscPalette[]; +extern const u16 gBerryBlenderArrowPalette[]; + +void sub_8080EA4(u8 taskId); +void sub_8080FD0(u8 taskId); +void sub_80810F8(u8 taskId); +void sub_80833F8(struct Sprite *sprite); +void sub_8082F68(struct Sprite *sprite); +void sub_8083010(struct Sprite *sprite); +void sub_80830C0(struct Sprite *sprite); // .rodata +// TODO: make those static once the file is decompiled +const u16 sBlenderCenterPal[] = INCBIN_U16("graphics/berry_blender/center.gbapal"); +const u8 sBlenderCenterMap[] = INCBIN_U8("graphics/berry_blender/center_map.bin"); +const u16 sBlenderOuterPal[] = INCBIN_U16("graphics/berry_blender/outer.gbapal"); + +// unreferenced pals? +static const u16 sUnknownPal_0[] = INCBIN_U16("graphics/unknown/unknown_339514.gbapal"); +static const u16 sUnknownArray_1[224] = {0}; + +// unused text? +static const u8 sUnusedText_YesNo[] = _("YES\nNO"); +static const u8 sUnusedText_2[] = _("▶"); +static const u8 sUnusedText_Space[] = _(" "); +static const u8 sUnusedText_Terminating[] = _("Terminating."); +static const u8 sUnusedText_LinkPartnerNotFound[] = _("Link partner(s) not found.\nPlease try again.\p"); + +const u8 gText_BerryBlenderStart[] = _("Starting up the BERRY BLENDER.\pPlease select a BERRY from your BAG\nto put in the BERRY BLENDER.\p"); +const u8 gText_NewParagraph[] = _("\p"); +const u8 gText_WasMade[] = _(" was made!"); +static const u8 sText_Mister[] = _("MISTER"); +static const u8 sText_Laddie[] = _("LADDIE"); +static const u8 sText_Lassie[] = _("LASSIE"); +static const u8 sText_Master[] = _("MASTER"); +static const u8 sText_Dude[] = _("DUDE"); +static const u8 sText_Miss[] = _("MISS"); + +const u8* const sBlenderOpponentsNames[] = +{ + sText_Mister, + sText_Laddie, + sText_Lassie, + sText_Master, + sText_Dude, + sText_Miss +}; + +static const u8 sText_PressAToStart[] = _("Press the A Button to start."); +static const u8 sText_PleaseWaitAWhile[] = _("Please wait a while."); +const u8 sText_CommunicationStandby[] = _("Communication standby…"); +const u8 sText_WouldLikeToBlendAnotherBerry[] = _("Would you like to blend another BERRY?"); +const u8 sText_RunOutOfBerriesForBlending[] = _("You’ve run out of BERRIES for\nblending in the BERRY BLENDER.\p"); +const u8 sText_YourPokeblockCaseIsFull[] = _("Your {POKEBLOCK} CASE is full.\p"); +const u8 sText_HasNoBerriesToPut[] = _(" has no BERRIES to put in\nthe BERRY BLENDER."); +const u8 sText_ApostropheSPokeblockCaseIsFull[] = _("’s {POKEBLOCK} CASE is full.\p"); +const u8 sText_BlendingResults[] = _("RESULTS OF BLENDING"); +static const u8 sText_BerryUsed[] = _("BERRY USED"); +const u8 sText_SpaceBerry[] = _(" BERRY"); +const u8 sText_Time[] = _("Time:"); +const u8 sText_Min[] = _(" min. "); +const u8 sText_Sec[] = _(" sec."); +const u8 sText_MaximumSpeed[] = _("MAXIMUM SPEED"); +const u8 sText_RPM[] = _(" RPM"); +const u8 sText_Dot[] = _("."); +const u8 sText_NewLine[] = _("\n"); +static const u8 sText_Space[] = _(" "); +const u8 sText_Ranking[] = _("RANKING"); +const u8 sText_TheLevelIs[] = _("The level is "); +const u8 sText_TheFeelIs[] = _(", and the feel is "); +const u8 sText_Dot2[] = _("."); + +const struct BgTemplate gUnknown_08339974[3] = +{ + { + .bg = 0, + .charBaseIndex = 3, + .mapBaseIndex = 31, + .screenSize = 0, + .paletteMode = 0, + .priority = 0, + .baseTile = 0, + }, + { + .bg = 1, + .charBaseIndex = 2, + .mapBaseIndex = 12, + .screenSize = 0, + .paletteMode = 0, + .priority = 1, + .baseTile = 0, + }, + { + .bg = 2, + .charBaseIndex = 0, + .mapBaseIndex = 8, + .screenSize = 1, + .paletteMode = 1, + .priority = 0, + .baseTile = 0, + } +}; + +const struct WindowTemplate gUnknown_08339980[] = +{ + {0, 1, 6, 7, 2, 0xE, 0x28}, + {0, 0x16, 6, 7, 2, 0xE, 0x36}, + {0, 1, 0xC, 7, 2, 0xE, 0x44}, + {0, 0x16, 0xC, 7, 2, 0xE, 0x52}, + {0, 2, 0xF, 0x1B, 4, 0xE, 0x60}, + {0, 5, 3, 0x15, 0xE, 0xE, 0x60}, + DUMMY_WIN_TEMPLATE +}; + +const struct WindowTemplate gUnknown_083399B8 = +{ + 0, 0x15, 9, 5, 4, 0xE, 0xCC +}; + +const s8 gUnknown_083399C0[][2] = +{ + {-1, -1}, {1, -1}, {-1, 1}, {1, 1} +}; + +const u8 sBlenderSyncArrowsPos[][2] = +{ + {72, 32}, {168, 32}, {72, 128}, {168, 128} +}; + +const u8 gUnknown_083399D0[3][4] = +{ + {-1, 0, 1, -1}, {-1, 0, 1, 2}, {0, 1, 2, 3} +}; + +const u16 gUnknown_083399DC[] = {0, 0xC000, 0x4000, 0x8000}; +const u8 gUnknown_083399E4[] = {1, 1, 0}; +const u8 gUnknown_083399E7[] = {32, 224, 96, 160, 0}; + +const TaskFunc gUnknown_083399EC[] = +{ + sub_8080EA4, sub_8080FD0, sub_80810F8 +}; + +static const struct OamData sOamData_8216314 = +{ + .y = 0, + .affineMode = 0, + .objMode = 0, + .mosaic = 0, + .bpp = 0, + .shape = 0, + .x = 0, + .matrixNum = 0, + .size = 2, + .tileNum = 0, + .priority = 1, + .paletteNum = 0, + .affineParam = 0, +}; + +static const union AnimCmd sSpriteAnim_821631C[] = +{ + ANIMCMD_FRAME(16, 5, 1, 1), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_8216324[] = +{ + ANIMCMD_FRAME(16, 5, .vFlip = TRUE), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_821632C[] = +{ + ANIMCMD_FRAME(16, 5, .hFlip = TRUE), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_8216334[] = +{ + ANIMCMD_FRAME(16, 5, 0, 0), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_821633C[] = +{ + ANIMCMD_FRAME(48, 2, 1, 1), + ANIMCMD_FRAME(32, 5, 1, 1), + ANIMCMD_FRAME(48, 3, 1, 1), + ANIMCMD_FRAME(16, 5, 1, 1), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_8216350[] = +{ + ANIMCMD_FRAME(48, 2, .vFlip = TRUE), + ANIMCMD_FRAME(32, 5, .vFlip = TRUE), + ANIMCMD_FRAME(48, 3, .vFlip = TRUE), + ANIMCMD_FRAME(16, 5, .vFlip = TRUE), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_8216364[] = +{ + ANIMCMD_FRAME(48, 2, .hFlip = TRUE), + ANIMCMD_FRAME(32, 5, .hFlip = TRUE), + ANIMCMD_FRAME(48, 3, .hFlip = TRUE), + ANIMCMD_FRAME(16, 5, .hFlip = TRUE), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_8216378[] = +{ + ANIMCMD_FRAME(48, 2, 0, 0), + ANIMCMD_FRAME(32, 5, 0, 0), + ANIMCMD_FRAME(48, 3, 0, 0), + ANIMCMD_FRAME(16, 5, 0, 0), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_821638C[] = +{ + ANIMCMD_FRAME(0, 5, 1, 1), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_8216394[] = +{ + ANIMCMD_FRAME(0, 5, .vFlip = TRUE), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_821639C[] = +{ + ANIMCMD_FRAME(0, 5, .hFlip = TRUE), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_82163A4[] = +{ + ANIMCMD_FRAME(0, 5, 0, 0), + ANIMCMD_END +}; + +static const union AnimCmd *const sSpriteAnimTable_82163AC[] = +{ + sSpriteAnim_821631C, + sSpriteAnim_8216324, + sSpriteAnim_821632C, + sSpriteAnim_8216334, + sSpriteAnim_821633C, + sSpriteAnim_8216350, + sSpriteAnim_8216364, + sSpriteAnim_8216378, + sSpriteAnim_821638C, + sSpriteAnim_8216394, + sSpriteAnim_821639C, + sSpriteAnim_82163A4 +}; + +const struct SpriteSheet sSpriteSheet_BlenderArrow = +{ + gBerryBlenderArrowTiles, 0x800, 46545 +}; + +const struct SpritePalette sSpritePal_BlenderMisc = +{ + gBerryBlenderMiscPalette, 46546 +}; + +const struct SpritePalette sSpritePal_BlenderArrow = +{ + gBerryBlenderArrowPalette, 12312 +}; + +const struct SpriteTemplate sBlenderSyncArrow_SpriteTemplate = +{ + .tileTag = 46545, + .paletteTag = 12312, + .oam = &sOamData_8216314, + .anims = sSpriteAnimTable_82163AC, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_80833F8 +}; + +static const struct OamData sOamData_821640C = +{ + .y = 0, + .affineMode = 0, + .objMode = 0, + .mosaic = 0, + .bpp = 0, + .shape = 0, + .x = 0, + .matrixNum = 0, + .size = 1, + .tileNum = 0, + .priority = 0, + .paletteNum = 0, + .affineParam = 0, +}; + +static const union AnimCmd sSpriteAnim_8216414[] = +{ + ANIMCMD_FRAME(0, 20), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_821641C[] = +{ + ANIMCMD_FRAME(4, 20, 1, 0), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_8216424[] = +{ + ANIMCMD_FRAME(8, 4), + ANIMCMD_FRAME(12, 4), + ANIMCMD_FRAME(8, 4), + ANIMCMD_FRAME(12, 4), + ANIMCMD_FRAME(8, 4), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_821643C[] = +{ + ANIMCMD_FRAME(8, 4), + ANIMCMD_END +}; + +static const union AnimCmd *const sSpriteAnimTable_8216444[] = +{ + sSpriteAnim_8216414, + sSpriteAnim_821641C, + sSpriteAnim_8216424, + sSpriteAnim_821643C, +}; + +const struct SpriteSheet gUnknown_08339B38 = +{ + gBerryBlenderMarubatsuTiles, 0x200, 48888 +}; + +const struct SpriteTemplate gUnknown_08339B40 = +{ + .tileTag = 48888, + .paletteTag = 46546, + .oam = &sOamData_821640C, + .anims = sSpriteAnimTable_8216444, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_8082F68 +}; + +static const struct OamData sOamData_8216474 = +{ + .y = 0, + .affineMode = 0, + .objMode = 0, + .mosaic = 0, + .bpp = 0, + .shape = 0, + .x = 0, + .matrixNum = 0, + .size = 0, + .tileNum = 0, + .priority = 1, + .paletteNum = 0, + .affineParam = 0, +}; + +static const union AnimCmd sSpriteAnim_821647C[] = +{ + ANIMCMD_FRAME(0, 3), + ANIMCMD_FRAME(1, 4), + ANIMCMD_FRAME(3, 5), + ANIMCMD_FRAME(1, 4), + ANIMCMD_FRAME(0, 3), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_8216494[] = +{ + ANIMCMD_FRAME(0, 3), + ANIMCMD_FRAME(2, 4), + ANIMCMD_FRAME(4, 5), + ANIMCMD_FRAME(2, 4), + ANIMCMD_FRAME(0, 3), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_82164AC[] = +{ + ANIMCMD_FRAME(0, 2), + ANIMCMD_FRAME(1, 2), + ANIMCMD_FRAME(2, 2), + ANIMCMD_FRAME(4, 4), + ANIMCMD_FRAME(3, 3), + ANIMCMD_FRAME(2, 2), + ANIMCMD_FRAME(1, 2), + ANIMCMD_FRAME(0, 2), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_82164D0[] = +{ + ANIMCMD_FRAME(5, 5, 1, 1), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_82164D8[] = +{ + ANIMCMD_FRAME(6, 5, 1, 1), + ANIMCMD_END +}; + +static const union AnimCmd *const sSpriteAnimTable_82164E0[] = +{ + sSpriteAnim_821647C, + sSpriteAnim_8216494, + sSpriteAnim_82164AC, + sSpriteAnim_82164D0, + sSpriteAnim_82164D8, +}; + +const struct SpriteSheet gUnknown_08339BD8 = +{ + gBerryBlenderParticlesTiles, 0xE0, 23456 +}; + +const struct SpriteTemplate gUnknown_08339BE0 = +{ + .tileTag = 23456, + .paletteTag = 46546, + .oam = &sOamData_8216474, + .anims = sSpriteAnimTable_82164E0, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy +}; + +static const struct OamData sOamData_8216514 = +{ + .y = 0, + .affineMode = 0, + .objMode = 0, + .mosaic = 0, + .bpp = 0, + .shape = 0, + .x = 0, + .matrixNum = 0, + .size = 2, + .tileNum = 0, + .priority = 1, + .paletteNum = 0, + .affineParam = 0, +}; + +static const union AnimCmd sSpriteAnim_821651C[] = +{ + ANIMCMD_FRAME(32, 30), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_8216524[] = +{ + ANIMCMD_FRAME(16, 30), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_821652C[] = +{ + ANIMCMD_FRAME(0, 30), + ANIMCMD_END +}; + +static const union AnimCmd *const sSpriteAnimTable_8216534[] = +{ + sSpriteAnim_821651C, + sSpriteAnim_8216524, + sSpriteAnim_821652C, +}; + +const struct SpriteSheet gUnknown_08339C24 = +{ + gBerryBlenderCountdownNumbersTiles, 0x600, 12345 +}; + +const struct SpriteTemplate gUnknown_08339C2C = +{ + .tileTag = 12345, + .paletteTag = 46546, + .oam = &sOamData_8216514, + .anims = sSpriteAnimTable_8216534, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_8083010 +}; + +static const struct OamData sOamData_8216560 = +{ + .y = 0, + .affineMode = 0, + .objMode = 0, + .mosaic = 0, + .bpp = 0, + .shape = 1, + .x = 0, + .matrixNum = 0, + .size = 3, + .tileNum = 0, + .priority = 1, + .paletteNum = 0, + .affineParam = 0, +}; + +static const union AnimCmd sSpriteAnim_8216568[] = +{ + ANIMCMD_FRAME(0, 30), + ANIMCMD_END +}; + +static const union AnimCmd *const sSpriteAnimTable_8216570[] = +{ + sSpriteAnim_8216568, +}; + +const struct SpriteSheet gUnknown_08339C58 = +{ + gBerryBlenderStartTiles, 0x400, 12346 +}; + +const struct SpriteTemplate gUnknown_08339C60 = +{ + .tileTag = 12346, + .paletteTag = 46546, + .oam = &sOamData_8216560, + .anims = sSpriteAnimTable_8216570, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_80830C0 +}; + +const s16 gUnknown_08339C78[][5] = +{ + {-10, 20, 10, 2, 1}, + {250, 20, 10, -2, 1}, + {-10, 140, 10, 2, -1}, + {250, 140, 10, -2, -1}, +}; + +const u8 gUnknown_08339CA0[][3] = +{ + {4, 3, 2}, {0, 4, 3}, {1, 0, 4}, {2, 1, 0}, {3, 2, 1}, {0, 2, 3}, {1, 3, 4}, {2, 4, 0}, {3, 0, 1}, {4, 1, 2}, +}; + +const u8 gUnknown_08339CBE[] = {30, 31, 32, 33, 34}; + +const u8 gUnknown_08339CC3[] = {1, 1, 2, 3, 4}; + +const u8 gUnknown_08339CC8[] = {0x1C, 0x16, 0x13, 0x1A, 0x19, 0x0E, 0x0D, 0x0B, 0x07, 0x15}; + +static const u8 gUnknown_08339CD2[] = +{ + 0xfe, 0x02, 0x02, 0xce, 0xd0, 0x37, 0x44, 0x07, 0x1f, 0x0c, 0x10, + 0x00, 0xff, 0xfe, 0x91, 0x72, 0xce, 0xd0, 0x37, 0x44, 0x07, 0x1f, + 0x0c, 0x10, 0x00, 0xff, 0x06, 0x27, 0x02, 0xff, 0x00, 0x0c, 0x48, + 0x02, 0xff, 0x00, 0x01, 0x1f, 0x02, 0xff, 0x00, 0x16, 0x37, 0x02, + 0xff, 0x00, 0x0d, 0x50, 0x4b, 0x02, 0xff, 0x06, 0x06, 0x06, 0x06, + 0x05, 0x03, 0x03, 0x03, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x02 +}; + +const struct WindowTemplate gUnknown_08339D14[] = {0, 6, 4, 0x12, 0xB, 0xF, 8}; // .text diff --git a/src/hall_of_fame.c b/src/hall_of_fame.c index d9fd40b84..bc7177bd7 100644 --- a/src/hall_of_fame.c +++ b/src/hall_of_fame.c @@ -1,4 +1,1556 @@ #include "global.h" #include "hall_of_fame.h" +#include "task.h" +#include "palette.h" +#include "sprite.h" +#include "pokemon.h" +#include "text.h" +#include "malloc.h" +#include "gpu_regs.h" +#include "main.h" +#include "sound.h" +#include "songs.h" +#include "decompress.h" +#include "save.h" +#include "window.h" +#include "bg.h" +#include "species.h" +#include "game_stat.h" +#include "blend_palette.h" +#include "string_util.h" +#include "m4a.h" +#include "international_string_util.h" +#include "unknown_task.h" +#include "trig.h" +#include "rng.h" +#include "event_data.h" +struct HallofFameMon +{ + u32 tid; + u32 personality; + u16 species:9; + u16 lvl:7; + u8 nick[10]; +}; +struct HallofFameTeam +{ + struct HallofFameMon mon[6]; +}; + +struct HofGfx +{ + u16 state; + u8 field_2[16]; + u8 tilemap1[0x1000]; + u8 tilemap2[0x1000]; +}; + +static EWRAM_DATA struct HallofFameTeam *sHofMonPtr = NULL; +static EWRAM_DATA struct HofGfx *sHofGfxPtr = NULL; + +extern bool8 gHasHallOfFameRecords; +extern u32 gUnknown_0203BCD4; +extern u8 gDecompressionBuffer[]; +extern struct MusicPlayerInfo gMPlay_BGM; +extern MainCallback gGameContinueCallback; +extern u32 gDamagedSaveSectors; +extern u8 gReservedSpritePaletteCount; + +#define HALL_OF_FAME_MAX_TEAMS 50 + +// strings +extern const u8 gText_SavingDontTurnOffPower[]; +extern const u8 gText_LeagueChamp[]; +extern const u8 gText_HOFNumber[]; +extern const u8 gText_PickNextCancel[]; +extern const u8 gText_PickCancel[]; +extern const u8 gText_UnkCtrlF800Exit[]; +extern const u8 gText_HOFCorrupted[]; +extern const u8 gText_WelcomeToHOF[]; +extern const u8 gText_Number[]; +extern const u8 gText_Level[]; +extern const u8 gText_IDNumber[]; +extern const u8 gText_Name[]; +extern const u8 gText_MainMenuTime[]; + +// graphics +extern const u8 gContestConfetti_Gfx[]; +extern const u8 gContestConfetti_Pal[]; + +extern void sub_81973C4(u8, u8); +extern u16 AddTextPrinterParametrized(u8 windowId, u8 fontId, const u8 *str, u8 speed, void ( *callback)(u16, struct TextPrinter *), u8 fgColor, u8 bgColor, u8 shadowColor); +extern void sub_8175620(void); +extern u8 TrySavingData(u8); +extern u8 sub_818D3E4(u16 species, u32 trainerId, u32 personality, u8 flags, s16 x, s16 y, u8, u16); +extern void sub_8197434(u8, u8); +extern u16 sub_818D97C(u8 playerGender, u8); +extern u16 sub_818D8AC(u16, u8, s16, s16, u8, u16); +extern const void* stdpal_get(u8); +extern void sub_80987D4(u8, u8, u16, u8); +extern u16 sub_818D820(u16); +extern u16 sub_818D8F0(u16); +extern u16 sub_818D7D8(u16 species, u32 trainerId, u32 personality, u8 arg3, s16 sp0, s16 sp1, u8 sp2, u16 sp3); +extern void sub_8198204(u8 *dst, const u8 *src, u8, u8, u8); +extern bool8 sub_80F9C30(void); +extern void sub_8198314(void); +extern void sub_8137C3C(void); +extern void sub_8198180(const u8 *src, u8, u8); +extern void sub_80F9BF4(u16, u16, u8); +extern void sub_81980F0(u8, u8, u8, u8, u16); +extern void sub_80F9BCC(u16, u16, u8); +extern bool8 sub_80F9C1C(void); +extern u16 SpeciesToPokedexNum(u16 species); +extern void dp13_810BB8C(void); +extern void sub_81971D0(void); +extern void sub_8197200(void); +extern void sub_8152254(void); +extern void sub_81525D0(u8); +extern void sub_8152438(u8, void*); +extern void sub_8152474(u8, u8, u8); +extern void sub_81522D4(void); +extern bool32 sub_81521C0(u8); +extern u8 sub_81524C4(const struct OamData *arg0, s16 arg1, s16 arg2, s16 arg3, s16 arg4, u8 arg5, s16 arg6); + +// this file's functions +static void ClearVramOamPltt_LoadHofPal(void); +static void sub_8174F70(void); +static void sub_8174FAC(void); +static bool8 sub_81751FC(void); +static void SetCallback2AfterHallOfFameDisplay(void); +static bool8 sub_8175024(void); +static void Task_Hof_InitMonData(u8 taskId); +static void Task_Hof_InitTeamSaveData(u8 taskId); +static void Task_Hof_SetMonDisplayTask(u8 taskId); +static void Task_Hof_TrySaveData(u8 taskId); +static void Task_Hof_WaitForFrames(u8 taskId); +static void Task_Hof_DisplayMon(u8 taskId); +static void Task_Hof_PrintMonInfoAfterAnimating(u8 taskId); +static void Task_Hof_TryDisplayAnotherMon(u8 taskId); +static void Task_Hof_PaletteFadeAndPrintWelcomeText(u8 taskId); +static void sub_8173DC0(u8 taskId); +static void sub_8173EA4(u8 taskId); +static void sub_8173EE4(u8 taskId); +static void Task_Hof_WaitAndPrintPlayerInfo(u8 taskId); +static void Task_Hof_ExitOnKeyPressed(u8 taskId); +static void Task_Hof_HandlePaletteOnExit(u8 taskId); +static void Task_Hof_HandleExit(u8 taskId); +static void Task_HofPC_CopySaveData(u8 taskId); +static void Task_HofPC_PrintDataIsCorrupted(u8 taskId); +static void Task_HofPC_DrawSpritesPrintText(u8 taskId); +static void Task_HofPC_PrintMonInfo(u8 taskId); +static void Task_HofPC_HandleInput(u8 taskId); +static void Task_HofPC_HandlePaletteOnExit(u8 taskId); +static void Task_HofPC_HandleExit(u8 taskId); +static void Task_HofPC_ExitOnButtonPress(u8 taskId); +static void SpriteCB_GetOnScreenAndAnimate(struct Sprite *sprite); +static void HallOfFame_PrintMonInfo(struct HallofFameMon* currMon, u8 unused1, u8 unused2); +static void HallOfFame_PrintWelcomeText(u8 unusedPossiblyWindowId, u8 unused2); +static void HallOfFame_PrintPlayerInfo(u8 unused1, u8 unused2); +static void sub_8175364(u8 taskId); +static void sub_81751A4(struct Sprite* sprite); + +// const rom data +static const struct BgTemplate sHof_BgTemplates[] = +{ + { + .bg = 0, + .charBaseIndex = 2, + .mapBaseIndex = 31, + .screenSize = 0, + .paletteMode = 0, + .priority = 0, + .baseTile = 0 + }, + { + .bg = 1, + .charBaseIndex = 0, + .mapBaseIndex = 30, + .screenSize = 0, + .paletteMode = 0, + .priority = 1, + .baseTile = 0 + }, + { + .bg = 3, + .charBaseIndex = 0, + .mapBaseIndex = 29, + .screenSize = 0, + .paletteMode = 0, + .priority = 3, + .baseTile = 0 + }, +}; + +static const struct WindowTemplate sHof_WindowTemplate = {0, 2, 2, 0xE, 6, 0xE, 1}; + +static const u8 gUnknown_085E5388[] = {0, 1, 2, 0}; + +static const u8 gUnknown_085E538C[] = {0, 2, 3, 0, 4, 5, 0, 0}; + +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_MonFullTeamPositions[6][4] = +{ + {120, 210, 120, 40}, + {326, 220, 56, 40}, + {-86, 220, 184, 40}, + {120, -62, 120, 88}, + {-70, -92, 200, 88}, + {310, -92, 40, 88} +}; + +static const s16 sHallOfFame_MonHalfTeamPositions[3][4] = +{ + {120, 234, 120, 64}, + {326, 244, 56, 64}, + {-86, 244, 184, 64} +}; + +static const struct OamData sOamData_85E53FC = +{ + .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_85E5404[] = +{ + ANIMCMD_FRAME(0, 30), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_85E540C[] = +{ + ANIMCMD_FRAME(1, 30), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_85E5414[] = +{ + ANIMCMD_FRAME(2, 30), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_85E541C[] = +{ + ANIMCMD_FRAME(3, 30), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_85E5424[] = +{ + ANIMCMD_FRAME(4, 30), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_85E542C[] = +{ + ANIMCMD_FRAME(5, 30), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_85E5434[] = +{ + ANIMCMD_FRAME(6, 30), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_85E543C[] = +{ + ANIMCMD_FRAME(7, 30), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_85E5444[] = +{ + ANIMCMD_FRAME(8, 30), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_85E544C[] = +{ + ANIMCMD_FRAME(9, 30), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_85E5454[] = +{ + ANIMCMD_FRAME(10, 30), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_85E545C[] = +{ + ANIMCMD_FRAME(11, 30), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_85E5464[] = +{ + ANIMCMD_FRAME(12, 30), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_85E546C[] = +{ + ANIMCMD_FRAME(13, 30), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_85E5474[] = +{ + ANIMCMD_FRAME(14, 30), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_85E547C[] = +{ + ANIMCMD_FRAME(15, 30), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_85E5484[] = +{ + ANIMCMD_FRAME(16, 30), + ANIMCMD_END +}; + +static const union AnimCmd * const sSpriteAnimTable_85E548C[] = +{ + sSpriteAnim_85E5404, sSpriteAnim_85E540C, sSpriteAnim_85E5414, sSpriteAnim_85E541C, + sSpriteAnim_85E5424, sSpriteAnim_85E542C, sSpriteAnim_85E5434, sSpriteAnim_85E543C, + sSpriteAnim_85E5444, sSpriteAnim_85E544C, sSpriteAnim_85E5454, sSpriteAnim_85E545C, + sSpriteAnim_85E5464, sSpriteAnim_85E546C, sSpriteAnim_85E5474, sSpriteAnim_85E547C, + sSpriteAnim_85E5484 +}; + +static const struct SpriteTemplate sSpriteTemplate_85E54D0 = +{ + .tileTag = 1001, + .paletteTag = 1001, + .oam = &sOamData_85E53FC, + .anims = sSpriteAnimTable_85E548C, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_81751A4 +}; + +static const u16 sHallOfFame_Pal[] = INCBIN_U16("graphics/misc/japanese_hof.gbapal"); + +static const u8 sHallOfFame_Gfx[] = INCBIN_U8("graphics/misc/japanese_hof.4bpp.lz"); + +static const struct HallofFameMon sDummyFameMon = +{ + 0x3EA03EA, 0, 0, 0, {0} +}; + +static const u8 sUnused2[6] = {2, 1, 3, 6, 4, 5}; + +// code +static void VBlankCB_HallOfFame(void) +{ + LoadOam(); + ProcessSpriteCopyRequests(); + TransferPlttBuffer(); +} + +static void CB2_HallOfFame(void) +{ + RunTasks(); + RunTextPrinters(); + AnimateSprites(); + BuildOamBuffer(); + UpdatePaletteFade(); +} + +static bool8 InitHallOfFameScreen(void) +{ + switch (gMain.state) + { + case 0: + SetVBlankCallback(NULL); + ClearVramOamPltt_LoadHofPal(); + sHofGfxPtr = AllocZeroed(sizeof(*sHofGfxPtr)); + gMain.state = 1; + break; + case 1: + sub_8174F70(); + gMain.state++; + break; + case 2: + SetGpuReg(REG_OFFSET_BLDCNT, 0x3F42); + SetGpuReg(REG_OFFSET_BLDALPHA, 0x710); + SetGpuReg(REG_OFFSET_BLDY, 0); + sub_8174FAC(); + sHofGfxPtr->state = 0; + gMain.state++; + break; + case 3: + if (!sub_8175024()) + { + SetVBlankCallback(VBlankCB_HallOfFame); + BeginNormalPaletteFade(-1, 0, 0x10, 0, 0); + gMain.state++; + } + break; + case 4: + UpdatePaletteFade(); + if (!gPaletteFade.active) + { + SetMainCallback2(CB2_HallOfFame); + PlayBGM(BGM_DENDOU); + return FALSE; + } + break; + } + return TRUE; +} + +#define tDontSaveData data[0] +#define tDisplayedMonId data[1] +#define tMonNumber data[2] +#define tFrameCount data[3] +#define tPlayerSpriteID data[4] +#define tMonSpriteId(i) data[i + 5] + +void CB2_DoHallOfFameScreen(void) +{ + if (!InitHallOfFameScreen()) + { + u8 taskId = CreateTask(Task_Hof_InitMonData, 0); + gTasks[taskId].tDontSaveData = FALSE; + sHofMonPtr = AllocZeroed(sizeof(*sHofMonPtr)); + } +} + +void CB2_DoHallOfFameScreenDontSaveData(void) +{ + if (!InitHallOfFameScreen()) + { + u8 taskId = CreateTask(Task_Hof_InitMonData, 0); + gTasks[taskId].tDontSaveData = TRUE; + sHofMonPtr = AllocZeroed(sizeof(*sHofMonPtr)); + } +} + +static void Task_Hof_InitMonData(u8 taskId) +{ + u16 i, j; + + gTasks[taskId].tMonNumber = 0; // valid pokes + + for (i = 0; i < 6; i++) + { + u8 nick[POKEMON_NAME_LENGTH + 2]; + if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES)) + { + sHofMonPtr->mon[i].species = GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2); + sHofMonPtr->mon[i].tid = GetMonData(&gPlayerParty[i], MON_DATA_OT_ID); + sHofMonPtr->mon[i].personality = GetMonData(&gPlayerParty[i], MON_DATA_PERSONALITY); + sHofMonPtr->mon[i].lvl = GetMonData(&gPlayerParty[i], MON_DATA_LEVEL); + GetMonData(&gPlayerParty[i], MON_DATA_NICKNAME, nick); + for (j = 0; j < POKEMON_NAME_LENGTH; j++) + { + sHofMonPtr->mon[i].nick[j] = nick[j]; + } + gTasks[taskId].tMonNumber++; + } + else + { + sHofMonPtr->mon[i].species = 0; + sHofMonPtr->mon[i].tid = 0; + sHofMonPtr->mon[i].personality = 0; + sHofMonPtr->mon[i].lvl = 0; + sHofMonPtr->mon[i].nick[0] = EOS; + } + } + + gUnknown_0203BCD4 = 0; + gTasks[taskId].tDisplayedMonId = 0; + gTasks[taskId].tPlayerSpriteID = 0xFF; + + for (i = 0; i < 6; i++) + { + gTasks[taskId].tMonSpriteId(i) = 0xFF; + } + + if (gTasks[taskId].tDontSaveData) + gTasks[taskId].func = Task_Hof_SetMonDisplayTask; + else + gTasks[taskId].func = Task_Hof_InitTeamSaveData; +} + +static void Task_Hof_InitTeamSaveData(u8 taskId) +{ + u16 i; + struct HallofFameTeam* lastSavedTeam = (struct HallofFameTeam*)(gDecompressionBuffer); + + if (!gHasHallOfFameRecords) + { + memset(gDecompressionBuffer, 0, 0x2000); + } + else + { + if (sub_81534D0(3) != TRUE) + memset(gDecompressionBuffer, 0, 0x2000); + } + + for (i = 0; i < HALL_OF_FAME_MAX_TEAMS; i++, lastSavedTeam++) + { + if (lastSavedTeam->mon[0].species == 0) + break; + } + if (i >= HALL_OF_FAME_MAX_TEAMS) + { + struct HallofFameTeam *afterTeam = (struct HallofFameTeam*)(gDecompressionBuffer); + struct HallofFameTeam *beforeTeam = (struct HallofFameTeam*)(gDecompressionBuffer); + afterTeam++; + for (i = 0; i < HALL_OF_FAME_MAX_TEAMS - 1; i++, beforeTeam++, afterTeam++) + { + *beforeTeam = *afterTeam; + } + lastSavedTeam--; + } + *lastSavedTeam = *sHofMonPtr; + + sub_81973C4(0, 0); + AddTextPrinterParametrized(0, 1, gText_SavingDontTurnOffPower, 0, NULL, 2, 1, 3); + CopyWindowToVram(0, 3); + gTasks[taskId].func = Task_Hof_TrySaveData; +} + +static void Task_Hof_TrySaveData(u8 taskId) +{ + gGameContinueCallback = CB2_DoHallOfFameScreenDontSaveData; + if (TrySavingData(3) == 0xFF && gDamagedSaveSectors != 0) + { + UnsetBgTilemapBuffer(1); + UnsetBgTilemapBuffer(3); + FreeAllWindowBuffers(); + + if (sHofGfxPtr != NULL) + FREE_AND_SET_NULL(sHofGfxPtr); + if (sHofMonPtr != NULL) + FREE_AND_SET_NULL(sHofMonPtr); + + DestroyTask(taskId); + } + else + { + PlaySE(SE_SAVE); + gTasks[taskId].func = Task_Hof_WaitForFrames; + gTasks[taskId].tFrameCount = 32; + } +} + +static void Task_Hof_WaitForFrames(u8 taskId) +{ + if (gTasks[taskId].tFrameCount) + gTasks[taskId].tFrameCount--; + else + gTasks[taskId].func = Task_Hof_SetMonDisplayTask; +} + +static void Task_Hof_SetMonDisplayTask(u8 taskId) +{ + gTasks[taskId].func = Task_Hof_DisplayMon; +} + +#define tDestinationX data1 +#define tDestinationY data2 +#define tSpecies data7 + +static void Task_Hof_DisplayMon(u8 taskId) +{ + u8 spriteId; + s16 xPos, yPos, field4, field6; + + u16 currMonId = gTasks[taskId].tDisplayedMonId; + struct HallofFameMon* currMon = &sHofMonPtr->mon[currMonId]; + + if (gTasks[taskId].tMonNumber > 3) + { + xPos = sHallOfFame_MonFullTeamPositions[currMonId][0]; + yPos = sHallOfFame_MonFullTeamPositions[currMonId][1]; + field4 = sHallOfFame_MonFullTeamPositions[currMonId][2]; + field6 = sHallOfFame_MonFullTeamPositions[currMonId][3]; + } + else + { + xPos = sHallOfFame_MonHalfTeamPositions[currMonId][0]; + yPos = sHallOfFame_MonHalfTeamPositions[currMonId][1]; + field4 = sHallOfFame_MonHalfTeamPositions[currMonId][2]; + field6 = sHallOfFame_MonHalfTeamPositions[currMonId][3]; + } + + if (currMon->species == SPECIES_EGG) + field6 += 10; + + spriteId = sub_818D3E4(currMon->species, currMon->tid, currMon->personality, 1, xPos, yPos, currMonId, 0xFFFF); + gSprites[spriteId].tDestinationX = field4; + gSprites[spriteId].tDestinationY = field6; + gSprites[spriteId].data0 = 0; + gSprites[spriteId].tSpecies = currMon->species; + gSprites[spriteId].callback = SpriteCB_GetOnScreenAndAnimate; + gTasks[taskId].tMonSpriteId(currMonId) = spriteId; + sub_8197434(0, 1); + gTasks[taskId].func = Task_Hof_PrintMonInfoAfterAnimating; +} + +static void Task_Hof_PrintMonInfoAfterAnimating(u8 taskId) +{ + u16 currMonId = gTasks[taskId].tDisplayedMonId; + struct HallofFameMon* currMon = &sHofMonPtr->mon[currMonId]; + struct Sprite *monSprite = &gSprites[gTasks[taskId].tMonSpriteId(currMonId)]; + + if (monSprite->callback == SpriteCallbackDummy) + { + monSprite->oam.affineMode = 0; + HallOfFame_PrintMonInfo(currMon, 0, 14); + gTasks[taskId].tFrameCount = 120; + gTasks[taskId].func = Task_Hof_TryDisplayAnotherMon; + } +} + +static void Task_Hof_TryDisplayAnotherMon(u8 taskId) +{ + u16 currPokeID = gTasks[taskId].tDisplayedMonId; + struct HallofFameMon* currMon = &sHofMonPtr->mon[currPokeID]; + + if (gTasks[taskId].tFrameCount != 0) + { + gTasks[taskId].tFrameCount--; + } + else + { + gUnknown_0203BCD4 |= (0x10000 << gSprites[gTasks[taskId].tMonSpriteId(currPokeID)].oam.paletteNum); + if (gTasks[taskId].tDisplayedMonId <= 4 && currMon[1].species != SPECIES_NONE) // there is another pokemon to display + { + gTasks[taskId].tDisplayedMonId++; + BeginNormalPaletteFade(gUnknown_0203BCD4, 0, 12, 12, 0x63B0); + gSprites[gTasks[taskId].tMonSpriteId(currPokeID)].oam.priority = 1; + gTasks[taskId].func = Task_Hof_DisplayMon; + } + else + { + gTasks[taskId].func = Task_Hof_PaletteFadeAndPrintWelcomeText; + } + } +} + +static void Task_Hof_PaletteFadeAndPrintWelcomeText(u8 taskId) +{ + u16 i; + + BeginNormalPaletteFade(0xFFFF0000, 0, 0, 0, 0); + for (i = 0; i < 6; i++) + { + if (gTasks[taskId].tMonSpriteId(i) != 0xFF) + gSprites[gTasks[taskId].tMonSpriteId(i)].oam.priority = 0; + } + + HallOfFame_PrintWelcomeText(0, 15); + PlaySE(SE_DENDOU); + gTasks[taskId].tFrameCount = 400; + gTasks[taskId].func = sub_8173DC0; +} + +static void sub_8173DC0(u8 taskId) +{ + if (gTasks[taskId].tFrameCount != 0) + { + gTasks[taskId].tFrameCount--; + if ((gTasks[taskId].tFrameCount & 3) == 0 && gTasks[taskId].tFrameCount > 110) + sub_81751FC(); + } + else + { + u16 i; + for (i = 0; i < 6; i++) + { + if (gTasks[taskId].tMonSpriteId(i) != 0xFF) + gSprites[gTasks[taskId].tMonSpriteId(i)].oam.priority = 1; + } + BeginNormalPaletteFade(gUnknown_0203BCD4, 0, 12, 12, 0x63B0); + FillWindowPixelBuffer(0, 0); + CopyWindowToVram(0, 3); + gTasks[taskId].tFrameCount = 7; + gTasks[taskId].func = sub_8173EA4; + } +} + +static void sub_8173EA4(u8 taskId) +{ + if (gTasks[taskId].tFrameCount >= 16) + { + gTasks[taskId].func = sub_8173EE4; + } + else + { + gTasks[taskId].tFrameCount++; + SetGpuReg(REG_OFFSET_BLDALPHA, gTasks[taskId].tFrameCount * 256); + } +} + +static void sub_8173EE4(u8 taskId) +{ + SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_ON | DISPCNT_OBJ_1D_MAP); + ShowBg(0); + ShowBg(1); + ShowBg(3); + gTasks[taskId].tPlayerSpriteID = sub_818D8AC(sub_818D97C(gSaveBlock2Ptr->playerGender, 1), 1, 120, 72, 6, 0xFFFF); + AddWindow(&sHof_WindowTemplate); + sub_80987D4(1, gSaveBlock2Ptr->optionsWindowFrameType, 0x21D, 0xD0); + LoadPalette(stdpal_get(1), 0xE0, 0x20); + gTasks[taskId].tFrameCount = 120; + gTasks[taskId].func = Task_Hof_WaitAndPrintPlayerInfo; +} + +static void Task_Hof_WaitAndPrintPlayerInfo(u8 taskId) +{ + if (gTasks[taskId].tFrameCount != 0) + { + gTasks[taskId].tFrameCount--; + } + else if (gSprites[gTasks[taskId].tPlayerSpriteID].pos1.x != 192) + { + gSprites[gTasks[taskId].tPlayerSpriteID].pos1.x++; + } + else + { + FillBgTilemapBufferRect_Palette0(0, 0, 0, 0, 0x20, 0x20); + HallOfFame_PrintPlayerInfo(1, 2); + sub_81973C4(0, 0); + AddTextPrinterParametrized(0, 1, gText_LeagueChamp, 0, NULL, 2, 1, 3); + CopyWindowToVram(0, 3); + gTasks[taskId].func = Task_Hof_ExitOnKeyPressed; + } +} + +static void Task_Hof_ExitOnKeyPressed(u8 taskId) +{ + if (gMain.newKeys & A_BUTTON) + { + FadeOutBGM(4); + gTasks[taskId].func = Task_Hof_HandlePaletteOnExit; + } +} + +static void Task_Hof_HandlePaletteOnExit(u8 taskId) +{ + CpuCopy16(gPlttBufferFaded, gPlttBufferUnfaded, 0x400); + BeginNormalPaletteFade(-1, 8, 0, 0x10, 0); + gTasks[taskId].func = Task_Hof_HandleExit; +} + +static void Task_Hof_HandleExit(u8 taskId) +{ + if (!gPaletteFade.active) + { + s32 i; + + for (i = 0; i < 6; i++) + { + u8 spriteId = gTasks[taskId].tMonSpriteId(i); + if (spriteId != 0xFF) + { + FreeOamMatrix(gSprites[spriteId].oam.matrixNum); + sub_818D820(spriteId); + } + } + + sub_818D8F0(gTasks[taskId].tPlayerSpriteID); + HideBg(0); + HideBg(1); + HideBg(3); + FreeAllWindowBuffers(); + UnsetBgTilemapBuffer(1); + UnsetBgTilemapBuffer(3); + ResetBgsAndClearDma3BusyFlags(0); + DestroyTask(taskId); + + if (sHofGfxPtr != NULL) + FREE_AND_SET_NULL(sHofGfxPtr); + if (sHofMonPtr != NULL) + FREE_AND_SET_NULL(sHofMonPtr); + + SetCallback2AfterHallOfFameDisplay(); + } +} + +static void SetCallback2AfterHallOfFameDisplay(void) +{ + SetMainCallback2(sub_8175620); +} + +#undef tDontSaveData +#undef tDisplayedPoke +#undef tMonNumber +#undef tFrameCount +#undef tPlayerSpriteID +#undef tMonSpriteId + +#define tCurrTeamNo data[0] +#define tCurrPageNo data[1] +#define tCurrMonId data[2] +#define tMonNo data[4] +#define tMonSpriteId(i) data[i + 5] + +void CB2_DoHallOfFamePC(void) +{ + switch (gMain.state) + { + case 0: + default: + SetVBlankCallback(NULL); + ClearVramOamPltt_LoadHofPal(); + sHofGfxPtr = AllocZeroed(sizeof(*sHofGfxPtr)); + gMain.state = 1; + break; + case 1: + sub_8174F70(); + gMain.state++; + break; + case 2: + SetGpuReg(REG_OFFSET_BLDCNT, 0); + SetGpuReg(REG_OFFSET_BLDALPHA, 0); + SetGpuReg(REG_OFFSET_BLDY, 0); + sub_8174FAC(); + gMain.state++; + break; + case 3: + if (!sub_8175024()) + { + struct HallofFameTeam *fameTeam = (struct HallofFameTeam*)(gDecompressionBuffer); + fameTeam->mon[0] = sDummyFameMon; + sub_80F9BCC(0, 0, 0); + SetVBlankCallback(VBlankCB_HallOfFame); + gMain.state++; + } + break; + case 4: + RunTasks(); + AnimateSprites(); + BuildOamBuffer(); + UpdatePaletteFade(); + if (!sub_80F9C1C()) + gMain.state++; + break; + case 5: + { + u8 taskId, i; + + SetGpuReg(REG_OFFSET_BLDCNT, 0x3F42); + SetGpuReg(REG_OFFSET_BLDALPHA, 0x710); + SetGpuReg(REG_OFFSET_BLDY, 0); + taskId = CreateTask(Task_HofPC_CopySaveData, 0); + + for (i = 0; i < 6; i++) + { + gTasks[taskId].tMonSpriteId(i) = 0xFF; + } + + sHofMonPtr = AllocZeroed(0x2000); + SetMainCallback2(CB2_HallOfFame); + } + break; + } +} + +static void Task_HofPC_CopySaveData(u8 taskId) +{ + sub_81980F0(0, 0x1E, 0, 0xC, 0x226); + if (sub_81534D0(3) != 1) + { + gTasks[taskId].func = Task_HofPC_PrintDataIsCorrupted; + } + else + { + u16 i; + struct HallofFameTeam* savedTeams; + + CpuCopy16(gDecompressionBuffer, sHofMonPtr, 0x2000); + savedTeams = sHofMonPtr; + for (i = 0; i < HALL_OF_FAME_MAX_TEAMS; i++, savedTeams++) + { + if (savedTeams->mon[0].species == SPECIES_NONE) + 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(GAME_STAT_ENTERED_HOF); + + gTasks[taskId].func = Task_HofPC_DrawSpritesPrintText; + } +} + +static void Task_HofPC_DrawSpritesPrintText(u8 taskId) +{ + struct HallofFameTeam* savedTeams = sHofMonPtr; + struct HallofFameMon* currMon; + u16 i; + + for (i = 0; i < gTasks[taskId].tCurrTeamNo; i++) + savedTeams++; + + currMon = &savedTeams->mon[0]; + gUnknown_0203BCD4 = 0; + gTasks[taskId].tCurrMonId = 0; + gTasks[taskId].tMonNo = 0; + + for (i = 0; i < 6; i++, currMon++) + { + if (currMon->species != 0) + gTasks[taskId].tMonNo++; + } + + currMon = &savedTeams->mon[0]; + + for (i = 0; i < 6; i++, currMon++) + { + if (currMon->species != 0) + { + u16 spriteId; + s16 posX, posY; + + if (gTasks[taskId].tMonNo > 3) + { + posX = sHallOfFame_MonFullTeamPositions[i][2]; + posY = sHallOfFame_MonFullTeamPositions[i][3]; + } + else + { + posX = sHallOfFame_MonHalfTeamPositions[i][2]; + posY = sHallOfFame_MonHalfTeamPositions[i][3]; + } + + if (currMon->species == SPECIES_EGG) + posY += 10; + + spriteId = sub_818D7D8(currMon->species, currMon->tid, currMon->personality, 1, posX, posY, i, 0xFFFF); + gSprites[spriteId].oam.priority = 1; + gTasks[taskId].tMonSpriteId(i) = spriteId; + } + else + { + gTasks[taskId].tMonSpriteId(i) = 0xFF; + } + } + + BlendPalettes(0xFFFF0000, 0xC, 0x63B0); + + ConvertIntToDecimalStringN(gStringVar1, gTasks[taskId].tCurrPageNo, STR_CONV_MODE_RIGHT_ALIGN, 3); + StringExpandPlaceholders(gStringVar4, gText_HOFNumber); + + if (gTasks[taskId].tCurrTeamNo <= 0) + sub_8198204(gStringVar4, gText_PickCancel, 0, 0, 1); + else + sub_8198204(gStringVar4, gText_PickNextCancel, 0, 0, 1); + + gTasks[taskId].func = Task_HofPC_PrintMonInfo; +} + +static void Task_HofPC_PrintMonInfo(u8 taskId) +{ + struct HallofFameTeam* savedTeams = sHofMonPtr; + 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].tCurrMonId); + gSprites[currMonID].oam.priority = 0; + gUnknown_0203BCD4 = (0x10000 << gSprites[currMonID].oam.paletteNum) ^ 0xFFFF0000; + BlendPalettesUnfaded(gUnknown_0203BCD4, 0xC, 0x63B0); + + currMon = &savedTeams->mon[gTasks[taskId].tCurrMonId]; + if (currMon->species != SPECIES_EGG) + { + StopCryAndClearCrySongs(); + PlayCry1(currMon->species, 0); + } + HallOfFame_PrintMonInfo(currMon, 0, 14); + + gTasks[taskId].func = Task_HofPC_HandleInput; +} + +static void Task_HofPC_HandleInput(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) + { + sub_818D820(spriteId); + gTasks[taskId].tMonSpriteId(i) = 0xFF; + } + } + if (gTasks[taskId].tCurrPageNo != 0) + gTasks[taskId].tCurrPageNo--; + gTasks[taskId].func = Task_HofPC_DrawSpritesPrintText; + } + else // no more teams to view, turn off hall of fame PC + { + if (IsCryPlayingOrClearCrySongs()) + { + StopCryAndClearCrySongs(); + m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 0x100); + } + gTasks[taskId].func = Task_HofPC_HandlePaletteOnExit; + } + } + else if (gMain.newKeys & B_BUTTON) // turn off hall of fame PC + { + if (IsCryPlayingOrClearCrySongs()) + { + StopCryAndClearCrySongs(); + m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 0x100); + } + gTasks[taskId].func = Task_HofPC_HandlePaletteOnExit; + } + else if (gMain.newKeys & DPAD_UP && gTasks[taskId].tCurrMonId != 0) // change mon -1 + { + gTasks[taskId].tCurrMonId--; + gTasks[taskId].func = Task_HofPC_PrintMonInfo; + } + else if (gMain.newKeys & DPAD_DOWN && gTasks[taskId].tCurrMonId < gTasks[taskId].tMonNo - 1) // change mon +1 + { + gTasks[taskId].tCurrMonId++; + gTasks[taskId].func = Task_HofPC_PrintMonInfo; + } +} + +static void Task_HofPC_HandlePaletteOnExit(u8 taskId) +{ + struct HallofFameTeam* fameTeam; + + CpuCopy16(gPlttBufferFaded, gPlttBufferUnfaded, 0x400); + fameTeam = (struct HallofFameTeam*)(gDecompressionBuffer); + fameTeam->mon[0] = sDummyFameMon; + sub_80F9BF4(0, 0, 0); + gTasks[taskId].func = Task_HofPC_HandleExit; +} + +static void Task_HofPC_HandleExit(u8 taskId) +{ + if (!sub_80F9C30()) + { + u8 i; + + for (i = 0; i < 6; i++) + { + u16 spriteId = gTasks[taskId].tMonSpriteId(i); + if (spriteId != 0xFF) + { + sub_818D820(spriteId); + gTasks[taskId].tMonSpriteId(i) = 0xFF; + } + } + + HideBg(0); + HideBg(1); + HideBg(3); + sub_8198314(); + FreeAllWindowBuffers(); + UnsetBgTilemapBuffer(1); + UnsetBgTilemapBuffer(3); + ResetBgsAndClearDma3BusyFlags(0); + DestroyTask(taskId); + + if (sHofGfxPtr != NULL) + FREE_AND_SET_NULL(sHofGfxPtr); + if (sHofMonPtr != NULL) + FREE_AND_SET_NULL(sHofMonPtr); + + sub_8137C3C(); + } +} + +static void Task_HofPC_PrintDataIsCorrupted(u8 taskId) +{ + sub_8198180(gText_UnkCtrlF800Exit, 8, 1); + sub_81973C4(0, 0); + AddTextPrinterParametrized(0, 1, gText_HOFCorrupted, 0, NULL, 2, 1, 3); + CopyWindowToVram(0, 3); + gTasks[taskId].func = Task_HofPC_ExitOnButtonPress; +} + +static void Task_HofPC_ExitOnButtonPress(u8 taskId) +{ + if (gMain.newKeys & A_BUTTON) + gTasks[taskId].func = Task_HofPC_HandlePaletteOnExit; +} + +#undef tCurrTeamNo +#undef tCurrPageNo +#undef tCurrMonId +#undef tMonNo +#undef tMonSpriteId + +static void HallOfFame_PrintWelcomeText(u8 unusedPossiblyWindowId, u8 unused2) +{ + FillWindowPixelBuffer(0, 0); + PutWindowTilemap(0); + box_print(0, 1, GetStringCenterAlignXOffset(1, gText_WelcomeToHOF, 0xD0), 1, gUnknown_085E5388, 0, gText_WelcomeToHOF); + CopyWindowToVram(0, 3); +} + +static void HallOfFame_PrintMonInfo(struct HallofFameMon* currMon, u8 unused1, u8 unused2) +{ + u8 text[30]; + u8 *stringPtr; + s32 dexNumber; + s32 width; + + FillWindowPixelBuffer(0, 0); + PutWindowTilemap(0); + + // dex number + if (currMon->species != SPECIES_EGG) + { + stringPtr = StringCopy(text, gText_Number); + dexNumber = SpeciesToPokedexNum(currMon->species); + if (dexNumber != 0xFFFF) + { + stringPtr[0] = (dexNumber / 100) + CHAR_0; + stringPtr++; + dexNumber %= 100; + stringPtr[0] = (dexNumber / 10) + CHAR_0; + stringPtr++; + stringPtr[0] = (dexNumber % 10) + CHAR_0; + stringPtr++; + } + else + { + *(stringPtr)++ = CHAR_QUESTION_MARK; + *(stringPtr)++ = CHAR_QUESTION_MARK; + *(stringPtr)++ = CHAR_QUESTION_MARK; + } + stringPtr[0] = EOS; + box_print(0, 1, 0x10, 1, gUnknown_085E5388, -1, text); + } + + // nick, species names, gender and level + memcpy(text, currMon->nick, POKEMON_NAME_LENGTH); + text[POKEMON_NAME_LENGTH] = EOS; + if (currMon->species == SPECIES_EGG) + { + width = GetStringCenterAlignXOffset(1, text, 0xD0); + box_print(0, 1, width, 1, gUnknown_085E5388, -1, text); + CopyWindowToVram(0, 3); + } + else + { + width = GetStringRightAlignXOffset(1, text, 0x80); + box_print(0, 1, width, 1, gUnknown_085E5388, -1, text); + + text[0] = CHAR_SLASH; + stringPtr = StringCopy(text + 1, gSpeciesNames[currMon->species]); + + 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] = EOS; + box_print(0, 1, 0x80, 1, gUnknown_085E5388, -1, text); + + stringPtr = StringCopy(text, gText_Level); + ConvertIntToDecimalStringN(stringPtr, currMon->lvl, STR_CONV_MODE_LEFT_ALIGN, 3); + box_print(0, 1, 0x24, 0x11, gUnknown_085E5388, -1, text); + + stringPtr = StringCopy(text, gText_IDNumber); + ConvertIntToDecimalStringN(stringPtr, (u16)(currMon->tid), STR_CONV_MODE_LEADING_ZEROS, 5); + box_print(0, 1, 0x68, 0x11, gUnknown_085E5388, -1, text); + + CopyWindowToVram(0, 3); + } +} + +static void HallOfFame_PrintPlayerInfo(u8 unused1, u8 unused2) +{ + u8 text[20]; + u32 width; + u16 trainerId; + + FillWindowPixelBuffer(1, 0x11); + PutWindowTilemap(1); + SetWindowBorderStyle(1, FALSE, 0x21D, 0xD); + box_print(1, 1, 0, 1, gUnknown_085E538C, -1, gText_Name); + + width = GetStringRightAlignXOffset(1, gSaveBlock2Ptr->playerName, 0x70); + box_print(1, 1, width, 1, gUnknown_085E538C, -1, gSaveBlock2Ptr->playerName); + + trainerId = (gSaveBlock2Ptr->playerTrainerId[0]) | (gSaveBlock2Ptr->playerTrainerId[1] << 8); + box_print(1, 1, 0, 0x11, gUnknown_085E538C, 0, gText_IDNumber); + text[0] = (trainerId % 100000) / 10000 + CHAR_0; + text[1] = (trainerId % 10000) / 1000 + CHAR_0; + text[2] = (trainerId % 1000) / 100 + CHAR_0; + text[3] = (trainerId % 100) / 10 + CHAR_0; + text[4] = (trainerId % 10) / 1 + CHAR_0; + text[5] = EOS; + width = GetStringRightAlignXOffset(1, text, 0x70); + box_print(1, 1, width, 0x11, gUnknown_085E538C, -1, text); + + box_print(1, 1, 0, 0x21, gUnknown_085E538C, -1, gText_MainMenuTime); + text[0] = (gSaveBlock2Ptr->playTimeHours / 100) + CHAR_0; + text[1] = (gSaveBlock2Ptr->playTimeHours % 100) / 10 + CHAR_0; + text[2] = (gSaveBlock2Ptr->playTimeHours % 10) + CHAR_0; + + if (text[0] == CHAR_0) + text[0] = CHAR_SPACE; + if (text[0] == CHAR_SPACE && text[1] == CHAR_0) + text[8] = CHAR_SPACE; + + text[3] = CHAR_COLON; + text[4] = (gSaveBlock2Ptr->playTimeMinutes % 100) / 10 + CHAR_0; + text[5] = (gSaveBlock2Ptr->playTimeMinutes % 10) + CHAR_0; + text[6] = EOS; + + width = GetStringRightAlignXOffset(1, text, 0x70); + box_print(1, 1, width, 0x21, gUnknown_085E538C, -1, text); + + CopyWindowToVram(1, 3); +} + +static void ClearVramOamPltt_LoadHofPal(void) +{ + u32 vramOffset, oamOffset, plttOffset; + u32 vramSize, oamSize, plttSize; + + vramOffset = (VRAM); + vramSize = VRAM_SIZE; + while (TRUE) + { + DmaFill16(3, 0, vramOffset, 0x1000); + vramOffset += 0x1000; + vramSize -= 0x1000; + if (vramSize <= 0x1000) + { + DmaFill16(3, 0, vramOffset, vramSize); + break; + } + } + + oamOffset = OAM; + oamSize = OAM_SIZE; + DmaFill32(3, 0, oamOffset, oamSize); + + plttOffset = PLTT; + plttSize = PLTT_SIZE; + DmaFill16(3, 0, plttOffset, plttSize); + + ResetPaletteFade(); + LoadPalette(sHallOfFame_Pal, 0, 0x20); +} + +static void sub_8174F70(void) +{ + remove_some_task(); + ResetTasks(); + ResetSpriteData(); + reset_temp_tile_data_buffers(); + dp13_810BB8C(); + FreeAllSpritePalettes(); + gReservedSpritePaletteCount = 8; + LoadCompressedObjectPic(&sHallOfFame_ConfettiSpriteSheet); + LoadCompressedObjectPalette(&sHallOfFame_ConfettiSpritePalette); +} + +static void sub_8174FAC(void) +{ + ResetBgsAndClearDma3BusyFlags(0); + InitBgsFromTemplates(0, sHof_BgTemplates, ARRAY_COUNT(sHof_BgTemplates)); + SetBgTilemapBuffer(1, sHofGfxPtr->tilemap1); + SetBgTilemapBuffer(3, sHofGfxPtr->tilemap2); + ChangeBgX(0, 0, 0); + ChangeBgY(0, 0, 0); + ChangeBgX(1, 0, 0); + ChangeBgY(1, 0, 0); + ChangeBgX(3, 0, 0); + ChangeBgY(3, 0, 0); +} + +static bool8 sub_8175024(void) +{ + switch (sHofGfxPtr->state) + { + case 0: + decompress_and_copy_tile_data_to_vram(1, sHallOfFame_Gfx, 0, 0, 0); + break; + case 1: + if (free_temp_tile_data_buffers_if_possible()) + return TRUE; + break; + case 2: + FillBgTilemapBufferRect_Palette0(1, 1, 0, 0, 0x20, 2); + FillBgTilemapBufferRect_Palette0(1, 0, 0, 3, 0x20, 0xB); + FillBgTilemapBufferRect_Palette0(1, 1, 0, 0xE, 0x20, 6); + FillBgTilemapBufferRect_Palette0(3, 2, 0, 0, 0x20, 0x20); + + CopyBgTilemapBufferToVram(1); + CopyBgTilemapBufferToVram(3); + break; + case 3: + sub_81971D0(); + sub_8197200(); + break; + case 4: + SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_1D_MAP | DISPCNT_OBJ_ON); + ShowBg(0); + ShowBg(1); + ShowBg(3); + sHofGfxPtr->state = 0; + return FALSE; + } + + sHofGfxPtr->state++; + return TRUE; +} + +static void SpriteCB_GetOnScreenAndAnimate(struct Sprite *sprite) +{ + if (sprite->pos1.x != sprite->tDestinationX + || sprite->pos1.y != sprite->tDestinationY) + { + if (sprite->pos1.x < sprite->tDestinationX) + sprite->pos1.x += 15; + if (sprite->pos1.x > sprite->tDestinationX) + sprite->pos1.x -= 15; + + if (sprite->pos1.y < sprite->tDestinationY) + sprite->pos1.y += 10; + if (sprite->pos1.y > sprite->tDestinationY) + sprite->pos1.y -= 10; + } + else + { + s16 species = sprite->tSpecies; + + if (species == SPECIES_EGG) + DoMonFrontSpriteAnimation(sprite, species, TRUE, 3); + else + DoMonFrontSpriteAnimation(sprite, species, FALSE, 3); + } +} + +#undef tDestinationX +#undef tDestinationY +#undef tSpecies + +static void sub_81751A4(struct Sprite* sprite) +{ + if (sprite->pos2.y > 120) + { + DestroySprite(sprite); + } + else + { + u16 rand; + u8 tableID; + + sprite->pos2.y++; + sprite->pos2.y += sprite->data1; + + tableID = sprite->data0; + rand = (Random() % 4) + 8; + sprite->pos2.x = rand * gSineTable[tableID] / 256; + + sprite->data0 += 4; + } +} + +static bool8 sub_81751FC(void) +{ + u8 spriteID; + struct Sprite* sprite; + + s16 posX = Random() % 240; + s16 posY = -(Random() % 8); + + spriteID = CreateSprite(&sSpriteTemplate_85E54D0, posX, posY, 0); + sprite = &gSprites[spriteID]; + + StartSpriteAnim(sprite, Random() % 17); + + if (Random() & 3) + sprite->data1 = 0; + else + sprite->data1 = 1; + + return FALSE; +} + +void sub_8175280(void) +{ + u8 taskId; + + gSpecialVar_0x8004 = 180; + taskId = CreateTask(sub_8175364, 0); + if (taskId != 0xFF) + { + gTasks[taskId].data[1] = gSpecialVar_0x8004; + gSpecialVar_0x8005 = taskId; + } +} + +static void sub_81752C0(void) +{ + u8 taskId; + + if ((taskId = FindTaskIdByFunc(sub_8175364)) != 0xFF) + DestroyTask(taskId); + + sub_8152254(); + FreeSpriteTilesByTag(0x3E9); + FreeSpritePaletteByTag(0x3E9); +} + +struct UnknownStruct912B4 +{ + s16 field_0; + s16 field_2; + s16 field_4; + s16 field_6; + s16 field_8; + s16 field_A; + s16 field_C; + s16 field_E; + s16 field_10; + s16 field_12; + s16 field_14; + s16 field_16; + s16 field_18; + s16 field_1A; + s16 field_1C; + s16 field_1E; + s16 field_20; + s16 field_22; + s16 field_24; + s16 field_26; + s16 field_28; +}; + +static void sub_81752F4(struct UnknownStruct912B4 *unkStruct) +{ + if (unkStruct->field_E > 110) + { + gTasks[unkStruct->field_28].data[15]--; + sub_81525D0(unkStruct->field_16); + } + else + { + u8 var; + s32 rand; + + unkStruct->field_E++; + unkStruct->field_E += unkStruct->field_1C; + + var = unkStruct->field_1A; + rand = Random(); + rand &= 3; + rand += 8; + unkStruct->field_C = (rand) * ((gSineTable[var])) / 256; + + unkStruct->field_1A += 4; + } +} + +static void sub_8175364(u8 taskId) +{ + u32 var = 0; + u16 *data = gTasks[taskId].data; + + switch (data[0]) + { + case 0: + if (!sub_81521C0(0x40)) + { + DestroyTask(taskId); + gSpecialVar_0x8004 = var; + gSpecialVar_0x8005 = 0xFFFF; + } + LoadCompressedObjectPic(&sHallOfFame_ConfettiSpriteSheet); + LoadCompressedObjectPalette(&sHallOfFame_ConfettiSpritePalette); + data[0]++; + break; + case 1: + if (data[1] != 0 && data[1] % 3 == 0) + { + var = sub_81524C4(&sOamData_85E53FC, 0x3E9, 0x3E9, Random() % 240, -(Random() % 8), Random() % 0x11, var); + if (var != 0xFF) + { + sub_8152438(var, sub_81752F4); + if ((Random() & 3) == 0) + sub_8152474(var, 1, 1); + sub_8152474(var, 7, taskId); + data[15]++; + } + } + sub_81522D4(); + if (data[1] != 0) + data[1]--; + else if (data[15] == 0) + data[0] = 0xFF; + break; + case 0xFF: + sub_81752C0(); + gSpecialVar_0x8004 = var; + gSpecialVar_0x8005 = 0xFFFF; + break; + } +} diff --git a/src/mail.c b/src/mail.c index 1060d73bd..1ceb1be1a 100644 --- a/src/mail.c +++ b/src/mail.c @@ -386,7 +386,7 @@ bool8 sub_81215EC(void) CopyBgTilemapBufferToVram(2); break; case 12: - LoadPalette(sub_8098C64(), 240, 32); + LoadPalette(GetOverworldTextboxPalettePtr(), 240, 32); gPlttBufferUnfaded[250] = gUnknown_0859F2B8[gUnknown_0203A134->mailType].color10; gPlttBufferFaded[250] = gUnknown_0859F2B8[gUnknown_0203A134->mailType].color10; gPlttBufferUnfaded[251] = gUnknown_0859F2B8[gUnknown_0203A134->mailType].color12; diff --git a/src/starter_choose.c b/src/starter_choose.c new file mode 100644 index 000000000..1f64a5db7 --- /dev/null +++ b/src/starter_choose.c @@ -0,0 +1,391 @@ +#include "global.h" +#include "starter_choose.h" +#include "palette.h" +#include "sprite.h" +#include "pokemon.h" +#include "task.h" +#include "bg.h" +#include "gpu_regs.h" +#include "main.h" +#include "window.h" +#include "text.h" +#include "decompress.h" +#include "menu.h" +#include "sound.h" +#include "songs.h" +#include "event_data.h" +#include "pokedex.h" +#include "data2.h" +#include "international_string_util.h" +#include "trig.h" + +#define STARTER_MON_COUNT 3 + +// Position of the sprite of the selected starter Pokemon +#define STARTER_PKMN_POS_X 120 +#define STARTER_PKMN_POS_Y 64 + +// graphics +extern const u32 gBirchHelpGfx[]; +extern const u32 gBirchBagTilemap[]; +extern const u32 gBirchGrassTilemap[]; +extern const u16 gBirchBagGrassPal[]; + +// text +extern const u8 gText_BirchInTrouble[]; +extern const u8 gText_ConfirmStarterChoice[]; + +extern const u16 sStarterMon[STARTER_MON_COUNT]; +extern const struct BgTemplate gUnknown_085B1E00[3]; +extern const struct WindowTemplate gUnknown_085B1DCC[]; +extern const struct WindowTemplate gUnknown_085B1DDC; +extern const struct CompressedSpriteSheet gUnknown_085B1ED8[]; +extern const struct CompressedSpriteSheet gUnknown_085B1EE8[]; +extern const struct SpritePalette gUnknown_085B1EF8[]; +extern const struct SpriteTemplate sSpriteTemplate_PokeBall; +extern const struct SpriteTemplate sSpriteTemplate_Hand; +extern const struct SpriteTemplate gUnknown_085B1F40; +extern const union AffineAnimCmd *const gUnknown_085B1ED0; +extern const u8 sPokeballCoords[STARTER_MON_COUNT][2]; +extern const struct WindowTemplate gUnknown_085B1DE4; +extern const u8 gStarterChoose_LabelCoords[][2]; +extern const u8 gUnknown_085B1E0C[]; +extern const u8 gUnknown_085B1E28[][2]; + +extern void sub_809882C(u8, u16, u8); +extern void remove_some_task(void); +extern void clear_scheduled_bg_copies_to_vram(void); +extern void dp13_810BB8C(void); +extern void do_scheduled_bg_tilemap_copies_to_vram(void); +extern u16 sub_818D820(u16); +extern const u16 *GetOverworldTextboxPalettePtr(void); +extern u8 sub_818D3E4(u16 species, u32 trainerId, u32 personality, u8 flags, s16 x, s16 y, u8, u16); + +// this file's functions +static void MainCallback2_StarterChoose(void); +static void sub_8134604(void); +static void Task_StarterChoose1(u8 taskId); +static void Task_StarterChoose2(u8 taskId); +static void Task_StarterChoose3(u8 taskId); +static void Task_StarterChoose4(u8 taskId); +static void Task_StarterChoose5(u8 taskId); +static void Task_StarterChoose6(u8 taskId); +static void Task_MoveStarterChooseCursor(u8 taskId); +static void sub_8134668(u8 taskId); +static void CreateStarterPokemonLabel(u8 selection); +static u8 CreatePokemonFrontSprite(u16 species, u8 x, u8 y); +static void StarterPokemonSpriteCallback(struct Sprite *sprite); + +static IWRAM_DATA u16 sStarterChooseWindowId; + +u16 GetStarterPokemon(u16 chosenStarterId) +{ + if (chosenStarterId > STARTER_MON_COUNT) + chosenStarterId = 0; + return sStarterMon[chosenStarterId]; +} + +static void VblankCB_StarterChoose(void) +{ + LoadOam(); + ProcessSpriteCopyRequests(); + TransferPlttBuffer(); +} + +#define tStarterSelection data[0] +#define tPkmnSpriteId data[1] +#define tCircleSpriteId data[2] + +void CB2_ChooseStarter(void) +{ + u16 savedIme; + u8 taskId; + u8 spriteId; + + SetVBlankCallback(NULL); + + SetGpuReg(REG_OFFSET_DISPCNT, 0); + SetGpuReg(REG_OFFSET_BG3CNT, 0); + SetGpuReg(REG_OFFSET_BG2CNT, 0); + SetGpuReg(REG_OFFSET_BG1CNT, 0); + SetGpuReg(REG_OFFSET_BG0CNT, 0); + + ChangeBgX(0, 0, 0); + ChangeBgY(0, 0, 0); + ChangeBgX(1, 0, 0); + ChangeBgY(1, 0, 0); + ChangeBgX(2, 0, 0); + ChangeBgY(2, 0, 0); + ChangeBgX(3, 0, 0); + ChangeBgY(3, 0, 0); + + DmaFill16(3, 0, VRAM, VRAM_SIZE); + DmaFill32(3, 0, OAM, OAM_SIZE); + DmaFill16(3, 0, PLTT, PLTT_SIZE); + + LZ77UnCompVram(&gBirchHelpGfx, (void *)VRAM); + LZ77UnCompVram(&gBirchBagTilemap, (void *)(VRAM + 0x3000)); + LZ77UnCompVram(&gBirchGrassTilemap, (void *)(VRAM + 0x3800)); + + ResetBgsAndClearDma3BusyFlags(0); + InitBgsFromTemplates(0, gUnknown_085B1E00, ARRAY_COUNT(gUnknown_085B1E00)); + InitWindows(gUnknown_085B1DCC); + + DeactivateAllTextPrinters(); + sub_809882C(0, 0x2A8, 0xD0); + clear_scheduled_bg_copies_to_vram(); + remove_some_task(); + ResetTasks(); + ResetSpriteData(); + ResetPaletteFade(); + FreeAllSpritePalettes(); + dp13_810BB8C(); + + LoadPalette(GetOverworldTextboxPalettePtr(), 0xE0, 0x20); + LoadPalette(gBirchBagGrassPal, 0, 0x40); + LoadCompressedObjectPic(&gUnknown_085B1ED8[0]); + LoadCompressedObjectPic(&gUnknown_085B1EE8[0]); + LoadSpritePalettes(gUnknown_085B1EF8); + BeginNormalPaletteFade(-1, 0, 0x10, 0, 0); + + EnableInterrupts(DISPSTAT_VBLANK); + SetVBlankCallback(VblankCB_StarterChoose); + SetMainCallback2(MainCallback2_StarterChoose); + + SetGpuReg(REG_OFFSET_WININ, 0x3F); + SetGpuReg(REG_OFFSET_WINOUT, 0x1F); + SetGpuReg(REG_OFFSET_WIN0H, 0); + SetGpuReg(REG_OFFSET_WIN0V, 0); + SetGpuReg(REG_OFFSET_BLDCNT, 0xFE); + SetGpuReg(REG_OFFSET_BLDALPHA, 0); + SetGpuReg(REG_OFFSET_BLDY, 7); + SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_WIN0_ON | DISPCNT_OBJ_ON | DISPCNT_OBJ_1D_MAP); + + ShowBg(0); + ShowBg(2); + ShowBg(3); + + taskId = CreateTask(Task_StarterChoose1, 0); + gTasks[taskId].tStarterSelection = 1; + + // Create hand sprite + spriteId = CreateSprite(&sSpriteTemplate_Hand, 120, 56, 2); + gSprites[spriteId].data0 = taskId; + + // Create three Pokeball sprites + spriteId = CreateSprite(&sSpriteTemplate_PokeBall, sPokeballCoords[0][0], sPokeballCoords[0][1], 2); + gSprites[spriteId].data0 = taskId; + gSprites[spriteId].data1 = 0; + + spriteId = CreateSprite(&sSpriteTemplate_PokeBall, sPokeballCoords[1][0], sPokeballCoords[1][1], 2); + gSprites[spriteId].data0 = taskId; + gSprites[spriteId].data1 = 1; + + spriteId = CreateSprite(&sSpriteTemplate_PokeBall, sPokeballCoords[2][0], sPokeballCoords[2][1], 2); + gSprites[spriteId].data0 = taskId; + gSprites[spriteId].data1 = 2; + + sStarterChooseWindowId = 0xFF; +} + +static void MainCallback2_StarterChoose(void) +{ + RunTasks(); + AnimateSprites(); + BuildOamBuffer(); + do_scheduled_bg_tilemap_copies_to_vram(); + UpdatePaletteFade(); +} + +static void Task_StarterChoose1(u8 taskId) +{ + CreateStarterPokemonLabel(gTasks[taskId].tStarterSelection); + SetWindowBorderStyle(0, FALSE, 0x2A8, 0xD); + PrintTextOnWindow(0, 1, gText_BirchInTrouble, 0, 1, 0, NULL); + PutWindowTilemap(0); + schedule_bg_copy_tilemap_to_vram(0); + gTasks[taskId].func = Task_StarterChoose2; +} + +static void Task_StarterChoose2(u8 taskId) +{ + u8 selection = gTasks[taskId].tStarterSelection; + + if (gMain.newKeys & A_BUTTON) + { + u8 spriteId; + + sub_8134604(); + + // Create white circle background + spriteId = CreateSprite(&gUnknown_085B1F40, sPokeballCoords[selection][0], sPokeballCoords[selection][1], 1); + gTasks[taskId].tCircleSpriteId = spriteId; + + // Create Pokemon sprite + spriteId = CreatePokemonFrontSprite(GetStarterPokemon(gTasks[taskId].tStarterSelection), sPokeballCoords[selection][0], sPokeballCoords[selection][1]); + gSprites[spriteId].affineAnims = &gUnknown_085B1ED0; + gSprites[spriteId].callback = StarterPokemonSpriteCallback; + + gTasks[taskId].tPkmnSpriteId = spriteId; + gTasks[taskId].func = Task_StarterChoose3; + } + else if ((gMain.newKeys & DPAD_LEFT) && selection > 0) + { + gTasks[taskId].tStarterSelection--; + gTasks[taskId].func = Task_MoveStarterChooseCursor; + } + else if ((gMain.newKeys & DPAD_RIGHT) && selection < (STARTER_MON_COUNT - 1)) + { + gTasks[taskId].tStarterSelection++; + gTasks[taskId].func = Task_MoveStarterChooseCursor; + } +} + +static void Task_StarterChoose3(u8 taskId) +{ + if (gSprites[gTasks[taskId].tCircleSpriteId].affineAnimEnded && + gSprites[gTasks[taskId].tCircleSpriteId].pos1.x == STARTER_PKMN_POS_X && + gSprites[gTasks[taskId].tCircleSpriteId].pos1.y == STARTER_PKMN_POS_Y) + { + gTasks[taskId].func = Task_StarterChoose4; + } +} + +static void Task_StarterChoose4(u8 taskId) +{ + PlayCry1(GetStarterPokemon(gTasks[taskId].tStarterSelection), 0); + FillWindowPixelBuffer(0, 0x11); + PrintTextOnWindow(0, 1, gText_ConfirmStarterChoice, 0, 1, 0, NULL); + schedule_bg_copy_tilemap_to_vram(0); + CreateYesNoMenu(&gUnknown_085B1DDC, 0x2A8, 0xD, 0); + gTasks[taskId].func = Task_StarterChoose5; +} + +static void Task_StarterChoose5(u8 taskId) +{ + u8 spriteId; + + switch (sub_8198C58()) + { + case 0: // YES + // Return the starter choice and exit. + gScriptResult = gTasks[taskId].tStarterSelection; + dp13_810BB8C(); + SetMainCallback2(gMain.savedCallback); + break; + case 1: // NO + case -1: // B button + PlaySE(SE_SELECT); + spriteId = gTasks[taskId].tPkmnSpriteId; + FreeOamMatrix(gSprites[spriteId].oam.matrixNum); + sub_818D820(spriteId); + + spriteId = gTasks[taskId].tCircleSpriteId; + FreeOamMatrix(gSprites[spriteId].oam.matrixNum); + DestroySprite(&gSprites[spriteId]); + gTasks[taskId].func = Task_StarterChoose6; + break; + } +} + +static void Task_StarterChoose6(u8 taskId) +{ + gTasks[taskId].func = Task_StarterChoose1; +} + +static void CreateStarterPokemonLabel(u8 selection) +{ + u8 text[32]; + struct WindowTemplate winTemplate; + const u8 *speciesName; + s32 width; + u8 labelLeft, labelRight, labelTop, labelBottom; + + u16 species = GetStarterPokemon(selection); + CopyMonCategoryText(SpeciesToNationalPokedexNum(species), text); + speciesName = gSpeciesNames[species]; + + winTemplate = gUnknown_085B1DE4; + winTemplate.tilemapLeft = gStarterChoose_LabelCoords[selection][0]; + winTemplate.tilemapTop = gStarterChoose_LabelCoords[selection][1]; + + sStarterChooseWindowId = AddWindow(&winTemplate); + FillWindowPixelBuffer(sStarterChooseWindowId, 0); + + width = GetStringCenterAlignXOffset(7, text, 0x68); + box_print(sStarterChooseWindowId, 7, width, 1, gUnknown_085B1E0C, 0, text); + + width = GetStringCenterAlignXOffset(1, speciesName, 0x68); + box_print(sStarterChooseWindowId, 1, width, 0x11, gUnknown_085B1E0C, 0, speciesName); + + PutWindowTilemap(sStarterChooseWindowId); + schedule_bg_copy_tilemap_to_vram(0); + + labelLeft = gStarterChoose_LabelCoords[selection][0] * 8 - 4; + labelRight = (gStarterChoose_LabelCoords[selection][0] + 13) * 8 + 4; + labelTop = gStarterChoose_LabelCoords[selection][1] * 8; + labelBottom = (gStarterChoose_LabelCoords[selection][1] + 4) * 8; + SetGpuReg(REG_OFFSET_WIN0H, WIN_RANGE(labelLeft, labelRight)); + SetGpuReg(REG_OFFSET_WIN0V, WIN_RANGE(labelTop, labelBottom)); +} + +static void sub_8134604(void) +{ + FillWindowPixelBuffer(sStarterChooseWindowId, 0); + ClearWindowTilemap(sStarterChooseWindowId); + RemoveWindow(sStarterChooseWindowId); + sStarterChooseWindowId = 0xFF; + SetGpuReg(REG_OFFSET_WIN0H, 0); + SetGpuReg(REG_OFFSET_WIN0V, 0); + schedule_bg_copy_tilemap_to_vram(0); +} + +static void Task_MoveStarterChooseCursor(u8 taskId) +{ + sub_8134604(); + gTasks[taskId].func = sub_8134668; +} + +static void sub_8134668(u8 taskId) +{ + CreateStarterPokemonLabel(gTasks[taskId].tStarterSelection); + gTasks[taskId].func = Task_StarterChoose2; +} + +static u8 CreatePokemonFrontSprite(u16 species, u8 x, u8 y) +{ + u8 spriteId; + + spriteId = sub_818D3E4(species, 8, 0, 1, x, y, 0xE, 0xFFFF); + gSprites[spriteId].oam.priority = 0; + return spriteId; +} + +static void sub_81346DC(struct Sprite *sprite) +{ + sprite->pos1.x = gUnknown_085B1E28[gTasks[sprite->data0].tStarterSelection][0]; + sprite->pos1.y = gUnknown_085B1E28[gTasks[sprite->data0].tStarterSelection][1]; + sprite->pos2.y = Sin(sprite->data1, 8); + sprite->data1 = (u8)(sprite->data1) + 4; +} + +static void sub_813473C(struct Sprite *sprite) +{ + if (gTasks[sprite->data0].tStarterSelection == sprite->data1) + StartSpriteAnimIfDifferent(sprite, 1); + else + StartSpriteAnimIfDifferent(sprite, 0); +} + +static void StarterPokemonSpriteCallback(struct Sprite *sprite) +{ + //Move sprite to upper center of screen + if (sprite->pos1.x > STARTER_PKMN_POS_X) + sprite->pos1.x -= 4; + if (sprite->pos1.x < STARTER_PKMN_POS_X) + sprite->pos1.x += 4; + if (sprite->pos1.y > STARTER_PKMN_POS_Y) + sprite->pos1.y -= 2; + if (sprite->pos1.y < STARTER_PKMN_POS_Y) + sprite->pos1.y += 2; +} diff --git a/src/text_window.c b/src/text_window.c index 55aedf688..336536c04 100644 --- a/src/text_window.c +++ b/src/text_window.c @@ -23,7 +23,7 @@ const struct TilesPal* sub_8098758(u8 id) void copy_textbox_border_tile_patterns_to_vram(u8 windowId, u16 destOffset, u8 palOffset) { LoadBgTiles(GetWindowAttribute(windowId, WINDOW_PRIORITY), gUnknown_08DDD748, 0x1C0, destOffset); - LoadPalette(sub_8098C64(), palOffset, 0x20); + LoadPalette(GetOverworldTextboxPalettePtr(), palOffset, 0x20); } void box_border_load_tiles_and_pal(u8 windowId, u16 destOffset, u8 palOffset) @@ -113,7 +113,7 @@ const u16* stdpal_get(u8 id) return &gUnknown_0851017C[id]; } -const u16* sub_8098C64(void) +const u16* GetOverworldTextboxPalettePtr(void) { return gUnknown_08DDD728; } |