#include "global.h" #include "gflib.h" #include "constants/songs.h" #include "event_data.h" #include "event_scripts.h" #include "graphics.h" #include "battle.h" #include "battle_setup.h" #include "menu.h" #include "trainer_pokemon_sprites.h" #include "scanline_effect.h" #include "new_menu_helpers.h" #include "item_menu.h" #include "list_menu.h" #include "task.h" #include "event_object_movement.h" #include "menu_indicators.h" #include "text_window.h" #include "fame_checker.h" #include "strings.h" #include "constants/event_objects.h" #define SPRITETAG_SELECTOR_CURSOR 1000 #define SPRITETAG_QUESTION_MARK 1001 #define SPRITETAG_SPINNING_POKEBALL 1002 #define SPRITETAG_SCROLL_INDICATORS 1004 #define SPRITETAG_DAISY 1006 // TODO: Investigate, seems to be used for other NPCs (e.g. Fan Club Chairman) #define SPRITETAG_FUJI 1007 #define SPRITETAG_OAK 1008 #define SPRITETAG_BILL 1009 #define FC_NONTRAINER_START 0xFE00 struct FameCheckerData { MainCallback savedCallback; u16 listMenuTopIdx; u8 scrollIndicatorPairTaskId; u8 personHasUnlockedPanels:1; u8 inPickMode:1; u8 numUnlockedPersons:6; u8 listMenuTaskId; u8 listMenuCurIdx; u8 listMenuTopIdx2; u8 listMenuDrawnSelIdx; u8 unlockedPersons[NUM_FAMECHECKER_PERSONS + 1]; u8 spriteIds[6]; u8 viewingFlavorText:1; u8 unk_23_1:1; // unused u8 pickModeOverCancel:1; }; static EWRAM_DATA u16 * sBg3TilemapBuffer = NULL; static EWRAM_DATA u16 * sBg1TilemapBuffer = NULL; static EWRAM_DATA u16 * sBg2TilemapBuffer = NULL; static EWRAM_DATA struct FameCheckerData * sFameCheckerData = NULL; static EWRAM_DATA struct ListMenuItem * sListMenuItems = NULL; static EWRAM_DATA s32 sLastMenuIdx = 0; struct ListMenuTemplate gFameChecker_ListMenuTemplate; u8 gIconDescriptionBoxIsOpen; static void MainCB2_LoadFameChecker(void); static void LoadUISpriteSheetsAndPalettes(void); static void Task_WaitFadeOnInit(u8 taskId); static void Task_TopMenuHandleInput(u8 taskId); static bool8 TryExitPickMode(u8 taskId); static void MessageBoxPrintEmptyText(void); static void Task_EnterPickMode(u8 taskId); static void Task_ExitPickMode(u8 taskId); static void Task_FlavorTextDisplayHandleInput(u8 taskId); static void FC_MoveSelectorCursor(u8 taskId, s8 dx, s8 dy); static void GetPickModeText(void); static void PrintSelectedNameInBrightGreen(u8 taskId); static void WipeMsgBoxAndTransfer(void); static void Setup_DrawMsgAndListBoxes(void); static void FC_PutWindowTilemapAndCopyWindowToVramMode3(u8 windowId); static bool8 SetMessageSelectorIconObjMode(u8 taskId, u8 objMode); static void Task_StartToCloseFameChecker(u8 taskId); static void Task_DestroyAssetsAndCloseFameChecker(u8 taskId); static void FC_DestroyWindow(u8 windowId); static void PrintUIHelp(u8 state); static bool8 CreateAllFlavorTextIcons(u8 who); static void FCSetup_ClearVideoRegisters(void); static void FCSetup_ResetTasksAndSpriteResources(void); static void FCSetup_TurnOnDisplay(void); static void FCSetup_ResetBGCoords(void); static bool8 HasUnlockedAllFlavorTextsForCurrentPerson(void); static void FreeSelectionCursorSpriteResources(void); static u8 CreateFlavorTextIconSelectorCursorSprite(s16 where); static void SpriteCB_DestroyFlavorTextIconSelectorCursor(struct Sprite *sprite); static void FreeQuestionMarkSpriteResources(void); static u8 PlaceQuestionMarkTile(u8 x, u8 y); static void FreeSpinningPokeballSpriteResources(void); static u8 CreateSpinningPokeballSprite(void); static void SpriteCB_DestroySpinningPokeball(struct Sprite *sprite); static void FreeNonTrainerPicTiles(void); static u8 CreatePersonPicSprite(u8 fcPersonIdx); static void DestroyPersonPicSprite(u8 taskId, u16 who); static void UpdateIconDescriptionBox(u8 whichText); static void UpdateIconDescriptionBoxOff(void); static void FC_CreateListMenu(void); static void SpriteCB_FCSpinningPokeball(struct Sprite * sprite); static void InitListMenuTemplate(void); static void FC_MoveCursorFunc(s32 itemIndex, bool8 onInit, struct ListMenu * list); static void Task_SwitchToPickMode(u8 taskId); static void PrintCancelDescription(void); static void FC_DoMoveCursor(s32 itemIndex, bool8 onInit); static u8 FC_PopulateListMenu(void); static void FC_PutWindowTilemapAndCopyWindowToVramMode3_2(u8 windowId); static void FC_CreateScrollIndicatorArrowPair(void); static void FreeListMenuSelectorArrowPairResources(void); static u16 FameCheckerGetCursorY(void); static void HandleFlavorTextModeSwitch(bool8 state); static void Task_FCOpenOrCloseInfoBox(u8 taskId); static void UpdateInfoBoxTilemap(u8 bg, s16 state); static void PlaceListMenuCursor(bool8 isActive); static const u16 sFameCheckerTilemap[] = INCBIN_U16("graphics/fame_checker/tilemap1.bin"); static const u8 sQuestionMarkSpriteGfx[] = INCBIN_U8("graphics/fame_checker/question_mark.4bpp"); static const u8 sSpinningPokeballSpriteGfx[] = INCBIN_U8("graphics/fame_checker/spinning_pokeball.4bpp"); static const u16 sSpinningPokeballSpritePalette[] = INCBIN_U16("graphics/fame_checker/spinning_pokeball.gbapal"); static const u8 sSelectorCursorSpriteGfx[] = INCBIN_U8("graphics/fame_checker/cursor.4bpp"); static const u16 sSelectorCursorSpritePalette[] = INCBIN_U16("graphics/fame_checker/cursor.gbapal"); static const u8 sFujiSpriteGfx[] = INCBIN_U8("graphics/fame_checker/mr_fuji.4bpp"); static const u16 sFujiSpritePalette[] = INCBIN_U16("graphics/fame_checker/mr_fuji.gbapal"); static const u8 sBillSpriteGfx[] = INCBIN_U8("graphics/fame_checker/bill.4bpp"); static const u16 sBillSpritePalette[] = INCBIN_U16("graphics/fame_checker/bill.gbapal"); static const u8 sDaisySpriteGfx[] = INCBIN_U8("graphics/fame_checker/daisy.4bpp"); static const u16 sDaisySpritePalette[] = INCBIN_U16("graphics/fame_checker/daisy.gbapal"); static const u8 sOakSpriteGfx[] = INCBIN_U8("graphics/fame_checker/prof_oak.4bpp"); static const u16 sOakSpritePalette[] = INCBIN_U16("graphics/fame_checker/prof_oak.gbapal"); static const u16 sUnkPalette[] = INCBIN_U16("graphics/fame_checker/unk.gbapal"); // unused? static const u16 sSilhouettePalette[] = INCBIN_U16("graphics/fame_checker/silhouette.gbapal"); static const u8 sTextColor_White[3] = {0, 1, 2}; static const u8 sTextColor_DkGrey[3] = {0, 2, 3}; static const u8 sTextColor_Green[3] = {0, 6, 7}; #define FAME_CHECKER_PROF_OAK (FC_NONTRAINER_START + 0) #define FAME_CHECKER_DAISY_OAK (FC_NONTRAINER_START + 1) #define FAME_CHECKER_BILL (FC_NONTRAINER_START + 2) #define FAME_CHECKER_MR_FUJI (FC_NONTRAINER_START + 3) static const u16 sTrainerIdxs[] = { [FAMECHECKER_OAK] = FAME_CHECKER_PROF_OAK, [FAMECHECKER_DAISY] = FAME_CHECKER_DAISY_OAK, [FAMECHECKER_BROCK] = TRAINER_LEADER_BROCK, [FAMECHECKER_MISTY] = TRAINER_LEADER_MISTY, [FAMECHECKER_LTSURGE] = TRAINER_LEADER_LT_SURGE, [FAMECHECKER_ERIKA] = TRAINER_LEADER_ERIKA, [FAMECHECKER_KOGA] = TRAINER_LEADER_KOGA, [FAMECHECKER_SABRINA] = TRAINER_LEADER_SABRINA, [FAMECHECKER_BLAINE] = TRAINER_LEADER_BLAINE, [FAMECHECKER_LORELEI] = TRAINER_ELITE_FOUR_LORELEI, [FAMECHECKER_BRUNO] = TRAINER_ELITE_FOUR_BRUNO, [FAMECHECKER_AGATHA] = TRAINER_ELITE_FOUR_AGATHA, [FAMECHECKER_LANCE] = TRAINER_ELITE_FOUR_LANCE, [FAMECHECKER_BILL] = FAME_CHECKER_BILL, [FAMECHECKER_MRFUJI] = FAME_CHECKER_MR_FUJI, [FAMECHECKER_GIOVANNI] = TRAINER_BOSS_GIOVANNI }; static const u8 *const sNonTrainerNamePointers[] = { gFameCheckerOakName, gFameCheckerDaisyName, gFameCheckerBillName, gFameCheckerMrFujiName }; static const u8 sFameCheckerTrainerPicIdxs[] = { [FAMECHECKER_OAK] = TRAINER_PIC_CAMPER, [FAMECHECKER_DAISY] = TRAINER_PIC_LASS, [FAMECHECKER_BROCK] = TRAINER_PIC_LEADER_BROCK, [FAMECHECKER_MISTY] = TRAINER_PIC_LEADER_MISTY, [FAMECHECKER_LTSURGE] = TRAINER_PIC_LEADER_LT_SURGE, [FAMECHECKER_ERIKA] = TRAINER_PIC_LEADER_ERIKA, [FAMECHECKER_KOGA] = TRAINER_PIC_LEADER_KOGA, [FAMECHECKER_SABRINA] = TRAINER_PIC_LEADER_SABRINA, [FAMECHECKER_BLAINE] = TRAINER_PIC_LEADER_BLAINE, [FAMECHECKER_LORELEI] = TRAINER_PIC_ELITE_FOUR_LORELEI, [FAMECHECKER_BRUNO] = TRAINER_PIC_ELITE_FOUR_BRUNO, [FAMECHECKER_AGATHA] = TRAINER_PIC_ELITE_FOUR_AGATHA, [FAMECHECKER_LANCE] = TRAINER_PIC_ELITE_FOUR_LANCE, [FAMECHECKER_BILL] = TRAINER_PIC_PSYCHIC_M, [FAMECHECKER_MRFUJI] = TRAINER_PIC_GENTLEMAN, [FAMECHECKER_GIOVANNI] = TRAINER_PIC_LEADER_GIOVANNI, }; static const u8 sFameCheckerTrainerGenders_Unused[] = { [FAMECHECKER_OAK] = MALE, [FAMECHECKER_DAISY] = FEMALE, [FAMECHECKER_BROCK] = MALE, [FAMECHECKER_MISTY] = FEMALE, [FAMECHECKER_LTSURGE] = MALE, [FAMECHECKER_ERIKA] = FEMALE, [FAMECHECKER_KOGA] = MALE, [FAMECHECKER_SABRINA] = FEMALE, [FAMECHECKER_BLAINE] = MALE, [FAMECHECKER_LORELEI] = FEMALE, [FAMECHECKER_BRUNO] = MALE, [FAMECHECKER_AGATHA] = FEMALE, [FAMECHECKER_LANCE] = MALE, [FAMECHECKER_BILL] = MALE, [FAMECHECKER_MRFUJI] = MALE, [FAMECHECKER_GIOVANNI] = MALE, }; static const u8 *const sFameCheckerNameAndQuotesPointers[2 * NUM_FAMECHECKER_PERSONS] = { gFameCheckerPersonName_ProfOak, gFameCheckerPersonName_Daisy, gFameCheckerPersonName_Brock, gFameCheckerPersonName_Misty, gFameCheckerPersonName_LtSurge, gFameCheckerPersonName_Erika, gFameCheckerPersonName_Koga, gFameCheckerPersonName_Sabrina, gFameCheckerPersonName_Blaine, gFameCheckerPersonName_Lorelei, gFameCheckerPersonName_Bruno, gFameCheckerPersonName_Agatha, gFameCheckerPersonName_Lance, gFameCheckerPersonName_Bill, gFameCheckerPersonName_MrFuji, gFameCheckerPersonName_Giovanni, gFameCheckerPersonQuote_ProfOak, gFameCheckerPersonQuote_Daisy, gFameCheckerPersonQuote_Brock, gFameCheckerPersonQuote_Misty, gFameCheckerPersonQuote_LtSurge, gFameCheckerPersonQuote_Erika, gFameCheckerPersonQuote_Koga, gFameCheckerPersonQuote_Sabrina, gFameCheckerPersonQuote_Blaine, gFameCheckerPersonQuote_Lorelei, gFameCheckerPersonQuote_Bruno, gFameCheckerPersonQuote_Agatha, gFameCheckerPersonQuote_Lance, gFameCheckerPersonQuote_Bill, gFameCheckerPersonQuote_MrFuji, gFameCheckerPersonQuote_Giovanni }; static const u8 *const sFameCheckerFlavorTextPointers[] = { gFameCheckerFlavorText_ProfOak0, gFameCheckerFlavorText_ProfOak1, gFameCheckerFlavorText_ProfOak2, gFameCheckerFlavorText_ProfOak3, gFameCheckerFlavorText_ProfOak4, gFameCheckerFlavorText_ProfOak5, gFameCheckerFlavorText_Daisy0, gFameCheckerFlavorText_Daisy1, gFameCheckerFlavorText_Daisy2, gFameCheckerFlavorText_Daisy3, gFameCheckerFlavorText_Daisy4, gFameCheckerFlavorText_Daisy5, gFameCheckerFlavorText_Brock0, gFameCheckerFlavorText_Brock1, gFameCheckerFlavorText_Brock2, gFameCheckerFlavorText_Brock3, gFameCheckerFlavorText_Brock4, gFameCheckerFlavorText_Brock5, gFameCheckerFlavorText_Misty0, gFameCheckerFlavorText_Misty1, gFameCheckerFlavorText_Misty2, gFameCheckerFlavorText_Misty3, gFameCheckerFlavorText_Misty4, gFameCheckerFlavorText_Misty5, gFameCheckerFlavorText_LtSurge0, gFameCheckerFlavorText_LtSurge1, gFameCheckerFlavorText_LtSurge2, gFameCheckerFlavorText_LtSurge3, gFameCheckerFlavorText_LtSurge4, gFameCheckerFlavorText_LtSurge5, gFameCheckerFlavorText_Erika0, gFameCheckerFlavorText_Erika1, gFameCheckerFlavorText_Erika2, gFameCheckerFlavorText_Erika3, gFameCheckerFlavorText_Erika4, gFameCheckerFlavorText_Erika5, gFameCheckerFlavorText_Koga0, gFameCheckerFlavorText_Koga1, gFameCheckerFlavorText_Koga2, gFameCheckerFlavorText_Koga3, gFameCheckerFlavorText_Koga4, gFameCheckerFlavorText_Koga5, gFameCheckerFlavorText_Sabrina0, gFameCheckerFlavorText_Sabrina1, gFameCheckerFlavorText_Sabrina2, gFameCheckerFlavorText_Sabrina3, gFameCheckerFlavorText_Sabrina4, gFameCheckerFlavorText_Sabrina5, gFameCheckerFlavorText_Blaine0, gFameCheckerFlavorText_Blaine1, gFameCheckerFlavorText_Blaine2, gFameCheckerFlavorText_Blaine3, gFameCheckerFlavorText_Blaine4, gFameCheckerFlavorText_Blaine5, gFameCheckerFlavorText_Lorelei0, gFameCheckerFlavorText_Lorelei1, gFameCheckerFlavorText_Lorelei2, gFameCheckerFlavorText_Lorelei3, gFameCheckerFlavorText_Lorelei4, gFameCheckerFlavorText_Lorelei5, gFameCheckerFlavorText_Bruno0, gFameCheckerFlavorText_Bruno1, gFameCheckerFlavorText_Bruno2, gFameCheckerFlavorText_Bruno3, gFameCheckerFlavorText_Bruno4, gFameCheckerFlavorText_Bruno5, gFameCheckerFlavorText_Agatha0, gFameCheckerFlavorText_Agatha1, gFameCheckerFlavorText_Agatha2, gFameCheckerFlavorText_Agatha3, gFameCheckerFlavorText_Agatha4, gFameCheckerFlavorText_Agatha5, gFameCheckerFlavorText_Lance0, gFameCheckerFlavorText_Lance1, gFameCheckerFlavorText_Lance2, gFameCheckerFlavorText_Lance3, gFameCheckerFlavorText_Lance4, gFameCheckerFlavorText_Lance5, gFameCheckerFlavorText_Bill0, gFameCheckerFlavorText_Bill1, gFameCheckerFlavorText_Bill2, gFameCheckerFlavorText_Bill3, gFameCheckerFlavorText_Bill4, gFameCheckerFlavorText_Bill5, gFameCheckerFlavorText_MrFuji0, gFameCheckerFlavorText_MrFuji1, gFameCheckerFlavorText_MrFuji2, gFameCheckerFlavorText_MrFuji3, gFameCheckerFlavorText_MrFuji4, gFameCheckerFlavorText_MrFuji5, gFameCheckerFlavorText_Giovanni0, gFameCheckerFlavorText_Giovanni1, gFameCheckerFlavorText_Giovanni2, gFameCheckerFlavorText_Giovanni3, gFameCheckerFlavorText_Giovanni4, gFameCheckerFlavorText_Giovanni5 }; static const u8 sFameCheckerArrayNpcGraphicsIds[] = { // OAK OBJ_EVENT_GFX_SIGN, OBJ_EVENT_GFX_PROF_OAK, OBJ_EVENT_GFX_WORKER_F, OBJ_EVENT_GFX_CLIPBOARD, OBJ_EVENT_GFX_AGATHA, OBJ_EVENT_GFX_SCIENTIST, // DAISY OBJ_EVENT_GFX_SCIENTIST, OBJ_EVENT_GFX_WORKER_F, OBJ_EVENT_GFX_GENTLEMAN, OBJ_EVENT_GFX_CLIPBOARD, OBJ_EVENT_GFX_OLD_WOMAN, OBJ_EVENT_GFX_CLIPBOARD, // BROCK OBJ_EVENT_GFX_GYM_SIGN, OBJ_EVENT_GFX_BROCK, OBJ_EVENT_GFX_FAT_MAN, OBJ_EVENT_GFX_BOY, OBJ_EVENT_GFX_BALDING_MAN, OBJ_EVENT_GFX_CLIPBOARD, // MISTY OBJ_EVENT_GFX_GYM_SIGN, OBJ_EVENT_GFX_MISTY, OBJ_EVENT_GFX_SWIMMER_M_WATER, OBJ_EVENT_GFX_CAMPER, OBJ_EVENT_GFX_BEAUTY, OBJ_EVENT_GFX_CLIPBOARD, // LTSURGE OBJ_EVENT_GFX_GYM_SIGN, OBJ_EVENT_GFX_LT_SURGE, OBJ_EVENT_GFX_GENTLEMAN, OBJ_EVENT_GFX_GENTLEMAN, OBJ_EVENT_GFX_SAILOR, OBJ_EVENT_GFX_CLIPBOARD, // ERIKA OBJ_EVENT_GFX_GYM_SIGN, OBJ_EVENT_GFX_ERIKA, OBJ_EVENT_GFX_LASS, OBJ_EVENT_GFX_BEAUTY, OBJ_EVENT_GFX_ERIKA, OBJ_EVENT_GFX_CLIPBOARD, // KOGA OBJ_EVENT_GFX_GYM_SIGN, OBJ_EVENT_GFX_KOGA, OBJ_EVENT_GFX_ROCKER, OBJ_EVENT_GFX_LASS, OBJ_EVENT_GFX_CLIPBOARD, OBJ_EVENT_GFX_BALDING_MAN, // SABRINA OBJ_EVENT_GFX_GYM_SIGN, OBJ_EVENT_GFX_MAN, OBJ_EVENT_GFX_SABRINA, OBJ_EVENT_GFX_SABRINA, OBJ_EVENT_GFX_CLIPBOARD, OBJ_EVENT_GFX_COOLTRAINER_M, // BLAINE OBJ_EVENT_GFX_GYM_SIGN, OBJ_EVENT_GFX_BLAINE, OBJ_EVENT_GFX_SCIENTIST, OBJ_EVENT_GFX_WOMAN_2, OBJ_EVENT_GFX_CLIPBOARD, OBJ_EVENT_GFX_CLIPBOARD, // LORELEI OBJ_EVENT_GFX_LORELEI, OBJ_EVENT_GFX_LORELEI, OBJ_EVENT_GFX_OLD_MAN_1, OBJ_EVENT_GFX_CLIPBOARD, OBJ_EVENT_GFX_LITTLE_GIRL, OBJ_EVENT_GFX_OLD_WOMAN, // BRUNO OBJ_EVENT_GFX_BRUNO, OBJ_EVENT_GFX_BRUNO, OBJ_EVENT_GFX_CLIPBOARD, OBJ_EVENT_GFX_BLACKBELT, OBJ_EVENT_GFX_BEAUTY, OBJ_EVENT_GFX_BLACKBELT, // AGATHA OBJ_EVENT_GFX_AGATHA, OBJ_EVENT_GFX_BLACKBELT, OBJ_EVENT_GFX_BLACKBELT, OBJ_EVENT_GFX_CLIPBOARD, OBJ_EVENT_GFX_AGATHA, OBJ_EVENT_GFX_OLD_WOMAN, // LANCE OBJ_EVENT_GFX_LANCE, OBJ_EVENT_GFX_LANCE, OBJ_EVENT_GFX_BATTLE_GIRL, OBJ_EVENT_GFX_WOMAN_1, OBJ_EVENT_GFX_CLIPBOARD, OBJ_EVENT_GFX_COOLTRAINER_M, // BILL OBJ_EVENT_GFX_BLUE, OBJ_EVENT_GFX_YOUNGSTER, OBJ_EVENT_GFX_OLD_MAN_1, OBJ_EVENT_GFX_CELIO, OBJ_EVENT_GFX_CELIO, OBJ_EVENT_GFX_CELIO, // MRFUJI OBJ_EVENT_GFX_LITTLE_GIRL, OBJ_EVENT_GFX_ROCKET_M, OBJ_EVENT_GFX_CLIPBOARD, OBJ_EVENT_GFX_BALDING_MAN, OBJ_EVENT_GFX_CLIPBOARD, OBJ_EVENT_GFX_CLIPBOARD, // GIOVANNI OBJ_EVENT_GFX_GIOVANNI, OBJ_EVENT_GFX_SCIENTIST, OBJ_EVENT_GFX_SCIENTIST, OBJ_EVENT_GFX_GIOVANNI, OBJ_EVENT_GFX_GYM_GUY, OBJ_EVENT_GFX_SCIENTIST }; static const u8 *const sFlavorTextOriginLocationTexts[] = { gFameCheckerFlavorTextOriginLocation_ProfOak0, gFameCheckerFlavorTextOriginLocation_ProfOak1, gFameCheckerFlavorTextOriginLocation_ProfOak2, gFameCheckerFlavorTextOriginLocation_ProfOak3, gFameCheckerFlavorTextOriginLocation_ProfOak4, gFameCheckerFlavorTextOriginLocation_ProfOak5, gFameCheckerFlavorTextOriginLocation_Daisy0, gFameCheckerFlavorTextOriginLocation_Daisy1, gFameCheckerFlavorTextOriginLocation_Daisy2, gFameCheckerFlavorTextOriginLocation_Daisy3, gFameCheckerFlavorTextOriginLocation_Daisy4, gFameCheckerFlavorTextOriginLocation_Daisy5, gFameCheckerFlavorTextOriginLocation_Brock0, gFameCheckerFlavorTextOriginLocation_Brock1, gFameCheckerFlavorTextOriginLocation_Brock2, gFameCheckerFlavorTextOriginLocation_Brock3, gFameCheckerFlavorTextOriginLocation_Brock4, gFameCheckerFlavorTextOriginLocation_Brock5, gFameCheckerFlavorTextOriginLocation_Misty0, gFameCheckerFlavorTextOriginLocation_Misty1, gFameCheckerFlavorTextOriginLocation_Misty2, gFameCheckerFlavorTextOriginLocation_Misty3, gFameCheckerFlavorTextOriginLocation_Misty4, gFameCheckerFlavorTextOriginLocation_Misty5, gFameCheckerFlavorTextOriginLocation_LtSurge0, gFameCheckerFlavorTextOriginLocation_LtSurge1, gFameCheckerFlavorTextOriginLocation_LtSurge2, gFameCheckerFlavorTextOriginLocation_LtSurge3, gFameCheckerFlavorTextOriginLocation_LtSurge4, gFameCheckerFlavorTextOriginLocation_LtSurge5, gFameCheckerFlavorTextOriginLocation_Erika0, gFameCheckerFlavorTextOriginLocation_Erika1, gFameCheckerFlavorTextOriginLocation_Erika2, gFameCheckerFlavorTextOriginLocation_Erika3, gFameCheckerFlavorTextOriginLocation_Erika4, gFameCheckerFlavorTextOriginLocation_Erika5, gFameCheckerFlavorTextOriginLocation_Koga0, gFameCheckerFlavorTextOriginLocation_Koga1, gFameCheckerFlavorTextOriginLocation_Koga2, gFameCheckerFlavorTextOriginLocation_Koga3, gFameCheckerFlavorTextOriginLocation_Koga4, gFameCheckerFlavorTextOriginLocation_Koga5, gFameCheckerFlavorTextOriginLocation_Sabrina0, gFameCheckerFlavorTextOriginLocation_Sabrina1, gFameCheckerFlavorTextOriginLocation_Sabrina2, gFameCheckerFlavorTextOriginLocation_Sabrina3, gFameCheckerFlavorTextOriginLocation_Sabrina4, gFameCheckerFlavorTextOriginLocation_Sabrina5, gFameCheckerFlavorTextOriginLocation_Blaine0, gFameCheckerFlavorTextOriginLocation_Blaine1, gFameCheckerFlavorTextOriginLocation_Blaine2, gFameCheckerFlavorTextOriginLocation_Blaine3, gFameCheckerFlavorTextOriginLocation_Blaine4, gFameCheckerFlavorTextOriginLocation_Blaine5, gFameCheckerFlavorTextOriginLocation_Lorelei0, gFameCheckerFlavorTextOriginLocation_Lorelei1, gFameCheckerFlavorTextOriginLocation_Lorelei2, gFameCheckerFlavorTextOriginLocation_Lorelei3, gFameCheckerFlavorTextOriginLocation_Lorelei4, gFameCheckerFlavorTextOriginLocation_Lorelei5, gFameCheckerFlavorTextOriginLocation_Bruno0, gFameCheckerFlavorTextOriginLocation_Bruno1, gFameCheckerFlavorTextOriginLocation_Bruno2, gFameCheckerFlavorTextOriginLocation_Bruno3, gFameCheckerFlavorTextOriginLocation_Bruno4, gFameCheckerFlavorTextOriginLocation_Bruno5, gFameCheckerFlavorTextOriginLocation_Agatha0, gFameCheckerFlavorTextOriginLocation_Agatha1, gFameCheckerFlavorTextOriginLocation_Agatha2, gFameCheckerFlavorTextOriginLocation_Agatha3, gFameCheckerFlavorTextOriginLocation_Agatha4, gFameCheckerFlavorTextOriginLocation_Agatha5, gFameCheckerFlavorTextOriginLocation_Lance0, gFameCheckerFlavorTextOriginLocation_Lance1, gFameCheckerFlavorTextOriginLocation_Lance2, gFameCheckerFlavorTextOriginLocation_Lance3, gFameCheckerFlavorTextOriginLocation_Lance4, gFameCheckerFlavorTextOriginLocation_Lance5, gFameCheckerFlavorTextOriginLocation_Bill0, gFameCheckerFlavorTextOriginLocation_Bill1, gFameCheckerFlavorTextOriginLocation_Bill2, gFameCheckerFlavorTextOriginLocation_Bill3, gFameCheckerFlavorTextOriginLocation_Bill4, gFameCheckerFlavorTextOriginLocation_Bill5, gFameCheckerFlavorTextOriginLocation_MrFuji0, gFameCheckerFlavorTextOriginLocation_MrFuji1, gFameCheckerFlavorTextOriginLocation_MrFuji2, gFameCheckerFlavorTextOriginLocation_MrFuji3, gFameCheckerFlavorTextOriginLocation_MrFuji4, gFameCheckerFlavorTextOriginLocation_MrFuji5, gFameCheckerFlavorTextOriginLocation_Giovanni0, gFameCheckerFlavorTextOriginLocation_Giovanni1, gFameCheckerFlavorTextOriginLocation_Giovanni2, gFameCheckerFlavorTextOriginLocation_Giovanni3, gFameCheckerFlavorTextOriginLocation_Giovanni4, gFameCheckerFlavorTextOriginLocation_Giovanni5 }; static const u8 *const sFlavorTextOriginObjectNameTexts[] = { gFameCheckerFlavorTextOriginObjectName_ProfOak0, gFameCheckerFlavorTextOriginObjectName_ProfOak1, gFameCheckerFlavorTextOriginObjectName_ProfOak2, gFameCheckerFlavorTextOriginObjectName_ProfOak3, gFameCheckerFlavorTextOriginObjectName_ProfOak4, gFameCheckerFlavorTextOriginObjectName_ProfOak5, gFameCheckerFlavorTextOriginObjectName_Daisy0, gFameCheckerFlavorTextOriginObjectName_Daisy1, gFameCheckerFlavorTextOriginObjectName_Daisy2, gFameCheckerFlavorTextOriginObjectName_Daisy3, gFameCheckerFlavorTextOriginObjectName_Daisy4, gFameCheckerFlavorTextOriginObjectName_Daisy5, gFameCheckerFlavorTextOriginObjectName_Brock0, gFameCheckerFlavorTextOriginObjectName_Brock1, gFameCheckerFlavorTextOriginObjectName_Brock2, gFameCheckerFlavorTextOriginObjectName_Brock3, gFameCheckerFlavorTextOriginObjectName_Brock4, gFameCheckerFlavorTextOriginObjectName_Brock5, gFameCheckerFlavorTextOriginObjectName_Misty0, gFameCheckerFlavorTextOriginObjectName_Misty1, gFameCheckerFlavorTextOriginObjectName_Misty2, gFameCheckerFlavorTextOriginObjectName_Misty3, gFameCheckerFlavorTextOriginObjectName_Misty4, gFameCheckerFlavorTextOriginObjectName_Misty5, gFameCheckerFlavorTextOriginObjectName_LtSurge0, gFameCheckerFlavorTextOriginObjectName_LtSurge1, gFameCheckerFlavorTextOriginObjectName_LtSurge2, gFameCheckerFlavorTextOriginObjectName_LtSurge3, gFameCheckerFlavorTextOriginObjectName_LtSurge4, gFameCheckerFlavorTextOriginObjectName_LtSurge5, gFameCheckerFlavorTextOriginObjectName_Erika0, gFameCheckerFlavorTextOriginObjectName_Erika1, gFameCheckerFlavorTextOriginObjectName_Erika2, gFameCheckerFlavorTextOriginObjectName_Erika3, gFameCheckerFlavorTextOriginObjectName_Erika4, gFameCheckerFlavorTextOriginObjectName_Erika5, gFameCheckerFlavorTextOriginObjectName_Koga0, gFameCheckerFlavorTextOriginObjectName_Koga1, gFameCheckerFlavorTextOriginObjectName_Koga2, gFameCheckerFlavorTextOriginObjectName_Koga3, gFameCheckerFlavorTextOriginObjectName_Koga4, gFameCheckerFlavorTextOriginObjectName_Koga5, gFameCheckerFlavorTextOriginObjectName_Sabrina0, gFameCheckerFlavorTextOriginObjectName_Sabrina1, gFameCheckerFlavorTextOriginObjectName_Sabrina2, gFameCheckerFlavorTextOriginObjectName_Sabrina3, gFameCheckerFlavorTextOriginObjectName_Sabrina4, gFameCheckerFlavorTextOriginObjectName_Sabrina5, gFameCheckerFlavorTextOriginObjectName_Blaine0, gFameCheckerFlavorTextOriginObjectName_Blaine1, gFameCheckerFlavorTextOriginObjectName_Blaine2, gFameCheckerFlavorTextOriginObjectName_Blaine3, gFameCheckerFlavorTextOriginObjectName_Blaine4, gFameCheckerFlavorTextOriginObjectName_Blaine5, gFameCheckerFlavorTextOriginObjectName_Lorelei0, gFameCheckerFlavorTextOriginObjectName_Lorelei1, gFameCheckerFlavorTextOriginObjectName_Lorelei2, gFameCheckerFlavorTextOriginObjectName_Lorelei3, gFameCheckerFlavorTextOriginObjectName_Lorelei4, gFameCheckerFlavorTextOriginObjectName_Lorelei5, gFameCheckerFlavorTextOriginObjectName_Bruno0, gFameCheckerFlavorTextOriginObjectName_Bruno1, gFameCheckerFlavorTextOriginObjectName_Bruno2, gFameCheckerFlavorTextOriginObjectName_Bruno3, gFameCheckerFlavorTextOriginObjectName_Bruno4, gFameCheckerFlavorTextOriginObjectName_Bruno5, gFameCheckerFlavorTextOriginObjectName_Agatha0, gFameCheckerFlavorTextOriginObjectName_Agatha1, gFameCheckerFlavorTextOriginObjectName_Agatha2, gFameCheckerFlavorTextOriginObjectName_Agatha3, gFameCheckerFlavorTextOriginObjectName_Agatha4, gFameCheckerFlavorTextOriginObjectName_Agatha5, gFameCheckerFlavorTextOriginObjectName_Lance0, gFameCheckerFlavorTextOriginObjectName_Lance1, gFameCheckerFlavorTextOriginObjectName_Lance2, gFameCheckerFlavorTextOriginObjectName_Lance3, gFameCheckerFlavorTextOriginObjectName_Lance4, gFameCheckerFlavorTextOriginObjectName_Lance5, gFameCheckerFlavorTextOriginObjectName_Bill0, gFameCheckerFlavorTextOriginObjectName_Bill1, gFameCheckerFlavorTextOriginObjectName_Bill2, gFameCheckerFlavorTextOriginObjectName_Bill3, gFameCheckerFlavorTextOriginObjectName_Bill4, gFameCheckerFlavorTextOriginObjectName_Bill5, gFameCheckerFlavorTextOriginObjectName_MrFuji0, gFameCheckerFlavorTextOriginObjectName_MrFuji1, gFameCheckerFlavorTextOriginObjectName_MrFuji2, gFameCheckerFlavorTextOriginObjectName_MrFuji3, gFameCheckerFlavorTextOriginObjectName_MrFuji4, gFameCheckerFlavorTextOriginObjectName_MrFuji5, gFameCheckerFlavorTextOriginObjectName_Giovanni0, gFameCheckerFlavorTextOriginObjectName_Giovanni1, gFameCheckerFlavorTextOriginObjectName_Giovanni2, gFameCheckerFlavorTextOriginObjectName_Giovanni3, gFameCheckerFlavorTextOriginObjectName_Giovanni4, gFameCheckerFlavorTextOriginObjectName_Giovanni5 }; static const struct SpriteSheet sUISpriteSheets[] = { {sSelectorCursorSpriteGfx, 0x400, SPRITETAG_SELECTOR_CURSOR}, {sQuestionMarkSpriteGfx, 0x100, SPRITETAG_QUESTION_MARK}, {sSpinningPokeballSpriteGfx, 0x1e0, SPRITETAG_SPINNING_POKEBALL}, {sDaisySpriteGfx, 0x800, SPRITETAG_DAISY}, {sFujiSpriteGfx, 0x800, SPRITETAG_FUJI}, {sOakSpriteGfx, 0x800, SPRITETAG_OAK}, {sBillSpriteGfx, 0x800, SPRITETAG_BILL}, {} }; static const struct SpritePalette sUISpritePalettes[] = { {sSelectorCursorSpritePalette, SPRITETAG_SELECTOR_CURSOR}, {sSpinningPokeballSpritePalette, SPRITETAG_SPINNING_POKEBALL}, {} }; static const struct BgTemplate sUIBgTemplates[4] = { { .bg = 3, .charBaseIndex = 3, .mapBaseIndex = 30, .screenSize = 0, .paletteMode = FALSE, .priority = 3, .baseTile = 0x000 }, { .bg = 2, .charBaseIndex = 3, .mapBaseIndex = 27, .screenSize = 0, .paletteMode = FALSE, .priority = 2, .baseTile = 0x000 }, { .bg = 1, .charBaseIndex = 3, .mapBaseIndex = 28, .screenSize = 1, .paletteMode = FALSE, .priority = 0, .baseTile = 0x000 }, { .bg = 0, .charBaseIndex = 0, .mapBaseIndex = 31, .screenSize = 0, .paletteMode = FALSE, .priority = 2, .baseTile = 0x000 }, }; static const struct WindowTemplate sUIWindowTemplates[] = { [FCWINDOWID_LIST] = { .bg = 0, .tilemapLeft = 1, .tilemapTop = 3, .width = 8, .height = 10, .paletteNum = 15, .baseBlock = 20 }, [FCWINDOWID_UIHELP] = { .bg = 0, .tilemapLeft = 6, .tilemapTop = 0, .width = 24, .height = 2, .paletteNum = 15, .baseBlock = 20 + 8 * 10 }, [FCWINDOWID_MSGBOX] = { .bg = 0, .tilemapLeft = 2, .tilemapTop = 15, .width = 26, .height = 4, .paletteNum = 15, .baseBlock = 20 + 8 * 10 + 24 * 2 }, [FCWINDOWID_ICONDESC] = { .bg = 0, .tilemapLeft = 15, .tilemapTop = 10, .width = 11, .height = 4, .paletteNum = 15, .baseBlock = 20 + 8 * 10 + 24 * 2 + 26 * 4 }, DUMMY_WIN_TEMPLATE }; static const union AnimCmd sSelectorCursorAnim0[] = { ANIMCMD_FRAME( 0, 15), ANIMCMD_FRAME(16, 15), ANIMCMD_JUMP(0) }; static const union AnimCmd *const sSelectorCursorAnims[] = { sSelectorCursorAnim0 }; static const struct OamData sSelectorCursorOamData = { .size = 2, .priority = 2 }; static const struct SpriteTemplate sSpriteTemplate_SelectorCursor = { SPRITETAG_SELECTOR_CURSOR, SPRITETAG_SELECTOR_CURSOR, &sSelectorCursorOamData, sSelectorCursorAnims, NULL, gDummySpriteAffineAnimTable, SpriteCallbackDummy }; static const u8 filler_845FC5C[8] = {}; // ??? static const struct OamData sQuestionMarkTileOamData = { .shape = ST_OAM_V_RECTANGLE, .size = 2, .priority = 2 }; static const union AnimCmd sQuestionMarkTileAnim0[] = { ANIMCMD_FRAME( 0, 10), ANIMCMD_END }; static const union AnimCmd *const sQuestionMarkTileAnims[] = { sQuestionMarkTileAnim0 }; static const struct SpriteTemplate sQuestionMarkTileSpriteTemplate = { SPRITETAG_QUESTION_MARK, 0xffff, &sQuestionMarkTileOamData, sQuestionMarkTileAnims, NULL, gDummySpriteAffineAnimTable, SpriteCallbackDummy }; static const union AnimCmd sSpinningPokeballAnim0[] = { ANIMCMD_FRAME( 0, 10), ANIMCMD_END }; static const union AnimCmd *const sSpinningPokeballAnims[] = { sSpinningPokeballAnim0 }; static const struct OamData sSpinningPokeballOamData = { .affineMode = ST_OAM_AFFINE_NORMAL, .size = 2 }; static const union AffineAnimCmd sSpinningPokeballAffineAnim0[] = { AFFINEANIMCMD_FRAME(0, 0, 4, 20), AFFINEANIMCMD_JUMP(0) }; static const union AffineAnimCmd *const sSpinningPokeballAffineAnims[] = { sSpinningPokeballAffineAnim0 }; static const struct SpriteTemplate sSpinningPokeballSpriteTemplate = { SPRITETAG_SPINNING_POKEBALL, SPRITETAG_SPINNING_POKEBALL, &sSpinningPokeballOamData, sSpinningPokeballAnims, NULL, sSpinningPokeballAffineAnims, SpriteCB_FCSpinningPokeball }; static const union AnimCmd sDaisyFujiOakBillAnim0[] = { ANIMCMD_FRAME( 0, 15), ANIMCMD_END }; static const union AnimCmd *const sDaisyFujiOakBillAnims[] = { sDaisyFujiOakBillAnim0 }; static const struct OamData sDaisyFujiOakBillOamData = { .size = 3 }; static const struct SpriteTemplate sDaisySpriteTemplate = { SPRITETAG_DAISY, 0xffff, &sDaisyFujiOakBillOamData, sDaisyFujiOakBillAnims, NULL, gDummySpriteAffineAnimTable, SpriteCallbackDummy }; static const struct SpriteTemplate sFujiSpriteTemplate = { SPRITETAG_FUJI, 0xffff, &sDaisyFujiOakBillOamData, sDaisyFujiOakBillAnims, NULL, gDummySpriteAffineAnimTable, SpriteCallbackDummy }; static const struct SpriteTemplate sOakSpriteTemplate = { SPRITETAG_OAK, 0xffff, &sDaisyFujiOakBillOamData, sDaisyFujiOakBillAnims, NULL, gDummySpriteAffineAnimTable, SpriteCallbackDummy }; static const struct SpriteTemplate sBillSpriteTemplate = { SPRITETAG_BILL, 0xffff, &sDaisyFujiOakBillOamData, sDaisyFujiOakBillAnims, NULL, gDummySpriteAffineAnimTable, SpriteCallbackDummy }; static void FC_VBlankCallback(void) { LoadOam(); ProcessSpriteCopyRequests(); TransferPlttBuffer(); } static void MainCB2_FameCheckerMain(void) { RunTasks(); AnimateSprites(); BuildOamBuffer(); UpdatePaletteFade(); } void UseFameChecker(MainCallback savedCallback) { SetVBlankCallback(NULL); sFameCheckerData = AllocZeroed(sizeof(struct FameCheckerData)); sFameCheckerData->savedCallback = savedCallback; sFameCheckerData->listMenuCurIdx = 0; sFameCheckerData->listMenuTopIdx2 = 0; sFameCheckerData->listMenuDrawnSelIdx = 0; sFameCheckerData->viewingFlavorText = FALSE; PlaySE(SE_M_SWIFT); SetMainCallback2(MainCB2_LoadFameChecker); } static void MainCB2_LoadFameChecker(void) { switch (gMain.state) { case 0: SetVBlankCallback(NULL); FCSetup_ClearVideoRegisters(); gMain.state++; break; case 1: FCSetup_ResetTasksAndSpriteResources(); gMain.state++; break; case 2: sBg3TilemapBuffer = AllocZeroed(BG_SCREEN_SIZE); // 256x256 sBg1TilemapBuffer = AllocZeroed(BG_SCREEN_SIZE * 2); // 512x256 sBg2TilemapBuffer = AllocZeroed(BG_SCREEN_SIZE); // 256x256 ResetBgsAndClearDma3BusyFlags(0); InitBgsFromTemplates(0, sUIBgTemplates, NELEMS(sUIBgTemplates)); SetBgTilemapBuffer(3, sBg3TilemapBuffer); SetBgTilemapBuffer(2, sBg2TilemapBuffer); SetBgTilemapBuffer(1, sBg1TilemapBuffer); FCSetup_ResetBGCoords(); gMain.state++; break; case 3: LoadBgTiles(3, gFameCheckerBgTiles, sizeof(gFameCheckerBgTiles), 0); CopyToBgTilemapBufferRect(3, gFameCheckerBg3Tilemap, 0, 0, 32, 32); LoadPalette(gFameCheckerBgPals + 0x00, 0x00, 0x40); LoadPalette(gFameCheckerBgPals + 0x10, 0x10, 0x20); CopyToBgTilemapBufferRect(2, gFameCheckerBg2Tilemap, 0, 0, 32, 32); CopyToBgTilemapBufferRect_ChangePalette(1, sFameCheckerTilemap, 30, 0, 32, 32, 0x11); LoadPalette(stdpal_get(2), 0xF0, 0x20); gMain.state++; break; case 4: if (IsDma3ManagerBusyWithBgCopy() != TRUE) { ShowBg(0); ShowBg(1); ShowBg(2); ShowBg(3); CopyBgTilemapBufferToVram(3); CopyBgTilemapBufferToVram(2); CopyBgTilemapBufferToVram(1); gMain.state++; } break; case 5: InitWindows(sUIWindowTemplates); DeactivateAllTextPrinters(); Setup_DrawMsgAndListBoxes(); sListMenuItems = AllocZeroed(17 * sizeof(struct ListMenuItem)); FC_CreateListMenu(); gMain.state++; break; case 6: LoadUISpriteSheetsAndPalettes(); CreateAllFlavorTextIcons(FAMECHECKER_OAK); WipeMsgBoxAndTransfer(); BeginNormalPaletteFade(0xFFFFFFFF,0, 16, 0, 0); gMain.state++; break; case 7: FCSetup_TurnOnDisplay(); SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_BG0 | BLDCNT_TGT2_BG1 | BLDCNT_TGT2_BG2 | BLDCNT_TGT2_BG3 | BLDCNT_TGT2_OBJ | BLDCNT_TGT2_BD); SetGpuReg(REG_OFFSET_BLDALPHA, 0x07); SetGpuReg(REG_OFFSET_BLDY, 0x08); SetVBlankCallback(FC_VBlankCallback); sFameCheckerData->listMenuTopIdx = 0; FC_CreateScrollIndicatorArrowPair(); UpdateInfoBoxTilemap(1, 4); CreateTask(Task_WaitFadeOnInit, 0x08); SetMainCallback2(MainCB2_FameCheckerMain); gMain.state = 0; break; } } static void LoadUISpriteSheetsAndPalettes(void) { LoadSpriteSheets(sUISpriteSheets); LoadSpritePalettes(sUISpritePalettes); } static void Task_WaitFadeOnInit(u8 taskId) { if (!gPaletteFade.active) gTasks[taskId].func = Task_TopMenuHandleInput; } static void Task_TopMenuHandleInput(u8 taskId) { u16 cursorPos; u8 i; struct Task *task = &gTasks[taskId]; s16 * data = gTasks[taskId].data; if (FindTaskIdByFunc(Task_FCOpenOrCloseInfoBox) == 0xFF) { RunTextPrinters(); if ((JOY_NEW(SELECT_BUTTON)) && !sFameCheckerData->inPickMode && sFameCheckerData->savedCallback != CB2_BagMenuFromStartMenu) task->func = Task_StartToCloseFameChecker; else if (JOY_NEW(START_BUTTON)) { cursorPos = FameCheckerGetCursorY(); if (TryExitPickMode(taskId) == TRUE) { PlaySE(SE_M_LOCK_ON); } else if (cursorPos != sFameCheckerData->numUnlockedPersons - 1) // anything but CANCEL { PlaySE(SE_M_LOCK_ON); FillWindowPixelRect(FCWINDOWID_ICONDESC, PIXEL_FILL(0), 0, 0, 88, 32); FC_PutWindowTilemapAndCopyWindowToVramMode3(FCWINDOWID_ICONDESC); UpdateInfoBoxTilemap(2, 4); UpdateInfoBoxTilemap(1, 5); PrintUIHelp(1); task->data[2] = CreatePersonPicSprite(sFameCheckerData->unlockedPersons[cursorPos]); gSprites[task->data[2]].x2 = 0xF0; gSprites[task->data[2]].data[0] = 1; task->data[3] = CreateSpinningPokeballSprite(); gSprites[task->data[3]].x2 = 0xF0; gSprites[task->data[3]].data[0] = 1; task->func = Task_EnterPickMode; } } else if (JOY_NEW(A_BUTTON)) { cursorPos = ListMenu_ProcessInput(0); if (cursorPos == sFameCheckerData->numUnlockedPersons - 1) // CANCEL task->func = Task_StartToCloseFameChecker; else if (sFameCheckerData->inPickMode) { if (!IsTextPrinterActive(2) && HasUnlockedAllFlavorTextsForCurrentPerson() == TRUE) GetPickModeText(); } else if (sFameCheckerData->personHasUnlockedPanels) { PlaySE(SE_SELECT); task->data[0] = CreateFlavorTextIconSelectorCursorSprite(task->data[1]); for (i = 0; i < 6; i++) { if (i != task->data[1]) SetMessageSelectorIconObjMode(sFameCheckerData->spriteIds[i], ST_OAM_OBJ_BLEND); } gIconDescriptionBoxIsOpen = 0xFF; PlaceListMenuCursor(FALSE); PrintUIHelp(2); if (gSprites[sFameCheckerData->spriteIds[task->data[1]]].data[1] != 0xFF) // not a ? tile { PrintSelectedNameInBrightGreen(taskId); UpdateIconDescriptionBox(data[1]); } FreeListMenuSelectorArrowPairResources(); task->func = Task_FlavorTextDisplayHandleInput; } } else if (JOY_NEW(B_BUTTON)) { if (TryExitPickMode(taskId) != TRUE) task->func = Task_StartToCloseFameChecker; } else ListMenu_ProcessInput(0); } } static bool8 TryExitPickMode(u8 taskId) { struct Task *task = &gTasks[taskId]; if (sFameCheckerData->inPickMode) { gSprites[task->data[2]].data[0] = 2; gSprites[task->data[2]].x2 += 10; gSprites[task->data[3]].data[0] = 2; gSprites[task->data[3]].x2 += 10; WipeMsgBoxAndTransfer(); task->func = Task_ExitPickMode; MessageBoxPrintEmptyText(); sFameCheckerData->pickModeOverCancel = FALSE; return TRUE; } return FALSE; } static void MessageBoxPrintEmptyText(void) { AddTextPrinterParameterized2(FCWINDOWID_MSGBOX, 2, gFameCheckerText_ClearTextbox, 0, NULL, 2, 1, 3); } static void Task_EnterPickMode(u8 taskId) { struct Task *task = &gTasks[taskId]; if (gSprites[task->data[2]].data[0] == 0) { GetPickModeText(); sFameCheckerData->inPickMode = TRUE; task->func = Task_TopMenuHandleInput; } else ChangeBgX(1, 0xA00, 1); } static void Task_ExitPickMode(u8 taskId) { struct Task *task = &gTasks[taskId]; if (GetBgX(1) != 0) ChangeBgX(1, 0xA00, 2); else ChangeBgX(1, 0x000, 0); if (gSprites[task->data[2]].data[0] == 0) { if (sFameCheckerData->personHasUnlockedPanels) PrintUIHelp(0); UpdateInfoBoxTilemap(1, 4); UpdateInfoBoxTilemap(2, 2); sFameCheckerData->inPickMode = FALSE; DestroyPersonPicSprite(taskId, FameCheckerGetCursorY()); task->func = Task_TopMenuHandleInput; gSprites[task->data[3]].callback = SpriteCB_DestroySpinningPokeball; } } static void Task_FlavorTextDisplayHandleInput(u8 taskId) { struct Task *task = &gTasks[taskId]; s16 *data = gTasks[taskId].data; RunTextPrinters(); if (JOY_NEW(A_BUTTON) && !IsTextPrinterActive(2)) { u8 spriteId = sFameCheckerData->spriteIds[data[1]]; if (gSprites[spriteId].data[1] != 0xFF) PrintSelectedNameInBrightGreen(taskId); } if (JOY_NEW(B_BUTTON)) { u8 i; PlaySE(SE_SELECT); for (i = 0; i < 6; i++) SetMessageSelectorIconObjMode(sFameCheckerData->spriteIds[i], ST_OAM_OBJ_NORMAL); WipeMsgBoxAndTransfer(); gSprites[task->data[0]].callback = SpriteCB_DestroyFlavorTextIconSelectorCursor; if (gIconDescriptionBoxIsOpen != 0xFF) UpdateIconDescriptionBoxOff(); PlaceListMenuCursor(TRUE); PrintUIHelp(0); FC_CreateScrollIndicatorArrowPair(); MessageBoxPrintEmptyText(); task->func = Task_TopMenuHandleInput; } else if (JOY_NEW(DPAD_UP) || JOY_NEW(DPAD_DOWN)) { if (task->data[1] >= 3) { task->data[1] -= 3; FC_MoveSelectorCursor(taskId, 0, -0x1b); } else { task->data[1] += 3; FC_MoveSelectorCursor(taskId, 0, +0x1b); } } else if (JOY_NEW(DPAD_LEFT)) { if (task->data[1] == 0 || task->data[1] % 3 == 0) { task->data[1] += 2; FC_MoveSelectorCursor(taskId, +0x5e, 0); } else { task->data[1]--; FC_MoveSelectorCursor(taskId, -0x2f, 0); } } else if (JOY_NEW(DPAD_RIGHT)) { if ((task->data[1] + 1) % 3 == 0) { task->data[1] -= 2; FC_MoveSelectorCursor(taskId, -0x5e, 0); } else { task->data[1]++; FC_MoveSelectorCursor(taskId, +0x2f, 0); } } } static void FC_MoveSelectorCursor(u8 taskId, s8 dx, s8 dy) { u8 i; s16 *data = gTasks[taskId].data; PlaySE(SE_M_SWAGGER2); gSprites[data[0]].x += dx; gSprites[data[0]].y += dy; for (i = 0; i < 6; i++) SetMessageSelectorIconObjMode(sFameCheckerData->spriteIds[i], ST_OAM_OBJ_BLEND); FillWindowPixelRect(FCWINDOWID_MSGBOX, PIXEL_FILL(1), 0, 0, 0xd0, 0x20); MessageBoxPrintEmptyText(); if (SetMessageSelectorIconObjMode(sFameCheckerData->spriteIds[data[1]], ST_OAM_OBJ_NORMAL) == TRUE) { PrintSelectedNameInBrightGreen(taskId); UpdateIconDescriptionBox(data[1]); } else if (gIconDescriptionBoxIsOpen != 0xFF) UpdateIconDescriptionBoxOff(); } static void GetPickModeText(void) { s32 whichText = 0; u16 who = FameCheckerGetCursorY(); if (gSaveBlock1Ptr->fameChecker[sFameCheckerData->unlockedPersons[who]].pickState != FCPICKSTATE_COLORED) { WipeMsgBoxAndTransfer(); MessageBoxPrintEmptyText(); } else { FillWindowPixelRect(FCWINDOWID_MSGBOX, PIXEL_FILL(1), 0, 0, 0xd0, 0x20); if (HasUnlockedAllFlavorTextsForCurrentPerson() == TRUE) whichText = NUM_FAMECHECKER_PERSONS; StringExpandPlaceholders(gStringVar4, sFameCheckerNameAndQuotesPointers[sFameCheckerData->unlockedPersons[who] + whichText]); AddTextPrinterParameterized2(FCWINDOWID_MSGBOX, 2, gStringVar4, GetTextSpeedSetting(), NULL, 2, 1, 3); FC_PutWindowTilemapAndCopyWindowToVramMode3(FCWINDOWID_MSGBOX); } } static void PrintSelectedNameInBrightGreen(u8 taskId) { s16 *data = gTasks[taskId].data; u16 cursorPos = FameCheckerGetCursorY(); FillWindowPixelRect(FCWINDOWID_MSGBOX, PIXEL_FILL(1), 0, 0, 0xd0, 0x20); StringExpandPlaceholders(gStringVar4, sFameCheckerFlavorTextPointers[sFameCheckerData->unlockedPersons[cursorPos] * 6 + data[1]]); AddTextPrinterParameterized2(FCWINDOWID_MSGBOX, 2, gStringVar4, GetTextSpeedSetting(), NULL, 2, 1, 3); FC_PutWindowTilemapAndCopyWindowToVramMode3(FCWINDOWID_MSGBOX); } static void WipeMsgBoxAndTransfer(void) { FillWindowPixelRect(FCWINDOWID_MSGBOX, PIXEL_FILL(1), 0, 0, 0xd0, 0x20); FC_PutWindowTilemapAndCopyWindowToVramMode3(FCWINDOWID_MSGBOX); } static void Setup_DrawMsgAndListBoxes(void) { LoadStdWindowFrameGfx(); DrawDialogueFrame(FCWINDOWID_MSGBOX, TRUE); FC_PutWindowTilemapAndCopyWindowToVramMode3(FCWINDOWID_MSGBOX); FC_PutWindowTilemapAndCopyWindowToVramMode3(FCWINDOWID_LIST); } static void FC_PutWindowTilemapAndCopyWindowToVramMode3(u8 windowId) { PutWindowTilemap(windowId); CopyWindowToVram(windowId, COPYWIN_BOTH); } static bool8 SetMessageSelectorIconObjMode(u8 spriteId, u8 objMode) { if (gSprites[spriteId].data[1] != 0xFF) { gSprites[spriteId].oam.objMode = objMode; return TRUE; } return FALSE; } static void Task_StartToCloseFameChecker(u8 taskId) { PlaySE(SE_M_SWIFT); BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, 0); gTasks[taskId].func = Task_DestroyAssetsAndCloseFameChecker; } static void Task_DestroyAssetsAndCloseFameChecker(u8 taskId) { u8 i; if (!gPaletteFade.active) { if (sFameCheckerData->inPickMode) { DestroyPersonPicSprite(taskId, FameCheckerGetCursorY()); FreeSpriteOamMatrix(&gSprites[gTasks[taskId].data[3]]); DestroySprite(&gSprites[gTasks[taskId].data[3]]); } for (i = 0; i < 6; i++) { DestroySprite(&gSprites[sFameCheckerData->spriteIds[i]]); } FreeNonTrainerPicTiles(); FreeSpinningPokeballSpriteResources(); FreeSelectionCursorSpriteResources(); FreeQuestionMarkSpriteResources(); FreeListMenuSelectorArrowPairResources(); SetMainCallback2(sFameCheckerData->savedCallback); DestroyListMenuTask(sFameCheckerData->listMenuTaskId, NULL, NULL); Free(sBg3TilemapBuffer); Free(sBg1TilemapBuffer); Free(sBg2TilemapBuffer); Free(sFameCheckerData); Free(sListMenuItems); FC_DestroyWindow(FCWINDOWID_LIST); FC_DestroyWindow(FCWINDOWID_UIHELP); FC_DestroyWindow(FCWINDOWID_MSGBOX); FC_DestroyWindow(FCWINDOWID_ICONDESC); FreeAllWindowBuffers(); DestroyTask(taskId); } } static void FC_DestroyWindow(u8 windowId) { FillWindowPixelBuffer(windowId, 0); ClearWindowTilemap(windowId); CopyWindowToVram(windowId, COPYWIN_GFX); RemoveWindow(windowId); } static u8 AdjustGiovanniIndexIfBeatenInGym(u8 a0) { if (HasTrainerBeenFought(TRAINER_LEADER_GIOVANNI) == TRUE) { if (a0 == 9) return FAMECHECKER_GIOVANNI; if (a0 > 9) return a0 - 1; } return a0; } static void PrintUIHelp(u8 state) { s32 width; const u8 * src = gFameCheckerText_MainScreenUI; if (state != 0) { src = gFameCheckerText_FlavorTextUI; if (state == 1) src = gFameCheckerText_PickScreenUI; } width = GetStringWidth(0, src, 0); FillWindowPixelRect(FCWINDOWID_UIHELP, PIXEL_FILL(0), 0, 0, 0xc0, 0x10); AddTextPrinterParameterized4(FCWINDOWID_UIHELP, 0, 188 - width, 0, 0, 2, sTextColor_White, -1, src); FC_PutWindowTilemapAndCopyWindowToVramMode3(FCWINDOWID_UIHELP); } static void DestroyAllFlavorTextIcons(void) { u8 i; for (i = 0; i < 6; i++) { DestroySprite(&gSprites[sFameCheckerData->spriteIds[i]]); } } static bool8 CreateAllFlavorTextIcons(u8 who) { bool8 result = FALSE; u8 i; for (i = 0; i < 6; i++) { if ((gSaveBlock1Ptr->fameChecker[sFameCheckerData->unlockedPersons[who]].flavorTextFlags >> i) & 1) { sFameCheckerData->spriteIds[i] = sub_805EB44( sFameCheckerArrayNpcGraphicsIds[sFameCheckerData->unlockedPersons[who] * 6 + i], i, 47 * (i % 3) + 0x72, 27 * (i / 3) + 0x2F ); result = TRUE; } else { sFameCheckerData->spriteIds[i] = PlaceQuestionMarkTile( 47 * (i % 3) + 0x72, 27 * (i / 3) + 0x1F ); gSprites[sFameCheckerData->spriteIds[i]].data[1] = 0xFF; } } if (result == TRUE) { sFameCheckerData->personHasUnlockedPanels = TRUE; if (sFameCheckerData->inPickMode) PrintUIHelp(1); else PrintUIHelp(0); } else { sFameCheckerData->personHasUnlockedPanels = FALSE; PrintUIHelp(1); } return result; } void ResetFameChecker(void) { u8 i; for (i = 0; i < NUM_FAMECHECKER_PERSONS; i++) { gSaveBlock1Ptr->fameChecker[i].pickState = FCPICKSTATE_NO_DRAW; gSaveBlock1Ptr->fameChecker[i].flavorTextFlags = 0; gSaveBlock1Ptr->fameChecker[i].unk_0_E = 0; } gSaveBlock1Ptr->fameChecker[FAMECHECKER_OAK].pickState = FCPICKSTATE_COLORED; } void FullyUnlockFameChecker(void) { u8 i, j; for (i = 0; i < NUM_FAMECHECKER_PERSONS; i++) { gSaveBlock1Ptr->fameChecker[i].pickState = FCPICKSTATE_COLORED; for (j = 0; j < 6; j++) { gSaveBlock1Ptr->fameChecker[i].flavorTextFlags |= (1 << j); } } } static void FCSetup_ClearVideoRegisters(void) { void * vram = (void *)VRAM; DmaClearLarge16(3, vram, VRAM_SIZE, 0x1000); DmaClear32(3, OAM, OAM_SIZE); DmaClear16(3, PLTT, PLTT_SIZE); SetGpuReg(REG_OFFSET_DISPCNT, 0); SetGpuReg(REG_OFFSET_BG0CNT, 0); SetGpuReg(REG_OFFSET_BG0HOFS, 0); SetGpuReg(REG_OFFSET_BG0VOFS, 0); SetGpuReg(REG_OFFSET_BG1CNT, 0); SetGpuReg(REG_OFFSET_BG1HOFS, 0); SetGpuReg(REG_OFFSET_BG1VOFS, 0); SetGpuReg(REG_OFFSET_BG2CNT, 0); SetGpuReg(REG_OFFSET_BG2HOFS, 0); SetGpuReg(REG_OFFSET_BG2VOFS, 0); SetGpuReg(REG_OFFSET_BG3CNT, 0); SetGpuReg(REG_OFFSET_BG3HOFS, 0); SetGpuReg(REG_OFFSET_BG3VOFS, 0); SetGpuReg(REG_OFFSET_WIN0H, 0); SetGpuReg(REG_OFFSET_WIN0V, 0); SetGpuReg(REG_OFFSET_WININ, 0); SetGpuReg(REG_OFFSET_WINOUT, 0); SetGpuReg(REG_OFFSET_BLDCNT, 0); SetGpuReg(REG_OFFSET_BLDALPHA, 0); SetGpuReg(REG_OFFSET_BLDY, 0); } static void FCSetup_ResetTasksAndSpriteResources(void) { ScanlineEffect_Stop(); ResetTasks(); ResetSpriteData(); ResetAllPicSprites(); ResetPaletteFade(); InitObjectEventPalettes(0); gReservedSpritePaletteCount = 7; } static void FCSetup_TurnOnDisplay(void) { SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_0 | DISPCNT_OBJ_1D_MAP | DISPCNT_BG_ALL_ON | DISPCNT_OBJ_ON); } static void FCSetup_ResetBGCoords(void) { 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); } void SetFlavorTextFlagFromSpecialVars(void) { if (gSpecialVar_0x8004 < NUM_FAMECHECKER_PERSONS && gSpecialVar_0x8005 < 6) { gSaveBlock1Ptr->fameChecker[gSpecialVar_0x8004].flavorTextFlags |= (1 << gSpecialVar_0x8005); gSpecialVar_0x8005 = FCPICKSTATE_SILHOUETTE; UpdatePickStateFromSpecialVar8005(); } } void UpdatePickStateFromSpecialVar8005(void) { if (gSpecialVar_0x8004 < NUM_FAMECHECKER_PERSONS && gSpecialVar_0x8005 < 3) { if (gSpecialVar_0x8005 == FCPICKSTATE_NO_DRAW) return; if ( gSpecialVar_0x8005 == FCPICKSTATE_SILHOUETTE && gSaveBlock1Ptr->fameChecker[gSpecialVar_0x8004].pickState == FCPICKSTATE_COLORED ) return; gSaveBlock1Ptr->fameChecker[gSpecialVar_0x8004].pickState = gSpecialVar_0x8005; } } static bool8 HasUnlockedAllFlavorTextsForCurrentPerson(void) { u8 i; u8 who = sFameCheckerData->unlockedPersons[FameCheckerGetCursorY()]; for (i = 0; i < 6; i++) { if (!((gSaveBlock1Ptr->fameChecker[who].flavorTextFlags >> i) & 1)) return FALSE; } return TRUE; } static void FreeSelectionCursorSpriteResources(void) { FreeSpriteTilesByTag(SPRITETAG_SELECTOR_CURSOR); FreeSpritePaletteByTag(SPRITETAG_SELECTOR_CURSOR); } static u8 CreateFlavorTextIconSelectorCursorSprite(s16 where) { s16 y = 34 + 27 * (where >= 3); s16 x = 114 + 47 * (where % 3); return CreateSprite(&sSpriteTemplate_SelectorCursor, x, y, 0); } static void SpriteCB_DestroyFlavorTextIconSelectorCursor(struct Sprite * sprite) { DestroySprite(sprite); } static void FreeQuestionMarkSpriteResources(void) { FreeSpriteTilesByTag(SPRITETAG_QUESTION_MARK); } static u8 PlaceQuestionMarkTile(u8 x, u8 y) { u8 spriteId = CreateSprite(&sQuestionMarkTileSpriteTemplate, x, y, 8); gSprites[spriteId].oam.priority = 2; gSprites[spriteId].oam.paletteNum = 2; return spriteId; } static void FreeSpinningPokeballSpriteResources(void) { FreeSpriteTilesByTag(SPRITETAG_SPINNING_POKEBALL); FreeSpritePaletteByTag(SPRITETAG_SPINNING_POKEBALL); } static u8 CreateSpinningPokeballSprite(void) { return CreateSprite(&sSpinningPokeballSpriteTemplate, 0xe2, 0x42, 0); } static void SpriteCB_DestroySpinningPokeball(struct Sprite * sprite) { FreeSpriteOamMatrix(sprite); DestroySprite(sprite); } static void FreeNonTrainerPicTiles(void) { FreeSpriteTilesByTag(SPRITETAG_DAISY); FreeSpriteTilesByTag(SPRITETAG_FUJI); FreeSpriteTilesByTag(SPRITETAG_OAK); FreeSpriteTilesByTag(SPRITETAG_BILL); } static void SpriteCB_FCSpinningPokeball(struct Sprite * sprite) { if (sprite->data[0] == 1) { if (sprite->x2 - 10 < 0) { sprite->x2 = 0; sprite->data[0] = 0; } else sprite->x2 -= 10; } else if (sprite->data[0] == 2) { if (sprite->x2 > 240) { sprite->x2 = 240; sprite->data[0] = 0; } else sprite->x2 += 10; } } static u8 CreatePersonPicSprite(u8 fcPersonIdx) { u8 spriteId; if (fcPersonIdx == FAMECHECKER_DAISY) { spriteId = CreateSprite(&sDaisySpriteTemplate, 0x94, 0x42, 0); LoadPalette(sDaisySpritePalette, 0x160, 0x20); gSprites[spriteId].oam.paletteNum = 6; } else if (fcPersonIdx == FAMECHECKER_MRFUJI) { spriteId = CreateSprite(&sFujiSpriteTemplate, 0x94, 0x42, 0); LoadPalette(sFujiSpritePalette, 0x160, 0x20); gSprites[spriteId].oam.paletteNum = 6; } else if (fcPersonIdx == FAMECHECKER_OAK) { spriteId = CreateSprite(&sOakSpriteTemplate, 0x94, 0x42, 0); LoadPalette(sOakSpritePalette, 0x160, 0x20); gSprites[spriteId].oam.paletteNum = 6; } else if (fcPersonIdx == FAMECHECKER_BILL) { spriteId = CreateSprite(&sBillSpriteTemplate, 0x94, 0x42, 0); LoadPalette(sBillSpritePalette, 0x160, 0x20); gSprites[spriteId].oam.paletteNum = 6; } else { spriteId = CreateTrainerPicSprite(sFameCheckerTrainerPicIdxs[fcPersonIdx], 1, 0x94, 0x42, 6, 0xFFFF); } gSprites[spriteId].callback = SpriteCB_FCSpinningPokeball; if (gSaveBlock1Ptr->fameChecker[fcPersonIdx].pickState == FCPICKSTATE_SILHOUETTE) LoadPalette(sSilhouettePalette, 0x160, 0x20); return spriteId; } static void DestroyPersonPicSprite(u8 taskId, u16 who) { s16 * data = gTasks[taskId].data; u16 who_copy = who; if (who == sFameCheckerData->numUnlockedPersons - 1) who_copy = who - 1; if ( sFameCheckerData->unlockedPersons[who_copy] == FAMECHECKER_DAISY || sFameCheckerData->unlockedPersons[who_copy] == FAMECHECKER_MRFUJI || sFameCheckerData->unlockedPersons[who_copy] == FAMECHECKER_OAK || sFameCheckerData->unlockedPersons[who_copy] == FAMECHECKER_BILL ) DestroySprite(&gSprites[data[2]]); else FreeAndDestroyTrainerPicSprite(data[2]); } static void UpdateIconDescriptionBox(u8 whichText) { s32 width; u32 idx = 6 * sFameCheckerData->unlockedPersons[FameCheckerGetCursorY()] + whichText; HandleFlavorTextModeSwitch(TRUE); gIconDescriptionBoxIsOpen = 1; FillWindowPixelRect(FCWINDOWID_ICONDESC, PIXEL_FILL(0), 0, 0, 0x58, 0x20); width = (0x54 - GetStringWidth(0, sFlavorTextOriginLocationTexts[idx], 0)) / 2; AddTextPrinterParameterized4(FCWINDOWID_ICONDESC, 0, width, 0, 0, 2, sTextColor_DkGrey, -1, sFlavorTextOriginLocationTexts[idx]); StringExpandPlaceholders(gStringVar1, sFlavorTextOriginObjectNameTexts[idx]); width = (0x54 - GetStringWidth(0, gStringVar1, 0)) / 2; AddTextPrinterParameterized4(FCWINDOWID_ICONDESC, 0, width, 10, 0, 2, sTextColor_DkGrey, -1, gStringVar1); FC_PutWindowTilemapAndCopyWindowToVramMode3(FCWINDOWID_ICONDESC); } static void UpdateIconDescriptionBoxOff(void) { HandleFlavorTextModeSwitch(FALSE); gIconDescriptionBoxIsOpen = 0xFF; } static void FC_CreateListMenu(void) { InitListMenuTemplate(); sFameCheckerData->numUnlockedPersons = FC_PopulateListMenu(); sFameCheckerData->listMenuTaskId = ListMenuInit(&gFameChecker_ListMenuTemplate, 0, 0); FC_PutWindowTilemapAndCopyWindowToVramMode3_2(FCWINDOWID_LIST); } static void InitListMenuTemplate(void) { gFameChecker_ListMenuTemplate.items = sListMenuItems; gFameChecker_ListMenuTemplate.moveCursorFunc = FC_MoveCursorFunc; gFameChecker_ListMenuTemplate.itemPrintFunc = NULL; gFameChecker_ListMenuTemplate.totalItems = 1; gFameChecker_ListMenuTemplate.maxShowed = 1; gFameChecker_ListMenuTemplate.windowId = FCWINDOWID_LIST; gFameChecker_ListMenuTemplate.header_X = 0; gFameChecker_ListMenuTemplate.item_X = 8; gFameChecker_ListMenuTemplate.cursor_X = 0; gFameChecker_ListMenuTemplate.upText_Y = 4; gFameChecker_ListMenuTemplate.cursorPal = 2; gFameChecker_ListMenuTemplate.fillValue = 0; gFameChecker_ListMenuTemplate.cursorShadowPal = 3; gFameChecker_ListMenuTemplate.lettersSpacing = 0; gFameChecker_ListMenuTemplate.itemVerticalPadding = 0; gFameChecker_ListMenuTemplate.scrollMultiple = 0; gFameChecker_ListMenuTemplate.fontId = 2; gFameChecker_ListMenuTemplate.cursorKind = 0; } static void FC_MoveCursorFunc(s32 itemIndex, bool8 onInit, struct ListMenu *list) { u16 listMenuTopIdx; u8 taskId; u16 personIdx; sLastMenuIdx = 0; personIdx = sFameCheckerData->listMenuTopIdx2 + sFameCheckerData->listMenuDrawnSelIdx; FC_DoMoveCursor(itemIndex, onInit); taskId = FindTaskIdByFunc(Task_TopMenuHandleInput); if (taskId != 0xFF) { struct Task *task = &gTasks[taskId]; PlaySE(SE_SELECT); task->data[1] = 0; ListMenuGetScrollAndRow(sFameCheckerData->listMenuTaskId, &listMenuTopIdx, NULL); sFameCheckerData->listMenuTopIdx = listMenuTopIdx; if (itemIndex != sFameCheckerData->numUnlockedPersons - 1) { DestroyAllFlavorTextIcons(); CreateAllFlavorTextIcons(itemIndex); if (sFameCheckerData->inPickMode) { if (!sFameCheckerData->pickModeOverCancel) { DestroyPersonPicSprite(taskId, personIdx); sLastMenuIdx = itemIndex; task->func = Task_SwitchToPickMode; } else { gSprites[task->data[2]].invisible = FALSE; sFameCheckerData->pickModeOverCancel = FALSE; gSprites[task->data[2]].data[0] = 0; GetPickModeText(); } } else { FillWindowPixelRect(FCWINDOWID_MSGBOX, PIXEL_FILL(1), 0, 0, 0xd0, 0x20); FC_PutWindowTilemapAndCopyWindowToVramMode3(FCWINDOWID_MSGBOX); } } else { PrintCancelDescription(); if (sFameCheckerData->inPickMode) { gSprites[task->data[2]].invisible = TRUE; sFameCheckerData->pickModeOverCancel = TRUE; } else { u8 i; for (i = 0; i < 6; i++) { gSprites[sFameCheckerData->spriteIds[i]].invisible = TRUE; } } } } } static void Task_SwitchToPickMode(u8 taskId) { struct Task * task = &gTasks[taskId]; task->data[2] = CreatePersonPicSprite(sFameCheckerData->unlockedPersons[sLastMenuIdx]); gSprites[task->data[2]].data[0] = 0; GetPickModeText(); task->func = Task_TopMenuHandleInput; } static void PrintCancelDescription(void) { FillWindowPixelRect(FCWINDOWID_MSGBOX, PIXEL_FILL(1), 0, 0, 0xd0, 0x20); AddTextPrinterParameterized2(FCWINDOWID_MSGBOX, 2, gFameCheckerText_FameCheckerWillBeClosed, 0, NULL, 2, 1, 3); FC_PutWindowTilemapAndCopyWindowToVramMode3(FCWINDOWID_MSGBOX); } static void FC_DoMoveCursor(s32 itemIndex, bool8 onInit) { u16 listY; u16 cursorY; u16 who; ListMenuGetScrollAndRow(sFameCheckerData->listMenuTaskId, &listY, &cursorY); who = listY + cursorY; AddTextPrinterParameterized4(FCWINDOWID_LIST, 2, 8, 14 * cursorY + 4, 0, 0, sTextColor_Green, 0, sListMenuItems[itemIndex].label); if (!onInit) { if (listY < sFameCheckerData->listMenuTopIdx2) sFameCheckerData->listMenuDrawnSelIdx++; else if (listY > sFameCheckerData->listMenuTopIdx2 && who != sFameCheckerData->numUnlockedPersons - 1) sFameCheckerData->listMenuDrawnSelIdx--; AddTextPrinterParameterized4(FCWINDOWID_LIST, 2, 8, 14 * sFameCheckerData->listMenuDrawnSelIdx + 4, 0, 0, sTextColor_DkGrey, 0, sListMenuItems[sFameCheckerData->listMenuCurIdx].label); } sFameCheckerData->listMenuCurIdx = itemIndex; sFameCheckerData->listMenuDrawnSelIdx = cursorY; sFameCheckerData->listMenuTopIdx2 = listY; } static u8 FC_PopulateListMenu(void) { u8 nitems = 0; u8 i; for (i = 0; i < NUM_FAMECHECKER_PERSONS; i++) { u8 fameCheckerIdx = AdjustGiovanniIndexIfBeatenInGym(i); if (gSaveBlock1Ptr->fameChecker[fameCheckerIdx].pickState != FCPICKSTATE_NO_DRAW) { if (sTrainerIdxs[fameCheckerIdx] < FC_NONTRAINER_START) { sListMenuItems[nitems].label = gTrainers[sTrainerIdxs[fameCheckerIdx]].trainerName; sListMenuItems[nitems].index = nitems; } else { sListMenuItems[nitems].label = sNonTrainerNamePointers[sTrainerIdxs[fameCheckerIdx] - FC_NONTRAINER_START]; sListMenuItems[nitems].index = nitems; } sFameCheckerData->unlockedPersons[nitems] = fameCheckerIdx; nitems++; } } sListMenuItems[nitems].label = gFameCheckerText_Cancel; sListMenuItems[nitems].index = nitems; sFameCheckerData->unlockedPersons[nitems] = 0xFF; nitems++; gFameChecker_ListMenuTemplate.totalItems = nitems; if (nitems < 5) gFameChecker_ListMenuTemplate.maxShowed = nitems; else gFameChecker_ListMenuTemplate.maxShowed = 5; return nitems; } static void FC_PutWindowTilemapAndCopyWindowToVramMode3_2(u8 windowId) { PutWindowTilemap(windowId); CopyWindowToVram(windowId, COPYWIN_BOTH); } static void FC_CreateScrollIndicatorArrowPair(void) { struct ScrollArrowsTemplate template = { 2, 40, 26, 3, 40, 100, 0, 0, SPRITETAG_SCROLL_INDICATORS, 0xFFFF, 1, }; if (sFameCheckerData->numUnlockedPersons > 5) { template.fullyUpThreshold = 0; template.fullyDownThreshold = sFameCheckerData->numUnlockedPersons - 5; sFameCheckerData->scrollIndicatorPairTaskId = AddScrollIndicatorArrowPair(&template, &sFameCheckerData->listMenuTopIdx); } } static void FreeListMenuSelectorArrowPairResources(void) { if (sFameCheckerData->numUnlockedPersons > 5) RemoveScrollIndicatorArrowPair(sFameCheckerData->scrollIndicatorPairTaskId); } static u16 FameCheckerGetCursorY(void) { u16 listY, cursorY; ListMenuGetScrollAndRow(sFameCheckerData->listMenuTaskId, &listY, &cursorY); return listY + cursorY; } static void HandleFlavorTextModeSwitch(bool8 state) { if (sFameCheckerData->viewingFlavorText != state) { u8 taskId = FindTaskIdByFunc(Task_FCOpenOrCloseInfoBox); if (taskId == 0xFF) taskId = CreateTask(Task_FCOpenOrCloseInfoBox, 8); gTasks[taskId].data[0] = 0; gTasks[taskId].data[1] = 4; if (state == TRUE) { gTasks[taskId].data[2] = 1; sFameCheckerData->viewingFlavorText = TRUE; } else { gTasks[taskId].data[2] = 4; sFameCheckerData->viewingFlavorText = FALSE; } } } static void Task_FCOpenOrCloseInfoBox(u8 taskId) { struct Task * task = &gTasks[taskId]; switch (task->data[0]) { case 0: if (--task->data[1] == 0) { UpdateInfoBoxTilemap(1, 0); task->data[1] = 4; task->data[0]++; } break; case 1: if (--task->data[1] == 0) { UpdateInfoBoxTilemap(1, task->data[2]); DestroyTask(taskId); } break; } } static void UpdateInfoBoxTilemap(u8 bg, s16 state) { if (state == 0 || state == 3) { FillBgTilemapBufferRect(bg, 0x8C, 14, 10, 1, 1, 1); FillBgTilemapBufferRect(bg, 0xA1, 15, 10, 10, 1, 1); FillBgTilemapBufferRect(bg, 0x8D, 25, 10, 1, 1, 1); FillBgTilemapBufferRect(bg, 0x8E, 26, 10, 1, 1, 1); FillBgTilemapBufferRect(bg, 0x8F, 14, 11, 1, 1, 1); FillBgTilemapBufferRect(bg, 0x00, 15, 11, 11, 1, 1); FillBgTilemapBufferRect(bg, 0x90, 26, 11, 1, 1, 1); FillBgTilemapBufferRect(bg, 0x91, 14, 12, 1, 1, 1); FillBgTilemapBufferRect(bg, 0xA3, 15, 12, 10, 1, 1); FillBgTilemapBufferRect(bg, 0x92, 25, 12, 1, 1, 1); FillBgTilemapBufferRect(bg, 0x93, 26, 12, 1, 1, 1); } else if (state == 1) { FillBgTilemapBufferRect(bg, 0x9B, 14, 10, 1, 1, 1); FillBgTilemapBufferRect(bg, 0x9C, 15, 10, 11, 1, 1); FillBgTilemapBufferRect(bg, 0x96, 26, 10, 1, 1, 1); FillBgTilemapBufferRect(bg, 0x9D, 14, 11, 1, 1, 1); FillBgTilemapBufferRect(bg, 0x00, 15, 11, 11, 1, 1); FillBgTilemapBufferRect(bg, 0x90, 26, 11, 1, 1, 1); FillBgTilemapBufferRect(bg, 0x9E, 14, 12, 1, 1, 1); FillBgTilemapBufferRect(bg, 0x9F, 15, 12, 11, 1, 1); FillBgTilemapBufferRect(bg, 0x99, 26, 12, 1, 1, 1); } else if (state == 2) { FillBgTilemapBufferRect(bg, 0x94, 14, 10, 1, 1, 1); FillBgTilemapBufferRect(bg, 0x95, 15, 10, 11, 1, 1); FillBgTilemapBufferRect(bg, 0x96, 26, 10, 1, 1, 1); FillBgTilemapBufferRect(bg, 0x8F, 14, 11, 1, 1, 1); FillBgTilemapBufferRect(bg, 0x9A, 15, 11, 11, 1, 1); FillBgTilemapBufferRect(bg, 0x90, 26, 11, 1, 1, 1); FillBgTilemapBufferRect(bg, 0x97, 14, 12, 1, 1, 1); FillBgTilemapBufferRect(bg, 0x98, 15, 12, 11, 1, 1); FillBgTilemapBufferRect(bg, 0x99, 26, 12, 1, 1, 1); } else if (state == 4) { FillBgTilemapBufferRect(bg, 0x83, 14, 10, 1, 1, 1); FillBgTilemapBufferRect(bg, 0xA0, 15, 10, 10, 1, 1); FillBgTilemapBufferRect(bg, 0x84, 25, 10, 1, 1, 1); FillBgTilemapBufferRect(bg, 0x85, 26, 10, 1, 1, 1); FillBgTilemapBufferRect(bg, 0x86, 14, 11, 1, 1, 1); FillBgTilemapBufferRect(bg, 0xA2, 15, 11, 10, 1, 1); FillBgTilemapBufferRect(bg, 0x87, 25, 11, 1, 1, 1); FillBgTilemapBufferRect(bg, 0x88, 26, 11, 1, 1, 1); FillBgTilemapBufferRect(bg, 0x83, 14, 12, 1, 1, 1); FillBgTilemapBufferRect(bg, 0xA0, 15, 12, 10, 1, 1); FillBgTilemapBufferRect(bg, 0x84, 25, 12, 1, 1, 1); FillBgTilemapBufferRect(bg, 0x85, 26, 12, 1, 1, 1); } else if (state == 5) { FillBgTilemapBufferRect(bg, 0x00, 14, 10, 13, 3, 1); } CopyBgTilemapBufferToVram(bg); } static void PlaceListMenuCursor(bool8 isActive) { u16 cursorY = ListMenuGetYCoordForPrintingArrowCursor(sFameCheckerData->listMenuTaskId); if (isActive == TRUE) AddTextPrinterParameterized4(FCWINDOWID_LIST, 2, 0, cursorY, 0, 0, sTextColor_DkGrey, 0, gText_SelectorArrow2); else AddTextPrinterParameterized4(FCWINDOWID_LIST, 2, 0, cursorY, 0, 0, sTextColor_White, 0, gText_SelectorArrow2); }