mirror of
https://github.com/pret/pokeruby.git
synced 2026-10-09 18:06:33 -04:00
1618 lines
41 KiB
C
1618 lines
41 KiB
C
#include "global.h"
|
|
#include "trainer_card.h"
|
|
#include "easy_chat.h"
|
|
#include "event_data.h"
|
|
#include "field_effect.h"
|
|
#include "graphics.h"
|
|
#include "link.h"
|
|
#include "m4a.h"
|
|
#include "main.h"
|
|
#include "menu.h"
|
|
#include "money.h"
|
|
#include "palette.h"
|
|
#include "pokedex.h"
|
|
#include "overworld.h"
|
|
#include "script_pokemon_80C4.h"
|
|
#include "constants/songs.h"
|
|
#include "sound.h"
|
|
#include "sprite.h"
|
|
#include "string_util.h"
|
|
#include "strings2.h"
|
|
#include "task.h"
|
|
#include "scanline_effect.h"
|
|
#include "util.h"
|
|
#include "ewram.h"
|
|
|
|
typedef void (*Callback)(void);
|
|
|
|
struct Struct2000000
|
|
{
|
|
/*0x00*/ u8 current_state;
|
|
/*0x01*/ bool8 isShowingLinkCard;
|
|
/*0x02*/ u8 starCount;
|
|
/*0x03*/ bool8 backSideShown;
|
|
/*0x04*/ u8 var_4;
|
|
/*0x05*/ bool8 showColon;
|
|
/*0x06*/ u8 frameCounter; /* Used to flash colon */
|
|
/*0x07*/ bool8 showPokedexCount;
|
|
/*0x08*/ bool8 showHallOfFame;
|
|
/*0x09*/ bool8 showLinkBattleStatus;
|
|
/*0x0A*/ bool8 showBattleTowerStatus;
|
|
/*0x0B*/ bool8 showContestRecord;
|
|
/*0x0C*/ bool8 showMixingRecord;
|
|
/*0x0D*/ bool8 showTradingRecord;
|
|
/*0x0E*/ bool8 ownedBadges[8];
|
|
/*0x16*/ u8 filler_16[10];
|
|
/*0x20*/ u8 easyChatPhrase[4][0x10];
|
|
/*0x60*/ Callback *var_60;
|
|
/*0x64*/ struct TrainerCard displayedCard;
|
|
/*0x9C*/ u8 language; // 0x9C
|
|
};
|
|
|
|
extern struct LinkPlayerMapObject gLinkPlayerMapObjects[];
|
|
|
|
EWRAM_DATA struct TrainerCard gTrainerCards[4] = {0};
|
|
|
|
extern const u16 gUnknown_083B5F0C[];
|
|
extern const u16 gBadgesPalette[];
|
|
extern const u16 gUnknown_083B5F4C[];
|
|
extern const u16 gUnknown_083B5F6C[];
|
|
extern const u16 gTrainerCardBadgesMap[][4];
|
|
|
|
const u8 gBadgesTiles[] = INCBIN_U8("graphics/trainer_card/badges.4bpp");
|
|
// XXX: what is this?
|
|
u8 *const ewram_ = gSharedMem;
|
|
|
|
#if DEBUG
|
|
const struct TrainerCard sTestTrainerCard =
|
|
{
|
|
.gender = FEMALE,
|
|
.stars = 4,
|
|
.hasPokedex = TRUE,
|
|
.var_3 = TRUE,
|
|
.var_4 = TRUE,
|
|
.firstHallOfFameA = 999,
|
|
.firstHallOfFameB = 99,
|
|
.firstHallOfFameC = 99,
|
|
.pokedexSeen = 411,
|
|
.trainerId = 12345,
|
|
.playTimeHours = 99,
|
|
.playTimeMinutes = 99,
|
|
.linkBattleWins = 9999,
|
|
.linkBattleLosses = 9999,
|
|
.battleTowerWins = 9999,
|
|
.battleTowerLosses = 9999,
|
|
.contestsWithFriends = 999,
|
|
.pokeblocksWithFriends = 0xFFFF,
|
|
.pokemonTrades = 0xFFFF,
|
|
.money = 99999,
|
|
.var_28 = {1, 2, 3, 4},
|
|
.playerName = _("てすと"), // "test"
|
|
};
|
|
#endif
|
|
|
|
bool8 TrainerCard_Init(struct Task *);
|
|
bool8 TrainerCard_WaitForFadeInToFinish(struct Task *);
|
|
bool8 TrainerCard_WaitForKeys(struct Task *);
|
|
bool8 TrainerCard_StartFlipAntimation(struct Task *);
|
|
bool8 TrainerCard_WaitForFlipToFinish(struct Task *);
|
|
bool8 TrainerCard_FadeOut(struct Task *);
|
|
bool8 TrainerCard_WaitForFadeOutToFinishAndQuit(struct Task *);
|
|
|
|
bool8 (*const TrainerCard_StateMachine[])(struct Task *) =
|
|
{
|
|
TrainerCard_Init,
|
|
TrainerCard_WaitForFadeInToFinish,
|
|
TrainerCard_WaitForKeys,
|
|
TrainerCard_StartFlipAntimation,
|
|
TrainerCard_WaitForFlipToFinish,
|
|
TrainerCard_FadeOut,
|
|
TrainerCard_WaitForFadeOutToFinishAndQuit,
|
|
};
|
|
|
|
bool8 TrainerCard_InitFlipAnimation(struct Task *);
|
|
bool8 TrainerCard_ScaleDownFlipAnimation(struct Task *);
|
|
bool8 TrainerCard_SwitchToNewSide(struct Task *);
|
|
bool8 TrainerCard_ScaleUpFlipAnimation(struct Task *);
|
|
bool8 TrainerCard_FinishFlipAnimation(struct Task *);
|
|
|
|
bool8 (*const TrainerCard_FlipAnimationStateMachine[])(struct Task *) =
|
|
{
|
|
TrainerCard_InitFlipAnimation,
|
|
TrainerCard_ScaleDownFlipAnimation,
|
|
TrainerCard_SwitchToNewSide,
|
|
TrainerCard_ScaleUpFlipAnimation,
|
|
TrainerCard_FinishFlipAnimation,
|
|
};
|
|
|
|
// FIXME: Other signature than on save_menu_util.h
|
|
void FormatPlayTime(u8 *playtime, u16 hours, u16 minutes, s16 colon);
|
|
u16 GetPokedexSeenCount(void);
|
|
|
|
enum
|
|
{
|
|
TD_SHOWING_LINK_CARD,
|
|
TD_CARD_INDEX,
|
|
TD_CALLBACK,
|
|
};
|
|
|
|
static void sub_8093174(void);
|
|
static void sub_809323C(void);
|
|
static void sub_8093254(void);
|
|
static void TrainerCard_InitScreenForPlayer(Callback callBack);
|
|
static void TrainerCard_InitScreenForLinkPlayer(u8 arg1, Callback callBack);
|
|
void TrainerCard_FillTrainerCardStruct(void);
|
|
static void nullsub_60(u8);
|
|
static u32 sav12_xor_get_clamped_above(u8 index, u32 maxVal);
|
|
static u8 TrainerCard_GetStarCount(struct TrainerCard *);
|
|
static void sub_8093534(void);
|
|
static void sub_8093550(void);
|
|
static void sub_8093598(void);
|
|
static void sub_80935EC(void);
|
|
static void sub_8093610(void);
|
|
static void sub_8093688(void);
|
|
static void TrainerCard_FillFlags(void);
|
|
static void sub_80937A4(void);
|
|
static void sub_80937BC(void);
|
|
static void sub_80937D8(void);
|
|
static void sub_80937F0(void);
|
|
static void nullsub_15(void);
|
|
static void sub_8093800(void);
|
|
static void TrainerCard_CreateStateMachine(void);
|
|
static void TrainerCard_RunStateMachine(u8 taskId);
|
|
static void TrainerCard_CreatePrintPlayTimeTask(void);
|
|
static void TrainerCard_DestoryPlayTimeTask(void);
|
|
static void TrainerCard_Front_PrintPlayTime(u8 taskId);
|
|
static void TrainerCard_CreateFlipAnimationTask(void);
|
|
static u8 TrainerCard_HasFlipAnimationFinished(void);
|
|
static void TrainerCard_RunFlipAnimationStateMachine(u8 taskId);
|
|
static void TrainerCard_FlipAnimationHBlankCallback(void);
|
|
static void TrainerCard_DrawCard(void);
|
|
static void TrainerCard_DrawCardFront(void);
|
|
static void TrainerCard_DrawCardBack(void);
|
|
static void TrainerCard_ResetOffsetRegisters(void);
|
|
static void TrainerCard_CopyGraphics(void);
|
|
static void TrainerCard_LoadPalettes(void);
|
|
static void TrainerCard_LoadTrainerGraphics(void);
|
|
static void sub_8093F14(void);
|
|
static void sub_8093F48(void);
|
|
static void sub_8093F64(void);
|
|
static void TrainerCard_LoadTrainerTilemap(void);
|
|
static void TrainerCard_DrawStars(void);
|
|
static void TrainerCard_DisplayBadges(void);
|
|
static void TrainerCard_ClearTrainerGraphics(void);
|
|
static void TrainerCard_ClearPokedexLabel(void);
|
|
static void TrainerCard_Front_PrintTexts(void);
|
|
static void TrainerCard_Back_PrintTexts(void);
|
|
static void TrainerCard_Front_PrintTrainerID(void);
|
|
static void TrainerCard_Front_PrintMoney(void);
|
|
static void TrainerCard_Front_PrintPokedexCount(void);
|
|
static void TrainerCard_Front_GetPlayTimeString(u8 *arg1, s16 colon);
|
|
static void TrainerCard_PrintEasyChatPhrase(void);
|
|
static void TrainerCard_Back_PrintName(void);
|
|
static void TrainerCard_Back_PrintHallOfFameTime_Label(void);
|
|
static void TrainerCard_Back_PrintHallOfFameTime(void);
|
|
static void TrainerCard_Back_PrintLinkBattlesLabel(void);
|
|
static void TrainerCard_Back_PrintLinkBattles(void);
|
|
static void TrainerCard_Back_PrintBattleTower_Label(void);
|
|
static void TrainerCard_Back_PrintBattleTower(void);
|
|
static void TrainerCard_Back_PrintLinkContests_Label(void);
|
|
static void TrainerCard_Back_PrintLinkContests(void);
|
|
static void TrainerCard_Back_PrintLinkPokeblocks_Label(void);
|
|
static void TrainerCard_Back_PrintLinkPokeblocks(void);
|
|
static void TrainerCard_Back_PrintPokemonTrades_Label(void);
|
|
static void TrainerCard_Back_PrintPokemonTrades(void);
|
|
void unref_sub_8094588(u16 left, u16 top);
|
|
|
|
#if DEBUG
|
|
static u8 gDebug_03000748;
|
|
#endif
|
|
|
|
void TrainerCard_ShowPlayerCard(Callback arg1)
|
|
{
|
|
#if DEBUG
|
|
gDebug_03000748 = 0;
|
|
#endif
|
|
TrainerCard_InitScreenForPlayer(arg1);
|
|
SetMainCallback2(sub_8093174);
|
|
ewram0_2.language = GAME_LANGUAGE;
|
|
}
|
|
|
|
void TrainerCard_ShowLinkCard(u8 playerIndex, Callback arg2)
|
|
{
|
|
#if DEBUG
|
|
gDebug_03000748 = 0;
|
|
#endif
|
|
TrainerCard_InitScreenForLinkPlayer(playerIndex, arg2);
|
|
SetMainCallback2(sub_8093174);
|
|
ewram0_2.language = gLinkPlayers[gLinkPlayerMapObjects[playerIndex].linkPlayerId].language;
|
|
}
|
|
|
|
#if DEBUG
|
|
void debug_sub_80A0710(Callback callback)
|
|
{
|
|
gDebug_03000748 = TRUE;
|
|
TrainerCard_InitScreenForPlayer(callback);
|
|
SetMainCallback2(sub_8093174);
|
|
ewram0_2.language = GAME_LANGUAGE;
|
|
}
|
|
|
|
void debug_sub_80A073C(Callback callback)
|
|
{
|
|
memcpy(&gTrainerCards[0], &sTestTrainerCard, sizeof(struct TrainerCard));
|
|
gDebug_03000748=TRUE;
|
|
TrainerCard_InitScreenForLinkPlayer(0, callback);
|
|
SetMainCallback2(sub_8093174);
|
|
ewram0_2.language = GAME_LANGUAGE;
|
|
}
|
|
|
|
void debug_sub_80A0780()
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < 4; i++)
|
|
memcpy(&gTrainerCards[i], &sTestTrainerCard, sizeof(struct TrainerCard));
|
|
}
|
|
#endif
|
|
|
|
static void sub_8093174(void)
|
|
{
|
|
switch (gMain.state)
|
|
{
|
|
case 0:
|
|
sub_8093534();
|
|
sub_8093688();
|
|
gMain.state++;
|
|
break;
|
|
case 1:
|
|
sub_8093598();
|
|
gMain.state++;
|
|
break;
|
|
case 2:
|
|
sub_80935EC();
|
|
gMain.state++;
|
|
break;
|
|
case 3:
|
|
sub_8093610();
|
|
sub_80937A4();
|
|
gMain.state++;
|
|
break;
|
|
case 4:
|
|
sub_80937BC();
|
|
gMain.state++;
|
|
case 5:
|
|
if (MultistepInitMenuWindowContinue())
|
|
gMain.state++;
|
|
break;
|
|
case 6:
|
|
sub_80937F0();
|
|
gMain.state++;
|
|
break;
|
|
case 7:
|
|
sub_80937D8();
|
|
gMain.state++;
|
|
break;
|
|
case 8:
|
|
nullsub_15();
|
|
sub_8093800();
|
|
sub_8093550();
|
|
SetMainCallback2(sub_809323C);
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void sub_809323C(void)
|
|
{
|
|
RunTasks();
|
|
AnimateSprites();
|
|
BuildOamBuffer();
|
|
UpdatePaletteFade();
|
|
}
|
|
|
|
static void sub_8093254(void)
|
|
{
|
|
LoadOam();
|
|
ProcessSpriteCopyRequests();
|
|
TransferPlttBuffer();
|
|
ewram0_2.frameCounter++;
|
|
if (ewram0_2.frameCounter >= 60)
|
|
{
|
|
ewram0_2.frameCounter = 0;
|
|
ewram0_2.showColon ^= 1;
|
|
}
|
|
if (ewram0_2.var_4)
|
|
DmaCopy16(3, &gScanlineEffectRegBuffers[0], &gScanlineEffectRegBuffers[1], 0x140);
|
|
}
|
|
|
|
static void TrainerCard_InitScreenForPlayer(Callback callBack)
|
|
{
|
|
u8 taskId = CreateTask(nullsub_60, 0xFF);
|
|
struct Task *task = &gTasks[taskId];
|
|
task->data[TD_SHOWING_LINK_CARD] = FALSE;
|
|
StoreWordInTwoHalfwords(&task->data[TD_CALLBACK], (u32)callBack);
|
|
}
|
|
|
|
static void TrainerCard_InitScreenForLinkPlayer(u8 arg1, Callback callBack)
|
|
{
|
|
u8 taskId = CreateTask(nullsub_60, 0xFF);
|
|
|
|
struct Task *task = &gTasks[taskId];
|
|
task->data[TD_SHOWING_LINK_CARD] = TRUE;
|
|
task->data[TD_CARD_INDEX] = arg1;
|
|
StoreWordInTwoHalfwords(&task->data[TD_CALLBACK], (u32)callBack);
|
|
}
|
|
|
|
void TrainerCard_FillTrainerCardStruct(void)
|
|
{
|
|
u8 taskId = FindTaskIdByFunc(nullsub_60);
|
|
struct Task *task = &gTasks[taskId];
|
|
ewram0_2.isShowingLinkCard = task->data[TD_SHOWING_LINK_CARD];
|
|
|
|
LoadWordFromTwoHalfwords((u16 *)&task->data[TD_CALLBACK], (u32 *)&ewram0_2.var_60);
|
|
|
|
if (ewram0_2.isShowingLinkCard)
|
|
{
|
|
ewram0_2.displayedCard = gTrainerCards[task->data[TD_CARD_INDEX]];
|
|
}
|
|
else
|
|
{
|
|
TrainerCard_GenerateCardForPlayer(&ewram0_2.displayedCard);
|
|
}
|
|
}
|
|
|
|
static void nullsub_60(u8 taskid)
|
|
{
|
|
}
|
|
|
|
void TrainerCard_GenerateCardForPlayer(struct TrainerCard *trainerCard)
|
|
{
|
|
u32 playTime;
|
|
bool32 enteredHallOfFame;
|
|
bool8 r4;
|
|
u8 i;
|
|
|
|
trainerCard->gender = gSaveBlock2.playerGender;
|
|
trainerCard->playTimeHours = gSaveBlock2.playTimeHours;
|
|
trainerCard->playTimeMinutes = gSaveBlock2.playTimeMinutes;
|
|
|
|
playTime = GetGameStat(GAME_STAT_FIRST_HOF_PLAY_TIME);
|
|
enteredHallOfFame = GetGameStat(GAME_STAT_ENTERED_HOF);
|
|
if (!enteredHallOfFame)
|
|
{
|
|
playTime = 0;
|
|
}
|
|
trainerCard->firstHallOfFameA = playTime >> 16;
|
|
trainerCard->firstHallOfFameB = (playTime >> 8) & 0xFF;
|
|
trainerCard->firstHallOfFameC = playTime & 0xFF;
|
|
|
|
trainerCard->hasPokedex = FlagGet(FLAG_SYS_POKEDEX_GET);
|
|
trainerCard->var_3 = CompletedHoennPokedex();
|
|
trainerCard->pokedexSeen = GetPokedexSeenCount();
|
|
|
|
trainerCard->trainerId = (gSaveBlock2.playerTrainerId[1] << 8) | gSaveBlock2.playerTrainerId[0];
|
|
|
|
// Link Cable Battles
|
|
trainerCard->linkBattleWins = sav12_xor_get_clamped_above(GAME_STAT_LINK_BATTLE_WINS, 9999);
|
|
trainerCard->linkBattleLosses = sav12_xor_get_clamped_above(GAME_STAT_LINK_BATTLE_LOSSES, 9999);
|
|
|
|
// Contests w/ Friends
|
|
trainerCard->contestsWithFriends = sav12_xor_get_clamped_above(GAME_STAT_WON_LINK_CONTEST, 999);
|
|
|
|
// Pokéblocks w/ Friends
|
|
trainerCard->pokeblocksWithFriends = sav12_xor_get_clamped_above(GAME_STAT_POKEBLOCKS_WITH_FRIENDS, 0xFFFF);
|
|
|
|
// Pokémon Trades
|
|
trainerCard->pokemonTrades = sav12_xor_get_clamped_above(GAME_STAT_POKEMON_TRADES, 0xFFFF);
|
|
|
|
// Battle Tower
|
|
trainerCard->battleTowerWins = gSaveBlock2.battleTower.totalBattleTowerWins;
|
|
trainerCard->battleTowerLosses = gSaveBlock2.battleTower.bestBattleTowerWinStreak;
|
|
if (trainerCard->battleTowerWins > 9999)
|
|
{
|
|
trainerCard->battleTowerWins = 9999;
|
|
}
|
|
if (trainerCard->battleTowerLosses > 9999)
|
|
{
|
|
trainerCard->battleTowerLosses = 9999;
|
|
}
|
|
|
|
r4 = FALSE;
|
|
if (sub_80C4D50() > 4)
|
|
{
|
|
r4 = TRUE;
|
|
}
|
|
trainerCard->var_4 = r4;
|
|
|
|
trainerCard->money = gSaveBlock1.money;
|
|
|
|
for (i = 0; i < 4; i++)
|
|
{
|
|
trainerCard->var_28[i] = gSaveBlock1.easyChats.unk2B1C[i];
|
|
}
|
|
|
|
for (i = 0; i < 8; i++)
|
|
{
|
|
trainerCard->playerName[i] = gSaveBlock2.playerName[i];
|
|
}
|
|
|
|
trainerCard->stars = TrainerCard_GetStarCount(trainerCard);
|
|
}
|
|
|
|
u8 sub_80934C4(u8 id)
|
|
{
|
|
return gTrainerCards[id].stars;
|
|
}
|
|
|
|
static u32 sav12_xor_get_clamped_above(u8 index, u32 maxVal)
|
|
{
|
|
u32 value = GetGameStat(index);
|
|
|
|
if (value > maxVal)
|
|
{
|
|
value = maxVal;
|
|
}
|
|
|
|
return value;
|
|
}
|
|
|
|
static u8 TrainerCard_GetStarCount(struct TrainerCard *trainerCard)
|
|
{
|
|
u8 value = 0;
|
|
|
|
if (trainerCard->firstHallOfFameA != 0 || trainerCard->firstHallOfFameB != 0 || trainerCard->firstHallOfFameC != 0)
|
|
{
|
|
value++;
|
|
}
|
|
|
|
if (trainerCard->var_3)
|
|
{
|
|
value++;
|
|
}
|
|
|
|
if (trainerCard->battleTowerLosses > 49)
|
|
{
|
|
value++;
|
|
}
|
|
|
|
if (trainerCard->var_4)
|
|
{
|
|
value++;
|
|
}
|
|
|
|
return value;
|
|
}
|
|
|
|
static void sub_8093534(void)
|
|
{
|
|
SetVBlankCallback(NULL);
|
|
SetHBlankCallback(NULL);
|
|
REG_DISPCNT = 0;
|
|
}
|
|
|
|
static void sub_8093550(void)
|
|
{
|
|
u16 backup;
|
|
|
|
SetVBlankCallback(sub_8093254);
|
|
|
|
backup = REG_IME;
|
|
REG_IME = 0;
|
|
REG_IE |= INTR_FLAG_VBLANK | INTR_FLAG_HBLANK;
|
|
REG_IME = backup;
|
|
|
|
REG_DISPSTAT |= DISPSTAT_VBLANK_INTR | DISPSTAT_HBLANK_INTR;
|
|
REG_DISPCNT = DISPCNT_MODE_0 | DISPCNT_OBJ_1D_MAP | DISPCNT_BG_ALL_ON | DISPCNT_OBJ_ON;
|
|
}
|
|
|
|
void sub_8093598(void)
|
|
{
|
|
DmaFill16Large(3, 0, (void *)VRAM, 0x10000, 0x1000);
|
|
}
|
|
|
|
void sub_80935EC(void)
|
|
{
|
|
DmaFill16Defvars(3, 0, (void *)OAM, 0x400);
|
|
}
|
|
|
|
void sub_8093610(void)
|
|
{
|
|
REG_BG0CNT = 0;
|
|
REG_BG1CNT = 0;
|
|
REG_BG2CNT = 0;
|
|
REG_BG3CNT = 0;
|
|
REG_BG0HOFS = 0;
|
|
REG_BG0VOFS = 0;
|
|
REG_BG1HOFS = 0;
|
|
REG_BG1VOFS = 0;
|
|
REG_BG2HOFS = 0;
|
|
REG_BG2VOFS = 0;
|
|
REG_BG3HOFS = 0;
|
|
REG_BG3VOFS = 0;
|
|
|
|
REG_BG0CNT = BGCNT_PRIORITY(0) | BGCNT_CHARBASE(2) | BGCNT_SCREENBASE(30) | BGCNT_16COLOR | BGCNT_TXT256x256;
|
|
REG_BG1CNT = BGCNT_PRIORITY(1) | BGCNT_CHARBASE(0) | BGCNT_SCREENBASE(8) | BGCNT_16COLOR | BGCNT_TXT256x256;
|
|
REG_BG2CNT = BGCNT_PRIORITY(2) | BGCNT_CHARBASE(0) | BGCNT_SCREENBASE(9) | BGCNT_16COLOR | BGCNT_TXT256x256;
|
|
REG_BG3CNT = BGCNT_PRIORITY(3) | BGCNT_CHARBASE(0) | BGCNT_SCREENBASE(10) | BGCNT_16COLOR | BGCNT_TXT256x256;
|
|
}
|
|
|
|
static void sub_8093688(void)
|
|
{
|
|
u8 i;
|
|
|
|
TrainerCard_FillTrainerCardStruct();
|
|
ewram0_2.current_state = 0;
|
|
ewram0_2.backSideShown = FALSE;
|
|
ewram0_2.var_4 = FALSE;
|
|
ewram0_2.starCount = ewram0_2.displayedCard.stars;
|
|
ewram0_2.showColon = 0;
|
|
ewram0_2.frameCounter = 0;
|
|
for (i = 0; i < 4; i++)
|
|
EasyChat_GetWordText(ewram0_2.easyChatPhrase[i], ewram0_2.displayedCard.var_28[i]);
|
|
TrainerCard_FillFlags();
|
|
}
|
|
|
|
static void TrainerCard_FillFlags(void)
|
|
{
|
|
ewram0_2.showPokedexCount = 0;
|
|
ewram0_2.showHallOfFame = 0;
|
|
ewram0_2.showLinkBattleStatus = 0;
|
|
ewram0_2.showBattleTowerStatus = 0;
|
|
ewram0_2.showContestRecord = 0;
|
|
ewram0_2.showMixingRecord = 0;
|
|
ewram0_2.showTradingRecord = 0;
|
|
memset(ewram0_2.ownedBadges, 0, sizeof(ewram0_2.ownedBadges));
|
|
|
|
if (ewram0_2.displayedCard.hasPokedex)
|
|
ewram0_2.showPokedexCount++;
|
|
|
|
if (ewram0_2.displayedCard.firstHallOfFameA != 0
|
|
|| ewram0_2.displayedCard.firstHallOfFameB != 0
|
|
|| ewram0_2.displayedCard.firstHallOfFameC != 0)
|
|
ewram0_2.showHallOfFame++;
|
|
|
|
if (ewram0_2.displayedCard.linkBattleWins != 0 || ewram0_2.displayedCard.linkBattleLosses != 0)
|
|
ewram0_2.showLinkBattleStatus++;
|
|
|
|
if (ewram0_2.displayedCard.battleTowerWins != 0 || ewram0_2.displayedCard.battleTowerLosses != 0)
|
|
ewram0_2.showBattleTowerStatus++;
|
|
|
|
if (ewram0_2.displayedCard.contestsWithFriends != 0)
|
|
ewram0_2.showContestRecord++;
|
|
|
|
if (ewram0_2.displayedCard.pokeblocksWithFriends != 0)
|
|
ewram0_2.showMixingRecord++;
|
|
|
|
if (ewram0_2.displayedCard.pokemonTrades != 0)
|
|
ewram0_2.showTradingRecord++;
|
|
|
|
if (!ewram0_2.isShowingLinkCard)
|
|
{
|
|
u32 badgeFlag;
|
|
int i = 0;
|
|
|
|
badgeFlag = FLAG_BADGE01_GET;
|
|
while (1)
|
|
{
|
|
if (FlagGet(badgeFlag))
|
|
ewram0_2.ownedBadges[i]++;
|
|
badgeFlag++;
|
|
i++;
|
|
if (badgeFlag > FLAG_BADGE08_GET)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
#if DEBUG
|
|
if (gDebug_03000748 != 0)
|
|
{
|
|
ewram0_2.showHallOfFame = TRUE;
|
|
ewram0_2.showLinkBattleStatus = TRUE;
|
|
ewram0_2.showBattleTowerStatus = TRUE;
|
|
ewram0_2.showContestRecord = TRUE;
|
|
ewram0_2.showMixingRecord = TRUE;
|
|
ewram0_2.showTradingRecord = TRUE;
|
|
memset(ewram0_2.ownedBadges, TRUE, sizeof(ewram0_2.ownedBadges));
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void sub_80937A4()
|
|
{
|
|
ResetPaletteFade();
|
|
ResetSpriteData();
|
|
FreeAllSpritePalettes();
|
|
ResetTasks();
|
|
}
|
|
|
|
void sub_80937BC()
|
|
{
|
|
Text_LoadWindowTemplate(&gWindowTemplate_TrainerCard_Back_Values);
|
|
MultistepInitMenuWindowBegin(&gWindowTemplate_TrainerCard_Back_Values);
|
|
}
|
|
|
|
static void sub_80937D8()
|
|
{
|
|
TrainerCard_ResetOffsetRegisters();
|
|
TrainerCard_CopyGraphics();
|
|
sub_8093F64();
|
|
TrainerCard_DrawCard();
|
|
}
|
|
|
|
static void sub_80937F0()
|
|
{
|
|
TrainerCard_LoadTrainerGraphics();
|
|
}
|
|
|
|
static void nullsub_15(void)
|
|
{
|
|
}
|
|
|
|
static void sub_8093800()
|
|
{
|
|
TrainerCard_CreateStateMachine();
|
|
}
|
|
|
|
static void TrainerCard_CreateStateMachine(void)
|
|
{
|
|
u8 taskId;
|
|
|
|
taskId = CreateTask(TrainerCard_RunStateMachine, 0);
|
|
TrainerCard_RunStateMachine(taskId);
|
|
}
|
|
|
|
static void TrainerCard_RunStateMachine(u8 taskId)
|
|
{
|
|
while (TrainerCard_StateMachine[ewram0_2.current_state](&gTasks[taskId]) != 0)
|
|
;
|
|
}
|
|
|
|
bool8 TrainerCard_Init(struct Task *task)
|
|
{
|
|
ewram0_2.showColon = gSaveBlock2.playTimeSeconds & 1;
|
|
ewram0_2.frameCounter = gSaveBlock2.playTimeVBlanks;
|
|
TrainerCard_CreatePrintPlayTimeTask();
|
|
BeginNormalPaletteFade(0xFFFFFFFF, 0, 16, 0, 0);
|
|
ewram0_2.current_state++; /* Advance state machine */
|
|
return FALSE;
|
|
}
|
|
|
|
bool8 TrainerCard_WaitForFadeInToFinish(struct Task *task)
|
|
{
|
|
if (!gPaletteFade.active)
|
|
ewram0_2.current_state++; /* Advance state machine */
|
|
return FALSE;
|
|
}
|
|
|
|
bool8 TrainerCard_WaitForKeys(struct Task *task)
|
|
{
|
|
if (gMain.newKeys & B_BUTTON)
|
|
{
|
|
ewram0_2.current_state = 5; /* Jump to fadeout state */
|
|
return TRUE;
|
|
}
|
|
else if (gMain.newKeys & A_BUTTON)
|
|
{
|
|
/* It appears that it was previously possible to return the the front side
|
|
after viewing the back side. This was probably removed due to being
|
|
unintuitive. */
|
|
if (ewram0_2.backSideShown)
|
|
{
|
|
ewram0_2.current_state = 5; /* Jump to fadeout state */
|
|
}
|
|
else
|
|
{
|
|
ewram0_2.backSideShown ^= 1; /* Switch to back side */
|
|
ewram0_2.current_state = 3; /* Jump to start flip animation state */
|
|
}
|
|
return TRUE;
|
|
}
|
|
#if DEBUG
|
|
else if (gDebug_03000748 && gMain.newKeys & R_BUTTON)
|
|
{
|
|
ewram0_2.starCount++;
|
|
ewram0_2.starCount %= 5;
|
|
TrainerCard_LoadPalettes();
|
|
if (ewram0_2.backSideShown == 0)
|
|
TrainerCard_DrawStars();
|
|
}
|
|
#endif
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
bool8 TrainerCard_StartFlipAntimation(struct Task *task)
|
|
{
|
|
TrainerCard_CreateFlipAnimationTask();
|
|
PlaySE(SE_CARD);
|
|
ewram0_2.current_state++; /* Advance state machine */
|
|
return FALSE;
|
|
}
|
|
|
|
bool8 TrainerCard_WaitForFlipToFinish(struct Task *task)
|
|
{
|
|
if (TrainerCard_HasFlipAnimationFinished())
|
|
ewram0_2.current_state = 2; /* Return to wait for keys state */
|
|
return FALSE;
|
|
}
|
|
|
|
bool8 TrainerCard_FadeOut(struct Task *task)
|
|
{
|
|
TrainerCard_DestoryPlayTimeTask();
|
|
BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, 0);
|
|
ewram0_2.current_state++; /* Advance state machine */
|
|
return FALSE;
|
|
}
|
|
|
|
bool8 TrainerCard_WaitForFadeOutToFinishAndQuit(struct Task *task)
|
|
{
|
|
if (!gPaletteFade.active)
|
|
SetMainCallback2((MainCallback)ewram0_2.var_60);
|
|
return FALSE;
|
|
}
|
|
|
|
static void TrainerCard_CreatePrintPlayTimeTask(void)
|
|
{
|
|
CreateTask(TrainerCard_Front_PrintPlayTime, 0);
|
|
BasicInitMenuWindow(&gWindowTemplate_TrainerCard_Back_Values);
|
|
}
|
|
|
|
static void TrainerCard_DestoryPlayTimeTask(void)
|
|
{
|
|
u8 taskId = FindTaskIdByFunc(TrainerCard_Front_PrintPlayTime);
|
|
|
|
if (taskId != 0xFF)
|
|
DestroyTask(taskId);
|
|
}
|
|
|
|
static void TrainerCard_Front_PrintPlayTime(u8 taskId)
|
|
{
|
|
u8 buffer[32];
|
|
struct Task *task = &gTasks[taskId];
|
|
|
|
if (ewram0_2.showColon != task->data[TD_CARD_INDEX])
|
|
{
|
|
task->data[TD_CARD_INDEX] = ewram0_2.showColon;
|
|
task->data[TD_SHOWING_LINK_CARD] ^= TRUE;
|
|
}
|
|
TrainerCard_Front_GetPlayTimeString(buffer, task->data[TD_SHOWING_LINK_CARD]);
|
|
Menu_PrintText(buffer, 10, 12);
|
|
}
|
|
|
|
static void TrainerCard_CreateFlipAnimationTask(void)
|
|
{
|
|
u8 taskId;
|
|
|
|
taskId = CreateTask(TrainerCard_RunFlipAnimationStateMachine, 0);
|
|
TrainerCard_RunFlipAnimationStateMachine(taskId);
|
|
}
|
|
|
|
static u8 TrainerCard_HasFlipAnimationFinished(void)
|
|
{
|
|
if (FindTaskIdByFunc(TrainerCard_RunFlipAnimationStateMachine) == 0xFF)
|
|
return TRUE;
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
static void TrainerCard_RunFlipAnimationStateMachine(u8 taskId)
|
|
{
|
|
while (TrainerCard_FlipAnimationStateMachine[gTasks[taskId].data[0]](&gTasks[taskId]) != 0)
|
|
;
|
|
}
|
|
|
|
bool8 TrainerCard_InitFlipAnimation(struct Task *task)
|
|
{
|
|
u32 i;
|
|
|
|
ewram0_2.var_4 = FALSE;
|
|
ScanlineEffect_Clear();
|
|
for (i = 0; i < 0xA0; i++)
|
|
gScanlineEffectRegBuffers[1][i] = -4;
|
|
SetHBlankCallback(TrainerCard_FlipAnimationHBlankCallback);
|
|
ewram0_2.var_4 = TRUE;
|
|
task->data[0]++;
|
|
return FALSE;
|
|
}
|
|
|
|
/*
|
|
bool8 TrainerCard_ScaleDownFlipAnimation(struct Task *task)
|
|
{
|
|
u32 r7;
|
|
u16 r9;
|
|
u32 r6;
|
|
u32 r5;
|
|
u32 r4;
|
|
u32 r10;
|
|
u32 sp0;
|
|
s16 i;
|
|
|
|
ewram0_2.var_4 = 0;
|
|
task->data[1] += 3;
|
|
if (task->data[1] > 79)
|
|
task->data[1] = 79;
|
|
|
|
r7 = task->data[1];
|
|
r9 = 160 - r7;
|
|
r4 = r9 - r7;
|
|
r6 = -r7 << 16;
|
|
r5 = (160 << 16) / r4;
|
|
r5 -= 1 << 16;
|
|
r10 = r5 * r4 + r6;
|
|
sp0 = r5 / r4;
|
|
r5 *= 2;
|
|
|
|
for (i = 0; i < r7; i++)
|
|
{
|
|
gScanlineEffectRegBuffers.filler0[i] = -4 - (u32)i;
|
|
}
|
|
//_08093B74
|
|
for (; i < r9; i++)
|
|
{
|
|
u16 var = r6 >> 16;
|
|
r6 += r5;
|
|
r5 -= sp0;
|
|
gScanlineEffectRegBuffers.filler0[i] = -4 + var;
|
|
}
|
|
for (; i < 160; i++)
|
|
gScanlineEffectRegBuffers.filler0[i] = -4 + (u16)(r10 >> 16);
|
|
ewram0_2.var_4 = 1;
|
|
if (task->data[1] > 0x4A)
|
|
task->data[0]++;
|
|
return FALSE;
|
|
}
|
|
*/
|
|
|
|
__attribute__((naked))
|
|
bool8 TrainerCard_ScaleDownFlipAnimation(struct Task *task)
|
|
{
|
|
asm(".syntax unified\n\
|
|
push {r4-r7,lr}\n\
|
|
mov r7, r10\n\
|
|
mov r6, r9\n\
|
|
mov r5, r8\n\
|
|
push {r5-r7}\n\
|
|
sub sp, 0x4\n\
|
|
mov r8, r0\n\
|
|
ldr r1, _08093BFC @ =gSharedMem\n\
|
|
movs r0, 0\n\
|
|
strb r0, [r1, 0x4]\n\
|
|
mov r2, r8\n\
|
|
ldrh r0, [r2, 0xA]\n\
|
|
adds r0, 0x3\n\
|
|
strh r0, [r2, 0xA]\n\
|
|
lsls r0, 16\n\
|
|
asrs r0, 16\n\
|
|
cmp r0, 0x4F\n\
|
|
ble _08093B18\n\
|
|
movs r0, 0x4F\n\
|
|
strh r0, [r2, 0xA]\n\
|
|
_08093B18:\n\
|
|
mov r4, r8\n\
|
|
movs r0, 0xA\n\
|
|
ldrsh r7, [r4, r0]\n\
|
|
movs r0, 0xA0\n\
|
|
subs r0, r7\n\
|
|
mov r9, r0\n\
|
|
subs r4, r0, r7\n\
|
|
negs r0, r7\n\
|
|
lsls r6, r0, 16\n\
|
|
movs r0, 0xA0\n\
|
|
lsls r0, 16\n\
|
|
adds r1, r4, 0\n\
|
|
bl __udivsi3\n\
|
|
adds r5, r0, 0\n\
|
|
ldr r1, _08093C00 @ =0xffff0000\n\
|
|
adds r5, r1\n\
|
|
adds r0, r5, 0\n\
|
|
muls r0, r4\n\
|
|
adds r0, r6\n\
|
|
mov r10, r0\n\
|
|
adds r0, r5, 0\n\
|
|
adds r1, r4, 0\n\
|
|
bl __udivsi3\n\
|
|
str r0, [sp]\n\
|
|
lsls r5, 1\n\
|
|
movs r3, 0\n\
|
|
cmp r3, r7\n\
|
|
bcs _08093B74\n\
|
|
ldr r2, _08093C04 @ =gScanlineEffectRegBuffers\n\
|
|
mov r12, r2\n\
|
|
ldr r0, _08093C08 @ =0x0000fffc\n\
|
|
adds r4, r0, 0\n\
|
|
_08093B5C:\n\
|
|
lsls r0, r3, 16\n\
|
|
asrs r0, 16\n\
|
|
lsls r1, r0, 1\n\
|
|
add r1, r12\n\
|
|
subs r2, r4, r0\n\
|
|
strh r2, [r1]\n\
|
|
adds r0, 0x1\n\
|
|
lsls r0, 16\n\
|
|
lsrs r3, r0, 16\n\
|
|
asrs r0, 16\n\
|
|
cmp r0, r7\n\
|
|
bcc _08093B5C\n\
|
|
_08093B74:\n\
|
|
lsls r2, r3, 16\n\
|
|
mov r1, r9\n\
|
|
lsls r0, r1, 16\n\
|
|
asrs r1, r0, 16\n\
|
|
mov r4, r10\n\
|
|
lsrs r7, r4, 16\n\
|
|
cmp r2, r0\n\
|
|
bge _08093BAE\n\
|
|
ldr r0, _08093C04 @ =gScanlineEffectRegBuffers\n\
|
|
mov r9, r0\n\
|
|
ldr r4, _08093C08 @ =0x0000fffc\n\
|
|
mov r12, r4\n\
|
|
adds r4, r1, 0\n\
|
|
_08093B8E:\n\
|
|
lsrs r1, r6, 16\n\
|
|
adds r6, r5\n\
|
|
ldr r0, [sp]\n\
|
|
subs r5, r0\n\
|
|
asrs r2, 16\n\
|
|
lsls r0, r2, 1\n\
|
|
add r0, r9\n\
|
|
add r1, r12\n\
|
|
strh r1, [r0]\n\
|
|
adds r2, 0x1\n\
|
|
lsls r2, 16\n\
|
|
lsrs r3, r2, 16\n\
|
|
lsls r2, r3, 16\n\
|
|
asrs r0, r2, 16\n\
|
|
cmp r0, r4\n\
|
|
blt _08093B8E\n\
|
|
_08093BAE:\n\
|
|
adds r1, r7, 0\n\
|
|
lsls r0, r3, 16\n\
|
|
asrs r0, 16\n\
|
|
cmp r0, 0x9F\n\
|
|
bgt _08093BD4\n\
|
|
ldr r4, _08093C04 @ =gScanlineEffectRegBuffers\n\
|
|
ldr r0, _08093C08 @ =0x0000fffc\n\
|
|
adds r2, r1, r0\n\
|
|
_08093BBE:\n\
|
|
lsls r1, r3, 16\n\
|
|
asrs r1, 16\n\
|
|
lsls r0, r1, 1\n\
|
|
adds r0, r4\n\
|
|
strh r2, [r0]\n\
|
|
adds r1, 0x1\n\
|
|
lsls r1, 16\n\
|
|
lsrs r3, r1, 16\n\
|
|
asrs r1, 16\n\
|
|
cmp r1, 0x9F\n\
|
|
ble _08093BBE\n\
|
|
_08093BD4:\n\
|
|
movs r0, 0x1\n\
|
|
ldr r1, _08093BFC @ =gSharedMem\n\
|
|
strb r0, [r1, 0x4]\n\
|
|
mov r2, r8\n\
|
|
movs r4, 0xA\n\
|
|
ldrsh r0, [r2, r4]\n\
|
|
cmp r0, 0x4A\n\
|
|
ble _08093BEA\n\
|
|
ldrh r0, [r2, 0x8]\n\
|
|
adds r0, 0x1\n\
|
|
strh r0, [r2, 0x8]\n\
|
|
_08093BEA:\n\
|
|
movs r0, 0\n\
|
|
add sp, 0x4\n\
|
|
pop {r3-r5}\n\
|
|
mov r8, r3\n\
|
|
mov r9, r4\n\
|
|
mov r10, r5\n\
|
|
pop {r4-r7}\n\
|
|
pop {r1}\n\
|
|
bx r1\n\
|
|
.align 2, 0\n\
|
|
_08093BFC: .4byte gSharedMem\n\
|
|
_08093C00: .4byte 0xffff0000\n\
|
|
_08093C04: .4byte gScanlineEffectRegBuffers\n\
|
|
_08093C08: .4byte 0x0000fffc\n\
|
|
.syntax divided\n");
|
|
}
|
|
|
|
bool8 TrainerCard_SwitchToNewSide(struct Task *task)
|
|
{
|
|
TrainerCard_DestoryPlayTimeTask();
|
|
TrainerCard_DrawCard();
|
|
if (!ewram0_2.backSideShown) {
|
|
/* This code never runs because it is impossible to flip the back side back to the front side */
|
|
TrainerCard_CreatePrintPlayTimeTask();
|
|
}
|
|
task->data[0]++;
|
|
return TRUE;
|
|
}
|
|
|
|
__attribute__((naked))
|
|
bool8 TrainerCard_ScaleUpFlipAnimation(struct Task *task)
|
|
{
|
|
asm(".syntax unified\n\
|
|
push {r4-r7,lr}\n\
|
|
mov r7, r10\n\
|
|
mov r6, r9\n\
|
|
mov r5, r8\n\
|
|
push {r5-r7}\n\
|
|
sub sp, 0x4\n\
|
|
mov r8, r0\n\
|
|
ldr r1, _08093D40 @ =gSharedMem\n\
|
|
movs r2, 0\n\
|
|
strb r2, [r1, 0x4]\n\
|
|
ldrh r0, [r0, 0xA]\n\
|
|
subs r0, 0x3\n\
|
|
mov r3, r8\n\
|
|
strh r0, [r3, 0xA]\n\
|
|
lsls r0, 16\n\
|
|
cmp r0, 0\n\
|
|
bgt _08093C5C\n\
|
|
strh r2, [r3, 0xA]\n\
|
|
_08093C5C:\n\
|
|
mov r4, r8\n\
|
|
movs r0, 0xA\n\
|
|
ldrsh r7, [r4, r0]\n\
|
|
movs r0, 0xA0\n\
|
|
subs r0, r7\n\
|
|
mov r9, r0\n\
|
|
subs r4, r0, r7\n\
|
|
negs r0, r7\n\
|
|
lsls r6, r0, 16\n\
|
|
movs r0, 0xA0\n\
|
|
lsls r0, 16\n\
|
|
adds r1, r4, 0\n\
|
|
bl __udivsi3\n\
|
|
adds r5, r0, 0\n\
|
|
ldr r1, _08093D44 @ =0xffff0000\n\
|
|
adds r5, r1\n\
|
|
adds r0, r5, 0\n\
|
|
muls r0, r4\n\
|
|
adds r0, r6\n\
|
|
mov r10, r0\n\
|
|
adds r0, r5, 0\n\
|
|
adds r1, r4, 0\n\
|
|
bl __udivsi3\n\
|
|
str r0, [sp]\n\
|
|
lsrs r5, 1\n\
|
|
movs r3, 0\n\
|
|
cmp r3, r7\n\
|
|
bcs _08093CB8\n\
|
|
ldr r2, _08093D48 @ =gScanlineEffectRegBuffers\n\
|
|
mov r12, r2\n\
|
|
ldr r0, _08093D4C @ =0x0000fffc\n\
|
|
adds r4, r0, 0\n\
|
|
_08093CA0:\n\
|
|
lsls r0, r3, 16\n\
|
|
asrs r0, 16\n\
|
|
lsls r1, r0, 1\n\
|
|
add r1, r12\n\
|
|
subs r2, r4, r0\n\
|
|
strh r2, [r1]\n\
|
|
adds r0, 0x1\n\
|
|
lsls r0, 16\n\
|
|
lsrs r3, r0, 16\n\
|
|
asrs r0, 16\n\
|
|
cmp r0, r7\n\
|
|
bcc _08093CA0\n\
|
|
_08093CB8:\n\
|
|
lsls r2, r3, 16\n\
|
|
mov r1, r9\n\
|
|
lsls r0, r1, 16\n\
|
|
asrs r1, r0, 16\n\
|
|
mov r4, r10\n\
|
|
lsrs r7, r4, 16\n\
|
|
cmp r2, r0\n\
|
|
bge _08093CF2\n\
|
|
ldr r0, _08093D48 @ =gScanlineEffectRegBuffers\n\
|
|
mov r9, r0\n\
|
|
ldr r3, _08093D4C @ =0x0000fffc\n\
|
|
mov r12, r3\n\
|
|
adds r4, r1, 0\n\
|
|
_08093CD2:\n\
|
|
lsrs r1, r6, 16\n\
|
|
adds r6, r5\n\
|
|
ldr r0, [sp]\n\
|
|
adds r5, r0\n\
|
|
asrs r2, 16\n\
|
|
lsls r0, r2, 1\n\
|
|
add r0, r9\n\
|
|
add r1, r12\n\
|
|
strh r1, [r0]\n\
|
|
adds r2, 0x1\n\
|
|
lsls r2, 16\n\
|
|
lsrs r3, r2, 16\n\
|
|
lsls r2, r3, 16\n\
|
|
asrs r0, r2, 16\n\
|
|
cmp r0, r4\n\
|
|
blt _08093CD2\n\
|
|
_08093CF2:\n\
|
|
adds r1, r7, 0\n\
|
|
lsls r0, r3, 16\n\
|
|
asrs r0, 16\n\
|
|
cmp r0, 0x9F\n\
|
|
bgt _08093D18\n\
|
|
ldr r4, _08093D48 @ =gScanlineEffectRegBuffers\n\
|
|
ldr r0, _08093D4C @ =0x0000fffc\n\
|
|
adds r2, r1, r0\n\
|
|
_08093D02:\n\
|
|
lsls r1, r3, 16\n\
|
|
asrs r1, 16\n\
|
|
lsls r0, r1, 1\n\
|
|
adds r0, r4\n\
|
|
strh r2, [r0]\n\
|
|
adds r1, 0x1\n\
|
|
lsls r1, 16\n\
|
|
lsrs r3, r1, 16\n\
|
|
asrs r1, 16\n\
|
|
cmp r1, 0x9F\n\
|
|
ble _08093D02\n\
|
|
_08093D18:\n\
|
|
movs r0, 0x1\n\
|
|
ldr r1, _08093D40 @ =gSharedMem\n\
|
|
strb r0, [r1, 0x4]\n\
|
|
mov r2, r8\n\
|
|
movs r3, 0xA\n\
|
|
ldrsh r0, [r2, r3]\n\
|
|
cmp r0, 0\n\
|
|
bgt _08093D2E\n\
|
|
ldrh r0, [r2, 0x8]\n\
|
|
adds r0, 0x1\n\
|
|
strh r0, [r2, 0x8]\n\
|
|
_08093D2E:\n\
|
|
movs r0, 0\n\
|
|
add sp, 0x4\n\
|
|
pop {r3-r5}\n\
|
|
mov r8, r3\n\
|
|
mov r9, r4\n\
|
|
mov r10, r5\n\
|
|
pop {r4-r7}\n\
|
|
pop {r1}\n\
|
|
bx r1\n\
|
|
.align 2, 0\n\
|
|
_08093D40: .4byte gSharedMem\n\
|
|
_08093D44: .4byte 0xffff0000\n\
|
|
_08093D48: .4byte gScanlineEffectRegBuffers\n\
|
|
_08093D4C: .4byte 0x0000fffc\n\
|
|
.syntax divided\n");
|
|
}
|
|
|
|
bool8 TrainerCard_FinishFlipAnimation(struct Task *task)
|
|
{
|
|
u8 taskId;
|
|
|
|
ewram0_2.var_4 = FALSE;
|
|
SetHBlankCallback(NULL);
|
|
TrainerCard_ResetOffsetRegisters();
|
|
taskId = FindTaskIdByFunc(TrainerCard_RunFlipAnimationStateMachine);
|
|
DestroyTask(taskId);
|
|
return FALSE;
|
|
}
|
|
|
|
static void TrainerCard_FlipAnimationHBlankCallback(void)
|
|
{
|
|
u16 bgVOffset = gScanlineEffectRegBuffers[1][REG_VCOUNT & 0xFF];
|
|
|
|
REG_BG0VOFS = bgVOffset;
|
|
REG_BG1VOFS = bgVOffset;
|
|
REG_BG2VOFS = bgVOffset;
|
|
}
|
|
|
|
static void TrainerCard_DrawCard(void)
|
|
{
|
|
if (ewram0_2.backSideShown)
|
|
TrainerCard_DrawCardBack();
|
|
else
|
|
TrainerCard_DrawCardFront();
|
|
}
|
|
|
|
static void TrainerCard_DrawCardFront(void)
|
|
{
|
|
Menu_EraseScreen();
|
|
TrainerCard_ClearTrainerGraphics();
|
|
sub_8093F14();
|
|
TrainerCard_LoadTrainerTilemap();
|
|
TrainerCard_DrawStars();
|
|
TrainerCard_DisplayBadges();
|
|
TrainerCard_Front_PrintTexts();
|
|
}
|
|
|
|
static void TrainerCard_DrawCardBack(void)
|
|
{
|
|
Menu_EraseScreen();
|
|
TrainerCard_ClearTrainerGraphics();
|
|
sub_8093F48();
|
|
TrainerCard_Back_PrintTexts();
|
|
}
|
|
|
|
static void TrainerCard_ResetOffsetRegisters(void)
|
|
{
|
|
REG_BG0VOFS = -4;
|
|
REG_BG1HOFS = 0;
|
|
REG_BG1VOFS = -4;
|
|
REG_BG2HOFS = 0;
|
|
REG_BG2VOFS = -4;
|
|
}
|
|
|
|
static void TrainerCard_CopyGraphics(void)
|
|
{
|
|
TrainerCard_LoadPalettes();
|
|
LoadPalette(gUnknown_083B5F6C, 0xE0, 32);
|
|
DmaCopyLarge16(3, gMenuTrainerCard_Gfx, (void *)VRAM, 0x1480, 0x1000);
|
|
DmaCopy16Defvars(3, gBadgesTiles, (void *)(VRAM + 0x1480), 0x400);
|
|
}
|
|
|
|
extern const u16 *const gTrainerCardPalettes[];
|
|
|
|
static void TrainerCard_LoadPalettes(void)
|
|
{
|
|
LoadPalette(gTrainerCardPalettes[ewram0_2.starCount], 0, 48 * 2);
|
|
LoadPalette(gBadgesPalette, 48, 16 * 2);
|
|
LoadPalette(gUnknown_083B5F4C, 64, 16 * 2);
|
|
if (ewram0_2.displayedCard.gender != MALE)
|
|
LoadPalette(gUnknown_083B5F0C, 16, 16 * 2);
|
|
}
|
|
|
|
static void TrainerCard_LoadTrainerGraphics(void)
|
|
{
|
|
LoadTrainerGfx_TrainerCard(ewram0_2.displayedCard.gender, 80, (void *)(VRAM + 0x1880));
|
|
}
|
|
|
|
static void sub_8093F14(void)
|
|
{
|
|
const void *arr[] = {gUnknown_08E8CAC0, gUnknown_08E8D4C0};
|
|
|
|
CpuFastSet(arr[ewram0_2.isShowingLinkCard], (void *)(VRAM + 0x4800), 0x140);
|
|
}
|
|
|
|
// I don't really know where to put the data. It's in such a weird order.
|
|
|
|
const u8 gUnknown_083B5EF4[] = _(" : ");
|
|
|
|
const u16 *const gTrainerCardPalettes[] =
|
|
{
|
|
gMenuTrainerCard0Star_Pal,
|
|
gMenuTrainerCard1Star_Pal,
|
|
gMenuTrainerCard2Star_Pal,
|
|
gMenuTrainerCard3Star_Pal,
|
|
gMenuTrainerCard4Star_Pal,
|
|
};
|
|
|
|
const u16 gUnknown_083B5F0C[] = INCBIN_U16("graphics/trainer_card/83B5F0C.gbapal");
|
|
const u16 gBadgesPalette[] = INCBIN_U16("graphics/trainer_card/badges.gbapal");
|
|
const u16 gUnknown_083B5F4C[] = INCBIN_U16("graphics/trainer_card/83B5F4C.gbapal");
|
|
const u16 gUnknown_083B5F6C[] = INCBIN_U16("graphics/trainer_card/83B5F6C.gbapal");
|
|
const u16 gTrainerCardBadgesMap[][4] = INCBIN_U16("graphics/trainer_card/83B5F8C_map.bin");
|
|
|
|
static void sub_8093F48(void)
|
|
{
|
|
CpuFastSet(gUnknown_08E8CFC0, (void *)(VRAM + 0x4800), 320);
|
|
}
|
|
|
|
static void sub_8093F64(void)
|
|
{
|
|
CpuFastSet(gUnknown_08E8D9C0, (void *)(VRAM + 0x5000), 320);
|
|
}
|
|
|
|
static void TrainerCard_LoadTrainerTilemap(void)
|
|
{
|
|
u16 r5 = 0xC4;
|
|
u16 *ptr = (u16 *)(VRAM + 0x4000);
|
|
s16 i;
|
|
s16 j;
|
|
|
|
for (i = 5; i < 13; i++)
|
|
{
|
|
for (j = 19; j < 27; j++, r5++)
|
|
ptr[i * 32 + j] = r5 | 0x5000;
|
|
}
|
|
}
|
|
|
|
static void TrainerCard_DrawStars(void)
|
|
{
|
|
u16 *ptr = (u16 *)(VRAM + 0x4000);
|
|
s16 i = 15;
|
|
s16 var = 15 + ewram0_2.starCount;
|
|
|
|
while (i < var)
|
|
{
|
|
ptr[6 * 32 + i] = 0x408F;
|
|
i++;
|
|
}
|
|
while (i < 0x13)
|
|
{
|
|
ptr[6 * 32 + i] = 0;
|
|
i++;
|
|
}
|
|
}
|
|
|
|
static void TrainerCard_DisplayBadges(void)
|
|
{
|
|
if (!ewram0_2.isShowingLinkCard)
|
|
{
|
|
u16 *ptr = (u16 *)(VRAM + 0x4000);
|
|
s16 i;
|
|
s16 r2;
|
|
|
|
for (i = 0, r2 = 4; i < 8; i++, r2 += 3)
|
|
{
|
|
if (ewram0_2.ownedBadges[i] != 0)
|
|
{
|
|
ptr[15 * 32 + r2 + 0] = gTrainerCardBadgesMap[i][0] | 0x3000;
|
|
ptr[15 * 32 + r2 + 1] = gTrainerCardBadgesMap[i][1] | 0x3000;
|
|
ptr[16 * 32 + r2 + 0] = gTrainerCardBadgesMap[i][2] | 0x3000;
|
|
ptr[16 * 32 + r2 + 1] = gTrainerCardBadgesMap[i][3] | 0x3000;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void TrainerCard_ClearTrainerGraphics(void)
|
|
{
|
|
s16 i;
|
|
u16 *ptr;
|
|
|
|
for (i = 0, ptr = (u16 *)(VRAM + 0x4000); i < 0x400; i++, ptr++)
|
|
*ptr = 0;
|
|
}
|
|
|
|
static void TrainerCard_ClearPokedexLabel(void)
|
|
{
|
|
u16 *ptr = (u16 *)(VRAM + 0x4800);
|
|
u16 i;
|
|
|
|
for (i = 3; i < 17; i++)
|
|
{
|
|
ptr[10 * 32 + i] = 1;
|
|
ptr[11 * 32 + i] = 1;
|
|
}
|
|
}
|
|
|
|
static void TrainerCard_Front_PrintTexts(void)
|
|
{
|
|
u8 *buffer;
|
|
|
|
BasicInitMenuWindow(&gWindowTemplate_TrainerCard_Back_Values);
|
|
|
|
buffer = gStringVar1;
|
|
StringCopy(buffer, ewram0_2.displayedCard.playerName);
|
|
ConvertInternationalString(buffer, ewram0_2.language);
|
|
Menu_PrintText(buffer, 7, 5);
|
|
|
|
TrainerCard_Front_PrintTrainerID();
|
|
TrainerCard_Front_PrintMoney();
|
|
TrainerCard_Front_PrintPokedexCount();
|
|
TrainerCard_PrintEasyChatPhrase();
|
|
}
|
|
|
|
static void TrainerCard_Back_PrintTexts(void)
|
|
{
|
|
BasicInitMenuWindow(&gWindowTemplate_TrainerCard_Back_Values);
|
|
TrainerCard_Back_PrintName();
|
|
TrainerCard_Back_PrintHallOfFameTime_Label();
|
|
TrainerCard_Back_PrintLinkBattlesLabel();
|
|
TrainerCard_Back_PrintBattleTower_Label();
|
|
TrainerCard_Back_PrintLinkContests_Label();
|
|
TrainerCard_Back_PrintLinkPokeblocks_Label();
|
|
TrainerCard_Back_PrintPokemonTrades_Label();
|
|
|
|
BasicInitMenuWindow(&gWindowTemplate_TrainerCard_Back_Labels);
|
|
TrainerCard_Back_PrintHallOfFameTime();
|
|
TrainerCard_Back_PrintLinkBattles();
|
|
TrainerCard_Back_PrintBattleTower();
|
|
TrainerCard_Back_PrintLinkContests();
|
|
TrainerCard_Back_PrintLinkPokeblocks();
|
|
TrainerCard_Back_PrintPokemonTrades();
|
|
}
|
|
|
|
static void TrainerCard_Front_PrintTrainerID(void)
|
|
{
|
|
u8 buffer[8];
|
|
|
|
ConvertIntToDecimalStringN(buffer, ewram0_2.displayedCard.trainerId, STR_CONV_MODE_LEADING_ZEROS, 5);
|
|
Menu_PrintText(buffer, 20, 2);
|
|
}
|
|
|
|
static void TrainerCard_Front_PrintMoney(void)
|
|
{
|
|
sub_80B7AEC(ewram0_2.displayedCard.money, 16, 8);
|
|
}
|
|
|
|
static void TrainerCard_Front_PrintPokedexCount(void)
|
|
{
|
|
u8 buffer[16];
|
|
|
|
if (
|
|
#if DEBUG
|
|
gDebug_03000748 == 0 &&
|
|
#endif
|
|
!ewram0_2.showPokedexCount)
|
|
{
|
|
TrainerCard_ClearPokedexLabel();
|
|
}
|
|
else
|
|
{
|
|
ConvertIntToDecimalStringN(buffer, ewram0_2.displayedCard.pokedexSeen, STR_CONV_MODE_LEFT_ALIGN, 3);
|
|
MenuPrint_RightAligned(buffer, 16, 10);
|
|
}
|
|
}
|
|
|
|
static void TrainerCard_Front_GetPlayTimeString(u8 *arg1, s16 colon)
|
|
{
|
|
u8 buffer[16];
|
|
u16 playTimeHours;
|
|
u16 playTimeMinutes;
|
|
|
|
playTimeHours = gSaveBlock2.playTimeHours;
|
|
playTimeMinutes = gSaveBlock2.playTimeMinutes;
|
|
if (ewram0_2.isShowingLinkCard != 0)
|
|
{
|
|
playTimeHours = ewram0_2.displayedCard.playTimeHours;
|
|
playTimeMinutes = ewram0_2.displayedCard.playTimeMinutes;
|
|
}
|
|
FormatPlayTime(buffer, playTimeHours, playTimeMinutes, colon);
|
|
sub_8072C74(arg1, buffer, 48, 1);
|
|
}
|
|
|
|
static void TrainerCard_PrintEasyChatPhrase(void)
|
|
{
|
|
u8 *str;
|
|
|
|
if (ewram0_2.isShowingLinkCard != 0)
|
|
{
|
|
str = gStringVar1;
|
|
str = StringCopy(str, ewram0_2.easyChatPhrase[0]);
|
|
str[0] = 00;
|
|
str++;
|
|
str = StringCopy(str, ewram0_2.easyChatPhrase[1]);
|
|
Menu_PrintText(gStringVar1, 2, 14);
|
|
|
|
str = gStringVar1;
|
|
str = StringCopy(str, ewram0_2.easyChatPhrase[2]);
|
|
str[0] = 00;
|
|
str++;
|
|
str = StringCopy(str, ewram0_2.easyChatPhrase[3]);
|
|
Menu_PrintText(gStringVar1, 2, 16);
|
|
}
|
|
}
|
|
|
|
static void TrainerCard_Back_PrintName(void)
|
|
{
|
|
u8 *str;
|
|
|
|
str = gStringVar1;
|
|
StringCopy(str, ewram0_2.displayedCard.playerName);
|
|
ConvertInternationalString(str, ewram0_2.language);
|
|
|
|
#if ENGLISH
|
|
StringAppend(str, gOtherText_TrainersTrainerCard);
|
|
#elif GERMAN
|
|
de_sub_8073174(str, gOtherText_TrainersTrainerCard);
|
|
#endif
|
|
|
|
MenuPrint_RightAligned(gStringVar1, 28, 2);
|
|
}
|
|
|
|
static void TrainerCard_Back_PrintHallOfFameTime_Label(void)
|
|
{
|
|
if (ewram0_2.showHallOfFame != 0)
|
|
Menu_PrintText(gOtherText_FirstHOF, 3, 5);
|
|
}
|
|
|
|
static void TrainerCard_Back_PrintHallOfFameTime(void)
|
|
{
|
|
u8 *str;
|
|
|
|
if (ewram0_2.showHallOfFame != 0)
|
|
{
|
|
str = gStringVar1;
|
|
str = ConvertIntToDecimalStringN(str, ewram0_2.displayedCard.firstHallOfFameA, STR_CONV_MODE_RIGHT_ALIGN, 3);
|
|
str = StringCopy(str, gUnknown_083B5EF4);
|
|
str = ConvertIntToDecimalStringN(str, ewram0_2.displayedCard.firstHallOfFameB, STR_CONV_MODE_LEADING_ZEROS, 2);
|
|
str = StringCopy(str, gUnknown_083B5EF4);
|
|
str = ConvertIntToDecimalStringN(str, ewram0_2.displayedCard.firstHallOfFameC, STR_CONV_MODE_LEADING_ZEROS, 2);
|
|
MenuPrint_RightAligned(gStringVar1, 28, 5);
|
|
}
|
|
}
|
|
|
|
static void TrainerCard_Back_PrintLinkBattlesLabel(void)
|
|
{
|
|
if (ewram0_2.showLinkBattleStatus != 0)
|
|
Menu_PrintText(gOtherText_LinkCableBattles, 3, 7);
|
|
}
|
|
|
|
static void TrainerCard_Back_PrintLinkBattles(void)
|
|
{
|
|
u8 buffer[16];
|
|
|
|
if (ewram0_2.showLinkBattleStatus != 0)
|
|
{
|
|
ConvertIntToDecimalString(buffer, ewram0_2.displayedCard.linkBattleWins);
|
|
MenuPrint_RightAligned(buffer, 22, 7);
|
|
|
|
ConvertIntToDecimalString(buffer, ewram0_2.displayedCard.linkBattleLosses);
|
|
MenuPrint_RightAligned(buffer, 28, 7);
|
|
}
|
|
}
|
|
|
|
static void TrainerCard_Back_PrintBattleTower_Label(void)
|
|
{
|
|
if (ewram0_2.showBattleTowerStatus != 0)
|
|
Menu_PrintText(gOtherText_BattleTowerWinRecord, 3, 15);
|
|
}
|
|
|
|
static void TrainerCard_Back_PrintBattleTower(void)
|
|
{
|
|
u8 buffer[16];
|
|
|
|
if (ewram0_2.showBattleTowerStatus != 0)
|
|
{
|
|
sub_8072C44(buffer, ewram0_2.displayedCard.battleTowerWins, 24, 1);
|
|
Menu_PrintTextPixelCoords(buffer, 112, 120, 0);
|
|
|
|
sub_8072C44(buffer, ewram0_2.displayedCard.battleTowerLosses, 24, 1);
|
|
Menu_PrintTextPixelCoords(buffer, 149, 120, 0);
|
|
}
|
|
}
|
|
|
|
static void TrainerCard_Back_PrintLinkContests_Label(void)
|
|
{
|
|
if (ewram0_2.showContestRecord != 0)
|
|
Menu_PrintText(gOtherText_ContestRecord, 3, 13);
|
|
}
|
|
|
|
static void TrainerCard_Back_PrintLinkContests(void)
|
|
{
|
|
u8 buffer[8];
|
|
|
|
if (ewram0_2.showContestRecord != 0)
|
|
{
|
|
ConvertIntToDecimalStringN(buffer, ewram0_2.displayedCard.contestsWithFriends, STR_CONV_MODE_RIGHT_ALIGN, 3);
|
|
MenuPrint_RightAligned(buffer, 28, 13);
|
|
}
|
|
}
|
|
|
|
static void TrainerCard_Back_PrintLinkPokeblocks_Label(void)
|
|
{
|
|
if (ewram0_2.showMixingRecord != 0)
|
|
Menu_PrintText(gOtherText_MixingRecord, 3, 11);
|
|
}
|
|
|
|
static void TrainerCard_Back_PrintLinkPokeblocks(void)
|
|
{
|
|
u8 buffer[8];
|
|
|
|
if (ewram0_2.showMixingRecord != 0)
|
|
{
|
|
ConvertIntToDecimalStringN(buffer, ewram0_2.displayedCard.pokeblocksWithFriends, STR_CONV_MODE_RIGHT_ALIGN, 5);
|
|
MenuPrint_RightAligned(buffer, 28, 11);
|
|
}
|
|
}
|
|
|
|
static void TrainerCard_Back_PrintPokemonTrades_Label(void)
|
|
{
|
|
if (ewram0_2.showTradingRecord != 0)
|
|
Menu_PrintText(gOtherText_TradeRecord, 3, 9);
|
|
}
|
|
|
|
static void TrainerCard_Back_PrintPokemonTrades(void)
|
|
{
|
|
u8 buffer[8];
|
|
|
|
if (ewram0_2.showTradingRecord != 0)
|
|
{
|
|
ConvertIntToDecimalStringN(buffer, ewram0_2.displayedCard.pokemonTrades, STR_CONV_MODE_RIGHT_ALIGN, 5);
|
|
MenuPrint_RightAligned(buffer, 28, 9);
|
|
}
|
|
}
|
|
|
|
void unref_sub_8094588(u16 left, u16 top)
|
|
{
|
|
const u8 *text = gOtherText_Boy;
|
|
|
|
if (gSaveBlock2.playerGender == FEMALE)
|
|
text = gOtherText_Girl;
|
|
Menu_PrintText(text, left, top);
|
|
}
|