diff options
author | ProjectRevoTPP <projectrevotpp@hotmail.com> | 2017-08-20 19:57:48 -0400 |
---|---|---|
committer | ProjectRevoTPP <projectrevotpp@hotmail.com> | 2017-08-20 19:57:48 -0400 |
commit | 613fd1aa059d6894662566049840f3e1fd8cb02e (patch) | |
tree | 894aec0c8284b6a0391838ab4f7e409d24a9586c /src | |
parent | b9e96a1ffa69f8dc1ae74374954318b60a1aae48 (diff) | |
parent | e81986cd20dbe0d8a98da646d964310a066f1af5 (diff) |
merge
Diffstat (limited to 'src')
-rw-r--r-- | src/battle/battle_4.c | 9 | ||||
-rw-r--r-- | src/battle/battle_message.c | 974 | ||||
-rw-r--r-- | src/field/choose_party.c | 96 | ||||
-rw-r--r-- | src/scene/egg_hatch.c | 814 | ||||
-rw-r--r-- | src/scene/hall_of_fame.c | 1413 |
5 files changed, 3207 insertions, 99 deletions
diff --git a/src/battle/battle_4.c b/src/battle/battle_4.c index 31d6c76dc..6dd5d7df6 100644 --- a/src/battle/battle_4.c +++ b/src/battle/battle_4.c @@ -246,15 +246,6 @@ extern u8 gUnknown_081D95DB[]; //bs payday money give #define CMP_COMMON_BITS 0x4 #define CMP_NO_COMMON_BITS 0x5 -#define BATTLE_WON 0x1 -#define BATTLE_LOST 0x2 -#define BATTLE_DREW 0x3 -#define BATTLE_RAN 0x4 -#define BATTLE_PLAYER_TELEPORTED 0x5 -#define BATTLE_POKE_FLED 0x6 -#define BATTLE_CAUGHT 0x7 -#define BATTLE_OPPONENT_TELEPORTED 0xA - #define uBYTE0_16(value)(( (u8) (((u16)(value) & (0x000000FF)) >> 0x00))) #define uBYTE1_16(value)(( (u8) (((u16)(value) & (0x0000FF00)) >> 0x08))) diff --git a/src/battle/battle_message.c b/src/battle/battle_message.c new file mode 100644 index 000000000..37ec14459 --- /dev/null +++ b/src/battle/battle_message.c @@ -0,0 +1,974 @@ +#include "global.h" +#include "battle_message.h" +#include "battle.h" +#include "item.h" +#include "items.h" +#include "pokemon.h" +#include "data2.h" +#include "text.h" +#include "string_util.h" +#include "link.h" +#include "battle_setup.h" +#include "battle_tower.h" +#include "flags.h" + +#define BATTLESTRING_TO_SUB 12 +#define BATTLESTRINGS_NO 351 +#define BATTLESTRINGS_MAX BATTLESTRINGS_NO + BATTLESTRING_TO_SUB + +extern const u8* const gBattleStringsTable[BATTLESTRINGS_NO]; + +extern u16 gLastUsedItem; +extern u8 gLastUsedAbility; +extern u8 gActiveBank; +extern u8 gBankAttacker; +extern u8 gBankTarget; +extern u8 gStringBank; +extern u8 gEffectBank; +extern u8 gAbilitiesPerBank[4]; +extern u8 gBattleTextBuff1[]; +extern u8 gBattleTextBuff2[]; +extern u8 gBattleTextBuff3[]; +extern u8 gStringVar1[]; +extern u8 gStringVar2[]; +extern u8 gStringVar3[]; +extern u16 gBattleTypeFlags; +extern u16 gTrainerBattleOpponent; +extern u8 gDisplayedStringBattle[]; +extern u8 gStringVar1[]; +extern u8 gStringVar2[]; +extern u8 gStringVar3[]; +extern u16 gBattlePartyID[4]; +extern struct BattleEnigmaBerry gEnigmaBerries[4]; +extern u8 gBattleBufferA[4][0x200]; + +extern const u8 gUnknown_084005DB[]; +extern const u8 gUnknown_084005C7[]; +extern const u8 gUnknown_084005AA[]; +extern const u8 gUnknown_08400568[]; +extern const u8 gUnknown_08400590[]; +extern const u8 gUnknown_0840057B[]; +extern const u8 gUnknown_08400555[]; +extern const u8 gUnknown_084006F1[]; +extern const u8 gUnknown_084006A4[]; +extern const u8 gUnknown_0840069C[]; +extern const u8 gUnknown_0840065C[]; +extern const u8 gUnknown_08400645[]; +extern const u8 gUnknown_08400608[]; +extern const u8 gUnknown_08400635[]; +extern const u8 gUnknown_084005F5[]; +extern const u8 gUnknown_08400709[]; +extern const u8 gUnknown_08400727[]; +extern const u8 gUnknown_08400736[]; +extern const u8 gUnknown_08400749[]; +extern const u8 gUnknown_08400781[]; +extern const u8 gUnknown_08400771[]; +extern const u8 gUnknown_0840075E[]; +extern const u8 gUnknown_084006B3[]; +extern const u8 gUnknown_084006BB[]; +extern const u8 gUnknown_084006C6[]; +extern const u8 gUnknown_084006D5[]; +extern const u8 gUnknown_0840068C[]; +extern const u8 gUnknown_0840067C[]; +extern const u8 gUnknown_08400622[]; +extern const u8 gUnknown_084007BD[]; +extern const u8 gUnknown_083FFEFC[]; +extern const u8 gUnknown_083FFFF7[]; +extern const u8 gUnknown_083FFFEA[]; +extern const u8 gUnknown_083FFF6A[]; +extern const u8 gUnknown_083FFF99[]; +extern const u8 gUnknown_083FFFCB[]; +extern const u8 gUnknown_083FFF56[]; +extern const u8 gUnknown_083FFF81[]; +extern const u8 gUnknown_083FFFB3[]; +extern const u8 gUnknown_08400A78[]; +extern const u8 gUnknown_08400A85[]; +extern const u8 gUnknown_08400797[]; +extern const u8 gUnknown_08400791[]; +extern const u8 gUnknown_084007B7[]; +extern const u8 gUnknown_084007B2[]; +extern const u8 gUnknown_0840079C[]; +extern const u8 gUnknown_084007A1[]; +extern const u8 gUnknown_084007A7[]; +extern const u8 gUnknown_084007AC[]; +extern const u8 gUnknown_084009ED[]; +extern const u8 gUnknown_084009F7[]; +extern const u8 gUnknown_084007C8[]; +extern const u8 gUnknown_084007CA[]; +extern const u8 gUnknown_084007CC[]; +extern const u8 gUnknown_084007CE[]; +extern const u8 gUnknown_084007D0[]; +extern const u8 gUnknown_08400E5E[]; +extern const u8 gUnknown_08400E62[]; + +extern const u16 gUnknown_084016BC[]; // a table of moves + +extern const u8* const gUnknown_08401674[]; // table of pointers to 'a -TYPE' strings +extern const u8* const gUnknown_08400F58[]; // table of pointers to stat strings +extern const u8* const gUnknown_08400F78[]; // table of pointers to flavour strings + +struct StatusFlagString +{ + u8* flag; + u8* ptr; +}; + +extern const struct StatusFlagString gUnknown_081FA6D4[7]; // status flag/text +extern const u8 gUnknown_084017A8[8]; // empty flags + +struct StringInfo +{ + u16 currentMove; + u16 lastMove; + u16 lastItem; + u8 lastAbility; + u8 scrActive; + u8 unk1605E; + u8 hpScale; + u8 StringBank; + u8 moveType; + u8 abilities[4]; + u8 textBuffs[3][0x10]; +}; + +extern struct StringInfo* gSelectedOrderFromParty; +#define gStringInfo gSelectedOrderFromParty + +void sub_8121D1C(u8* textBuff); +void sub_8121D74(u8* textBuff); +void StrCpyDecodeBattleTextBuff(u8* src, u8* dst); + +u8 GetBankSide(u8 bank); +s32 sub_803FC34(u16); +void get_trainer_name(u8* dst); +u8 get_trainer_class_name_index(void); +u8 sub_8135FD8(void); +u8 GetMultiplayerId(void); +u8 GetBankByPlayerAI(u8 ID); +u8 GetBankSide(u8 bank); +u8 GetBankIdentity(u8 bank); +#ifdef GERMAN +extern u8 *de_sub_804110C(); +#endif + +void BufferStringBattle(u16 stringID) +{ + int i; + const u8* stringPtr = NULL; + + gStringInfo = (struct StringInfo*)(&gBattleBufferA[gActiveBank][4]); + gLastUsedItem = gStringInfo->lastItem; + gLastUsedAbility = gStringInfo->lastAbility; + BATTLE_STRUCT->scriptingActive = gStringInfo->scrActive; + BATTLE_STRUCT->unk1605E = gStringInfo->unk1605E; + BATTLE_STRUCT->hpScale = gStringInfo->hpScale; + gStringBank = gStringInfo->StringBank; + BATTLE_STRUCT->stringMoveType = gStringInfo->moveType; + for (i = 0; i < 4; i++) + { + gAbilitiesPerBank[i] = gStringInfo->abilities[i]; + } + for (i = 0; i < 0x10; i++) + { + gBattleTextBuff1[i] = gStringInfo->textBuffs[0][i]; + gBattleTextBuff2[i] = gStringInfo->textBuffs[1][i]; + gBattleTextBuff3[i] = gStringInfo->textBuffs[2][i]; + } + switch (stringID) + { + case 0: // first battle msg + if (gBattleTypeFlags & BATTLE_TYPE_TRAINER) + { + if (gBattleTypeFlags & BATTLE_TYPE_LINK) + { + if (gBattleTypeFlags & BATTLE_TYPE_MULTI) + stringPtr = gUnknown_084005DB; + else + stringPtr = gUnknown_084005C7; + } + else + { + stringPtr = gUnknown_084005AA; +#ifdef GERMAN + stringPtr = de_sub_804110C(0xFFFF, stringPtr); +#endif + } + } + else + { + if (gBattleTypeFlags & BATTLE_TYPE_LEGENDARY) + stringPtr = gUnknown_08400568; + else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) // interesting, looks like they had something planned for wild double battles + stringPtr = gUnknown_08400590; + else if (gBattleTypeFlags & BATTLE_TYPE_WALLY_TUTORIAL) + stringPtr = gUnknown_0840057B; + else + stringPtr = gUnknown_08400555; + } + break; + case 1: // poke first send-out + if (GetBankSide(gActiveBank) == 0) + { + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + { + if (gBattleTypeFlags & BATTLE_TYPE_MULTI) + stringPtr = gUnknown_084006F1; + else + stringPtr = gUnknown_084006A4; + } + else + stringPtr = gUnknown_0840069C; + } + else + { + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + { + if (gBattleTypeFlags & BATTLE_TYPE_MULTI) + stringPtr = gUnknown_0840065C; + else if (gBattleTypeFlags & BATTLE_TYPE_LINK) + stringPtr = gUnknown_08400645; + else + { + stringPtr = gUnknown_08400608; +#ifdef GERMAN + stringPtr = de_sub_804110C(0xFFFF, stringPtr); +#endif + } + } + else if (gBattleTypeFlags & BATTLE_TYPE_LINK) + stringPtr = gUnknown_08400635; + else + { + stringPtr = gUnknown_084005F5; +#ifdef GERMAN + stringPtr = de_sub_804110C(0xFFFF, stringPtr); +#endif + } + } + break; + case 2: // sending poke to ball msg + if (GetBankSide(gActiveBank) == 0) + { + if (BATTLE_STRUCT->hpScale == 0) + stringPtr = gUnknown_08400709; + else if (BATTLE_STRUCT->hpScale == 1 || gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + stringPtr = gUnknown_08400727; + else if (BATTLE_STRUCT->hpScale == 2) + stringPtr = gUnknown_08400736; + else + stringPtr = gUnknown_08400749; + } + else + { + if (gTrainerBattleOpponent == 0x800) + { + if (gBattleTypeFlags & BATTLE_TYPE_MULTI) + stringPtr = gUnknown_08400781; + else + stringPtr = gUnknown_08400771; + } + else + { + stringPtr = gUnknown_0840075E; +#ifdef GERMAN + stringPtr = de_sub_804110C(0xFFFF, stringPtr); +#endif + } + } + break; + case 3: // switch-in msg + if (GetBankSide(BATTLE_STRUCT->scriptingActive) == 0) + { + if (BATTLE_STRUCT->hpScale == 0 || gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + stringPtr = gUnknown_084006B3; + else if (BATTLE_STRUCT->hpScale == 1) + stringPtr = gUnknown_084006BB; + else if (BATTLE_STRUCT->hpScale == 2) + stringPtr = gUnknown_084006C6; + else + stringPtr = gUnknown_084006D5; + } + else + { + if (gBattleTypeFlags & BATTLE_TYPE_LINK) + { + if (gBattleTypeFlags & BATTLE_TYPE_MULTI) + stringPtr = gUnknown_0840068C; + else + stringPtr = gUnknown_0840067C; + } + else + { + stringPtr = gUnknown_08400622; +#ifdef GERMAN + stringPtr = de_sub_804110C(0xFFFF, stringPtr); +#endif + } + } + break; + case 4: // pokemon used a move msg + sub_8121D1C(gBattleTextBuff1); + if (gStringInfo->currentMove > 0x162) + StringCopy(gBattleTextBuff2, gUnknown_08401674[BATTLE_STRUCT->stringMoveType]); + else + StringCopy(gBattleTextBuff2, gMoveNames[gStringInfo->currentMove]); + sub_8121D74(gBattleTextBuff2); + stringPtr = gUnknown_084007BD; + break; + case 5: // battle end + if (gBattleTextBuff1[0] & 0x80) + { + gBattleTextBuff1[0] &= ~(0x80); + if (GetBankSide(gActiveBank) == 1 && gBattleTextBuff1[0] != 3) + gBattleTextBuff1[0] ^= 3; + if (gBattleTextBuff1[0] == BATTLE_LOST || gBattleTextBuff1[0] == BATTLE_DREW) + stringPtr = gUnknown_083FFEFC; + else + { + if (gBattleTypeFlags & BATTLE_TYPE_MULTI) + stringPtr = gUnknown_083FFFF7; + else + stringPtr = gUnknown_083FFFEA; + } + } + else + { + if (GetBankSide(gActiveBank) == 1 && gBattleTextBuff1[0] != 3) + gBattleTextBuff1[0] ^= 3; + if (gBattleTypeFlags & BATTLE_TYPE_MULTI) + { + switch (gBattleTextBuff1[0]) + { + case BATTLE_WON: + stringPtr = gUnknown_083FFF6A; + break; + case BATTLE_LOST: + stringPtr = gUnknown_083FFF99; + break; + case BATTLE_DREW: + stringPtr = gUnknown_083FFFCB; + break; + } + } + else + { + switch (gBattleTextBuff1[0]) + { + case BATTLE_WON: + stringPtr = gUnknown_083FFF56; + break; + case BATTLE_LOST: + stringPtr = gUnknown_083FFF81; + break; + case BATTLE_DREW: + stringPtr = gUnknown_083FFFB3; + break; + } + } + } + break; + default: // load a string from the table + if (stringID >= BATTLESTRINGS_MAX) + { + gDisplayedStringBattle[0] = EOS; + return; + } + else + { + stringPtr = gBattleStringsTable[stringID - BATTLESTRING_TO_SUB]; +#ifdef GERMAN + stringPtr = de_sub_804110C(stringID, stringPtr); +#endif + } + break; + } + StrCpyDecodeToDisplayedStringBattle(stringPtr); +} + +u32 StrCpyDecodeToDisplayedStringBattle(const u8* src) +{ + StrCpyDecodeBattle(src, gDisplayedStringBattle); +} + +const u8* AppendStatusString(u8* src) +{ + u32 i; + u8 status[8]; + u32 flag1, flag2; + u8* statusPtr; + + memcpy(status, gUnknown_084017A8, 8); + + statusPtr = status; + for (i = 0; i < sizeof(struct StatusFlagString); i++) + { + if (*src == EOS) + break; + *statusPtr = *src; + src++; + statusPtr++; + } + flag1 = *(u32*)(&status[0]); + flag2 = *(u32*)(&status[4]); + for (i = 0; i < 7; i++) + { + if (flag1 == *(u32*)(&gUnknown_081FA6D4[i].flag[0]) && flag2 == *(u32*)(&gUnknown_081FA6D4[i].flag[4])) + return gUnknown_081FA6D4[i].ptr; + } + return NULL; +} + +#ifdef GERMAN +extern u8 *de_sub_8073174(u8 *, const u8 *); +extern u8 *de_sub_8041024(s32, u32); +#endif + +#ifdef ENGLISH +#define HANDLE_NICKNAME_STRING_CASE(bank, monIndex) \ + if (GetBankSide(bank) != 0) \ + { \ + if (gBattleTypeFlags & BATTLE_TYPE_TRAINER) \ + toCpy = gUnknown_08400797; \ + else \ + toCpy = gUnknown_08400791; \ + while (*toCpy != EOS) \ + { \ + dst[dstID] = *toCpy; \ + dstID++; \ + toCpy++; \ + } \ + GetMonData(&gEnemyParty[monIndex], MON_DATA_NICKNAME, text); \ + } \ + else \ + { \ + GetMonData(&gPlayerParty[monIndex], MON_DATA_NICKNAME, text); \ + } \ + StringGetEnd10(text); \ + toCpy = text; +#else +#define HANDLE_NICKNAME_STRING_CASE(bank, monIndex) \ + if (GetBankSide(bank) != 0) \ + { \ + GetMonData(&gEnemyParty[monIndex], MON_DATA_NICKNAME, text); \ + StringGetEnd10(text); \ + toCpy = text; \ + while (*toCpy != EOS) \ + { \ + dst[dstID] = *toCpy; \ + dstID++; \ + toCpy++; \ + } \ + if (gBattleTypeFlags & BATTLE_TYPE_TRAINER) \ + toCpy = gUnknown_08400797; \ + else \ + toCpy = gUnknown_08400791; \ + } \ + else \ + { \ + GetMonData(&gPlayerParty[monIndex], MON_DATA_NICKNAME, text); \ + StringGetEnd10(text); \ + toCpy = text; \ + } +#endif + +u32 StrCpyDecodeBattle(const u8* src, u8* dst) +{ + u32 dstID = 0; // if they used dstID, why not use srcID as well? + const u8* toCpy = NULL; + u8 text[12]; + u8 multiplayerID = GetMultiplayerId(); + + while (*src != EOS) + { + if (*src == 0xFD) + { + src++; + switch (*src) + { + case 0: + if (gBattleTextBuff1[0] == 0xFD) + { + StrCpyDecodeBattleTextBuff(gBattleTextBuff1, gStringVar1); + toCpy = gStringVar1; + } + else + { + toCpy = AppendStatusString(gBattleTextBuff1); + if (toCpy == 0) + toCpy = gBattleTextBuff1; + } + break; + case 1: + if (gBattleTextBuff2[0] == 0xFD) + { + StrCpyDecodeBattleTextBuff(gBattleTextBuff2, gStringVar2); + toCpy = gStringVar2; + } + else + toCpy = gBattleTextBuff2; + break; + case 42: + if (gBattleTextBuff3[0] == 0xFD) + { + StrCpyDecodeBattleTextBuff(gBattleTextBuff3, gStringVar3); + toCpy = gStringVar3; + } + else + toCpy = gBattleTextBuff3; + break; + case 2: // first player poke name + GetMonData(&gPlayerParty[gBattlePartyID[GetBankByPlayerAI(0)]], MON_DATA_NICKNAME, text); + StringGetEnd10(text); + toCpy = text; + break; + case 3: // first enemy poke name + GetMonData(&gEnemyParty[gBattlePartyID[GetBankByPlayerAI(1)]], MON_DATA_NICKNAME, text); + StringGetEnd10(text); + toCpy = text; + break; + case 4: // second player poke name + GetMonData(&gPlayerParty[gBattlePartyID[GetBankByPlayerAI(2)]], MON_DATA_NICKNAME, text); + StringGetEnd10(text); + toCpy = text; + break; + case 5: // second enemy poke name + GetMonData(&gEnemyParty[gBattlePartyID[GetBankByPlayerAI(3)]], MON_DATA_NICKNAME, text); + StringGetEnd10(text); + toCpy = text; + break; + case 6: // link first player poke name + GetMonData(&gPlayerParty[gBattlePartyID[gLinkPlayers[multiplayerID].lp_field_18]], MON_DATA_NICKNAME, text); + StringGetEnd10(text); + toCpy = text; + break; + case 7: // link first opponent poke name + GetMonData(&gEnemyParty[gBattlePartyID[gLinkPlayers[multiplayerID].lp_field_18 ^ 1]], MON_DATA_NICKNAME, text); + StringGetEnd10(text); + toCpy = text; + break; + case 8: // link second player poke name + GetMonData(&gPlayerParty[gBattlePartyID[gLinkPlayers[multiplayerID].lp_field_18 ^ 2]], MON_DATA_NICKNAME, text); + StringGetEnd10(text); + toCpy = text; + break; + case 9: // link second opponent poke name + GetMonData(&gEnemyParty[gBattlePartyID[gLinkPlayers[multiplayerID].lp_field_18 ^ 3]], MON_DATA_NICKNAME, text); + StringGetEnd10(text); + toCpy = text; + break; + case 10: // attacker name with prefix, only bank 0/1 + HANDLE_NICKNAME_STRING_CASE(gBankAttacker, gBattlePartyID[GetBankByPlayerAI(GetBankIdentity(gBankAttacker) & 1)]) + break; + case 11: // attacker partner name, only bank 0/1 + if (GetBankSide(gBankAttacker) == 0) + GetMonData(&gPlayerParty[gBattlePartyID[GetBankByPlayerAI(GetBankIdentity(gBankAttacker) & 1) + 2]], MON_DATA_NICKNAME, text); + else + GetMonData(&gEnemyParty[gBattlePartyID[GetBankByPlayerAI(GetBankIdentity(gBankAttacker) & 1) + 2]], MON_DATA_NICKNAME, text); + + StringGetEnd10(text); + toCpy = text; + break; + case 12: // attacker name with prefix + HANDLE_NICKNAME_STRING_CASE(gBankAttacker, gBattlePartyID[gBankAttacker]) + break; + case 13: // target name with prefix + HANDLE_NICKNAME_STRING_CASE(gBankTarget, gBattlePartyID[gBankTarget]) + break; + case 14: // effect bank name with prefix + HANDLE_NICKNAME_STRING_CASE(gEffectBank, gBattlePartyID[gEffectBank]) + break; + case 15: // active bank name with prefix + HANDLE_NICKNAME_STRING_CASE(gActiveBank, gBattlePartyID[gActiveBank]) + break; + case 16: // scripting active bank name with prefix + HANDLE_NICKNAME_STRING_CASE(BATTLE_STRUCT->scriptingActive, gBattlePartyID[BATTLE_STRUCT->scriptingActive]) + break; + case 17: // current move name + if (gStringInfo->currentMove > 0x162) + toCpy = (void*) &gUnknown_08401674[BATTLE_STRUCT->stringMoveType]; + else + toCpy = gMoveNames[gStringInfo->currentMove]; + break; + case 18: // last used move name + if (gStringInfo->lastMove > 0x162) + toCpy = (void*) &gUnknown_08401674[BATTLE_STRUCT->stringMoveType]; + else + toCpy = gMoveNames[gStringInfo->lastMove]; + break; + case 19: // last used item + if (gBattleTypeFlags & BATTLE_TYPE_LINK) + { + if (gLastUsedItem == ITEM_ENIGMA_BERRY) + { + if (gLinkPlayers[BATTLE_STRUCT->linkPlayerIndex].lp_field_18 == gStringBank) + { + StringCopy(text, gEnigmaBerries[gStringBank].name); +#ifdef ENGLISH + StringAppend(text, gUnknown_08400A85); +#else + de_sub_8073174(text, gUnknown_08400A85); +#endif + toCpy = text; + } + else + toCpy = gUnknown_08400A78; + } + else + { + CopyItemName(gLastUsedItem, text); + toCpy = text; + } + } + else + { + CopyItemName(gLastUsedItem, text); + toCpy = text; + } + break; + case 20: // last used ability + toCpy = gAbilityNames[gLastUsedAbility]; + break; + case 21: // attacker ability + toCpy = gAbilityNames[gAbilitiesPerBank[gBankAttacker]]; + break; + case 22: // target ability + toCpy = gAbilityNames[gAbilitiesPerBank[gBankTarget]]; + break; + case 23: // scripting active ability + toCpy = gAbilityNames[gAbilitiesPerBank[BATTLE_STRUCT->scriptingActive]]; + break; + case 24: // effect bank ability + toCpy = gAbilityNames[gAbilitiesPerBank[gEffectBank]]; + break; + case 25: // trainer class name +#ifdef ENGLISH + if (gTrainerBattleOpponent == 0x400) + toCpy = gTrainerClassNames[GetSecretBaseTrainerNameIndex()]; + else if (gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER) + toCpy = gTrainerClassNames[get_trainer_class_name_index()]; + else if (gBattleTypeFlags & BATTLE_TYPE_EREADER_TRAINER) + toCpy = gTrainerClassNames[sub_8135FD8()]; + else + toCpy = gTrainerClassNames[gTrainers[gTrainerBattleOpponent].trainerClass]; + break; +#else + if (gTrainerBattleOpponent == 0x400) + toCpy = de_sub_8041024(gTrainerBattleOpponent, 0); + else if (gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER) + toCpy = de_sub_8041024(BATTLE_TYPE_BATTLE_TOWER, 0); + else if (gBattleTypeFlags & BATTLE_TYPE_EREADER_TRAINER) + toCpy = de_sub_8041024(BATTLE_TYPE_EREADER_TRAINER, 0); + else + toCpy = de_sub_8041024(0, gTrainerBattleOpponent); + break; +#endif + case 26: // trainer name + if (gTrainerBattleOpponent == 0x400) + { + memset(text, 0xFF, 8); + memcpy(text, &ewram[0x17002], 7); + toCpy = text; + } + else if (gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER) + { + get_trainer_name(text); + toCpy = text; + } + else if (gBattleTypeFlags & BATTLE_TYPE_EREADER_TRAINER) + { + sub_8135FF4(text); + toCpy = text; + } + else + toCpy = gTrainers[gTrainerBattleOpponent].trainerName; + break; + case 27: // link player name? + toCpy = gLinkPlayers[multiplayerID].name; + break; + case 28: // link partner name? + toCpy = gLinkPlayers[sub_803FC34(2 ^ gLinkPlayers[multiplayerID].lp_field_18)].name; + break; + case 29: // link opponent 1 name? + toCpy = gLinkPlayers[sub_803FC34(1 ^ gLinkPlayers[multiplayerID].lp_field_18)].name; + break; + case 30: // link opponent 2 name? + toCpy = gLinkPlayers[sub_803FC34(3 ^ gLinkPlayers[multiplayerID].lp_field_18)].name; + break; + case 31: // link scripting active name + toCpy = gLinkPlayers[sub_803FC34(BATTLE_STRUCT->scriptingActive)].name; + break; + case 32: // player name + toCpy = gSaveBlock2.playerName; + break; + case 33: // ? + toCpy = sub_8082830(); + break; + case 34: // ? + HANDLE_NICKNAME_STRING_CASE(BATTLE_STRUCT->scriptingActive, BATTLE_STRUCT->unk1605E) + break; + case 35: // lanette pc + if (FlagGet(SYS_PC_LANETTE)) + toCpy = gUnknown_084009F7; + else + toCpy = gUnknown_084009ED; + break; + case 38: + if (GetBankSide(gBankAttacker) == 0) + toCpy = gUnknown_084007AC; + else + toCpy = gUnknown_084007A7; + break; + case 39: + if (GetBankSide(gBankTarget) == 0) + toCpy = gUnknown_084007AC; + else + toCpy = gUnknown_084007A7; + break; + case 36: + if (GetBankSide(gBankAttacker) == 0) + toCpy = gUnknown_084007A1; + else + toCpy = gUnknown_0840079C; + break; + case 37: + if (GetBankSide(gBankTarget) == 0) + toCpy = gUnknown_084007A1; + else + toCpy = gUnknown_0840079C; + break; + case 40: + if (GetBankSide(gBankAttacker) == 0) + toCpy = gUnknown_084007B7; + else + toCpy = gUnknown_084007B2; + break; + case 41: + if (GetBankSide(gBankTarget) == 0) + toCpy = gUnknown_084007B7; + else + toCpy = gUnknown_084007B2; + break; + } + //if (toCpy != NULL) really GF, why did you forget about this? + while (*toCpy != EOS) + { + dst[dstID] = *toCpy; + dstID++; + toCpy++; + } + if (*src == 33) + { + dst[dstID] = 0xFC; + dstID++; + dst[dstID] = 9; + dstID++; + } + } + else + { + dst[dstID] = *src; + dstID++; + } + src++; + } + dst[dstID] = *src; + dstID++; + return dstID; +} + +#define ByteRead16(ptr) ((ptr)[0] | ((ptr)[1] << 8)) +#define ByteRead32(ptr) ((ptr)[0] | (ptr)[1] << 8 | (ptr)[2] << 16 | (ptr)[3] << 24) + +void StrCpyDecodeBattleTextBuff(u8* src, u8* dst) +{ + u32 srcID = 1; + u32 value = 0; + u8 text[12]; + u16 hword; + + *dst = EOS; + while (src[srcID] != EOS) + { + switch (src[srcID]) + { + case 0: // battle string + hword = ByteRead16(&src[srcID + 1]); +#ifdef GERMAN + if (hword == 209 || hword == 211) + srcID += 3; +#endif + StringAppend(dst, gBattleStringsTable[hword - BATTLESTRING_TO_SUB]); + srcID += 3; + break; + case 1: // int to string + switch (src[srcID + 1]) + { + case 1: + value = src[srcID + 3]; + break; + case 2: + value = ByteRead16(&src[srcID + 3]); + break; + case 4: + value = ByteRead32(&src[srcID + 3]); + break; + } + ConvertIntToDecimalStringN(dst, value, 0, src[srcID + 2]); + srcID += src[srcID + 1] + 3; + break; + case 2: // move name + StringAppend(dst, gMoveNames[ByteRead16(&src[srcID + 1])]); + srcID += 3; + break; + case 3: // type name + StringAppend(dst, gTypeNames[src[srcID + 1]]); + srcID += 2; + break; + case 4: // poke nick with prefix +#ifdef ENGLISH + if (GetBankSide(src[srcID + 1]) == 0) + { + GetMonData(&gPlayerParty[src[srcID + 2]], MON_DATA_NICKNAME, text); + } + else + { + if (gBattleTypeFlags & BATTLE_TYPE_TRAINER) + StringAppend(dst, gUnknown_08400797); + else + StringAppend(dst, gUnknown_08400791); + GetMonData(&gEnemyParty[src[srcID + 2]], MON_DATA_NICKNAME, text); + } + StringGetEnd10(text); + StringAppend(dst, text); +#else + if (GetBankSide(src[srcID + 1]) == 0) + { + GetMonData(&gPlayerParty[src[srcID + 2]], MON_DATA_NICKNAME, text); + StringGetEnd10(text); + StringAppend(dst, text); + } + else + { + GetMonData(&gEnemyParty[src[srcID + 2]], MON_DATA_NICKNAME, text); + StringGetEnd10(text); + StringAppend(dst, text); + if (gBattleTypeFlags & BATTLE_TYPE_TRAINER) + StringAppend(dst, gUnknown_08400797); + else + StringAppend(dst, gUnknown_08400791); + } +#endif + srcID += 3; + break; + case 5: // stats + StringAppend(dst, gUnknown_08400F58[src[srcID + 1]]); + srcID += 2; + break; + case 6: // species name + GetSpeciesName(dst, ByteRead16(&src[srcID + 1])); + srcID += 3; + break; + case 7: // poke nick without prefix + if (GetBankSide(src[srcID + 1]) == 0) + GetMonData(&gPlayerParty[src[srcID + 2]], MON_DATA_NICKNAME, dst); + else + GetMonData(&gEnemyParty[src[srcID + 2]], MON_DATA_NICKNAME, dst); + StringGetEnd10(dst); + srcID += 3; + break; + case 8: // flavour table + StringAppend(dst, gUnknown_08400F78[src[srcID + 1]]); + srcID += 2; + break; + case 9: // ability names + StringAppend(dst, gAbilityNames[src[srcID + 1]]); + srcID += 2; + break; + case 10: // item name + { + hword = ByteRead16(&src[srcID + 1]); + if (gBattleTypeFlags & BATTLE_TYPE_LINK) + { + if (hword == ITEM_ENIGMA_BERRY) + { + if (gLinkPlayers[BATTLE_STRUCT->linkPlayerIndex].lp_field_18 == gStringBank) + { + StringCopy(dst, gEnigmaBerries[gStringBank].name); +#ifdef ENGLISH + StringAppend(dst, gUnknown_08400A85); +#else + de_sub_8073174(dst, gUnknown_08400A85); +#endif + } + else + StringAppend(dst, gUnknown_08400A78); + } + else + CopyItemName(hword, dst); + } + else + CopyItemName(hword, dst); + srcID += 3; + } + break; + } + } +} + +void sub_8121D1C(u8* textBuff) +{ + s32 counter = 0; + u32 i = 0; + + while (counter != 4) + { + if (gUnknown_084016BC[i] == 0) + counter++; + if (gUnknown_084016BC[i++] == gStringInfo->currentMove) + break; + } + + if (counter >= 0) + { + if (counter <= 2) + StringCopy(textBuff, gUnknown_08400E5E); // is + else if (counter <= 4) + StringCopy(textBuff, gUnknown_08400E62); // 's + } +} + +void sub_8121D74(u8* dst) +{ + s32 counter = 0; + s32 i = 0; + + while (*dst != EOS) + dst++; + + while (counter != 4) + { + if (gUnknown_084016BC[i] == 0) + counter++; + if (gUnknown_084016BC[i++] == gStringInfo->currentMove) + break; + } + + switch (counter) + { + case 0: + StringCopy(dst, gUnknown_084007C8); + break; + case 1: + StringCopy(dst, gUnknown_084007CA); + break; + case 2: + StringCopy(dst, gUnknown_084007CC); + break; + case 3: + StringCopy(dst, gUnknown_084007CE); + break; + case 4: + StringCopy(dst, gUnknown_084007D0); + break; + } +} diff --git a/src/field/choose_party.c b/src/field/choose_party.c index d8df44028..7b2c833e1 100644 --- a/src/field/choose_party.c +++ b/src/field/choose_party.c @@ -211,11 +211,10 @@ bool8 sub_8121E78(void) return FALSE; } -#ifdef NONMATCHING static bool8 IsMonAllowedInBattleTower(struct Pokemon *pkmn) { - u16 r3; - s32 i; + u16 species; + s32 i = 0; if (GetMonData(pkmn, MON_DATA_IS_EGG)) return FALSE; @@ -232,97 +231,16 @@ static bool8 IsMonAllowedInBattleTower(struct Pokemon *pkmn) && GetMonData(pkmn, MON_DATA_LEVEL) > 50) return FALSE; - r3 = GetMonData(pkmn, MON_DATA_SPECIES); - // Can't stop the compiler from optimizing out the first index - for (i = 0; gBattleTowerBanlist[i] != 0xFFFF; i++) + // Check if the pkmn is in the ban list + species = GetMonData(pkmn, MON_DATA_SPECIES); + while (gBattleTowerBanlist[i] != 0xFFFF) { - if (gBattleTowerBanlist[i] == r3) + if (gBattleTowerBanlist[i] == species) return FALSE; + i++; } return TRUE; } -#else -__attribute__((naked)) -static bool8 IsMonAllowedInBattleTower(struct Pokemon *pkmn) -{ - asm_unified( - "push {r4,lr}\n\ - adds r4, r0, 0\n\ - movs r1, 0x2D\n\ - bl GetMonData\n\ - cmp r0, 0\n\ - bne _0812207C\n\ - ldr r0, _08122058 @ =0x0201b000\n\ - ldr r1, _0812205C @ =0x00000263\n\ - adds r0, r1\n\ - ldrb r0, [r0]\n\ - cmp r0, 0\n\ - bne _08122060\n\ - adds r0, r4, 0\n\ - movs r1, 0x39\n\ - bl GetMonData\n\ - cmp r0, 0\n\ - beq _0812207C\n\ - b _081220B6\n\ - .align 2, 0\n\ -_08122058: .4byte 0x0201b000\n\ -_0812205C: .4byte 0x00000263\n\ -_08122060:\n\ - ldr r0, _08122080 @ =gSaveBlock2\n\ - ldr r1, _08122084 @ =0x00000554\n\ - adds r0, r1\n\ - ldrb r1, [r0]\n\ - movs r0, 0x1\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - bne _08122088\n\ - adds r0, r4, 0\n\ - movs r1, 0x38\n\ - bl GetMonData\n\ - cmp r0, 0x32\n\ - bls _08122088\n\ -_0812207C:\n\ - movs r0, 0\n\ - b _081220B8\n\ - .align 2, 0\n\ -_08122080: .4byte gSaveBlock2\n\ -_08122084: .4byte 0x00000554\n\ -_08122088:\n\ - adds r0, r4, 0\n\ - movs r1, 0xB\n\ - bl GetMonData\n\ - lsls r0, 16\n\ - lsrs r3, r0, 16\n\ - ldr r1, _081220C0 @ =gBattleTowerBanlist\n\ - movs r0, 0\n\ - lsls r0, 1\n\ - adds r2, r0, r1\n\ - ldrh r0, [r2]\n\ - ldr r1, _081220C4 @ =0x0000ffff\n\ - cmp r0, r1\n\ - beq _081220B6\n\ - adds r4, r1, 0\n\ - adds r1, r2, 0\n\ -_081220A8:\n\ - ldrh r0, [r1]\n\ - cmp r0, r3\n\ - beq _0812207C\n\ - adds r1, 0x2\n\ - ldrh r0, [r1]\n\ - cmp r0, r4\n\ - bne _081220A8\n\ -_081220B6:\n\ - movs r0, 0x1\n\ -_081220B8:\n\ - pop {r4}\n\ - pop {r1}\n\ - bx r1\n\ - .align 2, 0\n\ -_081220C0: .4byte gBattleTowerBanlist\n\ -_081220C4: .4byte 0x0000ffff\n" - ); -} -#endif static u8 sub_81220C8(void) { diff --git a/src/scene/egg_hatch.c b/src/scene/egg_hatch.c index 32fbe1547..2b68d83e8 100644 --- a/src/scene/egg_hatch.c +++ b/src/scene/egg_hatch.c @@ -1,7 +1,226 @@ #include "global.h" #include "pokemon.h" +#include "items.h" +#include "decompress.h" +#include "data2.h" +#include "task.h" +#include "script.h" +#include "palette.h" +#include "rom4.h" +#include "main.h" +#include "event_data.h" +#include "sound.h" +#include "songs.h" +#include "text.h" +#include "text_window.h" +#include "string_util.h" +#include "strings2.h" +#include "menu.h" +#include "naming_screen.h" +#include "trig.h" +#include "rng.h" -void CreatedHatchedMon(struct Pokemon *egg, struct Pokemon *temp) { +extern u8 ewram[]; +extern struct SpriteTemplate gUnknown_02024E8C; + +struct EggHatchData +{ + u8 eggSpriteID; + u8 pokeSpriteID; + u8 CB2_state; + u8 CB2_PalCounter; + u8 eggPartyID; + struct Window window; + u8 tileDataStartOffset; + u8 unused_39; + u8 eggShardVelocityID; +}; + +struct EggHatchData* gEggHatchData; + +extern const u32 gUnknown_08D00000[]; +extern const u32 gUnknown_08D00524[]; +extern const u32 gUnknown_0820CA98[]; +extern const u32 gUnknown_0820F798[]; +extern const u16 gUnknown_08D004E0[]; //palette +extern const u16 gUnknown_0820C9F8[]; //palette +extern const struct SpriteSheet sUnknown_0820A3B0; +extern const struct SpriteSheet sUnknown_0820A3B8; +extern const struct SpritePalette sUnknown_0820A3C0; + +bool8 GetNationalPokedexFlag(u16 nationalNum, u8 caseID); +u8* GetMonNick(struct Pokemon* mon, u8* dst); +u8 sav1_map_get_name(void); +const struct CompressedSpritePalette* sub_8040990(struct Pokemon* mon); //gets pokemon palette address +void sub_8080990(void); + +static void Task_EggHatch(u8 taskID); +static void CB2_EggHatch_0(void); +static void CB2_EggHatch_1(void); +static void SpriteCB_Egg_0(struct Sprite* sprite); +static void SpriteCB_Egg_1(struct Sprite* sprite); +static void SpriteCB_Egg_2(struct Sprite* sprite); +static void SpriteCB_Egg_3(struct Sprite* sprite); +static void SpriteCB_Egg_4(struct Sprite* sprite); +static void SpriteCB_Egg_5(struct Sprite* sprite); +static void SpriteCB_EggShard(struct Sprite* sprite); +static void EggHatchPrintMessage2(u8* src); +static void EggHatchPrintMessage1(u8* src); +static bool8 EggHatchUpdateWindowText(void); +static void CreateRandomEggShardSprite(void); +static void CreateEggShardSprite(u8 x, u8 y, s16 data1, s16 data2, s16 data3, u8 spriteAnimIndex); + +// graphics + +static const u16 sEggPalette[] = INCBIN_U16("graphics/pokemon/egg/palette.gbapal"); +static const u8 sEggHatchTiles[] = INCBIN_U8("graphics/misc/egg_hatch.4bpp"); +static const u8 sEggShardTiles[] = INCBIN_U8("graphics/misc/egg_shard.4bpp"); + +static const struct OamData sOamData_820A378 = +{ + .y = 0, + .affineMode = 0, + .objMode = 0, + .mosaic = 0, + .bpp = 0, + .shape = 0, + .x = 0, + .matrixNum = 0, + .size = 2, + .tileNum = 0, + .priority = 1, + .paletteNum = 0, + .affineParam = 0, +}; + +static const union AnimCmd sSpriteAnim_820A380[] = +{ + ANIMCMD_FRAME(0, 5), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_820A388[] = +{ + ANIMCMD_FRAME(16, 5), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_820A390[] = +{ + ANIMCMD_FRAME(32, 5), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_820A398[] = +{ + ANIMCMD_FRAME(48, 5), + ANIMCMD_END +}; + +static const union AnimCmd *const sSpriteAnimTable_820A3A0[] = +{ + sSpriteAnim_820A380, + sSpriteAnim_820A388, + sSpriteAnim_820A390, + sSpriteAnim_820A398, +}; + +static const struct SpriteSheet sUnknown_0820A3B0 = +{ + .data = sEggHatchTiles, + .size = 2048, + .tag = 12345, +}; + +static const struct SpriteSheet sUnknown_0820A3B8 = +{ + .data = sEggShardTiles, + .size = 128, + .tag = 23456, +}; + +static const struct SpritePalette sUnknown_0820A3C0 = +{ + .data = sEggPalette, + .tag = 54321 +}; + +static const struct SpriteTemplate sSpriteTemplate_820A3C8 = +{ + .tileTag = 12345, + .paletteTag = 54321, + .oam = &sOamData_820A378, + .anims = sSpriteAnimTable_820A3A0, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy +}; + + +static const struct OamData sOamData_820A3E0 = +{ + .y = 0, + .affineMode = 0, + .objMode = 0, + .mosaic = 0, + .bpp = 0, + .shape = 0, + .x = 0, + .matrixNum = 0, + .size = 0, + .tileNum = 0, + .priority = 2, + .paletteNum = 0, + .affineParam = 0, +}; + +static const union AnimCmd sSpriteAnim_820A3E8[] = +{ + ANIMCMD_FRAME(0, 5), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_820A3F0[] = +{ + ANIMCMD_FRAME(1, 5), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_820A3F8[] = +{ + ANIMCMD_FRAME(2, 5), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_820A400[] = +{ + ANIMCMD_FRAME(3, 5), + ANIMCMD_END +}; + +static const union AnimCmd *const sSpriteAnimTable_820A408[] = +{ + sSpriteAnim_820A3E8, + sSpriteAnim_820A3F0, + sSpriteAnim_820A3F8, + sSpriteAnim_820A400, +}; + +static const struct SpriteTemplate sSpriteTemplate_820A418 = +{ + .tileTag = 23456, + .paletteTag = 54321, + .oam = &sOamData_820A3E0, + .anims = sSpriteAnimTable_820A408, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCB_EggShard +}; + +// actual code + +static void CreatedHatchedMon(struct Pokemon *egg, struct Pokemon *temp) +{ u16 species; u32 personality, pokerus; u8 i, friendship, language, gameMet, markings; @@ -50,3 +269,596 @@ void CreatedHatchedMon(struct Pokemon *egg, struct Pokemon *temp) { *egg = *temp; } + +static void AddHatchedMonToParty(u8 id) +{ + u8 isEgg; + u16 pokeNum; + u8 name[12]; + u16 ball; + u16 caughtLvl; + u8 mapNameID; + struct Pokemon* mon = &gPlayerParty[id]; + + CreatedHatchedMon(mon, &gEnemyParty[0]); + isEgg = 0; + SetMonData(mon, MON_DATA_IS_EGG, &isEgg); + + pokeNum = GetMonData(mon, MON_DATA_SPECIES); + GetSpeciesName(name, pokeNum); + SetMonData(mon, MON_DATA_NICKNAME, name); + + pokeNum = SpeciesToNationalPokedexNum(pokeNum); + GetNationalPokedexFlag(pokeNum, 2); + GetNationalPokedexFlag(pokeNum, 3); + + GetMonNick(mon, gStringVar1); + + ball = ITEM_POKE_BALL; + SetMonData(mon, MON_DATA_POKEBALL, (const u8*) &ball); + + caughtLvl = 0; + SetMonData(mon, MON_DATA_MET_LEVEL, (const u8*) &caughtLvl); + + mapNameID = sav1_map_get_name(); + SetMonData(mon, MON_DATA_MET_LOCATION, &mapNameID); + + MonRestorePP(mon); + CalculateMonStats(mon); +} + +void ScriptHatchMon(void) +{ + AddHatchedMonToParty(gSpecialVar_0x8004); +} + +#ifdef NONMATCHING +static bool8 sub_8042ABC(void* a, u8 b) +{ + +} + +#else +__attribute__((naked)) +static bool8 sub_8042ABC(void* a, u8 b) +{ + asm(".syntax unified\n\ + push {r4-r6,lr}\n\ + sub sp, 0x20\n\ + adds r5, r0, 0\n\ + lsls r4, r1, 24\n\ + lsrs r4, 24\n\ + lsls r0, r4, 2\n\ + adds r0, r4\n\ + lsls r0, 4\n\ + adds r0, r5, r0\n\ + mov r1, sp\n\ + bl GetBoxMonNick\n\ + lsls r0, r4, 3\n\ + subs r0, r4\n\ + lsls r1, r0, 3\n\ + adds r0, r5, r1\n\ + adds r0, 0xC0\n\ + ldrh r0, [r0]\n\ + cmp r0, 0\n\ + beq _08042B40\n\ + adds r0, r1, 0\n\ + adds r0, 0xA0\n\ + adds r5, r0\n\ + adds r6, r5, 0\n\ + adds r6, 0x2C\n\ + mov r0, sp\n\ + adds r1, r6, 0\n\ + bl StringCompareWithoutExtCtrlCodes\n\ + cmp r0, 0\n\ + bne _08042B08\n\ + ldr r0, _08042B30 @ =gSaveBlock2\n\ + adds r1, r5, 0\n\ + adds r1, 0x24\n\ + bl StringCompareWithoutExtCtrlCodes\n\ + cmp r0, 0\n\ + beq _08042B40\n\ +_08042B08:\n\ + ldr r0, _08042B34 @ =gStringVar1\n\ + mov r1, sp\n\ + bl StringCopy\n\ + ldr r4, _08042B38 @ =gStringVar2\n\ + adds r1, r5, 0\n\ + adds r1, 0x24\n\ + adds r0, r4, 0\n\ + bl StringCopy\n\ + ldr r0, _08042B3C @ =gStringVar3\n\ + adds r1, r6, 0\n\ + bl StringCopy\n\ + adds r0, r4, 0\n\ + bl SanitizeNameString\n\ + movs r0, 0x1\n\ + b _08042B42\n\ + .align 2, 0\n\ +_08042B30: .4byte gSaveBlock2\n\ +_08042B34: .4byte gStringVar1\n\ +_08042B38: .4byte gStringVar2\n\ +_08042B3C: .4byte gStringVar3\n\ +_08042B40:\n\ + movs r0, 0\n\ +_08042B42:\n\ + add sp, 0x20\n\ + pop {r4-r6}\n\ + pop {r1}\n\ + bx r1\n\ + .syntax divided"); +} + +#endif // NONMATCHING + +bool8 sub_8042B4C(void) +{ + return sub_8042ABC(&gSaveBlock1.daycareData, gSpecialVar_0x8004); +} + +static u8 EggHatchCreateMonSprite(u8 a0, u8 switchID, u8 pokeID) +{ + u8 r5 = 0; + u8 spriteID = 0; + struct Pokemon* mon = NULL; + + if (a0 == 0) + { + mon = &gPlayerParty[pokeID]; + r5 = 1; + } + if (a0 == 1) + { + mon = &gPlayerParty[pokeID]; + r5 = 3; + } + switch (switchID) + { + case 0: + { + u16 species = GetMonData(mon, MON_DATA_SPECIES); + u32 pid = GetMonData(mon, MON_DATA_PERSONALITY); + HandleLoadSpecialPokePic(&gMonFrontPicTable[species], gMonFrontPicCoords[species].coords, gMonFrontPicCoords[species].y_offset,(u32)(&ewram[0]), gUnknown_081FAF4C[2 * a0 + 1], species, pid); + LoadCompressedObjectPalette(sub_8040990(mon)); + } + break; + case 1: + GetMonSpriteTemplate_803C56C(sub_8040990(mon)->tag, r5); + spriteID = CreateSprite(&gUnknown_02024E8C, 120, 70, 6); + gSprites[spriteID].invisible = 1; + gSprites[spriteID].callback = SpriteCallbackDummy; + break; + } + return spriteID; +} + +static void VBlankCB_EggHatch(void) +{ + LoadOam(); + ProcessSpriteCopyRequests(); + TransferPlttBuffer(); +} + +void EggHatch(void) +{ + ScriptContext2_Enable(); + CreateTask(Task_EggHatch, 10); + BeginNormalPaletteFade(-1, 0, 0, 0x10, 0); +} + +static void Task_EggHatch(u8 taskID) +{ + if (!gPaletteFade.active) + { + SetMainCallback2(CB2_EggHatch_0); + gFieldCallback = sub_8080990; + DestroyTask(taskID); + } +} + +static void CB2_EggHatch_0(void) +{ + switch (gMain.state) + { + case 0: + REG_DISPCNT = 0; + gEggHatchData = (struct EggHatchData*)(&ewram[0x18000]); + gEggHatchData->eggPartyID = gSpecialVar_0x8004; + gEggHatchData->eggShardVelocityID = 0; + ResetTasks(); + ResetSpriteData(); + FreeAllSpritePalettes(); + SetVBlankCallback(VBlankCB_EggHatch); + gMain.state++; + gSpecialVar_0x8005 = GetCurrentMapMusic(); + break; + case 1: + SetUpWindowConfig(&gWindowConfig_81E6F84); + InitWindowFromConfig(&gEggHatchData->window, &gWindowConfig_81E6F84); + gEggHatchData->tileDataStartOffset = SetTextWindowBaseTileNum(20); + LoadTextWindowGraphics(&gEggHatchData->window); + gMain.state++; + break; + case 2: + LZDecompressVram(&gUnknown_08D00000, (void*)(VRAM)); + CpuSet(&gUnknown_08D00524, &ewram[0], 0x800); + DmaCopy16(3, &ewram[0], (void*)(VRAM + 0x2800), 0x500); + LoadCompressedPalette(&gUnknown_08D004E0, 0, 0x20); + gMain.state++; + break; + case 3: + LoadSpriteSheet(&sUnknown_0820A3B0); + LoadSpriteSheet(&sUnknown_0820A3B8); + LoadSpritePalette(&sUnknown_0820A3C0); + gMain.state++; + break; + case 4: + gEggHatchData->eggSpriteID = CreateSprite(&sSpriteTemplate_820A3C8, 0x78, 0x4B, 5); + AddHatchedMonToParty(gEggHatchData->eggPartyID); + gMain.state++; + break; + case 5: + EggHatchCreateMonSprite(0, 0, gEggHatchData->eggPartyID); + gMain.state++; + break; + case 6: + gEggHatchData->pokeSpriteID = EggHatchCreateMonSprite(0, 1, gEggHatchData->eggPartyID); + gMain.state++; + break; + case 7: + { + u32 offsetRead, offsetWrite; + u32 offsetRead2, offsetWrite2; + u32 size; + + REG_BG2CNT = 0x4C06; + LoadPalette(&gUnknown_0820C9F8, 0x10, 0xA0); + + offsetRead = (u32)(&gUnknown_0820CA98); + offsetWrite = (VRAM + 0x4000); + size = 0x1300; + while (TRUE) + { + DmaCopy16(3, offsetRead, (void *) (offsetWrite), 0x1000); + offsetRead += 0x1000; + offsetWrite += 0x1000; + size -= 0x1000; + if (size <= 0x1000) + { + DmaCopy16(3, offsetRead, (void *) (offsetWrite), size); + break; + } + } + + offsetRead2 = (u32)(&gUnknown_0820F798); + offsetWrite2 = (u32)(VRAM + 0x6000); + DmaCopy16(3, offsetRead2, (void*)(offsetWrite2), 0x1000); + gMain.state++; + } + break; + case 8: + REG_BG1CNT = 0x501; + + REG_BG0HOFS = 0; + REG_BG0VOFS = 0; + + REG_BG1HOFS = 0; + REG_BG1VOFS = 0; + + REG_BG2HOFS = 0; + REG_BG2VOFS = 0; + + SetMainCallback2(CB2_EggHatch_1); + gEggHatchData->CB2_state = 0; + break; + } +} + +static void EggHatchSetMonNickname(void) +{ + SetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_NICKNAME, gStringVar3); + SetMainCallback2(c2_exit_to_overworld_2_switch); +} + +static void Task_EggHatchPlayBGM(u8 taskID) +{ + if (gTasks[taskID].data[0] == 0) + StopMapMusic(); + if (gTasks[taskID].data[0] == 1) + PlayBGM(376); + if (gTasks[taskID].data[0] > 60) + { + PlayBGM(377); + DestroyTask(taskID); + //return; task is destroyed, yet you increment the value? + } + gTasks[taskID].data[0]++; +} + +static void CB2_EggHatch_1(void) +{ + switch (gEggHatchData->CB2_state) + { + case 0: + BeginNormalPaletteFade(-1, 0, 0x10, 0, 0); + REG_DISPCNT = 0x1740; + gEggHatchData->CB2_state++; + CreateTask(Task_EggHatchPlayBGM, 5); + break; + case 1: + if (!gPaletteFade.active) + { + gEggHatchData->CB2_PalCounter = 0; + gEggHatchData->CB2_state++; + } + break; + case 2: + if (++gEggHatchData->CB2_PalCounter > 30) + { + gEggHatchData->CB2_state++; + gSprites[gEggHatchData->eggSpriteID].callback = SpriteCB_Egg_0; + } + break; + case 3: + if (gSprites[gEggHatchData->eggSpriteID].callback == SpriteCallbackDummy) + gEggHatchData->CB2_state++; + break; + case 4: + GetMonNick(&gPlayerParty[gEggHatchData->eggPartyID], gStringVar1); + StringExpandPlaceholders(gStringVar4, gOtherText_HatchedFromEgg); + EggHatchPrintMessage2(gStringVar4); + PlayFanfare(371); + gEggHatchData->CB2_state++; + break; + case 5: + if (IsFanfareTaskInactive()) + gEggHatchData->CB2_state++; + break; + case 6: + if (IsFanfareTaskInactive()) + gEggHatchData->CB2_state++; + break; + case 7: + GetMonNick(&gPlayerParty[gEggHatchData->eggPartyID], gStringVar1); + StringExpandPlaceholders(gStringVar4, gOtherText_NickHatchPrompt); + EggHatchPrintMessage1(gStringVar4); + gEggHatchData->CB2_state++; + break; + case 8: + if (EggHatchUpdateWindowText()) + { + MenuDrawTextWindow(22, 8, 27, 13); + InitYesNoMenu(22, 8, 4); + gEggHatchData->CB2_state++; + } + break; + case 9: + { + s8 menuInput; + if ((menuInput = ProcessMenuInputNoWrap_()) != -2) + { + if (menuInput != -1 && menuInput != 1) + { + u16 species; + u8 gender; + u32 personality; + + GetMonNick(&gPlayerParty[gEggHatchData->eggPartyID], gStringVar3); + species = GetMonData(&gPlayerParty[gEggHatchData->eggPartyID], MON_DATA_SPECIES); + gender = GetMonGender(&gPlayerParty[gEggHatchData->eggPartyID]); + personality = GetMonData(&gPlayerParty[gEggHatchData->eggPartyID], MON_DATA_PERSONALITY, 0); + DoNamingScreen(3, gStringVar3, species, gender, personality, EggHatchSetMonNickname); + } + else + gEggHatchData->CB2_state++; + } + } + break; + case 10: + BeginNormalPaletteFade(-1, 0, 0, 0x10, 0); + gEggHatchData->CB2_state++; + break; + case 11: + if (!gPaletteFade.active) + SetMainCallback2(c2_exit_to_overworld_2_switch); + break; + } + RunTasks(); + AnimateSprites(); + BuildOamBuffer(); + UpdatePaletteFade(); +} + +static void SpriteCB_Egg_0(struct Sprite* sprite) +{ + if (++sprite->data0 > 20) + { + sprite->callback = SpriteCB_Egg_1; + sprite->data0 = 0; + } + else + { + sprite->data1 = (sprite->data1 + 20) & 0xFF; + sprite->pos2.x = Sin(sprite->data1, 1); + if (sprite->data0 == 15) + { + PlaySE(SE_BOWA); + StartSpriteAnim(sprite, 1); + CreateRandomEggShardSprite(); + } + } +} + +static void SpriteCB_Egg_1(struct Sprite* sprite) +{ + if (++sprite->data2 > 30) + { + if (++sprite->data0 > 20) + { + sprite->callback = SpriteCB_Egg_2; + sprite->data0 = 0; + sprite->data2 = 0; + } + else + { + sprite->data1 = (sprite->data1 + 20) & 0xFF; + sprite->pos2.x = Sin(sprite->data1, 2); + if (sprite->data0 == 15) + { + PlaySE(SE_BOWA); + StartSpriteAnim(sprite, 2); + } + } + } +} + +static void SpriteCB_Egg_2(struct Sprite* sprite) +{ + if (++sprite->data2 > 30) + { + if (++sprite->data0 > 38) + { + u16 species; + + sprite->callback = SpriteCB_Egg_3; + sprite->data0 = 0; + species = GetMonData(&gPlayerParty[gEggHatchData->eggPartyID], MON_DATA_SPECIES); + gSprites[gEggHatchData->pokeSpriteID].pos2.x = 0; + gSprites[gEggHatchData->pokeSpriteID].pos2.y = gMonFrontPicCoords[species].y_offset; + } + else + { + sprite->data1 = (sprite->data1 + 20) & 0xFF; + sprite->pos2.x = Sin(sprite->data1, 2); + if (sprite->data0 == 15) + { + PlaySE(SE_BOWA); + StartSpriteAnim(sprite, 2); + CreateRandomEggShardSprite(); + CreateRandomEggShardSprite(); + } + if (sprite->data0 == 30) + PlaySE(SE_BOWA); + } + } +} + +static void SpriteCB_Egg_3(struct Sprite* sprite) +{ + if (++sprite->data0 > 50) + { + sprite->callback = SpriteCB_Egg_4; + sprite->data0 = 0; + } +} + +static void SpriteCB_Egg_4(struct Sprite* sprite) +{ + s16 i; + if (sprite->data0 == 0) + BeginNormalPaletteFade(-1, -1, 0, 0x10, 0xFFFF); + if (sprite->data0 < 4u) + { + for (i = 0; i <= 3; i++) + CreateRandomEggShardSprite(); + } + sprite->data0++; + if (!gPaletteFade.active) + { + PlaySE(SE_TAMAGO); + sprite->invisible = 1; + sprite->callback = SpriteCB_Egg_5; + sprite->data0 = 0; + } +} + +static void SpriteCB_Egg_5(struct Sprite* sprite) +{ + if (sprite->data0 == 0) + { + gSprites[gEggHatchData->pokeSpriteID].invisible = 0; + StartSpriteAffineAnim(&gSprites[gEggHatchData->pokeSpriteID], 1); + } + if (sprite->data0 == 8) + BeginNormalPaletteFade(-1, -1, 0x10, 0, 0xFFFF); + if (sprite->data0 <= 9) + gSprites[gEggHatchData->pokeSpriteID].pos1.y -= 1; + if (sprite->data0 > 40) + sprite->callback = SpriteCallbackDummy; + sprite->data0++; +} + +static void SpriteCB_EggShard(struct Sprite* sprite) +{ + sprite->data4 += sprite->data1; + sprite->data5 += sprite->data2; + + sprite->pos2.x = sprite->data4 / 256; + sprite->pos2.y = sprite->data5 / 256; + + sprite->data2 += sprite->data3; + + if (sprite->pos1.y + sprite->pos2.y > sprite->pos1.y + 20 && sprite->data2 > 0) + DestroySprite(sprite); +} + +// Converts a number to Q8.8 fixed-point format +#define Q_8_8(n) ((s16)((n) * 256)) + +static const s16 sEggShardVelocities[][2] = +{ + {Q_8_8(-1.5), Q_8_8(-3.75)}, + {Q_8_8(-5), Q_8_8(-3)}, + {Q_8_8(3.5), Q_8_8(-3)}, + {Q_8_8(-4), Q_8_8(-3.75)}, + {Q_8_8(2), Q_8_8(-1.5)}, + {Q_8_8(-0.5), Q_8_8(-6.75)}, + {Q_8_8(5), Q_8_8(-2.25)}, + {Q_8_8(-1.5), Q_8_8(-3.75)}, + {Q_8_8(4.5), Q_8_8(-1.5)}, + {Q_8_8(-1), Q_8_8(-6.75)}, + {Q_8_8(4), Q_8_8(-2.25)}, + {Q_8_8(-3.5), Q_8_8(-3.75)}, + {Q_8_8(1), Q_8_8(-1.5)}, + {Q_8_8(-3.515625), Q_8_8(-6.75)}, + {Q_8_8(4.5), Q_8_8(-2.25)}, + {Q_8_8(-0.5), Q_8_8(-7.5)}, + {Q_8_8(1), Q_8_8(-4.5)}, + {Q_8_8(-2.5), Q_8_8(-2.25)}, + {Q_8_8(2.5), Q_8_8(-7.5)}, +}; + +static void CreateRandomEggShardSprite(void) +{ + u16 spriteAnimIndex; + + s16 velocity1 = sEggShardVelocities[gEggHatchData->eggShardVelocityID][0]; + s16 velocity2 = sEggShardVelocities[gEggHatchData->eggShardVelocityID][1]; + gEggHatchData->eggShardVelocityID++; + spriteAnimIndex = Random() % 4; + CreateEggShardSprite(120, 60, velocity1, velocity2, 100, spriteAnimIndex); +} + +static void CreateEggShardSprite(u8 x, u8 y, s16 data1, s16 data2, s16 data3, u8 spriteAnimIndex) +{ + u8 spriteID = CreateSprite(&sSpriteTemplate_820A418, x, y, 4); + gSprites[spriteID].data1 = data1; + gSprites[spriteID].data2 = data2; + gSprites[spriteID].data3 = data3; + StartSpriteAnim(&gSprites[spriteID], spriteAnimIndex); +} + +static void EggHatchPrintMessage1(u8* src) +{ + sub_8002EB0(&gEggHatchData->window, src, gEggHatchData->tileDataStartOffset, 3, 15); +} + +static void EggHatchPrintMessage2(u8* src) +{ + sub_8003460(&gEggHatchData->window, src, gEggHatchData->tileDataStartOffset, 3, 15); +} + +static bool8 EggHatchUpdateWindowText(void) +{ + return sub_80035AC(&gEggHatchData->window); +} diff --git a/src/scene/hall_of_fame.c b/src/scene/hall_of_fame.c new file mode 100644 index 000000000..a04f9d65b --- /dev/null +++ b/src/scene/hall_of_fame.c @@ -0,0 +1,1413 @@ +#include "global.h" +#include "main.h" +#include "task.h" +#include "palette.h" +#include "sound.h" +#include "songs.h" +#include "pokemon.h" +#include "text.h" +#include "strings.h" +#include "string_util.h" +#include "menu.h" +#include "save.h" +#include "species.h" +#include "rom4.h" +#include "m4a.h" +#include "data2.h" +#include "decompress.h" +#include "rng.h" +#include "trig.h" + +static EWRAM_DATA u32 sUnknown_0203931C = 0; + +extern u8 ewram[]; +extern bool8 gUnknown_02039324; // has hall of fame records +extern void (*gGameContinueCallback)(void); +extern struct MusicPlayerInfo gMPlay_BGM; +extern u8 gReservedSpritePaletteCount; +extern struct SpriteTemplate gUnknown_02024E8C; + +extern const u8 gContestConfetti_Gfx[]; +extern const u8 gContestConfetti_Pal[]; +extern const u8 gHallOfFame_Gfx[]; +extern const u16 gHallOfFame_Pal[]; + +struct HallofFameMon +{ + u32 tid; + u32 personality; + u16 species : 9; + u16 lvl : 7; + u8 nick[10]; +}; + +struct HallofFameMons +{ + struct HallofFameMon mons[6]; +}; + +#define HALL_OF_FAME_MAX_TEAMS 50 + +static void sub_8141FF8(u8 taskID); +static void sub_81422E8(u8 taskID); +static void sub_814217C(u8 taskID); +static void sub_8142274(u8 taskID); +static void sub_81422B8(u8 taskID); +static void sub_8142320(u8 taskID); +static void sub_8142404(u8 taskID); +static void sub_8142484(u8 taskID); +static void sub_8142570(u8 taskID); +static void sub_8142618(u8 taskID); +static void sub_81426F8(u8 taskID); +static void sub_8142738(u8 taskID); +static void sub_8142794(u8 taskID); +static void sub_8142818(u8 taskID); +static void sub_8142850(u8 taskID); +static void sub_81428A0(u8 taskID); +static void sub_8142A28(u8 taskID); +static void sub_8142FEC(u8 taskID); +static void sub_8142B04(u8 taskID); +static void sub_8142CC8(u8 taskID); +static void sub_8142DF4(u8 taskID); +static void sub_8142F78(u8 taskID); +static void sub_8142FCC(u8 taskID); +static void sub_814302C(u8 taskID); + +static void sub_81435DC(struct Sprite* sprite); +static void sub_814386C(struct Sprite* sprite); +static void SpriteCB_HallOfFame_Dummy(struct Sprite* sprite); + +static void sub_8143068(u8 a0, u8 a1); +static void HallOfFame_PrintMonInfo(struct HallofFameMon* currMon, u8 a1, u8 a2); +static void HallOfFame_PrintPlayerInfo(u8 a0, u8 a1); +static void sub_81433E0(void); +static void sub_8143570(void); +static void sub_81435B8(void); +static u32 HallOfFame_LoadPokemonPic(u16 species, s16 posX, s16 posY, u16 pokeID, u32 tid, u32 pid); +static u32 HallOfFame_LoadTrainerPic(u16 trainerPicID, s16 posX, s16 posY, u16 a3); +static bool8 sub_81438C4(void); + +// functions from different files +void sub_81439D0(void); +void sub_80C5CD4(void*); // ? +void sub_80C5E38(void*); // ? +bool8 sub_80C5DCC(void); +bool8 sub_80C5F98(void); +void ReturnFromHallOfFamePC(void); +u16 SpeciesToPokedexNum(u16 species); +void remove_some_task(void); + +// data and gfx + +static const struct CompressedSpriteSheet sHallOfFame_ConfettiSpriteSheet = +{ + gContestConfetti_Gfx, 0x220, 1001 +}; + +static const u8 sUnused0[8] = {}; + +static const struct CompressedSpritePalette sHallOfFame_ConfettiSpritePalette = +{ + gContestConfetti_Pal, 1001 +}; + +static const u8 sUnused1[8] = {}; + +static const s16 sHallOfFame_MonsFullTeamPositions[6][4] = +{ + {120, 210, 120, 40}, + {326, 220, 56, 40}, + {-86, 220, 184, 40}, + {120, -62, 120, 88}, + {-25, -62, 200, 88}, + {265, -62, 40, 88} +}; + +static const s16 sHallOfFame_MonsHalfTeamPositions[3][4] = +{ + {120, 214, 120, 64}, + {281, 214, 56, 64}, + {-41, 214, 184, 64} +}; + +static const struct HallofFameMon sDummyFameMon = +{ + 0x3EA03EA, 0, 0, 0, {0} +}; + +static const u8 sUnused2[6] = {2, 1, 3, 6, 4, 5}; + +static const struct OamData sOamData_840B598 = +{ + .y = 0, + .affineMode = 0, + .objMode = 0, + .mosaic = 0, + .bpp = 0, + .shape = 0, + .x = 0, + .matrixNum = 0, + .size = 3, + .tileNum = 0, + .priority = 0, + .paletteNum = 0, + .affineParam = 0, +}; + +void* const gUnknown_0840B5A0[] = +{ + &ewram[0x08000], + &ewram[0x0A000], + &ewram[0x0C000], + &ewram[0x0E000], + &ewram[0x10000], + &ewram[0x14000], + &ewram[0x18000] +}; + +static const struct SpriteFrameImage sSpriteImageTable_840B5BC[] = +{ + {&ewram[0x8000], 0x800}, + {&ewram[0x8800], 0x800}, + {&ewram[0x9000], 0x800}, + {&ewram[0x9800], 0x800} +}; + +static const struct SpriteFrameImage sSpriteImageTable_840B5DC[] = +{ + {&ewram[0xA000], 0x800}, + {&ewram[0xA800], 0x800}, + {&ewram[0xB000], 0x800}, + {&ewram[0xB800], 0x800} +}; + +static const struct SpriteFrameImage sSpriteImageTable_840B5FC[] = +{ + {&ewram[0xC000], 0x800}, + {&ewram[0xC800], 0x800}, + {&ewram[0xD000], 0x800}, + {&ewram[0xD800], 0x800} +}; + +static const struct SpriteFrameImage sSpriteImageTable_840B61C[] = +{ + {&ewram[0xE000], 0x800}, + {&ewram[0xE800], 0x800}, + {&ewram[0xF000], 0x800}, + {&ewram[0xF800], 0x800} +}; + +static const struct SpriteFrameImage sSpriteImageTable_840B63C[] = +{ + {&ewram[0x10000], 0x800}, + {&ewram[0x10800], 0x800}, + {&ewram[0x11000], 0x800}, + {&ewram[0x11800], 0x800} +}; + +static const struct SpriteFrameImage sSpriteImageTable_840B65C[] = +{ + {&ewram[0x14000], 0x800}, + {&ewram[0x14800], 0x800}, + {&ewram[0x15000], 0x800}, + {&ewram[0x15800], 0x800} +}; + +static const struct SpriteFrameImage sSpriteImageTable_840B67C[] = +{ + {&ewram[0x18000], 0x800}, + {&ewram[0x18800], 0x800}, + {&ewram[0x19000], 0x800}, + {&ewram[0x19800], 0x800} +}; + +static const struct SpriteFrameImage* const sUnknown_0840B69C[7] = +{ + sSpriteImageTable_840B5BC, + sSpriteImageTable_840B5DC, + sSpriteImageTable_840B5FC, + sSpriteImageTable_840B61C, + sSpriteImageTable_840B63C, + sSpriteImageTable_840B65C, + sSpriteImageTable_840B67C +}; + +static const struct SpriteTemplate sUnknown_0840B6B8 = +{ + .tileTag = -1, + .paletteTag = -1, + .oam = &sOamData_840B598, + .anims = NULL, + .images = sSpriteImageTable_840B5BC, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCB_HallOfFame_Dummy +}; + +static const struct OamData sOamData_840B6D0 = +{ + .y = 0, + .affineMode = 0, + .objMode = 0, + .mosaic = 0, + .bpp = 0, + .shape = 0, + .x = 0, + .matrixNum = 0, + .size = 0, + .tileNum = 0, + .priority = 0, + .paletteNum = 0, + .affineParam = 0, +}; + +static const union AnimCmd sSpriteAnim_840B6D8[] = +{ + ANIMCMD_FRAME(0, 30), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_840B6E0[] = +{ + ANIMCMD_FRAME(1, 30), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_840B6E8[] = +{ + ANIMCMD_FRAME(2, 30), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_840B6F0[] = +{ + ANIMCMD_FRAME(3, 30), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_840B6F8[] = +{ + ANIMCMD_FRAME(4, 30), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_840B700[] = +{ + ANIMCMD_FRAME(5, 30), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_840B708[] = +{ + ANIMCMD_FRAME(6, 30), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_840B710[] = +{ + ANIMCMD_FRAME(7, 30), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_840B718[] = +{ + ANIMCMD_FRAME(8, 30), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_840B720[] = +{ + ANIMCMD_FRAME(9, 30), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_840B728[] = +{ + ANIMCMD_FRAME(10, 30), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_840B730[] = +{ + ANIMCMD_FRAME(11, 30), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_840B738[] = +{ + ANIMCMD_FRAME(12, 30), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_840B740[] = +{ + ANIMCMD_FRAME(13, 30), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_840B748[] = +{ + ANIMCMD_FRAME(14, 30), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_840B750[] = +{ + ANIMCMD_FRAME(15, 30), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_840B758[] = +{ + ANIMCMD_FRAME(16, 30), + ANIMCMD_END +}; + +static const union AnimCmd* const sSpriteAnimTable_840B760[] = +{ + sSpriteAnim_840B6D8, + sSpriteAnim_840B6E0, + sSpriteAnim_840B6E8, + sSpriteAnim_840B6F0, + sSpriteAnim_840B6F8, + sSpriteAnim_840B700, + sSpriteAnim_840B708, + sSpriteAnim_840B710, + sSpriteAnim_840B718, + sSpriteAnim_840B720, + sSpriteAnim_840B728, + sSpriteAnim_840B730, + sSpriteAnim_840B738, + sSpriteAnim_840B740, + sSpriteAnim_840B748, + sSpriteAnim_840B750, + sSpriteAnim_840B758 +}; + +static const struct SpriteTemplate sSpriteTemplate_840B7A4 = +{ + .tileTag = 1001, + .paletteTag = 1001, + .oam = &sOamData_840B6D0, + .anims = sSpriteAnimTable_840B760, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_814386C +}; + +// code + +#define tDisplayedPoke data[1] +#define tPokesNumber data[2] +#define tFrameCount data[3] +#define tPlayerSpriteID data[4] +#define tMonSpriteID(i) data[i + 5] + +static void VBlankCB_HallOfFame(void) +{ + LoadOam(); + ProcessSpriteCopyRequests(); + TransferPlttBuffer(); +} + +static void CB2_HallOfFame(void) +{ + RunTasks(); + AnimateSprites(); + BuildOamBuffer(); + UpdatePaletteFade(); +} + +static bool8 sub_8141E64(void) +{ + switch (gMain.state) + { + case 0: + default: + SetVBlankCallback(NULL); + sub_81433E0(); + gMain.state = 1; + break; + case 1: + sub_8143570(); + gMain.state++; + break; + case 2: + { + u16 saved_IME; + + BeginNormalPaletteFade(-1, 0, 0x10, 0, 0); + SetVBlankCallback(VBlankCB_HallOfFame); + saved_IME = REG_IME; + REG_IME = 0; + REG_IE |= 1; + REG_IME = saved_IME; + REG_DISPSTAT |= 8; + gMain.state++; + } + break; + case 3: + REG_BLDCNT = 0x3F42; + REG_BLDALPHA = 0x710; + REG_BLDY = 0; + sub_81435B8(); + gMain.state++; + break; + case 4: + UpdatePaletteFade(); + if (!gPaletteFade.active) + { + SetMainCallback2(CB2_HallOfFame); + PlayBGM(BGM_DENDOU); + return 0; + } + break; + } + return 1; +} + +void sub_8141F90(void) +{ + if (sub_8141E64() == 0) + { + u8 taskID = CreateTask(sub_8141FF8, 0); + gTasks[taskID].data[0] = 0; + } +} + +static void sub_8141FC4(void) +{ + if (sub_8141E64() == 0) + { + u8 taskID = CreateTask(sub_8141FF8, 0); + gTasks[taskID].data[0] = 1; + } +} + +static void sub_8141FF8(u8 taskID) +{ + u16 i, j; + struct HallofFameMons* fameMons = (struct HallofFameMons*)(&ewram[0x1C000]); + + gTasks[taskID].tPokesNumber = 0; // valid pokes + for (i = 0; i < 6; i++) + { + u8 nick[12]; + if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES)) + { + fameMons->mons[i].species = GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2); + fameMons->mons[i].tid = GetMonData(&gPlayerParty[i], MON_DATA_OT_ID); + fameMons->mons[i].personality = GetMonData(&gPlayerParty[i], MON_DATA_PERSONALITY); + fameMons->mons[i].lvl = GetMonData(&gPlayerParty[i], MON_DATA_LEVEL); + GetMonData(&gPlayerParty[i], MON_DATA_NICKNAME, nick); + for (j = 0; j < 10; j++) + { + fameMons->mons[i].nick[j] = nick[j]; + } + gTasks[taskID].tPokesNumber++; + } + else + { + fameMons->mons[i].species = 0; + fameMons->mons[i].tid = 0; + fameMons->mons[i].personality = 0; + fameMons->mons[i].lvl = 0; + fameMons->mons[i].nick[0] = EOS; + } + } + sUnknown_0203931C = 0; + gTasks[taskID].tDisplayedPoke = 0; + gTasks[taskID].data[4] = 0xFF; + for (i = 0; i < 6; i++) + { + gTasks[taskID].tMonSpriteID(i) = 0xFF; + } + if (gTasks[taskID].data[0]) + gTasks[taskID].func = sub_81422E8; + else + gTasks[taskID].func = sub_814217C; +} + +static void sub_814217C(u8 taskID) +{ + u16 i; + struct HallofFameMons* fameMons = (struct HallofFameMons*)(&ewram[0x1C000]); + struct HallofFameMons* lastSavedTeam = (struct HallofFameMons*)(&ewram[0x1E000]); + + if (gUnknown_02039324 == FALSE) + { + for (i = 0; i < 0x2000; i++) + ewram[i + 0x1E000] = 0; + } + else + sub_8125EC8(3); + + for (i = 0; i < HALL_OF_FAME_MAX_TEAMS; i++, lastSavedTeam++) + { + if (lastSavedTeam->mons[0].species == 0) + break; + } + if (i >= HALL_OF_FAME_MAX_TEAMS) + { + struct HallofFameMons* r5 = (struct HallofFameMons*)(&ewram[0x1E000]); + struct HallofFameMons* r6 = (struct HallofFameMons*)(&ewram[0x1E000]); + r5++; + for (i = 0; i < HALL_OF_FAME_MAX_TEAMS - 1; i++, r6++, r5++) + { + *r6 = *r5; + } + lastSavedTeam--; + } + *lastSavedTeam = *fameMons; + MenuDrawTextWindow(2, 14, 27, 19); + MenuPrint(gMenuText_HOFSaving, 3, 15); + gTasks[taskID].func = sub_8142274; +} + +static void sub_8142274(u8 taskID) +{ + gGameContinueCallback = sub_8141FC4; + TrySavingData(3); + PlaySE(SE_SAVE); + gTasks[taskID].func = sub_81422B8; + gTasks[taskID].tFrameCount = 32; +} + +static void sub_81422B8(u8 taskID) +{ + if (gTasks[taskID].tFrameCount) + gTasks[taskID].tFrameCount--; + else + gTasks[taskID].func = sub_81422E8; +} + +static void sub_81422E8(u8 taskID) +{ + SetUpWindowConfig(&gWindowConfig_81E7198); + InitMenuWindow(&gWindowConfig_81E7198); + gTasks[taskID].func = sub_8142320; +} + +static void sub_8142320(u8 taskID) +{ + u8 spriteID; + s16 xPos, yPos, field4, field6; + + struct HallofFameMons* fameMons = (struct HallofFameMons*)(&ewram[0x1C000]); + u16 currPokeID = gTasks[taskID].tDisplayedPoke; + struct HallofFameMon* currMon = &fameMons->mons[currPokeID]; + + if (gTasks[taskID].tPokesNumber > 3) + { + xPos = sHallOfFame_MonsFullTeamPositions[currPokeID][0]; + yPos = sHallOfFame_MonsFullTeamPositions[currPokeID][1]; + field4 = sHallOfFame_MonsFullTeamPositions[currPokeID][2]; + field6 = sHallOfFame_MonsFullTeamPositions[currPokeID][3]; + } + else + { + xPos = sHallOfFame_MonsHalfTeamPositions[currPokeID][0]; + yPos = sHallOfFame_MonsHalfTeamPositions[currPokeID][1]; + field4 = sHallOfFame_MonsHalfTeamPositions[currPokeID][2]; + field6 = sHallOfFame_MonsHalfTeamPositions[currPokeID][3]; + } + + spriteID = HallOfFame_LoadPokemonPic(currMon->species, xPos, yPos, currPokeID, currMon->tid, currMon->personality); + gSprites[spriteID].data1 = field4; + gSprites[spriteID].data2 = field6; + gSprites[spriteID].data0 = 0; + gSprites[spriteID].callback = sub_81435DC; + gTasks[taskID].tMonSpriteID(currPokeID) = spriteID; + MenuZeroFillWindowRect(0, 14, 29, 19); + gTasks[taskID].func = sub_8142404; +} + +static void sub_8142404(u8 taskID) +{ + struct HallofFameMons* fameMons = (struct HallofFameMons*)(&ewram[0x1C000]); + u16 currPokeID = gTasks[taskID].tDisplayedPoke; + struct HallofFameMon* currMon = &fameMons->mons[currPokeID]; + + if (gSprites[gTasks[taskID].tMonSpriteID(currPokeID)].data0 != 0) + { + if (currMon->species != SPECIES_EGG) + PlayCry1(currMon->species, 0); + HallOfFame_PrintMonInfo(currMon, 0, 14); + gTasks[taskID].tFrameCount = 120; + gTasks[taskID].func = sub_8142484; + } +} + +static void sub_8142484(u8 taskID) +{ + struct HallofFameMons* fameMons = (struct HallofFameMons*)(&ewram[0x1C000]); + u16 currPokeID = gTasks[taskID].tDisplayedPoke; + struct HallofFameMon* currMon = &fameMons->mons[currPokeID]; + + if (gTasks[taskID].tFrameCount != 0) + gTasks[taskID].tFrameCount--; + else + { + sUnknown_0203931C |= (0x10000 << gSprites[gTasks[taskID].tMonSpriteID(currPokeID)].oam.paletteNum); + if (gTasks[taskID].tDisplayedPoke <= 4 && currMon[1].species != 0) // there is another pokemon to display + { + gTasks[taskID].tDisplayedPoke++; + BeginNormalPaletteFade(sUnknown_0203931C, 0, 12, 12, 0x735F); + gSprites[gTasks[taskID].tMonSpriteID(currPokeID)].oam.priority = 1; + gTasks[taskID].func = sub_8142320; + } + else + gTasks[taskID].func = sub_8142570; + } +} + +static void sub_8142570(u8 taskID) +{ + u16 i; + + BeginNormalPaletteFade(0xFFFF0000, 0, 0, 0, 0); + for (i = 0; i < 6; i++) + { + if (gTasks[taskID].tMonSpriteID(i) != 0xFF) + gSprites[gTasks[taskID].tMonSpriteID(i)].oam.priority = 0; + } + MenuZeroFillWindowRect(0, 14, 29, 19); + sub_8143068(0, 15); + PlaySE(SE_DENDOU); + gTasks[taskID].tFrameCount = 400; + gTasks[taskID].func = sub_8142618; +} + +static void sub_8142618(u8 taskID) +{ + if (gTasks[taskID].tFrameCount != 0) + { + gTasks[taskID].tFrameCount--; + if ((gTasks[taskID].tFrameCount & 3) == 0 && gTasks[taskID].tFrameCount > 110) + sub_81438C4(); + } + else + { + u16 i; + for (i = 0; i < 6; i++) + { + if (gTasks[taskID].tMonSpriteID(i) != 0xFF) + gSprites[gTasks[taskID].tMonSpriteID(i)].oam.priority = 1; + } + BeginNormalPaletteFade(sUnknown_0203931C, 0, 12, 12, 0x735F); + MenuZeroFillWindowRect(0, 14, 29, 19); + gTasks[taskID].tFrameCount = 7; + gTasks[taskID].func = sub_81426F8; + } +} + +static void sub_81426F8(u8 taskID) +{ + if (gTasks[taskID].tFrameCount >= 16) + gTasks[taskID].func = sub_8142738; + else + { + gTasks[taskID].tFrameCount++; + REG_BLDALPHA = gTasks[taskID].tFrameCount * 256; + } +} + +static void sub_8142738(u8 taskID) +{ + REG_DISPCNT = 0x1940; + SetUpWindowConfig(&gWindowConfig_81E71B4); + InitMenuWindow(&gWindowConfig_81E71B4); + + gTasks[taskID].tPlayerSpriteID = HallOfFame_LoadTrainerPic(gSaveBlock2.playerGender, 120, 72, 6); + gTasks[taskID].tFrameCount = 120; + gTasks[taskID].func = sub_8142794; +} + +static void sub_8142794(u8 taskID) +{ + if (gTasks[taskID].tFrameCount != 0) + gTasks[taskID].tFrameCount--; + else + { + if (gSprites[gTasks[taskID].tPlayerSpriteID].pos1.x != 160) + gSprites[gTasks[taskID].tPlayerSpriteID].pos1.x++; + else + { + MenuDrawTextWindow(1, 2, 15, 9); + HallOfFame_PrintPlayerInfo(1, 2); + MenuDrawTextWindow(2, 14, 27, 19); + MenuPrint(gMenuText_HOFCongratulations, 4, 15); + gTasks[taskID].func = sub_8142818; + } + } +} + +static void sub_8142818(u8 taskID) +{ + if (gMain.newKeys & A_BUTTON) + { + FadeOutBGM(4); + gTasks[taskID].func = sub_8142850; + } +} + +static void sub_8142850(u8 taskID) +{ + CpuSet(gPlttBufferFaded, gPlttBufferUnfaded, 0x200); + BeginNormalPaletteFade(-1, 8, 0, 0x10, 0); + gTasks[taskID].func = sub_81428A0; +} + +static void sub_81428A0(u8 taskID) +{ + if (!gPaletteFade.active) + { + DestroyTask(taskID); + SetMainCallback2(sub_81439D0); + } +} + +#undef tDisplayedPoke +#undef tPokesNumber +#undef tFrameCount +#undef tPlayerSpriteID +#undef tMonSpriteID + +void sub_81428CC(void) +{ + switch (gMain.state) + { + case 0: + default: + SetVBlankCallback(NULL); + sub_81433E0(); + gMain.state = 1; + break; + case 1: + sub_8143570(); + gMain.state++; + break; + case 2: + { + u16 savedIme; + + SetVBlankCallback(VBlankCB_HallOfFame); + savedIme = REG_IME; + REG_IME = 0; + REG_IE |= 1; + REG_IME = savedIme; + REG_DISPSTAT |= 8; + gMain.state++; + } + break; + case 3: + { + struct HallofFameMons* fameMons; + + REG_BLDCNT = 0; + REG_BLDALPHA = 0; + REG_BLDY = 0; + sub_81435B8(); + + fameMons = (struct HallofFameMons*)(&ewram[0x1C000]); + fameMons->mons[0] = sDummyFameMon; + + sub_80C5CD4(fameMons); + gMain.state++; + } + break; + case 4: + AnimateSprites(); + BuildOamBuffer(); + UpdatePaletteFade(); + if (sub_80C5DCC()) + gMain.state++; + break; + case 5: + REG_BLDCNT = 0x3F42; + REG_BLDALPHA = 0x710; + REG_BLDY = 0; + CreateTask(sub_8142A28, 0); + SetMainCallback2(CB2_HallOfFame); + break; + } +} + +#define tCurrTeamNo data[0] +#define tCurrPageNo data[1] +#define tCurrPokeID data[2] +#define tPokesNo data[4] +#define tMonSpriteID(i) data[i + 5] + +static void sub_8142A28(u8 taskID) +{ + if (sub_8125EC8(3) != 1) + gTasks[taskID].func = sub_8142FEC; + else + { + u16 *vram1, *vram2; + + u16 i; + struct HallofFameMons* savedTeams = (struct HallofFameMons*)(&ewram[0x1E000]); + for (i = 0; i < HALL_OF_FAME_MAX_TEAMS; i++, savedTeams++) + { + if (savedTeams->mons[0].species == 0) + break; + } + if (i < HALL_OF_FAME_MAX_TEAMS) + gTasks[taskID].tCurrTeamNo = i - 1; + else + gTasks[taskID].tCurrTeamNo = HALL_OF_FAME_MAX_TEAMS - 1; + gTasks[taskID].tCurrPageNo = GetGameStat(10); + + for (i = 0, vram1 = (u16*)(VRAM + 0x381A), vram2 = (u16*)(VRAM + 0x385A); i <= 16; i++) + { + *(vram1 + i) = i + 3; + *(vram2 + i) = i + 20; + } + SetUpWindowConfig(&gWindowConfig_81E7198); + InitMenuWindow(&gWindowConfig_81E7198); + gTasks[taskID].func = sub_8142B04; + } +} + +static void sub_8142B04(u8 taskID) +{ + struct HallofFameMons* savedTeams = (struct HallofFameMons*)(&ewram[0x1E000]); + struct HallofFameMon* currMon; + u16 i; + u8* stringPtr; + + for (i = 0; i < gTasks[taskID].tCurrTeamNo; i++) + savedTeams++; + + currMon = &savedTeams->mons[0]; + sUnknown_0203931C = 0; + gTasks[taskID].tCurrPokeID = 0; + gTasks[taskID].tPokesNo = 0; + + for (i = 0; i < 6; i++, currMon++) + { + if (currMon->species != 0) + gTasks[taskID].tPokesNo++; + } + + currMon = &savedTeams->mons[0]; + + for (i = 0; i < 6; i++, currMon++) + { + if (currMon->species != 0) + { + u16 spriteID; + s16 posX, posY; + if (gTasks[taskID].tPokesNo > 3) + { + posX = sHallOfFame_MonsFullTeamPositions[i][2]; + posY = sHallOfFame_MonsFullTeamPositions[i][3]; + } + else + { + posX = sHallOfFame_MonsHalfTeamPositions[i][2]; + posY = sHallOfFame_MonsHalfTeamPositions[i][3]; + } + spriteID = HallOfFame_LoadPokemonPic(currMon->species, posX, posY, i, currMon->tid, currMon->personality); + gSprites[spriteID].oam.priority = 1; + gTasks[taskID].tMonSpriteID(i) = spriteID; + } + else + gTasks[taskID].tMonSpriteID(i) = 0xFF; + } + + BlendPalettes(0xFFFF0000, 0xC, 0x735F); + + stringPtr = gStringVar1; + stringPtr = StringCopy(stringPtr, gMenuText_HOFNumber); + stringPtr[0] = 0xFC; + stringPtr[1] = 0x14; + stringPtr[2] = 0x6; + stringPtr += 3; + stringPtr = ConvertIntToDecimalString(stringPtr, gTasks[taskID].tCurrPageNo); + stringPtr[0] = 0xFC; + stringPtr[1] = 0x13; + stringPtr[2] = 0xF0; + stringPtr[3] = EOS; + MenuPrint(gStringVar1, 0, 0); + + gTasks[taskID].func = sub_8142CC8; +} + +static void sub_8142CC8(u8 taskID) +{ + struct HallofFameMons* savedTeams = (struct HallofFameMons*)(&ewram[0x1E000]); + struct HallofFameMon* currMon; + u16 i; + u16 currMonID; + + for (i = 0; i < gTasks[taskID].tCurrTeamNo; i++) + savedTeams++; + + for (i = 0; i < 6; i++) + { + u16 spriteID = gTasks[taskID].tMonSpriteID(i); + if (spriteID != 0xFF) + gSprites[spriteID].oam.priority = 1; + } + + currMonID = gTasks[taskID].tMonSpriteID(gTasks[taskID].tCurrPokeID); + gSprites[currMonID].oam.priority = 0; + sUnknown_0203931C = (0x10000 << gSprites[currMonID].oam.paletteNum) ^ 0xFFFF0000; + BlendPalettesUnfaded(sUnknown_0203931C, 0xC, 0x735F); + + currMon = &savedTeams->mons[gTasks[taskID].tCurrPokeID]; + if (currMon->species != SPECIES_EGG) + { + StopCryAndClearCrySongs(); + PlayCry1(currMon->species, 0); + } + HallOfFame_PrintMonInfo(currMon, 0, 14); + + gTasks[taskID].func = sub_8142DF4; +} + +static void sub_8142DF4(u8 taskID) +{ + u16 i; + if (gMain.newKeys & A_BUTTON) + { + if (gTasks[taskID].tCurrTeamNo != 0) // prepare another team to view + { + gTasks[taskID].tCurrTeamNo--; + for (i = 0; i < 6; i++) + { + u8 spriteID = gTasks[taskID].tMonSpriteID(i); + if (spriteID != 0xFF) + { + FreeSpritePaletteByTag(GetSpritePaletteTagByPaletteNum(gSprites[spriteID].oam.paletteNum)); + DestroySprite(&gSprites[spriteID]); + } + } + if (gTasks[taskID].tCurrPageNo != 0) + gTasks[taskID].tCurrPageNo--; + gTasks[taskID].func = sub_8142B04; + } + else // no more teams to view, turn off hall of fame PC + { + if (IsCryPlayingOrClearCrySongs()) + { + StopCryAndClearCrySongs(); + m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 0x100); + } + gTasks[taskID].func = sub_8142F78; + } + } + else if (gMain.newKeys & B_BUTTON) // turn off hall of fame PC + { + if (IsCryPlayingOrClearCrySongs()) + { + StopCryAndClearCrySongs(); + m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 0x100); + } + gTasks[taskID].func = sub_8142F78; + } + else if (gMain.newKeys & DPAD_UP && gTasks[taskID].tCurrPokeID != 0) // change poke -1 + { + gTasks[taskID].tCurrPokeID--; + gTasks[taskID].func = sub_8142CC8; + } + else if (gMain.newKeys & DPAD_DOWN && gTasks[taskID].tCurrPokeID < gTasks[taskID].tPokesNo - 1) // change poke +1 + { + gTasks[taskID].tCurrPokeID++; + gTasks[taskID].func = sub_8142CC8; + } +} + +static void sub_8142F78(u8 taskID) +{ + struct HallofFameMons* fameMons; + + CpuSet(gPlttBufferFaded, gPlttBufferUnfaded, 0x200); + fameMons = (struct HallofFameMons*)(&ewram[0x1C000]); + fameMons->mons[0] = sDummyFameMon; + sub_80C5E38(fameMons); + gTasks[taskID].func = sub_8142FCC; +} + +static void sub_8142FCC(u8 taskID) +{ + if (sub_80C5F98()) + { + DestroyTask(taskID); + ReturnFromHallOfFamePC(); + } +} + +static void sub_8142FEC(u8 taskID) +{ + MenuDrawTextWindow(2, 14, 27, 19); + MenuPrintMessage(gMenuText_HOFCorrupt, 3, 15); + gTasks[taskID].func = sub_814302C; +} + +static void sub_814302C(u8 taskID) +{ + if (MenuUpdateWindowText() && gMain.newKeys & A_BUTTON) + gTasks[taskID].func = sub_8142F78; +} + +#undef tCurrTeamNo +#undef tCurrPageNo +#undef tCurrPokeID +#undef tPokesNo +#undef tMonSpriteID + +static void sub_8143068(u8 a0, u8 a1) +{ + sub_8072BD8(gMenuText_WelcomeToHOFAndDexRating, 0, a1 + 1, 0xF0); +} + +static void HallOfFame_PrintMonInfo(struct HallofFameMon* currMon, u8 a1, u8 a2) +{ + u8* stringPtr; + u16 monData; + u16 i; + + stringPtr = gStringVar1; + stringPtr[0] = EXT_CTRL_CODE_BEGIN; + stringPtr[1] = 0x13; + stringPtr[2] = 0x28; + stringPtr[3] = EOS; + + if (currMon->species != SPECIES_EGG) + { + monData = SpeciesToPokedexNum(currMon->species); + if (monData != 0xFFFF) + { + stringPtr = StringCopy(stringPtr, gOtherText_Number2); + ConvertIntToDecimalStringN(stringPtr, monData, 2, 3); + } + } + + MenuPrint(gStringVar1, a1 + 4, a2 + 1); + stringPtr = gStringVar1; + + for (i = 0; i < 10 && currMon->nick[i] != EOS; stringPtr[i] = currMon->nick[i], i++) {} + stringPtr += i; + stringPtr[0] = EOS; + + if (currMon->species == SPECIES_EGG) + { + stringPtr[0] = EXT_CTRL_CODE_BEGIN; + stringPtr[1] = 0x13; + stringPtr[2] = 0xA0; + stringPtr[3] = EOS; + MenuPrint(gStringVar1, a1 + 9, a2 + 1); + MenuZeroFillWindowRect(0, a2 + 3, 29, a2 + 4); + } + else + { + + stringPtr[0] = EXT_CTRL_CODE_BEGIN; + stringPtr[1] = 0x13; + stringPtr[2] = 0x3E; + stringPtr += 3; + + stringPtr[0] = CHAR_SLASH; + stringPtr++; + + for (i = 0; i < 10 && gSpeciesNames[currMon->species][i] != EOS; stringPtr[i] = gSpeciesNames[currMon->species][i], i++) {} + + stringPtr += i; + stringPtr[0] = CHAR_SPACE; + stringPtr++; + + if (currMon->species != SPECIES_NIDORAN_M && currMon->species != SPECIES_NIDORAN_F) + { + switch (GetGenderFromSpeciesAndPersonality(currMon->species, currMon->personality)) + { + case MON_MALE: + stringPtr[0] = CHAR_MALE; + stringPtr++; + break; + case MON_FEMALE: + stringPtr[0] = CHAR_FEMALE; + stringPtr++; + break; + } + } + + stringPtr[0] = EXT_CTRL_CODE_BEGIN; + stringPtr[1] = 0x13; + stringPtr[2] = 0xA0; + stringPtr[3] = EOS; + + MenuPrint(gStringVar1, a1 + 9, a2 + 1); + + monData = currMon->lvl; + + stringPtr = StringCopy(gStringVar1, gOtherText_Level3); + + stringPtr[0] = EXT_CTRL_CODE_BEGIN; + stringPtr[1] = 0x14; + stringPtr[2] = 6; + stringPtr += 3; + + stringPtr = ConvertIntToDecimalStringN(stringPtr, monData, 0, 3); + + stringPtr[0] = EXT_CTRL_CODE_BEGIN; + stringPtr[1] = 0x13; + stringPtr[2] = 0x30; + stringPtr[3] = EOS; + + MenuPrint(gStringVar1, a1 + 7, a2 + 3); + + monData = currMon->tid; + + stringPtr = StringCopy(gStringVar1, gOtherText_IDNumber); + ConvertIntToDecimalStringN(stringPtr, monData, 2, 5); + + MenuPrint(gStringVar1, a1 + 13, a2 + 3); + } +} + +#define ByteRead16(ptr) ((ptr)[0] | ((ptr)[1] << 8)) + +static void HallOfFame_PrintPlayerInfo(u8 a0, u8 a1) +{ + u8* stringPtr; + u16 visibleTid; + + MenuPrint(gOtherText_Name, a0 + 1, a1 + 1); + MenuPrint_RightAligned(gSaveBlock2.playerName, a0 + 14, a1 + 1); + + MenuPrint(gOtherText_IDNumber2, a0 + 1, a1 + 3); + visibleTid = ByteRead16(gSaveBlock2.playerTrainerId); + ConvertIntToDecimalStringN(gStringVar1, visibleTid, 2, 5); + + MenuPrint_RightAligned(gStringVar1, a0 + 14, a1 + 3); + MenuPrint(gMainMenuString_Time, a0 + 1, a1 + 5); + + stringPtr = ConvertIntToDecimalString(gStringVar1, gSaveBlock2.playTimeHours); + stringPtr[0] = CHAR_SPACE; + stringPtr[1] = CHAR_COLON; + stringPtr[2] = CHAR_SPACE; + stringPtr += 3; + + stringPtr = ConvertIntToDecimalStringN(stringPtr, gSaveBlock2.playTimeMinutes, 2, 2); + stringPtr[0] = EOS; + + MenuPrint_RightAligned(gStringVar1, a0 + 14, a1 + 5); +} + +static void sub_81433E0(void) +{ + u32 offsetWrite, offsetWrite2, offsetWrite3, offsetWrite4; + u32 size, size2, size3, size4; + u16 i; + + REG_DISPCNT = 0; + + REG_BG0CNT = 0; + REG_BG0HOFS = 0; + REG_BG0VOFS = 0; + + REG_BG1CNT = 0; + REG_BG1HOFS = 0; + REG_BG1VOFS = 0; + + REG_BG2CNT = 0; + REG_BG2HOFS = 0; + REG_BG2VOFS = 0; + + REG_BG3CNT = 0; + REG_BG3HOFS = 0; + REG_BG3VOFS = 0; + + offsetWrite = (VRAM); + size = 0x18000; + while (TRUE) + { + DmaFill16(3, 0, offsetWrite, 0x1000); + offsetWrite += 0x1000; + size -= 0x1000; + if (size <= 0x1000) + { + DmaFill16(3, 0, offsetWrite, size); + break; + } + } + + offsetWrite2 = OAM; + size2 = OAM_SIZE; + DmaFill32(3, 0, offsetWrite2, size2); + + offsetWrite3 = PLTT; + size3 = PLTT_SIZE; + DmaFill16(3, 0, offsetWrite3, size3); + + LZ77UnCompVram(gHallOfFame_Gfx, (void*)(VRAM)); + + for (i = 0; i < 64; i++) + { + *((u16*)(VRAM + 0x3800) + i) = 1; + } + for (i = 0; i < 192; i++) + { + *((u16*)(VRAM + 0x3B80) + i) = 1; + } + for (i = 0; i < 1024; i++) + { + *((u16*)(VRAM + 0x3000) + i) = 2; + } + + offsetWrite4 = (u32)(&ewram[0]); + size4 = 0x4000; + while (TRUE) + { + DmaFill16(3, 0, offsetWrite4, 0x1000); + offsetWrite4 += 0x1000; + size4 -= 0x1000; + if (size4 <= 0x1000) + { + DmaFill16(3, 0, offsetWrite4, size4); + break; + } + } + + ResetPaletteFade(); + LoadPalette(gHallOfFame_Pal, 0, 0x20); +} + +static void sub_8143570(void) +{ + remove_some_task(); + ResetTasks(); + ResetSpriteData(); + FreeAllSpritePalettes(); + gReservedSpritePaletteCount = 8; + LoadCompressedObjectPic(&sHallOfFame_ConfettiSpriteSheet); + LoadCompressedObjectPalette(&sHallOfFame_ConfettiSpritePalette); + SetUpWindowConfig(&gWindowConfig_81E71B4); + InitMenuWindow(&gWindowConfig_81E71B4); +} + +static void sub_81435B8(void) +{ + REG_BG1CNT = 0x700; + REG_BG3CNT = 0x603; + REG_DISPCNT = 0x1B40; +} + +static void sub_81435DC(struct Sprite* sprite) +{ + u32 spritePos = *(u32*)(&sprite->pos1); + u32 dataPos = *(u32*)(&sprite->data1); + if (spritePos != dataPos) + { + if (sprite->pos1.x < sprite->data1) + sprite->pos1.x += 15; + if (sprite->pos1.x > sprite->data1) + sprite->pos1.x -= 15; + + if (sprite->pos1.y < sprite->data2) + sprite->pos1.y += 10; + if (sprite->pos1.y > sprite->data2) + sprite->pos1.y -= 10; + } + else + { + sprite->data0 = 1; + sprite->callback = SpriteCB_HallOfFame_Dummy; + } +} + +static void SpriteCB_HallOfFame_Dummy(struct Sprite* sprite) +{ + +} + +void sub_8143648(u16 paletteTag, u8 animID) +{ + gUnknown_02024E8C = sUnknown_0840B6B8; + gUnknown_02024E8C.paletteTag = paletteTag; + gUnknown_02024E8C.images = sUnknown_0840B69C[animID]; + gUnknown_02024E8C.anims = gSpriteAnimTable_81E7C64; +} + +void sub_8143680(u16 paletteTag, u8 animID) +{ + gUnknown_02024E8C = sUnknown_0840B6B8; + gUnknown_02024E8C.paletteTag = paletteTag; + gUnknown_02024E8C.images = sUnknown_0840B69C[animID]; + gUnknown_02024E8C.anims = gUnknown_081EC2A4[0]; +} + +static u32 HallOfFame_LoadPokemonPic(u16 species, s16 posX, s16 posY, u16 pokeID, u32 tid, u32 pid) +{ + u8 spriteID; + const u8* pokePal; + + LoadSpecialPokePic(&gMonFrontPicTable[species], gMonFrontPicCoords[species].coords, gMonFrontPicCoords[species].y_offset, 0x2000000, gUnknown_0840B5A0[pokeID], species, pid, 1); + + pokePal = species_and_otid_get_pal(species, tid, pid); + LoadCompressedPalette(pokePal, 16 * pokeID + 256, 0x20); + + sub_8143648(pokeID, pokeID); + spriteID = CreateSprite(&gUnknown_02024E8C, posX, posY, 10 - pokeID); + gSprites[spriteID].oam.paletteNum = pokeID; + return spriteID; +} + +static u32 HallOfFame_LoadTrainerPic(u16 trainerPicID, s16 posX, s16 posY, u16 a3) +{ + u8 spriteID; + + DecompressPicFromTable_2(&gTrainerFrontPicTable[trainerPicID], gTrainerFrontPicCoords[trainerPicID].coords, gTrainerFrontPicCoords[trainerPicID].y_offset, (void*) 0x2000000, gUnknown_0840B5A0[a3], trainerPicID); + + LoadCompressedPalette(gTrainerFrontPicPaletteTable[trainerPicID].data, 16 * a3 + 256, 0x20); + sub_8143680(a3, a3); + + spriteID = CreateSprite(&gUnknown_02024E8C, posX, posY, 1); + gSprites[spriteID].oam.paletteNum = a3; + + return spriteID; +} + +static void sub_814386C(struct Sprite* sprite) +{ + if (sprite->pos2.y > 120) + DestroySprite(sprite); + else + { + u16 rand; + u8 tableID; + + sprite->pos2.y++; + sprite->pos2.y += sprite->data1; + + tableID = sprite->data0; + rand = (Random() % 4) + 8; + sprite->pos2.x = rand * gSineTable[tableID] / 256; + + sprite->data0 += 4; + } +} + +static bool8 sub_81438C4(void) +{ + u8 spriteID; + struct Sprite* sprite; + + s16 posX = Random() % 240; + s16 posY = -(Random() % 8); + + spriteID = CreateSprite(&sSpriteTemplate_840B7A4, posX, posY, 0); + sprite = &gSprites[spriteID]; + + StartSpriteAnim(sprite, Random() % 17); + + if (Random() & 3) + sprite->data1 = 0; + else + sprite->data1 = 1; + + return 0; +} |