diff options
author | PikalaxALT <PikalaxALT@users.noreply.github.com> | 2019-12-11 18:20:58 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-12-11 18:20:58 -0500 |
commit | f12824e3b1643f86599e2c03c96b752a87a73746 (patch) | |
tree | ea95b65775cf7caf2089ea21f47a07c8571413bd /src | |
parent | 7526b2ccf1ab02a975ee477341f8accbf3f108c5 (diff) | |
parent | b43c48202ba3b3a1cd31c8abf1a726bf8980f043 (diff) |
Merge pull request #180 from ghoulslash/trainer-card
Trainer card
Diffstat (limited to 'src')
-rw-r--r-- | src/money.c | 6 | ||||
-rw-r--r-- | src/pokedex.c | 2 | ||||
-rw-r--r-- | src/start_menu.c | 4 | ||||
-rw-r--r-- | src/trainer_card.c | 1932 |
4 files changed, 1937 insertions, 7 deletions
diff --git a/src/money.c b/src/money.c index 39e5aaa32..323b2e5f6 100644 --- a/src/money.c +++ b/src/money.c @@ -4,9 +4,7 @@ #include "string_util.h" #include "menu.h" #include "text_window.h" - -extern const u8 gText_PokedollarVar1[]; -extern const u8 gUnknown_8419CE7[]; +#include "strings.h" #define MAX_MONEY 999999 @@ -110,7 +108,7 @@ void PrintMoneyAmount(u8 windowId, u8 x, u8 y, int amount, u8 speed) void PrintMoneyAmountInMoneyBoxWithBorder(u8 windowId, u16 tileStart, u8 pallete, int amount) { DrawStdFrameWithCustomTileAndPalette(windowId, FALSE, tileStart, pallete); - AddTextPrinterParameterized(windowId, 2, gUnknown_8419CE7, 0, 0, 0xFF, 0); + AddTextPrinterParameterized(windowId, 2, gText_TrainerCardMoney, 0, 0, 0xFF, 0); PrintMoneyAmountInMoneyBox(windowId, amount, 0); } diff --git a/src/pokedex.c b/src/pokedex.c index 84ca59549..1354aac8c 100644 --- a/src/pokedex.c +++ b/src/pokedex.c @@ -88,7 +88,7 @@ bool16 HasAllHoennMons(void) return TRUE; } -bool8 HasAllKantoMons(void) +bool16 HasAllKantoMons(void) { u16 i; diff --git a/src/start_menu.c b/src/start_menu.c index 2a1713902..31bb3beb7 100644 --- a/src/start_menu.c +++ b/src/start_menu.c @@ -504,7 +504,7 @@ static bool8 StartMenuPlayerCallback(void) PlayRainStoppingSoundEffect(); DestroySafariZoneStatsWindow(); CleanupOverworldWindowsAndTilemaps(); - InitTrainerCard(CB2_ReturnToFieldWithOpenMenu); + ShowPlayerTrainerCard(CB2_ReturnToFieldWithOpenMenu); return TRUE; } return FALSE; @@ -554,7 +554,7 @@ static bool8 StartMenuLinkPlayerCallback(void) { PlayRainStoppingSoundEffect(); CleanupOverworldWindowsAndTilemaps(); - InitLinkPartnerTrainerCard(gUnknown_300502C, CB2_ReturnToFieldWithOpenMenu); + ShowTrainerCardInLink(gUnknown_300502C, CB2_ReturnToFieldWithOpenMenu); return TRUE; } return FALSE; diff --git a/src/trainer_card.c b/src/trainer_card.c new file mode 100644 index 000000000..766935244 --- /dev/null +++ b/src/trainer_card.c @@ -0,0 +1,1932 @@ +#include "global.h" +#include "scanline_effect.h" +#include "palette.h" +#include "task.h" +#include "main.h" +#include "window.h" +#include "malloc.h" +#include "link.h" +#include "bg.h" +#include "sound.h" +#include "overworld.h" +#include "menu.h" +#include "text.h" +#include "event_data.h" +#include "easy_chat.h" +#include "money.h" +#include "window.h" +#include "strings.h" +#include "string_util.h" +#include "trainer_card.h" +#include "gpu_regs.h" +#include "pokedex.h" +#include "pokemon_icon.h" +#include "graphics.h" +#include "pokemon_icon.h" +#include "help_system.h" +#include "trainer_pokemon_sprites.h" +#include "new_menu_helpers.h" +#include "constants/songs.h" +#include "constants/flags.h" +#include "constants/game_stat.h" +#include "constants/vars.h" +#include "constants/species.h" + +#define BADGE_COUNT 8 + +// Trainer Card Types +enum +{ + CARD_TYPE_FRLG, + CARD_TYPE_EMERALD, +}; + +// Trainer Card Strings +enum +{ + TRAINER_CARD_STRING_NAME = 0, + TRAINER_CARD_STRING_HOF_TIME, + TRAINER_CARD_STRING_LINK_RECORD, + TRAINER_CARD_STRING_WIN_LOSS, + TRAINER_CARD_STRING_LINK_WINS, + TRAINER_CARD_STRING_LINK_LOSSES, + TRAINER_CARD_STRING_TRADES, + TRAINER_CARD_STRING_TRADE_COUNT, + TRAINER_CARD_STRING_BERRY_CRUSH, + TRAINER_CARD_STRING_BERRY_CRUSH_COUNT, + TRAINER_CARD_STRING_UNION_ROOM, + TRAINER_CARD_STRING_UNION_ROOM_NUM, + TRAINER_CARD_STRING_COUNT, +}; + +struct TrainerCardData +{ + /*0x0000*/ u8 taskState; + /*0x0001*/ u8 printState; + /*0x0002*/ u8 gfxLoadState; + /*0x0003*/ u8 bgPalLoadState; + /*0x0004*/ u8 var_4; + /*0x0005*/ bool8 isLink; + /*0x0006*/ u8 var_6; + /*0x0007*/ u8 var_7; + /*0x0008*/ u8 var_8; + /*0x0009*/ bool8 allowDMACopy; + /*0x000A*/ bool8 hasPokedex; + /*0x000B*/ bool8 hasHofResult; + /*0x000C*/ bool8 hasLinkResults; + /*0x000D*/ bool8 hasBattleTowerWins; + /*0x000E*/ u8 var_E; + /*0x000F*/ u8 var_F; + /*0x0010*/ bool8 hasTrades; + /*0x0011*/ bool8 hasBadge[BADGE_COUNT]; + /*0x0019*/ u8 var_19[4][13]; + /*0x004D*/ u8 strings[TRAINER_CARD_STRING_COUNT][70]; + /*0x0395*/ u8 var_395; + /*0x0396*/ u16 monIconPals[0x30]; + /*0x03F6*/ u8 var_3DB[0x60]; + /*0x0456*/ s8 var_456; + /*0x0457*/ u8 cardType; + /*0x0458*/ void (*callback2)(void); + /*0x045C*/ struct TrainerCard trainerCard; + /*0x04BC*/ u16 var_4BC; + /*0x04BE*/ u8 var_4BE[0x4AE]; + /*0x096C*/ u16 var_96C[0x258]; + /*0x0E1C*/ u16 var_E1C; + /*0x0E1E*/ u8 unk_E1E[0x4AE]; + /*0x12CC*/ u16 cardTiles[0x200]; + /*0x16CC*/ u16 bgTiles[0x100]; + /*0x18CC*/ u16 var_18CC[0x1180]; + /*0x3BCC*/ u16 bgTilemap0[0x1000]; + /*0x5BCC*/ u16 bgTilemap2[0x1000]; + /*0x7BCC*/ u16 var_7BCC; + /*0x7BCE*/ bool8 var_7BCE; + /*0x7BCF*/ u8 language; +}; /* size = 0x7BD0 */ + +// RAM +EWRAM_DATA struct TrainerCard gTrainerCards[4] = {0}; +EWRAM_DATA static struct TrainerCardData *sTrainerCardDataPtr = NULL; + +// Function Declaration +static void VBlankCB_TrainerCard(void); +static void HBlankCB_TrainerCard(void); +static void CB2_TrainerCard(void); +static void CloseTrainerCard(u8 taskId); +static void Task_TrainerCard(u8 taskId); +static bool8 LoadCardGfx(void); +static void CB2_InitTrainerCard(void); +static u32 GetCappedGameStat(u8 statId, u32 maxValue); +static u8 GetTrainerStarCount(struct TrainerCard *trainerCard); +static void SetPlayerCardData(struct TrainerCard *trainerCard, u8 cardType); +static void SetDataFromTrainerCard(void); +static void HandleGpuRegs(void); +static void sub_8089BD8(u16 arg0); +static void ResetGpuRegs(void); +static void TrainerCardNull(void); +static void sub_8089C5C(void); +static void sub_8089C80(void); +static void sub_8089CA4(void); +static void ResetTrainerCard(void); +static void SetTrainerCardCB2(void); +static void sub_8089DA4(void); +static bool8 PrintAllOnCardPage1(void); +static bool8 PrintStringsOnCardPage2(void); +static void sub_8089ECC(void); +static void PrintNameOnCard(void); +static void PrintIdOnCard(void); +static void PrintMoneyOnCard(void); +static u16 GetCaughtMonsCount(void); +static void PrintPokedexOnCard(void); +static void PrintTimeOnCard(void); +static void PrintProfilePhraseOnCard(void); +static void PrintNameOnCard2(void); +static void sub_808A4FC(void); +static void PrintHofTimeOnCard(void); +static void PrintHofDebutStringOnCard(void); +static void PrintLinkResultsNumsOnCard(void); +static void PrintWinsLossesStringOnCard(void); +static void PrintTradesNumOnCard(void); +static void PrintTradesStringOnCard(void); +static void PrintBerryCrushNumOnCard(void); +static void PrintBerryCrushStringOnCard(void); +static void PrintUnionNumOnCard(void); +static void PrintUnionStringOnCard(void); +static void TrainerCard_PrintPokemonIconsOnCard(void); +static void sub_808AB10(void); +static void sub_808ABE0(void); +static void TrainerCardLoadStickerPals(void); +static void PutTrainerCardWindow(u8 windowId); +static bool8 SetTrainerCardBgsAndPals(void); +static void LoadTrainerCardTilemap2(const u16* ptr); +static void LoadTrainerCardTilemap0(const u16* ptr); +static void TrainerCard_PrintStarsAndBadgesOnCard(void); +static void sub_808B090(void); +static void sub_808B180(void); +static void sub_808B1D4(void); +static bool8 sub_808B1FC(void); +static void sub_808B21C(u8 taskId); +static bool8 sub_808B254(struct Task* task); +static bool8 sub_808B294(struct Task* task); +static bool8 sub_808B3C4(struct Task* task); +static bool8 sub_808B4D8(struct Task* task); +static bool8 sub_808B540(struct Task* task); +static bool8 sub_808B66C(struct Task *task); +static void sub_808B774(void); +static u8 GetCardType(void); +static void sub_808B838(void); + +// Data +static const u32 sTrainerCardStickers[] = INCBIN_U32("graphics/trainer_card/stickers.4bpp.lz"); +static const u32 sUnknown_83CC4DC[] = INCBIN_U32("graphics/trainer_card/unk_83CC4DC.bin"); +static const u32 sUnknown_83CC6F0[] = INCBIN_U32("graphics/trainer_card/unk_83CC6F0.bin"); +static const u32 sUnknown_83CC8A8[] = INCBIN_U32("graphics/trainer_card/unk_83CC8A8.bin"); +static const u32 sUnknown_83CC984[] = INCBIN_U32("graphics/trainer_card/unk_83CC984.bin"); +static const u32 sUnknown_83CCAB0[] = INCBIN_U32("graphics/trainer_card/unk_83CCAB0.bin"); +static const u32 sUnknown_83CCCA4[] = INCBIN_U32("graphics/trainer_card/unk_83CCCA4.bin"); +static const u32 sUnknown_83CCE30[] = INCBIN_U32("graphics/trainer_card/unk_83CCE30.bin"); +static const u32 sUnknown_83CCEC8[] = INCBIN_U32("graphics/trainer_card/unk_83CCEC8.bin"); +static const u16 sEmeraldTrainerCard1Stars_Pals[] = INCBIN_U16("graphics/trainer_card/em_1stars_pals.gbapal"); +static const u16 sFireRedTrainerCard1Stars_Pals[] = INCBIN_U16("graphics/trainer_card/fr_1stars_pals.gbapal"); +static const u16 sEmeraldTrainerCard2Stars_Pals[] = INCBIN_U16("graphics/trainer_card/em_2stars_pals.gbapal"); +static const u16 sFireRedTrainerCard2Stars_Pals[] = INCBIN_U16("graphics/trainer_card/fr_2stars_pals.gbapal"); +static const u16 sEmeraldTrainerCard3Stars_Pals[] = INCBIN_U16("graphics/trainer_card/em_3stars_pals.gbapal"); +static const u16 sFireRedTrainerCard3Stars_Pals[] = INCBIN_U16("graphics/trainer_card/fr_3stars_pals.gbapal"); +static const u16 sEmeraldTrainerCard4Stars_Pals[] = INCBIN_U16("graphics/trainer_card/em_4stars_pals.gbapal"); +static const u16 sFireRedTrainerCard4Stars_Pals[] = INCBIN_U16("graphics/trainer_card/fr_4stars_pals.gbapal"); +static const u16 sEmeraldTrainerCardFemaleBackground_Pal[] = INCBIN_U16("graphics/trainer_card/em_female_bg.gbapal"); +static const u16 sFireRedTrainerCardFemaleBackground_Pal[] = INCBIN_U16("graphics/trainer_card/fr_female_bg.gbapal"); +static const u16 sEmeraldTrainerCardBadges_Pal[] = INCBIN_U16("graphics/trainer_card/em_badges.gbapal"); +static const u16 sFireRedTrainerCardBadges_Pal[] = INCBIN_U16("graphics/trainer_card/fr_badges.gbapal"); +static const u16 sUnknown_83CD300[] = INCBIN_U16("graphics/trainer_card/unk_83CD300.gbapal"); +static const u16 sTrainerCardStickerPal1[] = INCBIN_U16("graphics/trainer_card/sticker1.gbapal"); +static const u16 sTrainerCardStickerPal2[] = INCBIN_U16("graphics/trainer_card/sticker2.gbapal"); +static const u16 sTrainerCardStickerPal3[] = INCBIN_U16("graphics/trainer_card/sticker3.gbapal"); +static const u16 sTrainerCardStickerPal4[] = INCBIN_U16("graphics/trainer_card/sticker4.gbapal"); +static const u32 sEmeraldTrainerCardBadges_Tile[] = INCBIN_U32("graphics/trainer_card/em_badges.4bpp.lz"); +static const u32 sFireRedTrainerCardBadges_Tile[] = INCBIN_U32("graphics/trainer_card/badges.4bpp.lz"); + +static const struct BgTemplate sTrainerCardBgTemplates[4] = +{ + { + .bg = 0, + .charBaseIndex = 0, + .mapBaseIndex = 27, + .screenSize = 2, + .paletteMode = 0, + .priority = 2, + .baseTile = 0 + }, + { + .bg = 1, + .charBaseIndex = 2, + .mapBaseIndex = 29, + .screenSize = 0, + .paletteMode = 0, + .priority = 0, + .baseTile = 0 + }, + { + .bg = 2, + .charBaseIndex = 0, + .mapBaseIndex = 30, + .screenSize = 0, + .paletteMode = 0, + .priority = 3, + .baseTile = 0 + }, + { + .bg = 3, + .charBaseIndex = 0, + .mapBaseIndex = 31, + .screenSize = 0, + .paletteMode = 0, + .priority = 1, + .baseTile = 192 + } +}; + +static const struct WindowTemplate sTrainerCardWindowTemplates[4] = +{ + { + .bg = 1, + .tilemapLeft = 2, + .tilemapTop = 15, + .width = 26, + .height = 4, + .paletteNum = 15, + .baseBlock = 0x241 + }, + { + .bg = 1, + .tilemapLeft = 1, + .tilemapTop = 1, + .width = 27, + .height = 18, + .paletteNum = 15, + .baseBlock = 0x1 + }, + { + .bg = 3, + .tilemapLeft = 19, + .tilemapTop = 5, + .width = 9, + .height = 10, + .paletteNum = 8, + .baseBlock = 0x150 + }, + DUMMY_WIN_TEMPLATE +}; + +static const u16 *const sEmeraldTrainerCardStarPals[] = +{ + gEmeraldTrainerCard_Pal, + sEmeraldTrainerCard1Stars_Pals, + sEmeraldTrainerCard2Stars_Pals, + sEmeraldTrainerCard3Stars_Pals, + sEmeraldTrainerCard4Stars_Pals +}; + +static const u16 *const sFireRedTrainerCardStarPals[] = +{ + gFireRedTrainerCard_Pal, + sFireRedTrainerCard1Stars_Pals, + sFireRedTrainerCard2Stars_Pals, + sFireRedTrainerCard3Stars_Pals, + sFireRedTrainerCard4Stars_Pals +}; + +static const u8 sFireRedTrainerCardPage1TextColors[] = {TEXT_COLOR_TRANSPARENT, TEXT_COLOR_DARK_GREY, TEXT_COLOR_LIGHT_GREY}; +static const u8 sTrainerCardPage2TextColors[] = {TEXT_COLOR_TRANSPARENT, TEXT_COLOR_RED, TEXT_COLOR_LIGHT_RED}; +static const u8 sEmeraldTrainerCardPage1TextColors[] = {TEXT_COLOR_TRANSPARENT, TEXT_COLOR_TRANSPARENT, TEXT_COLOR_TRANSPARENT}; +static const u8 sTrainerCardFontIds[] = {0, 2, 0}; + +static const u8 sTrainerCardPicPositions[][2][2] = +{ + {{13, 4}, {13, 4}}, + {{1, 0}, {1, 0}} +}; + +static const u8 sLinkTrainerCardFrontPics[][2] = +{ + {TRAINER_PIC_RS_MAY_2, TRAINER_PIC_RED}, + {TRAINER_PIC_PROFESSOR_OAK, TRAINER_PIC_RS_BRENDAN_2}, +}; + +static const u8 sLinkTrainerCardFacilityClasses[][8] = +{ + {0x74, 0x6F, 0x5C, 0x58, 0x6A, 0x59, 0x6D, 0x6C}, + {0x75, 0x7D, 0x5D, 0x5A, 0x16, 0x30, 0x41, 0x68} +}; + +static bool8 (*const sTrainerCardTasks[])(struct Task *) = +{ + sub_808B254, + sub_808B294, + sub_808B3C4, + sub_808B4D8, + sub_808B540, + sub_808B66C +}; + +static const u8 sTrainerCardPlayerNameXPositions[] = {0x14, 0x10}; +static const u8 sTrainerCardPlayerNameYPositions[] = {0x1D, 0x21}; +static const u8 sTrainerCardIdXPositions[] = {0x8E, 0x80}; +static const u8 sTrainerCardIdYPositions[] = {0xA, 0x9}; +static const u8 *const sTrainerCardTextColors[] = {sFireRedTrainerCardPage1TextColors, sEmeraldTrainerCardPage1TextColors}; +static const u8 sTrainerCardTimeHoursXPositions[] = {0x65, 0x55}; +static const u8 sTrainerCardTimeHoursYPositions[] = {0x77, 0x67}; +static const u8 sTrainerCardTimeMinutesXPositions[] = {0x7C, 0x6C}; +static const u8 sTrainerCardTimeMinutesYPositions[] = {0x58, 0x59}; +static const u8 sTrainerCardProfilePhraseXPositions[] = {0x73, 0x69}; +static const u8 sTrainerCardProfilePhraseYPositions[] = {0x82, 0x78}; +static const u8 sUnknown_83CD93C[] = {0x8A, 0xD8}; +static const u8 sUnknown_83CD93E[] = {0xB, 0xA}; +static const u8 sTrainerCardHofDebutXPositions[] = {0xA, 0x10, 0x0, 0x0}; +static const u8 *const sLinkTrainerCardRecordStrings[] = {gText_LinkBattles, gText_LinkCableBattles}; +static const u8 sUnknown_83CD94C[] = {5, 6, 7, 8, 9, 10}; +static const u8 sUnknown_83CD952[] = {0, 4, 8, 12, 16, 20}; +static const u8 sUnknown_83CD958[] = {11, 12, 13, 14}; +static const u8 sUnknown_83CD95C[] = {7, 6, 0, 0}; + +static const struct TrainerCard sLinkPlayerTrainerCardTemplate1 = +{ + .gender = MALE, + .stars = 4, + .hasPokedex = TRUE, + .caughtAllHoenn = TRUE, + .hasAllPaintings = TRUE, + .hofDebutHours = 999, + .hofDebutMinutes = 59, + .hofDebutSeconds = 59, + .caughtMonsCount = 200, + .trainerId = 0x6072, + .playTimeHours = 999, + .playTimeMinutes = 59, + .linkBattleWins = 5535, + .linkBattleLosses = 5535, + .battleTowerWins = 5535, + .battleTowerStraightWins = 5535, + .contestsWithFriends = 55555, + .pokeblocksWithFriends = 44444, + .pokemonTrades = 33333, + .money = 999999, + .var_28 = {0, 0, 0, 0}, + .playerName = _("あかみ どりお"), + .version = VERSION_FIRE_RED, + .var_3A = 0, + .berryCrushPoints = 5555, + .unionRoomNum = 8500, + .berriesPicked = 5456, + .jumpsInRow = 6300, + .var_4C = TRUE, + .hasAllMons = TRUE, + .var_4E = 2, + .var_4F = 0, + .var_50 = {1, 2, 3, 0}, + .monSpecies = {SPECIES_CHARIZARD, SPECIES_DIGLETT, SPECIES_NIDORINA, SPECIES_FEAROW, SPECIES_PARAS, SPECIES_SLOWBRO} +}; + +static const struct TrainerCard sLinkPlayerTrainerCardTemplate2 = +{ + .gender = FEMALE, + .stars = 2, + .hasPokedex = TRUE, + .caughtAllHoenn = TRUE, + .hasAllPaintings = TRUE, + .hofDebutHours = 999, + .hofDebutMinutes = 59, + .hofDebutSeconds = 59, + .caughtMonsCount = 200, + .trainerId = 0x6072, + .playTimeHours = 999, + .playTimeMinutes = 59, + .linkBattleWins = 5535, + .linkBattleLosses = 5535, + .battleTowerWins = 65535, + .battleTowerStraightWins = 65535, + .contestsWithFriends = 55555, + .pokeblocksWithFriends = 44444, + .pokemonTrades = 33333, + .money = 999999, + .var_28 = {0, 0, 0, 0}, + .playerName = _("るびさふぁこ!"), + .version = 0, + .var_3A = 0, + .berryCrushPoints = 555, + .unionRoomNum = 500, + .berriesPicked = 456, + .jumpsInRow = 300, + .var_4C = TRUE, + .hasAllMons = TRUE, + .var_4E = 2, + .var_4F = 0, + .var_50 = {1, 2, 3, 0}, + .monSpecies = {SPECIES_CHARIZARD, SPECIES_DIGLETT, SPECIES_NIDORINA, SPECIES_FEAROW, SPECIES_PARAS, SPECIES_SLOWBRO} +}; + +// Functions +static void VBlankCB_TrainerCard(void) +{ + LoadOam(); + ProcessSpriteCopyRequests(); + TransferPlttBuffer(); + sub_808B180(); + if (sTrainerCardDataPtr->allowDMACopy) + DmaCopy16(3, &gScanlineEffectRegBuffers[0], &gScanlineEffectRegBuffers[1], 0x140); +} + +static void HBlankCB_TrainerCard(void) +{ + u16 backup; + u16 bgVOffset; + + backup = REG_IME; + REG_IME = 0; + bgVOffset = gScanlineEffectRegBuffers[1][REG_VCOUNT & 0xFF]; + REG_BG0VOFS = bgVOffset; + REG_IME = backup; +} + +static void CB2_TrainerCard(void) +{ + RunTasks(); + AnimateSprites(); + BuildOamBuffer(); + UpdatePaletteFade(); +} + +static void CloseTrainerCard(u8 taskId) +{ + SetMainCallback2(sTrainerCardDataPtr->callback2); + FreeAllWindowBuffers(); + FREE_AND_SET_NULL(sTrainerCardDataPtr); + DestroyTask(taskId); +} + +static void Task_TrainerCard(u8 taskId) +{ + switch (sTrainerCardDataPtr->taskState) + { + case 0: + if (!IsDma3ManagerBusyWithBgCopy()) + { + FillWindowPixelBuffer(1, PIXEL_FILL(0)); + sTrainerCardDataPtr->taskState++; + } + break; + case 1: + if (PrintAllOnCardPage1()) + sTrainerCardDataPtr->taskState++; + break; + case 2: + PutTrainerCardWindow(1); + sTrainerCardDataPtr->taskState++; + break; + case 3: + FillWindowPixelBuffer(2, PIXEL_FILL(0)); + sub_808B838(); + PutTrainerCardWindow(2); + sTrainerCardDataPtr->taskState++; + break; + case 4: + LoadTrainerCardTilemap2(&sTrainerCardDataPtr->var_E1C); + sTrainerCardDataPtr->taskState++; + break; + case 5: + LoadTrainerCardTilemap0(&sTrainerCardDataPtr->var_4BC); + sTrainerCardDataPtr->taskState++; + break; + case 6: + TrainerCard_PrintStarsAndBadgesOnCard(); + sTrainerCardDataPtr->taskState++; + break; + case 7: + if (gWirelessCommType == 1 && gReceivedRemoteLinkPlayers == TRUE) + { + LoadWirelessStatusIndicatorSpriteGfx(); + CreateWirelessStatusIndicatorSprite(230, 150); + } + BeginNormalPaletteFade(0xFFFFFFFF, 0, 16, 0, RGB_BLACK); + SetVBlankCallback(VBlankCB_TrainerCard); + sTrainerCardDataPtr->taskState++; + break; + case 8: + if (!UpdatePaletteFade() && !IsDma3ManagerBusyWithBgCopy()) + { + PlaySE(SE_CARD3); + sTrainerCardDataPtr->taskState = 10; + } + break; + case 9: + if (!IsSEPlaying()) + sTrainerCardDataPtr->taskState++; + break; + case 10: + if (!gReceivedRemoteLinkPlayers && sTrainerCardDataPtr->var_7BCE) + { + PrintTimeOnCard(); + PutTrainerCardWindow(1); + sTrainerCardDataPtr->var_7BCE = FALSE; + } + + if (JOY_NEW(A_BUTTON)) + { + HelpSystem_SetSomeVariable2(11); + sub_808B1D4(); + PlaySE(SE_CARD1); + sTrainerCardDataPtr->taskState = 12; + } + else if (JOY_NEW(B_BUTTON)) + { + if (gReceivedRemoteLinkPlayers && sTrainerCardDataPtr->isLink && InUnionRoom() == TRUE) + { + sTrainerCardDataPtr->taskState = 15; + } + else + { + BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB_BLACK); + sTrainerCardDataPtr->taskState = 14; + } + } + break; + case 12: + if (sub_808B1FC() && sub_8058244() != TRUE) + { + PlaySE(SE_CARD3); + sTrainerCardDataPtr->taskState = 11; + } + break; + case 11: + if (JOY_NEW(B_BUTTON)) + { + if (gReceivedRemoteLinkPlayers && sTrainerCardDataPtr->isLink && InUnionRoom() == TRUE) + { + sTrainerCardDataPtr->taskState = 15; + } + else if (gReceivedRemoteLinkPlayers) + { + BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB_BLACK); + sTrainerCardDataPtr->taskState = 14; + } + else + { + HelpSystem_SetSomeVariable2(10); + sub_808B1D4(); + sTrainerCardDataPtr->taskState = 13; + PlaySE(SE_CARD1); + } + } + else if (JOY_NEW(A_BUTTON)) + { + if (gReceivedRemoteLinkPlayers && sTrainerCardDataPtr->isLink && InUnionRoom() == TRUE) + { + sTrainerCardDataPtr->taskState = 15; + } + else + { + BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB_BLACK); + sTrainerCardDataPtr->taskState = 14; + } + } + break; + case 15: + sub_800AAC0(); + DrawDialogueFrame(0, 1); + AddTextPrinterParameterized(0, 2, gText_WaitingTrainerFinishReading, 0, 1, TEXT_SPEED_FF, 0); + CopyWindowToVram(0, 3); + sTrainerCardDataPtr->taskState = 16; + break; + case 16: + if (!gReceivedRemoteLinkPlayers) + { + BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB_BLACK); + sTrainerCardDataPtr->taskState = 14; + } + break; + case 14: + if (!UpdatePaletteFade()) + CloseTrainerCard(taskId); + break; + case 13: + if (sub_808B1FC() && sub_8058244() != TRUE) + { + sTrainerCardDataPtr->taskState = 10; + PlaySE(SE_CARD3); + } + break; + } +} + +static bool8 LoadCardGfx(void) +{ + switch (sTrainerCardDataPtr->gfxLoadState) + { + case 0: + if (sTrainerCardDataPtr->cardType == CARD_TYPE_EMERALD) + LZ77UnCompWram(sUnknown_83CCE30, &sTrainerCardDataPtr->var_E1C); + else + LZ77UnCompWram(sUnknown_83CCEC8, &sTrainerCardDataPtr->var_E1C); + break; + case 1: + if (sTrainerCardDataPtr->cardType == CARD_TYPE_EMERALD) + LZ77UnCompWram(sUnknown_83CC8A8, &sTrainerCardDataPtr->var_96C); + else + LZ77UnCompWram(sUnknown_83CC984, &sTrainerCardDataPtr->var_96C); + break; + case 2: + if (!sTrainerCardDataPtr->isLink) + { + if (sTrainerCardDataPtr->cardType == CARD_TYPE_EMERALD) + LZ77UnCompWram(sUnknown_83CC4DC, &sTrainerCardDataPtr->var_4BC); + else + LZ77UnCompWram(sUnknown_83CC6F0, &sTrainerCardDataPtr->var_4BC); + } + else + { + if (sTrainerCardDataPtr->cardType == CARD_TYPE_EMERALD) + LZ77UnCompWram(sUnknown_83CCAB0, &sTrainerCardDataPtr->var_4BC); + else + LZ77UnCompWram(sUnknown_83CCCA4, &sTrainerCardDataPtr->var_4BC); + } + break; + case 3: + LZ77UnCompWram(sFireRedTrainerCardBadges_Tile, &sTrainerCardDataPtr->cardTiles); + break; + case 4: + if (sTrainerCardDataPtr->cardType == CARD_TYPE_EMERALD) + LZ77UnCompWram(gEmeraldTrainerCard_Gfx, &sTrainerCardDataPtr->var_18CC); + else + LZ77UnCompWram(gFireRedTrainerCard_Gfx, &sTrainerCardDataPtr->var_18CC); + break; + case 5: + if (sTrainerCardDataPtr->cardType == CARD_TYPE_FRLG) + LZ77UnCompWram(sTrainerCardStickers, &sTrainerCardDataPtr->bgTiles); + break; + default: + sTrainerCardDataPtr->gfxLoadState = 0; + return TRUE; + } + sTrainerCardDataPtr->gfxLoadState++; + return FALSE; +} + +static void CB2_InitTrainerCard(void) +{ + switch (gMain.state) + { + case 0: + ResetGpuRegs(); + sub_8089DA4(); + gMain.state++; + break; + case 1: + TrainerCardNull(); + gMain.state++; + break; + case 2: + sub_8089C5C(); + gMain.state++; + break; + case 3: + sub_8089C80(); + gMain.state++; + // fallthrough + case 4: + sub_8089CA4(); + gMain.state++; + break; + case 5: + ResetTrainerCard(); + gMain.state++; + break; + case 6: + LoadStdWindowFrameGfx(); + gMain.state++; + break; + case 7: + sub_808AB10(); + gMain.state++; + break; + case 8: + if (LoadCardGfx() == TRUE) + gMain.state++; + break; + case 9: + TrainerCardLoadStickerPals(); + gMain.state++; + break; + case 10: + HandleGpuRegs(); + gMain.state++; + break; + case 11: + sub_8089ECC(); + gMain.state++; + break; + case 12: + if (SetTrainerCardBgsAndPals() == TRUE) + gMain.state++; + break; + case 13: + gMain.state++; + break; + default: + SetTrainerCardCB2(); + break; + } +} + +static u32 GetCappedGameStat(u8 statId, u32 maxValue) +{ + u32 statValue = GetGameStat(statId); + return min(maxValue, statValue); +} + +static u8 GetTrainerStarCount(struct TrainerCard *trainerCard) +{ + u8 stars = 0; + + if (trainerCard->hofDebutHours != 0 || trainerCard->hofDebutMinutes != 0 || trainerCard->hofDebutSeconds != 0) + stars++; + + if (trainerCard->caughtAllHoenn) + stars++; + + if (trainerCard->battleTowerStraightWins > 49) + stars++; + + if (trainerCard->hasAllPaintings) + stars++; + + return stars; +} + +static void SetPlayerCardData(struct TrainerCard *trainerCard, u8 cardType) +{ + u32 playTime; + u8 i; + + trainerCard->gender = gSaveBlock2Ptr->playerGender; + trainerCard->playTimeHours = gSaveBlock2Ptr->playTimeHours; + trainerCard->playTimeMinutes = gSaveBlock2Ptr->playTimeMinutes; + + playTime = GetGameStat(GAME_STAT_FIRST_HOF_PLAY_TIME); + if (!GetGameStat(GAME_STAT_ENTERED_HOF)) + playTime = 0; + + trainerCard->hofDebutHours = playTime >> 16; + trainerCard->hofDebutMinutes = (playTime >> 8) & 0xFF; + trainerCard->hofDebutSeconds = playTime & 0xFF; + if ((playTime >> 16) > 999) + { + trainerCard->hofDebutHours = 999; + trainerCard->hofDebutMinutes = 59; + trainerCard->hofDebutSeconds = 59; + } + + trainerCard->hasPokedex = FlagGet(FLAG_SYS_POKEDEX_GET); + trainerCard->caughtAllHoenn = HasAllHoennMons(); + trainerCard->caughtMonsCount = GetCaughtMonsCount(); + + trainerCard->trainerId = (gSaveBlock2Ptr->playerTrainerId[1] << 8) | gSaveBlock2Ptr->playerTrainerId[0]; + + trainerCard->linkBattleWins = GetCappedGameStat(GAME_STAT_LINK_BATTLE_WINS, 9999); + trainerCard->linkBattleLosses = GetCappedGameStat(GAME_STAT_LINK_BATTLE_LOSSES, 9999); + trainerCard->pokemonTrades = GetCappedGameStat(GAME_STAT_POKEMON_TRADES, 0xFFFF); + + trainerCard->battleTowerWins = 0; + trainerCard->battleTowerStraightWins = 0; + trainerCard->contestsWithFriends = 0; + trainerCard->pokeblocksWithFriends = 0; + + trainerCard->hasAllPaintings = FALSE; + + trainerCard->money = GetMoney(&gSaveBlock1Ptr->money); + + for (i = 0; i < 4; i++) + trainerCard->var_28[i] = gSaveBlock1Ptr->easyChatProfile[i]; + + StringCopy(trainerCard->playerName, gSaveBlock2Ptr->playerName); + + if (cardType == CARD_TYPE_FRLG) + { + trainerCard->stars = GetTrainerStarCount(trainerCard); + } + else if (cardType == CARD_TYPE_EMERALD) + { + trainerCard->stars = 0; + if (trainerCard->hofDebutHours != 0 || (trainerCard->hofDebutMinutes != 0 || trainerCard->hofDebutSeconds != 0)) + trainerCard->stars = cardType; + + if (HasAllKantoMons()) + trainerCard->stars++; + + if (HasAllMons()) + trainerCard->stars++; + } +} + +void TrainerCard_GenerateCardForLinkPlayer(struct TrainerCard *trainerCard) +{ + u8 id = 0; + + trainerCard->version = VERSION_FIRE_RED; + SetPlayerCardData(trainerCard, CARD_TYPE_EMERALD); + if (GetCardType() != CARD_TYPE_FRLG) + return; + + trainerCard->stars = id; + if (trainerCard->hofDebutHours != 0 || trainerCard->hofDebutMinutes != 0 || trainerCard->hofDebutSeconds != 0) + trainerCard->stars = 1; + + trainerCard->caughtAllHoenn = HasAllKantoMons(); + trainerCard->hasAllMons = HasAllMons(); + trainerCard->berriesPicked = gSaveBlock2Ptr->berryPick.berriesPicked; + trainerCard->jumpsInRow = gSaveBlock2Ptr->pokeJump.jumpsInRow; + + trainerCard->berryCrushPoints = GetCappedGameStat(GAME_STAT_BERRY_CRUSH_POINTS, 0xFFFF); + trainerCard->unionRoomNum = GetCappedGameStat(GAME_STAT_NUM_UNION_ROOM_BATTLES, 0xFFFF); + trainerCard->var_4C = TRUE; + + if (trainerCard->caughtAllHoenn) + trainerCard->stars++; + + if (trainerCard->hasAllMons) + trainerCard->stars++; + + if (trainerCard->berriesPicked >= 200 && trainerCard->jumpsInRow >= 200) + trainerCard->stars++; + + id = ((u16)trainerCard->trainerId) % 8; + if (trainerCard->gender == FEMALE) + trainerCard->var_4F = sLinkTrainerCardFacilityClasses[1][id]; + else + trainerCard->var_4F = sLinkTrainerCardFacilityClasses[0][id]; + + trainerCard->var_50[0] = VarGet(VAR_HOF_BRAG_STATE); + trainerCard->var_50[1] = VarGet(VAR_EGG_BRAG_STATE); + trainerCard->var_50[2] = VarGet(VAR_LINK_WIN_BRAG_STATE); + + trainerCard->var_4E = VarGet(VAR_TRAINER_CARD_MON_ICON_TINT_IDX); + + trainerCard->monSpecies[0] = MailSpeciesToIconSpecies(VarGet(VAR_TRAINER_CARD_MON_ICON_1)); + trainerCard->monSpecies[1] = MailSpeciesToIconSpecies(VarGet(VAR_TRAINER_CARD_MON_ICON_2)); + trainerCard->monSpecies[2] = MailSpeciesToIconSpecies(VarGet(VAR_TRAINER_CARD_MON_ICON_3)); + trainerCard->monSpecies[3] = MailSpeciesToIconSpecies(VarGet(VAR_TRAINER_CARD_MON_ICON_4)); + trainerCard->monSpecies[4] = MailSpeciesToIconSpecies(VarGet(VAR_TRAINER_CARD_MON_ICON_5)); + trainerCard->monSpecies[5] = MailSpeciesToIconSpecies(VarGet(VAR_TRAINER_CARD_MON_ICON_6)); +} + +static void SetDataFromTrainerCard(void) +{ + u32 badgeFlag; + u8 i; + + sTrainerCardDataPtr->hasPokedex = FALSE; + sTrainerCardDataPtr->hasHofResult = FALSE; + sTrainerCardDataPtr->hasLinkResults = FALSE; + sTrainerCardDataPtr->hasBattleTowerWins = FALSE; + sTrainerCardDataPtr->var_E = FALSE; + sTrainerCardDataPtr->var_F = FALSE; + sTrainerCardDataPtr->hasTrades = FALSE; + + memset(&sTrainerCardDataPtr->hasBadge, FALSE, BADGE_COUNT); + if (sTrainerCardDataPtr->trainerCard.hasPokedex) + sTrainerCardDataPtr->hasPokedex++; + + if (sTrainerCardDataPtr->trainerCard.hofDebutHours != 0 + || sTrainerCardDataPtr->trainerCard.hofDebutMinutes != 0 + || sTrainerCardDataPtr->trainerCard.hofDebutSeconds != 0) + sTrainerCardDataPtr->hasHofResult++; + + if (sTrainerCardDataPtr->trainerCard.linkBattleWins != 0 || sTrainerCardDataPtr->trainerCard.linkBattleLosses != 0) + sTrainerCardDataPtr->hasLinkResults++; + + if (sTrainerCardDataPtr->trainerCard.pokemonTrades != 0) + sTrainerCardDataPtr->hasTrades++; + + for (i = 0, badgeFlag = FLAG_BADGE01_GET; badgeFlag <= FLAG_BADGE08_GET; badgeFlag++, i++) + { + if (FlagGet(badgeFlag)) + sTrainerCardDataPtr->hasBadge[i]++; + } +} + +static void HandleGpuRegs(void) +{ + ShowBg(0); + ShowBg(1); + ShowBg(2); + ShowBg(3); + SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_WIN0_ON | DISPCNT_OBJ_ON | DISPCNT_OBJ_1D_MAP | DISPCNT_BG_ALL_ON); + SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG0 | BLDCNT_EFFECT_DARKEN); + SetGpuReg(REG_OFFSET_BLDY, 0); + SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR); + SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WIN01_BG1 | WINOUT_WIN01_BG2 | WINOUT_WIN01_BG3 | WINOUT_WIN01_OBJ); + SetGpuReg(REG_OFFSET_WIN0V, WININ_WIN0_CLR | WIN_RANGE(0, 0x80)); + SetGpuReg(REG_OFFSET_WIN0H, WININ_WIN0_CLR | WININ_WIN0_OBJ | WIN_RANGE(0, 0xC0)); + if (gReceivedRemoteLinkPlayers) + EnableInterrupts(INTR_FLAG_VBLANK | INTR_FLAG_HBLANK | INTR_FLAG_VCOUNT | INTR_FLAG_TIMER3 | INTR_FLAG_SERIAL); + else + EnableInterrupts(INTR_FLAG_VBLANK | INTR_FLAG_HBLANK); +} + +static void sub_8089BD8(u16 arg0) +{ + s8 quotient = (arg0 + 40) / 10; + + if (quotient <= 4) + quotient = 0; + + sTrainerCardDataPtr->var_456 = quotient; + SetGpuReg(REG_OFFSET_BLDY, sTrainerCardDataPtr->var_456); + SetGpuReg(REG_OFFSET_WIN0V, WIN_RANGE(sTrainerCardDataPtr->var_7BCC, 160 - sTrainerCardDataPtr->var_7BCC)); +} + +static void ResetGpuRegs(void) +{ + SetVBlankCallback(NULL); + SetHBlankCallback(NULL); + SetGpuReg(REG_OFFSET_DISPCNT, 0); +} + +static void TrainerCardNull(void) +{ +} + +static void sub_8089C5C(void) +{ + DmaClear32(3, (void *)OAM, OAM_SIZE); +} + +static void sub_8089C80(void) +{ + DmaClear16(3, (void *)PLTT, PLTT_SIZE); +} + +static void sub_8089CA4(void) +{ + SetGpuReg(REG_OFFSET_BG0CNT, DISPCNT_MODE_0); + SetGpuReg(REG_OFFSET_BG1CNT, DISPCNT_MODE_0); + SetGpuReg(REG_OFFSET_BG2CNT, DISPCNT_MODE_0); + SetGpuReg(REG_OFFSET_BG3CNT, DISPCNT_MODE_0); + SetGpuReg(REG_OFFSET_BG0HOFS, DISPCNT_MODE_0); + SetGpuReg(REG_OFFSET_BG0VOFS, DISPCNT_MODE_0); + SetGpuReg(REG_OFFSET_BG1HOFS, DISPCNT_MODE_0); + SetGpuReg(REG_OFFSET_BG1VOFS, DISPCNT_MODE_0); + SetGpuReg(REG_OFFSET_BG2HOFS, DISPCNT_MODE_0); + SetGpuReg(REG_OFFSET_BG2VOFS, DISPCNT_MODE_0); + SetGpuReg(REG_OFFSET_BG3HOFS, DISPCNT_MODE_0); + SetGpuReg(REG_OFFSET_BG3VOFS, DISPCNT_MODE_0); +} + +static void ResetTrainerCard(void) +{ + ResetSpriteData(); + ResetPaletteFade(); + ResetBgsAndClearDma3BusyFlags(0); + InitBgsFromTemplates(0, sTrainerCardBgTemplates, NELEMS(sTrainerCardBgTemplates)); + 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); + InitWindows(sTrainerCardWindowTemplates); + DeactivateAllTextPrinters(); +} + +static void SetTrainerCardCB2(void) +{ + SetMainCallback2(CB2_TrainerCard); + HelpSystem_SetSomeVariable2(10); +} + +static void sub_8089DA4(void) +{ + ResetTasks(); + ScanlineEffect_Stop(); + CreateTask(Task_TrainerCard, 0); + sub_808B774(); + SetDataFromTrainerCard(); +} + +static bool8 PrintAllOnCardPage1(void) +{ + switch (sTrainerCardDataPtr->printState) + { + case 0: + PrintNameOnCard(); + break; + case 1: + PrintIdOnCard(); + break; + case 2: + PrintMoneyOnCard(); + break; + case 3: + PrintPokedexOnCard(); + break; + case 4: + PrintTimeOnCard(); + break; + case 5: + PrintProfilePhraseOnCard(); + break; + default: + sTrainerCardDataPtr->printState = 0; + return TRUE; + } + sTrainerCardDataPtr->printState++; + return FALSE; +} + +static bool8 PrintStringsOnCardPage2(void) +{ + switch (sTrainerCardDataPtr->printState) + { + case 0: + sub_808A4FC(); + break; + case 1: + PrintHofDebutStringOnCard(); + break; + case 2: + PrintWinsLossesStringOnCard(); + break; + case 3: + PrintTradesStringOnCard(); + break; + case 4: + PrintBerryCrushStringOnCard(); + break; + case 5: + PrintUnionStringOnCard(); + break; + case 6: + TrainerCard_PrintPokemonIconsOnCard(); + break; + case 7: + sub_808ABE0(); + break; + default: + sTrainerCardDataPtr->printState = 0; + return TRUE; + } + sTrainerCardDataPtr->printState++; + return FALSE; +} + +static void sub_8089ECC(void) +{ + PrintNameOnCard2(); + PrintHofTimeOnCard(); + PrintLinkResultsNumsOnCard(); + PrintTradesNumOnCard(); + PrintBerryCrushNumOnCard(); + PrintUnionNumOnCard(); +} + +static void PrintNameOnCard(void) +{ + u8 buffer[2][32]; + u8* txtPtr; + + txtPtr = StringCopy(buffer[0], gText_TrainerCardName); + txtPtr = buffer[1]; + StringCopy(txtPtr, sTrainerCardDataPtr->trainerCard.playerName); + ConvertInternationalString(txtPtr, sTrainerCardDataPtr->language); + StringAppend(buffer[0], txtPtr); + AddTextPrinterParameterized3(1, sTrainerCardFontIds[1], sTrainerCardPlayerNameXPositions[sTrainerCardDataPtr->cardType], sTrainerCardPlayerNameYPositions[sTrainerCardDataPtr->cardType], sFireRedTrainerCardPage1TextColors, TEXT_SPEED_FF, buffer[0]); +} + +static void PrintIdOnCard(void) +{ + u8 buffer[32]; + u8* txtPtr; + + txtPtr = StringCopy(buffer, gText_TrainerCardIDNo); + ConvertIntToDecimalStringN(txtPtr, sTrainerCardDataPtr->trainerCard.trainerId, STR_CONV_MODE_LEADING_ZEROS, 5); + AddTextPrinterParameterized3(1, sTrainerCardFontIds[1], sTrainerCardIdXPositions[sTrainerCardDataPtr->cardType], sTrainerCardIdYPositions[sTrainerCardDataPtr->cardType], sFireRedTrainerCardPage1TextColors, TEXT_SPEED_FF, buffer); +} + +static void PrintMoneyOnCard(void) +{ + u8 buffer[10]; + u8* txtPtr; + u8 x; + + txtPtr = StringCopy(buffer, gText_TrainerCardYen); + ConvertIntToDecimalStringN(txtPtr, sTrainerCardDataPtr->trainerCard.money, STR_CONV_MODE_LEFT_ALIGN, 6); + if (sTrainerCardDataPtr->cardType != CARD_TYPE_EMERALD) + { + x = -122 - 6 * StringLength(buffer); + AddTextPrinterParameterized3(1, sTrainerCardFontIds[1], 20, 56, sFireRedTrainerCardPage1TextColors, TEXT_SPEED_FF, gText_TrainerCardMoney); + AddTextPrinterParameterized3(1, sTrainerCardFontIds[1], x, 56, sFireRedTrainerCardPage1TextColors, TEXT_SPEED_FF, buffer); + } + else + { + x = 118 - 6 * StringLength(buffer); + AddTextPrinterParameterized3(1, sTrainerCardFontIds[1], 16, 57, sFireRedTrainerCardPage1TextColors, TEXT_SPEED_FF, gText_TrainerCardMoney); + AddTextPrinterParameterized3(1, sTrainerCardFontIds[1], x, 57, sFireRedTrainerCardPage1TextColors, TEXT_SPEED_FF, buffer); + } +} + +static u16 GetCaughtMonsCount(void) +{ + if (IsNationalPokedexEnabled()) + return GetNationalPokedexCount(FLAG_GET_CAUGHT); + else + return GetKantoPokedexCount(FLAG_GET_CAUGHT); +} + +static void PrintPokedexOnCard(void) +{ + u8 buffer[10]; + u8 x; + + if (FlagGet(FLAG_SYS_POKEDEX_GET)) + { + ConvertIntToDecimalStringN(buffer, sTrainerCardDataPtr->trainerCard.caughtMonsCount, 0, 3); + if (sTrainerCardDataPtr->cardType != CARD_TYPE_EMERALD) + { + x = -120 - 6 * StringLength(buffer); + AddTextPrinterParameterized3(1, sTrainerCardFontIds[1], 20, 72, sFireRedTrainerCardPage1TextColors, TEXT_SPEED_FF, gText_TrainerCardPokedex); + AddTextPrinterParameterized3(1, sTrainerCardFontIds[1], x, 72, sFireRedTrainerCardPage1TextColors, TEXT_SPEED_FF, buffer); + AddTextPrinterParameterized3(1, sTrainerCardFontIds[1], 138, 72, sFireRedTrainerCardPage1TextColors, TEXT_SPEED_FF, gText_TrainerCardNull); + } + else + { + x = 120 - 6 * StringLength(buffer); + AddTextPrinterParameterized3(1, sTrainerCardFontIds[1], 16, 73, sFireRedTrainerCardPage1TextColors, TEXT_SPEED_FF, gText_TrainerCardPokedex); + AddTextPrinterParameterized3(1, sTrainerCardFontIds[1], x, 73, sFireRedTrainerCardPage1TextColors, TEXT_SPEED_FF, buffer); + AddTextPrinterParameterized3(1, sTrainerCardFontIds[1], 138, 73, sFireRedTrainerCardPage1TextColors, TEXT_SPEED_FF, gText_TrainerCardNull); + } + } +} + +static void PrintTimeOnCard(void) +{ + u16 hours; + u16 minutes; + u8 buffer[6]; + + hours = gSaveBlock2Ptr->playTimeHours; + minutes = gSaveBlock2Ptr->playTimeMinutes; + if (sTrainerCardDataPtr->isLink) + { + hours = sTrainerCardDataPtr->trainerCard.playTimeHours; + minutes = sTrainerCardDataPtr->trainerCard.playTimeMinutes; + } + + if (hours > 999) + hours = 999; + + if (minutes > 59) + minutes = 59; + + FillWindowPixelRect(1, PIXEL_FILL(0), sTrainerCardTimeHoursXPositions[sTrainerCardDataPtr->cardType], sTrainerCardTimeMinutesYPositions[sTrainerCardDataPtr->cardType], 50, 12); + if (sTrainerCardDataPtr->cardType != CARD_TYPE_EMERALD) + AddTextPrinterParameterized3(1, sTrainerCardFontIds[1], 20, 88, sFireRedTrainerCardPage1TextColors, TEXT_SPEED_FF, gText_TrainerCardTime); + else + AddTextPrinterParameterized3(1, sTrainerCardFontIds[1], 16, 89, sFireRedTrainerCardPage1TextColors, TEXT_SPEED_FF, gText_TrainerCardTime); + + ConvertIntToDecimalStringN(buffer, hours, STR_CONV_MODE_RIGHT_ALIGN, 3); + AddTextPrinterParameterized3(1, sTrainerCardFontIds[1], sTrainerCardTimeHoursXPositions[sTrainerCardDataPtr->cardType], + sTrainerCardTimeMinutesYPositions[sTrainerCardDataPtr->cardType], sFireRedTrainerCardPage1TextColors, TEXT_SPEED_FF, buffer); + AddTextPrinterParameterized3(1, sTrainerCardFontIds[1], sTrainerCardTimeHoursYPositions[sTrainerCardDataPtr->cardType], + sTrainerCardTimeMinutesYPositions[sTrainerCardDataPtr->cardType], sTrainerCardTextColors[sTrainerCardDataPtr->var_7], TEXT_SPEED_FF, gText_Colon2); + + ConvertIntToDecimalStringN(buffer, minutes, STR_CONV_MODE_LEADING_ZEROS, 2); + AddTextPrinterParameterized3(1, sTrainerCardFontIds[1], sTrainerCardTimeMinutesXPositions[sTrainerCardDataPtr->cardType], sTrainerCardTimeMinutesYPositions[sTrainerCardDataPtr->cardType], sFireRedTrainerCardPage1TextColors, TEXT_SPEED_FF, buffer); +} + +static void PrintProfilePhraseOnCard(void) +{ + if (sTrainerCardDataPtr->isLink) + { + AddTextPrinterParameterized3(1, 2, 10, sTrainerCardProfilePhraseXPositions[sTrainerCardDataPtr->cardType], + sFireRedTrainerCardPage1TextColors, TEXT_SPEED_FF, sTrainerCardDataPtr->var_19[0]); + + AddTextPrinterParameterized3(1, 2, GetStringWidth(2, sTrainerCardDataPtr->var_19[0], 0) + 16, sTrainerCardProfilePhraseXPositions[sTrainerCardDataPtr->cardType], + sFireRedTrainerCardPage1TextColors, TEXT_SPEED_FF, sTrainerCardDataPtr->var_19[1]); + + AddTextPrinterParameterized3(1, 2, 10, sTrainerCardProfilePhraseYPositions[sTrainerCardDataPtr->cardType], + sFireRedTrainerCardPage1TextColors, TEXT_SPEED_FF, sTrainerCardDataPtr->var_19[2]); + + AddTextPrinterParameterized3(1, 2, GetStringWidth(2, sTrainerCardDataPtr->var_19[2], 0) + 16, sTrainerCardProfilePhraseYPositions[sTrainerCardDataPtr->cardType], + sFireRedTrainerCardPage1TextColors, TEXT_SPEED_FF, sTrainerCardDataPtr->var_19[3]); + } +} + +static void PrintNameOnCard2(void) +{ + StringCopy(sTrainerCardDataPtr->strings[TRAINER_CARD_STRING_NAME], sTrainerCardDataPtr->trainerCard.playerName); + ConvertInternationalString(sTrainerCardDataPtr->strings[TRAINER_CARD_STRING_NAME], sTrainerCardDataPtr->language); + if (sTrainerCardDataPtr->cardType == CARD_TYPE_EMERALD) + { + StringAppend(sTrainerCardDataPtr->strings[TRAINER_CARD_STRING_NAME], gText_Var1sTrainerCard); + } +} + +static void sub_808A4FC(void) +{ + u8 x; + + if (sTrainerCardDataPtr->cardType == CARD_TYPE_FRLG) + { + AddTextPrinterParameterized3(1, sTrainerCardFontIds[1], sUnknown_83CD93C[sTrainerCardDataPtr->cardType], + sUnknown_83CD93E[sTrainerCardDataPtr->cardType], sFireRedTrainerCardPage1TextColors, TEXT_SPEED_FF, sTrainerCardDataPtr->strings[TRAINER_CARD_STRING_NAME]); + } + else + { + x = sUnknown_83CD93C[sTrainerCardDataPtr->cardType] - GetStringWidth(sTrainerCardFontIds[1], sTrainerCardDataPtr->strings[TRAINER_CARD_STRING_NAME], GetFontAttribute(sTrainerCardFontIds[1], FONTATTR_LETTER_SPACING)); + + AddTextPrinterParameterized3(1, sTrainerCardFontIds[1], x, sUnknown_83CD93E[sTrainerCardDataPtr->cardType], + sFireRedTrainerCardPage1TextColors, TEXT_SPEED_FF, sTrainerCardDataPtr->strings[TRAINER_CARD_STRING_NAME]); + } +} + +static void PrintHofTimeOnCard(void) +{ + u8 buffer[10]; + u8* txtPtr; + + if (sTrainerCardDataPtr->hasHofResult) + { + ConvertIntToDecimalStringN(buffer, sTrainerCardDataPtr->trainerCard.hofDebutHours, STR_CONV_MODE_RIGHT_ALIGN, 3); + txtPtr = StringCopy(sTrainerCardDataPtr->strings[TRAINER_CARD_STRING_HOF_TIME], buffer); + StringAppendN(sTrainerCardDataPtr->strings[TRAINER_CARD_STRING_HOF_TIME], gText_Colon2, 2); + ConvertIntToDecimalStringN(buffer, sTrainerCardDataPtr->trainerCard.hofDebutMinutes, STR_CONV_MODE_LEADING_ZEROS, 2); + StringAppendN(sTrainerCardDataPtr->strings[TRAINER_CARD_STRING_HOF_TIME], buffer, 3); + StringAppendN(sTrainerCardDataPtr->strings[TRAINER_CARD_STRING_HOF_TIME], gText_Colon2, 2); + ConvertIntToDecimalStringN(buffer, sTrainerCardDataPtr->trainerCard.hofDebutSeconds, STR_CONV_MODE_LEADING_ZEROS, 2); + StringAppendN(sTrainerCardDataPtr->strings[TRAINER_CARD_STRING_HOF_TIME], buffer, 3); + } +} + +static void PrintHofDebutStringOnCard(void) +{ + if (sTrainerCardDataPtr->hasHofResult) + { + AddTextPrinterParameterized3(1, sTrainerCardFontIds[1], sTrainerCardHofDebutXPositions[sTrainerCardDataPtr->cardType], 35, sFireRedTrainerCardPage1TextColors, TEXT_SPEED_FF, gText_HallOfFameDebut); + AddTextPrinterParameterized3(1, sTrainerCardFontIds[1], 164, 35, sTrainerCardPage2TextColors, TEXT_SPEED_FF, sTrainerCardDataPtr->strings[TRAINER_CARD_STRING_HOF_TIME]); + } +} + +static void PrintLinkResultsNumsOnCard(void) +{ + u8 buffer[30]; + + if (sTrainerCardDataPtr->hasLinkResults) + { + StringCopy(sTrainerCardDataPtr->strings[TRAINER_CARD_STRING_LINK_RECORD], sLinkTrainerCardRecordStrings[sTrainerCardDataPtr->cardType]); + StringCopy(sTrainerCardDataPtr->strings[TRAINER_CARD_STRING_WIN_LOSS], gText_WinLossRatio); + ConvertIntToDecimalStringN(buffer, sTrainerCardDataPtr->trainerCard.linkBattleWins, STR_CONV_MODE_RIGHT_ALIGN, 4); + StringCopy(sTrainerCardDataPtr->strings[TRAINER_CARD_STRING_LINK_WINS], buffer); + ConvertIntToDecimalStringN(buffer, sTrainerCardDataPtr->trainerCard.linkBattleLosses, STR_CONV_MODE_RIGHT_ALIGN, 4); + StringCopy(sTrainerCardDataPtr->strings[TRAINER_CARD_STRING_LINK_LOSSES], buffer); + } +} + +static void PrintWinsLossesStringOnCard(void) +{ + if (sTrainerCardDataPtr->hasLinkResults) + { + AddTextPrinterParameterized3(1, sTrainerCardFontIds[1], sTrainerCardHofDebutXPositions[sTrainerCardDataPtr->cardType], 51, + sFireRedTrainerCardPage1TextColors, TEXT_SPEED_FF, sTrainerCardDataPtr->strings[TRAINER_CARD_STRING_LINK_RECORD]); + AddTextPrinterParameterized3(1, sTrainerCardFontIds[1], 130, 51, sFireRedTrainerCardPage1TextColors, TEXT_SPEED_FF, sTrainerCardDataPtr->strings[TRAINER_CARD_STRING_WIN_LOSS]); + AddTextPrinterParameterized3(1, sTrainerCardFontIds[1], 144, 51, sTrainerCardPage2TextColors, TEXT_SPEED_FF, sTrainerCardDataPtr->strings[TRAINER_CARD_STRING_LINK_WINS]); + AddTextPrinterParameterized3(1, sTrainerCardFontIds[1], 192, 51, sTrainerCardPage2TextColors, TEXT_SPEED_FF, sTrainerCardDataPtr->strings[TRAINER_CARD_STRING_LINK_LOSSES]); + } +} + +static void PrintTradesNumOnCard(void) +{ + if (sTrainerCardDataPtr->hasTrades) + { + StringCopy(sTrainerCardDataPtr->strings[TRAINER_CARD_STRING_TRADES], gText_PokemonTrades); + ConvertIntToDecimalStringN(sTrainerCardDataPtr->strings[TRAINER_CARD_STRING_TRADE_COUNT], sTrainerCardDataPtr->trainerCard.pokemonTrades, STR_CONV_MODE_RIGHT_ALIGN, 5); + } +} + +static void PrintTradesStringOnCard(void) +{ + if (sTrainerCardDataPtr->hasTrades) + { + AddTextPrinterParameterized3(1, sTrainerCardFontIds[1], sTrainerCardHofDebutXPositions[sTrainerCardDataPtr->cardType], 67, sFireRedTrainerCardPage1TextColors, TEXT_SPEED_FF, sTrainerCardDataPtr->strings[TRAINER_CARD_STRING_TRADES]); + AddTextPrinterParameterized3(1, sTrainerCardFontIds[1], 186, 67, sTrainerCardPage2TextColors, TEXT_SPEED_FF, sTrainerCardDataPtr->strings[TRAINER_CARD_STRING_TRADE_COUNT]); + } +} + +static void PrintBerryCrushNumOnCard(void) +{ + if (sTrainerCardDataPtr->cardType != CARD_TYPE_EMERALD) + { + StringCopy(sTrainerCardDataPtr->strings[TRAINER_CARD_STRING_BERRY_CRUSH], gText_BerryCrushes); + ConvertIntToDecimalStringN(sTrainerCardDataPtr->strings[TRAINER_CARD_STRING_BERRY_CRUSH_COUNT], sTrainerCardDataPtr->trainerCard.berryCrushPoints, STR_CONV_MODE_RIGHT_ALIGN, 5); + } +} + +static void PrintBerryCrushStringOnCard(void) +{ + if (sTrainerCardDataPtr->cardType != CARD_TYPE_EMERALD && sTrainerCardDataPtr->trainerCard.berryCrushPoints) + { + AddTextPrinterParameterized3(1, sTrainerCardFontIds[1], sTrainerCardHofDebutXPositions[sTrainerCardDataPtr->cardType], 99, sFireRedTrainerCardPage1TextColors, TEXT_SPEED_FF, sTrainerCardDataPtr->strings[TRAINER_CARD_STRING_BERRY_CRUSH]); + AddTextPrinterParameterized3(1, sTrainerCardFontIds[1], 186, 99, sTrainerCardPage2TextColors, TEXT_SPEED_FF, sTrainerCardDataPtr->strings[TRAINER_CARD_STRING_BERRY_CRUSH_COUNT]); + } +} + +static void PrintUnionNumOnCard(void) +{ + if (sTrainerCardDataPtr->cardType != CARD_TYPE_EMERALD) + { + StringCopy(sTrainerCardDataPtr->strings[TRAINER_CARD_STRING_UNION_ROOM], gText_UnionRoomTradesBattles); + ConvertIntToDecimalStringN(sTrainerCardDataPtr->strings[TRAINER_CARD_STRING_UNION_ROOM_NUM], sTrainerCardDataPtr->trainerCard.unionRoomNum, STR_CONV_MODE_RIGHT_ALIGN, 5); + } +} + +static void PrintUnionStringOnCard(void) +{ + if (sTrainerCardDataPtr->cardType != CARD_TYPE_EMERALD && sTrainerCardDataPtr->trainerCard.unionRoomNum) + { + AddTextPrinterParameterized3(1, sTrainerCardFontIds[1], sTrainerCardHofDebutXPositions[sTrainerCardDataPtr->cardType], 83, sFireRedTrainerCardPage1TextColors, TEXT_SPEED_FF, sTrainerCardDataPtr->strings[TRAINER_CARD_STRING_UNION_ROOM]); + AddTextPrinterParameterized3(1, sTrainerCardFontIds[1], 186, 83, sTrainerCardPage2TextColors, TEXT_SPEED_FF, sTrainerCardDataPtr->strings[TRAINER_CARD_STRING_UNION_ROOM_NUM]); + } +} + +static void TrainerCard_PrintPokemonIconsOnCard(void) +{ + u8 i; + u8 buffer[6]; + u8 buffer2[6]; + + memcpy(buffer, sUnknown_83CD94C, sizeof(sUnknown_83CD94C)); + memcpy(buffer2, sUnknown_83CD952, sizeof(sUnknown_83CD952)); + if (sTrainerCardDataPtr->cardType != CARD_TYPE_EMERALD) + { + for (i = 0; i < 6; i++) + { + if (sTrainerCardDataPtr->trainerCard.monSpecies[i]) + { + u8 monSpecies = GetMonIconPaletteIndexFromSpecies(sTrainerCardDataPtr->trainerCard.monSpecies[i]); + WriteSequenceToBgTilemapBuffer(3, 16 * i + 224, buffer2[i] + 3, 15, 4, 4, buffer[monSpecies], 1); + } + } + } +} + + +static void sub_808AB10(void) +{ + u8 i; + + CpuSet(gMonIconPalettes, sTrainerCardDataPtr->monIconPals, 32 * 3); + switch (sTrainerCardDataPtr->trainerCard.var_4E) + { + case 0: + break; + case 1: + TintPalette_CustomTone(sTrainerCardDataPtr->monIconPals, 96, 0, 0, 0); + break; + case 2: + TintPalette_CustomTone(sTrainerCardDataPtr->monIconPals, 96, 500, 330, 310); + break; + case 3: + TintPalette_SepiaTone(sTrainerCardDataPtr->monIconPals, 96); + break; + } + + LoadPalette(sTrainerCardDataPtr->monIconPals, 80, 192); + for (i = 0; i < 6; i++) + { + LoadBgTiles(3, GetMonIconTiles(sTrainerCardDataPtr->trainerCard.monSpecies[i], 0), 512, 16 * i + 32); + } +} + +static void sub_808ABE0(void) +{ + u8 i; + u8 buffer[4]; + + memcpy(buffer, sUnknown_83CD958, sizeof(sUnknown_83CD958)); + if (sTrainerCardDataPtr->cardType == CARD_TYPE_FRLG && sTrainerCardDataPtr->trainerCard.var_4C == 1) + { + for (i = 0; i < 3; i++) + { + u8 var_50 = sTrainerCardDataPtr->trainerCard.var_50[i]; + if (sTrainerCardDataPtr->trainerCard.var_50[i]) + WriteSequenceToBgTilemapBuffer(3, i * 4 + 320, i * 3 + 2, 2, 2, 2, buffer[var_50 - 1], 1); + } + } +} + +static void TrainerCardLoadStickerPals(void) +{ + LoadPalette(sTrainerCardStickerPal1, 176, 32); + LoadPalette(sTrainerCardStickerPal2, 192, 32); + LoadPalette(sTrainerCardStickerPal3, 208, 32); + LoadPalette(sTrainerCardStickerPal4, 224, 32); + LoadBgTiles(3, sTrainerCardDataPtr->bgTiles, 1024, 128); +} + +static void PutTrainerCardWindow(u8 windowId) +{ + PutWindowTilemap(windowId); + CopyWindowToVram(windowId, 3); +} + +static bool8 SetTrainerCardBgsAndPals(void) +{ + switch (sTrainerCardDataPtr->bgPalLoadState) + { + case 0: + LoadBgTiles(3, sTrainerCardDataPtr->cardTiles, 1024, 0); + break; + case 1: + LoadBgTiles(0, sTrainerCardDataPtr->var_18CC, 6144, 0); + break; + case 2: + if (sTrainerCardDataPtr->cardType == CARD_TYPE_EMERALD) + LoadPalette(sEmeraldTrainerCardStarPals[sTrainerCardDataPtr->trainerCard.stars], 0, 96); + else + LoadPalette(sFireRedTrainerCardStarPals[sTrainerCardDataPtr->trainerCard.stars], 0, 96); + break; + case 3: + if (sTrainerCardDataPtr->cardType == CARD_TYPE_EMERALD) + LoadPalette(sEmeraldTrainerCardBadges_Pal, 48, 32); + else + LoadPalette(sFireRedTrainerCardBadges_Pal, 48, 32); + break; + case 4: + if (sTrainerCardDataPtr->cardType == CARD_TYPE_EMERALD && sTrainerCardDataPtr->trainerCard.gender != MALE) + LoadPalette(sEmeraldTrainerCardFemaleBackground_Pal, 16, 32); + else if (sTrainerCardDataPtr->trainerCard.gender != MALE) + LoadPalette(sFireRedTrainerCardFemaleBackground_Pal, 16, 32); + break; + case 5: + LoadPalette(sUnknown_83CD300, 64, 32); + break; + case 6: + SetBgTilemapBuffer(0, sTrainerCardDataPtr->bgTilemap0); + SetBgTilemapBuffer(2, sTrainerCardDataPtr->bgTilemap2); + break; + default: + FillBgTilemapBufferRect_Palette0(0, 0, 0, 0, 32, 32); + FillBgTilemapBufferRect_Palette0(2, 0, 0, 0, 32, 32); + FillBgTilemapBufferRect_Palette0(3, 0, 0, 0, 32, 32); + return TRUE; + } + + sTrainerCardDataPtr->bgPalLoadState++; + return FALSE; +} + +static void LoadTrainerCardTilemap2(const u16* ptr) +{ + s16 i, j; + u16 *dst = sTrainerCardDataPtr->bgTilemap2; + + for (i = 0; i < 20; i++) + { + for (j = 0; j < 32; j++) + { + if (j < 30) + dst[32 * i + j] = ptr[30 * i + j]; + else + dst[32 * i + j] = ptr[0]; + } + } + + CopyBgTilemapBufferToVram(2); +} + +static void LoadTrainerCardTilemap0(const u16* ptr) +{ + s16 i, j; + u16 *dst = sTrainerCardDataPtr->bgTilemap0; + + for (i = 0; i < 20; i++) + { + for (j = 0; j < 32; j++) + { + if (j < 30) + dst[32 * i + j] = ptr[30 * i + j]; + else + dst[32 * i + j] = ptr[0]; + } + } + + CopyBgTilemapBufferToVram(0); +} + +static void TrainerCard_PrintStarsAndBadgesOnCard(void) +{ + s16 i, x; + u16 tileNum = 192; + u8 palNum = 3; + + FillBgTilemapBufferRect(3, 143, 15, sUnknown_83CD95C[sTrainerCardDataPtr->cardType], sTrainerCardDataPtr->trainerCard.stars, 1, 4); + if (!sTrainerCardDataPtr->isLink) + { + x = 4; + for (i = 0; i < BADGE_COUNT; i++, tileNum += 2, x += 3) + { + if (sTrainerCardDataPtr->hasBadge[i]) + { + FillBgTilemapBufferRect(3, tileNum, x, 16, 1, 1, palNum); + FillBgTilemapBufferRect(3, tileNum + 1, x + 1, 16, 1, 1, palNum); + FillBgTilemapBufferRect(3, tileNum + 16, x, 17, 1, 1, palNum); + FillBgTilemapBufferRect(3, tileNum + 17, x + 1, 17, 1, 1, palNum); + } + } + } + + CopyBgTilemapBufferToVram(3); +} + +static void sub_808B090(void) +{ + if (sTrainerCardDataPtr->cardType != CARD_TYPE_EMERALD) + { + if (sTrainerCardDataPtr->hasTrades) + { + FillBgTilemapBufferRect(3, 141, 26, 9, 1, 1, 1); + FillBgTilemapBufferRect(3, 157, 26, 10, 1, 1, 1); + } + + if (sTrainerCardDataPtr->trainerCard.berryCrushPoints) + { + FillBgTilemapBufferRect(3, 141, 21, 13, 1, 1, 1); + FillBgTilemapBufferRect(3, 157, 21, 14, 1, 1, 1); + } + + if (sTrainerCardDataPtr->trainerCard.unionRoomNum) + { + FillBgTilemapBufferRect(3, 141, 27, 11, 1, 1, 1); + FillBgTilemapBufferRect(3, 157, 27, 12, 1, 1, 1); + } + } + else + { + if (sTrainerCardDataPtr->hasTrades) + { + FillBgTilemapBufferRect(3, 141, 26, 9, 1, 1, 0); + FillBgTilemapBufferRect(3, 157, 26, 10, 1, 1, 0); + } + } + + CopyBgTilemapBufferToVram(3); +} + +static void sub_808B180(void) +{ + if (++sTrainerCardDataPtr->var_6 > 60) + { + sTrainerCardDataPtr->var_6 = 0; + sTrainerCardDataPtr->var_7 ^= 1; + sTrainerCardDataPtr->var_7BCE = TRUE; + } +} + +u8 GetTrainerCardStars(u8 cardId) +{ + return gTrainerCards[cardId].stars; +} + +static void sub_808B1D4(void) +{ + u8 taskId = CreateTask(sub_808B21C, 0); + sub_808B21C(taskId); + SetHBlankCallback(HBlankCB_TrainerCard); +} + +static bool8 sub_808B1FC(void) +{ + if (FindTaskIdByFunc(sub_808B21C) == 0xFF) + return TRUE; + else + return FALSE; +} + +static void sub_808B21C(u8 taskId) +{ + while(sTrainerCardTasks[gTasks[taskId].data[0]](&gTasks[taskId])) + ; +} + +static bool8 sub_808B254(struct Task* task) +{ + u32 i; + + HideBg(1); + HideBg(3); + ScanlineEffect_Stop(); + ScanlineEffect_Clear(); + for (i = 0; i < 160; i++) + { + gScanlineEffectRegBuffers[1][i] = 0; + } + + task->data[0]++; + return FALSE; +} + +static bool8 sub_808B294(struct Task* task) +{ + u32 r4, r5, r10, r7, r6, var_24, r9, var; + s16 i; + + sTrainerCardDataPtr->allowDMACopy = FALSE; + if (task->data[1] >= 77) + task->data[1] = 77; + else + task->data[1] += 7; + + sTrainerCardDataPtr->var_7BCC = task->data[1]; + sub_8089BD8(task->data[1]); + + r7 = task->data[1]; + r9 = 160 - r7; + r4 = r9 - r7; + r6 = -r7 << 16; + r5 = 0xA00000 / r4; + r5 += 0xFFFF0000; + var_24 = r6; + var_24 += r5 * r4; + r10 = r5 / r4; + r5 *= 2; + + for (i = 0; i < r7; i++) + { + gScanlineEffectRegBuffers[0][i] = -i; + } + + for (; i < (s16)r9; i++) + { + var = r6 >> 16; + r6 += r5; + r5 -= r10; + gScanlineEffectRegBuffers[0][i] = var; + } + + var = var_24 >> 16; + for (; i < 160; i++) + { + gScanlineEffectRegBuffers[0][i] = var; + } + + sTrainerCardDataPtr->allowDMACopy = TRUE; + if (task->data[1] >= 77) + task->data[0]++; + + return FALSE; +} + +static bool8 sub_808B3C4(struct Task* task) +{ + sTrainerCardDataPtr->allowDMACopy = FALSE; + if (sub_8058244() == TRUE) + return FALSE; + + do + { + switch (sTrainerCardDataPtr->var_4) + { + case 0: + FillWindowPixelBuffer(1, PIXEL_FILL(0)); + FillBgTilemapBufferRect_Palette0(3, 0, 0, 0, 32, 32); + break; + case 1: + if (!sTrainerCardDataPtr->var_8) + { + if (!PrintStringsOnCardPage2()) + return FALSE; + } + else + { + if (!PrintAllOnCardPage1()) + return FALSE; + } + break; + case 2: + if (!sTrainerCardDataPtr->var_8) + LoadTrainerCardTilemap0(sTrainerCardDataPtr->var_96C); + else + PutTrainerCardWindow(1); + break; + case 3: + if (!sTrainerCardDataPtr->var_8) + sub_808B090(); + else + FillWindowPixelBuffer(2, PIXEL_FILL(0)); + break; + case 4: + if (sTrainerCardDataPtr->var_8) + sub_808B838(); + break; + default: + task->data[0]++; + sTrainerCardDataPtr->allowDMACopy = TRUE; + sTrainerCardDataPtr->var_4 = 0; + return FALSE; + } + sTrainerCardDataPtr->var_4++; + } while (gReceivedRemoteLinkPlayers == 0); + + return FALSE; +} + +static bool8 sub_808B4D8(struct Task* task) +{ + sTrainerCardDataPtr->allowDMACopy = FALSE; + if (sTrainerCardDataPtr->var_8) + { + PutTrainerCardWindow(2); + LoadTrainerCardTilemap2(&sTrainerCardDataPtr->var_E1C); + LoadTrainerCardTilemap0(&sTrainerCardDataPtr->var_4BC); + TrainerCard_PrintStarsAndBadgesOnCard(); + } + + PutTrainerCardWindow(1); + sTrainerCardDataPtr->var_8 ^= 1; + task->data[0]++; + sTrainerCardDataPtr->allowDMACopy = TRUE; + PlaySE(SE_CARD2); + return FALSE; +} + +static bool8 sub_808B540(struct Task* task) +{ + u32 r4, r5, r10, r7, r6, var_24, r9, var; + s16 i; + + sTrainerCardDataPtr->allowDMACopy = FALSE; + if (task->data[1] <= 5) + task->data[1] = 0; + else + task->data[1] -= 5; + + sTrainerCardDataPtr->var_7BCC = task->data[1]; + sub_8089BD8(task->data[1]); + + r7 = task->data[1]; + r9 = 160 - r7; + r4 = r9 - r7; + r6 = -r7 << 16; + r5 = 0xA00000 / r4; + r5 += 0xFFFF0000; + var_24 = r6; + var_24 += r5 * r4; + r10 = r5 / r4; + r5 /= 2; + + for (i = 0; i < r7; i++) + { + gScanlineEffectRegBuffers[0][i] = -i; + } + + for (; i < (s16)(r9); i++) + { + var = r6 >> 16; + r6 += r5; + r5 += r10; + gScanlineEffectRegBuffers[0][i] = var; + } + + var = var_24 >> 16; + for (; i < 160; i++) + { + gScanlineEffectRegBuffers[0][i] = var; + } + + sTrainerCardDataPtr->allowDMACopy = TRUE; + if (task->data[1] <= 0) + task->data[0]++; + + return FALSE; +} + +static bool8 sub_808B66C(struct Task *task) +{ + ShowBg(1); + ShowBg(3); + SetHBlankCallback(NULL); + DestroyTask(FindTaskIdByFunc(sub_808B21C)); + return FALSE; +} + +void ShowPlayerTrainerCard(void (*callback)(void)) +{ + sTrainerCardDataPtr = AllocZeroed(sizeof(*sTrainerCardDataPtr)); + sTrainerCardDataPtr->callback2 = callback; + if (InUnionRoom() == TRUE) + sTrainerCardDataPtr->isLink = TRUE; + else + sTrainerCardDataPtr->isLink = FALSE; + + sTrainerCardDataPtr->language = GAME_LANGUAGE; + TrainerCard_GenerateCardForLinkPlayer(&sTrainerCardDataPtr->trainerCard); + SetMainCallback2(CB2_InitTrainerCard); +} + +void ShowTrainerCardInLink(u8 cardId, void (*callback)(void)) +{ + sTrainerCardDataPtr = AllocZeroed(sizeof(*sTrainerCardDataPtr)); + sTrainerCardDataPtr->callback2 = callback; + sTrainerCardDataPtr->isLink = TRUE; + sTrainerCardDataPtr->trainerCard = gTrainerCards[cardId]; + sTrainerCardDataPtr->language = gLinkPlayers[cardId].language; + SetMainCallback2(CB2_InitTrainerCard); +} + +static void sub_808B774(void) +{ + u8 i; + + sTrainerCardDataPtr->taskState = 0; + sTrainerCardDataPtr->var_6 = gSaveBlock2Ptr->playTimeVBlanks; + sTrainerCardDataPtr->var_7 = 0; + sTrainerCardDataPtr->var_8 = 0; + sTrainerCardDataPtr->var_456 = 0; + if (GetCardType() == CARD_TYPE_EMERALD) + sTrainerCardDataPtr->cardType = CARD_TYPE_EMERALD; + else + sTrainerCardDataPtr->cardType = CARD_TYPE_FRLG; + + for (i = 0; i < 4; i++) + { + CopyEasyChatWord(sTrainerCardDataPtr->var_19[i], sTrainerCardDataPtr->trainerCard.var_28[i]); + } +} + +static u8 GetCardType(void) +{ + if (sTrainerCardDataPtr == NULL) + { + if (gGameVersion == VERSION_FIRE_RED || gGameVersion == VERSION_LEAF_GREEN) + return CARD_TYPE_FRLG; + else + return CARD_TYPE_EMERALD; + } + else + { + if (sTrainerCardDataPtr->trainerCard.version == VERSION_FIRE_RED || sTrainerCardDataPtr->trainerCard.version == VERSION_LEAF_GREEN) + return CARD_TYPE_FRLG; + else + return CARD_TYPE_EMERALD; + } +} + +static void sub_808B838(void) +{ + u8 val = sLinkTrainerCardFrontPics[sTrainerCardDataPtr->cardType][sTrainerCardDataPtr->trainerCard.gender]; + + if (InUnionRoom() == TRUE && gReceivedRemoteLinkPlayers == 1) + { + val = sTrainerCardDataPtr->trainerCard.var_4F; + sub_810C330(FacilityClassToPicIndex(val), TRUE, sTrainerCardPicPositions[sTrainerCardDataPtr->cardType][sTrainerCardDataPtr->trainerCard.gender][0], + sTrainerCardPicPositions[sTrainerCardDataPtr->cardType][sTrainerCardDataPtr->trainerCard.gender][1], 8, 2); + } + else + { + if (sTrainerCardDataPtr->cardType != CARD_TYPE_FRLG) + { + sub_810C330(FacilityClassToPicIndex(val), TRUE, sTrainerCardPicPositions[sTrainerCardDataPtr->cardType][sTrainerCardDataPtr->trainerCard.gender][0], + sTrainerCardPicPositions[sTrainerCardDataPtr->cardType][sTrainerCardDataPtr->trainerCard.gender][1], 8, 2); + } + else + { + sub_810C330(PlayerGenderToFrontTrainerPicId_Debug(sTrainerCardDataPtr->trainerCard.gender, TRUE), TRUE, + sTrainerCardPicPositions[sTrainerCardDataPtr->cardType][sTrainerCardDataPtr->trainerCard.gender][0], + sTrainerCardPicPositions[sTrainerCardDataPtr->cardType][sTrainerCardDataPtr->trainerCard.gender][1], + 8, 2); + } + } +} + +// Unused +static void Unref_InitTrainerCard(void (*callback)(void)) +{ + ShowPlayerTrainerCard(callback); + SetMainCallback2(CB2_InitTrainerCard); +} + +// Unused +static void Unref_InitTrainerCardLink(void (*callback)(void)) +{ + memcpy(gTrainerCards, &sLinkPlayerTrainerCardTemplate1, sizeof(sLinkPlayerTrainerCardTemplate1)); + ShowTrainerCardInLink(CARD_TYPE_FRLG, callback); + SetMainCallback2(CB2_InitTrainerCard); +} + +// Unused +static void Unref_InitTrainerCardLink2(void (*callback)(void)) +{ + memcpy(gTrainerCards, &sLinkPlayerTrainerCardTemplate2, sizeof(sLinkPlayerTrainerCardTemplate2)); + ShowTrainerCardInLink(CARD_TYPE_FRLG, callback); + SetMainCallback2(CB2_InitTrainerCard); +} + |