#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 "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 "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: Link_TryStartSend5FFF(); 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 = GAME_VERSION; 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); }