diff options
Diffstat (limited to 'src')
92 files changed, 22678 insertions, 3179 deletions
diff --git a/src/bard_music.c b/src/bard_music.c new file mode 100644 index 000000000..ee70f5319 --- /dev/null +++ b/src/bard_music.c @@ -0,0 +1,84 @@ +#include "global.h" +#include "asm.h" + +struct BardSound +{ + u8 pad_00[48]; +}; + +struct UnkBard +{ + /*0x00*/ u8 var00; + /*0x01*/ s8 var01; + /*0x02*/ u16 var02; + /*0x04*/ u16 var04; + /*0x06*/ u16 var06; +}; + +struct UnkBard3 +{ + /*0x00*/ u16 var00; + /*0x02*/ u16 var02; + /*0x04*/ s16 var04; + /*0x06*/ u16 var06; +}; + +struct UnkBard2 +{ + /*0x00*/ u8 var00; + /*0x01*/ u8 var01; + /*0x02*/ u8 var02; + /*0x03*/ u8 var03; + /*0x04*/ u16 var04; + u8 pad06[4]; + /*0x0A*/ u16 var0A; + u8 pad0C[12]; + /*0x18*/ struct UnkBard3 var18[6]; +}; + +extern struct BardSound *gBardMusicTable[]; +extern s16 *gUnknown_08417068[]; +extern u32 gUnknown_084170F4[]; + +static s16 sub_814A2B8(u32 arg0, u32 arg1) +{ + return gUnknown_08417068[arg0][arg1]; +} + +struct BardSound *sub_814A2D0(u16 arg0, u16 arg1) +{ + struct BardSound *sounds = gBardMusicTable[arg0]; + + return &sounds[arg1]; +} + +s32 sub_814A2EC(struct UnkBard2 *dest, struct UnkBard *src, u16 arg2) +{ + s32 i; + s32 j; + s32 thirty; + + for (i = 0; i < 6; i++) + { + dest->var18[i].var00 = src[i].var00; + if (src[i].var00 != 0xFF) + { + s32 r1 = src[i].var01 +gUnknown_084170F4[src[i].var00]; + + dest->var18[i].var02 = r1; + dest->var18[i].var06 = src[i].var04; + dest->var04 += r1; + } + } + + for (j = 0, thirty = 30; j < i; j++) + dest->var18[j].var04 = sub_814A2B8(thirty + arg2, j); + + dest->var00++; + dest->var01 = 0; + dest->var02 = 0; + dest->var03 = 0; + dest->var0A = 0; + + //warning: no return statement in function returning non-void +} diff --git a/src/battle_ai.c b/src/battle_ai.c index 945176b64..e60bf478f 100644 --- a/src/battle_ai.c +++ b/src/battle_ai.c @@ -1,42 +1,39 @@ #include "global.h" #include "battle.h" +#include "asm.h" #include "pokemon.h" #include "rng.h" +#include "abilities.h" #define AIScriptRead32(ptr) ((ptr)[0] | (ptr)[1] << 8 | (ptr)[2] << 16 | (ptr)[3] << 24) #define AIScriptRead16(ptr) ((ptr)[0] | (ptr)[1] << 8) #define AIScriptRead8(ptr) ((ptr)[0]) +#define AIScriptReadPtr(ptr) (u8*) AIScriptRead32(ptr) -/* -this file is a mess. I stopped part way because it starts to involve a huge struct that begins at 0x2000000 and goes -all the way to at least 0x2016800, in addition to extremely hard functions that I can't seem to get right. I am leaving this file -as it currently is until someone bothers to document this huge struct. -*/ +enum +{ + TARGET, + USER +}; -extern u8 sub_8015A98(u8, u8, u8); -extern u8 battle_side_get_owner(u8); -extern s16 battle_get_per_side_status(u8); -extern u8 b_first_side(u8, u8, u8); +extern void move_effectiveness_something(u16, u8, u8); -extern u16 gUnknown_020239F8; +extern u16 gBattleTypeFlags; extern u8 gUnknown_02024A60; -extern u8 gUnknown_02024C07; -extern u8 gUnknown_02024C08; +extern u16 gUnknown_02024BE6; +extern u32 gUnknown_02024BEC; +extern u8 gUnknown_02024C07; // something player? +extern u8 gUnknown_02024C08; // something opponent? extern u8 gUnknown_02024C0C; -extern u16 gUnknown_02024DEC; extern u8 gUnknown_02024C68; -extern u32 gUnknown_02024BEC; -extern u8 gUnknown_0201601C; -extern u8 gUnknown_0201601F; -extern u16 gUnknown_02024BE6; -extern u8 gCritMultiplier; +extern u16 gUnknown_02024DEC; extern u16 gUnknown_02024C34[]; extern u32 gUnknown_02024ACC[]; extern u32 gUnknown_02024C98[]; extern u16 gUnknown_02024C7A[]; extern struct BattlePokemon gUnknown_02024A8C[]; extern u8 gUnknown_030042E0[]; -extern u8 *gAIScriptPtr; +extern u8 gCritMultiplier; extern u16 gTrainerBattleOpponent; extern u32 gBitTable[]; extern u8 *BattleAIs[]; @@ -46,6 +43,15 @@ extern struct BattleMove gBattleMoves[]; extern struct BaseStats gBaseStats[]; extern void (*gBattleAICmdTable[])(void); +/* +gAIScriptPtr is a pointer to the next battle AI cmd command to read. +when a command finishes processing, gAIScriptPtr is incremented by +the number of bytes that the current command had reserved for arguments +in order to read the next command correctly. refer to battle_ai_scripts.s for the +AI scripts. +*/ +extern u8 *gAIScriptPtr; + struct UnknownStruct1 { /* 0x00 */ u16 unk0[2][8]; @@ -55,261 +61,196 @@ struct UnknownStruct1 /* 0x2C */ u8 unk8; }; -struct UnknownStruct2 /* 0x2016800 */ -{ -/* 0x00 */ u8 unk0; -/* 0x01 */ u8 moveConsidered; -/* 0x02 */ u16 unk2; -/* 0x04 */ s8 score[4]; // score? -/* 0x08 */ u32 unk8; -/* 0x0C */ u32 aiFlags; -/* 0x10 */ u8 unk10; -/* 0x11 */ u8 unk11; -/* 0x12 */ u8 filler12[6]; -/* 0x18 */ u8 unk18[4]; -}; - struct UnknownStruct3 { u8 filler0[0x20]; u8 unk20; }; -struct SmallBattleStruct1 -{ - u8 unk1; - u8 unk2; - u8 unk3; - u8 unk4; -}; - -// move to battle.h before PR. -struct BattleStruct /* 0x2000000 */ -{ - u8 filler0[0x1601C]; - struct SmallBattleStruct1 unk; -}; - -extern struct BattleStruct unk_2000000; -extern struct UnknownStruct2 unk_2016800; extern struct UnknownStruct1 unk_2016A00; extern struct UnknownStruct3 unk_2016C00; -void sub_810715C(void); -void sub_8107374(void); +void BattleAI_SetupAIData(void); +void BattleAI_DoAIProcessing(void); void sub_810745C(void); -void sub_81070D4(void) +// if the AI is a Link battle, safari, battle tower, or ereader, it will ignore considering item uses. +void BattleAI_HandleItemUseBeforeAISetup(void) { s32 i; u8 *data = (u8 *)&unk_2016A00; - - for(i = 0; (u32)i < 48; i++) + + for (i = 0; (u32)i < 48; i++) data[i] = 0; - if((gUnknown_020239F8 & 8) && gTrainerBattleOpponent != 0x400 && !(gUnknown_020239F8 & 0x982)) + if ((gBattleTypeFlags & BATTLE_TYPE_TRAINER) + && gTrainerBattleOpponent != 0x400 + && !(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_SAFARI | BATTLE_TYPE_BATTLE_TOWER | BATTLE_TYPE_EREADER_TRAINER))) { - for(i = 0; i < 4; i++) + for (i = 0; i < 4; i++) { - if(gTrainers[gTrainerBattleOpponent].items[i] != 0) + if (gTrainers[gTrainerBattleOpponent].items[i] != 0) { unk_2016A00.items[unk_2016A00.unk8] = gTrainers[gTrainerBattleOpponent].items[i]; unk_2016A00.unk8++; } } } - sub_810715C(); + + BattleAI_SetupAIData(); } -void sub_810715C(void) +void BattleAI_SetupAIData(void) { s32 i; - u8 *data = (u8 *)&unk_2016800; + u8 *data = (u8 *)&gAIThinkingSpace; u8 r7; - + + // clear AI data and set default move score to 100. for(i = 0; (u32)i < 28; i++) data[i] = 0; for(i = 0; i < 4; i++) - unk_2016800.score[i] = 100; + gAIThinkingSpace.score[i] = 100; + r7 = sub_8015A98(gUnknown_02024A60, 0, 0xFF); + for(i = 0; i < 4; i++) { u16 rand; - + if(gBitTable[i] & r7) - unk_2016800.score[i] = 0; + gAIThinkingSpace.score[i] = 0; rand = Random(); - unk_2016800.unk18[i] = 100 - (rand & 0xF); + gAIThinkingSpace.unk18[i] = 100 - (rand & 0xF); } + unk_2016C00.unk20 = 0; gUnknown_02024C07 = gUnknown_02024A60; - - if(gUnknown_020239F8 & 1) + + if(gBattleTypeFlags & BATTLE_TYPE_DOUBLE) { gUnknown_02024C08 = Random() & 2; - + if(gUnknown_02024C0C & gBitTable[gUnknown_02024C08]) gUnknown_02024C08 ^= 2; } else gUnknown_02024C08 = gUnknown_02024A60 ^ 1; - - if(gUnknown_020239F8 & 0x80) - unk_2016800.aiFlags = 0x40000000; - else if(gUnknown_020239F8 & 0x400) - unk_2016800.aiFlags = 0x20000000; - else if(gUnknown_020239F8 & 0x10) - unk_2016800.aiFlags = 0x80000000; - else - unk_2016800.aiFlags = gTrainers[gTrainerBattleOpponent].aiFlags; + + // special AI flag cases. + if(gBattleTypeFlags & BATTLE_TYPE_SAFARI) + gAIThinkingSpace.aiFlags = 0x40000000; + else if(gBattleTypeFlags & BATTLE_TYPE_ROAMER) + gAIThinkingSpace.aiFlags = 0x20000000; + else if(gBattleTypeFlags & BATTLE_TYPE_FIRST_BATTLE) + gAIThinkingSpace.aiFlags = 0x80000000; + else // otherwise, just set aiFlags to whatever flags the trainer has set in their data. + gAIThinkingSpace.aiFlags = gTrainers[gTrainerBattleOpponent].aiFlags; } -u8 sub_81072A8(void) +u8 BattleAI_GetAIActionToUse(void) { u8 arr1[4]; u8 arr2[4]; u8 r5; s32 i; - + sub_810745C(); - while(unk_2016800.aiFlags != 0) + while(gAIThinkingSpace.aiFlags != 0) { - if(unk_2016800.aiFlags & 1) + if(gAIThinkingSpace.aiFlags & 1) { - unk_2016800.unk0 = 0; - sub_8107374(); + gAIThinkingSpace.unk0 = 0; + BattleAI_DoAIProcessing(); } - unk_2016800.aiFlags >>= 1; - unk_2016800.unk11++; - unk_2016800.moveConsidered = 0; + gAIThinkingSpace.aiFlags >>= 1; + gAIThinkingSpace.aiLogicId++; + gAIThinkingSpace.moveConsidered = 0; } - if(unk_2016800.unk10 & 2) + if(gAIThinkingSpace.unk10 & 2) return 4; - if(unk_2016800.unk10 & 4) + if(gAIThinkingSpace.unk10 & 4) return 5; r5 = 1; - arr1[0] = unk_2016800.score[0]; + arr1[0] = gAIThinkingSpace.score[0]; arr2[0] = 0; for(i = 1; i < 4; i++) { - if(arr1[0] < (s8)unk_2016800.score[i]) + if(arr1[0] < (s8)gAIThinkingSpace.score[i]) { r5 = 1; - arr1[0] = unk_2016800.score[i]; + arr1[0] = gAIThinkingSpace.score[i]; arr2[0] = i; } - if(arr1[0] == (s8)unk_2016800.score[i]) + if(arr1[0] == (s8)gAIThinkingSpace.score[i]) { - arr1[r5] = unk_2016800.score[i]; + arr1[r5] = gAIThinkingSpace.score[i]; arr2[r5++] = i; } } return arr2[Random() % r5]; } -void sub_8107374(void) +void BattleAI_DoAIProcessing(void) { - while(unk_2016800.unk0 != 2) + while(gAIThinkingSpace.unk0 != 2) { - switch(unk_2016800.unk0) + switch(gAIThinkingSpace.unk0) { case 3: //Needed to match. break; case 0: - gAIScriptPtr = BattleAIs[unk_2016800.unk11]; - if(gBattleMons[gUnknown_02024C07].pp[unk_2016800.moveConsidered] == 0) + gAIScriptPtr = BattleAIs[gAIThinkingSpace.aiLogicId]; + if(gBattleMons[gUnknown_02024C07].pp[gAIThinkingSpace.moveConsidered] == 0) { - unk_2016800.unk2 = 0; + gAIThinkingSpace.unk2 = 0; } else { - unk_2016800.unk2 = gBattleMons[gUnknown_02024C07].moves[unk_2016800.moveConsidered]; + gAIThinkingSpace.unk2 = gBattleMons[gUnknown_02024C07].moves[gAIThinkingSpace.moveConsidered]; } - unk_2016800.unk0++; + gAIThinkingSpace.unk0++; break; case 1: - if(unk_2016800.unk2 != 0) - gBattleAICmdTable[*(u8 *)gAIScriptPtr](); //weird... + if(gAIThinkingSpace.unk2 != 0) + gBattleAICmdTable[*(u8 *)gAIScriptPtr](); // run AI command. else { - unk_2016800.score[unk_2016800.moveConsidered] = 0; - unk_2016800.unk10 |= 1; + gAIThinkingSpace.score[gAIThinkingSpace.moveConsidered] = 0; + gAIThinkingSpace.unk10 |= 1; } - if(unk_2016800.unk10 & 1) + if(gAIThinkingSpace.unk10 & 1) { - unk_2016800.moveConsidered++; - if(unk_2016800.moveConsidered < 4 && !(unk_2016800.unk10 & 8)) - unk_2016800.unk0 = 0; + gAIThinkingSpace.moveConsidered++; + if(gAIThinkingSpace.moveConsidered < 4 && !(gAIThinkingSpace.unk10 & 8)) + gAIThinkingSpace.unk0 = 0; else - unk_2016800.unk0++; - unk_2016800.unk10 &= 0xFE; + gAIThinkingSpace.unk0++; + gAIThinkingSpace.unk10 &= 0xFE; } break; } } } -#ifdef NONMATCHING void sub_810745C(void) { s32 i; - + for(i = 0; i < 8; i++) { - if(unk_2016A00.unk0[gUnknown_02024C08 / 2][i] == 0) + // this is the same as dividing it by 2, but for some reason, >> 1 is needed to match the asm. + if(unk_2016A00.unk0[gUnknown_02024C08 >> 1][i] == 0) { - //gUnknown_02024C34[gUnknown_02024C08] += 0; - unk_2016A00.unk0[gUnknown_02024C08 / 2][i] = gUnknown_02024C34[gUnknown_02024C08]; + unk_2016A00.unk0[gUnknown_02024C08 >> 1][i] = gUnknown_02024C34[gUnknown_02024C08]; return; } } } -#else -__attribute__((naked)) -void sub_810745C(void) -{ - asm(".syntax unified\n\ - push {r4-r6,lr}\n\ - movs r2, 0\n\ - ldr r3, _08107488 @ =gUnknown_02024C08\n\ - ldr r5, _0810748C @ =0x02016a00\n\ - ldr r6, _08107490 @ =gUnknown_02024C34\n\ - adds r4, r3, 0\n\ -_08107468:\n\ - lsls r0, r2, 1\n\ - ldrb r1, [r4]\n\ - lsrs r1, 1\n\ - lsls r1, 4\n\ - adds r0, r1\n\ - adds r1, r0, r5\n\ - ldrh r0, [r1]\n\ - cmp r0, 0\n\ - bne _08107494\n\ - ldrb r0, [r3]\n\ - lsls r0, 1\n\ - adds r0, r6\n\ - ldrh r0, [r0]\n\ - strh r0, [r1]\n\ - b _0810749A\n\ - .align 2, 0\n\ -_08107488: .4byte gUnknown_02024C08\n\ -_0810748C: .4byte 0x02016a00\n\ -_08107490: .4byte gUnknown_02024C34\n\ -_08107494:\n\ - adds r2, 0x1\n\ - cmp r2, 0x7\n\ - ble _08107468\n\ -_0810749A:\n\ - pop {r4-r6}\n\ - pop {r0}\n\ - bx r0\n\ - .syntax divided"); -} -#endif void unref_sub_81074A0(u8 a) { s32 i; - + for(i = 0; i < 8; i++) unk_2016A00.unk0[a / 2][i] = 0; } @@ -328,363 +269,363 @@ void sub_81074F8(u8 a, u8 b) void BattleAICmd_if_random(void) { - u16 random = Random(); - - if (!(random % 256 >= gAIScriptPtr[1])) // roll a random value. is it less than the parameter of the if_random call? (96 on if_random 80 will return true) - gAIScriptPtr = AIScriptRead32(gAIScriptPtr + 2); - else - gAIScriptPtr += 6; + u16 random = Random(); + + if (!(random % 256 >= gAIScriptPtr[1])) // roll a random value. is it less than the parameter of the if_random call? (96 on if_random 80 will return true) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2); + else + gAIScriptPtr += 6; } void BattleAICmd_if_not_random(void) { - u16 random = Random(); - - if (!(random % 256 <= gAIScriptPtr[1])) // roll a random value. is it greater than the parameter of the if_random call? (96 on if_random 80 will return true) - gAIScriptPtr = AIScriptRead32(gAIScriptPtr + 2); - else - gAIScriptPtr += 6; + u16 random = Random(); + + if (!(random % 256 <= gAIScriptPtr[1])) // roll a random value. is it greater than the parameter of the if_random call? (96 on if_random 80 will return true) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2); + else + gAIScriptPtr += 6; } void BattleAICmd_if_random_1(void) // if RNG Value equal to { - u16 random = Random(); - - if (random % 256 == gAIScriptPtr[1]) // roll a random value. is it greater than the parameter of the if_random call? (96 on if_random 80 will return true) - gAIScriptPtr = AIScriptRead32(gAIScriptPtr + 2); - else - gAIScriptPtr += 6; + u16 random = Random(); + + if (random % 256 == gAIScriptPtr[1]) // roll a random value. is it greater than the parameter of the if_random call? (96 on if_random 80 will return true) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2); + else + gAIScriptPtr += 6; } void BattleAICmd_if_not_random_1(void) // if RNG value not equal to { - u16 random = Random(); - - if (random % 256 != gAIScriptPtr[1]) // roll a random value. is it greater than the parameter of the if_random call? (96 on if_random 80 will return true) - gAIScriptPtr = AIScriptRead32(gAIScriptPtr + 2); - else - gAIScriptPtr += 6; + u16 random = Random(); + + if (random % 256 != gAIScriptPtr[1]) // roll a random value. is it greater than the parameter of the if_random call? (96 on if_random 80 will return true) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2); + else + gAIScriptPtr += 6; } void BattleAICmd_score(void) { - unk_2016800.score[unk_2016800.moveConsidered] += gAIScriptPtr[1]; // add the result to the array of the move consider's score. - - if(unk_2016800.score[unk_2016800.moveConsidered] < 0) // if the score is negative, flatten it to 0. - unk_2016800.score[unk_2016800.moveConsidered] = 0; + gAIThinkingSpace.score[gAIThinkingSpace.moveConsidered] += gAIScriptPtr[1]; // add the result to the array of the move consider's score. - gAIScriptPtr += 2; // AI return. + if(gAIThinkingSpace.score[gAIThinkingSpace.moveConsidered] < 0) // if the score is negative, flatten it to 0. + gAIThinkingSpace.score[gAIThinkingSpace.moveConsidered] = 0; + + gAIScriptPtr += 2; // AI return. } void BattleAICmd_if_hp_less_than(void) { - u16 var; - - if ( gAIScriptPtr[1] == 1 ) - var = gUnknown_02024C07; - else - var = gUnknown_02024C08; - - if ((u32)(100 * gBattleMons[var].hp / gBattleMons[var].maxHP) < gAIScriptPtr[2]) - gAIScriptPtr = AIScriptRead32(gAIScriptPtr + 3); - else - gAIScriptPtr += 7; + u16 var; + + if (gAIScriptPtr[1] == USER) + var = gUnknown_02024C07; + else + var = gUnknown_02024C08; + + if ((u32)(100 * gBattleMons[var].hp / gBattleMons[var].maxHP) < gAIScriptPtr[2]) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 3); + else + gAIScriptPtr += 7; } void BattleAICmd_if_hp_more_than(void) { - u16 var; - - if ( gAIScriptPtr[1] == 1 ) - var = gUnknown_02024C07; - else - var = gUnknown_02024C08; - - if ((u32)(100 * gBattleMons[var].hp / gBattleMons[var].maxHP) > gAIScriptPtr[2]) - gAIScriptPtr = AIScriptRead32(gAIScriptPtr + 3); - else - gAIScriptPtr += 7; + u16 var; + + if (gAIScriptPtr[1] == USER) + var = gUnknown_02024C07; + else + var = gUnknown_02024C08; + + if ((u32)(100 * gBattleMons[var].hp / gBattleMons[var].maxHP) > gAIScriptPtr[2]) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 3); + else + gAIScriptPtr += 7; } void BattleAICmd_if_hp_equal(void) { - u16 var; - - if ( gAIScriptPtr[1] == 1 ) - var = gUnknown_02024C07; - else - var = gUnknown_02024C08; - - if ((u32)(100 * gBattleMons[var].hp / gBattleMons[var].maxHP) == gAIScriptPtr[2]) - gAIScriptPtr = AIScriptRead32(gAIScriptPtr + 3); - else - gAIScriptPtr += 7; + u16 var; + + if (gAIScriptPtr[1] == USER) + var = gUnknown_02024C07; + else + var = gUnknown_02024C08; + + if ((u32)(100 * gBattleMons[var].hp / gBattleMons[var].maxHP) == gAIScriptPtr[2]) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 3); + else + gAIScriptPtr += 7; } void BattleAICmd_if_hp_not_equal(void) { - u16 var; - - if ( gAIScriptPtr[1] == 1 ) - var = gUnknown_02024C07; - else - var = gUnknown_02024C08; - - if ((u32)(100 * gBattleMons[var].hp / gBattleMons[var].maxHP) != gAIScriptPtr[2]) - gAIScriptPtr = AIScriptRead32(gAIScriptPtr + 3); - else - gAIScriptPtr += 7; + u16 var; + + if (gAIScriptPtr[1] == USER) + var = gUnknown_02024C07; + else + var = gUnknown_02024C08; + + if ((u32)(100 * gBattleMons[var].hp / gBattleMons[var].maxHP) != gAIScriptPtr[2]) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 3); + else + gAIScriptPtr += 7; } void BattleAICmd_if_status(void) { - u16 var; - u32 temp; - - if ( gAIScriptPtr[1] == 1 ) - var = gUnknown_02024C07; - else - var = gUnknown_02024C08; - - temp = AIScriptRead32(gAIScriptPtr + 2); - - if (gBattleMons[var].status1 & temp) - gAIScriptPtr = AIScriptRead32(gAIScriptPtr + 6); - else - gAIScriptPtr += 10; + u16 var; + u32 temp; + + if (gAIScriptPtr[1] == USER) + var = gUnknown_02024C07; + else + var = gUnknown_02024C08; + + temp = AIScriptRead32(gAIScriptPtr + 2); + + if (gBattleMons[var].status1 & temp) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 6); + else + gAIScriptPtr += 10; } void BattleAICmd_if_not_status(void) { - u16 var; - u32 temp; - - if ( gAIScriptPtr[1] == 1 ) - var = gUnknown_02024C07; - else - var = gUnknown_02024C08; - - temp = AIScriptRead32(gAIScriptPtr + 2); - - if (!(gBattleMons[var].status1 & temp)) - gAIScriptPtr = AIScriptRead32(gAIScriptPtr + 6); - else - gAIScriptPtr += 10; + u16 var; + u32 temp; + + if (gAIScriptPtr[1] == USER) + var = gUnknown_02024C07; + else + var = gUnknown_02024C08; + + temp = AIScriptRead32(gAIScriptPtr + 2); + + if (!(gBattleMons[var].status1 & temp)) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 6); + else + gAIScriptPtr += 10; } void BattleAICmd_if_status2(void) { - u8 var; - u32 temp; - - if ( gAIScriptPtr[1] == 1 ) - var = gUnknown_02024C07; - else - var = gUnknown_02024C08; - - temp = AIScriptRead32(gAIScriptPtr + 2); - - if (gBattleMons[var].status2 & temp) - gAIScriptPtr = AIScriptRead32(gAIScriptPtr + 6); - else - gAIScriptPtr += 10; + u8 var; + u32 temp; + + if (gAIScriptPtr[1] == USER) + var = gUnknown_02024C07; + else + var = gUnknown_02024C08; + + temp = AIScriptRead32(gAIScriptPtr + 2); + + if (gBattleMons[var].status2 & temp) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 6); + else + gAIScriptPtr += 10; } void BattleAICmd_if_not_status2(void) { - u8 var; - u32 temp; - - if ( gAIScriptPtr[1] == 1 ) - var = gUnknown_02024C07; - else - var = gUnknown_02024C08; - - temp = AIScriptRead32(gAIScriptPtr + 2); - - if (!(gBattleMons[var].status2 & temp)) - gAIScriptPtr = AIScriptRead32(gAIScriptPtr + 6); - else - gAIScriptPtr += 10; + u8 var; + u32 temp; + + if (gAIScriptPtr[1] == USER) + var = gUnknown_02024C07; + else + var = gUnknown_02024C08; + + temp = AIScriptRead32(gAIScriptPtr + 2); + + if (!(gBattleMons[var].status2 & temp)) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 6); + else + gAIScriptPtr += 10; } void BattleAICmd_if_status3(void) { - u8 var; - u32 temp; - - if ( gAIScriptPtr[1] == 1 ) - var = gUnknown_02024C07; - else - var = gUnknown_02024C08; - - temp = AIScriptRead32(gAIScriptPtr + 2); - - if ( gUnknown_02024C98[var] & temp ) - gAIScriptPtr = AIScriptRead32(gAIScriptPtr + 6); - else - gAIScriptPtr += 10; + u8 var; + u32 temp; + + if (gAIScriptPtr[1] == USER) + var = gUnknown_02024C07; + else + var = gUnknown_02024C08; + + temp = AIScriptRead32(gAIScriptPtr + 2); + + if ( gUnknown_02024C98[var] & temp ) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 6); + else + gAIScriptPtr += 10; } void BattleAICmd_if_not_status3(void) { - u8 var; - u32 temp; - - if ( gAIScriptPtr[1] == 1 ) - var = gUnknown_02024C07; - else - var = gUnknown_02024C08; - - temp = AIScriptRead32(gAIScriptPtr + 2); - - if (!(gUnknown_02024C98[var] & temp)) - gAIScriptPtr = AIScriptRead32(gAIScriptPtr + 6); - else - gAIScriptPtr += 10; + u8 var; + u32 temp; + + if (gAIScriptPtr[1] == USER) + var = gUnknown_02024C07; + else + var = gUnknown_02024C08; + + temp = AIScriptRead32(gAIScriptPtr + 2); + + if (!(gUnknown_02024C98[var] & temp)) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 6); + else + gAIScriptPtr += 10; } void BattleAICmd_if_status4(void) { - u8 var; - u32 temp; - u32 temp2; - - if ( gAIScriptPtr[1] == 1 ) - var = gUnknown_02024C07; - else - var = gUnknown_02024C08; - - temp = battle_get_per_side_status(var) & 1; - temp2 = AIScriptRead32(gAIScriptPtr + 2); - - if ( gUnknown_02024C7A[temp] & temp2 ) - gAIScriptPtr = AIScriptRead32(gAIScriptPtr + 6); - else - gAIScriptPtr += 10; + u8 var; + u32 temp; + u32 temp2; + + if (gAIScriptPtr[1] == USER) + var = gUnknown_02024C07; + else + var = gUnknown_02024C08; + + temp = battle_get_per_side_status(var) & 1; + temp2 = AIScriptRead32(gAIScriptPtr + 2); + + if ( gUnknown_02024C7A[temp] & temp2 ) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 6); + else + gAIScriptPtr += 10; } void BattleAICmd_if_not_status4(void) { - u8 var; - u32 temp; - u32 temp2; - - if (gAIScriptPtr[1] == 1) - var = gUnknown_02024C07; - else - var = gUnknown_02024C08; - - temp = battle_get_per_side_status(var) & 1; - temp2 = AIScriptRead32(gAIScriptPtr + 2); - - if (!(gUnknown_02024C7A[temp] & temp2)) - gAIScriptPtr = AIScriptRead32(gAIScriptPtr + 6); - else - gAIScriptPtr += 10; + u8 var; + u32 temp; + u32 temp2; + + if (gAIScriptPtr[1] == USER) + var = gUnknown_02024C07; + else + var = gUnknown_02024C08; + + temp = battle_get_per_side_status(var) & 1; + temp2 = AIScriptRead32(gAIScriptPtr + 2); + + if (!(gUnknown_02024C7A[temp] & temp2)) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 6); + else + gAIScriptPtr += 10; } void BattleAICmd_if_less_than(void) { - if (unk_2016800.unk8 < gAIScriptPtr[1]) - gAIScriptPtr = AIScriptRead32(gAIScriptPtr + 2); - else - gAIScriptPtr += 6; + if (gAIThinkingSpace.unk8 < gAIScriptPtr[1]) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2); + else + gAIScriptPtr += 6; } void BattleAICmd_if_more_than(void) { - if (unk_2016800.unk8 > gAIScriptPtr[1]) - gAIScriptPtr = AIScriptRead32(gAIScriptPtr + 2); - else - gAIScriptPtr += 6; + if (gAIThinkingSpace.unk8 > gAIScriptPtr[1]) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2); + else + gAIScriptPtr += 6; } void BattleAICmd_if_equal(void) { - if (unk_2016800.unk8 == gAIScriptPtr[1]) - gAIScriptPtr = AIScriptRead32(gAIScriptPtr + 2); - else - gAIScriptPtr += 6; + if (gAIThinkingSpace.unk8 == gAIScriptPtr[1]) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2); + else + gAIScriptPtr += 6; } void BattleAICmd_if_not_equal(void) { - if (unk_2016800.unk8 != gAIScriptPtr[1]) - gAIScriptPtr = AIScriptRead32(gAIScriptPtr + 2); - else - gAIScriptPtr += 6; + if (gAIThinkingSpace.unk8 != gAIScriptPtr[1]) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2); + else + gAIScriptPtr += 6; } void BattleAICmd_if_less_than_32(void) { - u8 *temp = AIScriptRead32(gAIScriptPtr + 1); + u8 *temp = AIScriptReadPtr(gAIScriptPtr + 1); - if (unk_2016800.unk8 < *temp) - gAIScriptPtr = AIScriptRead32(gAIScriptPtr + 5); - else - gAIScriptPtr += 9; + if (gAIThinkingSpace.unk8 < *temp) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 5); + else + gAIScriptPtr += 9; } void BattleAICmd_if_more_than_32(void) { - u8 *temp = AIScriptRead32(gAIScriptPtr + 1); + u8 *temp = AIScriptReadPtr(gAIScriptPtr + 1); - if (unk_2016800.unk8 > *temp) - gAIScriptPtr = AIScriptRead32(gAIScriptPtr + 5); - else - gAIScriptPtr += 9; + if (gAIThinkingSpace.unk8 > *temp) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 5); + else + gAIScriptPtr += 9; } void BattleAICmd_if_equal_32(void) { - u8 *temp = AIScriptRead32(gAIScriptPtr + 1); + u8 *temp = AIScriptReadPtr(gAIScriptPtr + 1); - if (unk_2016800.unk8 == *temp) - gAIScriptPtr = AIScriptRead32(gAIScriptPtr + 5); - else - gAIScriptPtr += 9; + if (gAIThinkingSpace.unk8 == *temp) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 5); + else + gAIScriptPtr += 9; } void BattleAICmd_if_not_equal_32(void) { - u8 *temp = AIScriptRead32(gAIScriptPtr + 1); + u8 *temp = AIScriptReadPtr(gAIScriptPtr + 1); - if (unk_2016800.unk8 != *temp) - gAIScriptPtr = AIScriptRead32(gAIScriptPtr + 5); - else - gAIScriptPtr += 9; + if (gAIThinkingSpace.unk8 != *temp) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 5); + else + gAIScriptPtr += 9; } void BattleAICmd_if_move(void) { - u16 move = AIScriptRead16(gAIScriptPtr + 1); + u16 move = AIScriptRead16(gAIScriptPtr + 1); - if (unk_2016800.unk2 == move) - gAIScriptPtr = AIScriptRead32(gAIScriptPtr + 3); - else - gAIScriptPtr += 7; + if (gAIThinkingSpace.unk2 == move) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 3); + else + gAIScriptPtr += 7; } void BattleAICmd_if_not_move(void) { - u16 move = AIScriptRead16(gAIScriptPtr + 1); + u16 move = AIScriptRead16(gAIScriptPtr + 1); - if (unk_2016800.unk2 != move) - gAIScriptPtr = AIScriptRead32(gAIScriptPtr + 3); - else - gAIScriptPtr += 7; + if (gAIThinkingSpace.unk2 != move) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 3); + else + gAIScriptPtr += 7; } void BattleAICmd_if_in_bytes(void) { - u8 *ptr = AIScriptRead32(gAIScriptPtr + 1); - + u8 *ptr = AIScriptReadPtr(gAIScriptPtr + 1); + while(*ptr != 0xFF) { - if(unk_2016800.unk8 == *ptr) + if(gAIThinkingSpace.unk8 == *ptr) { - gAIScriptPtr = AIScriptRead32(gAIScriptPtr + 5); + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 5); return; } ptr++; @@ -694,29 +635,29 @@ void BattleAICmd_if_in_bytes(void) void BattleAICmd_if_not_in_bytes(void) { - u8 *ptr = AIScriptRead32(gAIScriptPtr + 1); - + u8 *ptr = AIScriptReadPtr(gAIScriptPtr + 1); + while(*ptr != 0xFF) { - if(unk_2016800.unk8 == *ptr) + if(gAIThinkingSpace.unk8 == *ptr) { gAIScriptPtr += 9; return; } ptr++; } - gAIScriptPtr = AIScriptRead32(gAIScriptPtr + 5); + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 5); } void BattleAICmd_if_in_words(void) { - u16 *ptr = AIScriptRead32(gAIScriptPtr + 1); - + u16 *ptr = (u16 *)AIScriptReadPtr(gAIScriptPtr + 1); + while(*ptr != 0xFFFF) { - if(unk_2016800.unk8 == *ptr) + if(gAIThinkingSpace.unk8 == *ptr) { - gAIScriptPtr = AIScriptRead32(gAIScriptPtr + 5); + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 5); return; } ptr++; @@ -726,24 +667,24 @@ void BattleAICmd_if_in_words(void) void BattleAICmd_if_not_in_words(void) { - u16 *ptr = AIScriptRead32(gAIScriptPtr + 1); - + u16 *ptr = (u16 *)AIScriptReadPtr(gAIScriptPtr + 1); + while(*ptr != 0xFFFF) { - if(unk_2016800.unk8 == *ptr) + if(gAIThinkingSpace.unk8 == *ptr) { gAIScriptPtr += 9; return; } ptr++; } - gAIScriptPtr = AIScriptRead32(gAIScriptPtr + 5); + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 5); } void BattleAICmd_if_user_can_damage(void) { s32 i; - + for(i = 0; i < 4; i++) { if (gBattleMons[gUnknown_02024C07].moves[i] != 0 @@ -753,13 +694,13 @@ void BattleAICmd_if_user_can_damage(void) if(i == 4) gAIScriptPtr += 5; else - gAIScriptPtr = AIScriptRead32(gAIScriptPtr + 1); + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 1); } void BattleAICmd_if_user_cant_damage(void) { s32 i; - + for(i = 0; i < 4; i++) { if (gBattleMons[gUnknown_02024C07].moves[i] != 0 @@ -769,209 +710,209 @@ void BattleAICmd_if_user_cant_damage(void) if(i != 4) gAIScriptPtr += 5; else - gAIScriptPtr = AIScriptRead32(gAIScriptPtr + 1); + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 1); } void BattleAICmd_unk_21(void) { - unk_2016800.unk8 = gUnknown_030042E0[19]; - gAIScriptPtr += 1; + gAIThinkingSpace.unk8 = gUnknown_030042E0[19]; + gAIScriptPtr += 1; } void BattleAICmd_get_type(void) { - u8 typeVar = gAIScriptPtr[1]; - - switch(typeVar) - { - case 1: - unk_2016800.unk8 = gBattleMons[gUnknown_02024C07].type1; - break; - case 0: - unk_2016800.unk8 = gBattleMons[gUnknown_02024C08].type1; - break; - case 3: - unk_2016800.unk8 = gBattleMons[gUnknown_02024C07].type2; - break; - case 2: - unk_2016800.unk8 = gBattleMons[gUnknown_02024C08].type2; - break; - case 4: - unk_2016800.unk8 = gBattleMoves[unk_2016800.unk2].type; - break; - } - gAIScriptPtr += 2; + u8 typeVar = gAIScriptPtr[1]; + + switch(typeVar) + { + case 1: + gAIThinkingSpace.unk8 = gBattleMons[gUnknown_02024C07].type1; + break; + case 0: + gAIThinkingSpace.unk8 = gBattleMons[gUnknown_02024C08].type1; + break; + case 3: + gAIThinkingSpace.unk8 = gBattleMons[gUnknown_02024C07].type2; + break; + case 2: + gAIThinkingSpace.unk8 = gBattleMons[gUnknown_02024C08].type2; + break; + case 4: + gAIThinkingSpace.unk8 = gBattleMoves[gAIThinkingSpace.unk2].type; + break; + } + gAIScriptPtr += 2; } void BattleAICmd_unk_23(void) { - unk_2016800.unk8 = gBattleMoves[unk_2016800.unk2].power; - gAIScriptPtr += 1; + gAIThinkingSpace.unk8 = gBattleMoves[gAIThinkingSpace.unk2].power; + gAIScriptPtr += 1; } __attribute__((naked)) void BattleAICmd_unk_24(void) { - 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, 0x14\n\ - movs r3, 0\n\ - ldr r0, _08108328 @ =gUnknown_083F62BC\n\ - ldrh r1, [r0]\n\ - ldr r4, _0810832C @ =0x0000ffff\n\ - ldr r6, _08108330 @ =gBattleMoves\n\ - ldr r5, _08108334 @ =0x02016800\n\ - cmp r1, r4\n\ - beq _0810822E\n\ - ldrh r1, [r5, 0x2]\n\ - lsls r0, r1, 1\n\ - adds r0, r1\n\ - lsls r0, 2\n\ - adds r0, r6\n\ - ldrb r2, [r0]\n\ - ldr r1, _08108328 @ =gUnknown_083F62BC\n\ + 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, 0x14\n\ + movs r3, 0\n\ + ldr r0, _08108328 @ =gUnknown_083F62BC\n\ + ldrh r1, [r0]\n\ + ldr r4, _0810832C @ =0x0000ffff\n\ + ldr r6, _08108330 @ =gBattleMoves\n\ + ldr r5, _08108334 @ =0x02016800\n\ + cmp r1, r4\n\ + beq _0810822E\n\ + ldrh r1, [r5, 0x2]\n\ + lsls r0, r1, 1\n\ + adds r0, r1\n\ + lsls r0, 2\n\ + adds r0, r6\n\ + ldrb r2, [r0]\n\ + ldr r1, _08108328 @ =gUnknown_083F62BC\n\ _0810821E:\n\ - ldrh r0, [r1]\n\ - cmp r2, r0\n\ - beq _0810822E\n\ - adds r1, 0x2\n\ - adds r3, 0x1\n\ - ldrh r0, [r1]\n\ - cmp r0, r4\n\ - bne _0810821E\n\ + ldrh r0, [r1]\n\ + cmp r2, r0\n\ + beq _0810822E\n\ + adds r1, 0x2\n\ + adds r3, 0x1\n\ + ldrh r0, [r1]\n\ + cmp r0, r4\n\ + bne _0810821E\n\ _0810822E:\n\ - ldrh r0, [r5, 0x2]\n\ - lsls r1, r0, 1\n\ - adds r1, r0\n\ - lsls r1, 2\n\ - adds r1, r6\n\ - ldrb r0, [r1, 0x1]\n\ - cmp r0, 0x1\n\ - bhi _08108240\n\ - b _081083B2\n\ + ldrh r0, [r5, 0x2]\n\ + lsls r1, r0, 1\n\ + adds r1, r0\n\ + lsls r1, 2\n\ + adds r1, r6\n\ + ldrb r0, [r1, 0x1]\n\ + cmp r0, 0x1\n\ + bhi _08108240\n\ + b _081083B2\n\ _08108240:\n\ - lsls r0, r3, 1\n\ - ldr r1, _08108328 @ =gUnknown_083F62BC\n\ - adds r0, r1\n\ - ldrh r3, [r0]\n\ - ldr r0, _0810832C @ =0x0000ffff\n\ - cmp r3, r0\n\ - beq _08108250\n\ - b _081083B2\n\ + lsls r0, r3, 1\n\ + ldr r1, _08108328 @ =gUnknown_083F62BC\n\ + adds r0, r1\n\ + ldrh r3, [r0]\n\ + ldr r0, _0810832C @ =0x0000ffff\n\ + cmp r3, r0\n\ + beq _08108250\n\ + b _081083B2\n\ _08108250:\n\ - ldr r0, _08108338 @ =gUnknown_02024DEC\n\ - movs r1, 0\n\ - strh r1, [r0]\n\ - ldr r2, _0810833C @ =0xfffff81c\n\ - adds r0, r5, r2\n\ - strb r1, [r0]\n\ - adds r2, 0x3\n\ - adds r0, r5, r2\n\ - movs r2, 0x1\n\ - strb r2, [r0]\n\ - ldr r0, _08108340 @ =gUnknown_02024C68\n\ - strb r1, [r0]\n\ - ldr r0, _08108344 @ =gCritMultiplier\n\ - strb r2, [r0]\n\ - movs r6, 0\n\ - mov r9, r3\n\ - ldr r0, _08108328 @ =gUnknown_083F62BC\n\ - ldrh r0, [r0]\n\ - str r0, [sp, 0x10]\n\ + ldr r0, _08108338 @ =gUnknown_02024DEC\n\ + movs r1, 0\n\ + strh r1, [r0]\n\ + ldr r2, _0810833C @ =0xfffff81c\n\ + adds r0, r5, r2\n\ + strb r1, [r0]\n\ + adds r2, 0x3\n\ + adds r0, r5, r2\n\ + movs r2, 0x1\n\ + strb r2, [r0]\n\ + ldr r0, _08108340 @ =gUnknown_02024C68\n\ + strb r1, [r0]\n\ + ldr r0, _08108344 @ =gCritMultiplier\n\ + strb r2, [r0]\n\ + movs r6, 0\n\ + mov r9, r3\n\ + ldr r0, _08108328 @ =gUnknown_083F62BC\n\ + ldrh r0, [r0]\n\ + str r0, [sp, 0x10]\n\ _08108276:\n\ - movs r3, 0\n\ - ldr r5, _08108348 @ =gBattleMons\n\ - lsls r4, r6, 1\n\ - ldr r7, _0810834C @ =gUnknown_02024C07\n\ - lsls r1, r6, 2\n\ - mov r8, r1\n\ - adds r2, r6, 0x1\n\ - mov r10, r2\n\ - ldr r0, [sp, 0x10]\n\ - cmp r0, r9\n\ - beq _081082BA\n\ - ldr r2, _08108330 @ =gBattleMoves\n\ - ldrb r1, [r7]\n\ - movs r0, 0x58\n\ - muls r0, r1\n\ - adds r0, r4, r0\n\ - adds r1, r5, 0\n\ - adds r1, 0xC\n\ - adds r0, r1\n\ - ldrh r1, [r0]\n\ - lsls r0, r1, 1\n\ - adds r0, r1\n\ - lsls r0, 2\n\ - adds r0, r2\n\ - ldrb r2, [r0]\n\ - ldr r1, _08108328 @ =gUnknown_083F62BC\n\ + movs r3, 0\n\ + ldr r5, _08108348 @ =gBattleMons\n\ + lsls r4, r6, 1\n\ + ldr r7, _0810834C @ =gUnknown_02024C07\n\ + lsls r1, r6, 2\n\ + mov r8, r1\n\ + adds r2, r6, 0x1\n\ + mov r10, r2\n\ + ldr r0, [sp, 0x10]\n\ + cmp r0, r9\n\ + beq _081082BA\n\ + ldr r2, _08108330 @ =gBattleMoves\n\ + ldrb r1, [r7]\n\ + movs r0, 0x58\n\ + muls r0, r1\n\ + adds r0, r4, r0\n\ + adds r1, r5, 0\n\ + adds r1, 0xC\n\ + adds r0, r1\n\ + ldrh r1, [r0]\n\ + lsls r0, r1, 1\n\ + adds r0, r1\n\ + lsls r0, 2\n\ + adds r0, r2\n\ + ldrb r2, [r0]\n\ + ldr r1, _08108328 @ =gUnknown_083F62BC\n\ _081082AA:\n\ - ldrh r0, [r1]\n\ - cmp r2, r0\n\ - beq _081082BA\n\ - adds r1, 0x2\n\ - adds r3, 0x1\n\ - ldrh r0, [r1]\n\ - cmp r0, r9\n\ - bne _081082AA\n\ + ldrh r0, [r1]\n\ + cmp r2, r0\n\ + beq _081082BA\n\ + adds r1, 0x2\n\ + adds r3, 0x1\n\ + ldrh r0, [r1]\n\ + cmp r0, r9\n\ + bne _081082AA\n\ _081082BA:\n\ - ldrb r1, [r7]\n\ - movs r0, 0x58\n\ - muls r0, r1\n\ - adds r0, r4, r0\n\ - adds r1, r5, 0\n\ - adds r1, 0xC\n\ - adds r1, r0, r1\n\ - ldrh r0, [r1]\n\ - cmp r0, 0\n\ - beq _0810835C\n\ - lsls r0, r3, 1\n\ - ldr r2, _08108328 @ =gUnknown_083F62BC\n\ - adds r0, r2\n\ - ldrh r0, [r0]\n\ - cmp r0, r9\n\ - bne _0810835C\n\ - ldr r0, _08108330 @ =gBattleMoves\n\ - ldrh r2, [r1]\n\ - lsls r1, r2, 1\n\ - adds r1, r2\n\ - lsls r1, 2\n\ - adds r1, r0\n\ - ldrb r0, [r1, 0x1]\n\ - cmp r0, 0x1\n\ - bls _0810835C\n\ - ldr r5, _08108350 @ =gUnknown_02024BE6\n\ - strh r2, [r5]\n\ - ldrb r0, [r7]\n\ - ldr r4, _08108354 @ =gUnknown_02024C08\n\ - ldrb r1, [r4]\n\ - bl sub_801CAF8\n\ - ldrh r0, [r5]\n\ - ldrb r1, [r7]\n\ - ldrb r2, [r4]\n\ - bl move_effectiveness_something\n\ - mov r4, sp\n\ - add r4, r8\n\ - ldr r2, _08108358 @ =gUnknown_02024BEC\n\ - ldr r0, _08108334 @ =0x02016800\n\ - adds r0, 0x18\n\ - adds r0, r6, r0\n\ - ldrb r1, [r0]\n\ - ldr r0, [r2]\n\ - muls r0, r1\n\ - movs r1, 0x64\n\ - bl __divsi3\n\ - str r0, [r4]\n\ - cmp r0, 0\n\ - bne _08108364\n\ - movs r0, 0x1\n\ - str r0, [r4]\n\ - b _08108364\n\ - .align 2, 0\n\ + ldrb r1, [r7]\n\ + movs r0, 0x58\n\ + muls r0, r1\n\ + adds r0, r4, r0\n\ + adds r1, r5, 0\n\ + adds r1, 0xC\n\ + adds r1, r0, r1\n\ + ldrh r0, [r1]\n\ + cmp r0, 0\n\ + beq _0810835C\n\ + lsls r0, r3, 1\n\ + ldr r2, _08108328 @ =gUnknown_083F62BC\n\ + adds r0, r2\n\ + ldrh r0, [r0]\n\ + cmp r0, r9\n\ + bne _0810835C\n\ + ldr r0, _08108330 @ =gBattleMoves\n\ + ldrh r2, [r1]\n\ + lsls r1, r2, 1\n\ + adds r1, r2\n\ + lsls r1, 2\n\ + adds r1, r0\n\ + ldrb r0, [r1, 0x1]\n\ + cmp r0, 0x1\n\ + bls _0810835C\n\ + ldr r5, _08108350 @ =gUnknown_02024BE6\n\ + strh r2, [r5]\n\ + ldrb r0, [r7]\n\ + ldr r4, _08108354 @ =gUnknown_02024C08\n\ + ldrb r1, [r4]\n\ + bl sub_801CAF8\n\ + ldrh r0, [r5]\n\ + ldrb r1, [r7]\n\ + ldrb r2, [r4]\n\ + bl move_effectiveness_something\n\ + mov r4, sp\n\ + add r4, r8\n\ + ldr r2, _08108358 @ =gUnknown_02024BEC\n\ + ldr r0, _08108334 @ =0x02016800\n\ + adds r0, 0x18\n\ + adds r0, r6, r0\n\ + ldrb r1, [r0]\n\ + ldr r0, [r2]\n\ + muls r0, r1\n\ + movs r1, 0x64\n\ + bl __divsi3\n\ + str r0, [r4]\n\ + cmp r0, 0\n\ + bne _08108364\n\ + movs r0, 0x1\n\ + str r0, [r4]\n\ + b _08108364\n\ + .align 2, 0\n\ _08108328: .4byte gUnknown_083F62BC\n\ _0810832C: .4byte 0x0000ffff\n\ _08108330: .4byte gBattleMoves\n\ @@ -986,113 +927,113 @@ _08108350: .4byte gUnknown_02024BE6\n\ _08108354: .4byte gUnknown_02024C08\n\ _08108358: .4byte gUnknown_02024BEC\n\ _0810835C:\n\ - mov r1, sp\n\ - add r1, r8\n\ - movs r0, 0\n\ - str r0, [r1]\n\ + mov r1, sp\n\ + add r1, r8\n\ + movs r0, 0\n\ + str r0, [r1]\n\ _08108364:\n\ - mov r6, r10\n\ - cmp r6, 0x3\n\ - ble _08108276\n\ - movs r6, 0\n\ - ldr r1, _081083A4 @ =0x02016800\n\ - ldrb r0, [r1, 0x1]\n\ - lsls r0, 2\n\ - add r0, sp\n\ - ldr r2, [sp]\n\ - ldr r0, [r0]\n\ - adds r5, r1, 0\n\ - ldr r4, _081083A8 @ =gAIScriptPtr\n\ - cmp r2, r0\n\ - bgt _0810839A\n\ - adds r3, r5, 0\n\ - mov r2, sp\n\ + mov r6, r10\n\ + cmp r6, 0x3\n\ + ble _08108276\n\ + movs r6, 0\n\ + ldr r1, _081083A4 @ =0x02016800\n\ + ldrb r0, [r1, 0x1]\n\ + lsls r0, 2\n\ + add r0, sp\n\ + ldr r2, [sp]\n\ + ldr r0, [r0]\n\ + adds r5, r1, 0\n\ + ldr r4, _081083A8 @ =gAIScriptPtr\n\ + cmp r2, r0\n\ + bgt _0810839A\n\ + adds r3, r5, 0\n\ + mov r2, sp\n\ _08108384:\n\ - adds r2, 0x4\n\ - adds r6, 0x1\n\ - cmp r6, 0x3\n\ - bgt _0810839A\n\ - ldrb r0, [r3, 0x1]\n\ - lsls r0, 2\n\ - add r0, sp\n\ - ldr r1, [r2]\n\ - ldr r0, [r0]\n\ - cmp r1, r0\n\ - ble _08108384\n\ + adds r2, 0x4\n\ + adds r6, 0x1\n\ + cmp r6, 0x3\n\ + bgt _0810839A\n\ + ldrb r0, [r3, 0x1]\n\ + lsls r0, 2\n\ + add r0, sp\n\ + ldr r1, [r2]\n\ + ldr r0, [r0]\n\ + cmp r1, r0\n\ + ble _08108384\n\ _0810839A:\n\ - cmp r6, 0x4\n\ - bne _081083AC\n\ - movs r0, 0x2\n\ - str r0, [r5, 0x8]\n\ - b _081083B8\n\ - .align 2, 0\n\ + cmp r6, 0x4\n\ + bne _081083AC\n\ + movs r0, 0x2\n\ + str r0, [r5, 0x8]\n\ + b _081083B8\n\ + .align 2, 0\n\ _081083A4: .4byte 0x02016800\n\ _081083A8: .4byte gAIScriptPtr\n\ _081083AC:\n\ - movs r0, 0x1\n\ - str r0, [r5, 0x8]\n\ - b _081083B8\n\ + movs r0, 0x1\n\ + str r0, [r5, 0x8]\n\ + b _081083B8\n\ _081083B2:\n\ - movs r0, 0\n\ - str r0, [r5, 0x8]\n\ - ldr r4, _081083D0 @ =gAIScriptPtr\n\ + movs r0, 0\n\ + str r0, [r5, 0x8]\n\ + ldr r4, _081083D0 @ =gAIScriptPtr\n\ _081083B8:\n\ - ldr r0, [r4]\n\ - adds r0, 0x1\n\ - str r0, [r4]\n\ - add sp, 0x14\n\ - pop {r3-r5}\n\ - mov r8, r3\n\ - mov r9, r4\n\ - mov r10, r5\n\ - pop {r4-r7}\n\ - pop {r0}\n\ - bx r0\n\ - .align 2, 0\n\ + ldr r0, [r4]\n\ + adds r0, 0x1\n\ + str r0, [r4]\n\ + add sp, 0x14\n\ + pop {r3-r5}\n\ + mov r8, r3\n\ + mov r9, r4\n\ + mov r10, r5\n\ + pop {r4-r7}\n\ + pop {r0}\n\ + bx r0\n\ + .align 2, 0\n\ _081083D0: .4byte gAIScriptPtr\n\ - .syntax divided\n"); + .syntax divided\n"); } void BattleAICmd_get_move(void) { - if ( gAIScriptPtr[1] == 1 ) - unk_2016800.unk8 = gUnknown_02024C34[gUnknown_02024C07]; - else - unk_2016800.unk8 = gUnknown_02024C34[gUnknown_02024C08]; + if (gAIScriptPtr[1] == USER) + gAIThinkingSpace.unk8 = gUnknown_02024C34[gUnknown_02024C07]; + else + gAIThinkingSpace.unk8 = gUnknown_02024C34[gUnknown_02024C08]; - gAIScriptPtr += 2; + gAIScriptPtr += 2; } void BattleAICmd_if_type(void) { - if ( gAIScriptPtr[1] == unk_2016800.unk8 ) - gAIScriptPtr = AIScriptRead32(gAIScriptPtr + 2); - else - gAIScriptPtr += 6; + if ( gAIScriptPtr[1] == gAIThinkingSpace.unk8 ) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2); + else + gAIScriptPtr += 6; } void BattleAICmd_unk_27(void) // if_not_type { - if ( gAIScriptPtr[1] != unk_2016800.unk8 ) - gAIScriptPtr = AIScriptRead32(gAIScriptPtr + 2); - else - gAIScriptPtr += 6; + if ( gAIScriptPtr[1] != gAIThinkingSpace.unk8 ) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2); + else + gAIScriptPtr += 6; } void BattleAICmd_if_would_go_first(void) { - if ( b_first_side(gUnknown_02024C07, gUnknown_02024C08, 1) == gAIScriptPtr[1] ) - gAIScriptPtr = AIScriptRead32(gAIScriptPtr + 2); - else - gAIScriptPtr += 6; + if ( b_first_side(gUnknown_02024C07, gUnknown_02024C08, 1) == gAIScriptPtr[1] ) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2); + else + gAIScriptPtr += 6; } void BattleAICmd_if_would_not_go_first(void) { - if ( b_first_side(gUnknown_02024C07, gUnknown_02024C08, 1) != gAIScriptPtr[1] ) - gAIScriptPtr = AIScriptRead32(gAIScriptPtr + 2); - else - gAIScriptPtr += 6; + if ( b_first_side(gUnknown_02024C07, gUnknown_02024C08, 1) != gAIScriptPtr[1] ) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2); + else + gAIScriptPtr += 6; } void BattleAICmd_unk_2A(void) @@ -1104,470 +1045,339 @@ void BattleAICmd_unk_2B(void) __attribute__((naked)) void BattleAICmd_count_alive_pokemon(void) { - asm(".syntax unified\n\ - push {r4-r7,lr}\n\ - mov r7, r9\n\ - mov r6, r8\n\ - push {r6,r7}\n\ - ldr r1, _08108550 @ =0x02016800\n\ - movs r0, 0\n\ - str r0, [r1, 0x8]\n\ - ldr r0, _08108554 @ =gAIScriptPtr\n\ - ldr r0, [r0]\n\ - ldrb r0, [r0, 0x1]\n\ - cmp r0, 0x1\n\ - bne _0810855C\n\ - ldr r0, _08108558 @ =gUnknown_02024C07\n\ - b _0810855E\n\ - .align 2, 0\n\ + asm(".syntax unified\n\ + push {r4-r7,lr}\n\ + mov r7, r9\n\ + mov r6, r8\n\ + push {r6,r7}\n\ + ldr r1, _08108550 @ =0x02016800\n\ + movs r0, 0\n\ + str r0, [r1, 0x8]\n\ + ldr r0, _08108554 @ =gAIScriptPtr\n\ + ldr r0, [r0]\n\ + ldrb r0, [r0, 0x1]\n\ + cmp r0, 0x1\n\ + bne _0810855C\n\ + ldr r0, _08108558 @ =gUnknown_02024C07\n\ + b _0810855E\n\ + .align 2, 0\n\ _08108550: .4byte 0x02016800\n\ _08108554: .4byte gAIScriptPtr\n\ _08108558: .4byte gUnknown_02024C07\n\ _0810855C:\n\ - ldr r0, _081085A8 @ =gUnknown_02024C08\n\ + ldr r0, _081085A8 @ =gUnknown_02024C08\n\ _0810855E:\n\ - ldrb r5, [r0]\n\ - adds r0, r5, 0\n\ - bl battle_side_get_owner\n\ - lsls r0, 24\n\ - ldr r1, _081085AC @ =gEnemyParty\n\ - mov r9, r1\n\ - cmp r0, 0\n\ - bne _08108574\n\ - ldr r0, _081085B0 @ =gPlayerParty\n\ - mov r9, r0\n\ + ldrb r5, [r0]\n\ + adds r0, r5, 0\n\ + bl battle_side_get_owner\n\ + lsls r0, 24\n\ + ldr r1, _081085AC @ =gEnemyParty\n\ + mov r9, r1\n\ + cmp r0, 0\n\ + bne _08108574\n\ + ldr r0, _081085B0 @ =gPlayerParty\n\ + mov r9, r0\n\ _08108574:\n\ - ldr r0, _081085B4 @ =gUnknown_020239F8\n\ - ldrh r1, [r0]\n\ - movs r0, 0x1\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - beq _081085BC\n\ - ldr r4, _081085B8 @ =gUnknown_02024A6A\n\ - lsls r0, r5, 1\n\ - adds r0, r4\n\ - ldrb r0, [r0]\n\ - mov r8, r0\n\ - adds r0, r5, 0\n\ - bl battle_get_per_side_status\n\ - movs r1, 0x2\n\ - eors r0, r1\n\ - lsls r0, 24\n\ - lsrs r0, 24\n\ - bl battle_get_side_with_given_state\n\ - lsls r0, 24\n\ - lsrs r0, 23\n\ - adds r0, r4\n\ - ldrb r6, [r0]\n\ - b _081085C6\n\ - .align 2, 0\n\ + ldr r0, _081085B4 @ =gBattleTypeFlags\n\ + ldrh r1, [r0]\n\ + movs r0, 0x1\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _081085BC\n\ + ldr r4, _081085B8 @ =gUnknown_02024A6A\n\ + lsls r0, r5, 1\n\ + adds r0, r4\n\ + ldrb r0, [r0]\n\ + mov r8, r0\n\ + adds r0, r5, 0\n\ + bl battle_get_per_side_status\n\ + movs r1, 0x2\n\ + eors r0, r1\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + bl battle_get_side_with_given_state\n\ + lsls r0, 24\n\ + lsrs r0, 23\n\ + adds r0, r4\n\ + ldrb r6, [r0]\n\ + b _081085C6\n\ + .align 2, 0\n\ _081085A8: .4byte gUnknown_02024C08\n\ _081085AC: .4byte gEnemyParty\n\ _081085B0: .4byte gPlayerParty\n\ -_081085B4: .4byte gUnknown_020239F8\n\ +_081085B4: .4byte gBattleTypeFlags\n\ _081085B8: .4byte gUnknown_02024A6A\n\ _081085BC:\n\ - ldr r1, _08108624 @ =gUnknown_02024A6A\n\ - lsls r0, r5, 1\n\ - adds r0, r1\n\ - ldrb r6, [r0]\n\ - mov r8, r6\n\ + ldr r1, _08108624 @ =gUnknown_02024A6A\n\ + lsls r0, r5, 1\n\ + adds r0, r1\n\ + ldrb r6, [r0]\n\ + mov r8, r6\n\ _081085C6:\n\ - movs r5, 0\n\ - ldr r7, _08108628 @ =0x02016800\n\ + movs r5, 0\n\ + ldr r7, _08108628 @ =0x02016800\n\ _081085CA:\n\ - cmp r5, r8\n\ - beq _08108608\n\ - cmp r5, r6\n\ - beq _08108608\n\ - movs r0, 0x64\n\ - muls r0, r5\n\ - mov r1, r9\n\ - adds r4, r1, r0\n\ - adds r0, r4, 0\n\ - movs r1, 0x39\n\ - bl GetMonData\n\ - cmp r0, 0\n\ - beq _08108608\n\ - adds r0, r4, 0\n\ - movs r1, 0x41\n\ - bl GetMonData\n\ - cmp r0, 0\n\ - beq _08108608\n\ - adds r0, r4, 0\n\ - movs r1, 0x41\n\ - bl GetMonData\n\ - movs r1, 0xCE\n\ - lsls r1, 1\n\ - cmp r0, r1\n\ - beq _08108608\n\ - ldr r0, [r7, 0x8]\n\ - adds r0, 0x1\n\ - str r0, [r7, 0x8]\n\ + cmp r5, r8\n\ + beq _08108608\n\ + cmp r5, r6\n\ + beq _08108608\n\ + movs r0, 0x64\n\ + muls r0, r5\n\ + mov r1, r9\n\ + adds r4, r1, r0\n\ + adds r0, r4, 0\n\ + movs r1, 0x39\n\ + bl GetMonData\n\ + cmp r0, 0\n\ + beq _08108608\n\ + adds r0, r4, 0\n\ + movs r1, 0x41\n\ + bl GetMonData\n\ + cmp r0, 0\n\ + beq _08108608\n\ + adds r0, r4, 0\n\ + movs r1, 0x41\n\ + bl GetMonData\n\ + movs r1, 0xCE\n\ + lsls r1, 1\n\ + cmp r0, r1\n\ + beq _08108608\n\ + ldr r0, [r7, 0x8]\n\ + adds r0, 0x1\n\ + str r0, [r7, 0x8]\n\ _08108608:\n\ - adds r5, 0x1\n\ - cmp r5, 0x5\n\ - ble _081085CA\n\ - ldr r1, _0810862C @ =gAIScriptPtr\n\ - ldr r0, [r1]\n\ - adds r0, 0x2\n\ - str r0, [r1]\n\ - pop {r3,r4}\n\ - mov r8, r3\n\ - mov r9, r4\n\ - pop {r4-r7}\n\ - pop {r0}\n\ - bx r0\n\ - .align 2, 0\n\ + adds r5, 0x1\n\ + cmp r5, 0x5\n\ + ble _081085CA\n\ + ldr r1, _0810862C @ =gAIScriptPtr\n\ + ldr r0, [r1]\n\ + adds r0, 0x2\n\ + str r0, [r1]\n\ + pop {r3,r4}\n\ + mov r8, r3\n\ + mov r9, r4\n\ + pop {r4-r7}\n\ + pop {r0}\n\ + bx r0\n\ + .align 2, 0\n\ _08108624: .4byte gUnknown_02024A6A\n\ _08108628: .4byte 0x02016800\n\ _0810862C: .4byte gAIScriptPtr\n\ - .syntax divided"); + .syntax divided"); } void BattleAICmd_unk_2D(void) { - unk_2016800.unk8 = unk_2016800.unk2; - gAIScriptPtr += 1; + gAIThinkingSpace.unk8 = gAIThinkingSpace.unk2; + gAIScriptPtr += 1; } void BattleAICmd_unk_2E(void) { - unk_2016800.unk8 = gBattleMoves[unk_2016800.unk2].effect; - gAIScriptPtr += 1; + gAIThinkingSpace.unk8 = gBattleMoves[gAIThinkingSpace.unk2].effect; + gAIScriptPtr += 1; } void BattleAICmd_get_ability(void) { u8 var; - - if(gAIScriptPtr[1] == 1) + + if(gAIScriptPtr[1] == USER) var = gUnknown_02024C07; else var = gUnknown_02024C08; - if(battle_side_get_owner(var) == 0) + + if(battle_side_get_owner(var) == TARGET) { - //register u8 unk asm("r1") = battle_get_per_side_status(var) & 1; - s32 unk = battle_get_per_side_status(var) & 1; - + u16 unk = battle_get_per_side_status(var) & 1; + if(unk_2016A00.unk20[unk] != 0) { - ((struct UnknownStruct2 *)((u8 *)&unk_2016A00 - 512))->unk8 = unk_2016A00.unk20[unk]; + ((struct AI_ThinkingStruct *)((u8 *)&unk_2016A00 - 512))->unk8 = unk_2016A00.unk20[unk]; gAIScriptPtr += 2; return; } - //_081086C8 - if(gBattleMons[var].ability == 0x17 || gBattleMons[var].ability == 0x2A || gBattleMons[var].ability == 0x47) + + // abilities that prevent fleeing. + if(gBattleMons[var].ability == ABILITY_SHADOW_TAG || gBattleMons[var].ability == ABILITY_MAGNET_PULL || gBattleMons[var].ability == ABILITY_ARENA_TRAP) { - //_081086E4 - unk_2016800.unk8 = gBattleMons[var].ability; + gAIThinkingSpace.unk8 = gBattleMons[var].ability; gAIScriptPtr += 2; return; } - //_081086FC - if(gBaseStats[gBattleMons[var].species].ability1 != 0) + + if(gBaseStats[gBattleMons[var].species].ability1 != ABILITY_NONE) { - if(gBaseStats[gBattleMons[var].species].ability2 != 0) + if(gBaseStats[gBattleMons[var].species].ability2 != ABILITY_NONE) { + // AI is guessing what ability? if(Random() & 1) { - ((struct UnknownStruct2 *)((u8 *)&unk_2016A00 - 512))->unk8 = gBaseStats[gBattleMons[var].species].ability1; + ((struct AI_ThinkingStruct *)((u8 *)&unk_2016A00 - 0x200))->unk8 = gBaseStats[gBattleMons[var].species].ability1; gAIScriptPtr += 2; return; } - //_0810873C else { - ((struct UnknownStruct2 *)((u8 *)&unk_2016A00 - 512))->unk8 = gBaseStats[gBattleMons[var].species].ability2; + ((struct AI_ThinkingStruct *)((u8 *)&unk_2016A00 - 0x200))->unk8 = gBaseStats[gBattleMons[var].species].ability2; gAIScriptPtr += 2; return; } } - //_08108754 else { - ((struct UnknownStruct2 *)((u8 *)&unk_2016A00 - 512))->unk8 = gBaseStats[gBattleMons[var].species].ability1; + ((struct AI_ThinkingStruct *)((u8 *)&unk_2016A00 - 0x200))->unk8 = gBaseStats[gBattleMons[var].species].ability1; // it's definitely ability 1. gAIScriptPtr += 2; return; } } - //_08108764 else { - ((struct UnknownStruct2 *)((u8 *)&unk_2016A00 - 512))->unk8 = gBaseStats[gBattleMons[var].species].ability2; + ((struct AI_ThinkingStruct *)((u8 *)&unk_2016A00 - 0x200))->unk8 = gBaseStats[gBattleMons[var].species].ability2; // AI cant actually reach this part since every mon has at least 1 ability. gAIScriptPtr += 2; return; } } - //_08108774 - unk_2016800.unk8 = gBattleMons[var].ability; - gAIScriptPtr += 2; -} - -// this should probably be in battle.h after this file is fully decompiled. -extern struct -{ - u8 unknownStuff[0x16000]; - struct + else { - u8 filler0[0x1C]; - u8 unk1C; - u8 filler1D[2]; - u8 unk1F; - u8 filler16020[0x7E0]; - } unk_2016000; - struct UnknownStruct2 unk_2016800; -} ewram; //0x02000000 - -#ifdef NONMATCHING -void BattleAICmd_unk_30(void) -{ - s32 loopCounter; - - gUnknown_02024DEC = 0; - ewram.unk_2016000.unk1C = 0; - ewram.unk_2016000.unk1F = 1; - gUnknown_02024C68 = 0; - gCritMultiplier = 1; - ewram.unk_2016800.unk8 = 0; - - for(loopCounter = 0; loopCounter <= 3; loopCounter++) - { - gUnknown_02024BEC = 40; - gUnknown_02024BE6 = gBattleMons[gUnknown_02024C07].moves[loopCounter]; - - if (gUnknown_02024BE6) - { - move_effectiveness_something(gUnknown_02024BE6, gUnknown_02024C07, gUnknown_02024C08); - - // reduce by 1/3. - if (gUnknown_02024BEC == 120) - gUnknown_02024BEC = 80; - if(gUnknown_02024BEC == 240) - gUnknown_02024BEC = 160; - if(gUnknown_02024BEC == 30) - gUnknown_02024BEC = 20; - if(gUnknown_02024BEC == 15) - gUnknown_02024BEC = 10; - - if(gUnknown_02024C68 & 8) - gUnknown_02024BEC = 0; - - if (ewram.unk_2016800.unk8 < gUnknown_02024BEC) - ewram.unk_2016800.unk8 = gUnknown_02024BEC; - } - } - gAIScriptPtr += 1; + // The AI knows its own ability. + gAIThinkingSpace.unk8 = gBattleMons[var].ability; + gAIScriptPtr += 2; + return; + } } -#else -__attribute__((naked)) + void BattleAICmd_unk_30(void) { - asm(".syntax unified\n\ - push {r4-r7,lr}\n\ - mov r7, r8\n\ - push {r7}\n\ - ldr r0, _0810885C @ =gUnknown_02024DEC\n\ - movs r2, 0\n\ - strh r2, [r0]\n\ - ldr r1, _08108860 @ =0x02000000\n\ - ldr r3, _08108864 @ =0x0001601c\n\ - adds r0, r1, r3\n\ - movs r4, 0\n\ - strb r2, [r0]\n\ - adds r3, 0x3\n\ - adds r0, r1, r3\n\ - movs r3, 0x1\n\ - strb r3, [r0]\n\ - ldr r0, _08108868 @ =gUnknown_02024C68\n\ - strb r2, [r0]\n\ - ldr r0, _0810886C @ =gCritMultiplier\n\ - strb r3, [r0]\n\ - movs r0, 0xB4\n\ - lsls r0, 9\n\ - adds r1, r0\n\ - str r4, [r1, 0x8]\n\ - movs r5, 0\n\ - ldr r4, _08108870 @ =gUnknown_02024BEC\n\ - ldr r7, _08108874 @ =gUnknown_02024BE6\n\ - ldr r3, _08108878 @ =gUnknown_02024A8C\n\ - mov r8, r3\n\ - ldr r6, _0810887C @ =gUnknown_02024C07\n\ -_081087DA:\n\ - movs r0, 0x28\n\ - str r0, [r4]\n\ - lsls r1, r5, 1\n\ - ldrb r2, [r6]\n\ - movs r0, 0x58\n\ - muls r0, r2\n\ - adds r1, r0\n\ - add r1, r8\n\ - ldrh r0, [r1]\n\ - strh r0, [r7]\n\ - lsls r0, 16\n\ - cmp r0, 0\n\ - beq _08108844\n\ - ldrh r0, [r7]\n\ - ldrb r1, [r6]\n\ - ldr r2, _08108880 @ =gUnknown_02024C08\n\ - ldrb r2, [r2]\n\ - bl move_effectiveness_something\n\ - ldr r0, [r4]\n\ - cmp r0, 0x78\n\ - bne _0810880A\n\ - movs r0, 0x50\n\ - str r0, [r4]\n\ -_0810880A:\n\ - ldr r0, [r4]\n\ - cmp r0, 0xF0\n\ - bne _08108814\n\ - movs r0, 0xA0\n\ - str r0, [r4]\n\ -_08108814:\n\ - ldr r0, [r4]\n\ - cmp r0, 0x1E\n\ - bne _0810881E\n\ - movs r0, 0x14\n\ - str r0, [r4]\n\ -_0810881E:\n\ - ldr r0, [r4]\n\ - cmp r0, 0xF\n\ - bne _08108828\n\ - movs r0, 0xA\n\ - str r0, [r4]\n\ -_08108828:\n\ - ldr r0, _08108868 @ =gUnknown_02024C68\n\ - ldrb r1, [r0]\n\ - movs r0, 0x8\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - beq _08108838\n\ - movs r0, 0\n\ - str r0, [r4]\n\ -_08108838:\n\ - ldr r2, _08108884 @ =0x02016800\n\ - ldr r0, [r2, 0x8]\n\ - ldr r1, [r4]\n\ - cmp r0, r1\n\ - bcs _08108844\n\ - str r1, [r2, 0x8]\n\ -_08108844:\n\ - adds r5, 0x1\n\ - cmp r5, 0x3\n\ - ble _081087DA\n\ - ldr r1, _08108888 @ =gAIScriptPtr\n\ - ldr r0, [r1]\n\ - adds r0, 0x1\n\ - str r0, [r1]\n\ - pop {r3}\n\ - mov r8, r3\n\ - pop {r4-r7}\n\ - pop {r0}\n\ - bx r0\n\ - .align 2, 0\n\ -_0810885C: .4byte gUnknown_02024DEC\n\ -_08108860: .4byte 0x02000000\n\ -_08108864: .4byte 0x0001601c\n\ -_08108868: .4byte gUnknown_02024C68\n\ -_0810886C: .4byte gCritMultiplier\n\ -_08108870: .4byte gUnknown_02024BEC\n\ -_08108874: .4byte gUnknown_02024BE6\n\ -_08108878: .4byte gUnknown_02024A8C\n\ -_0810887C: .4byte gUnknown_02024C07\n\ -_08108880: .4byte gUnknown_02024C08\n\ -_08108884: .4byte 0x02016800\n\ -_08108888: .4byte gAIScriptPtr\n\ - .syntax divided\n"); + s32 i; + struct AI_ThinkingStruct *ai; + struct AI_ThinkingStruct *ai2; + + gUnknown_02024DEC = 0; + battle_2000000.unk.unk1 = 0; + battle_2000000.unk.unk4 = 1; + gUnknown_02024C68 = 0; + gCritMultiplier = 1; + ai = &battle_2000000.ai; + ai->unk8 = 0; + + for(i = 0; i < 4; i++) + { + gUnknown_02024BEC = 40; + gUnknown_02024BE6 = gBattleMons[gUnknown_02024C07].moves[i]; + + if (gUnknown_02024BE6) + { + move_effectiveness_something(gUnknown_02024BE6, gUnknown_02024C07, gUnknown_02024C08); + + // reduce by 1/3. + if (gUnknown_02024BEC == 120) + gUnknown_02024BEC = 80; + if(gUnknown_02024BEC == 240) + gUnknown_02024BEC = 160; + if(gUnknown_02024BEC == 30) + gUnknown_02024BEC = 20; + if(gUnknown_02024BEC == 15) + gUnknown_02024BEC = 10; + + if(gUnknown_02024C68 & 8) + gUnknown_02024BEC = 0; + + ai2 = &battle_2000000.ai; + if (ai2->unk8 < gUnknown_02024BEC) + ai2->unk8 = gUnknown_02024BEC; + } + } + gAIScriptPtr += 1; } -#endif // same function as above but no for loop. __attribute__((naked)) void BattleAICmd_if_damage_bonus(void) { - asm(".syntax unified\n\ - push {r4,r5,lr}\n\ - ldr r0, _08108928 @ =gUnknown_02024DEC\n\ - movs r1, 0\n\ - strh r1, [r0]\n\ - ldr r2, _0810892C @ =0x02000000\n\ - ldr r3, _08108930 @ =0x0001601c\n\ - adds r0, r2, r3\n\ - strb r1, [r0]\n\ - adds r3, 0x3\n\ - adds r0, r2, r3\n\ - movs r3, 0x1\n\ - strb r3, [r0]\n\ - ldr r5, _08108934 @ =gUnknown_02024C68\n\ - strb r1, [r5]\n\ - ldr r0, _08108938 @ =gCritMultiplier\n\ - strb r3, [r0]\n\ - ldr r4, _0810893C @ =gUnknown_02024BEC\n\ - movs r0, 0x28\n\ - str r0, [r4]\n\ - ldr r1, _08108940 @ =gUnknown_02024BE6\n\ - movs r0, 0xB4\n\ - lsls r0, 9\n\ - adds r2, r0\n\ - ldrh r0, [r2, 0x2]\n\ - strh r0, [r1]\n\ - ldrh r0, [r1]\n\ - ldr r1, _08108944 @ =gUnknown_02024C07\n\ - ldrb r1, [r1]\n\ - ldr r2, _08108948 @ =gUnknown_02024C08\n\ - ldrb r2, [r2]\n\ - bl move_effectiveness_something\n\ - ldr r0, [r4]\n\ - cmp r0, 0x78\n\ - bne _081088D6\n\ - movs r0, 0x50\n\ - str r0, [r4]\n\ + asm(".syntax unified\n\ + push {r4,r5,lr}\n\ + ldr r0, _08108928 @ =gUnknown_02024DEC\n\ + movs r1, 0\n\ + strh r1, [r0]\n\ + ldr r2, _0810892C @ =0x02000000\n\ + ldr r3, _08108930 @ =0x0001601c\n\ + adds r0, r2, r3\n\ + strb r1, [r0]\n\ + adds r3, 0x3\n\ + adds r0, r2, r3\n\ + movs r3, 0x1\n\ + strb r3, [r0]\n\ + ldr r5, _08108934 @ =gUnknown_02024C68\n\ + strb r1, [r5]\n\ + ldr r0, _08108938 @ =gCritMultiplier\n\ + strb r3, [r0]\n\ + ldr r4, _0810893C @ =gUnknown_02024BEC\n\ + movs r0, 0x28\n\ + str r0, [r4]\n\ + ldr r1, _08108940 @ =gUnknown_02024BE6\n\ + movs r0, 0xB4\n\ + lsls r0, 9\n\ + adds r2, r0\n\ + ldrh r0, [r2, 0x2]\n\ + strh r0, [r1]\n\ + ldrh r0, [r1]\n\ + ldr r1, _08108944 @ =gUnknown_02024C07\n\ + ldrb r1, [r1]\n\ + ldr r2, _08108948 @ =gUnknown_02024C08\n\ + ldrb r2, [r2]\n\ + bl move_effectiveness_something\n\ + ldr r0, [r4]\n\ + cmp r0, 0x78\n\ + bne _081088D6\n\ + movs r0, 0x50\n\ + str r0, [r4]\n\ _081088D6:\n\ - ldr r0, [r4]\n\ - cmp r0, 0xF0\n\ - bne _081088E0\n\ - movs r0, 0xA0\n\ - str r0, [r4]\n\ + ldr r0, [r4]\n\ + cmp r0, 0xF0\n\ + bne _081088E0\n\ + movs r0, 0xA0\n\ + str r0, [r4]\n\ _081088E0:\n\ - ldr r0, [r4]\n\ - cmp r0, 0x1E\n\ - bne _081088EA\n\ - movs r0, 0x14\n\ - str r0, [r4]\n\ + ldr r0, [r4]\n\ + cmp r0, 0x1E\n\ + bne _081088EA\n\ + movs r0, 0x14\n\ + str r0, [r4]\n\ _081088EA:\n\ - ldr r0, [r4]\n\ - cmp r0, 0xF\n\ - bne _081088F4\n\ - movs r0, 0xA\n\ - str r0, [r4]\n\ + ldr r0, [r4]\n\ + cmp r0, 0xF\n\ + bne _081088F4\n\ + movs r0, 0xA\n\ + str r0, [r4]\n\ _081088F4:\n\ - ldrb r1, [r5]\n\ - movs r0, 0x8\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - beq _08108902\n\ - movs r0, 0\n\ - str r0, [r4]\n\ + ldrb r1, [r5]\n\ + movs r0, 0x8\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _08108902\n\ + movs r0, 0\n\ + str r0, [r4]\n\ _08108902:\n\ - ldrb r0, [r4]\n\ - ldr r3, _0810894C @ =gAIScriptPtr\n\ - ldr r2, [r3]\n\ - ldrb r1, [r2, 0x1]\n\ - cmp r0, r1\n\ - bne _08108950\n\ - ldrb r1, [r2, 0x2]\n\ - ldrb r0, [r2, 0x3]\n\ - lsls r0, 8\n\ - orrs r1, r0\n\ - ldrb r0, [r2, 0x4]\n\ - lsls r0, 16\n\ - orrs r1, r0\n\ - ldrb r0, [r2, 0x5]\n\ - lsls r0, 24\n\ - orrs r1, r0\n\ - str r1, [r3]\n\ - b _08108954\n\ - .align 2, 0\n\ + ldrb r0, [r4]\n\ + ldr r3, _0810894C @ =gAIScriptPtr\n\ + ldr r2, [r3]\n\ + ldrb r1, [r2, 0x1]\n\ + cmp r0, r1\n\ + bne _08108950\n\ + ldrb r1, [r2, 0x2]\n\ + ldrb r0, [r2, 0x3]\n\ + lsls r0, 8\n\ + orrs r1, r0\n\ + ldrb r0, [r2, 0x4]\n\ + lsls r0, 16\n\ + orrs r1, r0\n\ + ldrb r0, [r2, 0x5]\n\ + lsls r0, 24\n\ + orrs r1, r0\n\ + str r1, [r3]\n\ + b _08108954\n\ + .align 2, 0\n\ _08108928: .4byte gUnknown_02024DEC\n\ _0810892C: .4byte 0x02000000\n\ _08108930: .4byte 0x0001601c\n\ @@ -1579,13 +1389,13 @@ _08108944: .4byte gUnknown_02024C07\n\ _08108948: .4byte gUnknown_02024C08\n\ _0810894C: .4byte gAIScriptPtr\n\ _08108950:\n\ - adds r0, r2, 0x6\n\ - str r0, [r3]\n\ + adds r0, r2, 0x6\n\ + str r0, [r3]\n\ _08108954:\n\ - pop {r4,r5}\n\ - pop {r0}\n\ - bx r0\n\ - .syntax divided\n"); + pop {r4,r5}\n\ + pop {r0}\n\ + bx r0\n\ + .syntax divided\n"); } void BattleAICmd_unk_32(void) diff --git a/src/battle_anim_80A7E7C.c b/src/battle_anim_80A7E7C.c new file mode 100644 index 000000000..2c7a10be5 --- /dev/null +++ b/src/battle_anim_80A7E7C.c @@ -0,0 +1,777 @@ +#include "global.h" +#include "task.h" +#include "sprite.h" +#include "trig.h" + +#define TASK gTasks[task] +#define SPRITE gSprites[TASK.data[0]] + +extern s16 gBattleAnimArgs[8]; + +extern u8 gUnknown_02024BE0[]; +extern s32 gUnknown_0202F7B8; +extern u16 gUnknown_0202F7BC; +extern u8 gUnknown_0202F7C8; +extern u8 gUnknown_0202F7C9; + +extern u8 obj_id_for_side_relative_to_move(u8 side); +extern void move_anim_task_del(u8 task); +extern bool8 b_side_obj__get_some_boolean(u8 side); +extern u8 battle_get_side_with_given_state(u8 state); +extern u8 battle_side_get_owner(u8 side); +extern void oamt_set_x3A_32(struct Sprite *sprite, void (*callback)(struct Sprite*)); +extern void sub_8078458(struct Sprite *sprite); +extern void move_anim_8072740(struct Sprite *sprite); +extern void sub_8078A5C(struct Sprite *sprite); +extern void sub_80784A8(struct Sprite *sprite); +extern void sub_8078E70(u8 sprite, u8); +extern void obj_id_set_rotscale(u8 sprite, int, int, u16); +extern void sub_8078F40(u8 sprite); +extern bool8 sub_8076BE0(); +extern void sub_8078F9C(u8 sprite); + +static void sub_80A7EF0(u8 task); +static void sub_80A808C(u8 task); +static void sub_80A81D8(u8 task); +static void sub_80A8374(u8 task); +static void sub_80A8488(u8 task); +static void sub_80A85A4(struct Sprite *sprite); +void sub_80A8614(struct Sprite* sprite); +static void sub_80A86F4(struct Sprite *sprite); +static void sub_80A88F0(struct Sprite *sprite); +static void sub_80A89B4(u8 task); +static void sub_80A8A18(u8 task); +static void sub_80A8C0C(u8 task); +static void sub_80A8D8C(u8 task); +void sub_80A8FD8(u8 task); +static void sub_80A913C(u8 taskId); + +void sub_80A7E7C(u8 task) { + u8 sprite; + sprite = obj_id_for_side_relative_to_move(gBattleAnimArgs[0]); + if (sprite == 0xff) { + move_anim_task_del(task); + return; + } + gSprites[sprite].pos2.x = gBattleAnimArgs[1]; + gSprites[sprite].pos2.y = gBattleAnimArgs[2]; + TASK.data[0] = sprite; + TASK.data[1] = gBattleAnimArgs[3]; + TASK.data[2] = gBattleAnimArgs[4]; + TASK.data[3] = gBattleAnimArgs[4]; + TASK.data[4] = gBattleAnimArgs[1]; + TASK.data[5] = gBattleAnimArgs[2]; + TASK.func = sub_80A7EF0; + sub_80A7EF0(task); +} + +static void sub_80A7EF0(u8 task) { + if (TASK.data[3] == 0) { + if (SPRITE.pos2.x == 0) { + SPRITE.pos2.x = TASK.data[4]; + } else { + SPRITE.pos2.x = 0; + } + if (SPRITE.pos2.y == 0) { + SPRITE.pos2.y = TASK.data[5]; + } else { + SPRITE.pos2.y = 0; + } + TASK.data[3] = TASK.data[2]; + if (--TASK.data[1] == 0) { + SPRITE.pos2.x = 0; + SPRITE.pos2.y = 0; + move_anim_task_del(task); + return; + } + } else { + TASK.data[3]--; + } +} + + +void sub_80A7FA0(u8 task) { + u8 sprite; + bool8 r6; + u8 side; + r6 = 0; + if (gBattleAnimArgs[0] < 4) { + sprite = obj_id_for_side_relative_to_move(gBattleAnimArgs[0]); + if (sprite == 0xff) { + move_anim_task_del(task); + return; + } + } else if (gBattleAnimArgs[0] != 8) { + switch (gBattleAnimArgs[0]) { + case 4: + side = battle_get_side_with_given_state(0); + break; + case 5: + side = battle_get_side_with_given_state(2); + break; + case 6: + side = battle_get_side_with_given_state(1); + break; + case 7: + default: + side = battle_get_side_with_given_state(3); + break; + } + if (b_side_obj__get_some_boolean(side) == FALSE) { + r6 = 1; + } + sprite = gUnknown_02024BE0[side]; + } else { + sprite = gUnknown_02024BE0[gUnknown_0202F7C8]; + } + if (r6) { + move_anim_task_del(task); + return; + } + gSprites[sprite].pos2.x = gBattleAnimArgs[1]; + gSprites[sprite].pos2.y = gBattleAnimArgs[2]; + TASK.data[0] = sprite; + TASK.data[1] = gBattleAnimArgs[3]; + TASK.data[2] = gBattleAnimArgs[4]; + TASK.data[3] = gBattleAnimArgs[4]; + TASK.data[4] = gBattleAnimArgs[1]; + TASK.data[5] = gBattleAnimArgs[2]; + TASK.func = sub_80A808C; + sub_80A808C(task); +} + +static void sub_80A808C(u8 task) { + if (TASK.data[3] == 0) { + if (SPRITE.pos2.x == TASK.data[4]) { + SPRITE.pos2.x = -TASK.data[4]; + } else { + SPRITE.pos2.x = TASK.data[4]; + } + if (SPRITE.pos2.y == TASK.data[5]) { + SPRITE.pos2.y = -TASK.data[5]; + } else { + SPRITE.pos2.y = TASK.data[5]; + } + TASK.data[3] = TASK.data[2]; + if (--TASK.data[1] == 0) { + SPRITE.pos2.x = 0; + SPRITE.pos2.y = 0; + move_anim_task_del(task); + return; + } + } else { + TASK.data[3]--; + } +} + +void sub_80A8154(u8 task) { + u8 sprite; + sprite = obj_id_for_side_relative_to_move(gBattleAnimArgs[0]); + if (sprite == 0xff) { + move_anim_task_del(task); + return; + } + gSprites[sprite].pos2.x += gBattleAnimArgs[1]; + gSprites[sprite].pos2.y += gBattleAnimArgs[2]; + TASK.data[0] = sprite; + TASK.data[1] = 0; + TASK.data[2] = gBattleAnimArgs[3]; + TASK.data[3] = 0; + TASK.data[4] = gBattleAnimArgs[4]; + TASK.data[5] = gBattleAnimArgs[1] * 2; + TASK.data[6] = gBattleAnimArgs[2] * 2; + TASK.func = sub_80A81D8; + sub_80A81D8(task); +} + +static void sub_80A81D8(u8 task) { + if (TASK.data[3] == 0) { + if (TASK.data[1] & 1) { + SPRITE.pos2.x += TASK.data[5]; + SPRITE.pos2.y += TASK.data[6]; + } else { + SPRITE.pos2.x -= TASK.data[5]; + SPRITE.pos2.y -= TASK.data[6]; + } + TASK.data[3] = TASK.data[4]; + if (++TASK.data[1] >= TASK.data[2]) { + if (TASK.data[1] & 1) { + SPRITE.pos2.x += TASK.data[5] / 2; + SPRITE.pos2.y += TASK.data[6] / 2; + } else { + SPRITE.pos2.x -= TASK.data[5] / 2; + SPRITE.pos2.y -= TASK.data[6] / 2; + } + move_anim_task_del(task); + return; + } + } else { + TASK.data[3]--; + } +} + +void sub_80A8314(u8 task) { + u8 sprite = obj_id_for_side_relative_to_move(gBattleAnimArgs[0]); + gSprites[sprite].pos2.x = gBattleAnimArgs[1]; + TASK.data[0] = sprite; + TASK.data[1] = gBattleAnimArgs[1]; + TASK.data[2] = gBattleAnimArgs[2]; + TASK.data[3] = gBattleAnimArgs[3]; + TASK.data[4] = gBattleAnimArgs[4]; + TASK.func = sub_80A8374; + sub_80A8374(task); +} + +static void sub_80A8374(u8 task) { + s16 x; + u8 sprite; + sprite = TASK.data[0]; + x = TASK.data[1]; + if (TASK.data[2] == TASK.data[8]++) { + TASK.data[8] = 0; + if (gSprites[sprite].pos2.x == x) { + x = -x; + } + gSprites[sprite].pos2.x += x; + } + TASK.data[1] = x; + TASK.data[9] += TASK.data[3]; + gSprites[sprite].pos2.y = TASK.data[9] >> 8; + if (--TASK.data[4] == 0) { + move_anim_task_del(task); + return; + } +} + +void sub_80A8408(u8 task) { + u8 i; + u8 sprite; + u8 v1; + v1 = 1; + sprite = obj_id_for_side_relative_to_move(gBattleAnimArgs[0]); + if (gBattleAnimArgs[4] > 5) { + gBattleAnimArgs[4] = 5; + } + for (i = 0; i < gBattleAnimArgs[4]; i++) { + v1 <<= 1; + } + TASK.data[0] = sprite; + TASK.data[1] = gBattleAnimArgs[1]; + TASK.data[2] = gBattleAnimArgs[2]; + TASK.data[3] = gBattleAnimArgs[3]; + TASK.data[4] = v1; + TASK.func = sub_80A8488; + sub_80A8488(task); +} + +static void sub_80A8488(u8 task) { + u8 sprite; + sprite = TASK.data[0]; + gSprites[sprite].pos2.x = Sin(TASK.data[5], TASK.data[1]); + gSprites[sprite].pos2.y = -Cos(TASK.data[5], TASK.data[2]); + gSprites[sprite].pos2.y += TASK.data[2]; + TASK.data[5] += TASK.data[4]; + TASK.data[5] &= 0xff; + if (TASK.data[5] == 0) { + TASK.data[3]--; + } + if (TASK.data[3] == 0) { + gSprites[sprite].pos2.x = 0; + gSprites[sprite].pos2.y = 0; + move_anim_task_del(task); + return; + } +} + +void sub_80A8500(u8 task) { + if (battle_side_get_owner(gUnknown_0202F7C8)) { + gBattleAnimArgs[1] = -gBattleAnimArgs[1]; + } + sub_80A8408(task); +} + +void sub_80A8530(struct Sprite *sprite) { + sprite->invisible = TRUE; + if (battle_side_get_owner(gUnknown_0202F7C8)) { + sprite->data1 = -gBattleAnimArgs[1]; + } else { + sprite->data1 = gBattleAnimArgs[1]; + } + sprite->data0 = gBattleAnimArgs[0]; + sprite->data2 = 0; + sprite->data3 = gUnknown_02024BE0[gUnknown_0202F7C8]; + sprite->data4 = gBattleAnimArgs[0]; + oamt_set_x3A_32(sprite, sub_80A85A4); + sprite->callback = sub_8078458; +} + +static void sub_80A85A4(struct Sprite *sprite) { + sprite->data0 = sprite->data4; + sprite->data1 = -sprite->data1; + sprite->callback = sub_8078458; + oamt_set_x3A_32(sprite, move_anim_8072740); +} + +void sub_80A85C8(struct Sprite *sprite) { + u8 spriteId; + sprite->invisible = TRUE; + spriteId = obj_id_for_side_relative_to_move(gBattleAnimArgs[2]); + sprite->data0 = gBattleAnimArgs[0]; + sprite->data1 = 0; + sprite->data2 = gBattleAnimArgs[1]; + sprite->data3 = spriteId; + sprite->data4 = gBattleAnimArgs[0]; + oamt_set_x3A_32(sprite, sub_80A8614); + sprite->callback = sub_8078458; +} + +void sub_80A8614(struct Sprite *sprite) { + sprite->data0 = sprite->data4; + sprite->data2 = -sprite->data2; + sprite->callback = sub_8078458; + oamt_set_x3A_32(sprite, move_anim_8072740); +} + +void sub_80A8638(struct Sprite *sprite) { + int something; + int spriteId; + if (!gBattleAnimArgs[0]) { + spriteId = gUnknown_02024BE0[gUnknown_0202F7C8]; + } else { + spriteId = gUnknown_02024BE0[gUnknown_0202F7C9]; + } + sprite->data0 = gBattleAnimArgs[2]; + sprite->data1 = gSprites[spriteId].pos1.x + gSprites[spriteId].pos2.x; + sprite->data2 = gSprites[spriteId].pos1.x; + sprite->data3 = gSprites[spriteId].pos1.y + gSprites[spriteId].pos2.y; + sprite->data4 = gSprites[spriteId].pos1.y; + something = 0; + sub_8078A5C(sprite); + sprite->data3 = something; + sprite->data4 = something; + sprite->data5 = gSprites[spriteId].pos2.x; + sprite->data6 = gSprites[spriteId].pos2.y; + sprite->invisible = TRUE; + if (gBattleAnimArgs[1] == 1) { + sprite->data2 = something; + } else if (gBattleAnimArgs[1] == 2) { + sprite->data1 = something; + } + sprite->data7 = gBattleAnimArgs[1]; + sprite->data7 |= spriteId << 8; + sprite->callback = sub_80A86F4; +} + +static void sub_80A86F4(struct Sprite *sprite) { + s8 spriteId; + u8 lo; + struct Sprite *sprite2; + lo = sprite->data7 & 0xff; + spriteId = sprite->data7 >> 8; + sprite2 = &gSprites[spriteId]; + if (sprite->data0 == 0) { + if (lo < 2) { + sprite2->pos2.x = 0; + } + if (lo == 2 || lo == 0) { + sprite2->pos2.y = 0; + } + move_anim_8072740(sprite); + } else { + sprite->data0--; + sprite->data3 += sprite->data1; + sprite->data4 += sprite->data2; + sprite2->pos2.x = (s8)(sprite->data3 >> 8) + sprite->data5; + sprite2->pos2.y = (s8)(sprite->data4 >> 8) + sprite->data6; + } +} + +void sub_80A8764(struct Sprite *sprite) { + u8 v1; + u8 spriteId; + if (!gBattleAnimArgs[0]) { + v1 = gUnknown_0202F7C8; + } else { + v1 = gUnknown_0202F7C9; + } + spriteId = gUnknown_02024BE0[v1]; + if (battle_side_get_owner(v1)) { + gBattleAnimArgs[1] = -gBattleAnimArgs[1]; + if (gBattleAnimArgs[3] == 1) { + gBattleAnimArgs[2] = -gBattleAnimArgs[2]; + } + } + sprite->data0 = gBattleAnimArgs[4]; + sprite->data1 = gSprites[spriteId].pos1.x; + sprite->data2 = gSprites[spriteId].pos1.x + gBattleAnimArgs[1]; + sprite->data3 = gSprites[spriteId].pos1.y; + sprite->data4 = gSprites[spriteId].pos1.y + gBattleAnimArgs[2]; + sub_8078A5C(sprite); + sprite->data3 = 0; + sprite->data4 = 0; + sprite->data5 = spriteId; + sprite->invisible = TRUE; + oamt_set_x3A_32(sprite, move_anim_8072740); + sprite->callback = sub_80784A8; +} + +void sub_80A8818(struct Sprite *sprite) { + u8 spriteId; + u8 v1; + sprite->invisible = TRUE; + if (!gBattleAnimArgs[0]) { + v1 = gUnknown_0202F7C8; + } else { + v1 = gUnknown_0202F7C9; + } + spriteId = gUnknown_02024BE0[v1]; + if (battle_side_get_owner(v1)) { + gBattleAnimArgs[1] = -gBattleAnimArgs[1]; + if (gBattleAnimArgs[3] == 1) { + gBattleAnimArgs[2] = -gBattleAnimArgs[2]; + } + } + sprite->data0 = gBattleAnimArgs[4]; + sprite->data1 = gSprites[spriteId].pos1.x + gSprites[spriteId].pos2.x; + sprite->data2 = sprite->data1 + gBattleAnimArgs[1]; + sprite->data3 = gSprites[spriteId].pos1.y + gSprites[spriteId].pos2.y; + sprite->data4 = sprite->data3 + gBattleAnimArgs[2]; + sub_8078A5C(sprite); + sprite->data3 = gSprites[spriteId].pos2.x << 8; + sprite->data4 = gSprites[spriteId].pos2.y << 8; + sprite->data5 = spriteId; + sprite->data6 = gBattleAnimArgs[5]; + if (!gBattleAnimArgs[5]) { + oamt_set_x3A_32(sprite, move_anim_8072740); + } else { + oamt_set_x3A_32(sprite, sub_80A88F0); + } + sprite->callback = sub_80784A8; +} + + +static void sub_80A88F0(struct Sprite *sprite) { + gSprites[sprite->data5].pos2.x = 0; + gSprites[sprite->data5].pos2.y = 0; + move_anim_8072740(sprite); +} + +void sub_80A8920(u8 task) { + s16 r7; + r7 = 0x8000 / gBattleAnimArgs[3]; + if (battle_side_get_owner(gUnknown_0202F7C8)) { + gBattleAnimArgs[1] = -gBattleAnimArgs[1]; + gBattleAnimArgs[5] = -gBattleAnimArgs[5]; + } + TASK.data[0] = obj_id_for_side_relative_to_move(gBattleAnimArgs[0]); + TASK.data[1] = (gBattleAnimArgs[1] << 8) / gBattleAnimArgs[3]; + TASK.data[2] = gBattleAnimArgs[2]; + TASK.data[3] = gBattleAnimArgs[3]; + TASK.data[4] = gBattleAnimArgs[4]; + TASK.data[5] = (gBattleAnimArgs[5] << 8) / gBattleAnimArgs[6]; + TASK.data[6] = gBattleAnimArgs[6]; + TASK.data[7] = r7; + TASK.func = sub_80A89B4; +} + +static void sub_80A89B4(u8 task) { + u8 spriteId; + spriteId = TASK.data[0]; + TASK.data[11] += TASK.data[1]; + gSprites[spriteId].pos2.x = TASK.data[11] >> 8; + gSprites[spriteId].pos2.y = Sin((u8)(TASK.data[10] >> 8), TASK.data[2]); + TASK.data[10] += TASK.data[7]; + if (--TASK.data[3] == 0) { + TASK.func = sub_80A8A18; + } +} + +static void sub_80A8A18(u8 task) { + u8 spriteId; + if (TASK.data[4] > 0) { + TASK.data[4]--; + } else { + spriteId = TASK.data[0]; + TASK.data[12] += TASK.data[5]; + gSprites[spriteId].pos2.x = (TASK.data[12] >> 8) + (TASK.data[11] >> 8); + if (--TASK.data[6] == 0) { + move_anim_task_del(task); + return; + } + } +} + +static void sub_80A8B3C(u8 task); + +void sub_80A8A80(u8 task) { + u8 spriteId; + switch (gBattleAnimArgs[0]) { + case 0: + case 1: + spriteId = obj_id_for_side_relative_to_move(gBattleAnimArgs[0]); + break; + case 2: + if (!b_side_obj__get_some_boolean(gUnknown_0202F7C8 ^ 2)) { + move_anim_task_del(task); + return; + } + spriteId = gUnknown_02024BE0[gUnknown_0202F7C8 ^ 2]; + break; + case 3: + if (!b_side_obj__get_some_boolean(gUnknown_0202F7C9 ^ 2)) { + move_anim_task_del(task); + return; + } + spriteId = gUnknown_02024BE0[gUnknown_0202F7C9 ^ 2]; + break; + default: + move_anim_task_del(task); + return; + } + TASK.data[0] = spriteId; + if (battle_side_get_owner(gUnknown_0202F7C9)) { + TASK.data[1] = gBattleAnimArgs[1]; + } else { + TASK.data[1] = -gBattleAnimArgs[1]; + } + TASK.func = sub_80A8B3C; +} + +static void sub_80A8B3C(u8 task) { + u8 spriteId = TASK.data[0]; + gSprites[spriteId].pos2.x += TASK.data[1]; + if (gSprites[spriteId].pos2.x + gSprites[spriteId].pos1.x + 0x20 > 0x130u) { + move_anim_task_del(task); + return; + } +} + +void sub_80A8B88(u8 task) { + u8 spriteId; + if (battle_side_get_owner(gUnknown_0202F7C8)) { + gBattleAnimArgs[1] = -gBattleAnimArgs[1]; + } + spriteId = obj_id_for_side_relative_to_move(gBattleAnimArgs[4]); + TASK.data[0] = gBattleAnimArgs[0]; + TASK.data[1] = gBattleAnimArgs[1]; + TASK.data[2] = gBattleAnimArgs[2]; + TASK.data[3] = gBattleAnimArgs[3]; + TASK.data[4] = spriteId; + if (gBattleAnimArgs[4] == 0) { + TASK.data[5] = gUnknown_0202F7C8; + } else { + TASK.data[5] = gUnknown_0202F7C9; + } + TASK.data[12] = 1; + TASK.func = sub_80A8C0C; +} + +static void sub_80A8C0C(u8 task) { + s16 y; + u8 spriteId; + int index; + u16 val; + spriteId = TASK.data[4]; + val = TASK.data[10] + TASK.data[2]; + TASK.data[10] = val; + index = val >> 8; + y = Sin(index, TASK.data[1]); + if (TASK.data[0] == 0) { + gSprites[spriteId].pos2.x = y; + } else { + if (battle_side_get_owner(TASK.data[5]) == 0) { + gSprites[spriteId].pos2.y = (y >= 0) ? y : -y; + } else { + gSprites[spriteId].pos2.y = (y >= 0) ? -y : y; + } + } + if (((index >= 0x80u) && (TASK.data[11] == 0) && (TASK.data[12] == 1)) + || ((index < 0x7fu) && (TASK.data[11] == 1) && (TASK.data[12] == 0))) { + TASK.data[11] ^= 1; + TASK.data[12] ^= 1; + if (--TASK.data[3] == 0) { + gSprites[spriteId].pos2.x = 0; + gSprites[spriteId].pos2.y = 0; + move_anim_task_del(task); + return; + } + } +} + +void sub_80A8D34(u8 task) { + u8 spriteId; + spriteId = obj_id_for_side_relative_to_move(gBattleAnimArgs[3]); + sub_8078E70(spriteId, gBattleAnimArgs[4]); + TASK.data[0] = gBattleAnimArgs[0]; + TASK.data[1] = gBattleAnimArgs[1]; + TASK.data[2] = gBattleAnimArgs[2]; + TASK.data[3] = gBattleAnimArgs[2]; + TASK.data[4] = spriteId; + TASK.data[10] = 0x100; + TASK.data[11] = 0x100; + TASK.func = sub_80A8D8C; +} + +static void sub_80A8D8C(u8 task) { + u8 spriteId; + TASK.data[10] += TASK.data[0]; + TASK.data[11] += TASK.data[1]; + spriteId = TASK.data[4]; + obj_id_set_rotscale(spriteId, TASK.data[10], TASK.data[11], 0); + if (--TASK.data[2] == 0) { + if (TASK.data[3] > 0) { + TASK.data[0] = -TASK.data[0]; + TASK.data[1] = -TASK.data[1]; + TASK.data[2] = TASK.data[3]; + TASK.data[3] = 0; + } else { + sub_8078F40(spriteId); + move_anim_task_del(task); + return; + } + } +} + +void sub_80A8E04(u8 task) { + u8 spriteId; + spriteId = obj_id_for_side_relative_to_move(gBattleAnimArgs[2]); + sub_8078E70(spriteId, 0); + TASK.data[1] = 0; + TASK.data[2] = gBattleAnimArgs[0]; + if (gBattleAnimArgs[3] != 1) { + TASK.data[3] = 0; + } else { + TASK.data[3] = gBattleAnimArgs[0] * gBattleAnimArgs[1]; + } + TASK.data[4] = gBattleAnimArgs[1]; + TASK.data[5] = spriteId; + TASK.data[6] = gBattleAnimArgs[3]; + if (sub_8076BE0()) { + TASK.data[7] = 1; + } else { + if (gBattleAnimArgs[2] == 0) { + TASK.data[7] = !battle_side_get_owner(gUnknown_0202F7C8); + } else { + TASK.data[7] = !battle_side_get_owner(gUnknown_0202F7C9); + } + } + if (TASK.data[7]) { + if (!sub_8076BE0()) { + TASK.data[3] *= -1; + TASK.data[4] *= -1; + } + } + TASK.func = sub_80A8FD8; +} + +void sub_80A8EFC(u8 task) { + u8 spriteId; + spriteId = obj_id_for_side_relative_to_move(gBattleAnimArgs[2]); + sub_8078E70(spriteId, 0); + TASK.data[1] = 0; + TASK.data[2] = gBattleAnimArgs[0]; + if (gBattleAnimArgs[2] == 0) { + if (battle_side_get_owner(gUnknown_0202F7C8)) { + gBattleAnimArgs[1] = -gBattleAnimArgs[1]; + } + } else { + if (battle_side_get_owner(gUnknown_0202F7C9)) { + gBattleAnimArgs[1] = -gBattleAnimArgs[1]; + } + } + if (gBattleAnimArgs[3] != 1) { + TASK.data[3] = 0; + } else { + TASK.data[3] = gBattleAnimArgs[0] * gBattleAnimArgs[1]; + } + TASK.data[4] = gBattleAnimArgs[1]; + TASK.data[5] = spriteId; + TASK.data[6] = gBattleAnimArgs[3]; + TASK.data[7] = 1; + TASK.data[3] *= -1; + TASK.data[4] *= -1; + TASK.func = sub_80A8FD8; +} + +void sub_80A8FD8(u8 task) { + TASK.data[3] += TASK.data[4]; + obj_id_set_rotscale(TASK.data[5], 0x100, 0x100, TASK.data[3]); + if (TASK.data[7]) { + sub_8078F9C(TASK.data[5]); + } + if (++TASK.data[1] >= TASK.data[2]) { + switch (TASK.data[6]) { + case 1: + sub_8078F40(TASK.data[5]); + case 0: + default: + move_anim_task_del(task); + return; + case 2: + TASK.data[1] = 0; + TASK.data[4] *= -1; + TASK.data[6] = 1; + break; + } + } +} + +void sub_80A9058(u8 task) { + if (!gBattleAnimArgs[0]) { + TASK.data[15] = gUnknown_0202F7BC / 12; + if (TASK.data[15] < 1) { + TASK.data[15] = 1; + } + if (TASK.data[15] > 16) { + TASK.data[15] = 16; + } + } else { + TASK.data[15] = gUnknown_0202F7B8 / 12; + if (TASK.data[15] < 1) { + TASK.data[15] = 1; + } + if (TASK.data[15] > 16) { + TASK.data[15] = 16; + } + } + TASK.data[14] = TASK.data[15] / 2; + TASK.data[13] = TASK.data[14] + (TASK.data[15] & 1); + TASK.data[12] = 0; + TASK.data[10] = gBattleAnimArgs[3]; + TASK.data[11] = gBattleAnimArgs[4]; + TASK.data[7] = obj_id_for_side_relative_to_move(1); + TASK.data[8] = gSprites[TASK.data[7]].pos2.x; + TASK.data[9] = gSprites[TASK.data[7]].pos2.y; + TASK.data[0] = 0; + TASK.data[1] = gBattleAnimArgs[1]; + TASK.data[2] = gBattleAnimArgs[2]; + TASK.func = sub_80A913C; +} + +static void sub_80A913C(u8 taskId) { + struct Task *task = &gTasks[taskId]; + if (++task->data[0] > task->data[1]) { + task->data[0] = 0; + task->data[12] = (task->data[12] + 1) & 1; + if (task->data[10]) { + if (task->data[12]) { + gSprites[task->data[7]].pos2.x = task->data[8] + task->data[13]; + } else { + gSprites[task->data[7]].pos2.x = task->data[8] - task->data[14]; + } + } + if (task->data[11]) { + if (task->data[12]) { + gSprites[task->data[7]].pos2.y = task->data[15]; + } else { + gSprites[task->data[7]].pos2.y = 0; + } + } + if (!--task->data[2]) { + gSprites[task->data[7]].pos2.x = 0; + gSprites[task->data[7]].pos2.y = 0; + move_anim_task_del(taskId); + return; + } + } +} diff --git a/src/battle_setup.c b/src/battle_setup.c index 15b09645f..1c3e8e836 100644 --- a/src/battle_setup.c +++ b/src/battle_setup.c @@ -1,59 +1,32 @@ #include "global.h" +#include "battle_setup.h" +#include "asm.h" +#include "safari_zone.h" +#include "weather.h" +#include "palette.h" +#include "field_player_avatar.h" +#include "rom4.h" #include "battle.h" #include "main.h" #include "species.h" -#include "pokemon.h" #include "songs.h" +#include "sound.h" #include "task.h" -#include "fieldmap.h" #include "string_util.h" #include "rng.h" -#include "flag.h" -#include "var.h" +#include "event_data.h" #include "script.h" #include "field_message_box.h" #include "trainer.h" +#include "starter_choose.h" +#include "metatile_behavior.h" #define NUM_TRAINER_EYE_TRAINERS 56 #define TRAINER_REMATCH_STEPS 255 -extern void prev_quest_postbuffer_cursor_backup_reset(void); -extern void overworld_poison_timer_set(void); -extern void current_map_music_set__default_for_battle(u16); -extern void c2_exit_to_overworld_1_continue_scripts_restart_music(void); -extern void c2_exit_to_overworld_2_switch(void); -extern void npc_set_running_behaviour_etc(struct MapObject *, u8); -extern void c2_whiteout(void); -extern void sub_800E7C4(void); -extern void sub_8081AA4(void); -extern void sub_8081A18(void); -extern void sub_8081C8C(void); -extern void sub_80C824C(void); -extern void sub_8081CEC(void); -extern void sub_8080E44(void); -extern void sub_80821D8(void); -extern void sub_8082228(void); -extern void sub_808260C(void); -extern void sub_8082CB8(void); -extern u8 *sub_80BCCE8(void); -extern void CB2_ChooseStarter(void); -extern void sub_811AABC(u8); -extern u8 sub_811AAE8(void); -extern u8 GetFieldObjectIdByLocalIdAndMap(u8, u8, u8); -extern u8 *sub_8082880(void); -extern u8 sub_803FC58(u16); -extern bool32 FieldPoisonEffectIsRunning(void); -extern bool32 GetSafariZoneFlag(void); -extern void player_bitmagic(void); - -u8 GetWildBattleTransition(void); -u8 GetTrainerBattleTransition(void); -bool32 battle_exit_is_player_defeat(u32 a1); -u8 *sub_808281C(void); -u16 sub_8082C4C(u16 a1); - extern u16 gScriptResult; +// IV + LEVEL + SPECIES struct TrainerPartyMember0 { u16 iv; @@ -61,6 +34,7 @@ struct TrainerPartyMember0 u16 species; }; +// IV + LEVEL + SPECIES + MOVES struct TrainerPartyMember1 { u16 iv; @@ -69,6 +43,7 @@ struct TrainerPartyMember1 u16 moves[4]; }; +// IV + LEVEL + SPECIES + ITEMS struct TrainerPartyMember2 { u16 iv; @@ -77,6 +52,7 @@ struct TrainerPartyMember2 u16 heldItem; }; +// IV + LEVEL + SPECIES + ITEMS + MOVES struct TrainerPartyMember3 { u16 iv; @@ -99,22 +75,6 @@ struct TrainerEyeTrainer u16 mapNum; }; -extern u16 MapGridGetMetatileBehaviorAt(s16, s16); -extern bool8 MetatileBehavior_IsTallGrass(char); -extern bool8 MetatileBehavior_IsLongGrass(char); -extern bool8 MetatileBehavior_IsSandOrDeepSand(char); -extern bool8 MetatileBehavior_IsSurfableWaterOrUnderwater(char); -extern bool8 MetatileBehavior_IsBridge(char); -extern bool8 sub_80574C4(char); -extern bool8 sub_80574D8(char); -extern bool8 sub_8057568(char); -extern u8 TestPlayerAvatarFlags(u8); -extern u8 sub_8057450(u8); -extern u8 GetSav1Weather(void); -extern void PlayNewMapMusic(u16); - -extern u8 ScriptGiveMon(u16, u8, u16, u32, u32, u8); - extern void (*gUnknown_0300485C)(void); extern struct Pokemon gEnemyParty[]; @@ -135,7 +95,7 @@ extern struct TrainerEyeTrainer gTrainerEyeTrainers[]; extern u8 gOtherText_CancelWithTerminator[]; -extern u16 gUnknown_020239F8; +extern u16 gBattleTypeFlags; extern u16 gScriptLastTalked; extern u8 gUnknown_02024D26; extern u16 gBadgeFlags[]; @@ -162,8 +122,6 @@ extern u8 gStringVar4[]; extern u8 gBattleTransitionTable_Wild[][2]; extern u8 gBattleTransitionTable_Trainer[][2]; -void sub_8082188(void); - void task01_battle_start(u8 taskId) { s16 *data = gTasks[taskId].data; @@ -200,123 +158,123 @@ void task_add_01_battle_start(u8 transition, u16 song) void CheckForSafariZoneAndProceed(void) { if (GetSafariZoneFlag()) - sub_8081AA4(); + StartBattle_Safari(); else - sub_8081A18(); + StartBattle_StandardWild(); } -void sub_8081A18(void) +void StartBattle_StandardWild(void) { ScriptContext2_Enable(); - player_bitmagic(); + FreezeMapObjects(); sub_80597F4(); - gMain.field_8 = sub_8081C8C; - gUnknown_020239F8 = 0; + gMain.savedCallback = HandleWildBattleEnd; + gBattleTypeFlags = 0; task_add_01_battle_start(GetWildBattleTransition(), 0); - sav12_xor_increment(7); - sav12_xor_increment(8); + IncrementGameStat(7); + IncrementGameStat(8); } -void sub_8081A5C(void) +void StartBattle_Roamer(void) { ScriptContext2_Enable(); - player_bitmagic(); + FreezeMapObjects(); sub_80597F4(); - gMain.field_8 = sub_8081C8C; - gUnknown_020239F8 = 1024; + gMain.savedCallback = HandleWildBattleEnd; + gBattleTypeFlags = BATTLE_TYPE_ROAMER; task_add_01_battle_start(GetWildBattleTransition(), 0); - sav12_xor_increment(7); - sav12_xor_increment(8); + IncrementGameStat(7); + IncrementGameStat(8); } -void sub_8081AA4(void) +void StartBattle_Safari(void) { ScriptContext2_Enable(); - player_bitmagic(); + FreezeMapObjects(); sub_80597F4(); - gMain.field_8 = sub_80C824C; - gUnknown_020239F8 = 128; + gMain.savedCallback = sub_80C824C; + gBattleTypeFlags = BATTLE_TYPE_SAFARI; task_add_01_battle_start(GetWildBattleTransition(), 0); } void task_add_01_battle_start_with_music_and_stats(void) { task_add_01_battle_start(GetTrainerBattleTransition(), 0); - sav12_xor_increment(7); - sav12_xor_increment(9); + IncrementGameStat(7); + IncrementGameStat(9); } //Initiates battle where Wally catches Ralts -void sub_8081AFC(void) +void StartBattle_WallyTutorial(void) { CreateMaleMon(&gEnemyParty[0], SPECIES_RALTS, 5); ScriptContext2_Enable(); - gMain.field_8 = c2_exit_to_overworld_1_continue_scripts_restart_music; - gUnknown_020239F8 = 512; + gMain.savedCallback = c2_exit_to_overworld_1_continue_scripts_restart_music; + gBattleTypeFlags = BATTLE_TYPE_WALLY_TUTORIAL; task_add_01_battle_start(8, 0); } -void sub_8081B3C(void) +void StartBattle_ScriptedWild(void) { ScriptContext2_Enable(); - gMain.field_8 = sub_8081CEC; - gUnknown_020239F8 = 0; + gMain.savedCallback = HandleScriptedWildBattleEnd; + gBattleTypeFlags = 0; task_add_01_battle_start(GetWildBattleTransition(), 0); - sav12_xor_increment(7); - sav12_xor_increment(8); + IncrementGameStat(7); + IncrementGameStat(8); } -void sub_8081B78(void) +void StartBattle_SouthernIsland(void) { ScriptContext2_Enable(); - gMain.field_8 = sub_8081CEC; - gUnknown_020239F8 = 0x2000; + gMain.savedCallback = HandleScriptedWildBattleEnd; + gBattleTypeFlags = BATTLE_TYPE_LEGENDARY; task_add_01_battle_start(GetWildBattleTransition(), 0); - sav12_xor_increment(7); - sav12_xor_increment(8); + IncrementGameStat(7); + IncrementGameStat(8); } -void sub_8081BB8(void) +void StartBattle_Rayquaza(void) { ScriptContext2_Enable(); - gMain.field_8 = sub_8081CEC; - gUnknown_020239F8 = 0x2000; + gMain.savedCallback = HandleScriptedWildBattleEnd; + gBattleTypeFlags = BATTLE_TYPE_LEGENDARY; task_add_01_battle_start(0, BGM_BATTLE34); - sav12_xor_increment(7); - sav12_xor_increment(8); + IncrementGameStat(7); + IncrementGameStat(8); } -void sub_8081BF8(void) +void StartBattle_GroudonKyogre(void) { ScriptContext2_Enable(); - gMain.field_8 = sub_8081CEC; - gUnknown_020239F8 = 12288; + gMain.savedCallback = HandleScriptedWildBattleEnd; + gBattleTypeFlags = BATTLE_TYPE_LEGENDARY | BATTLE_TYPE_KYOGRE_GROUDON; if (gGameVersion == 2) task_add_01_battle_start(0xB, BGM_BATTLE34); // KYOGRE else task_add_01_battle_start(0x6, BGM_BATTLE34); // GROUDON - sav12_xor_increment(7); - sav12_xor_increment(8); + IncrementGameStat(7); + IncrementGameStat(8); } -void sub_8081C50(void) +void StartBattle_Regi(void) { ScriptContext2_Enable(); - gMain.field_8 = sub_8081CEC; - gUnknown_020239F8 = 24576; + gMain.savedCallback = HandleScriptedWildBattleEnd; + gBattleTypeFlags = BATTLE_TYPE_LEGENDARY | BATTLE_TYPE_REGI; task_add_01_battle_start(0xA, BGM_BATTLE36); - sav12_xor_increment(7); - sav12_xor_increment(8); + IncrementGameStat(7); + IncrementGameStat(8); } -void sub_8081C8C(void) +void HandleWildBattleEnd(void) { CpuFill16(0, (void *)BG_PLTT, BG_PLTT_SIZE); ResetOamRange(0, 128); if (battle_exit_is_player_defeat(gUnknown_02024D26) == TRUE) { - SetMainCallback2(c2_whiteout); + SetMainCallback2(CB2_WhiteOut); } else { @@ -325,18 +283,18 @@ void sub_8081C8C(void) } } -void sub_8081CEC(void) +void HandleScriptedWildBattleEnd(void) { CpuFill16(0, (void *)BG_PLTT, BG_PLTT_SIZE); ResetOamRange(0, 128); if (battle_exit_is_player_defeat(gUnknown_02024D26) == TRUE) - SetMainCallback2(c2_whiteout); + SetMainCallback2(CB2_WhiteOut); else SetMainCallback2(c2_exit_to_overworld_1_continue_scripts_restart_music); } -s8 sub_8081D3C(void) +s8 GetBattleTerrain(void) { u16 tileBehavior; s16 x, y; @@ -350,24 +308,24 @@ s8 sub_8081D3C(void) return 1; if (MetatileBehavior_IsSandOrDeepSand(tileBehavior)) return 2; - switch (gMapHeader.light) + switch (gMapHeader.mapType) { - case 1: - case 2: - case 3: + case MAP_TYPE_TOWN: + case MAP_TYPE_CITY: + case MAP_TYPE_ROUTE: break; - case 4: + case MAP_TYPE_UNDERGROUND: if (sub_80574C4(tileBehavior)) return 8; if (MetatileBehavior_IsSurfableWaterOrUnderwater(tileBehavior)) return 5; return 7; - case 8: - case 9: + case MAP_TYPE_INDOOR: + case MAP_TYPE_SECRET_BASE: return 8; - case 5: + case MAP_TYPE_UNDERWATER: return 3; - case 6: + case MAP_TYPE_6: if (MetatileBehavior_IsSurfableWaterOrUnderwater(tileBehavior)) return 4; return 9; @@ -378,7 +336,7 @@ s8 sub_8081D3C(void) return 5; if (sub_80574D8(tileBehavior)) return 6; - if (TestPlayerAvatarFlags(8)) + if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_SURFING)) { if (sub_8057450(tileBehavior)) return 5; @@ -392,7 +350,7 @@ s8 sub_8081D3C(void) return 9; } -s8 sub_8081E90(void) +s8 GetBattleTransitionTypeByMap(void) { u8 flashUsed; u16 tileBehavior; @@ -408,11 +366,11 @@ s8 sub_8081E90(void) if (!MetatileBehavior_IsSurfableWaterOrUnderwater(tileBehavior)) { - switch (gMapHeader.light) + switch (gMapHeader.mapType) { - case 4: + case MAP_TYPE_UNDERGROUND: return 1; - case 5: + case MAP_TYPE_UNDERWATER: return 3; default: return 0; @@ -430,7 +388,7 @@ u16 GetSumOfPartyMonLevel(u8 numMons) { u32 species = GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2); - if (species != 412 && species != 0 && GetMonData(&gPlayerParty[i], MON_DATA_HP) != 0) + if (species != SPECIES_EGG && species != SPECIES_NONE && GetMonData(&gPlayerParty[i], MON_DATA_HP) != 0) { sum += GetMonData(&gPlayerParty[i], MON_DATA_LEVEL); numMons--; @@ -482,7 +440,7 @@ u8 GetSumOfEnemyPartyLevel(u16 trainerNum, u8 numMons) u8 GetWildBattleTransition(void) { - u8 flashVar = sub_8081E90(); + u8 flashVar = GetBattleTransitionTypeByMap(); u8 level = GetMonData(&gEnemyParty[0], MON_DATA_LEVEL); if (level < (u8)GetSumOfPartyMonLevel(1)) // is wild mon level than the player's mon level? @@ -494,8 +452,7 @@ u8 GetWildBattleTransition(void) u8 GetTrainerBattleTransition(void) { struct Trainer *trainer; - u8 trainerClass; - u8 partyCount; + u8 minPartyCount; u8 flashVar; u8 level; @@ -521,14 +478,14 @@ u8 GetTrainerBattleTransition(void) return 16; if (trainer[gTrainerBattleOpponent].doubleBattle == TRUE) - partyCount = 2; // double battles always at least have 2 pokemon. + minPartyCount = 2; // double battles always at least have 2 pokemon. else - partyCount = 1; + minPartyCount = 1; - flashVar = sub_8081E90(); - level = GetSumOfEnemyPartyLevel(gTrainerBattleOpponent, partyCount); + flashVar = GetBattleTransitionTypeByMap(); + level = GetSumOfEnemyPartyLevel(gTrainerBattleOpponent, minPartyCount); - if (level < (u8)GetSumOfPartyMonLevel(partyCount)) // is wild mon level than the player's mon level? + if (level < (u8)GetSumOfPartyMonLevel(minPartyCount)) // is wild mon level than the player's mon level? return gBattleTransitionTable_Trainer[flashVar][0]; else return gBattleTransitionTable_Trainer[flashVar][1]; @@ -544,13 +501,13 @@ u8 GetBattleTowerBattleTransition(void) return 3; } -void sub_8082168(void) +void ChooseStarter(void) { SetMainCallback2(CB2_ChooseStarter); - gMain.field_8 = sub_8082188; + gMain.savedCallback = CB2_GiveStarter; } -void sub_8082188(void) +void CB2_GiveStarter(void) { u16 starterPoke; @@ -559,28 +516,28 @@ void sub_8082188(void) ScriptGiveMon(starterPoke, 5, 0, 0, 0, 0); ResetTasks(); sub_80408BC(); - SetMainCallback2(sub_80821D8); + SetMainCallback2(CB2_StartFirstBattle); sub_811AAD8(0); } -void sub_80821D8(void) +void CB2_StartFirstBattle(void) { UpdatePaletteFade(); RunTasks(); if (sub_811AAE8() == TRUE) { - gUnknown_020239F8 = 16; - gMain.field_8 = sub_8082228; + gBattleTypeFlags = BATTLE_TYPE_FIRST_BATTLE; + gMain.savedCallback = HandleFirstBattleEnd; SetMainCallback2(sub_800E7C4); prev_quest_postbuffer_cursor_backup_reset(); overworld_poison_timer_set(); - sav12_xor_increment(7); - sav12_xor_increment(8); + IncrementGameStat(7); + IncrementGameStat(8); } } -void sub_8082228(void) +void HandleFirstBattleEnd(void) { sav1_reset_battle_music_maybe(); SetMainCallback2(c2_exit_to_overworld_1_continue_scripts_restart_music); @@ -730,7 +687,7 @@ void TrainerWantsBattle(u8 trainerMapObjId, u8 *trainerScript) ScriptContext2_Enable(); } -u8 GetTrainerFlagFromScriptPointer(u8 *data) +bool32 GetTrainerFlagFromScriptPointer(u8 *data) { u32 flag = TrainerBattleLoadArg16(data + 2); return FlagGet(TRAINER_FLAG_START + flag); @@ -780,8 +737,8 @@ void trainer_flag_clear(u16 flag) void sub_80825E4(void) { - gUnknown_020239F8 = 8; - gMain.field_8 = sub_808260C; + gBattleTypeFlags = BATTLE_TYPE_TRAINER; + gMain.savedCallback = sub_808260C; task_add_01_battle_start_with_music_and_stats(); ScriptContext1_Stop(); } @@ -794,7 +751,7 @@ void sub_808260C(void) } else if (battle_exit_is_player_defeat(gUnknown_02024D26) == TRUE) { - SetMainCallback2(c2_whiteout); + SetMainCallback2(CB2_WhiteOut); } else { @@ -811,7 +768,7 @@ void do_choose_name_or_words_screen(void) } else if (battle_exit_is_player_defeat(gUnknown_02024D26) == TRUE) { - SetMainCallback2(c2_whiteout); + SetMainCallback2(CB2_WhiteOut); } else { @@ -823,8 +780,8 @@ void do_choose_name_or_words_screen(void) void sub_80826B0(void) { - gUnknown_020239F8 = 8; - gMain.field_8 = do_choose_name_or_words_screen; + gBattleTypeFlags = BATTLE_TYPE_TRAINER; + gMain.savedCallback = do_choose_name_or_words_screen; task_add_01_battle_start_with_music_and_stats(); ScriptContext1_Stop(); } diff --git a/src/berry.c b/src/berry.c index e00015477..84db22a27 100644 --- a/src/berry.c +++ b/src/berry.c @@ -1,56 +1,47 @@ #include "global.h" +#include "berry.h" +#include "asm.h" +#include "item.h" +#include "main.h" #include "text.h" +#include "rng.h" +#include "items.h" -#define FIRST_BERRY 0x85 // ITEM_CHERI_BERRY -#define LAST_BERRY 0xaf // ITEM_ENIGMA_BERRY - -extern u8 GetStageByBerryTreeId(u8); -extern u16 GetStageDurationByBerryType(u8); -extern void SetMainCallback2(void*); -extern void sub_80A68CC(); -extern u16 Random(void); -extern u8 sub_8060234(u8, u8, u8); -extern u8 AddBagItem(u16, u8); -extern void sub_8060288(u8, u8, u8); -extern u8 IsBagPocketNonEmpty(u8); -extern void GetCameraCoords(s16*, s16*); -extern u8 FieldObjectGetBerryTreeId(u8); -extern u8 *GetFieldObjectScriptPointerForComparison(); +#define FIRST_BERRY ITEM_CHERI_BERRY +#define LAST_BERRY ITEM_ENIGMA_BERRY extern struct Berry gBerries[]; extern u8 BerryTreeScript; -extern struct BerryTree gUnknown_083CD780; +extern struct BerryTree gBlankBerryTree; extern u16 gScriptItemId; extern u16 gScriptLastTalked; extern u16 gSpecialVar_0x8004; extern u16 gSpecialVar_0x8005; extern u16 gSpecialVar_0x8006; -u8 CalcBerryYield(struct BerryTree *tree); - -void unref_sub_80B4884(void) +// unused +void ClearEnigmaBerries(void) { CpuFill16(0, &gSaveBlock1.enigmaBerry, sizeof(gSaveBlock1.enigmaBerry)); } -// setEnigmaBerry -void sub_80B48A8(u8 *src) +void SetEnigmaBerry(u8 *src) { - unsigned int i; + u32 i; u8 *dest = (u8*)&gSaveBlock1.enigmaBerry; for (i = 0; i < sizeof(gSaveBlock1.enigmaBerry); i++) dest[i] = src[i]; + gSaveBlock1.enigmaBerry.berry.description1 = gSaveBlock1.enigmaBerry.description1; gSaveBlock1.enigmaBerry.berry.description2 = gSaveBlock1.enigmaBerry.description2; } -// checksum -u32 sub_80B48F8(struct EnigmaBerry *enigmaBerry) +u32 GetEnigmaBerryChecksum(struct EnigmaBerry *enigmaBerry) { u8 *description1; u8 *description2; - unsigned int i; + u32 i; u32 checksum; u8 *dest; @@ -61,7 +52,7 @@ u32 sub_80B48F8(struct EnigmaBerry *enigmaBerry) dest = (u8*)enigmaBerry; checksum = 0; - for (i = 0; i < ((int)&gSaveBlock1.enigmaBerry.checksum - (int)&gSaveBlock1.enigmaBerry); i++) + for (i = 0; i < ((u32)&gSaveBlock1.enigmaBerry.checksum - (u32)&gSaveBlock1.enigmaBerry); i++) { checksum += dest[i]; } @@ -72,20 +63,20 @@ u32 sub_80B48F8(struct EnigmaBerry *enigmaBerry) return checksum; } -bool32 sub_80B4940(void) +bool32 IsEnigmaBerryValid(void) { if (!gSaveBlock1.enigmaBerry.berry.stageDuration) return FALSE; if (!gSaveBlock1.enigmaBerry.berry.maxYield) return FALSE; - if (sub_80B48F8(&gSaveBlock1.enigmaBerry) != gSaveBlock1.enigmaBerry.checksum) + if (GetEnigmaBerryChecksum(&gSaveBlock1.enigmaBerry) != gSaveBlock1.enigmaBerry.checksum) return FALSE; return TRUE; } struct Berry *GetBerryInfo(u8 berry) { - if (berry == 0x2B && sub_80B4940()) + if (berry == 0x2B && IsEnigmaBerryValid()) return &gSaveBlock1.enigmaBerry.berry; else { @@ -133,7 +124,7 @@ bool32 IsPlayerFacingPlantedBerryTree(void) return FALSE; } -u8 WaterBerryTree(void) +u8 TryToWaterBerryTree(void) { if (GetFieldObjectScriptPointerForComparison() != &BerryTreeScript) return 0; @@ -141,11 +132,11 @@ u8 WaterBerryTree(void) return FieldObjectInteractionWaterBerryTree(); } -void sub_80B4A90(void) +void ClearBerryTrees(void) { int i; struct SaveBlock1 *saveBlock1 = &gSaveBlock1; - struct BerryTree berryTree = gUnknown_083CD780; + struct BerryTree berryTree = gBlankBerryTree; for (i = 0; i < 128; i++) saveBlock1->berryTrees[i] = berryTree; @@ -174,7 +165,7 @@ bool32 BerryTreeGrow(struct BerryTree *tree) tree->berryYield = 0; tree->stage = 2; if (++tree->regrowthCount == 10) - *tree = gUnknown_083CD780; + *tree = gBlankBerryTree; break; } return TRUE; @@ -193,7 +184,7 @@ void BerryTreeTimeUpdate(int time) { if (time >= GetStageDurationByBerryType(tree->berry) * 71) { - *tree = gUnknown_083CD780; + *tree = gBlankBerryTree; } else { @@ -222,7 +213,7 @@ void PlantBerryTree(u8 id, u8 berry, u8 stage, bool8 sparkle) { struct BerryTree *tree = GetBerryTreeInfo(id); - *tree = gUnknown_083CD780; + *tree = gBlankBerryTree; tree->berry = berry; tree->secondsUntilNextStage = GetStageDurationByBerryType(berry); tree->stage = stage; @@ -239,7 +230,7 @@ void PlantBerryTree(u8 id, u8 berry, u8 stage, bool8 sparkle) void RemoveBerryTree(u8 id) { - gSaveBlock1.berryTrees[id] = gUnknown_083CD780; + gSaveBlock1.berryTrees[id] = gBlankBerryTree; } u8 GetBerryTypeByBerryTreeId(u8 id) @@ -397,7 +388,7 @@ void FieldObjectInteractionRemoveBerryTree(void) u8 PlayerHasBerries(void) { - return IsBagPocketNonEmpty(4); + return IsBagPocketNonEmpty(BAG_BERRIES); } void ResetBerryTreeSparkleFlags(void) diff --git a/src/berry_tag_screen.c b/src/berry_tag_screen.c new file mode 100644 index 000000000..1b432fe70 --- /dev/null +++ b/src/berry_tag_screen.c @@ -0,0 +1,878 @@ +#include "global.h" +#include "berry_tag_screen.h" +#include "asm.h" +#include "berry.h" +#include "decompress.h" +#include "main.h" +#include "menu.h" +#include "palette.h" +#include "rom4.h" +#include "songs.h" +#include "sound.h" +#include "sprite.h" +#include "string_util.h" +#include "task.h" +#include "text.h" +#include "items.h" + +#define OFFSET_7B (123) +#define FIRST_BERRY ITEM_CHERI_BERRY + +struct Struct2000000 { + /*0x00*/ u8 filler_0[0x1FFFF]; + /*0x1FFFF*/ bool8 var_1FFFF; +}; + +struct BerryTagStatus { + s16 circles[5]; +}; + +extern struct Struct2000000 unk_2000000; +extern u16 gBGTilemapBuffers[4][0x400]; +extern u8 gUnknown_0203932C; +extern struct BerryTagStatus gUnknown_0203932E; +extern u16 gScriptItemId; +extern u16 gUnknown_030041B4; + +extern const struct SpriteSheet gUnknown_083C1F74; +extern const struct SpritePalette gUnknown_083C1F7C; + +extern u8 gOtherText_ThreeQuestions2[]; +extern u8 gOtherText_Size[]; +extern u8 gOtherText_Firm[]; +extern u8 gContestStatsText_Unknown1[]; +extern u8 *gUnknown_0841192C[]; + +extern u8 gBerryCheck_Gfx[]; +extern u8 gBerryCheck_Pal[]; +extern u8 gUnknown_08E788E4[]; +extern u8 gUnknown_08E78A84[]; + +static void sub_8146014(void); +static void sub_814602C(void); +static bool8 sub_8146058(void); +static void sub_8146288(void); +static bool8 sub_81462B8(void); +static void sub_814640C(u8 taskId); +static void sub_8146440(u8 taskId); +static void sub_8146480(u8 taskid); +static void sub_81464E4(void); +static void sub_8146600(u8 berry); +// static void sub_81466A0(void); +static void sub_81466E8(u8 taskId, s32 direction); +// static void sub_8146798(u8 berry); +// static void sub_8146810(u8 berry); +// static void sub_81468BC(void); + +static void sub_8146014(void) { + AnimateSprites(); + BuildOamBuffer(); + RunTasks(); + UpdatePaletteFade(); +} + +static void sub_814602C(void) { + REG_BG0VOFS = gUnknown_030041B4; + REG_BG1VOFS = gUnknown_030041B4; + + LoadOam(); + ProcessSpriteCopyRequests(); + TransferPlttBuffer(); +} + +static bool8 sub_8146058(void) { + u8 berry; + u16 backup; + + switch (gMain.state) { + case 0: + sub_80F9438(); + sub_80F9368(); + sub_8146288(); + REG_BLDCNT = 0; + gMain.state += 1; + break; + + case 1: + ResetPaletteFade(); + gPaletteFade.bufferTransferDisabled = 1; + gMain.state += 1; + break; + + case 2: + ResetSpriteData(); + gMain.state += 1; + break; + + case 3: + SetUpWindowConfig(&gWindowConfig_81E6E18); + gMain.state += 1; + break; + + case 4: + MultistepInitMenuWindowBegin(&gWindowConfig_81E6E18); + gMain.state += 1; + break; + + case 5: + if (!MultistepInitMenuWindowContinue()) { + return FALSE; + } + unk_2000000.var_1FFFF = 0; + gMain.state += 1; + break; + + case 6: + if (!sub_81462B8()) { + break; + } + + unk_2000000.var_1FFFF = 0; + gMain.state += 1; + break; + + case 7: + sub_81464E4(); + gMain.state += 1; + break; + + case 8: + berry = gScriptItemId + OFFSET_7B; + gUnknown_0203932C = sub_80A7D8C(berry, 56, 64); + gMain.state += 1; + break; + + case 9: + sub_8146600(gScriptItemId + OFFSET_7B); + gMain.state += 1; + break; + + case 10: + backup = REG_IME; + REG_IME = 0; + REG_IE |= INTR_FLAG_VBLANK; + REG_IME = backup; + + REG_DISPSTAT |= DISPSTAT_VBLANK_INTR; + SetVBlankCallback(sub_814602C); + REG_DISPCNT = DISPCNT_OBJ_ON | DISPCNT_BG_ALL_ON | DISPCNT_OBJ_1D_MAP; + gMain.state += 1; + break; + + case 11: + if (sub_8055870() == TRUE) { + break; + } + gMain.state += 1; + break; + + case 12: + BeginNormalPaletteFade(-1, 0, 0x10, 0, 0); + gPaletteFade.bufferTransferDisabled = 0; + SetMainCallback2(sub_8146014); + return TRUE; + + } + + return FALSE; +} + +void BerryTagScreen_814625C(u8 taskId) { + do { + if (sub_8146058() == TRUE) { + CreateTask(sub_8146480, 0); + return; + } + + } while (sub_80F9344() != TRUE); +} + +static void sub_8146288(void) { + REG_BG1CNT = 0x502; + REG_BG2CNT = 0x600; + REG_BG3CNT = 0x703; + gUnknown_030041B4 = 0; +} + +#ifdef NONMATCHING +bool8 sub_81462B8(void) { + u16 i; + + switch (unk_2000000.var_1FFFF) { + case 0: + LZDecompressVram(gBerryCheck_Gfx, (void *) VRAM); + unk_2000000.var_1FFFF += 1; + break; + + case 1: + LZDecompressVram(gUnknown_08E788E4, (void *) VRAM + 0x2800); + unk_2000000.var_1FFFF += 1; + break; + + case 2: + LZDecompressVram(gUnknown_08E78A84, (void *) VRAM + 0x3000); + unk_2000000.var_1FFFF += 1; + break; + + case 3: + for (i = 0; i < 0x400; i++) { + u16 (*buffer)[0x400] = &gBGTilemapBuffers[3]; + if (gSaveBlock2.playerGender == MALE) { + (*buffer)[i] = 0x4042; + } else { + (*buffer)[i] = 0x5042; + } + } + unk_2000000.var_1FFFF += 1; + break; + + case 4: + LoadCompressedPalette(gBerryCheck_Pal, 0, 96 * 2); + unk_2000000.var_1FFFF += 1; + break; + + case 5: + LoadCompressedObjectPic(&gUnknown_083C1F74); + unk_2000000.var_1FFFF += 1; + break; + + case 6: + LoadCompressedObjectPalette(&gUnknown_083C1F7C); + unk_2000000.var_1FFFF = 0; + return TRUE; + } + + return FALSE; +} +#else +__attribute__((naked)) +static bool8 sub_81462B8(void) { + asm(".syntax unified\n\ + push {r4-r7,lr}\n\ + ldr r1, _081462D4 @ =0x02000000\n\ + ldr r2, _081462D8 @ =0x0001ffff\n\ + adds r0, r1, r2\n\ + ldrb r0, [r0]\n\ + mov r12, r1\n\ + cmp r0, 0x6\n\ + bls _081462CA\n\ + b _08146404\n\ +_081462CA:\n\ + lsls r0, 2\n\ + ldr r1, _081462DC @ =_081462E0\n\ + adds r0, r1\n\ + ldr r0, [r0]\n\ + mov pc, r0\n\ + .align 2, 0\n\ +_081462D4: .4byte 0x02000000\n\ +_081462D8: .4byte 0x0001ffff\n\ +_081462DC: .4byte _081462E0\n\ + .align 2, 0\n\ +_081462E0:\n\ + .4byte _081462FC\n\ + .4byte _0814630C\n\ + .4byte _0814632C\n\ + .4byte _08146340\n\ + .4byte _081463A4\n\ + .4byte _081463C4\n\ + .4byte _081463E4\n\ +_081462FC:\n\ + ldr r0, _08146308 @ =gBerryCheck_Gfx\n\ + movs r1, 0xC0\n\ + lsls r1, 19\n\ + bl LZDecompressVram\n\ + b _081463CA\n\ + .align 2, 0\n\ +_08146308: .4byte gBerryCheck_Gfx\n\ +_0814630C:\n\ + ldr r0, _0814631C @ =gUnknown_08E788E4\n\ + ldr r1, _08146320 @ =0x06002800\n\ + bl LZDecompressVram\n\ + ldr r1, _08146324 @ =0x02000000\n\ + ldr r2, _08146328 @ =0x0001ffff\n\ + adds r1, r2\n\ + b _081463D0\n\ + .align 2, 0\n\ +_0814631C: .4byte gUnknown_08E788E4\n\ +_08146320: .4byte 0x06002800\n\ +_08146324: .4byte 0x02000000\n\ +_08146328: .4byte 0x0001ffff\n\ +_0814632C:\n\ + ldr r0, _08146338 @ =gUnknown_08E78A84\n\ + ldr r1, _0814633C @ =0x06003000\n\ + bl LZDecompressVram\n\ + b _081463CA\n\ + .align 2, 0\n\ +_08146338: .4byte gUnknown_08E78A84\n\ +_0814633C: .4byte 0x06003000\n\ +_08146340:\n\ + movs r1, 0\n\ + ldr r7, _0814635C @ =gBGTilemapBuffers + 0x1000\n\ + adds r2, r7, 0\n\ + ldr r6, _08146360 @ =0x00004042\n\ + ldr r5, _08146364 @ =gSaveBlock2\n\ + ldr r4, _08146368 @ =0x00005042\n\ + ldr r3, _0814636C @ =0x000003ff\n\ +_0814634E:\n\ + ldrb r0, [r5, 0x8]\n\ + cmp r0, 0\n\ + bne _08146370\n\ + lsls r0, r1, 1\n\ + adds r0, r2\n\ + strh r6, [r0]\n\ + b _08146376\n\ + .align 2, 0\n\ +_0814635C: .4byte gBGTilemapBuffers + 0x1000\n\ +_08146360: .4byte 0x00004042\n\ +_08146364: .4byte gSaveBlock2\n\ +_08146368: .4byte 0x00005042\n\ +_0814636C: .4byte 0x000003ff\n\ +_08146370:\n\ + lsls r0, r1, 1\n\ + adds r0, r2\n\ + strh r4, [r0]\n\ +_08146376:\n\ + adds r0, r1, 0x1\n\ + lsls r0, 16\n\ + lsrs r1, r0, 16\n\ + cmp r1, r3\n\ + bls _0814634E\n\ + ldr r1, _08146394 @ =0x06003800\n\ + ldr r0, _08146398 @ =0x040000d4\n\ + str r7, [r0]\n\ + str r1, [r0, 0x4]\n\ + ldr r1, _0814639C @ =0x80000400\n\ + str r1, [r0, 0x8]\n\ + ldr r0, [r0, 0x8]\n\ + ldr r1, _081463A0 @ =0x0001ffff\n\ + add r1, r12\n\ + b _081463D0\n\ + .align 2, 0\n\ +_08146394: .4byte 0x06003800\n\ +_08146398: .4byte 0x040000d4\n\ +_0814639C: .4byte 0x80000400\n\ +_081463A0: .4byte 0x0001ffff\n\ +_081463A4:\n\ + ldr r0, _081463B8 @ =gBerryCheck_Pal\n\ + movs r1, 0\n\ + movs r2, 0xC0\n\ + bl LoadCompressedPalette\n\ + ldr r1, _081463BC @ =0x02000000\n\ + ldr r2, _081463C0 @ =0x0001ffff\n\ + adds r1, r2\n\ + b _081463D0\n\ + .align 2, 0\n\ +_081463B8: .4byte gBerryCheck_Pal\n\ +_081463BC: .4byte 0x02000000\n\ +_081463C0: .4byte 0x0001ffff\n\ +_081463C4:\n\ + ldr r0, _081463D8 @ =gUnknown_083C1F74\n\ + bl LoadCompressedObjectPic\n\ +_081463CA:\n\ + ldr r1, _081463DC @ =0x02000000\n\ + ldr r0, _081463E0 @ =0x0001ffff\n\ + adds r1, r0\n\ +_081463D0:\n\ + ldrb r0, [r1]\n\ + adds r0, 0x1\n\ + strb r0, [r1]\n\ + b _08146404\n\ + .align 2, 0\n\ +_081463D8: .4byte gUnknown_083C1F74\n\ +_081463DC: .4byte 0x02000000\n\ +_081463E0: .4byte 0x0001ffff\n\ +_081463E4:\n\ + ldr r0, _081463F8 @ =gUnknown_083C1F7C\n\ + bl LoadCompressedObjectPalette\n\ + ldr r0, _081463FC @ =0x02000000\n\ + ldr r1, _08146400 @ =0x0001ffff\n\ + adds r0, r1\n\ + movs r1, 0\n\ + strb r1, [r0]\n\ + movs r0, 0x1\n\ + b _08146406\n\ + .align 2, 0\n\ +_081463F8: .4byte gUnknown_083C1F7C\n\ +_081463FC: .4byte 0x02000000\n\ +_08146400: .4byte 0x0001ffff\n\ +_08146404:\n\ + movs r0, 0\n\ +_08146406:\n\ + pop {r4-r7}\n\ + pop {r1}\n\ + bx r1\n\ + .syntax divided\n"); +} +#endif + +static void sub_814640C(u8 taskId) { + if (gPaletteFade.active) { + return; + } + + SetMainCallback2(sub_80A5B40); + sub_80A7DD4(); + gpu_pal_allocator_reset__manage_upper_four(); + DestroyTask(taskId); +} + +static void sub_8146440(u8 taskId) { + PlaySE(SE_SELECT); + BeginNormalPaletteFade(-1, 0, 0, 0x10, 0); + + gTasks[taskId].func = sub_814640C; +} + +static void sub_8146480(u8 taskid) { + register u16 keys asm("r1"); + + if (gPaletteFade.active) { + return; + } + + keys = gMain.newAndRepeatedKeys & (DPAD_RIGHT | DPAD_LEFT | DPAD_UP | DPAD_DOWN); + if (keys == DPAD_UP) { + sub_81466E8(taskid, -1); + } + + keys = gMain.newAndRepeatedKeys & (DPAD_RIGHT | DPAD_LEFT | DPAD_UP | DPAD_DOWN); + if (keys == DPAD_DOWN) { + sub_81466E8(taskid, 1); + } + + if (gMain.newKeys & A_BUTTON || gMain.newKeys & B_BUTTON) { + sub_8146440(taskid); + } +} + +static void sub_81464E4(void) { + struct Berry *berryInfo; + u32 size; + s32 sizeMajor; + s32 sizeMinor; + + berryInfo = GetBerryInfo(gScriptItemId + OFFSET_7B + 1); + + ConvertIntToDecimalStringN(gStringVar1, gScriptItemId - FIRST_BERRY + 1, STR_CONV_MODE_LEADING_ZEROS, 2); + MenuPrint(gStringVar1, 12, 4); + + MenuPrint(berryInfo->name, 14, 4); + MenuPrint(berryInfo->description1, 4, 14); + MenuPrint(berryInfo->description2, 4, 16); + + size = (berryInfo->size * 1000) / 254; + if (size % 10 >= 5) { + size += 10; + } + sizeMinor = (size % 100) / 10; + sizeMajor = size / 100; + + MenuPrint(gOtherText_Size, 11, 7); + if (berryInfo->size != 0) { + ConvertIntToDecimalStringN(gStringVar1, sizeMajor, STR_CONV_MODE_LEFT_ALIGN, 2); + ConvertIntToDecimalStringN(gStringVar2, sizeMinor, STR_CONV_MODE_LEFT_ALIGN, 2); + MenuPrint(gContestStatsText_Unknown1, 16, 7); + } else { + MenuPrint(gOtherText_ThreeQuestions2, 16, 7); + } + + MenuPrint(gOtherText_Firm, 11, 9); + if (berryInfo->firmness != 0) { + MenuPrint(gUnknown_0841192C[berryInfo->firmness - 1], 16, 9); + } else { + MenuPrint(gOtherText_ThreeQuestions2, 16, 9); + } +} + +#ifdef NONMATCHING +static void sub_8146600(u8 berry) { + struct Berry *berryInfo; + u16 i; + + berryInfo = GetBerryInfo(berry +1); + + for (i = 0; i < 5; i++) { + gUnknown_0203932E.circles[i] |= 0xFFFF; + } + + if (berryInfo->spicy) { + // argument is the center of the circle + gUnknown_0203932E.circles[0] = sub_80A7E5C(48); + } + + if (berryInfo->dry) { + gUnknown_0203932E.circles[1] = sub_80A7E5C(88); + } + + if (berryInfo->sweet) { + gUnknown_0203932E.circles[2] = sub_80A7E5C(128); + } + + if (berryInfo->bitter) { + gUnknown_0203932E.circles[3] = sub_80A7E5C(168); + } + + if (berryInfo->sour) { + gUnknown_0203932E.circles[4] = sub_80A7E5C(208); + } +} +#else +__attribute__((naked)) +static void sub_8146600(u8 berry) { + asm(".syntax unified\n\ + push {r4,r5,lr}\n\ + lsls r0, 24\n\ + movs r1, 0x80\n\ + lsls r1, 17\n\ + adds r0, r1\n\ + lsrs r0, 24\n\ + bl GetBerryInfo\n\ + adds r4, r0, 0\n\ + movs r2, 0\n\ + ldr r5, _08146698 @ =gUnknown_0203932E\n\ + ldr r0, _0814669C @ =0x0000ffff\n\ + adds r3, r0, 0\n\ +_0814661A:\n\ + lsls r0, r2, 1\n\ + adds r0, r5\n\ + ldrh r1, [r0]\n\ + orrs r1, r3\n\ + strh r1, [r0]\n\ + adds r0, r2, 0x1\n\ + lsls r0, 16\n\ + lsrs r2, r0, 16\n\ + cmp r2, 0x4\n\ + bls _0814661A\n\ + ldrb r0, [r4, 0x15]\n\ + cmp r0, 0\n\ + beq _08146642\n\ + movs r0, 0x30\n\ + bl sub_80A7E5C\n\ + ldr r1, _08146698 @ =gUnknown_0203932E\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + strh r0, [r1]\n\ +_08146642:\n\ + ldrb r0, [r4, 0x16]\n\ + cmp r0, 0\n\ + beq _08146656\n\ + movs r0, 0x58\n\ + bl sub_80A7E5C\n\ + ldr r1, _08146698 @ =gUnknown_0203932E\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + strh r0, [r1, 0x2]\n\ +_08146656:\n\ + ldrb r0, [r4, 0x17]\n\ + cmp r0, 0\n\ + beq _0814666A\n\ + movs r0, 0x80\n\ + bl sub_80A7E5C\n\ + ldr r1, _08146698 @ =gUnknown_0203932E\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + strh r0, [r1, 0x4]\n\ +_0814666A:\n\ + ldrb r0, [r4, 0x18]\n\ + cmp r0, 0\n\ + beq _0814667E\n\ + movs r0, 0xA8\n\ + bl sub_80A7E5C\n\ + ldr r1, _08146698 @ =gUnknown_0203932E\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + strh r0, [r1, 0x6]\n\ +_0814667E:\n\ + ldrb r0, [r4, 0x19]\n\ + cmp r0, 0\n\ + beq _08146692\n\ + movs r0, 0xD0\n\ + bl sub_80A7E5C\n\ + ldr r1, _08146698 @ =gUnknown_0203932E\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + strh r0, [r1, 0x8]\n\ +_08146692:\n\ + pop {r4,r5}\n\ + pop {r0}\n\ + bx r0\n\ + .align 2, 0\n\ +_08146698: .4byte gUnknown_0203932E\n\ +_0814669C: .4byte 0x0000ffff\n\ + .syntax divided\n"); +} +#endif + + +void sub_81466A0(void) { + u16 i; + + for (i = 0; i < 5; i++) { + if (gUnknown_0203932E.circles[i] != -1) { + DestroySprite(&gSprites[gUnknown_0203932E.circles[i]]); + gUnknown_0203932E.circles[i] = -1; + } + } +} + + +__attribute__((naked)) +static void sub_81466E8(u8 taskId, s32 direction) { + asm(".syntax unified\n\ + push {r4-r7,lr}\n\ + mov r7, r8\n\ + push {r7}\n\ + lsls r0, 24\n\ + lsrs r7, r0, 24\n\ + lsls r1, 24\n\ + lsrs r2, r1, 24\n\ + lsls r0, r7, 2\n\ + adds r0, r7\n\ + lsls r0, 3\n\ + ldr r1, _08146748 @ =gTasks + 0x8\n\ + adds r6, r0, r1\n\ + ldr r4, _0814674C @ =gUnknown_03005D10\n\ + movs r0, 0xC\n\ + adds r0, r4\n\ + mov r8, r0\n\ + ldrb r1, [r0, 0x1]\n\ + ldrb r0, [r4, 0xC]\n\ + adds r1, r0\n\ + cmp r1, 0\n\ + bne _08146718\n\ + lsls r0, r2, 24\n\ + cmp r0, 0\n\ + blt _0814678C\n\ +_08146718:\n\ + adds r0, r1, 0x1\n\ + lsls r5, r2, 24\n\ + mov r1, r8\n\ + ldrb r1, [r1, 0x2]\n\ + cmp r0, r1\n\ + bne _08146728\n\ + cmp r5, 0\n\ + bgt _0814678C\n\ +_08146728:\n\ + movs r0, 0x5\n\ + bl PlaySE\n\ + mov r2, r8\n\ + ldrb r3, [r2, 0x1]\n\ + ldrb r4, [r4, 0xC]\n\ + mov r12, r4\n\ + adds r0, r3, r4\n\ + asrs r2, r5, 24\n\ + adds r1, r0, r2\n\ + cmp r1, 0\n\ + bge _08146750\n\ + negs r0, r0\n\ + strh r0, [r6, 0x2]\n\ + b _08146766\n\ + .align 2, 0\n\ +_08146748: .4byte gTasks + 0x8\n\ +_0814674C: .4byte gUnknown_03005D10\n\ +_08146750:\n\ + mov r4, r8\n\ + ldrb r0, [r4, 0x2]\n\ + cmp r1, r0\n\ + blt _08146764\n\ + subs r0, r3\n\ + mov r1, r12\n\ + subs r0, r1\n\ + subs r0, 0x1\n\ + strh r0, [r6, 0x2]\n\ + b _08146766\n\ +_08146764:\n\ + strh r2, [r6, 0x2]\n\ +_08146766:\n\ + ldr r0, _08146780 @ =gTasks\n\ + lsls r1, r7, 2\n\ + adds r1, r7\n\ + lsls r1, 3\n\ + adds r1, r0\n\ + ldr r0, _08146784 @ =sub_8146798\n\ + str r0, [r1]\n\ + cmp r5, 0\n\ + bge _08146788\n\ + movs r2, 0x10\n\ + negs r2, r2\n\ + adds r0, r2, 0\n\ + b _0814678A\n\ + .align 2, 0\n\ +_08146780: .4byte gTasks\n\ +_08146784: .4byte sub_8146798\n\ +_08146788:\n\ + movs r0, 0x10\n\ +_0814678A:\n\ + strh r0, [r6]\n\ +_0814678C:\n\ + pop {r3}\n\ + mov r8, r3\n\ + pop {r4-r7}\n\ + pop {r0}\n\ + bx r0\n\ + .syntax divided\n"); +} + +__attribute__((naked)) +void sub_8146798(u8 berry) { + asm(".syntax unified\n\ + push {r4,r5,lr}\n\ + lsls r0, 24\n\ + lsrs r4, r0, 24\n\ + lsls r0, r4, 2\n\ + adds r0, r4\n\ + lsls r0, 3\n\ + ldr r1, _08146800 @ =gTasks + 0x8\n\ + adds r0, r1\n\ + ldr r2, _08146804 @ =gUnknown_030041B4\n\ + ldrh r1, [r0]\n\ + ldrh r5, [r2]\n\ + adds r3, r1, r5\n\ + movs r1, 0xFF\n\ + ands r3, r1\n\ + strh r3, [r2]\n\ + movs r1, 0\n\ + ldrsh r0, [r0, r1]\n\ + cmp r0, 0\n\ + ble _081467C2\n\ + cmp r3, 0x90\n\ + beq _081467CA\n\ +_081467C2:\n\ + cmp r0, 0\n\ + bge _081467E0\n\ + cmp r3, 0x70\n\ + bne _081467E0\n\ +_081467CA:\n\ + ldr r0, _08146808 @ =gTasks\n\ + lsls r1, r4, 2\n\ + adds r1, r4\n\ + lsls r1, 3\n\ + adds r1, r0\n\ + movs r0, 0xA\n\ + ldrsb r0, [r1, r0]\n\ + bl sub_8146810\n\ + bl sub_81468BC\n\ +_081467E0:\n\ + ldr r0, _08146804 @ =gUnknown_030041B4\n\ + ldrh r2, [r0]\n\ + cmp r2, 0\n\ + bne _081467FA\n\ + ldr r0, _08146808 @ =gTasks\n\ + lsls r1, r4, 2\n\ + adds r1, r4\n\ + lsls r1, 3\n\ + adds r1, r0\n\ + strh r2, [r1, 0x8]\n\ + strh r2, [r1, 0xA]\n\ + ldr r0, _0814680C @ =sub_8146480\n\ + str r0, [r1]\n\ +_081467FA:\n\ + pop {r4,r5}\n\ + pop {r0}\n\ + bx r0\n\ + .align 2, 0\n\ +_08146800: .4byte gTasks + 0x8\n\ +_08146804: .4byte gUnknown_030041B4\n\ +_08146808: .4byte gTasks\n\ +_0814680C: .4byte sub_8146480\n\ + .syntax divided\n"); +} + +__attribute__((naked)) +void sub_8146810(u8 berry) { + asm(".syntax unified\n\ + push {r4-r6,lr}\n\ + lsls r0, 24\n\ + lsrs r3, r0, 24\n\ + adds r4, r3, 0\n\ + lsls r0, r3, 24\n\ + asrs r1, r0, 24\n\ + cmp r1, 0\n\ + ble _08146848\n\ + ldr r0, _08146840 @ =gUnknown_03005D10\n\ + adds r4, r0, 0\n\ + adds r4, 0xC\n\ + ldrb r2, [r0, 0xC]\n\ + adds r1, r2, r1\n\ + adds r6, r0, 0\n\ + cmp r1, 0x7\n\ + ble _08146844\n\ + adds r0, r3, 0\n\ + adds r0, 0xF9\n\ + adds r0, r2, r0\n\ + ldrb r1, [r4, 0x1]\n\ + adds r0, r1\n\ + strb r0, [r4, 0x1]\n\ + movs r0, 0x7\n\ + b _0814686E\n\ + .align 2, 0\n\ +_08146840: .4byte gUnknown_03005D10\n\ +_08146844:\n\ + adds r0, r2, r3\n\ + b _0814686E\n\ +_08146848:\n\ + ldr r0, _08146868 @ =gUnknown_03005D10\n\ + adds r5, r0, 0\n\ + adds r5, 0xC\n\ + ldrb r2, [r0, 0xC]\n\ + adds r1, r2, r1\n\ + adds r6, r0, 0\n\ + cmp r1, 0\n\ + bge _0814686C\n\ + adds r0, r2, r3\n\ + ldrb r1, [r5, 0x1]\n\ + adds r0, r1\n\ + movs r1, 0\n\ + strb r0, [r5, 0x1]\n\ + strb r1, [r6, 0xC]\n\ + b _08146870\n\ + .align 2, 0\n\ +_08146868: .4byte gUnknown_03005D10\n\ +_0814686C:\n\ + adds r0, r2, r4\n\ +_0814686E:\n\ + strb r0, [r6, 0xC]\n\ +_08146870:\n\ + ldr r2, _081468AC @ =gScriptItemId\n\ + movs r0, 0x3\n\ + lsls r0, 2\n\ + adds r0, r6\n\ + ldrb r1, [r0, 0x1]\n\ + ldrb r0, [r0]\n\ + adds r1, r0\n\ + ldr r0, _081468B0 @ =gUnknown_03005D24\n\ + ldr r0, [r0]\n\ + lsls r1, 2\n\ + adds r1, r0\n\ + ldrh r0, [r1]\n\ + strh r0, [r2]\n\ + ldr r0, _081468B4 @ =gUnknown_0203932C\n\ + ldrb r1, [r0]\n\ + lsls r0, r1, 4\n\ + adds r0, r1\n\ + lsls r0, 2\n\ + ldr r1, _081468B8 @ =gSprites\n\ + adds r0, r1\n\ + bl DestroySprite\n\ + bl sub_81466A0\n\ + bl sub_80A7DD4\n\ + pop {r4-r6}\n\ + pop {r0}\n\ + bx r0\n\ + .align 2, 0\n\ +_081468AC: .4byte gScriptItemId\n\ +_081468B0: .4byte gUnknown_03005D24\n\ +_081468B4: .4byte gUnknown_0203932C\n\ +_081468B8: .4byte gSprites\n\ + .syntax divided\n"); +} + +void sub_81468BC(void) { + MenuZeroFillWindowRect(0, 4, 29, 19); + sub_81464E4(); + + // center of berry sprite + gUnknown_0203932C = sub_80A7D8C(gScriptItemId + OFFSET_7B, 56, 64); + + sub_8146600(gScriptItemId + OFFSET_7B); +} diff --git a/src/blend_palette.c b/src/blend_palette.c index c9503388f..843c50ac1 100644 --- a/src/blend_palette.c +++ b/src/blend_palette.c @@ -1,4 +1,5 @@ #include "global.h" +#include "blend_palette.h" #include "palette.h" void BlendPalette(u16 palOffset, u16 numEntries, u8 coeff, u16 blendColor) diff --git a/src/calculate_base_damage.c b/src/calculate_base_damage.c new file mode 100644 index 000000000..86446e588 --- /dev/null +++ b/src/calculate_base_damage.c @@ -0,0 +1,1487 @@ +#include "global.h" +#include "text.h" +#include "string_util.h" +#include "pokemon.h" +#include "species.h" +#include "main.h" +#include "sprite.h" +#include "berry.h" +#include "item.h" +#include "abilities.h" +#include "hold_effects.h" +#include "event_data.h" +#include "battle.h" +#include "items.h" + +extern u8 gPlayerPartyCount; +extern struct Pokemon gPlayerParty[6]; +extern u8 gEnemyPartyCount; +extern struct Pokemon gEnemyParty[6]; + +extern u16 unk_20160BC[]; +extern struct SecretBaseRecord gSecretBaseRecord; +extern u32 dword_2017100[]; +extern u16 gBattleTypeFlags; +extern struct BattlePokemon gBattleMons[4]; +extern u16 gUnknown_02024BE6; +extern u8 byte_2024C06; +extern u8 gCritMultiplier; +extern u16 gBattleWeather; +extern struct BattleEnigmaBerry gEnigmaBerries[]; +extern u16 gBattleMovePower; +extern struct SpriteTemplate gUnknown_02024E8C; +extern u16 gTrainerBattleOpponent; +extern struct PokemonStorage gPokemonStorage; + +extern u8 gBadEggNickname[]; +extern u8 gEggNickname[]; +extern u32 gBitTable[]; +extern struct BaseStats gBaseStats[]; +extern u8 gSpeciesNames[][11]; +extern struct BattleMove gBattleMoves[]; +extern struct SpriteTemplate gSpriteTemplate_8208288[]; +extern union AmimCmd *gSpriteAnimTable_81E7C64[]; +extern union AnimCmd **gUnknown_081EC2A4[]; +extern union AnimCmd **gUnknown_081ECACC[]; +extern u8 gTrainerClassToPicIndex[]; +extern u8 gTrainerClassToNameIndex[]; +extern u8 gSecretBaseTrainerClasses[]; +extern u8 gUnknown_08208238[]; +extern u8 gUnknown_0820823C[]; +extern u8 gStatStageRatios[]; +extern u8 gHoldEffectToType[][2]; + +extern u8 battle_side_get_owner(u8); +extern u8 sub_8018324(u8, u8, u8, u8, u16); +extern u8 sub_803C348(u8); + +#define APPLY_STAT_MOD(var, mon, stat, statIndex) \ +{ \ + (var) = (stat) * (gStatStageRatios)[(mon)->statStages[(statIndex)] * 2]; \ + (var) /= (gStatStageRatios + 1)[(mon)->statStages[(statIndex)] * 2]; \ +} + +#ifdef NONMATCHING +s32 CalculateBaseDamage(struct BattlePokemon *attacker, struct BattlePokemon *defender, u32 move, u16 a4, u16 powerOverride, u8 typeOverride, u8 a7, u8 a8) +{ + s32 i; + s32 damage = 0; + u8 type; + u16 attack, defense; + u16 spAttack, spDefense; + u8 defenderHoldEffect; + u8 defenderHoldEffectParam; + u8 attackerHoldEffect; + u8 attackerHoldEffectParam; + s32 a, b; + + if (!powerOverride) + gBattleMovePower = gBattleMoves[move].power; + else + gBattleMovePower = powerOverride; + + if (!typeOverride) + type = gBattleMoves[move].type; + else + type = typeOverride & 0x3F; + + attack = attacker->attack; + defense = defender->defense; + spAttack = attacker->spAttack; + spDefense = defender->spDefense; + + if (attacker->item == ITEM_ENIGMA_BERRY) + { + attackerHoldEffect = gEnigmaBerries[a7].holdEffect; + attackerHoldEffectParam = gEnigmaBerries[a7].holdEffectParam; + } + else + { + attackerHoldEffect = ItemId_GetHoldEffect(attacker->item); + attackerHoldEffectParam = ItemId_GetHoldEffectParam(attacker->item); + } + + if (defender->item == ITEM_ENIGMA_BERRY) + { + defenderHoldEffect = gEnigmaBerries[a8].holdEffect; + defenderHoldEffectParam = gEnigmaBerries[a8].holdEffectParam; + } + else + { + defenderHoldEffect = ItemId_GetHoldEffect(defender->item); + defenderHoldEffectParam = ItemId_GetHoldEffectParam(defender->item); + } + + if (attacker->ability == ABILITY_HUGE_POWER || attacker->ability == ABILITY_PURE_POWER) + attack *= 2; + + if (!(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_BATTLE_TOWER | BATTLE_TYPE_EREADER_TRAINER))) + { + if ((gBattleTypeFlags & BATTLE_TYPE_TRAINER) + && gTrainerBattleOpponent != 1024 + && FlagGet(BADGE01_GET) + && !battle_side_get_owner(a7)) + attack = (110 * attack) / 100; + + if (!(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_BATTLE_TOWER | BATTLE_TYPE_EREADER_TRAINER))) + { + if ((gBattleTypeFlags & BATTLE_TYPE_TRAINER) + && gTrainerBattleOpponent != 1024 + && FlagGet(BADGE05_GET) + && !battle_side_get_owner(a8)) + defense = (110 * defense) / 100; + + if (!(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_BATTLE_TOWER | BATTLE_TYPE_EREADER_TRAINER))) + { + if ((gBattleTypeFlags & BATTLE_TYPE_TRAINER) + && gTrainerBattleOpponent != 1024 + && FlagGet(BADGE07_GET) + && !battle_side_get_owner(a7)) + spAttack = (110 * spAttack) / 100; + + if (!(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_BATTLE_TOWER | BATTLE_TYPE_EREADER_TRAINER))) + { + if ((gBattleTypeFlags & BATTLE_TYPE_TRAINER) + && gTrainerBattleOpponent != 1024 + && FlagGet(BADGE07_GET) + && !battle_side_get_owner(a8)) + spDefense = (110 * spDefense) / 100; + } + } + } + } + + for (i = 0; i < 17; i++) + { + if (attackerHoldEffect == gHoldEffectToType[i][0] + && type == gHoldEffectToType[i][1]) + { + if (type <= 8) + attack = (attack * (attackerHoldEffectParam + 100)) / 100; + else + spAttack = (spAttack * (attackerHoldEffectParam + 100)) / 100; + break; + } + } + + if (attackerHoldEffect == HOLD_EFFECT_CHOICE_BAND) + attack = (150 * attack) / 100; + if (attackerHoldEffect == HOLD_EFFECT_SOUL_DEW && !(gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER) && (attacker->species == SPECIES_LATIAS || attacker->species == SPECIES_LATIOS)) + spAttack = (150 * spAttack) / 100; + if (defenderHoldEffect == HOLD_EFFECT_SOUL_DEW && !(gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER) && (defender->species == SPECIES_LATIAS || defender->species == SPECIES_LATIOS)) + spDefense = (150 * spDefense) / 100; + if (attackerHoldEffect == HOLD_EFFECT_DEEP_SEA_TOOTH && attacker->species == SPECIES_CLAMPERL) + spAttack *= 2; + if (defenderHoldEffect == HOLD_EFFECT_DEEP_SEA_SCALE && defender->species == SPECIES_CLAMPERL) + spDefense *= 2; + if (attackerHoldEffect == HOLD_EFFECT_LIGHT_BALL && attacker->species == SPECIES_PIKACHU) + spAttack *= 2; + if (defenderHoldEffect == HOLD_EFFECT_METAL_POWDER && defender->species == SPECIES_DITTO) + defense *= 2; + if (attackerHoldEffect == HOLD_EFFECT_THICK_CLUB && (attacker->species == SPECIES_CUBONE || attacker->species == SPECIES_MAROWAK)) + attack *= 2; + if (defender->ability == ABILITY_THICK_FAT && (type == TYPE_FIRE || type == TYPE_ICE)) + spAttack /= 2; + if (attacker->ability == ABILITY_HUSTLE) + attack = (150 * attack) / 100; + if (attacker->ability == ABILITY_PLUS && sub_8018324(0xE, 0, ABILITY_MINUS, 0, 0)) + spAttack = (150 * spAttack) / 100; + if (attacker->ability == ABILITY_MINUS && sub_8018324(0xE, 0, ABILITY_PLUS, 0, 0)) + spAttack = (150 * spAttack) / 100; + if (attacker->ability == ABILITY_GUTS && attacker->status1) + attack = (150 * attack) / 100; + if (defender->ability == ABILITY_MARVEL_SCALE && defender->status1) + defense = (150 * defense) / 100; + if (type == TYPE_ELECTRIC && sub_8018324(0xE, 0, 0, 0xFD, 0)) + gBattleMovePower /= 2; + if (type == TYPE_FIRE && sub_8018324(0xE, 0, 0, 0xFE, 0)) + gBattleMovePower /= 2; + if (type == TYPE_GRASS && attacker->ability == ABILITY_OVERGROW && attacker->hp <= (attacker->maxHP / 3)) + gBattleMovePower = (150 * gBattleMovePower) / 100; + if (type == TYPE_FIRE && attacker->ability == ABILITY_BLAZE && attacker->hp <= (attacker->maxHP / 3)) + gBattleMovePower = (150 * gBattleMovePower) / 100; + if (type == TYPE_WATER && attacker->ability == ABILITY_TORRENT && attacker->hp <= (attacker->maxHP / 3)) + gBattleMovePower = (150 * gBattleMovePower) / 100; + if (type == TYPE_BUG && attacker->ability == ABILITY_SWARM && attacker->hp <= (attacker->maxHP / 3)) + gBattleMovePower = (150 * gBattleMovePower) / 100; + if (gBattleMoves[gUnknown_02024BE6].effect == 7) + defense /= 2; + + if (type < TYPE_MYSTERY) // is physical? + { + if (gCritMultiplier == 2) + { + if (attacker->statStages[1] > 6) + APPLY_STAT_MOD(a, attacker, attack, 1) + else + a = attack; + } + else + APPLY_STAT_MOD(a, attacker, attack, 1) + + a = a * gBattleMovePower * (2 * attacker->level / 5 + 2); + + if (gCritMultiplier == 2) + { + if (defender->statStages[2] < 6) + APPLY_STAT_MOD(b, defender, defense, 2) + else + b = defense; + } + else + APPLY_STAT_MOD(b, defender, defense, 2) + + damage = (a / b) / 50; + + if ((attacker->status1 & 0x10) && attacker->ability != ABILITY_GUTS) + damage /= 2; + + if ((a4 & 1) && gCritMultiplier == 1) + { + if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) && sub_803C348(2) == 2) + damage = 2 * (damage / 3); + else + damage /= 2; + } + + if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) && gBattleMoves[move].target == 8 && sub_803C348(2) == 2) + damage /= 2; + + // moves always do at least 1 damage. + if (damage == 0) + damage = 1; + } + + if (type == TYPE_MYSTERY) + damage = 0; // is ??? type. does 0 damage. + + if (type > TYPE_MYSTERY) // is special? + { + if (gCritMultiplier == 2) + { + if (attacker->statStages[4] > 6) + APPLY_STAT_MOD(a, attacker, spAttack, 4) + else + a = spAttack; + } + else + APPLY_STAT_MOD(a, attacker, spAttack, 4) + + a = a * gBattleMovePower * (2 * attacker->level / 5 + 2); + + if (gCritMultiplier == 2) + { + if (defender->statStages[5] < 6) + APPLY_STAT_MOD(b, defender, spDefense, 5) + else + b = spDefense; + } + else + APPLY_STAT_MOD(b, defender, spDefense, 5) + + damage = (a / b) / 50; + + if ((a4 & 2) && gCritMultiplier == 1) + { + if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) && sub_803C348(2) == 2) + damage = 2 * (damage / 3); + else + damage /= 2; + } + + if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) && gBattleMoves[move].target == 8 && sub_803C348(2) == 2) + damage /= 2; + + // are effects of weather negated with cloud nine or air lock? + if (!sub_8018324(0xE, 0, ABILITY_CLOUD_NINE, 0, 0) && !sub_8018324(0xE, 0, ABILITY_AIR_LOCK, 0, 0)) + { + // rain? + if (gBattleWeather & 1) + { + if (type == TYPE_FIRE) + damage /= 2; + else if (type == TYPE_WATER) + damage = (15 * damage) / 10; + } + + // does lack of sun half solar beam damage? + if ((gBattleWeather & 0x9F) && gUnknown_02024BE6 == 76) + damage /= 2; + + // sunny? + if (gBattleWeather & 0x60) + { + if (type == TYPE_FIRE) + damage = (15 * damage) / 10; + else if (type == TYPE_WATER) + damage /= 2; + } + } + + // flash fire triggered? + if ((dword_2017100[a7] & 1) && type == TYPE_FIRE) + damage = (15 * damage) / 10; + } + + return damage + 2; +} +#else +__attribute__((naked)) +s32 CalculateBaseDamage(struct BattlePokemon *attacker, struct BattlePokemon *defender, u32 move, u16 a4, u16 powerOverride, u8 typeOverride, u8 a7, u8 a8) +{ + 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, 0x2C\n\ + adds r7, r0, 0\n\ + str r1, [sp, 0x4]\n\ + str r2, [sp, 0x8]\n\ + ldr r0, [sp, 0x4C]\n\ + ldr r1, [sp, 0x50]\n\ + ldr r2, [sp, 0x54]\n\ + ldr r4, [sp, 0x58]\n\ + lsls r3, 16\n\ + lsrs r3, 16\n\ + str r3, [sp, 0xC]\n\ + lsls r0, 16\n\ + lsrs r3, r0, 16\n\ + lsls r1, 24\n\ + lsrs r6, r1, 24\n\ + lsls r2, 24\n\ + lsrs r2, 24\n\ + str r2, [sp, 0x10]\n\ + lsls r4, 24\n\ + lsrs r4, 24\n\ + movs r5, 0\n\ + cmp r3, 0\n\ + bne _0803BA80\n\ + ldr r2, _0803BA78 @ =gBattleMovePower\n\ + ldr r1, _0803BA7C @ =gBattleMoves\n\ + ldr r3, [sp, 0x8]\n\ + lsls r0, r3, 1\n\ + adds r0, r3\n\ + lsls r0, 2\n\ + adds r0, r1\n\ + ldrb r0, [r0, 0x1]\n\ + strh r0, [r2]\n\ + b _0803BA84\n\ + .align 2, 0\n\ +_0803BA78: .4byte gBattleMovePower\n\ +_0803BA7C: .4byte gBattleMoves\n\ +_0803BA80:\n\ + ldr r0, _0803BA9C @ =gBattleMovePower\n\ + strh r3, [r0]\n\ +_0803BA84:\n\ + cmp r6, 0\n\ + bne _0803BAA4\n\ + ldr r1, _0803BAA0 @ =gBattleMoves\n\ + ldr r6, [sp, 0x8]\n\ + lsls r0, r6, 1\n\ + adds r0, r6\n\ + lsls r0, 2\n\ + adds r0, r1\n\ + ldrb r0, [r0, 0x2]\n\ + mov r9, r0\n\ + b _0803BAAE\n\ + .align 2, 0\n\ +_0803BA9C: .4byte gBattleMovePower\n\ +_0803BAA0: .4byte gBattleMoves\n\ +_0803BAA4:\n\ + movs r0, 0x3F\n\ + mov r9, r0\n\ + mov r1, r9\n\ + ands r1, r6\n\ + mov r9, r1\n\ +_0803BAAE:\n\ + ldrh r6, [r7, 0x2]\n\ + ldr r2, [sp, 0x4]\n\ + ldrh r2, [r2, 0x4]\n\ + str r2, [sp, 0x14]\n\ + ldrh r3, [r7, 0x8]\n\ + mov r8, r3\n\ + ldr r0, [sp, 0x4]\n\ + ldrh r0, [r0, 0xA]\n\ + str r0, [sp, 0x18]\n\ + ldrh r0, [r7, 0x2E]\n\ + cmp r0, 0xAF\n\ + bne _0803BAE0\n\ + ldr r1, _0803BADC @ =gEnigmaBerries\n\ + ldr r2, [sp, 0x10]\n\ + lsls r0, r2, 3\n\ + subs r0, r2\n\ + lsls r0, 2\n\ + adds r0, r1\n\ + ldrb r3, [r0, 0x7]\n\ + mov r10, r3\n\ + ldrb r0, [r0, 0x1A]\n\ + b _0803BAF6\n\ + .align 2, 0\n\ +_0803BADC: .4byte gEnigmaBerries\n\ +_0803BAE0:\n\ + ldrh r0, [r7, 0x2E]\n\ + bl ItemId_GetHoldEffect\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + mov r10, r0\n\ + ldrh r0, [r7, 0x2E]\n\ + bl ItemId_GetHoldEffectParam\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ +_0803BAF6:\n\ + str r0, [sp, 0x20]\n\ + ldr r1, [sp, 0x4]\n\ + ldrh r0, [r1, 0x2E]\n\ + cmp r0, 0xAF\n\ + bne _0803BB26\n\ + ldr r1, _0803BB10 @ =gEnigmaBerries\n\ + lsls r0, r4, 3\n\ + subs r0, r4\n\ + lsls r0, 2\n\ + adds r0, r1\n\ + ldrb r0, [r0, 0x7]\n\ + str r0, [sp, 0x1C]\n\ + b _0803BB3C\n\ + .align 2, 0\n\ +_0803BB10: .4byte gEnigmaBerries\n\ +_0803BB14:\n\ + ldr r0, [sp, 0x20]\n\ + adds r0, 0x64\n\ + muls r0, r6\n\ + movs r1, 0x64\n\ + bl __divsi3\n\ + lsls r0, 16\n\ + lsrs r6, r0, 16\n\ + b _0803BCDC\n\ +_0803BB26:\n\ + ldr r2, [sp, 0x4]\n\ + ldrh r0, [r2, 0x2E]\n\ + bl ItemId_GetHoldEffect\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + str r0, [sp, 0x1C]\n\ + ldr r3, [sp, 0x4]\n\ + ldrh r0, [r3, 0x2E]\n\ + bl ItemId_GetHoldEffectParam\n\ +_0803BB3C:\n\ + adds r0, r7, 0\n\ + adds r0, 0x20\n\ + ldrb r1, [r0]\n\ + str r0, [sp, 0x24]\n\ + cmp r1, 0x25\n\ + beq _0803BB4C\n\ + cmp r1, 0x4A\n\ + bne _0803BB50\n\ +_0803BB4C:\n\ + lsls r0, r6, 17\n\ + lsrs r6, r0, 16\n\ +_0803BB50:\n\ + ldr r0, _0803BCB8 @ =gBattleTypeFlags\n\ + ldrh r1, [r0]\n\ + ldr r0, _0803BCBC @ =0x00000902\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _0803BB5E\n\ + b _0803BC78\n\ +_0803BB5E:\n\ + movs r0, 0x8\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _0803BB98\n\ + ldr r0, _0803BCC0 @ =gTrainerBattleOpponent\n\ + ldrh r1, [r0]\n\ + movs r0, 0x80\n\ + lsls r0, 3\n\ + cmp r1, r0\n\ + beq _0803BB98\n\ + ldr r0, _0803BCC4 @ =0x00000807\n\ + bl FlagGet\n\ + lsls r0, 24\n\ + cmp r0, 0\n\ + beq _0803BB98\n\ + ldr r0, [sp, 0x10]\n\ + bl battle_side_get_owner\n\ + lsls r0, 24\n\ + cmp r0, 0\n\ + bne _0803BB98\n\ + movs r0, 0x6E\n\ + muls r0, r6\n\ + movs r1, 0x64\n\ + bl __divsi3\n\ + lsls r0, 16\n\ + lsrs r6, r0, 16\n\ +_0803BB98:\n\ + ldr r0, _0803BCB8 @ =gBattleTypeFlags\n\ + ldrh r1, [r0]\n\ + ldr r0, _0803BCBC @ =0x00000902\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + bne _0803BC78\n\ + movs r0, 0x8\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _0803BBE2\n\ + ldr r0, _0803BCC0 @ =gTrainerBattleOpponent\n\ + ldrh r1, [r0]\n\ + movs r0, 0x80\n\ + lsls r0, 3\n\ + cmp r1, r0\n\ + beq _0803BBE2\n\ + ldr r0, _0803BCC8 @ =0x0000080b\n\ + bl FlagGet\n\ + lsls r0, 24\n\ + cmp r0, 0\n\ + beq _0803BBE2\n\ + adds r0, r4, 0\n\ + bl battle_side_get_owner\n\ + lsls r0, 24\n\ + cmp r0, 0\n\ + bne _0803BBE2\n\ + movs r0, 0x6E\n\ + ldr r1, [sp, 0x14]\n\ + muls r0, r1\n\ + movs r1, 0x64\n\ + bl __divsi3\n\ + lsls r0, 16\n\ + lsrs r0, 16\n\ + str r0, [sp, 0x14]\n\ +_0803BBE2:\n\ + ldr r0, _0803BCB8 @ =gBattleTypeFlags\n\ + ldrh r1, [r0]\n\ + ldr r0, _0803BCBC @ =0x00000902\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + bne _0803BC78\n\ + movs r0, 0x8\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _0803BC2E\n\ + ldr r0, _0803BCC0 @ =gTrainerBattleOpponent\n\ + ldrh r1, [r0]\n\ + movs r0, 0x80\n\ + lsls r0, 3\n\ + cmp r1, r0\n\ + beq _0803BC2E\n\ + ldr r0, _0803BCCC @ =0x0000080d\n\ + bl FlagGet\n\ + lsls r0, 24\n\ + cmp r0, 0\n\ + beq _0803BC2E\n\ + ldr r0, [sp, 0x10]\n\ + bl battle_side_get_owner\n\ + lsls r0, 24\n\ + cmp r0, 0\n\ + bne _0803BC2E\n\ + movs r0, 0x6E\n\ + mov r2, r8\n\ + muls r2, r0\n\ + adds r0, r2, 0\n\ + movs r1, 0x64\n\ + bl __divsi3\n\ + lsls r0, 16\n\ + lsrs r0, 16\n\ + mov r8, r0\n\ +_0803BC2E:\n\ + ldr r0, _0803BCB8 @ =gBattleTypeFlags\n\ + ldrh r1, [r0]\n\ + ldr r0, _0803BCBC @ =0x00000902\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + bne _0803BC78\n\ + movs r0, 0x8\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _0803BC78\n\ + ldr r0, _0803BCC0 @ =gTrainerBattleOpponent\n\ + ldrh r1, [r0]\n\ + movs r0, 0x80\n\ + lsls r0, 3\n\ + cmp r1, r0\n\ + beq _0803BC78\n\ + ldr r0, _0803BCCC @ =0x0000080d\n\ + bl FlagGet\n\ + lsls r0, 24\n\ + cmp r0, 0\n\ + beq _0803BC78\n\ + adds r0, r4, 0\n\ + bl battle_side_get_owner\n\ + lsls r0, 24\n\ + cmp r0, 0\n\ + bne _0803BC78\n\ + movs r0, 0x6E\n\ + ldr r3, [sp, 0x18]\n\ + muls r0, r3\n\ + movs r1, 0x64\n\ + bl __divsi3\n\ + lsls r0, 16\n\ + lsrs r0, 16\n\ + str r0, [sp, 0x18]\n\ +_0803BC78:\n\ + movs r2, 0\n\ + ldr r4, _0803BCD0 @ =gHoldEffectToType\n\ + ldr r0, [sp, 0x4]\n\ + adds r0, 0x20\n\ + str r0, [sp, 0x28]\n\ + adds r3, r4, 0\n\ +_0803BC84:\n\ + lsls r1, r2, 1\n\ + ldrb r0, [r3]\n\ + cmp r10, r0\n\ + bne _0803BCD4\n\ + adds r0, r4, 0x1\n\ + adds r0, r1, r0\n\ + ldrb r0, [r0]\n\ + cmp r9, r0\n\ + bne _0803BCD4\n\ + mov r1, r9\n\ + cmp r1, 0x8\n\ + bhi _0803BC9E\n\ + b _0803BB14\n\ +_0803BC9E:\n\ + ldr r0, [sp, 0x20]\n\ + adds r0, 0x64\n\ + mov r2, r8\n\ + muls r2, r0\n\ + adds r0, r2, 0\n\ + movs r1, 0x64\n\ + bl __divsi3\n\ + lsls r0, 16\n\ + lsrs r0, 16\n\ + mov r8, r0\n\ + b _0803BCDC\n\ + .align 2, 0\n\ +_0803BCB8: .4byte gBattleTypeFlags\n\ +_0803BCBC: .4byte 0x00000902\n\ +_0803BCC0: .4byte gTrainerBattleOpponent\n\ +_0803BCC4: .4byte 0x00000807\n\ +_0803BCC8: .4byte 0x0000080b\n\ +_0803BCCC: .4byte 0x0000080d\n\ +_0803BCD0: .4byte gHoldEffectToType\n\ +_0803BCD4:\n\ + adds r3, 0x2\n\ + adds r2, 0x1\n\ + cmp r2, 0x10\n\ + bls _0803BC84\n\ +_0803BCDC:\n\ + mov r3, r10\n\ + cmp r3, 0x1D\n\ + bne _0803BCF0\n\ + movs r0, 0x96\n\ + muls r0, r6\n\ + movs r1, 0x64\n\ + bl __divsi3\n\ + lsls r0, 16\n\ + lsrs r6, r0, 16\n\ +_0803BCF0:\n\ + mov r0, r10\n\ + cmp r0, 0x22\n\ + bne _0803BD28\n\ + ldr r0, _0803BFDC @ =gBattleTypeFlags\n\ + ldrh r1, [r0]\n\ + movs r0, 0x80\n\ + lsls r0, 1\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + bne _0803BD28\n\ + ldr r1, _0803BFE0 @ =0xfffffe69\n\ + adds r0, r1, 0\n\ + ldrh r2, [r7]\n\ + adds r0, r2\n\ + lsls r0, 16\n\ + lsrs r0, 16\n\ + cmp r0, 0x1\n\ + bhi _0803BD28\n\ + movs r0, 0x96\n\ + mov r3, r8\n\ + muls r3, r0\n\ + adds r0, r3, 0\n\ + movs r1, 0x64\n\ + bl __divsi3\n\ + lsls r0, 16\n\ + lsrs r0, 16\n\ + mov r8, r0\n\ +_0803BD28:\n\ + ldr r0, [sp, 0x1C]\n\ + cmp r0, 0x22\n\ + bne _0803BD60\n\ + ldr r0, _0803BFDC @ =gBattleTypeFlags\n\ + ldrh r1, [r0]\n\ + movs r0, 0x80\n\ + lsls r0, 1\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + bne _0803BD60\n\ + ldr r1, _0803BFE0 @ =0xfffffe69\n\ + adds r0, r1, 0\n\ + ldr r2, [sp, 0x4]\n\ + ldrh r2, [r2]\n\ + adds r0, r2\n\ + lsls r0, 16\n\ + lsrs r0, 16\n\ + cmp r0, 0x1\n\ + bhi _0803BD60\n\ + movs r0, 0x96\n\ + ldr r3, [sp, 0x18]\n\ + muls r0, r3\n\ + movs r1, 0x64\n\ + bl __divsi3\n\ + lsls r0, 16\n\ + lsrs r0, 16\n\ + str r0, [sp, 0x18]\n\ +_0803BD60:\n\ + mov r0, r10\n\ + cmp r0, 0x23\n\ + bne _0803BD76\n\ + ldrh r1, [r7]\n\ + ldr r0, _0803BFE4 @ =0x00000175\n\ + cmp r1, r0\n\ + bne _0803BD76\n\ + mov r1, r8\n\ + lsls r0, r1, 17\n\ + lsrs r0, 16\n\ + mov r8, r0\n\ +_0803BD76:\n\ + ldr r2, [sp, 0x1C]\n\ + cmp r2, 0x24\n\ + bne _0803BD8E\n\ + ldr r3, [sp, 0x4]\n\ + ldrh r1, [r3]\n\ + ldr r0, _0803BFE4 @ =0x00000175\n\ + cmp r1, r0\n\ + bne _0803BD8E\n\ + ldr r1, [sp, 0x18]\n\ + lsls r0, r1, 17\n\ + lsrs r0, 16\n\ + str r0, [sp, 0x18]\n\ +_0803BD8E:\n\ + mov r2, r10\n\ + cmp r2, 0x2D\n\ + bne _0803BDA2\n\ + ldrh r0, [r7]\n\ + cmp r0, 0x19\n\ + bne _0803BDA2\n\ + mov r3, r8\n\ + lsls r0, r3, 17\n\ + lsrs r0, 16\n\ + mov r8, r0\n\ +_0803BDA2:\n\ + ldr r0, [sp, 0x1C]\n\ + cmp r0, 0x40\n\ + bne _0803BDB8\n\ + ldr r1, [sp, 0x4]\n\ + ldrh r0, [r1]\n\ + cmp r0, 0x84\n\ + bne _0803BDB8\n\ + ldr r2, [sp, 0x14]\n\ + lsls r0, r2, 17\n\ + lsrs r0, 16\n\ + str r0, [sp, 0x14]\n\ +_0803BDB8:\n\ + mov r3, r10\n\ + cmp r3, 0x41\n\ + bne _0803BDCE\n\ + ldrh r0, [r7]\n\ + subs r0, 0x68\n\ + lsls r0, 16\n\ + lsrs r0, 16\n\ + cmp r0, 0x1\n\ + bhi _0803BDCE\n\ + lsls r0, r6, 17\n\ + lsrs r6, r0, 16\n\ +_0803BDCE:\n\ + ldr r1, [sp, 0x28]\n\ + ldrb r0, [r1]\n\ + cmp r0, 0x2F\n\ + bne _0803BDE6\n\ + mov r2, r9\n\ + cmp r2, 0xA\n\ + beq _0803BDE0\n\ + cmp r2, 0xF\n\ + bne _0803BDE6\n\ +_0803BDE0:\n\ + mov r3, r8\n\ + lsrs r3, 1\n\ + mov r8, r3\n\ +_0803BDE6:\n\ + ldr r0, [sp, 0x24]\n\ + ldrb r4, [r0]\n\ + cmp r4, 0x37\n\ + bne _0803BDFC\n\ + movs r0, 0x96\n\ + muls r0, r6\n\ + movs r1, 0x64\n\ + bl __divsi3\n\ + lsls r0, 16\n\ + lsrs r6, r0, 16\n\ +_0803BDFC:\n\ + cmp r4, 0x39\n\ + bne _0803BE2A\n\ + movs r0, 0\n\ + str r0, [sp]\n\ + movs r0, 0xE\n\ + movs r1, 0\n\ + movs r2, 0x3A\n\ + movs r3, 0\n\ + bl sub_8018324\n\ + lsls r0, 24\n\ + cmp r0, 0\n\ + beq _0803BE2A\n\ + movs r0, 0x96\n\ + mov r1, r8\n\ + muls r1, r0\n\ + adds r0, r1, 0\n\ + movs r1, 0x64\n\ + bl __divsi3\n\ + lsls r0, 16\n\ + lsrs r0, 16\n\ + mov r8, r0\n\ +_0803BE2A:\n\ + ldr r2, [sp, 0x24]\n\ + ldrb r0, [r2]\n\ + cmp r0, 0x3A\n\ + bne _0803BE5C\n\ + movs r0, 0\n\ + str r0, [sp]\n\ + movs r0, 0xE\n\ + movs r1, 0\n\ + movs r2, 0x39\n\ + movs r3, 0\n\ + bl sub_8018324\n\ + lsls r0, 24\n\ + cmp r0, 0\n\ + beq _0803BE5C\n\ + movs r0, 0x96\n\ + mov r3, r8\n\ + muls r3, r0\n\ + adds r0, r3, 0\n\ + movs r1, 0x64\n\ + bl __divsi3\n\ + lsls r0, 16\n\ + lsrs r0, 16\n\ + mov r8, r0\n\ +_0803BE5C:\n\ + ldr r1, [sp, 0x24]\n\ + ldrb r0, [r1]\n\ + cmp r0, 0x3E\n\ + bne _0803BE78\n\ + ldr r0, [r7, 0x4C]\n\ + cmp r0, 0\n\ + beq _0803BE78\n\ + movs r0, 0x96\n\ + muls r0, r6\n\ + movs r1, 0x64\n\ + bl __divsi3\n\ + lsls r0, 16\n\ + lsrs r6, r0, 16\n\ +_0803BE78:\n\ + ldr r2, [sp, 0x28]\n\ + ldrb r0, [r2]\n\ + cmp r0, 0x3F\n\ + bne _0803BE9A\n\ + ldr r3, [sp, 0x4]\n\ + ldr r0, [r3, 0x4C]\n\ + cmp r0, 0\n\ + beq _0803BE9A\n\ + movs r0, 0x96\n\ + ldr r1, [sp, 0x14]\n\ + muls r0, r1\n\ + movs r1, 0x64\n\ + bl __divsi3\n\ + lsls r0, 16\n\ + lsrs r0, 16\n\ + str r0, [sp, 0x14]\n\ +_0803BE9A:\n\ + mov r2, r9\n\ + cmp r2, 0xD\n\ + bne _0803BEBE\n\ + movs r0, 0\n\ + str r0, [sp]\n\ + movs r0, 0xE\n\ + movs r1, 0\n\ + movs r2, 0\n\ + movs r3, 0xFD\n\ + bl sub_8018324\n\ + lsls r0, 24\n\ + cmp r0, 0\n\ + beq _0803BEBE\n\ + ldr r1, _0803BFE8 @ =gBattleMovePower\n\ + ldrh r0, [r1]\n\ + lsrs r0, 1\n\ + strh r0, [r1]\n\ +_0803BEBE:\n\ + mov r3, r9\n\ + cmp r3, 0xA\n\ + bne _0803BEE2\n\ + movs r0, 0\n\ + str r0, [sp]\n\ + movs r0, 0xE\n\ + movs r1, 0\n\ + movs r2, 0\n\ + movs r3, 0xFE\n\ + bl sub_8018324\n\ + lsls r0, 24\n\ + cmp r0, 0\n\ + beq _0803BEE2\n\ + ldr r1, _0803BFE8 @ =gBattleMovePower\n\ + ldrh r0, [r1]\n\ + lsrs r0, 1\n\ + strh r0, [r1]\n\ +_0803BEE2:\n\ + mov r0, r9\n\ + cmp r0, 0xC\n\ + bne _0803BF12\n\ + ldr r1, [sp, 0x24]\n\ + ldrb r0, [r1]\n\ + cmp r0, 0x41\n\ + bne _0803BF12\n\ + ldrh r0, [r7, 0x2C]\n\ + movs r1, 0x3\n\ + bl __udivsi3\n\ + ldrh r1, [r7, 0x28]\n\ + lsls r0, 16\n\ + lsrs r0, 16\n\ + cmp r1, r0\n\ + bhi _0803BF12\n\ + ldr r4, _0803BFE8 @ =gBattleMovePower\n\ + ldrh r1, [r4]\n\ + movs r0, 0x96\n\ + muls r0, r1\n\ + movs r1, 0x64\n\ + bl __divsi3\n\ + strh r0, [r4]\n\ +_0803BF12:\n\ + mov r2, r9\n\ + cmp r2, 0xA\n\ + bne _0803BF42\n\ + ldr r3, [sp, 0x24]\n\ + ldrb r0, [r3]\n\ + cmp r0, 0x42\n\ + bne _0803BF42\n\ + ldrh r0, [r7, 0x2C]\n\ + movs r1, 0x3\n\ + bl __udivsi3\n\ + ldrh r1, [r7, 0x28]\n\ + lsls r0, 16\n\ + lsrs r0, 16\n\ + cmp r1, r0\n\ + bhi _0803BF42\n\ + ldr r4, _0803BFE8 @ =gBattleMovePower\n\ + ldrh r1, [r4]\n\ + movs r0, 0x96\n\ + muls r0, r1\n\ + movs r1, 0x64\n\ + bl __divsi3\n\ + strh r0, [r4]\n\ +_0803BF42:\n\ + mov r0, r9\n\ + cmp r0, 0xB\n\ + bne _0803BF72\n\ + ldr r1, [sp, 0x24]\n\ + ldrb r0, [r1]\n\ + cmp r0, 0x43\n\ + bne _0803BF72\n\ + ldrh r0, [r7, 0x2C]\n\ + movs r1, 0x3\n\ + bl __udivsi3\n\ + ldrh r1, [r7, 0x28]\n\ + lsls r0, 16\n\ + lsrs r0, 16\n\ + cmp r1, r0\n\ + bhi _0803BF72\n\ + ldr r4, _0803BFE8 @ =gBattleMovePower\n\ + ldrh r1, [r4]\n\ + movs r0, 0x96\n\ + muls r0, r1\n\ + movs r1, 0x64\n\ + bl __divsi3\n\ + strh r0, [r4]\n\ +_0803BF72:\n\ + mov r2, r9\n\ + cmp r2, 0x6\n\ + bne _0803BFA2\n\ + ldr r3, [sp, 0x24]\n\ + ldrb r0, [r3]\n\ + cmp r0, 0x44\n\ + bne _0803BFA2\n\ + ldrh r0, [r7, 0x2C]\n\ + movs r1, 0x3\n\ + bl __udivsi3\n\ + ldrh r1, [r7, 0x28]\n\ + lsls r0, 16\n\ + lsrs r0, 16\n\ + cmp r1, r0\n\ + bhi _0803BFA2\n\ + ldr r4, _0803BFE8 @ =gBattleMovePower\n\ + ldrh r1, [r4]\n\ + movs r0, 0x96\n\ + muls r0, r1\n\ + movs r1, 0x64\n\ + bl __divsi3\n\ + strh r0, [r4]\n\ +_0803BFA2:\n\ + ldr r2, _0803BFEC @ =gBattleMoves\n\ + ldr r0, _0803BFF0 @ =gUnknown_02024BE6\n\ + ldrh r1, [r0]\n\ + lsls r0, r1, 1\n\ + adds r0, r1\n\ + lsls r0, 2\n\ + adds r0, r2\n\ + ldrb r0, [r0]\n\ + cmp r0, 0x7\n\ + bne _0803BFBC\n\ + ldr r0, [sp, 0x14]\n\ + lsrs r0, 1\n\ + str r0, [sp, 0x14]\n\ +_0803BFBC:\n\ + mov r1, r9\n\ + cmp r1, 0x8\n\ + bls _0803BFC4\n\ + b _0803C122\n\ +_0803BFC4:\n\ + ldr r0, _0803BFF4 @ =gCritMultiplier\n\ + ldrb r1, [r0]\n\ + adds r4, r0, 0\n\ + cmp r1, 0x2\n\ + bne _0803C000\n\ + movs r0, 0x19\n\ + ldrsb r0, [r7, r0]\n\ + cmp r0, 0x6\n\ + ble _0803BFFC\n\ + ldr r2, _0803BFF8 @ =gStatStageRatios\n\ + b _0803C006\n\ + .align 2, 0\n\ +_0803BFDC: .4byte gBattleTypeFlags\n\ +_0803BFE0: .4byte 0xfffffe69\n\ +_0803BFE4: .4byte 0x00000175\n\ +_0803BFE8: .4byte gBattleMovePower\n\ +_0803BFEC: .4byte gBattleMoves\n\ +_0803BFF0: .4byte gUnknown_02024BE6\n\ +_0803BFF4: .4byte gCritMultiplier\n\ +_0803BFF8: .4byte gStatStageRatios\n\ +_0803BFFC:\n\ + adds r5, r6, 0\n\ + b _0803C01E\n\ +_0803C000:\n\ + ldr r2, _0803C050 @ =gStatStageRatios\n\ + movs r0, 0x19\n\ + ldrsb r0, [r7, r0]\n\ +_0803C006:\n\ + lsls r0, 1\n\ + adds r1, r0, r2\n\ + ldrb r1, [r1]\n\ + adds r5, r6, 0\n\ + muls r5, r1\n\ + adds r2, 0x1\n\ + adds r0, r2\n\ + ldrb r1, [r0]\n\ + adds r0, r5, 0\n\ + bl __divsi3\n\ + adds r5, r0, 0\n\ +_0803C01E:\n\ + ldr r0, _0803C054 @ =gBattleMovePower\n\ + ldrh r0, [r0]\n\ + muls r5, r0\n\ + adds r0, r7, 0\n\ + adds r0, 0x2A\n\ + ldrb r0, [r0]\n\ + lsls r0, 1\n\ + movs r1, 0x5\n\ + bl __divsi3\n\ + adds r0, 0x2\n\ + muls r5, r0\n\ + ldrb r0, [r4]\n\ + cmp r0, 0x2\n\ + bne _0803C05C\n\ + ldr r2, [sp, 0x4]\n\ + movs r0, 0x1A\n\ + ldrsb r0, [r2, r0]\n\ + cmp r0, 0x5\n\ + bgt _0803C058\n\ + ldr r2, _0803C050 @ =gStatStageRatios\n\ + ldr r3, [sp, 0x4]\n\ + movs r0, 0x1A\n\ + ldrsb r0, [r3, r0]\n\ + b _0803C064\n\ + .align 2, 0\n\ +_0803C050: .4byte gStatStageRatios\n\ +_0803C054: .4byte gBattleMovePower\n\ +_0803C058:\n\ + ldr r3, [sp, 0x14]\n\ + b _0803C07E\n\ +_0803C05C:\n\ + ldr r2, _0803C0DC @ =gStatStageRatios\n\ + ldr r1, [sp, 0x4]\n\ + movs r0, 0x1A\n\ + ldrsb r0, [r1, r0]\n\ +_0803C064:\n\ + lsls r0, 1\n\ + adds r1, r0, r2\n\ + ldrb r1, [r1]\n\ + ldr r6, [sp, 0x14]\n\ + adds r3, r6, 0\n\ + muls r3, r1\n\ + adds r2, 0x1\n\ + adds r0, r2\n\ + ldrb r1, [r0]\n\ + adds r0, r3, 0\n\ + bl __divsi3\n\ + adds r3, r0, 0\n\ +_0803C07E:\n\ + adds r0, r5, 0\n\ + adds r1, r3, 0\n\ + bl __divsi3\n\ + adds r5, r0, 0\n\ + movs r1, 0x32\n\ + bl __divsi3\n\ + adds r5, r0, 0\n\ + ldr r0, [r7, 0x4C]\n\ + movs r1, 0x10\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _0803C0A8\n\ + ldr r1, [sp, 0x24]\n\ + ldrb r0, [r1]\n\ + cmp r0, 0x3E\n\ + beq _0803C0A8\n\ + lsrs r0, r5, 31\n\ + adds r0, r5, r0\n\ + asrs r5, r0, 1\n\ +_0803C0A8:\n\ + movs r0, 0x1\n\ + ldr r2, [sp, 0xC]\n\ + ands r0, r2\n\ + cmp r0, 0\n\ + beq _0803C0EA\n\ + ldrb r1, [r4]\n\ + cmp r1, 0x1\n\ + bne _0803C0EA\n\ + ldr r0, _0803C0E0 @ =gBattleTypeFlags\n\ + ldrh r0, [r0]\n\ + ands r1, r0\n\ + cmp r1, 0\n\ + beq _0803C0E4\n\ + movs r0, 0x2\n\ + bl sub_803C348\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + cmp r0, 0x2\n\ + bne _0803C0E4\n\ + adds r0, r5, 0\n\ + movs r1, 0x3\n\ + bl __divsi3\n\ + lsls r5, r0, 1\n\ + b _0803C0EA\n\ + .align 2, 0\n\ +_0803C0DC: .4byte gStatStageRatios\n\ +_0803C0E0: .4byte gBattleTypeFlags\n\ +_0803C0E4:\n\ + lsrs r0, r5, 31\n\ + adds r0, r5, r0\n\ + asrs r5, r0, 1\n\ +_0803C0EA:\n\ + ldr r0, _0803C148 @ =gBattleTypeFlags\n\ + ldrh r1, [r0]\n\ + movs r0, 0x1\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _0803C11C\n\ + ldr r0, _0803C14C @ =gBattleMoves\n\ + ldr r3, [sp, 0x8]\n\ + lsls r1, r3, 1\n\ + adds r1, r3\n\ + lsls r1, 2\n\ + adds r1, r0\n\ + ldrb r0, [r1, 0x6]\n\ + cmp r0, 0x8\n\ + bne _0803C11C\n\ + movs r0, 0x2\n\ + bl sub_803C348\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + cmp r0, 0x2\n\ + bne _0803C11C\n\ + lsrs r0, r5, 31\n\ + adds r0, r5, r0\n\ + asrs r5, r0, 1\n\ +_0803C11C:\n\ + cmp r5, 0\n\ + bne _0803C122\n\ + movs r5, 0x1\n\ +_0803C122:\n\ + mov r6, r9\n\ + cmp r6, 0x9\n\ + bne _0803C12A\n\ + movs r5, 0\n\ +_0803C12A:\n\ + mov r0, r9\n\ + cmp r0, 0x9\n\ + bhi _0803C132\n\ + b _0803C330\n\ +_0803C132:\n\ + ldr r0, _0803C150 @ =gCritMultiplier\n\ + ldrb r1, [r0]\n\ + adds r4, r0, 0\n\ + cmp r1, 0x2\n\ + bne _0803C15C\n\ + movs r0, 0x1C\n\ + ldrsb r0, [r7, r0]\n\ + cmp r0, 0x6\n\ + ble _0803C158\n\ + ldr r2, _0803C154 @ =gStatStageRatios\n\ + b _0803C162\n\ + .align 2, 0\n\ +_0803C148: .4byte gBattleTypeFlags\n\ +_0803C14C: .4byte gBattleMoves\n\ +_0803C150: .4byte gCritMultiplier\n\ +_0803C154: .4byte gStatStageRatios\n\ +_0803C158:\n\ + mov r5, r8\n\ + b _0803C17A\n\ +_0803C15C:\n\ + ldr r2, _0803C1A8 @ =gStatStageRatios\n\ + movs r0, 0x1C\n\ + ldrsb r0, [r7, r0]\n\ +_0803C162:\n\ + lsls r0, 1\n\ + adds r1, r0, r2\n\ + ldrb r1, [r1]\n\ + mov r5, r8\n\ + muls r5, r1\n\ + adds r2, 0x1\n\ + adds r0, r2\n\ + ldrb r1, [r0]\n\ + adds r0, r5, 0\n\ + bl __divsi3\n\ + adds r5, r0, 0\n\ +_0803C17A:\n\ + ldr r0, _0803C1AC @ =gBattleMovePower\n\ + ldrh r0, [r0]\n\ + muls r5, r0\n\ + adds r0, r7, 0\n\ + adds r0, 0x2A\n\ + ldrb r0, [r0]\n\ + lsls r0, 1\n\ + movs r1, 0x5\n\ + bl __divsi3\n\ + adds r0, 0x2\n\ + muls r5, r0\n\ + ldrb r0, [r4]\n\ + cmp r0, 0x2\n\ + bne _0803C1B4\n\ + ldr r1, [sp, 0x4]\n\ + movs r0, 0x1D\n\ + ldrsb r0, [r1, r0]\n\ + cmp r0, 0x5\n\ + bgt _0803C1B0\n\ + ldr r2, _0803C1A8 @ =gStatStageRatios\n\ + b _0803C1BC\n\ + .align 2, 0\n\ +_0803C1A8: .4byte gStatStageRatios\n\ +_0803C1AC: .4byte gBattleMovePower\n\ +_0803C1B0:\n\ + ldr r3, [sp, 0x18]\n\ + b _0803C1D6\n\ +_0803C1B4:\n\ + ldr r2, _0803C21C @ =gStatStageRatios\n\ + ldr r1, [sp, 0x4]\n\ + movs r0, 0x1D\n\ + ldrsb r0, [r1, r0]\n\ +_0803C1BC:\n\ + lsls r0, 1\n\ + adds r1, r0, r2\n\ + ldrb r1, [r1]\n\ + ldr r6, [sp, 0x18]\n\ + adds r3, r6, 0\n\ + muls r3, r1\n\ + adds r2, 0x1\n\ + adds r0, r2\n\ + ldrb r1, [r0]\n\ + adds r0, r3, 0\n\ + bl __divsi3\n\ + adds r3, r0, 0\n\ +_0803C1D6:\n\ + adds r0, r5, 0\n\ + adds r1, r3, 0\n\ + bl __divsi3\n\ + adds r5, r0, 0\n\ + movs r1, 0x32\n\ + bl __divsi3\n\ + adds r5, r0, 0\n\ + movs r0, 0x2\n\ + ldr r1, [sp, 0xC]\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _0803C22A\n\ + ldrb r1, [r4]\n\ + cmp r1, 0x1\n\ + bne _0803C22A\n\ + ldr r0, _0803C220 @ =gBattleTypeFlags\n\ + ldrh r0, [r0]\n\ + ands r1, r0\n\ + cmp r1, 0\n\ + beq _0803C224\n\ + movs r0, 0x2\n\ + bl sub_803C348\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + cmp r0, 0x2\n\ + bne _0803C224\n\ + adds r0, r5, 0\n\ + movs r1, 0x3\n\ + bl __divsi3\n\ + lsls r5, r0, 1\n\ + b _0803C22A\n\ + .align 2, 0\n\ +_0803C21C: .4byte gStatStageRatios\n\ +_0803C220: .4byte gBattleTypeFlags\n\ +_0803C224:\n\ + lsrs r0, r5, 31\n\ + adds r0, r5, r0\n\ + asrs r5, r0, 1\n\ +_0803C22A:\n\ + ldr r0, _0803C2A4 @ =gBattleTypeFlags\n\ + ldrh r1, [r0]\n\ + movs r0, 0x1\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _0803C25C\n\ + ldr r0, _0803C2A8 @ =gBattleMoves\n\ + ldr r2, [sp, 0x8]\n\ + lsls r1, r2, 1\n\ + adds r1, r2\n\ + lsls r1, 2\n\ + adds r1, r0\n\ + ldrb r0, [r1, 0x6]\n\ + cmp r0, 0x8\n\ + bne _0803C25C\n\ + movs r0, 0x2\n\ + bl sub_803C348\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + cmp r0, 0x2\n\ + bne _0803C25C\n\ + lsrs r0, r5, 31\n\ + adds r0, r5, r0\n\ + asrs r5, r0, 1\n\ +_0803C25C:\n\ + movs r0, 0\n\ + str r0, [sp]\n\ + movs r0, 0xE\n\ + movs r1, 0\n\ + movs r2, 0xD\n\ + movs r3, 0\n\ + bl sub_8018324\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + cmp r0, 0\n\ + bne _0803C30C\n\ + str r0, [sp]\n\ + movs r0, 0xE\n\ + movs r1, 0\n\ + movs r2, 0x4D\n\ + movs r3, 0\n\ + bl sub_8018324\n\ + lsls r0, 24\n\ + cmp r0, 0\n\ + bne _0803C30C\n\ + ldr r2, _0803C2AC @ =gBattleWeather\n\ + ldrh r1, [r2]\n\ + movs r0, 0x1\n\ + ands r0, r1\n\ + adds r4, r2, 0\n\ + cmp r0, 0\n\ + beq _0803C2C4\n\ + mov r3, r9\n\ + cmp r3, 0xA\n\ + beq _0803C2B0\n\ + cmp r3, 0xB\n\ + beq _0803C2B8\n\ + b _0803C2C4\n\ + .align 2, 0\n\ +_0803C2A4: .4byte gBattleTypeFlags\n\ +_0803C2A8: .4byte gBattleMoves\n\ +_0803C2AC: .4byte gBattleWeather\n\ +_0803C2B0:\n\ + lsrs r0, r5, 31\n\ + adds r0, r5, r0\n\ + asrs r5, r0, 1\n\ + b _0803C2C4\n\ +_0803C2B8:\n\ + lsls r0, r5, 4\n\ + subs r0, r5\n\ + movs r1, 0xA\n\ + bl __divsi3\n\ + adds r5, r0, 0\n\ +_0803C2C4:\n\ + ldrh r1, [r4]\n\ + movs r0, 0x9F\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _0803C2DC\n\ + ldr r0, _0803C2F4 @ =gUnknown_02024BE6\n\ + ldrh r0, [r0]\n\ + cmp r0, 0x4C\n\ + bne _0803C2DC\n\ + lsrs r0, r5, 31\n\ + adds r0, r5, r0\n\ + asrs r5, r0, 1\n\ +_0803C2DC:\n\ + ldrh r1, [r4]\n\ + movs r0, 0x60\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _0803C30C\n\ + mov r6, r9\n\ + cmp r6, 0xA\n\ + beq _0803C2F8\n\ + cmp r6, 0xB\n\ + beq _0803C306\n\ + b _0803C30C\n\ + .align 2, 0\n\ +_0803C2F4: .4byte gUnknown_02024BE6\n\ +_0803C2F8:\n\ + lsls r0, r5, 4\n\ + subs r0, r5\n\ + movs r1, 0xA\n\ + bl __divsi3\n\ + adds r5, r0, 0\n\ + b _0803C30C\n\ +_0803C306:\n\ + lsrs r0, r5, 31\n\ + adds r0, r5, r0\n\ + asrs r5, r0, 1\n\ +_0803C30C:\n\ + ldr r1, _0803C344 @ =0x02017100\n\ + ldr r2, [sp, 0x10]\n\ + lsls r0, r2, 2\n\ + adds r0, r1\n\ + ldr r0, [r0]\n\ + movs r1, 0x1\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _0803C330\n\ + mov r3, r9\n\ + cmp r3, 0xA\n\ + bne _0803C330\n\ + lsls r0, r5, 4\n\ + subs r0, r5\n\ + movs r1, 0xA\n\ + bl __divsi3\n\ + adds r5, r0, 0\n\ +_0803C330:\n\ + adds r0, r5, 0x2\n\ + add sp, 0x2C\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\ +_0803C344: .4byte 0x02017100\n\ + .syntax divided"); +} +#endif diff --git a/src/clear_save_data_menu.c b/src/clear_save_data_menu.c index 22fc8cc13..198dce340 100644 --- a/src/clear_save_data_menu.c +++ b/src/clear_save_data_menu.c @@ -1,4 +1,6 @@ #include "global.h" +#include "clear_save_data_menu.h" +#include "save.h" #include "task.h" #include "songs.h" #include "menu.h" @@ -6,11 +8,10 @@ #include "sprite.h" #include "palette.h" #include "sound.h" -#include "clear_save_data_menu.h" extern u8 gSystemText_ClearAllSaveDataPrompt[]; extern u8 gSystemText_ClearingData[]; -extern u8 *gUnknown_08376D74[][2]; +extern const struct MenuAction gMenuYesNoItems[]; static void VBlankCB_ClearSaveDataScreen(void); static void Task_InitMenu(u8); @@ -47,7 +48,7 @@ static void Task_InitMenu(u8 taskId) MenuPrint(gSystemText_ClearAllSaveDataPrompt, 3, 15); MenuDrawTextWindow(2, 1, 8, 6); - PrintMenuItems(3, 2, 2, gUnknown_08376D74); + PrintMenuItems(3, 2, 2, gMenuYesNoItems); InitMenu(0, 3, 2, 2, 1, 5); gTasks[taskId].func = Task_ProcessMenuInput; diff --git a/src/clock.c b/src/clock.c new file mode 100644 index 000000000..e660abdd3 --- /dev/null +++ b/src/clock.c @@ -0,0 +1,92 @@ +#include "global.h" +#include "main.h" +#include "rtc.h" +#include "event_data.h" +#include "lottery_corner.h" +#include "berry.h" +#include "rom4.h" +#include "wallclock.h" + +extern void sub_80FA220(u16); +extern void sub_80BE8C4(u16); +extern void sub_8080834(u16); +extern void UpdatePartyPokerusTime(u16); +extern void sub_810D2F4(u16); +extern void UpdateBirchState(u16); +extern void sub_810F618(u16); + +static void InitTimeBasedEvents(void); +static void UpdatePerDay(struct Time *time); +static void UpdatePerSecond(struct Time *time); +static void ReturnFromStartWallClock(void); + +static void InitTimeBasedEvents(void) +{ + FlagSet(SYS_CLOCK_SET); + RtcCalcLocalTime(); + gSaveBlock2.lastBerryTreeUpdate = gLocalTime; + VarSet(VAR_DAYS, gLocalTime.days); +} + +void DoTimeBasedEvents(void) +{ + if (FlagGet(SYS_CLOCK_SET)) + { + RtcCalcLocalTime(); + UpdatePerDay(&gLocalTime); + UpdatePerSecond(&gLocalTime); + } +} + +static void UpdatePerDay(struct Time *time) +{ + u16 *varPtr = GetVarPointer(VAR_DAYS); + int days = *varPtr; + u16 newDays; + + if (days != time->days && days <= time->days) + { + newDays = time->days - days; + ClearUpperFlags(); + sub_80FA220(newDays); + sub_80BE8C4(newDays); + sub_8080834(newDays); + UpdatePartyPokerusTime(newDays); + sub_810D2F4(newDays); + UpdateBirchState(newDays); + sub_810F618(newDays); + SetRandomLotteryNumber(newDays); + *varPtr = time->days; + } +} + +static void UpdatePerSecond(struct Time *time) +{ + struct Time newTime; + s32 totalSeconds; + + CalcTimeDifference(&newTime, &gSaveBlock2.lastBerryTreeUpdate, time); + totalSeconds = 1440 * newTime.days + 60 * newTime.hours + newTime.minutes; + + // there's no way to get the correct assembly other than with this nested if check. so dumb. + if (totalSeconds != 0) + { + if (totalSeconds >= 0) + { + BerryTreeTimeUpdate(totalSeconds); + gSaveBlock2.lastBerryTreeUpdate = *time; + } + } +} + +static void ReturnFromStartWallClock(void) +{ + InitTimeBasedEvents(); + SetMainCallback2(c2_exit_to_overworld_1_continue_scripts_restart_music); +} + +void StartWallClock(void) +{ + SetMainCallback2(CB2_StartWallClock); + gMain.savedCallback = ReturnFromStartWallClock; +} diff --git a/src/coins.c b/src/coins.c index acd8c6e10..ad4f5fc34 100644 --- a/src/coins.c +++ b/src/coins.c @@ -1,4 +1,5 @@ #include "global.h" +#include "coins.h" #include "menu.h" #include "string_util.h" @@ -6,8 +7,6 @@ extern u8 gOtherText_Coins2[]; -void PrintCoins(s32, u8, u8, u8); - void UpdateCoinsWindow(s32 a, u8 b, u8 c) { PrintCoins(a, 4, b + 2, c + 1); @@ -29,7 +28,6 @@ void PrintCoins(s32 a, u8 b, u8 c, u8 d) u8 string[16]; u8 *ptr; u8 r1; - u8 r6; u8 foo; ConvertIntToDecimalString(string, a); diff --git a/src/contest_painting.c b/src/contest_painting.c new file mode 100644 index 000000000..2e8a73ec4 --- /dev/null +++ b/src/contest_painting.c @@ -0,0 +1,1353 @@ +#include "global.h" +#include "asm.h" +#include "decompress.h" +#include "main.h" +#include "menu.h" +#include "palette.h" +#include "rng.h" +#include "sprite.h" +#include "string_util.h" +#include "text.h" + +#define MOSAIC_BIT_BG_HSIZE (0) +#define MOSAIC_BIT_BG_VSIZE (4) +#define MOSAIC_BIT_OBJ_HSIZE (8) +#define MOSAIC_BIT_OBJ_VSIZE (12) + +enum { + CONTEST_COOL, + CONTEST_BEAUTY, + CONTEST_CUTE, + CONTEST_SMART, + CONTEST_TOUGH, +}; + +enum { + CONTESTRESULT_COOL = 9, + CONTESTRESULT_BEAUTY = 13, + CONTESTRESULT_CUTE = 2, + CONTESTRESULT_SMART = 36, + CONTESTRESULT_TOUGH = 6, +}; + +struct ContestEntry { + /* 0x00 */ u8 var0; + /* 0x04 */ u32 var4; + /* 0x08 */ u16 var8; + /* 0x0A */ u8 contestType; + /* 0x0B */ u8 pokemon_name[POKEMON_NAME_LENGTH]; + /* 0x15 */ u8 pad15; + /* 0x16 */ u8 trainer_name[OT_NAME_LENGTH]; +}; + +struct Unk3000756 { + /* 0x00 */ u8 var_0; +}; + +struct LabelPair { + u8 (*prefix)[]; + u8 (*suffix)[]; +}; + +struct Unk03005E20 { + u8 var_0; + u8 pad1[3]; + u16 (*var_4)[][32]; + u16 (*var_8)[]; + u8 pad0C[4]; + u32 var_10; + u16 var_14; + u16 var_16; + u8 var_18; + u8 var_19; + u8 var_1A; + u8 var_1B; + u8 var_1C; + u8 var_1D; + u8 var_1E; + u8 var_1F; +}; + +extern struct Unk03005E20 gUnknown_03005E20; +extern u16 (*gUnknown_03005E90)[]; + +extern u8 gUnknown_03005E40[]; + +extern u8 unk_2000000[]; +extern u8 unk_2015de0[]; +extern u16 gUnknown_03000752; +extern u16 gUnknown_03000754; +extern struct Unk3000756 gUnknown_03000756; +extern struct ContestEntry *gUnknown_03005E8C; + +extern u16 (*gUnknown_03005E10)[32][32]; + +extern const struct SpriteSheet gMonFrontPicTable[]; +extern const struct MonCoords gMonFrontPicCoords[]; +extern const struct SpriteSheet gMonBackPicTable[]; +extern const struct MonCoords gMonBackPicCoords[]; + +extern void *gUnknown_081FAF4C[]; + +extern u16 gPictureFramePalettes[]; + +extern u8 gPictureFrameTiles_0[]; +extern u8 gPictureFrameTiles_1[]; +extern u8 gPictureFrameTiles_2[]; +extern u8 gPictureFrameTiles_3[]; +extern u8 gPictureFrameTiles_4[]; +extern u8 gPictureFrameTiles_5[]; + +extern u8 gPictureFrameTilemap_0[]; +extern u8 gPictureFrameTilemap_1[]; +extern u8 gPictureFrameTilemap_2[]; +extern u8 gPictureFrameTilemap_3[]; +extern u8 gPictureFrameTilemap_4[]; +extern u8 gPictureFrameTilemap_5[]; + +extern u8 *gUnknown_083F60AC[]; +extern struct LabelPair gUnknown_083F60C0[]; +extern struct OamData gOamData_83F6138; +extern u16 gUnknown_083F6140[]; + +extern u8 gContestText_ContestWinner[]; +extern u8 gOtherText_Unknown1[]; + +void HoldContestPainting(void); +void ShowContestPainting(); +void ContestPaintingInitWindow(u8 arg0); +void ContestPaintingInitVars(u8 arg0); +void sub_8107090(u8 arg0, u8 arg1); +void ContestPaintingPrintCaption(u8 arg0, u8 arg1); +void ContestPaintingInitBG(void); +void CB2_HoldContestPainting(void); +void VBlankCB_ContestPainting(void); + +void sub_80FC7A0(struct Unk03005E20*); +void sub_80FDA18(struct Unk03005E20*); +void sub_80FD8CC(struct Unk03005E20*); +extern void *species_and_otid_get_pal(); +void sub_8106B90(); + +__attribute__((naked)) +void sub_8106630(u32 arg0) { + asm(".syntax unified\n\ + push {r4-r7,lr}\n\ + ldr r2, _0810665C @ =0x02015de0\n\ + subs r4, r2, 0x2\n\ + subs r5, r2, 0x1\n\ + ldr r3, _08106660 @ =gSaveBlock1\n\ + subs r0, 0x1\n\ + lsls r1, r0, 5\n\ + adds r1, r3\n\ + ldr r3, _08106664 @ =0x00002dfc\n\ + adds r1, r3\n\ + ldm r1!, {r3,r6,r7}\n\ + stm r2!, {r3,r6,r7}\n\ + ldm r1!, {r3,r6,r7}\n\ + stm r2!, {r3,r6,r7}\n\ + ldm r1!, {r6,r7}\n\ + stm r2!, {r6,r7}\n\ + strb r0, [r4]\n\ + movs r0, 0\n\ + strb r0, [r5]\n\ + pop {r4-r7}\n\ + pop {r0}\n\ + bx r0\n\ + .align 2, 0\n\ +_0810665C: .4byte 0x02015de0\n\ +_08106660: .4byte gSaveBlock1\n\ +_08106664: .4byte 0x00002dfc\n\ + .syntax divided\n"); +} + +void CB2_ContestPainting(void) { + ShowContestPainting(); +} + +#ifdef NONMATCHING +void ShowContestPainting(void) { + switch (gMain.state) { + case 0: + remove_some_task(); + SetVBlankCallback(NULL); + gUnknown_03005E8C->data = &unk_2015de0; + ContestPaintingInitVars(FALSE); + ContestPaintingInitBG(); + gMain.state += 1; + break; + + case 1: + ResetPaletteFade(); + + // DMA STUFF + + ResetSpriteData(); + gMain.state += 1; + break; + + case 2: + SeedRng(gMain.vblankCounter1); + InitKeys(); + ContestPaintingInitWindow(unk_2000000[0x15DDF]); + gMain.state += 1; + break; + + case 3: + sub_8107090(unk_2000000[0x15DDE], unk_2000000[0x15DDF]); + gMain.state += 1; + break; + + case 4: + ContestPaintingPrintCaption(unk_2000000[0x15DDE], unk_2000000[0x15DDF]); + LoadPalette(gUnknown_083F6140, 0, 1 * 2); + // DMA STUFF + BeginFastPaletteFade(2); + SetVBlankCallback(VBlankCB_ContestPainting); + REG_DISPCNT = DISPCNT_OBJ_1D_MAP | DISPCNT_BG0_ON | DISPCNT_BG1_ON | DISPCNT_OBJ_ON; + SetMainCallback2(CB2_HoldContestPainting); + break; + } +} +#else +__attribute__((naked)) +void ShowContestPainting(void) { + asm(".syntax unified\n\ + push {r4-r7,lr}\n\ + sub sp, 0x4\n\ + ldr r1, _08106694 @ =gMain\n\ + ldr r2, _08106698 @ =0x0000043c\n\ + adds r0, r1, r2\n\ + ldrb r0, [r0]\n\ + adds r4, r1, 0\n\ + cmp r0, 0x4\n\ + bls _08106688\n\ + b _081067E0\n\ +_08106688:\n\ + lsls r0, 2\n\ + ldr r1, _0810669C @ =_081066A0\n\ + adds r0, r1\n\ + ldr r0, [r0]\n\ + mov pc, r0\n\ + .align 2, 0\n\ +_08106694: .4byte gMain\n\ +_08106698: .4byte 0x0000043c\n\ +_0810669C: .4byte _081066A0\n\ + .align 2, 0\n\ +_081066A0:\n\ + .4byte _081066B4\n\ + .4byte _081066D8\n\ + .4byte _08106734\n\ + .4byte _0810675C\n\ + .4byte _0810678C\n\ +_081066B4:\n\ + bl remove_some_task\n\ + movs r0, 0\n\ + bl SetVBlankCallback\n\ + ldr r1, _081066D0 @ =gUnknown_03005E8C\n\ + ldr r0, _081066D4 @ =0x02015de0\n\ + str r0, [r1]\n\ + movs r0, 0x1\n\ + bl ContestPaintingInitVars\n\ + bl ContestPaintingInitBG\n\ + b _0810676E\n\ + .align 2, 0\n\ +_081066D0: .4byte gUnknown_03005E8C\n\ +_081066D4: .4byte 0x02015de0\n\ +_081066D8:\n\ + bl ResetPaletteFade\n\ + movs r2, 0xC0\n\ + lsls r2, 19\n\ + movs r3, 0xC0\n\ + lsls r3, 9\n\ + movs r5, 0\n\ + ldr r1, _08106724 @ =0x040000d4\n\ + movs r4, 0x80\n\ + lsls r4, 5\n\ + ldr r6, _08106728 @ =0x85000400\n\ + movs r7, 0x85\n\ + lsls r7, 24\n\ +_081066F2:\n\ + str r5, [sp]\n\ + mov r0, sp\n\ + str r0, [r1]\n\ + str r2, [r1, 0x4]\n\ + str r6, [r1, 0x8]\n\ + ldr r0, [r1, 0x8]\n\ + adds r2, r4\n\ + subs r3, r4\n\ + cmp r3, r4\n\ + bhi _081066F2\n\ + str r5, [sp]\n\ + mov r0, sp\n\ + str r0, [r1]\n\ + str r2, [r1, 0x4]\n\ + lsrs r0, r3, 2\n\ + orrs r0, r7\n\ + str r0, [r1, 0x8]\n\ + ldr r0, [r1, 0x8]\n\ + bl ResetSpriteData\n\ + ldr r1, _0810672C @ =gMain\n\ + ldr r2, _08106730 @ =0x0000043c\n\ + adds r1, r2\n\ + b _08106774\n\ + .align 2, 0\n\ +_08106724: .4byte 0x040000d4\n\ +_08106728: .4byte 0x85000400\n\ +_0810672C: .4byte gMain\n\ +_08106730: .4byte 0x0000043c\n\ +_08106734:\n\ + ldrh r0, [r4, 0x20]\n\ + bl SeedRng\n\ + bl InitKeys\n\ + ldr r0, _08106750 @ =0x02000000\n\ + ldr r1, _08106754 @ =0x00015ddf\n\ + adds r0, r1\n\ + ldrb r0, [r0]\n\ + bl ContestPaintingInitWindow\n\ + ldr r2, _08106758 @ =0x0000043c\n\ + adds r1, r4, r2\n\ + b _08106774\n\ + .align 2, 0\n\ +_08106750: .4byte 0x02000000\n\ +_08106754: .4byte 0x00015ddf\n\ +_08106758: .4byte 0x0000043c\n\ +_0810675C:\n\ + ldr r1, _0810677C @ =0x02000000\n\ + ldr r2, _08106780 @ =0x00015dde\n\ + adds r0, r1, r2\n\ + ldrb r0, [r0]\n\ + adds r2, 0x1\n\ + adds r1, r2\n\ + ldrb r1, [r1]\n\ + bl sub_8107090\n\ +_0810676E:\n\ + ldr r1, _08106784 @ =gMain\n\ + ldr r0, _08106788 @ =0x0000043c\n\ + adds r1, r0\n\ +_08106774:\n\ + ldrb r0, [r1]\n\ + adds r0, 0x1\n\ + strb r0, [r1]\n\ + b _081067E0\n\ + .align 2, 0\n\ +_0810677C: .4byte 0x02000000\n\ +_08106780: .4byte 0x00015dde\n\ +_08106784: .4byte gMain\n\ +_08106788: .4byte 0x0000043c\n\ +_0810678C:\n\ + ldr r1, _081067E8 @ =0x02000000\n\ + ldr r2, _081067EC @ =0x00015dde\n\ + adds r0, r1, r2\n\ + ldrb r0, [r0]\n\ + adds r2, 0x1\n\ + adds r1, r2\n\ + ldrb r1, [r1]\n\ + bl ContestPaintingPrintCaption\n\ + ldr r0, _081067F0 @ =gUnknown_083F6140\n\ + movs r1, 0\n\ + movs r2, 0x2\n\ + bl LoadPalette\n\ + movs r1, 0xA0\n\ + lsls r1, 19\n\ + movs r4, 0\n\ + str r4, [sp]\n\ + ldr r0, _081067F4 @ =0x040000d4\n\ + mov r2, sp\n\ + str r2, [r0]\n\ + str r1, [r0, 0x4]\n\ + ldr r1, _081067F8 @ =0x85000100\n\ + str r1, [r0, 0x8]\n\ + ldr r0, [r0, 0x8]\n\ + movs r0, 0x2\n\ + bl BeginFastPaletteFade\n\ + ldr r0, _081067FC @ =VBlankCB_ContestPainting\n\ + bl SetVBlankCallback\n\ + ldr r0, _08106800 @ =gUnknown_03000750\n\ + strb r4, [r0]\n\ + movs r1, 0x80\n\ + lsls r1, 19\n\ + movs r2, 0x9A\n\ + lsls r2, 5\n\ + adds r0, r2, 0\n\ + strh r0, [r1]\n\ + ldr r0, _08106804 @ =CB2_HoldContestPainting\n\ + bl SetMainCallback2\n\ +_081067E0:\n\ + add sp, 0x4\n\ + pop {r4-r7}\n\ + pop {r0}\n\ + bx r0\n\ + .align 2, 0\n\ +_081067E8: .4byte 0x02000000\n\ +_081067EC: .4byte 0x00015dde\n\ +_081067F0: .4byte gUnknown_083F6140\n\ +_081067F4: .4byte 0x040000d4\n\ +_081067F8: .4byte 0x85000100\n\ +_081067FC: .4byte VBlankCB_ContestPainting\n\ +_08106800: .4byte gUnknown_03000750\n\ +_08106804: .4byte CB2_HoldContestPainting\n\ + .syntax divided\n"); +} + +#endif + +void CB2_HoldContestPainting(void) { + HoldContestPainting(); + UpdatePaletteFade(); +} + +void CB2_QuitContestPainting(void) { + SetMainCallback2(gMain.savedCallback); +} + +__attribute__((naked)) +void HoldContestPainting(void) { + asm(".syntax unified\n\ + push {lr}\n\ + sub sp, 0x4\n\ + ldr r3, _08106844 @ =gUnknown_03000750\n\ + ldrb r1, [r3]\n\ + cmp r1, 0x1\n\ + beq _08106880\n\ + cmp r1, 0x1\n\ + bgt _08106848\n\ + cmp r1, 0\n\ + beq _0810684E\n\ + b _081068E6\n\ + .align 2, 0\n\ +_08106844: .4byte gUnknown_03000750\n\ +_08106848:\n\ + cmp r1, 0x2\n\ + beq _081068C0\n\ + b _081068E6\n\ +_0810684E:\n\ + ldr r0, _08106874 @ =gPaletteFade\n\ + ldrb r1, [r0, 0x7]\n\ + movs r0, 0x80\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + bne _0810685E\n\ + movs r0, 0x1\n\ + strb r0, [r3]\n\ +_0810685E:\n\ + ldr r0, _08106878 @ =gUnknown_03000756\n\ + ldrb r0, [r0]\n\ + cmp r0, 0\n\ + beq _081068E6\n\ + ldr r1, _0810687C @ =gUnknown_03000754\n\ + ldrh r0, [r1]\n\ + cmp r0, 0\n\ + beq _081068E6\n\ + subs r0, 0x1\n\ + b _081068E4\n\ + .align 2, 0\n\ +_08106874: .4byte gPaletteFade\n\ +_08106878: .4byte gUnknown_03000756\n\ +_0810687C: .4byte gUnknown_03000754\n\ +_08106880:\n\ + ldr r0, _081068B4 @ =gMain\n\ + ldrh r2, [r0, 0x2E]\n\ + ands r1, r2\n\ + cmp r1, 0\n\ + bne _08106892\n\ + movs r0, 0x2\n\ + ands r0, r2\n\ + cmp r0, 0\n\ + beq _081068A4\n\ +_08106892:\n\ + movs r0, 0x2\n\ + strb r0, [r3]\n\ + subs r0, 0x3\n\ + movs r1, 0\n\ + str r1, [sp]\n\ + movs r2, 0\n\ + movs r3, 0x10\n\ + bl BeginNormalPaletteFade\n\ +_081068A4:\n\ + ldr r0, _081068B8 @ =gUnknown_03000756\n\ + ldrb r0, [r0]\n\ + cmp r0, 0\n\ + beq _081068E6\n\ + ldr r1, _081068BC @ =gUnknown_03000754\n\ + movs r0, 0\n\ + b _081068E4\n\ + .align 2, 0\n\ +_081068B4: .4byte gMain\n\ +_081068B8: .4byte gUnknown_03000756\n\ +_081068BC: .4byte gUnknown_03000754\n\ +_081068C0:\n\ + ldr r0, _081068EC @ =gPaletteFade\n\ + ldrb r1, [r0, 0x7]\n\ + movs r0, 0x80\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + bne _081068D2\n\ + ldr r0, _081068F0 @ =CB2_QuitContestPainting\n\ + bl SetMainCallback2\n\ +_081068D2:\n\ + ldr r0, _081068F4 @ =gUnknown_03000756\n\ + ldrb r0, [r0]\n\ + cmp r0, 0\n\ + beq _081068E6\n\ + ldr r1, _081068F8 @ =gUnknown_03000754\n\ + ldrh r0, [r1]\n\ + cmp r0, 0x1D\n\ + bhi _081068E6\n\ + adds r0, 0x1\n\ +_081068E4:\n\ + strh r0, [r1]\n\ +_081068E6:\n\ + add sp, 0x4\n\ + pop {r0}\n\ + bx r0\n\ + .align 2, 0\n\ +_081068EC: .4byte gPaletteFade\n\ +_081068F0: .4byte CB2_QuitContestPainting\n\ +_081068F4: .4byte gUnknown_03000756\n\ +_081068F8: .4byte gUnknown_03000754\n\ + .syntax divided\n"); +} + +void ContestPaintingInitWindow(u8 arg0) { + InitMenuWindow(&gWindowConfig_81E7160); + SetUpWindowConfig(&gWindowConfig_81E7160); +} + +void ContestPaintingPrintCaption(u8 contestType, u8 arg1) { + u8 xPos, yPos; + u8 *ptr; + u8 type; + + if (arg1 == TRUE) { + return; + } + + ptr = gUnknown_03005E40; + type = gUnknown_03005E8C->contestType; + if (contestType < 8) { + ptr = StringCopy(ptr, gUnknown_083F60AC[type]); + ptr = StringCopy(ptr, gContestText_ContestWinner); + ptr = StringCopy(ptr, gUnknown_03005E8C->trainer_name); + + // {ENG} + ptr[0] = 0xFC; + ptr[1] = 0x16; + ptr += 2; + + ptr = StringCopy(ptr, gOtherText_Unknown1); + ptr = StringCopy10(ptr, gUnknown_03005E8C->pokemon_name); + + xPos = 6; + yPos = 14; + } else { + ptr = StringCopy(ptr, *gUnknown_083F60C0[type].prefix); + ptr = StringCopy10(ptr, gUnknown_03005E8C->pokemon_name); + ptr = StringCopy(ptr, *gUnknown_083F60C0[type].suffix); + + xPos = 3; + yPos = 14; + } + + MenuPrint_PixelCoords(gUnknown_03005E40, xPos * 8 + 1, yPos * 8, 1); +} + +void ContestPaintingInitBG(void) { + REG_DISPCNT = 0; + REG_IE |= INTR_FLAG_VBLANK; + REG_BG0CNT = 0x0C42; + REG_BG1CNT = 0x0A45; + REG_BLDCNT = 0; + REG_BLDALPHA = 0; + REG_BLDY = 0; +} + +void ContestPaintingInitVars(bool8 arg0) { + if (arg0 == 0) { + gUnknown_03000756.var_0 = FALSE; + gUnknown_03000752 = 0; + gUnknown_03000754 = 0; + } else { + gUnknown_03000756.var_0 = TRUE; + gUnknown_03000752 = 15; + gUnknown_03000754 = 30; + } +} + +void ContestPaintingMosaic(void) { + if (gUnknown_03000756.var_0 == FALSE) { + REG_MOSAIC = 0; + return; + } + + REG_BG1CNT = 0xA45; + gUnknown_03000752 = gUnknown_03000754 / 2; + + REG_MOSAIC = (gUnknown_03000752 << 12) | (gUnknown_03000752 << 8) | (gUnknown_03000752 << 4) | (gUnknown_03000752 << 0); +} + +void VBlankCB_ContestPainting(void) { + ContestPaintingMosaic(); + LoadOam(); + ProcessSpriteCopyRequests(); + TransferPlttBuffer(); +} + +struct MonCoords { + u8 x, y; +}; + +#ifdef NONMATCHING +void sub_8106AC4(u16 species, u8 arg1) { + void *pal; + + // Unsure what gUnknown_03005E8C->var0 is supposed to be. + pal = species_and_otid_get_pal(species, gUnknown_03005E8C->var4, gUnknown_03005E8C->var0); + LZDecompressVram(pal, gUnknown_03005E90); + + if (arg1 == 1) { + HandleLoadSpecialPokePic( + &gMonFrontPicTable[species], + gMonFrontPicCoords[species].x, + gMonFrontPicCoords[species].y, + 0x2000000, + gUnknown_081FAF4C[1], + species, + (u32) gUnknown_03005E8C->var0 + ); + sub_8106B90(gUnknown_081FAF4C[1], gUnknown_03005E90, gUnknown_03005E10); + } else { + HandleLoadSpecialPokePic( + &gMonBackPicTable[species], + gMonBackPicCoords[species].x, + gMonBackPicCoords[species].y, + 0x2000000, + gUnknown_081FAF4C[0], + species, + (u32) gUnknown_03005E8C->var0 + ); + sub_8106B90(gUnknown_081FAF4C[0], gUnknown_03005E90, gUnknown_03005E10); + } +} +#else +__attribute__((naked)) +void sub_8106AC4(u16 arg0, u8 arg2) { + asm(".syntax unified\n\ + push {r4-r7,lr}\n\ + mov r7, r8\n\ + push {r7}\n\ + sub sp, 0xC\n\ + adds r4, r1, 0\n\ + lsls r0, 16\n\ + lsrs r6, r0, 16\n\ + lsls r4, 24\n\ + lsrs r4, 24\n\ + ldr r7, _08106B28 @ =gUnknown_03005E8C\n\ + ldr r0, [r7]\n\ + ldr r1, [r0, 0x4]\n\ + ldr r2, [r0]\n\ + adds r0, r6, 0\n\ + bl species_and_otid_get_pal\n\ + ldr r1, _08106B2C @ =gUnknown_03005E90\n\ + mov r8, r1\n\ + ldr r1, [r1]\n\ + bl LZDecompressVram\n\ + cmp r4, 0\n\ + bne _08106B40\n\ + lsls r0, r6, 3\n\ + ldr r1, _08106B30 @ =gMonFrontPicTable\n\ + adds r0, r1\n\ + ldr r1, _08106B34 @ =gMonFrontPicCoords\n\ + lsls r2, r6, 2\n\ + adds r2, r1\n\ + ldrb r1, [r2]\n\ + ldrb r2, [r2, 0x1]\n\ + movs r3, 0x80\n\ + lsls r3, 18\n\ + ldr r4, _08106B38 @ =gUnknown_081FAF4C\n\ + ldr r5, [r4, 0x4]\n\ + str r5, [sp]\n\ + str r6, [sp, 0x4]\n\ + ldr r4, [r7]\n\ + ldr r4, [r4]\n\ + str r4, [sp, 0x8]\n\ + bl HandleLoadSpecialPokePic\n\ + mov r2, r8\n\ + ldr r1, [r2]\n\ + ldr r0, _08106B3C @ =gUnknown_03005E10\n\ + ldr r2, [r0]\n\ + adds r0, r5, 0\n\ + bl sub_8106B90\n\ + b _08106B74\n\ + .align 2, 0\n\ +_08106B28: .4byte gUnknown_03005E8C\n\ +_08106B2C: .4byte gUnknown_03005E90\n\ +_08106B30: .4byte gMonFrontPicTable\n\ +_08106B34: .4byte gMonFrontPicCoords\n\ +_08106B38: .4byte gUnknown_081FAF4C\n\ +_08106B3C: .4byte gUnknown_03005E10\n\ +_08106B40:\n\ + lsls r0, r6, 3\n\ + ldr r1, _08106B80 @ =gMonBackPicTable\n\ + adds r0, r1\n\ + ldr r1, _08106B84 @ =gMonBackPicCoords\n\ + lsls r2, r6, 2\n\ + adds r2, r1\n\ + ldrb r1, [r2]\n\ + ldrb r2, [r2, 0x1]\n\ + movs r3, 0x80\n\ + lsls r3, 18\n\ + ldr r4, _08106B88 @ =gUnknown_081FAF4C\n\ + ldr r5, [r4]\n\ + str r5, [sp]\n\ + str r6, [sp, 0x4]\n\ + ldr r4, [r7]\n\ + ldr r4, [r4]\n\ + str r4, [sp, 0x8]\n\ + bl HandleLoadSpecialPokePic\n\ + mov r0, r8\n\ + ldr r1, [r0]\n\ + ldr r0, _08106B8C @ =gUnknown_03005E10\n\ + ldr r2, [r0]\n\ + adds r0, r5, 0\n\ + bl sub_8106B90\n\ +_08106B74:\n\ + add sp, 0xC\n\ + pop {r3}\n\ + mov r8, r3\n\ + pop {r4-r7}\n\ + pop {r0}\n\ + bx r0\n\ + .align 2, 0\n\ +_08106B80: .4byte gMonBackPicTable\n\ +_08106B84: .4byte gMonBackPicCoords\n\ +_08106B88: .4byte gUnknown_081FAF4C\n\ +_08106B8C: .4byte gUnknown_03005E10\n\ + .syntax divided\n"); +} +#endif + +__attribute__((naked)) +void sub_8106B90() { + 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, 0xC\n\ + mov r10, r0\n\ + mov r9, r1\n\ + str r2, [sp]\n\ + movs r0, 0\n\ +_08106BA4:\n\ + movs r3, 0\n\ + adds r1, r0, 0x1\n\ + str r1, [sp, 0x4]\n\ + lsls r0, 3\n\ + str r0, [sp, 0x8]\n\ +_08106BAE:\n\ + movs r1, 0\n\ + adds r2, r3, 0x1\n\ + mov r8, r2\n\ + ldr r7, [sp, 0x8]\n\ + adds r0, r7, r3\n\ + lsls r0, 5\n\ + mov r12, r0\n\ + lsls r4, r3, 3\n\ +_08106BBE:\n\ + movs r3, 0\n\ + lsls r0, r1, 2\n\ + adds r6, r1, 0x1\n\ + mov r2, r12\n\ + adds r5, r2, r0\n\ + ldr r7, [sp, 0x8]\n\ + adds r0, r7, r1\n\ + lsls r0, 7\n\ + ldr r1, [sp]\n\ + adds r2, r0, r1\n\ +_08106BD2:\n\ + lsrs r0, r3, 1\n\ + adds r0, r5, r0\n\ + add r0, r10\n\ + ldrb r1, [r0]\n\ + movs r0, 0x1\n\ + ands r0, r3\n\ + cmp r0, 0\n\ + beq _08106BE6\n\ + lsrs r1, 4\n\ + b _08106BEA\n\ +_08106BE6:\n\ + movs r0, 0xF\n\ + ands r1, r0\n\ +_08106BEA:\n\ + cmp r1, 0\n\ + bne _08106BFC\n\ + adds r0, r4, r3\n\ + lsls r0, 1\n\ + adds r0, r2\n\ + movs r7, 0x80\n\ + lsls r7, 8\n\ + adds r1, r7, 0\n\ + b _08106C08\n\ +_08106BFC:\n\ + adds r0, r4, r3\n\ + lsls r0, 1\n\ + adds r0, r2\n\ + lsls r1, 1\n\ + add r1, r9\n\ + ldrh r1, [r1]\n\ +_08106C08:\n\ + strh r1, [r0]\n\ + adds r0, r3, 0x1\n\ + lsls r0, 16\n\ + lsrs r3, r0, 16\n\ + cmp r3, 0x7\n\ + bls _08106BD2\n\ + lsls r0, r6, 16\n\ + lsrs r1, r0, 16\n\ + cmp r1, 0x7\n\ + bls _08106BBE\n\ + mov r1, r8\n\ + lsls r0, r1, 16\n\ + lsrs r3, r0, 16\n\ + cmp r3, 0x7\n\ + bls _08106BAE\n\ + ldr r2, [sp, 0x4]\n\ + lsls r0, r2, 16\n\ + lsrs r0, 16\n\ + cmp r0, 0x7\n\ + bls _08106BA4\n\ + add sp, 0xC\n\ + pop {r3-r5}\n\ + mov r8, r3\n\ + mov r9, r4\n\ + mov r10, r5\n\ + pop {r4-r7}\n\ + pop {r0}\n\ + bx r0\n\ + .syntax divided\n"); +} + +#ifdef NONMATCHING +void sub_8106C40(u8 arg0, u8 arg1) { + LoadPalette(gPictureFramePalettes, 0, 128 * 2); + + if (arg1 == 1) { + switch (gUnknown_03005E8C->contestType / 3) { + case CONTEST_COOL: + RLUnCompVram(gPictureFrameTiles_0, (void *) VRAM); + RLUnCompWram(gPictureFrameTilemap_0, gUnknown_03005E10); + break; + + case CONTEST_BEAUTY: + RLUnCompVram(gPictureFrameTiles_1, (void *) VRAM); + RLUnCompWram(gPictureFrameTilemap_1, gUnknown_03005E10); + break; + + case CONTEST_CUTE: + RLUnCompVram(gPictureFrameTiles_2, (void *) VRAM); + RLUnCompWram(gPictureFrameTilemap_2, gUnknown_03005E10); + break; + + case CONTEST_SMART: + RLUnCompVram(gPictureFrameTiles_3, (void *) VRAM); + RLUnCompWram(gPictureFrameTilemap_3, gUnknown_03005E10); + break; + + case CONTEST_TOUGH: + RLUnCompVram(gPictureFrameTiles_4, (void *) VRAM); + RLUnCompWram(gPictureFrameTilemap_4, gUnknown_03005E10); + break; + } + + { + u8 x; + u8 y; + + u16 (*vram)[32][32] = (void *) (VRAM + 0x6000); + + // Set the background + for (y = 0; y < 20; y++) { + for (x = 0; x < 32; x++) { + (*vram)[y][x] = 1 << 12 | 21; + } + } + + // Copy the image frame + for (y = 0; y < 10; y++) { + for (x = 0; x < 18; x++) { + (*vram)[y + 2][x + 6] = (*gUnknown_03005E10)[y + 2][x + 6]; + } + } + + // Re-set the entire top row to the first top frame part + for (x = 0; x < 16; x++) { + (*vram)[2][x + 7] = (*gUnknown_03005E10)[2][7]; + } + } + + // def_8106C7A + } else { + if (arg0 < 8) { + RLUnCompVram(gPictureFrameTiles_5, (void *) VRAM); + RLUnCompVram(gPictureFrameTilemap_5, (void *) (VRAM + 0x6000)); + return; + } + + switch (gUnknown_03005E8C->contestType / 3) { + case CONTEST_COOL: + RLUnCompVram(gPictureFrameTiles_0, (void *) VRAM); + RLUnCompVram(gPictureFrameTilemap_0, (void *) (VRAM + 0x6000)); + break; + + case CONTEST_BEAUTY: + RLUnCompVram(gPictureFrameTiles_1, (void *) VRAM); + RLUnCompVram(gPictureFrameTilemap_1, (void *) (VRAM + 0x6000)); + break; + + case CONTEST_CUTE: + RLUnCompVram(gPictureFrameTiles_2, (void *) VRAM); + RLUnCompVram(gPictureFrameTilemap_2, (void *) (VRAM + 0x6000)); + break; + + case CONTEST_SMART: + RLUnCompVram(gPictureFrameTiles_3, (void *) VRAM); + RLUnCompVram(gPictureFrameTilemap_3, (void *) (VRAM + 0x6000)); + break; + + case CONTEST_TOUGH: + RLUnCompVram(gPictureFrameTiles_4, (void *) VRAM); + RLUnCompVram(gPictureFrameTilemap_4, (void *) (VRAM + 0x6000)); + break; + } + } +} +#else +__attribute__((naked)) +void sub_8106C40(u8 arg0, u8 arg1) { + asm(".syntax unified\n\ + push {r4-r7,lr}\n\ + adds r4, r1, 0\n\ + lsls r0, 24\n\ + lsrs r5, r0, 24\n\ + lsls r4, 24\n\ + lsrs r4, 24\n\ + ldr r0, _08106C7C @ =gPictureFramePalettes\n\ + movs r2, 0x80\n\ + lsls r2, 1\n\ + movs r1, 0\n\ + bl LoadPalette\n\ + cmp r4, 0x1\n\ + beq _08106C5E\n\ + b _08106DB4\n\ +_08106C5E:\n\ + ldr r0, _08106C80 @ =gUnknown_03005E8C\n\ + ldr r0, [r0]\n\ + ldrb r0, [r0, 0xA]\n\ + movs r1, 0x3\n\ + bl __udivsi3\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + cmp r0, 0x4\n\ + bhi _08106D1C\n\ + lsls r0, 2\n\ + ldr r1, _08106C84 @ =_08106C88\n\ + adds r0, r1\n\ + ldr r0, [r0]\n\ + mov pc, r0\n\ + .align 2, 0\n\ +_08106C7C: .4byte gPictureFramePalettes\n\ +_08106C80: .4byte gUnknown_03005E8C\n\ +_08106C84: .4byte _08106C88\n\ + .align 2, 0\n\ +_08106C88:\n\ + .4byte _08106C9C\n\ + .4byte _08106CB4\n\ + .4byte _08106CCC\n\ + .4byte _08106CE4\n\ + .4byte _08106D08\n\ +_08106C9C:\n\ + ldr r0, _08106CAC @ =gPictureFrameTiles_0\n\ + movs r1, 0xC0\n\ + lsls r1, 19\n\ + bl RLUnCompVram\n\ + ldr r0, _08106CB0 @ =gPictureFrameTilemap_0\n\ + b _08106CF0\n\ + .align 2, 0\n\ +_08106CAC: .4byte gPictureFrameTiles_0\n\ +_08106CB0: .4byte gPictureFrameTilemap_0\n\ +_08106CB4:\n\ + ldr r0, _08106CC4 @ =gPictureFrameTiles_1\n\ + movs r1, 0xC0\n\ + lsls r1, 19\n\ + bl RLUnCompVram\n\ + ldr r0, _08106CC8 @ =gPictureFrameTilemap_1\n\ + b _08106CF0\n\ + .align 2, 0\n\ +_08106CC4: .4byte gPictureFrameTiles_1\n\ +_08106CC8: .4byte gPictureFrameTilemap_1\n\ +_08106CCC:\n\ + ldr r0, _08106CDC @ =gPictureFrameTiles_2\n\ + movs r1, 0xC0\n\ + lsls r1, 19\n\ + bl RLUnCompVram\n\ + ldr r0, _08106CE0 @ =gPictureFrameTilemap_2\n\ + b _08106CF0\n\ + .align 2, 0\n\ +_08106CDC: .4byte gPictureFrameTiles_2\n\ +_08106CE0: .4byte gPictureFrameTilemap_2\n\ +_08106CE4:\n\ + ldr r0, _08106CFC @ =gPictureFrameTiles_3\n\ + movs r1, 0xC0\n\ + lsls r1, 19\n\ + bl RLUnCompVram\n\ + ldr r0, _08106D00 @ =gPictureFrameTilemap_3\n\ +_08106CF0:\n\ + ldr r1, _08106D04 @ =gUnknown_03005E10\n\ + ldr r1, [r1]\n\ + bl RLUnCompWram\n\ + b _08106D1C\n\ + .align 2, 0\n\ +_08106CFC: .4byte gPictureFrameTiles_3\n\ +_08106D00: .4byte gPictureFrameTilemap_3\n\ +_08106D04: .4byte gUnknown_03005E10\n\ +_08106D08:\n\ + ldr r0, _08106D98 @ =gPictureFrameTiles_4\n\ + movs r1, 0xC0\n\ + lsls r1, 19\n\ + bl RLUnCompVram\n\ + ldr r0, _08106D9C @ =gPictureFrameTilemap_4\n\ + ldr r1, _08106DA0 @ =gUnknown_03005E10\n\ + ldr r1, [r1]\n\ + bl RLUnCompWram\n\ +_08106D1C:\n\ + movs r1, 0\n\ + ldr r5, _08106DA4 @ =0x06006000\n\ + ldr r0, _08106DA8 @ =0x00001015\n\ + adds r4, r0, 0\n\ +_08106D24:\n\ + movs r3, 0\n\ + lsls r2, r1, 5\n\ +_08106D28:\n\ + adds r0, r2, r3\n\ + lsls r0, 1\n\ + adds r0, r5\n\ + strh r4, [r0]\n\ + adds r0, r3, 0x1\n\ + lsls r0, 24\n\ + lsrs r3, r0, 24\n\ + cmp r3, 0x1F\n\ + bls _08106D28\n\ + adds r0, r1, 0x1\n\ + lsls r0, 24\n\ + lsrs r1, r0, 24\n\ + cmp r1, 0x13\n\ + bls _08106D24\n\ + movs r1, 0\n\ + ldr r0, _08106DAC @ =0x0600608c\n\ + mov r12, r0\n\ + ldr r7, _08106DA0 @ =gUnknown_03005E10\n\ +_08106D4C:\n\ + movs r3, 0\n\ + adds r6, r1, 0x1\n\ + lsls r5, r1, 5\n\ + lsls r4, r1, 6\n\ +_08106D54:\n\ + adds r2, r5, r3\n\ + lsls r2, 1\n\ + add r2, r12\n\ + ldr r0, [r7]\n\ + adds r0, r4, r0\n\ + lsls r1, r3, 1\n\ + adds r0, r1\n\ + adds r0, 0x8C\n\ + ldrh r0, [r0]\n\ + strh r0, [r2]\n\ + adds r0, r3, 0x1\n\ + lsls r0, 24\n\ + lsrs r3, r0, 24\n\ + cmp r3, 0x11\n\ + bls _08106D54\n\ + lsls r0, r6, 24\n\ + lsrs r1, r0, 24\n\ + cmp r1, 0x9\n\ + bls _08106D4C\n\ + movs r3, 0\n\ + ldr r4, _08106DB0 @ =0x0600608e\n\ + ldr r2, _08106DA0 @ =gUnknown_03005E10\n\ +_08106D80:\n\ + lsls r1, r3, 1\n\ + adds r1, r4\n\ + ldr r0, [r2]\n\ + adds r0, 0x8E\n\ + ldrh r0, [r0]\n\ + strh r0, [r1]\n\ + adds r0, r3, 0x1\n\ + lsls r0, 24\n\ + lsrs r3, r0, 24\n\ + cmp r3, 0xF\n\ + bls _08106D80\n\ + b _08106E86\n\ + .align 2, 0\n\ +_08106D98: .4byte gPictureFrameTiles_4\n\ +_08106D9C: .4byte gPictureFrameTilemap_4\n\ +_08106DA0: .4byte gUnknown_03005E10\n\ +_08106DA4: .4byte 0x06006000\n\ +_08106DA8: .4byte 0x00001015\n\ +_08106DAC: .4byte 0x0600608c\n\ +_08106DB0: .4byte 0x0600608e\n\ +_08106DB4:\n\ + cmp r5, 0x7\n\ + bhi _08106DD0\n\ + ldr r0, _08106DC8 @ =gPictureFrameTiles_5\n\ + movs r1, 0xC0\n\ + lsls r1, 19\n\ + bl RLUnCompVram\n\ + ldr r0, _08106DCC @ =gPictureFrameTilemap_5\n\ + b _08106E60\n\ + .align 2, 0\n\ +_08106DC8: .4byte gPictureFrameTiles_5\n\ +_08106DCC: .4byte gPictureFrameTilemap_5\n\ +_08106DD0:\n\ + ldr r0, _08106DF0 @ =gUnknown_03005E8C\n\ + ldr r0, [r0]\n\ + ldrb r0, [r0, 0xA]\n\ + movs r1, 0x3\n\ + bl __udivsi3\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + cmp r0, 0x4\n\ + bhi _08106E86\n\ + lsls r0, 2\n\ + ldr r1, _08106DF4 @ =_08106DF8\n\ + adds r0, r1\n\ + ldr r0, [r0]\n\ + mov pc, r0\n\ + .align 2, 0\n\ +_08106DF0: .4byte gUnknown_03005E8C\n\ +_08106DF4: .4byte _08106DF8\n\ + .align 2, 0\n\ +_08106DF8:\n\ + .4byte _08106E0C\n\ + .4byte _08106E24\n\ + .4byte _08106E3C\n\ + .4byte _08106E54\n\ + .4byte _08106E74\n\ +_08106E0C:\n\ + ldr r0, _08106E1C @ =gPictureFrameTiles_0\n\ + movs r1, 0xC0\n\ + lsls r1, 19\n\ + bl RLUnCompVram\n\ + ldr r0, _08106E20 @ =gPictureFrameTilemap_0\n\ + b _08106E60\n\ + .align 2, 0\n\ +_08106E1C: .4byte gPictureFrameTiles_0\n\ +_08106E20: .4byte gPictureFrameTilemap_0\n\ +_08106E24:\n\ + ldr r0, _08106E34 @ =gPictureFrameTiles_1\n\ + movs r1, 0xC0\n\ + lsls r1, 19\n\ + bl RLUnCompVram\n\ + ldr r0, _08106E38 @ =gPictureFrameTilemap_1\n\ + b _08106E60\n\ + .align 2, 0\n\ +_08106E34: .4byte gPictureFrameTiles_1\n\ +_08106E38: .4byte gPictureFrameTilemap_1\n\ +_08106E3C:\n\ + ldr r0, _08106E4C @ =gPictureFrameTiles_2\n\ + movs r1, 0xC0\n\ + lsls r1, 19\n\ + bl RLUnCompVram\n\ + ldr r0, _08106E50 @ =gPictureFrameTilemap_2\n\ + b _08106E60\n\ + .align 2, 0\n\ +_08106E4C: .4byte gPictureFrameTiles_2\n\ +_08106E50: .4byte gPictureFrameTilemap_2\n\ +_08106E54:\n\ + ldr r0, _08106E68 @ =gPictureFrameTiles_3\n\ + movs r1, 0xC0\n\ + lsls r1, 19\n\ + bl RLUnCompVram\n\ + ldr r0, _08106E6C @ =gPictureFrameTilemap_3\n\ +_08106E60:\n\ + ldr r1, _08106E70 @ =0x06006000\n\ + bl RLUnCompVram\n\ + b _08106E86\n\ + .align 2, 0\n\ +_08106E68: .4byte gPictureFrameTiles_3\n\ +_08106E6C: .4byte gPictureFrameTilemap_3\n\ +_08106E70: .4byte 0x06006000\n\ +_08106E74:\n\ + ldr r0, _08106E8C @ =gPictureFrameTiles_4\n\ + movs r1, 0xC0\n\ + lsls r1, 19\n\ + bl RLUnCompVram\n\ + ldr r0, _08106E90 @ =gPictureFrameTilemap_4\n\ + ldr r1, _08106E94 @ =0x06006000\n\ + bl RLUnCompVram\n\ +_08106E86:\n\ + pop {r4-r7}\n\ + pop {r0}\n\ + bx r0\n\ + .align 2, 0\n\ +_08106E8C: .4byte gPictureFrameTiles_4\n\ +_08106E90: .4byte gPictureFrameTilemap_4\n\ +_08106E94: .4byte 0x06006000\n\ + .syntax divided\n"); +} +#endif + +#ifdef NONMATCHING +void sub_8106E98(u8 arg0 ) { + gMain.oamBuffer[0] = gOamData_83F6138; + + gMain.oamBuffer[0].tileNum = 0; + gMain.oamBuffer[0].x = 88; + gMain.oamBuffer[0].y = 24; +} +#else +__attribute__((naked)) +void sub_8106E98(u8 arg0) { + asm(".syntax unified\n\ + push {r4,lr}\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + ldr r4, _08106ED0 @ =gMain\n\ + ldr r1, _08106ED4 @ =gOamData_83F6138\n\ + ldr r2, [r1, 0x4]\n\ + ldr r1, [r1]\n\ + str r1, [r4, 0x3C]\n\ + str r2, [r4, 0x40]\n\ + adds r3, r4, 0\n\ + adds r3, 0x40\n\ + ldrh r2, [r3]\n\ + ldr r1, _08106ED8 @ =0xfffffc00\n\ + ands r1, r2\n\ + strh r1, [r3]\n\ + ldrh r1, [r4, 0x3E]\n\ + ldr r0, _08106EDC @ =0xfffffe00\n\ + ands r0, r1\n\ + movs r1, 0x58\n\ + orrs r0, r1\n\ + strh r0, [r4, 0x3E]\n\ + adds r1, r4, 0\n\ + adds r1, 0x3C\n\ + movs r0, 0x18\n\ + strb r0, [r1]\n\ + pop {r4}\n\ + pop {r0}\n\ + bx r0\n\ + .align 2, 0\n\ +_08106ED0: .4byte gMain\n\ +_08106ED4: .4byte gOamData_83F6138\n\ +_08106ED8: .4byte 0xfffffc00\n\ +_08106EDC: .4byte 0xfffffe00\n\ + .syntax divided\n"); +} +#endif + +u8 sub_8106EE0(u8 arg0) { + u8 contestType; + + if (arg0 < 8) { + contestType = gUnknown_03005E8C->contestType; + } else { + contestType = gUnknown_03005E8C->contestType / 3; + } + + switch (contestType) { + case CONTEST_COOL: + return CONTESTRESULT_COOL; + + case CONTEST_BEAUTY: + return CONTESTRESULT_BEAUTY; + + case CONTEST_CUTE: + return CONTESTRESULT_CUTE; + + case CONTEST_SMART: + return CONTESTRESULT_SMART; + + case CONTEST_TOUGH: + return CONTESTRESULT_TOUGH; + } + + return contestType; +} + +#ifdef NONMATCHING +void sub_8106F4C(void) { + gUnknown_03005E90 = (void *) 0x02017e00; + gUnknown_03005E10 = (void *) 0x02015e00; +} +#else +__attribute__((naked)) +void sub_8106F4C(void) { + asm(".syntax unified\n\ + ldr r0, _08106F5C @ =gUnknown_03005E90\n\ + ldr r1, _08106F60 @ =0x02017e00\n\ + str r1, [r0]\n\ + ldr r0, _08106F64 @ =gUnknown_03005E10\n\ + ldr r2, _08106F68 @ =0xffffe000\n\ + adds r1, r2\n\ + str r1, [r0]\n\ + bx lr\n\ + .align 2, 0\n\ +_08106F5C: .4byte gUnknown_03005E90\n\ +_08106F60: .4byte 0x02017e00\n\ +_08106F64: .4byte gUnknown_03005E10\n\ +_08106F68: .4byte 0xffffe000\n\ + .syntax divided\n"); +} +#endif + +void sub_8106F6C(u8 arg0) { + gUnknown_03005E20.var_4 = gUnknown_03005E10; + gUnknown_03005E20.var_8 = gUnknown_03005E90; + gUnknown_03005E20.var_18 = 0; + gUnknown_03005E20.var_1F = gUnknown_03005E8C->var0; + gUnknown_03005E20.var_19 = 0; + gUnknown_03005E20.var_1A = 0; + gUnknown_03005E20.var_1B = 64; + gUnknown_03005E20.var_1C = 64; + gUnknown_03005E20.var_1D = 64; + gUnknown_03005E20.var_1E = 64; + + switch (arg0) { + case CONTESTRESULT_SMART: + case CONTESTRESULT_TOUGH: + gUnknown_03005E20.var_14 = 3; + break; + + case CONTESTRESULT_COOL: + case CONTESTRESULT_BEAUTY: + case CONTESTRESULT_CUTE: + default: + gUnknown_03005E20.var_14 = 1; + break; + } + + gUnknown_03005E20.var_16 = 2; + gUnknown_03005E20.var_0 = arg0; + gUnknown_03005E20.var_10 = 0x6010000; + + sub_80FC7A0(&gUnknown_03005E20); + sub_80FDA18(&gUnknown_03005E20); + sub_80FD8CC(&gUnknown_03005E20); + + LoadPalette(gUnknown_03005E90, 256, 256 * 2); +} + +void sub_8107090(u8 arg0, u8 arg1) { + u8 local0; + + sub_8106F4C(); + sub_8106AC4(gUnknown_03005E8C->var8, 0); + + local0 = sub_8106EE0(arg0); + sub_8106F6C(local0); + + sub_8106E98(arg0); + sub_8106C40(arg0, arg1); +} diff --git a/src/coord_event_weather.c b/src/coord_event_weather.c new file mode 100644 index 000000000..f033e5391 --- /dev/null +++ b/src/coord_event_weather.c @@ -0,0 +1,117 @@ +#include "global.h" +#include "asm.h" + +struct CoordEventWeather +{ + u8 weather; + void (*func)(void); +}; + +static void CoordEventWeather_Indoor(void); +static void CoordEventWeather_Sunny(void); +static void CoordEventWeather_Rain(void); +static void CoordEventWeather_Snowflakes(void); +static void CoordEventWeather_Thunderstorm(void); +static void CoordEventWeather_Fog(void); +static void CoordEventWeather_DiagonalFog(void); +static void CoordEventWeather_Snow(void); +static void CoordEventWeather_Sandstorm(void); +static void CoordEventWeather_Cloudy(void); +static void CoordEventWeather_Drought(void); +static void CoordEventWeather_UnderwaterFog(void); +static void CoordEventWeather_UnderwaterBubbles(void); + +static const struct CoordEventWeather sCoordEventWeatherFuncs[] = +{ + { 0x1, CoordEventWeather_Indoor }, + { 0x2, CoordEventWeather_Sunny }, + { 0x3, CoordEventWeather_Rain }, + { 0x4, CoordEventWeather_Snowflakes }, + { 0x5, CoordEventWeather_Thunderstorm }, + { 0x6, CoordEventWeather_Fog }, + { 0x7, CoordEventWeather_DiagonalFog }, + { 0x8, CoordEventWeather_Snow }, + { 0x9, CoordEventWeather_Sandstorm }, + { 0xa, CoordEventWeather_Cloudy }, + { 0xb, CoordEventWeather_Drought }, + { 0x14, CoordEventWeather_UnderwaterFog }, + { 0x15, CoordEventWeather_UnderwaterBubbles }, +}; + +static void CoordEventWeather_Indoor(void) +{ + SetWeather(1); +} + +static void CoordEventWeather_Sunny(void) +{ + SetWeather(2); +} + +static void CoordEventWeather_Rain(void) +{ + SetWeather(3); +} + +static void CoordEventWeather_Snowflakes(void) +{ + SetWeather(4); +} + +static void CoordEventWeather_Thunderstorm(void) +{ + SetWeather(5); +} + +static void CoordEventWeather_Fog(void) +{ + SetWeather(6); +} + +static void CoordEventWeather_DiagonalFog(void) +{ + SetWeather(9); +} + +static void CoordEventWeather_Snow(void) +{ + SetWeather(7); +} + +static void CoordEventWeather_Sandstorm(void) +{ + SetWeather(8); +} + +static void CoordEventWeather_Cloudy(void) +{ + SetWeather(11); +} + +static void CoordEventWeather_Drought(void) +{ + SetWeather(12); +} + +static void CoordEventWeather_UnderwaterFog(void) +{ + SetWeather(20); +} + +static void CoordEventWeather_UnderwaterBubbles(void) +{ + SetWeather(21); +} + +void DoCoordEventWeather(u8 n) +{ + u8 i; + for (i = 0; i < ARRAY_COUNT(sCoordEventWeatherFuncs); i++) + { + if (sCoordEventWeatherFuncs[i].weather == n) + { + sCoordEventWeatherFuncs[i].func(); + return; + } + } +} diff --git a/src/credits.c b/src/credits.c new file mode 100644 index 000000000..13a6a1633 --- /dev/null +++ b/src/credits.c @@ -0,0 +1,916 @@ +#include "global.h" +#include "m4a.h" +#include "main.h" +#include "menu.h" +#include "palette.h" +#include "songs.h" +#include "sound.h" +#include "sprite.h" +#include "task.h" +#include "text.h" + +enum { + PAGE_TITLE, + PAGE_DIRECTOR, + PAGE_ART_DIRECTOR, + PAGE_BATTLE_DIRECTOR, + PAGE_MAIN_PROGRAMMER, + PAGE_BATTLE_SYSTEM_PROGRAMMER, + PAGE_PROGRAMMERS_1, + PAGE_PROGRAMMERS_2, + PAGE_PROGRAMMERS_3, + PAGE_MAIN_GRAHPICS_DESIGNER, + PAGE_POKEMON_GRAHPIC_DESIGNERS_1, + PAGE_POKEMON_GRAHPIC_DESIGNERS_2, + PAGE_POKEMON_GRAHPIC_DESIGNERS_3, + PAGE_POKEMON_DESIGNERS_1, + PAGE_POKEMON_DESIGNERS_2, + PAGE_MUSIC_COMPOSITION, + PAGE_SOUND_EFFECTS, + PAGE_GAME_DESIGNERS_1, + PAGE_GAME_DESIGNERS_2, + PAGE_GAME_DESIGNERS_3, + PAGE_PLOT_SCENARIO, + PAGE_GAME_SCENARIO, + PAGE_SCRIPT_DESIGNERS, + PAGE_MAP_DESIGNERS, + PAGE_MAP_DATA_DESIGNERS, + PAGE_PARAMETRIC_DESIGNERS, + PAGE_POKEDEX_TEXT, + PAGE_ENVIRONMENT_TOOLS, + PAGE_PRODUCT_TESTING, + PAGE_SPECIAL_THANKS, + PAGE_SPECIAL_THANKS_1, + PAGE_SPECIAL_THANKS_2, + PAGE_SPECIAL_THANKS_3, + PAGE_INFORMATION_SUPERVISORS, + PAGE_COORDINATORS, + PAGE_TASK_MANAGERS, + PAGE_PRODUCERS, + PAGE_EXECUTIVE_DIRECTOR, + PAGE_EXECUTIVE_PRODUCERS_1, + PAGE_EXECUTIVE_PRODUCERS_2, + PAGE_TRANSLATION_COORDINATOR, + PAGE_TRANSLATORS, + PAGE_PROGRAMMERS, + PAGE_GRAPHIC_DESIGNERS, + PAGE_PRODUCT_SUPPORT, + PAGE_ARTWORK, + PAGE_TEXT_EDITOR, + PAGE_NOA_TESTING, + PAGE_BRAILLE_CODE_CHECK_1, + PAGE_BRAILLE_CODE_CHECK_2, + PAGE_SPECIAL_THANKS_4, + PAGE_SPECIAL_THANKS_5, + + PAGE_COUNT +}; + +#define UNK_DEFINE_82 (0x82) + +#define COLOR_DARK_GREEN 0x1967 +#define COLOR_LIGHT_GREEN 0x328D + +enum { + TD_CURRENT_PAGE = 2, +}; + +struct Unk201C000 { + u8 pad_00[0x88]; + u16 var_88; + u16 var_8A; + u16 var_8C; +}; + +struct HallOfFame { + u8 sheet0[0x800]; + u8 sheet1[0x800]; + u8 sheet2[0x800]; +}; + +struct CreditsEntry { + u8 var_0; + u8 *text; +}; + +extern struct Unk201C000 unk_201C000; + +extern struct HallOfFame gHallOfFame; +extern u8 unk_201e800[0x800]; +extern u8 unk_201f000[0x800]; +extern u16 unk_201f800[]; + +extern s16 gUnknown_02039320; +extern u16 gUnknown_02039322; +extern u8 gUnknown_02039324; +extern u8 gUnknown_02039325; +extern u16 gUnknown_0203935C; + +extern u8 gReservedSpritePaletteCount; + +// data/starter_choose +extern u16 gBirchBagGrassPal[32]; +extern u8 gBirchBagTilemap[]; +extern u8 gBirchHelpGfx[]; + +// data/credits +extern u16 gUnknown_0840B7BC[32]; +extern u16 gUnknown_0840B7FC[32]; +extern struct CreditsEntry *gCreditsEntryPointerTable[][5]; +extern struct SpriteSheet gUnknown_0840CAA0; +extern struct SpritePalette gUnknown_0840CAB0; + +static void sub_8143B38(u8 taskId); +void sub_8143B68(u8 taskId); +static void sub_8143BFC(u8 taskId); +static void c2_080C9BFC(u8 taskId); +static void sub_8143CC0(u8 taskId); +static void sub_8143D04(u8 taskId); +static void sub_8143EBC(u8 taskId); +static void sub_8143F04(u8 taskId); +static void sub_8143F3C(u8 taskId); +static void sub_8143FDC(u8 taskId); +static void sub_8144024(u8 taskId); +static void sub_8144080(u8 taskId); +static void sub_8144114(u8 taskId); +static void sub_8144130(void); +static void sub_81441B8(u8 taskId); +static u8 sub_8144454(u8 page, u8 taskId); + +void sub_8144514(u8 taskId); +u8 sub_8144ECC(u8 data, u8 taskId); +void sub_81450AC(u8 taskId); +void sub_8145128(u16, u16, u16); +void sub_81452D0(int, int); +void sub_81458DC(void); + +static void sub_8143948(void) { + LoadOam(); + ProcessSpriteCopyRequests(); + TransferPlttBuffer(); +} + +static void sub_814395C(void) { + RunTasks(); + AnimateSprites(); + BuildOamBuffer(); + UpdatePaletteFade(); + + if (!(gMain.heldKeys & B_BUTTON)) + { + return; + } + + if (!gUnknown_02039324) + { + return; + } + + if (gTasks[gUnknown_02039322].func != sub_8143B68) + { + return; + } + + sub_8143948(); + RunTasks(); + AnimateSprites(); + BuildOamBuffer(); + UpdatePaletteFade(); + gUnknown_02039325 = 1; +} + +void sub_81439D0(void) { + u8 taskId; + s16 taskId3; + u8 taskId2; + u16 savedIme; + struct Unk201C000 *c000; + + sub_8144130(); + SetVBlankCallback(NULL); + ResetPaletteFade(); + ResetTasks(); + + taskId = CreateTask(sub_8143B38, 0); + + gTasks[taskId].data[4] = 0; + gTasks[taskId].data[7] = 0; + gTasks[taskId].data[11] = 0; + gTasks[taskId].data[13] = 1; + + while (TRUE) + { + if (sub_8144ECC(0, taskId)) + { + break; + } + } + + taskId3 = gTasks[taskId].data[1]; + gTasks[taskId3].data[0] = 40; + + SetUpWindowConfig(&gWindowConfig_81E7208); + InitMenuWindow(&gWindowConfig_81E7208); + LoadPalette(&gUnknown_0840B7BC, 0x80, sizeof(gUnknown_0840B7BC)); + + CpuCopy16(&gUnknown_0840B7FC, (void *) (VRAM + 0xBEE0), sizeof(gUnknown_0840B7FC)); + + REG_BG0VOFS = 0xFFFC; + + taskId2 = CreateTask(sub_81441B8, 0); + + gTasks[taskId2].data[1] = taskId; + gTasks[taskId].data[15] = taskId2; + + BeginNormalPaletteFade(-1, 0, 16, 0, 0); + + + savedIme = REG_IME; + REG_IME = 0; + REG_IE |= INTR_FLAG_VBLANK; + REG_IME = savedIme; + REG_DISPSTAT |= DISPSTAT_VBLANK_INTR; + + + SetVBlankCallback(sub_8143948); + m4aSongNumStart(BGM_THANKFOR); + SetMainCallback2(sub_814395C); + gUnknown_02039325 = 0; + + c000 = &unk_201C000; + + sub_81458DC(); + + c000->var_88 = 0; + c000->var_8A = 0; + c000->var_8C = 0; + + gUnknown_02039322 = taskId; +} + +void sub_8143B38(u8 taskId) { + if (gPaletteFade.active) + { + return; + } + + gTasks[taskId].func = sub_8143B68; +} + +void sub_8143B68(u8 taskId) { + u16 data11; + + if (gTasks[taskId].data[4]) + { + s16 secondaryTaskId; + + secondaryTaskId = gTasks[taskId].data[1]; + gTasks[secondaryTaskId].data[0] = 30; + + gTasks[taskId].data[12] = 0x100; + gTasks[taskId].func = sub_8143EBC; + return; + } + + gUnknown_02039320 = 0; + data11 = gTasks[taskId].data[11]; + + if (gTasks[taskId].data[11] == 1) + { + gTasks[taskId].data[13] = data11; + gTasks[taskId].data[11] = 0; + BeginNormalPaletteFade(-1, 0, 0, 16, 0); + gTasks[taskId].func = sub_8143BFC; + } + else if (gTasks[taskId].data[11] == 2) + { + gTasks[taskId].data[13] = data11; + gTasks[taskId].data[11] = 0; + BeginNormalPaletteFade(-1, 0, 0, 16, 0); + gTasks[taskId].func = sub_8143CC0; + } +} + +static void sub_8143BFC(u8 taskId) { + if (gPaletteFade.active) + { + return; + } + + REG_DISPCNT = 0; + sub_81450AC(taskId); + gTasks[taskId].func = c2_080C9BFC; +} + +static void c2_080C9BFC(u8 taskId) { + u16 backup; + + SetVBlankCallback(NULL); + + if (!sub_8144ECC(gTasks[taskId].data[7], taskId)) + { + return; + } + + BeginNormalPaletteFade(-1, 0, 16, 0, 0); + + backup = REG_IME; + REG_IME = 0; + REG_IE |= INTR_FLAG_VBLANK; + REG_IME = backup; + REG_DISPSTAT |= DISPSTAT_VBLANK_INTR; + + SetVBlankCallback(sub_8143948); + gTasks[taskId].func = sub_8143B38; +} + +static void sub_8143CC0(u8 taskId) { + if (gPaletteFade.active) + { + return; + } + + REG_DISPCNT = 0; + sub_81450AC(taskId); + gTasks[taskId].func = sub_8143D04; +} + +#ifdef NONMATCHING +static void sub_8143D04(u8 taskId) { + switch (gMain.state) { + default: + case 0: { + u16 i; + + ResetSpriteData(); + FreeAllSpritePalettes(); + gReservedSpritePaletteCount = 8; + LZ77UnCompVram(&gBirchHelpGfx, (void *) VRAM); + LZ77UnCompVram(&gBirchBagTilemap, (void *) (VRAM + 0x3800)); + LoadPalette(gBirchBagGrassPal + 2, 1, 31 * 2); + + for (i = 0; i < 0x800; i++) { + gHallOfFame.sheet0[i] = 0x11; + } + + for (i = 0; i < 0x800; i++) { + gHallOfFame.sheet1[i] = 0x22; + } + + for (i = 0; i < 0x800; i++) { + gHallOfFame.sheet2[i] = 0x33; + } + + unk_201f800[0] = 0; + unk_201f800[1] = 0x53FF; // light yellow + unk_201f800[2] = 0x529F; // light red + unk_201f800[3] = 0x7E94; // light blue + + LoadSpriteSheet(&gUnknown_0840CAA0); + LoadSpritePalette(&gUnknown_0840CAB0); + + gMain.state += 1; + break; + } + + case 1: { + gTasks[taskId].data[3] = CreateTask(sub_8144514, 0); + gTasks[gTasks[taskId].data[3]].data[0] = 1; + gTasks[gTasks[taskId].data[3]].data[1] = taskId; + gTasks[gTasks[taskId].data[3]].data[2] = gTasks[taskId].data[7]; + + BeginNormalPaletteFade(-1, 0, 16, 0, 0); + REG_BG3HOFS = 0; + REG_BG3VOFS = 32; + REG_BG3CNT = 0x703; + REG_DISPCNT = 0x1940; + + gMain.state = 0; + gUnknown_0203935C = 0; + gTasks[taskId].func = sub_8143B38; + break; + } + } +} +#else +__attribute__((naked)) +static void sub_8143D04(u8 taskId) { + asm(".syntax unified\n\ + push {r4-r7,lr}\n\ + mov r7, r9\n\ + mov r6, r8\n\ + push {r6,r7}\n\ + sub sp, 0x4\n\ + lsls r0, 24\n\ + lsrs r6, r0, 24\n\ + ldr r0, _08143DC8 @ =gMain\n\ + ldr r1, _08143DCC @ =0x0000043c\n\ + adds r1, r0\n\ + mov r8, r1\n\ + ldrb r7, [r1]\n\ + cmp r7, 0\n\ + beq _08143D24\n\ + cmp r7, 0x1\n\ + beq _08143E0C\n\ +_08143D24:\n\ + bl ResetSpriteData\n\ + bl FreeAllSpritePalettes\n\ + ldr r1, _08143DD0 @ =gReservedSpritePaletteCount\n\ + movs r0, 0x8\n\ + strb r0, [r1]\n\ + ldr r0, _08143DD4 @ =gBirchHelpGfx\n\ + movs r1, 0xC0\n\ + lsls r1, 19\n\ + bl LZ77UnCompVram\n\ + ldr r0, _08143DD8 @ =gBirchGrassTilemap\n\ + ldr r1, _08143DDC @ =0x06003800\n\ + bl LZ77UnCompVram\n\ + ldr r0, _08143DE0 @ =gBirchBagGrassPal + 2\n\ + movs r1, 0x1\n\ + movs r2, 0x3E\n\ + bl LoadPalette\n\ + movs r1, 0\n\ + ldr r4, _08143DE4 @ =0x0201e000\n\ + movs r3, 0x11\n\ + ldr r2, _08143DE8 @ =0x000007ff\n\ +_08143D56:\n\ + adds r0, r1, r4\n\ + strb r3, [r0]\n\ + adds r0, r1, 0x1\n\ + lsls r0, 16\n\ + lsrs r1, r0, 16\n\ + cmp r1, r2\n\ + bls _08143D56\n\ + movs r1, 0\n\ + ldr r2, _08143DEC @ =0x0201f800\n\ + ldr r6, _08143DF0 @ =gUnknown_0840CAA0\n\ + ldr r0, _08143DF4 @ =0xfffff000\n\ + adds r5, r2, r0\n\ + movs r4, 0x22\n\ + ldr r3, _08143DE8 @ =0x000007ff\n\ +_08143D72:\n\ + adds r0, r1, r5\n\ + strb r4, [r0]\n\ + adds r0, r1, 0x1\n\ + lsls r0, 16\n\ + lsrs r1, r0, 16\n\ + cmp r1, r3\n\ + bls _08143D72\n\ + movs r1, 0\n\ + ldr r5, _08143DF8 @ =0x0201f000\n\ + movs r4, 0x33\n\ + ldr r3, _08143DE8 @ =0x000007ff\n\ +_08143D88:\n\ + adds r0, r1, r5\n\ + strb r4, [r0]\n\ + adds r0, r1, 0x1\n\ + lsls r0, 16\n\ + lsrs r1, r0, 16\n\ + cmp r1, r3\n\ + bls _08143D88\n\ + movs r0, 0\n\ + strh r0, [r2]\n\ + ldr r1, _08143DFC @ =0x000053ff\n\ + adds r0, r1, 0\n\ + strh r0, [r2, 0x2]\n\ + ldr r1, _08143E00 @ =0x0000529f\n\ + adds r0, r1, 0\n\ + strh r0, [r2, 0x4]\n\ + ldr r1, _08143E04 @ =0x00007e94\n\ + adds r0, r1, 0\n\ + strh r0, [r2, 0x6]\n\ + adds r0, r6, 0\n\ + bl LoadSpriteSheet\n\ + ldr r0, _08143E08 @ =gUnknown_0840CAB0\n\ + bl LoadSpritePalette\n\ + ldr r1, _08143DC8 @ =gMain\n\ + ldr r2, _08143DCC @ =0x0000043c\n\ + adds r1, r2\n\ + ldrb r0, [r1]\n\ + adds r0, 0x1\n\ + strb r0, [r1]\n\ + b _08143E90\n\ + .align 2, 0\n\ +_08143DC8: .4byte gMain\n\ +_08143DCC: .4byte 0x0000043c\n\ +_08143DD0: .4byte gReservedSpritePaletteCount\n\ +_08143DD4: .4byte gBirchHelpGfx\n\ +_08143DD8: .4byte gBirchGrassTilemap\n\ +_08143DDC: .4byte 0x06003800\n\ +_08143DE0: .4byte gBirchBagGrassPal + 2\n\ +_08143DE4: .4byte 0x0201e000\n\ +_08143DE8: .4byte 0x000007ff\n\ +_08143DEC: .4byte 0x0201f800\n\ +_08143DF0: .4byte gUnknown_0840CAA0\n\ +_08143DF4: .4byte 0xfffff000\n\ +_08143DF8: .4byte 0x0201f000\n\ +_08143DFC: .4byte 0x000053ff\n\ +_08143E00: .4byte 0x0000529f\n\ +_08143E04: .4byte 0x00007e94\n\ +_08143E08: .4byte gUnknown_0840CAB0\n\ +_08143E0C:\n\ + ldr r0, _08143EA0 @ =sub_8144514\n\ + movs r1, 0\n\ + bl CreateTask\n\ + ldr r2, _08143EA4 @ =gTasks\n\ + lsls r4, r6, 2\n\ + adds r4, r6\n\ + lsls r4, 3\n\ + adds r4, r2\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + movs r1, 0\n\ + mov r9, r1\n\ + movs r5, 0\n\ + strh r0, [r4, 0xE]\n\ + movs r0, 0xE\n\ + ldrsh r1, [r4, r0]\n\ + lsls r0, r1, 2\n\ + adds r0, r1\n\ + lsls r0, 3\n\ + adds r0, r2\n\ + strh r7, [r0, 0x8]\n\ + movs r0, 0xE\n\ + ldrsh r1, [r4, r0]\n\ + lsls r0, r1, 2\n\ + adds r0, r1\n\ + lsls r0, 3\n\ + adds r0, r2\n\ + strh r6, [r0, 0xA]\n\ + movs r0, 0xE\n\ + ldrsh r1, [r4, r0]\n\ + lsls r0, r1, 2\n\ + adds r0, r1\n\ + lsls r0, 3\n\ + adds r0, r2\n\ + ldrh r1, [r4, 0x16]\n\ + strh r1, [r0, 0xC]\n\ + movs r0, 0x1\n\ + negs r0, r0\n\ + str r5, [sp]\n\ + movs r1, 0\n\ + movs r2, 0x10\n\ + movs r3, 0\n\ + bl BeginNormalPaletteFade\n\ + ldr r0, _08143EA8 @ =REG_BG3HOFS\n\ + strh r5, [r0]\n\ + ldr r1, _08143EAC @ =REG_BG3VOFS\n\ + movs r0, 0x20\n\ + strh r0, [r1]\n\ + subs r1, 0x10\n\ + ldr r2, _08143EB0 @ =0x00000703\n\ + adds r0, r2, 0\n\ + strh r0, [r1]\n\ + subs r1, 0xE\n\ + movs r2, 0xCA\n\ + lsls r2, 5\n\ + adds r0, r2, 0\n\ + strh r0, [r1]\n\ + mov r1, r9\n\ + mov r0, r8\n\ + strb r1, [r0]\n\ + ldr r0, _08143EB4 @ =gUnknown_0203935C\n\ + strh r5, [r0]\n\ + ldr r0, _08143EB8 @ =sub_8143B38\n\ + str r0, [r4]\n\ +_08143E90:\n\ + add sp, 0x4\n\ + pop {r3,r4}\n\ + mov r8, r3\n\ + mov r9, r4\n\ + pop {r4-r7}\n\ + pop {r0}\n\ + bx r0\n\ + .align 2, 0\n\ +_08143EA0: .4byte sub_8144514\n\ +_08143EA4: .4byte gTasks\n\ +_08143EA8: .4byte 0x4000000 + 0x1c\n\ +_08143EAC: .4byte 0x4000000 + 0x1e\n\ +_08143EB0: .4byte 0x00000703\n\ +_08143EB4: .4byte gUnknown_0203935C\n\ +_08143EB8: .4byte sub_8143B38\n\ + .syntax divided\n"); +} +#endif + +static void sub_8143EBC(u8 taskId) { + if (gTasks[taskId].data[12]) + { + gTasks[taskId].data[12] -= 1; + return; + } + + BeginNormalPaletteFade(-1, 12, 0, 16, 0); + gTasks[taskId].func = sub_8143F04; +} + +static void sub_8143F04(u8 taskId) { + if (gPaletteFade.active) + { + return; + } + + sub_81450AC(taskId); + gTasks[taskId].func = sub_8143F3C; +} + +static void sub_8143F3C(u8 taskId) { + u16 backup; + + sub_8144130(); + ResetPaletteFade(); + sub_8145128(0, 0x3800, 0); + ResetSpriteData(); + FreeAllSpritePalettes(); + BeginNormalPaletteFade(-1, 8, 16, 0, 0); + + REG_BG0CNT = 0x700; + backup = REG_IME; + REG_IME = 0; + REG_IE |= INTR_FLAG_VBLANK; + REG_IME = backup; + REG_DISPSTAT |= DISPSTAT_VBLANK_INTR; + REG_DISPCNT = 0x140; + + gTasks[taskId].data[0] = 0x100; + gTasks[taskId].func = sub_8143FDC; +} + +static void sub_8143FDC(u8 taskId) { + if (gTasks[taskId].data[0]) + { + gTasks[taskId].data[0] -= 1; + return; + } + + BeginNormalPaletteFade(-1, 6, 0, 16, 0); + gTasks[taskId].func = sub_8144024; +} + +static void sub_8144024(u8 taskId) { + if (gPaletteFade.active) + { + return; + } + + sub_81452D0(0x3800, 0); + + BeginNormalPaletteFade(-1, 0, 0, 0, 0); + gTasks[taskId].data[0] = 7200; + gTasks[taskId].func = sub_8144080; +} + +static void sub_8144080(u8 taskId) { + if (gPaletteFade.active) + { + return; + } + + if (gTasks[taskId].data[0] == 0) + { + FadeOutBGM(4); + BeginNormalPaletteFade(-1, 8, 0, 16, 0xFFFF); + gTasks[taskId].func = sub_8144114; + return; + } + + if (gMain.newKeys) + { + FadeOutBGM(4); + BeginNormalPaletteFade(-1, 8, 0, 16, 0xFFFF); + gTasks[taskId].func = sub_8144114; + return; + } + + if (gTasks[taskId].data[0] == 7144) + { + FadeOutBGM(8); + } + + if (gTasks[taskId].data[0] == 6840) + { + m4aSongNumStart(BGM_END); + } + + gTasks[taskId].data[0] -= 1; +} + +static void sub_8144114(u8 taskId) { + if (gPaletteFade.active) + { + return; + } + + SoftReset(0xFF); +} + +static void sub_8144130(void) { + REG_DISPCNT = 0; + + REG_BG3HOFS = 0; + REG_BG3VOFS = 0; + REG_BG2HOFS = 0; + REG_BG2VOFS = 0; + REG_BG1HOFS = 0; + REG_BG1VOFS = 0; + REG_BG0HOFS = 0; + REG_BG0VOFS = 0; + + REG_BLDCNT = 0; + REG_BLDALPHA = 0; + REG_BLDY = 0; + + DmaFill16(3, 0, (void *) VRAM, VRAM_SIZE); + DmaFill32(3, 0, (void *) OAM, OAM_SIZE); + DmaFill16(3, 0, (void *) (PLTT + 2), PLTT_SIZE - 2); +} + +static void sub_81441B8(u8 taskId) { + u16 i; + + switch (gTasks[taskId].data[0]) + { + case 0: + case 6: + case 7: + case 8: + case 9: + default: + if (gPaletteFade.active) + { + return; + } + gTasks[taskId].data[0] = 1; + gTasks[taskId].data[3] = 0x58; + gTasks[gTasks[taskId].data[1]].data[14] = 0; + gUnknown_02039320 = 0; + return; + + case 1: + if (gTasks[taskId].data[3] != 0) + { + gTasks[taskId].data[3] -= 1; + return; + } + + gTasks[taskId].data[0] += 1; + return; + + case 2: + REG_DISPCNT &= ~DISPCNT_BG0_ON; + + if (gTasks[gTasks[taskId].data[1]].func == sub_8143B68) + { + if (gTasks[taskId].data[TD_CURRENT_PAGE] < PAGE_COUNT) + { + + for (i = 0; i < 5; i++) + { + sub_8072BD8(gCreditsEntryPointerTable[gTasks[taskId].data[TD_CURRENT_PAGE]][i]->text, 0, + 9 + i * 2, 240); + } + + gTasks[taskId].data[TD_CURRENT_PAGE] += 1; + gTasks[taskId].data[0] += 1; + + gTasks[gTasks[taskId].data[1]].data[14] = 1; + + if (gTasks[gTasks[taskId].data[1]].data[13] == 1) + { + BeginNormalPaletteFade(0x300, 0, 16, 0, COLOR_LIGHT_GREEN); + } + else + { + BeginNormalPaletteFade(0x300, 0, 16, 0, COLOR_DARK_GREEN); + } + return; + } + + + gTasks[taskId].data[0] = 10; + return; + } + + gTasks[gTasks[taskId].data[1]].data[14] = 0; + return; + + case 3: + REG_DISPCNT |= DISPCNT_BG0_ON; + + if (gPaletteFade.active) + { + return; + } + + gTasks[taskId].data[3] = UNK_DEFINE_82; + gTasks[taskId].data[0] += 1; + return; + + case 4: + if (gTasks[taskId].data[3] != 0) + { + gTasks[taskId].data[3] -= 1; + return; + } + + if (sub_8144454((u8) gTasks[taskId].data[2], (u8) gTasks[taskId].data[1])) + { + gTasks[taskId].data[0] += 1; + return; + } + + gTasks[taskId].data[0] += 1; + + if (gTasks[gTasks[taskId].data[1]].data[13] == 1) + { + BeginNormalPaletteFade(0x300, 0, 0, 16, COLOR_LIGHT_GREEN); + } + else + { + BeginNormalPaletteFade(0x300, 0, 0, 16, COLOR_DARK_GREEN); + } + + return; + + case 5: + if (gPaletteFade.active) + { + return; + } + + MenuZeroFillWindowRect(0, 9, 29, 19); + gTasks[taskId].data[0] = 2; + return; + + case 10: + gTasks[gTasks[taskId].data[1]].data[4] = 1; + DestroyTask(taskId); + return; + } +} + +#define LAST_PAGE (PAGE_TEXT_EDITOR) + +static u8 sub_8144454(u8 page, u8 taskId) { + // Starts with bike + ocean + morning + + if (page == PAGE_PROGRAMMERS_1) + { + // Grass patch + gTasks[taskId].data[11] = 2; + } + + if (page == PAGE_POKEMON_GRAHPIC_DESIGNERS_3) + { + // Bike + ocean + sunset + gTasks[taskId].data[7] = 1; + gTasks[taskId].data[11] = 1; + } + + if (page == PAGE_GAME_DESIGNERS_2) + { + // Grass patch + gTasks[taskId].data[11] = 2; + } + + if (page == PAGE_MAP_DATA_DESIGNERS) + { + // Bike + forest + sunset + gTasks[taskId].data[7] = 2; + gTasks[taskId].data[11] = 1; + } + + if (page == PAGE_SPECIAL_THANKS_1) + { + // Grass patch + gTasks[taskId].data[11] = 2; + } + + if (page == PAGE_TASK_MANAGERS) + { + // Bike + forest + sunset + gTasks[taskId].data[7] = 3; + gTasks[taskId].data[11] = 1; + } + + if (page == PAGE_TRANSLATION_COORDINATOR) + { + // Grass patch + gTasks[taskId].data[11] = 2; + } + + if (page == LAST_PAGE) + { + // Bike + town + night + gTasks[taskId].data[7] = 4; + gTasks[taskId].data[11] = 1; + } + + if (gTasks[taskId].data[11] != 0) + { + // Returns true if changed? + return TRUE; + } + + return FALSE; +} diff --git a/src/daycare.c b/src/daycare.c new file mode 100644 index 000000000..23f0305d8 --- /dev/null +++ b/src/daycare.c @@ -0,0 +1,33 @@ +#include "global.h" +#include "pokemon.h" +#include "string_util.h" + +u8 *pokemon_get_nick(struct Pokemon *mon, u8 *dest) +{ + s8 nickname[POKEMON_NAME_LENGTH * 2]; + + GetMonData(mon, MON_DATA_NICKNAME, nickname); + return StringCopy10(dest, nickname); +} + +u8 *pokemon_get_nick_(struct BoxPokemon *mon, u8 *dest) +{ + s8 nickname[POKEMON_NAME_LENGTH * 2]; + + GetBoxMonData(mon, MON_DATA_NICKNAME, nickname); + return StringCopy10(dest, nickname); +} + +u8 daycare_count_pokemon(struct BoxPokemon *daycare_data) +{ + u8 i, count; + count = 0; + + for(i = 0;i <= 1;i++) { + if(GetBoxMonData(daycare_data + i, MON_DATA_SPECIES) != 0) { + count++; + } + } + + return count; +} diff --git a/src/decompress.c b/src/decompress.c index adc6798b6..8f573fecb 100644 --- a/src/decompress.c +++ b/src/decompress.c @@ -1,6 +1,7 @@ #include "global.h" +#include "decompress.h" #include "species.h" -#include "sprite.h" +#include "asm.h" #define WRAM 0x02000000 @@ -8,10 +9,6 @@ extern struct SpriteSheet gMonFrontPicTable[]; extern struct SpriteSheet gMonBackPicTable[]; extern void *gUnknown_081FAF4C[]; -extern void DrawSpindaSpots(u16, u32, void *, u8); - -void sub_800D378(struct SpriteSheet *a, u32 b, u32 c, u32 d, void *e, s32 f, u32 g, u32 h); - void sub_800D238(const void *src, void *dest) { LZ77UnCompWram(src, dest); @@ -22,7 +19,7 @@ void LZDecompressVram(const void *src, void *dest) LZ77UnCompVram(src, dest); } -void LoadCompressedObjectPic(struct SpriteSheet *a) +void LoadCompressedObjectPic(const struct SpriteSheet *a) { struct SpriteSheet spriteSheet; @@ -33,7 +30,7 @@ void LoadCompressedObjectPic(struct SpriteSheet *a) LoadSpriteSheet(&spriteSheet); } -void LoadCompressedObjectPicOverrideBuffer(struct SpriteSheet *a, void *buffer) +void LoadCompressedObjectPicOverrideBuffer(const struct SpriteSheet *a, void *buffer) { struct SpriteSheet spriteSheet; @@ -44,7 +41,7 @@ void LoadCompressedObjectPicOverrideBuffer(struct SpriteSheet *a, void *buffer) LoadSpriteSheet(&spriteSheet); } -void LoadCompressedObjectPalette(struct SpritePalette *a) +void LoadCompressedObjectPalette(const struct SpritePalette *a) { struct SpritePalette spritePalette; @@ -54,7 +51,7 @@ void LoadCompressedObjectPalette(struct SpritePalette *a) LoadSpritePalette(&spritePalette); } -void LoadCompressedObjectPaletteOverrideBuffer(struct SpritePalette *a, void *buffer) +void LoadCompressedObjectPaletteOverrideBuffer(const struct SpritePalette *a, void *buffer) { struct SpritePalette spritePalette; @@ -64,53 +61,55 @@ void LoadCompressedObjectPaletteOverrideBuffer(struct SpritePalette *a, void *bu LoadSpritePalette(&spritePalette); } -void DecompressPicFromTable_2(const struct SpriteSheet *a, u8 b, u8 c, void *d, void *e, s32 f) +void DecompressPicFromTable_2(const struct SpriteSheet *a, u8 b, u8 c, void *d, void *e, s32 species) { - if (f > 412) + if (species > SPECIES_EGG) LZ77UnCompWram(gMonFrontPicTable[0].data, e); else LZ77UnCompWram(a->data, e); } -void sub_800D334(struct SpriteSheet *a, u32 b, u32 c, u32 d, void *dest, s32 f, u32 g) +void HandleLoadSpecialPokePic(const struct SpriteSheet *spriteSheet, u32 b, u32 c, u32 d, void *dest, s32 species, u32 g) { - u32 unk; + u32 frontOrBack; + // gUnknown_081FAF4C appears to be a list of pointers to locations to store poke pics for back and front pic here. the first and third pointers are used for back while the others are used for front. if (dest == gUnknown_081FAF4C[0] || dest == gUnknown_081FAF4C[2]) - unk = 0; + frontOrBack = 0; // backPic else - unk = 1; - sub_800D378(a, b, c, d, dest, f, g, unk); + frontOrBack = 1; // frontPic + + LoadSpecialPokePic(spriteSheet, b, c, d, dest, species, g, frontOrBack); } -void sub_800D378(struct SpriteSheet *a, u32 b, u32 c, u32 d, void *dest, s32 f, u32 g, u32 h) +void LoadSpecialPokePic(const struct SpriteSheet *spriteSheet, u32 b, u32 c, u32 d, void *dest, s32 species, u32 g, u32 frontOrBack) { - u8 r7 = h; + u8 frontOrBack8 = frontOrBack; - if (f == SPECIES_UNOWN) + if (species == SPECIES_UNOWN) { - u16 r1 = (((g & 0x3000000) >> 18) | ((g & 0x30000) >> 12) | ((g & 0x300) >> 6) | (g & 3)) % 0x1C; + u16 i = (((g & 0x3000000) >> 18) | ((g & 0x30000) >> 12) | ((g & 0x300) >> 6) | (g & 3)) % 0x1C; - if (r1 == 0) - r1 = SPECIES_UNOWN; + // if it is Unown A, set the index to where Unown begins, otherwise add the egg index to get the correct letter to load. + if (i == 0) + i = SPECIES_UNOWN; else - r1 += 412; - if (r7 == 0) - LZ77UnCompWram(gMonBackPicTable[r1].data, dest); + i += SPECIES_EGG; + + if (frontOrBack8 == 0) + LZ77UnCompWram(gMonBackPicTable[i].data, dest); else - LZ77UnCompWram(gMonFrontPicTable[r1].data, dest); + LZ77UnCompWram(gMonFrontPicTable[i].data, dest); } + else if (species > SPECIES_EGG) // is species unknown? draw the ? icon + LZ77UnCompWram(gMonFrontPicTable[0].data, dest); else - { - if (f > 412) - LZ77UnCompWram(gMonFrontPicTable[0].data, dest); - else - LZ77UnCompWram(a->data, dest); - } - DrawSpindaSpots(f, g, dest, r7); + LZ77UnCompWram(spriteSheet->data, dest); + + DrawSpindaSpots(species, g, dest, frontOrBack8); } -static void Unused_LZDecompressWramIndirect(const void **src, void *dest) +void Unused_LZDecompressWramIndirect(const void **src, void *dest) { LZ77UnCompWram(*src, dest); } diff --git a/src/decoration.c b/src/decoration.c new file mode 100644 index 000000000..cf137799a --- /dev/null +++ b/src/decoration.c @@ -0,0 +1,26 @@ +#include "global.h" +#include "asm.h" +#include "menu.h" + +extern u8 gUnknown_020388F2; +extern u8 gUnknown_020388F3; +extern u8 gUnknown_020388F4; +extern u8 gUnknown_020388F6; +extern u8 gUnknown_020388D5; + +void sub_80FEC94(u8 arg0); +void sub_80FECB8(u8 arg0); +void sub_80FECE0(u8 arg0); + +void sub_80FE7EC(u8 arg0) { + sub_8072DEC(); + MenuZeroFillWindowRect(0, 0, 29, 19); + + sub_80FEC94(arg0); + sub_80FECB8(gUnknown_020388F6); + + MenuDrawTextWindow(15, 12, 29, 19); + + sub_80FECE0(gUnknown_020388F2 + gUnknown_020388F4); + InitMenu(0, 1, 2, gUnknown_020388F3 + 1, gUnknown_020388F2, 13); +} diff --git a/src/dewford_trend.c b/src/dewford_trend.c index 8d683e072..d534a9990 100644 --- a/src/dewford_trend.c +++ b/src/dewford_trend.c @@ -1,23 +1,14 @@ #include "global.h" +#include "asm.h" #include "link.h" #include "rng.h" -#include "flag.h" - -extern u8 GetLinkPlayerCount(void); -extern u16 sub_80EB72C(u16); -extern u8 ConvertEasyChatWordsToString(u8 *dst, u16 *words, u16, u16); +#include "event_data.h" extern struct EasyChatPair unk_2007800[5]; extern struct EasyChatPair unk_2007900[5]; extern u16 gScriptResult; extern u16 gSpecialVar_0x8004; -void sub_80FA740(struct EasyChatPair *); -void sub_80FA46C(struct EasyChatPair *, u16, u8); -bool8 sub_80FA670(struct EasyChatPair *, struct EasyChatPair *, u8); -bool8 IsEasyChatPairEqual(u16 *, u16 *); -bool8 SB1ContainsWords(u16 *); - void sub_80FA17C(void) { u16 i; @@ -394,7 +385,7 @@ void sub_80FA4E4(u8 *a, u32 b) } #else __attribute__((naked)) -void sub_80FA4E4(u8 *a, u32 b) +void sub_80FA4E4(struct EasyChatPair *a, u32 b, u8 c) { asm(".syntax unified\n\ push {r4-r7,lr}\n\ diff --git a/src/diploma.c b/src/diploma.c index 4d81ad4b0..8fabe3a2f 100644 --- a/src/diploma.c +++ b/src/diploma.c @@ -1,16 +1,15 @@ #include "global.h" +#include "asm.h" #include "main.h" #include "menu.h" #include "palette.h" +#include "pokedex.h" +#include "rom4.h" #include "sprite.h" #include "string_util.h" #include "task.h" #include "text.h" -extern void remove_some_task(void); -extern void sub_80546F0(void); -extern u16 sub_8090FF4(void); - extern u8 gDiplomaTiles[]; extern u8 gDiplomaTilemap[]; extern u8 gDiplomaPalettes[]; diff --git a/src/event_data.c b/src/event_data.c new file mode 100644 index 000000000..b1c0632ec --- /dev/null +++ b/src/event_data.c @@ -0,0 +1,163 @@ +#include "global.h" +#include "event_data.h" +#include "pokedex.h" + +extern u8 gUnknown_0202E8E2[]; +extern u16 *gSpecialVars[]; + +void InitEventData(void) +{ + memset(gSaveBlock1.flags, 0, sizeof(gSaveBlock1.flags)); + memset(gSaveBlock1.vars, 0, sizeof(gSaveBlock1.vars)); + memset(gUnknown_0202E8E2, 0, 16); +} + +void ClearTempFieldEventData(void) +{ + memset(gSaveBlock1.flags, 0, 4); + memset(gSaveBlock1.vars, 0, 32); + FlagReset(SYS_ENC_UP_ITEM); + FlagReset(SYS_ENC_DOWN_ITEM); + FlagReset(SYS_USE_STRENGTH); + FlagReset(SYS_CTRL_OBJ_DELETE); +} + +void ClearUpperFlags(void) +{ + memset(gSaveBlock1.flags + 0x118, 0, 8); +} + +void DisableNationalPokedex(void) +{ + u16 *nationalDexVar = GetVarPointer(VAR_NATIONAL_DEX); + gSaveBlock2.pokedex.nationalMagic = 0; + *nationalDexVar = 0; + FlagReset(SYS_NATIONAL_DEX); +} + +void EnableNationalPokedex(void) +{ + u16 *nationalDexVar = GetVarPointer(VAR_NATIONAL_DEX); + gSaveBlock2.pokedex.nationalMagic = 0xDA; + *nationalDexVar = 0x302; + FlagSet(SYS_NATIONAL_DEX); + gSaveBlock2.pokedex.unknown1 = 1; + gSaveBlock2.pokedex.order = 0; + sub_808C0A0(); +} + +bool32 IsNationalPokedexEnabled(void) +{ + if (gSaveBlock2.pokedex.nationalMagic == 0xDA && VarGet(VAR_NATIONAL_DEX) == 0x302 && FlagGet(SYS_NATIONAL_DEX)) + return TRUE; + else + return FALSE; +} + +void DisableMysteryGift(void) +{ + FlagReset(SYS_EXDATA_ENABLE); +} + +void EnableMysteryGift(void) +{ + FlagSet(SYS_EXDATA_ENABLE); +} + +bool32 IsMysteryGiftEnabled(void) +{ + return FlagGet(SYS_EXDATA_ENABLE); +} + +void DisableResetRTC(void) +{ + VarSet(VAR_RESET_RTC_ENABLE, 0); + FlagReset(SYS_RESET_RTC_ENABLE); +} + +void EnableResetRTC(void) +{ + VarSet(VAR_RESET_RTC_ENABLE, 0x920); + FlagSet(SYS_RESET_RTC_ENABLE); +} + +bool32 CanResetRTC(void) +{ + if (FlagGet(SYS_RESET_RTC_ENABLE) && VarGet(VAR_RESET_RTC_ENABLE) == 0x920) + return TRUE; + else + return FALSE; +} + +u16 *GetVarPointer(u16 id) +{ + if (id < 0x4000) + return NULL; + + if ((s16)id >= 0) + return &gSaveBlock1.vars[id - 0x4000]; + + return gSpecialVars[id - 0x8000]; +} + +u16 VarGet(u16 id) +{ + u16 *ptr = GetVarPointer(id); + if (!ptr) + return id; + return *ptr; +} + +bool8 VarSet(u16 id, u16 value) +{ + u16 *ptr = GetVarPointer(id); + if (!ptr) + return FALSE; + *ptr = value; + return TRUE; +} + +u8 VarGetFieldObjectGraphicsId(u8 id) +{ + return VarGet(0x4010 + id); +} + +u8 *GetFlagPointer(u16 id) +{ + if (id == 0) + return 0; + + if (id < 0x4000) + return &gSaveBlock1.flags[id / 8]; + + return &gUnknown_0202E8E2[(id - 0x4000) / 8]; +} + +u8 FlagSet(u16 id) +{ + u8 *ptr = GetFlagPointer(id); + if (ptr) + *ptr |= 1 << (id & 7); + return 0; +} + +u8 FlagReset(u16 id) +{ + u8 *ptr = GetFlagPointer(id); + if (ptr) + *ptr &= ~(1 << (id & 7)); + return 0; +} + +bool8 FlagGet(u16 id) +{ + u8 *ptr = GetFlagPointer(id); + + if (!ptr) + return FALSE; + + if (!(((*ptr) >> (id & 7)) & 1)) + return FALSE; + + return TRUE; +} diff --git a/src/field_camera.c b/src/field_camera.c index 02db33bf2..c55d8e2a3 100644 --- a/src/field_camera.c +++ b/src/field_camera.c @@ -1,19 +1,14 @@ #include "global.h" -#include "fieldmap.h" +#include "field_camera.h" +#include "asm.h" +#include "berry.h" +#include "field_player_avatar.h" +#include "asm_fieldmap.h" #include "sprite.h" #include "text.h" extern u16 gBGTilemapBuffers[4][0x400]; - -//ToDo: argument types -extern u8 MapGridGetMetatileLayerTypeAt(); -extern u8 player_get_direction_upper_nybble(void); -extern void ResetBerryTreeSparkleFlags(void); -extern void RotatingGatePuzzleCameraUpdate(s16, s16); -extern int MapGridGetMetatileIdAt(int, int); -extern int CameraMove(int, int); - extern u8 gUnknown_0202E854; @@ -51,13 +46,10 @@ static void RedrawMapSliceSouth(struct UnknownStruct *a, struct MapData *mapData static void RedrawMapSliceEast(struct UnknownStruct *a, struct MapData *mapData); static void RedrawMapSliceWest(struct UnknownStruct *a, struct MapData *mapData); static s32 MapPosToBgTilemapOffset(struct UnknownStruct *a, s32 x, s32 y); -void CameraUpdate(void); static void DrawWholeMapViewInternal(int x, int y, struct MapData *mapData); static void DrawMetatileAt(struct MapData *mapData, u16, int, int); static void DrawMetatile(s32 a, u16 *b, u16 c); -u8 AddCameraObject(u8); -void UpdateFieldObjectsForCameraUpdate(s16, s16); static void CameraPanningCB_PanAhead(void); static void move_tilemap_camera_to_upper_left_corner_(struct UnknownStruct *a) @@ -435,7 +427,7 @@ void CameraUpdate(void) gUnknown_03004898 -= r8; } -static void camera_move_and_redraw(int a, int b) +void camera_move_and_redraw(int a, int b) { CameraMove(a, b); UpdateFieldObjectsForCameraUpdate(a, b); diff --git a/src/field_door.c b/src/field_door.c index 68c884af1..85a5965a0 100644 --- a/src/field_door.c +++ b/src/field_door.c @@ -1,7 +1,8 @@ #include "global.h" +#include "asm.h" #include "task.h" - -extern u8 MetatileBehavior_IsDoor(u8); +#include "field_camera.h" +#include "metatile_behavior.h" struct DoorGraphics { @@ -186,7 +187,7 @@ static s8 cur_mapdata_get_door_x2_at(struct DoorGraphics *gfx, u32 x, u32 y) return gfx->unk2; } -static void unref_sub_805869C(u32 x, u32 y) +void unref_sub_805869C(u32 x, u32 y) { StartDoorOpenAnimation(gDoorAnimGraphicsTable, x, y); } @@ -224,7 +225,7 @@ bool8 FieldIsDoorAnimationRunning(void) return FuncIsActiveTask(Task_AnimateDoor); } -u8 sub_8058790(u32 x, u32 y) +u32 sub_8058790(u32 x, u32 y) { if (cur_mapdata_get_door_x2_at(gDoorAnimGraphicsTable, x, y) == 0) return 8; diff --git a/src/field_effect.c b/src/field_effect.c index 97301ab50..fe586fcb6 100644 --- a/src/field_effect.c +++ b/src/field_effect.c @@ -1,4 +1,6 @@ #include "global.h" +#include "field_effect.h" +#include "weather.h" #include "sprite.h" typedef bool8 (*FldEffCmd)(u8 **, u32 *); @@ -9,18 +11,6 @@ extern u8 *gFieldEffectScriptPointers[]; extern FldEffCmd gFieldEffectScriptFuncs[]; -void FieldEffectScript_LoadTiles(u8 **script); -void FieldEffectScript_LoadFadedPalette(u8 **script); -void FieldEffectScript_LoadPalette(u8 **script); -void FieldEffectScript_CallNative(u8 **script, u32 *val); -void FieldEffectFreeGraphicsResources(struct Sprite *sprite); -void FieldEffectStop(struct Sprite *sprite, u8 id); -void FieldEffectFreeTilesIfUnused(u16 tileStart); -void FieldEffectFreePaletteIfUnused(u8 paletteNum); -void FieldEffectActiveListClear(void); -void FieldEffectActiveListAdd(u8 id); -void FieldEffectActiveListRemove(u8 id); - u32 FieldEffectStart(u8 id) { u8 *script; diff --git a/src/field_ground_effect.c b/src/field_ground_effect.c new file mode 100644 index 000000000..1aea8f52e --- /dev/null +++ b/src/field_ground_effect.c @@ -0,0 +1,256 @@ +#include "global.h" +#include "asm_fieldmap.h" +#include "metatile_behavior.h" + +extern u32 gUnknown_08376008[]; + +void FieldObjectUpdateMetatileBehaviors(struct MapObject *); +void GetGroundEffectFlags_Reflection(struct MapObject *, u32 *); +void GetGroundEffectFlags_TallGrassOnSpawn(struct MapObject *, u32 *); +void GetGroundEffectFlags_TallGrassOnBeginStep(struct MapObject *, u32 *); +void GetGroundEffectFlags_LongGrassOnSpawn(struct MapObject *, u32 *); +void GetGroundEffectFlags_LongGrassOnBeginStep(struct MapObject *, u32 *); +void GetGroundEffectFlags_Tracks(struct MapObject *, u32 *); +void GetGroundEffectFlags_SandPile(struct MapObject *, u32 *); +void GetGroundEffectFlags_ShallowFlowingWater(struct MapObject *, u32 *); +void GetGroundEffectFlags_Puddle(struct MapObject *, u32 *); +void GetGroundEffectFlags_Ripple(struct MapObject *, u32 *); +void GetGroundEffectFlags_ShortGrass(struct MapObject *, u32 *); +void GetGroundEffectFlags_HotSprings(struct MapObject *, u32 *); +void GetGroundEffectFlags_Seaweed(struct MapObject *, u32 *); +void GetGroundEffectFlags_JumpLanding(struct MapObject *, u32 *); +u8 FieldObjectCheckForReflectiveSurface(struct MapObject *); + +void GetAllGroundEffectFlags_OnSpawn(struct MapObject *mapObj, u32 *flags) +{ + FieldObjectUpdateMetatileBehaviors(mapObj); + GetGroundEffectFlags_Reflection(mapObj, flags); + GetGroundEffectFlags_TallGrassOnSpawn(mapObj, flags); + GetGroundEffectFlags_LongGrassOnSpawn(mapObj, flags); + GetGroundEffectFlags_SandPile(mapObj, flags); + GetGroundEffectFlags_ShallowFlowingWater(mapObj, flags); + GetGroundEffectFlags_ShortGrass(mapObj, flags); + GetGroundEffectFlags_HotSprings(mapObj, flags); +} + +void GetAllGroundEffectFlags_OnBeginStep(struct MapObject *mapObj, u32 *flags) +{ + FieldObjectUpdateMetatileBehaviors(mapObj); + GetGroundEffectFlags_Reflection(mapObj, flags); + GetGroundEffectFlags_TallGrassOnBeginStep(mapObj, flags); + GetGroundEffectFlags_LongGrassOnBeginStep(mapObj, flags); + GetGroundEffectFlags_Tracks(mapObj, flags); + GetGroundEffectFlags_SandPile(mapObj, flags); + GetGroundEffectFlags_ShallowFlowingWater(mapObj, flags); + GetGroundEffectFlags_Puddle(mapObj, flags); + GetGroundEffectFlags_ShortGrass(mapObj, flags); + GetGroundEffectFlags_HotSprings(mapObj, flags); +} + +void GetAllGroundEffectFlags_OnFinishStep(struct MapObject *mapObj, u32 *flags) +{ + FieldObjectUpdateMetatileBehaviors(mapObj); + GetGroundEffectFlags_ShallowFlowingWater(mapObj, flags); + GetGroundEffectFlags_SandPile(mapObj, flags); + GetGroundEffectFlags_Puddle(mapObj, flags); + GetGroundEffectFlags_Ripple(mapObj, flags); + GetGroundEffectFlags_ShortGrass(mapObj, flags); + GetGroundEffectFlags_HotSprings(mapObj, flags); + GetGroundEffectFlags_Seaweed(mapObj, flags); + GetGroundEffectFlags_JumpLanding(mapObj, flags); +} + +void FieldObjectUpdateMetatileBehaviors(struct MapObject *mapObj) +{ + mapObj->mapobj_unk_1F = MapGridGetMetatileBehaviorAt(mapObj->coords3.x, mapObj->coords3.y); + mapObj->mapobj_unk_1E = MapGridGetMetatileBehaviorAt(mapObj->coords2.x, mapObj->coords2.y); +} + +void GetGroundEffectFlags_Reflection(struct MapObject *mapObj, u32 *flags) +{ + u32 reflectionFlags[2] = { 0x00000020, 0x00000010 }; + u8 type = FieldObjectCheckForReflectiveSurface(mapObj); + + if (type) + { + if (!mapObj->mapobj_bit_17) + { + mapObj->mapobj_bit_17 = 0; + mapObj->mapobj_bit_17 = 1; + *flags |= reflectionFlags[type - 1]; + } + } + else + { + mapObj->mapobj_bit_17 = 0; + } +} + +void GetGroundEffectFlags_TallGrassOnSpawn(struct MapObject *mapObj, u32 *flags) +{ + if (MetatileBehavior_IsTallGrass(mapObj->mapobj_unk_1E)) + *flags |= 0x1; +} + +void GetGroundEffectFlags_TallGrassOnBeginStep(struct MapObject *mapObj, u32 *flags) +{ + if (MetatileBehavior_IsTallGrass(mapObj->mapobj_unk_1E)) + *flags |= 0x2; +} + +void GetGroundEffectFlags_LongGrassOnSpawn(struct MapObject *mapObj, u32 *flags) +{ + if (MetatileBehavior_IsLongGrass(mapObj->mapobj_unk_1E)) + *flags |= 0x4; +} + +void GetGroundEffectFlags_LongGrassOnBeginStep(struct MapObject *mapObj, u32 *flags) +{ + if (MetatileBehavior_IsLongGrass(mapObj->mapobj_unk_1E)) + *flags |= 0x8; +} + +void GetGroundEffectFlags_Tracks(struct MapObject *mapObj, u32 *flags) +{ + if (MetatileBehavior_IsDeepSand(mapObj->mapobj_unk_1F)) + { + *flags |= 0x100; + } + else if (MetatileBehavior_IsSandOrDeepSand(mapObj->mapobj_unk_1F) + || MetatileBehavior_IsUnusedFootprintMetatile(mapObj->mapobj_unk_1F)) + { + *flags |= 0x80; + } +} + +void GetGroundEffectFlags_SandPile(struct MapObject *mapObj, u32 *flags) +{ + if (MetatileBehavior_IsDeepSand(mapObj->mapobj_unk_1E) + && MetatileBehavior_IsDeepSand(mapObj->mapobj_unk_1F)) + { + if (!mapObj->mapobj_bit_20) + { + mapObj->mapobj_bit_20 = 0; + mapObj->mapobj_bit_20 = 1; + *flags |= 0x800; + } + } + else + { + mapObj->mapobj_bit_20 = 0; + } +} + +void GetGroundEffectFlags_ShallowFlowingWater(struct MapObject *mapObj, u32 *flags) +{ + if ((MetatileBehavior_IsShallowFlowingWater(mapObj->mapobj_unk_1E) && MetatileBehavior_IsShallowFlowingWater(mapObj->mapobj_unk_1F)) + || (MetatileBehavior_IsPacifidlogLog(mapObj->mapobj_unk_1E) && MetatileBehavior_IsPacifidlogLog(mapObj->mapobj_unk_1F))) + { + if (!mapObj->mapobj_bit_19) + { + mapObj->mapobj_bit_19 = 0; + mapObj->mapobj_bit_19 = 1; + *flags |= 0x40; + } + } + else + { + mapObj->mapobj_bit_19 = 0; + } +} + +void GetGroundEffectFlags_Puddle(struct MapObject *mapObj, u32 *flags) +{ + if (MetatileBehavior_IsPuddle(mapObj->mapobj_unk_1E) + && MetatileBehavior_IsPuddle(mapObj->mapobj_unk_1F)) + { + *flags |= 0x400; + } +} + +void GetGroundEffectFlags_Ripple(struct MapObject *mapObj, u32 *flags) +{ + if (MetatileBehavior_HasRipples(mapObj->mapobj_unk_1E)) + *flags |= 0x200; +} + +void GetGroundEffectFlags_ShortGrass(struct MapObject *mapObj, u32 *flags) +{ + if (MetatileBehavior_IsShortGrass(mapObj->mapobj_unk_1E) + && MetatileBehavior_IsShortGrass(mapObj->mapobj_unk_1F)) + { + if (!mapObj->mapobj_bit_18) + { + mapObj->mapobj_bit_18 = 0; + mapObj->mapobj_bit_18 = 1; + *flags |= 0x20000; + } + } + else + { + mapObj->mapobj_bit_18 = 0; + } +} + +void GetGroundEffectFlags_HotSprings(struct MapObject *mapObj, u32 *flags) +{ + if (MetatileBehavior_IsHotSprings(mapObj->mapobj_unk_1E) + && MetatileBehavior_IsHotSprings(mapObj->mapobj_unk_1F)) + { + if (!mapObj->mapobj_bit_21) + { + mapObj->mapobj_bit_21 = 0; + mapObj->mapobj_bit_21 = 1; + *flags |= 0x40000; + } + } + else + { + mapObj->mapobj_bit_21 = 0; + } +} + +void GetGroundEffectFlags_Seaweed(struct MapObject *mapObj, u32 *flags) +{ + if (MetatileBehavior_IsSeaweed(mapObj->mapobj_unk_1E)) + *flags |= 0x80000; +} + +void GetGroundEffectFlags_JumpLanding(struct MapObject *mapObj, u32 *flags) +{ + typedef bool8 (*MetatileFunc)(u8); + + static const MetatileFunc metatileFuncs[] = + { + MetatileBehavior_IsTallGrass, + MetatileBehavior_IsLongGrass, + MetatileBehavior_IsPuddle, + MetatileBehavior_IsSurfableWaterOrUnderwater, + MetatileBehavior_IsShallowFlowingWater, + MetatileBehavior_IsATile, + }; + + static const u32 jumpLandingFlags[] = + { + 0x00001000, // Landing in tall grass + 0x00002000, // Landing in long grass + 0x00004000, // Landing on puddle + 0x00008000, // Landing on surfable water or underwater + 0x00004000, // Landing on shallow flowing water + 0x00010000, // Landing on any other type of ground + }; + + if (mapObj->mapobj_bit_5 && !mapObj->mapobj_bit_25) + { + u8 i; + + for (i = 0; i < 6; i++) + { + if (metatileFuncs[i](mapObj->mapobj_unk_1E)) + { + *flags |= jumpLandingFlags[i]; + return; + } + } + } +} diff --git a/src/map_obj_80643A4.c b/src/field_map_obj_helpers.c index 8e2faf268..6e835d744 100644 --- a/src/map_obj_80643A4.c +++ b/src/field_map_obj_helpers.c @@ -1,12 +1,8 @@ #include "global.h" +#include "asm.h" #include "sprite.h" -#include "fieldmap.h" - -extern void SetObjectSubpriorityByZCoord(u8, struct Sprite *, u8); -extern u8 FieldObjectDirectionToImageAnimId(u8); -extern u32 FieldEffectStart(u8); -extern void FieldObjectGetLocalIdAndMap(struct MapObject *, u8 *, u8 *, u8 *); -extern struct MapObjectGraphicsInfo *GetFieldObjectGraphicsInfo(u8); +#include "asm_fieldmap.h" +#include "field_effect.h" typedef void (*SpriteStepFunc)(struct Sprite *sprite, u8 dir); @@ -21,7 +17,7 @@ extern u8 gUnknown_083761E2[]; extern s16 gUnknown_083761E6[]; extern u8 gUnknown_083761EC[]; -bool8 sub_80643A4(struct MapObject *mapObject) +bool8 FreezeMapObject(struct MapObject *mapObject) { if (mapObject->mapobj_bit_6 || mapObject->mapobj_bit_8) { @@ -38,23 +34,23 @@ bool8 sub_80643A4(struct MapObject *mapObject) } } -void player_bitmagic() +void FreezeMapObjects() { u8 i; for (i = 0; i < 16; i++) if (gMapObjects[i].active && i != gPlayerAvatar.mapObjectId) - sub_80643A4(&gMapObjects[i]); + FreezeMapObject(&gMapObjects[i]); } -void sub_8064470(u8 a1) +void FreezeMapObjectsExceptOne(u8 a1) { u8 i; for (i = 0; i < 16; i++) if (i != a1 && gMapObjects[i].active && i != gPlayerAvatar.mapObjectId) - sub_80643A4(&gMapObjects[i]); + FreezeMapObject(&gMapObjects[i]); } -void npc_sync_anim_pause_bits(struct MapObject *mapObject) +void UnfreezeMapObject(struct MapObject *mapObject) { if (mapObject->active && mapObject->mapobj_bit_8) { @@ -64,39 +60,39 @@ void npc_sync_anim_pause_bits(struct MapObject *mapObject) } } -void sub_806451C(void) +void UnfreezeMapObjects(void) { u8 i; for (i = 0; i < 16; i++) if (gMapObjects[i].active) - npc_sync_anim_pause_bits(&gMapObjects[i]); + UnfreezeMapObject(&gMapObjects[i]); } -void little_step(struct Sprite *sprite, u8 dir) +void Step1(struct Sprite *sprite, u8 dir) { sprite->pos1.x += gDirectionToVector[dir].x; sprite->pos1.y += gDirectionToVector[dir].y; } -void sub_806456C(struct Sprite *sprite, u8 dir) +void Step2(struct Sprite *sprite, u8 dir) { sprite->pos1.x += 2 * gDirectionToVector[dir].x; sprite->pos1.y += 2 * gDirectionToVector[dir].y; } -void sub_8064590(struct Sprite *sprite, u8 dir) +void Step3(struct Sprite *sprite, u8 dir) { sprite->pos1.x += 2 * gDirectionToVector[dir].x + gDirectionToVector[dir].x; sprite->pos1.y += 2 * gDirectionToVector[dir].y + gDirectionToVector[dir].y; } -void sub_80645B8(struct Sprite *sprite, u8 dir) +void Step4(struct Sprite *sprite, u8 dir) { sprite->pos1.x += 4 * gDirectionToVector[dir].x; sprite->pos1.y += 4 * gDirectionToVector[dir].y; } -void sub_80645DC(struct Sprite *sprite, u8 dir) +void Step8(struct Sprite *sprite, u8 dir) { sprite->pos1.x += 8 * gDirectionToVector[dir].x; sprite->pos1.y += 8 * gDirectionToVector[dir].y; @@ -135,7 +131,7 @@ bool8 sub_806468C(struct Sprite *sprite) { if (!(sprite->data4 & 1)) { - little_step(sprite, sprite->data3); + Step1(sprite, sprite->data3); sprite->data5++; } @@ -172,7 +168,7 @@ u8 sub_8064704(struct Sprite *sprite) v2 = 0; if (sprite->data4) - little_step(sprite, sprite->data3); + Step1(sprite, sprite->data3); sprite->pos2.y = sub_80646C8(sprite->data6 >> v6[sprite->data4], sprite->data5); @@ -202,7 +198,7 @@ u8 sub_806478C(struct Sprite *sprite) v2 = 0; if (sprite->data4 && !(sprite->data6 & 1)) - little_step(sprite, sprite->data3); + Step1(sprite, sprite->data3); sprite->pos2.y = sub_80646C8(sprite->data6 >> v6[sprite->data4], sprite->data5); diff --git a/src/field_message_box.c b/src/field_message_box.c index f42541c49..a7d1a2fd8 100644 --- a/src/field_message_box.c +++ b/src/field_message_box.c @@ -22,7 +22,7 @@ void InitFieldMessageBox(void) { sMessageBoxMode = FIELD_MESSAGE_BOX_HIDDEN; SetMessageBoxBaseTileNum(gMenuTextWindowContentTileOffset); - InitWindowFromConfig(&gFieldMessageBoxWindow, (struct WindowConfig *)&gWindowConfig_81E6CE4); + InitWindowFromConfig(&gFieldMessageBoxWindow, &gWindowConfig_81E6CE4); } static void Task_FieldMessageBox(u8 taskId) diff --git a/src/field_player_avatar.c b/src/field_player_avatar.c new file mode 100644 index 000000000..fdd5ae5c5 --- /dev/null +++ b/src/field_player_avatar.c @@ -0,0 +1,1602 @@ +#include "global.h" +#include "field_player_avatar.h" +#include "asm.h" +#include "field_map_obj.h" +#include "rom4.h" +#include "event_data.h" +#include "main.h" +#include "menu.h" +#include "rng.h" +#include "script.h" +#include "songs.h" +#include "sound.h" +#include "task.h" +#include "field_effect.h" +#include "wild_encounter.h" +#include "asm_fieldmap.h" +#include "metatile_behavior.h" + +extern u8 gOtherText_OhABite[]; +extern u8 gOtherText_PokeOnHook[]; +extern u8 gOtherText_NotEvenANibble[]; +extern u8 gOtherText_ItGotAway[]; + +extern struct +{ + s32 x; + s32 y; + u32 unk8; + u32 unkC; +} gUnknown_0202FF84; + +extern bool8 (*gUnknown_0830FB58[])(u8); +extern u8 (*gUnknown_0830FBA0[])(void); +extern void (*gUnknown_0830FBEC[])(u8, u16); +extern bool8 (*gUnknown_0830FBF8[])(u8); +extern u8 gUnknown_0830FC0C[]; +extern void (*gUnknown_0830FC14[])(struct MapObject *); +extern bool8 (*gUnknown_0830FC34[])(u8); +extern u8 gUnknown_0830FC44[][2]; +extern u8 gUnknown_0830FC54[][2]; +extern u8 gUnknown_0830FC64[2][5][2]; +extern bool8 (*gUnknown_0830FC78[])(u8); //Duplicate of gUnknown_0830FC34 +extern u8 (*gUnknown_0830FC88[])(struct Task *, struct MapObject *, struct MapObject *); +extern u8 (*gUnknown_0830FC94[])(struct Task *, struct MapObject *); +extern u8 (*gUnknown_0830FC98[])(struct Task *, struct MapObject *); +extern u8 gUnknown_0830FCA8[]; +extern u8 gUnknown_0830FCAC[]; +extern u8 (*gUnknown_0830FCB4[])(struct Task *); +extern s16 gUnknown_0830FCF4[]; +extern s16 gUnknown_0830FCFA[]; +extern u8 gUnknown_0830FD00[]; +extern s16 gUnknown_0830FD02[]; +extern s16 gUnknown_0830FD08[]; + +//Functions +static u32 sub_80587D8(void); +static bool8 sub_8058854(struct MapObject *, u8); +static void npc_clear_strange_bits(struct MapObject *a); +static void MovePlayerAvatarUsingKeypadInput(u8 a, u16 b, u16 c); +static void PlayerAllowForcedMovementIfMovingSameDirection(void); +static u8 TryDoMetatileBehaviorForcedMovement(void); +static u8 GetForcedMovementByMetatileBehavior(void); +static void MovePlayerNotOnBike(u8 a, u16 b); +static u8 CheckMovementInputNotOnBike(u8 a); +static u8 CheckForPlayerAvatarCollision(u8 a); +static u8 sub_8058EF0(s16 a, s16 b, u8 c); +static bool8 ShouldJumpLedge(s16 a, s16 b, u8 c); +static u8 sub_8058F6C(s16 a, s16 b, u8 c); +static void check_acro_bike_metatile(int unused1, int unused2, u8 c, u8 *d); +static void DoPlayerAvatarTransition(void); +static bool8 player_is_anim_in_certain_ranges(void); +static bool8 sub_80592A4(void); +static bool8 PlayerIsAnimActive(void); +static bool8 PlayerCheckIfAnimFinishedOrInactive(void); +static void PlayerNotOnBikeCollide(u8 a); +static void PlayCollisionSoundIfNotFacingWarp(u8 a); +static void sub_8059D60(struct MapObject *a); +static void StartStrengthAnim(u8 a, u8 b); +static void sub_8059F94(void); +static void sub_805A06C(void); + +void sub_80587B4(struct Sprite *sprite) +{ + meta_step(&gMapObjects[sprite->data0], sprite, sub_80587D8); +} + +static u32 sub_80587D8(void) +{ + return 0; +} + +void player_step(u8 a, u16 b, u16 c) +{ + struct MapObject *playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId]; + + sub_8059D60(playerMapObj); + if (gPlayerAvatar.unk6 == 0) + { + sub_80E5B38(b, c); + if (sub_8058854(playerMapObj, a) == 0) + { + npc_clear_strange_bits(playerMapObj); + DoPlayerAvatarTransition(); + if (TryDoMetatileBehaviorForcedMovement() == 0) + { + MovePlayerAvatarUsingKeypadInput(a, b, c); + PlayerAllowForcedMovementIfMovingSameDirection(); + } + } + } +} + +static bool8 sub_8058854(struct MapObject *a, u8 b) +{ + if (FieldObjectIsSpecialAnimOrDirectionSequenceAnimActive(a) + && !FieldObjectClearAnimIfSpecialAnimFinished(a)) + { + u8 specialAnim = FieldObjectGetSpecialAnim(a); + + if (specialAnim > 24 && specialAnim < 29 && b != 0 && a->placeholder18 != b) + { + FieldObjectClearAnim(a); + return FALSE; + } + else + { + return TRUE; + } + } + return FALSE; +} + +static void npc_clear_strange_bits(struct MapObject *a) +{ + a->mapobj_bit_12 = 0; + a->mapobj_bit_10 = 0; + a->mapobj_bit_9 = 0; + gPlayerAvatar.flags &= ~PLAYER_AVATAR_FLAG_DASH; +} + +static void MovePlayerAvatarUsingKeypadInput(u8 a, u16 b, u16 c) +{ + if ((gPlayerAvatar.flags & PLAYER_AVATAR_FLAG_MACH_BIKE) + || (gPlayerAvatar.flags & PLAYER_AVATAR_FLAG_ACRO_BIKE)) + MovePlayerOnBike(a, b, c); + else + MovePlayerNotOnBike(a, c); +} + +static void PlayerAllowForcedMovementIfMovingSameDirection(void) +{ + if (gPlayerAvatar.running2 == 2) + gPlayerAvatar.flags &= ~PLAYER_AVATAR_FLAG_5; +} + +static u8 TryDoMetatileBehaviorForcedMovement(void) +{ + return gUnknown_0830FBA0[GetForcedMovementByMetatileBehavior()](); +} + +static u8 GetForcedMovementByMetatileBehavior(void) +{ + u8 i; + + if (!(gPlayerAvatar.flags & PLAYER_AVATAR_FLAG_5)) + { + u8 r5 = gMapObjects[gPlayerAvatar.mapObjectId].mapobj_unk_1E; + + for (i = 0; i < 18; i++) + { + if (gUnknown_0830FB58[i](r5)) + return i + 1; + } + } + return 0; +} + +u8 ForcedMovement_None(void) +{ + if (gPlayerAvatar.flags & PLAYER_AVATAR_FLAG_6) + { + struct MapObject *playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId]; + + playerMapObj->mapobj_bit_9 = 0; + playerMapObj->mapobj_bit_11 = 1; + FieldObjectSetDirection(playerMapObj, playerMapObj->mapobj_unk_18); + gPlayerAvatar.flags &= ~PLAYER_AVATAR_FLAG_6; + } + return 0; +} + +static u8 DoForcedMovement(u8 a, void (*b)(u8)) +{ + struct PlayerAvatar *playerAvatar = &gPlayerAvatar; + u8 r7 = CheckForPlayerAvatarCollision(a); + + playerAvatar->flags |= PLAYER_AVATAR_FLAG_6; + if (r7 != 0) + { + ForcedMovement_None(); + if (r7 <= 4) + { + return 0; + } + else + { + if (r7 == 6) + PlayerJumpLedge(a); + playerAvatar->flags |= PLAYER_AVATAR_FLAG_6; + playerAvatar->running2 = 2; + return 1; + } + } + else + { + playerAvatar->running2 = 2; + b(a); + return 1; + } +} + +static u8 DoForcedMovementInCurrentDirection(void (*a)(u8)) +{ + struct MapObject *playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId]; + + playerMapObj->mapobj_bit_10 = 1; + return DoForcedMovement(playerMapObj->placeholder18, a); +} + +u8 ForcedMovement_Slip(void) +{ + return DoForcedMovementInCurrentDirection(sub_80593C4); +} + +u8 sub_8058AAC(void) +{ + return DoForcedMovement(1, PlayerGoSpeed0); +} + +u8 sub_8058AC4(void) +{ + return DoForcedMovement(2, PlayerGoSpeed0); +} + +u8 sub_8058ADC(void) +{ + return DoForcedMovement(3, PlayerGoSpeed0); +} + +u8 sub_8058AF4(void) +{ + return DoForcedMovement(4, PlayerGoSpeed0); +} + +u8 sub_8058B0C(void) +{ + return DoForcedMovement(1, npc_use_some_d2s); +} + +u8 sub_8058B24(void) +{ + return DoForcedMovement(2, npc_use_some_d2s); +} + +u8 sub_8058B3C(void) +{ + return DoForcedMovement(3, npc_use_some_d2s); +} + +u8 sub_8058B54(void) +{ + return DoForcedMovement(4, npc_use_some_d2s); +} + +static u8 ForcedMovement_Slide(u8 a, void (*b)(u8)) +{ + struct MapObject *playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId]; + + playerMapObj->mapobj_bit_10 = 1; + playerMapObj->mapobj_bit_9 = 1; + return DoForcedMovement(a, b); +} + +u8 ForcedMovement_SlideSouth(void) +{ + return ForcedMovement_Slide(1, sub_80593C4); +} + +u8 ForcedMovement_SlideNorth(void) +{ + return ForcedMovement_Slide(2, sub_80593C4); +} + +u8 ForcedMovement_SlideWest(void) +{ + return ForcedMovement_Slide(3, sub_80593C4); +} + +u8 ForcedMovement_SlideEast(void) +{ + return ForcedMovement_Slide(4, sub_80593C4); +} + +u8 sub_8058C04(void) +{ + sub_8059F94(); + return 1; +} + +u8 sub_8058C10(void) +{ + sub_805A06C(); + return 1; +} + +u8 ForcedMovement_MuddySlope(void) +{ + struct MapObject *playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId]; + + if (playerMapObj->placeholder18 != 2 || sub_80E6034() <= 3) + { + sub_80E6010(0); + playerMapObj->mapobj_bit_9 = 1; + return DoForcedMovement(1, sub_80593C4); + } + else + { + return 0; + } +} + +static void MovePlayerNotOnBike(u8 a, u16 b) +{ + gUnknown_0830FBEC[CheckMovementInputNotOnBike(a)](a, b); +} + +static u8 CheckMovementInputNotOnBike(u8 a) +{ + if (a == 0) + { + gPlayerAvatar.running2 = 0; + return 0; + } + else if (a != player_get_direction_upper_nybble() && gPlayerAvatar.running2 != 2) + { + gPlayerAvatar.running2 = 1; + return 1; + } + else + { + gPlayerAvatar.running2 = 2; + return 2; + } +} + +void PlayerNotOnBikeNotMoving(u8 a, u16 b) +{ + PlayerFaceDirection(player_get_direction_lower_nybble()); +} + +void PlayerNotOnBikeTurningInPlace(u8 a, u16 b) +{ + PlayerTurnInPlace(a); +} + +void sub_8058D0C(u8 a, u16 b) +{ + u8 r1 = CheckForPlayerAvatarCollision(a); + + switch (r1) + { + case 6: + PlayerJumpLedge(a); + return; + default: + if (r1 > 8 || r1 < 5) + PlayerNotOnBikeCollide(a); + return; + case 0: + if (gPlayerAvatar.flags & PLAYER_AVATAR_FLAG_SURFING) + { + sub_80593C4(a); + return; + } + if (!(gPlayerAvatar.flags & PLAYER_AVATAR_FLAG_4) && (b & 2) && FlagGet(SYS_B_DASH) + && sub_80E5DEC(gMapObjects[gPlayerAvatar.mapObjectId].mapobj_unk_1E) == 0) + { + sub_805940C(a); + gPlayerAvatar.flags |= PLAYER_AVATAR_FLAG_DASH; + } + else + { + PlayerGoSpeed0(a); + } + } +} + +static u8 CheckForPlayerAvatarCollision(u8 a) +{ + s16 x, y; + struct MapObject *playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId]; + + x = playerMapObj->coords2.x; + y = playerMapObj->coords2.y; + MoveCoords(a, &x, &y); + return CheckForFieldObjectCollision(playerMapObj, x, y, a, MapGridGetMetatileBehaviorAt(x, y)); +} + +u8 CheckForFieldObjectCollision(struct MapObject *a, s16 b, s16 c, u8 d, u8 e) +{ + u8 sp0; + + sp0 = npc_block_way(a, b, c, d); + if (sp0 == 3 && sub_8058EF0(b, c, d)) + return 5; + if (ShouldJumpLedge(b, c, d)) + { + IncrementGameStat(0x2B); + return 6; + } + if (sp0 == 4 && sub_8058F6C(b, c, d)) + return 7; + + if (sp0 == 0) + { + if (CheckForRotatingGatePuzzleCollision(d, b, c)) + return 8; + check_acro_bike_metatile(b, c, e, &sp0); + } + return sp0; +} + +static u8 sub_8058EF0(s16 a, s16 b, u8 c) +{ + if ((gPlayerAvatar.flags & PLAYER_AVATAR_FLAG_SURFING) + && MapGridGetZCoordAt(a, b) == 3 + && GetFieldObjectIdByXYZ(a, b, 3) == 16) + { + sub_805A20C(c); + return 1; + } + else + { + return 0; + } +} + +static bool8 ShouldJumpLedge(s16 a, s16 b, u8 c) +{ + if (GetLedgeJumpDirection(a, b, c) != 0) + return 1; + else + return 0; +} + +static u8 sub_8058F6C(s16 a, s16 b, u8 c) +{ + if (FlagGet(SYS_USE_STRENGTH)) + { + u8 mapObjectId = GetFieldObjectIdByXY(a, b); + + if (mapObjectId != 16) + { + if (gMapObjects[mapObjectId].graphicsId == 0x57) + { + a = gMapObjects[mapObjectId].coords2.x; + b = gMapObjects[mapObjectId].coords2.y; + MoveCoords(c, &a, &b); + if (npc_block_way(&gMapObjects[mapObjectId], a, b, c) == 0 + && MetatileBehavior_IsNonAnimDoor(MapGridGetMetatileBehaviorAt(a, b)) == 0) + { + StartStrengthAnim(mapObjectId, c); + return 1; + } + } + } + } + return 0; +} + +static void check_acro_bike_metatile(int unused1, int unused2, u8 c, u8 *d) +{ + u8 i; + + for (i = 0; i < 5; i++) + { + if (gUnknown_0830FBF8[i](c)) + { + *d = gUnknown_0830FC0C[i]; + return; + } + } +} + +void SetPlayerAvatarTransitionFlags(u16 a) +{ + gPlayerAvatar.bike |= a; + DoPlayerAvatarTransition(); +} + +static void DoPlayerAvatarTransition(void) +{ + u8 i; + u32 flags = gPlayerAvatar.bike; + + if (flags != 0) + { + for (i = 0; i < 8; i++, flags >>= 1) + { +#ifdef NONMATCHING + if (flags & 1) + { + gUnknown_0830FC14[i](&gMapObjects[gPlayerAvatar.mapObjectId]); + } +#else + if (flags & 1) + { + register void (**funcs)(struct MapObject *) asm("r0") = gUnknown_0830FC14; + funcs[i](&gMapObjects[gPlayerAvatar.mapObjectId]); + } +#endif + } + gPlayerAvatar.bike = 0; + } +} + +void nullsub_49(struct MapObject *a) +{ +} + +void PlayerAvatarTransition_Normal(struct MapObject *a) +{ + sub_805B980(a, GetPlayerAvatarGraphicsIdByStateId(0)); + FieldObjectTurn(a, a->placeholder18); + SetPlayerAvatarStateMask(1); +} + +void PlayerAvatarTransition_MachBike(struct MapObject *a) +{ + sub_805B980(a, GetPlayerAvatarGraphicsIdByStateId(1)); + FieldObjectTurn(a, a->placeholder18); + SetPlayerAvatarStateMask(2); + sub_80E5FCC(0, 0); +} + +void PlayerAvatarTransition_AcroBike(struct MapObject *a) +{ + sub_805B980(a, GetPlayerAvatarGraphicsIdByStateId(2)); + FieldObjectTurn(a, a->placeholder18); + SetPlayerAvatarStateMask(4); + sub_80E5FCC(0, 0); + sub_80E6084(); +} + +void PlayerAvatarTransition_Surfing(struct MapObject *a) +{ + u8 unk; + + sub_805B980(a, GetPlayerAvatarGraphicsIdByStateId(3)); + FieldObjectTurn(a, a->placeholder18); + SetPlayerAvatarStateMask(8); + gUnknown_0202FF84.x = a->coords2.x; + gUnknown_0202FF84.y = a->coords2.y; + gUnknown_0202FF84.unk8 = gPlayerAvatar.mapObjectId; + unk = FieldEffectStart(8); + a->mapobj_unk_1A = unk; + sub_8127ED0(unk, 1); +} + +void PlayerAvatarTransition_Underwater(struct MapObject *a) +{ + sub_805B980(a, GetPlayerAvatarGraphicsIdByStateId(4)); + FieldObjectTurn(a, a->placeholder18); + SetPlayerAvatarStateMask(16); + a->mapobj_unk_1A = sub_8128124(a->spriteId); +} + +void sub_80591F4(struct MapObject *a) +{ + gPlayerAvatar.flags |= PLAYER_AVATAR_FLAG_5; +} + +void sub_8059204(void) +{ + gPlayerAvatar.running1 = 0; + if (PlayerIsAnimActive()) + { + if (!PlayerCheckIfAnimFinishedOrInactive()) + { + if (!player_is_anim_in_certain_ranges()) + gPlayerAvatar.running1 = 1; + } + else + { + if (!sub_80592A4()) + gPlayerAvatar.running1 = 2; + } + } +} + +static bool8 player_is_anim_in_certain_ranges(void) +{ + u8 unk = gMapObjects[gPlayerAvatar.mapObjectId].mapobj_unk_1C; + + if (unk < 4 + || (unk >= 16 && unk < 0x15) + || (unk >= 25 && unk < 41) + || (unk >= 98 && unk < 110) + || (unk >= 122 && unk < 126)) + return TRUE; + else + return FALSE; +} + +static bool8 sub_80592A4(void) +{ + if (player_is_anim_in_certain_ranges() && gPlayerAvatar.running2 != 1) + return TRUE; + else + return FALSE; +} + +static bool8 PlayerIsAnimActive(void) +{ + return FieldObjectIsSpecialAnimOrDirectionSequenceAnimActive(&gMapObjects[gPlayerAvatar.mapObjectId]); +} + +static bool8 PlayerCheckIfAnimFinishedOrInactive(void) +{ + return FieldObjectCheckIfSpecialAnimFinishedOrInactive(&gMapObjects[gPlayerAvatar.mapObjectId]); +} + +static void player_set_x22(u8 a) +{ + gMapObjects[gPlayerAvatar.mapObjectId].mapobj_unk_22 = a; +} + +u8 player_get_x22(void) +{ + return gMapObjects[gPlayerAvatar.mapObjectId].mapobj_unk_22; +} + +static void sub_8059348(u8 a) +{ + FieldObjectForceSetSpecialAnim(&gMapObjects[gPlayerAvatar.mapObjectId], a); +} + +void player_npc_set_state_and_x22_etc(u8 a, u8 b) +{ + if (!PlayerIsAnimActive()) + { + player_set_x22(b); + FieldObjectSetSpecialAnim(&gMapObjects[gPlayerAvatar.mapObjectId], a); + } +} + +void PlayerGoSpeed0(u8 a) +{ + player_npc_set_state_and_x22_etc(GetGoSpeed0AnimId(a), 2); +} + +void sub_80593C4(u8 a) +{ + player_npc_set_state_and_x22_etc(sub_8060744(a), 2); +} + +void npc_use_some_d2s(u8 a) +{ + player_npc_set_state_and_x22_etc(d2s_08064034(a), 2); +} + +void sub_80593F4(u8 a) +{ + player_npc_set_state_and_x22_etc(sub_806079C(a), 2); +} + +void sub_805940C(u8 a) +{ + player_npc_set_state_and_x22_etc(sub_80607F4(a), 2); +} + +void PlayerOnBikeCollide(u8 a) +{ + PlayCollisionSoundIfNotFacingWarp(a); + player_npc_set_state_and_x22_etc(GetStepInPlaceDelay16AnimId(a), 2); +} + +static void PlayerNotOnBikeCollide(u8 a) +{ + PlayCollisionSoundIfNotFacingWarp(a); + player_npc_set_state_and_x22_etc(GetStepInPlaceDelay32AnimId(a), 2); +} + +void PlayerFaceDirection(u8 a) +{ + player_npc_set_state_and_x22_etc(GetFaceDirectionAnimId(a), 1); +} + +void PlayerTurnInPlace(u8 a) +{ + player_npc_set_state_and_x22_etc(GetStepInPlaceDelay8AnimId(a), 1); +} + +void PlayerJumpLedge(u8 a) +{ + PlaySE(SE_DANSA); + player_npc_set_state_and_x22_etc(GetJumpLedgeAnimId(a), 8); +} + +void sub_80594C0(void) +{ + if (gPlayerAvatar.running1 == 2 || gPlayerAvatar.running1 == 0) + { + if (player_should_look_direction_be_enforced_upon_movement()) + sub_8059348(GetFaceDirectionAnimId(gMapObjects[gPlayerAvatar.mapObjectId].mapobj_unk_18)); + } +} + +void sub_8059504(u8 a) +{ + player_npc_set_state_and_x22_etc(sub_80609D8(a), 1); +} + +void sub_805951C(u8 a) +{ + player_npc_set_state_and_x22_etc(sub_8060A04(a), 1); +} + +void sub_8059534(u8 a) +{ + player_npc_set_state_and_x22_etc(sub_8060A30(a), 1); +} + +void sub_805954C(u8 a) +{ + PlaySE(SE_JITE_PYOKO); + player_npc_set_state_and_x22_etc(sub_8060A5C(a), 1); +} + +void sub_8059570(u8 a) +{ + PlaySE(SE_JITE_PYOKO); + player_npc_set_state_and_x22_etc(sub_8060A88(a), 2); +} + +void sub_8059594(u8 a) +{ + PlaySE(SE_JITE_PYOKO); + player_npc_set_state_and_x22_etc(sub_8060AB4(a), 8); +} + +void sub_80595B8(u8 a) +{ + PlaySE(SE_JITE_PYOKO); + player_npc_set_state_and_x22_etc(sub_8060878(a), 1); +} + +void sub_80595DC(u8 a) +{ + PlaySE(SE_WALL_HIT); + player_npc_set_state_and_x22_etc(sub_8060AE0(a), 2); +} + +void sub_8059600(u8 a) +{ + player_npc_set_state_and_x22_etc(sub_8060B0C(a), 2); +} + +void sub_8059618(u8 a) +{ + player_npc_set_state_and_x22_etc(sub_8060B38(a), 2); +} + +void sub_8059630(u8 a) +{ + player_npc_set_state_and_x22_etc(sub_8060B64(a), 2); +} + +static void PlayCollisionSoundIfNotFacingWarp(u8 a) +{ + s16 x, y; + u8 unk = gMapObjects[gPlayerAvatar.mapObjectId].mapobj_unk_1E; + + if (!gUnknown_0830FC34[a - 1](unk)) + { + if (a == 2) + { + PlayerGetDestCoords(&x, &y); + MoveCoords(2, &x, &y); + if (MetatileBehavior_IsWarpDoor(MapGridGetMetatileBehaviorAt(x, y))) + return; + } + PlaySE(SE_WALL_HIT); + } +} + +void GetXYCoordsOneStepInFrontOfPlayer(s16 *x, s16 *y) +{ + *x = gMapObjects[gPlayerAvatar.mapObjectId].coords2.x; + *y = gMapObjects[gPlayerAvatar.mapObjectId].coords2.y; + MoveCoords(player_get_direction_lower_nybble(), x, y); +} + +void PlayerGetDestCoords(s16 *x, s16 *y) +{ + *x = gMapObjects[gPlayerAvatar.mapObjectId].coords2.x; + *y = gMapObjects[gPlayerAvatar.mapObjectId].coords2.y; +} + +u8 player_get_direction_lower_nybble(void) +{ + return gMapObjects[gPlayerAvatar.mapObjectId].mapobj_unk_18; +} + +u8 player_get_direction_upper_nybble(void) +{ + return gMapObjects[gPlayerAvatar.mapObjectId].placeholder18; +} + +u8 PlayerGetZCoord(void) +{ + return gMapObjects[gPlayerAvatar.mapObjectId].elevation; +} + +void unref_sub_8059790(s16 a, s16 b) +{ + sub_805C058(&gMapObjects[gPlayerAvatar.mapObjectId], a, b); +} + +u8 TestPlayerAvatarFlags(u8 a) +{ + return gPlayerAvatar.flags & a; +} + +u8 sub_80597D0(void) +{ + return gPlayerAvatar.flags; +} + +u8 GetPlayerAvatarObjectId(void) +{ + return gPlayerAvatar.spriteId; +} + +void sub_80597E8(void) +{ + ForcedMovement_None(); +} + +void sub_80597F4(void) +{ + struct MapObject *playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId]; + + npc_clear_strange_bits(playerMapObj); + FieldObjectSetDirection(playerMapObj, playerMapObj->mapobj_unk_18); + if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_MACH_BIKE | PLAYER_AVATAR_FLAG_ACRO_BIKE)) + { + sub_80E6084(); + sub_80E6010(0); + } +} + +u8 sub_805983C(u8 a, u8 b) +{ + return gUnknown_0830FC44[a][b]; +} + +static u8 GetPlayerAvatarGraphicsIdByStateIdAndGender(u8 a, u8 b) +{ + return gUnknown_0830FC54[a][b]; +} + +u8 GetPlayerAvatarGraphicsIdByStateId(u8 a) +{ + return GetPlayerAvatarGraphicsIdByStateIdAndGender(a, gPlayerAvatar.gender); +} + +u8 unref_sub_8059888(u8 a) +{ + switch (a) + { + case 0x69: + case 0x6A: + case 0x6B: + case 0x6C: + case 0x6D: + case 0x70: + case 0x8A: + case 0xC0: + return FEMALE; + default: + return MALE; + } +} + +u8 GetPlayerAvatarGenderByGraphicsId(u8 a) +{ + switch (a) + { + case 0x59: + case 0x5A: + case 0x5B: + case 0x5C: + case 0x5D: + case 0x70: + case 0x8A: + case 0xC0: + return FEMALE; + default: + return MALE; + } +} + +bool8 PartyHasMonWithSurf(void) +{ + u8 i; + + if (!TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_SURFING)) + { + for (i = 0; i < 6; i++) + { + if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES) == 0) + break; + if (pokemon_has_move(&gPlayerParty[i], 0x39)) + return TRUE; + } + } + return FALSE; +} + +bool8 IsPlayerSurfingNorth(void) +{ + if (player_get_direction_upper_nybble() == 2 && TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_SURFING)) + return TRUE; + else + return FALSE; +} + +bool8 IsPlayerFacingSurfableFishableWater(void) +{ + struct MapObject *playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId]; + s16 x = playerMapObj->coords2.x; + s16 y = playerMapObj->coords2.y; + + MoveCoords(playerMapObj->mapobj_unk_18, &x, &y); + if (npc_block_way(playerMapObj, x, y, playerMapObj->mapobj_unk_18) == 3 && PlayerGetZCoord() == 3 + && MetatileBehavior_IsSurfableFishableWater(MapGridGetMetatileBehaviorAt(x, y))) + return TRUE; + else + return FALSE; +} + +void ClearPlayerAvatarInfo(void) +{ + //TODO: 0x24 should be the size of gPlayerAvatar + memset(&gPlayerAvatar, 0, 0x24); +} + +void SetPlayerAvatarStateMask(u8 a) +{ + gPlayerAvatar.flags &= 0xE0; + gPlayerAvatar.flags |= a; +} + +static u8 GetPlayerAvatarStateTransitionByGraphicsId(u8 a, u8 gender) +{ + u8 i; + + for (i = 0; i < 5; i++) + { + if (gUnknown_0830FC64[gender][i][0] == a) + return gUnknown_0830FC64[gender][i][1]; + } + return 1; +} + +u8 GetPlayerAvatarGraphicsIdByCurrentState(void) +{ + u8 i; + u8 r5 = gPlayerAvatar.flags; + + for (i = 0; i < 5; i++) + { + if (gUnknown_0830FC64[gPlayerAvatar.gender][i][1] & r5) + return gUnknown_0830FC64[gPlayerAvatar.gender][i][0]; + } + return 0; +} + +void SetPlayerAvatarExtraStateTransition(u8 a, u8 b) +{ + u8 unk = GetPlayerAvatarStateTransitionByGraphicsId(a, gPlayerAvatar.gender); + + gPlayerAvatar.bike |= unk | b; + DoPlayerAvatarTransition(); +} + +void InitPlayerAvatar(s16 a, s16 b, u8 c, u8 d) +{ + struct UnknownStruct_FPA s; + u8 mapObjectId; + struct MapObject *mapObject; + + s.unk0 = 0xFF; + s.unk1 = GetPlayerAvatarGraphicsIdByStateIdAndGender(0, d); + s.unk4 = a - 7; + s.unk6 = b - 7; + s.unk8 = 0; + s.unk9 = 11; + s.unkA_0 = 0; + s.unkA_4 = 0; + s.unkC = 0; + s.unkE = 0; + s.unk10 = 0; + s.unk14 = 0; + mapObjectId = SpawnSpecialFieldObject(&s); + mapObject = &gMapObjects[mapObjectId]; + mapObject->mapobj_bit_16 = 1; + mapObject->mapobj_unk_1B = sub_8126B54(); + FieldObjectTurn(mapObject, c); + ClearPlayerAvatarInfo(); + gPlayerAvatar.running2 = 0; + gPlayerAvatar.running1 = 0; + gPlayerAvatar.mapObjectId = mapObjectId; + gPlayerAvatar.spriteId = mapObject->spriteId; + gPlayerAvatar.gender = d; + SetPlayerAvatarStateMask(0x21); +} + +void sub_8059B88(u8 a) +{ + gMapObjects[gPlayerAvatar.mapObjectId].mapobj_bit_13 = a; + if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_SURFING)) + gSprites[gMapObjects[gPlayerAvatar.mapObjectId].mapobj_unk_1A].invisible = a; +} + +void sub_8059BF4(void) +{ + sub_805B980(&gMapObjects[gPlayerAvatar.mapObjectId], GetPlayerAvatarGraphicsIdByStateId(5)); + StartSpriteAnim(&gSprites[gPlayerAvatar.spriteId], 0); +} + +void sub_8059C3C(u8 a) +{ + sub_805B980(&gMapObjects[gPlayerAvatar.mapObjectId], GetPlayerAvatarGraphicsIdByStateId(6)); + StartSpriteAnim(&gSprites[gPlayerAvatar.spriteId], sub_805FDE8(a)); +} + +void sub_8059C94(u8 a) +{ + sub_805B980(&gMapObjects[gPlayerAvatar.mapObjectId], GetPlayerAvatarGraphicsIdByStateId(2)); + StartSpriteAnim(&gSprites[gPlayerAvatar.spriteId], sub_805FD98(a)); + SeekSpriteAnim(&gSprites[gPlayerAvatar.spriteId], 1); +} + +void sub_8059D08(u8 a) +{ + sub_805B980(&gMapObjects[gPlayerAvatar.mapObjectId], GetPlayerAvatarGraphicsIdByStateId(7)); + StartSpriteAnim(&gSprites[gPlayerAvatar.spriteId], FieldObjectDirectionToImageAnimId(a)); +} + +static void sub_8059D60(struct MapObject *a) +{ + s16 x; + s16 y; + u8 r6; + u8 r8 = a->mapobj_unk_1E; + + for (x = 0, r6 = 1; x < 4; x++, r6++) + { + if (gUnknown_0830FC78[x](r8) && r6 == a->placeholder18) + { + x = a->coords2.x; + y = a->coords2.y; + MoveCoords(r6, &x, &y); + sub_8126BC4(a->mapobj_unk_1B, r6, x, y); + return; + } + } + objid_set_invisible(a->mapobj_unk_1B); +} + +/* Strength */ + +static void sub_8059E2C(u8 taskId); + +static void StartStrengthAnim(u8 a, u8 b) +{ + u8 taskId = CreateTask(sub_8059E2C, 0xFF); + + gTasks[taskId].data[1] = a; + gTasks[taskId].data[2] = b; + sub_8059E2C(taskId); +} + +static void sub_8059E2C(u8 taskId) +{ + while (gUnknown_0830FC88[gTasks[taskId].data[0]](&gTasks[taskId], + &gMapObjects[gPlayerAvatar.mapObjectId], + &gMapObjects[gTasks[taskId].data[1]])) + ; +} + +u8 sub_8059E84(struct Task *task, struct MapObject *b, struct MapObject *c) +{ + ScriptContext2_Enable(); + gPlayerAvatar.unk6 = 1; + task->data[0]++; + return 0; +} + +u8 sub_8059EA4(struct Task *task, struct MapObject *b, struct MapObject *c) +{ + if (!FieldObjectIsSpecialAnimOrDirectionSequenceAnimActive(b) + && !FieldObjectIsSpecialAnimOrDirectionSequenceAnimActive(c)) + { + FieldObjectClearAnimIfSpecialAnimFinished(b); + FieldObjectClearAnimIfSpecialAnimFinished(c); + FieldObjectSetSpecialAnim(b, GetStepInPlaceDelay16AnimId(task->data[2])); + FieldObjectSetSpecialAnim(c, GetSimpleGoAnimId(task->data[2])); + gUnknown_0202FF84.x = c->coords2.x; + gUnknown_0202FF84.y = c->coords2.y; + gUnknown_0202FF84.unk8 = c->elevation; + gUnknown_0202FF84.unkC = gSprites[c->spriteId].oam.priority; + FieldEffectStart(10); + PlaySE(SE_W070); + task->data[0]++; + } + return 0; +} + +u8 sub_8059F40(struct Task *task, struct MapObject *b, struct MapObject *c) +{ + if (FieldObjectCheckIfSpecialAnimFinishedOrInactive(b) + && FieldObjectCheckIfSpecialAnimFinishedOrInactive(c)) + { + FieldObjectClearAnimIfSpecialAnimFinished(b); + FieldObjectClearAnimIfSpecialAnimFinished(c); + gPlayerAvatar.unk6 = 0; + ScriptContext2_Disable(); + DestroyTask(FindTaskIdByFunc(sub_8059E2C)); + } + return 0; +} + +/* Some field effect */ + +static void sub_8059FB4(u8 taskId); + +static void sub_8059F94(void) +{ + u8 taskId = CreateTask(sub_8059FB4, 0xFF); + + sub_8059FB4(taskId); +} + +static void sub_8059FB4(u8 taskId) +{ + while (gUnknown_0830FC94[gTasks[taskId].data[0]](&gTasks[taskId], &gMapObjects[gPlayerAvatar.mapObjectId])) + ; +} + +u8 sub_805A000(struct Task *task, struct MapObject *mapObject) +{ + gPlayerAvatar.unk6 = 1; + if (FieldObjectClearAnimIfSpecialAnimFinished(mapObject)) + { + PlaySE(SE_DANSA); + FieldObjectSetSpecialAnim(mapObject, sub_806084C(mapObject->mapobj_unk_18)); + task->data[1]++; + if (task->data[1] > 1) + { + gPlayerAvatar.unk6 = 0; + gPlayerAvatar.bike |= 0x20; + DestroyTask(FindTaskIdByFunc(sub_8059FB4)); + } + } + return 0; +} + +/* Some field effect */ + +static void sub_805A08C(u8 taskId); + +static void sub_805A06C(void) +{ + u8 taskId = CreateTask(sub_805A08C, 0xFF); + + sub_805A08C(taskId); +} + +static void sub_805A08C(u8 taskId) +{ + while (gUnknown_0830FC98[gTasks[taskId].data[0]](&gTasks[taskId], &gMapObjects[gPlayerAvatar.mapObjectId])) + ; +} + +u8 sub_805A0D8(struct Task *task, struct MapObject *mapObject) +{ + task->data[0]++; + task->data[1] = mapObject->placeholder18; + gPlayerAvatar.unk6 = 1; + ScriptContext2_Enable(); + PlaySE(SE_TK_WARPIN); + return 1; +} + +u8 sub_805A100(struct Task *task, struct MapObject *mapObject) +{ + u8 directions[4]; + + memcpy(directions, gUnknown_0830FCA8, sizeof(directions)); + if (FieldObjectClearAnimIfSpecialAnimFinished(mapObject)) + { + u8 direction; + + FieldObjectSetSpecialAnim(mapObject, GetFaceDirectionAnimId(direction = directions[mapObject->placeholder18 - 1])); + if (direction == (u8)task->data[1]) + task->data[2]++; + task->data[0]++; + if (task->data[2] > 3 && direction == GetOppositeDirection(task->data[1])) + task->data[0]++; + } + return 0; +} + +u8 sub_805A178(struct Task *task, struct MapObject *mapObject) +{ + u8 arr[5]; + + memcpy(arr, gUnknown_0830FCAC, sizeof(arr)); + if (FieldObjectClearAnimIfSpecialAnimFinished(mapObject)) + { + FieldObjectSetSpecialAnim(mapObject, arr[task->data[2]]); + task->data[0] = 1; + } + return 0; +} + +u8 sub_805A1B8(struct Task *task, struct MapObject *mapObject) +{ + if (FieldObjectClearAnimIfSpecialAnimFinished(mapObject)) + { + FieldObjectSetSpecialAnim(mapObject, GetSimpleGoAnimId(GetOppositeDirection(task->data[1]))); + ScriptContext2_Disable(); + gPlayerAvatar.unk6 = 0; + DestroyTask(FindTaskIdByFunc(sub_805A08C)); + } + return 0; +} + +/* Some Field effect */ + +static void taskFF_0805D1D4(u8 taskId); +static void sub_805A2D0(u8 taskId); + +void sub_805A20C(u8 a) +{ + u8 taskId; + + ScriptContext2_Enable(); + sav1_reset_battle_music_maybe(); + sub_8053F84(); + gPlayerAvatar.flags &= ~PLAYER_AVATAR_FLAG_SURFING; + gPlayerAvatar.flags |= PLAYER_AVATAR_FLAG_ON_FOOT; + gPlayerAvatar.unk6 = 1; + taskId = CreateTask(taskFF_0805D1D4, 0xFF); + gTasks[taskId].data[0] = a; + taskFF_0805D1D4(taskId); +} + +static void taskFF_0805D1D4(u8 taskId) +{ + struct MapObject *playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId]; + + if (FieldObjectIsSpecialAnimOrDirectionSequenceAnimActive(playerMapObj)) + { + if (!FieldObjectClearAnimIfSpecialAnimFinished(playerMapObj)) + return; + } + sub_8127ED0(playerMapObj->mapobj_unk_1A, 2); + FieldObjectSetSpecialAnim(playerMapObj, sub_80608D0(gTasks[taskId].data[0])); + gTasks[taskId].func = sub_805A2D0; +} + +static void sub_805A2D0(u8 taskId) +{ + struct MapObject *playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId]; + + if (FieldObjectClearAnimIfSpecialAnimFinished(playerMapObj)) + { + sub_805B980(playerMapObj, GetPlayerAvatarGraphicsIdByStateId(0)); + FieldObjectSetSpecialAnim(playerMapObj, GetFaceDirectionAnimId(playerMapObj->mapobj_unk_18)); + gPlayerAvatar.unk6 = 0; + ScriptContext2_Disable(); + DestroySprite(&gSprites[playerMapObj->mapobj_unk_1A]); + DestroyTask(taskId); + } +} + +/* Fishing */ + +static void Task_Fishing(u8 taskId); +static void sub_805A954(void); + +void StartFishing(u8 a) +{ + u8 taskId = CreateTask(Task_Fishing, 0xFF); + + gTasks[taskId].data[15] = a; + Task_Fishing(taskId); +} + +static void Task_Fishing(u8 taskId) +{ + while (gUnknown_0830FCB4[gTasks[taskId].data[0]](&gTasks[taskId])) + ; +} + +u8 Fishing1(struct Task *task) +{ + ScriptContext2_Enable(); + gPlayerAvatar.unk6 = 1; + task->data[0]++; + return 0; +} + +u8 Fishing2(struct Task *task) +{ + s16 arr1[3]; + s16 arr2[3]; + struct MapObject *playerMapObj; + + memcpy(arr1, gUnknown_0830FCF4, sizeof(arr1)); + memcpy(arr2, gUnknown_0830FCFA, sizeof(arr2)); + task->data[12] = 0; + task->data[13] = arr1[task->data[15]] + (Random() % arr2[task->data[15]]); + task->data[14] = gMapObjects[gPlayerAvatar.mapObjectId].graphicsId; + playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId]; + FieldObjectClearAnimIfSpecialAnimActive(playerMapObj); + playerMapObj->mapobj_bit_11 = 1; + sub_8059C3C(playerMapObj->mapobj_unk_18); + task->data[0]++; + return 0; +} + +u8 Fishing3(struct Task *task) +{ + sub_805A954(); + task->data[1]++; + if (task->data[1] > 0x3B) + task->data[0]++; + return 0; +} + +u8 Fishing4(struct Task *task) +{ + u32 randVal; + + MenuDisplayMessageBox(); + task->data[0]++; + task->data[1] = 0; + task->data[2] = 0; + randVal = Random(); + randVal %= 10; + task->data[3] = randVal + 1; + if (task->data[12] == 0) + task->data[3] = randVal + 4; + if (task->data[3] > 9) + task->data[3] = 10; + return 1; +} + +u8 Fishing5(struct Task *task) +{ + u8 dot[2]; + + memcpy(dot, gUnknown_0830FD00, sizeof(dot)); + sub_805A954(); + task->data[1]++; + if (gMain.newKeys & A_BUTTON) + { + task->data[0] = 11; + if (task->data[12] != 0) + task->data[0] = 12; + return 1; + } + else + { + if (task->data[1] > 0x13) + { + task->data[1] = 0; + if (task->data[2] >= task->data[3]) + { + task->data[0]++; + if (task->data[12] != 0) + task->data[0]++; + task->data[12]++; + } + else + { + MenuPrint(dot, task->data[2] + 4, 15); + task->data[2]++; + } + } + return 0; + } +} + +u8 Fishing6(struct Task *task) +{ + sub_805A954(); + task->data[0]++; + if (!GetFishingWildMonListHeader() || (Random() & 1)) + task->data[0] = 11; + else + StartSpriteAnim(&gSprites[gPlayerAvatar.spriteId], sub_805FE08(player_get_direction_lower_nybble())); + return 1; +} + +u8 Fishing7(struct Task *task) +{ + sub_805A954(); + MenuPrint(gOtherText_OhABite, 4, 17); + task->data[0]++; + task->data[1] = 0; + return 0; +} + +u8 Fishing8(struct Task *task) +{ + s16 arr[3]; + + memcpy(arr, gUnknown_0830FD02, sizeof(arr)); + sub_805A954(); + task->data[1]++; + if (task->data[1] >= arr[task->data[15]]) + task->data[0] = 12; + else if (gMain.newKeys & A_BUTTON) + task->data[0]++; + return 0; +} + +u8 Fishing9(struct Task *task) +{ + s16 arr[3][2]; + + memcpy(arr, gUnknown_0830FD08, sizeof(arr)); + sub_805A954(); + task->data[0]++; + if (task->data[12] < task->data[13]) + { + task->data[0] = 3; + } + else if (task->data[12] < 2) + { + s16 randVal = Random() % 100; + + if (arr[task->data[15]][task->data[12]] > randVal) + task->data[0] = 3; + } + return 0; +} + +u8 Fishing10(struct Task *task) +{ + sub_805A954(); + sub_8072044(gOtherText_PokeOnHook); + MenuDisplayMessageBox(); + task->data[0]++; + task->data[1] = 0; + return 0; +} + +u8 Fishing11(struct Task *task) +{ + if (task->data[1] == 0) + { + sub_805A954(); + if (task->data[1] == 0) + { + if (MenuUpdateWindowText()) + { + struct MapObject *playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId]; + + sub_805B980(playerMapObj, task->data[14]); + FieldObjectTurn(playerMapObj, playerMapObj->placeholder18); + if (gPlayerAvatar.flags & PLAYER_AVATAR_FLAG_SURFING) + sub_8127F28(gMapObjects[gPlayerAvatar.mapObjectId].mapobj_unk_1A, 0, 0); + gSprites[gPlayerAvatar.spriteId].pos2.x = 0; + gSprites[gPlayerAvatar.spriteId].pos2.y = 0; + MenuZeroFillScreen(); + task->data[1]++; + return 0; + } + else + { + if (task->data[1] == 0) + return 0; + } + } + } + gPlayerAvatar.unk6 = 0; + ScriptContext2_Disable(); + FishingWildEncounter(task->data[15]); + sub_80BE97C(1); + DestroyTask(FindTaskIdByFunc(Task_Fishing)); + return 0; +} + +u8 Fishing12(struct Task *task) +{ + sub_805A954(); + StartSpriteAnim(&gSprites[gPlayerAvatar.spriteId], sub_805FDF8(player_get_direction_lower_nybble())); + sub_8072044(gOtherText_NotEvenANibble); + task->data[0] = 13; + return 1; +} + +u8 Fishing13(struct Task *task) +{ + sub_805A954(); + StartSpriteAnim(&gSprites[gPlayerAvatar.spriteId], sub_805FDF8(player_get_direction_lower_nybble())); + sub_8072044(gOtherText_ItGotAway); + task->data[0]++; + return 1; +} + +u8 Fishing14(struct Task *task) +{ + sub_805A954(); + MenuDisplayMessageBox(); + task->data[0]++; + return 0; +} + +u8 Fishing15(struct Task *task) +{ + sub_805A954(); + if (gSprites[gPlayerAvatar.spriteId].animEnded) + { + struct MapObject *playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId]; + + sub_805B980(playerMapObj, task->data[14]); + FieldObjectTurn(playerMapObj, playerMapObj->placeholder18); + if (gPlayerAvatar.flags & PLAYER_AVATAR_FLAG_SURFING) + sub_8127F28(gMapObjects[gPlayerAvatar.mapObjectId].mapobj_unk_1A, 0, 0); + gSprites[gPlayerAvatar.spriteId].pos2.x = 0; + gSprites[gPlayerAvatar.spriteId].pos2.y = 0; + task->data[0]++; + } + return 0; +} + +u8 Fishing16(struct Task *task) +{ + if (MenuUpdateWindowText()) + { + gPlayerAvatar.unk6 = 0; + ScriptContext2_Disable(); + UnfreezeMapObjects(); + MenuZeroFillScreen(); + sub_80BE97C(0); + DestroyTask(FindTaskIdByFunc(Task_Fishing)); + } + return 0; +} + +static void sub_805A954(void) +{ + struct Sprite *playerSprite = &gSprites[gPlayerAvatar.spriteId]; + u8 animCmdIndex; + u8 animType; + + AnimateSprite(playerSprite); + playerSprite->pos2.x = 0; + playerSprite->pos2.y = 0; + animCmdIndex = playerSprite->animCmdIndex; + if (playerSprite->anims[playerSprite->animNum][animCmdIndex].type == -1) + { + animCmdIndex--; + } + else + { + playerSprite->animDelayCounter++; + if (playerSprite->anims[playerSprite->animNum][animCmdIndex].type == -1) + animCmdIndex--; + } + animType = playerSprite->anims[playerSprite->animNum][animCmdIndex].type; + if (animType == 1 || animType == 2 || animType == 3) + { + playerSprite->pos2.x = 8; + if (player_get_direction_lower_nybble() == 3) + playerSprite->pos2.x = -8; + } + if (animType == 5) + playerSprite->pos2.y = -8; + if (animType == 10 || animType == 11) + playerSprite->pos2.y = 8; + if (gPlayerAvatar.flags & PLAYER_AVATAR_FLAG_SURFING) + sub_8127F28(gMapObjects[gPlayerAvatar.mapObjectId].mapobj_unk_1A, 1, playerSprite->pos2.y); +} diff --git a/src/field_poison.c b/src/field_poison.c index a51fe5546..9b21ac5f3 100644 --- a/src/field_poison.c +++ b/src/field_poison.c @@ -1,14 +1,11 @@ #include "global.h" +#include "asm.h" #include "field_message_box.h" #include "pokemon.h" #include "script.h" #include "string_util.h" #include "task.h" -extern void AdjustFriendship(struct Pokemon *, u8); -extern u8 pokemon_ailments_get_primary(u32); -extern void DoFieldPoisonEffect(void); - extern struct Pokemon gPlayerParty[6]; extern u16 gScriptResult; extern u8 fieldPoisonText_PokemonFainted[]; @@ -103,7 +100,7 @@ void Task_WhiteOut(u8 taskId) } } -void DoWhiteOut(void) +void ExecuteWhiteOut(void) { CreateTask(Task_WhiteOut, 0x50); ScriptContext1_Stop(); diff --git a/src/fieldmap.c b/src/fieldmap.c new file mode 100644 index 000000000..4dcfbe30b --- /dev/null +++ b/src/fieldmap.c @@ -0,0 +1,809 @@ +#include "global.h" +#include "palette.h" + +struct BackupMapData +{ + s32 width; + s32 height; + u16 *map; +}; + +extern struct MapHeader * const get_mapheader_by_bank_and_number(u8, u8); +extern void mapheader_run_script_with_tag_x1(void); +extern void sub_80BB970(struct MapEvents *); +extern void sub_80BBCCC(); +extern void sub_8056670(); +extern void UpdateTVScreensOnMap(); +extern void sub_80538F0(u8 mapGroup, u8 mapNum); + +struct Camera { + bool8 field_0:1; + s32 x; + s32 y; +}; + +struct ConnectionFlags { + u8 south:1; + u8 north:1; + u8 west:1; + u8 east:1; +}; + +struct Coords32 { + s32 x; + s32 y; +}; + +extern const struct Coords32 gUnknown_0821664C[]; +extern struct BackupMapData gUnknown_03004870; + +EWRAM_DATA static u16 gUnknown_02029828[0x2800] = {0}; +EWRAM_DATA struct MapHeader gMapHeader = {0}; +EWRAM_DATA struct Camera gUnknown_0202E844 = {0}; +EWRAM_DATA static struct ConnectionFlags gUnknown_0202E850 = {0}; + +static const struct ConnectionFlags sDummyConnectionFlags = {0}; + +void mapheader_copy_mapdata_with_padding(struct MapHeader *mapHeader); +void sub_80560AC(struct MapHeader *); +void map_copy_with_padding(u16 *map, u16 width, u16 height); +void fillSouthConnection(struct MapHeader *, struct MapHeader *, s32); +void fillNorthConnection(struct MapHeader *, struct MapHeader *, s32); +void fillWestConnection(struct MapHeader *, struct MapHeader *, s32); +void fillEastConnection(struct MapHeader *, struct MapHeader *, s32); +u32 GetBehaviorByMetatileId(u16 metatile); +struct MapConnection *sub_8056A64(u8 direction, int x, int y); +bool8 sub_8056ABC(u8 direction, int x, int y, struct MapConnection *connection); +bool8 sub_8056B20(int x, int src_width, int dest_width, int offset); + +struct MapHeader *mapconnection_get_mapheader(struct MapConnection *connection) { + return get_mapheader_by_bank_and_number(connection->mapGroup, connection->mapNum); +} + +void not_trainer_hill_battle_pyramid(void) { + mapheader_copy_mapdata_with_padding(&gMapHeader); + sub_80BB970(gMapHeader.events); + mapheader_run_script_with_tag_x1(); +} + +void sub_8055FC0(void) { + mapheader_copy_mapdata_with_padding(&gMapHeader); + sub_80BBCCC(0); + sub_80BB970(gMapHeader.events); + sub_8056670(); + mapheader_run_script_with_tag_x1(); + UpdateTVScreensOnMap(gUnknown_03004870.width, gUnknown_03004870.height); +} + +void mapheader_copy_mapdata_with_padding(struct MapHeader *mapHeader) { + struct MapData *mapData; + int width; + int height; + mapData = mapHeader->mapData; + CpuFastFill16(0x03ff, gUnknown_02029828, sizeof(gUnknown_02029828)); + gUnknown_03004870.map = gUnknown_02029828; + width = mapData->width + 15; + gUnknown_03004870.width = width; + height = mapData->height + 14; + gUnknown_03004870.height = height; + if (width * height <= 0x2800) { + map_copy_with_padding(mapData->map, mapData->width, mapData->height); + sub_80560AC(mapHeader); + } +} + +void map_copy_with_padding(u16 *map, u16 width, u16 height) { + u16 *dest; + int y; + dest = gUnknown_03004870.map; + dest += gUnknown_03004870.width * 7 + 7; + for (y = 0; y < height; y++) { + CpuCopy16(map, dest, width * 2); + dest += width + 0xf; + map += width; + } +} + +void sub_80560AC(struct MapHeader *mapHeader) { + int i; + struct MapConnection *connection; + struct MapHeader *cMap; + u32 offset; + int count; + count = mapHeader->connections->count; + connection = mapHeader->connections->connections; + gUnknown_0202E850 = sDummyConnectionFlags; + for (i = 0; i < count; i++, connection++) { + cMap = mapconnection_get_mapheader(connection); + offset = connection->offset; + switch (connection->direction) { + case CONNECTION_SOUTH: + fillSouthConnection(mapHeader, cMap, offset); + gUnknown_0202E850.south = 1; + break; + case CONNECTION_NORTH: + fillNorthConnection(mapHeader, cMap, offset); + gUnknown_0202E850.north = 1; + break; + case CONNECTION_WEST: + fillWestConnection(mapHeader, cMap, offset); + gUnknown_0202E850.west = 1; + break; + case CONNECTION_EAST: + fillEastConnection(mapHeader, cMap, offset); + gUnknown_0202E850.east = 1; + break; + } + } +} + +void sub_8056134(int x, int y, struct MapHeader *mapHeader, int x2, int y2, int width, int height) { + int i; + u16 *src; + u16 *dest; + int mapWidth; + + mapWidth = mapHeader->mapData->width; + src = &mapHeader->mapData->map[mapWidth * y2 + x2]; + dest = &gUnknown_03004870.map[gUnknown_03004870.width * y + x]; + + for (i = 0; i < height; i++) { + CpuCopy16(src, dest, width * 2); + dest += gUnknown_03004870.width; + src += mapWidth; + } +} + +void fillSouthConnection(struct MapHeader *mapHeader, struct MapHeader *connectedMapHeader, s32 offset) { + int x, y; + int x2; + int width; + int cWidth; + + if (connectedMapHeader) { + cWidth = connectedMapHeader->mapData->width; + x = offset + 7; + y = mapHeader->mapData->height + 7; + if (x < 0) { + x2 = -x; + x += cWidth; + if (x < gUnknown_03004870.width) { + width = x; + } else { + width = gUnknown_03004870.width; + } + x = 0; + } else { + x2 = 0; + if (x + cWidth < gUnknown_03004870.width) { + width = cWidth; + } else { + width = gUnknown_03004870.width - x; + } + } + sub_8056134( + x, y, + connectedMapHeader, + x2, /*y2*/ 0, + width, /*height*/ 7); + } +} + +void fillNorthConnection(struct MapHeader *mapHeader, struct MapHeader *connectedMapHeader, s32 offset) { + int x; + int x2, y2; + int width; + int cWidth, cHeight; + + if (connectedMapHeader) { + cWidth = connectedMapHeader->mapData->width; + cHeight = connectedMapHeader->mapData->height; + x = offset + 7; + y2 = cHeight - 7; + if (x < 0) { + x2 = -x; + x += cWidth; + if (x < gUnknown_03004870.width) { + width = x; + } else { + width = gUnknown_03004870.width; + } + x = 0; + } else { + x2 = 0; + if (x + cWidth < gUnknown_03004870.width) { + width = cWidth; + } else { + width = gUnknown_03004870.width - x; + } + } + + sub_8056134( + x, /*y*/ 0, + connectedMapHeader, + x2, y2, + width, /*height*/ 7); + + } +} + + +void fillWestConnection(struct MapHeader *mapHeader, struct MapHeader *connectedMapHeader, s32 offset) { + int y; + int x2, y2; + int height; + int cWidth, cHeight; + if (connectedMapHeader) { + cWidth = connectedMapHeader->mapData->width; + cHeight = connectedMapHeader->mapData->height; + y = offset + 7; + x2 = cWidth - 7; + if (y < 0) { + y2 = -y; + if (y + cHeight < gUnknown_03004870.height) { + height = y + cHeight; + } else { + height = gUnknown_03004870.height; + } + y = 0; + } else { + y2 = 0; + if (y + cHeight < gUnknown_03004870.height) { + height = cHeight; + } else { + height = gUnknown_03004870.height - y; + } + } + + sub_8056134( + /*x*/ 0, y, + connectedMapHeader, + x2, y2, + /*width*/ 7, height); + } +} + +void fillEastConnection(struct MapHeader *mapHeader, struct MapHeader *connectedMapHeader, s32 offset) { + int x, y; + int y2; + int height; + int cHeight; + if (connectedMapHeader) { + cHeight = connectedMapHeader->mapData->height; + x = mapHeader->mapData->width + 7; + y = offset + 7; + if (y < 0) { + y2 = -y; + if (y + cHeight < gUnknown_03004870.height) { + height = y + cHeight; + } else { + height = gUnknown_03004870.height; + } + y = 0; + } else { + y2 = 0; + if (y + cHeight < gUnknown_03004870.height) { + height = cHeight; + } else { + height = gUnknown_03004870.height - y; + } + } + + sub_8056134( + x, y, + connectedMapHeader, + /*x2*/ 0, y2, + /*width*/ 8, height); + } +} + +union Block { + struct { + u16 block:10; + u16 collision:2; + u16 elevation:4; + } block; + u16 value; +}; + +u16 MapGridGetZCoordAt(int x, int y) { + u16 block; + int i; + u16 *border; + + if (x >= 0 && x < gUnknown_03004870.width + && y >= 0 && y < gUnknown_03004870.height) { + block = gUnknown_03004870.map[x + gUnknown_03004870.width * y]; + } else { + border = gMapHeader.mapData->border; + i = (x + 1) & 1; + i += ((y + 1) & 1) * 2; + block = gMapHeader.mapData->border[i]; + block |= 0xc00; + } + if (block == 0x3ff) { + return 0; + } + return block >> 12; +} + +u16 MapGridIsImpassableAt(int x, int y) { + u16 block; + int i; + u16 *border; + + if (x >= 0 && x < gUnknown_03004870.width + && y >= 0 && y < gUnknown_03004870.height) { + block = gUnknown_03004870.map[x + gUnknown_03004870.width * y]; + } else { + border = gMapHeader.mapData->border; + i = (x + 1) & 1; + i += ((y + 1) & 1) * 2; + block = gMapHeader.mapData->border[i]; + block |= 0xc00; + } + if (block == 0x3ff) { + return 1; + } + return (block & 0xc00) >> 10; +} + +u16 MapGridGetMetatileIdAt(int x, int y) { + u16 block; + int i; + int j; + struct MapData *mapData; + u16 *border; + u16 block2; + + if (x >= 0 && x < gUnknown_03004870.width + && y >= 0 && y < gUnknown_03004870.height) { + block = gUnknown_03004870.map[x + gUnknown_03004870.width * y]; + } else { + mapData = gMapHeader.mapData; + i = (x + 1) & 1; + i += ((y + 1) & 1) * 2; + block = mapData->border[i] | 0xc00; + } + if (block == 0x3ff) { + border = gMapHeader.mapData->border; + j = (x + 1) & 1; + j += ((y + 1) & 1) * 2; + block2 = gMapHeader.mapData->border[j]; + block2 |= 0xc00; + return block2 & block; + } + return block & 0x3ff; +} + +u32 MapGridGetMetatileBehaviorAt(int x, int y) { + u16 metatile; + metatile = MapGridGetMetatileIdAt(x, y); + return GetBehaviorByMetatileId(metatile) & 0xff; +} + +u16 MapGridGetMetatileLayerTypeAt(int x, int y) { + u16 metatile; + metatile = MapGridGetMetatileIdAt(x, y); + return (GetBehaviorByMetatileId(metatile) & 0xf000) >> 12; +} + +void MapGridSetMetatileIdAt(int x, int y, u16 metatile) { + int i; + if (x >= 0 && x < gUnknown_03004870.width + && y >= 0 && y < gUnknown_03004870.height) { + i = x + y * gUnknown_03004870.width; + gUnknown_03004870.map[i] = (gUnknown_03004870.map[i] & 0xf000) | (metatile & 0xfff); + } +} + +void MapGridSetMetatileEntryAt(int x, int y, u16 metatile) { + int i; + if (x >= 0 && x < gUnknown_03004870.width + && y >= 0 && y < gUnknown_03004870.height) { + i = x + gUnknown_03004870.width * y; + gUnknown_03004870.map[i] = metatile; + } +} + +u32 GetBehaviorByMetatileId(u16 metatile) { + u16 *attributes; + if (metatile <= 0x1ff) { + attributes = gMapHeader.mapData->primaryTileset->metatileAttributes; + return attributes[metatile]; + } else if (metatile <= 0x3ff) { + attributes = gMapHeader.mapData->secondaryTileset->metatileAttributes; + return attributes[metatile - 0x200]; + } else { + return 0xff; + } +} + +void save_serialize_map(void) { + int i, j; + int x, y; + u16 *mapView; + int width; + mapView = gSaveBlock1.mapView; + width = gUnknown_03004870.width; + x = gSaveBlock1.pos.x; + y = gSaveBlock1.pos.y; + for (i = y; i < y + 14; i++) + for (j = x; j < x + 15; j++) { + *mapView++ = gUnknown_02029828[width * i + j]; + } +} + +int sub_8056618(void) { + u16 i; + u32 r2; + r2 = 0; + for (i = 0; i < 0x200; i++) { + r2 |= gSaveBlock1.mapView[i]; + } + if (r2 == 0) { + return 1; + } + return 0; +} + +void sav2_mapdata_clear(void) { + CpuFill16(0, gSaveBlock1.mapView, sizeof(gSaveBlock1.mapView)); +} + +void sub_8056670(void) { + int i, j; + int x, y; + u16 *mapView; + int width; + mapView = gSaveBlock1.mapView; + if (!sub_8056618()) { + width = gUnknown_03004870.width; + x = gSaveBlock1.pos.x; + y = gSaveBlock1.pos.y; + for (i = y; i < y + 14; i++) + for (j = x; j < x + 15; j++) { + gUnknown_02029828[width * i + j] = *mapView++; + } + sav2_mapdata_clear(); + } +} + +void sub_80566F0(u8 a1) { + u16 *mapView; + int width; + int x0, y0; + int x2, y2; + u16 *src, *dest; + int srci, desti; + int r9, r8; + int x, y; + int i, j; + mapView = gSaveBlock1.mapView; + width = gUnknown_03004870.width; + r9 = 0; + r8 = 0; + x0 = gSaveBlock1.pos.x; + y0 = gSaveBlock1.pos.y; + x2 = 15; + y2 = 14; + switch (a1) { + case CONNECTION_NORTH: + y0 += 1; + y2 = 13; + break; + case CONNECTION_SOUTH: + r8 = 1; + y2 = 13; + break; + case CONNECTION_WEST: + x0 += 1; + x2 = 14; + break; + case CONNECTION_EAST: + r9 = 1; + x2 = 14; + break; + } + for (y = 0; y < y2; y++) { + i = 0; + j = 0; + for (x = 0; x < x2; x++) { + desti = width * (y + y0); + srci = (y + r8) * 15 + r9; + src = &mapView[srci + i]; + dest = &gUnknown_02029828[x0 + desti + j]; + *dest = *src; + i++; + j++; + } + } + sav2_mapdata_clear(); +} + +int GetMapBorderIdAt(int x, int y) { + struct MapData *mapData; + u16 block, block2; + int i, j; + if (x >= 0 && x < gUnknown_03004870.width + && y >= 0 && y < gUnknown_03004870.height) { + i = gUnknown_03004870.width; + i *= y; + block = gUnknown_03004870.map[x + i]; + if (block == 0x3ff) { + goto fail; + } + } else { + mapData = gMapHeader.mapData; + j = (x + 1) & 1; + j += ((y + 1) & 1) * 2; + block2 = 0xc00 | mapData->border[j]; + if (block2 == 0x3ff) { + goto fail; + } + } + goto success; +fail: + return -1; +success: + + if (x >= (gUnknown_03004870.width - 8)) { + if (!gUnknown_0202E850.east) { + return -1; + } + return CONNECTION_EAST; + } else if (x < 7) { + if (!gUnknown_0202E850.west) { + return -1; + } + return CONNECTION_WEST; + } else if (y >= (gUnknown_03004870.height - 7)) { + if (!gUnknown_0202E850.south) { + return -1; + } + return CONNECTION_SOUTH; + } else if (y < 7) { + if (!gUnknown_0202E850.north) { + return -1; + } + return CONNECTION_NORTH; + } else { + return 0; + } +} + +int GetPostCameraMoveMapBorderId(int x, int y) { + return GetMapBorderIdAt(gSaveBlock1.pos.x + 7 + x, gSaveBlock1.pos.y + 7 + y); +} + +int CanCameraMoveInDirection(int direction) { + int x, y; + x = gSaveBlock1.pos.x + 7 + gUnknown_0821664C[direction].x; + y = gSaveBlock1.pos.y + 7 + gUnknown_0821664C[direction].y; + if (GetMapBorderIdAt(x, y) == -1) { + return 0; + } + return 1; +} + +void sub_8056918(struct MapConnection *connection, int direction, int x, int y) { + struct MapHeader *mapHeader; + mapHeader = mapconnection_get_mapheader(connection); + switch (direction) { + case CONNECTION_EAST: + gSaveBlock1.pos.x = -x; + gSaveBlock1.pos.y -= connection->offset; + break; + case CONNECTION_WEST: + gSaveBlock1.pos.x = mapHeader->mapData->width; + gSaveBlock1.pos.y -= connection->offset; + break; + case CONNECTION_SOUTH: + gSaveBlock1.pos.x -= connection->offset; + gSaveBlock1.pos.y = -y; + break; + case CONNECTION_NORTH: + gSaveBlock1.pos.x -= connection->offset; + gSaveBlock1.pos.y = mapHeader->mapData->height; + break; + } +} + +bool8 CameraMove(int x, int y) { + unsigned int direction; + struct MapConnection *connection; + int old_x, old_y; + gUnknown_0202E844.field_0 = FALSE; + direction = GetPostCameraMoveMapBorderId(x, y); + if (direction + 1 <= 1) { + gSaveBlock1.pos.x += x; + gSaveBlock1.pos.y += y; + } else { + save_serialize_map(); + old_x = gSaveBlock1.pos.x; + old_y = gSaveBlock1.pos.y; + connection = sub_8056A64(direction, gSaveBlock1.pos.x, gSaveBlock1.pos.y); + sub_8056918(connection, direction, x, y); + sub_80538F0(connection->mapGroup, connection->mapNum); + gUnknown_0202E844.field_0 = TRUE; + gUnknown_0202E844.x = old_x - gSaveBlock1.pos.x; + gUnknown_0202E844.y = old_y - gSaveBlock1.pos.y; + gSaveBlock1.pos.x += x; + gSaveBlock1.pos.y += y; + sub_80566F0(direction); + } + return gUnknown_0202E844.field_0; +} + +struct MapConnection *sub_8056A64(u8 direction, int x, int y) { + int count; + struct MapConnection *connection; + int i; + count = gMapHeader.connections->count; + connection = gMapHeader.connections->connections; + for (i = 0; i < count; i++, connection++) { + if (connection->direction == direction) { + if (sub_8056ABC(direction, x, y, connection) == TRUE) { + return connection; + } + } + } + return NULL; +} + +bool8 sub_8056ABC(u8 direction, int x, int y, struct MapConnection *connection) { + struct MapHeader *mapHeader; + mapHeader = mapconnection_get_mapheader(connection); + switch (direction) { + case CONNECTION_SOUTH: + case CONNECTION_NORTH: + return sub_8056B20(x, gMapHeader.mapData->width, mapHeader->mapData->width, connection->offset); + case CONNECTION_WEST: + case CONNECTION_EAST: + return sub_8056B20(y, gMapHeader.mapData->height, mapHeader->mapData->height, connection->offset); + } + return FALSE; +} + +bool8 sub_8056B20(int x, int src_width, int dest_width, int offset) { + int offset2; + offset2 = offset; + if (offset2 < 0) { + offset2 = 0; + } + if (dest_width + offset < src_width) { + src_width = dest_width + offset; + } + if (offset2 <= x && x <= src_width) { + return TRUE; + } + return FALSE; +} + +int sub_8056B4C(int x, int width) { + if (x >= 0 && x < width) { + return TRUE; + } + return FALSE; +} + +int sub_8056B60(struct MapConnection *connection, int x, int y) { + struct MapHeader *mapHeader; + mapHeader = mapconnection_get_mapheader(connection); + switch (connection->direction) { + case CONNECTION_SOUTH: + case CONNECTION_NORTH: + return sub_8056B4C(x - connection->offset, mapHeader->mapData->width); + case CONNECTION_WEST: + case CONNECTION_EAST: + return sub_8056B4C(y - connection->offset, mapHeader->mapData->height); + } + return FALSE; +} + +struct MapConnection *sub_8056BA0(s16 x, s16 y) { + int count; + struct MapConnection *connection; + int i; + u8 direction; + if (!gMapHeader.connections) { + return NULL; + } else { + count = gMapHeader.connections->count; + connection = gMapHeader.connections->connections; + for (i = 0; i < count; i++, connection++) { + direction = connection->direction; + if ( + (direction == CONNECTION_DIVE || direction == CONNECTION_EMERGE) + || (direction == CONNECTION_NORTH && y > 6) + || (direction == CONNECTION_SOUTH && y < gMapHeader.mapData->height + 7) + || (direction == CONNECTION_WEST && x > 6) + || (direction == CONNECTION_EAST && x < gMapHeader.mapData->width + 7) + ) { + continue; + } + if (sub_8056B60(connection, x - 7, y - 7) == TRUE) { + return connection; + } + } + } + return NULL; +} + +void sub_8056C50(u16 x, u16 y) { + gSaveBlock1.pos.x = x - 7; + gSaveBlock1.pos.y = y - 7; +} + +void sav1_camera_get_focus_coords(u16 *x, u16 *y) { + *x = gSaveBlock1.pos.x + 7; + *y = gSaveBlock1.pos.y + 7; +} + +void unref_sub_8056C7C(u16 x, u16 y) { + gSaveBlock1.pos.x = x; + gSaveBlock1.pos.y = y; +} + +void GetCameraCoords(u16 *x, u16 *y) { + *x = gSaveBlock1.pos.x; + *y = gSaveBlock1.pos.y; +} + +void sub_8056C98(struct Tileset *tileset, void *src) { + if (tileset) { + if (!tileset->isCompressed) { + CpuFastSet(tileset->tiles, src, 0x1000); + } else { + LZ77UnCompVram(tileset->tiles, src); + } + } +} + +void sub_8056CBC(struct Tileset *tileset, int offset, int size) { + u16 black; + if (tileset) { + if (tileset->isSecondary == FALSE) { + black = 0; + LoadPalette(&black, offset, 2); + LoadPalette(tileset->palettes + 2, offset + 1, size - 2); + } else if (tileset->isSecondary == TRUE) { + LoadPalette(tileset->palettes + 0xc0, offset, size); + } else { + LZ77UnCompVram(tileset->palettes, (void*)0x2000000); + LoadPalette((void*)0x2000000, offset, size); + } + } +} + +void sub_8056D28(struct MapData *mapData) { + void *src = (void*)(BG_VRAM); + sub_8056C98(mapData->primaryTileset, src); +} + +void sub_8056D38(struct MapData *mapData) { + void *src = (void*)(BG_VRAM + 0x4000); + sub_8056C98(mapData->secondaryTileset, src); +} + +void apply_map_tileset1_palette(struct MapData *mapData) { + sub_8056CBC(mapData->primaryTileset, 0, 0xc0); +} + +void apply_map_tileset2_palette(struct MapData *mapData) { + sub_8056CBC(mapData->secondaryTileset, 0x60, 0xc0); +} + +void copy_map_tileset1_tileset2_to_vram(struct MapData *mapData) { + if (mapData) { + sub_8056D28(mapData); + sub_8056D38(mapData); + } +} + +void apply_map_tileset1_tileset2_palette(struct MapData *mapData) { + if (mapData) { + apply_map_tileset1_palette(mapData); + apply_map_tileset2_palette(mapData); + } +} diff --git a/src/flag.c b/src/flag.c deleted file mode 100644 index e7347ad0d..000000000 --- a/src/flag.c +++ /dev/null @@ -1,44 +0,0 @@ -#include "global.h" -#include "flag.h" - -extern u8 gUnknown_0202E8E2[]; - -u8 *GetFlagPointer(u16 id) -{ - if (id == 0) - return 0; - - if (id < 0x4000) - return &gSaveBlock1.flags[id / 8]; - - return &gUnknown_0202E8E2[(id - 0x4000) / 8]; -} - -u8 FlagSet(u16 id) -{ - u8 *ptr = GetFlagPointer(id); - if (ptr) - *ptr |= 1 << (id & 7); - return 0; -} - -u8 FlagReset(u16 id) -{ - u8 *ptr = GetFlagPointer(id); - if (ptr) - *ptr &= ~(1 << (id & 7)); - return 0; -} - -bool8 FlagGet(u16 id) -{ - u8 *ptr = GetFlagPointer(id); - - if (!ptr) - return FALSE; - - if (!(((*ptr) >> (id & 7)) & 1)) - return FALSE; - - return TRUE; -} diff --git a/src/fldeff_emotion.c b/src/fldeff_emotion.c deleted file mode 100644 index 06eb7bd9e..000000000 --- a/src/fldeff_emotion.c +++ /dev/null @@ -1,82 +0,0 @@ -#include "global.h" -#include "sprite.h" -#include "fieldmap.h" - -extern u32 gUnknown_0202FF84[]; - -extern struct SpriteTemplate gSpriteTemplate_839B510; -extern struct SpriteTemplate gSpriteTemplate_839B528; - -bool8 TryGetFieldObjectIdByLocalIdAndMap(u8, u8, u8, u8 *); - -void FieldEffectStop(struct Sprite *sprite, u16 a2); -void sub_8084894(struct Sprite *sprite, u16 a2, u8 a3); -void objc_exclamation_mark_probably(struct Sprite *sprite); - -u8 FldEff_ExclamationMarkIcon1(void) -{ - u8 spriteId = CreateSpriteAtEnd(&gSpriteTemplate_839B510, 0, 0, 0x53); - - if (spriteId != 64) - sub_8084894(&gSprites[spriteId], 0, 0); - - return 0; -} - -u8 FldEff_ExclamationMarkIcon2(void) -{ - u8 spriteId = CreateSpriteAtEnd(&gSpriteTemplate_839B510, 0, 0, 0x52); - - if (spriteId != 64) - sub_8084894(&gSprites[spriteId], 33, 1); - - return 0; -} - -u8 FldEff_HeartIcon(void) -{ - u8 spriteId = CreateSpriteAtEnd(&gSpriteTemplate_839B528, 0, 0, 0x52); - - if (spriteId != 64) - sub_8084894(&gSprites[spriteId], 46, 0); - - return 0; -} - -void sub_8084894(struct Sprite *sprite, u16 a2, u8 a3) -{ - sprite->oam.priority = 1; - sprite->coordOffsetEnabled = 1; - - sprite->data0 = gUnknown_0202FF84[0]; - sprite->data1 = gUnknown_0202FF84[1]; - sprite->data2 = gUnknown_0202FF84[2]; - sprite->data3 = -5; - sprite->data7 = a2; - - StartSpriteAnim(sprite, a3); -} - -void objc_exclamation_mark_probably(struct Sprite *sprite) -{ - u8 mapObjId; - - if (TryGetFieldObjectIdByLocalIdAndMap(sprite->data0, sprite->data1, sprite->data2, &mapObjId) - || sprite->animEnded) - { - FieldEffectStop(sprite, (u8)sprite->data7); - } - else - { - struct Sprite *mapObjSprite = &gSprites[gMapObjects[mapObjId].spriteId]; - sprite->data4 += sprite->data3; - sprite->pos1.x = mapObjSprite->pos1.x; - sprite->pos1.y = mapObjSprite->pos1.y - 16; - sprite->pos2.x = mapObjSprite->pos2.x; - sprite->pos2.y = mapObjSprite->pos2.y + sprite->data4; - if (sprite->data4) - sprite->data3++; - else - sprite->data3 = 0; - } -}
\ No newline at end of file diff --git a/src/fldeff_strength.c b/src/fldeff_strength.c new file mode 100644 index 000000000..4da04326a --- /dev/null +++ b/src/fldeff_strength.c @@ -0,0 +1,74 @@ +#include "global.h" +#include "field_effect.h" +#include "asm.h" +#include "pokemon.h" +#include "script.h" +#include "task.h" + +static void sub_811AA18(void); +static void sub_811AA38(void); +static void sub_811AA9C(void); + +extern u32 gUnknown_0202FF84; + +extern u8 gUnknown_03005CE0; +extern u16 gScriptResult; +extern void (*gUnknown_0300485C)(void); +extern void (*gUnknown_03005CE4)(void); + +extern u8 UseStrengthScript[]; + +bool8 SetUpFieldMove_Strength(void) +{ + if (ShouldDoBrailleStrengthEffect()) + { + gScriptResult = gUnknown_03005CE0; + gUnknown_0300485C = sub_808AB90; + gUnknown_03005CE4 = sub_811AA38; + } + else + { + if (npc_before_player_of_type(87) != TRUE) + return 0; + gScriptResult = gUnknown_03005CE0; + gUnknown_0300485C = sub_808AB90; + gUnknown_03005CE4 = sub_811AA18; + } + + return TRUE; +} + +static void sub_811AA18(void) +{ + gUnknown_0202FF84 = gUnknown_03005CE0; + ScriptContext1_SetupScript(UseStrengthScript); +} + +static void sub_811AA38(void) +{ + gUnknown_0202FF84 = gUnknown_03005CE0; + FieldEffectStart(40); +} + +bool8 FldEff_UseStrength(void) +{ + u8 taskId = oei_task_add(); + + gTasks[taskId].data[8] = (u32)sub_811AA9C >> 16; + gTasks[taskId].data[9] = (u32)sub_811AA9C; + GetMonNickname(&gPlayerParty[gUnknown_0202FF84], gStringVar1); + return FALSE; +} + +static void sub_811AA9C(void) +{ + if (ShouldDoBrailleStrengthEffect()) + { + DoBrailleStrengthEffect(); + } + else + { + FieldEffectActiveListRemove(40); + EnableBothScriptContexts(); + } +} diff --git a/src/heal_location.c b/src/heal_location.c index da2e466a9..13bb125b6 100644 --- a/src/heal_location.c +++ b/src/heal_location.c @@ -1,15 +1,8 @@ #include "global.h" +#include "heal_location.h" #define NUM_HEAL_LOCATIONS 22 -struct HealLocation -{ - s8 group; - s8 map; - u16 x; - u16 y; -}; - extern const struct HealLocation gHealLocations[]; u32 GetHealLocationIndexByMap(u16 mapGroup, u16 mapNum) diff --git a/src/intro.c b/src/intro.c index e103109f9..544d8b64f 100644 --- a/src/intro.c +++ b/src/intro.c @@ -1,66 +1,190 @@ #include "global.h" +#include "intro.h" +#include "asm.h" +#include "gba/m4a_internal.h" +#include "m4a.h" +#include "libgncmultiboot.h" +#include "save.h" +#include "decompress.h" +#include "title_screen.h" +#include "new_game.h" +#include "link.h" #include "main.h" #include "palette.h" +#include "rng.h" +#include "songs.h" +#include "sound.h" +#include "species.h" #include "task.h" -#include "link.h" +#include "trig.h" + +extern void *species_and_otid_get_pal(/*TODO: arg types*/); +extern void sub_8143648(int, u8); +extern void sub_8143680(int, u8); -struct GcmbStruct +struct MonCoords { - u16 gcmb_field_0; - u8 gcmb_field_2; + u8 x, y; }; -extern s32 gUnknown_03005ED0; + +extern struct SpriteTemplate gUnknown_02024E8C; +extern u16 gUnknown_02039318; +extern u16 gUnknown_0203931A; +extern u16 gUnknown_02039358; +extern u16 gUnknown_0203935A; + +extern u32 gIntroFrameCounter; extern struct GcmbStruct gUnknown_03005EE0; extern u16 gSaveFileStatus; +extern u8 gReservedSpritePaletteCount; +extern struct SpriteSheet gMonFrontPicTable[]; +extern struct MonCoords gMonFrontPicCoords[]; +extern struct SpriteSheet gMonBackPicTable[]; +extern struct MonCoords gMonBackPicCoords[]; +extern struct SpriteSheet gTrainerBackPicTable[]; +extern struct MonCoords gTrainerBackPicCoords[]; +extern struct SpritePalette gTrainerBackPicPaletteTable[]; + +extern const u16 gIntro1BGPals[]; +extern const u8 gIntro1BG0_Tilemap[]; +extern const u8 gIntro1BG1_Tilemap[]; +extern const u8 gIntro1BG2_Tilemap[]; +extern const u8 gIntro1BG3_Tilemap[]; +extern const u8 gIntro1BGLeavesGfx[]; +extern const u8 gIntro3PokeballPal[]; +extern const u8 gIntro3Pokeball_Tilemap[]; +extern const u8 gIntro3Pokeball_Gfx[]; +extern const u16 gIntro3Streaks_Pal[]; +extern const u8 gIntro3Streaks_Gfx[]; +extern const u8 gIntro3Streaks_Tilemap[]; +extern union AnimCmd *gUnknown_0840AE80[]; +extern const struct SpriteTemplate gSpriteTemplate_840AFF0; +extern const struct SpriteSheet gUnknown_0840B008; +extern const struct SpriteSheet gUnknown_0840B018; +extern const struct SpritePalette gUnknown_0840B028[]; +extern const struct SpriteTemplate gSpriteTemplate_840B1F4; +extern const struct SpriteSheet gIntro3PokeballGfx_Table; +extern const struct SpriteSheet gIntro3MiscGfx_Table; +extern const struct SpritePalette gInterfacePokeballPal_Table; +extern const struct SpritePalette gIntro3MiscPal_Table[]; +extern const struct SpriteSheet gIntro2BrendanSpriteSheet; +extern const struct SpriteSheet gIntro2MaySpriteSheet; +extern const struct SpriteSheet gIntro2BicycleSpriteSheet; +extern const struct SpriteSheet gIntro2LatiosSpriteSheet; +extern const struct SpriteSheet gIntro2LatiasSpriteSheet; +extern const struct SpritePalette gIntro2SpritePalettes[]; + +extern const struct SpriteTemplate gSpriteTemplate_840AE20; extern const u8 gIntroCopyright_Gfx[]; extern const u16 gIntroCopyright_Pal[]; extern const u16 gIntroCopyright_Tilemap[]; -extern void CB2_InitTitleScreen(void); +extern const u16 gUnknown_08393E64[]; +extern const s16 gUnknown_0840AF50[][2]; +extern const s16 gUnknown_0840AF74[][2]; +extern const struct SpriteTemplate gSpriteTemplate_840AF94; +extern const struct SpriteTemplate gSpriteTemplate_840AFAC; +extern const struct SpriteTemplate gSpriteTemplate_840AFC4; +extern union AnimCmd *gUnknown_0840B064[]; +extern const struct SpriteTemplate gSpriteTemplate_840B084; +extern const struct SpriteTemplate gSpriteTemplate_840B0B0; +extern const struct SpriteTemplate gSpriteTemplate_840B0DC; +extern const struct SpriteTemplate gSpriteTemplate_840B0F4; +extern const struct SpriteTemplate gSpriteTemplate_840B124; +extern const struct SpriteTemplate gSpriteTemplate_840B150; +extern const u8 gUnknown_0840B168[]; +extern const struct SpriteTemplate gSpriteTemplate_840B170; +extern const u16 gUnknown_0840B188[]; +extern const struct SpriteTemplate gSpriteTemplate_840B1B0; +extern const struct SpriteTemplate gSpriteTemplate_840B1C8; +extern void *gUnknown_0840B5A0[]; -void CB2_813B7EC(void); -void task_intro_1(u8); +extern const s16 gSineTable[]; -void sub_813B784(void) +static void MainCB2_EndIntro(void); +static void Task_IntroLoadPart1Graphics(u8); +static void Task_IntroFadeIn(u8); +static void Task_IntroWaterDrops(u8); +static void Task_IntroScrollDownAndShowEon(u8); +static void Task_IntroWaitToSetupPart2(u8); +static void Task_IntroLoadPart2Graphics(u8); +static void Task_IntroStartBikeRide(u8); +static void Task_IntroHandleBikeAndEonMovement(u8); +static void Task_IntroWaitToSetupPart3(u8); +static void Task_IntroLoadPart3Graphics(u8); +static void Task_IntroSpinAndZoomPokeball(u8); +static void Task_IntroWaitToSetupPart3DoubleFight(u8); +static void Task_IntroLoadPart3Streaks(u8); +static void task_intro_14(u8); +static void task_intro_15(u8); +static void task_intro_16(u8); +static void task_intro_17(u8); +static void Task_IntroPokemonBattle(u8); +static void task_intro_19(u8); +static void task_intro_20(u8); +static void intro_reset_and_hide_bgs(void); +static void sub_813CCE8(u8); +static u16 sub_813CE88(u16, s16, s16, u16, u8); +static u8 sub_813CFA8(u16, u16, u16, u16); +static void sub_813D084(u8); +void sub_813D220(struct Sprite *); +void sub_813D368(struct Sprite *); +void sub_813D414(struct Sprite *); +void SpriteCB_WaterDropFall(struct Sprite *); +static u8 CreateWaterDrop(s16, s16, u16, u16, u16, u8); +void sub_813D788(struct Sprite *); +void sub_813D880(struct Sprite *); +static u8 CreateGameFreakLogo(s16, s16, u8); +void sub_813DB9C(struct Sprite *); +void sub_813DE70(struct Sprite *); +void sub_813E10C(struct Sprite *); +void sub_813E210(struct Sprite *); +static void sub_813E580(u16, u16); +static void sub_813E7C0(u8); +static void sub_813E930(u8); +static void InitIntroTorchicAttackAnim(u8); +static void InitIntroMudkipAttackAnim(u8); + +static void VBlankCB_Intro(void) { LoadOam(); ProcessSpriteCopyRequests(); TransferPlttBuffer(); } -void CB2_813B798(void) +static void MainCB2_Intro(void) { RunTasks(); AnimateSprites(); BuildOamBuffer(); UpdatePaletteFade(); if (gMain.newKeys && !gPaletteFade.active) - SetMainCallback2(CB2_813B7EC); - else if (gUnknown_03005ED0 != -1) - gUnknown_03005ED0++; + SetMainCallback2(MainCB2_EndIntro); + else if (gIntroFrameCounter != -1) + gIntroFrameCounter++; } -void CB2_813B7EC(void) +static void MainCB2_EndIntro(void) { if (!UpdatePaletteFade()) SetMainCallback2(CB2_InitTitleScreen); } -void sub_813B808(u16 a1, u16 a2, u16 a3) +static void LoadCopyrightGraphics(u16 a1, u16 a2, u16 a3) { LZ77UnCompVram(gIntroCopyright_Gfx, (void *)(VRAM + a1)); LoadPalette(gIntroCopyright_Pal, a3, 0x20); CpuCopy16(gIntroCopyright_Tilemap, (void *)(VRAM + a2), 0x500); } -void SerialCb_CopyrightScreen(void) +static void SerialCb_CopyrightScreen(void) { GameCubeMultiBoot_HandleSerialInterrupt(&gUnknown_03005EE0); } -u8 SetUpCopyrightScreen(void) +static u8 SetUpCopyrightScreen(void) { u16 ime; @@ -79,7 +203,7 @@ u8 SetUpCopyrightScreen(void) DmaFill32(3, 0, (void *)OAM, OAM_SIZE); DmaFill16(3, 0, (void *)(PLTT + 2), PLTT_SIZE - 2); ResetPaletteFade(); - sub_813B808(0, 14336, 0); + LoadCopyrightGraphics(0, 14336, 0); remove_some_task(); ResetTasks(); ResetSpriteData(); @@ -90,9 +214,9 @@ u8 SetUpCopyrightScreen(void) REG_IME = 0; REG_IE |= INTR_FLAG_VBLANK; REG_IME = ime; - REG_DISPSTAT |= 8; - SetVBlankCallback(sub_813B784); - REG_DISPCNT = 320; + REG_DISPSTAT |= DISPSTAT_VBLANK_INTR; + SetVBlankCallback(VBlankCB_Intro); + REG_DISPCNT = DISPCNT_MODE_0 | DISPCNT_OBJ_1D_MAP | DISPCNT_BG0_ON; SetSerialCallback(SerialCb_CopyrightScreen); GameCubeMultiBoot_Init(&gUnknown_03005EE0); default: @@ -111,8 +235,8 @@ u8 SetUpCopyrightScreen(void) case 141: if (UpdatePaletteFade()) break; - CreateTask(task_intro_1, 0); - SetMainCallback2(CB2_813B798); + CreateTask(Task_IntroLoadPart1Graphics, 0); + SetMainCallback2(MainCB2_Intro); if (gUnknown_03005EE0.gcmb_field_2) { GameCubeMultiBoot_ExecuteProgram(&gUnknown_03005EE0); @@ -145,3 +269,2217 @@ void CB2_InitCopyrightScreen(void) { SetUpCopyrightScreen(); } + +static void Task_IntroLoadPart1Graphics(u8 taskId) +{ + SetVBlankCallback(NULL); + gUnknown_02039318 = Random() & 1; + intro_reset_and_hide_bgs(); + REG_BG3VOFS = 0; + REG_BG2VOFS = 0x50; + REG_BG1VOFS = 0x18; + REG_BG0VOFS = 0x28; + LZ77UnCompVram(gIntro1BGLeavesGfx, (void *)VRAM); + LZ77UnCompVram(gIntro1BG0_Tilemap, (void *)(VRAM + 0x8000)); + DmaClear16(3, VRAM + 0x8800, 0x800); + LZ77UnCompVram(gIntro1BG1_Tilemap, (void *)(VRAM + 0x9000)); + DmaClear16(3, VRAM + 0x9800, 0x800); + LZ77UnCompVram(gIntro1BG2_Tilemap, (void *)(VRAM + 0xA000)); + DmaClear16(3, VRAM + 0xA800, 0x800); + LZ77UnCompVram(gIntro1BG3_Tilemap, (void *)(VRAM + 0xB000)); + DmaClear16(3, VRAM + 0xB800, 0x800); + LoadPalette(gIntro1BGPals, 0, 0x200); + REG_BG3CNT = 0x9603; + REG_BG2CNT = 0x9402; + REG_BG1CNT = 0x9201; + REG_BG0CNT = 0x9000; + LoadCompressedObjectPic(&gUnknown_0840B008); + LoadCompressedObjectPic(&gUnknown_0840B018); + LoadSpritePalettes(gUnknown_0840B028); + CpuCopy16(gPlttBufferUnfaded + 0x100, gPlttBufferUnfaded + 0x1F0, 0x20); + CpuCopy16(gPlttBufferUnfaded + 0x100, gPlttBufferUnfaded + 0x1E1, 0x1E); + CpuCopy16(gPlttBufferUnfaded + 0x100, gPlttBufferUnfaded + 0x1D2, 0x1C); + CpuCopy16(gPlttBufferUnfaded + 0x100, gPlttBufferUnfaded + 0x1C3, 0x1A); + CpuCopy16(gPlttBufferUnfaded + 0x100, gPlttBufferUnfaded + 0x1B4, 0x18); + CpuCopy16(gPlttBufferUnfaded + 0x100, gPlttBufferUnfaded + 0x1A5, 0x16); + CpuCopy16(gPlttBufferUnfaded + 0x100, gPlttBufferUnfaded + 0x196, 0x14); + gTasks[taskId].data[0] = CreateWaterDrop(236, -14, 0x200, 1, 0x78, FALSE); + gTasks[taskId].func = Task_IntroFadeIn; +} + +static void Task_IntroFadeIn(u8 taskId) +{ + BeginNormalPaletteFade(0xFFFFFFFF, 0, 16, 0, 0); + SetVBlankCallback(VBlankCB_Intro); + REG_DISPCNT = DISPCNT_MODE_0 | DISPCNT_OBJ_1D_MAP | DISPCNT_BG_ALL_ON | DISPCNT_OBJ_ON; + gTasks[taskId].func = Task_IntroWaterDrops; + gIntroFrameCounter = 0; + m4aSongNumStart(0x19E); + ResetSerial(); +} + +static void Task_IntroWaterDrops(u8 taskId) +{ + //start moving rock + if (gIntroFrameCounter == 76) + gSprites[gTasks[taskId].data[0]].data0 = 1; + + //drop rock + if (gIntroFrameCounter == 251) + gSprites[gTasks[taskId].data[0]].data0 = 2; + + if (gIntroFrameCounter == 368) + CreateWaterDrop(48, 0, 0x400, 5, 0x70, TRUE); + if (gIntroFrameCounter == 384) + CreateWaterDrop(200, 60, 0x400, 9, 0x80, TRUE); + + if (gIntroFrameCounter == 560) + CreateGameFreakLogo(DISPLAY_WIDTH / 2, DISPLAY_HEIGHT / 2, CreateTask(sub_813CCE8, 0)); + + if (gIntroFrameCounter > 739) + { + gTasks[taskId].data[1] = 0x50; + gTasks[taskId].data[2] = 0; + gTasks[taskId].data[3] = 0x18; + gTasks[taskId].data[4] = 0; + gTasks[taskId].data[5] = 0x28; + gTasks[taskId].data[6] = 0; + gTasks[taskId].func = Task_IntroScrollDownAndShowEon; + } +} + +static void Task_IntroScrollDownAndShowEon(u8 taskId) +{ + if (gIntroFrameCounter < 904) + { + s32 r2; + + //slide backgrounds downward + r2 = (gTasks[taskId].data[1] << 16) + (u16)gTasks[taskId].data[2] - 0xC000; + gTasks[taskId].data[1] = r2 >> 16; + gTasks[taskId].data[2] = r2; + REG_BG2VOFS = gTasks[taskId].data[1]; + r2 = (gTasks[taskId].data[3] << 16) + (u16)gTasks[taskId].data[4] - 0x10000; + gTasks[taskId].data[3] = r2 >> 16; + gTasks[taskId].data[4] = r2; + REG_BG1VOFS = gTasks[taskId].data[3]; + r2 = (gTasks[taskId].data[5] << 16) + (u16)gTasks[taskId].data[6] - 0x18000; + gTasks[taskId].data[5] = r2 >> 16; + gTasks[taskId].data[6] = r2; + REG_BG0VOFS = gTasks[taskId].data[5]; + + //show Lati@s sprite + if (gIntroFrameCounter == 880) + { + u8 spriteId = CreateSprite(&gSpriteTemplate_840AFF0, 200, 160, 10); + + gSprites[spriteId].invisible = 1; + } + } + else + { + //fade to white + if (gIntroFrameCounter > 1007) + { + BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, 0xFFFF); + gTasks[taskId].func = Task_IntroWaitToSetupPart2; + } + } +} + +static void Task_IntroWaitToSetupPart2(u8 taskId) +{ + if (gIntroFrameCounter > 1026) + gTasks[taskId].func = Task_IntroLoadPart2Graphics; +} + +static void Task_IntroLoadPart2Graphics(u8 taskId) +{ + intro_reset_and_hide_bgs(); + SetVBlankCallback(NULL); + ResetSpriteData(); + FreeAllSpritePalettes(); + gUnknown_02039358 = 0; + gUnknown_0203935A = 0; +#ifdef SAPPHIRE + load_intro_part2_graphics(0); +#else + load_intro_part2_graphics(1); +#endif + gTasks[taskId].func = Task_IntroStartBikeRide; +} + +static void Task_IntroStartBikeRide(u8 taskId) +{ + u8 spriteId; + + if (gUnknown_02039318 == 0) + LoadCompressedObjectPic(&gIntro2BrendanSpriteSheet); + else + LoadCompressedObjectPic(&gIntro2MaySpriteSheet); + LoadCompressedObjectPic(&gIntro2BicycleSpriteSheet); +#ifdef SAPPHIRE + LoadCompressedObjectPic(&gIntro2LatiasSpriteSheet); +#else + LoadCompressedObjectPic(&gIntro2LatiosSpriteSheet); +#endif + LoadSpritePalettes(gIntro2SpritePalettes); + if (gUnknown_02039318 == 0) + spriteId = intro_create_brendan_sprite(0x110, 100); + else + spriteId = intro_create_may_sprite(0x110, 100); + gSprites[spriteId].callback = sub_813D788; + gSprites[spriteId].anims = gUnknown_0840AE80; + gTasks[taskId].data[1] = spriteId; +#ifdef SAPPHIRE + spriteId = intro_create_latias_sprite(-0x40, 0x3C); +#else + spriteId = intro_create_latios_sprite(-0x40, 0x3C); +#endif + gSprites[spriteId].callback = sub_813D880; + gTasks[taskId].data[2] = spriteId; + BeginNormalPaletteFade(0xFFFFFFFF, 0, 16, 0, 0xFFFF); + SetVBlankCallback(VBlankCB_Intro); +#ifdef SAPPHIRE + gTasks[taskId].data[0] = sub_8148EC0(0, 0x4000, 0x40, 0x10); + sub_8148C78(0); +#else + gTasks[taskId].data[0] = sub_8148EC0(1, 0x4000, 0x400, 0x10); + sub_8148C78(1); +#endif + gTasks[taskId].func = Task_IntroHandleBikeAndEonMovement; +} + +static void Task_IntroHandleBikeAndEonMovement(u8 taskId) +{ + s16 a; + u16 sine; + + if (gIntroFrameCounter > 1823) + { + BeginNormalPaletteFade(0xFFFFFFFF, 16, 0, 16, 0xFFFF); + gTasks[taskId].func = Task_IntroWaitToSetupPart3; + } + if (gIntroFrameCounter == 1109) + gSprites[gTasks[taskId].data[1]].data0 = 1; + if (gIntroFrameCounter == 1214) + gSprites[gTasks[taskId].data[1]].data0 = 0; + if (gIntroFrameCounter == 1394) + gSprites[gTasks[taskId].data[2]].data0 = 1; + if (gIntroFrameCounter == 1398) + gSprites[gTasks[taskId].data[1]].data0 = 2; + if (gIntroFrameCounter == 1586) + gSprites[gTasks[taskId].data[1]].data0 = 3; + if (gIntroFrameCounter == 1727) + gSprites[gTasks[taskId].data[1]].data0 = 4; + + //TODO: Clean this up + a = (((u16)gTasks[taskId].data[3] << 16) >> 18) & 0x7F; + sine = Sin(a, 48); + gUnknown_0203935A = sine; + if (gTasks[taskId].data[3] < 512) + gTasks[taskId].data[3]++; +#ifdef SAPPHIRE + sub_8149020(0); +#else + sub_8149020(1); +#endif +} + +static void Task_IntroWaitToSetupPart3(u8 taskId) +{ + if (gIntroFrameCounter > 2068) + { + DestroyTask(gTasks[taskId].data[0]); + gTasks[taskId].func = Task_IntroLoadPart3Graphics; + } +} + +static void Task_IntroLoadPart3Graphics(u8 taskId) +{ + intro_reset_and_hide_bgs(); + LZ77UnCompVram(gIntro3Pokeball_Gfx, (void *)VRAM); + LZ77UnCompVram(gIntro3Pokeball_Tilemap, (void *)(VRAM + 0x4000)); + LoadPalette(gIntro3PokeballPal, 0, 0x200); + gTasks[taskId].data[0] = 0; + gTasks[taskId].data[1] = 0; + gTasks[taskId].data[2] = 0; + gTasks[taskId].data[3] = 0; + sub_813CE30(0x78, 0x50, 0, 0); + ResetSpriteData(); + FreeAllSpritePalettes(); + BeginNormalPaletteFade(0xFFFFFFFF, 0, 0x10, 0, 0xFFFF); + REG_BG2CNT = 0x4883; + REG_DISPCNT = DISPCNT_MODE_1 | DISPCNT_OBJ_1D_MAP | DISPCNT_BG2_ON | DISPCNT_OBJ_ON; + gTasks[taskId].func = Task_IntroSpinAndZoomPokeball; + gIntroFrameCounter = 0; + m4aSongNumStart(0x1BA); +} + +static void Task_IntroSpinAndZoomPokeball(u8 taskId) +{ + gTasks[taskId].data[0] += 0x400; + if (gTasks[taskId].data[1] <= 0x6BF) + { + gTasks[taskId].data[1] += gTasks[taskId].data[2]; + gTasks[taskId].data[2]++; + } + else + { + gTasks[taskId].func = Task_IntroWaitToSetupPart3DoubleFight; + } + sub_813CE30(0x78, 0x50, 0x10000 / gTasks[taskId].data[1], gTasks[taskId].data[0]); + if (gIntroFrameCounter == 44) + BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 0x10, 0xFFFF); +} + +static void Task_IntroWaitToSetupPart3DoubleFight(u8 taskId) +{ + if (gIntroFrameCounter > 59) + gTasks[taskId].func = Task_IntroLoadPart3Streaks; +} + +extern u8 unk_2000000[][32]; + +static void Task_IntroLoadPart3Streaks(u8 taskId) +{ + u16 i; + void *vram; + + intro_reset_and_hide_bgs(); + for (i = 0; i < 32; i++) + { + unk_2000000[0][i] = 0; + unk_2000000[1][i] = 17; + unk_2000000[2][i] = 34; + } + vram = (void *)VRAM; + DmaCopy16(3, unk_2000000, vram, 0x60); + for (i = 0; i < 0x280; i++) + ((u16 *)(VRAM + 0x3000))[i] = 0xF001; + for (i = 0; i < 0x80; i++) + ((u16 *)(VRAM + 0x3800))[i] = 0xF002; + for (i = 0; i < 0x180; i++) + ((u16 *)(VRAM + 0x3900))[i] = 0xF000; + for (i = 0; i < 0x80; i++) + ((u16 *)(VRAM + 0x3C00))[i] = 0xF002; + gPlttBufferUnfaded[0xF0] = RGB_WHITE; + gPlttBufferFaded[0xF0] = RGB_WHITE; + sub_813D084(1); + gPlttBufferUnfaded[0xF2] = RGB_BLACK; + gPlttBufferFaded[0xF2] = RGB_BLACK; + LZ77UnCompVram(gIntro3Streaks_Gfx, (void *)(VRAM + 0x4000)); + LZ77UnCompVram(gIntro3Streaks_Tilemap, (void *)(VRAM + 0x7000)); + LoadPalette(gIntro3Streaks_Pal, 0, 0x20); + ResetSpriteData(); + FreeAllSpritePalettes(); + gReservedSpritePaletteCount = 8; + LoadCompressedObjectPic(&gIntro3PokeballGfx_Table); + LoadCompressedObjectPic(&gIntro3MiscGfx_Table); + LoadCompressedObjectPalette(&gInterfacePokeballPal_Table); + LoadSpritePalettes(gIntro3MiscPal_Table); + gTasks[taskId].func = task_intro_14; +} + +static void task_intro_14(u8 taskId) +{ + REG_WIN0H = 0xF0; + REG_WIN0V = 0xA0; + REG_WININ = 0x1C; + REG_WINOUT = 0x1D; + REG_BG3CNT = 0x603; + REG_BG0CNT = 0x700; + REG_DISPCNT = DISPCNT_MODE_0 | DISPCNT_OBJ_1D_MAP | DISPCNT_BG0_ON | DISPCNT_BG3_ON | DISPCNT_OBJ_ON | DISPCNT_WIN0_ON; + gTasks[taskId].data[15] = CreateTask(task_intro_20, 0); + gTasks[gTasks[taskId].data[15]].data[0] = 0; + gTasks[taskId].data[0] = 0; + gTasks[taskId].func = task_intro_15; +} + +static void task_intro_15(u8 taskId) +{ + u16 foo = gTasks[taskId].data[0]; + + if (gTasks[taskId].data[0] != 32) + { + u32 bar; //needed to match for some reason + + gTasks[taskId].data[0] += 4; + REG_WIN0V = (gTasks[taskId].data[0] * 256) - (bar = foo - 0x9C); + } + else + { + REG_WIN0V = 0x2080; + gTasks[taskId].func = task_intro_16; + } +} + +static void task_intro_16(u8 taskId) +{ + gTasks[taskId].func = task_intro_17; +} + +static void task_intro_17(u8 taskId) +{ + gUnknown_0203931A = 0; + gTasks[taskId].func = Task_IntroPokemonBattle; +} + +static void Task_IntroPokemonBattle(u8 taskId) +{ + u8 spriteId; + + if (gIntroFrameCounter == 80) + { + spriteId = sub_813CE88(SPECIES_SHARPEDO, 0xF0, 0xA0, 5, 1); + gSprites[spriteId].callback = sub_813DB9C; + gSprites[spriteId].data1 = 1; + gSprites[spriteId].data2 = 0; + } + if (gIntroFrameCounter == 152) + { + spriteId = sub_813CE88(SPECIES_DUSKULL, 0, 0xA0, 4, 1); + gSprites[spriteId].callback = sub_813DB9C; + gSprites[spriteId].data1 = 2; + gSprites[spriteId].data2 = 1; + } + if (gIntroFrameCounter == 219) + { + sub_813D084(0); + spriteId = sub_813CFA8(gUnknown_02039318, 0x110, 0x60, 6); + gSprites[spriteId].callback = sub_813DE70; + gTasks[taskId].data[1] = spriteId; + } + if (gIntroFrameCounter == 304) + { + gTasks[gTasks[taskId].data[15]].data[0] = 4; + gSprites[gTasks[taskId].data[1]].data0 = 2; + } + if (gIntroFrameCounter == 384) + { + gTasks[gTasks[taskId].data[15]].data[0] = 0; + gSprites[gTasks[taskId].data[1]].data0 = 4; + } + if (gIntroFrameCounter == 400) + { + BeginNormalPaletteFade(0xFF0000, 0, 0x10, 0, 0x7EFF); + } + if (gIntroFrameCounter == 432) + { + gSprites[gTasks[taskId].data[1]].data0 = 5; + } + if (gIntroFrameCounter == 462) + { + gSprites[gTasks[taskId].data[1]].data0 = 6; + gTasks[gTasks[taskId].data[15]].data[0] = 2; + } + if (gIntroFrameCounter == 463) + { + sub_813D084(1); + spriteId = sub_813CE88(SPECIES_SHARPEDO, 0xD0, 8, 5, 1); + gSprites[spriteId].callback = sub_813E10C; + gTasks[taskId].data[2] = spriteId; + sub_813E7C0(spriteId); + } + if (gIntroFrameCounter == 539) + { + spriteId = sub_813CE88(SPECIES_DUSKULL, 0xF8, 0x10, 4, 1); + gSprites[spriteId].callback = sub_813E10C; + gTasks[taskId].data[3] = spriteId; + sub_813E930(spriteId); + } + if (gIntroFrameCounter == 623) + { + gSprites[gTasks[taskId].data[2]].data0 = 2; + gSprites[gTasks[taskId].data[3]].data0 = 2; + gTasks[gTasks[taskId].data[15]].data[0] = 3; + } + if (gIntroFrameCounter == 624) + { + sub_813D084(0); + spriteId = sub_813CE88(SPECIES_MUDKIP, 0x20, 0x98, 0, 0); + gSprites[spriteId].callback = sub_813E210; + gTasks[taskId].data[4] = spriteId; + InitIntroMudkipAttackAnim(spriteId); + } + if (gIntroFrameCounter == 700) + { + spriteId = sub_813CE88(SPECIES_TORCHIC, -8, 0x90, 1, 0); + gSprites[spriteId].callback = sub_813E210; + gTasks[taskId].data[5] = spriteId; + InitIntroTorchicAttackAnim(spriteId); + } + if (gIntroFrameCounter == 776) + { + gUnknown_0203931A = 1; + gSprites[gTasks[taskId].data[4]].data0 = 2; + gSprites[gTasks[taskId].data[5]].data0 = 2; + gTasks[gTasks[taskId].data[15]].data[0] = 0; + } + if (gIntroFrameCounter == 781) + { + sub_813D084(2); + gSprites[gTasks[taskId].data[2]].data0 = 3; + gSprites[gTasks[taskId].data[3]].data0 = 3; + gSprites[gTasks[taskId].data[4]].data0 = 3; + gSprites[gTasks[taskId].data[5]].data0 = 3; + spriteId = CreateSprite(&gSpriteTemplate_840B1F4, 0x78, 0x50, 15); + gSprites[spriteId].invisible = 1; + } + if (gIntroFrameCounter == 800) + PlaySE(SE_OP_BASYU); + if (gIntroFrameCounter == 850) + BeginNormalPaletteFade(0xFFFFFFFF, 4, 0, 0x10, 0xFFFF); + if (gIntroFrameCounter == 946) + gTasks[taskId].func = task_intro_19; +} + +static void task_intro_19(u8 taskId) +{ + DestroyTask(taskId); + SetMainCallback2(MainCB2_EndIntro); +} + +static void task_intro_20(u8 taskId) +{ + gTasks[taskId].data[15]++; + switch (gTasks[taskId].data[0]) + { + case 0: + REG_DISPCNT = 0x3940; + REG_BG2CNT = 0; + gTasks[taskId].data[0] = 0xFF; + break; + case 2: + BeginNormalPaletteFade(1, 0, 0x10, 0, 0xFFFF); + REG_BG2CNT = 0x0E07; + REG_DISPCNT = 0x3D40; + gTasks[taskId].data[1] = 0; + gTasks[taskId].data[2] = 0; + gTasks[taskId].data[0] = 20; + //fall through + case 20: + REG_BG2VOFS = gTasks[taskId].data[1]; + REG_BG2HOFS = gTasks[taskId].data[2]; + gTasks[taskId].data[1] += 6; + gTasks[taskId].data[2] -= 8; + break; + case 3: + BeginNormalPaletteFade(1, 0, 0x10, 0, 0xFFFF); + REG_BG2CNT = 0x0E07; + REG_DISPCNT = 0x3D40; + gTasks[taskId].data[1] = 0; + gTasks[taskId].data[2] = 0; + gTasks[taskId].data[0] = 0x1E; + //fall through + case 0x1E: + REG_BG2VOFS = gTasks[taskId].data[1]; + REG_BG2HOFS = gTasks[taskId].data[2]; + gTasks[taskId].data[1] -= 6; + gTasks[taskId].data[2] += 8; + break; + case 4: + BeginNormalPaletteFade(1, 5, 0, 0x10, 0x37F7); + REG_BG2CNT = 0x0E07; + REG_DISPCNT = 0x3D40; + gTasks[taskId].data[1] = 0; + gTasks[taskId].data[2] = 0; + gTasks[taskId].data[3] = 8; + gTasks[taskId].data[0] = 0x28; + //fall through + case 0x28: + REG_BG2VOFS = gTasks[taskId].data[1]; + REG_BG2HOFS = gTasks[taskId].data[2]; + gTasks[taskId].data[1] -= gTasks[taskId].data[3]; + gTasks[taskId].data[2] += gTasks[taskId].data[3]; + if (!(gTasks[taskId].data[15] & 7) && gTasks[taskId].data[3] != 0) + gTasks[taskId].data[3]--; + break; + case 0xFF: //needed to prevent jump table optimization + break; + } +} + +static void intro_reset_and_hide_bgs(void) +{ + REG_DISPCNT = 0; + REG_BG3HOFS = 0; + REG_BG3VOFS = 0; + REG_BG2HOFS = 0; + REG_BG2VOFS = 0; + REG_BG1HOFS = 0; + REG_BG1VOFS = 0; + REG_BG0HOFS = 0; + REG_BG0VOFS = 0; + REG_BLDCNT = 0; + REG_BLDALPHA = 0; + REG_BLDY = 0; +} + +#ifdef NONMATCHING +static void sub_813CCE8(u8 taskId) +{ + switch (gTasks[taskId].data[0]) + { + default: + case 0: + REG_BLDCNT = 0x3F50; + REG_BLDALPHA = 0x1000; + REG_BLDY = 0; + gTasks[taskId].data[1] = 0x40; + gTasks[taskId].data[0] = 1; + return; + case 1: + if (gTasks[taskId].data[1] != 0) + { + u32 foo; + u32 bar asm("r2"); + + gTasks[taskId].data[1]--; + //tail merge at _0813CDC2 + foo = gTasks[taskId].data[1] + (gTasks[taskId].data[1] < 0); + bar = 0x1FE; + REG_BLDALPHA = gUnknown_08393E64[(foo & bar) / 2]; + } + else + { + REG_BLDALPHA = gUnknown_08393E64[0]; + gTasks[taskId].data[1] = 0x80; + gTasks[taskId].data[0]++; + } + return; + case 2: + if (gTasks[taskId].data[1] != 0) + { + //tail merge at _0813CE0E + gTasks[taskId].data[1]--; + } + else + { + gTasks[taskId].data[1] = 0; //redundant? + gTasks[taskId].data[0]++; + } + return; + case 3: + if (gTasks[taskId].data[1] <= 0x3D) + { + u32 foo; + u32 bar asm("r2"); + + gTasks[taskId].data[1]++; + //_0813CDC2 + foo = gTasks[taskId].data[1] + (gTasks[taskId].data[1] < 0); + bar = 0x1FE; + REG_BLDALPHA = gUnknown_08393E64[(foo & bar) / 2]; + } + else + { + //_0813CDE0 + REG_BLDALPHA = gUnknown_08393E64[0x1F]; + gTasks[taskId].data[1] = 0x10; + gTasks[taskId].data[0]++; + } + return; + case 4: + if (gTasks[taskId].data[1] != 0) + { + gTasks[taskId].data[1]--; + } + else + { + REG_BLDCNT = 0; + REG_BLDALPHA = 0; + REG_BLDY = 0; + DestroyTask(taskId); + } + return; + } +} +#else +__attribute__((naked)) +static void sub_813CCE8(u8 taskId) +{ + asm("\n\ + .equ REG_BLDCNT, 0x4000050\n\ + .equ REG_BLDALPHA, 0x4000052\n\ + .syntax unified\n\ + push {r4,lr}\n\ + lsls r0, 24\n\ + lsrs r3, r0, 24\n\ + ldr r1, _0813CD0C @ =gTasks\n\ + lsls r0, r3, 2\n\ + adds r0, r3\n\ + lsls r0, 3\n\ + adds r0, r1\n\ + movs r2, 0x8\n\ + ldrsh r0, [r0, r2]\n\ + adds r2, r1, 0\n\ + cmp r0, 0x4\n\ + bhi _0813CD28\n\ + lsls r0, 2\n\ + ldr r1, _0813CD10 @ =_0813CD14\n\ + adds r0, r1\n\ + ldr r0, [r0]\n\ + mov pc, r0\n\ + .align 2, 0\n\ +_0813CD0C: .4byte gTasks\n\ +_0813CD10: .4byte _0813CD14\n\ + .align 2, 0\n\ +_0813CD14:\n\ + .4byte _0813CD28\n\ + .4byte _0813CD5C\n\ + .4byte _0813CD8C\n\ + .4byte _0813CDA8\n\ + .4byte _0813CDFC\n\ +_0813CD28:\n\ + ldr r1, _0813CD54 @ =REG_BLDCNT\n\ + ldr r4, _0813CD58 @ =0x00003f50\n\ + adds r0, r4, 0\n\ + strh r0, [r1]\n\ + adds r1, 0x2\n\ + movs r4, 0x80\n\ + lsls r4, 5\n\ + adds r0, r4, 0\n\ + strh r0, [r1]\n\ + adds r1, 0x2\n\ + movs r0, 0\n\ + strh r0, [r1]\n\ + lsls r0, r3, 2\n\ + adds r0, r3\n\ + lsls r0, 3\n\ + adds r0, r2\n\ + movs r1, 0x40\n\ + strh r1, [r0, 0xA]\n\ + movs r1, 0x1\n\ + strh r1, [r0, 0x8]\n\ + b _0813CE26\n\ + .align 2, 0\n\ +_0813CD54: .4byte REG_BLDCNT\n\ +_0813CD58: .4byte 0x00003f50\n\ +_0813CD5C:\n\ + lsls r0, r3, 2\n\ + adds r0, r3\n\ + lsls r0, 3\n\ + adds r2, r0, r2\n\ + ldrh r1, [r2, 0xA]\n\ + movs r3, 0xA\n\ + ldrsh r0, [r2, r3]\n\ + cmp r0, 0\n\ + beq _0813CD78\n\ + subs r0, r1, 0x1\n\ + strh r0, [r2, 0xA]\n\ + movs r4, 0xA\n\ + ldrsh r0, [r2, r4]\n\ + b _0813CDC2\n\ +_0813CD78:\n\ + ldr r1, _0813CD84 @ =REG_BLDALPHA\n\ + ldr r0, _0813CD88 @ =gUnknown_08393E64\n\ + ldrh r0, [r0]\n\ + strh r0, [r1]\n\ + movs r0, 0x80\n\ + b _0813CDEA\n\ + .align 2, 0\n\ +_0813CD84: .4byte REG_BLDALPHA\n\ +_0813CD88: .4byte gUnknown_08393E64\n\ +_0813CD8C:\n\ + lsls r0, r3, 2\n\ + adds r0, r3\n\ + lsls r0, 3\n\ + adds r1, r0, r2\n\ + ldrh r0, [r1, 0xA]\n\ + movs r3, 0xA\n\ + ldrsh r2, [r1, r3]\n\ + cmp r2, 0\n\ + bne _0813CE0E\n\ + strh r2, [r1, 0xA]\n\ + ldrh r0, [r1, 0x8]\n\ + adds r0, 0x1\n\ + strh r0, [r1, 0x8]\n\ + b _0813CE26\n\ +_0813CDA8:\n\ + lsls r0, r3, 2\n\ + adds r0, r3\n\ + lsls r0, 3\n\ + adds r2, r0, r2\n\ + ldrh r1, [r2, 0xA]\n\ + movs r4, 0xA\n\ + ldrsh r0, [r2, r4]\n\ + cmp r0, 0x3D\n\ + bgt _0813CDE0\n\ + adds r0, r1, 0x1\n\ + strh r0, [r2, 0xA]\n\ + movs r1, 0xA\n\ + ldrsh r0, [r2, r1]\n\ +_0813CDC2:\n\ + lsrs r1, r0, 31\n\ + adds r0, r1\n\ + movs r2, 0xFF\n\ + lsls r2, 1\n\ + ldr r3, _0813CDD8 @ =REG_BLDALPHA\n\ + ldr r1, _0813CDDC @ =gUnknown_08393E64\n\ + ands r0, r2\n\ + adds r0, r1\n\ + ldrh r0, [r0]\n\ + strh r0, [r3]\n\ + b _0813CE26\n\ + .align 2, 0\n\ +_0813CDD8: .4byte REG_BLDALPHA\n\ +_0813CDDC: .4byte gUnknown_08393E64\n\ +_0813CDE0:\n\ + ldr r1, _0813CDF4 @ =REG_BLDALPHA\n\ + ldr r0, _0813CDF8 @ =gUnknown_08393E64\n\ + ldrh r0, [r0, 0x3E]\n\ + strh r0, [r1]\n\ + movs r0, 0x10\n\ +_0813CDEA:\n\ + strh r0, [r2, 0xA]\n\ + ldrh r0, [r2, 0x8]\n\ + adds r0, 0x1\n\ + strh r0, [r2, 0x8]\n\ + b _0813CE26\n\ + .align 2, 0\n\ +_0813CDF4: .4byte REG_BLDALPHA\n\ +_0813CDF8: .4byte gUnknown_08393E64\n\ +_0813CDFC:\n\ + lsls r0, r3, 2\n\ + adds r0, r3\n\ + lsls r0, 3\n\ + adds r1, r0, r2\n\ + ldrh r0, [r1, 0xA]\n\ + movs r4, 0xA\n\ + ldrsh r2, [r1, r4]\n\ + cmp r2, 0\n\ + beq _0813CE14\n\ +_0813CE0E:\n\ + subs r0, 0x1\n\ + strh r0, [r1, 0xA]\n\ + b _0813CE26\n\ +_0813CE14:\n\ + ldr r0, _0813CE2C @ =REG_BLDCNT\n\ + strh r2, [r0]\n\ + adds r0, 0x2\n\ + strh r2, [r0]\n\ + adds r0, 0x2\n\ + strh r2, [r0]\n\ + adds r0, r3, 0\n\ + bl DestroyTask\n\ +_0813CE26:\n\ + pop {r4}\n\ + pop {r0}\n\ + bx r0\n\ + .align 2, 0\n\ +_0813CE2C: .4byte REG_BLDCNT\n\ + .syntax divided\n"); +} +#endif + +void sub_813CE30(u16 scrX, u16 scrY, u16 zoom, u16 alpha) +{ + struct BgAffineSrcData src; + struct BgAffineDstData dest; + + src.texX = 0x8000; + src.texY = 0x8000; + src.scrX = scrX; + src.scrY = scrY; + src.sx = zoom; + src.sy = zoom; + src.alpha = alpha; + BgAffineSet(&src, &dest, 1); + REG_BG2PA = dest.pa; + REG_BG2PB = dest.pb; + REG_BG2PC = dest.pc; + REG_BG2PD = dest.pd; + REG_BG2X = dest.dx; + REG_BG2Y = dest.dy; +} + +static u16 sub_813CE88(u16 species, s16 x, s16 y, u16 d, u8 front) +{ + void *pal; + u8 spriteId; + + if (front) + LoadSpecialPokePic(&gMonFrontPicTable[species], gMonFrontPicCoords[species].x, gMonFrontPicCoords[species].y, 0x2000000, gUnknown_0840B5A0[d], species, 0, 1); + else + LoadSpecialPokePic(&gMonBackPicTable[species], gMonBackPicCoords[species].x, gMonBackPicCoords[species].y, 0x2000000, gUnknown_0840B5A0[d], species, 0, 0); + pal = species_and_otid_get_pal(species, 0, 0xFFFF); + LoadCompressedPalette(pal, 0x100 + d * 0x10, 0x20); + sub_8143648(d, d); + spriteId = CreateSprite(&gUnknown_02024E8C, x, y, (d + 1) * 4); + gSprites[spriteId].oam.paletteNum = d; + gSprites[spriteId].oam.priority = 1; + return spriteId; +} + +static u8 sub_813CFA8(u16 a, u16 b, u16 c, u16 d) +{ + u8 spriteId; + + DecompressPicFromTable_2(&gTrainerBackPicTable[a], gTrainerBackPicCoords[a].x, gTrainerBackPicCoords[a].y, (void *)0x2000000, gUnknown_0840B5A0[d], a); + LoadCompressedPalette(gTrainerBackPicPaletteTable[a].data, 0x100 + d * 0x10, 0x20); + sub_8143680(d, d); + gUnknown_02024E8C.anims = gUnknown_0840B064; + spriteId = CreateSprite(&gUnknown_02024E8C, b, c, 1); + gSprites[spriteId].oam.paletteNum = d; + gSprites[spriteId].oam.priority = 1; + return spriteId; +} + +static void sub_813D084(u8 a) +{ + u16 color; + + switch (a) + { + default: + case 0: + color = RGB(22, 31, 15); + break; + case 1: + color = RGB(31, 14, 12); + break; + case 2: + color = RGB(12, 12, 20); + break; + } + gPlttBufferUnfaded[241] = color; + gPlttBufferFaded[241] = color; +} + +void sub_813D0CC(struct Sprite *sprite) +{ + u8 r0; + + if (sprite->data2 >= 192) + { + if (sprite->data3 != 0) + { + sprite->data3--; + } + else + { + sprite->invisible = FALSE; + SetOamMatrix(sprite->data1, sprite->data2, 0, 0, sprite->data2); + sprite->data2 = (sprite->data2 * 95) / 100; + r0 = (sprite->data2 - 192) / 128 + 9; + if (r0 > 15) + r0 = 15; + sprite->oam.paletteNum = r0; + } + } + else + { + DestroySprite(sprite); + } +} + +void sub_813D158(struct Sprite *sprite) +{ + if (gSprites[sprite->data7].data7 != 0) + { + sprite->invisible = TRUE; + sprite->pos1.x += sprite->pos2.x; + sprite->pos1.y += sprite->pos2.y; + StartSpriteAnim(sprite, 3); + sprite->data2 = 1024; + sprite->data3 = 8 * (sprite->data1 & 3); + sprite->callback = sub_813D0CC; + sprite->oam.shape = 1; + sprite->oam.size = 3; + CalcCenterToCornerVec(sprite, 1, 3, 2); + } + else + { + sprite->pos2.x = gSprites[sprite->data7].pos2.x; + sprite->pos2.y = gSprites[sprite->data7].pos2.y; + sprite->pos1.x = gSprites[sprite->data7].pos1.x; + sprite->pos1.y = gSprites[sprite->data7].pos1.y; + } +} + +void sub_813D208(struct Sprite *sprite) +{ + if (sprite->data0 != 0) + sprite->callback = sub_813D220; +} + +void sub_813D220(struct Sprite *sprite) +{ + if (sprite->pos1.x <= 116) + { + sprite->pos1.y += sprite->pos2.y; + sprite->pos2.y = 0; + sprite->pos1.x += 4; + sprite->pos2.x = -4; + sprite->data4 = 128; + sprite->callback = sub_813D368; + } + else + { + u16 data2; + u16 data3; + u16 data4; + s16 sin1; + s16 sin2; + s16 sin3; + s16 sin4; + s16 var1; + s16 var2; + s16 var3; + s16 var4; + s16 temp; + + data4 = sprite->data4; + sin1 = gSineTable[(u8)data4]; + sin2 = gSineTable[(u8)(data4 + 64)]; + sprite->data4 += 2; + sprite->pos2.y = sin1 / 32; + sprite->pos1.x--; + if (sprite->pos1.x & 1) + sprite->pos1.y++; + temp = -sin2 / 16; + data2 = sprite->data2; + data3 = sprite->data3; + sin3 = gSineTable[(u8)(temp - 16)]; + sin4 = gSineTable[(u8)(temp + 48)]; + var1 = sin4 * data2 / 256; + var2 = -sin3 * data3 / 256; + var3 = sin3 * data2 / 256; + var4 = sin4 * data3 / 256; + SetOamMatrix(sprite->data1, data2, 0, 0, data3); + SetOamMatrix(sprite->data1 + 1, var1, var3, var2, var4); + SetOamMatrix(sprite->data1 + 2, var1, var3, var2 * 2, var4 * 2); + } +} + +void sub_813D368(struct Sprite *sprite) +{ + SetOamMatrix(sprite->data1, sprite->data6 + 64, 0, 0, sprite->data6 + 64); + SetOamMatrix(sprite->data1 + 1, sprite->data6 + 64, 0, 0, sprite->data6 + 64); + SetOamMatrix(sprite->data1 + 2, sprite->data6 + 64, 0, 0, sprite->data6 + 64); + if (sprite->data4 != 64) + { + u16 data4; + + sprite->data4 -= 8; + data4 = sprite->data4; + sprite->pos2.x = gSineTable[(u8)(data4 + 64)] / 64; + sprite->pos2.y = gSineTable[(u8)data4] / 64; + } + else + { + sprite->data4 = 0; + sprite->callback = sub_813D414; + } +} + +void sub_813D414(struct Sprite *sprite) +{ + if (sprite->data0 != 2) + { + s16 r2; + + sprite->data4 += 8; + r2 = gSineTable[(u8)sprite->data4] / 16 + 64; + sprite->pos2.x = gSineTable[(u8)(r2 + 64)] / 64; + sprite->pos2.y = gSineTable[(u8)r2] / 64; + } + else + { + sprite->callback = SpriteCB_WaterDropFall; + } +} + +void SpriteCB_WaterDropFall(struct Sprite *sprite) +{ + if (sprite->pos1.y < sprite->data5) + { + sprite->pos1.y += 4; + } + else + { + sprite->data7 = 1; + sprite->invisible = TRUE; + sprite->pos1.x += sprite->pos2.x; + sprite->pos1.y += sprite->pos2.y; + StartSpriteAnim(sprite, 3); + sprite->data2 = 1024; + sprite->data3 = 8 * (sprite->data1 & 3); + sprite->callback = sub_813D0CC; + sprite->oam.shape = 1; + sprite->oam.size = 3; + CalcCenterToCornerVec(sprite, 1, 3, 2); + } +} + +//Duplicate function +void SpriteCB_WaterDropFall_2(struct Sprite *sprite) +{ + if (sprite->pos1.y < sprite->data5) + { + sprite->pos1.y += 4; + } + else + { + sprite->data7 = 1; + sprite->invisible = TRUE; + sprite->pos1.x += sprite->pos2.x; + sprite->pos1.y += sprite->pos2.y; + StartSpriteAnim(sprite, 3); + sprite->data2 = 1024; + sprite->data3 = 8 * (sprite->data1 & 3); + sprite->callback = sub_813D0CC; + sprite->oam.shape = 1; + sprite->oam.size = 3; + CalcCenterToCornerVec(sprite, 1, 3, 2); + } +} + +static u8 CreateWaterDrop(s16 x, s16 y, u16 c, u16 d, u16 e, u8 fallImmediately) +{ + u8 spriteId; + u8 oldSpriteId; + + spriteId = CreateSprite(&gSpriteTemplate_840AE20, x, y, 0); + gSprites[spriteId].data0 = 0; + gSprites[spriteId].data7 = 0; + gSprites[spriteId].data1 = d; + gSprites[spriteId].data2 = c; + gSprites[spriteId].data3 = c; + gSprites[spriteId].data5 = e; + gSprites[spriteId].data6 = c; + gSprites[spriteId].oam.affineMode = 3; + gSprites[spriteId].oam.matrixNum = d; + CalcCenterToCornerVec(&gSprites[spriteId], 0, 2, 2); + StartSpriteAnim(&gSprites[spriteId], 2); + if (!fallImmediately) + gSprites[spriteId].callback = sub_813D208; + else + gSprites[spriteId].callback = SpriteCB_WaterDropFall_2; + oldSpriteId = spriteId; + + spriteId = CreateSprite(&gSpriteTemplate_840AE20, x, y, 0); + gSprites[spriteId].data7 = oldSpriteId; + gSprites[spriteId].data1 = d + 1; + gSprites[spriteId].oam.affineMode = 3; + gSprites[spriteId].oam.matrixNum = d + 1; + CalcCenterToCornerVec(&gSprites[spriteId], 0, 2, 2); + gSprites[spriteId].callback = sub_813D158; + + spriteId = CreateSprite(&gSpriteTemplate_840AE20, x, y, 0); + gSprites[spriteId].data7 = oldSpriteId; + gSprites[spriteId].data1 = d + 2; + StartSpriteAnim(&gSprites[spriteId], 1); + gSprites[spriteId].oam.affineMode = 3; + gSprites[spriteId].oam.matrixNum = d + 2; + CalcCenterToCornerVec(&gSprites[spriteId], 0, 2, 2); + gSprites[spriteId].callback = sub_813D158; + + SetOamMatrix(d, c + 32, 0, 0, c + 32); + SetOamMatrix(d + 1, c + 32, 0, 0, c + 32); + SetOamMatrix(d + 2, c + 32, 0, 0, 2 * (c + 32)); + + return oldSpriteId; +} + +void sub_813D788(struct Sprite *sprite) +{ + switch (sprite->data0) + { + case 0: + StartSpriteAnimIfDifferent(sprite, 0); + sprite->pos1.x--; + break; + case 1: + StartSpriteAnimIfDifferent(sprite, 0); + if (gIntroFrameCounter & 7) + return; + sprite->pos1.x++; + break; + case 2: + StartSpriteAnimIfDifferent(sprite, 2); + if (sprite->pos1.x <= 120 || (gIntroFrameCounter & 7)) + sprite->pos1.x++; + break; + case 3: + StartSpriteAnimIfDifferent(sprite, 3); + break; + case 4: + StartSpriteAnimIfDifferent(sprite, 0); + if (sprite->pos1.x > -32) + sprite->pos1.x -= 2; + break; + } + if (gIntroFrameCounter & 7) + return; + if (sprite->pos2.y != 0) + { + sprite->pos2.y = 0; + } + else + { + switch (Random() & 3) + { + case 0: + sprite->pos2.y = -1; + break; + case 1: + sprite->pos2.y = 1; + break; + case 2: + case 3: + sprite->pos2.y = 0; + break; + } + } +} + +void sub_813D880(struct Sprite *sprite) +{ + switch (sprite->data0) + { + case 0: + break; + case 1: + if (sprite->pos2.x + sprite->pos1.x < 304) + sprite->pos2.x += 8; + else + sprite->data0 = 2; + break; + case 2: + if (sprite->pos2.x + sprite->pos1.x > 120) + sprite->pos2.x -= 1; + else + sprite->data0 = 3; + break; + case 3: + if (sprite->pos2.x > 0) + sprite->pos2.x -= 2; + break; + } + sprite->pos2.y = Sin((u8)sprite->data1, 8) - gUnknown_0203935A; + sprite->data1 += 4; +} + +void sub_813D908(struct Sprite *sprite) +{ + if (gTasks[sprite->data0].data[0] == 0) + { + sprite->invisible = TRUE; + } + else if (gTasks[sprite->data0].data[0] != 4) + { + sprite->invisible = FALSE; + } + else + { + DestroySprite(sprite); + } +} + +static u8 CreateGameFreakLogo(s16 a, s16 b, u8 c) +{ + u8 spriteId; + u16 i; + + for (i = 0; i < 9; i++) + { + spriteId = CreateSprite(&gSpriteTemplate_840AF94, gUnknown_0840AF50[i][1] + a, b - 4, 0); + gSprites[spriteId].data0 = c; + StartSpriteAnim(&gSprites[spriteId], gUnknown_0840AF50[i][0]); + } + for (i = 0; i < 8; i++) + { + spriteId = CreateSprite(&gSpriteTemplate_840AFAC, gUnknown_0840AF74[i][1] + a, b + 12, 0); + gSprites[spriteId].data0 = c; + StartSpriteAnim(&gSprites[spriteId], gUnknown_0840AF74[i][0]); + } + spriteId = CreateSprite(&gSpriteTemplate_840AFC4, 120, b - 4, 0); + gSprites[spriteId].data0 = c; + + return spriteId; +} + +#ifdef NONMATCHING +void sub_813DA64(struct Sprite *sprite) +{ + sprite->data7++; + + switch(sprite->data0) + { + case 0: + default: + sprite->oam.affineMode = 3; + sprite->oam.matrixNum = 1; + CalcCenterToCornerVec(sprite, 1, 3, 3); + sprite->invisible = FALSE; + sprite->data0 = 1; + sprite->data1 = 128; + sprite->data2 = -24; + sprite->data3 = 0; + break; + case 1: + { + s16 r3; + s16 sin1; + s16 r6; + s16 foo; + s16 r5; + s16 r2; + + //_0813DAC0 + if (sprite->data3 < 0x50) + { + sprite->pos2.y = -Sin((u8)sprite->data3, 0x78); + sprite->pos2.x = -Sin((u8)sprite->data3, 0x8C); + if (sprite->data3 > 64) + sprite->oam.priority = 3; + } + //_0813DAF8 + r3 = gSineTable[(u8)sprite->data2]; + sin1 = gSineTable[(u8)(sprite->data2 + 64)]; + r6 = sin1 * sprite->data1 / 256; + foo = sin1 * sprite->data1 / 256; + r5 = -r3 * sprite->data1 / 256; + r2 = r3 * sprite->data1 / 256; + + SetOamMatrix(1, r6, r2, r5, foo); + + if (sprite->data1 < 0x100) + sprite->data1 += 8; + else + sprite->data1 += 32; + if (sprite->data2 < 0x18) + sprite->data2 += 1; + if (sprite->data3 < 64) + sprite->data3 += 2; + else if (!(sprite->data7 & 3)) + sprite->data3 += 1; + break; + } + } + //_0813DB92 +} +#else +__attribute__((naked)) +void sub_813DA64(struct Sprite *sprite) +{ + asm(".syntax unified\n\ + push {r4-r6,lr}\n\ + sub sp, 0x4\n\ + adds r4, r0, 0\n\ + ldrh r0, [r4, 0x3C]\n\ + adds r0, 0x1\n\ + strh r0, [r4, 0x3C]\n\ + movs r1, 0x2E\n\ + ldrsh r0, [r4, r1]\n\ + cmp r0, 0\n\ + beq _0813DA7C\n\ + cmp r0, 0x1\n\ + beq _0813DAC0\n\ +_0813DA7C:\n\ + ldrb r0, [r4, 0x1]\n\ + movs r1, 0x3\n\ + orrs r0, r1\n\ + strb r0, [r4, 0x1]\n\ + ldrb r1, [r4, 0x3]\n\ + movs r0, 0x3F\n\ + negs r0, r0\n\ + ands r0, r1\n\ + movs r1, 0x2\n\ + orrs r0, r1\n\ + strb r0, [r4, 0x3]\n\ + adds r0, r4, 0\n\ + movs r1, 0x1\n\ + movs r2, 0x3\n\ + movs r3, 0x3\n\ + bl CalcCenterToCornerVec\n\ + adds r2, r4, 0\n\ + adds r2, 0x3E\n\ + ldrb r1, [r2]\n\ + movs r0, 0x5\n\ + negs r0, r0\n\ + ands r0, r1\n\ + strb r0, [r2]\n\ + movs r0, 0x1\n\ + strh r0, [r4, 0x2E]\n\ + movs r0, 0x80\n\ + strh r0, [r4, 0x30]\n\ + ldr r0, _0813DABC @ =0x0000ffe8\n\ + strh r0, [r4, 0x32]\n\ + movs r0, 0\n\ + b _0813DB92\n\ + .align 2, 0\n\ +_0813DABC: .4byte 0x0000ffe8\n\ +_0813DAC0:\n\ + ldrh r1, [r4, 0x34]\n\ + movs r2, 0x34\n\ + ldrsh r0, [r4, r2]\n\ + cmp r0, 0x4F\n\ + bgt _0813DAF8\n\ + lsls r0, r1, 24\n\ + lsrs r0, 24\n\ + movs r1, 0x78\n\ + bl Sin\n\ + negs r0, r0\n\ + strh r0, [r4, 0x26]\n\ + ldrh r0, [r4, 0x34]\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + movs r1, 0x8C\n\ + bl Sin\n\ + negs r0, r0\n\ + strh r0, [r4, 0x24]\n\ + movs r1, 0x34\n\ + ldrsh r0, [r4, r1]\n\ + cmp r0, 0x40\n\ + ble _0813DAF8\n\ + ldrb r0, [r4, 0x5]\n\ + movs r1, 0xC\n\ + orrs r0, r1\n\ + strb r0, [r4, 0x5]\n\ +_0813DAF8:\n\ + ldr r2, _0813DB60 @ =gSineTable\n\ + ldrh r1, [r4, 0x32]\n\ + lsls r0, r1, 24\n\ + lsrs r0, 23\n\ + adds r0, r2\n\ + ldrh r3, [r0]\n\ + adds r1, 0x40\n\ + lsls r1, 24\n\ + lsrs r1, 23\n\ + adds r1, r2\n\ + movs r2, 0\n\ + ldrsh r0, [r1, r2]\n\ + movs r1, 0x30\n\ + ldrsh r2, [r4, r1]\n\ + adds r1, r0, 0\n\ + muls r1, r2\n\ + adds r0, r1, 0\n\ + cmp r1, 0\n\ + bge _0813DB20\n\ + adds r0, 0xFF\n\ +_0813DB20:\n\ + lsls r0, 8\n\ + lsrs r6, r0, 16\n\ + lsls r0, r3, 16\n\ + asrs r3, r0, 16\n\ + negs r0, r3\n\ + muls r0, r2\n\ + cmp r0, 0\n\ + bge _0813DB32\n\ + adds r0, 0xFF\n\ +_0813DB32:\n\ + lsls r0, 8\n\ + lsrs r5, r0, 16\n\ + adds r0, r3, 0\n\ + muls r0, r2\n\ + cmp r0, 0\n\ + bge _0813DB40\n\ + adds r0, 0xFF\n\ +_0813DB40:\n\ + lsls r0, 8\n\ + lsrs r2, r0, 16\n\ + adds r1, r6, 0\n\ + adds r3, r5, 0\n\ + str r1, [sp]\n\ + movs r0, 0x1\n\ + bl SetOamMatrix\n\ + ldrh r1, [r4, 0x30]\n\ + movs r2, 0x30\n\ + ldrsh r0, [r4, r2]\n\ + cmp r0, 0xFF\n\ + bgt _0813DB64\n\ + adds r0, r1, 0\n\ + adds r0, 0x8\n\ + b _0813DB68\n\ + .align 2, 0\n\ +_0813DB60: .4byte gSineTable\n\ +_0813DB64:\n\ + adds r0, r1, 0\n\ + adds r0, 0x20\n\ +_0813DB68:\n\ + strh r0, [r4, 0x30]\n\ + ldrh r1, [r4, 0x32]\n\ + movs r2, 0x32\n\ + ldrsh r0, [r4, r2]\n\ + cmp r0, 0x17\n\ + bgt _0813DB78\n\ + adds r0, r1, 0x1\n\ + strh r0, [r4, 0x32]\n\ +_0813DB78:\n\ + ldrh r2, [r4, 0x34]\n\ + movs r1, 0x34\n\ + ldrsh r0, [r4, r1]\n\ + cmp r0, 0x3F\n\ + bgt _0813DB86\n\ + adds r0, r2, 0x2\n\ + b _0813DB92\n\ +_0813DB86:\n\ + ldrh r1, [r4, 0x3C]\n\ + movs r0, 0x3\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + bne _0813DB94\n\ + adds r0, r2, 0x1\n\ +_0813DB92:\n\ + strh r0, [r4, 0x34]\n\ +_0813DB94:\n\ + add sp, 0x4\n\ + pop {r4-r6}\n\ + pop {r0}\n\ + bx r0\n\ + .syntax divided\n"); +} +#endif + +void sub_813DB9C(struct Sprite *sprite) +{ + switch (sprite->data0) + { + case 0: + default: + if (sprite->data2 != 0) + sprite->hFlip = TRUE; + else + sprite->hFlip = FALSE; + sprite->data0 = 1; + //fall through + case 1: + if (sprite->pos1.y > 96) + { + sprite->pos1.y -= 4; + if (sprite->data2 != 0) + sprite->pos1.x += 2; + else + sprite->pos1.x -= 2; + } + else + { + sprite->data0++; + sprite->data3 = 8; + } + break; + case 2: + if (sprite->data3 != 0) + { + sprite->data3--; + } + else + { + sprite->data0++; + sprite->data3 = 0; //redundant? + } + break; + case 3: + sprite->oam.affineMode = 3; + sprite->oam.matrixNum = sprite->data1; + CalcCenterToCornerVec(sprite, 0, 3, 3); + if (sprite->data2 != 0) + SetOamMatrix(sprite->data1, -256, 0, 0, 256); + else + SetOamMatrix(sprite->data1, 256, 0, 0, 256); + sprite->data0++; + sprite->data4 = 0; + break; + case 4: + sprite->data4++; + if (sprite->pos1.y + sprite->pos2.y > -32 + && sprite->pos1.x + sprite->pos2.x > -64) + { + u16 r2; + + sprite->pos2.y = -(sprite->data4 * sprite->data4) / 8; + if (sprite->data2 != 0) + sprite->pos2.x += sprite->data4; + else + sprite->pos2.x -= sprite->data4; + if (sprite->data3 < 128) + sprite->data3 += 8; + r2 = 256 - sprite->data3; + if (sprite->data2 != 0) + SetOamMatrix(sprite->data1, -r2, 0, 0, r2); + else + SetOamMatrix(sprite->data1, r2, 0, 0, r2); + } + else + { + DestroySprite(sprite); + } + } +} + +void sub_813DD58(struct Sprite *sprite) +{ + switch (sprite->data0) + { + case 0: + default: + sprite->invisible = FALSE; + sprite->oam.affineMode = 1; + sprite->oam.matrixNum = sprite->data1; + sprite->data3 = 2048; + sprite->data0 = 1; + //fall through + case 1: + if (sprite->data3 > 256) + { + sprite->data3 -= 128; + if (sprite->data2 != 0) + SetOamMatrix(sprite->data1, -sprite->data3, 0, 0, sprite->data3); + else + SetOamMatrix(sprite->data1, sprite->data3, 0, 0, sprite->data3); + } + else + { + if (sprite->data2 != 0) + SetOamMatrix(sprite->data1, -256, 0, 0, 256); + else + SetOamMatrix(sprite->data1, 256, 0, 0, 256); + sprite->data0++; + } + break; + case 2: + break; + case 3: + sprite->data4++; + sprite->pos2.y = sprite->data4 * sprite->data4 / 32; + if (sprite->data2 != 0) + sprite->pos2.x = sprite->data4 / 4; + else + sprite->pos2.x = -(sprite->data4 / 4); + break; + } +} + +void sub_813DE70(struct Sprite *sprite) +{ + switch (sprite->data0) + { + case 0: + default: + if (sprite->pos1.x > 40) + { + sprite->pos1.x -= 4; + } + else + { + StartSpriteAnim(sprite, 1); + sprite->data6 = CreateSprite(&gSpriteTemplate_840B084, 16, 104, 100); + sprite->data7 = CreateSprite(&gSpriteTemplate_840B084, 12, 106, 101); + sprite->data0 = 1; + } + break; + case 1: + break; + case 2: + StartSpriteAnim(sprite, 2); + gSprites[sprite->data6].data0 = 1; + gSprites[sprite->data7].data0 = 2; + sprite->data0++; + break; + case 3: + if (sprite->pos1.y > 160) + { + sprite->invisible = 1; + sprite->data0 = 1; + } + else + { + sprite->pos1.y += 2; + sprite->pos1.x--; + } + break; + case 4: + { + s16 r4, r5; + + r5 = gSprites[sprite->data6].pos1.x + gSprites[sprite->data6].pos2.x; + r4 = gSprites[sprite->data6].pos1.y + gSprites[sprite->data6].pos2.y; + DestroySprite(&gSprites[sprite->data6]); + sprite->data6 = sub_813CE88(SPECIES_TORCHIC, r5, r4, 2, 1); + gSprites[sprite->data6].callback = sub_813DD58; + gSprites[sprite->data6].invisible = TRUE; + gSprites[sprite->data6].data1 = 1; + gSprites[sprite->data6].data2 = 1; + sub_813E580(r5, r4); + + r5 = gSprites[sprite->data7].pos1.x + gSprites[sprite->data7].pos2.x; + r4 = gSprites[sprite->data7].pos1.y + gSprites[sprite->data7].pos2.y; + DestroySprite(&gSprites[sprite->data7]); + sprite->data7 = sub_813CE88(SPECIES_MUDKIP, r5, r4, 3, 1); + gSprites[sprite->data7].callback = sub_813DD58; + gSprites[sprite->data7].invisible = TRUE; + gSprites[sprite->data7].data1 = 2; + gSprites[sprite->data7].data2 = 0; + sub_813E580(r5, r4); + + BeginNormalPaletteFade(0xFF0000, 0, 16, 16, RGB(31, 23, 31)); + sprite->data0 = 1; + break; + } + case 5: + gSprites[sprite->data6].data0 = 3; + gSprites[sprite->data7].data0 = 3; + break; + case 6: + DestroySprite(&gSprites[sprite->data6]); + DestroySprite(&gSprites[sprite->data7]); + DestroySprite(sprite); + break; + } +} + +void sub_813E10C(struct Sprite *sprite) +{ + switch (sprite->data0) + { + case 0: + default: + if (sprite->pos2.x > -56) + { + sprite->pos2.x -= 8; + sprite->pos2.y += 6; + } + else + { + sprite->data6 = sprite->pos1.x; + sprite->data7 = sprite->pos1.y; + sprite->pos1.x += sprite->pos2.x; + sprite->pos1.y += sprite->pos2.y; + sprite->pos2.x = 0; + sprite->pos2.y = 0; + sprite->data0 = 1; + sprite->data1 = 0; + } + break; + case 1: + if (!(sprite->data1 & 1)) + { + if (sprite->data1 & 2) + { + sprite->pos2.x = -1; + sprite->pos2.y = 1; + } + else + { + sprite->pos2.x = 0; + sprite->pos2.y = 0; + } + } + sprite->data1++; + break; + case 2: + sprite->invisible = TRUE; + sprite->pos1.x = sprite->data6; + sprite->pos1.y = sprite->data7; + sprite->pos2.x = 0; + sprite->pos2.y = 0; + break; + case 3: + sprite->invisible = FALSE; + sprite->data1++; + //fall through + case 4: + if (sprite->pos2.x > -56) + { + sprite->pos2.x -= 4; + sprite->pos2.y += 3; + } + else + { + sprite->pos1.x += sprite->pos2.x; + sprite->pos1.y += sprite->pos2.y; + sprite->pos2.x = 0; + sprite->pos2.y = 0; + sprite->data0 = 1; + } + break; + } +} + +void sub_813E210(struct Sprite *sprite) +{ + switch (sprite->data0) + { + case 0: + default: + if (sprite->pos2.x < 56) + { + sprite->pos2.x += 8; + sprite->pos2.y -= 6; + } + else + { + sprite->data6 = sprite->pos1.x; + sprite->data7 = sprite->pos1.y; + sprite->pos1.x += sprite->pos2.x; + sprite->pos1.y += sprite->pos2.y; + sprite->pos2.x = 0; + sprite->pos2.y = 0; + sprite->data0 = 1; + sprite->data1 = 0; + } + break; + case 1: + if (!(sprite->data1 & 1)) + { + if (sprite->data1 & 2) + { + sprite->pos2.x = 1; + sprite->pos2.y = -1; + } + else + { + sprite->pos2.x = 0; + sprite->pos2.y = 0; + } + } + sprite->data1++; + break; + case 2: + sprite->invisible = TRUE; + sprite->pos1.x = sprite->data6; + sprite->pos1.y = sprite->data7; + sprite->pos2.x = 0; + sprite->pos2.y = 0; + break; + case 3: + sprite->invisible = FALSE; + sprite->data1++; + //fall through + case 4: + if (sprite->pos2.x < 56) + { + sprite->pos2.x += 4; + sprite->pos2.y -= 3; + } + else + { + sprite->pos1.x += sprite->pos2.x; + sprite->pos1.y += sprite->pos2.y; + sprite->pos2.x = 0; + sprite->pos2.y = 0; + sprite->data0 = 1; + } + break; + } +} + +void sub_813E30C(struct Sprite *sprite) +{ + u16 r4, r1; + + sprite->data7++; + switch (sprite->data0) + { + case 0: + default: + break; + case 1: + sprite->oam.affineMode = 1; + sprite->oam.matrixNum = 1; + sprite->data0 = 10; + sprite->data4 = 36; + //fall through + case 10: + if (sprite->pos1.x <= 144) + { + sprite->pos1.x += 4; + sprite->pos1.y -= 1; + sprite->pos2.y = -Sin((u8)sprite->data2, 24); + sprite->data2 += 4; + } + sprite->data3 -= sprite->data4; + if ((sprite->data7 & 1) && sprite->data4 != 0) + sprite->data4--; + r4 = gSineTable[(u8)sprite->data3]; + r1 = gSineTable[(u8)(sprite->data3 + 64)]; + SetOamMatrix(1, r1, r4, -r4, r1); + break; + case 2: + sprite->oam.affineMode = 1; + sprite->oam.matrixNum = 2; + sprite->data0 = 20; + sprite->data4 = 36; + //fall through + case 20: + if (sprite->pos1.x <= 96) + { + sprite->pos1.x += 3; + sprite->pos1.y -= 1; + sprite->pos2.y = -Sin((u8)sprite->data2, 24); + sprite->data2 += 4; + } + sprite->data3 -= sprite->data4; + if ((sprite->data7 & 1) && sprite->data4 != 0) + sprite->data4--; + r4 = gSineTable[(u8)sprite->data3]; + r1 = gSineTable[(u8)(sprite->data3 + 64)]; + SetOamMatrix(2, r1, r4, -r4, r1); + break; + } +} + +void sub_813E4B8(struct Sprite *sprite) +{ + u16 r4; + u16 r2; + u16 r1; + + sprite->data7++; + if (sprite->data7 & 1) + sprite->invisible = FALSE; + else + sprite->invisible = TRUE; + if (sprite->data2 >= 64) + { + DestroySprite(sprite); + return; + } + sprite->data2 += 2; + r4 = Sin((u8)sprite->data2, 40); + sprite->pos2.x = Cos((u8)(sprite->data0 * 32), r4); + sprite->pos2.y = Sin((u8)(sprite->data0 * 32), r4); + if (sprite->data0 == 0) + { + sprite->data3 -= sprite->data1; + if ((sprite->data7 & 1) && sprite->data1 != 0) + sprite->data1--; + r2 = gSineTable[(u8)sprite->data3]; + r1 = gSineTable[(u8)(sprite->data3 + 64)]; + SetOamMatrix(16, r1, r2, -r2, r1); + } +} + +static void sub_813E580(u16 x, u16 y) +{ + u8 i; + u8 spriteId; + + for (i = 0; i < 8; i++) + { + spriteId = CreateSprite(&gSpriteTemplate_840B0B0, x, y, 0); + gSprites[spriteId].oam.affineMode = 1; + gSprites[spriteId].oam.matrixNum = 16; + gSprites[spriteId].data0 = i; + gSprites[spriteId].data1 = 32; + } +} + +void sub_813E5E0(struct Sprite *sprite) +{ + if (gUnknown_0203931A != 0) + { + DestroySprite(sprite); + } + else + { + sprite->invisible = gSprites[sprite->data0].invisible; + if (sprite->data7 < 12) + sprite->data7++; + sprite->data6 += 4; + sprite->pos1.x = sprite->data4 + gSineTable[(u8)(sprite->data3 + 64)] * sprite->data6 / 256; + //This useless '+ 0' is needed to make the asm match + sprite->pos1.y = sprite->data5 + gSineTable[(u8)(sprite->data3 + 0)] * sprite->data6 / 256; + sprite->pos2.y = gSineTable[(u8)(sprite->data1 + 0)] * sprite->data7 / 256; + sprite->data1 += 16; + if (sprite->pos1.y > sprite->data2) + DestroySprite(sprite); + } +} + +void sub_813E6C0(struct Sprite *sprite) +{ + u8 spriteId; + u8 i; + s16 var1; + s16 var2; + + if (gUnknown_0203931A != 0) + { + DestroySprite(sprite); + } + else + { + sprite->data7++; + sprite->invisible = TRUE; + if (gSprites[sprite->data0].data0 == 1 && !(sprite->data7 & 3)) + { + var1 = sprite->data1 + gSprites[sprite->data0].pos1.x; + var2 = sprite->data2 + gSprites[sprite->data0].pos1.y; + for (i = 0; i < 3; i++) + { + u8 r3 = gSprites[sprite->data0].subpriority - 1; + //Make redundant copies of these variables to get the asm to match + s16 _var1 = var1; + s16 _var2 = var2; + + spriteId = CreateSprite(&gSpriteTemplate_840B0DC, _var1, _var2, r3); + if (spriteId != 64) + { + gSprites[spriteId].data0 = sprite->data0; + gSprites[spriteId].data1 = (((sprite->data7 >> 2) & 7) << 5) + i * 85; + gSprites[spriteId].data2 = sprite->data3; + gSprites[spriteId].data3 = 104; + gSprites[spriteId].data4 = var1; + gSprites[spriteId].data5 = var2; + gSprites[spriteId].data6 = 0; + } + } + } + } +} + +static void sub_813E7C0(u8 a) +{ + u8 spriteId; + + spriteId = CreateSprite(&gSpriteTemplate_840B0F4, 0, 0, 0); + if (spriteId != 64) + { + gSprites[spriteId].data0 = a; + gSprites[spriteId].data1 = -12; + gSprites[spriteId].data2 = 0; + gSprites[spriteId].data3 = 136; + } +} + +void sub_813E804(struct Sprite *sprite) +{ + if (gUnknown_0203931A != 0) + { + DestroySprite(sprite); + } + else + { + sprite->invisible = gSprites[sprite->data0].invisible; + sprite->data7++; + if (sprite->data3 < 40) + sprite->data3 += 2; + //This useless '+ 0' is needed to make the asm match + sprite->pos1.x = gSprites[sprite->data0].pos1.x + gSprites[sprite->data0].pos2.x + gSineTable[(u8)(sprite->data1 + 64)] * sprite->data3 / 256; + sprite->pos1.y = gSprites[sprite->data0].pos1.y + gSprites[sprite->data0].pos2.y + gSineTable[(u8)(sprite->data1 + 0)] * sprite->data3 / 512; + sprite->data1 += 2; + sprite->pos2.y = gSineTable[(u8)(sprite->data2 + 0)] / 32; + sprite->data2 += 8; + if ((sprite->data1 & 0xFF) < 128) + sprite->subpriority = gSprites[sprite->data0].subpriority - 1; + else + sprite->subpriority = gSprites[sprite->data0].subpriority + 1; + } +} + +static void sub_813E930(u8 a) +{ + u8 i; + u8 spriteId; + + for (i = 0; i < 8; i++) + { + spriteId = CreateSprite(&gSpriteTemplate_840B124, gSprites[a].pos1.x, gSprites[a].pos1.y, 0); + if (spriteId != 64) + { + gSprites[spriteId].data0 = a; + gSprites[spriteId].data1 = i * 32; + } + } +} + +void sub_813E980(struct Sprite *sprite) +{ + if (gUnknown_0203931A != 0) + { + DestroySprite(sprite); + } + else + { + u8 r0; + u16 matrixNum; + + sprite->invisible = gSprites[sprite->data0].invisible; + sprite->data7++; + sprite->data6 += 8; + sprite->pos1.x = sprite->data4 + gSineTable[(u8)(sprite->data3 + 64)] * sprite->data6 / 256; + sprite->pos1.y = sprite->data5 + gSineTable[(u8)(sprite->data3 + 0)] * sprite->data6 / 256; + r0 = sprite->data6 / 16; + if (r0 > 9) + r0 = 9; + matrixNum = (r0 + 18) & 31; + sprite->oam.matrixNum = matrixNum; + if (sprite->data6 > 160) + DestroySprite(sprite); + } +} + +void sub_813EA60(struct Sprite *sprite) +{ + bool32 r6; + s16 r1, r2; + u8 spriteId; + + if (gUnknown_0203931A != 0) + { + DestroySprite(sprite); + } + else + { + sprite->data7++; + sprite->invisible = TRUE; + if (gSprites[sprite->data0].data0 == 1) + { + r6 = (sprite->data7 & 1); + if (!r6) + { + r1 = sprite->data1 + gSprites[sprite->data0].pos1.x; + r2 = sprite->data2 + gSprites[sprite->data0].pos1.y; + spriteId = CreateSprite(&gSpriteTemplate_840B150, r1, r2, gSprites[sprite->data0].subpriority + 1); + if (spriteId != 64) + { + gSprites[spriteId].oam.affineMode = 3; + gSprites[spriteId].oam.matrixNum = 18; + CalcCenterToCornerVec(&gSprites[spriteId], 0, 1, 3); + gSprites[spriteId].data0 = sprite->data0; + gSprites[spriteId].data3 = gUnknown_0840B168[(sprite->data7 >> 1) & 7]; + gSprites[spriteId].data4 = r1; + gSprites[spriteId].data5 = r2; + gSprites[spriteId].data6 = r6; + } + } + } + } +} + +static void InitIntroTorchicAttackAnim(u8 a) +{ + u8 spriteId; + u8 i; + + spriteId = CreateSprite(&gSpriteTemplate_840B170, 0, 0, 0); + if (spriteId != 64) + { + gSprites[spriteId].data0 = a; + gSprites[spriteId].data1 = 0; + gSprites[spriteId].data2 = 8; + gSprites[spriteId].data3 = 24; + } + for (i = 0; i < 10; i++) + { + SetOamMatrix(18 + i, gUnknown_0840B188[i], 0, 0, gUnknown_0840B188[i]); + } +} + +void sub_813EBBC(struct Sprite *sprite) +{ + if (gUnknown_0203931A != 0) + { + DestroySprite(sprite); + } + else + { + sprite->invisible = gSprites[sprite->data0].invisible; + sprite->data7 += 1; + sprite->data6 += 8; + sprite->pos1.x = sprite->data4 + gSineTable[(u8)(sprite->data3 + 64)] * sprite->data6 / 256; + sprite->pos1.y = sprite->data5 + gSineTable[(u8)(sprite->data3 + 0)] * sprite->data6 / 256; + sprite->pos2.y = gSineTable[(u8)(sprite->data1 + 0)] / 64; + sprite->data1 += 16; + if (sprite->pos1.y < sprite->data2) + DestroySprite(sprite); + } +} + +void sub_813EC90(struct Sprite *sprite) +{ + bool32 r6; + s16 r1, r2; + u8 spriteId; + u16 foo; + + if (gUnknown_0203931A != 0) + { + DestroySprite(sprite); + } + else + { + sprite->data7++; + sprite->invisible = TRUE; + if (gSprites[sprite->data0].data0 == 1) + { + r6 = sprite->data7 & 1; + if (!r6) + { + r1 = sprite->data1 + gSprites[sprite->data0].pos1.x; + r2 = sprite->data2 + gSprites[sprite->data0].pos1.y; + spriteId = CreateSprite(&gSpriteTemplate_840B1B0, r1, r2, gSprites[sprite->data0].subpriority + 1); + if (spriteId != 64) + { + gSprites[spriteId].oam.affineMode = 3; + gSprites[spriteId].oam.matrixNum = 17; + CalcCenterToCornerVec(&gSprites[spriteId], 0, 1, 3); + gSprites[spriteId].data0 = sprite->data0; + gSprites[spriteId].data1 = ((sprite->data7 >> 2) & 7) << 5; + gSprites[spriteId].data2 = sprite->data3; + gSprites[spriteId].data3 = 232; + gSprites[spriteId].data4 = r1; + gSprites[spriteId].data5 = r2; + gSprites[spriteId].data6 = r6; + } + } + if (sprite->data6 < 112) + sprite->data6 += 4; + } + foo = 256 - gSineTable[(u8)sprite->data6] / 2; + SetOamMatrix(17, foo, 0, 0, foo); + } +} + +static void InitIntroMudkipAttackAnim(u8 a) +{ + u8 spriteId; + + spriteId = CreateSprite(&gSpriteTemplate_840B1C8, 0, 0, 0); + if (spriteId != 64) + { + gSprites[spriteId].data0 = a; + gSprites[spriteId].data1 = 0; + gSprites[spriteId].data2 = 12; + gSprites[spriteId].data3 = 24; + } +} + +void sub_813EDFC(struct Sprite *sprite) +{ + u16 foo; + + //I'm not sure why a switch statement was used here. + //if (sprite->data0 != 1) would have been more appropriate. + switch (sprite->data0) + { + case 0: + default: + sprite->invisible = FALSE; + sprite->oam.affineMode = 3; + sprite->oam.matrixNum = 18; + CalcCenterToCornerVec(sprite, 0, 3, 3); + sprite->data1 = 0; + sprite->data0 = 1; + //fall through + case 1: + break; + } + sprite->data7++; + if (sprite->data7 & 1) + { + sprite->invisible = TRUE; + } + else + { + sprite->invisible = FALSE; + if (sprite->data1 < 64) + sprite->data1++; + } + foo = 256 - gSineTable[(u8)sprite->data1] / 2; + SetOamMatrix(18, foo, 0, 0, foo); +} diff --git a/src/item.c b/src/item.c index 8bc0cf0f0..3f74b5925 100644 --- a/src/item.c +++ b/src/item.c @@ -1,5 +1,5 @@ #include "global.h" -#include "berry.h" +#include "item.h" #include "string_util.h" extern struct Berry *GetBerryInfo(u8 berry); @@ -7,8 +7,6 @@ extern struct Berry *GetBerryInfo(u8 berry); extern u8 gOtherText_Berry2[]; extern u8 gUnknown_02038560; -typedef void (*ItemUseFunc)(u8); - struct Item { u8 name[14]; @@ -46,8 +44,6 @@ enum KEYITEMS_POCKET }; -struct Item *ItemId_GetItem(u16); -u8 ItemId_GetPocket(u16); static void CompactPCItems(void); void CopyItemName(u16 itemId, u8 *string) @@ -62,7 +58,7 @@ void CopyItemName(u16 itemId, u8 *string) } //Unreferenced -static s8 CountUsedBagPocketSlots(u8 pocket) +s8 CountUsedBagPocketSlots(u8 pocket) { u8 i; diff --git a/src/item_use.c b/src/item_use.c new file mode 100644 index 000000000..557705460 --- /dev/null +++ b/src/item_use.c @@ -0,0 +1,414 @@ +#include "global.h" +#include "task.h" +#include "item.h" +#include "palette.h" +#include "weather.h" +#include "string_util.h" +#include "menu.h" +#include "mail.h" +#include "asm.h" +#include "rom4.h" +#include "metatile_behavior.h" +#include "field_player_avatar.h" +#include "event_data.h" +#include "map_obj_lock.h" +#include "script.h" +#include "field_player_avatar.h" +#include "sound.h" +#include "songs.h" + +extern void (* const gExitToOverworldFuncList[])(); +extern void (* gUnknown_03005D00)(u8); +extern void (* gUnknown_0300485C)(void); + +extern void HandleItemMenuPaletteFade(u8); +extern void ExecuteItemUseFromBlackPalette(void); +extern void DisplayItemMessageOnField(u8, u8*, TaskFunc, u16); +extern void CleanUpItemMenuMessage(u8); +extern void CleanUpOverworldMessage(u8); +extern void ItemUseOutOfBattle_TMHM(u8); +extern void ItemUseOutOfBattle_EvolutionStone(u8); +extern void ItemUseOnFieldCB_Bike(u8); +extern void ItemUseOnFieldCB_Rod(u8); +extern void ItemUseOnFieldCB_Itemfinder(u8); +extern void sub_80A5D04(void); +extern bool8 IsBikingDisallowedByPlayer(void); +extern void GetOnOffBike(u8); +extern u8 GetPlayerDirectionTowardsHiddenItem(s16, s16); +extern void SetPlayerDirectionTowardsItem(u8); +extern void DisplayItemRespondingMessageAndExitItemfinder(u8); +extern void RotatePlayerAndExitItemfinder(u8); + +extern u8 gOtherText_DadsAdvice[]; +extern u8 gOtherText_CantGetOffBike[]; +extern u8 gOtherText_NoResponse[]; + +extern u8 gItemFinderDirections[]; + +extern u16 gScriptItemId; + +bool8 ItemfinderCheckForHiddenItems(struct MapEvents *events, int); +void RunItemfinderResults(u8); +void ExitItemfinder(u8); + +void ExecuteSwitchToOverworldFromItemUse(u8 taskId) +{ + u8 taskData; + + if(gScriptItemId == 0xAF) + taskData = gTasks[taskId].data[15] - 1; + else + taskData = ItemId_GetType(gScriptItemId) - 1; + + gTasks[taskId].data[8] = (u32)gExitToOverworldFuncList[taskData] >> 16; + gTasks[taskId].data[9] = (u32)gExitToOverworldFuncList[taskData]; + gTasks[taskId].func = HandleItemMenuPaletteFade; +} + +void ItemMenu_ConfirmNormalFade(u8 var) +{ + ExecuteSwitchToOverworldFromItemUse(var); + BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, 0); +} + +void ItemMenu_ConfirmComplexFade(u8 var) +{ + ExecuteSwitchToOverworldFromItemUse(var); + fade_screen(1, 0); +} + +void SetUpItemUseOnFieldCallback(u8 taskId) +{ + if(gTasks[taskId].data[2] != 1) + { + gUnknown_0300485C = (void *)ExecuteItemUseFromBlackPalette; + ItemMenu_ConfirmNormalFade(taskId); + } + else + gUnknown_03005D00(taskId); +} + +void HandleDeniedItemUseMessage(u8 var1, u8 playerMenuStatus, const u8 *var3) +{ + StringExpandPlaceholders(gStringVar4, var3); + + switch(playerMenuStatus) + { + case 0: // Item Menu + MenuZeroFillWindowRect(0, 13, 13, 20); + DisplayItemMessageOnField(var1, gStringVar4, CleanUpItemMenuMessage, 1); + break; + default: // Field + DisplayItemMessageOnField(var1, gStringVar4, CleanUpOverworldMessage, 0); + break; + } +} + +void DisplayDadsAdviceCannotUseItemMessage(u8 var1, u8 playerMenuStatus) +{ + HandleDeniedItemUseMessage(var1, playerMenuStatus, gOtherText_DadsAdvice); +} + +void DisplayCantGetOffBikeItemMessage(u8 var1, u8 playerMenuStatus) +{ + HandleDeniedItemUseMessage(var1, playerMenuStatus, gOtherText_CantGetOffBike); +} + +u8 CheckIfItemIsTMHMOrEvolutionStone(u16 itemId) +{ + if(ItemId_GetFieldFunc(itemId) == ItemUseOutOfBattle_TMHM) + return 1; + else if(ItemId_GetFieldFunc(itemId) == ItemUseOutOfBattle_EvolutionStone) + return 2; + else + return 0; +} + +void ItemMenu_ReadMail(u8 taskId) +{ + struct MailStruct mailStruct; + + if(!gPaletteFade.active) + { + mailStruct.itemId = gScriptItemId; + HandleReadMail(&mailStruct, sub_80A5D04, 0); + DestroyTask(taskId); + } +} + +void ItemUseOutOfBattle_Mail(u8 taskId) +{ + BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, 0); + gTasks[taskId].func = ItemMenu_ReadMail; +} + +void ItemUseOutOfBattle_Bike(u8 taskId) +{ + s16 x, y; + u8 tileBehavior; + + PlayerGetDestCoords(&x, &y); + tileBehavior = MapGridGetMetatileBehaviorAt(x, y); + + if(FlagGet(SYS_CYCLING_ROAD) == TRUE // on cycling road? + || MetatileBehavior_IsVerticalRail(tileBehavior) == TRUE + || MetatileBehavior_IsHorizontalRail(tileBehavior) == TRUE + || MetatileBehavior_IsIsolatedVerticalRail(tileBehavior) == TRUE + || MetatileBehavior_IsIsolatedHorizontalRail(tileBehavior) == TRUE) + { + DisplayCantGetOffBikeItemMessage(taskId, gTasks[taskId].data[2]); + } + else + { + if(IsBikingAllowedByMap() == TRUE && IsBikingDisallowedByPlayer() == FALSE) + { + gUnknown_03005D00 = (void *)ItemUseOnFieldCB_Bike; + SetUpItemUseOnFieldCallback(taskId); + } + else + DisplayDadsAdviceCannotUseItemMessage(taskId, gTasks[taskId].data[2]); + } +} + +void ItemUseOnFieldCB_Bike(u8 taskId) +{ + if(ItemId_GetSecondaryId(gScriptItemId) == 0) + GetOnOffBike(2); + if(ItemId_GetSecondaryId(gScriptItemId) == 1) + GetOnOffBike(4); + + sub_8064E2C(); + ScriptContext2_Disable(); + DestroyTask(taskId); +} + +bool32 CanFish(void) +{ + s16 x, y; + u16 tileBehavior; + + GetXYCoordsOneStepInFrontOfPlayer(&x, &y); + tileBehavior = MapGridGetMetatileBehaviorAt(x, y); + + if (MetatileBehavior_IsWaterfall(tileBehavior)) + return FALSE; + + if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_4)) + return FALSE; + + if (!TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_SURFING)) + { + if (IsPlayerFacingSurfableFishableWater()) + return TRUE; + } + else + { + if (MetatileBehavior_IsSurfableWaterOrUnderwater(tileBehavior) && !MapGridIsImpassableAt(x, y)) + return TRUE; + if (MetatileBehavior_IsBridge(tileBehavior) == TRUE) + return TRUE; + } + + return FALSE; +} + +void ItemUseOutOfBattle_Rod(u8 taskId) +{ + if(CanFish() == TRUE) + { + gUnknown_03005D00 = (void *)ItemUseOnFieldCB_Rod; + SetUpItemUseOnFieldCallback(taskId); + } + else + DisplayDadsAdviceCannotUseItemMessage(taskId, gTasks[taskId].data[2]); +} + +void ItemUseOnFieldCB_Rod(u8 taskId) +{ + StartFishing(ItemId_GetSecondaryId(gScriptItemId)); + DestroyTask(taskId); +} + +void ItemUseOutOfBattle_Itemfinder(u8 var) +{ + IncrementGameStat(0x27); + gUnknown_03005D00 = (void *)ItemUseOnFieldCB_Itemfinder; + SetUpItemUseOnFieldCallback(var); +} + +void ItemUseOnFieldCB_Itemfinder(u8 taskId) +{ + if(ItemfinderCheckForHiddenItems(gMapHeader.events, taskId) == TRUE) + gTasks[taskId].func = RunItemfinderResults; + else + DisplayItemMessageOnField(taskId, gOtherText_NoResponse, ExitItemfinder, 0); +} + +void RunItemfinderResults(u8 taskId) +{ + u8 playerDir; + u8 playerDirToItem; + u8 i; + s16 *data = gTasks[taskId].data; + + if(!data[3]) + { + if(data[4] == 4) + { + playerDirToItem = GetPlayerDirectionTowardsHiddenItem(data[0], data[1]); + if(playerDirToItem) + { + SetPlayerDirectionTowardsItem(gItemFinderDirections[playerDirToItem - 1]); + gTasks[taskId].func = DisplayItemRespondingMessageAndExitItemfinder; + } + else // player is above hidden item. + { + playerDir = player_get_direction_lower_nybble(); + + // rotate player clockwise depending on current direction. + for (i = 0; i < 4; i++) + if (playerDir == gItemFinderDirections[i]) + data[5] = (i + 1) & 3; + + gTasks[taskId].func = RotatePlayerAndExitItemfinder; + data[3] = 0; + data[2] = 0; + } + return; + } + PlaySE(SE_DAUGI); // play the itemfinder jingle 4 times before executing the itemfinder. + data[4]++; + } + data[3] = (data[3] + 1) & 0x1F; +} + +void ExitItemfinder(u8 taskId) +{ + MenuZeroFillWindowRect(0, 14, 29, 19); + sub_8064E2C(); + ScriptContext2_Disable(); + DestroyTask(taskId); +} + +// too much struct math. +__attribute__((naked)) +bool8 ItemfinderCheckForHiddenItems(struct MapEvents *events, int var) +{ + asm(".syntax unified\n\ + push {r4-r7,lr}\n\ + mov r7, r9\n\ + mov r6, r8\n\ + push {r6,r7}\n\ + sub sp, 0x4\n\ + adds r5, r0, 0\n\ + lsls r1, 24\n\ + lsrs r6, r1, 24\n\ + mov r4, sp\n\ + adds r4, 0x2\n\ + mov r0, sp\n\ + adds r1, r4, 0\n\ + bl PlayerGetDestCoords\n\ + ldr r1, _080C9618 @ =gTasks\n\ + lsls r0, r6, 2\n\ + adds r0, r6\n\ + lsls r0, 3\n\ + adds r0, r1\n\ + movs r1, 0\n\ + strh r1, [r0, 0xC]\n\ + movs r3, 0\n\ + mov r9, r4\n\ + ldrb r0, [r5, 0x3]\n\ + cmp r3, r0\n\ + bge _080C95FC\n\ + subs r1, 0x5\n\ + mov r8, r1\n\ +_080C9580:\n\ + lsls r3, 16\n\ + asrs r1, r3, 16\n\ + ldr r2, [r5, 0x10]\n\ + lsls r0, r1, 1\n\ + adds r0, r1\n\ + lsls r4, r0, 2\n\ + adds r1, r4, r2\n\ + ldrb r0, [r1, 0x5]\n\ + adds r7, r3, 0\n\ + cmp r0, 0x7\n\ + bne _080C95EC\n\ + movs r2, 0x96\n\ + lsls r2, 2\n\ + adds r0, r2, 0\n\ + ldrh r1, [r1, 0xA]\n\ + adds r0, r1\n\ + lsls r0, 16\n\ + lsrs r0, 16\n\ + bl FlagGet\n\ + lsls r0, 24\n\ + cmp r0, 0\n\ + bne _080C95EC\n\ + ldr r1, [r5, 0x10]\n\ + adds r1, r4, r1\n\ + ldrh r2, [r1]\n\ + adds r2, 0x7\n\ + mov r0, sp\n\ + ldrh r0, [r0]\n\ + subs r2, r0\n\ + ldrh r0, [r1, 0x2]\n\ + adds r0, 0x7\n\ + mov r3, r9\n\ + ldrh r1, [r3]\n\ + subs r0, r1\n\ + lsls r0, 16\n\ + lsrs r0, 16\n\ + lsls r2, 16\n\ + asrs r1, r2, 16\n\ + movs r3, 0xE0\n\ + lsls r3, 11\n\ + adds r2, r3\n\ + lsrs r2, 16\n\ + cmp r2, 0xE\n\ + bhi _080C95EC\n\ + lsls r0, 16\n\ + asrs r2, r0, 16\n\ + cmp r2, r8\n\ + blt _080C95EC\n\ + cmp r2, 0x5\n\ + bgt _080C95EC\n\ + adds r0, r6, 0\n\ + bl sub_80C9838\n\ +_080C95EC:\n\ + movs r1, 0x80\n\ + lsls r1, 9\n\ + adds r0, r7, r1\n\ + lsrs r3, r0, 16\n\ + asrs r0, 16\n\ + ldrb r2, [r5, 0x3]\n\ + cmp r0, r2\n\ + blt _080C9580\n\ +_080C95FC:\n\ + adds r0, r6, 0\n\ + bl sub_80C9720\n\ + ldr r0, _080C9618 @ =gTasks\n\ + lsls r1, r6, 2\n\ + adds r1, r6\n\ + lsls r1, 3\n\ + adds r1, r0\n\ + movs r3, 0xC\n\ + ldrsh r0, [r1, r3]\n\ + cmp r0, 0x1\n\ + beq _080C961C\n\ + movs r0, 0\n\ + b _080C961E\n\ + .align 2, 0\n\ +_080C9618: .4byte gTasks\n\ +_080C961C:\n\ + movs r0, 0x1\n\ +_080C961E:\n\ + add sp, 0x4\n\ + pop {r3,r4}\n\ + mov r8, r3\n\ + mov r9, r4\n\ + pop {r4-r7}\n\ + pop {r1}\n\ + bx r1\n\ + .syntax divided"); +} diff --git a/src/landmark.c b/src/landmark.c index aa4d8c6fa..6a53716bb 100644 --- a/src/landmark.c +++ b/src/landmark.c @@ -1,5 +1,6 @@ #include "global.h" -#include "flag.h" +#include "landmark.h" +#include "event_data.h" #define MAPSEC_NONE 0x58 diff --git a/src/link.c b/src/link.c index 47820185c..7b4625bfd 100644 --- a/src/link.c +++ b/src/link.c @@ -1,14 +1,17 @@ #include "global.h" +#include "link.h" +#include "asm.h" #include "main.h" #include "task.h" #include "text.h" #include "sprite.h" #include "songs.h" -#include "link.h" #include "palette.h" #include "rng.h" #include "menu.h" #include "sound.h" +#include "save.h" +#include "battle.h" #define SIO_MULTI_CNT ((struct SioMultiCnt *)REG_ADDR_SIOCNT) @@ -29,11 +32,9 @@ struct LinkTestBGInfo u32 dummy_C; }; -extern void sub_80516C4(u8, u16); - extern u8 unk_2000000[]; extern u8 unk_2004000[]; -extern u16 gUnknown_020239F8; +extern u16 gBattleTypeFlags; extern u16 gScriptItemId; extern u16 word_3004858; @@ -41,8 +42,8 @@ extern u16 word_3004858; extern u8 gMultiText_LinkError[]; static void InitLinkTestBG(u8, u8, u8, u8); -static void InitLinkTestBG_Unused(u8, u8, u8, u8); -static void LinkTestScreen(); +void InitLinkTestBG_Unused(u8, u8, u8, u8); +void LinkTestScreen(); static void InitLocalLinkPlayer(void); static void VBlankCB_LinkTest(void); static void InitLink(void); @@ -60,15 +61,15 @@ static void LinkCB_BlockSendBegin(void); static void LinkCB_BlockSend(void); static void LinkCB_BlockSendEnd(void); static void sub_8007E04(void); -static u32 sub_8007E40(void); +u32 sub_8007E40(void); static void SetBlockReceivedFlag(u8); static u16 LinkTestCalcBlockChecksum(void *, u16); static void PrintHexDigit(u8, u8, u8); static void PrintHex(u32, u8, u8, u8); static void LinkCB_RequestPlayerDataExchange(void); static void Task_PrintTestData(u8); -static bool8 sub_8008224(void); -static u8 GetDummy2(void); +bool8 sub_8008224(void); +u8 GetDummy2(void); static void sub_8008350(void); static void sub_800837C(void); static void sub_80083E0(void); @@ -90,8 +91,8 @@ static void DoRecv(void); static void DoSend(void); static void StopTimer(void); static void SendRecvDone(void); -static void ResetSendBuffer(void); -static void ResetRecvBuffer(void); +void ResetSendBuffer(void); +void ResetRecvBuffer(void); static struct BlockTransfer sBlockSend; static struct BlockTransfer sBlockRecv[MAX_LINK_PLAYERS]; @@ -212,7 +213,7 @@ static void InitLinkTestBG(u8 paletteNum, u8 bgNum, u8 screenBaseBlock, u8 charB } } -static void InitLinkTestBG_Unused(u8 paletteNum, u8 bgNum, u8 screenBaseBlock, u8 charBaseBlock) +void InitLinkTestBG_Unused(u8 paletteNum, u8 bgNum, u8 screenBaseBlock, u8 charBaseBlock) { LoadPalette(sLinkTestDigitPalette, 16 * paletteNum, 32); DmaCopy16(3, sLinkTestDigitTiles, BG_CHAR_ADDR(charBaseBlock), 0x220); @@ -223,7 +224,7 @@ static void InitLinkTestBG_Unused(u8 paletteNum, u8 bgNum, u8 screenBaseBlock, u *gBGControlRegs[bgNum] = (screenBaseBlock << 8) | (charBaseBlock << 2); } -static void LinkTestScreen(void) +void LinkTestScreen(void) { s32 i; ResetSpriteData(); @@ -461,7 +462,7 @@ static void HandleReceiveRemoteLinkPlayer(u8 multiplayerId) gReceivedRemoteLinkPlayers = TRUE; } -static void ProcessRecvCmds(u8 a1) +static void ProcessRecvCmds(u8 unusedParam) { u16 i; for (i = 0; i < MAX_LINK_PLAYERS; i++) @@ -829,7 +830,7 @@ static void LinkCB_BlockSendEnd(void) static void sub_8007E04(void) { - GetMultiplayerId(); + GetMultiplayerId(); // whats the point of calling this if you dont use the multiplayer ID? BuildSendCmd(0x4444); dword_20238BC++; } @@ -840,7 +841,7 @@ void sub_8007E24(void) gLinkCallback = sub_8007E04; } -static u32 sub_8007E40(void) +u32 sub_8007E40(void) { return dword_20238BC; } @@ -1025,7 +1026,7 @@ u8 sub_8008218(void) return gSavedMultiplayerId; } -static bool8 sub_8008224(void) +bool8 sub_8008224(void) { s32 count = 0; s32 i; @@ -1072,7 +1073,7 @@ bool8 IsLinkMaster(void) return EXTRACT_MASTER(gLinkStatus); } -static u8 GetDummy2(void) +u8 GetDummy2(void) { return sDummy2; } @@ -1107,7 +1108,7 @@ static void sub_800837C(void) if (count == totalCount) { - gUnknown_020239F8 &= 0xFFDF; + gBattleTypeFlags &= ~BATTLE_TYPE_20; gLinkVSyncDisabled = TRUE; CloseLink(); gLinkCallback = NULL; @@ -1131,7 +1132,7 @@ static void sub_80083E0(void) if (count == totalCount) { - gUnknown_020239F8 &= 0xFFDF; + gBattleTypeFlags &= ~BATTLE_TYPE_20; gLinkVSyncDisabled = TRUE; CloseLink(); gLinkCallback = 0; @@ -1224,7 +1225,7 @@ void CB2_LinkError(void) REG_BG0VOFS = 0; REG_BG0HOFS = 0; REG_DISPCNT = DISPCNT_MODE_0 | DISPCNT_OBJ_1D_MAP | DISPCNT_BG0_ON; - gUnknown_3001BB4 = 0; + gSoftResetDisabled = FALSE; CreateTask(Task_DestroySelf, 0); StopMapMusic(); RunTasks(); @@ -1236,7 +1237,7 @@ void CB2_LinkError(void) static void CB2_PrintErrorMessage(void) { - u8 array[64]; // unused + u8 array[64] __attribute__((unused)); // unused switch (gMain.state) { @@ -1772,7 +1773,7 @@ static void SendRecvDone(void) } } -static void ResetSendBuffer(void) +void ResetSendBuffer(void) { u8 i; u8 j; @@ -1785,7 +1786,7 @@ static void ResetSendBuffer(void) gLink.sendQueue.data[i][j] = 0xEFFF; } -static void ResetRecvBuffer(void) +void ResetRecvBuffer(void) { u8 i; u8 j; diff --git a/src/load_save.c b/src/load_save.c new file mode 100644 index 000000000..5babb843e --- /dev/null +++ b/src/load_save.c @@ -0,0 +1,164 @@ +#include "global.h" +#include "load_save.h" +#include "asm.h" +#include "main.h" +#include "pokemon.h" +#include "rom4.h" + +extern u8 gPlayerPartyCount; +extern u32 gUnknown_3004820; + +struct LoadedSaveData +{ + struct ItemSlot items[20]; + struct ItemSlot keyItems[20]; + struct ItemSlot pokeBalls[16]; + struct ItemSlot TMsHMs[64]; + struct ItemSlot berries[46]; + struct MailStruct mail[16]; +}; + +extern struct LoadedSaveData gLoadedSaveData[]; + +void CheckForFlashMemory(void) +{ + if(!IdentifyFlash()) + { + gUnknown_3004820 = 1; + InitFlashTimer(); + } + else + gUnknown_3004820 = 0; +} + +bool32 GetSecretBase2Field_9(void) +{ + return gSaveBlock2.specialSaveWarp; +} + +void ClearSecretBase2Field_9(void) +{ + gSaveBlock2.specialSaveWarp = 0; +} + +void SetSecretBase2Field_9(void) +{ + gSaveBlock2.specialSaveWarp = 1; +} + +void SetSecretBase2Field_9_AndHideBG(void) // note: no other function sets specialSaveWarp to values other than 0 or 1, hence clear and set distinctions. +{ + gpu_sync_bg_hide(0); // the function doesn't use the parameter passed to it, but this is necessary to match. + gSaveBlock2.specialSaveWarp = 1; +} + +void ClearSecretBase2Field_9_2(void) // duplicate function +{ + gSaveBlock2.specialSaveWarp = 0; +} + +void SavePlayerParty(void) +{ + int i; + + gSaveBlock1.playerPartyCount = gPlayerPartyCount; + + for (i = 0; i < 6; i++) + gSaveBlock1.playerParty[i] = gPlayerParty[i]; +} + +void LoadPlayerParty(void) +{ + int i; + + gPlayerPartyCount = gSaveBlock1.playerPartyCount; + + for (i = 0; i < 6; i++) + gPlayerParty[i] = gSaveBlock1.playerParty[i]; +} + +static void SaveMapObjects(void) +{ + int i; + + for(i = 0; i < 16; i++) + gSaveBlock1.mapObjects[i] = gMapObjects[i]; +} + +static void LoadMapObjects(void) +{ + int i; + + for(i = 0; i < 16; i++) + gMapObjects[i] = gSaveBlock1.mapObjects[i]; +} + +void SaveSerializedGame(void) +{ + SavePlayerParty(); + SaveMapObjects(); +} + +void LoadSerializedGame(void) +{ + LoadPlayerParty(); + LoadMapObjects(); +} + +void LoadPlayerBag(void) +{ + int i; + + // load player items. + for(i = 0; i < 20; i++) + gLoadedSaveData->items[i] = gSaveBlock1.bagPocket_Items[i]; + + // load player key items. + for(i = 0; i < 20; i++) + gLoadedSaveData->keyItems[i] = gSaveBlock1.bagPocket_KeyItems[i]; + + // load player pokeballs. + for(i = 0; i < 16; i++) + gLoadedSaveData->pokeBalls[i] = gSaveBlock1.bagPocket_PokeBalls[i]; + + // load player TMs and HMs. + for(i = 0; i < 64; i++) + gLoadedSaveData->TMsHMs[i] = gSaveBlock1.bagPocket_TMHM[i]; + + // load player berries. + for(i = 0; i < 46; i++) + gLoadedSaveData->berries[i] = gSaveBlock1.bagPocket_Berries[i]; + + // load mail. + for(i = 0; i < 16; i++) + gLoadedSaveData->mail[i] = gSaveBlock1.mail[i]; +} + +void SavePlayerBag(void) +{ + int i; + + // save player items. + for(i = 0; i < 20; i++) + gSaveBlock1.bagPocket_Items[i] = gLoadedSaveData->items[i]; + + // save player key items. + for(i = 0; i < 20; i++) + gSaveBlock1.bagPocket_KeyItems[i] = gLoadedSaveData->keyItems[i]; + + // save player pokeballs. + for(i = 0; i < 16; i++) + gSaveBlock1.bagPocket_PokeBalls[i] = gLoadedSaveData->pokeBalls[i]; + + // save player TMs and HMs. + for(i = 0; i < 64; i++) + gSaveBlock1.bagPocket_TMHM[i] = gLoadedSaveData->TMsHMs[i]; + + // save player berries. + for(i = 0; i < 46; i++) + gSaveBlock1.bagPocket_Berries[i] = gLoadedSaveData->berries[i]; + + // save mail. + for(i = 0; i < 16; i++) + gSaveBlock1.mail[i] = gLoadedSaveData->mail[i]; +} diff --git a/src/lottery_corner.c b/src/lottery_corner.c index c807237af..c18aeef48 100644 --- a/src/lottery_corner.c +++ b/src/lottery_corner.c @@ -1,49 +1,54 @@ #include "global.h" -#include "pokemon.h" +#include "lottery_corner.h" #include "rng.h" #include "string_util.h" -#include "var.h" +#include "event_data.h" +#include "species.h" +#include "items.h" extern u16 gScriptResult; extern u16 gSpecialVar_0x8004; extern struct Pokemon gPlayerParty[6]; extern struct PokemonStorage gPokemonStorage; extern u16 gSpecialVar_0x8005; -extern u16 gUnknown_0840CB04[]; extern u16 gSpecialVar_0x8006; static EWRAM_DATA u16 sWinNumberDigit = 0; static EWRAM_DATA u16 sOtIdDigit = 0; -void sub_8145D14(u32); -u32 sub_8145D3C(void); +static const u16 sLotteryPrizes[] = +{ + ITEM_PP_UP, + ITEM_EXP_SHARE, + ITEM_MAX_REVIVE, + ITEM_MASTER_BALL, +}; + static u8 GetMatchingDigits(u16, u16); -void sub_8145A78(void) +void ResetLotteryCorner(void) { u16 rand = Random(); - sub_8145D14((Random() << 16) | rand); - VarSet(0x4045, 0); + SetLotteryNumber((Random() << 16) | rand); + VarSet(VAR_POKELOT_PRIZE, 0); } -void sub_8145AA4(u16 a) +void SetRandomLotteryNumber(u16 i) { u32 var = Random(); - while(--a != 0xFFFF) - { + while(--i != 0xFFFF) var = var * 1103515245 + 12345; - } - sub_8145D14(var); + + SetLotteryNumber(var); } -void sub_8145AEC(void) +void RetrieveLotteryNumber(void) { - u16 a = sub_8145D3C(); - gScriptResult = a; + u16 lottoNumber = GetLotteryNumber(); + gScriptResult = lottoNumber; } -//Script special function void PickLotteryCornerTicket(void) { u16 i; @@ -59,41 +64,44 @@ void PickLotteryCornerTicket(void) struct Pokemon *pkmn = &gPlayerParty[i]; // UB: Too few arguments for function GetMonData - if(GetMonData(pkmn, MON_DATA_SPECIES) != 0) + if(GetMonData(pkmn, MON_DATA_SPECIES) != SPECIES_NONE) { + // do not calculate ticket values for eggs. if(!GetMonData(pkmn, MON_DATA_IS_EGG)) { u32 otId = GetMonData(pkmn, MON_DATA_OT_ID); - u8 a = GetMatchingDigits(gScriptResult, otId); + u8 numMatchingDigits = GetMatchingDigits(gScriptResult, otId); - if(a > gSpecialVar_0x8004 && a > 1) + if(numMatchingDigits > gSpecialVar_0x8004 && numMatchingDigits > 1) { - gSpecialVar_0x8004 = a - 1; + gSpecialVar_0x8004 = numMatchingDigits - 1; box = 14; slot = i; } } } - else + else // pokemon are always arranged from populated spots first to unpopulated, so the moment a NONE species is found, that's the end of the list. break; } + // player has 14 boxes. for(i = 0; i < 14; i++) { - for(j = 0; j < 0x1E; j++) + // player has 30 slots per box. + for(j = 0; j < 30; j++) { struct BoxPokemon *pkmn = &gPokemonStorage.boxes[i][j]; // UB: Too few arguments for function GetMonData - if(GetBoxMonData(pkmn, MON_DATA_SPECIES) != 0 && + if(GetBoxMonData(pkmn, MON_DATA_SPECIES) != SPECIES_NONE && !GetBoxMonData(pkmn, MON_DATA_IS_EGG)) { u32 otId = GetBoxMonData(pkmn, MON_DATA_OT_ID); - u8 a = GetMatchingDigits(gScriptResult, otId); + u8 numMatchingDigits = GetMatchingDigits(gScriptResult, otId); - if(a > gSpecialVar_0x8004 && a > 1) + if(numMatchingDigits > gSpecialVar_0x8004 && numMatchingDigits > 1) { - gSpecialVar_0x8004 = a - 1; + gSpecialVar_0x8004 = numMatchingDigits - 1; box = i; slot = j; } @@ -103,7 +111,7 @@ void PickLotteryCornerTicket(void) if(gSpecialVar_0x8004 != 0) { - gSpecialVar_0x8005 = gUnknown_0840CB04[gSpecialVar_0x8004 - 1]; + gSpecialVar_0x8005 = sLotteryPrizes[gSpecialVar_0x8004 - 1]; if(box == 14) { @@ -122,7 +130,7 @@ void PickLotteryCornerTicket(void) static u8 GetMatchingDigits(u16 winNumber, u16 otId) { u8 i; - u8 matchingDigits = 0; //Why not just use i? + u8 matchingDigits = 0; for(i = 0; i < 5; i++) { @@ -141,24 +149,26 @@ static u8 GetMatchingDigits(u16 winNumber, u16 otId) return matchingDigits; } -void sub_8145D14(u32 a) +// lottery numbers go from 0 to 99999, not 65535 (0xFFFF). interestingly enough, the function that calls GetLotteryNumber shifts to u16, so it cant be anything above 65535 anyway. +void SetLotteryNumber(u32 lotteryNum) { - u16 b = a >> 16; - u16 c = a; - - VarSet(0x404B, c); - VarSet(0x404C, b); + u16 lowNum = lotteryNum >> 16; + u16 highNum = lotteryNum; + + VarSet(VAR_POKELOT_RND1, highNum); + VarSet(VAR_POKELOT_RND2, lowNum); } -u32 sub_8145D3C(void) +u32 GetLotteryNumber(void) { - u16 var1 = VarGet(0x404B); - u16 var2 = VarGet(0x404C); + u16 highNum = VarGet(VAR_POKELOT_RND1); + u16 lowNum = VarGet(VAR_POKELOT_RND2); - return (var2 << 16) | var1; + return (lowNum << 16) | highNum; } -void unref_sub_8145D64(u16 a) +// interestingly, this may have been the original lottery number set function, but GF tried to change it to 32-bit later but didnt finish changing all calls as one GetLotteryNumber still shifts to u16. +void SetLotteryNumber16_Unused(u16 lotteryNum) { - sub_8145D14(a); + SetLotteryNumber(lotteryNum); } diff --git a/src/mail.c b/src/mail.c new file mode 100644 index 000000000..6cff514a1 --- /dev/null +++ b/src/mail.c @@ -0,0 +1,669 @@ +#include "global.h" +#include "mail.h" +#include "asm.h" +#include "menu.h" +#include "palette.h" +#include "rom4.h" +#include "sprite.h" +#include "string_util.h" +#include "task.h" +#include "text.h" +#include "items.h" + +struct UnkMailStruct +{ + u8 unk_0_0:2; + u8 unk_0_2:2; + u8 unk_0_4:4; +}; + +struct MailLayout { + u8 var0; + u8 var1; + u8 var2; + u8 var3_0:4; + u8 var3_4:4; + struct UnkMailStruct *var4; +}; + +struct Unk2000000 { + /* 0x00 */ u8 words[8][27]; + /* 0xEC */ u8 varD8[20]; + /* 0xEC */ MainCallback varEC; + /* 0xF0 */ MainCallback varF0; + /* 0xFF */ struct MailStruct *varF4; + /* 0xF8 */ u8 varF8; + /* 0xF9 */ u8 varF9; + /* 0xFA */ u8 varFA; + /* 0xFB */ u8 varFB; + /* 0xFC */ u8 varFC; + u8 padFD[1]; + /* 0xFE */ u8 varFE; + /* 0xFF */ u8 varFF; + /* 0x100 */ u8 var100; + u8 pad101[3]; + /* 0x104 */ MainCallback var104; + /* 0x108 */ MainCallback var108; + /* 0x10C */ struct MailLayout *var10C; +}; + +struct MailGraphics { + u16 (*palette)[]; + u8 (*tiles)[]; + u8 (*tileMap)[]; + u16 var0C; + u16 var0E; + u16 color10; + u16 color12; +}; + +extern struct Unk2000000 unk_2000000; +extern struct MailGraphics gMailGraphicsTable[]; +extern u16 gUnknown_083E562C[][2]; + +extern struct MailLayout gUnknown_083E5730[]; +extern struct MailLayout gUnknown_083E57A4[]; + +extern u8 gOtherText_From[]; + +static u8 sub_80F8A28(void); +// static void sub_80F8D50(void); +// static u8 *sub_80F8D7C(u8 *dest, u8 *src); +static void sub_80F8DA0(void); +static void sub_80F8E80(void); +static void sub_80F8F18(void); +static void sub_80F8F2C(void); +static void sub_80F8F58(void); +static void sub_80F8F78(void); +static void sub_80F8FB4(void); + +#ifdef NONMATCHING +void HandleReadMail(struct MailStruct *arg0, MainCallback arg1, bool8 arg2) { + u16 mailDesign; + u8 buffer[4]; + u8 local1; + + unk_2000000.varFF = GAME_LANGUAGE; + + // Compiler uses [sub 1], while asm uses [ptr + FE] + unk_2000000.varFE = 1; + unk_2000000.var104 = (MainCallback) sub_80EB3FC; + unk_2000000.var108 = (MainCallback) ConvertEasyChatWordsToString; + + mailDesign = arg0->itemId - ITEM_ORANGE_MAIL; + + if (mailDesign <= 11) { + unk_2000000.varFA = arg0->itemId - ITEM_ORANGE_MAIL; + } else { + unk_2000000.varFA = 0; + arg2 = FALSE; + } + + switch (unk_2000000.var100) { + case 0: + default: + unk_2000000.var10C = &gUnknown_083E5730[unk_2000000.varFA]; + break; + + case 1: + unk_2000000.var10C = &gUnknown_083E57A4[unk_2000000.varFA]; + break; + } + + if (((sub_80A2D64(arg0->species, buffer) << 16) +0xFFFF0000) <= (410 << 16)) { + switch (unk_2000000.varFA) { + case 6: + unk_2000000.varFB = 1; + break; + + case 9: + unk_2000000.varFB = 2; + break; + + default: + unk_2000000.varFB = 0; + break; + } + } else { + unk_2000000.varFB = 0; + } + + + unk_2000000.varF4 = arg0; + unk_2000000.varEC = arg1; + unk_2000000.varF8 = arg2; + + SetMainCallback2(sub_80F8D50); +} +#else +__attribute__((naked)) +void HandleReadMail(struct MailStruct *arg0, MainCallback arg1, bool8 arg2) { + asm(".syntax unified\n\ + push {r4-r6,lr}\n\ + sub sp, 0x4\n\ + adds r4, r0, 0\n\ + adds r6, r1, 0\n\ + lsls r2, 24\n\ + lsrs r5, r2, 24\n\ + ldr r2, _080F8958 @ =0x02000000\n\ + adds r1, r2, 0\n\ + adds r1, 0xFF\n\ + movs r0, 0x2\n\ + strb r0, [r1]\n\ + adds r0, 0xFE\n\ + adds r1, r2, r0\n\ + movs r0, 0x1\n\ + strb r0, [r1]\n\ + movs r0, 0x82\n\ + lsls r0, 1\n\ + adds r1, r2, r0\n\ + ldr r0, _080F895C @ =sub_80EB3FC\n\ + str r0, [r1]\n\ + movs r0, 0x84\n\ + lsls r0, 1\n\ + adds r1, r2, r0\n\ + ldr r0, _080F8960 @ =ConvertEasyChatWordsToString\n\ + str r0, [r1]\n\ + ldrh r1, [r4, 0x20]\n\ + adds r0, r1, 0\n\ + subs r0, 0x79\n\ + lsls r0, 16\n\ + lsrs r0, 16\n\ + cmp r0, 0xB\n\ + bhi _080F8964\n\ + subs r1, 0x79\n\ + adds r0, r2, 0\n\ + adds r0, 0xFA\n\ + strb r1, [r0]\n\ + b _080F896E\n\ + .align 2, 0\n\ +_080F8958: .4byte 0x02000000\n\ +_080F895C: .4byte sub_80EB3FC\n\ +_080F8960: .4byte ConvertEasyChatWordsToString\n\ +_080F8964:\n\ + adds r1, r2, 0\n\ + adds r1, 0xFA\n\ + movs r0, 0\n\ + strb r0, [r1]\n\ + movs r5, 0\n\ +_080F896E:\n\ + ldr r1, _080F8994 @ =0x02000000\n\ + movs r2, 0x80\n\ + lsls r2, 1\n\ + adds r0, r1, r2\n\ + ldrb r0, [r0]\n\ + cmp r0, 0\n\ + beq _080F8980\n\ + cmp r0, 0x1\n\ + beq _080F899C\n\ +_080F8980:\n\ + movs r0, 0x86\n\ + lsls r0, 1\n\ + adds r2, r1, r0\n\ + adds r0, r1, 0\n\ + adds r0, 0xFA\n\ + ldrb r0, [r0]\n\ + lsls r0, 3\n\ + ldr r1, _080F8998 @ =gUnknown_083E5730\n\ + b _080F89AC\n\ + .align 2, 0\n\ +_080F8994: .4byte 0x02000000\n\ +_080F8998: .4byte gUnknown_083E5730\n\ +_080F899C:\n\ + movs r0, 0x86\n\ + lsls r0, 1\n\ + adds r2, r1, r0\n\ + adds r0, r1, 0\n\ + adds r0, 0xFA\n\ + ldrb r0, [r0]\n\ + lsls r0, 3\n\ + ldr r1, _080F89DC @ =gUnknown_083E57A4\n\ +_080F89AC:\n\ + adds r0, r1\n\ + str r0, [r2]\n\ + ldrh r0, [r4, 0x1E]\n\ + mov r1, sp\n\ + bl sub_80A2D64\n\ + lsls r0, 16\n\ + ldr r1, _080F89E0 @ =0xffff0000\n\ + adds r0, r1\n\ + movs r1, 0xCD\n\ + lsls r1, 17\n\ + cmp r0, r1\n\ + bhi _080F89F8\n\ + ldr r0, _080F89E4 @ =0x02000000\n\ + adds r1, r0, 0\n\ + adds r1, 0xFA\n\ + ldrb r2, [r1]\n\ + adds r1, r0, 0\n\ + cmp r2, 0x6\n\ + beq _080F89E8\n\ + cmp r2, 0x9\n\ + beq _080F89F0\n\ + b _080F89FA\n\ + .align 2, 0\n\ +_080F89DC: .4byte gUnknown_083E57A4\n\ +_080F89E0: .4byte 0xffff0000\n\ +_080F89E4: .4byte 0x02000000\n\ +_080F89E8:\n\ + adds r2, r1, 0\n\ + adds r2, 0xFB\n\ + movs r0, 0x1\n\ + b _080F8A00\n\ +_080F89F0:\n\ + adds r2, r1, 0\n\ + adds r2, 0xFB\n\ + movs r0, 0x2\n\ + b _080F8A00\n\ +_080F89F8:\n\ + ldr r1, _080F8A20 @ =0x02000000\n\ +_080F89FA:\n\ + adds r2, r1, 0\n\ + adds r2, 0xFB\n\ + movs r0, 0\n\ +_080F8A00:\n\ + strb r0, [r2]\n\ + adds r0, r1, 0\n\ + adds r0, 0xF4\n\ + str r4, [r0]\n\ + subs r0, 0x8\n\ + str r6, [r0]\n\ + adds r0, 0xC\n\ + strb r5, [r0]\n\ + ldr r0, _080F8A24 @ =sub_80F8D50\n\ + bl SetMainCallback2\n\ + add sp, 0x4\n\ + pop {r4-r6}\n\ + pop {r0}\n\ + bx r0\n\ + .align 2, 0\n\ +_080F8A20: .4byte 0x02000000\n\ +_080F8A24: .4byte sub_80F8D50\n\ + .syntax divided\n"); +} + +#endif + +#define RETURN_UP_STATE break +#define RETURN_SKIP_STATE return FALSE + +static u8 sub_80F8A28(void) { + switch (gMain.state) { + case 0: + SetVBlankCallback(NULL); + remove_some_task(); + REG_DISPCNT = 0; + RETURN_UP_STATE; + + case 1: CpuFill16(0, (void *) OAM, OAM_SIZE); + RETURN_UP_STATE; + + case 2: + ResetPaletteFade(); + RETURN_UP_STATE; + + case 3: + ResetTasks(); + RETURN_UP_STATE; + + case 4: + ResetSpriteData(); + RETURN_UP_STATE; + + case 5: + FreeAllSpritePalettes(); + REG_BG0HOFS = 0; + REG_BG0VOFS = 0; + REG_BG1HOFS = 0; + REG_BG1VOFS = 0; + REG_BG2VOFS = 0; + REG_BG2HOFS = 0; + REG_BG3HOFS = 0; + REG_BG3VOFS = 0; + REG_BLDCNT = 0; + REG_BLDALPHA = 0; + RETURN_UP_STATE; + + case 6: + SetUpWindowConfig(&gWindowConfig_81E6DFC); + RETURN_UP_STATE; + + case 7: + MultistepInitMenuWindowBegin(&gWindowConfig_81E6DFC); + RETURN_UP_STATE; + + case 8: + if (MultistepInitMenuWindowContinue() == 0) { + return FALSE; + } + RETURN_UP_STATE; + + case 9: + MenuZeroFillScreen(); + RETURN_UP_STATE; + + case 10: CpuFill16(1, (void *) (VRAM + 0x4800), 0x800); + RETURN_UP_STATE; + + case 11: + LoadPalette(gMailGraphicsTable[unk_2000000.varFA].palette, 0, 16 * 2); + RETURN_UP_STATE; + + case 12: + LZ77UnCompVram(gMailGraphicsTable[unk_2000000.varFA].tileMap, (void *) (VRAM + 0x4000)); + RETURN_UP_STATE; + + case 13: + LZ77UnCompVram(gMailGraphicsTable[unk_2000000.varFA].tiles, (void *) (VRAM)); + + gPlttBufferUnfaded[241] = gMailGraphicsTable[unk_2000000.varFA].color10; + gPlttBufferUnfaded[248] = gMailGraphicsTable[unk_2000000.varFA].color12; + gPlttBufferUnfaded[10] = gUnknown_083E562C[gSaveBlock2.playerGender][0]; + gPlttBufferUnfaded[11] = gUnknown_083E562C[gSaveBlock2.playerGender][1]; + RETURN_UP_STATE; + + case 14: + if (unk_2000000.varF8 != 0) { + sub_80F8DA0(); + } + RETURN_UP_STATE; + + case 15: + if (unk_2000000.varF8 != 0) { + sub_80F8E80(); + } + + SetVBlankCallback(sub_80F8F18); + gPaletteFade.bufferTransferDisabled = 1; + RETURN_UP_STATE; + + case 16: { + u16 local1; + + local1 = sub_809D4A8(unk_2000000.varF4->species); + + switch (unk_2000000.varFB) { + case 1: + sub_809D580(local1); + unk_2000000.varFC = sub_809D3A4(local1, SpriteCallbackDummy, 96, 128, 0); + break; + + case 2: + sub_809D580(local1); + unk_2000000.varFC = sub_809D3A4(local1, SpriteCallbackDummy, 40, 128, 0); + break; + } + RETURN_UP_STATE; + } + + case 17: + if (sub_8055870() != TRUE) { + RETURN_UP_STATE; + } + RETURN_SKIP_STATE; + + case 18: + REG_BG0CNT = 0x9F08; + REG_BG1CNT = 0x0801; + REG_BG2CNT = 0x0902; + REG_BLDCNT = 0; + REG_DISPCNT = DISPCNT_OBJ_1D_MAP | DISPCNT_BG0_ON | DISPCNT_BG1_ON | DISPCNT_BG2_ON | DISPCNT_OBJ_ON; + BeginNormalPaletteFade(-1, 0, 16, 0, 0); + gPaletteFade.bufferTransferDisabled = 0; + unk_2000000.varF0 = sub_80F8F58; + return TRUE; + + default: + return FALSE; + } + + gMain.state += 1; + return FALSE; +} + +void sub_80F8D50(void) { + do { + if (sub_80F8A28() == 1) { + SetMainCallback2(sub_80F8F2C); + return; + } + } while (sub_80F9344() != 1); +} + +u8 *sub_80F8D7C(u8 *dest, u8 *src) { + u16 length; + + StringCopy(dest, src); + SanitizeNameString(dest); + + length = StringLength(dest); + + return dest + length; +} + +#ifdef NONMATCHING +static void sub_80F8DA0(void) { + u8 local0; + + local0 = unk_2000000.var10C->var0; + + // No idea what's happening in this loop. + if (local0 <= 0) { + u8 i; + u8 i2 = 0; + + for (i = 0; i < unk_2000000.var10C->var0; i++) { + ConvertEasyChatWordsToString(unk_2000000.words[i], &unk_2000000.varF4->words[i2], + ((*unk_2000000.var10C->var4)[i] << 28) >> 30, 1); + i2 += ((*unk_2000000.var10C->var4)[i] << 28) >> 30; + } + } + + if (unk_2000000.var100 == 0) { + u8 *ptr; + u16 length; + + ptr = sub_80F8D7C(unk_2000000.varD8, unk_2000000.varF4->playerName); + StringCopy(ptr, gOtherText_From); + + length = StringLength(unk_2000000.varD8); + + unk_2000000.varF9 = unk_2000000.var10C->var2 - length; + } else { + u8 *ptr; + + ptr = StringCopy(unk_2000000.varD8, gOtherText_From); + sub_80F8D7C(ptr, unk_2000000.varF4->playerName); + + unk_2000000.varF9 = unk_2000000.var10C->var2; + } +} +#else +__attribute__((naked)) +static void sub_80F8DA0(void) { + asm(".syntax unified\n\ + push {r4-r7,lr}\n\ + mov r7, r8\n\ + push {r7}\n\ + movs r6, 0\n\ + movs r5, 0\n\ + ldr r2, _080F8E3C @ =0x02000000\n\ + movs r0, 0x86\n\ + lsls r0, 1\n\ + adds r1, r2, r0\n\ + ldr r0, [r1]\n\ + ldrb r0, [r0]\n\ + cmp r5, r0\n\ + bcs _080F8E04\n\ + mov r8, r2\n\ + adds r7, r1, 0\n\ +_080F8DBE:\n\ + lsls r0, r5, 3\n\ + subs r0, r5\n\ + lsls r0, 2\n\ + subs r0, r5\n\ + add r0, r8\n\ + mov r1, r8\n\ + adds r1, 0xF4\n\ + lsls r2, r6, 1\n\ + ldr r1, [r1]\n\ + adds r1, r2\n\ + ldr r2, [r7]\n\ + ldr r2, [r2, 0x4]\n\ + lsls r4, r5, 2\n\ + adds r2, r4, r2\n\ + ldr r2, [r2]\n\ + lsls r2, 28\n\ + lsrs r2, 30\n\ + movs r3, 0x1\n\ + bl ConvertEasyChatWordsToString\n\ + ldr r1, [r7]\n\ + ldr r0, [r1, 0x4]\n\ + adds r4, r0\n\ + ldr r0, [r4]\n\ + lsls r0, 28\n\ + lsrs r0, 30\n\ + adds r0, r6, r0\n\ + lsls r0, 24\n\ + lsrs r6, r0, 24\n\ + adds r0, r5, 0x1\n\ + lsls r0, 16\n\ + lsrs r5, r0, 16\n\ + ldrb r1, [r1]\n\ + cmp r5, r1\n\ + bcc _080F8DBE\n\ +_080F8E04:\n\ + ldr r2, _080F8E40 @ =0x020000d8\n\ + adds r4, r2, 0\n\ + subs r4, 0xD8\n\ + adds r0, r2, 0\n\ + adds r0, 0x28\n\ + ldrb r0, [r0]\n\ + cmp r0, 0\n\ + bne _080F8E48\n\ + ldr r1, [r2, 0x1C]\n\ + adds r1, 0x12\n\ + adds r0, r2, 0\n\ + bl sub_80F8D7C\n\ + adds r2, r0, 0\n\ + ldr r1, _080F8E44 @ =gOtherText_From\n\ + bl StringCopy\n\ + ldr r0, _080F8E40 @ =0x020000d8\n\ + bl StringLength\n\ + movs r2, 0x86\n\ + lsls r2, 1\n\ + adds r1, r4, r2\n\ + ldr r1, [r1]\n\ + ldrb r1, [r1, 0x2]\n\ + subs r1, r0\n\ + b _080F8E6A\n\ + .align 2, 0\n\ +_080F8E3C: .4byte 0x02000000\n\ +_080F8E40: .4byte 0x020000d8\n\ +_080F8E44: .4byte gOtherText_From\n\ +_080F8E48:\n\ + ldr r1, _080F8E7C @ =gOtherText_From\n\ + adds r0, r2, 0\n\ + bl StringCopy\n\ + adds r2, r0, 0\n\ + adds r0, r4, 0\n\ + adds r0, 0xF4\n\ + ldr r1, [r0]\n\ + adds r1, 0x12\n\ + adds r0, r2, 0\n\ + bl sub_80F8D7C\n\ + movs r1, 0x86\n\ + lsls r1, 1\n\ + adds r0, r4, r1\n\ + ldr r0, [r0]\n\ + ldrb r1, [r0, 0x2]\n\ +_080F8E6A:\n\ + adds r0, r4, 0\n\ + adds r0, 0xF9\n\ + strb r1, [r0]\n\ + pop {r3}\n\ + mov r8, r3\n\ + pop {r4-r7}\n\ + pop {r0}\n\ + bx r0\n\ + .align 2, 0\n\ +_080F8E7C: .4byte gOtherText_From\n\ + .syntax divided\n"); +} +#endif + +static void sub_80F8E80(void) { + u16 pos; + u8 x; + u8 y = 0; + + for (pos = 0; pos < unk_2000000.var10C->var0; pos++) { + if (unk_2000000.words[pos][0] == 0xFF) { + continue; + } + + if (unk_2000000.words[pos][0] == 0x00) { + continue; + } + + x = unk_2000000.var10C->var4[pos].unk_0_4; + y += unk_2000000.var10C->var4[pos].unk_0_0; + MenuPrint(unk_2000000.words[pos], unk_2000000.var10C->var3_4 + x, unk_2000000.var10C->var3_0 + y); + y += 2; + } + + MenuPrint(unk_2000000.varD8, unk_2000000.varF9, unk_2000000.var10C->var1); +} + +static void sub_80F8F18(void) { + LoadOam(); + ProcessSpriteCopyRequests(); + TransferPlttBuffer(); +} + +static void sub_80F8F2C(void) { + if(unk_2000000.varFB != 0) { + AnimateSprites(); + BuildOamBuffer(); + } + + unk_2000000.varF0(); +} + +static void sub_80F8F58(void) { + u8 local0; + + local0 = UpdatePaletteFade(); + if(local0 == 0) { + unk_2000000.varF0 = sub_80F8F78; + } +} + +static void sub_80F8F78(void) { + if (gMain.newKeys & (A_BUTTON | B_BUTTON)) { + BeginNormalPaletteFade(-1, 0, 0, 16, 0); + unk_2000000.varF0 = sub_80F8FB4; + } +} + +static void sub_80F8FB4(void) { + u16 local1; + + if (UpdatePaletteFade()) { + return; + } + + SetMainCallback2(unk_2000000.varEC); + switch (unk_2000000.varFB) { + case 2: + case 1: + local1 = sub_809D4A8(unk_2000000.varF4->species); + sub_809D608(local1); + + sub_809D510(&gSprites[unk_2000000.varFC]); + break; + } + + memset(&unk_2000000, 0, 0x110); + ResetPaletteFade(); +} diff --git a/src/main.c b/src/main.c index ef7e76df6..76ac3d6d9 100644 --- a/src/main.c +++ b/src/main.c @@ -1,11 +1,17 @@ #include "global.h" -#include "gba/m4a_internal.h" -#include "gba/flash_internal.h" -#include "siirtc.h" #include "main.h" -#include "rtc.h" +#include "asm.h" +#include "gba/flash_internal.h" +#include "gba/m4a_internal.h" +#include "intro.h" #include "link.h" +#include "load_save.h" +#include "m4a.h" +#include "play_time.h" #include "rng.h" +#include "rom4.h" +#include "rtc.h" +#include "siirtc.h" #include "sound.h" extern struct SoundInfo gSoundInfo; @@ -26,7 +32,7 @@ static void IntrDummy(void); const u8 gGameVersion = GAME_VERSION; -const u8 gGameLanguage = 2; // English +const u8 gGameLanguage = GAME_LANGUAGE; // English const char BuildDateTime[] = "2002 10 15 20:34"; @@ -54,21 +60,13 @@ u16 gKeyRepeatStartDelay; u8 gUnknown_3001764; struct Main gMain; u16 gKeyRepeatContinueDelay; -u8 gUnknown_3001BB4; +u8 gSoftResetDisabled; IntrFunc gIntrTable[INTR_COUNT]; bool8 gLinkVSyncDisabled; u32 IntrMain_Buffer[0x200]; u8 gPcmDmaCounter; -EWRAM_DATA void (*gFlashTimerIntrFunc)(void) = NULL; - -extern void sub_800C35C(void); -extern void remove_some_task(void); -extern void c2_copyright_1(); -extern u32 sub_80558AC(void); -extern u32 sub_8055910(void); -extern u32 sub_8055940(void); -extern void CheckForFlashMemory(void); +EWRAM_DATA void (**gFlashTimerIntrFunc)(void) = NULL; static void UpdateLinkAndCallCallbacks(void); static void InitMainCallbacks(void); @@ -93,7 +91,7 @@ void AgbMain() InitMapMusic(); SeedRngWithRtc(); - gUnknown_3001BB4 = 0; + gSoftResetDisabled = FALSE; if (gUnknown_3004820 != 1) SetMainCallback2(0); @@ -104,7 +102,7 @@ void AgbMain() { ReadKeys(); - if (!gUnknown_3001BB4 + if (gSoftResetDisabled == FALSE && (gMain.heldKeysRaw & A_BUTTON) && (gMain.heldKeysRaw & B_START_SELECT) == B_START_SELECT) DoSoftReset(); @@ -335,8 +333,7 @@ static void SerialIntr(void) } static void IntrDummy(void) -{ -} +{} static void WaitForVBlank(void) { diff --git a/src/main_menu.c b/src/main_menu.c index 966f93f0d..7adbda096 100644 --- a/src/main_menu.c +++ b/src/main_menu.c @@ -1,42 +1,49 @@ #include "global.h" -#include "text.h" -#include "sprite.h" -#include "task.h" -#include "main.h" +#include "main_menu.h" +#include "asm.h" +#include "decompress.h" +#include "menu.h" +#include "mystery_event_menu.h" +#include "option_menu.h" +#include "palette.h" +#include "rom4.h" #include "rtc.h" +#include "save_menu_util.h" #include "songs.h" -#include "palette.h" -#include "string_util.h" -#include "species.h" -#include "pokemon.h" -#include "menu.h" #include "sound.h" +#include "species.h" +#include "string_util.h" +#include "task.h" +#include "text.h" +#include "title_screen.h" +#include "event_data.h" #define BirchSpeechUpdateWindowText() ((u8)MenuUpdateWindowText_OverrideLineLength(24)) -extern void remove_some_task(void); -extern void CreatePokeballSprite(u8 r0, u8 r1, u8 r2, u8 r3, u8 s1, u8 s2, u8 s3, u16 s4); -extern bool32 IsMysteryGiftAvailable(void); -extern void CB2_ContinueSavedGame(void); -extern void CB2_InitMysteryEventMenu(void); -extern void CB2_InitOptionMenu(void); -extern void CB2_InitTitleScreen(void); -extern void FormatPlayTime(u8 *str, u16 hours, u16 minutes, bool16 colon); -extern u16 GetPokedexSeenCount(void); -extern u8 GetBadgeCount(void); -extern void DoNamingScreen(u8 r0, struct SaveBlock2 *r1, u16 r2, u16 r3, u8 s0, MainCallback s4); -extern void CB2_NewGame(void); -extern void DecompressPicFromTable_2(const struct SpriteSheet *, u8, u8, void *, void *, u32); -extern void LoadCompressedObjectPalette(const struct SpritePalette *); -extern u8 CreateBirchSprite(u8, u8, u8); -extern u8 CreateTrainerSprite_BirchSpeech(u8, u16, u16, u8, void *); +struct MonCoords +{ + u8 x, y; +}; extern struct PaletteFadeControl gPaletteFade; + +extern u16 gSaveFileStatus; + +extern u16 gMainMenuPalette[]; + +extern const u8 gBirchSpeech_Welcome[]; +extern const u8 gBirchSpeech_ThisIsPokemon[]; +extern const u8 gBirchSpeech_WorldInhabitedByPokemon[]; +extern const u8 gBirchSpeech_AndYouAre[]; +extern const u8 gBirchSpeech_AreYouBoyOrGirl[]; +extern const u8 gBirchSpeech_WhatsYourName[]; +extern u8 gBirchSpeech_SoItsPlayer[]; +extern u8 gBirchSpeech_AhOkayYouArePlayer[]; +extern u8 gBirchSpeech_AreYouReady[]; extern u8 gSaveFileDeletedMessage[]; extern u8 gSaveFileCorruptMessage[]; extern u8 gBoardNotInstalledMessage[]; extern u8 gBatteryDryMessage[]; -extern u16 gSaveFileStatus; extern u8 gMainMenuString_Continue[]; extern u8 gMainMenuString_NewGame[]; extern u8 gMainMenuString_MysteryEvents[]; @@ -46,10 +53,57 @@ extern u8 gMainMenuString_Time[]; extern u8 gMainMenuString_Pokedex[]; extern u8 gMainMenuString_Badges[]; -void CB2_MainMenu(void); -void VBlankCB_MainMenu(void); -void CB2_InitMainMenu(void); -static void sub_80096FC(void); +extern const struct MonCoords gMonFrontPicCoords[]; +extern const struct SpriteSheet gMonFrontPicTable[]; +extern const struct SpritePalette gMonPaletteTable[]; +extern struct SpriteTemplate gUnknown_02024E8C; +extern void * const gUnknown_081FAF4C[]; +extern u16 gUnknown_081E795C[]; +extern const struct MenuAction gUnknown_081E79B0[]; +extern const struct MenuAction gMalePresetNames[]; +extern const struct MenuAction gFemalePresetNames[]; + +extern const u8 gUnknown_081E764C[]; +extern const u8 gBirchIntroShadowGfx[]; +extern const u8 gUnknown_081E7834[]; +extern const u8 gUnknown_081E796C[]; +extern const u8 gSystemText_NewPara[]; + +extern u8 gSpriteAffineAnimTable_81E79AC[]; + +extern u8 gStringVar4[]; + +extern u8 unk_2000000[]; + +//Task data +enum { + TD_MENULAYOUT, + TD_SELECTEDMENUITEM, +}; + +//Menu layouts +enum { + HAS_NO_SAVED_GAME, //NEW GAME, OPTION + HAS_SAVED_GAME, //CONTINUE, NEW GAME, OPTION + HAS_MYSTERY_GIFT, //CONTINUE, NEW GAME, MYSTERY EVENTS, OPTION +}; + +//Task data +enum { + TD_TRAINER_SPRITE_ID = 2, //Trainer sprite being displayed during gender menu + TD_BGHOFS = 4, //Used to set REG_BG1HOFS and slide the platform around + TD_SUBTASK_DONE, //Set to true if the spawned task has finished + TD_GENDER_SELECTION, + TD_COUNTER, + TD_BIRCH_SPRITE_ID, + TD_AZURILL_SPRITE_ID, + TD_BRENDAN_SPRITE_ID, + TD_MAY_SPRITE_ID +}; + +static void CB2_MainMenu(void); +static void VBlankCB_MainMenu(void); +static void CB2_InitMainMenuFromOptions(void); static u32 InitMainMenu(bool8 a1); static void Task_MainMenuCheckSave(u8 taskId); static void Task_MainMenuWaitForSaveErrorAck(u8 taskId); @@ -61,31 +115,66 @@ static bool8 MainMenuProcessKeyInput(u8 taskId); static void Task_MainMenuProcessKeyInput(u8 taskId); static void Task_MainMenuPressedA(u8 taskId); static void Task_MainMenuPressedB(u8 taskId); -static void HighlightCurrentMenuItem(u8, u8); -static void PrintMainMenuItem(u8 *text, u8, u8); +static void HighlightCurrentMenuItem(u8 layout, u8 menuItem); +static void PrintMainMenuItem(u8 *text, u8 left, u8 top); static void PrintSaveFileInfo(void); static void PrintPlayerName(void); static void PrintPlayTime(void); static void PrintPokedexCount(void); static void PrintBadgeCount(void); -void Task_NewGameSpeech1(u8); - -extern u16 gMainMenuPalette[]; - -//Task data -enum { - TD_MENULAYOUT, - TD_SELECTEDMENUITEM, -}; - -//Menu layouts -enum { - HAS_NO_SAVED_GAME, //NEW GAME, OPTION - HAS_SAVED_GAME, //CONTINUE, NEW GAME, OPTION - HAS_MYSTERY_GIFT, //CONTINUE, NEW GAME, MYSTERY EVENTS, OPTION -}; - -void CB2_MainMenu(void) +static void Task_NewGameSpeech1(u8 taskId); +static void Task_NewGameSpeech2(u8 taskId); +static void Task_NewGameSpeech3(u8 taskId); +static void Task_NewGameSpeech4(u8 taskId); +static void Task_NewGameSpeech5(u8 taskId); +static void Task_NewGameSpeech6(u8 taskId); +static void Task_NewGameSpeech7(u8 taskId); +static void Task_NewGameSpeech8(u8 taskId); +static void Task_NewGameSpeech9(u8 taskId); +static void Task_NewGameSpeech10(u8 taskId); +static void Task_NewGameSpeech11(u8 taskId); +static void Task_NewGameSpeech12(u8 taskId); +static void Task_NewGameSpeech13(u8 taskId); +static void Task_NewGameSpeech14(u8 taskId); +static void Task_NewGameSpeech15(u8 taskId); +static void Task_NewGameSpeech16(u8 taskId); +static void Task_NewGameSpeech17(u8 taskId); +static void Task_NewGameSpeech18(u8 taskId); +static void Task_NewGameSpeech19(u8 taskId); +static void Task_NewGameSpeech20(u8 taskId); +static void Task_NewGameSpeech21(u8 taskId); +static void Task_NewGameSpeech22(u8 taskId); +static void Task_NewGameSpeech23(u8 taskId); +static void Task_NewGameSpeech24(u8 taskId); +static void Task_NewGameSpeech25(u8 taskId); +static void Task_NewGameSpeech26(u8 taskId); +static void Task_NewGameSpeech27(u8 taskId); +static void Task_NewGameSpeech28(u8 taskId); +static void Task_NewGameSpeech29(u8 taskId); +static void Task_NewGameSpeech30(u8 taskId); +static void Task_NewGameSpeech31(u8 taskId); +static void Task_NewGameSpeech32(u8 taskId); +static void Task_NewGameSpeech33(u8 taskId); +static void CB_ContinueNewGameSpeechPart2(); +static void nullsub_34(struct Sprite *sprite); +static void ShrinkPlayerSprite(struct Sprite *sprite); +static u8 CreateAzurillSprite(u8 x, u8 y); +static void AddBirchSpeechObjects(u8 taskId); +static void Task_SpriteFadeOut(u8 taskId); +static void StartSpriteFadeOut(u8 taskId, u8 interval); +static void Task_SpriteFadeIn(u8 taskId); +static void StartSpriteFadeIn(u8 taskId, u8 interval); +static void HandleFloorShadowFadeOut(u8 taskId); +static void StartBackgroundFadeOut(u8 taskId, u8 interval); +static void HandleFloorShadowFadeIn(u8 taskId); +static void StartBackgroundFadeIn(u8 taskId, u8 interval); +static void CreateGenderMenu(u8 left, u8 top); +static s8 GenderMenuProcessInput(void); +static void CreateNameMenu(u8 left, u8 top); +static s8 NameMenuProcessInput(void); +static void SetPresetPlayerName(u8 index); + +static void CB2_MainMenu(void) { RunTasks(); AnimateSprites(); @@ -105,7 +194,7 @@ void CB2_InitMainMenu(void) InitMainMenu(FALSE); } -static void sub_80096FC(void) +static void CB2_InitMainMenuFromOptions(void) { InitMainMenu(TRUE); } @@ -189,7 +278,7 @@ void Task_MainMenuCheckSave(u8 taskId) switch (gSaveFileStatus) { case 1: - if (IsMysteryGiftAvailable() == TRUE) + if (IsMysteryGiftEnabled() == TRUE) gTasks[taskId].data[TD_MENULAYOUT] = HAS_MYSTERY_GIFT; else gTasks[taskId].data[TD_MENULAYOUT] = HAS_SAVED_GAME; @@ -212,7 +301,7 @@ void Task_MainMenuCheckSave(u8 taskId) gTasks[taskId].data[TD_MENULAYOUT] = HAS_SAVED_GAME; gTasks[taskId].func = Task_MainMenuWaitForSaveErrorAck; - if (IsMysteryGiftAvailable() == TRUE) + if (IsMysteryGiftEnabled() == TRUE) gTasks[taskId].data[TD_MENULAYOUT] = HAS_MYSTERY_GIFT; else gTasks[taskId].data[TD_MENULAYOUT] = HAS_SAVED_GAME; @@ -493,7 +582,7 @@ void Task_MainMenuPressedA(u8 taskId) DestroyTask(taskId); break; case OPTION: - gMain.field_8 = sub_80096FC; + gMain.savedCallback = CB2_InitMainMenuFromOptions; SetMainCallback2(CB2_InitOptionMenu); DestroyTask(taskId); break; @@ -628,109 +717,7 @@ void PrintBadgeCount(void) MenuPrint_PixelCoords(buffer, 205, 40, 1); } -//Text Strings -extern const u8 gBirchSpeech_Welcome[]; -extern const u8 gBirchSpeech_ThisIsPokemon[]; -extern const u8 gBirchSpeech_WorldInhabitedByPokemon[]; -extern const u8 gBirchSpeech_AndYouAre[]; -extern const u8 gBirchSpeech_AreYouBoyOrGirl[]; -extern const u8 gBirchSpeech_WhatsYourName[]; -extern u8 gBirchSpeech_SoItsPlayer[]; -extern u8 gBirchSpeech_AhOkayYouArePlayer[]; -extern u8 gBirchSpeech_AreYouReady[]; - -struct MonCoords -{ - u8 x, y; -}; - -extern const struct MonCoords gMonFrontPicCoords[]; -extern const struct SpriteSheet gMonFrontPicTable[]; -extern const struct SpritePalette gMonPaletteTable[]; -extern struct SpriteTemplate gUnknown_02024E8C; -extern void * const gUnknown_081FAF4C[]; -extern u16 gUnknown_081E795C[]; -extern u8 * const gUnknown_081E79B0[][2]; -extern u8 * const gMalePresetNames[][2]; -extern u8 * const gFemalePresetNames[][2]; - -extern const u8 gUnknown_081E764C[]; -extern const u8 gUnknown_081E768C[]; -extern const u8 gUnknown_081E7834[]; -extern const u8 gUnknown_081E796C[]; -extern const u8 gSystemText_NewPara[]; - -extern u8 gSpriteAffineAnimTable_81E79AC[]; - -extern u8 gStringVar4[]; - -extern u8 unk_2000000[]; - -void Task_NewGameSpeech2(u8 taskId); -void Task_NewGameSpeech3(u8 taskId); -void Task_NewGameSpeech4(u8 taskId); -void Task_NewGameSpeech5(u8 taskId); -void Task_NewGameSpeech6(u8 taskId); -void Task_NewGameSpeech7(u8 taskId); -void Task_NewGameSpeech8(u8 taskId); -void Task_NewGameSpeech9(u8 taskId); -void Task_NewGameSpeech10(u8 taskId); -void Task_NewGameSpeech11(u8 taskId); -void Task_NewGameSpeech12(u8 taskId); -void Task_NewGameSpeech13(u8 taskId); -void Task_NewGameSpeech14(u8 taskId); -void Task_NewGameSpeech15(u8 taskId); -void Task_NewGameSpeech16(u8 taskId); -void Task_NewGameSpeech17(u8 taskId); -void Task_NewGameSpeech18(u8 taskId); -void Task_NewGameSpeech19(u8 taskId); -void Task_NewGameSpeech20(u8 taskId); -void Task_NewGameSpeech21(u8 taskId); -void Task_NewGameSpeech22(u8 taskId); -void Task_NewGameSpeech23(u8 taskId); -void Task_NewGameSpeech24(u8 taskId); -void Task_NewGameSpeech25(u8 taskId); -void Task_NewGameSpeech26(u8 taskId); -void Task_NewGameSpeech27(u8 taskId); -void Task_NewGameSpeech28(u8 taskId); -void Task_NewGameSpeech29(u8 taskId); -void Task_NewGameSpeech30(u8 taskId); -void Task_NewGameSpeech31(u8 taskId); -void Task_NewGameSpeech32(u8 taskId); -void Task_NewGameSpeech33(u8 taskId); -void CB_ContinueNewGameSpeechPart2(); -void nullsub_34(struct Sprite *sprite); -void sub_800B240(struct Sprite *sprite); -u8 CreateAzurillSprite(u8, u8); -void AddBirchSpeechObjects(u8); -void sub_800B3EC(u8); -void StartSpriteFadeOut(u8, u8); -void Task_StartSpriteFadeIn(u8); -void StartSpriteFadeIn(u8 taskId, u8 a); -void sub_800B5A8(u8); -void StartBackgroundFadeOut(u8, u8); -void sub_800B654(u8); -void StartBackgroundFadeIn(u8 taskId, u8 a); -void CreateGenderMenu(u8 left, u8 top); -s8 GenderMenuProcessInput(void); -void CreateNameMenu(u8 a, u8 b); -s8 NameMenuProcessInput(void); -void SetPresetPlayerName(u8 a); - -//Task data -enum { - TD_TRAINER_SPRITE_ID = 2, //Trainer sprite being displayed during gender menu - TD_BGHOFS = 4, //Used to set REG_BG1HOFS and slide the platform around - TD_SUBTASK_DONE, //Set to true if the spawned task has finished - TD_GENDER_SELECTION, - TD_COUNTER, - TD_BIRCH_SPRITE_ID, - TD_AZURILL_SPRITE_ID, - TD_BRENDAN_SPRITE_ID, - TD_MAY_SPRITE_ID -}; - -void Task_NewGameSpeech1(u8 taskId) +static void Task_NewGameSpeech1(u8 taskId) { SetUpWindowConfig(&gWindowConfig_81E6C3C); InitMenuWindow((struct WindowConfig *)&gWindowConfig_81E6CE4); @@ -741,7 +728,7 @@ void Task_NewGameSpeech1(u8 taskId) REG_BLDCNT = 0; REG_BLDALPHA = 0; REG_BLDY = 0; - LZ77UnCompVram(gUnknown_081E768C, (void *)BG_VRAM); + LZ77UnCompVram(gBirchIntroShadowGfx, (void *)BG_VRAM); LZ77UnCompVram(gUnknown_081E7834, (void *)(BG_VRAM + 0x3800)); LoadPalette(gUnknown_081E764C, 0, 0x40); LoadPalette(gUnknown_081E796C, 1, 0x10); @@ -761,7 +748,7 @@ void Task_NewGameSpeech1(u8 taskId) PlayBGM(BGM_DOORO_X4); } -void Task_NewGameSpeech2(u8 taskId) +static void Task_NewGameSpeech2(u8 taskId) { if (gTasks[taskId].data[TD_COUNTER] != 0) { @@ -783,7 +770,7 @@ void Task_NewGameSpeech2(u8 taskId) } } -void Task_NewGameSpeech3(u8 taskId) +static void Task_NewGameSpeech3(u8 taskId) { if (gTasks[taskId].data[TD_SUBTASK_DONE] != FALSE) { @@ -803,7 +790,7 @@ void Task_NewGameSpeech3(u8 taskId) } } -void Task_NewGameSpeech4(u8 taskId) +static void Task_NewGameSpeech4(u8 taskId) { if (!gPaletteFade.active && BirchSpeechUpdateWindowText()) { @@ -813,13 +800,13 @@ void Task_NewGameSpeech4(u8 taskId) } } -void Task_NewGameSpeech5(u8 taskId) +static void Task_NewGameSpeech5(u8 taskId) { if (BirchSpeechUpdateWindowText()) gTasks[taskId].func = Task_NewGameSpeech6; } -void Task_NewGameSpeech6(u8 taskId) +static void Task_NewGameSpeech6(u8 taskId) { u8 spriteId = gTasks[taskId].data[TD_AZURILL_SPRITE_ID]; @@ -832,7 +819,7 @@ void Task_NewGameSpeech6(u8 taskId) gTasks[taskId].data[TD_COUNTER] = 0; } -void Task_NewGameSpeech7(u8 taskId) +static void Task_NewGameSpeech7(u8 taskId) { if (IsCryFinished()) { @@ -853,7 +840,7 @@ void Task_NewGameSpeech7(u8 taskId) } } -void Task_NewGameSpeech8(u8 taskId) +static void Task_NewGameSpeech8(u8 taskId) { if (BirchSpeechUpdateWindowText()) { @@ -864,7 +851,7 @@ void Task_NewGameSpeech8(u8 taskId) } } -void Task_NewGameSpeech9(u8 taskId) +static void Task_NewGameSpeech9(u8 taskId) { if (BirchSpeechUpdateWindowText()) { @@ -875,7 +862,7 @@ void Task_NewGameSpeech9(u8 taskId) } } -void Task_NewGameSpeech10(u8 taskId) +static void Task_NewGameSpeech10(u8 taskId) { if (BirchSpeechUpdateWindowText()) { @@ -889,7 +876,7 @@ void Task_NewGameSpeech10(u8 taskId) } //Slide platform away to the right -void Task_NewGameSpeech11(u8 taskId) +static void Task_NewGameSpeech11(u8 taskId) { if (gTasks[taskId].data[TD_BGHOFS] != -60) { @@ -903,7 +890,7 @@ void Task_NewGameSpeech11(u8 taskId) } } -void Task_NewGameSpeech12(u8 taskId) +static void Task_NewGameSpeech12(u8 taskId) { if (gTasks[taskId].data[TD_SUBTASK_DONE]) { @@ -933,7 +920,7 @@ void Task_NewGameSpeech12(u8 taskId) } } -void Task_NewGameSpeech13(u8 taskId) +static void Task_NewGameSpeech13(u8 taskId) { if (gTasks[taskId].data[TD_SUBTASK_DONE]) { @@ -942,7 +929,7 @@ void Task_NewGameSpeech13(u8 taskId) } } -void Task_NewGameSpeech14(u8 taskId) +static void Task_NewGameSpeech14(u8 taskId) { MenuDrawTextWindow(2, 13, 27, 18); //"Are you a boy? Or are you a girl?" @@ -950,7 +937,7 @@ void Task_NewGameSpeech14(u8 taskId) gTasks[taskId].func = Task_NewGameSpeech15; } -void Task_NewGameSpeech15(u8 taskId) +static void Task_NewGameSpeech15(u8 taskId) { if (BirchSpeechUpdateWindowText()) { @@ -960,7 +947,7 @@ void Task_NewGameSpeech15(u8 taskId) } //Process gender menu -void Task_NewGameSpeech16(u8 taskId) +static void Task_NewGameSpeech16(u8 taskId) { u8 cursorPos; @@ -995,7 +982,7 @@ void Task_NewGameSpeech16(u8 taskId) } //Slide old trainer sprite off right of screen -void Task_NewGameSpeech17(u8 taskId) +static void Task_NewGameSpeech17(u8 taskId) { u8 spriteId = gTasks[taskId].data[TD_TRAINER_SPRITE_ID]; @@ -1006,7 +993,7 @@ void Task_NewGameSpeech17(u8 taskId) else { gSprites[spriteId].invisible = TRUE; - + //Set up new trainer sprite if (gTasks[taskId].data[TD_GENDER_SELECTION]) spriteId = gTasks[taskId].data[TD_MAY_SPRITE_ID]; @@ -1023,7 +1010,7 @@ void Task_NewGameSpeech17(u8 taskId) } //Slide new trainer sprite from right of screen -void Task_NewGameSpeech18(u8 taskId) +static void Task_NewGameSpeech18(u8 taskId) { u8 spriteId = gTasks[taskId].data[TD_TRAINER_SPRITE_ID]; @@ -1034,7 +1021,7 @@ void Task_NewGameSpeech18(u8 taskId) else { gSprites[spriteId].pos1.x = 180; - if (gTasks[taskId].data[5]) + if (gTasks[taskId].data[TD_SUBTASK_DONE]) { gSprites[spriteId].oam.objMode = ST_OAM_OBJ_NORMAL; gTasks[taskId].func = Task_NewGameSpeech16; //Go back to gender menu @@ -1042,7 +1029,7 @@ void Task_NewGameSpeech18(u8 taskId) } } -void Task_NewGameSpeech19(u8 taskId) +static void Task_NewGameSpeech19(u8 taskId) { MenuDrawTextWindow(2, 13, 27, 18); //"All right. What's your name?" @@ -1050,7 +1037,7 @@ void Task_NewGameSpeech19(u8 taskId) gTasks[taskId].func = Task_NewGameSpeech20; } -void Task_NewGameSpeech20(u8 taskId) +static void Task_NewGameSpeech20(u8 taskId) { if (BirchSpeechUpdateWindowText()) { @@ -1060,7 +1047,7 @@ void Task_NewGameSpeech20(u8 taskId) } //Handle name menu selection -void Task_NewGameSpeech21(u8 taskId) +static void Task_NewGameSpeech21(u8 taskId) { s8 selection = NameMenuProcessInput(); @@ -1091,7 +1078,7 @@ void Task_NewGameSpeech21(u8 taskId) } //Open naming screen -void Task_NewGameSpeech22(u8 taskId) +static void Task_NewGameSpeech22(u8 taskId) { if (!gPaletteFade.active) { @@ -1100,7 +1087,7 @@ void Task_NewGameSpeech22(u8 taskId) } } -void Task_NewGameSpeech23(u8 taskId) +static void Task_NewGameSpeech23(u8 taskId) { MenuDrawTextWindow(2, 13, 27, 18); //"So it's (PLAYER)?" @@ -1109,7 +1096,7 @@ void Task_NewGameSpeech23(u8 taskId) gTasks[taskId].func = Task_NewGameSpeech24; } -void Task_NewGameSpeech24(u8 taskId) +static void Task_NewGameSpeech24(u8 taskId) { if (BirchSpeechUpdateWindowText()) { @@ -1119,7 +1106,7 @@ void Task_NewGameSpeech24(u8 taskId) } //Handle yes/no menu selection -void Task_NewGameSpeech25(u8 taskId) +static void Task_NewGameSpeech25(u8 taskId) { switch (ProcessMenuInputNoWrap_()) { @@ -1140,7 +1127,7 @@ void Task_NewGameSpeech25(u8 taskId) } } -void Task_NewGameSpeech26(u8 taskId) +static void Task_NewGameSpeech26(u8 taskId) { if (gTasks[taskId].data[TD_BGHOFS]) { @@ -1153,7 +1140,7 @@ void Task_NewGameSpeech26(u8 taskId) } } -void Task_NewGameSpeech27(u8 taskId) +static void Task_NewGameSpeech27(u8 taskId) { if (gTasks[taskId].data[TD_SUBTASK_DONE]) { @@ -1188,7 +1175,7 @@ void Task_NewGameSpeech27(u8 taskId) } } -void Task_NewGameSpeech28(u8 taskId) +static void Task_NewGameSpeech28(u8 taskId) { if (gTasks[taskId].data[TD_SUBTASK_DONE]) { @@ -1216,7 +1203,7 @@ void Task_NewGameSpeech28(u8 taskId) } } -void Task_NewGameSpeech29(u8 taskId) +static void Task_NewGameSpeech29(u8 taskId) { if (gTasks[taskId].data[TD_SUBTASK_DONE]) { @@ -1235,7 +1222,7 @@ void Task_NewGameSpeech29(u8 taskId) else { u8 spriteId; - + //Fade in trainer and background if (gSaveBlock2.playerGender) spriteId = (u8)gTasks[taskId].data[TD_MAY_SPRITE_ID]; @@ -1256,7 +1243,7 @@ void Task_NewGameSpeech29(u8 taskId) } } -void Task_NewGameSpeech30(u8 taskId) +static void Task_NewGameSpeech30(u8 taskId) { if (gTasks[taskId].data[TD_SUBTASK_DONE]) { @@ -1274,7 +1261,7 @@ void Task_NewGameSpeech30(u8 taskId) gSprites[spriteId].affineAnims = (union AffineAnimCmd **)gSpriteAffineAnimTable_81E79AC; InitSpriteAffineAnim(&gSprites[spriteId]); StartSpriteAffineAnim(&gSprites[spriteId], 0); - gSprites[spriteId].callback = sub_800B240; + gSprites[spriteId].callback = ShrinkPlayerSprite; BeginNormalPaletteFade(0x0000FFFF, 0, 0, 0x10, 0); FadeOutBGM(4); gTasks[taskId].func = Task_NewGameSpeech31; @@ -1282,7 +1269,7 @@ void Task_NewGameSpeech30(u8 taskId) } } -void Task_NewGameSpeech31(u8 taskId) +static void Task_NewGameSpeech31(u8 taskId) { u8 spriteId = gTasks[taskId].data[TD_TRAINER_SPRITE_ID]; @@ -1290,7 +1277,7 @@ void Task_NewGameSpeech31(u8 taskId) gTasks[taskId].func = Task_NewGameSpeech32; } -void Task_NewGameSpeech32(u8 taskId) +static void Task_NewGameSpeech32(u8 taskId) { if (!gPaletteFade.active) { @@ -1302,7 +1289,7 @@ void Task_NewGameSpeech32(u8 taskId) } } -void Task_NewGameSpeech33(u8 taskId) +static void Task_NewGameSpeech33(u8 taskId) { if (!gPaletteFade.active) { @@ -1339,7 +1326,7 @@ void CB_ContinueNewGameSpeechPart2() ResetPaletteFade(); - LZ77UnCompVram(gUnknown_081E768C, (void *)BG_VRAM); + LZ77UnCompVram(gBirchIntroShadowGfx, (void *)BG_VRAM); LZ77UnCompVram(gUnknown_081E7834, (void *)(BG_VRAM + 0x3800)); LoadPalette(gUnknown_081E764C, 0, 0x40); @@ -1360,12 +1347,12 @@ void CB_ContinueNewGameSpeechPart2() if (gSaveBlock2.playerGender != MALE) { - gTasks[taskId].data[6] = FEMALE; + gTasks[taskId].data[TD_GENDER_SELECTION] = FEMALE; spriteId = gTasks[taskId].data[TD_MAY_SPRITE_ID]; } else { - gTasks[taskId].data[6] = MALE; + gTasks[taskId].data[TD_GENDER_SELECTION] = MALE; spriteId = gTasks[taskId].data[TD_BRENDAN_SPRITE_ID]; } @@ -1403,14 +1390,14 @@ void nullsub_34(struct Sprite *sprite) { } -void sub_800B240(struct Sprite *sprite) +void ShrinkPlayerSprite(struct Sprite *sprite) { u32 y = (sprite->pos1.y << 16) + sprite->data0 + 0xC000; sprite->pos1.y = y >> 16; sprite->data0 = y; } -u8 CreateAzurillSprite(u8 a1, u8 a2) +u8 CreateAzurillSprite(u8 x, u8 y) { DecompressPicFromTable_2( &gMonFrontPicTable[SPECIES_AZURILL], @@ -1421,7 +1408,7 @@ u8 CreateAzurillSprite(u8 a1, u8 a2) SPECIES_AZURILL); LoadCompressedObjectPalette(&gMonPaletteTable[SPECIES_AZURILL]); GetMonSpriteTemplate_803C56C(SPECIES_AZURILL, 1); - return CreateSprite(&gUnknown_02024E8C, a1, a2, 0); + return CreateSprite(&gUnknown_02024E8C, x, y, 0); } void AddBirchSpeechObjects(u8 taskId) @@ -1463,7 +1450,7 @@ enum { TD_FRAMECOUNTER }; -void Task_SpriteFadeOut(u8 taskId) +static void Task_SpriteFadeOut(u8 taskId) { if (gTasks[taskId].data[TD_EVA] == 0) { @@ -1487,14 +1474,14 @@ void Task_SpriteFadeOut(u8 taskId) } //Launches a helper task to fade out sprites -void StartSpriteFadeOut(u8 taskId, u8 interval) +static void StartSpriteFadeOut(u8 taskId, u8 interval) { u8 newTaskId; REG_BLDCNT = 592; REG_BLDALPHA = 16; REG_BLDY = 0; - gTasks[taskId].data[5] = FALSE; + gTasks[taskId].data[TD_SUBTASK_DONE] = FALSE; newTaskId = CreateTask(Task_SpriteFadeOut, 0); gTasks[newTaskId].data[TD_PARENT_TASK_ID] = taskId; @@ -1504,11 +1491,11 @@ void StartSpriteFadeOut(u8 taskId, u8 interval) gTasks[newTaskId].data[TD_FRAMECOUNTER] = interval; } -void Task_SpriteFadeIn(u8 taskId) +static void Task_SpriteFadeIn(u8 taskId) { if (gTasks[taskId].data[TD_EVA] == 16) { - gTasks[gTasks[taskId].data[TD_PARENT_TASK_ID]].data[5] = TRUE; + gTasks[gTasks[taskId].data[TD_PARENT_TASK_ID]].data[TD_SUBTASK_DONE] = TRUE; DestroyTask(taskId); } else if (gTasks[taskId].data[TD_FRAMECOUNTER]) @@ -1525,7 +1512,7 @@ void Task_SpriteFadeIn(u8 taskId) } //Launches a helper task to fade in sprites -void StartSpriteFadeIn(u8 taskId, u8 interval) +static void StartSpriteFadeIn(u8 taskId, u8 interval) { u8 newTaskId; @@ -1547,22 +1534,16 @@ enum { TD_DELAY, }; -void sub_800B5A8(u8 taskId) +static void HandleFloorShadowFadeOut(u8 taskId) { if (gTasks[taskId].data[TD_DELAY]) - { gTasks[taskId].data[TD_DELAY]--; - } else { if (gTasks[taskId].data[TD_FADELEVEL] == 8) - { DestroyTask(taskId); - } else if (gTasks[taskId].data[TD_FRAMECOUNTER]) - { gTasks[taskId].data[TD_FRAMECOUNTER]--; - } else { gTasks[taskId].data[TD_FRAMECOUNTER] = gTasks[taskId].data[TD_INTERVAL]; @@ -1573,9 +1554,9 @@ void sub_800B5A8(u8 taskId) } //Launches a helper task to fade out the background -void StartBackgroundFadeOut(u8 taskId, u8 interval) +static void StartBackgroundFadeOut(u8 taskId, u8 interval) { - u8 newTaskId = CreateTask(sub_800B5A8, 0); + u8 newTaskId = CreateTask(HandleFloorShadowFadeOut, 0); gTasks[newTaskId].data[TD_PARENT_TASK_ID] = taskId; gTasks[newTaskId].data[TD_FADELEVEL] = 0; gTasks[newTaskId].data[TD_DELAY] = 8; @@ -1583,24 +1564,18 @@ void StartBackgroundFadeOut(u8 taskId, u8 interval) gTasks[newTaskId].data[TD_FRAMECOUNTER] = interval; } -void sub_800B654(u8 taskId) +static void HandleFloorShadowFadeIn(u8 taskId) { if (gTasks[taskId].data[TD_DELAY]) - { gTasks[taskId].data[TD_DELAY]--; - } else { if (gTasks[taskId].data[TD_FADELEVEL] == 0) - { DestroyTask(taskId); - } else { if (gTasks[taskId].data[TD_FRAMECOUNTER]) - { gTasks[taskId].data[TD_FRAMECOUNTER]--; - } else { gTasks[taskId].data[TD_FRAMECOUNTER] = gTasks[taskId].data[TD_INTERVAL]; @@ -1612,9 +1587,9 @@ void sub_800B654(u8 taskId) } //Launches a helper task to fade in the background -void StartBackgroundFadeIn(u8 taskId, u8 interval) +static void StartBackgroundFadeIn(u8 taskId, u8 interval) { - u8 newTaskId = CreateTask(sub_800B654, 0); + u8 newTaskId = CreateTask(HandleFloorShadowFadeIn, 0); gTasks[newTaskId].data[TD_PARENT_TASK_ID] = taskId; gTasks[newTaskId].data[TD_FADELEVEL] = 8; gTasks[newTaskId].data[TD_DELAY] = 8; @@ -1622,7 +1597,7 @@ void StartBackgroundFadeIn(u8 taskId, u8 interval) gTasks[newTaskId].data[TD_FRAMECOUNTER] = interval; } -void CreateGenderMenu(u8 left, u8 top) +static void CreateGenderMenu(u8 left, u8 top) { u8 menuLeft, menuTop; MenuDrawTextWindow(left, top, left + 6, top + 5); @@ -1632,12 +1607,12 @@ void CreateGenderMenu(u8 left, u8 top) InitMenu(0, menuLeft, menuTop, 2, 0, 5); } -s8 GenderMenuProcessInput(void) +static s8 GenderMenuProcessInput(void) { return ProcessMenuInputNoWrap(); } -void CreateNameMenu(u8 left, u8 top) +static void CreateNameMenu(u8 left, u8 top) { MenuDrawTextWindow(left, top, left + 10, top + 11); @@ -1649,20 +1624,20 @@ void CreateNameMenu(u8 left, u8 top) InitMenu(0, left + 1, top + 1, 5, 0, 9); } -s8 NameMenuProcessInput(void) +static s8 NameMenuProcessInput(void) { return ProcessMenuInput(); } -void SetPresetPlayerName(u8 index) +static void SetPresetPlayerName(u8 index) { u8 i; u8 *name; if (gSaveBlock2.playerGender == MALE) - name = gMalePresetNames[index][0]; + name = gMalePresetNames[index].text; else - name = gFemalePresetNames[index][0]; + name = gFemalePresetNames[index].text; for (i = 0; i < 7; i++) gSaveBlock2.playerName[i] = name[i]; diff --git a/src/map_obj_lock.c b/src/map_obj_lock.c index 422903a97..b1e7bb3df 100644 --- a/src/map_obj_lock.c +++ b/src/map_obj_lock.c @@ -1,17 +1,8 @@ #include "global.h" +#include "map_obj_lock.h" +#include "asm.h" +#include "field_player_avatar.h" #include "task.h" -#include "fieldmap.h" - -extern void sub_80594C0(void); -extern void sub_80597F4(void); -extern void player_bitmagic(void); -extern void sub_80643A4(struct MapObject *); -extern void sub_8064470(u8); -extern u8 GetFieldObjectIdByLocalIdAndMap(u8, u8, u8); -extern u8 FieldObjectClearAnimIfSpecialAnimFinished(void *); -extern void sub_80A2178(void); -extern void sub_806451C(void); -extern u8 FieldObjectFaceOppositeDirection(void *, u8); extern u16 gScriptFacing; @@ -45,9 +36,9 @@ bool8 sub_8064CFC(void) } } -void sub_8064D20(void) +void ScriptFreezeMapObjects(void) { - player_bitmagic(); + FreezeMapObjects(); CreateTask(sub_8064CDC, 80); } @@ -62,7 +53,7 @@ void sub_8064D38(u8 taskId) } if (!task->data[1] && !gMapObjects[gSelectedMapObject].mapobj_bit_1) { - sub_80643A4(&gMapObjects[gSelectedMapObject]); + FreezeMapObject(&gMapObjects[gSelectedMapObject]); task->data[1] = 1; } if (task->data[0] && task->data[1]) @@ -85,11 +76,11 @@ bool8 sub_8064DB4(void) void sub_8064DD8(void) { u8 taskId; - sub_8064470(gSelectedMapObject); + FreezeMapObjectsExceptOne(gSelectedMapObject); taskId = CreateTask(sub_8064D38, 80); if (!gMapObjects[gSelectedMapObject].mapobj_bit_1) { - sub_80643A4(&gMapObjects[gSelectedMapObject]); + FreezeMapObject(&gMapObjects[gSelectedMapObject]); gTasks[taskId].data[1] = 1; } } @@ -99,7 +90,7 @@ void sub_8064E2C(void) u8 objectId = GetFieldObjectIdByLocalIdAndMap(0xFF, 0, 0); FieldObjectClearAnimIfSpecialAnimFinished(&gMapObjects[objectId]); sub_80A2178(); - sub_806451C(); + UnfreezeMapObjects(); } void unref_sub_8064E5C(void) @@ -111,7 +102,7 @@ void unref_sub_8064E5C(void) objectId = GetFieldObjectIdByLocalIdAndMap(0xFF, 0, 0); FieldObjectClearAnimIfSpecialAnimFinished(&gMapObjects[objectId]); sub_80A2178(); - sub_806451C(); + UnfreezeMapObjects(); } void sub_8064EAC(void) diff --git a/src/matsuda_debug_menu.c b/src/matsuda_debug_menu.c new file mode 100644 index 000000000..131369e91 --- /dev/null +++ b/src/matsuda_debug_menu.c @@ -0,0 +1,1132 @@ +#include "global.h" +#include "asm.h" +#include "link.h" +#include "main.h" +#include "menu.h" +#include "palette.h" +#include "rom4.h" +#include "sprite.h" +#include "start_menu.h" +#include "string_util.h" +#include "task.h" +#include "text.h" + +#define BIT(n) (1 << (n)) + +extern u8 gUnknown_0203856C; +extern u8 gUnknown_0203857D[][64]; +extern u16 gUnknown_02038670[]; +extern u16 gUnknown_02038678[]; +extern u16 gUnknown_02038680[]; +extern u8 gUnknown_02038690[]; +extern u8 gUnknown_02038694; +extern u8 gIsLinkContest; +extern u8 gUnknown_0203869B; +extern u8 gContestPlayerMonIndex; +extern u16 gScriptContestCategory; +extern u16 gScriptContestRank; + +extern struct Window gMenuWindow; + +extern u16 gUnknown_030042A4; +extern u16 gUnknown_030042A0; +extern u16 gUnknown_030042C0; +extern u16 gUnknown_030041B4; +extern u16 gUnknown_03004288; +extern u16 gUnknown_03004280; +extern u16 gUnknown_030041B0; +extern u16 gUnknown_030041B8; +extern struct Window gUnknown_03004210; +extern u8 (*gCallback_03004AE8)(void); + +extern u8 gUnknown_083C926E[][2]; +extern u8 gUnknown_083C9282[]; +extern const u8 gUnknown_083C928E[][2]; +extern u8 gUnknown_083C9296[]; +extern u8 gUnknown_083C92A8[]; +extern u8 unk_2000000[]; +extern u8 gMatsudaDebugMenu_GoBackText[]; +extern u8 gMatsudaDebugMenu_BattlePointsText[]; +extern u8 gMatsudaDebugMenu_StartText[]; + +extern struct SpritePalette gUnknown_083C92BC; +extern struct SpriteSheet gUnknown_083C92B4; +extern struct SpriteTemplate gSpriteTemplate_83C92CC; +extern void (*gUnknown_083C92E4[][2])(struct Sprite *, s8); +extern u32 gUnknown_083C9400[2]; + +extern u8 gMoveNames[][13]; + +extern u8 gMatsudaDebugMenu_UnknownByteArray[]; +extern u8* gMatsudaDebugMenuTextList1[]; +extern u8* gMatsudaDebugMenuTextList2[]; +extern u8* gMatsudaDebugMenuTextList3[]; +extern u8 gMatsudaDebugMenuContestTopLeft[][2]; + +struct ContestPokemon +{ + /* 0x00 */ u16 species; + /* 0x02 */ u8 nickname[POKEMON_NAME_LENGTH]; + /* 0x0D */ u8 trainerName[8]; + /* 0x15 */ u8 filler15[9]; + /* 0x1E */ u16 moves[4]; // moves + /* 0x26 */ u8 cool; // cool + /* 0x27 */ u8 beauty; // beauty + /* 0x28 */ u8 cute; // cute + /* 0x29 */ u8 smart; // smart + /* 0x2A */ u8 tough; // tough + /* 0x2B */ u8 sheen; // sheen + /* 0x2C */ u8 filler2C[20]; +}; + +extern struct ContestPokemon gContestMons[]; + +extern bool8 gReceivedRemoteLinkPlayers; +extern u16 gBlockRecvBuffer[MAX_LINK_PLAYERS][BLOCK_BUFFER_SIZE / 2]; + +extern struct MenuAction gMatsudaDebugMenuActions[]; + +static bool8 sub_80A9B78(void); +static void sub_80A9BE4(u8 taskId); +static void sub_80A9C98(u8); +static void sub_80A9CC0(u8); +static void sub_80A9CDC(u8); +static void sub_80A9D58(u8); +static void sub_80A9DBC(u8); +static void sub_80A9DD8(u8); +static void sub_80A9E04(u8 taskId); +static void sub_80A9E3C(u8 taskId); +static void sub_80A9E80(u8); +static void sub_80A9ED8(u8); +static void sub_80A9F10(u8); +static void sub_80AA10C(void); +static void sub_80AA5BC(u8); +static void sub_80AA614(u8, u8); +static void sub_80AAD08(struct Sprite *, s8); +extern void sub_80AB184(void); +extern void sub_80AB47C(void); +extern int sub_80B2A7C(u8); //Don't know return type size + +u8 unref_sub_80A9B28(void) +{ + MenuZeroFillScreen(); + MenuDrawTextWindow(0, 0, 17, 18); + PrintMenuItems(1, 1, 7, gMatsudaDebugMenuActions); + InitMenu(0, 1, 1, 7, 0, 16); + gCallback_03004AE8 = sub_80A9B78; + return 0; +} + +static bool8 sub_80A9B78(void) +{ + s8 choice = ProcessMenuInput(); + + switch(choice) + { + case -2: + return FALSE; + default: + gCallback_03004AE8 = gMatsudaDebugMenuActions[choice].func; + return FALSE; + case -1: + CloseMenu(); + return TRUE; + } +} + +s8 MatsudaDebugMenu_ContestResults(void) +{ + BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, 0); + CreateTask(sub_80A9BE4, 0xFF); + return 1; +} + +static void sub_80A9BE4(u8 taskId) +{ + if(!gPaletteFade.active) + { + DestroyTask(taskId); + + if(!(gIsLinkContest & 1)) + sub_80AF668(); + + sub_80C2358(); + } +} + +s8 MatsudaDebugMenu_Contest(void) +{ + gIsLinkContest = 0; + sub_80AA10C(); + return 0; +} + +s8 MatsudaDebugMenu_ContestComm(void) +{ + sub_80AA10C(); + return 0; +} + +s8 MatsudaDebugMenu_CommTest(void) +{ + u8 newTaskId; + u8 newTaskId2; + + newTaskId = CreateTask(sub_80A9E3C, 0); + SetTaskFuncWithFollowupFunc(newTaskId, sub_80A9E3C, sub_80A9C98); + newTaskId2 = CreateTask(sub_80A9E04, 1); + gTasks[newTaskId2].data[10] = newTaskId; + gTasks[newTaskId].data[10] = newTaskId2; + return 1; +} + +static void sub_80A9C98(u8 taskId) +{ + sub_80AE098(0); + SetTaskFuncWithFollowupFunc(taskId, sub_80C8734, sub_80A9CC0); +} + +static void sub_80A9CC0(u8 taskId) +{ + SetTaskFuncWithFollowupFunc(taskId, sub_80C88AC, sub_80A9CDC); +} + +static void sub_80A9CDC(u8 taskId) +{ + SetTaskFuncWithFollowupFunc(taskId, sub_80C8E1C, sub_80A9D58); +} + +static void sub_80A9CF8(u8 taskId) +{ + if(gReceivedRemoteLinkPlayers == FALSE) + { + DestroyTask(gTasks[taskId].data[10]); + DestroyTask(taskId); + CloseMenu(); + } +} + +static void sub_80A9D30(u8 taskId) +{ + sub_800832C(); + gTasks[taskId].func = sub_80A9CF8; +} + +static void sub_80A9D58(u8 taskId) +{ + int i; + u8 dest[4]; + + for(i = 0; i < 4; i++) + dest[i] = gTasks[taskId].data[5 + i]; + + gUnknown_0203869B = sub_80C4B34(dest); + sub_80AE82C((u8)gScriptContestCategory); + sub_80B0F28(0); + SetTaskFuncWithFollowupFunc(taskId, sub_80C8EBC, sub_80A9DBC); +} + +static void sub_80A9DBC(u8 taskId) +{ + SetTaskFuncWithFollowupFunc(taskId, sub_80C8F34, sub_80A9DD8); +} + +static void sub_80A9DD8(u8 taskId) +{ + DestroyTask(gTasks[taskId].data[10]); + DestroyTask(taskId); + CloseMenu(); +} + +static void sub_80A9E04(u8 taskId) +{ + if(gMain.newKeys == 2) + gTasks[(u8)gTasks[taskId].data[10]].func = sub_80A9D30; +} + +static void sub_80A9E3C(u8 taskId) +{ + u8 i; + + OpenLink(); + + for(i = 0; i < 4; i++) + gBlockRecvBuffer[i][0] = 255; + + gTasks[taskId].data[0] = 0; + gTasks[taskId].func = sub_80A9E80; +} + +static void sub_80A9E80(u8 taskId) +{ + TaskFunc func; + + if(gTasks[taskId].data[0] < 10) + gTasks[taskId].data[0]++; + else + { + if(GetLinkPlayerCount_2() > 3) + { + gTasks[taskId].data[0] = 0; + + if(IsLinkMaster()) + { + func = sub_80A9ED8; + gTasks[taskId].func = (TaskFunc)func; + } + else + { + func = sub_80A9F10; + gTasks[taskId].func = (TaskFunc)func; + } + } + } +} + +static void sub_80A9ED8(u8 taskId) +{ + gTasks[taskId].data[0] = gTasks[taskId].data[0] + 1; + if((gTasks[taskId].data[0]) == 101) + { + sub_8007F4C(); + gTasks[taskId].data[0] = 0; + gTasks[taskId].func = sub_80A9F10; + } +} + +static void sub_80A9F10(u8 taskId) +{ + if(gReceivedRemoteLinkPlayers) + { + gContestPlayerMonIndex = GetMultiplayerId(); + if(GetLinkPlayerCount() == 4) + { + gIsLinkContest = 1; + SwitchTaskToFollowupFunc(taskId); + } + } +} + +static void sub_80A9F50(void) +{ + REG_DISPCNT = DISPCNT_OBJ_1D_MAP; + REG_DISPCNT |= DISPCNT_OBJ_ON | DISPCNT_BG0_ON; + SetUpWindowConfig(&gWindowConfig_81E6C3C); + InitWindowFromConfig(&gMenuWindow, &gWindowConfig_81E6C3C); + REG_MOSAIC = 0; + REG_BLDCNT = 0; + REG_BLDALPHA = 0; + REG_BLDY = 0; + REG_BG0HOFS = 0; + REG_BG0VOFS = 0; + gUnknown_030042A4 = 0; + gUnknown_030042A0 = 0; + gUnknown_030042C0 = 0; + gUnknown_030041B4 = 0; + gUnknown_03004288 = 0; + gUnknown_03004280 = 0; + gUnknown_030041B0 = 0; + gUnknown_030041B8 = 0; +} + +static void sub_80A9FE4(void) +{ + u8 *addr; + u32 i; + u8 ptr[5]; + + memcpy(ptr, gMatsudaDebugMenu_UnknownByteArray, 5); + + addr = (void *)VRAM; + i = VRAM_SIZE; + + while(1) + { + DmaFill32(3, 0, addr, 0x1000); + addr += 0x1000; + i -= 0x1000; + if(i <= 0x1000) + { + DmaFill32(3, 0, addr, i); + break; + } + } + sub_80034D4((void *)VRAM, ptr); + LoadFontDefaultPalette(&gWindowConfig_81E6C3C); +} + +static void sub_80AA064(void) +{ + AnimateSprites(); + BuildOamBuffer(); + RunTasks(); + UpdatePaletteFade(); + if(gMain.newKeys == 4) + SetMainCallback2(sub_805469C); +} + +static void sub_80AA090(void) +{ + REG_BG0HOFS = gUnknown_030042A4; + REG_BG0VOFS = gUnknown_030042A0; + REG_BG1HOFS = gUnknown_030042C0; + REG_BG1VOFS = gUnknown_030041B4; + REG_BG2HOFS = gUnknown_03004288; + REG_BG2VOFS = gUnknown_03004280; + REG_BG3HOFS = gUnknown_030041B0; + REG_BG3VOFS = gUnknown_030041B8; + LoadOam(); + ProcessSpriteCopyRequests(); + TransferPlttBuffer(); + sub_8089668(); +} + +static void sub_80AA10C(void) +{ + u8 i; + u8 zero; + u8 spriteId; + + gPaletteFade.bufferTransferDisabled = 1; + SetVBlankCallback(0); + sub_80A9F50(); + dp12_8087EA4(); + ResetPaletteFade(); + ResetSpriteData(); + ResetTasks(); + FreeAllSpritePalettes(); + sub_80A9FE4(); + SetVBlankCallback(sub_80AA090); + SetMainCallback2(sub_80AA064); + gPaletteFade.bufferTransferDisabled = 0; + gUnknown_02038694 = 0; + + if(!(gContestMons[0].nickname[0])) + sub_80AE398(0, 0); + + sub_80AE098(gUnknown_02038694); + + for(i = 0; i < 6; i++) + { + sub_8003460(&gMenuWindow, gMatsudaDebugMenuTextList1[i], + (0xA * i + 0x2A), gMatsudaDebugMenuContestTopLeft[i][0], + gMatsudaDebugMenuContestTopLeft[i][1]); + } + + gScriptContestCategory = gScriptContestRank = 0; + zero = 0; // it's possible this was some assignment that matsuda used to quickly edit and test things without changing whats passed to the later functions. + sub_80AA5BC(zero); + sub_80AA5E8(gScriptContestRank); + sub_8003460(&gMenuWindow, gMatsudaDebugMenu_GoBackText, 0xD6, 0x12, 0x12); + sub_8003460(&gMenuWindow, gMatsudaDebugMenu_BattlePointsText, 0xDC, zero, 0xC); + LoadSpriteSheet(&gUnknown_083C92B4); + LoadSpritePalette(&gUnknown_083C92BC); + sub_80AA280(3); + sub_80AA658(3); + sub_80AA614(3, zero); + spriteId = CreateSprite(&gSpriteTemplate_83C92CC, gUnknown_083C9296[3], gUnknown_083C92A8[1], 5); + gSprites[spriteId].data0 = 1; + gSprites[spriteId].data1 = 1; + gSprites[spriteId].data2 = 3; + gSprites[spriteId].data3 = zero; // only this assignment of zero is necessary. other replacements of 0 with zero do not change the asm, compiler will treat it the same. +} + +void sub_80AA280(u8 var) +{ + u8 i; + + FillWindowRect_DefaultPalette(&gMenuWindow, 0, 0, 0, 0x1E, 3); + StringCopy(unk_2000000, gMatsudaDebugMenu_StartText); + StringAppend(unk_2000000, &gUnknown_0203857D[var][0]); + + for(i = 0; i < 4; i++) + { + if(var == i) + { + sub_8003460(&gMenuWindow, unk_2000000, (10 * i + 2), gUnknown_083C926E[i][0], gUnknown_083C926E[i][1]); + } + else + { + u8 *ptr = gUnknown_0203857D[i]; + sub_8003460(&gMenuWindow, ptr, (10 * i + 2), gUnknown_083C926E[i][0], gUnknown_083C926E[i][1]); + } + } +} + +static void sub_80AA340(u8 var) +{ + ConvertIntToDecimalStringN(unk_2000000, gContestMons[var].cool, STR_CONV_MODE_RIGHT_ALIGN, 3); + sub_8003460(&gMenuWindow, unk_2000000, 0x66, gUnknown_083C9282[0], gUnknown_083C9282[1]); +} + +static void sub_80AA388(u8 var) +{ + ConvertIntToDecimalStringN(unk_2000000, gContestMons[var].cute, STR_CONV_MODE_RIGHT_ALIGN, 3); + sub_8003460(&gMenuWindow, unk_2000000, 0x6C, gUnknown_083C9282[2], gUnknown_083C9282[3]); +} + +static void sub_80AA3D0(u8 var) +{ + ConvertIntToDecimalStringN(unk_2000000, gContestMons[var].beauty, STR_CONV_MODE_RIGHT_ALIGN, 3); + sub_8003460(&gMenuWindow, unk_2000000, 0x72, gUnknown_083C9282[4], gUnknown_083C9282[5]); +} + +static void sub_80AA418(u8 var) +{ + ConvertIntToDecimalStringN(unk_2000000, gContestMons[var].smart, STR_CONV_MODE_RIGHT_ALIGN, 3); + sub_8003460(&gMenuWindow, unk_2000000, 0x78, gUnknown_083C9282[6], gUnknown_083C9282[7]); +} + +static void sub_80AA460(u8 var) +{ + ConvertIntToDecimalStringN(unk_2000000, gContestMons[var].tough, STR_CONV_MODE_RIGHT_ALIGN, 3); + sub_8003460(&gMenuWindow, unk_2000000, 0x7E, gUnknown_083C9282[8], gUnknown_083C9282[9]); +} + +static void sub_80AA4A8(u8 var) +{ + ConvertIntToDecimalStringN(unk_2000000, gContestMons[var].sheen, STR_CONV_MODE_RIGHT_ALIGN, 3); + sub_8003460(&gMenuWindow, unk_2000000, 0x84, gUnknown_083C9282[10], gUnknown_083C9282[11]); +} + +static void sub_80AA4F0(u8 var1, u8 var2) +{ + FillWindowRect_DefaultPalette(&gMenuWindow, 0, gUnknown_083C928E[var2][0], gUnknown_083C928E[var2][1], gUnknown_083C928E[var2][0] + 7, gUnknown_083C928E[var2][1] + 1); + sub_8003460(&gMenuWindow, gMoveNames[gContestMons[var1].moves[var2]], 0x8A + var2 * 14, gUnknown_083C928E[var2][0], gUnknown_083C928E[var2][1]); + ConvertIntToDecimalStringN(gStringVar1, gContestMons[var1].moves[var2], STR_CONV_MODE_LEADING_ZEROS, 3); + sub_8003460(&gMenuWindow, gStringVar1, 0xFA + var2 * 6, gUnknown_083C928E[var2][0] + 7, gUnknown_083C928E[var2][1]); +} + +static void sub_80AA5BC(u8 var) +{ + sub_8003460(&gMenuWindow, gMatsudaDebugMenuTextList2[var], 0xC2, 3, 0x12); +} + +void sub_80AA5E8(u8 var) +{ + sub_8003460(&gMenuWindow, gMatsudaDebugMenuTextList3[var], 0xE8, 3, 4); +} + +static void sub_80AA614(u8 var1, u8 var2) +{ + u16 var = sub_80AE770(var1, var2); + + ConvertIntToDecimalStringN(unk_2000000, var, STR_CONV_MODE_RIGHT_ALIGN, 3); + sub_8003460(&gMenuWindow, unk_2000000, 0xE2, 3, 0xC); +} + +void sub_80AA658(u8 var) +{ + u8 i; + + sub_80AA340(var); + sub_80AA388(var); + sub_80AA3D0(var); + sub_80AA418(var); + sub_80AA460(var); + sub_80AA4A8(var); + + for(i = 0; i < 4; i++) + sub_80AA4F0(var, i); +} + +void SetDebugMonForContest(void) +{ + SetMonData(&gPlayerParty[0], MON_DATA_COOL, &gContestMons[gContestPlayerMonIndex].cool); + SetMonData(&gPlayerParty[0], MON_DATA_CUTE, &gContestMons[gContestPlayerMonIndex].cute); + SetMonData(&gPlayerParty[0], MON_DATA_BEAUTY, &gContestMons[gContestPlayerMonIndex].beauty); + SetMonData(&gPlayerParty[0], MON_DATA_SMART, &gContestMons[gContestPlayerMonIndex].smart); + SetMonData(&gPlayerParty[0], MON_DATA_TOUGH, &gContestMons[gContestPlayerMonIndex].tough); + SetMonData(&gPlayerParty[0], MON_DATA_SHEEN, &gContestMons[gContestPlayerMonIndex].sheen); + SetMonData(&gPlayerParty[0], MON_DATA_MOVE1, (const u8 *) &gContestMons[gContestPlayerMonIndex].moves[0]); + SetMonData(&gPlayerParty[0], MON_DATA_MOVE2, (const u8 *) &gContestMons[gContestPlayerMonIndex].moves[1]); + SetMonData(&gPlayerParty[0], MON_DATA_MOVE3, (const u8 *) &gContestMons[gContestPlayerMonIndex].moves[2]); + SetMonData(&gPlayerParty[0], MON_DATA_MOVE4, (const u8 *) &gContestMons[gContestPlayerMonIndex].moves[3]); +} + +void sub_80AA754(struct Sprite *sprite) +{ + switch (gMain.newAndRepeatedKeys) + { + case 0x10: + case 0x20: + sprite->data0 ^= 1; + break; + case 0x40: + if (sprite->data1 == 0) + sprite->data1 = 8; + else + sprite->data1--; + break; + case 0x80: + if (sprite->data1 == 8) + sprite->data1 = 0; + else + sprite->data1++; + break; + case 0x1: + gUnknown_083C92E4[sprite->data1][sprite->data0](sprite, 1); + sub_80AA614(sprite->data2, sprite->data3); + break; + case 0x2: + gUnknown_083C92E4[sprite->data1][sprite->data0](sprite, -1); + sub_80AA614(sprite->data2, sprite->data3); + break; + case 0x100: + gUnknown_083C92E4[sprite->data1][sprite->data0](sprite, 10); + sub_80AA614(sprite->data2, sprite->data3); + break; + case 0x200: + gUnknown_083C92E4[sprite->data1][sprite->data0](sprite, -10); + sub_80AA614(sprite->data2, sprite->data3); + break; + case 0x8: + sub_80AAD08(sprite, 1); + break; + } + sprite->pos1.x = gUnknown_083C9296[sprite->data0 + sprite->data1 * 2]; + sprite->pos1.y = gUnknown_083C92A8[sprite->data1]; +} + +static void sub_80AA8A0(struct Sprite *sprite, s8 var1, u8 var2) +{ + if(var1 == 1) + { + sprite->data2 = var2; + sub_80AA280(var2); + sub_80AA658(sprite->data2); + } +} + +void sub_80AA8C8(struct Sprite *sprite, s8 var1) +{ + sub_80AA8A0(sprite, var1, 0); +} + +void sub_80AA8D8(struct Sprite *sprite, s8 var1) +{ + sub_80AA8A0(sprite, var1, 1); +} + +void sub_80AA8E8(struct Sprite *sprite, s8 var1) +{ + sub_80AA8A0(sprite, var1, 2); +} + +void sub_80AA8F8(struct Sprite *sprite, s8 var1) +{ + sub_80AA8A0(sprite, var1, 3); +} + +static u8 sub_80AA908(u32 a1, u8 a2, s8 a3) // first param is unused. +{ + s16 val = a2 + a3; + + if (val > 255) + val = 255; + else if (val < 0) + val = 0; + + return val; +} + +void sub_80AA930(struct Sprite *sprite, u8 var2) +{ + u8 val = sprite->data2; + + gContestMons[sprite->data2].cool = sub_80AA908(val, gContestMons[sprite->data2].cool, var2); + sub_80AA340(sprite->data2); +} + +void sub_80AA974(struct Sprite *sprite, u8 var2) +{ + u8 val = sprite->data2; + + gContestMons[sprite->data2].cute = sub_80AA908(val, gContestMons[sprite->data2].cute, var2); + sub_80AA388(sprite->data2); +} + +void sub_80AA9B8(struct Sprite *sprite, u8 var2) +{ + u8 val = sprite->data2; + + gContestMons[sprite->data2].beauty = sub_80AA908(val, gContestMons[sprite->data2].beauty, var2); + sub_80AA3D0(sprite->data2); +} + +void sub_80AA9FC(struct Sprite *sprite, u8 var2) +{ + u8 val = sprite->data2; + + gContestMons[sprite->data2].smart = sub_80AA908(val, gContestMons[sprite->data2].smart, var2); + sub_80AA418(sprite->data2); +} + +void sub_80AAA40(struct Sprite *sprite, u8 var2) +{ + u8 val = sprite->data2; + + gContestMons[sprite->data2].tough = sub_80AA908(val, gContestMons[sprite->data2].tough, var2); + sub_80AA460(sprite->data2); +} + +void sub_80AAA84(struct Sprite *sprite, u8 var2) +{ + u8 val = sprite->data2; + + gContestMons[sprite->data2].sheen = sub_80AA908(val, gContestMons[sprite->data2].sheen, var2); + sub_80AA4A8(sprite->data2); +} + +// a similar function is at 0x80AA908, however, it apparently returns the wrong type (u8 vs u16). +static u16 sub_80AAAC8(u32 a1, u16 a2, s8 a3) // first param is unused. +{ + s16 val = a2 + a3; + + if (val > 354) + val = 1; + else if (val < 0) + val = 354; + + return val; +} + +void sub_80AAAF0(struct Sprite *sprite, u8 var2) +{ + u8 val = sprite->data2; + + gContestMons[sprite->data2].moves[0] = sub_80AAAC8(val, gContestMons[sprite->data2].moves[0], var2); + sub_80AA4F0(sprite->data2, 0); +} + +void sub_80AAB30(struct Sprite *sprite, u8 var2) +{ + u8 val = sprite->data2; + + gContestMons[sprite->data2].moves[1] = sub_80AAAC8(val, gContestMons[sprite->data2].moves[1], var2); + sub_80AA4F0(sprite->data2, 1); +} + +void sub_80AAB70(struct Sprite *sprite, u8 var2) +{ + u8 val = sprite->data2; + + gContestMons[sprite->data2].moves[2] = sub_80AAAC8(val, gContestMons[sprite->data2].moves[2], var2); + sub_80AA4F0(sprite->data2, 2); +} + +void sub_80AABB0(struct Sprite *sprite, u8 var2) +{ + u8 val = sprite->data2; + + gContestMons[sprite->data2].moves[3] = sub_80AAAC8(val, gContestMons[sprite->data2].moves[3], var2); + sub_80AA4F0(sprite->data2, 3); +} + +void sub_80AABF0(struct Sprite *sprite, s8 var2) +{ + s8 a = (var2 > 0) ? 1 : -1; + s8 r4 = sprite->data3 + a; + + if (r4 < 0) + r4 = 0; + else if (r4 > 4) + r4 = 4; + sub_80AA5BC(r4); + sprite->data3 = r4; + gScriptContestCategory = sprite->data3; + sub_80AE398(sprite->data3, gScriptContestRank); + sub_80AA280(sprite->data2); + sub_80AA658(sprite->data2); +} + +void sub_80AAC5C(struct Sprite *sprite, s8 var2) +{ + if (var2 > 0) + gScriptContestRank++; + else if (gScriptContestRank != 0) + gScriptContestRank--; + if (gScriptContestRank > 3) + gScriptContestRank = 3; + sub_80AA5E8(gScriptContestRank); + sub_80AE398(gScriptContestCategory, gScriptContestRank); + sub_80AA280(sprite->data2); + sub_80AA658(sprite->data2); +} + +void sub_80AACC4(void) +{ + UpdatePaletteFade(); + if (!gPaletteFade.active) + { + SetDebugMonForContest(); + if (!(gIsLinkContest & 1)) + sub_80AE82C(unk_2000000[0]); + SetMainCallback2(sub_80AB47C); + } +} + +void sub_80AAD08(struct Sprite *sprite, s8 var2) +{ + if (var2 == 1) + { + unk_2000000[0] = sprite->data3; + SetMainCallback2(sub_80AACC4); + BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 0x10, 0); + } +} + +void sub_80AAD44(struct Sprite *sprite, s8 var2) +{ + if (var2 == 1) + { + int i; + + SetDebugMonForContest(); + for (i = 0; i < 4; i++) + gUnknown_02038670[i] = sub_80AE770(i, gScriptContestCategory); + SetMainCallback2(sub_805469C); + } +} + +//Do this later +/* +void sub_80AAD84(u8 *string, u8 b, u8 c, u8 d) +{ + u32 r5; + u16 r7; + u8 r7_2; + //u32 sp44; + //u32 sp48; + u32 sp58; + + gMain.state = 0; + + r5 = d + 1; + //Could also be DmaClear32 + DmaFill32(3, 0, (u8 *)VRAM + 0x18000 - r5 * 256, 0x100); + + r7 = StringLength(string); + if (r7 > 8) + r7 = 8; + sp58 = d * 2; + + //More stuff + + r7_2 = 0x7C - sp58; + +} +*/ + +__attribute__((naked)) +void sub_80AAD84(u8 *string, u8 b, u8 c, u8 d) +{ + 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, 0x64\n\ + mov r9, r0\n\ + lsls r1, 24\n\ + lsrs r1, 24\n\ + str r1, [sp, 0x48]\n\ + lsls r2, 24\n\ + lsrs r2, 24\n\ + str r2, [sp, 0x4C]\n\ + lsls r3, 24\n\ + lsrs r3, 24\n\ + mov r10, r3\n\ + mov r5, r10\n\ + adds r5, 0x1\n\ + lsls r1, r5, 8\n\ + ldr r0, _080AAEC4 @ =0x06018000\n\ + subs r1, r0, r1\n\ + movs r0, 0\n\ + str r0, [sp, 0x44]\n\ + ldr r4, _080AAEC8 @ =0x040000d4\n\ + add r0, sp, 0x44\n\ + str r0, [r4]\n\ + str r1, [r4, 0x4]\n\ + ldr r0, _080AAECC @ =0x85000040\n\ + str r0, [r4, 0x8]\n\ + ldr r0, [r4, 0x8]\n\ + mov r0, r9\n\ + bl StringLength\n\ + lsls r0, 16\n\ + lsrs r7, r0, 16\n\ + cmp r7, 0x8\n\ + bls _080AADD0\n\ + movs r7, 0x8\n\ +_080AADD0:\n\ + movs r6, 0\n\ + mov r8, r5\n\ + mov r1, r10\n\ + lsls r1, 1\n\ + str r1, [sp, 0x58]\n\ + ldr r2, [sp, 0x48]\n\ + adds r2, 0x20\n\ + str r2, [sp, 0x5C]\n\ + cmp r6, r7\n\ + bge _080AAE1E\n\ + add r5, sp, 0x40\n\ + add r0, sp, 0x20\n\ + mov r10, r0\n\ + ldr r2, _080AAEC4 @ =0x06018000\n\ +_080AADEC:\n\ + mov r1, r9\n\ + adds r0, r1, r6\n\ + ldrb r0, [r0]\n\ + strb r0, [r5]\n\ + movs r0, 0xFF\n\ + strb r0, [r5, 0x1]\n\ + mov r0, sp\n\ + adds r1, r5, 0\n\ + str r2, [sp, 0x60]\n\ + bl sub_80034D4\n\ + mov r1, r8\n\ + lsls r0, r1, 8\n\ + ldr r2, [sp, 0x60]\n\ + subs r0, r2, r0\n\ + mov r1, r10\n\ + str r1, [r4]\n\ + str r0, [r4, 0x4]\n\ + ldr r0, _080AAED0 @ =0x84000008\n\ + str r0, [r4, 0x8]\n\ + ldr r0, [r4, 0x8]\n\ + adds r2, 0x20\n\ + adds r6, 0x1\n\ + cmp r6, r7\n\ + blt _080AADEC\n\ +_080AAE1E:\n\ + movs r1, 0x7C\n\ + ldr r2, [sp, 0x58]\n\ + subs r1, r2\n\ + lsls r1, 24\n\ + lsrs r7, r1, 24\n\ + ldr r0, _080AAED4 @ =gMain\n\ + mov r9, r0\n\ + lsls r3, r7, 3\n\ + add r3, r9\n\ + ldr r0, _080AAED8 @ =gUnknown_083C9400\n\ + ldr r1, [r0]\n\ + ldr r2, [r0, 0x4]\n\ + str r1, [sp, 0x50]\n\ + str r2, [sp, 0x54]\n\ + str r1, [r3, 0x3C]\n\ + str r2, [r3, 0x40]\n\ + mov r2, r8\n\ + lsls r0, r2, 3\n\ + movs r1, 0x80\n\ + lsls r1, 3\n\ + adds r2, r1, 0\n\ + subs r2, r0\n\ + adds r6, r3, 0\n\ + adds r6, 0x40\n\ + ldr r0, _080AAEDC @ =0x000003ff\n\ + mov r8, r0\n\ + mov r1, r8\n\ + ands r2, r1\n\ + ldrh r5, [r6]\n\ + ldr r4, _080AAEE0 @ =0xfffffc00\n\ + adds r0, r4, 0\n\ + ands r0, r5\n\ + orrs r0, r2\n\ + strh r0, [r6]\n\ + ldrh r5, [r3, 0x3E]\n\ + ldr r2, _080AAEE4 @ =0xfffffe00\n\ + adds r0, r2, 0\n\ + ands r0, r5\n\ + ldr r1, [sp, 0x48]\n\ + orrs r0, r1\n\ + strh r0, [r3, 0x3E]\n\ + adds r3, 0x3C\n\ + add r0, sp, 0x4C\n\ + ldrb r0, [r0]\n\ + strb r0, [r3]\n\ + adds r1, r7, 0x1\n\ + lsls r1, 3\n\ + mov r0, r9\n\ + adds r7, r1, r0\n\ + ldr r0, [sp, 0x50]\n\ + ldr r1, [sp, 0x54]\n\ + str r0, [r7, 0x3C]\n\ + str r1, [r7, 0x40]\n\ + ldrh r0, [r6]\n\ + lsls r0, 22\n\ + lsrs r0, 22\n\ + adds r0, 0x4\n\ + adds r5, r7, 0\n\ + adds r5, 0x40\n\ + mov r1, r8\n\ + ands r0, r1\n\ + ldrh r3, [r5]\n\ + ands r4, r3\n\ + orrs r4, r0\n\ + strh r4, [r5]\n\ + ldrh r0, [r7, 0x3E]\n\ + ands r2, r0\n\ + ldr r0, [sp, 0x5C]\n\ + orrs r2, r0\n\ + strh r2, [r7, 0x3E]\n\ + adds r1, r7, 0\n\ + adds r1, 0x3C\n\ + add r2, sp, 0x4C\n\ + ldrb r2, [r2]\n\ + strb r2, [r1]\n\ + add sp, 0x64\n\ + pop {r3-r5}\n\ + mov r8, r3\n\ + mov r9, r4\n\ + mov r10, r5\n\ + pop {r4-r7}\n\ + pop {r0}\n\ + bx r0\n\ + .align 2, 0\n\ +_080AAEC4: .4byte 0x06018000\n\ +_080AAEC8: .4byte 0x040000d4\n\ +_080AAECC: .4byte 0x85000040\n\ +_080AAED0: .4byte 0x84000008\n\ +_080AAED4: .4byte gMain\n\ +_080AAED8: .4byte gUnknown_083C9400\n\ +_080AAEDC: .4byte 0x000003ff\n\ +_080AAEE0: .4byte 0xfffffc00\n\ +_080AAEE4: .4byte 0xfffffe00\n\ + .syntax divided\n"); +} + +void unref_sub_80AAEE8(s32 a, u8 b, u8 c, u8 d) +{ + u8 string[12]; + u8 offset = 0; + + if (a < 0) + { + string[0] = 0xAE; + offset = 1; + } + ConvertIntToDecimalStringN(string + offset, (a < 0) ? -a : a, 0, 8); + sub_80AAD84(string, b, c, d); +} + +void sub_80AAF30(void) +{ + s32 i; + + gUnknown_0203856C = 1; + gContestPlayerMonIndex = 3; + sub_80AE098(0); + for (i = 3; i > -1; i--) + gUnknown_02038690[i] = 3 - i; + for (i = 0; i < 3; i++) + { + gUnknown_02038670[i] = 0; + gUnknown_02038680[i] = 0; + gUnknown_02038678[i] = 0; + memcpy(&gContestMons[i], &gContestMons[3], 0x40); + } + gUnknown_02038670[3] = 0x12C; + gUnknown_02038680[3] = 0x190; + gUnknown_02038678[3] = 0x190; + sub_80B2A7C(0xFE); +} + +//Don't know size of return type +int MatsudaDebugMenu_SetHighScore(void) +{ + sub_80AAF30(); + CloseMenu(); + return 1; +} + +//Don't know size of return type +int MatsudaDebugMenu_ResetHighScore(void) +{ + s32 i; + + gUnknown_0203856C = 0; + for (i = 0; i < 4; i++) + { + gUnknown_02038670[i] = 0; + gUnknown_02038680[i] = 0; + gUnknown_02038678[i] = 0; + } + CloseMenu(); + return 1; +} + +//Don't know size of return type +int MatsudaDebugMenu_SetArtMuseumItems(void) +{ + s32 i; + + gContestPlayerMonIndex = 3; + sub_80AE098(0); + for (i = 3; i > -1; i--) + gUnknown_02038690[i] = 3 - i; + for (gScriptContestCategory = 0; gScriptContestCategory < 5; gScriptContestCategory++) + sub_80B2A7C(0xFF); + CloseMenu(); + return 1; +} + +void unref_sub_80AB084(u8 *text) +{ + u16 savedIme; + u8 *addr; + size_t size; + + 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_WIN0H = 0; + REG_WIN0V = 0; + REG_WIN1H = 0; + REG_WIN1V = 0; + REG_DISPCNT = 0x1F40; + + savedIme = REG_IME; + REG_IME = 0; + REG_IE |= INTR_FLAG_VBLANK; + REG_IME = savedIme; + REG_DISPSTAT = 8; + ResetTasks(); + ResetSpriteData(); + SetMainCallback2(sub_80AB184); + + addr = (void *)VRAM; + size = 0x18000; + while(1) + { + DmaFill32(3, 0, addr, 0x1000); + addr += 0x1000; + size -= 0x1000; + if(size <= 0x1000) + { + DmaFill32(3, 0, addr, size); + break; + } + } + SetUpWindowConfig(&gWindowConfig_81E6FD8); + InitWindowFromConfig(&gUnknown_03004210, &gWindowConfig_81E6FD8); + LoadFontDefaultPalette(&gWindowConfig_81E6FD8); + sub_8003460(&gUnknown_03004210, text, 1, 9, 7); +} + +void sub_80AB184(void) +{ + REG_BG0HOFS = 0; + REG_BG0VOFS = 0; + REG_BG1HOFS = 0; + REG_BG1VOFS = 0; + REG_BG2HOFS = 0; + REG_BG2VOFS = 0; + REG_BG3HOFS = 0; + REG_BG3VOFS = 0; +} diff --git a/src/menu.c b/src/menu.c index 5744df4c1..ee9376079 100644 --- a/src/menu.c +++ b/src/menu.c @@ -5,6 +5,9 @@ #include "songs.h" #include "text_window.h" #include "sound.h" +#include "menu_cursor.h" +#include "map_obj_lock.h" +#include "script.h" struct Menu { @@ -19,20 +22,17 @@ struct Menu u8 columnXCoords[8]; }; -static void MultistepInitMenuWindowInternal(struct WindowConfig *, u16); -static void InitMenuWindowInternal(struct WindowConfig *, u16); +extern u8 OtherText_Yes[]; +extern u8 OtherText_No[]; + +static void MultistepInitMenuWindowInternal(const struct WindowConfig *, u16); +static void InitMenuWindowInternal(const struct WindowConfig *, u16); static bool8 sub_80723D4(void); static u8 sub_8072484(u8, u8, u8, u8, u8, u8, u32); -static u8 sub_80724F4(u8, u8, u8, u8 * const [][2], u8); -static void sub_8072620(u8, u8, u8, u8 * const [][2], u8); +static u8 sub_80724F4(u8, u8, u8, const struct MenuAction[], u8); +static void sub_8072620(u8, u8, u8, const struct MenuAction[], u8); static void sub_8072D18(u8, u8); -extern void sub_814A5C0(u8, u16, u8, u16, u8); -extern void sub_814A880(u8, u8); -extern void sub_814A904(void); -extern void sub_814A958(u8); -extern void sub_814A7FC(void); - static struct Menu gMenu; EWRAM_DATA struct Window gMenuWindow = {0}; @@ -44,19 +44,38 @@ EWRAM_DATA u16 gMenuTextWindowTileOffset = 0; EWRAM_DATA u16 gMenuTextWindowContentTileOffset = 0; EWRAM_DATA u16 gMenuMessageBoxContentTileOffset = 0; -extern const u8 *gUnknown_08376D74[][2]; +const struct MenuAction gMenuYesNoItems[] = +{ + { OtherText_Yes, NULL }, + { OtherText_No, NULL }, +}; + +void CloseMenu(void) +{ + PlaySE(SE_SELECT); + MenuZeroFillScreen(); + sub_8064E2C(); + ScriptContext2_Disable(); + sub_8072DEC(); +} + +void AppendToList(u8 *list, u8 *pindex, u32 value) +{ + list[*pindex] = value; + (*pindex)++; +} -void InitMenuWindow(struct WindowConfig *winConfig) +void InitMenuWindow(const struct WindowConfig *winConfig) { InitMenuWindowInternal(winConfig, 1); } -void MultistepInitMenuWindowBegin(struct WindowConfig *winConfig) +void MultistepInitMenuWindowBegin(const struct WindowConfig *winConfig) { MultistepInitMenuWindowInternal(winConfig, 1); } -static void MultistepInitMenuWindowInternal(struct WindowConfig *winConfig, u16 tileOffset) +static void MultistepInitMenuWindowInternal(const struct WindowConfig *winConfig, u16 tileOffset) { gMenuMultistepInitState = 0; gMenuTextTileOffset = tileOffset; @@ -93,7 +112,7 @@ bool32 MultistepInitMenuWindowContinue(void) } } -static void InitMenuWindowInternal(struct WindowConfig *winConfig, u16 tileOffset) +static void InitMenuWindowInternal(const struct WindowConfig *winConfig, u16 tileOffset) { gMenuWindowPtr = &gMenuWindow; InitWindowFromConfig(&gMenuWindow, winConfig); @@ -125,13 +144,13 @@ void MenuLoadTextWindowGraphics(void) LoadTextWindowGraphics(gMenuWindowPtr); } -void BasicInitMenuWindow(struct WindowConfig *winConfig) +void BasicInitMenuWindow(const struct WindowConfig *winConfig) { InitWindowFromConfig(gMenuWindowPtr, winConfig); gMenuWindowPtr->tileDataStartOffset = gMenuTextTileOffset; } -void MenuPrint(u8 *str, u8 left, u8 top) +void MenuPrint(const u8 *str, u8 left, u8 top) { sub_8003460(gMenuWindowPtr, str, gMenuTextTileOffset, left, top); } @@ -395,7 +414,7 @@ static u8 sub_8072484(u8 a1, u8 a2, u8 menuItemCount, u8 a4, u8 width, u8 a6, u3 return a4; } -static u8 sub_80724F4(u8 left, u8 top, u8 menuItemCount, u8 * const menuItems[][2], u8 columnCount) +static u8 sub_80724F4(u8 left, u8 top, u8 menuItemCount, const struct MenuAction menuItems[], u8 columnCount) { u8 i; u8 maxWidth; @@ -407,7 +426,7 @@ static u8 sub_80724F4(u8 left, u8 top, u8 menuItemCount, u8 * const menuItems[][ maxWidth = 0; for (i = 0; i < menuItemCount; i++) { - u8 width = (sub_8072CA4(menuItems[i][0]) + 7) / 8; + u8 width = (sub_8072CA4(menuItems[i].text) + 7) / 8; if (width > maxWidth) maxWidth = width; @@ -453,7 +472,7 @@ static u8 sub_80724F4(u8 left, u8 top, u8 menuItemCount, u8 * const menuItems[][ return maxWidth; } -static void sub_8072620(u8 left, u8 top, u8 menuItemCount, u8 * const menuItems[][2], u8 columnCount) +static void sub_8072620(u8 left, u8 top, u8 menuItemCount, const struct MenuAction menuItems[], u8 columnCount) { u8 i; u8 maxWidth; @@ -464,7 +483,7 @@ static void sub_8072620(u8 left, u8 top, u8 menuItemCount, u8 * const menuItems[ maxWidth = 0; for (i = 0; i < menuItemCount; i++) { - u8 width = (sub_8072CA4(menuItems[i][0]) + 7) / 8; + u8 width = (sub_8072CA4(menuItems[i].text) + 7) / 8; if (width > maxWidth) maxWidth = width; @@ -483,11 +502,11 @@ static void sub_8072620(u8 left, u8 top, u8 menuItemCount, u8 * const menuItems[ u8 row = 0; u8 j; for (j = 0; i + j < menuItemCount; j += columnCount, row++) - MenuPrint(menuItems[i + j][0], left + gMenu.columnXCoords[i % columnCount], top + 2 * row); + MenuPrint(menuItems[i + j].text, left + gMenu.columnXCoords[i % columnCount], top + 2 * row); } } -void sub_807274C(u8 left, u8 top, u8 menuItemCount, u8 a4, u8 * const menuItems[][2], u8 columnCount, u32 a7) +void sub_807274C(u8 left, u8 top, u8 menuItemCount, u8 a4, const struct MenuAction menuItems[], u8 columnCount, u32 a7) { u8 maxWidth = sub_80724F4(left, top, menuItemCount, menuItems, columnCount); @@ -545,25 +564,25 @@ u8 sub_807288C(u8 column) return gMenu.columnXCoords[column]; } -void PrintMenuItems(u8 left, u8 top, u8 menuItemCount, u8 * const menuItems[][2]) +void PrintMenuItems(u8 left, u8 top, u8 menuItemCount, const struct MenuAction menuItems[]) { u8 i; for (i = 0; i < menuItemCount; i++) - MenuPrint(menuItems[i][0], left, top + 2 * i); + MenuPrint(menuItems[i].text, left, top + 2 * i); } -void PrintMenuItemsReordered(u8 left, u8 top, u8 menuItemCount, u8 * const menuItems[][2], u8 *order) +void PrintMenuItemsReordered(u8 left, u8 top, u8 menuItemCount, const struct MenuAction menuItems[], u8 *order) { u8 i; for (i = 0; i < menuItemCount; i++) - MenuPrint(menuItems[order[i]][0], left, top + 2 * i); + MenuPrint(menuItems[order[i]].text, left, top + 2 * i); } void InitYesNoMenu(u8 left, u8 top, u8 a3) { - PrintMenuItems(left + 1, top + 1, 2, (void *)gUnknown_08376D74); + PrintMenuItems(left + 1, top + 1, 2, gMenuYesNoItems); InitMenu(0, left + 1, top + 1, 2, 0, a3); } diff --git a/src/menu_cursor.c b/src/menu_cursor.c index 21e4d9d58..5c1f0addf 100644 --- a/src/menu_cursor.c +++ b/src/menu_cursor.c @@ -1,4 +1,5 @@ #include "global.h" +#include "menu_cursor.h" #include "sprite.h" #include "palette.h" @@ -29,11 +30,6 @@ extern u8 gUnknown_0203A3D2; extern u8 gUnknown_0203A3D3; extern u8 gUnknown_0203A3D4; -void sub_814A7FC(void); -void sub_814A958(u8 a1); -void sub_814AD44(void); -void sub_814ADF4(u8 a1); - void sub_814A590(void) { gUnknown_0203A3D0 = 0x40; @@ -509,7 +505,7 @@ void unref_sub_814ABE4(int a1) { struct Sprite *spr; - CpuSet(gUnknown_0842F5BC[a1], &gMenuCursorSubsprites, 0x28); + CpuCopy16(gUnknown_0842F5BC[a1], &gMenuCursorSubsprites, 80); if (gUnknown_0203A3D0 != 0x40) { diff --git a/src/metatile_behavior.c b/src/metatile_behavior.c new file mode 100644 index 000000000..b78e76e10 --- /dev/null +++ b/src/metatile_behavior.c @@ -0,0 +1,1065 @@ +#include "global.h" +#include "metatile_behaviors.h" + +extern u8 gUnknown_08308E2C[]; + +bool8 MetatileBehavior_IsWaterfall(u8); + +// only used as default case for checking jump landing in field_ground_effect. +bool8 MetatileBehavior_IsATile(u8 var) +{ + return TRUE; +} + +bool8 MetatileBehavior_IsEncounterTile(u8 var) +{ + if((gUnknown_08308E2C[var] & 1) != 0) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsJumpEast(u8 var) +{ + if(var == MB_JUMP_EAST) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsJumpWest(u8 var) +{ + if(var == MB_JUMP_WEST) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsJumpNorth(u8 var) +{ + if(var == MB_JUMP_NORTH) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsJumpSouth(u8 var) +{ + if(var == MB_JUMP_SOUTH) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsPokeGrass(u8 var) +{ + if(var == MB_TALL_GRASS || var == MB_LONG_GRASS) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsSandOrDeepSand(u8 var) +{ + if(var == MB_SAND || var == MB_DEEP_SAND) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsDeepSand(u8 var) +{ + if(var == MB_DEEP_SAND) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsReflective(u8 var) +{ + if(var == MB_POND_WATER || var == MB_PUDDLE || var == MB_1A || var == MB_ICE || var == MB_SOOTOPOLIS_DEEP_WATER || var == MB_REFLECTION_UNDER_BRIDGE) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsIce(u8 var) +{ + if(var == MB_ICE) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsWarpDoor(u8 var) +{ + if(var == MB_ANIMATED_DOOR) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsDoor(u8 var) +{ + if(var == MB_8D || var == MB_ANIMATED_DOOR) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsEscalator(u8 var) +{ + if(var == MB_UP_ESCALATOR || var == MB_DOWN_ESCALATOR) + return TRUE; + else + return FALSE; +} + +bool8 unref_sub_8056EE0(u8 var) +{ + if(var == MB_04) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsLadder(u8 var) +{ + if(var == MB_LADDER) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsNonAnimDoor(u8 var) +{ + if(var == MB_NON_ANIMATED_DOOR || var == MB_WATER_DOOR || var == MB_DEEP_SOUTH_WARP) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsDeepSouthWarp(u8 var) +{ + if(var == MB_DEEP_SOUTH_WARP) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsSurfableWaterOrUnderwater(u8 var) +{ + if((gUnknown_08308E2C[var] & 2) != 0) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsEastArrowWarp(u8 var) +{ + if(var == MB_EAST_ARROW_WARP) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsWestArrowWarp(u8 var) +{ + if(var == MB_WEST_ARROW_WARP) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsNorthArrowWarp(u8 var) +{ + if(var == MB_NORTH_ARROW_WARP || var == MB_STAIRS_OUTSIDE_ABANDONED_SHIP) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsSouthArrowWarp(u8 var) +{ + if(var == MB_SOUTH_ARROW_WARP || var == MB_WATER_SOUTH_ARROW_WARP || var == MB_SHOAL_CAVE_ENTRANCE) + return TRUE; + else + return FALSE; +} + +// unused +bool8 MetatileBehavior_IsArrowWarp(u8 var) +{ + u8 var2 = 0; + + if(MetatileBehavior_IsEastArrowWarp(var) + || MetatileBehavior_IsWestArrowWarp(var) + || MetatileBehavior_IsNorthArrowWarp(var) + || MetatileBehavior_IsSouthArrowWarp(var)) + { + var2 = 1; + } + return var2; +} + +bool8 MetatileBehavior_IsMoveTile(u8 var) +{ + if((var >= MB_WALK_EAST && var <= MB_TRICK_HOUSE_PUZZLE_8_FLOOR) || (var >= MB_EASTWARD_CURRENT && var <= MB_SOUTHWARD_CURRENT) + || var == MB_MUDDY_SLOPE || var == MB_CRACKED_FLOOR || var == MB_WATERFALL || var == MB_ICE || var == MB_BB || var == MB_BC) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsIce_2(u8 var) +{ + if(var == MB_ICE) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsTrickHouseSlipperyFloor(u8 var) +{ + if(var == MB_TRICK_HOUSE_PUZZLE_8_FLOOR) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_0x05(u8 var) +{ + if(var == MB_05) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsWalkNorth(u8 var) +{ + if(var == MB_WALK_NORTH) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsWalkSouth(u8 var) +{ + if(var == MB_WALK_SOUTH) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsWalkWest(u8 var) +{ + if(var == MB_WALK_WEST) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsWalkEast(u8 var) +{ + if(var == MB_WALK_EAST) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsNorthwardCurrent(u8 var) +{ + if(var == MB_NORTHWARD_CURRENT) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsSouthwardCurrent(u8 var) +{ + if(var == MB_SOUTHWARD_CURRENT) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsWestwardCurrent(u8 var) +{ + if(var == MB_WESTWARD_CURRENT) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsEastwardCurrent(u8 var) +{ + if(var == MB_EASTWARD_CURRENT) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsSlideNorth(u8 var) +{ + if(var == MB_SLIDE_NORTH) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsSlideSouth(u8 var) +{ + if(var == MB_SLIDE_SOUTH) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsSlideWest(u8 var) +{ + if(var == MB_SLIDE_WEST) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsSlideEast(u8 var) +{ + if(var == MB_SLIDE_EAST) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsCounter(u8 var) +{ + if(var == MB_COUNTER) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsPlayerFacingTVScreen(u8 tile, u8 playerDir) +{ + if(playerDir != CONNECTION_NORTH) // if the player isn't facing north, forget about it. + return FALSE; + else if(tile == MB_TELEVISION) // is the player's north tile a TV? + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsPC(u8 var) +{ + if(var == MB_PC) + return TRUE; + else + return FALSE; +} + +bool8 is_tile_x84(u8 var) +{ + if(var == MB_84) + return TRUE; + else + return FALSE; +} + +bool8 sub_80571C0(u8 var) +{ + if(var == MB_91 || var == MB_93 || var == MB_95 || var == MB_97 + || var == MB_99 || var == MB_9B || var == MB_9D) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsSecretBaseCave(u8 var) +{ + if(var == MB_SECRET_BASE_SPOT_RED_CAVE || var == MB_SECRET_BASE_SPOT_BROWN_CAVE || var == MB_SECRET_BASE_SPOT_YELLOW_CAVE || var == MB_SECRET_BASE_SPOT_BLUE_CAVE) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsSecretBaseTree(u8 var) +{ + if(var == MB_SECRET_BASE_SPOT_TREE_1 || var == MB_SECRET_BASE_SPOT_TREE_2) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsSecretBaseShrub(u8 var) +{ + if(var == MB_SECRET_BASE_SPOT_SHRUB) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsSecretBasePC(u8 var) +{ + if(var == MB_SECRET_BASE_PC) + return TRUE; + else + return FALSE; +} + +bool8 sub_805724C(u8 var) +{ + if(var == MB_B1) + return TRUE; + else + return FALSE; +} + +bool8 unref_sub_8057260(u8 var) +{ + if(var == MB_B2) + return TRUE; + else + return FALSE; +} + +bool8 sub_8057274(u8 var) +{ + if(var == MB_B3) + return TRUE; + else + return FALSE; +} + +bool8 sub_8057288(u8 var) +{ + if(var == MB_B9) + return TRUE; + else + return FALSE; +} + +bool8 sub_805729C(u8 var) +{ + if(var == MB_NORMAL) + return TRUE; + else + return FALSE; +} + +bool8 sub_80572B0(u8 var) +{ + if(var == MB_B7) + return TRUE; + else + return FALSE; +} + +bool8 unref_sub_80572C4(u8 var) +{ + if(var == MB_B2) + return TRUE; + else + return FALSE; +} + +bool8 sub_80572D8(u8 var) +{ + if(var == MB_B5) + return TRUE; + else + return FALSE; +} + +bool8 sub_80572EC(u8 var) +{ + if(var == MB_C3) + return TRUE; + else + return FALSE; +} + +bool8 sub_8057300(u8 var) +{ + if(var == MB_C2) + return TRUE; + else + return FALSE; +} + +bool8 sub_8057314(u8 var) +{ + if(var == MB_B8) + return TRUE; + else + return FALSE; +} + +bool8 sub_8057328(u8 var) +{ + if(var == MB_BE) + return TRUE; + else + return FALSE; +} + +bool8 sub_805733C(u8 var) +{ + if(var == MB_BD) + return TRUE; + else + return FALSE; +} + +bool8 sub_8057350(u8 var) +{ + if(var == MB_BA) + return TRUE; + else + return FALSE; +} + +bool8 sub_8057364(u8 var) +{ + if(var == MB_BF) + return TRUE; + else + return FALSE; +} + +bool8 sub_8057378(u8 var) +{ + if(var == MB_C4) + return TRUE; + else + return FALSE; +} + +bool8 sub_805738C(u8 var) +{ + if(var == MB_C5) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_HasRipples(u8 var) +{ + if(var == MB_POND_WATER || var == MB_PUDDLE || var == MB_SOOTOPOLIS_DEEP_WATER) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsPuddle(u8 var) +{ + if(var == MB_PUDDLE) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsTallGrass(u8 var) +{ + if(var == MB_TALL_GRASS) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsLongGrass(u8 var) +{ + if(var == MB_LONG_GRASS) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsBerryTreeSoil(u8 var) +{ + if(var == MB_BERRY_TREE_SOIL) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsAsh(u8 var) +{ + if(var == MB_ASH) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsUnusedFootprintMetatile(u8 var) +{ + if(var == MB_25) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsBridge(u8 var) +{ + if(var >= MB_WARP_OR_BRIDGE && var <= MB_ROUTE120_NORTH_BRIDGE_2) + return TRUE; + else + return FALSE; +} + +u8 sub_8057450(u8 var) +{ + u8 result = var - MB_WARP_OR_BRIDGE; + + if(result > 3) + result = 0; + + return result; +} + +bool8 MetatileBehavior_IsLandWildEncounter(u8 var) +{ + if(MetatileBehavior_IsSurfableWaterOrUnderwater(var) == FALSE && MetatileBehavior_IsEncounterTile(var) == TRUE) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsWaterWildEncounter(u8 var) +{ + if(MetatileBehavior_IsSurfableWaterOrUnderwater(var) == TRUE && MetatileBehavior_IsEncounterTile(var) == TRUE) + return TRUE; + else + return FALSE; +} + +bool8 sub_80574C4(u8 var) +{ + if(var == MB_0B) + return TRUE; + else + return FALSE; +} + +bool8 sub_80574D8(u8 var) +{ + if(var == MB_MOUNTAIN_TOP) + return TRUE; + else + return FALSE; +} + +bool8 sub_80574EC(u8 var) +{ + if(var == MB_SEMI_DEEP_WATER || var == MB_DEEP_WATER || var == MB_SOOTOPOLIS_DEEP_WATER) + return TRUE; + else + return FALSE; +} + +bool8 sub_805750C(u8 var) +{ + if(var == MB_NO_SURFACING || var == MB_SEAWEED_NO_SURFACING) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsShallowFlowingWater(u8 var) +{ + if(var == MB_SHALLOW_WATER || var == MB_STAIRS_OUTSIDE_ABANDONED_SHIP || var == MB_SHOAL_CAVE_ENTRANCE) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsThinIce(u8 var) +{ + if(var == MB_THIN_ICE) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsCrackedIce(u8 var) +{ + if(var == MB_CRACKED_ICE) + return TRUE; + else + return FALSE; +} + +bool8 sub_8057568(u8 var) +{ + if(var == MB_OCEAN_WATER || var == MB_SEMI_DEEP_WATER || var == MB_DEEP_WATER) + return TRUE; + else + return FALSE; +} + +bool8 unref_sub_8057584(u8 var) +{ + if(var == MB_18 || var == MB_1A) + return TRUE; + else + return FALSE; +} + +bool8 sub_805759C(u8 var) +{ + if(MetatileBehavior_IsSurfableWaterOrUnderwater(var) && MetatileBehavior_IsWaterfall(var) == FALSE) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsEastBlocked(u8 var) +{ + if(var == MB_IMPASSABLE_EAST || var == MB_IMPASSABLE_NORTHEAST || var == MB_IMPASSABLE_SOUTHEAST || var == MB_C1 || var == MB_BE) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsWestBlocked(u8 var) +{ + if(var == MB_IMPASSABLE_WEST || var == MB_IMPASSABLE_NORTHWEST || var == MB_IMPASSABLE_SOUTHWEST || var == MB_C1 || var == MB_BE) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsNorthBlocked(u8 var) +{ + if(var == MB_IMPASSABLE_NORTH || var == MB_IMPASSABLE_NORTHEAST || var == MB_IMPASSABLE_NORTHWEST || var == MB_BED) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsSouthBlocked(u8 var) +{ + if(var == MB_IMPASSABLE_SOUTH || var == MB_IMPASSABLE_SOUTHEAST || var == MB_IMPASSABLE_SOUTHWEST || var == MB_BED) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsShortGrass(u8 var) +{ + if(var == MB_SHORT_GRASS) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsHotSprings(u8 var) +{ + if(var == MB_HOT_SPRINGS) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsWaterfall(u8 var) +{ + if(var == MB_WATERFALL) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsFortreeBridge(u8 var) +{ + if(var == MB_FORTREE_BRIDGE) + return TRUE; + else + return FALSE; +} + +bool8 sub_80576A0(u8 var) +{ + if(var == MB_PACIFIDLOG_VERTICAL_LOG_1) + return TRUE; + else + return FALSE; +} + +bool8 sub_80576B4(u8 var) +{ + if(var == MB_PACIFIDLOG_VERTICAL_LOG_2) + return TRUE; + else + return FALSE; +} + +bool8 sub_80576C8(u8 var) +{ + if(var == MB_PACIFIDLOG_HORIZONTAL_LOG_1) + return TRUE; + else + return FALSE; +} + +bool8 sub_80576DC(u8 var) +{ + if(var == MB_PACIFIDLOG_HORIZONTAL_LOG_2) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsPacifidlogLog(u8 var) +{ + if(var >= MB_PACIFIDLOG_VERTICAL_LOG_1 && var <= MB_PACIFIDLOG_HORIZONTAL_LOG_2) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsTrickHousePuzzleDoor(u8 var) +{ + if(var == MB_TRICK_HOUSE_PUZZLE_DOOR) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsRegionMap(u8 var) +{ + if(var == MB_REGION_MAP) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsClosedSootpolisGymDoor(u8 var) +{ + if(var == MB_CLOSED_SOOTOPOLIS_GYM_DOOR) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsRoulette(u8 var) +{ + if(var == MB_ROULETTE) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsPokeblockFeeder(u8 var) +{ + if(var == MB_POKEBLOCK_FEEDER) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_0xBB(u8 var) +{ + if(var == MB_BB) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_0xBC(u8 var) +{ + if(var == MB_BC) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsLavaridgeB1FWarp(u8 var) +{ + if(var == MB_LAVARIDGE_GYM_B1F_WARP) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsLavaridge1FWarp(u8 var) +{ + if(var == MB_LAVARIDGE_GYM_1F_WARP) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsAquaHideoutWarp(u8 var) +{ + if(var == MB_AQUA_HIDEOUT_WARP) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsSurfableFishableWater(u8 var) +{ + if(var == MB_POND_WATER || var == MB_OCEAN_WATER || var == MB_SEMI_DEEP_WATER || var == MB_DEEP_WATER || var == MB_SOOTOPOLIS_DEEP_WATER || (var >= MB_EASTWARD_CURRENT && var <= MB_SOUTHWARD_CURRENT)) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsMtPyreHole(u8 var) +{ + if(var == MB_MT_PYRE_HOLE) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsCrackedFloorHole(u8 var) +{ + if(var == MB_CRACKED_FLOOR_HOLE) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsCrackedFloor(u8 var) +{ + if(var == MB_CRACKED_FLOOR) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsMuddySlope(u8 var) +{ + if(var == MB_MUDDY_SLOPE) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsBumpySlope(u8 var) +{ + if(var == MB_BUMPY_SLOPE) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsIsolatedVerticalRail(u8 var) +{ + if(var == MB_ISOLATED_VERTICAL_RAIL) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsIsolatedHorizontalRail(u8 var) +{ + if(var == MB_ISOLATED_HORIZONTAL_RAIL) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsVerticalRail(u8 var) +{ + if(var == MB_VERTICAL_RAIL) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsHorizontalRail(u8 var) +{ + if(var == MB_HORIZONTAL_RAIL) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsSeaweed(u8 var) +{ + if(var == MB_SEAWEED || var == MB_SEAWEED_NO_SURFACING) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsRunningDisallowed(u8 var) +{ + if(var == MB_NO_RUNNING || var == MB_LONG_GRASS || var == MB_HOT_SPRINGS || MetatileBehavior_IsPacifidlogLog(var) != FALSE) + return TRUE; + else + return FALSE; +} + +bool8 sub_80578F8(u8 var) +{ + if(var == MB_TALL_GRASS || var == MB_LONG_GRASS || var == MB_ASH || var == MB_LONG_GRASS_SOUTH_EDGE) + return TRUE; + else + return FALSE; +} + +bool8 sub_805791C(u8 var) +{ + if(var == MB_8E) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsPictureBookShelf(u8 var) +{ + if(var == MB_PICTURE_BOOK_SHELF) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsBookShelf(u8 var) +{ + if(var == MB_BOOKSHELF) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsPokeCenterBookShelf(u8 var) +{ + if(var == MB_POKEMON_CENTER_BOOKSHELF) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsVase(u8 var) +{ + if(var == MB_VASE) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsTrashCan(u8 var) +{ + if(var == MB_TRASH_CAN) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsShopShelf(u8 var) +{ + if(var == MB_SHOP_SHELF) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsBlueprint(u8 var) +{ + if(var == MB_BLUEPRINT) + return TRUE; + else + return FALSE; +} diff --git a/src/money.c b/src/money.c new file mode 100644 index 000000000..2a59cab50 --- /dev/null +++ b/src/money.c @@ -0,0 +1,240 @@ +#include "global.h" +#include "money.h" +#include "decompress.h" +#include "menu.h" +#include "sprite.h" +#include "string_util.h" + +#define SPRITE_TAG_MONEY (0x2722) + +extern u16 gSpecialVar_0x8005; +extern u8 gUnknown_02038734; + +extern const struct SpriteSheet gUnknown_083CF584; +extern const struct SpritePalette gUnknown_083CF58C; +extern const struct SpriteTemplate gSpriteTemplate_83CF56C; + +bool8 IsEnoughMoney(u32 budget, u32 cost) { + if (budget >= cost) { + return TRUE; + } + + return FALSE; +} + +void sub_80B79B8(u32 *arg0, u32 arg1) { + if (*arg0 > *arg0 + arg1) { + *arg0 = 999999; + return; + } + + *arg0 = *arg0 + arg1; + if (*arg0 > 999999) { + *arg0 = 999999; + } +} + +void sub_80B79E0(u32 *arg0, u32 arg1) { + if (*arg0 < arg1) { + *arg0 = 0; + } else { + *arg0 = *arg0 - arg1; + } +} + +void sub_80B79F8(u8 *buffer, u32 arg1, u8 arg2) { + u8 width; + u8 i; + + if (arg1 > 999999) { + width = 7; + } else if (arg1 > 99999) { + width = 6; + } else if (arg1 > 10000) { + width = 5; + } else if (arg1 > 999) { + width = 4; + } else if (arg1 > 99) { + width = 3; + } else if (arg1 > 9) { + width = 2; + } else { + width = 1; + } + + buffer[0] = EXT_CTRL_CODE_BEGIN; + buffer[1] = 0x14; + buffer[2] = 0x06; + buffer += 3; + + for (i = 0; i < arg2 - width; i++) { + buffer[0] = CHAR_SPACE; + buffer += 1; + } + + buffer[0] = CHAR_CURRENCY; + buffer += 1; + + buffer = ConvertIntToDecimalString(buffer, arg1); + + buffer[0] = EXT_CTRL_CODE_BEGIN; + buffer[1] = 0x14; + buffer[2] = 0x00; + buffer[3] = EOS; +} + +void sub_80B7A94(u32 arg0, u8 size, u8 x, u8 y) { + u8 buffer[16]; + u8 stringWidth; + + sub_80B79F8(buffer, arg0, size); + stringWidth = sub_8072CA4(buffer); + + if (stringWidth >= (size + 1) * 8) + MenuPrint(buffer, x, y); + else + { + int xPlusOne = x + 1; + MenuPrint_PixelCoords(buffer, (xPlusOne + size) * 8 - stringWidth, y * 8, 1); + } +} + +void sub_80B7AEC(u32 arg0, u8 left, u8 top) { + u8 buffer[32]; + u8 *ptr; + + ptr = &buffer[0]; + + ptr[0] = CHAR_CURRENCY; + ptr++; + + ptr = ConvertIntToDecimalString(ptr, arg0); + + MenuPrint_RightAligned(buffer, left, top); + + ptr[0] = 0xFC; + ptr[1] = 0x14; + ptr[2] = 0x00; + ptr[3] = 0xFF; +} + +__attribute__((naked)) +void sub_80B7B34(void) { + asm(".syntax unified\n\ + push {r4-r7,lr}\n\ + mov r7, r9\n\ + mov r6, r8\n\ + push {r6,r7}\n\ + sub sp, 0x4\n\ + mov r8, r0\n\ + adds r5, r1, 0\n\ + mov r9, r2\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + mov r8, r0\n\ + lsls r5, 24\n\ + lsrs r5, 24\n\ + mov r1, r9\n\ + lsls r1, 8\n\ + mov r9, r1\n\ + ldr r4, _080B7BD8 @ =gDecoration10000_Gfx\n\ + adds r0, r1, r4\n\ + lsls r6, r5, 4\n\ + subs r6, r5\n\ + lsls r1, r6, 6\n\ + mov r3, r8\n\ + adds r3, 0x1\n\ + lsls r3, 5\n\ + ldr r2, _080B7BDC @ =0x06008000\n\ + adds r3, r2\n\ + adds r1, r3\n\ + movs r2, 0x20\n\ + str r3, [sp]\n\ + bl CpuFastSet\n\ + adds r4, 0x80\n\ + add r9, r4\n\ + adds r0, r5, 0x1\n\ + lsls r4, r0, 4\n\ + subs r4, r0\n\ + lsls r1, r4, 6\n\ + ldr r3, [sp]\n\ + adds r1, r3\n\ + mov r0, r9\n\ + movs r2, 0x20\n\ + bl CpuFastSet\n\ + movs r3, 0\n\ + lsls r5, 5\n\ + mov r0, r8\n\ + adds r7, r5, r0\n\ + lsls r6, 1\n\ + adds r6, 0x1\n\ + add r6, r8\n\ + ldr r1, _080B7BE0 @ =0xfffff000\n\ + adds r5, r1, 0\n\ + ldr r0, _080B7BE4 @ =0x0600f800\n\ + mov r12, r0\n\ + ldr r1, _080B7BE8 @ =0x0600f840\n\ + mov r9, r1\n\ + lsls r4, 1\n\ + adds r4, 0x1\n\ + add r4, r8\n\ +_080B7BAA:\n\ + adds r1, r7, r3\n\ + lsls r1, 1\n\ + mov r0, r12\n\ + adds r2, r1, r0\n\ + adds r0, r3, r6\n\ + adds r0, r5\n\ + strh r0, [r2]\n\ + add r1, r9\n\ + adds r0, r3, r4\n\ + adds r0, r5\n\ + strh r0, [r1]\n\ + adds r0, r3, 0x1\n\ + lsls r0, 16\n\ + lsrs r3, r0, 16\n\ + cmp r3, 0x3\n\ + bls _080B7BAA\n\ + add sp, 0x4\n\ + pop {r3,r4}\n\ + mov r8, r3\n\ + mov r9, r4\n\ + pop {r4-r7}\n\ + pop {r0}\n\ + bx r0\n\ + .align 2, 0\n\ +_080B7BD8: .4byte gDecoration10000_Gfx\n\ +_080B7BDC: .4byte 0x06008000\n\ +_080B7BE0: .4byte 0xfffff000\n\ +_080B7BE4: .4byte 0x0600f800\n\ +_080B7BE8: .4byte 0x0600f840\n\ + .syntax divided\n"); +} + +void sub_80B7BEC(u32 arg0, u8 x, u8 y) { + sub_80B7A94(arg0, 6, x + 6, y + 1); +} + +void sub_80B7C14(u32 arg0, u8 x, u8 y) { + MenuDrawTextWindow(x, y, x + 13, y + 3); + sub_80B7BEC(arg0, x, y); + + LoadCompressedObjectPic(&gUnknown_083CF584); + LoadCompressedObjectPalette(&gUnknown_083CF58C); + + gUnknown_02038734 = CreateSprite(&gSpriteTemplate_83CF56C, x * 8 + 19, y * 8 + 11, 0); +} + +void RemoveMoneyLabelObject(u8 x, u8 y) { + DestroySpriteAndFreeResources(&gSprites[gUnknown_02038734]); + FreeSpritePaletteByTag(SPRITE_TAG_MONEY); + MenuZeroFillWindowRect(x, y, x + 13, y + 3); +} + +bool8 sub_80B7CE8(void) { + return IsEnoughMoney(gSaveBlock1.money, gSpecialVar_0x8005); +} + +void sub_80B7D0C(void) { + sub_80B79E0(&gSaveBlock1.money, gSpecialVar_0x8005); +} diff --git a/src/mori_debug_menu.c b/src/mori_debug_menu.c index 139650c12..645aecc9e 100644 --- a/src/mori_debug_menu.c +++ b/src/mori_debug_menu.c @@ -1,38 +1,47 @@ +#include "global.h" +#include "mori_debug_menu.h" +#include "asm.h" +#include "start_menu.h" +#include "menu.h" #include "main.h" #include "string_util.h" -#include "pokemon.h" +#include "link.h" -extern void sub_8071C20(void); -extern u16 sub_8041870(u16); -extern void sub_810CA6C(s32); -extern u8 (*gCallback_03004AE8)(void); - -extern u8 daycare_count_pokemon(u32); -extern u8 daycare_relationship_score_from_savegame(void); +#define SIO_MULTI_CNT ((struct SioMultiCnt *)REG_ADDR_SIOCNT) -struct DebugMenuAction -{ - u8 *text; - u8 (*func)(void); -}; +extern u8 gUnknown_03004DA0[]; +extern u8 (*gCallback_03004AE8)(void); +extern u8 gUnknown_0839B22C[][3]; +extern u8 gUnknown_0839B24A[]; extern u8 gUnknown_0839B24D[]; extern u8 gUnknown_0839B255[]; extern u8 gUnknown_0839B257[]; -extern struct DebugMenuAction gMoriDebugMenuActions[]; +extern const struct MenuAction gMoriDebugMenuActions[]; extern u8 gSpeciesNames[][11]; -s8 sub_8083D4C(void) +void unref_sub_8083CF0(void) +{ + int i; + int id = SIO_MULTI_CNT->id; + gUnknown_03004DA0[0] = EOS; + StringAppend(gUnknown_03004DA0, gUnknown_0839B24A); + for (i = 0; i < 10; i++) + if ((word_3002910[id ^ 1] >> i) & 1) + StringAppend(gUnknown_03004DA0, gUnknown_0839B22C[i]); +} + +bool8 sub_8083D4C(void) { - if ( gMain.newKeys & 1 ) + if ( gMain.newKeys & A_BUTTON ) { - sub_8071C20(); - return 1; + CloseMenu(); + return TRUE; } else - return 0; + return FALSE; } u8 MoriDebugMenu_SearchChild(u8 a1, u8 a2, u8 *ptr) @@ -58,7 +67,7 @@ s8 MoriDebugMenu_Egg(void) { if ( daycare_count_pokemon(gSaveBlock1.filler_2F9C) == 2 && daycare_relationship_score_from_savegame() ) sub_8041940(); - sub_8071C20(); + CloseMenu(); return 1; } @@ -67,7 +76,7 @@ s8 MoriDebugMenu_MaleEgg(void) { if ( daycare_count_pokemon(gSaveBlock1.filler_2F9C) == 2 && daycare_relationship_score_from_savegame() ) sub_8041950(); - sub_8071C20(); + CloseMenu(); return 1; } @@ -75,21 +84,21 @@ s8 MoriDebugMenu_MaleEgg(void) s8 MoriDebugMenu_1000Steps(void) { sub_8041790(1000); - sub_8071C20(); + CloseMenu(); return 1; } s8 MoriDebugMenu_10000Steps(void) { sub_8041790(10000); - sub_8071C20(); + CloseMenu(); return 1; } s8 MoriDebugMenu_MoveTutor(void) { sub_8132670(); - sub_8071C20(); + CloseMenu(); return 1; } @@ -107,14 +116,14 @@ s8 MoriDebugMenu_BreedEgg(void) } } gSaveBlock1.filler_30B6 = -3; - sub_8071C20(); + CloseMenu(); return 1; } s8 MoriDebugMenu_LongName(void) { - SetMonData(gPlayerParty, 2, &gUnknown_0839B257); - sub_8071C20(); + SetMonData(gPlayerParty, MON_DATA_NICKNAME, gUnknown_0839B257); + CloseMenu(); return 1; } @@ -125,11 +134,11 @@ s8 MoriDebugMenu_PokeblockCase(void) for(loopCounter = 0; loopCounter <= 39; loopCounter++) sub_810CA6C((u8)loopCounter); - sub_8071C20(); + CloseMenu(); return 1; } -s8 MoriDebugMenuProcessInput(void) +bool8 MoriDebugMenuProcessInput(void) { s8 choice = ProcessMenuInput(); @@ -137,12 +146,12 @@ s8 MoriDebugMenuProcessInput(void) { default: gCallback_03004AE8 = gMoriDebugMenuActions[choice].func; - return 0; + return FALSE; case -2: - return 0; + return FALSE; case -1: - sub_8071C20(); - return 1; + CloseMenu(); + return TRUE; } } diff --git a/src/mystery_event_menu.c b/src/mystery_event_menu.c new file mode 100644 index 000000000..09523ff40 --- /dev/null +++ b/src/mystery_event_menu.c @@ -0,0 +1,346 @@ +#include "global.h" +#include "sprite.h" +#include "menu.h" +#include "link.h" +#include "text.h" +#include "main.h" +#include "palette.h" +#include "task.h" +#include "string_util.h" +#include "songs.h" +#include "sound.h" +#include "save.h" +#include "asm.h" +#include "mystery_event_menu.h" + +extern u8 unk_2000000[]; +extern u8 gUnknown_02039338; + +extern u8 gSystemText_LinkStandby[]; +extern u8 gSystemText_LoadEventPressA[]; +extern u8 gSystemText_LoadingEvent[]; +extern u8 gSystemText_DontCutLink[]; +extern u8 gSystemText_EventLoadSuccess[]; +extern u8 gSystemText_LoadingError[]; + +static void VBlankCB(void); +static bool8 CheckLanguageMatch(void); +static bool8 GetEventLoadMessage(u8 *dest, u32 status); +static void CB2_MysteryEventMenu(void); + +static void VBlankCB(void) +{ + LoadOam(); + ProcessSpriteCopyRequests(); + TransferPlttBuffer(); +} + +static bool8 CheckLanguageMatch(void) +{ + bool8 val = FALSE; + + if (gLinkPlayers[0].language == gLinkPlayers[1].language) + val = TRUE; + + return val; +} + +void CB2_InitMysteryEventMenu(void) +{ + ResetSpriteData(); + FreeAllSpritePalettes(); + ResetTasks(); + SetVBlankCallback(VBlankCB); + SetUpWindowConfig(&gWindowConfig_81E6CE4); + InitMenuWindow(&gWindowConfig_81E6CE4); + MenuZeroFillScreen(); + REG_DISPCNT = 320; + REG_BLDCNT = 0; + CreateTask(Task_DestroySelf, 0); + StopMapMusic(); + RunTasks(); + AnimateSprites(); + BuildOamBuffer(); + UpdatePaletteFade(); + FillPalette(0, 0, 2); + SetMainCallback2(CB2_MysteryEventMenu); +} + +static bool8 GetEventLoadMessage(u8 *dest, u32 status) +{ + bool8 retVal = 1; + + if (status == 0) + { + StringCopy(dest, gSystemText_EventLoadSuccess); + retVal = 0; + } + + if (status == 2) + retVal = 0; + + if (status == 1) + StringCopy(dest, gSystemText_LoadingError); + + return retVal; +} + +static void CB2_MysteryEventMenu(void) +{ + u16 unkVal; + + switch (gMain.state) + { + case 0: + MenuDrawTextWindow(0, 14, 29, 19); + BeginNormalPaletteFade(0xFFFFFFFF, 0, 0x10, 0, 0); + gMain.state++; + break; + case 1: + if (gPaletteFade.active) + break; + sub_8072044(gSystemText_LinkStandby); + gMain.state++; + break; + case 2: + if (MenuUpdateWindowText()) + { + gMain.state++; + gLinkType = 21761; + OpenLink(); + } + break; + case 3: + if ((gLinkStatus & 0x20) && (gLinkStatus & 0x1C) > 4) + { + PlaySE(SE_PIN); + sub_8072044(gSystemText_LoadEventPressA); + gMain.state++; + } + if (gMain.newKeys & B_BUTTON) + { + PlaySE(SE_SELECT); + CloseLink(); + gMain.state = 15; + } + break; + case 4: + if (MenuUpdateWindowText()) + gMain.state++; + break; +#ifdef NONMATCHING + case 5: + if (GetLinkPlayerCount_2() != 2) + { + GetEventLoadMessage(gStringVar4, 1); + sub_8072044(gStringVar4); + gMain.state = 13; + break; + } + if (gMain.newKeys & A_BUTTON) + { + PlaySE(SE_SELECT); + sub_8007F4C(); + MenuDrawTextWindow(6, 5, 23, 8); + MenuPrint(gSystemText_LoadingEvent, 7, 6); + gMain.state++; + } + else if (gMain.newKeys & B_BUTTON) + { + PlaySE(SE_SELECT); + CloseLink(); + gMain.state = 15; + } + break; + case 6: + if (IsLinkConnectionEstablished()) + { + if (!gReceivedRemoteLinkPlayers) + break; + + if (GetLinkPlayerDataExchangeStatusTimed() == 3) + { + sub_800832C(); + MenuZeroFillWindowRect(6, 5, 23, 8); + GetEventLoadMessage(gStringVar4, 1); + sub_8072044(gStringVar4); + gMain.state = 13; + break; + } + else if (CheckLanguageMatch()) + { + sub_8072044(gSystemText_DontCutLink); + gMain.state++; + break; + } + else + { + CloseLink(); + MenuZeroFillWindowRect(6, 5, 23, 8); + GetEventLoadMessage(gStringVar4, 1); + sub_8072044(gStringVar4); + gMain.state = 13; + break; + } + } + if (gMain.newKeys & B_BUTTON) + { + PlaySE(SE_SELECT); + CloseLink(); + gMain.state = 15; + break; + } + break; +#else + case 5: + if (GetLinkPlayerCount_2() != 2) + { + goto label; + } + if (gMain.newKeys & A_BUTTON) + { + PlaySE(SE_SELECT); + sub_8007F4C(); + MenuDrawTextWindow(6, 5, 23, 8); + MenuPrint(gSystemText_LoadingEvent, 7, 6); + gMain.state++; + } + else if (gMain.newKeys & B_BUTTON) + { + PlaySE(SE_SELECT); + CloseLink(); + gMain.state = 15; + } + break; + case 6: + if (IsLinkConnectionEstablished()) + { + register u8 *ptr asm("r0"); + register u32 offset1 asm("r2"); + register u32 offset2 asm("r1"); + + if (!gReceivedRemoteLinkPlayers) + break; + + if (GetLinkPlayerDataExchangeStatusTimed() == 3) + { + sub_800832C(); + MenuZeroFillWindowRect(6, 5, 23, 8); + GetEventLoadMessage(gStringVar4, 1); + sub_8072044(gStringVar4); + ptr = (u8 *)&gMain; + offset1 = offsetof(struct Main, state); + asm("" ::: "r1"); + ptr += offset1; + *ptr = 13; + } + else if (CheckLanguageMatch()) + { + register u8 *ptr2 asm("r1"); + register int offset3 asm("r0"); + register int dummy asm("r2"); + sub_8072044(gSystemText_DontCutLink); + ptr2 = (u8 *)&gMain; + offset3 = offsetof(struct Main, state); + if (dummy) + dummy++; + ptr2 += offset3; + (*ptr2)++; + break; + } + else + { + CloseLink(); + MenuZeroFillWindowRect(6, 5, 23, 8); + label: + GetEventLoadMessage(gStringVar4, 1); + sub_8072044(gStringVar4); + ptr = (u8 *)&gMain; + offset2 = offsetof(struct Main, state); + ptr += offset2; + *ptr = 13; + } + break; + } + if (gMain.newKeys & B_BUTTON) + { + PlaySE(SE_SELECT); + CloseLink(); + gMain.state = 15; + break; + } + break; +#endif + case 7: + if (MenuUpdateWindowText()) + gMain.state++; + break; + case 8: + if (GetBlockReceivedStatus()) + { + ResetBlockReceivedFlags(); + gMain.state++; + } + break; + case 9: + gMain.state++; + break; + case 10: + sub_800832C(); + gMain.state++; + break; + case 11: + if (gReceivedRemoteLinkPlayers) + break; + unkVal = sub_812613C(unk_2000000); + CpuFill32(0, unk_2000000, 0x7D4); + if (!GetEventLoadMessage(gStringVar4, unkVal)) + sub_8125D44(0); + gMain.state++; + break; + case 12: + sub_8072044(gStringVar4); + gMain.state++; + break; + case 13: + MenuZeroFillWindowRect(6, 5, 23, 8); + if (MenuUpdateWindowText()) + { + gMain.state++; + gUnknown_02039338 = 0; + } + break; + case 14: + if (gMain.newKeys & A_BUTTON) + { + PlaySE(SE_SELECT); + gMain.state++; + } + break; + case 15: + BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 0x10, 0); + gMain.state++; + break; + case 16: + if (!gPaletteFade.active) + DoSoftReset(); + break; + } + + if (gLinkStatus & 0x40) + { + if (!IsLinkMaster()) + { + CloseLink(); + MenuZeroFillWindowRect(6, 5, 23, 8); + GetEventLoadMessage(gStringVar4, 1); + sub_8072044(gStringVar4); + gMain.state = 13; + } + } + + RunTasks(); + AnimateSprites(); + BuildOamBuffer(); + UpdatePaletteFade(); +} diff --git a/src/mystery_event_script.c b/src/mystery_event_script.c new file mode 100644 index 000000000..4aa3784d7 --- /dev/null +++ b/src/mystery_event_script.c @@ -0,0 +1,97 @@ +#include "global.h" +#include "script.h" +#include "string_util.h" + +#ifdef SAPPHIRE +#define UNK_MASK 0x100 +#else +#define UNK_MASK 0x80 +#endif + +extern struct ScriptContext gUnknown_02039288; + +extern ScrCmdFunc gScriptFuncs[]; +extern ScrCmdFunc gScriptFuncs_End[]; + +extern u8 gOtherText_DataCannotUseVersion[]; + +void sub_8126160(u32 val); + +bool32 sub_8126098(u16 a1, u32 a2, u16 a3, u32 a4) +{ + if (!(a1 & 0x2)) + return FALSE; + + if (!(a2 & 0x2)) + return FALSE; + + if (!(a3 & 0x4)) + return FALSE; + + if (!(a4 & UNK_MASK)) + return FALSE; + + return TRUE; +} + +void sub_81260D0(void) +{ + StringExpandPlaceholders(gStringVar4, gOtherText_DataCannotUseVersion); + sub_8126160(3); +} + +void sub_81260EC(struct ScriptContext *ctx, u8 *ptr) +{ + InitScriptContext(ctx, gScriptFuncs, gScriptFuncs_End); + SetupBytecodeScript(ctx, ptr); + ctx->data[0] = (u32)ptr; + ctx->data[1] = 0; + ctx->data[2] = 0; + ctx->data[3] = 0; +} + +bool32 sub_812611C(struct ScriptContext *ctx) +{ + if (RunScript(ctx) && ctx->data[3]) + return TRUE; + else + return FALSE; +} + +u32 sub_812613C(u8 *ptr) +{ + struct ScriptContext *ctx = &gUnknown_02039288; + sub_81260EC(ctx, ptr); + while (sub_812611C(ctx)) + ; + return ctx->data[2]; +} + +void sub_8126160(u32 val) +{ + gUnknown_02039288.data[2] = val; +} + +int sub_812616C(u8 *a1, int a2) +{ + unsigned int i; + int sum = 0; + + for (i = 0; i < a2; i++) + sum += a1[i]; + + return sum; +} + +u32 sub_812618C(u8 *ptr) +{ + return ptr[0] | (ptr[1] << 8) | (ptr[2] << 16) | (ptr[3] << 24); +} + +void sub_81261A4(u8 *ptr, u32 val) +{ + ptr[0] = val; + ptr[1] = val >> 8; + ptr[2] = val >> 16; + ptr[3] = val >> 24; +} diff --git a/src/new_game.c b/src/new_game.c index 3225ba2bd..4f93e4e3c 100644 --- a/src/new_game.c +++ b/src/new_game.c @@ -1,9 +1,16 @@ #include "global.h" +#include "new_game.h" +#include "asm.h" +#include "berry.h" +#include "play_time.h" +#include "pokemon_size_record.h" +#include "script.h" +#include "rom4.h" +#include "pokedex.h" +#include "lottery_corner.h" #include "rng.h" #include "rtc.h" -#include "pokemon.h" - -extern void warp1_set(s8, s8, s8, s8, s8); +#include "event_data.h" extern u8 gUnknown_020297EC; @@ -12,21 +19,29 @@ extern u8 gUnknown_03005CE8; extern u16 gSaveFileStatus; extern u8 gUnknown_0819FA81[]; -extern const struct SB1_2EFC_Struct gUnknown_08216604; -void write_word_to_mem(u32 a1, u8 *a2) +const struct SB1_2EFC_Struct gUnknown_08216604 = +{ + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + } +}; + +void write_word_to_mem(u32 var, u8 *dataPtr) { - a2[0] = a1; - a2[1] = a1 >> 8; - a2[2] = a1 >> 16; - a2[3] = a1 >> 24; + dataPtr[0] = var; + dataPtr[1] = var >> 8; + dataPtr[2] = var >> 16; + dataPtr[3] = var >> 24; } -void sub_8052D10(u8 *a1, u8 *a2) +void copy_word_to_mem(u8 *copyTo, u8 *copyFrom) { s32 i; for (i = 0; i < 4; i++) - a1[i] = a2[i]; + copyTo[i] = copyFrom[i]; } void set_player_trainer_id(void) @@ -34,6 +49,7 @@ void set_player_trainer_id(void) write_word_to_mem((Random() << 16) | Random(), gSaveBlock2.playerTrainerId); } +// L=A isnt set here for some reason. void SetDefaultOptions(void) { gSaveBlock2.optionsTextSpeed = OPTIONS_TEXT_SPEED_MID; @@ -44,7 +60,7 @@ void SetDefaultOptions(void) gSaveBlock2.regionMapZoom = FALSE; } -void sub_8052D78(void) +void ClearPokedexFlags(void) { gUnknown_03005CE8 = 0; memset(&gSaveBlock2.pokedex.owned, 0, sizeof(gSaveBlock2.pokedex.owned)); @@ -61,10 +77,10 @@ void sub_8052DA8(void) void sub_8052DE4(void) { - CpuFill32(0, gSaveBlock2.filler_A8, sizeof(gSaveBlock2.filler_A8)); + CpuFill32(0, &gSaveBlock2.filler_A8, sizeof(gSaveBlock2.filler_A8)); } -void sub_8052E04(void) +void WarpToTruck(void) { warp1_set(25, 40, -1, -1, -1); // inside of truck warp_in(); @@ -96,18 +112,18 @@ void NewGameInitData(void) sub_8052DE4(); memset(&gSaveBlock1, 0, sizeof(gSaveBlock1)); sub_80A2B18(); - gSaveBlock2.sb2_field_9 = 0; + gSaveBlock2.specialSaveWarp = 0; set_player_trainer_id(); PlayTimeCounter_Reset(); - sub_8052D78(); - sub_8069030(); + ClearPokedexFlags(); + InitEventData(); sub_80BD7A8(); sub_80BDAB4(); sub_80BB5B4(); - sub_80B4A90(); + ClearBerryTrees(); gSaveBlock1.money = 3000; sub_80AB1B0(); - sub_80530AC(); + ResetGameStats(); sub_8052DA8(); InitLinkBattleRecords(); InitShroomishSizeRecord(); @@ -126,7 +142,7 @@ void NewGameInitData(void) sub_80F7AA4(); sub_80FA17C(); sub_810FA54(); - sub_8145A78(); - sub_8052E04(); + ResetLotteryCorner(); + WarpToTruck(); ScriptContext2_RunNewScript(gUnknown_0819FA81); } diff --git a/src/option_menu.c b/src/option_menu.c index ede91acf0..f597429c1 100644 --- a/src/option_menu.c +++ b/src/option_menu.c @@ -1,4 +1,5 @@ #include "global.h" +#include "option_menu.h" #include "main.h" #include "menu.h" #include "palette.h" @@ -309,7 +310,7 @@ static void Task_OptionMenuFadeOut(u8 taskId) if(!gPaletteFade.active) { DestroyTask(taskId); - SetMainCallback2(gMain.field_8); + SetMainCallback2(gMain.savedCallback); } } diff --git a/src/palette.c b/src/palette.c index 243c0c87b..165eb2eae 100644 --- a/src/palette.c +++ b/src/palette.c @@ -1,5 +1,8 @@ #include "global.h" #include "palette.h" +#include "asm.h" +#include "blend_palette.h" +#include "decompress.h" enum { @@ -27,7 +30,7 @@ struct PaletteStructTemplate struct PaletteStruct { - struct PaletteStructTemplate *base; + const struct PaletteStructTemplate *base; u32 ps_field_4_0:1; u16 ps_field_4_1:1; u32 baseDestOffset:9; @@ -37,9 +40,6 @@ struct PaletteStruct u8 ps_field_9; }; -extern void sub_800D238(const void *src, void *dest); -extern void BlendPalette(u16, u16, u8, u16); - EWRAM_DATA u16 gPlttBufferUnfaded[0x200] = {0}; EWRAM_DATA u16 gPlttBufferFaded[0x200] = {0}; EWRAM_DATA static struct PaletteStruct sPaletteStructs[0x10] = {0}; @@ -48,7 +48,19 @@ EWRAM_DATA u32 gFiller_202F394 = 0; EWRAM_DATA static u32 sPlttBufferTransferPending = 0; EWRAM_DATA static u8 sPaletteDecompressionBuffer[0x400] = {0}; -extern struct PaletteStructTemplate gDummyPaletteStructTemplate; +static const struct PaletteStructTemplate sDummyPaletteStructTemplate = +{ + 0xFFFF, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0 +}; static void unused_sub_8073DFC(struct PaletteStruct *, u32 *); static void unused_sub_8073F60(struct PaletteStruct *, u32 *); @@ -332,7 +344,7 @@ void ResetPaletteStructByUid(u16 a1) void ResetPaletteStruct(u8 paletteNum) { - sPaletteStructs[paletteNum].base = &gDummyPaletteStructTemplate; + sPaletteStructs[paletteNum].base = &sDummyPaletteStructTemplate; sPaletteStructs[paletteNum].ps_field_4_0 = 0; sPaletteStructs[paletteNum].baseDestOffset = 0; sPaletteStructs[paletteNum].destOffset = 0; diff --git a/src/party_menu.c b/src/party_menu.c new file mode 100644 index 000000000..ce1b0f32a --- /dev/null +++ b/src/party_menu.c @@ -0,0 +1,317 @@ +#include "global.h" +#include "menu.h" +#include "pokemon.h" +#include "songs.h" +#include "sound.h" +#include "string_util.h" +#include "task.h" + +#define DATA_COUNT (6) + +struct Unk201C000 { + /* 0x00 */ struct Pokemon *pokemon; + /* 0x04 */ u8 var04; + /* 0x05 */ u8 var05; + /* 0x06 */ u16 var06; + u8 pad_08[10]; + /* 0x12 */ u16 var12; +}; + +struct Unk201B260 { + /* 0x00 */ u8 var00; + /* 0x01 */ u8 var01; + u8 pad_02[2]; + /* 0x04 */ s16 var04[DATA_COUNT * 2]; + u8 pad_1C[2]; + /* 0x1E */ u16 var1E; + /* 0x20 */ u16 var20; +}; + +extern struct Unk201B260 unk_201B260; +extern struct Unk201C000 unk_201C000; +extern u8 gStringVar1[]; +extern u8 gUnknown_0202E8F4; +extern u8 gUnknown_0202E8F6; + +extern u8 gUnknown_083769A8[][12]; +extern u8 gUnknown_08376D1C[DATA_COUNT]; +extern u8 *gUnknown_08376D04[DATA_COUNT]; +extern u8 gOtherText_TallPlusAndRightArrow[]; + +void task_pc_turn_off(u8 *u8, int i); +static void sub_806E884(u8 taskId); +void sub_806F8AC(u8 taskId); +void PartyMenuUpdateLevelOrStatus(struct Pokemon *, u8); +u8 ExecuteTableBasedItemEffect__(u8 u8, u16 u16, int i); +void sub_80701DC(u8 taskId); + +u8 sub_806E834(u8 *message, u8 arg1) { + u8 taskId; + + gUnknown_0202E8F6 = 1; + + MenuDrawTextWindow(3, 14, 26, 19); + MenuPrintMessage(message, 4, 15); + + taskId = CreateTask(sub_806E884, 1); + gTasks[taskId].data[0] = arg1; + + return taskId; +} + +static void sub_806E884(u8 taskId) { + if (MenuUpdateWindowText() == 0) { + return; + } + + gUnknown_0202E8F6 = 0; + + if (gTasks[taskId].data[0] == 0) { + MenuZeroFillWindowRect(3, 14, 26, 19); + } + + DestroyTask(taskId); +} + +asm(".section .text_b"); + +#ifdef NONMATCHING +void sub_8070088(u8 taskId) { + u8 dummyTaskId; + struct Task *task2; + + gTasks[taskId].func = TaskDummy; + + if (GetMonData(&gPlayerParty[unk_201C000.var04], MON_DATA_SPECIES) == 0) { + gTasks[taskId].func = sub_80701DC; + return; + } + + dummyTaskId = CreateTask(TaskDummy, 5); + task2 = &gTasks[dummyTaskId]; + + task2->data[10] = GetMonData(unk_201C000.pokemon, MON_DATA_MAX_HP); + task2->data[11] = GetMonData(unk_201C000.pokemon, MON_DATA_HP); + + if (ExecuteTableBasedItemEffect__(unk_201C000.var05, unk_201C000.var06, 0)) { + DestroyTask(dummyTaskId); + gTasks[taskId].func = sub_80701DC; + return; + } + + gUnknown_0202E8F4 = 1; + MenuZeroFillWindowRect(3, 14, 26, 19); + PlaySE(SE_KAIFUKU); + PartyMenuUpdateLevelOrStatus(unk_201C000.pokemon, unk_201C000.var05); + + task_pc_turn_off(&gUnknown_083769A8[IsDoubleBattle()][unk_201C000.var05], 9); + unk_201B260.var01 = 2; // u8 + + task2->data[12] = GetMonData(unk_201C000.pokemon, MON_DATA_HP) - task2->data[11]; + task2->data[14]= 1; + unk_201B260.var1E = 1; // u16 + unk_201B260.var20 = 1; // u16 + + unk_201C000.var12 = -0x8000; + task2->func = sub_806F8AC; +} +#else +__attribute__((naked)) +void sub_8070088(void) { + 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\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + ldr r1, _08070120 @ =gTasks\n\ + mov r10, r1\n\ + lsls r1, r0, 2\n\ + adds r1, r0\n\ + lsls r1, 3\n\ + mov r2, r10\n\ + adds r7, r1, r2\n\ + ldr r5, _08070124 @ =TaskDummy\n\ + str r5, [r7]\n\ + ldr r4, _08070128 @ =0x0201c000\n\ + ldrb r0, [r4, 0x5]\n\ + movs r1, 0x64\n\ + mov r9, r1\n\ + mov r2, r9\n\ + muls r2, r0\n\ + adds r0, r2, 0\n\ + ldr r1, _0807012C @ =gPlayerParty\n\ + mov r8, r1\n\ + add r0, r8\n\ + movs r1, 0xB\n\ + bl GetMonData\n\ + cmp r0, 0\n\ + beq _08070118\n\ + adds r0, r5, 0\n\ + movs r1, 0x5\n\ + bl CreateTask\n\ + lsls r0, 24\n\ + lsrs r5, r0, 24\n\ + lsls r0, r5, 2\n\ + adds r0, r5\n\ + lsls r0, 3\n\ + str r0, [sp]\n\ + mov r0, r10\n\ + adds r0, 0x8\n\ + ldr r2, [sp]\n\ + adds r6, r2, r0\n\ + ldrb r0, [r4, 0x5]\n\ + mov r1, r9\n\ + muls r1, r0\n\ + adds r0, r1, 0\n\ + add r0, r8\n\ + str r0, [r4]\n\ + movs r1, 0x3A\n\ + bl GetMonData\n\ + strh r0, [r6, 0x14]\n\ + ldr r0, [r4]\n\ + movs r1, 0x39\n\ + bl GetMonData\n\ + strh r0, [r6, 0x16]\n\ + ldrb r0, [r4, 0x5]\n\ + ldrh r1, [r4, 0x6]\n\ + movs r2, 0\n\ + bl ExecuteTableBasedItemEffect__\n\ + lsls r0, 24\n\ + cmp r0, 0\n\ + beq _08070134\n\ + adds r0, r5, 0\n\ + bl DestroyTask\n\ +_08070118:\n\ + ldr r0, _08070130 @ =sub_80701DC\n\ + str r0, [r7]\n\ + b _080701B0\n\ + .align 2, 0\n\ +_08070120: .4byte gTasks\n\ +_08070124: .4byte TaskDummy\n\ +_08070128: .4byte 0x0201c000\n\ +_0807012C: .4byte gPlayerParty\n\ +_08070130: .4byte sub_80701DC\n\ +_08070134:\n\ + ldr r1, _080701C0 @ =gUnknown_0202E8F4\n\ + movs r0, 0x1\n\ + strb r0, [r1]\n\ + movs r0, 0x3\n\ + movs r1, 0xE\n\ + movs r2, 0x1A\n\ + movs r3, 0x13\n\ + bl MenuZeroFillWindowRect\n\ + movs r0, 0x1\n\ + bl PlaySE\n\ + ldr r0, [r4]\n\ + ldrb r1, [r4, 0x5]\n\ + bl PartyMenuUpdateLevelOrStatus\n\ + bl IsDoubleBattle\n\ + adds r1, r0, 0\n\ + lsls r1, 24\n\ + lsrs r1, 24\n\ + lsls r0, r1, 1\n\ + adds r0, r1\n\ + lsls r0, 2\n\ + ldrb r1, [r4, 0x5]\n\ + lsls r1, 1\n\ + adds r0, r1\n\ + ldr r1, _080701C4 @ =gUnknown_083769A8\n\ + adds r0, r1\n\ + movs r1, 0x9\n\ + bl task_pc_turn_off\n\ + ldr r2, _080701C8 @ =0xfffff261\n\ + adds r1, r4, r2\n\ + movs r0, 0x2\n\ + strb r0, [r1]\n\ + ldr r0, [r4]\n\ + movs r1, 0x39\n\ + bl GetMonData\n\ + ldrh r1, [r6, 0x16]\n\ + subs r0, r1\n\ + strh r0, [r6, 0x18]\n\ + movs r0, 0x1\n\ + strh r0, [r6, 0x1C]\n\ + ldr r1, _080701CC @ =0xfffff27e\n\ + adds r0, r4, r1\n\ + movs r1, 0x1\n\ + strh r1, [r0]\n\ + ldr r2, _080701D0 @ =0xfffff280\n\ + adds r0, r4, r2\n\ + strh r1, [r0]\n\ + ldrh r1, [r6, 0x16]\n\ + adds r2, 0x2\n\ + adds r0, r4, r2\n\ + strh r1, [r0]\n\ + ldr r0, _080701D4 @ =0xffff8000\n\ + str r0, [r4, 0xC]\n\ + ldr r1, [sp]\n\ + add r1, r10\n\ + ldr r0, _080701D8 @ =sub_806F8AC\n\ + str r0, [r1]\n\ +_080701B0:\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 {r0}\n\ + bx r0\n\ + .align 2, 0\n\ +_080701C0: .4byte gUnknown_0202E8F4\n\ +_080701C4: .4byte gUnknown_083769A8\n\ +_080701C8: .4byte 0xfffff261\n\ +_080701CC: .4byte 0xfffff27e\n\ +_080701D0: .4byte 0xfffff280\n\ +_080701D4: .4byte 0xffff8000\n\ +_080701D8: .4byte sub_806F8AC\n\ + .syntax divided\n"); +} +#endif + + +asm(".section .text_c"); + +void sub_8070848(u8 taskId) { + u8 i; + + MenuDrawTextWindow(11, 0, 29, 7); + + for (i = 0; i < DATA_COUNT; i++) { + u8 x; + u8 y; + u32 stat; + struct Pokemon **pokemon; + + pokemon = &unk_201C000.pokemon; + asm("" ::: "r0"); + stat = GetMonData(*pokemon, gUnknown_08376D1C[i]); + + unk_201B260.var04[i + DATA_COUNT] = stat; + unk_201B260.var04[i] = stat - unk_201B260.var04[i]; + + x = (i / 3) * 9 + 11; + y = ((i % 3) << 1) + 1; + + MenuPrint_PixelCoords(gUnknown_08376D04[i], (x + 1) * 8, y * 8, 1); + + + if (i == 2) { + MenuPrint_PixelCoords(gOtherText_TallPlusAndRightArrow, (x + 6) * 8 + 6, y * 8, 0); + } else { + MenuPrint_PixelCoords(gOtherText_TallPlusAndRightArrow, (x + 6) * 8 + 6, y * 8, 1); + } + + gStringVar1[0] = 0xFC; + gStringVar1[1] = 0x14; + gStringVar1[2] = 0x06; + + ConvertIntToDecimalStringN(gStringVar1 + 3, unk_201B260.var04[i], 1, 2); + + MenuPrint_PixelCoords(gStringVar1, (x + 6) * 8 + 12, y * 8, 0); + } +} diff --git a/src/play_time.c b/src/play_time.c index 4eabf38cc..9882c9c4b 100644 --- a/src/play_time.c +++ b/src/play_time.c @@ -10,8 +10,6 @@ enum static u8 sPlayTimeCounterState; -void PlayTimeCounter_SetToMax(); - void PlayTimeCounter_Reset() { sPlayTimeCounterState = STOPPED; diff --git a/src/player_pc.c b/src/player_pc.c new file mode 100644 index 000000000..822e2108e --- /dev/null +++ b/src/player_pc.c @@ -0,0 +1,818 @@ +#include "global.h" +#include "item.h" +#include "task.h" +#include "menu.h" +#include "sound.h" +#include "main.h" +#include "script.h" +#include "palette.h" +#include "weather.h" +#include "asm.h" +#include "string_util.h" + +extern void DisplayItemMessageOnField(u8, u8*, TaskFunc, u16); +extern void ItemStorageMenuProcessInput(u8); +extern void DoPlayerPCDecoration(u8); +extern void BuyMenuFreeMemory(void); +extern void DestroyVerticalScrollIndicator(u8); +extern u8 sub_813AF3C(void); +extern void sub_813AF78(void); +extern void sub_813A240(u8); +extern void sub_813B108(u8); +extern void sub_813B174(u8); +extern void sub_80A6A30(void); +extern u8 sub_807D770(void); +extern void sub_813A280(u8); +extern void sub_813AE6C(u8, u8); +extern void sub_813A240(u8); +extern void sub_813AD58(u16); +extern void sub_813AE0C(u8); +extern void sub_813ABE8(u8); +extern void sub_813AA30(u8, u8); +extern void sub_813A4B4(u8); +extern void sub_813A468(u8); + +extern u8 gOtherText_NoItems[]; + +extern u16 gNewGamePCItems[]; + +extern u8 gOtherText_WhatWillYouDo[]; +extern u8 gOtherText_NoMailHere[]; + +extern u8 *gUnknown_02039314; +extern struct MenuAction gUnknown_08406298[]; +extern u8 gUnknown_084062B8[]; +extern u8 gUnknown_084062BC[]; +extern u8 gUnknown_030007B4; +extern u8 unk_201FE00[]; + +extern u8 gUnknown_08152850; +extern u8 gUnknown_08152C75; + +extern u32 gUnknown_08406288[]; +extern const struct MenuAction gUnknown_084062C0[]; + +void InitPlayerPCMenu(u8 taskId); +void PlayerPCProcessMenuInput(u8 taskId); +void InitItemStorageMenu(u8); +void ItemStorageMenuPrint(u8 *); + +void NewGameInitPCItems(void) +{ + u8 i = 0; + + ClearItemSlots(gSaveBlock1.pcItems, 0x32); + + while (gNewGamePCItems[i * 2] && (gNewGamePCItems + 1)[i * 2]) + { + if(AddPCItem(gNewGamePCItems[i * 2], (gNewGamePCItems + 1)[i * 2]) != 1) + break; + i++; + } +} + +void BedroomPC(void) +{ + u8 taskId; + + gUnknown_02039314 = gUnknown_084062B8; + gUnknown_030007B4 = 4; + taskId = CreateTask(TaskDummy, 0); + DisplayItemMessageOnField(taskId, gOtherText_WhatWillYouDo, InitPlayerPCMenu, 0); +} + +void PlayerPC(void) +{ + u8 taskId; + + gUnknown_02039314 = gUnknown_084062BC; + gUnknown_030007B4 = 3; + taskId = CreateTask(TaskDummy, 0); + DisplayItemMessageOnField(taskId, gOtherText_WhatWillYouDo, InitPlayerPCMenu, 0); +} + +void InitPlayerPCMenu(u8 taskId) +{ + MenuDrawTextWindow(0, 0, 10, gUnknown_030007B4 * 2 + 1); + PrintMenuItemsReordered(1, 1, gUnknown_030007B4, gUnknown_08406298, gUnknown_02039314); + InitMenu(0, 1, 1, gUnknown_030007B4, 0, 9); + gTasks[taskId].func = PlayerPCProcessMenuInput; +} + +void PlayerPCProcessMenuInput(u8 taskId) +{ + if(gMain.newAndRepeatedKeys & 0x40) + { + PlaySE(5); + MoveMenuCursor(-1); + } + else if(gMain.newAndRepeatedKeys & 0x80) + { + PlaySE(5); + MoveMenuCursor(1); + } + else if(gMain.newKeys & 0x1) + { + sub_8072DEC(); + PlaySE(5); + gUnknown_08406298[gUnknown_02039314[GetMenuCursorPos()]].func(taskId); + } + else if(gMain.newKeys & 0x2) + { + sub_8072DEC(); + PlaySE(5); + gUnknown_08406298[gUnknown_030007B4[gUnknown_02039314 - 1]].func(taskId); + } +} + +void ReshowPlayerPC(u8 var) +{ + DisplayItemMessageOnField(var, gOtherText_WhatWillYouDo, InitPlayerPCMenu, 0); +} + +void PlayerPC_ItemStorage(u8 taskId) +{ + InitItemStorageMenu(0); + gTasks[taskId].func = ItemStorageMenuProcessInput; +} + +void PlayerPC_Mailbox(u8 taskId) +{ + MenuZeroFillWindowRect(0, 0, 10, 9); + unk_201FE00[3] = sub_813AF3C(); + if(!unk_201FE00[3]) + DisplayItemMessageOnField(taskId, gOtherText_NoMailHere, ReshowPlayerPC, 0); + else + { + unk_201FE00[0] = 0; + unk_201FE00[2] = 0; + sub_813AF78(); + sub_813A240(taskId); + sub_813B108(taskId); + gTasks[taskId].func = sub_813B174; + } +} + +void PlayerPC_Decoration(u8 var) +{ + MenuZeroFillWindowRect(0, 0, 10, 9); + DoPlayerPCDecoration(var); +} + +void PlayerPC_TurnOff(u8 taskId) +{ + if(gUnknown_030007B4 == 4) + { + MenuZeroFillWindowRect(0, 0, 0x1D, 0x13); + if(!gSaveBlock2.playerGender) + ScriptContext1_SetupScript(&gUnknown_08152850); // male + else + ScriptContext1_SetupScript(&gUnknown_08152C75); // female + } + else + { + MenuZeroFillWindowRect(0, 0, 10, 9); + EnableBothScriptContexts(); + } + DestroyTask(taskId); +} + +void InitItemStorageMenu(u8 var) +{ + MenuZeroFillWindowRect(0, 0, 10, 9); + MenuDrawTextWindow(0, 0, 11, 9); + PrintMenuItems(1, 1, 4, gUnknown_084062C0); + InitMenu(0, 1, 1, 4, var, 10); + ItemStorageMenuPrint((u8 *)gUnknown_08406288[var]); +} + +void ItemStorageMenuPrint(u8 *textPtr) +{ + MenuFillWindowRectWithBlankTile(2, 15, 27, 18); + MenuPrint(textPtr, 2, 15); +} + +void ItemStorageMenuProcessInput(u8 var) +{ + if(gMain.newAndRepeatedKeys & 0x40) + { + PlaySE(5); + MoveMenuCursor(-1); + ItemStorageMenuPrint((u8 *)gUnknown_08406288[GetMenuCursorPos()]); + } + else if(gMain.newAndRepeatedKeys & 0x80) + { + PlaySE(5); + MoveMenuCursor(1); + ItemStorageMenuPrint((u8 *)gUnknown_08406288[GetMenuCursorPos()]); + } + else if(gMain.newKeys & 0x1) + { + PlaySE(5); + gUnknown_084062C0[GetMenuCursorPos()].func(var); + } + else if(gMain.newKeys & 0x2) + { + sub_8072DEC(); + PlaySE(5); + gUnknown_084062C0[3].func(var); + } +} + +void Task_ItemStorage_Deposit(u8 taskId) +{ + if(!gPaletteFade.active) + { + sub_80A6A30(); + DestroyTask(taskId); + } +} + +void ItemStorage_Deposit(u8 taskId) +{ + gTasks[taskId].func = Task_ItemStorage_Deposit; + fade_screen(1, 0); +} + +void sub_813A0C8(u8 taskId) +{ + if(sub_807D770() == 1) + gTasks[taskId].func = ItemStorageMenuProcessInput; +} + +void sub_813A0F8(void) +{ + MenuDisplayMessageBox(); + InitItemStorageMenu(1); + CreateTask(sub_813A0C8, 0); + pal_fill_black(); +} + +void ItemStorage_Withdraw(u8 taskId) +{ + u8 var; + u16 * data = gTasks[taskId].data; + + sub_8072DEC(); + MenuZeroFillWindowRect(0, 0, 11, 9); + var = CountUsedPCItemSlots(); + data[2] = var; + + if(var) + { + MenuZeroFillWindowRect(0, 14, 29, 19); + data[6] = 0; + data[0] = 0; + data[1] = 0; + sub_813A240(taskId); + sub_813AE6C(taskId, 0); + gTasks[taskId].func = sub_813A280; + } + else + DisplayItemMessageOnField(taskId, gOtherText_NoItems, PlayerPC_ItemStorage, 0); +} + +void ItemStorage_Toss(u8 taskId) +{ + u8 var; + u16 * data = gTasks[taskId].data; + + sub_8072DEC(); + MenuZeroFillWindowRect(0, 0, 11, 9); + var = CountUsedPCItemSlots(); + data[2] = var; + + if(var) + { + MenuZeroFillWindowRect(0, 14, 29, 19); + data[6] = 2; + data[0] = 0; + data[1] = 0; + sub_813A240(taskId); + sub_813AE6C(taskId, 2); + gTasks[taskId].func = sub_813A280; + } + else + DisplayItemMessageOnField(taskId, gOtherText_NoItems, PlayerPC_ItemStorage, 0); +} + +void ItemStorage_Exit(u8 var) +{ + sub_8072DEC(); + MenuZeroFillWindowRect(0, 0, 11, 9); + ReshowPlayerPC(var); +} + +void sub_813A240(u8 taskId) +{ + s16 *data = gTasks[taskId].data; + + if (data[2] > 7) + data[4] = 8; + else + data[4] = data[2] + 1; + + if(unk_201FE00[3] > 7) + unk_201FE00[1] = 8; + else + unk_201FE00[1] = unk_201FE00[3] + 1; +} + +#ifdef NONMATCHING +void sub_813A280(u8 taskId) +{ + s16 *data = gTasks[taskId].data; + + if(gMain.newAndRepeatedKeys & 0x40) + { + if(data[0]) + { + PlaySE(5); + data[0] = MoveMenuCursor(-1); + if(!data[9]) + { + if(data[1] + data[0] == data[2]) + { + sub_813AD58(0xFFFF); + return; + } + sub_813AD58(gSaveBlock1.pcItems[data[1] + data[0]].itemId); + } + return; + } + if(!data[1]) + return; + PlaySE(5); + sub_813AE0C(taskId); + if(data[9]) + MoveMenuCursor(0); + return; + } + if(!(gMain.newAndRepeatedKeys & 0x80)) + { + if(gMain.newKeys & 0x4) + { + if(!data[9]) + { + if(data[0] + data[1] != data[2]) + { + PlaySE(5); + data[9] = 1; + data[8] = data[0] + data[1]; + sub_813AD58(0xFFF7); + } + sub_813ABE8(taskId); + return; + } + PlaySE(5); + sub_813AA30(taskId, 0); + sub_813AE0C(taskId); + return; + } + if(gMain.newKeys & 0x1) + { + PlaySE(5); + if(data[9]) + { + sub_813AA30(taskId, 0); + sub_813AE0C(taskId); + return; + } + if(data[1] + data[0] != data[2]) + { + sub_813A4B4(taskId); + return; + } + } + else + { + if(!(gMain.newKeys & 0x2)) + return; + PlaySE(5); + if(data[9]) + { + sub_813AA30(taskId, 1); + sub_813AE0C(taskId); + return; + } + sub_8072DEC(); + } + sub_813A468(taskId); + return; + } + if(data[0] == data[4] - 1) + { + if(data[1] + data[0] == data[2]) + return; + PlaySE(5); + data[1]++; + sub_813AE0C(taskId); + if(data[9]) + MoveMenuCursor(0); + return; + } + PlaySE(5); + data[0] = MoveMenuCursor(1); + if(!data[9]) + { + if(data[1] + data[0] != data[2]) + { + sub_813AD58(gSaveBlock1.pcItems[data[1] + data[0]].itemId); + return; + } + sub_813AD58(0xFFFF); + } +} +#else +__attribute__((naked)) +void sub_813A280(u8 taskId) +{ + asm(".syntax unified\n\ + push {r4-r6,lr}\n\ + lsls r0, 24\n\ + lsrs r5, r0, 24\n\ + adds r6, r5, 0\n\ + lsls r0, r5, 2\n\ + adds r0, r5\n\ + lsls r0, 3\n\ + ldr r1, _0813A2DC @ =gTasks + 0x8\n\ + adds r4, r0, r1\n\ + ldr r2, _0813A2E0 @ =gMain\n\ + ldrh r1, [r2, 0x30]\n\ + movs r0, 0x40\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _0813A306\n\ + movs r1, 0\n\ + ldrsh r0, [r4, r1]\n\ + cmp r0, 0\n\ + beq _0813A2E4\n\ + movs r0, 0x5\n\ + bl PlaySE\n\ + movs r0, 0x1\n\ + negs r0, r0\n\ + bl MoveMenuCursor\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + strh r0, [r4]\n\ + ldrh r1, [r4, 0x2]\n\ + adds r1, r0\n\ + lsls r1, 16\n\ + lsrs r1, 16\n\ + movs r2, 0x12\n\ + ldrsh r0, [r4, r2]\n\ + cmp r0, 0\n\ + beq _0813A2CC\n\ + b _0813A460\n\ +_0813A2CC:\n\ + lsls r0, r1, 16\n\ + asrs r1, r0, 16\n\ + movs r2, 0x4\n\ + ldrsh r0, [r4, r2]\n\ + cmp r1, r0\n\ + beq _0813A34C\n\ + b _0813A358\n\ + .align 2, 0\n\ +_0813A2DC: .4byte gTasks + 0x8\n\ +_0813A2E0: .4byte gMain\n\ +_0813A2E4:\n\ + movs r1, 0x2\n\ + ldrsh r0, [r4, r1]\n\ + cmp r0, 0\n\ + bne _0813A2EE\n\ + b _0813A460\n\ +_0813A2EE:\n\ + movs r0, 0x5\n\ + bl PlaySE\n\ + ldrh r0, [r4, 0x2]\n\ + subs r0, 0x1\n\ + strh r0, [r4, 0x2]\n\ + adds r0, r5, 0\n\ + bl sub_813AE0C\n\ + movs r2, 0x12\n\ + ldrsh r0, [r4, r2]\n\ + b _0813A394\n\ +_0813A306:\n\ + movs r0, 0x80\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _0813A3A0\n\ + movs r0, 0\n\ + ldrsh r1, [r4, r0]\n\ + movs r2, 0x8\n\ + ldrsh r0, [r4, r2]\n\ + subs r0, 0x1\n\ + cmp r1, r0\n\ + beq _0813A370\n\ + movs r0, 0x5\n\ + bl PlaySE\n\ + movs r0, 0x1\n\ + bl MoveMenuCursor\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + strh r0, [r4]\n\ + ldrh r1, [r4, 0x2]\n\ + adds r1, r0\n\ + lsls r1, 16\n\ + lsrs r1, 16\n\ + movs r2, 0x12\n\ + ldrsh r0, [r4, r2]\n\ + cmp r0, 0\n\ + beq _0813A340\n\ + b _0813A460\n\ +_0813A340:\n\ + lsls r0, r1, 16\n\ + asrs r1, r0, 16\n\ + movs r2, 0x4\n\ + ldrsh r0, [r4, r2]\n\ + cmp r1, r0\n\ + bne _0813A358\n\ +_0813A34C:\n\ + ldr r0, _0813A354 @ =0x0000ffff\n\ + bl sub_813AD58\n\ + b _0813A460\n\ + .align 2, 0\n\ +_0813A354: .4byte 0x0000ffff\n\ +_0813A358:\n\ + ldr r0, _0813A36C @ =gSaveBlock1\n\ + lsls r1, 2\n\ + adds r1, r0\n\ + movs r0, 0x93\n\ + lsls r0, 3\n\ + adds r1, r0\n\ + ldrh r0, [r1]\n\ + bl sub_813AD58\n\ + b _0813A460\n\ + .align 2, 0\n\ +_0813A36C: .4byte gSaveBlock1\n\ +_0813A370:\n\ + movs r2, 0x2\n\ + ldrsh r0, [r4, r2]\n\ + adds r0, r1\n\ + movs r2, 0x4\n\ + ldrsh r1, [r4, r2]\n\ + cmp r0, r1\n\ + beq _0813A460\n\ + movs r0, 0x5\n\ + bl PlaySE\n\ + ldrh r0, [r4, 0x2]\n\ + adds r0, 0x1\n\ + strh r0, [r4, 0x2]\n\ + adds r0, r5, 0\n\ + bl sub_813AE0C\n\ + movs r1, 0x12\n\ + ldrsh r0, [r4, r1]\n\ +_0813A394:\n\ + cmp r0, 0\n\ + beq _0813A460\n\ + movs r0, 0\n\ + bl MoveMenuCursor\n\ + b _0813A460\n\ +_0813A3A0:\n\ + ldrh r1, [r2, 0x2E]\n\ + movs r0, 0x4\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _0813A3F0\n\ + movs r2, 0x12\n\ + ldrsh r0, [r4, r2]\n\ + cmp r0, 0\n\ + bne _0813A3E8\n\ + movs r1, 0\n\ + ldrsh r0, [r4, r1]\n\ + movs r2, 0x2\n\ + ldrsh r1, [r4, r2]\n\ + adds r0, r1\n\ + movs r2, 0x4\n\ + ldrsh r1, [r4, r2]\n\ + cmp r0, r1\n\ + beq _0813A3DC\n\ + movs r0, 0x5\n\ + bl PlaySE\n\ + movs r0, 0x1\n\ + strh r0, [r4, 0x12]\n\ + ldrh r0, [r4]\n\ + ldrh r1, [r4, 0x2]\n\ + adds r0, r1\n\ + strh r0, [r4, 0x10]\n\ + ldr r0, _0813A3E4 @ =0x0000fff7\n\ + bl sub_813AD58\n\ +_0813A3DC:\n\ + adds r0, r5, 0\n\ + bl sub_813ABE8\n\ + b _0813A460\n\ + .align 2, 0\n\ +_0813A3E4: .4byte 0x0000fff7\n\ +_0813A3E8:\n\ + movs r0, 0x5\n\ + bl PlaySE\n\ + b _0813A420\n\ +_0813A3F0:\n\ + movs r0, 0x1\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _0813A430\n\ + movs r0, 0x5\n\ + bl PlaySE\n\ + movs r2, 0x12\n\ + ldrsh r0, [r4, r2]\n\ + cmp r0, 0\n\ + bne _0813A420\n\ + movs r1, 0x2\n\ + ldrsh r0, [r4, r1]\n\ + movs r2, 0\n\ + ldrsh r1, [r4, r2]\n\ + adds r0, r1\n\ + movs r2, 0x4\n\ + ldrsh r1, [r4, r2]\n\ + cmp r0, r1\n\ + beq _0813A44A\n\ + adds r0, r5, 0\n\ + bl sub_813A4B4\n\ + b _0813A460\n\ +_0813A420:\n\ + adds r0, r5, 0\n\ + movs r1, 0\n\ + bl sub_813AA30\n\ + adds r0, r5, 0\n\ + bl sub_813AE0C\n\ + b _0813A460\n\ +_0813A430:\n\ + movs r0, 0x2\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _0813A460\n\ + movs r0, 0x5\n\ + bl PlaySE\n\ + movs r1, 0x12\n\ + ldrsh r0, [r4, r1]\n\ + cmp r0, 0\n\ + bne _0813A452\n\ + bl sub_8072DEC\n\ +_0813A44A:\n\ + adds r0, r5, 0\n\ + bl sub_813A468\n\ + b _0813A460\n\ +_0813A452:\n\ + adds r0, r6, 0\n\ + movs r1, 0x1\n\ + bl sub_813AA30\n\ + adds r0, r6, 0\n\ + bl sub_813AE0C\n\ +_0813A460:\n\ + pop {r4-r6}\n\ + pop {r0}\n\ + bx r0\n\ + .syntax divided"); +} +#endif + +void sub_813A468(u8 taskId) +{ + BuyMenuFreeMemory(); + DestroyVerticalScrollIndicator(0); + DestroyVerticalScrollIndicator(1); + MenuZeroFillWindowRect(0, 0, 29, 19); + MenuDisplayMessageBox(); + InitItemStorageMenu(gTasks[taskId].data[6]); + gTasks[taskId].func = ItemStorageMenuProcessInput; +} + +#ifdef NONMATCHING +void sub_813A4B4(u8 taskId) +{ + u16 *data = gTasks[taskId].data; + u16 var = data[2] + data[0]; + + sub_80F996C(0); + sub_80F996C(1); + + if(data[6]) + { + if(gSaveBlock1.pcItems[var].itemId == 1) + { + data[3] = 1; + sub_813A794(taskId); + return; + } + sub_813AD58(0xFFF7); + data[3] = 1; + MenuDrawTextWindow(6, 8, 13, 11); + sub_80A418C(data[3], STR_CONV_MODE_RIGHT_ALIGN, 8, 9, 3); + gTasks[taskId].func = sub_813A584; + return; + } + if(gSaveBlock1.pcItems[var].itemId != 1) + { + sub_813AD58(0xFFF7); + data[3] = 1; + MenuDrawTextWindow(6, 8, 13, 11); + sub_80A418C(data[3], STR_CONV_MODE_RIGHT_ALIGN, 8, 9, 3); + gTasks[taskId].func = sub_813A584; + return; + } + data[3] = 1; + sub_813A6FC(taskId); +} +#else +__attribute__((naked)) +void sub_813A4B4(u8 taskId) +{ + asm(".syntax unified\n\ + push {r4-r6,lr}\n\ + sub sp, 0x4\n\ + lsls r0, 24\n\ + lsrs r6, r0, 24\n\ + lsls r0, r6, 2\n\ + adds r0, r6\n\ + lsls r0, 3\n\ + ldr r1, _0813A500 @ =gTasks + 0x8\n\ + adds r4, r0, r1\n\ + ldrb r0, [r4, 0x2]\n\ + ldrb r1, [r4]\n\ + adds r0, r1\n\ + lsls r0, 24\n\ + lsrs r5, r0, 24\n\ + movs r0, 0\n\ + bl sub_80F996C\n\ + movs r0, 0x1\n\ + bl sub_80F996C\n\ + movs r1, 0xC\n\ + ldrsh r0, [r4, r1]\n\ + cmp r0, 0\n\ + bne _0813A518\n\ + ldr r1, _0813A504 @ =gSaveBlock1\n\ + lsls r0, r5, 2\n\ + adds r0, r1\n\ + ldr r1, _0813A508 @ =0x0000049a\n\ + adds r0, r1\n\ + ldrh r0, [r0]\n\ + cmp r0, 0x1\n\ + bne _0813A50C\n\ + strh r0, [r4, 0x6]\n\ + adds r0, r6, 0\n\ + bl sub_813A6FC\n\ + b _0813A570\n\ + .align 2, 0\n\ +_0813A500: .4byte gTasks + 0x8\n\ +_0813A504: .4byte gSaveBlock1\n\ +_0813A508: .4byte 0x0000049a\n\ +_0813A50C:\n\ + ldr r0, _0813A514 @ =0x0000fffe\n\ + bl sub_813AD58\n\ + b _0813A542\n\ + .align 2, 0\n\ +_0813A514: .4byte 0x0000fffe\n\ +_0813A518:\n\ + ldr r1, _0813A534 @ =gSaveBlock1\n\ + lsls r0, r5, 2\n\ + adds r0, r1\n\ + ldr r1, _0813A538 @ =0x0000049a\n\ + adds r0, r1\n\ + ldrh r0, [r0]\n\ + cmp r0, 0x1\n\ + bne _0813A53C\n\ + strh r0, [r4, 0x6]\n\ + adds r0, r6, 0\n\ + bl sub_813A794\n\ + b _0813A570\n\ + .align 2, 0\n\ +_0813A534: .4byte gSaveBlock1\n\ +_0813A538: .4byte 0x0000049a\n\ +_0813A53C:\n\ + ldr r0, _0813A578 @ =0x0000fffc\n\ + bl sub_813AD58\n\ +_0813A542:\n\ + movs r0, 0x1\n\ + strh r0, [r4, 0x6]\n\ + movs r0, 0x6\n\ + movs r1, 0x8\n\ + movs r2, 0xD\n\ + movs r3, 0xB\n\ + bl MenuDrawTextWindow\n\ + ldrh r0, [r4, 0x6]\n\ + movs r1, 0x3\n\ + str r1, [sp]\n\ + movs r1, 0x1\n\ + movs r2, 0x8\n\ + movs r3, 0x9\n\ + bl sub_80A418C\n\ + ldr r1, _0813A57C @ =gTasks\n\ + lsls r0, r6, 2\n\ + adds r0, r6\n\ + lsls r0, 3\n\ + adds r0, r1\n\ + ldr r1, _0813A580 @ =sub_813A584\n\ + str r1, [r0]\n\ +_0813A570:\n\ + add sp, 0x4\n\ + pop {r4-r6}\n\ + pop {r0}\n\ + bx r0\n\ + .align 2, 0\n\ +_0813A578: .4byte 0x0000fffc\n\ +_0813A57C: .4byte gTasks\n\ +_0813A580: .4byte sub_813A584\n\ + .syntax divided"); +} +#endif diff --git a/src/pokedex.c b/src/pokedex.c index 8dfc4212c..48e3a57aa 100644 --- a/src/pokedex.c +++ b/src/pokedex.c @@ -1,65 +1,18 @@ #include "global.h" +#include "pokedex.h" +#include "asm.h" +#include "gba/m4a_internal.h" +#include "string_util.h" +#include "m4a.h" +#include "decompress.h" #include "main.h" #include "menu.h" #include "palette.h" #include "rng.h" #include "songs.h" #include "sound.h" -#include "sprite.h" #include "task.h" -#include "text.h" - -struct PokedexListItem -{ - u16 dexNum; - u16 seen:1; - u16 owned:1; -}; - -struct PokedexView -{ - struct PokedexListItem unk0[386]; - u16 unk608; - u8 unk60A_1:1; - u8 unk60A_2:1; - u8 unk60B; - u16 unk60C; - u16 selectedPokemon; - u16 unk610; - u16 dexMode; //National or Hoenn - u16 unk614; - u16 dexOrder; - u16 unk618; - u16 unk61A; - u16 unk61C; - u16 unk61E[4]; - u16 unk626; //sprite id of selected Pokemon - u16 unk628; - u16 unk62A; - u8 unk62C; - u8 unk62D; - u8 unk62E; - u8 unk62F; - s16 unk630; - s16 unk632; - u16 unk634; - u16 unk636; - u16 unk638; - u16 unk63A[4]; - u8 filler642[8]; - u8 unk64A; - u8 unk64B; - u8 unk64C_1:1; - u8 selectedScreen; - u8 unk64E; - u8 unk64F; - u8 menuIsOpen; //menuIsOpen - u8 unk651; - u16 menuCursorPos; //Menu cursor position - s16 menuY; //Menu Y position (inverted because we use REG_BG0VOFS for this) - u8 unk656[8]; - u8 unk65E[8]; -}; +#include "event_data.h" // I'm #define-ing these just for now so I can keep using the old unkXXX member names #define unk60E selectedPokemon @@ -118,7 +71,7 @@ extern u8 gUnknown_08E96738[]; extern u8 gUnknown_08E9C6DC[]; extern u8 gUnknown_08E96888[]; extern u8 gUnknown_08E96994[]; -extern u8 gUnknown_083A05CC[]; +extern struct SpriteSheet gUnknown_083A05CC; extern struct SpritePalette gUnknown_083A05DC[]; extern u8 gUnknown_0839FA7C[]; extern u8 gUnknown_0839F67C[]; @@ -156,12 +109,9 @@ extern u8 gDexText_RegisterComplete[]; extern void m4aMPlayVolumeControl(struct MusicPlayerInfo *mplayInfo, u16 trackBits, u16 volume); extern bool8 BeginNormalPaletteFade(u32, s8, u8, u8, u16); extern void remove_some_task(void); -extern bool32 IsNationalPokedex(void); -extern u16 GetNationalPokedexCount(u8); extern u8 sub_8091E3C(void); -extern void sub_80690C8(void); +extern void DisableNationalPokedex(void); extern void sub_805469C(void); -extern void LoadCompressedObjectPic(void *); extern u16 HoennToNationalOrder(u16); extern u16 NationalToHoennOrder(u16); extern u16 gPokedexOrder_Alphabetical[]; @@ -169,73 +119,17 @@ extern u16 gPokedexOrder_Weight[]; extern u16 gPokedexOrder_Height[]; extern u8 gSpeciesNames[][11]; -void ClearPokedexView(struct PokedexView *); -void Task_PokedexShowMainScreen(u8 taskId); -void sub_808C0B8(void); -void MainCB(void); -bool8 sub_808D344(u8); -void Task_PokedexMainScreen(u8 taskId); -void sub_808E6BC(void); -void sub_808EDB8(struct Sprite *); -void sub_808CA64(u8 taskId); -void Task_PokedexMainScreenMenu(u8 taskId); -void sub_808CB8C(u8 taskId); -u16 sub_808E48C(u16, u16); -void sub_808C898(u8 taskId); -void Task_ClosePokedex(u8 taskId); -void sub_8091060(u16); -void sub_808CAE4(u8 taskId); -void sub_808D198(u8 taskId); -bool8 sub_808E208(u8, u8, u8); -u8 sub_808E82C(void); -void sub_808E0CC(u16, u16); -u8 sub_808F210(struct PokedexListItem *, u8); -u8 sub_808F284(struct PokedexListItem *, u8); -bool8 sub_808F250(u8); -bool8 sub_808E71C(void); -void sub_808CCC4(u8 taskId); -u16 GetHoennPokedexCount(u8); -void SortPokedex(u8, u8); -void Task_PokedexResultsScreen(u8 taskId); -void sub_808D118(u8 taskId); -void Task_PokedexResultsScreenMenu(u8 taskId); -void Task_PokedexResultsScreenReturnToMainScreen(u8 taskId); -void sub_808CEF8(u8 taskId); -void Task_PokedexResultsScreenExitPokedex(u8 taskId); -void sub_808D640(void); -void sub_808E978(u8); -bool8 sub_8090D90(u16, u8); -void sub_808E090(u8, u8, u16); -void sub_808DEB0(u16, u8, u8, u16); -void sub_808DF88(u16, u8, u8, u16); -u8 sub_808DFE4(u16, u8, u8); -u16 sub_808E888(u16); -u32 sub_808E8C8(u16, u16, u16); -void sub_808EE28(struct Sprite *sprite); -u16 sub_8091818(u8, u16, u16, u16); -u16 sub_80918EC(u16 a, s16 b, s16 c, u16 d); //Not sure of return type -void Task_InitPageScreenMultistep(u8 taskId); -void Task_PageScreenProcessInput(u8 taskId); -void Task_InitCryScreenMultistep(u8 taskId); -void Task_InitAreaScreenMultistep(u8 taskId); -void Task_ClosePageScreen(u8 taskId); -void sub_808F888(u8 taskId); -void Task_InitSizeScreenMultistep(u8 taskId); -void Task_AreaScreenProcessInput(u8 taskId); -void sub_808FA00(u8 taskId); -void Task_CryScreenProcessInput(u8 taskId); -void sub_808FFBC(u8 taskId); -void Task_SizeScreenProcessInput(u8 taskId); -void sub_8090040(u8); -void sub_8090498(u8 taskId); -void sub_80904FC(u16); -void sub_8090540(u16); -void sub_8090750(u8); -void sub_8090A3C(u8); -void sub_8091738(u16, u16, u16); u16 NationalPokedexNumToSpecies(u16); + +// asm/pokedex_area_screen +void ShowPokedexAreaScreen(u16 species, u8 *string); + +// asm/pokedex_cry_screen u8 sub_8119E3C(struct CryRelatedStruct *, u8); +void sub_8119F88(u8 a); +void sub_811A050(u16 species); u8 ShowPokedexCryScreen(struct CryRelatedStruct *, u8); +void DestroyCryMeterNeedleSprite(); void sub_808C02C(void) { @@ -251,7 +145,7 @@ void sub_808C02C(void) gSaveBlock2.pokedex.unownPersonality = 0; gSaveBlock2.pokedex.spindaPersonality = 0; gSaveBlock2.pokedex.unknown3 = 0; - sub_80690C8(); + DisableNationalPokedex(); for(i = 0; i <= 51; i++) { gSaveBlock2.pokedex.owned[i] = 0; @@ -277,7 +171,6 @@ void sub_808C0B8(void) void ClearPokedexView(struct PokedexView *pokedexView) { u16 i; - struct UnknownStruct3 *p; for(i = 0; i <= 385; i++) { @@ -387,14 +280,14 @@ void CB2_InitPokedex(void) ClearPokedexView(gPokedexView); CreateTask(Task_PokedexShowMainScreen, 0); gPokedexView->dexMode = gSaveBlock2.pokedex.unknown1; - if(!IsNationalPokedex()) + if(!IsNationalPokedexEnabled()) gPokedexView->dexMode = DEX_MODE_HOENN; gPokedexView->dexOrder = gSaveBlock2.pokedex.order; gPokedexView->selectedPokemon = gUnknown_0202FFB8; gPokedexView->unk62C = gUnknown_0202FFBA; gPokedexView->selectedScreen = PAGE_SCREEN; gPokedexView->unk64E = 0; - if(!IsNationalPokedex()) + if(!IsNationalPokedexEnabled()) { gPokedexView->unk61A = GetHoennPokedexCount(0); gPokedexView->unk61C = GetHoennPokedexCount(1); @@ -639,7 +532,7 @@ void sub_808CB8C(u8 taskId) gPokedexView->unk62C = gPokedexView->unk62A; gPokedexView->selectedPokemon = gPokedexView->unk610; gPokedexView->dexMode = gPokedexView->unk614; - if(!IsNationalPokedex()) + if(!IsNationalPokedexEnabled()) gPokedexView->dexMode = DEX_MODE_HOENN; gPokedexView->dexOrder = gPokedexView->unk618; gTasks[taskId].func = Task_PokedexShowMainScreen; @@ -652,7 +545,7 @@ void Task_ClosePokedex(u8 taskId) if(!gPaletteFade.active) { gSaveBlock2.pokedex.unknown1 = gPokedexView->dexMode; - if(!IsNationalPokedex()) + if(!IsNationalPokedexEnabled()) gSaveBlock2.pokedex.unknown1 = 0; gSaveBlock2.pokedex.order = gPokedexView->dexOrder; DestroyTask(taskId); @@ -823,7 +716,7 @@ void Task_PokedexResultsScreenReturnToMainScreen(u8 taskId) gPokedexView->unk62C = gPokedexView->unk62A; gPokedexView->selectedPokemon = gPokedexView->unk610; gPokedexView->dexMode = gPokedexView->unk614; - if(!IsNationalPokedex()) + if(!IsNationalPokedexEnabled()) gPokedexView->dexMode = DEX_MODE_HOENN; gPokedexView->dexOrder = gPokedexView->unk618; gTasks[taskId].func = Task_PokedexShowMainScreen; @@ -837,7 +730,7 @@ void Task_PokedexResultsScreenExitPokedex(u8 taskId) gPokedexView->unk62C = gPokedexView->unk62A; gPokedexView->selectedPokemon = gPokedexView->unk610; gPokedexView->dexMode = gPokedexView->unk614; - if(!IsNationalPokedex()) + if(!IsNationalPokedexEnabled()) gPokedexView->dexMode = DEX_MODE_HOENN; gPokedexView->dexOrder = gPokedexView->unk618; gTasks[taskId].func = Task_ClosePokedex; @@ -878,7 +771,7 @@ bool8 sub_808D344(u8 a) ResetSpriteData(); FreeAllSpritePalettes(); gReservedSpritePaletteCount = 8; - LoadCompressedObjectPic(gUnknown_083A05CC); + LoadCompressedObjectPic(&gUnknown_083A05CC); LoadSpritePalettes(gUnknown_083A05DC); sub_808E978(a); gMain.state++; @@ -934,7 +827,7 @@ void sub_808D640(void) { if(gPokedexView->unk64C_1) LoadPalette(gUnknown_0839F67C + 0x2, 1, 0xBE); - else if(!IsNationalPokedex()) + else if(!IsNationalPokedexEnabled()) LoadPalette(gPokedexMenu_Pal + 0x2, 1, 0xBE); else LoadPalette(gUnknown_0839F73C + 0x2, 1, 0xBE); @@ -955,7 +848,7 @@ void SortPokedex(u8 dexMode, u8 sortMode) vars[1] = 1; break; case DEX_MODE_NATIONAL: - if(IsNationalPokedex()) + if(IsNationalPokedexEnabled()) { vars[0] = 386; vars[1] = 0; @@ -1839,7 +1732,6 @@ void sub_808E6BC(void) u8 sub_808E71C(void) { u16 r2; - u16 r3; u16 r4 = gPokedexView->selectedPokemon; if((gMain.newKeys & DPAD_UP) && r4) @@ -2284,8 +2176,6 @@ void sub_808F168(struct Sprite *sprite) if(gPokedexView->menuIsOpen != 0 && gPokedexView->menuY == r1) { - u8 data2; - sprite->invisible = 0; sprite->pos2.y = gPokedexView->menuCursorPos * 16; sprite->pos2.x = gSineTable[(u8)sprite->data2] / 64; @@ -3252,7 +3142,7 @@ void sub_8090750(u8 taskId) break; case 3: sub_8072BD8(gDexText_RegisterComplete, 2, 0, 0xD0); - if(!IsNationalPokedex()) + if(!IsNationalPokedexEnabled()) sub_8091154(NationalToHoennOrder(dexNum), 13, 3); else sub_8091154(dexNum, 13, 3); @@ -3297,4 +3187,4 @@ void sub_8090750(u8 taskId) break; } } -*/
\ No newline at end of file +*/ diff --git a/src/pokemon_1.c b/src/pokemon_1.c index 0c34279f7..b8735fbc4 100644 --- a/src/pokemon_1.c +++ b/src/pokemon_1.c @@ -1,11 +1,14 @@ #include "global.h" +#include "asm.h" #include "text.h" #include "string_util.h" #include "pokemon.h" +#include "rom4.h" #include "species.h" #include "main.h" #include "rng.h" #include "sprite.h" +#include "items.h" //Extracts the upper 16 bits of a 32-bit number #define HIHALF(n) (((n) & 0xFFFF0000) >> 16) @@ -13,8 +16,6 @@ //Extracts the lower 16 bits of a 32-bit number #define LOHALF(n) ((n) & 0xFFFF) -extern u8 sav1_map_get_name(); - extern struct Pokemon gPlayerParty[6]; // 0x3004360 extern struct Pokemon gEnemyParty[6]; // 0x30045C0 @@ -200,7 +201,7 @@ void CreateMonWithGenderNatureLetter(struct Pokemon *mon, u16 species, u8 level, do { personality = Random32(); - actualLetter = ((((personality & 0x3000000) >> 18) | ((personality & 0x30000) >> 12) | ((personality & 0x300) >> 6) | personality & 0x3) % 28); + actualLetter = ((((personality & 0x3000000) >> 18) | ((personality & 0x30000) >> 12) | ((personality & 0x300) >> 6) | (personality & 0x3)) % 28); } while (nature != GetNatureFromPersonality(personality) || gender != GetGenderFromSpeciesAndPersonality(species, personality) @@ -302,9 +303,9 @@ void sub_803ADE8(struct Pokemon *mon, struct UnknownPokemonStruct *src) StringCopy(nickname, src->nickname); if (nickname[0] == 0xFC && nickname[1] == 0x15) - language = 1; + language = LANGUAGE_JAPANESE; else - language = 2; + language = GAME_LANGUAGE; SetMonData(mon, MON_DATA_LANGUAGE, &language); StripExtCtrlCodes(nickname); @@ -341,7 +342,7 @@ void sub_803AF78(struct Pokemon *mon, struct UnknownPokemonStruct *dest) dest->species = GetMonData(mon, MON_DATA_SPECIES, NULL); heldItem = GetMonData(mon, MON_DATA_HELD_ITEM, NULL); - if (heldItem == 175) + if (heldItem == ITEM_ENIGMA_BERRY) heldItem = 0; dest->heldItem = heldItem; @@ -422,7 +423,6 @@ void CalculateMonStats(struct Pokemon *mon) u16 species = GetMonData(mon, MON_DATA_SPECIES, NULL); s32 level = GetLevelFromMonExp(mon); s32 newMaxHP; - u8 nature; SetMonData(mon, MON_DATA_LEVEL, (u8 *)&level); diff --git a/src/pokemon_2.c b/src/pokemon_2.c index c8d07f88d..8b55baaba 100644 --- a/src/pokemon_2.c +++ b/src/pokemon_2.c @@ -1,12 +1,13 @@ #include "global.h" +#include "asm.h" #include "text.h" #include "string_util.h" #include "pokemon.h" +#include "rng.h" #include "species.h" #include "main.h" #include "sprite.h" -#include "berry.h" -#include "flag.h" +#include "event_data.h" extern u8 gPlayerPartyCount; extern struct Pokemon gPlayerParty[6]; @@ -16,7 +17,7 @@ extern struct Pokemon gEnemyParty[6]; extern u16 unk_20160BC[]; extern struct SecretBaseRecord gSecretBaseRecord; extern u32 dword_2017100[]; -extern u16 gUnknown_020239F8; +extern u16 gBattleTypeFlags; extern u8 gUnknown_02024A60; extern struct BattlePokemon gBattleMons[4]; extern u16 gUnknown_02024BE6; @@ -25,7 +26,7 @@ extern u8 gUnknown_02024C07; extern u8 gUnknown_02024C08; extern u8 gUnknown_02024C0C; extern u8 gXXX_CritRelated; -extern u16 word_2024DB8; +extern u16 gBattleWeather; extern struct BattleEnigmaBerry gEnigmaBerries[]; extern u16 gBattleMovePower; extern struct SpriteTemplate gUnknown_02024E8C; @@ -50,12 +51,6 @@ extern u8 gUnknown_0820823C[]; extern u8 gStatStageRatios[][2]; extern u8 gHoldEffectToType[][2]; -extern u8 battle_side_get_owner(u8); -extern u8 battle_get_side_with_given_state(u8); -extern u32 battle_get_per_side_status(u8); -extern u8 sub_8018324(u8, u8, u8, u8, u16); -extern u8 sub_803C348(u8); - u8 sub_803C348(u8 a1) { s32 i; @@ -89,6 +84,7 @@ u8 sub_803C348(u8 a1) return retVal; } +#ifdef NONMATCHING u8 sub_803C434(u8 a1) { u32 status0 = battle_get_per_side_status(a1); @@ -102,7 +98,7 @@ u8 sub_803C434(u8 a1) status = status_ ^ mask1; { - register u16 val_ asm("r1") = gUnknown_020239F8; + register u16 val_ asm("r1") = gBattleTypeFlags; u32 val = mask2; val &= val_; if (!val) @@ -113,7 +109,7 @@ u8 sub_803C434(u8 a1) if (sub_803C348(0) > 1) { - u32 r = Random(); + u16 r = Random(); register u32 val asm("r1") = mask2; val &= r; if (!val) @@ -135,6 +131,77 @@ u8 sub_803C434(u8 a1) return battle_get_side_with_given_state(status); } } +#else +__attribute__((naked)) +u8 sub_803C434(u8 a1) { + asm(".syntax unified\n\ + push {r4-r6,lr}\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + bl battle_get_per_side_status\n\ + movs r1, 0x1\n\ + movs r6, 0x1\n\ + adds r4, r6, 0\n\ + ands r4, r0\n\ + eors r4, r1\n\ + adds r5, r4, 0\n\ + ldr r0, _0803C45C\n\ + ldrh r1, [r0]\n\ + adds r0, r6, 0\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + bne _0803C460\n\ + adds r0, r4, 0\n\ + b _0803C4AA\n\ + .align 2, 0\n\ +_0803C45C: .4byte gBattleTypeFlags\n\ +_0803C460:\n\ + movs r0, 0\n\ + bl sub_803C348\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + cmp r0, 0x1\n\ + bls _0803C484\n\ + bl Random\n\ + adds r1, r6, 0\n\ + ands r1, r0\n\ + cmp r1, 0\n\ + bne _0803C480\n\ + movs r0, 0x2\n\ + eors r0, r4\n\ + b _0803C4AA\n\ +_0803C480:\n\ + adds r0, r4, 0\n\ + b _0803C4AA\n\ +_0803C484:\n\ + ldr r0, _0803C49C\n\ + ldrb r1, [r0]\n\ + ldr r2, _0803C4A0\n\ + lsls r0, r4, 2\n\ + adds r0, r2\n\ + ldr r0, [r0]\n\ + ands r1, r0\n\ + cmp r1, 0\n\ + bne _0803C4A4\n\ + adds r0, r4, 0\n\ + b _0803C4AA\n\ + .align 2, 0\n\ +_0803C49C: .4byte gUnknown_02024C0C\n\ +_0803C4A0: .4byte gBitTable\n\ +_0803C4A4:\n\ + movs r0, 0x2\n\ + eors r5, r0\n\ + adds r0, r5, 0\n\ +_0803C4AA:\n\ + bl battle_get_side_with_given_state\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + pop {r4-r6}\n\ + pop {r1}\n\ + bx r1\n\ + .syntax divided\n"); +} +#endif u8 GetMonGender(struct Pokemon *mon) { @@ -949,7 +1016,11 @@ void SetBoxMonData(struct BoxPokemon *boxMon, s32 field, const u8 *data) break; case MON_DATA_IVS: { +#ifdef BUGFIX_SETMONIVS + u32 ivs = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24); +#else u32 ivs = *data; // Bug: Only the HP IV and the lower 3 bits of the Attack IV are read. The rest become 0. +#endif substruct3->hpIV = ivs & 0x1F; substruct3->attackIV = (ivs >> 5) & 0x1F; substruct3->defenseIV = (ivs >> 10) & 0x1F; @@ -1116,7 +1187,7 @@ void CreateSecretBaseEnemyParty(struct SecretBaseRecord *secretBaseRecord) } } - gUnknown_020239F8 = 8; + gBattleTypeFlags = 8; gTrainerBattleOpponent = 1024; } diff --git a/src/pokemon_3.c b/src/pokemon_3.c new file mode 100644 index 000000000..cf172b122 --- /dev/null +++ b/src/pokemon_3.c @@ -0,0 +1,478 @@ +#include "global.h" +#include "asm.h" +#include "text.h" +#include "string_util.h" +#include "pokemon.h" +#include "rng.h" +#include "species.h" +#include "main.h" +#include "sprite.h" +#include "event_data.h" +#include "rtc.h" +#include "item.h" +#include "items.h" + +#define EVO_FRIENDSHIP 0x0001 // Pokémon levels up with friendship ≥ 220 +#define EVO_FRIENDSHIP_DAY 0x0002 // Pokémon levels up during the day with friendship ≥ 220 +#define EVO_FRIENDSHIP_NIGHT 0x0003 // Pokémon levels up at night with friendship ≥ 220 +#define EVO_LEVEL 0x0004 // Pokémon reaches the specified level +#define EVO_TRADE 0x0005 // Pokémon is traded +#define EVO_TRADE_ITEM 0x0006 // Pokémon is traded while it's holding the specified item +#define EVO_ITEM 0x0007 // specified item is used on Pokémon +#define EVO_LEVEL_ATK_GT_DEF 0x0008 // Pokémon reaches the specified level with attack > defense +#define EVO_LEVEL_ATK_EQ_DEF 0x0009 // Pokémon reaches the specified level with attack = defense +#define EVO_LEVEL_ATK_LT_DEF 0x000a // Pokémon reaches the specified level with attack < defense +#define EVO_LEVEL_SILCOON 0x000b // Pokémon reaches the specified level with a Silcoon personality value +#define EVO_LEVEL_CASCOON 0x000c // Pokémon reaches the specified level with a Cascoon personality value +#define EVO_LEVEL_NINJASK 0x000d // Pokémon reaches the specified level (special value for Ninjask) +#define EVO_LEVEL_SHEDINJA 0x000e // Pokémon reaches the specified level (special value for Shedinja) +#define EVO_BEAUTY 0x000f // Pokémon levels up with beauty ≥ specified value + +struct Evolution +{ + u16 method; + u16 param; + u16 targetSpecies; +}; + +struct EvolutionData +{ + struct Evolution evolutions[5]; +}; + +extern void get_battle_strings_(u8 *); + +extern u8 gPlayerPartyCount; +extern struct Pokemon gPlayerParty[6]; +extern u8 gEnemyPartyCount; +extern struct Pokemon gEnemyParty[6]; +extern struct BattlePokemon gBattleMons[4]; +extern u8 * const gItemEffectTable[]; +extern u8 gUnknown_02024A60; +extern struct BattleEnigmaBerry gEnigmaBerries[]; +extern struct EvolutionData gEvolutionTable[]; +extern u16 gSpeciesToHoennPokedexNum[]; +extern u16 gSpeciesToNationalPokedexNum[]; +extern u16 gHoennToNationalOrder[]; +extern u16 gSpeciesIdToCryId[]; +extern u8 gUnknown_030041C0[]; +extern u8 gUnknown_03004290[]; +extern u8 gUnknown_020238CC[]; +extern u8 gUnknown_02024C07; +extern u8 gUnknown_02024C08; +extern u8 gUnknown_02024C0B; +extern u8 gUnknown_02024E6C; + +extern u8 gUnknown_082082F8[]; +extern u8 gUnknown_083FFDB3[]; +extern u8 gUnknown_083FFDD3[]; +extern u8 gUnknown_083FEE5D[]; +extern u8 gUnknown_083FEE92[]; +extern u8 *gUnknown_08400F58[]; + +bool8 HealStatusConditions(struct Pokemon *mon, u32 unused, u32 healMask, u8 battleId) +{ + u32 status = GetMonData(mon, MON_DATA_STATUS, 0); + + if (status & healMask) + { + status &= ~healMask; + SetMonData(mon, MON_DATA_STATUS, (u8 *)&status); + if (gMain.inBattle && battleId != 4) + gBattleMons[battleId].status1 &= ~healMask; + return FALSE; + } + else + { + return TRUE; + } +} + +u8 GetItemEffectParamOffset(u16 itemId, u8 effectByte, u8 effectBit) +{ + u8 *temp; + u8 *itemEffect; + u8 offset; + int i; + u8 j; + u8 val; + + offset = 6; + + temp = gItemEffectTable[itemId - 13]; + + if (!temp && itemId != ITEM_ENIGMA_BERRY) + return 0; + + if (itemId == ITEM_ENIGMA_BERRY) + { + temp = gEnigmaBerries[gUnknown_02024A60].itemEffect; + } + + itemEffect = temp; + + for (i = 0; i < 6; i++) + { + switch (i) + { + case 0: + case 1: + case 2: + case 3: + if (i == effectByte) + return 0; + break; + case 4: + val = itemEffect[4]; + if (val & 0x20) + val &= 0xDF; + j = 0; + while (val) + { + if (val & 1) + { + switch (j) + { + case 2: + if (val & 0x10) + val &= 0xEF; + case 0: + if (i == effectByte && (val & effectBit)) + return offset; + offset++; + break; + case 1: + if (i == effectByte && (val & effectBit)) + return offset; + offset++; + break; + case 3: + if (i == effectByte && (val & effectBit)) + return offset; + offset++; + break; + case 7: + if (i == effectByte) + return 0; + break; + } + } + j++; + val >>= 1; + if (i == effectByte) + effectBit >>= 1; + } + break; + case 5: + val = itemEffect[5]; + j = 0; + while (val) + { + if (val & 1) + { + switch (j) + { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + if (i == effectByte && (val & effectBit)) + return offset; + offset++; + break; + case 7: + if (i == effectByte) + return 0; + break; + } + } + j++; + val >>= 1; + if (i == effectByte) + effectBit >>= 1; + } + break; + } + } + + return offset; +} + +void sub_803F324(int stat) +{ + gUnknown_02024C08 = gUnknown_02024E6C; + StringCopy(gUnknown_030041C0, gUnknown_08400F58[gUnknown_082082F8[stat]]); + StringCopy(gUnknown_03004290, gUnknown_083FFDB3); + get_battle_strings_(gUnknown_083FFDD3); +} + +u8 *sub_803F378(u16 itemId) +{ + int i; + u8 *itemEffect; + + if (itemId == ITEM_ENIGMA_BERRY) + { + if (gMain.inBattle) + { + itemEffect = gEnigmaBerries[gUnknown_02024E6C].itemEffect; + } + else + { + itemEffect = gSaveBlock1.enigmaBerry.itemEffect; + } + } + else + { + itemEffect = gItemEffectTable[itemId - 13]; + } + + gUnknown_02024C0B = gUnknown_02024E6C; + + for (i = 0; i < 3; i++) + { + if (itemEffect[i] & 0xF) + sub_803F324(i * 2); + if (itemEffect[i] & 0xF0) + { + if (i) + { + sub_803F324(i * 2 + 1); + } + else + { + gUnknown_02024C07 = gUnknown_02024E6C; + get_battle_strings_(gUnknown_083FEE92); + } + } + } + + if (itemEffect[3] & 0x80) + { + gUnknown_02024C07 = gUnknown_02024E6C; + get_battle_strings_(gUnknown_083FEE5D); + } + + return gUnknown_020238CC; +} + +u8 GetNature(struct Pokemon *mon) +{ + return GetMonData(mon, MON_DATA_PERSONALITY, 0) % 25; +} + +u8 GetNatureFromPersonality(u32 personality) +{ + return personality % 25; +} + +u16 GetEvolutionTargetSpecies(struct Pokemon *mon, u8 type, u16 evolutionItem) +{ + int i; + u16 targetSpecies = 0; + u16 species = GetMonData(mon, MON_DATA_SPECIES, 0); + u16 heldItem = GetMonData(mon, MON_DATA_HELD_ITEM, 0); + u32 personality = GetMonData(mon, MON_DATA_PERSONALITY, 0); + u8 level; + u16 friendship; + u8 beauty = GetMonData(mon, MON_DATA_BEAUTY, 0); + u16 upperPersonality = personality >> 16; + u8 holdEffect; + + if (heldItem == ITEM_ENIGMA_BERRY) + holdEffect = gSaveBlock1.enigmaBerry.holdEffect; + else + holdEffect = ItemId_GetHoldEffect(heldItem); + + if (holdEffect == 38 && type != 3) + return 0; + + switch (type) + { + case 0: + level = GetMonData(mon, MON_DATA_LEVEL, 0); + friendship = GetMonData(mon, MON_DATA_FRIENDSHIP, 0); + + for (i = 0; i < 5; i++) + { + switch (gEvolutionTable[species].evolutions[i].method) + { + case EVO_FRIENDSHIP: + if (friendship >= 220) + targetSpecies = gEvolutionTable[species].evolutions[i].targetSpecies; + break; + case EVO_FRIENDSHIP_DAY: + RtcCalcLocalTime(); + if (gLocalTime.hours >= 12 && gLocalTime.hours < 24 && friendship >= 220) + targetSpecies = gEvolutionTable[species].evolutions[i].targetSpecies; + break; + case EVO_FRIENDSHIP_NIGHT: + RtcCalcLocalTime(); + if (gLocalTime.hours >= 0 && gLocalTime.hours < 12 && friendship >= 220) + targetSpecies = gEvolutionTable[species].evolutions[i].targetSpecies; + break; + case EVO_LEVEL: + if (gEvolutionTable[species].evolutions[i].param <= level) + targetSpecies = gEvolutionTable[species].evolutions[i].targetSpecies; + break; + case EVO_LEVEL_ATK_GT_DEF: + if (gEvolutionTable[species].evolutions[i].param <= level) + if (GetMonData(mon, MON_DATA_ATK, 0) > GetMonData(mon, MON_DATA_DEF, 0)) + targetSpecies = gEvolutionTable[species].evolutions[i].targetSpecies; + break; + case EVO_LEVEL_ATK_EQ_DEF: + if (gEvolutionTable[species].evolutions[i].param <= level) + if (GetMonData(mon, MON_DATA_ATK, 0) == GetMonData(mon, MON_DATA_DEF, 0)) + targetSpecies = gEvolutionTable[species].evolutions[i].targetSpecies; + break; + case EVO_LEVEL_ATK_LT_DEF: + if (gEvolutionTable[species].evolutions[i].param <= level) + if (GetMonData(mon, MON_DATA_ATK, 0) < GetMonData(mon, MON_DATA_DEF, 0)) + targetSpecies = gEvolutionTable[species].evolutions[i].targetSpecies; + break; + case EVO_LEVEL_SILCOON: + if (gEvolutionTable[species].evolutions[i].param <= level && (upperPersonality % 10) <= 4) + targetSpecies = gEvolutionTable[species].evolutions[i].targetSpecies; + break; + case EVO_LEVEL_CASCOON: + if (gEvolutionTable[species].evolutions[i].param <= level && (upperPersonality % 10) > 4) + targetSpecies = gEvolutionTable[species].evolutions[i].targetSpecies; + break; + case EVO_LEVEL_NINJASK: + if (gEvolutionTable[species].evolutions[i].param <= level) + targetSpecies = gEvolutionTable[species].evolutions[i].targetSpecies; + break; + case EVO_BEAUTY: + if (gEvolutionTable[species].evolutions[i].param <= beauty) + targetSpecies = gEvolutionTable[species].evolutions[i].targetSpecies; + break; + } + } + break; + case 1: + for (i = 0; i < 5; i++) + { + switch (gEvolutionTable[species].evolutions[i].method) + { + case EVO_TRADE: + targetSpecies = gEvolutionTable[species].evolutions[i].targetSpecies; + break; + case EVO_TRADE_ITEM: + if (gEvolutionTable[species].evolutions[i].param == heldItem) + { + heldItem = 0; + SetMonData(mon, MON_DATA_HELD_ITEM, (u8 *)&heldItem); + targetSpecies = gEvolutionTable[species].evolutions[i].targetSpecies; + } + break; + } + } + break; + case 2: + case 3: + for (i = 0; i < 5; i++) + { + if (gEvolutionTable[species].evolutions[i].method == EVO_ITEM + && gEvolutionTable[species].evolutions[i].param == evolutionItem) + { + targetSpecies = gEvolutionTable[species].evolutions[i].targetSpecies; + break; + } + } + break; + } + + return targetSpecies; +} + +u16 HoennPokedexNumToSpecies(u16 hoennNum) +{ + u16 species; + + if (!hoennNum) + return 0; + + species = 0; + + while (species < 411 && gSpeciesToHoennPokedexNum[species] != hoennNum) + species++; + + if (species == 411) + return 0; + + return species + 1; +} + +u16 NationalPokedexNumToSpecies(u16 nationalNum) +{ + u16 species; + + if (!nationalNum) + return 0; + + species = 0; + + while (species < 411 && gSpeciesToNationalPokedexNum[species] != nationalNum) + species++; + + if (species == 411) + return 0; + + return species + 1; +} + +u16 NationalToHoennOrder(u16 nationalNum) +{ + u16 hoennNum; + + if (!nationalNum) + return 0; + + hoennNum = 0; + + while (hoennNum < 411 && gHoennToNationalOrder[hoennNum] != nationalNum) + hoennNum++; + + if (hoennNum == 411) + return 0; + + return hoennNum + 1; +} + +u16 SpeciesToNationalPokedexNum(u16 species) +{ + if (!species) + return 0; + + return gSpeciesToNationalPokedexNum[species - 1]; +} + +u16 SpeciesToHoennPokedexNum(u16 species) +{ + if (!species) + return 0; + + return gSpeciesToHoennPokedexNum[species - 1]; +} + +u16 HoennToNationalOrder(u16 hoennNum) +{ + if (!hoennNum) + return 0; + + return gHoennToNationalOrder[hoennNum - 1]; +} + +u32 SpeciesToCryId(u16 species) +{ + if (species <= 250) + return species; + + if (species < 276) + return 200; + + return gSpeciesIdToCryId[species - 276]; +} diff --git a/src/pokemon_size_record.c b/src/pokemon_size_record.c index 6381881b7..6cf3411a9 100644 --- a/src/pokemon_size_record.c +++ b/src/pokemon_size_record.c @@ -1,12 +1,11 @@ -#include "gba/gba.h" #include "global.h" -#include "pokemon.h" +#include "pokemon_size_record.h" +#include "string_util.h" #include "species.h" -#include "flag.h" -#include "var.h" +#include "event_data.h" extern u16 SpeciesToNationalPokedexNum(u16); -extern u16 sub_8090D54(u16, u8); +extern u16 GetPokedexHeightWeight(u16, u8); struct UnknownStruct { @@ -15,15 +14,30 @@ struct UnknownStruct u16 unk4; }; -extern struct UnknownStruct gUnknown_083D180C[]; -extern u8 gOtherText_DecimalPoint[]; extern u8 gOtherText_Marco[]; extern u16 gScriptResult; extern u8 gSpeciesNames[][11]; -extern u8 gUnknown_083D188E[]; -#define VAR_SHROOMISH_SIZE_RECORD 0x4047 -#define VAR_BARBOACH_SIZE_RECORD 0x404F +static const struct UnknownStruct sBigMonSizeTable[] = +{ + { 290, 1, 0 }, + { 300, 1, 10 }, + { 400, 2, 110 }, + { 500, 4, 310 }, + { 600, 20, 710 }, + { 700, 50, 2710 }, + { 800, 100, 7710 }, + { 900, 150, 17710 }, + { 1000, 150, 32710 }, + { 1100, 100, -17826 }, + { 1200, 50, -7826 }, + { 1300, 20, -2826 }, + { 1400, 5, -826 }, + { 1500, 2, -326 }, + { 1600, 1, -126 }, + { 1700, 1, -26 }, +}; + #define CM_PER_INCH 2.54 static u32 GetMonSizeHash(struct Pokemon *pkmn) @@ -38,17 +52,17 @@ static u32 GetMonSizeHash(struct Pokemon *pkmn) u16 spDefIV = GetMonData(pkmn, MON_DATA_SPDEF_IV) & 0xF; u32 hibyte = ((attackIV ^ defenseIV) * hpIV) ^ (personality & 0xFF); u32 lobyte = ((spAtkIV ^ spDefIV) * speedIV) ^ (personality >> 8); - + return (hibyte << 8) + lobyte; } static u8 TranslateBigMonSizeTableIndex(u16 a) { u8 i; - + for(i = 1; i < 15; i++) { - if(a < gUnknown_083D180C[i].unk4) + if(a < sBigMonSizeTable[i].unk4) return i - 1; } return i; @@ -59,24 +73,22 @@ static u32 GetMonSize(u16 species, u16 b) u64 unk2; u64 unk4; u64 unk0; - u32 r7; + u32 height; u32 var; - struct UnknownStruct *s; - - r7 = sub_8090D54(SpeciesToNationalPokedexNum(species), 0); + + height = GetPokedexHeightWeight(SpeciesToNationalPokedexNum(species), 0); var = TranslateBigMonSizeTableIndex(b); - unk0 = gUnknown_083D180C[var].unk0; - unk2 = gUnknown_083D180C[var].unk2; - unk4 = gUnknown_083D180C[var].unk4; + unk0 = sBigMonSizeTable[var].unk0; + unk2 = sBigMonSizeTable[var].unk2; + unk4 = sBigMonSizeTable[var].unk4; unk0 += (b - unk4) / unk2; - return r7 * unk0 / 10; + return height * unk0 / 10; } static void FormatMonSizeRecord(u8 *string, u32 size) { - u8 decimalPoint[2]; - - memcpy(decimalPoint, gOtherText_DecimalPoint, 2); + u8 decimalPoint[] = _"."; + //Convert size from centimeters to inches size = (double)(size * 10) / (CM_PER_INCH * 10); string = ConvertIntToDecimalStringN(string, size / 10, 0, 8); @@ -85,29 +97,34 @@ static void FormatMonSizeRecord(u8 *string, u32 size) } static u8 CompareMonSize(u16 species, u16 *sizeRecord) -{ +{ if(gScriptResult == 0xFF) + { return 0; + } else { struct Pokemon *pkmn = &gPlayerParty[gScriptResult]; - + // UB: Too few arguments for function 'GetMonData' if(GetMonData(pkmn, MON_DATA_IS_EGG) == TRUE || GetMonData(pkmn, MON_DATA_SPECIES) != species) + { return 1; + } else { u32 oldSize; u32 newSize; u16 sizeParams; - u16 *ptr = &sizeParams; //Why the pointer? - - *ptr = GetMonSizeHash(pkmn); + + *(&sizeParams) = GetMonSizeHash(pkmn); newSize = GetMonSize(species, sizeParams); oldSize = GetMonSize(species, *sizeRecord); FormatMonSizeRecord(gStringVar2, newSize); if(newSize <= oldSize) + { return 2; + } else { *sizeRecord = sizeParams; @@ -121,7 +138,7 @@ static u8 CompareMonSize(u16 species, u16 *sizeRecord) static void GetMonSizeRecordInfo(u16 species, u16 *sizeRecord) { u32 size = GetMonSize(species, *sizeRecord); - + FormatMonSizeRecord(gStringVar3, size); StringCopy(gStringVar1, gSpeciesNames[species]); if(*sizeRecord == 0x8100) @@ -138,14 +155,14 @@ void InitShroomishSizeRecord(void) void GetShroomishSizeRecordInfo(void) { u16 *sizeRecord = GetVarPointer(VAR_SHROOMISH_SIZE_RECORD); - + GetMonSizeRecordInfo(SPECIES_SHROOMISH, sizeRecord); } void CompareShroomishSize(void) { u16 *sizeRecord = GetVarPointer(VAR_SHROOMISH_SIZE_RECORD); - + gScriptResult = CompareMonSize(SPECIES_SHROOMISH, sizeRecord); } @@ -157,32 +174,31 @@ void InitBarboachSizeRecord(void) void GetBarboachSizeRecordInfo(void) { u16 *sizeRecord = GetVarPointer(VAR_BARBOACH_SIZE_RECORD); - + GetMonSizeRecordInfo(SPECIES_BARBOACH, sizeRecord); } void CompareBarboachSize(void) { u16 *sizeRecord = GetVarPointer(VAR_BARBOACH_SIZE_RECORD); - + gScriptResult = CompareMonSize(SPECIES_BARBOACH, sizeRecord); } void GiveGiftRibbonToParty(u8 index, u8 ribbonId) { s32 i; - u8 arr[7]; bool32 gotRibbon = FALSE; u8 data = 1; - - memcpy(arr, gUnknown_083D188E, 7); + u8 arr[] = { 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E }; + if(index < 11 && ribbonId < 65) { gSaveBlock1.giftRibbons[index] = ribbonId; for(i = 0; i < 6; i++) { struct Pokemon *pkmn = &gPlayerParty[i]; - + if(GetMonData(pkmn, MON_DATA_SPECIES) != 0 && GetMonData(pkmn, MON_DATA_SANITY_BIT3) == 0) { SetMonData(pkmn, arr[index], &data); diff --git a/src/pokemon_summary_screen.c b/src/pokemon_summary_screen.c new file mode 100644 index 000000000..b6b24b9d7 --- /dev/null +++ b/src/pokemon_summary_screen.c @@ -0,0 +1,175 @@ +#include "global.h" +#include "asm.h" +#include "menu.h" +#include "pokemon.h" +#include "string_util.h" +#include "link.h" + +extern u8 gStringVar1[]; +extern u8 gStringVar4[]; + +extern struct Pokemon *unk_2018000; + +extern u8 *(gNatureNames[]); +extern const u8 gOtherText_Terminator4[]; +extern const u8 gOtherText_Nature[]; + +extern const u8 gOtherText_Met[]; +extern const u8 gOtherText_Egg2[]; +extern const u8 gOtherText_ObtainedInTrade[]; +extern const u8 gOtherText_FatefulEncounter[]; +extern const u8 gOtherText_Met2[]; +extern const u8 gOtherText_EggDayCare[]; +extern const u8 gOtherText_EggNicePlace[]; +extern const u8 gOtherText_EggObtainedInTrade[]; +extern const u8 gOtherText_EggHotSprings[]; + +u8 *sub_80A1E9C(u8 *dest, u8 *src, u8); +u8 PokemonSummaryScreen_CheckOT(struct Pokemon *pokemon); +u8 *PokemonSummaryScreen_CopyPokemonLevel(u8 *dest, u8 level); +u32 GetPlayerTrainerId(void); + +bool8 PokemonSummaryScreen_CheckOT(struct Pokemon *mon) +{ + u32 trainerId; + + if (unk_2018000 == gEnemyParty) + { + u8 enemyId = GetMultiplayerId() ^ 1; + trainerId = gLinkPlayers[enemyId].trainerId & 0xFFFF; + StringCopy(gStringVar1, gLinkPlayers[enemyId].name); + StripExtCtrlCodes(gStringVar1); + } + else + { + trainerId = GetPlayerTrainerId() & 0xFFFF; + StringCopy(gStringVar1, gSaveBlock2.playerName); + } + + if (trainerId != (GetMonData(mon, MON_DATA_OT_ID) & 0xFFFF)) + return FALSE; + + GetMonData(mon, MON_DATA_OT_NAME, gStringVar2); + + if (!StringCompareWithoutExtCtrlCodes(gStringVar1, gStringVar2)) + return TRUE; + + return FALSE; +} + +void PokemonSummaryScreen_PrintEggTrainerMemo(struct Pokemon *mon, u8 left, u8 top) +{ + u8 locationMet; + u8 gameMet = GetMonData(mon, MON_DATA_MET_GAME); + + if (!(gameMet == VERSION_RUBY || gameMet == VERSION_SAPPHIRE || gameMet == VERSION_EMERALD)) + { + MenuPrint(gOtherText_EggObtainedInTrade, left, top); + return; + } + + locationMet = GetMonData(mon, MON_DATA_MET_LOCATION); + + if (locationMet == 255) + { + MenuPrint(gOtherText_EggNicePlace, left, top); + return; + } + + if (!PokemonSummaryScreen_CheckOT(mon)) + { + MenuPrint(gOtherText_EggObtainedInTrade, left, top); + return; + } + + asm(""); // needed to match for some reason + + if (locationMet == 253) + { + MenuPrint(gOtherText_EggHotSprings, left, top); + return; + } + + MenuPrint(gOtherText_EggDayCare, left, top); +} + +void PokemonSummaryScreen_PrintTrainerMemo(struct Pokemon *pokemon, u8 left, u8 top) { + u8 locationMet; + u8 gameMet; + u8 *ptr = gStringVar4; + u8 nature = GetNature(pokemon); + + ptr = sub_80A1E9C(ptr, gNatureNames[nature], 14); + + if (nature != NATURE_BOLD && nature != NATURE_GENTLE) { + ptr = StringCopy(ptr, gOtherText_Terminator4); + } + + ptr = StringCopy(ptr, gOtherText_Nature); + + if (PokemonSummaryScreen_CheckOT(pokemon) == TRUE) { + locationMet = GetMonData(pokemon, MON_DATA_MET_LOCATION); + + if (GetMonData(pokemon, MON_DATA_MET_LEVEL) == 0) { + ptr = PokemonSummaryScreen_CopyPokemonLevel(ptr, 5); + *ptr = CHAR_NEWLINE; + ptr++; + + CopyLocationName(gStringVar1, locationMet); + ptr = sub_80A1E9C(ptr, gStringVar1, 14); + StringCopy(ptr, gOtherText_Egg2); + } else if (locationMet >= 88) { + *ptr = CHAR_NEWLINE; + ptr++; + + StringCopy(ptr, gOtherText_ObtainedInTrade); + } else { + u8 levelMet = GetMonData(pokemon, MON_DATA_MET_LEVEL); + + ptr = PokemonSummaryScreen_CopyPokemonLevel(ptr, levelMet); + *ptr = CHAR_NEWLINE; + ptr++; + + CopyLocationName(gStringVar1, locationMet); + ptr = sub_80A1E9C(ptr, gStringVar1, 14); + StringCopy(ptr, gOtherText_Met); + } + } else { + gameMet = GetMonData(pokemon, MON_DATA_MET_GAME); + + if (!(gameMet == VERSION_RUBY || gameMet == VERSION_SAPPHIRE || gameMet == VERSION_EMERALD)) { + *ptr = CHAR_NEWLINE; + ptr++; + + StringCopy(ptr, gOtherText_ObtainedInTrade); + } else { + locationMet = GetMonData(pokemon, MON_DATA_MET_LOCATION); + if (locationMet == 0xFF) { + u8 levelMet = GetMonData(pokemon, MON_DATA_MET_LEVEL); + + ptr = PokemonSummaryScreen_CopyPokemonLevel(ptr, levelMet); + *ptr = CHAR_NEWLINE; + ptr++; + + StringCopy(ptr, gOtherText_FatefulEncounter); + } else if (locationMet >= 88) { + *ptr = CHAR_NEWLINE; + ptr++; + + StringCopy(ptr, gOtherText_ObtainedInTrade); + } else { + u8 levelMet = GetMonData(pokemon, MON_DATA_MET_LEVEL); + + ptr = PokemonSummaryScreen_CopyPokemonLevel(ptr, levelMet); + *ptr = CHAR_NEWLINE; + ptr++; + + CopyLocationName(gStringVar1, locationMet); + ptr = sub_80A1E9C(ptr, gStringVar1, 14); + StringCopy(ptr, gOtherText_Met2); + } + } + } + + MenuPrint(gStringVar4, left++, top++); +} diff --git a/src/record_mixing.c b/src/record_mixing.c index 4996dc01f..12b87b2b1 100644 --- a/src/record_mixing.c +++ b/src/record_mixing.c @@ -1,15 +1,15 @@ #include "global.h" +#include "record_mixing.h" +#include "asm.h" #include "link.h" #include "menu.h" -#include "pokemon.h" -#include "rng.h" +#include "rom4.h" #include "script.h" #include "songs.h" #include "sound.h" #include "string_util.h" #include "task.h" -#include "flag.h" -#include "var.h" +#include "event_data.h" extern void *recordMixingSecretBases; extern void *recordMixingTvShows; @@ -33,38 +33,6 @@ extern bool8 gReceivedRemoteLinkPlayers; extern u8 gBlockSendBuffer[BLOCK_BUFFER_SIZE]; extern u16 gBlockRecvBuffer[MAX_LINK_PLAYERS][BLOCK_BUFFER_SIZE / 2]; -extern void sub_8083A84(TaskFunc); -extern void sub_8041324(struct BoxPokemon *, void *); -extern void sub_80BD674(void *, u32, u8); -extern void sub_80BFD44(void *, u32, u8); -extern void sub_80C0514(void *, u32, u8); -// UB: sub_80FA4E4 declared with 3 arguments instead of 2 -extern void sub_80FA4E4(void *, u32, u8); -extern void sub_80B9C6C(void *, u32, u8, void *); -extern void sub_80B9F3C(void *, u8); -extern u16 sub_8126338(void); -extern u8 sub_8083664(void); -extern void sub_80720B0(void); -extern void CreateRecordMixingSprite(void); -extern void DestroyRecordMixingSprite(void); -extern u16 sub_8055588(void); -extern void sub_80F7F30(void); -extern void sub_8134AC0(void *); - -void sub_80B9484(u8); -void sub_80B95F0(u8); -void sub_80BA00C(u8); -void sub_80B97DC(u8); -void Task_CopyRecvBuffer(u8); -void sub_80B9A1C(u8); -u8 GetMultiplayerId_(void); -void StorePtrInTaskData(void *, u16 *); -void *LoadPtrFromTaskData(u16 *); -void sub_80B9B1C(u8 *, size_t, u8); -void sub_80B9B70(u8 *, size_t, u8); -u16 *GetPlayerRecvBuffer(u8 player); -void sub_80B9A78(void); - #define BUFFER_CHUNK_SIZE 200 void sub_80B929C(void) diff --git a/src/rom4.c b/src/rom4.c index 15041cb39..4f3e35fea 100644 --- a/src/rom4.c +++ b/src/rom4.c @@ -1,16 +1,35 @@ #include "global.h" -#include "fieldmap.h" +#include "rom4.h" +#include "asm.h" +#include "asm_fieldmap.h" +#include "battle_setup.h" +#include "berry.h" +#include "field_camera.h" +#include "field_effect.h" +#include "field_map_obj.h" +#include "field_message_box.h" +#include "field_player_avatar.h" +#include "event_data.h" +#include "heal_location.h" +#include "link.h" +#include "load_save.h" +#include "main.h" +#include "menu.h" +#include "new_game.h" +#include "palette.h" +#include "play_time.h" +#include "rng.h" +#include "safari_zone.h" #include "script.h" #include "songs.h" #include "sound.h" -#include "rng.h" -#include "main.h" -#include "palette.h" -#include "text.h" -#include "link.h" -#include "sprite.h" -#include "flag.h" -#include "var.h" +#include "start_menu.h" +#include "task.h" +#include "tileset_anim.h" +#include "truck_scene.h" +#include "weather.h" +#include "wild_encounter.h" +#include "metatile_behavior.h" #ifdef SAPPHIRE #define LEGENDARY_MUSIC BGM_OOAME // Heavy Rain @@ -18,58 +37,12 @@ #define LEGENDARY_MUSIC BGM_HIDERI // Drought #endif -struct UnkWarpStruct -{ - s8 mapGroup; - s8 mapNum; - s16 x, y; -}; - struct UnkTVStruct { u32 tv_field_0; u32 tv_field_4; }; -struct UnkPlayerStruct -{ - u8 player_field_0; - u8 player_field_1; -}; - -struct UnkInputStruct -{ - u8 input_field_0; - u8 input_field_1; - u8 input_field_2; - u8 input_field_3; -}; - -struct UnkStruct_8054FF8_Substruct -{ - s16 x; - s16 y; - u8 field_8; -}; - -struct UnkStruct_8054FF8 -{ - u8 a; - u8 b; - u8 c; - u8 d; - struct UnkStruct_8054FF8_Substruct sub; - u16 field_C; -}; - -struct LinkPlayerMapObject -{ - u8 active; - u8 linkPlayerId; - u8 mapObjId; - u8 mode; -}; - struct UCoords32 { u32 x, y; @@ -101,25 +74,25 @@ extern struct UnkTVStruct gUnknown_03004870; extern u16 gUnknown_03004898; extern u16 gUnknown_0300489C; -extern u8 gUnknown_0819FC74[]; +extern u8 EventScript_LeagueWhiteOut[]; extern u8 gUnknown_0819FC9F[]; -extern u8 gUnknown_081A436F[]; -extern u8 gUnknown_081A4379[]; -extern u8 gUnknown_081A4383[]; -extern u8 gUnknown_081A439E[]; -extern u8 gUnknown_081A43B9[]; -extern u8 gUnknown_081A43D4[]; -extern u8 gUnknown_081A43F0[]; -extern u8 gUnknown_081A43FA[]; -extern u8 gUnknown_081A4418[]; -extern u8 gUnknown_081A442D[]; -extern u8 gUnknown_081A4442[]; -extern u8 gUnknown_081A4457[]; -extern u8 gUnknown_081A4479[]; -extern u8 gUnknown_081A4487[]; -extern u8 gUnknown_081A4495[]; -extern u8 gUnknown_081A44E5[]; -extern u8 gUnknown_081A44FE[]; +extern u8 SingleBattleColosseum_EventScript_1A436F[]; +extern u8 SingleBattleColosseum_EventScript_1A4379[]; +extern u8 DoubleBattleColosseum_EventScript_1A4383[]; +extern u8 DoubleBattleColosseum_EventScript_1A439E[]; +extern u8 DoubleBattleColosseum_EventScript_1A43B9[]; +extern u8 DoubleBattleColosseum_EventScript_1A43D4[]; +extern u8 TradeCenter_EventScript_1A43F0[]; +extern u8 TradeCenter_EventScript_1A43FA[]; +extern u8 RecordCorner_EventScript_1A4418[]; +extern u8 RecordCorner_EventScript_1A442D[]; +extern u8 RecordCorner_EventScript_1A4442[]; +extern u8 RecordCorner_EventScript_1A4457[]; +extern u8 TradeRoom_ReadTrainerCard1[]; +extern u8 TradeRoom_ReadTrainerCard2[]; +extern u8 TradeRoom_TooBusyToNotice[]; +extern u8 TradeRoom_PromptToCancelLink[]; +extern u8 TradeRoom_TerminateLink[]; extern u8 gUnknown_081A4508[]; extern struct UCoords32 gUnknown_0821664C[]; @@ -134,122 +107,10 @@ extern const struct WarpData gDummyWarpData; extern s32 gUnknown_0839ACE8; extern u32 gUnknown_08216694[]; -extern struct UnkWarpStruct *GetHealLocation(u8); -extern u8 GetSav1Weather(void); -extern void PlayerGetDestCoords(u16 *, u16 *); -extern u8 sub_810D32C(void); -extern u16 GetLocalWildMon(bool8 *); -extern u16 GetMirageIslandMon(void); -extern void ExecuteTruckSequence(void); -extern void sub_8080B60(void); -extern void sub_810CC80(void); -extern void sub_8080AC4(void); -extern void sub_8080A3C(void); -extern void atk17_seteffectuser(void); -extern void sub_80809B0(void); -extern void sub_8080990(void); -extern u8 sub_80BBB24(void); -extern u16 MapGridGetMetatileBehaviorAt(int, int); -extern u8 *sub_80682A8(void *, u8, u8); -extern u8 *sub_8068E24(struct UnkStruct_8054FF8_Substruct *); -extern bool8 MapGridIsImpassableAt(s16, s16); -extern u8 ZCoordToPriority(u8); - -void sub_8053050(void); -void warp_in(void); -void sub_8053570(void); -u8 sav1_map_get_light_level(void); -u8 get_map_light_level_by_bank_and_number(s8, s8); -bool8 is_light_level_1_2_3_5_or_6(u8); -void sub_805363C(s8, s8, s8, s8, s8); -void sub_807D874(u8); -void sub_8082BD0(u16, u16); -void player_avatar_init_params_reset(void); -u8 TestPlayerAvatarFlags(u8); -u8 player_get_direction_lower_nybble(void); -u8 sub_8053B00(struct UnkPlayerStruct *playerStruct, u16, u8); -u8 sub_8053B60(struct UnkPlayerStruct *playerStruct, u8, u16, u8); -u8 MetatileBehavior_IsSurfableWaterOrUnderwater(u8); -bool8 sub_8056F24(u8); -bool8 sub_8056F08(u8); -bool8 MetatileBehavior_IsDoor(u8); -bool8 MetatileBehavior_IsSouthArrowWarp(u8); -bool8 MetatileBehavior_IsNorthArrowWarp(u8); -bool8 MetatileBehavior_IsWestArrowWarp(u8); -bool8 MetatileBehavior_IsEastArrowWarp(u8); -bool8 MetatileBehavior_IsLadder(u8); -u16 cur_mapdata_block_role_at_screen_center_acc_to_sav1(void); -bool32 sub_8053C44(void); -void sub_8053C98(void); -void sav1_reset_battle_music_maybe(void); -void sub_8053F0C(void); -u8 is_light_level_8_or_9(u8); -void sub_8054164(void); -void sub_8055354(void); -void c2_overworld(void); -void CB2_LoadMap2(void); -void c2_80567AC(void); -void c2_exit_to_overworld_2_link(void); -void c2_exit_to_overworld_2_local(void); -void FieldClearVBlankHBlankCallbacks(void); -void SetFieldVBlankCallback(void); -void VBlankCB_Field(void); -bool32 sub_805483C(u8 *); -bool32 sub_805493C(u8 *, u32); -bool32 sub_8054A4C(u8 *); -bool32 sub_8054A9C(u8 *a1); -void do_load_map_stuff_loop(u8 *a1); -void sub_8054BA8(void); -void sub_8054C2C(void); -void sub_8054C54(void); -void sub_8054D4C(u32 a1); -void sub_8054D90(void); -void mli4_mapscripts_and_other(void); -void sub_8054E20(void); -void sub_8054E34(void); -void sub_8054E60(void); -void sub_8054E7C(void); -void sub_8054E98(void); -void sub_8054EC8(void); -void sub_8054F48(void); -void sub_8054F70(void); -u16 sub_805530C(u16); -void sub_8055340(u16 *); -u16 sub_8055390(u32); -u16 sub_80553E4(u32); -u16 sub_8055408(u32); -u16 sub_8055438(u32); -bool32 sub_8055618(struct UnkStruct_8054FF8 *); -bool32 sub_8055630(struct UnkStruct_8054FF8 *); -u8 *sub_8055648(struct UnkStruct_8054FF8 *); -bool32 sub_8055660(struct UnkStruct_8054FF8 *); -u8 *sub_805568C(struct UnkStruct_8054FF8 *); -u16 sub_8055758(u8 *); -void sub_80557E8(void); -void sub_80557F4(void); -void sub_8055808(u8 *); -void sub_8055824(void); -void sub_8055840(u8 *); -void sub_805585C(void); -bool32 sub_8055870(void); -void SpawnLinkPlayerMapObject(u8, s16, s16, u8); -void InitLinkPlayerMapObjectPos(struct MapObject *, s16, s16); -void sub_80555B0(int, int, struct UnkStruct_8054FF8 *); -u8 sub_8055AE8(u8); -void sub_8055B08(u8, u16 *, u16 *); -u8 sub_8055B30(u8); -u8 sub_8055B50(u8); -u8 GetLinkPlayerIdAt(s16, s16); -void sub_8055BFC(u8, u8); -u8 npc_something3(u8, u8); -u8 LinkPlayerDetectCollision(u8, u8, s16, s16); -void CreateLinkPlayerSprite(u8); -void SpriteCB_LinkPlayer(struct Sprite *); -void sub_8056C50(u16, u16); - -void sub_8052F5C(void) -{ - ScriptContext2_RunNewScript(gUnknown_0819FC74); + +void DoWhiteOut(void) +{ + ScriptContext2_RunNewScript(EventScript_LeagueWhiteOut); gSaveBlock1.money /= 2; HealPlayerParty(); sub_8053050(); @@ -307,14 +168,15 @@ void sub_805308C(void) sub_8134348(); } -void sub_80530AC(void) +void ResetGameStats(void) { s32 i; + for (i = 0; i < NUM_GAME_STATS; i++) gSaveBlock1.gameStats[i] = 0; } -void sav12_xor_increment(u8 index) +void IncrementGameStat(u8 index) { if (index < NUM_GAME_STATS) { @@ -325,7 +187,7 @@ void sav12_xor_increment(u8 index) } } -u32 sub_8053108(u8 index) +u32 GetGameStat(u8 index) { if (index >= NUM_GAME_STATS) return 0; @@ -333,7 +195,7 @@ u32 sub_8053108(u8 index) return gSaveBlock1.gameStats[index]; } -void sav12_xor_set(u8 index, u32 value) +void SetGameStat(u8 index, u32 value) { if (index < NUM_GAME_STATS) gSaveBlock1.gameStats[index] = value; @@ -515,9 +377,9 @@ void copy_saved_warp2_bank_and_enter_x_to_warp1(void) void sub_8053538(u8 a1) { - struct UnkWarpStruct *warp = GetHealLocation(a1); + const struct HealLocation *warp = GetHealLocation(a1); if (warp) - warp1_set(warp->mapGroup, warp->mapNum, -1, warp->x, warp->y); + warp1_set(warp->group, warp->map, -1, warp->x, warp->y); } void sub_8053570(void) @@ -527,9 +389,9 @@ void sub_8053570(void) void sub_8053588(u8 a1) { - struct UnkWarpStruct *warp = GetHealLocation(a1); + const struct HealLocation *warp = GetHealLocation(a1); if (warp) - warp_set(&gSaveBlock1.warp3, warp->mapGroup, warp->mapNum, -1, warp->x, warp->y); + warp_set(&gSaveBlock1.warp3, warp->group, warp->map, -1, warp->x, warp->y); } void sub_80535C4(u16 a1, u16 a2) @@ -589,12 +451,12 @@ void unref_sub_8053790(s8 mapGroup, s8 mapNum, s8 warpId, s8 x, s8 y) void sub_80537CC(u8 a1) { - struct UnkWarpStruct *warp = GetHealLocation(a1); + const struct HealLocation *warp = GetHealLocation(a1); if (warp) - warp_set(&gSaveBlock1.warp1, warp->mapGroup, warp->mapNum, -1, warp->x, warp->y); + warp_set(&gSaveBlock1.warp1, warp->group, warp->map, -1, warp->x, warp->y); } -void gpu_sync_bg_hide(void) +void gpu_sync_bg_hide() { gSaveBlock1.warp1 = gSaveBlock1.warp2; } @@ -651,12 +513,13 @@ bool8 sub_80538D0(u16 x, u16 y) void sub_80538F0(u8 mapGroup, u8 mapNum) { s32 i; + warp1_set(mapGroup, mapNum, -1, -1, -1); sub_8053F0C(); warp_shift(); set_current_map_header_from_sav1_save_old_name(); sub_8053154(); - sub_806906C(); + ClearTempFieldEventData(); ResetCyclingRoadChallengeData(); prev_quest_postbuffer_cursor_backup_reset(); sub_8082BD0(mapGroup, mapNum); @@ -669,13 +532,15 @@ void sub_80538F0(u8 mapGroup, u8 mapNum) not_trainer_hill_battle_pyramid(); sub_8056D38(gMapHeader.mapData); apply_map_tileset2_palette(gMapHeader.mapData); + for (i = 6; i < 12; i++) sub_807D874(i); + sub_8072ED0(); mapnumbers_history_shift_sav1_0_2_4_out(); sub_8134394(); - sub_808073C(); - wild_encounter_reset_coro_args(); + DoCurrentWeather(); + ResetFieldTasksArgs(); mapheader_run_script_with_tag_x5(); AddMapNamePopUpWindowTask(); } @@ -687,9 +552,9 @@ void sub_8053994(u32 a1) set_current_map_header_from_sav1_save_old_name(); sub_8053154(); - v2 = is_light_level_1_2_3_5_or_6(gMapHeader.light); - v3 = is_light_level_8_or_9(gMapHeader.light); - sub_806906C(); + v2 = is_light_level_1_2_3_5_or_6(gMapHeader.mapType); + v3 = is_light_level_8_or_9(gMapHeader.mapType); + ClearTempFieldEventData(); ResetCyclingRoadChallengeData(); prev_quest_postbuffer_cursor_backup_reset(); sub_8082BD0(gSaveBlock1.location.mapGroup, gSaveBlock1.location.mapNum); @@ -722,13 +587,13 @@ void walkrun_find_lowest_active_bit_in_bitfield(void) { gUnknown_02029810.player_field_1 = player_get_direction_lower_nybble(); - if (TestPlayerAvatarFlags(2)) + if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_MACH_BIKE)) gUnknown_02029810.player_field_0 = 2; - else if (TestPlayerAvatarFlags(4)) + else if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_ACRO_BIKE)) gUnknown_02029810.player_field_0 = 4; - else if (TestPlayerAvatarFlags(8)) + else if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_SURFING)) gUnknown_02029810.player_field_0 = 8; - else if (TestPlayerAvatarFlags(0x10)) + else if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_4)) gUnknown_02029810.player_field_0 = 16; else gUnknown_02029810.player_field_0 = 1; @@ -754,7 +619,7 @@ u8 sub_8053B00(struct UnkPlayerStruct *playerStruct, u16 a2, u8 a3) return 16; if (MetatileBehavior_IsSurfableWaterOrUnderwater(a2) == 1) return 8; - if (sub_8053C44() != 1) + if (IsBikingAllowedByMap() != TRUE) return 1; if (playerStruct->player_field_0 == 2) return 2; @@ -767,9 +632,9 @@ u8 sub_8053B60(struct UnkPlayerStruct *playerStruct, u8 a2, u16 a3, u8 a4) { if (FlagGet(SYS_CRUISE_MODE) && a4 == 6) return 4; - if (sub_8056F24(a3) == TRUE) + if (MetatileBehavior_IsDeepSouthWarp(a3) == TRUE) return 2; - if (sub_8056F08(a3) == TRUE || MetatileBehavior_IsDoor(a3) == TRUE) + if (MetatileBehavior_IsNonAnimDoor(a3) == TRUE || MetatileBehavior_IsDoor(a3) == TRUE) return 1; if (MetatileBehavior_IsSouthArrowWarp(a3) == TRUE) return 2; @@ -792,20 +657,28 @@ u16 cur_mapdata_block_role_at_screen_center_acc_to_sav1(void) return MapGridGetMetatileBehaviorAt(gSaveBlock1.pos.x + 7, gSaveBlock1.pos.y + 7); } -bool32 sub_8053C44(void) +bool32 IsBikingAllowedByMap(void) { + // is player in cycling road entrance? if (gSaveBlock1.location.mapGroup == 29 && (gSaveBlock1.location.mapNum == 11 || gSaveBlock1.location.mapNum == 12)) return TRUE; - if (gMapHeader.light == 8) + + // is player indoor, in a secret base, or underwater? + if (gMapHeader.mapType == MAP_TYPE_INDOOR) return FALSE; - if (gMapHeader.light == 9) + if (gMapHeader.mapType == MAP_TYPE_SECRET_BASE) return FALSE; - if (gMapHeader.light == 5) + if (gMapHeader.mapType == MAP_TYPE_UNDERWATER) return FALSE; + + // is player in SeafloorCavern_Room9? if (gSaveBlock1.location.mapGroup == 24 && gSaveBlock1.location.mapNum == 36) return FALSE; + + // is player in CaveOfOrigin_B4F? if (gSaveBlock1.location.mapGroup == 24 && gSaveBlock1.location.mapNum == 42) return FALSE; + return TRUE; } @@ -862,7 +735,7 @@ bool16 sub_8053D30(struct WarpData *warp) bool16 sub_8053D6C(struct WarpData *warp) { - if (VarGet(16563)) + if (VarGet(0x40B3)) return FALSE; if (warp->mapGroup != 32) return FALSE; @@ -935,7 +808,7 @@ void sub_8053E90(void) music = gSaveBlock1.battleMusic; else if (sav1_map_get_light_level() == 5) music = BGM_DEEPDEEP; - else if (TestPlayerAvatarFlags(8)) + else if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_SURFING)) music = BGM_NAMINORI; } @@ -963,12 +836,12 @@ void sub_8053F0C(void) { if (currentMusic == BGM_DEEPDEEP || currentMusic == BGM_NAMINORI) return; - if (TestPlayerAvatarFlags(8)) + if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_SURFING)) newMusic = BGM_NAMINORI; } if (newMusic != currentMusic) { - if (TestPlayerAvatarFlags(6)) + if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_MACH_BIKE | PLAYER_AVATAR_FLAG_ACRO_BIKE)) FadeOutAndFadeInNewMapMusic(newMusic, 4, 4); else FadeOutAndPlayNewMapMusic(newMusic, 8); @@ -993,7 +866,7 @@ void sub_8053FB0(u16 music) u8 is_warp1_light_level_8_or_9(void) { struct MapHeader *mapHeader = warp1_get_mapheader(); - if (is_light_level_8_or_9(mapHeader->light) == TRUE) + if (is_light_level_8_or_9(mapHeader->mapType) == TRUE) return 2; else return 4; @@ -1078,7 +951,7 @@ void sub_8054164(void) u8 get_map_light_level_by_bank_and_number(s8 mapGroup, s8 mapNum) { - return get_mapheader_by_bank_and_number(mapGroup, mapNum)->light; + return get_mapheader_by_bank_and_number(mapGroup, mapNum)->mapType; } u8 get_map_light_level_from_warp(struct WarpData *warp) @@ -1237,7 +1110,7 @@ void CB2_NewGame(void) SetMainCallback2(c2_overworld); } -void c2_whiteout(void) +void CB2_WhiteOut(void) { u8 val; gMain.state++; @@ -1246,7 +1119,7 @@ void c2_whiteout(void) FieldClearVBlankHBlankCallbacks(); StopMapMusic(); ResetSafariZoneFlag_(); - sub_8052F5C(); + DoWhiteOut(); player_avatar_init_params_reset(); ScriptContext1_Init(); ScriptContext2_Disable(); @@ -1266,7 +1139,7 @@ void CB2_LoadMap(void) ScriptContext2_Disable(); set_callback1(NULL); SetMainCallback2(sub_810CC80); - gMain.field_8 = CB2_LoadMap2; + gMain.savedCallback = CB2_LoadMap2; } void CB2_LoadMap2(void) @@ -1395,16 +1268,16 @@ void CB2_ContinueSavedGame(void) ResetSafariZoneFlag_(); sub_805338C(); sub_8053198(); - sub_806451C(); + UnfreezeMapObjects(); DoTimeBasedEvents(); sub_805308C(); sub_8055FC0(); PlayTimeCounter_Start(); ScriptContext1_Init(); ScriptContext2_Disable(); - if (sub_80479F8() == 1) + if (GetSecretBase2Field_9() == 1) { - sub_8047A04(); + ClearSecretBase2Field_9(); sub_8053778(); warp_in(); SetMainCallback2(CB2_LoadMap); @@ -1550,7 +1423,7 @@ bool32 sub_805493C(u8 *a1, u32 a2) sub_8054814(); sub_8054C54(); SetUpWindowConfig(&gWindowConfig_81E6C3C); - InitMenuWindow((u8 *)&gWindowConfig_81E6CE4); + InitMenuWindow(&gWindowConfig_81E6CE4); (*a1)++; break; case 5: @@ -1767,7 +1640,7 @@ void sub_8054D4C(u32 a1) sub_807C828(); sub_8080750(); if (!a1) - overworld_ensure_per_step_coros_running(); + SetUpFieldTasks(); mapheader_run_script_with_tag_x5(); } @@ -2286,12 +2159,13 @@ u8 *sub_805568C(struct UnkStruct_8054FF8 *a1) if (linkPlayerId != 4) { if (!a1->b) - return gUnknown_081A4495; + return TradeRoom_TooBusyToNotice; if (gUnknown_03000580[linkPlayerId] != 0x80) - return gUnknown_081A4495; + return TradeRoom_TooBusyToNotice; if (!sub_8083BF4(linkPlayerId)) - return gUnknown_081A4479; - return gUnknown_081A4487; + return TradeRoom_ReadTrainerCard1; + else + return TradeRoom_ReadTrainerCard2; } return sub_80682A8(&unkStruct, a1->field_C, a1->d); @@ -2299,29 +2173,29 @@ u8 *sub_805568C(struct UnkStruct_8054FF8 *a1) u16 sub_8055758(u8 *script) { - if (script == gUnknown_081A4383) + if (script == DoubleBattleColosseum_EventScript_1A4383) return 10; - if (script == gUnknown_081A439E) + if (script == DoubleBattleColosseum_EventScript_1A439E) return 9; - if (script == gUnknown_081A43B9) + if (script == DoubleBattleColosseum_EventScript_1A43B9) return 10; - if (script == gUnknown_081A43D4) + if (script == DoubleBattleColosseum_EventScript_1A43D4) return 9; - if (script == gUnknown_081A4418) + if (script == RecordCorner_EventScript_1A4418) return 10; - if (script == gUnknown_081A442D) + if (script == RecordCorner_EventScript_1A442D) return 9; - if (script == gUnknown_081A4442) + if (script == RecordCorner_EventScript_1A4442) return 10; - if (script == gUnknown_081A4457) + if (script == RecordCorner_EventScript_1A4457) return 9; - if (script == gUnknown_081A436F) + if (script == SingleBattleColosseum_EventScript_1A436F) return 10; - if (script == gUnknown_081A4379) + if (script == SingleBattleColosseum_EventScript_1A4379) return 9; - if (script == gUnknown_081A43F0) + if (script == TradeCenter_EventScript_1A43F0) return 10; - if (script == gUnknown_081A43FA) + if (script == TradeCenter_EventScript_1A43FA) return 9; return 0; } @@ -2348,7 +2222,7 @@ void sub_8055808(u8 *script) void sub_8055824(void) { PlaySE(SE_WIN_OPEN); - ScriptContext1_SetupScript(gUnknown_081A44E5); + ScriptContext1_SetupScript(TradeRoom_PromptToCancelLink); ScriptContext2_Enable(); } @@ -2361,7 +2235,7 @@ void sub_8055840(u8 *script) void sub_805585C(void) { - ScriptContext1_SetupScript(gUnknown_081A44FE); + ScriptContext1_SetupScript(TradeRoom_TerminateLink); ScriptContext2_Enable(); } diff --git a/src/rom_800D42C.c b/src/rom_800D42C.c new file mode 100644 index 000000000..e9c816818 --- /dev/null +++ b/src/rom_800D42C.c @@ -0,0 +1,89 @@ +#include "global.h" +#include "battle.h" +#include "link.h" +#include "text.h" + +extern u16 gBattleTypeFlags; +extern u8 gUnknown_02024D26; + +extern struct Window gUnknown_03004210; + +extern u8 BattleText_Win[]; +extern u8 BattleText_Loss[]; +extern u8 BattleText_Tie[]; + +#define LEFT_MESSAGE_X 6 +#define RIGHT_MESSAGE_X 21 +#define CENTER_MESSAGE_X 13 +#define MESSAGE_Y 2 + +#define PRINT_MESSAGE(text, tileDataStartOffset, x) \ +{ \ + InitWindow(&gUnknown_03004210, text, tileDataStartOffset, x, MESSAGE_Y); \ + sub_8002F44(&gUnknown_03004210); \ +} + +#define PRINT_MESSAGE_LEFT(text, tileDataStartOffset) PRINT_MESSAGE(text, tileDataStartOffset, LEFT_MESSAGE_X) +#define PRINT_MESSAGE_RIGHT(text, tileDataStartOffset) PRINT_MESSAGE(text, tileDataStartOffset, RIGHT_MESSAGE_X) + +void sub_800DC24(void) { + + if (gUnknown_02024D26 == 3) { + PRINT_MESSAGE(BattleText_Tie, 160, CENTER_MESSAGE_X); + return; + } + + if (gBattleTypeFlags & BATTLE_TYPE_40) { + // Double battle? + + if (gUnknown_02024D26 == 1) { + + // lp_field_18 = player position? + switch (gLinkPlayers[battle_2000000.linkPlayerIndex].lp_field_18) { + case 0: + case 2: PRINT_MESSAGE_LEFT(BattleText_Win, 160); + PRINT_MESSAGE_RIGHT(BattleText_Loss, 168); + return; + + case 1: + case 3: PRINT_MESSAGE_RIGHT(BattleText_Win, 160) + PRINT_MESSAGE_LEFT(BattleText_Loss, 168) + return; + } + } else { + + switch (gLinkPlayers[battle_2000000.linkPlayerIndex].lp_field_18) { + case 1: + case 3: PRINT_MESSAGE_LEFT(BattleText_Win, 160); + PRINT_MESSAGE_RIGHT(BattleText_Loss, 168); + return; + + case 0: + case 2: PRINT_MESSAGE_RIGHT(BattleText_Win, 160); + PRINT_MESSAGE_LEFT(BattleText_Loss, 168); + return; + } + } + + return; + } + + + if (gUnknown_02024D26 == 1) { + if (gLinkPlayers[battle_2000000.linkPlayerIndex].lp_field_18 != 0) { + PRINT_MESSAGE_RIGHT(BattleText_Win, 160); + PRINT_MESSAGE_LEFT(BattleText_Loss, 168); + } else { + PRINT_MESSAGE_LEFT(BattleText_Win, 160); + PRINT_MESSAGE_RIGHT(BattleText_Loss, 168); + } + } else { + if (gLinkPlayers[battle_2000000.linkPlayerIndex].lp_field_18 != 0) { + PRINT_MESSAGE_LEFT(BattleText_Win, 160); + PRINT_MESSAGE_RIGHT(BattleText_Loss, 168); + } else { + PRINT_MESSAGE_RIGHT(BattleText_Win, 160); + PRINT_MESSAGE_LEFT(BattleText_Loss, 168); + } + } +} @@ -1,5 +1,4 @@ #include "global.h" -#include "siirtc.h" #include "rtc.h" #include "string_util.h" #include "text.h" @@ -29,19 +28,6 @@ static const s32 sNumDaysInMonths[12] = 31, }; -void RtcDisableInterrupts(); -void RtcRestoreInterrupts(); -u32 ConvertBcdToBinary(u8 bcd); -bool8 IsLeapYear(u8 year); -u16 ConvertDateToDayCount(u8 year, u8 month, u8 day); -u16 RtcGetDayCount(struct SiiRtcInfo *rtc); -void RtcGetInfo(struct SiiRtcInfo *rtc); -void RtcGetDateTime(struct SiiRtcInfo *rtc); -void RtcGetStatus(struct SiiRtcInfo *rtc); -void RtcGetRawInfo(struct SiiRtcInfo *rtc); -u16 RtcCheckInfo(struct SiiRtcInfo *rtc); -void RtcCalcTimeDifference(struct SiiRtcInfo *rtc, struct Time *result, struct Time *t); - void RtcDisableInterrupts() { sSavedIme = REG_IME; @@ -77,9 +63,8 @@ u16 ConvertDateToDayCount(u8 year, u8 month, u8 day) s32 i; u16 dayCount = 0; -#if (REVISION < 2) - // Revisions 0 and 1 don't add days for the year 2000, - // causing the berry glitch. +#ifndef BUGFIX_BERRY + // The berry glitch was caused by not adding days for the year 2000. for (i = year - 1; i > 0; i--) { dayCount += 365; @@ -88,8 +73,7 @@ u16 ConvertDateToDayCount(u8 year, u8 month, u8 day) dayCount++; } #else - // Revision 2 has "i >= 0" as the condition instead of "i > 0", - // which fixes the issue. + // The fix was to use "i >= 0" as the condition instead of "i > 0". for (i = year - 1; i >= 0; i--) { dayCount += 365; @@ -97,7 +81,7 @@ u16 ConvertDateToDayCount(u8 year, u8 month, u8 day) if (IsLeapYear(i) == TRUE) dayCount++; } -#endif +#endif // BUGFIX_BERRY for (i = 0; i < month - 1; i++) dayCount += sNumDaysInMonths[i]; diff --git a/src/safari_zone.c b/src/safari_zone.c index 600ba95d2..08bfbefbf 100644 --- a/src/safari_zone.c +++ b/src/safari_zone.c @@ -1,8 +1,12 @@ #include "global.h" -#include "flag.h" +#include "safari_zone.h" +#include "asm.h" +#include "field_player_avatar.h" +#include "event_data.h" #include "main.h" #include "script.h" #include "string_util.h" +#include "rom4.h" struct PokeblockFeeder { @@ -15,16 +19,8 @@ struct PokeblockFeeder #define NUM_POKEBLOCK_FEEDERS 10 -void ClearAllPokeblockFeeders(void); -void DecrementFeederStepCounters(void); -extern void c2_exit_to_overworld_2_switch(void); -extern void c2_exit_to_overworld_1_continue_scripts_restart_music(void); -extern void sub_8080E44(void); -extern void CB2_LoadMap(void); -extern void sav12_xor_increment(u8); -extern void warp_in(void); -extern void GetXYCoordsOneStepInFrontOfPlayer(void *, void *); -extern void PlayerGetDestCoords(u16 *, u16 *); +static void ClearAllPokeblockFeeders(void); +static void DecrementFeederStepCounters(void); extern u8 gUnknown_02024D26; @@ -59,7 +55,7 @@ void ResetSafariZoneFlag(void) void EnterSafariMode(void) { - sav12_xor_increment(0x11); + IncrementGameStat(0x11); SetSafariZoneFlag(); ClearAllPokeblockFeeders(); gNumSafariBalls = 30; diff --git a/src/save.c b/src/save.c index c6b82bc0a..49db679f8 100644 --- a/src/save.c +++ b/src/save.c @@ -1,30 +1,11 @@ #include "global.h" +#include "save.h" +#include "asm.h" +#include "gba/gba.h" +#include "load_save.h" +#include "rom4.h" #include "gba/flash_internal.h" - -struct SaveSectionLocation -{ - void *data; - u16 size; -}; - -struct SaveSection -{ - u8 data[0xFF4]; - u16 id; - u16 checksum; - u32 unknown; - u32 counter; -}; - -struct UnkSaveSection -{ - u8 data[0xFF4]; - u32 unknown; -}; - -extern u32 sub_8053108(u8); -extern void sav12_xor_increment(u8); -extern u32 ProgramFlashSectorAndVerifyNBytes(u16 sectorNum, u8 *src, u32 n); +#include "save_failed_screen.h" extern struct SaveSection unk_2000000; @@ -46,14 +27,6 @@ extern struct SaveSectionLocation gSaveSectionLocations[]; extern struct SaveSectionLocation gHallOfFameSaveSectionLocations[]; extern u8 gUnknown_08401E24[]; -u8 sub_81252D8(u16, struct SaveSectionLocation *); -u8 sub_8125440(u8, u8 *); -u8 sub_81255B8(u16, struct SaveSectionLocation *); -u8 sub_81258BC(u16, struct SaveSectionLocation *); -u8 sub_8125BF8(u8, struct SaveSection *); -u8 sub_8125974(struct SaveSectionLocation *); -u16 sub_8125C10(void *, u16); - void ClearSaveData(void) { u16 i; @@ -551,7 +524,7 @@ u8 sub_8125B88(u8 a1, u8 *data, u16 size) u8 sub_8125BF8(u8 sector, struct SaveSection *section) { - ReadFlash(sector, 0, section, 0x1000); + ReadFlash(sector, 0, section->data, 0x1000); return 1; } @@ -575,31 +548,31 @@ u8 sub_8125C3C(u8 a1) for (i = 28; i < 32; i++) EraseFlashSector(i); case 3: - if (sub_8053108(10) < 999) - sav12_xor_increment(10); + if (GetGameStat(10) < 999) + IncrementGameStat(10); for (i = 0; i < 2; i++) sub_81253C8(28 + i, gHallOfFameSaveSectionLocations[i].data, gHallOfFameSaveSectionLocations[i].size); - save_serialize_game(); + SaveSerializedGame(); save_write_to_flash(0xFFFF, gSaveSectionLocations); break; case 0: default: - save_serialize_game(); + SaveSerializedGame(); save_write_to_flash(0xFFFF, gSaveSectionLocations); break; case 1: - save_serialize_game(); + SaveSerializedGame(); for (i = 0; i < 5; i++) save_write_to_flash(i, gSaveSectionLocations); break; case 2: - save_serialize_game(); + SaveSerializedGame(); save_write_to_flash(0, gSaveSectionLocations); break; case 4: for (i = 28; i < 32; i++) EraseFlashSector(i); - save_serialize_game(); + SaveSerializedGame(); save_write_to_flash(0xFFFF, gSaveSectionLocations); break; } @@ -613,7 +586,7 @@ u8 sub_8125D44(u8 a1) sub_8125C3C(a1); if (!gUnknown_03005EA8) return 1; - fullscreen_save_activate(a1); + DoSaveFailedScreen(a1); return 0xFF; } @@ -621,7 +594,7 @@ u8 sub_8125D80(void) { if (gUnknown_3004820 != 1) return 1; - save_serialize_game(); + SaveSerializedGame(); sub_812546C(gSaveSectionLocations); return 0; } @@ -630,7 +603,7 @@ bool8 sub_8125DA8(void) { u8 v0 = sub_812550C(14, gSaveSectionLocations); if (gUnknown_03005EA8) - fullscreen_save_activate(0); + DoSaveFailedScreen(0); if (v0 == 0xFF) return 1; else @@ -641,7 +614,7 @@ u8 sub_8125DDC(void) { sub_812556C(14, gSaveSectionLocations); if (gUnknown_03005EA8) - fullscreen_save_activate(0); + DoSaveFailedScreen(0); return 0; } @@ -649,7 +622,7 @@ u8 sub_8125E04(void) { sub_8125758(14, gSaveSectionLocations); if (gUnknown_03005EA8) - fullscreen_save_activate(0); + DoSaveFailedScreen(0); return 0; } @@ -658,7 +631,7 @@ u8 sub_8125E2C(void) if (gUnknown_3004820 != 1) return 1; - save_serialize_game(); + SaveSerializedGame(); sub_81254C8(gSaveSectionLocations); sub_812556C(gUnknown_03005EB4 + 1, gSaveSectionLocations); return 0; @@ -679,7 +652,7 @@ u8 sub_8125E6C(void) retVal = 1; } if (gUnknown_03005EA8) - fullscreen_save_activate(1); + DoSaveFailedScreen(1); return retVal; } @@ -698,7 +671,7 @@ u8 sub_8125EC8(u8 a1) case 0: default: result = sub_812587C(0xFFFF, gSaveSectionLocations); - save_deserialize_game(); + LoadSerializedGame(); gSaveFileStatus = result; gUnknown_03005EBC = 0; break; @@ -720,7 +693,7 @@ bool8 unref_sub_8125F4C(struct UnkSaveSection *a1) for (i = 0; i < 0x1000; i++) raw[i] = 0; - ReadFlash(gUnknown_08401E24[0], 0, a1, 4096); + ReadFlash(gUnknown_08401E24[0], 0, a1->data, 4096); if (a1->unknown != 0x8012025) return FALSE; diff --git a/src/save_failed_screen.c b/src/save_failed_screen.c new file mode 100644 index 000000000..41e61eadb --- /dev/null +++ b/src/save_failed_screen.c @@ -0,0 +1,301 @@ +#include "global.h" +#include "main.h" +#include "sprite.h" +#include "palette.h" +#include "task.h" +#include "text.h" +#include "menu.h" +#include "save.h" +#include "m4a.h" +#include "gba/flash_internal.h" +#include "asm.h" + +// In English 1.0, the text window is too small, causing text to overflow. + +#ifdef BUGFIX_SAVEFAILEDSCREEN1 +#define MSG_WIN_TOP 10 +#else +#define MSG_WIN_TOP 12 +#endif + +#define CLOCK_WIN_TOP (MSG_WIN_TOP - 4) + +struct SaveFailedStruct +{ + u16 unk0; + u16 unk2; +}; + +extern u8 unk_2000000[]; + +extern u16 gUnknown_0203933C; +extern struct SaveFailedStruct gUnknown_0203933E; +extern u32 gUnknown_03005EA8; +extern u32 gUnknown_03005EBC; + +extern struct OamData gUnknown_08411940; +extern u8 gUnknown_08411948[][3]; + +extern u8 gBirchHelpGfx[]; + +extern u8 gSystemText_SaveFailedBackupCheck[]; +extern u8 gSystemText_CheckCompleteSaveAttempt[]; +extern u8 gSystemText_BackupDamagedGameContinue[]; +extern u8 gSystemText_SaveCompletedPressA[]; +extern u8 gSystemText_SaveCompletedGameEnd[]; +extern u8 gSystemText_GameplayEnded[]; + +extern u8 gBirchGrassTilemap[]; +extern u8 gBirchBagTilemap[]; + +extern const u8 gSaveFailedClockGfx[]; +extern const u8 gSaveFailedClockPal[]; +extern u8 gBirchBagGrassPal[]; + +static void VBlankCB(void); +static void CB2_SaveFailedScreen(void); +static void CB2_WipeSave(void); +static void CB2_GameplayCannotBeContinued(void); +static void CB2_FadeAndReturnToTitleScreen(void); +static void CB2_ReturnToTitleScreen(void); +static void VBlankCB_UpdateClockGraphics(void); +static bool8 VerifySectorWipe(u16 sector); +static bool8 WipeSector(u16 sector); +static bool8 WipeSectors(u32 sectorBits); + +void DoSaveFailedScreen(u8 var) +{ + SetMainCallback2(CB2_SaveFailedScreen); + gUnknown_0203933C = var; + gUnknown_0203933E.unk0 = 0; +} + +static void VBlankCB(void) +{ + LoadOam(); + ProcessSpriteCopyRequests(); + TransferPlttBuffer(); +} + +static void CB2_SaveFailedScreen(void) +{ + u16 ime; + + switch(gMain.state) + { + case 0: + default: + SetVBlankCallback(0); + REG_DISPCNT = 0; + REG_BG3CNT = 0; + REG_BG2CNT = 0; + REG_BG1CNT = 0; + REG_BG0CNT = 0; + REG_BG3HOFS = 0; + REG_BG3VOFS = 0; + REG_BG2HOFS = 0; + REG_BG2VOFS = 0; + REG_BG1HOFS = 0; + REG_BG1VOFS = 0; + REG_BG0HOFS = 0; + REG_BG0VOFS = 0; + DmaFill16(3, 0, VRAM, VRAM_SIZE); + DmaFill32(3, 0, OAM, OAM_SIZE); + DmaFill16(3, 0, PLTT, PLTT_SIZE); + LZ77UnCompVram(&gBirchHelpGfx, (void *)VRAM); + LZ77UnCompVram(&gBirchBagTilemap, (void *)(VRAM + 0x3000)); + LZ77UnCompVram(&gBirchGrassTilemap, (void *)(VRAM + 0x3800)); + LZ77UnCompVram(&gSaveFailedClockGfx, (void *)(VRAM + 0x10020)); + ResetSpriteData(); + ResetTasks(); + ResetPaletteFade(); + LoadPalette(&gBirchBagGrassPal, 0, 0x40); + LoadPalette(&gSaveFailedClockPal, 0x100, 0x20); + SetUpWindowConfig(&gWindowConfig_81E6C3C); + InitMenuWindow(&gWindowConfig_81E6CE4); + MenuDrawTextWindow(13, CLOCK_WIN_TOP, 16, CLOCK_WIN_TOP + 3); // clock window + MenuDrawTextWindow(1, MSG_WIN_TOP, 28, 19); // message window + MenuPrint(gSystemText_SaveFailedBackupCheck, 2, MSG_WIN_TOP + 1); + BeginNormalPaletteFade(0xFFFFFFFF, 0, 16, 0, 0); + ime = REG_IME; + REG_IME = 0; + REG_IE |= INTR_FLAG_VBLANK; + REG_IME = ime; + REG_DISPSTAT |= DISPSTAT_VBLANK_INTR; + SetVBlankCallback(VBlankCB); + REG_BG3CNT = 0x703; + REG_BG2CNT = 0x602; + REG_BG0CNT = 0x1f08; + REG_DISPCNT = DISPCNT_OBJ_ON | DISPCNT_BG3_ON | DISPCNT_BG2_ON | DISPCNT_BG0_ON | DISPCNT_OBJ_1D_MAP | DISPCNT_MODE_0; + gMain.state++; + break; + case 1: + if (!UpdatePaletteFade()) + { + SetMainCallback2(CB2_WipeSave); + SetVBlankCallback(VBlankCB_UpdateClockGraphics); + } + break; + } +} + +static void CB2_WipeSave(void) +{ + u8 wipeTries = 0; + + gUnknown_0203933E.unk0 = 1; + + while (gUnknown_03005EA8 && wipeTries < 3) + { + if (WipeSectors(gUnknown_03005EA8)) + { + MenuDrawTextWindow(1, MSG_WIN_TOP, 28, 19); + MenuPrint(gSystemText_BackupDamagedGameContinue, 2, MSG_WIN_TOP + 1); + SetMainCallback2(CB2_GameplayCannotBeContinued); + return; + } + + MenuDrawTextWindow(1, MSG_WIN_TOP, 28, 19); + MenuPrint(gSystemText_CheckCompleteSaveAttempt, 2, MSG_WIN_TOP + 1); + sub_8125C3C(gUnknown_0203933C); + + if (gUnknown_03005EA8) + { +#ifdef BUGFIX_SAVEFAILEDSCREEN2 + MenuDrawTextWindow(1, MSG_WIN_TOP, 28, 19); +#endif + MenuPrint(gSystemText_SaveFailedBackupCheck, 2, MSG_WIN_TOP + 1); + } + + wipeTries++; + } + + if (wipeTries == 3) + { + MenuDrawTextWindow(1, MSG_WIN_TOP, 28, 19); + MenuPrint(gSystemText_BackupDamagedGameContinue, 2, MSG_WIN_TOP + 1); + SetMainCallback2(CB2_FadeAndReturnToTitleScreen); // called again below + } + else + { + MenuDrawTextWindow(1, MSG_WIN_TOP, 28, 19); + + if (!gUnknown_03005EBC) // cant continue game. + MenuPrint(gSystemText_SaveCompletedGameEnd, 2, MSG_WIN_TOP + 1); + else // can continue game. + MenuPrint(gSystemText_SaveCompletedPressA, 2, MSG_WIN_TOP + 1); + } + + SetMainCallback2(CB2_FadeAndReturnToTitleScreen); +} + +static void CB2_GameplayCannotBeContinued(void) +{ + gUnknown_0203933E.unk0 = 0; + + if (gMain.newKeys & A_BUTTON) + { + MenuDrawTextWindow(1, MSG_WIN_TOP, 28, 19); + MenuPrint(gSystemText_GameplayEnded, 2, MSG_WIN_TOP + 1); + SetVBlankCallback(VBlankCB); + SetMainCallback2(CB2_FadeAndReturnToTitleScreen); + } +} + +static void CB2_FadeAndReturnToTitleScreen(void) +{ + u8 zero; + + gUnknown_0203933E.unk0 = zero = 0; + + if (gMain.newKeys & A_BUTTON) + { + BeginNormalPaletteFade(0xFFFFFFFF, 0, zero, 16, 0); + SetVBlankCallback(VBlankCB); + SetMainCallback2(CB2_ReturnToTitleScreen); + } +} + +static void CB2_ReturnToTitleScreen(void) +{ + if (!UpdatePaletteFade()) + { + if (!gUnknown_03005EBC) + { + DoSoftReset(); + } + else + { + SetMainCallback2((MainCallback)gUnknown_03005EBC); + gUnknown_03005EBC = 0; + } + } +} + +static void VBlankCB_UpdateClockGraphics(void) +{ + unsigned int n = (gMain.vblankCounter2 >> 3) & 7; + + gMain.oamBuffer[0] = gUnknown_08411940; + gMain.oamBuffer[0].x = 112; + gMain.oamBuffer[0].y = (CLOCK_WIN_TOP + 1) * 8; + + if (gUnknown_0203933E.unk0) + { + gMain.oamBuffer[0].tileNum = gUnknown_08411948[n][0]; + gMain.oamBuffer[0].matrixNum = (gUnknown_08411948[n][2] << 4) | (gUnknown_08411948[n][1] << 3); + } + else + { + gMain.oamBuffer[0].tileNum = 1; + } + + CpuFastCopy(gMain.oamBuffer, (void *)OAM, 4); + + if (gUnknown_0203933E.unk2) + gUnknown_0203933E.unk2--; +} + +static bool8 VerifySectorWipe(u16 sector) +{ + u32 *ptr = (u32 *)unk_2000000; + u16 i; + + ReadFlash(sector, 0, (u8 *)ptr, 4096); + + for (i = 0; i < 0x400; i++, ptr++) + if (*ptr) + return TRUE; + + return FALSE; +} + +static bool8 WipeSector(u16 sector) +{ + u16 i, j; + bool8 failed = TRUE; + + for (i = 0; failed && i < 130; i++) + { + for (j = 0; j < 0x1000; j++) + ProgramFlashByte(sector, j, 0); + + failed = VerifySectorWipe(sector); + } + + return failed; +} + +static bool8 WipeSectors(u32 sectorBits) +{ + u16 i; + + for (i = 0; i < 0x20; i++) + if ((sectorBits & (1 << i)) && !WipeSector(i)) + sectorBits &= ~(1 << i); + + if (sectorBits == 0) + return FALSE; + else + return TRUE; +} diff --git a/src/save_menu_util.c b/src/save_menu_util.c index c811f5244..d2fda59d6 100644 --- a/src/save_menu_util.c +++ b/src/save_menu_util.c @@ -1,23 +1,16 @@ #include "global.h" +#include "save_menu_util.h" +#include "asm.h" #include "menu.h" -#include "flag.h" +#include "event_data.h" +#include "string_util.h" +#include "pokedex.h" extern u8 gOtherText_Player[]; extern u8 gOtherText_Badges[]; extern u8 gOtherText_Pokedex[]; extern u8 gOtherText_PlayTime[]; -extern void ConvertIntToDecimalStringN(u8 *dest, u32 value, int mode, u8 n); - -u8 sub_809473C(void); -u8 GetBadgeCount(void); - -void PrintSavePlayerName(s16 x, s16 y); -void PrintSaveMapName(s16 x, s16 y); -void PrintSaveBadges(s16 x, s16 y); -void PrintSavePokedexCount(s16 x, s16 y); -void PrintSavePlayTime(s16 x, s16 y); - void HandleDrawSaveWindowInfo(s16 left, s16 top) { u32 width = 12; @@ -125,7 +118,7 @@ u16 GetPokedexSeenCount() { u16 pokedexSeenCount; - if (IsNationalPokedex()) + if (IsNationalPokedexEnabled()) pokedexSeenCount = GetNationalPokedexCount(1); else pokedexSeenCount = GetHoennPokedexCount(1); diff --git a/src/scrcmd.c b/src/scrcmd.c index 9d6f36a54..d3d28f923 100644 --- a/src/scrcmd.c +++ b/src/scrcmd.c @@ -1,143 +1,28 @@ #include "global.h" +#include "asm.h" +#include "battle_setup.h" +#include "berry.h" +#include "field_player_avatar.h" +#include "item.h" #include "script.h" #include "rng.h" #include "palette.h" #include "rtc.h" #include "pokemon.h" -#include "fieldmap.h" +#include "asm_fieldmap.h" #include "main.h" #include "menu.h" +#include "money.h" #include "decoration.h" #include "field_message_box.h" #include "sound.h" #include "string_util.h" -#include "flag.h" -#include "var.h" - -extern void ClearRamScript(void); -extern void sub_8126160(u8); -extern u8 AddBagItem(u16, u16); -extern u8 RemoveBagItem(u16, u16); -extern u8 CheckBagHasSpace(u16, u16); -extern u8 CheckBagHasItem(u16, u16); -extern u8 GetPocketByItemId(u16); -extern u8 AddPCItem(u16, u16); -extern u8 CheckPCHasItem(u16, u16); -extern u8 IsThereStorageSpaceForDecoration(u8); -extern s8 sub_81340A8(u8); -extern u8 sub_8134074(u8); -extern u8 sub_8133FE4(u8); -extern void sav12_xor_increment(u8); -extern void sub_8081594(u8); -extern void sub_8053CE4(u32); -extern void fade_screen(u8, u8); -extern void DoTimeBasedEvents(void); -extern void SetSav1Weather(u32); -extern void sub_80806E4(void); -extern void sub_808073C(void); -extern void activate_per_step_callback(u8); -extern void sub_8053D14(u16); -extern void warp1_set(s8, s8, s8, s8, s8); -extern void sub_8080E88(void); -extern void player_avatar_init_params_reset(void); -extern void sp13E_warp_to_last_warp(void); -extern void sub_8080EF0(void); -extern void sp13F_fall_to_last_warp(void); -extern void sub_8053720(s16, s16); -extern void PlayerGetDestCoords(u16 *, u16 *); -extern void sub_8080F68(void); -extern void saved_warp2_set_2(s8, s8, s8, s8, s8, s8); -extern void sub_8053690(s8, s8, s8, s8, s8); -extern void sub_80536E4(s8, s8, s8, s8, s8); -extern void sub_805363C(s8, s8, s8, s8, s8); -extern void sav1_set_battle_music_maybe(u16); -extern void sub_8053F84(void); -extern void sub_8053FB0(u16); -extern u8 exec_movement(u8, u8, u8, void *); -extern bool8 sub_80A212C(u8, u8, u8); -extern void RemoveFieldObjectByLocalIdAndMap(u8, u8, u8); -extern u8 show_sprite(u8, u8, u8); -extern void sub_805C0F8(u8, u8, u8, s16, s16); -extern void update_saveblock1_field_object_coords(u8, s16, s16); -extern void sub_805C78C(u8, u8, u8); -extern void npc_by_local_id_and_map_set_field_1_bit_x20(u8, u8, u8, u8); -extern void sub_805BCF0(u8, u8, u8, u8); -extern void sub_805BD48(u8, u8, u8); -extern u8 player_get_direction_lower_nybble(void); -extern u8 FieldObjectFaceOppositeDirection(void *, u8); -extern void FieldObjectTurnByLocalIdAndMap(u8, u8, u8, u8); -extern void update_saveblock1_field_object_movement_behavior(u8, u8); -extern u8 sub_805B410(u8, u8, s16, s16, u8, u8); -extern void sub_8064990(u8, u8); -extern bool32 is_c1_link_related_active(void); -extern void sub_8064D20(void); -extern bool8 sub_8064CFC(void); -extern void sub_8064DD8(void); -extern bool8 sub_8064DB4(void); -extern u8 GetFieldObjectIdByLocalIdAndMap(u8, u8, u8); -extern u8 FieldObjectClearAnimIfSpecialAnimFinished(void *); -extern void sub_80A2178(void); -extern void sub_806451C(void); -extern bool8 yes_no_box(u8, u8); -extern bool8 sub_80B5054(u8, u8, u8, u8); -extern bool8 sub_80B50B0(u8, u8, u8, u8, u8); -extern bool8 sub_80B5578(u8, u8, u8, u8, u8); -extern bool8 Multichoice(u8, u8, u8, u8); -extern bool8 sub_80B58C4(u16, u8, u8); -extern void *picbox_close(void); -extern void sub_8106630(u32); -extern void ShowContestWinner(void); -extern u8 GetLeadMonIndex(void); -extern void CopyItemName(u16, u8 *); -extern u8 sub_80BF0B8(u32); -extern void sub_80B79B8(u32 *, u32); -extern void sub_80B79E0(u32 *, u32); -extern bool8 IsEnoughMoney(u32, u32); -extern void sub_80B7C14(u32, u8, u8); -extern void RemoveMoneyLabelObject(u8, u8); -extern void sub_80B7BEC(u32, u8, u8); -extern void ShowCoinsWindow(u32, u8, u8); -extern void HideCoinsWindow(u8, u8); -extern void UpdateCoinsWindow(u32, u8, u8); -extern void *TrainerBattleConfigure(u8 *); -extern void sub_80825E4(void); -extern u8 *sub_80826E8(void); -extern u8 *sub_8082700(void); -extern u8 trainer_flag_check(u16); -extern void trainer_flag_set(u16); -extern void trainer_flag_clear(u16); -extern void ScriptWildBattle(u16, u8, u16); -extern void sub_8081B3C(void); -extern void CreatePokemartMenu(void *); -extern void CreateDecorationShop1Menu(void *); -extern void CreateDecorationShop2Menu(void *); -extern void PlaySlotMachine(u8, void *); -extern void PlantBerryTree(u8, u8, u8, bool8); -extern bool8 GetPriceReduction(u8); -extern void sub_80F99CC(void); -extern void sub_80C48C8(void); -extern void sub_80C4940(void); -extern void sub_80C4980(u8); -extern u32 FieldEffectStart(u8); -extern bool8 FieldEffectActiveListContains(u8); -extern void sub_8053588(u8); -extern void MapGridSetMetatileIdAt(u32, u32, u16); -extern u16 sub_8058790(u32, u32); -extern bool8 FieldAnimateDoorOpen(u32, u32); -extern bool8 FieldAnimateDoorClose(u32, u32); -extern bool8 FieldIsDoorAnimationRunning(void); -extern void FieldSetDoorOpened(u32, u32); -extern void FieldSetDoorClosed(u32, u32); -extern void ScriptAddElevatorMenuItem(u8, u8, u8, u8); -extern void ScriptShowElevatorMenu(void); -extern u16 GetCoins(void); -extern bool8 GiveCoins(u16); -extern bool8 TakeCoins(u16); -extern u8 ScriptGiveMon(u16, u8, u16, u32, u32, u8); -extern u8 ScriptGiveEgg(u16); -extern void ScriptSetMonMoveSlot(u8, u16, u8); -extern bool8 pokemon_has_move(struct Pokemon *, u16); -extern void c2_exit_to_overworld_1_continue_scripts_restart_music(void); +#include "event_data.h" +#include "rom4.h" +#include "weather.h" +#include "map_obj_lock.h" +#include "coins.h" +#include "field_effect.h" typedef u16 (*SpecialFunc)(void); typedef void (*NativeFunc)(void); @@ -170,11 +55,31 @@ extern u8 *gStdScripts_End[]; extern u8 gSpeciesNames[][11]; extern u8 gMoveNames[][13]; -extern u8 gScriptConditionTable[6][3]; -extern u8 * const gUnknown_083762F0[]; extern u8 * const gUnknown_083CE048[]; extern struct Decoration gDecorations[]; +// This is defined in here so the optimizer can't see its value when compiling +// script.c. +void * const gNullScriptPtr = NULL; + +static const u8 sScriptConditionTable[6][3] = +{ +// < = > + 1, 0, 0, // < + 0, 1, 0, // = + 0, 0, 1, // > + 1, 1, 0, // <= + 0, 1, 1, // >= + 1, 0, 1, // != +}; + +static u8 * const sScriptStringVars[] = +{ + gStringVar1, + gStringVar2, + gStringVar3, +}; + bool8 ScrCmd_snop(struct ScriptContext *ctx) { return FALSE; @@ -250,7 +155,7 @@ bool8 ScrCmd_jumpif(struct ScriptContext *ctx) { u8 condition = ScriptReadByte(ctx); u8 *ptr = (u8 *)ScriptReadWord(ctx); - if (gScriptConditionTable[condition][ctx->comparisonResult] == 1) + if (sScriptConditionTable[condition][ctx->comparisonResult] == 1) ScriptJump(ctx, ptr); return FALSE; } @@ -259,7 +164,7 @@ bool8 ScrCmd_callif(struct ScriptContext *ctx) { u8 condition = ScriptReadByte(ctx); u8 *ptr = (u8 *)ScriptReadWord(ctx); - if (gScriptConditionTable[condition][ctx->comparisonResult] == 1) + if (sScriptConditionTable[condition][ctx->comparisonResult] == 1) ScriptCall(ctx, ptr); return FALSE; } @@ -290,7 +195,7 @@ bool8 ScrCmd_if5(struct ScriptContext *ctx) { u8 condition = ScriptReadByte(ctx); u8 *ptr = (u8 *)(ScriptReadWord(ctx) - gUnknown_0202E8B0); - if (gScriptConditionTable[condition][ctx->comparisonResult] == 1) + if (sScriptConditionTable[condition][ctx->comparisonResult] == 1) ScriptJump(ctx, ptr); return FALSE; } @@ -299,7 +204,7 @@ bool8 ScrCmd_if6(struct ScriptContext *ctx) { u8 condition = ScriptReadByte(ctx); u8 *ptr = (u8 *)(ScriptReadWord(ctx) - gUnknown_0202E8B0); - if (gScriptConditionTable[condition][ctx->comparisonResult] == 1) + if (sScriptConditionTable[condition][ctx->comparisonResult] == 1) ScriptCall(ctx, ptr); return FALSE; } @@ -326,7 +231,7 @@ bool8 ScrCmd_jumpstdif(struct ScriptContext *ctx) { u8 condition = ScriptReadByte(ctx); u8 index = ScriptReadByte(ctx); - if (gScriptConditionTable[condition][ctx->comparisonResult] == 1) + if (sScriptConditionTable[condition][ctx->comparisonResult] == 1) { u8 **ptr = &gStdScripts[index]; if (ptr < gStdScripts_End) @@ -339,7 +244,7 @@ bool8 ScrCmd_callstdif(struct ScriptContext *ctx) { u8 condition = ScriptReadByte(ctx); u8 index = ScriptReadByte(ctx); - if (gScriptConditionTable[condition][ctx->comparisonResult] == 1) + if (sScriptConditionTable[condition][ctx->comparisonResult] == 1) { u8 **ptr = &gStdScripts[index]; if (ptr < gStdScripts_End) @@ -638,7 +543,7 @@ bool8 ScrCmd_checkflag(struct ScriptContext *ctx) bool8 ScrCmd_inccounter(struct ScriptContext *ctx) { - sav12_xor_increment(ScriptReadByte(ctx)); + IncrementGameStat(ScriptReadByte(ctx)); return FALSE; } @@ -673,9 +578,9 @@ bool8 ScrCmd_fadescreen(struct ScriptContext *ctx) bool8 ScrCmd_fadescreendelay(struct ScriptContext *ctx) { - u8 val1 = ScriptReadByte(ctx); - u8 val2 = ScriptReadByte(ctx); - fade_screen(val1, val2); + u8 duration = ScriptReadByte(ctx); + u8 delay = ScriptReadByte(ctx); + fade_screen(duration, delay); SetupNativeScript(ctx, sub_8066248); return TRUE; } @@ -735,13 +640,13 @@ bool8 ScrCmd_resetweather(struct ScriptContext *ctx) bool8 ScrCmd_doweather(struct ScriptContext *ctx) { - sub_808073C(); + DoCurrentWeather(); return FALSE; } bool8 ScrCmd_tileeffect(struct ScriptContext *ctx) { - activate_per_step_callback(ScriptReadByte(ctx)); + ActivatePerStepCallback(ScriptReadByte(ctx)); return FALSE; } @@ -1180,7 +1085,7 @@ bool8 ScrCmd_lockall(struct ScriptContext *ctx) } else { - sub_8064D20(); + ScriptFreezeMapObjects(); SetupNativeScript(ctx, sub_8064CFC); return TRUE; } @@ -1201,7 +1106,7 @@ bool8 ScrCmd_lock(struct ScriptContext *ctx) } else { - sub_8064D20(); + ScriptFreezeMapObjects(); SetupNativeScript(ctx, sub_8064CFC); } @@ -1217,7 +1122,7 @@ bool8 ScrCmd_releaseall(struct ScriptContext *ctx) objectId = GetFieldObjectIdByLocalIdAndMap(0xFF, 0, 0); FieldObjectClearAnimIfSpecialAnimFinished(&gMapObjects[objectId]); sub_80A2178(); - sub_806451C(); + UnfreezeMapObjects(); return FALSE; } @@ -1231,7 +1136,7 @@ bool8 ScrCmd_release(struct ScriptContext *ctx) objectId = GetFieldObjectIdByLocalIdAndMap(0xFF, 0, 0); FieldObjectClearAnimIfSpecialAnimFinished(&gMapObjects[objectId]); sub_80A2178(); - sub_806451C(); + UnfreezeMapObjects(); return FALSE; } @@ -1440,14 +1345,14 @@ bool8 ScrCmd_bufferpoke(struct ScriptContext *ctx) { u8 stringVarIndex = ScriptReadByte(ctx); u16 species = VarGet(ScriptReadHalfword(ctx)); - StringCopy(gUnknown_083762F0[stringVarIndex], gSpeciesNames[species]); + StringCopy(sScriptStringVars[stringVarIndex], gSpeciesNames[species]); return FALSE; } bool8 ScrCmd_bufferfirstpoke(struct ScriptContext *ctx) { u8 stringVarIndex = ScriptReadByte(ctx); - u8 *dest = gUnknown_083762F0[stringVarIndex]; + u8 *dest = sScriptStringVars[stringVarIndex]; u8 partyIndex = GetLeadMonIndex(); u32 species = GetMonData(&gPlayerParty[partyIndex], MON_DATA_SPECIES, NULL); StringCopy(dest, gSpeciesNames[species]); @@ -1458,8 +1363,8 @@ bool8 ScrCmd_bufferpartypoke(struct ScriptContext *ctx) { u8 stringVarIndex = ScriptReadByte(ctx); u16 partyIndex = VarGet(ScriptReadHalfword(ctx)); - GetMonData(&gPlayerParty[partyIndex], MON_DATA_NICKNAME, gUnknown_083762F0[stringVarIndex]); - StringGetEnd10(gUnknown_083762F0[stringVarIndex]); + GetMonData(&gPlayerParty[partyIndex], MON_DATA_NICKNAME, sScriptStringVars[stringVarIndex]); + StringGetEnd10(sScriptStringVars[stringVarIndex]); return FALSE; } @@ -1467,7 +1372,7 @@ bool8 ScrCmd_bufferitem(struct ScriptContext *ctx) { u8 stringVarIndex = ScriptReadByte(ctx); u16 itemId = VarGet(ScriptReadHalfword(ctx)); - CopyItemName(itemId, gUnknown_083762F0[stringVarIndex]); + CopyItemName(itemId, sScriptStringVars[stringVarIndex]); return FALSE; } @@ -1475,7 +1380,7 @@ bool8 ScrCmd_bufferdecor(struct ScriptContext *ctx) { u8 stringVarIndex = ScriptReadByte(ctx); u16 decorId = VarGet(ScriptReadHalfword(ctx)); - StringCopy(gUnknown_083762F0[stringVarIndex], gDecorations[decorId].name); + StringCopy(sScriptStringVars[stringVarIndex], gDecorations[decorId].name); return FALSE; } @@ -1483,7 +1388,7 @@ bool8 ScrCmd_bufferattack(struct ScriptContext *ctx) { u8 stringVarIndex = ScriptReadByte(ctx); u16 moveId = VarGet(ScriptReadHalfword(ctx)); - StringCopy(gUnknown_083762F0[stringVarIndex], gMoveNames[moveId]); + StringCopy(sScriptStringVars[stringVarIndex], gMoveNames[moveId]); return FALSE; } @@ -1492,7 +1397,7 @@ bool8 ScrCmd_buffernum(struct ScriptContext *ctx) u8 stringVarIndex = ScriptReadByte(ctx); u16 v1 = VarGet(ScriptReadHalfword(ctx)); u8 v2 = sub_80BF0B8(v1); - ConvertIntToDecimalStringN(gUnknown_083762F0[stringVarIndex], v1, 0, v2); + ConvertIntToDecimalStringN(sScriptStringVars[stringVarIndex], v1, 0, v2); return FALSE; } @@ -1500,7 +1405,7 @@ bool8 ScrCmd_bufferstd(struct ScriptContext *ctx) { u8 stringVarIndex = ScriptReadByte(ctx); u16 index = VarGet(ScriptReadHalfword(ctx)); - StringCopy(gUnknown_083762F0[stringVarIndex], gUnknown_083CE048[index]); + StringCopy(sScriptStringVars[stringVarIndex], gUnknown_083CE048[index]); return FALSE; } @@ -1508,7 +1413,7 @@ bool8 ScrCmd_buffertext(struct ScriptContext *ctx) { u8 stringVarIndex = ScriptReadByte(ctx); u8 *text = (u8 *)ScriptReadWord(ctx); - StringCopy(gUnknown_083762F0[stringVarIndex], text); + StringCopy(sScriptStringVars[stringVarIndex], text); return FALSE; } @@ -1524,7 +1429,7 @@ bool8 ScrCmd_vbuffer(struct ScriptContext *ctx) u8 stringVarIndex = ScriptReadByte(ctx); u32 addr = ScriptReadWord(ctx); u8 *src = (u8 *)(addr - gUnknown_0202E8B0); - u8 *dest = gUnknown_083762F0[stringVarIndex]; + u8 *dest = sScriptStringVars[stringVarIndex]; StringCopy(dest, src); return FALSE; } @@ -1713,7 +1618,7 @@ bool8 ScrCmd_setwildbattle(struct ScriptContext *ctx) bool8 ScrCmd_dowildbattle(struct ScriptContext *ctx) { - sub_8081B3C(); + StartBattle_ScriptedWild(); ScriptContext1_Stop(); return TRUE; } @@ -1812,7 +1717,7 @@ bool8 ScrCmd_setanimation(struct ScriptContext *ctx) return FALSE; } -bool8 sub_8067B48() +static bool8 sub_8067B48() { if (!FieldEffectActiveListContains(gUnknown_0202E8BC)) return TRUE; @@ -1890,7 +1795,7 @@ bool8 ScrCmd_setdoorclosed(struct ScriptContext *ctx) return FALSE; } -bool8 IsDoorAnimationStopped() +static bool8 IsDoorAnimationStopped() { if (!FieldIsDoorAnimationRunning()) return TRUE; @@ -1950,8 +1855,8 @@ bool8 ScrCmd_checkcoins(struct ScriptContext *ctx) bool8 ScrCmd_givecoins(struct ScriptContext *ctx) { - u16 v2 = VarGet(ScriptReadHalfword(ctx)); - if (GiveCoins(v2) == TRUE) + u16 coins = VarGet(ScriptReadHalfword(ctx)); + if (GiveCoins(coins) == TRUE) gScriptResult = 0; else gScriptResult = 1; @@ -1961,8 +1866,8 @@ bool8 ScrCmd_givecoins(struct ScriptContext *ctx) bool8 ScrCmd_removecoins(struct ScriptContext *ctx) { - u16 v2 = VarGet(ScriptReadHalfword(ctx)); - if (TakeCoins(v2) == TRUE) + u16 coins = VarGet(ScriptReadHalfword(ctx)); + if (TakeCoins(coins) == TRUE) gScriptResult = 0; else gScriptResult = 1; diff --git a/src/script.c b/src/script.c index 8e07a580e..7a9c8e102 100644 --- a/src/script.c +++ b/src/script.c @@ -1,7 +1,7 @@ #include "global.h" #include "script.h" -#include "fieldmap.h" -#include "var.h" +#include "asm_fieldmap.h" +#include "event_data.h" #define RAM_SCRIPT_MAGIC 51 @@ -15,7 +15,7 @@ static bool8 sScriptContext2Enabled; extern ScrCmdFunc gScriptCmdTable[]; extern ScrCmdFunc gScriptCmdTableEnd[]; -extern void *gUnknown_083762D8; +extern void *gNullScriptPtr; void InitScriptContext(struct ScriptContext *ctx, void *cmdTable, void *cmdTableEnd) { @@ -83,7 +83,7 @@ u8 RunScript(struct ScriptContext *ctx) return 0; } - if (ctx->scriptPtr == gUnknown_083762D8) + if (ctx->scriptPtr == gNullScriptPtr) { while (1) asm("svc 2"); // HALT diff --git a/src/script_menu.c b/src/script_menu.c new file mode 100644 index 000000000..c4f0b5292 --- /dev/null +++ b/src/script_menu.c @@ -0,0 +1,431 @@ +#include "global.h" +#include "task.h" +#include "menu.h" +#include "palette.h" +#include "script.h" +#include "sound.h" +#include "event_data.h" +#include "sprite.h" + +struct MultichoiceListStruct +{ + struct MenuAction *list; + u8 count; +}; + +extern const struct MultichoiceListStruct gMultichoiceLists[]; + +extern u16 gScriptResult; + +extern void FreeResourcesAndDestroySprite(struct Sprite *sprite); +extern u8 CreateMonSprite_PicBox(u16, s16, s16, u8); +extern u8 sub_80B59AC(void); + +extern u8 gPCText_PlayersPC[]; +extern u8 gPCText_SomeonesPC[]; +extern u8 gPCText_HallOfFame[]; +extern u8 gPCText_LogOff[]; +extern u8 gPCText_LanettesPC[]; +extern u8 gPCText_WhichPCShouldBeAccessed[]; + +void DrawMultichoiceMenu(u8, u8, u8, struct MenuAction *list, u8, u8); +void sub_80B53B4(u8, u8, u8, struct MenuAction *list, u8); +void sub_80B52B4(u8); +void sub_80B5230(u8, u8, u8, u8, u8, u8); +void task_yes_no_maybe(u8); +void sub_80B5684(u8); +void CreatePCMenu(void); + +bool8 sub_80B5054(u8 left, u8 top, u8 var3, u8 var4) +{ + if(FuncIsActiveTask(sub_80B52B4) == 1) + return FALSE; + else + { + gScriptResult = 0xFF; + DrawMultichoiceMenu(left, top, gMultichoiceLists[var3].count, gMultichoiceLists[var3].list, var4, 0); + return TRUE; + } +} + +bool8 sub_80B50B0(u8 left, u8 top, u8 var3, u8 var4, u8 var5) +{ + if(FuncIsActiveTask(sub_80B52B4) == 1) + return FALSE; + else + { + gScriptResult = 0xFF; + DrawMultichoiceMenu(left, top, gMultichoiceLists[var3].count, gMultichoiceLists[var3].list, var4, var5); + return TRUE; + } +} + +u16 GetStringWidthInTilesForScriptMenu(u8 *str) +{ + // each tile on screen is 8x8, so it needs the number of tiles and not pixels, hence the division by 8. + return (GetStringWidthGivenWindowConfig((struct WindowConfig *)&gWindowConfig_81E6CE4, str) + 7) / 8; +} + +void DrawMultichoiceMenu(u8 left, u8 top, u8 count, struct MenuAction *list, u8 var4, u8 cursorPos) +{ + u16 width = GetStringWidthInTilesForScriptMenu(list[0].text); + u16 newWidth; + u8 i; + u8 right; + u8 bottom; + + for(i = 1; i < count; i++) + { + newWidth = GetStringWidthInTilesForScriptMenu(list[i].text); + if(width < newWidth) + width = newWidth; + } + + right = width; + right = (right + left) + 1; + + if(right > 29) + { + left = left + (29 - right); + right = 29; + } + + bottom = top + (2 * count + 1); + + MenuDrawTextWindow(left, top, right, bottom); + PrintMenuItems(left + 1, top + 1, count, list); + InitMenu(0, left + 1, top + 1, count, cursorPos, right - left - 1); + sub_80B5230(left, top, right, bottom, var4, count); +} + +void sub_80B5230(u8 left, u8 top, u8 right, u8 bottom, u8 unkVar, u8 count) +{ + u8 taskId = CreateTask(sub_80B52B4, 80); + + gTasks[taskId].data[0] = left; + gTasks[taskId].data[1] = top; + gTasks[taskId].data[2] = right; + gTasks[taskId].data[3] = bottom; + gTasks[taskId].data[4] = unkVar; + + if(count > 3) + gTasks[taskId].data[5] = TRUE; + else + gTasks[taskId].data[5] = FALSE; +} + +void sub_80B52B4(u8 taskId) +{ + s8 var; + + if(!gPaletteFade.active) + { + if(!gTasks[taskId].data[5]) + var = ProcessMenuInputNoWrap(); + else + var = ProcessMenuInput(); + + if(var != -2) + { + if(var == -1) + { + if(!gTasks[taskId].data[4]) + { + PlaySE(5); + gScriptResult = 127; + } + else + { + return; + } + } + else + { + gScriptResult = var; + } + sub_8072DEC(); + MenuZeroFillWindowRect(gTasks[taskId].data[0], gTasks[taskId].data[1], gTasks[taskId].data[2], gTasks[taskId].data[3]); + DestroyTask(taskId); + EnableBothScriptContexts(); + } + } +} + +bool8 Multichoice(u8 var1, u8 var2, u8 var3, u8 var4) +{ + if(FuncIsActiveTask(sub_80B52B4) == 1) + return FALSE; + else + { + gScriptResult = 0xFF; + sub_80B53B4(var1, var2, gMultichoiceLists[var3].count, gMultichoiceLists[var3].list, var4); + return TRUE; + } +} + +void sub_80B53B4(u8 left, u8 top, u8 count, struct MenuAction *list, u8 var4) +{ + u16 width = GetStringWidthInTilesForScriptMenu(list[0].text); + u16 newWidth; + u8 i; + u8 right; + u8 bottom; + + for(i = 1; i < count; i++) + { + newWidth = GetStringWidthInTilesForScriptMenu(list[i].text); + if(width < newWidth) + width = newWidth; + } + + right = width; + right = (right + left) + 2; + bottom = top + (2 * count + 1); + + PrintMenuItems(left, top, count, list); + InitMenu(0, left, top, count, 0, right - left - 1); + sub_80B5230(left, top, right, bottom, var4, count); +} + +bool8 yes_no_box(u8 var1, u8 var2) +{ + u8 taskId; + + if(FuncIsActiveTask(task_yes_no_maybe) == 1) + return FALSE; + else + { + gScriptResult = 0xFF; + DisplayYesNoMenu(var1, var2, 1); + taskId = CreateTask(task_yes_no_maybe, 0x50); + gTasks[taskId].data[0] = var1; + gTasks[taskId].data[1] = var2; + return TRUE; + } +} + +// unused +bool8 IsScriptActive(void) +{ + if(gScriptResult == 0xFF) + return FALSE; + else + return TRUE; +} + +void task_yes_no_maybe(u8 taskId) +{ + u8 left, top; + + if (gTasks[taskId].data[2] < 5) + { + gTasks[taskId].data[2]++; + return; + } + + switch (ProcessMenuInputNoWrap()) + { + case -2: + return; + case -1: + case 1: + PlaySE(5); + gScriptResult = 0; + break; + case 0: + gScriptResult = 1; + break; + } + + left = gTasks[taskId].data[0]; + top = gTasks[taskId].data[1]; + + MenuZeroFillWindowRect(left, top, left + 6, top + 5); + DestroyTask(taskId); + EnableBothScriptContexts(); +} + +bool8 sub_80B5578(u8 left, u8 top, u8 multichoiceId, u8 a4, u8 columnCount) +{ + u8 bottom = 0; + + if (FuncIsActiveTask(sub_80B5684) == TRUE) + { + return FALSE; + } + else + { + u8 taskId; + u8 width; + + gScriptResult = 0xFF; + + sub_807274C(left, top, gMultichoiceLists[multichoiceId].count, 0, gMultichoiceLists[multichoiceId].list, columnCount, 0); + + taskId = CreateTask(sub_80B5684, 80); + + if (!((gMultichoiceLists[multichoiceId].count >> 1) < columnCount || (gMultichoiceLists[multichoiceId].count & 1)) + || columnCount == 1 || gMultichoiceLists[multichoiceId].count == columnCount) + { + bottom = (2 * (gMultichoiceLists[multichoiceId].count / columnCount)) + 1 + top; + } + else + { + bottom = (2 * (gMultichoiceLists[multichoiceId].count / columnCount)) + 3 + top; + } + + width = sub_807288C(columnCount); + gTasks[taskId].data[0] = left; + gTasks[taskId].data[1] = top; + gTasks[taskId].data[2] = width + left + 2; + gTasks[taskId].data[3] = bottom; + gTasks[taskId].data[4] = a4; + return TRUE; + } +} + +void sub_80B5684(u8 taskId) +{ + s8 var = sub_80727CC(); + + if (var != -2) + { + if (var == -1) + { + if (!gTasks[taskId].data[4]) + { + PlaySE(5); + gScriptResult = 127; + } + else + { + return; + } + } + else + { + gScriptResult = var; + } + sub_8072DEC(); + MenuZeroFillWindowRect(gTasks[taskId].data[0], gTasks[taskId].data[1], gTasks[taskId].data[2], gTasks[taskId].data[3]); + DestroyTask(taskId); + EnableBothScriptContexts(); + } +} + +bool8 TryCreatePCMenu(void) +{ + if(FuncIsActiveTask(sub_80B52B4) == 1) + return FALSE; + else + { + gScriptResult = 0xFF; + CreatePCMenu(); + return TRUE; + } +} + +void CreatePCMenu(void) +{ + u16 playersPCWidth = GetStringWidthInTilesForScriptMenu(gPCText_PlayersPC); + u8 width; + u8 numChoices; + + if(playersPCWidth > GetStringWidthInTilesForScriptMenu(gPCText_SomeonesPC)) + width = playersPCWidth; + else + width = 8; + + if(FlagGet(SYS_GAME_CLEAR)) // player has cleared game? + { + numChoices = 4; + MenuDrawTextWindow(0, 0, width + 2, 9); + MenuPrint(gPCText_HallOfFame, 1, 5); + MenuPrint(gPCText_LogOff, 1, 7); + } + else + { + numChoices = 3; + MenuDrawTextWindow(0, 0, width + 2, 7); + MenuPrint(gPCText_LogOff, 1, 5); + } + + if(FlagGet(SYS_PC_LANETTE)) // player met lanette? + MenuPrint(gPCText_LanettesPC, 1, 1); + else + MenuPrint(gPCText_SomeonesPC, 1, 1); + + MenuPrint(gPCText_PlayersPC, 1, 3); + InitMenu(0, 1, 1, numChoices, 0, width + 1); + sub_80B5230(0, 0, width + 2, 2 * numChoices + 1, 0, numChoices); +} + +void sub_80B5838(void) +{ + MenuDisplayMessageBox(); + MenuPrint(gPCText_WhichPCShouldBeAccessed, 2, 15); +} + +void task_picbox(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + + switch(task->data[0]) + { + case 0: + task->data[0]++; + break; + case 1: + break; + case 2: + FreeResourcesAndDestroySprite(&gSprites[task->data[2]]); + task->data[0]++; + break; + case 3: + MenuZeroFillWindowRect(task->data[3], task->data[4], task->data[3] + 9, task->data[4] + 10); + DestroyTask(taskId); + break; + } +} + +bool8 sub_80B58C4(u16 var1, u8 var2, u8 var3) +{ + u8 taskId; + u8 var; + + if(FindTaskIdByFunc(task_picbox) != 0xFF) + return FALSE; + else + { + MenuDrawTextWindow(var2, var3, var2 + 9, var3 + 10); + taskId = CreateTask(task_picbox, 0x50); + gTasks[taskId].data[0] = 0; + gTasks[taskId].data[1] = var1; + var = CreateMonSprite_PicBox(var1, var2 * 8 + 40, var3 * 8 + 40, 0); + gTasks[taskId].data[2] = var; + gTasks[taskId].data[3] = var2; + gTasks[taskId].data[4] = var3; + gSprites[var].callback = SpriteCallbackDummy; + gSprites[var].oam.priority = 0; + return TRUE; + } +} + +void *picbox_close(void) +{ + u8 taskId = FindTaskIdByFunc(task_picbox); + + if(taskId == 0xFF) + return NULL; + + gTasks[taskId].data[0]++; + return (void *)sub_80B59AC; +} + +bool8 sub_80B59AC(void) +{ + if(FindTaskIdByFunc(task_picbox) == 0xFF) + return TRUE; + else + return FALSE; +} diff --git a/src/sound.c b/src/sound.c index 49ab78cc7..c244c5cbe 100644 --- a/src/sound.c +++ b/src/sound.c @@ -1,8 +1,11 @@ #include "global.h" +#include "sound.h" +#include "asm.h" #include "gba/m4a_internal.h" #include "task.h" -#include "sound.h" #include "songs.h" +#include "m4a.h" +#include "battle.h" struct Fanfare { @@ -10,9 +13,10 @@ struct Fanfare u16 duration; }; -extern u32 SpeciesToCryId(u32); +// Hack: different prototype than definition +u32 SpeciesToCryId(u32); -extern u16 gUnknown_020239F8; +extern u16 gBattleTypeFlags; extern struct MusicPlayerInfo *gMPlay_PokemonCry; extern u8 gPokemonCryBGMDuckingCounter; @@ -28,8 +32,6 @@ extern struct MusicPlayerInfo gMPlay_SE1; extern struct MusicPlayerInfo gMPlay_SE2; extern struct MusicPlayerInfo gMPlay_SE3; -extern struct Fanfare gFanfares[]; - extern struct ToneData voicegroup_8452590[]; extern struct ToneData voicegroup_8452B90[]; extern struct ToneData voicegroup_8453190[]; @@ -40,6 +42,22 @@ extern struct ToneData voicegroup_8453DC0[]; extern struct ToneData voicegroup_84543C0[]; extern struct ToneData voicegroup_84549C0[]; +static const struct Fanfare sFanfares[] = +{ + { BGM_FANFA1, 80 }, + { BGM_FANFA4, 160 }, + { BGM_FANFA5, 220 }, + { BGM_ME_WAZA, 220 }, + { BGM_ME_ASA, 160 }, + { BGM_ME_BACHI, 340 }, + { BGM_ME_WASURE, 180 }, + { BGM_ME_KINOMI, 120 }, + { BGM_ME_TAMA, 710 }, + { BGM_ME_B_BIG, 250 }, + { BGM_ME_B_SMALL, 150 }, + { BGM_ME_ZANNEN, 160 }, +}; + static void Task_Fanfare(u8 taskId); static void CreateFanfareTask(void); static void PlayCryInternal(u16 species, s8 pan, s8 volume, u8 priority, u8 mode); @@ -170,14 +188,10 @@ bool8 IsNotWaitingForBGMStop(void) void PlayFanfareByFanfareNum(u8 fanfareNum) { - struct Fanfare *fanfares; - struct Fanfare *fanfare; u16 songNum; m4aMPlayStop(&gMPlay_BGM); - fanfares = gFanfares; - fanfare = &fanfares[fanfareNum]; - songNum = fanfare->songNum; - sFanfareCounter = fanfare->duration; + songNum = sFanfares[fanfareNum].songNum; + sFanfareCounter = sFanfares[fanfareNum].duration; m4aSongNumStart(songNum); } @@ -201,7 +215,7 @@ bool8 WaitFanfare(bool8 stop) void StopFanfareByFanfareNum(u8 fanfareNum) { - m4aSongNumStop(gFanfares[fanfareNum].songNum); + m4aSongNumStop(sFanfares[fanfareNum].songNum); } void PlayFanfare(u16 songNum) @@ -209,8 +223,7 @@ void PlayFanfare(u16 songNum) s32 i; for (i = 0; (u32)i < 12; i++) { - struct Fanfare *fanfare = &gFanfares[i]; - if (fanfare->songNum == songNum) + if (sFanfares[i].songNum == songNum) { PlayFanfareByFanfareNum(i); CreateFanfareTask(); @@ -326,7 +339,7 @@ void PlayCry4(u16 species, s8 pan, u8 mode) } else { - if (!(gUnknown_020239F8 & 0x40)) + if (!(gBattleTypeFlags & BATTLE_TYPE_40)) m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 85); PlayCryInternal(species, pan, 125, 10, mode); } diff --git a/src/sprite.c b/src/sprite.c index 12c62145e..df101b61f 100644 --- a/src/sprite.c +++ b/src/sprite.c @@ -1,6 +1,8 @@ #include "global.h" -#include "main.h" #include "sprite.h" +#include "main.h" +#include "palette.h" +#include "menu_cursor.h" #define MAX_SPRITE_COPY_REQUESTS 64 @@ -8,12 +10,8 @@ #define SET_SPRITE_TILE_RANGE(index, start, count) \ { \ - u16 *rangeStarts; \ - u16 *rangeCounts; \ - rangeStarts = sSpriteTileRanges; \ - rangeStarts[index * 2] = start; \ - rangeCounts = sSpriteTileRanges + 1; \ - rangeCounts[index * 2] = count; \ + sSpriteTileRanges[index * 2] = start; \ + (sSpriteTileRanges + 1)[index * 2] = count; \ } #define ALLOC_SPRITE_TILE(n) \ @@ -49,23 +47,18 @@ struct OamDimensions s8 height; }; -void LoadPalette(u16 *, u16, u32); -void sub_814A590(void); - static void UpdateOamCoords(void); static void BuildSpritePriorities(void); static void SortSprites(void); static void CopyMatricesToOamBuffer(void); static void AddSpritesToOamBuffer(void); -static u8 CreateSpriteAt(u8 index, struct SpriteTemplate *template, s16 x, s16 y, u8 subpriority); +static u8 CreateSpriteAt(u8 index, const struct SpriteTemplate *template, s16 x, s16 y, u8 subpriority); static void ClearSpriteCopyRequests(void); static void ResetOamMatrices(void); static void ResetSprite(struct Sprite *sprite); static s16 AllocSpriteTiles(u16 tileCount); -static u8 SpriteTileAllocBitmapOp(u16 bit, u8 op); +u8 SpriteTileAllocBitmapOp(u16 bit, u8 op); static void RequestSpriteFrameImageCopy(u16 index, u16 tileNum, struct SpriteFrameImage *images); -static void CopyFromSprites(u8 *dest); -static void CopyToSprites(u8 *src); static void ResetAllSprites(void); static void BeginAnim(struct Sprite *sprite); static void ContinueAnim(struct Sprite *sprite); @@ -530,7 +523,7 @@ static void AddSpritesToOamBuffer(void) } } -u8 CreateSprite(struct SpriteTemplate *template, s16 x, s16 y, u8 subpriority) +u8 CreateSprite(const struct SpriteTemplate *template, s16 x, s16 y, u8 subpriority) { u8 i; @@ -541,7 +534,7 @@ u8 CreateSprite(struct SpriteTemplate *template, s16 x, s16 y, u8 subpriority) return MAX_SPRITES; } -u8 CreateSpriteAtEnd(struct SpriteTemplate *template, u16 x, u16 y, u8 subpriority) +u8 CreateSpriteAtEnd(const struct SpriteTemplate *template, u16 x, u16 y, u8 subpriority) { s16 i; @@ -554,7 +547,7 @@ u8 CreateSpriteAtEnd(struct SpriteTemplate *template, u16 x, u16 y, u8 subpriori u8 CreateInvisibleSprite(void (*callback)(struct Sprite *)) { - u8 index = CreateSprite((struct SpriteTemplate *)&gDummySpriteTemplate, 0, 0, 31); + u8 index = CreateSprite(&gDummySpriteTemplate, 0, 0, 31); if (index == MAX_SPRITES) { @@ -568,7 +561,7 @@ u8 CreateInvisibleSprite(void (*callback)(struct Sprite *)) } } -static u8 CreateSpriteAt(u8 index, struct SpriteTemplate *template, s16 x, s16 y, u8 subpriority) +static u8 CreateSpriteAt(u8 index, const struct SpriteTemplate *template, s16 x, s16 y, u8 subpriority) { struct Sprite *sprite = &gSprites[index]; @@ -787,7 +780,7 @@ static s16 AllocSpriteTiles(u16 tileCount) return start; } -static u8 SpriteTileAllocBitmapOp(u16 bit, u8 op) +u8 SpriteTileAllocBitmapOp(u16 bit, u8 op) { u8 index = bit / 8; u8 shift = bit % 8; @@ -856,7 +849,7 @@ void RequestSpriteCopy(u8 *src, u8 *dest, u16 size) } } -static void CopyFromSprites(u8 *dest) +void CopyFromSprites(u8 *dest) { u32 i; u8 *src = (u8 *)gSprites; @@ -868,7 +861,7 @@ static void CopyFromSprites(u8 *dest) } } -static void CopyToSprites(u8 *src) +void CopyToSprites(u8 *src) { u32 i; u8 *dest = (u8 *)gSprites; @@ -1635,7 +1628,7 @@ void FreeAllSpritePalettes(void) sSpritePaletteTags[i] = 0xFFFF; } -u8 LoadSpritePalette(struct SpritePalette *palette) +u8 LoadSpritePalette(const struct SpritePalette *palette) { u8 index = IndexOfSpritePaletteTag(palette->tag); @@ -1656,7 +1649,7 @@ u8 LoadSpritePalette(struct SpritePalette *palette) } } -void LoadSpritePalettes(struct SpritePalette *palettes) +void LoadSpritePalettes(const struct SpritePalette *palettes) { u8 i; for (i = 0; palettes[i].data != NULL; i++) diff --git a/src/start_menu.c b/src/start_menu.c index c8e77af66..31ba31766 100644 --- a/src/start_menu.c +++ b/src/start_menu.c @@ -1,47 +1,27 @@ #include "global.h" +#include "start_menu.h" +#include "asm.h" +#include "field_player_avatar.h" +#include "event_data.h" +#include "load_save.h" #include "main.h" +#include "map_obj_lock.h" #include "menu.h" +#include "option_menu.h" #include "palette.h" +#include "pokedex.h" +#include "rom4.h" +#include "safari_zone.h" +#include "save.h" +#include "save_menu_util.h" #include "script.h" #include "songs.h" #include "sound.h" #include "sprite.h" #include "string_util.h" #include "task.h" -#include "flag.h" - -//External functions -extern void sub_8064E2C(void); -extern void sub_8047A1C(void); -extern u8 sub_8125E6C(void); -extern void sub_8047A34(void); -extern void sub_8125E2C(void); -extern void remove_some_task(void); -extern void dp12_8087EA4(void); -extern void sav12_xor_increment(u8 index); -extern bool8 sub_8125D44(u8); //Saving related -extern void HandleDrawSaveWindowInfo(u8, u8); -extern void sub_80946C8(u8, u8); -extern void save_serialize_map(void); -extern void PlayRainSoundEffect(void); -extern void sub_8093130(u8, void (*)(void)); -extern void sub_805469C(void); -extern void SafariZoneRetirePrompt(void); -extern void CB2_InitOptionMenu(void); -extern void sub_8093110(void (*)(void)); -extern void sub_80EBA5C(void); -extern void sub_80A53F8(void); -extern void sub_8089A70(void); -extern void CB2_InitPokedex(void); -extern u16 GetNationalPokedexCount(u8); -extern void fade_screen(u8, u8); -extern bool32 is_c1_link_related_active(); -extern void sub_80594C0(void); -extern void sub_80597F4(void); -extern void player_bitmagic(void); -extern bool32 GetSafariZoneFlag(void); -extern u8 *sub_8072C44(u8 *, s32, u8, u8); -extern bool32 is_c1_link_related_active(void); +#include "trainer_card.h" +#include "weather.h" //Menu actions enum { @@ -57,11 +37,6 @@ enum { MENU_ACTION_PLAYER_LINK }; -struct MenuItem { - u8 *text; - u8 (*callback)(void); -}; - static u8 (*saveDialogCallback)(void); static u8 saveDialogTimer; //Number of frames to keep the window on screen after save was completed static bool8 savingComplete; @@ -71,7 +46,6 @@ extern u16 gSaveFileStatus; extern u16 gScriptResult; extern u8 (*gCallback_03004AE8)(void); extern u8 gUnknown_03004860; -extern struct MenuItem gStartMenuItems[]; extern u8 gNumSafariBalls; EWRAM_DATA static u8 sStartMenuCursorPos = 0; @@ -87,25 +61,41 @@ extern u8 gSaveText_ThereIsAlreadyAFile[]; extern u8 gSaveText_ThereIsADifferentFile[]; extern u8 gSaveText_WouldYouLikeToSave[]; extern u8 gOtherText_SafariStock[]; - -//Public functions -void CreateStartMenuTask(void (*func)(u8)); -void sub_80712B4(u8 taskId); -void sub_8071310(void); -u8 StartMenu_PokedexCallback(void); -u8 StartMenu_PokemonCallback(void); -u8 StartMenu_BagCallback(void); -u8 StartMenu_PokenavCallback(void); -u8 StartMenu_PlayerCallback(void); -u8 StartMenu_SaveCallback(void); -u8 StartMenu_OptionCallback(void); -u8 StartMenu_ExitCallback(void); -u8 StartMenu_RetireCallback(void); -u8 StartMenu_PlayerLinkCallback(void); -void InitSaveDialog(void); -void sub_8071B28(void); -void sub_8071C20(void); -void AppendToList(u8 *list, u8 *pindex, u32 value); +extern u8 SystemText_Pokedex[]; +extern u8 SystemText_Pokemon[]; +extern u8 SystemText_BAG[]; +extern u8 SystemText_Pokenav[]; +extern u8 SystemText_Player[]; +extern u8 SystemText_Save[]; +extern u8 SystemText_Option[]; +extern u8 SystemText_Exit[]; +extern u8 SystemText_Retire[]; +extern u8 SystemText_Player[]; + +static u8 StartMenu_PokedexCallback(void); +static u8 StartMenu_PokemonCallback(void); +static u8 StartMenu_BagCallback(void); +static u8 StartMenu_PokenavCallback(void); +static u8 StartMenu_PlayerCallback(void); +static u8 StartMenu_SaveCallback(void); +static u8 StartMenu_OptionCallback(void); +static u8 StartMenu_ExitCallback(void); +static u8 StartMenu_RetireCallback(void); +static u8 StartMenu_PlayerLinkCallback(void); + +static const struct MenuAction sStartMenuItems[] = +{ + { SystemText_Pokedex, StartMenu_PokedexCallback }, + { SystemText_Pokemon, StartMenu_PokemonCallback }, + { SystemText_BAG, StartMenu_BagCallback }, + { SystemText_Pokenav, StartMenu_PokenavCallback }, + { SystemText_Player, StartMenu_PlayerCallback }, + { SystemText_Save, StartMenu_SaveCallback }, + { SystemText_Option, StartMenu_OptionCallback }, + { SystemText_Exit, StartMenu_ExitCallback }, + { SystemText_Retire, StartMenu_RetireCallback }, + { SystemText_Player, StartMenu_PlayerLinkCallback }, +}; //Private functions static void BuildStartMenuActions(void); @@ -116,7 +106,6 @@ static void BuildStartMenuActions_Link(void); static void DisplaySafariBallsWindow(void); static bool32 PrintStartMenuItemsMultistep(s16 *a, u32 b); static bool32 InitStartMenuMultistep(s16 *a, s16 *b); -static void sub_8071230(void); static void Task_StartMenu(u8 taskId); static u8 StartMenu_InputProcessCallback(void); static u8 SaveCallback1(void); @@ -220,7 +209,7 @@ static bool32 PrintStartMenuItemsMultistep(s16 *index, u32 n) do { - MenuPrint(gStartMenuItems[sCurrentStartMenuActions[_index]].text, 23, 2 + _index * 2); + MenuPrint(sStartMenuItems[sCurrentStartMenuActions[_index]].text, 23, 2 + _index * 2); _index++; if(_index >= sNumStartMenuActions) { @@ -320,7 +309,7 @@ void sub_8071310(void) { if(!is_c1_link_related_active()) { - player_bitmagic(); + FreezeMapObjects(); sub_80594C0(); sub_80597F4(); } @@ -343,12 +332,12 @@ static u8 StartMenu_InputProcessCallback(void) if(gMain.newKeys & A_BUTTON) { PlaySE(SE_SELECT); - if(gStartMenuItems[sCurrentStartMenuActions[sStartMenuCursorPos]].callback == StartMenu_PokedexCallback) + if(sStartMenuItems[sCurrentStartMenuActions[sStartMenuCursorPos]].func == StartMenu_PokedexCallback) { if(GetNationalPokedexCount(0) == 0) return 0; } - gCallback_03004AE8 = gStartMenuItems[sCurrentStartMenuActions[sStartMenuCursorPos]].callback; + gCallback_03004AE8 = sStartMenuItems[sCurrentStartMenuActions[sStartMenuCursorPos]].func; if(gCallback_03004AE8 != StartMenu_SaveCallback && gCallback_03004AE8 != StartMenu_ExitCallback && gCallback_03004AE8 != StartMenu_RetireCallback) @@ -357,18 +346,18 @@ static u8 StartMenu_InputProcessCallback(void) } if(gMain.newKeys & (START_BUTTON | B_BUTTON)) { - sub_8071C20(); + CloseMenu(); return 1; } return 0; } //When player selects POKEDEX -u8 StartMenu_PokedexCallback(void) +static u8 StartMenu_PokedexCallback(void) { if(!gPaletteFade.active) { - sav12_xor_increment(0x29); + IncrementGameStat(0x29); PlayRainSoundEffect(); SetMainCallback2(CB2_InitPokedex); return 1; @@ -377,7 +366,7 @@ u8 StartMenu_PokedexCallback(void) } //When player selects POKEMON -u8 StartMenu_PokemonCallback(void) +static u8 StartMenu_PokemonCallback(void) { if(!gPaletteFade.active) { @@ -389,7 +378,7 @@ u8 StartMenu_PokemonCallback(void) } //When player selects BAG -u8 StartMenu_BagCallback(void) +static u8 StartMenu_BagCallback(void) { if(!gPaletteFade.active) { @@ -401,7 +390,7 @@ u8 StartMenu_BagCallback(void) } //When player selects POKENAV -u8 StartMenu_PokenavCallback(void) +static u8 StartMenu_PokenavCallback(void) { if(!gPaletteFade.active) { @@ -413,7 +402,7 @@ u8 StartMenu_PokenavCallback(void) } //When player selects his/her name -u8 StartMenu_PlayerCallback(void) +static u8 StartMenu_PlayerCallback(void) { if(!gPaletteFade.active) { @@ -425,7 +414,7 @@ u8 StartMenu_PlayerCallback(void) } //When player selects SAVE -u8 StartMenu_SaveCallback(void) +static u8 StartMenu_SaveCallback(void) { sub_8072DEC(); gCallback_03004AE8 = SaveCallback1; @@ -433,35 +422,35 @@ u8 StartMenu_SaveCallback(void) } //When player selects OPTION -u8 StartMenu_OptionCallback(void) +static u8 StartMenu_OptionCallback(void) { if(!gPaletteFade.active) { PlayRainSoundEffect(); SetMainCallback2(CB2_InitOptionMenu); - gMain.field_8 = sub_805469C; + gMain.savedCallback = sub_805469C; return 1; } return 0; } //When player selects EXIT -u8 StartMenu_ExitCallback(void) +static u8 StartMenu_ExitCallback(void) { - sub_8071C20(); + CloseMenu(); return 1; } //When player selects RETIRE -u8 StartMenu_RetireCallback(void) +static u8 StartMenu_RetireCallback(void) { - sub_8071C20(); + CloseMenu(); SafariZoneRetirePrompt(); return 1; } //When player selects their name in multiplayer mode -u8 StartMenu_PlayerLinkCallback(void) +static u8 StartMenu_PlayerLinkCallback(void) { if(!gPaletteFade.active) { @@ -690,7 +679,7 @@ static u8 SaveDialogCB_DoSave(void) { u8 a; - sav12_xor_increment(0); + IncrementGameStat(0); if(gUnknown_020297EC == TRUE) { a = sub_8125D44(4); @@ -851,14 +840,14 @@ static void Task_8071B64(u8 taskId) (*step)++; break; case 1: - sub_8047A1C(); + SetSecretBase2Field_9_AndHideBG(); sub_8125E2C(); (*step)++; break; case 2: if(!sub_8125E6C()) break; - sub_8047A34(); + ClearSecretBase2Field_9_2(); (*step)++; break; case 3: @@ -866,24 +855,9 @@ static void Task_8071B64(u8 taskId) (*step)++; break; case 4: - SetMainCallback2(gMain.field_8); + SetMainCallback2(gMain.savedCallback); DestroyTask(taskId); break; } } } - -void sub_8071C20(void) -{ - PlaySE(SE_SELECT); - MenuZeroFillScreen(); - sub_8064E2C(); - ScriptContext2_Disable(); - sub_8072DEC(); -} - -void AppendToList(u8 *list, u8 *pindex, u32 value) -{ - list[*pindex] = value; - (*pindex)++; -} diff --git a/src/starter_choose.c b/src/starter_choose.c index a80401e8b..68e644353 100644 --- a/src/starter_choose.c +++ b/src/starter_choose.c @@ -1,22 +1,17 @@ #include "global.h" +#include "starter_choose.h" +#include "asm.h" #include "main.h" #include "menu.h" #include "palette.h" -#include "pokemon.h" +#include "pokedex.h" #include "songs.h" #include "sound.h" -#include "sprite.h" #include "string_util.h" #include "task.h" -#include "text.h" #include "trig.h" - -//Functions that need to be put in headers -void remove_some_task(void); -void LoadCompressedObjectPic(void *); -void LoadCompressedObjectPalette(const struct SpritePalette *); -u16 SpeciesToNationalPokedexNum(u16); -void DecompressPicFromTable_2(const struct SpriteSheet *, u8, u8, void *, void *, u32); +#include "decompress.h" +#include "sprite.h" struct MonCoords { @@ -25,12 +20,12 @@ struct MonCoords extern void * const gUnknown_081FAF4C[]; extern const u8 gStarterChoose_PokeballCoords[][2]; -extern u8 gUnknown_083F66F0[]; +extern u8 gBirchHelpGfx[]; extern u8 gBirchBagTilemap[]; extern u8 gBirchGrassTilemap[]; -extern u8 gUnknown_083F7794[]; -extern u8 gUnknown_083F77A4[]; -extern u8 gUnknown_083F62EC[]; +extern struct SpriteSheet gUnknown_083F7794; +extern struct SpriteSheet gUnknown_083F77A4; +extern u8 gBirchBagGrassPal[]; extern const u8 gStarterChoose_LabelCoords[][2]; extern u16 gStarterMons[]; extern union AffineAnimCmd *gUnknown_083F778C[]; @@ -50,7 +45,6 @@ extern struct SpritePalette gUnknown_083F77B4[]; extern struct SpriteTemplate gSpriteTemplate_83F77FC; extern struct SpriteTemplate gUnknown_02024E8C; -u16 GetStarterPokemon(u16); static void MainCallback2(void); static void Task_StarterChoose1(u8 taskId); static void Task_StarterChoose2(u8 taskId); @@ -59,10 +53,8 @@ static void Task_StarterChoose4(u8 taskId); static void Task_StarterChoose5(u8 taskId); static void Task_StarterChoose6(u8 taskId); -extern u8 *GetPokemonCategory(u16); static void CreateStarterPokemonLabel(u8, u8); static u8 CreatePokemonFrontSprite(u16, u8, u8); -void StarterPokemonSpriteAnimCallback(struct Sprite *); //Position of the sprite of the selected starter Pokemon #define STARTER_PKMN_POS_X 120 @@ -116,7 +108,7 @@ void CB2_ChooseStarter(void) DmaFill32(3, 0, OAM, OAM_SIZE); DmaFill16(3, 0, PLTT, PLTT_SIZE); - LZ77UnCompVram(&gUnknown_083F66F0, (void *)VRAM); + LZ77UnCompVram(&gBirchHelpGfx, (void *)VRAM); LZ77UnCompVram(&gBirchBagTilemap, (void *)(VRAM + 0x3000)); LZ77UnCompVram(&gBirchGrassTilemap, (void *)(VRAM + 0x3800)); remove_some_task(); @@ -124,9 +116,9 @@ void CB2_ChooseStarter(void) ResetSpriteData(); ResetPaletteFade(); FreeAllSpritePalettes(); - LoadPalette(gUnknown_083F62EC, 0, 0x40); - LoadCompressedObjectPic(gUnknown_083F7794); - LoadCompressedObjectPic(gUnknown_083F77A4); + LoadPalette(gBirchBagGrassPal, 0, 0x40); + LoadCompressedObjectPic(&gUnknown_083F7794); + LoadCompressedObjectPic(&gUnknown_083F77A4); LoadSpritePalettes(gUnknown_083F77B4); SetUpWindowConfig(&gWindowConfig_81E6C3C); InitMenuWindow(&gWindowConfig_81E6CE4); @@ -274,7 +266,7 @@ static void Task_StarterChoose5(u8 taskId) case 0: //YES //Return the starter choice and exit. gScriptResult = gTasks[taskId].data[TD_STARTERSELECTION]; - SetMainCallback2(gMain.field_8); + SetMainCallback2(gMain.savedCallback); break; case 1: //NO case -1: //B button diff --git a/src/task.c b/src/task.c index 4545c0168..e79929c63 100644 --- a/src/task.c +++ b/src/task.c @@ -49,7 +49,6 @@ u8 CreateTask(TaskFunc func, u8 priority) return 0; } -#ifdef NONMATCHING static void InsertTask(u8 newTaskId) { u8 taskId = FindFirstActiveTask(); @@ -62,7 +61,7 @@ static void InsertTask(u8 newTaskId) return; } - for (;;) + while (1) { if (gTasks[newTaskId].priority < gTasks[taskId].priority) { @@ -70,112 +69,22 @@ static void InsertTask(u8 newTaskId) // so we insert the new task before it. gTasks[newTaskId].prev = gTasks[taskId].prev; gTasks[newTaskId].next = taskId; - if (gTasks[taskId].prev != HEAD_SENTINEL) gTasks[gTasks[taskId].prev].next = newTaskId; - gTasks[taskId].prev = newTaskId; return; } - - if (gTasks[taskId].next != TAIL_SENTINEL) - taskId = gTasks[taskId].next; - else - break; + if (gTasks[taskId].next == TAIL_SENTINEL) + { + // We've reached the end. + gTasks[newTaskId].prev = taskId; + gTasks[newTaskId].next = gTasks[taskId].next; + gTasks[taskId].next = newTaskId; + return; + } + taskId = gTasks[taskId].next; } - - // We've reached the end. - gTasks[newTaskId].prev = taskId; - gTasks[newTaskId].next = gTasks[taskId].next; - gTasks[taskId].next = newTaskId; -} -#else -__attribute__((naked)) -static void InsertTask(u8 newTaskId) -{ - asm("push {r4, r5, r6, r7, lr}\n\ - mov r7, r8\n\ - push {r7}\n\ - lsl r0, r0, #24\n\ - lsr r4, r0, #24\n\ - bl FindFirstActiveTask\n\ - lsl r0, r0, #24\n\ - lsr r1, r0, #24\n\ - cmp r1, #16\n\ - bne .LInsertTask_foundActiveTask\n\ - ldr r1, .LInsertTask_gTasks1\n\ - lsl r0, r4, #2\n\ - add r0, r0, r4\n\ - lsl r0, r0, #3\n\ - add r0, r0, r1\n\ - mov r1, #254\n\ - strb r1, [r0, #5]\n\ - mov r1, #255\n\ - strb r1, [r0, #6]\n\ - b .LInsertTask_done\n\ - .align 2, 0\n\ -.LInsertTask_gTasks1:\n\ - .word gTasks\n\ -.LInsertTask_foundActiveTask:\n\ - ldr r6, .LInsertTask_gTasks2\n\ - lsl r0, r4, #2\n\ - mov r12, r0\n\ - mov r8, r6\n\ - add r0, r0, r4\n\ - lsl r0, r0, #3\n\ - add r2, r0, r6\n\ -.LInsertTask_loop:\n\ - lsl r0, r1, #2\n\ - add r0, r0, r1\n\ - lsl r5, r0, #3\n\ - mov r7, r8\n\ - add r3, r5, r7\n\ - ldrb r0, [r2, #7]\n\ - ldrb r7, [r3, #7]\n\ - cmp r0, r7\n\ - bcs .LInsertTask_next\n\ - ldrb r0, [r3, #5]\n\ - strb r0, [r2, #5]\n\ - strb r1, [r2, #6]\n\ - ldrb r0, [r3, #5]\n\ - cmp r0, #254\n\ - beq .LInsertTask_insertAtHead\n\ - add r1, r0, #0\n\ - lsl r0, r1, #2\n\ - add r0, r0, r1\n\ - lsl r0, r0, #3\n\ - add r0, r0, r8\n\ - strb r4, [r0, #6]\n\ -.LInsertTask_insertAtHead:\n\ - strb r4, [r3, #5]\n\ - b .LInsertTask_done\n\ - .align 2, 0\n\ -.LInsertTask_gTasks2:\n\ - .word gTasks\n\ -.LInsertTask_next:\n\ - ldrb r0, [r3, #6]\n\ - cmp r0, #255\n\ - beq .LInsertTask_insertAtTail\n\ - add r1, r0, #0\n\ - b .LInsertTask_loop\n\ -.LInsertTask_insertAtTail:\n\ - mov r2, r12\n\ - add r0, r2, r4\n\ - lsl r0, r0, #3\n\ - add r0, r0, r6\n\ - strb r1, [r0, #5]\n\ - add r2, r5, r6\n\ - ldrb r1, [r2, #6]\n\ - strb r1, [r0, #6]\n\ - strb r4, [r2, #6]\n\ -.LInsertTask_done:\n\ - pop {r3}\n\ - mov r8, r3\n\ - pop {r4, r5, r6, r7}\n\ - pop {r0}\n\ - bx r0\n"); } -#endif // NONMATCHING void DestroyTask(u8 taskId) { diff --git a/src/text.c b/src/text.c index 885fb7547..6089fdba8 100644 --- a/src/text.c +++ b/src/text.c @@ -5,12 +5,7 @@ #include "songs.h" #include "palette.h" #include "sound.h" - -enum -{ - CHARSET_JAPANESE = 1, - CHARSET_LATIN -}; +#include "battle.h" enum { @@ -184,8 +179,8 @@ EWRAM_DATA u8 gStringVar2[0x100] = {0}; EWRAM_DATA u8 gStringVar3[0x100] = {0}; EWRAM_DATA u8 gStringVar4[0x100] = {0}; -extern u16 gUnknown_020239F8; -extern u8 gUnknown_0203869A; +extern u16 gBattleTypeFlags; +extern u8 gIsLinkContest; extern u8 gTileBuffer[]; vu16 *const gBGControlRegs[] = @@ -361,7 +356,7 @@ static const WriteGlyphTilemapFunc sWriteGlyphTilemapFuncs[] = WriteGlyphTilemap_Font6, }; -static const struct Window sDefaultWindow = { .charset = CHARSET_LATIN }; +static const struct Window sDefaultWindow = { .language = GAME_LANGUAGE }; typedef u8 (*ExtCtrlCodeFunc)(struct Window *); @@ -770,7 +765,7 @@ const struct WindowConfig gWindowConfig_81E6DA8 = (u16 *)BG_SCREEN_ADDR(11), // tilemap }; -const struct WindowConfig gWindowConfig_81E6DC4 = +const struct WindowConfig WindowConfig_TrainerCard_Back_Values = { 0, // BG number 2, // BG character base block @@ -791,7 +786,7 @@ const struct WindowConfig gWindowConfig_81E6DC4 = (u16 *)BG_SCREEN_ADDR(30), // tilemap }; -const struct WindowConfig gWindowConfig_81E6DE0 = +const struct WindowConfig WindowConfig_TrainerCard_Back_Labels = { 0, // BG number 2, // BG character base block @@ -1918,14 +1913,14 @@ static void MultistepLoadFont_LoadGlyph(struct Window *win, u16 startOffset, u8 } } -static void EmptyFunc(void) +void EmptyFunc(void) { } -void InitWindowFromConfig(struct Window *win, struct WindowConfig *winConfig) +void InitWindowFromConfig(struct Window *win, const struct WindowConfig *winConfig) { *win = sDefaultWindow; - win->config = winConfig; + win->config = (struct WindowConfig *)winConfig; win->textMode = winConfig->textMode; win->spacing = winConfig->spacing; win->fontNum = winConfig->fontNum; @@ -1947,7 +1942,7 @@ void InitWindow(struct Window *win, const u8 *text, u16 tileDataStartOffset, u8 struct WindowConfig *winConfig = win->config; win->textMode = winConfig->textMode; win->fontNum = winConfig->fontNum; - win->charset = CHARSET_LATIN; + win->language = GAME_LANGUAGE; win->paletteNum = winConfig->paletteNum; win->win_field_B = 0; win->win_field_C = 0; @@ -2045,7 +2040,7 @@ u8 sub_8002F44(struct Window *win) static u8 sub_8002FA0(struct Window *win, const u8 *text) { u8 retVal; - u8 savedCharset = win->charset; + u8 savedLanguage = win->language; const u8 *savedText = win->text; u16 savedTextIndex = win->textIndex; win->text = text; @@ -2055,7 +2050,7 @@ static u8 sub_8002FA0(struct Window *win, const u8 *text) win->text = savedText; win->textIndex = savedTextIndex; win->state = WIN_STATE_NORMAL; - win->charset = savedCharset; + win->language = savedLanguage; return retVal; } @@ -2291,13 +2286,13 @@ static u8 ExtCtrlCode_Spacing(struct Window *win) static u8 ExtCtrlCode_Japanese(struct Window *win) { - win->charset = CHARSET_JAPANESE; + win->language = LANGUAGE_JAPANESE; return 2; } static u8 ExtCtrlCode_Latin(struct Window *win) { - win->charset = CHARSET_LATIN; + win->language = GAME_LANGUAGE; return 2; } @@ -2596,7 +2591,7 @@ static void LoadFixedWidthGlyph(struct Window *win, u32 glyph, u8 *dest) u8 *upperTile; u8 *lowerTile; - GetGlyphTilePointers(win->fontNum, win->charset, glyph, &upperTile, &lowerTile); + GetGlyphTilePointers(win->fontNum, win->language, glyph, &upperTile, &lowerTile); switch (win->fontNum) { @@ -2627,17 +2622,17 @@ static void WriteGlyphTilemap(struct Window *win, u16 upperTileNum, u16 lowerTil } } -static void GetGlyphTilePointers(u8 fontNum, u8 charset, u16 glyph, u8 **upperTilePtr, u8 **lowerTilePtr) +static void GetGlyphTilePointers(u8 fontNum, u8 language, u16 glyph, u8 **upperTilePtr, u8 **lowerTilePtr) { u16 index; const struct Font *font; - if (charset == CHARSET_JAPANESE) - charset = 0; + if (language == LANGUAGE_JAPANESE) + language = 0; else - charset = 7; + language = 7; - font = &sFonts[charset + fontNum]; + font = &sFonts[language + fontNum]; switch (font->type) { @@ -2912,12 +2907,10 @@ static bool8 PlayerCanInterruptWait(struct Window *win) retVal = FALSE; break; case 3: - retVal = FALSE; - if (!gUnknown_0203869A) - retVal = TRUE; + retVal = gIsLinkContest ? FALSE : TRUE; break; case 1: - retVal &= ~(gUnknown_020239F8 >> 1); + retVal = (gBattleTypeFlags & BATTLE_TYPE_LINK) ? FALSE : TRUE; break; } @@ -3137,7 +3130,7 @@ static void DrawDownArrow(struct Window *win) { u8 *upperTile; u8 *lowerTile; - GetGlyphTilePointers(win->fontNum, win->charset, 0, &upperTile, &lowerTile); + GetGlyphTilePointers(win->fontNum, win->language, 0, &upperTile, &lowerTile); glyphTileInfo.width = 8 - glyphTileInfo.startPixel; glyphTileInfo.src = upperTile; glyphTileInfo.dest = (u32 *)(win->tileData + 32 * GetCursorTileNum(win, 1, 0)); @@ -3340,10 +3333,10 @@ static u8 GetGlyphWidth(struct Window *win, u32 glyph) { u8 width = 8; -#if REVISION >= 1 - if (win->charset != CHARSET_JAPANESE) +#ifdef BUGFIX_GLYPHWIDTH + if (win->language != LANGUAGE_JAPANESE) #else - if (win->charset == CHARSET_LATIN) + if (win->language == LANGUAGE_ENGLISH) #endif { width = win->spacing; @@ -3539,7 +3532,7 @@ u8 GetStringWidth(struct Window *win, const u8 *s) { u8 width = 0; u8 savedFontNum = win->fontNum; - u8 savedCharset = win->charset; + u8 savedCharset = win->language; u8 savedSpacing = win->spacing; s32 i = 0; @@ -3552,9 +3545,9 @@ u8 GetStringWidth(struct Window *win, const u8 *s) { u8 temp; i++; - temp = win->charset; + temp = win->language; width += GetStringWidth(win, GetExpandedPlaceholder(s[i])); - win->charset = temp; + win->language = temp; i++; break; } @@ -3580,10 +3573,10 @@ u8 GetStringWidth(struct Window *win, const u8 *s) win->spacing = s[i + 1]; break; case 0x15: - win->charset = 1; + win->language = LANGUAGE_JAPANESE; break; case 0x16: - win->charset = 2; + win->language = GAME_LANGUAGE; break; } @@ -3596,7 +3589,7 @@ u8 GetStringWidth(struct Window *win, const u8 *s) } win->spacing = savedSpacing; - win->charset = savedCharset; + win->language = savedCharset; win->fontNum = savedFontNum; return width; @@ -3659,10 +3652,9 @@ u8 GetStringWidthGivenWindowConfig(struct WindowConfig *winConfig, const u8 *s) void ConvertInternationalString(u8 *s, u8 language) { - if (language == CHARSET_JAPANESE) + if (language == LANGUAGE_JAPANESE) { u8 i; - u8 length; StripExtCtrlCodes(s); i = StringLength(s); @@ -4254,7 +4246,7 @@ static s32 DrawGlyphTiles(struct Window *win, u32 glyph, u32 glyphWidth) u8 *lowerTile; s32 retVal = 0; - GetGlyphTilePointers(win->fontNum, win->charset, glyph, &upperTile, &lowerTile); + GetGlyphTilePointers(win->fontNum, win->language, glyph, &upperTile, &lowerTile); glyphTileInfo.textMode = win->textMode; glyphTileInfo.startPixel = (win->left + win->cursorX) & 7; glyphTileInfo.width = glyphWidth; diff --git a/src/text_window.c b/src/text_window.c index e7f72a80b..1ac624dd0 100644 --- a/src/text_window.c +++ b/src/text_window.c @@ -1,40 +1,23 @@ #include "global.h" +#include "text_window.h" #include "main.h" #include "text.h" -#include "text_window.h" +#include "palette.h" #define STD_MSG_BOX_LEFT 0 #define STD_MSG_BOX_TOP 14 #define STD_MSG_BOX_WIDTH 26 #define STD_MSG_BOX_HEIGHT 4 -u16 SetTextWindowBaseTileNum(u16); -void LoadTextWindowGraphics(struct Window *); -void LoadTextWindowGraphics_OverridePalSlot(struct Window *, u8); -void LoadTextWindowGraphics_OverrideFrameType(struct Window *, u8); -void DrawTextWindow(struct Window *win, u8 left, u8 top, u8 right, u8 bottom); -const struct FrameGraphics *GetTextWindowFrameGraphics(u8 frameType); static void LoadTextWindowTiles(u8, void *); static void LoadTextWindowPalette(u8, u8); static void DrawTextWindowInternal(u16 *dest, u16 baseTileNum, u8 left, u8 top, u8 right, u8 bottom); -u16 SetMessageBoxBaseTileNum(u16); -void unref_sub_80651DC(struct Window *, u8 *); -void DisplayMessageBox(struct Window *); static u16 GetMessageBoxTilemapEntry(u16 tilemapEntry, u8 x, u8 y, u8 width, u8 height); static void DrawMessageBox(struct Window *win, u8 left, u8 top, u8 width, u8 height); -void DrawStandardMessageBox(struct Window *win); -void LoadMessageBoxTiles(struct Window *win); -void ClearStandardMessageBox(struct Window *win); static u16 sTextWindowBaseTileNum; static u16 sMessageBoxBaseTileNum; -struct FrameGraphics -{ - u8 *tiles; - u16 *palette; -}; - extern const struct FrameGraphics gUnknown_083761F0[20]; extern const u16 gMessageBoxTilemap[5][7]; diff --git a/src/tileset_anim.c b/src/tileset_anim.c index 96030f037..415b69cfe 100644 --- a/src/tileset_anim.c +++ b/src/tileset_anim.c @@ -1,4 +1,5 @@ #include "global.h" +#include "tileset_anim.h" extern u8 *gTilesetAnimTable_General_0[]; extern u8 *gTilesetAnimTable_General_1[]; diff --git a/src/title_screen.c b/src/title_screen.c index d5cfa032b..ffa803d2e 100644 --- a/src/title_screen.c +++ b/src/title_screen.c @@ -1,17 +1,18 @@ #include "global.h" +#include "title_screen.h" +#include "asm.h" +#include "clear_save_data_menu.h" +#include "m4a.h" +#include "main_menu.h" +#include "intro.h" #include "gba/m4a_internal.h" #include "main.h" #include "palette.h" #include "sound.h" #include "sprite.h" #include "task.h" - -extern void m4aSongNumStart(u16); -extern void LoadCompressedObjectPic(void *); -extern void CB2_InitCopyrightScreen(void); -extern void CB2_InitMainMenu(void); -extern void CB2_InitClearSaveDataScreen(void); -extern void CB2_InitResetRtcScreen(void); +#include "decompress.h" +#include "event_data.h" extern u8 gReservedSpritePaletteCount; extern struct MusicPlayerInfo gMPlay_BGM; @@ -25,12 +26,12 @@ extern u8 gUnknown_08393BF8[]; extern u16 gUnknown_08393E64[]; extern struct SpriteTemplate gSpriteTemplate_8393ECC; extern struct SpriteTemplate gSpriteTemplate_8393EE4; -extern u8 gUnknown_08393EFC[]; +extern struct SpriteSheet gUnknown_08393EFC; extern struct SpriteTemplate gSpriteTemplate_8393F74; -extern u8 gUnknown_08393F8C[]; -extern u8 gUnknown_08393F9C[]; +extern struct SpriteSheet gUnknown_08393F8C; +extern const struct SpritePalette gUnknown_08393F9C[]; extern struct SpriteTemplate gSpriteTemplate_8393FC0; -extern u8 gUnknown_08393FD8[]; +extern struct SpriteSheet gUnknown_08393FD8; extern u8 gUnknown_08E9D8CC[]; extern u8 gUnknown_08E9F624[]; extern u8 gUnknown_08E9F7E4[]; @@ -253,11 +254,11 @@ void CB2_InitTitleScreen(void) ResetSpriteData(); FreeAllSpritePalettes(); gReservedSpritePaletteCount = 14; - LoadCompressedObjectPic(gUnknown_08393EFC); - LoadCompressedObjectPic(gUnknown_08393F8C); - LoadCompressedObjectPic(gUnknown_08393FD8); + LoadCompressedObjectPic(&gUnknown_08393EFC); + LoadCompressedObjectPic(&gUnknown_08393F8C); + LoadCompressedObjectPic(&gUnknown_08393FD8); LoadPalette(gUnknown_08E9F624, 0x100, 0x1C0); - LoadSpritePalette(gUnknown_08393F9C); + LoadSpritePalette(&gUnknown_08393F9C[0]); gMain.state = 2; break; case 2: @@ -427,7 +428,7 @@ static void Task_TitleScreenPhase3(u8 taskId) if ((gMain.heldKeys & CLEAR_SAVE_BUTTON_COMBO) == CLEAR_SAVE_BUTTON_COMBO) SetMainCallback2(CB2_GoToClearSaveDataScreen); if ((gMain.heldKeys & RESET_RTC_BUTTON_COMBO) == RESET_RTC_BUTTON_COMBO - && sub_80691DC() == 1) + && CanResetRTC() == 1) { FadeOutBGM(4); BeginNormalPaletteFade(-1, 0, 0, 0x10, 0); diff --git a/src/trainer_card.c b/src/trainer_card.c new file mode 100644 index 000000000..83551eb2b --- /dev/null +++ b/src/trainer_card.c @@ -0,0 +1,2027 @@ +#include "global.h" +#include "trainer_card.h" +#include "asm.h" +#include "event_data.h" +#include "link.h" +#include "main.h" +#include "menu.h" +#include "money.h" +#include "palette.h" +#include "pokedex.h" +#include "rom4.h" +#include "songs.h" +#include "sound.h" +#include "sprite.h" +#include "string_util.h" +#include "task.h" + +typedef void (*Callback)(void); + +struct Struct2000000 { + /*0x00*/ u8 var_0; + /*0x01*/ bool8 var_1; + /*0x02*/ u8 var_2; + /*0x03*/ bool8 var_3; + /*0x04*/ u8 var_4; + /*0x05*/ u8 var_5; + /*0x06*/ u8 var_6; + /*0x07*/ bool8 var_7; + /*0x08*/ bool8 var_8; + /*0x09*/ bool8 var_9; + /*0x0A*/ bool8 var_a; + /*0x0B*/ bool8 var_b; + /*0x0C*/ bool8 var_c; + /*0x0D*/ bool8 var_d; + /*0x0E*/ u8 var_e[8]; + /*0x16*/ u8 filler_16[10]; + /*0x20*/ u8 var_20[4][0x10]; + /*0x60*/ Callback *var_60; + /*0x64*/ struct TrainerCard var_64; + /*0x9C*/ u8 language; // 0x9C +}; + +extern struct Struct2000000 unk_2000000; +extern struct LinkPlayerMapObject gLinkPlayerMapObjects[]; +extern struct TrainerCard gTrainerCards[4]; + +extern u8 gUnknown_03004DE0[]; // TODO: find out correct type + +extern u8 gUnknown_083B5EF4[]; +extern u16 *gUnknown_083B5EF8[5]; +extern u16 gUnknown_083B5F0C[]; +extern u16 gBadgesPalette[]; +extern u16 gUnknown_083B5F4C[]; + +extern u16 gUnknown_08E8CFC0[]; +extern u16 gUnknown_08E8D9C0[]; + +extern u8 gOtherText_TrainersTrainerCard[]; +extern u8 gOtherText_FirstHOF[]; +extern u8 gOtherText_LinkCableBattles[]; +extern u8 gOtherText_BattleTowerWinRecord[]; +extern u8 gOtherText_ContestRecord[]; +extern u8 gOtherText_MixingRecord[]; +extern u8 gOtherText_TradeRecord[]; +extern u8 gOtherText_Boy[]; +extern u8 gOtherText_Girl[]; + +// Other signature than on save_menu_util.h +void FormatPlayTime(u8 *playtime, u16 hours, u16 minutes, s16 colon); + +u16 GetPokedexSeenCount(void); + +enum { + TD_0, + TD_1, + TD_CALLBACK, +}; + +static void sub_8093174(void); +static void sub_809323C(void); +static void sub_8093254(void); +static void sub_80932AC(Callback callBack); +static void sub_80932E4(u8 arg1, Callback callBack); +void sub_8093324(void); +static void nullsub_60(u8); +static u32 sav12_xor_get_clamped_above(u8 index, u32 maxVal); +static u8 sub_80934F4(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); +void sub_80936D4(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 sub_809380C(); +static void sub_809382C(u8 taskId); +static void sub_80939A4(void); +static void sub_80939C0(void); +static void sub_80939DC(u8 taskId); +static void sub_8093A28(void); +static u8 sub_8093A48(void); +static void sub_8093A68(u8 taskId); +void sub_8093D7C(void); +static void sub_8093DAC(void); +static void sub_8093DC8(void); +static void sub_8093DEC(void); +static void sub_8093E04(void); +static void sub_8093E28(void); +void sub_8093EA0(void); +static void sub_8093EF8(void); +static void sub_8093F14(void); +static void sub_8093F48(void); +static void sub_8093F64(void); +static void sub_8093F80(void); +static void sub_8093FD0(void); +static void sub_8094038(void); +static void sub_80940E4(void); +static void sub_8094110(void); +static void sub_8094140(void); +static void sub_8094188(void); +static void TrainerCard_Front_PrintTrainerID(void); +static void TrainerCard_Front_PrintMoney(void); +static void TrainerCard_Front_PrintPokedexCount(void); +static void TrainerCard_Front_PrintPlayTime(u8 *arg1, s16 colon); +static void sub_809429C(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); + +void sub_8093110(Callback arg1) { + sub_80932AC(arg1); + SetMainCallback2(sub_8093174); + unk_2000000.language = GAME_LANGUAGE; +} + +void sub_8093130(u8 playerIndex, Callback arg2) { + struct Struct2000000* r2; + struct LinkPlayer* r3; + struct LinkPlayerMapObject* r4; + u8 linkPlayerId; + + sub_80932E4(playerIndex, arg2); + SetMainCallback2(sub_8093174); + + r2 = &unk_2000000; + r3 = gLinkPlayers; + r4 = gLinkPlayerMapObjects; + + linkPlayerId = r4[playerIndex].linkPlayerId; + + r2->language = r3[linkPlayerId].language; +} + + +static void sub_8093174(void) { + switch (gMain.state) { + case 0: + sub_8093534(); + sub_8093688(); + gMain.state += 1; + break; + case 1: + sub_8093598(); + gMain.state += 1; + break; + case 2: + sub_80935EC(); + gMain.state += 1; + break; + case 3: + sub_8093610(); + sub_80937A4(); + gMain.state += 1; + break; + case 4: + sub_80937BC(); + gMain.state += 1; + case 5: + if (MultistepInitMenuWindowContinue() == FALSE) { + return; + } + gMain.state += 1; + break; + case 6: + sub_80937F0(); + gMain.state += 1; + break; + case 7: + sub_80937D8(); + gMain.state += 1; + 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(); + unk_2000000.var_6++; + if (unk_2000000.var_6 >= 60) + { + unk_2000000.var_6 = 0; + unk_2000000.var_5 ^= 1; + } + if (unk_2000000.var_4) + DmaCopy16(3, gUnknown_03004DE0, gUnknown_03004DE0 + 0x780, 320); +} + +static void sub_80932AC(Callback callBack) { + u8 taskId = CreateTask(nullsub_60, 0xFF); + struct Task *task = &gTasks[taskId]; + task->data[TD_0] = FALSE; + StoreWordInTwoHalfwords(&task->data[TD_CALLBACK], (u32) callBack); +} + +static void sub_80932E4(u8 arg1, Callback callBack) { + u8 taskId = CreateTask(nullsub_60, 0xFF); + + struct Task *task = &gTasks[taskId]; + task->data[TD_0] = TRUE; + task->data[TD_1] = arg1; + StoreWordInTwoHalfwords(&task->data[TD_CALLBACK], (u32) callBack); +} + +void sub_8093324(void) { + u8 taskId = FindTaskIdByFunc(nullsub_60); + struct Task *task = &gTasks[taskId]; + unk_2000000.var_1 = task->data[TD_0]; + + LoadWordFromTwoHalfwords((u16 *) &task->data[TD_CALLBACK], (u32 *) &unk_2000000.var_60); + + if (unk_2000000.var_1) { + struct TrainerCard (*trainerCards)[4] = &gTrainerCards; + s16 var = task->data[TD_1]; + struct TrainerCard *dest = &(*trainerCards)[var]; + memcpy(&unk_2000000.var_64, dest, sizeof(struct TrainerCard)); + } else { + sub_8093390(&unk_2000000.var_64); + } +} + +static void nullsub_60(u8 taskid) { +} + +void sub_8093390(struct TrainerCard *arg1) { + u32 playTime; + bool32 enteredHallOfFame; + bool8 r4; + u8 i; + + arg1->gender = gSaveBlock2.playerGender; + arg1->playTimeHours = gSaveBlock2.playTimeHours; + arg1->playTimeMinutes = gSaveBlock2.playTimeMinutes; + + playTime = GetGameStat(GAME_STAT_FIRST_HOF_PLAY_TIME); + enteredHallOfFame = GetGameStat(GAME_STAT_ENTERED_HOF); + if (!enteredHallOfFame) { + playTime = 0; + } + arg1->firstHallOfFameA = playTime >> 16; + arg1->firstHallOfFameB = (playTime >> 8) & 0xFF; + arg1->firstHallOfFameC = playTime & 0xFF; + + arg1->hasPokedex = FlagGet(SYS_POKEDEX_GET); + arg1->var_3 = sub_8090FC0(); + arg1->pokedexSeen = GetPokedexSeenCount(); + + arg1->trainerId = (gSaveBlock2.playerTrainerId[1] << 8) | gSaveBlock2.playerTrainerId[0]; + + // Link Cable Battles + arg1->linkBattleWins = sav12_xor_get_clamped_above(GAME_STAT_LINK_BATTLE_WINS, 9999); + arg1->linkBattleLosses = sav12_xor_get_clamped_above(GAME_STAT_LINK_BATTLE_LOSSES, 9999); + + // Contests w/ Friends + arg1->contestsWithFriends = sav12_xor_get_clamped_above(GAME_STAT_WON_LINK_CONTEST, 999); + + // Pokéblocks w/ Friends + arg1->pokeblocksWithFriends = sav12_xor_get_clamped_above(GAME_STAT_POKEBLOCKS_WITH_FRIENDS, 0xFFFF); + + // Pokémon Trades + arg1->pokemonTrades = sav12_xor_get_clamped_above(GAME_STAT_POKEMON_TRADES, 0xFFFF); + + // Battle tower? + arg1->battleTowerWins = gSaveBlock2.filler_A8.var_4C8; + arg1->battleTowerLosses = gSaveBlock2.filler_A8.var_4CA; + if (arg1->battleTowerWins > 9999) { + arg1->battleTowerWins = 9999; + } + if (arg1->battleTowerLosses > 9999) { + arg1->battleTowerLosses = 9999; + } + + r4 = FALSE; + if (sub_80C4D50() > 4) { + r4 = TRUE; + } + arg1->var_4 = r4; + + arg1->money = gSaveBlock1.money; + + for (i = 0; i < 4; i++) { + arg1->var_28[i] = gSaveBlock1.unk2B1C[i]; + } + + for (i = 0; i < 8; i++) { + arg1->playerName[i] = gSaveBlock2.playerName[i]; + } + + arg1->stars = sub_80934F4(arg1); +} + +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 sub_80934F4(struct TrainerCard *trainerCard) { + u8 value = 0; + + if (trainerCard->firstHallOfFameA != 0 || trainerCard->firstHallOfFameB != 0 || trainerCard->firstHallOfFameC != 0) { + value += 1; + } + + if (trainerCard->var_3) { + value += 1; + } + + if (trainerCard->battleTowerLosses > 49) { + value += 1; + } + + if (trainerCard->var_4) { + value += 1; + } + + 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 = 0x1f40; +} + +__attribute__((naked)) +void sub_8093598() { + asm(".syntax unified\n\ + push {r4-r7,lr}\n\ + sub sp, 0x4\n\ + movs r2, 0xC0\n\ + lsls r2, 19\n\ + movs r3, 0x80\n\ + lsls r3, 9\n\ + mov r4, sp\n\ + movs r6, 0\n\ + ldr r1, _080935E4 @ =0x040000d4\n\ + movs r5, 0x80\n\ + lsls r5, 5\n\ + ldr r7, _080935E8 @ =0x81000800\n\ + movs r0, 0x81\n\ + lsls r0, 24\n\ + mov r12, r0\n\ +_080935B6:\n\ + strh r6, [r4]\n\ + mov r0, sp\n\ + str r0, [r1]\n\ + str r2, [r1, 0x4]\n\ + str r7, [r1, 0x8]\n\ + ldr r0, [r1, 0x8]\n\ + adds r2, r5\n\ + subs r3, r5\n\ + cmp r3, r5\n\ + bhi _080935B6\n\ + strh r6, [r4]\n\ + mov r0, sp\n\ + str r0, [r1]\n\ + str r2, [r1, 0x4]\n\ + lsrs r0, r3, 1\n\ + mov r2, r12\n\ + orrs r0, r2\n\ + str r0, [r1, 0x8]\n\ + ldr r0, [r1, 0x8]\n\ + add sp, 0x4\n\ + pop {r4-r7}\n\ + pop {r0}\n\ + bx r0\n\ + .align 2, 0\n\ +_080935E4: .4byte 0x040000d4\n\ +_080935E8: .4byte 0x81000800\n\ + .syntax divided\n"); +} + +__attribute__((naked)) +void sub_80935EC() { + asm(".syntax unified\n\ + sub sp, 0x4\n\ + movs r2, 0xE0\n\ + lsls r2, 19\n\ + mov r1, sp\n\ + movs r0, 0\n\ + strh r0, [r1]\n\ + ldr r0, _08093608 @ =0x040000d4\n\ + str r1, [r0]\n\ + str r2, [r0, 0x4]\n\ + ldr r1, _0809360C @ =0x81000200\n\ + str r1, [r0, 0x8]\n\ + ldr r0, [r0, 0x8]\n\ + add sp, 0x4\n\ + bx lr\n\ + .align 2, 0\n\ +_08093608: .4byte 0x040000d4\n\ +_0809360C: .4byte 0x81000200\n\ + .syntax divided\n"); +} + +__attribute__((naked)) +void sub_8093610() { + asm(".syntax unified\n\ + push {r4,r5,lr}\n\ + ldr r5, _08093664 @ =REG_BG0CNT\n\ + movs r1, 0\n\ + strh r1, [r5]\n\ + ldr r2, _08093668 @ =REG_BG1CNT\n\ + strh r1, [r2]\n\ + ldr r3, _0809366C @ =REG_BG2CNT\n\ + strh r1, [r3]\n\ + ldr r4, _08093670 @ =REG_BG3CNT\n\ + strh r1, [r4]\n\ + ldr r0, _08093674 @ =REG_BG0HOFS\n\ + strh r1, [r0]\n\ + adds r0, 0x2\n\ + strh r1, [r0]\n\ + adds r0, 0x2\n\ + strh r1, [r0]\n\ + adds r0, 0x2\n\ + strh r1, [r0]\n\ + adds r0, 0x2\n\ + strh r1, [r0]\n\ + adds r0, 0x2\n\ + strh r1, [r0]\n\ + adds r0, 0x2\n\ + strh r1, [r0]\n\ + adds r0, 0x2\n\ + strh r1, [r0]\n\ + ldr r1, _08093678 @ =0x00001e08\n\ + adds r0, r1, 0\n\ + strh r0, [r5]\n\ + ldr r1, _0809367C @ =0x00000801\n\ + adds r0, r1, 0\n\ + strh r0, [r2]\n\ + ldr r1, _08093680 @ =0x00000902\n\ + adds r0, r1, 0\n\ + strh r0, [r3]\n\ + ldr r1, _08093684 @ =0x00000a03\n\ + adds r0, r1, 0\n\ + strh r0, [r4]\n\ + pop {r4,r5}\n\ + pop {r0}\n\ + bx r0\n\ + .align 2, 0\n\ +_08093664: .4byte 0x4000008 @ REG_BG0CNT\n\ +_08093668: .4byte 0x400000A @ REG_BG1CNT\n\ +_0809366C: .4byte 0x400000C @ REG_BG2CNT\n\ +_08093670: .4byte 0x400000E @ REG_BG3CNT\n\ +_08093674: .4byte 0x4000010 @ REG_BG0HOFS\n\ +_08093678: .4byte 0x00001e08\n\ +_0809367C: .4byte 0x00000801\n\ +_08093680: .4byte 0x00000902\n\ +_08093684: .4byte 0x00000a03\n\ + .syntax divided\n"); +} + +#ifdef NONMATCHING +static void sub_8093688(void) { + int i; + + asm_comment("WIP"); + sub_8093324(); + + unk_2000000.var_0 = FALSE; + unk_2000000.var_3 = FALSE; + unk_2000000.var_4 = FALSE; + + unk_2000000.var_2 = unk_2000000.var_64.stars; + + unk_2000000.var_5 = FALSE; + unk_2000000.var_6 = FALSE; + + for (i = 0; i < 4; i++) { + sub_80EB3FC(unk_2000000.var_20[i], unk_2000000.var_64.var_28[i]); + } + + sub_80936D4(); +} +#else + +__attribute__((naked)) +static void sub_8093688(void) { + asm(".syntax unified\n\ + push {r4-r6,lr}\n\ + bl sub_8093324\n\ + ldr r2, _080936D0 @ =0x02000000\n\ + movs r1, 0\n\ + strb r1, [r2]\n\ + strb r1, [r2, 0x3]\n\ + strb r1, [r2, 0x4]\n\ + adds r0, r2, 0\n\ + adds r0, 0x65\n\ + ldrb r0, [r0]\n\ + strb r0, [r2, 0x2]\n\ + strb r1, [r2, 0x5]\n\ + strb r1, [r2, 0x6]\n\ + movs r4, 0\n\ + adds r6, r2, 0\n\ + adds r6, 0x20\n\ + adds r5, r2, 0\n\ + adds r5, 0x8C\n\ +_080936AE:\n\ + lsls r0, r4, 4\n\ + adds r0, r6\n\ + lsls r1, r4, 1\n\ + adds r1, r5, r1\n\ + ldrh r1, [r1]\n\ + bl sub_80EB3FC\n\ + adds r0, r4, 0x1\n\ + lsls r0, 24\n\ + lsrs r4, r0, 24\n\ + cmp r4, 0x3\n\ + bls _080936AE\n\ + bl sub_80936D4\n\ + pop {r4-r6}\n\ + pop {r0}\n\ + bx r0\n\ + .align 2, 0\n\ +_080936D0: .4byte 0x02000000\n\ + .syntax divided\n"); +} + +#endif + +void sub_80936D4(void) { + unk_2000000.var_7 = FALSE; + unk_2000000.var_8 = FALSE; + unk_2000000.var_9 = FALSE; + unk_2000000.var_a = FALSE; + unk_2000000.var_b = FALSE; + unk_2000000.var_c = FALSE; + unk_2000000.var_d = FALSE; + + memset(unk_2000000.var_e, 0, sizeof(unk_2000000.var_e)); + + if (unk_2000000.var_64.hasPokedex) { + unk_2000000.var_7 += TRUE; + } + + if (unk_2000000.var_64.firstHallOfFameA != 0 || unk_2000000.var_64.firstHallOfFameB != 0 || + unk_2000000.var_64.firstHallOfFameC != 0) { + unk_2000000.var_8 += TRUE; + } + + if (unk_2000000.var_64.linkBattleWins != 0 || unk_2000000.var_64.linkBattleLosses != 0) { + unk_2000000.var_9 += TRUE; + } + + if (unk_2000000.var_64.battleTowerWins != 0 || unk_2000000.var_64.battleTowerLosses != 0) { + unk_2000000.var_a += TRUE; + } + + if (unk_2000000.var_64.contestsWithFriends != 0) { + unk_2000000.var_b += TRUE; + } + + if (unk_2000000.var_64.pokeblocksWithFriends != 0) { + unk_2000000.var_c += TRUE; + } + + if (unk_2000000.var_64.pokemonTrades != 0) { + unk_2000000.var_d += TRUE; + } + + if (!unk_2000000.var_1) { + u32 badgeFlag; + int i; + + i = 0; + badgeFlag = BADGE01_GET; + while (TRUE) { + if (FlagGet(badgeFlag)) { + unk_2000000.var_e[i] += TRUE; + } + + badgeFlag += 1; + i += 1; + if (badgeFlag > BADGE08_GET) { + break; + } + } + } +} + +void sub_80937A4() { + ResetPaletteFade(); + ResetSpriteData(); + FreeAllSpritePalettes(); + ResetTasks(); +} + +void sub_80937BC() { + SetUpWindowConfig(&WindowConfig_TrainerCard_Back_Values); + MultistepInitMenuWindowBegin(&WindowConfig_TrainerCard_Back_Values); +} + +static void sub_80937D8() { + sub_8093E04(); + sub_8093E28(); + sub_8093F64(); + sub_8093DAC(); +} + +static void sub_80937F0() { + sub_8093EF8(); +} + +static void nullsub_15(void) { +} + +static void sub_8093800() { + sub_809380C(); +} + +static void sub_809380C() { + u8 taskId; + + taskId = CreateTask(sub_809382C, 0); + sub_809382C(taskId); +} + +__attribute__((naked)) +static void sub_809382C(u8 taskId) { + asm(".syntax unified\n\ + push {r4-r7,lr}\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + ldr r7, _08093858 @ =gUnknown_083B5EBC\n\ + lsls r1, r0, 2\n\ + adds r1, r0\n\ + lsls r4, r1, 3\n\ + ldr r6, _0809385C @ =0x02000000\n\ + ldr r5, _08093860 @ =gTasks\n\ +_0809383E:\n\ + ldrb r0, [r6]\n\ + lsls r0, 2\n\ + adds r0, r7\n\ + ldr r1, [r0]\n\ + adds r0, r4, r5\n\ + bl _call_via_r1\n\ + lsls r0, 24\n\ + cmp r0, 0\n\ + bne _0809383E\n\ + pop {r4-r7}\n\ + pop {r0}\n\ + bx r0\n\ + .align 2, 0\n\ +_08093858: .4byte gUnknown_083B5EBC\n\ +_0809385C: .4byte 0x02000000\n\ +_08093860: .4byte gTasks\n\ + .syntax divided\n"); +} + +__attribute__((naked)) +bool8 sub_8093864() { + asm(".syntax unified\n\ + push {r4,r5,lr}\n\ + sub sp, 0x4\n\ + ldr r4, _080938A0 @ =0x02000000\n\ + ldr r2, _080938A4 @ =gSaveBlock2\n\ + ldrb r1, [r2, 0x11]\n\ + movs r0, 0x1\n\ + ands r0, r1\n\ + movs r5, 0\n\ + strb r0, [r4, 0x5]\n\ + ldrb r0, [r2, 0x12]\n\ + strb r0, [r4, 0x6]\n\ + bl sub_80939A4\n\ + movs r0, 0x1\n\ + negs r0, r0\n\ + str r5, [sp]\n\ + movs r1, 0\n\ + movs r2, 0x10\n\ + movs r3, 0\n\ + bl BeginNormalPaletteFade\n\ + ldrb r0, [r4]\n\ + adds r0, 0x1\n\ + strb r0, [r4]\n\ + movs r0, 0\n\ + add sp, 0x4\n\ + pop {r4,r5}\n\ + pop {r1}\n\ + bx r1\n\ + .align 2, 0\n\ +_080938A0: .4byte 0x02000000\n\ +_080938A4: .4byte gSaveBlock2\n\ + .syntax divided\n"); +} + +__attribute__((naked)) +bool8 sub_80938A8() { + asm(".syntax unified\n\ + push {lr}\n\ + ldr r0, _080938C4 @ =gPaletteFade\n\ + ldrb r1, [r0, 0x7]\n\ + movs r0, 0x80\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + bne _080938BE\n\ + ldr r1, _080938C8 @ =0x02000000\n\ + ldrb r0, [r1]\n\ + adds r0, 0x1\n\ + strb r0, [r1]\n\ +_080938BE:\n\ + movs r0, 0\n\ + pop {r1}\n\ + bx r1\n\ + .align 2, 0\n\ +_080938C4: .4byte gPaletteFade\n\ +_080938C8: .4byte 0x02000000\n\ + .syntax divided\n"); +} + +__attribute__((naked)) +bool8 sub_80938CC() { + asm(".syntax unified\n\ + push {lr}\n\ + ldr r0, _080938E4 @ =gMain\n\ + ldrh r1, [r0, 0x2E]\n\ + movs r0, 0x2\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _080938EC\n\ + ldr r1, _080938E8 @ =0x02000000\n\ + movs r0, 0x5\n\ + strb r0, [r1]\n\ + movs r0, 0x1\n\ + b _08093914\n\ + .align 2, 0\n\ +_080938E4: .4byte gMain\n\ +_080938E8: .4byte 0x02000000\n\ +_080938EC:\n\ + movs r0, 0x1\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _08093912\n\ + ldr r2, _08093900 @ =0x02000000\n\ + ldrb r1, [r2, 0x3]\n\ + cmp r1, 0\n\ + beq _08093904\n\ + movs r0, 0x5\n\ + b _0809390C\n\ + .align 2, 0\n\ +_08093900: .4byte 0x02000000\n\ +_08093904:\n\ + movs r0, 0x1\n\ + eors r0, r1\n\ + strb r0, [r2, 0x3]\n\ + movs r0, 0x3\n\ +_0809390C:\n\ + strb r0, [r2]\n\ + movs r0, 0x1\n\ + b _08093914\n\ +_08093912:\n\ + movs r0, 0\n\ +_08093914:\n\ + pop {r1}\n\ + bx r1\n\ + .syntax divided\n"); +} + +bool8 sub_8093918() { + sub_8093A28(); + PlaySE(SE_CARD); + + unk_2000000.var_0 += TRUE; + + return FALSE; +} + +bool8 sub_8093938() { + if (sub_8093A48()) { + unk_2000000.var_0 = 2; + } + + return FALSE; +} + +__attribute__((naked)) +bool8 sub_8093954() { + asm(".syntax unified\n\ + push {lr}\n\ + sub sp, 0x4\n\ + bl sub_80939C0\n\ + movs r0, 0x1\n\ + negs r0, r0\n\ + movs r1, 0\n\ + str r1, [sp]\n\ + movs r2, 0\n\ + movs r3, 0x10\n\ + bl BeginNormalPaletteFade\n\ + ldr r1, _0809397C @ =0x02000000\n\ + ldrb r0, [r1]\n\ + adds r0, 0x1\n\ + strb r0, [r1]\n\ + movs r0, 0\n\ + add sp, 0x4\n\ + pop {r1}\n\ + bx r1\n\ + .align 2, 0\n\ +_0809397C: .4byte 0x02000000\n\ + .syntax divided\n"); +} + +bool8 sub_8093980() { + if (!gPaletteFade.active) { + SetMainCallback2((MainCallback) unk_2000000.var_60); + } + + return FALSE; +} + +static void sub_80939A4(void) { + CreateTask(sub_80939DC, 0); + BasicInitMenuWindow(&WindowConfig_TrainerCard_Back_Values); +} + +static void sub_80939C0(void) { + u8 taskId; + + taskId = FindTaskIdByFunc(sub_80939DC); + + if (taskId != 0xFF) { + DestroyTask(taskId); + } +} + +static void sub_80939DC(u8 taskId) { + u8 buffer[32]; + struct Task *task; + task = &gTasks[taskId]; + + if (unk_2000000.var_5 != task->data[TD_1]) { + task->data[TD_1] = unk_2000000.var_5; + task->data[TD_0] ^= TRUE; + } + + TrainerCard_Front_PrintPlayTime(buffer, task->data[TD_0]); + MenuPrint(buffer, 10, 12); +} + +static void sub_8093A28(void) { + u8 taskId; + + taskId = CreateTask(sub_8093A68, 0); + sub_8093A68(taskId); +} + +__attribute__((naked)) +static u8 sub_8093A48() { + asm(".syntax unified\n\ + push {lr}\n\ + ldr r0, _08093A5C @ =sub_8093A68\n\ + bl FindTaskIdByFunc\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + cmp r0, 0xFF\n\ + beq _08093A60\n\ + movs r0, 0\n\ + b _08093A62\n\ + .align 2, 0\n\ +_08093A5C: .4byte sub_8093A68\n\ +_08093A60:\n\ + movs r0, 0x1\n\ +_08093A62:\n\ + pop {r1}\n\ + bx r1\n\ + .syntax divided\n"); +} + +__attribute__((naked)) +static void sub_8093A68(u8 taskId) { + asm(".syntax unified\n\ + push {r4,r5,lr}\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + ldr r5, _08093A98 @ =gUnknown_083B5ED8\n\ + ldr r2, _08093A9C @ =gTasks\n\ + lsls r1, r0, 2\n\ + adds r1, r0\n\ + lsls r1, 3\n\ + adds r4, r1, r2\n\ +_08093A7A:\n\ + movs r1, 0x8\n\ + ldrsh r0, [r4, r1]\n\ + lsls r0, 2\n\ + adds r0, r5\n\ + ldr r1, [r0]\n\ + adds r0, r4, 0\n\ + bl _call_via_r1\n\ + lsls r0, 24\n\ + cmp r0, 0\n\ + bne _08093A7A\n\ + pop {r4,r5}\n\ + pop {r0}\n\ + bx r0\n\ + .align 2, 0\n\ +_08093A98: .4byte gUnknown_083B5ED8\n\ +_08093A9C: .4byte gTasks\n\ + .syntax divided\n"); +} + +__attribute__((naked)) +bool8 sub_8093AA0() { + asm(".syntax unified\n\ + push {r4,lr}\n\ + adds r4, r0, 0\n\ + ldr r0, _08093AE0 @ =0x02000000\n\ + movs r1, 0\n\ + strb r1, [r0, 0x4]\n\ + bl dp12_8087EA4\n\ + movs r1, 0\n\ + ldr r0, _08093AE4 @ =gUnknown_03004DE0\n\ + ldr r2, _08093AE8 @ =0x0000fffc\n\ + movs r3, 0xF0\n\ + lsls r3, 3\n\ + adds r0, r3\n\ +_08093ABA:\n\ + strh r2, [r0]\n\ + adds r0, 0x2\n\ + adds r1, 0x1\n\ + cmp r1, 0x9F\n\ + bls _08093ABA\n\ + ldr r0, _08093AEC @ =sub_8093D7C\n\ + bl SetHBlankCallback\n\ + ldr r1, _08093AE0 @ =0x02000000\n\ + movs r0, 0x1\n\ + strb r0, [r1, 0x4]\n\ + ldrh r0, [r4, 0x8]\n\ + adds r0, 0x1\n\ + strh r0, [r4, 0x8]\n\ + movs r0, 0\n\ + pop {r4}\n\ + pop {r1}\n\ + bx r1\n\ + .align 2, 0\n\ +_08093AE0: .4byte 0x02000000\n\ +_08093AE4: .4byte gUnknown_03004DE0\n\ +_08093AE8: .4byte 0x0000fffc\n\ +_08093AEC: .4byte sub_8093D7C\n\ + .syntax divided\n"); +} + +__attribute__((naked)) +bool8 sub_8093AF0() { + 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 @ =0x02000000\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 @ =gUnknown_03004DE0\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 @ =gUnknown_03004DE0\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 @ =gUnknown_03004DE0\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 @ =0x02000000\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 0x02000000\n\ +_08093C00: .4byte 0xffff0000\n\ +_08093C04: .4byte gUnknown_03004DE0\n\ +_08093C08: .4byte 0x0000fffc\n\ + .syntax divided\n"); +} + +bool8 sub_8093C0C(struct TrainerCard *trainerCard) { + sub_80939C0(); + sub_8093DAC(); + + if (!unk_2000000.var_3) { + sub_80939A4(); + } + + trainerCard->firstHallOfFameB += 1; + + return TRUE; +} + +__attribute__((naked)) +bool8 sub_8093C38() { + 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 @ =0x02000000\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 @ =gUnknown_03004DE0\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 @ =gUnknown_03004DE0\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 @ =gUnknown_03004DE0\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 @ =0x02000000\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 0x02000000\n\ +_08093D44: .4byte 0xffff0000\n\ +_08093D48: .4byte gUnknown_03004DE0\n\ +_08093D4C: .4byte 0x0000fffc\n\ + .syntax divided\n"); +} + +bool8 sub_8093D50(void) { + u8 taskId; + + unk_2000000.var_4 = FALSE; + SetHBlankCallback(NULL); + sub_8093E04(); + + taskId = FindTaskIdByFunc(sub_8093A68); + DestroyTask(taskId); + + return FALSE; +} + +__attribute__((naked)) +void sub_8093D7C(void) { + asm(".syntax unified\n\ + ldr r1, _08093DA0 @ =gUnknown_03004DE0\n\ + ldr r0, _08093DA4 @ =REG_VCOUNT\n\ + ldrh r2, [r0]\n\ + movs r0, 0xFF\n\ + ands r0, r2\n\ + lsls r0, 1\n\ + movs r2, 0xF0\n\ + lsls r2, 3\n\ + adds r1, r2\n\ + adds r0, r1\n\ + ldrh r1, [r0]\n\ + ldr r0, _08093DA8 @ =REG_BG0VOFS\n\ + strh r1, [r0]\n\ + adds r0, 0x4\n\ + strh r1, [r0]\n\ + adds r0, 0x4\n\ + strh r1, [r0]\n\ + bx lr\n\ + .align 2, 0\n\ +_08093DA0: .4byte gUnknown_03004DE0\n\ +_08093DA4: .4byte 0x4000006 @ REG_VCOUNT\n\ +_08093DA8: .4byte 0x4000012 @ REG_BG0VOFS\n\ + .syntax divided\n"); +} + +static void sub_8093DAC(void) { + if (unk_2000000.var_3) { + sub_8093DEC(); + } else { + sub_8093DC8(); + } +} + +static void sub_8093DC8(void) { + MenuZeroFillScreen(); + sub_80940E4(); + sub_8093F14(); + sub_8093F80(); + sub_8093FD0(); + sub_8094038(); + sub_8094140(); +} + +static void sub_8093DEC(void) { + MenuZeroFillScreen(); + sub_80940E4(); + sub_8093F48(); + sub_8094188(); +} + +__attribute__((naked)) +static void sub_8093E04() { + asm(".syntax unified\n\ + ldr r0, _08093E20 @ =REG_BG0VOFS\n\ + ldr r2, _08093E24 @ =0x0000fffc\n\ + adds r1, r2, 0\n\ + strh r1, [r0]\n\ + adds r0, 0x2\n\ + movs r2, 0\n\ + strh r2, [r0]\n\ + adds r0, 0x2\n\ + strh r1, [r0]\n\ + adds r0, 0x2\n\ + strh r2, [r0]\n\ + adds r0, 0x2\n\ + strh r1, [r0]\n\ + bx lr\n\ + .align 2, 0\n\ +_08093E20: .4byte 0x4000012 @ REG_BG0VOFS\n\ +_08093E24: .4byte 0x0000fffc\n\ + .syntax divided\n"); +} + +__attribute__((naked)) +static void sub_8093E28(void) { + asm(".syntax unified\n\ + push {r4-r7,lr}\n\ + bl sub_8093EA0\n\ + ldr r0, _08093E84 @ =gUnknown_083B5F6C\n\ + movs r1, 0xE0\n\ + movs r2, 0x20\n\ + bl LoadPalette\n\ + ldr r3, _08093E88 @ =gMenuTrainerCard_Gfx\n\ + movs r4, 0xC0\n\ + lsls r4, 19\n\ + movs r5, 0xA4\n\ + lsls r5, 5\n\ + ldr r1, _08093E8C @ =0x040000d4\n\ + ldr r6, _08093E90 @ =0x80000800\n\ + movs r2, 0x80\n\ + lsls r2, 5\n\ + movs r7, 0x80\n\ + lsls r7, 24\n\ +_08093E4E:\n\ + str r3, [r1]\n\ + str r4, [r1, 0x4]\n\ + str r6, [r1, 0x8]\n\ + ldr r0, [r1, 0x8]\n\ + adds r3, r2\n\ + adds r4, r2\n\ + subs r5, r2\n\ + cmp r5, r2\n\ + bhi _08093E4E\n\ + str r3, [r1]\n\ + str r4, [r1, 0x4]\n\ + lsrs r0, r5, 1\n\ + orrs r0, r7\n\ + str r0, [r1, 0x8]\n\ + ldr r0, [r1, 0x8]\n\ + ldr r1, _08093E94 @ =gBadgesTiles\n\ + ldr r2, _08093E98 @ =0x06001480\n\ + ldr r0, _08093E8C @ =0x040000d4\n\ + str r1, [r0]\n\ + str r2, [r0, 0x4]\n\ + ldr r1, _08093E9C @ =0x80000200\n\ + str r1, [r0, 0x8]\n\ + ldr r0, [r0, 0x8]\n\ + pop {r4-r7}\n\ + pop {r0}\n\ + bx r0\n\ + .align 2, 0\n\ +_08093E84: .4byte gUnknown_083B5F6C\n\ +_08093E88: .4byte gMenuTrainerCard_Gfx\n\ +_08093E8C: .4byte 0x040000d4\n\ +_08093E90: .4byte 0x80000800\n\ +_08093E94: .4byte gBadgesTiles\n\ +_08093E98: .4byte 0x06001480\n\ +_08093E9C: .4byte 0x80000200\n\ + .syntax divided\n"); +} + +void sub_8093EA0(void) { + LoadPalette(gUnknown_083B5EF8[unk_2000000.var_2], 0, 48 * 2); + LoadPalette(gBadgesPalette, 48, 16 * 2); + LoadPalette(gUnknown_083B5F4C, 64, 16 * 2); + + if (unk_2000000.var_64.gender != MALE) { + LoadPalette(gUnknown_083B5F0C, 16, 16 * 2); + } +} + +static void sub_8093EF8(void) { + LoadTrainerGfx_TrainerCard(unk_2000000.var_64.gender, 80, (void *) (VRAM + 0x1880)); +} + +__attribute__((naked)) +static void sub_8093F14(void) { + asm(".syntax unified\n\ + push {lr}\n\ + sub sp, 0x8\n\ + ldr r0, _08093F3C @ =gUnknown_083B5EEC\n\ + ldr r1, [r0, 0x4]\n\ + ldr r0, [r0]\n\ + str r0, [sp]\n\ + str r1, [sp, 0x4]\n\ + ldr r0, _08093F40 @ =0x02000000\n\ + ldrb r0, [r0, 0x1]\n\ + lsls r0, 2\n\ + add r0, sp\n\ + ldr r0, [r0]\n\ + ldr r1, _08093F44 @ =0x06004800\n\ + movs r2, 0xA0\n\ + lsls r2, 1\n\ + bl CpuFastSet\n\ + add sp, 0x8\n\ + pop {r0}\n\ + bx r0\n\ + .align 2, 0\n\ +_08093F3C: .4byte gUnknown_083B5EEC\n\ +_08093F40: .4byte 0x02000000\n\ +_08093F44: .4byte 0x06004800\n\ + .syntax divided\n"); +} + +static void sub_8093F48(void) { + CpuFastSet(gUnknown_08E8CFC0, (void *) (VRAM + 0x4800), 320); +} + +static void sub_8093F64(void) { + CpuFastSet(gUnknown_08E8D9C0, (void *) (VRAM + 0x5000), 320); +} + +__attribute__((naked)) +static void sub_8093F80(void) { + asm(".syntax unified\n\ + push {r4-r7,lr}\n\ + movs r5, 0xC4\n\ + ldr r7, _08093FCC @ =0x06004000\n\ + movs r1, 0x5\n\ + movs r0, 0xA0\n\ + lsls r0, 7\n\ + adds r6, r0, 0\n\ +_08093F8E:\n\ + movs r0, 0x13\n\ + lsls r3, r1, 16\n\ + asrs r4, r3, 11\n\ +_08093F94:\n\ + lsls r2, r0, 16\n\ + asrs r2, 16\n\ + adds r1, r4, r2\n\ + lsls r1, 1\n\ + adds r1, r7\n\ + adds r0, r5, 0\n\ + orrs r0, r6\n\ + strh r0, [r1]\n\ + adds r2, 0x1\n\ + lsls r2, 16\n\ + adds r0, r5, 0x1\n\ + lsls r0, 16\n\ + lsrs r5, r0, 16\n\ + lsrs r0, r2, 16\n\ + asrs r2, 16\n\ + cmp r2, 0x1A\n\ + ble _08093F94\n\ + movs r1, 0x80\n\ + lsls r1, 9\n\ + adds r0, r3, r1\n\ + lsrs r1, r0, 16\n\ + asrs r0, 16\n\ + cmp r0, 0xC\n\ + ble _08093F8E\n\ + pop {r4-r7}\n\ + pop {r0}\n\ + bx r0\n\ + .align 2, 0\n\ +_08093FCC: .4byte 0x06004000\n\ + .syntax divided\n"); +} + +__attribute__((naked)) +static void sub_8093FD0(void) { + asm(".syntax unified\n\ + push {r4-r6,lr}\n\ + ldr r4, _0809402C @ =0x06004000\n\ + movs r2, 0xF\n\ + ldr r0, _08094030 @ =0x02000000\n\ + ldrb r0, [r0, 0x2]\n\ + adds r0, 0xF\n\ + cmp r2, r0\n\ + bge _08094002\n\ + movs r6, 0xC0\n\ + lsls r6, 1\n\ + ldr r1, _08094034 @ =0x0000408f\n\ + adds r5, r1, 0\n\ + adds r3, r0, 0\n\ +_08093FEA:\n\ + lsls r1, r2, 16\n\ + asrs r1, 16\n\ + lsls r0, r1, 1\n\ + adds r0, r4\n\ + adds r0, r6\n\ + strh r5, [r0]\n\ + adds r1, 0x1\n\ + lsls r1, 16\n\ + lsrs r2, r1, 16\n\ + asrs r1, 16\n\ + cmp r1, r3\n\ + blt _08093FEA\n\ +_08094002:\n\ + lsls r1, r2, 16\n\ + asrs r0, r1, 16\n\ + cmp r0, 0x12\n\ + bgt _08094024\n\ + movs r3, 0xC0\n\ + lsls r3, 1\n\ + movs r2, 0\n\ +_08094010:\n\ + asrs r0, r1, 16\n\ + lsls r1, r0, 1\n\ + adds r1, r4\n\ + adds r1, r3\n\ + strh r2, [r1]\n\ + adds r0, 0x1\n\ + lsls r1, r0, 16\n\ + asrs r0, r1, 16\n\ + cmp r0, 0x12\n\ + ble _08094010\n\ +_08094024:\n\ + pop {r4-r6}\n\ + pop {r0}\n\ + bx r0\n\ + .align 2, 0\n\ +_0809402C: .4byte 0x06004000\n\ +_08094030: .4byte 0x02000000\n\ +_08094034: .4byte 0x0000408f\n\ + .syntax divided\n"); +} + +__attribute__((naked)) +static void sub_8094038(void) { + asm(".syntax unified\n\ + push {r4-r7,lr}\n\ + mov r7, r9\n\ + mov r6, r8\n\ + push {r6,r7}\n\ + ldr r1, _080940D0 @ =0x02000000\n\ + ldrb r0, [r1, 0x1]\n\ + cmp r0, 0\n\ + bne _080940C2\n\ + ldr r0, _080940D4 @ =0x06004000\n\ + mov r9, r0\n\ + movs r0, 0\n\ + movs r2, 0x4\n\ + adds r1, 0xE\n\ + mov r8, r1\n\ + ldr r7, _080940D8 @ =gUnknown_083B5F8C\n\ + movs r1, 0xC0\n\ + lsls r1, 6\n\ + adds r6, r1, 0\n\ + adds r1, r7, 0x6\n\ + mov r12, r1\n\ +_08094060:\n\ + lsls r0, 16\n\ + asrs r4, r0, 16\n\ + mov r1, r8\n\ + adds r0, r4, r1\n\ + ldrb r0, [r0]\n\ + lsls r5, r2, 16\n\ + cmp r0, 0\n\ + beq _080940AE\n\ + asrs r1, r5, 15\n\ + add r1, r9\n\ + movs r2, 0xF0\n\ + lsls r2, 2\n\ + adds r3, r1, r2\n\ + lsls r2, r4, 3\n\ + adds r0, r2, r7\n\ + ldrh r0, [r0]\n\ + orrs r0, r6\n\ + strh r0, [r3]\n\ + ldr r0, _080940DC @ =0x000003c2\n\ + adds r3, r1, r0\n\ + adds r0, r7, 0x2\n\ + adds r0, r2, r0\n\ + ldrh r0, [r0]\n\ + orrs r0, r6\n\ + strh r0, [r3]\n\ + movs r0, 0x80\n\ + lsls r0, 3\n\ + adds r3, r1, r0\n\ + adds r0, r7, 0x4\n\ + adds r0, r2, r0\n\ + ldrh r0, [r0]\n\ + orrs r0, r6\n\ + strh r0, [r3]\n\ + ldr r0, _080940E0 @ =0x00000402\n\ + adds r1, r0\n\ + add r2, r12\n\ + ldrh r0, [r2]\n\ + orrs r0, r6\n\ + strh r0, [r1]\n\ +_080940AE:\n\ + adds r1, r4, 0x1\n\ + lsls r1, 16\n\ + movs r2, 0xC0\n\ + lsls r2, 10\n\ + adds r0, r5, r2\n\ + lsrs r2, r0, 16\n\ + lsrs r0, r1, 16\n\ + asrs r1, 16\n\ + cmp r1, 0x7\n\ + ble _08094060\n\ +_080940C2:\n\ + pop {r3,r4}\n\ + mov r8, r3\n\ + mov r9, r4\n\ + pop {r4-r7}\n\ + pop {r0}\n\ + bx r0\n\ + .align 2, 0\n\ +_080940D0: .4byte 0x02000000\n\ +_080940D4: .4byte 0x06004000\n\ +_080940D8: .4byte gUnknown_083B5F8C\n\ +_080940DC: .4byte 0x000003c2\n\ +_080940E0: .4byte 0x00000402\n\ + .syntax divided\n"); +} + +__attribute__((naked)) +static void sub_80940E4() { + asm(".syntax unified\n\ + push {r4,lr}\n\ + movs r2, 0\n\ + ldr r1, _08094108 @ =0x06004000\n\ + movs r4, 0\n\ + ldr r3, _0809410C @ =0x000003ff\n\ +_080940EE:\n\ + strh r4, [r1]\n\ + lsls r0, r2, 16\n\ + movs r2, 0x80\n\ + lsls r2, 9\n\ + adds r0, r2\n\ + adds r1, 0x2\n\ + lsrs r2, r0, 16\n\ + asrs r0, 16\n\ + cmp r0, r3\n\ + ble _080940EE\n\ + pop {r4}\n\ + pop {r0}\n\ + bx r0\n\ + .align 2, 0\n\ +_08094108: .4byte 0x06004000\n\ +_0809410C: .4byte 0x000003ff\n\ + .syntax divided\n"); +} + +__attribute__((naked)) +static void sub_8094110() { + asm(".syntax unified\n\ + push {r4-r6,lr}\n\ + ldr r6, _0809413C @ =0x06004800\n\ + movs r2, 0x3\n\ + movs r5, 0xA0\n\ + lsls r5, 2\n\ + movs r3, 0x1\n\ + movs r4, 0xB0\n\ + lsls r4, 2\n\ +_08094120:\n\ + lsls r0, r2, 1\n\ + adds r0, r6\n\ + adds r1, r0, r5\n\ + strh r3, [r1]\n\ + adds r0, r4\n\ + strh r3, [r0]\n\ + adds r0, r2, 0x1\n\ + lsls r0, 16\n\ + lsrs r2, r0, 16\n\ + cmp r2, 0x10\n\ + bls _08094120\n\ + pop {r4-r6}\n\ + pop {r0}\n\ + bx r0\n\ + .align 2, 0\n\ +_0809413C: .4byte 0x06004800\n\ + .syntax divided\n"); +} + + +static void sub_8094140(void) { + u8 *buffer; + + BasicInitMenuWindow(&WindowConfig_TrainerCard_Back_Values); + + buffer = gStringVar1; + StringCopy(buffer, unk_2000000.var_64.playerName); + ConvertInternationalString(buffer, unk_2000000.language); + MenuPrint(buffer, 7, 5); + + TrainerCard_Front_PrintTrainerID(); + TrainerCard_Front_PrintMoney(); + TrainerCard_Front_PrintPokedexCount(); + sub_809429C(); +} + +static void sub_8094188(void) { + BasicInitMenuWindow(&WindowConfig_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(&WindowConfig_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, unk_2000000.var_64.trainerId, STR_CONV_MODE_LEADING_ZEROS, 5); + MenuPrint(buffer, 20, 2); +} + +static void TrainerCard_Front_PrintMoney(void) { + sub_80B7AEC(unk_2000000.var_64.money, 16, 8); +} + +static void TrainerCard_Front_PrintPokedexCount(void) { + u8 buffer[16]; + + if (unk_2000000.var_7 == FALSE) { + sub_8094110(); + return; + } + + ConvertIntToDecimalStringN(buffer, unk_2000000.var_64.pokedexSeen, STR_CONV_MODE_LEFT_ALIGN, 3); + MenuPrint_RightAligned(buffer, 16, 10); +} + +static void TrainerCard_Front_PrintPlayTime(u8 *arg1, s16 colon) { + u8 buffer[16]; + u16 playTimeHours; + u16 playTimeMinutes; + + playTimeHours = gSaveBlock2.playTimeHours; + playTimeMinutes = gSaveBlock2.playTimeMinutes; + + if (unk_2000000.var_1 != 0) { + playTimeHours = unk_2000000.var_64.playTimeHours; + playTimeMinutes = unk_2000000.var_64.playTimeMinutes; + } + + FormatPlayTime(buffer, playTimeHours, playTimeMinutes, colon); + sub_8072C74(arg1, buffer, 48, 1); +} + +static void sub_809429C(void) { + u8 *bufferPtr; + + if (unk_2000000.var_1 == FALSE) { + return; + } + + bufferPtr = gStringVar1; + bufferPtr = StringCopy(bufferPtr, unk_2000000.var_20[0]); + bufferPtr[0] = 00; + bufferPtr++; + bufferPtr = StringCopy(bufferPtr, unk_2000000.var_20[1]); + MenuPrint(gStringVar1, 2, 14); + + bufferPtr = gStringVar1; + bufferPtr = StringCopy(bufferPtr, unk_2000000.var_20[2]); + bufferPtr[0] = 00; + bufferPtr++; + bufferPtr = StringCopy(bufferPtr, unk_2000000.var_20[3]); + MenuPrint(gStringVar1, 2, 16); +} + +static void TrainerCard_Back_PrintName(void) { + u8 *bufferPtr; + + bufferPtr = gStringVar1; + StringCopy(bufferPtr, unk_2000000.var_64.playerName); + ConvertInternationalString(bufferPtr, unk_2000000.language); + + StringAppend(bufferPtr, gOtherText_TrainersTrainerCard); + + MenuPrint_RightAligned(gStringVar1, 28, 2); +} + +static void TrainerCard_Back_PrintHallOfFameTime_Label(void) { + if (unk_2000000.var_8 == FALSE) { + return; + } + + MenuPrint(gOtherText_FirstHOF, 3, 5); +} + +static void TrainerCard_Back_PrintHallOfFameTime(void) { + u8 *bufferPtr; + + if (unk_2000000.var_8 == FALSE) { + return; + } + + bufferPtr = gStringVar1; + bufferPtr = ConvertIntToDecimalStringN(bufferPtr, unk_2000000.var_64.firstHallOfFameA, STR_CONV_MODE_RIGHT_ALIGN, + 3); + bufferPtr = StringCopy(bufferPtr, gUnknown_083B5EF4); + bufferPtr = ConvertIntToDecimalStringN(bufferPtr, unk_2000000.var_64.firstHallOfFameB, STR_CONV_MODE_LEADING_ZEROS, + 2); + bufferPtr = StringCopy(bufferPtr, gUnknown_083B5EF4); + bufferPtr = ConvertIntToDecimalStringN(bufferPtr, unk_2000000.var_64.firstHallOfFameC, STR_CONV_MODE_LEADING_ZEROS, + 2); + + MenuPrint_RightAligned(gStringVar1, 28, 5); +} + +static void TrainerCard_Back_PrintLinkBattlesLabel(void) { + if (unk_2000000.var_9 == FALSE) { + return; + } + + MenuPrint(gOtherText_LinkCableBattles, 3, 7); +} + +static void TrainerCard_Back_PrintLinkBattles(void) { + u8 buffer[16]; + + if (unk_2000000.var_9 == FALSE) { + return; + } + + ConvertIntToDecimalString(buffer, unk_2000000.var_64.linkBattleWins); + MenuPrint_RightAligned(buffer, 22, 7); + + ConvertIntToDecimalString(buffer, unk_2000000.var_64.linkBattleLosses); + MenuPrint_RightAligned(buffer, 28, 7); +} + +static void TrainerCard_Back_PrintBattleTower_Label(void) { + if (unk_2000000.var_a == FALSE) { + return; + } + + MenuPrint(gOtherText_BattleTowerWinRecord, 3, 15); +} + +static void TrainerCard_Back_PrintBattleTower(void) { + u8 buffer[16]; + + if (unk_2000000.var_a == FALSE) { + return; + } + + sub_8072C44(buffer, unk_2000000.var_64.battleTowerWins, 24, 1); + MenuPrint_PixelCoords(buffer, 112, 120, 0); + + sub_8072C44(buffer, unk_2000000.var_64.battleTowerLosses, 24, 1); + MenuPrint_PixelCoords(buffer, 149, 120, 0); +} + +static void TrainerCard_Back_PrintLinkContests_Label(void) { + if (unk_2000000.var_b == FALSE) { + return; + } + + MenuPrint(gOtherText_ContestRecord, 3, 13); +} + +static void TrainerCard_Back_PrintLinkContests(void) { + u8 buffer[8]; + + if (unk_2000000.var_b == FALSE) { + return; + } + + ConvertIntToDecimalStringN(buffer, unk_2000000.var_64.contestsWithFriends, STR_CONV_MODE_RIGHT_ALIGN, 3); + MenuPrint_RightAligned(buffer, 28, 13); +} + +static void TrainerCard_Back_PrintLinkPokeblocks_Label(void) { + if (unk_2000000.var_c == FALSE) { + return; + } + + MenuPrint(gOtherText_MixingRecord, 3, 11); +} + +static void TrainerCard_Back_PrintLinkPokeblocks(void) { + u8 buffer[8]; + + if (unk_2000000.var_c == FALSE) { + return; + } + + ConvertIntToDecimalStringN(buffer, unk_2000000.var_64.pokeblocksWithFriends, STR_CONV_MODE_RIGHT_ALIGN, 5); + MenuPrint_RightAligned(buffer, 28, 11); +} + +static void TrainerCard_Back_PrintPokemonTrades_Label(void) { + if (unk_2000000.var_d == FALSE) { + return; + } + + MenuPrint(gOtherText_TradeRecord, 3, 9); +} + +static void TrainerCard_Back_PrintPokemonTrades(void) { + u8 buffer[8]; + + if (unk_2000000.var_d == FALSE) { + return; + } + + ConvertIntToDecimalStringN(buffer, unk_2000000.var_64.pokemonTrades, STR_CONV_MODE_RIGHT_ALIGN, 5); + MenuPrint_RightAligned(buffer, 28, 9); +} + +void unref_sub_8094588(u16 left, u16 top) { + u8 *text = gOtherText_Boy; + + if (gSaveBlock2.playerGender == FEMALE) { + text = gOtherText_Girl; + } + + MenuPrint(text, (u8) left, (u8) top); +} diff --git a/src/trainer_see.c b/src/trainer_see.c index 968f7c0a1..c6cdc5658 100644 --- a/src/trainer_see.c +++ b/src/trainer_see.c @@ -1,28 +1,14 @@ #include "global.h" -#include "fieldmap.h" +#include "trainer_see.h" +#include "asm.h" +#include "battle_setup.h" +#include "field_player_avatar.h" +#include "field_map_obj.h" +#include "asm_fieldmap.h" #include "task.h" #include "sprite.h" - -extern u8 * GetFieldObjectScriptPointerByFieldObjectId(u8); -extern u8 * GetTrainerFlagFromScriptPointer(u8 *); -extern u8 TrainerCanApproachPlayer(struct MapObject *); -extern u8 sub_8060024(struct MapObject *, s16, s16, u8); -extern u8 npc_block_way(struct MapObject *, s16, s16, u8); -extern u8 npc_running_behaviour_by_direction(u8); -extern u8 GetGoSpeed0AnimId(u8); -extern u8 GetOppositeDirection(u8); -extern u8 GetFaceDirectionAnimId(u8); -extern bool8 FieldEffectActiveListContains(u8); -extern bool8 FieldObjectIsSpecialAnimOrDirectionSequenceAnimActive(struct MapObject *); -extern bool8 FieldObjectCheckIfSpecialAnimFinishedOrInactive(struct MapObject *); -extern bool8 FieldObjectClearAnimIfSpecialAnimFinished(struct MapObject *); -extern void FieldObjectClearAnim(struct MapObject *); -extern void TrainerWantsBattle(u8, u8 *); -extern void FieldObjectSetSpecialAnim(struct MapObject *, u8); -extern void LoadWordFromTwoHalfwords(u32, u8 *); -extern void StoreWordInTwoHalfwords(u32, u8 *); - -extern void sub_80842FC(void (*func)(u8)); +#include "field_effect.h" +#include "script.h" extern bool8 (*gIsTrainerInRange[])(struct MapObject *, u16, s16, s16); extern bool8 (*gTrainerSeeFuncList[])(u8, struct Task *, struct MapObject *); @@ -30,16 +16,13 @@ extern bool8 (*gTrainerSeeFuncList2[])(u8, struct Task *, struct MapObject *); extern u32 gUnknown_0202FF84[]; -bool8 CheckTrainer(u8); -bool8 CheckPathBetweenTrainerAndPlayer(struct MapObject2 *, u8, u8); -void sub_80842C8(struct MapObject *, u8); -void RunTrainerSeeFuncList(u8); -void sub_80847D8(u8); +extern struct SpriteTemplate gSpriteTemplate_839B510; +extern struct SpriteTemplate gSpriteTemplate_839B528; bool8 CheckTrainers(void) { u8 i; - + for(i = 0; i < 16; i++) { if ( gMapObjects[i].active ) @@ -79,19 +62,19 @@ bool8 TrainerCanApproachPlayer(struct MapObject *trainerObj) s16 x, y; u8 i; u8 playerCoord; - + PlayerGetDestCoords(&x, &y); if ( trainerObj->trainerType == 1 ) // trainers that don't spin { playerCoord = gIsTrainerInRange[trainerObj->mapobj_unk_18 - 1](trainerObj, trainerObj->trainerRange_berryTreeId, x, y); - return CheckPathBetweenTrainerAndPlayer(trainerObj, playerCoord, trainerObj->mapobj_unk_18); + return CheckPathBetweenTrainerAndPlayer((struct MapObject2 *)trainerObj, playerCoord, trainerObj->mapobj_unk_18); } else // spinners { for(i = 0; i < 4; i++) { playerCoord = gIsTrainerInRange[i](trainerObj, trainerObj->trainerRange_berryTreeId, x, y); - if ( CheckPathBetweenTrainerAndPlayer(trainerObj, playerCoord, i + 1) ) // directions are 1-4 instead of 0-3. south north west east + if ( CheckPathBetweenTrainerAndPlayer((struct MapObject2 *)trainerObj, playerCoord, i + 1) ) // directions are 1-4 instead of 0-3. south north west east return playerCoord; } return FALSE; @@ -138,6 +121,12 @@ bool8 IsTrainerInRangeEast(struct MapObject *trainerObj, s16 vision, s16 x, s16 return FALSE; } +#ifdef BUGFIX_TRAINERAPPROACH +#define COLLISION_MASK ~1 +#else +#define COLLISION_MASK 1 +#endif + bool8 CheckPathBetweenTrainerAndPlayer(struct MapObject2 *trainerObj, u8 playerCoord, u8 direction) { s16 x, y; @@ -146,21 +135,18 @@ bool8 CheckPathBetweenTrainerAndPlayer(struct MapObject2 *trainerObj, u8 playerC u8 i; u8 var; - if ( !playerCoord ) + if (!playerCoord) return FALSE; x = trainerObj->coords2.x; y = trainerObj->coords2.y; - for(i = 0; i <= playerCoord - 1;) + for (i = 0; i <= playerCoord - 1; i++, MoveCoords(direction, &x, &y)) { - var = sub_8060024(trainerObj, x, y, direction); + var = sub_8060024((struct MapObject *)trainerObj, x, y, direction); - if (var != 0 && (var & 1) != 0 ) + if (var && (var & COLLISION_MASK)) return FALSE; - - i++; - MoveCoords(direction, &x, &y); } // preserve mapobj_unk_19 before clearing. @@ -169,11 +155,11 @@ bool8 CheckPathBetweenTrainerAndPlayer(struct MapObject2 *trainerObj, u8 playerC trainerObj->mapobj_unk_19 = 0; trainerObj->mapobj_unk_19b = 0; - var = npc_block_way(trainerObj, x, y, direction); + var = npc_block_way((struct MapObject *)trainerObj, x, y, direction); trainerObj->mapobj_unk_19 = unk19_temp; trainerObj->mapobj_unk_19b = unk19b_temp; - if ( var == 4 ) + if (var == 4) return playerCoord; return FALSE; @@ -192,7 +178,7 @@ void sub_80842FC(TaskFunc func) { TaskFunc func2 = RunTrainerSeeFuncList; u8 taskId = FindTaskIdByFunc(func2); - + SetTaskFuncWithFollowupFunc(taskId, RunTrainerSeeFuncList, func); gTasks[taskId].data[0] = 1; func2(taskId); @@ -201,7 +187,7 @@ void sub_80842FC(TaskFunc func) void RunTrainerSeeFuncList(u8 taskId) { struct Task *task = &gTasks[taskId]; - struct MapObject *trainerObj = (task->data[1] << 16) | (task->data[2]); + struct MapObject *trainerObj = (struct MapObject *)((task->data[1] << 16) | (task->data[2])); if (!trainerObj->active) SwitchTaskToFollowupFunc(taskId); @@ -218,9 +204,9 @@ s8 sub_8084398(u8 taskId, struct Task *task, struct MapObject *trainerObj) { u8 direction; - FieldObjectGetLocalIdAndMap(trainerObj, &gUnknown_0202FF84[0], &gUnknown_0202FF84[1], &gUnknown_0202FF84[2]); + FieldObjectGetLocalIdAndMap(trainerObj, (u8 *)&gUnknown_0202FF84[0], (u8 *)&gUnknown_0202FF84[1], (u8 *)&gUnknown_0202FF84[2]); FieldEffectStart(0); - + direction = GetFaceDirectionAnimId(trainerObj->mapobj_unk_18); FieldObjectSetSpecialAnim(trainerObj, direction); @@ -286,17 +272,17 @@ s8 sub_8084478(u8 taskId, struct Task *task, struct MapObject *trainerObj) s8 sub_8084534(u8 taskId, struct Task *task, struct MapObject *trainerObj) // technically only 1 parameter, but needs all 3 for TrainerSeeFuncList call. { struct MapObject *playerObj = &gMapObjects[gPlayerAvatar.mapObjectId]; - + if ( !FieldObjectIsSpecialAnimOrDirectionSequenceAnimActive(playerObj) || FieldObjectClearAnimIfSpecialAnimFinished(playerObj) ) SwitchTaskToFollowupFunc(taskId); - + return 0; } s8 sub_8084578(u8 taskId, struct Task *task, struct MapObject *trainerObj) { - if(!FieldObjectIsSpecialAnimOrDirectionSequenceAnimActive(trainerObj) + if(!FieldObjectIsSpecialAnimOrDirectionSequenceAnimActive(trainerObj) || FieldObjectClearAnimIfSpecialAnimFinished(trainerObj)) { FieldObjectSetSpecialAnim(trainerObj, 0x59); @@ -309,13 +295,13 @@ s8 sub_80845AC(u8 taskId, struct Task *task, struct MapObject *trainerObj) { if ( FieldObjectClearAnimIfSpecialAnimFinished(trainerObj) ) task->data[0] = 3; - + return 0; } s8 sub_80845C8(u8 taskId, struct Task *task, struct MapObject *trainerObj) { - if(!FieldObjectIsSpecialAnimOrDirectionSequenceAnimActive(trainerObj) + if(!FieldObjectIsSpecialAnimOrDirectionSequenceAnimActive(trainerObj) || FieldObjectClearAnimIfSpecialAnimFinished(trainerObj)) { FieldObjectSetSpecialAnim(trainerObj, 0x3E); @@ -346,7 +332,7 @@ s8 sub_8084654(u8 taskId, struct Task *task, struct MapObject *trainerObj) { trainerObj->mapobj_bit_26 = 0; trainerObj->mapobj_bit_2 = 1; - + sprite = &gSprites[trainerObj->spriteId]; sprite->oam.priority = 2; FieldObjectClearAnimIfSpecialAnimFinished(trainerObj); @@ -370,7 +356,7 @@ void sub_80846E4(u8 taskId) struct MapObject *mapObj; // another mapObj loaded into by loadword? - LoadWordFromTwoHalfwords(&task->data[1], &mapObj); + LoadWordFromTwoHalfwords(&task->data[1], (u32 *)&mapObj); if(!task->data[7]) { FieldObjectClearAnim(mapObj); @@ -402,3 +388,71 @@ void sub_80847D8(u8 taskId) DestroyTask(taskId); EnableBothScriptContexts(); } + +u8 FldEff_ExclamationMarkIcon1(void) +{ + u8 spriteId = CreateSpriteAtEnd(&gSpriteTemplate_839B510, 0, 0, 0x53); + + if (spriteId != 64) + sub_8084894(&gSprites[spriteId], 0, 0); + + return 0; +} + +u8 FldEff_ExclamationMarkIcon2(void) +{ + u8 spriteId = CreateSpriteAtEnd(&gSpriteTemplate_839B510, 0, 0, 0x52); + + if (spriteId != 64) + sub_8084894(&gSprites[spriteId], 33, 1); + + return 0; +} + +u8 FldEff_HeartIcon(void) +{ + u8 spriteId = CreateSpriteAtEnd(&gSpriteTemplate_839B528, 0, 0, 0x52); + + if (spriteId != 64) + sub_8084894(&gSprites[spriteId], 46, 0); + + return 0; +} + +void sub_8084894(struct Sprite *sprite, u16 a2, u8 a3) +{ + sprite->oam.priority = 1; + sprite->coordOffsetEnabled = 1; + + sprite->data0 = gUnknown_0202FF84[0]; + sprite->data1 = gUnknown_0202FF84[1]; + sprite->data2 = gUnknown_0202FF84[2]; + sprite->data3 = -5; + sprite->data7 = a2; + + StartSpriteAnim(sprite, a3); +} + +void objc_exclamation_mark_probably(struct Sprite *sprite) +{ + u8 mapObjId; + + if (TryGetFieldObjectIdByLocalIdAndMap(sprite->data0, sprite->data1, sprite->data2, &mapObjId) + || sprite->animEnded) + { + FieldEffectStop(sprite, (u8)sprite->data7); + } + else + { + struct Sprite *mapObjSprite = &gSprites[gMapObjects[mapObjId].spriteId]; + sprite->data4 += sprite->data3; + sprite->pos1.x = mapObjSprite->pos1.x; + sprite->pos1.y = mapObjSprite->pos1.y - 16; + sprite->pos2.x = mapObjSprite->pos2.x; + sprite->pos2.y = mapObjSprite->pos2.y + sprite->data4; + if (sprite->data4) + sprite->data3++; + else + sprite->data3 = 0; + } +} diff --git a/src/truck_scene.c b/src/truck_scene.c index 565851856..64eca498c 100644 --- a/src/truck_scene.c +++ b/src/truck_scene.c @@ -1,24 +1,17 @@ #include "global.h" +#include "truck_scene.h" +#include "asm.h" #include "palette.h" #include "task.h" #include "script.h" #include "songs.h" #include "sound.h" +#include "field_camera.h" extern s8 gTruckCamera_HorizontalTable[]; -extern void SetCameraPanning(s16 a1, s16 a2); -extern void sub_805BD90(u8 localId, u8 mapNum, u8 mapGroup, s16 x, s16 y); - -void Task_Truck1(u8 taskId); -void Task_Truck2(u8 taskId); -void Task_Truck3(u8 taskId); -void ExecuteTruckSequence(void); - s32 GetTruckCameraBobbingY(int a1) { - s32 result; - if (!(a1 % 120)) return -1; else if ((a1 % 10) <= 4) @@ -29,8 +22,6 @@ s32 GetTruckCameraBobbingY(int a1) s32 GetTruckBoxMovement(int a1) // for the box movement? { - s32 result; - if (!((a1 + 120) % 180)) return -1; diff --git a/src/tv.c b/src/tv.c new file mode 100644 index 000000000..d2a54a539 --- /dev/null +++ b/src/tv.c @@ -0,0 +1,293 @@ +#include "global.h" +#include "asm.h" +#include "event_data.h" +#include "field_message_box.h" +#include "flags.h" +#include "global.h" +#include "rng.h" +#include "string_util.h" +#include "text.h" + +enum { + TVSHOW_FAN_CLUB_LETTER = 1, + TVSHOW_RECENT_HAPPENINGS = 2, + TVSHOW_PKMN_FAN_CLUB_OPINIONS = 3, + TVSHOW_NAME_RATER_SHOW = 5, + TVSHOW_MASS_OUTBREAK = 41, +}; + +struct UnkTvStruct { + s8 var0; +}; + +struct OutbreakPokemon { + /* 0x00 */ u16 species; + /* 0x02 */ u16 moves[4]; + /* 0x0A */ u8 level; + /* 0x0B */ u8 location; +}; + +extern u16 gSpecialVar_0x8004; +extern u8 gSpecialVar_0x8007; +extern u16 gScriptResult; +extern u8 gUnknown_020387E8; + +extern struct UnkTvStruct gUnknown_03005D38; + +extern u8 gSpeciesNames[][11]; +extern u8 *gTVPokemonOutbreakTextGroup[]; +extern struct OutbreakPokemon gPokeOutbreakSpeciesList[5]; + +void sub_80BE478(void) { + u16 playerNameLength; + u16 pokemonNicknameLength; + TVShow *tvShow; + + sub_80BF478(); + + if (gScriptResult == 1) { + return; + } + + GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_NICKNAME, gStringVar1); + + playerNameLength = StringLength(gSaveBlock2.playerName); + if (playerNameLength <= 1) { + return; + } + + pokemonNicknameLength = StringLength(gStringVar1); + if (pokemonNicknameLength <= 1) { + return; + } + + tvShow = &gSaveBlock1.tvShows[gUnknown_03005D38.var0]; + + tvShow->nameRaterShow.var00 = TVSHOW_NAME_RATER_SHOW; + tvShow->nameRaterShow.var01 = 1; + + tvShow->nameRaterShow.species = GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_SPECIES, NULL); + tvShow->nameRaterShow.random = Random() % 3; + tvShow->nameRaterShow.random2 = Random() % 2; + + tvShow->nameRaterShow.var1C = sub_80BF674(tvShow->nameRaterShow.species); + + StringCopy(tvShow->nameRaterShow.trainerName, gSaveBlock2.playerName); + + GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_NICKNAME, tvShow->nameRaterShow.pokemonName); + + sub_80BE160(tvShow); + + tvShow->nameRaterShow.language = GAME_LANGUAGE; + tvShow->nameRaterShow.var1F = sub_80BDEAC(tvShow->nameRaterShow.pokemonName); + + StripExtCtrlCodes(tvShow->nameRaterShow.pokemonName); +} + +void StartMassOutbreak(void) { + TVShow *tvShow; + + tvShow = &gSaveBlock1.tvShows[gSpecialVar_0x8004]; + + gSaveBlock1.outbreakPokemonSpecies = tvShow->massOutbreak.species; + gSaveBlock1.outbreakLocationMapNum = tvShow->massOutbreak.locationMapNum; + gSaveBlock1.outbreakLocationMapGroup = tvShow->massOutbreak.locationMapGroup; + gSaveBlock1.outbreakPokemonLevel = tvShow->massOutbreak.level; + gSaveBlock1.outbreakUnk1 = tvShow->massOutbreak.var02; + gSaveBlock1.outbreakUnk2 = tvShow->massOutbreak.var0E; + gSaveBlock1.outbreakPokemonMoves[0] = tvShow->massOutbreak.moves[0]; + gSaveBlock1.outbreakPokemonMoves[1] = tvShow->massOutbreak.moves[1]; + gSaveBlock1.outbreakPokemonMoves[2] = tvShow->massOutbreak.moves[2]; + gSaveBlock1.outbreakPokemonMoves[3] = tvShow->massOutbreak.moves[3]; + gSaveBlock1.outbreakUnk4 = tvShow->massOutbreak.var03; + gSaveBlock1.outbreakPokemonProbability = tvShow->massOutbreak.probability; + gSaveBlock1.outbreakUnk5 = 2; +} + +void sub_80BE5FC(void) { + TVShow *tvShow; + u16 species; + + tvShow = &gSaveBlock1.tvShows[gUnknown_03005D38.var0]; + + tvShow->fanclubLetter.var00 = TVSHOW_FAN_CLUB_LETTER; + tvShow->fanclubLetter.var01 = 1; + StringCopy(tvShow->fanclubLetter.playerName, gSaveBlock2.playerName); + + species = GetMonData(&gPlayerParty[GetLeadMonIndex()], MON_DATA_SPECIES, NULL); + tvShow->fanclubLetter.species = species; + sub_80BE160(tvShow); + tvShow->fanclubLetter.var18 = GAME_LANGUAGE; +} + +void sub_80BE65C(void) { + TVShow *tvShow; + + tvShow = &gSaveBlock1.tvShows[gUnknown_03005D38.var0]; + + tvShow->recentHappenings.var00 = TVSHOW_RECENT_HAPPENINGS; + tvShow->recentHappenings.var01 = 1; + StringCopy(&tvShow->recentHappenings.var10[0], &gSaveBlock2.playerName[0]); + tvShow->recentHappenings.var02 = 0; + + sub_80BE160(tvShow); + tvShow->recentHappenings.var18 = GAME_LANGUAGE; +} + +void sub_80BE6A0(void) { + TVShow *tvShow; + u8 monIndex; + + tvShow = &gSaveBlock1.tvShows[gUnknown_03005D38.var0]; + + tvShow->fanclubOpinions.var00 = TVSHOW_PKMN_FAN_CLUB_OPINIONS; + tvShow->fanclubOpinions.var01 = 1; + + monIndex = GetLeadMonIndex(); + + tvShow->fanclubOpinions.var04A = GetMonData(&gPlayerParty[monIndex], MON_DATA_FRIENDSHIP, NULL) / 16; + tvShow->fanclubOpinions.var04B = gSpecialVar_0x8007; + + + StringCopy(tvShow->fanclubOpinions.var05, gSaveBlock2.playerName); + + GetMonData(&gPlayerParty[GetLeadMonIndex()], MON_DATA_NICKNAME, tvShow->fanclubOpinions.var10); + + tvShow->fanclubOpinions.var02 = GetMonData(&gPlayerParty[GetLeadMonIndex()], MON_DATA_SPECIES, NULL); + sub_80BE160(tvShow); + tvShow->fanclubOpinions.var0D = GAME_LANGUAGE; + tvShow->fanclubOpinions.var0E = sub_80BDEAC(tvShow->fanclubOpinions.var10); + StripExtCtrlCodes(tvShow->fanclubOpinions.var10); +} + +void nullsub_21(void) { + +} + +void sub_80BE778(void) { + u8 i; + + if (!FlagGet(SYS_GAME_CLEAR)) { + return; + } + + + for (i = 0; i < 24; i++) { + if (gSaveBlock1.tvShows[i].massOutbreak.var00 == TVSHOW_MASS_OUTBREAK) { + return; + } + } + + if (sub_80BF77C(0x147)) { + return; + } + + gUnknown_03005D38.var0 = sub_80BF720(gSaveBlock1.tvShows); + if (gUnknown_03005D38.var0 == -1) { + return; + } + { + u16 rand; + u16 val; + s32 val2; + TVShow *tvShow; + + rand = Random(); + val = rand % 5; + + val2 = gUnknown_03005D38.var0; + + tvShow = &gSaveBlock1.tvShows[val2]; + + tvShow->massOutbreak.var00 = TVSHOW_MASS_OUTBREAK; + tvShow->massOutbreak.var01 = 1; + + tvShow->massOutbreak.level = gPokeOutbreakSpeciesList[val].level; + tvShow->massOutbreak.var02 = 0; + tvShow->massOutbreak.var03 = 0; + tvShow->massOutbreak.species = gPokeOutbreakSpeciesList[val].species; + tvShow->massOutbreak.var0E = 0; + tvShow->massOutbreak.moves[0] = gPokeOutbreakSpeciesList[val].moves[0]; + tvShow->massOutbreak.moves[1] = gPokeOutbreakSpeciesList[val].moves[1]; + tvShow->massOutbreak.moves[2] = gPokeOutbreakSpeciesList[val].moves[2]; + tvShow->massOutbreak.moves[3] = gPokeOutbreakSpeciesList[val].moves[3]; + tvShow->massOutbreak.locationMapNum = gPokeOutbreakSpeciesList[val].location; + tvShow->massOutbreak.locationMapGroup = 0; + tvShow->massOutbreak.var12 = 0; + tvShow->massOutbreak.probability = 0x32; + tvShow->massOutbreak.var15 = 0; + tvShow->massOutbreak.var16 = 0x01; + sub_80BE160(tvShow); + + tvShow->massOutbreak.var18 = GAME_LANGUAGE; + } +} + +void EndMassOutbreak(void) { + gSaveBlock1.outbreakPokemonSpecies = 0; + gSaveBlock1.outbreakLocationMapNum = 0; + gSaveBlock1.outbreakLocationMapGroup = 0; + gSaveBlock1.outbreakPokemonLevel = 0; + gSaveBlock1.outbreakUnk1 = 0; + gSaveBlock1.outbreakUnk2 = 0; + gSaveBlock1.outbreakPokemonMoves[0] = 0; + gSaveBlock1.outbreakPokemonMoves[1] = 0; + gSaveBlock1.outbreakPokemonMoves[2] = 0; + gSaveBlock1.outbreakPokemonMoves[3] = 0; + gSaveBlock1.outbreakUnk4 = 0; + gSaveBlock1.outbreakPokemonProbability = 0; + gSaveBlock1.outbreakUnk5 = 0; +} + +void sub_80BE8C4(u16 arg0) { + sub_80BE8EC(arg0); + UpdateMassOutbreakTimeLeft(arg0); + sub_80BEE84(arg0); + sub_80BEA5C(arg0); +} + +asm(".section .text_b"); + +u8 sub_80BF4F4(u8 arg0) { + u32 species; + + GetMonData(&gPlayerParty[arg0], MON_DATA_NICKNAME, &gStringVar1); + + species = GetMonData(&gPlayerParty[arg0], MON_DATA_SPECIES, NULL); + + if (StringCompareWithoutExtCtrlCodes(gSpeciesNames[species], gStringVar1) == FALSE) { + return FALSE; + } + + return TRUE; +} + +asm(".section .text_c"); + +void DoTVShowPokemonNewsMassOutbreak(void) { + TVShow *tvShow; + + tvShow = &gSaveBlock1.tvShows[gSpecialVar_0x8004]; + + sub_80FBFB4(gStringVar1, tvShow->massOutbreak.locationMapNum, 0); + + StringCopy(gStringVar2, gSpeciesNames[tvShow->massOutbreak.species]); + + TVShowDone(); + StartMassOutbreak(); + + ShowFieldMessage(gTVPokemonOutbreakTextGroup[gUnknown_020387E8]); +} + +asm(".section .text_d"); + +void TVShowDone(void) { + gScriptResult = 1; + gUnknown_020387E8 = 0; + + gSaveBlock1.tvShows[gSpecialVar_0x8004].common.var01 = 0; +} + +void sub_80C2014(void) { + gUnknown_020387E8 = 0; +} diff --git a/src/var.c b/src/var.c deleted file mode 100644 index 08b109e6f..000000000 --- a/src/var.c +++ /dev/null @@ -1,37 +0,0 @@ -#include "global.h" -#include "var.h" - -extern u16 *gSpecialVars[]; - -u16 *GetVarPointer(u16 id) -{ - if (id < 0x4000) - return NULL; - - if ((s16)id >= 0) - return &gSaveBlock1.vars[id - 0x4000]; - - return gSpecialVars[id - 0x8000]; -} - -u16 VarGet(u16 id) -{ - u16 *ptr = GetVarPointer(id); - if (!ptr) - return id; - return *ptr; -} - -bool8 VarSet(u16 id, u16 value) -{ - u16 *ptr = GetVarPointer(id); - if (!ptr) - return FALSE; - *ptr = value; - return TRUE; -} - -u8 VarGetFieldObjectGraphicsId(u8 id) -{ - return VarGet(0x4010 + id); -} diff --git a/src/wallclock.c b/src/wallclock.c index 05e30a8cb..147a68d31 100644 --- a/src/wallclock.c +++ b/src/wallclock.c @@ -1,33 +1,28 @@ #include "global.h" +#include "wallclock.h" +#include "asm.h" +#include "decompress.h" #include "main.h" #include "menu.h" #include "palette.h" #include "rtc.h" #include "songs.h" -#include "sprite.h" #include "task.h" -#include "text.h" #include "trig.h" #include "sound.h" -//Functions that need to be put in headers -void remove_some_task(void); -void LoadCompressedObjectPic(void *); - extern u16 gSpecialVar_0x8004; extern u16 gMiscClockMale_Pal[]; extern u16 gMiscClockFemale_Pal[]; extern u8 gMiscClock_Gfx[]; -extern u8 gUnknown_083F7A90[]; +extern struct SpriteSheet gUnknown_083F7A90; extern struct SpritePalette gUnknown_083F7AA0; extern u8 gUnknown_08E95774[]; extern u8 gUnknown_08E954B0[]; extern u8 gOtherText_CorrectTimePrompt[]; -extern u8 * const gUnknown_08376D74[][2]; +extern const struct MenuAction gMenuYesNoItems[]; extern s8 gClockHandCoords[][2]; -extern struct WindowConfig gWindowConfig_81E6C3C; -extern struct WindowConfig gWindowConfig_81E6CE4; extern struct SpriteTemplate gSpriteTemplate_83F7AD8; extern struct SpriteTemplate gSpriteTemplate_83F7AF0; extern struct SpriteTemplate gSpriteTemplate_83F7B28; @@ -127,7 +122,7 @@ static void LoadWallClockGraphics(void) ResetSpriteData(); ResetPaletteFade(); FreeAllSpritePalettes(); - LoadCompressedObjectPic(gUnknown_083F7A90); + LoadCompressedObjectPic(&gUnknown_083F7A90); LoadSpritePalettes(&gUnknown_083F7AA0); SetUpWindowConfig(&gWindowConfig_81E6C3C); InitMenuWindow(&gWindowConfig_81E6CE4); @@ -155,7 +150,7 @@ static void WallClockInit(void) } //Allow player to set the clock -void Cb2_StartWallClock(void) +void CB2_StartWallClock(void) { u8 taskId; u8 spriteId; @@ -194,7 +189,7 @@ void Cb2_StartWallClock(void) } //View, but don't set, the clock -void Cb2_ViewWallClock(void) +void CB2_ViewWallClock(void) { u8 taskId; s16 angle1; @@ -302,7 +297,7 @@ static void Task_SetClock3(u8 taskId) MenuDrawTextWindow(2, 16, 27, 19); MenuPrint(gOtherText_CorrectTimePrompt, 3, 17); MenuDrawTextWindow(23, 8, 29, 13); - PrintMenuItems(24, 9, 2, gUnknown_08376D74); + PrintMenuItems(24, 9, 2, gMenuYesNoItems); InitMenu(0, 24, 9, 2, 1, 5); gTasks[taskId].func = Task_SetClock4; } @@ -337,7 +332,7 @@ static void Task_SetClock5(u8 taskId) static void Task_SetClock6(u8 taskId) { if(!gPaletteFade.active) - SetMainCallback2((MainCallback)gMain.field_8); + SetMainCallback2((MainCallback)gMain.savedCallback); } static void Task_ViewClock1(u8 taskId) @@ -363,7 +358,7 @@ static void Task_ViewClock3(u8 taskId) static void Task_ViewClock4(u8 taskId) { if(!gPaletteFade.active) - SetMainCallback2((MainCallback)gMain.field_8); + SetMainCallback2((MainCallback)gMain.savedCallback); } static u8 CalcMinHandDelta(u16 speed) diff --git a/src/weather.c b/src/weather.c new file mode 100644 index 000000000..520185441 --- /dev/null +++ b/src/weather.c @@ -0,0 +1,307 @@ +#include "global.h" +#include "weather.h" +#include "asm.h" +#include "task.h" +#include "sprite.h" +#include "palette.h" + +struct Weather { + u8 filler_000[0x200]; + u8 unknown_200[2][32]; + u8 filler_240[0x480]; + s8 unknown_6C0; + s8 unknown_6C1; + u8 unknown_6C2; + u8 unknown_6C3; + u16 unknown_6C4; + u8 unknown_6C6; + u8 unknown_6C7; + u8 unknown_6C8; + u8 unknown_6C9; + u8 unknown_6CA; + u8 unknown_6CB; + u8 filler_6CC[2]; + u16 unknown_6CE; + u8 unknown_6D0; + u8 unknown_6D1; + u8 filler_6D2[1]; + u8 unknown_6D3; + u8 unknown_6D4; + u8 unknown_6D5; + u8 filler_6D6[2]; + u8 unknown_6D8; + u8 filler_6D9[1]; + u8 unknown_6DA; + u8 filler_6DB[3]; + u8 unknown_6DE; + u8 filler_6DF[5]; + u8 unknown_6E4; + u8 filler_6E5[0x15]; + u8 unknown_6FA; + u8 unknown_6FB; + u8 filler_6FC[4]; + u8 unknown_700; + u8 filler_701[0x15]; + u8 unknown_716; + u8 unknown_717; + u8 filler_718[0xc]; + u8 unknown_724; + u8 filler_725[9]; + u8 unknown_72E; +}; + +#define gWeather gUnknown_0202F7E8 +extern struct Weather gWeather; +extern u8 *gUnknown_083970E8; +extern u8 (*gUnknown_08396FC8[][4])(void); +extern u8 (*gUnknown_083970B8[])(void); +extern u8 *gUnknown_030006DC; +extern u8 gUnknown_083970C8; +extern u8 (*gUnknown_0202FC48)[32]; +extern u8 gUnknown_0202F9E8[32]; + + +void sub_807C828(void) { + u8 index; + if (!FuncIsActiveTask(&sub_807CA34)) { + index = AllocSpritePalette(0x1200); + CpuCopy32(&gUnknown_083970E8, &gPlttBufferUnfaded[0x100 + index * 16], 32); + sub_807CB10(); + gWeather.unknown_6D5 = index; + gWeather.unknown_6D4 = AllocSpritePalette(0x1201); + gWeather.unknown_6DA = 0; + gWeather.unknown_6D8 = 0; + gWeather.unknown_6DE = 0; + gWeather.unknown_6E4 = 0; + gWeather.unknown_700 = 0; + gWeather.unknown_6FB = 0; + gWeather.unknown_724 = 0; + gWeather.unknown_716 = 0; + gWeather.unknown_717 = 0; + gWeather.unknown_72E = 0; + gWeather.unknown_6FA = 0; + sub_807DB64(16, 0); + gWeather.unknown_6D0 = 0; + gWeather.unknown_6C6 = 3; + gWeather.unknown_6C8 = 0; + gWeather.unknown_6D3 = 1; + gWeather.unknown_6C9 = CreateTask(&sub_807C9E4, 80); + } +} + +void DoWeatherEffect(u8 effect) { + if (effect != 3 && effect != 5 && effect != 13) { + PlayRainSoundEffect(); + } + if (gWeather.unknown_6D1 != effect && gWeather.unknown_6D0 == effect) { + gUnknown_08396FC8[effect][0](); + } + gWeather.unknown_6D3 = 0; + gWeather.unknown_6D1 = effect; + gWeather.unknown_6CE = 0; +} + +void sub_807C988(u8 effect) { + PlayRainSoundEffect(); + gWeather.unknown_6D0 = effect; + gWeather.unknown_6D1 = effect; +} + +void sub_807C9B4(u8 effect) { + PlayRainSoundEffect(); + gWeather.unknown_6D0 = effect; + gWeather.unknown_6D1 = effect; + gWeather.unknown_6C8 = 1; +} + +void sub_807C9E4(u8 task) { + if (gWeather.unknown_6C8) { + gUnknown_08396FC8[gWeather.unknown_6D0][2](); + gTasks[task].func = &sub_807CA34; + } +} + +void sub_807CA34(u8 task) { + u8 v1; + if (gWeather.unknown_6D0 != gWeather.unknown_6D1) { + v1 = gUnknown_08396FC8[gWeather.unknown_6D0][3](); + if (!v1) { + gUnknown_08396FC8[gWeather.unknown_6D1][0](); + gWeather.unknown_6C3 = 0; // compiler reuses v1 + gWeather.unknown_6C6 = 0; // compiler reuses v1 + gWeather.unknown_6D0 = gWeather.unknown_6D1; + gWeather.unknown_6D3 = 1; + } + } else { + gUnknown_08396FC8[gWeather.unknown_6D0][1](); + } + gUnknown_083970B8[gWeather.unknown_6C6](); +} + +void sub_807CAE8(void) { + gWeather.unknown_6C1 = 0; + gWeather.unknown_6C2 = 0; +} + +void nullsub_38(void) { +} + +u32 sub_807CB0C(void) { + return 0; +} + +void sub_807CB10(void) { + u16 v0; + u8 (*v1)[32]; + u16 v2; + u16 v4; + u16 v5; + u16 v6; + u16 v9; + u32 v10; + u16 v11; + s16 dunno; + + gUnknown_030006DC = &gUnknown_083970C8; + for (v0 = 0; v0 <= 1; v0++) { + if (v0 == 0) { + v1 = &gUnknown_0202F9E8; + } else { + v1 = &gUnknown_0202F9E8 + 19; + } + for (v2 = 0; (u16)v2 <= 0x1f; v2++) { + v4 = v2 << 8; + if (v0 == 0) { + v5 = (v2 << 8) / 16; + } else { + v5 = 0; + } + v6 = 0; + for (; v6 <= 2; v6++) { + v4 = (v4 - v5); + v1[v6][v2] = v4 >> 8; + } + v9 = v4; + v10 = 0x1f00 - v4; + if ((0x1f00 - v4) < 0) { + v10 += 0xf; + } + v11 = v10 >> 4; + if (v2 <= 0xb) { + for (; v6 <= 0x12; v6++) { + v4 += v11; + dunno = v4 - v9; + if (dunno > 0) { + v4 -= (dunno + ((u16)dunno >> 15)) >> 1; + } + v1[v6][v2] = v4 >> 8; + if (v1[v6][v2] > 0x1f) { + v1[v6][v2] = 0x1f; + } + } + } else { + for (; v6 <= 0x12; v6++) { + v4 += v11; + v1[v6][v2] = v4 >> 8; + if (v1[v6][v2] > 0x1f) { + v1[v6][v2] = 0x1f; + } + } + } + } + } +} + +void sub_807CC24(void) { + if (gWeather.unknown_6C0 == gWeather.unknown_6C1) { + gWeather.unknown_6C6 = 3; + } else { + if (++gWeather.unknown_6C3 >= gWeather.unknown_6C2) { + gWeather.unknown_6C3 = 0; + if (gWeather.unknown_6C0 < gWeather.unknown_6C1) { + gWeather.unknown_6C0++; + } else { + gWeather.unknown_6C0--; + } + sub_807CEBC(0, 0x20, gWeather.unknown_6C0); + } + } +} + +void sub_807CCAC(void) { + if (++gWeather.unknown_6CB > 1) { + gWeather.unknown_6CA = 0; + } + switch (gWeather.unknown_6D0) { + case 3: + case 4: + case 5: + case 11: + case 13: + if (sub_807CDC4() == 0) { + gWeather.unknown_6C0 = 3; + gWeather.unknown_6C6 = 3; + } + break; + case 12: + if (sub_807CE24() == 0) { + gWeather.unknown_6C0 = -6; + gWeather.unknown_6C6 = 3; + } + break; + case 6: + if (sub_807CE7C() == 0) { + gWeather.unknown_6C0 = 0; + gWeather.unknown_6C6 = 3; + } + break; + case 7: + case 8: + case 9: + case 10: + default: + if (!gPaletteFade.active) { + gWeather.unknown_6C0 = gWeather.unknown_6C1; + gWeather.unknown_6C6 = 3; + } + break; + } +} + +u8 sub_807CDC4(void) { + if (gWeather.unknown_6C7 == 0x10) { + return 0; + } + if (++gWeather.unknown_6C7 >= 0x10) { + sub_807CEBC(0, 0x20, 3); + gWeather.unknown_6C7 = 0x10; + return 0; + } + sub_807D1BC(0, 0x20, 3, 0x10 - gWeather.unknown_6C7, gWeather.unknown_6C4); + return 1; +} + +u8 sub_807CE24(void) { + if (gWeather.unknown_6C7 == 0x10) { + return 0; + } + if (++gWeather.unknown_6C7 >= 0x10) { + sub_807CEBC(0, 0x20, -6); + gWeather.unknown_6C7 = 0x10; + return 0; + } + sub_807D304(-6, 0x10 - gWeather.unknown_6C7, gWeather.unknown_6C4); + return 1; +} + +u8 sub_807CE7C(void) { + if (gWeather.unknown_6C7 == 0x10) { + return 0; + } + ++gWeather.unknown_6C7; + sub_807D424(0x10 - gWeather.unknown_6C7, gWeather.unknown_6C4); + return 1; +} + +void nullsub_39(void) { +} diff --git a/src/wild_encounter.c b/src/wild_encounter.c index 151088cd6..8e983c300 100644 --- a/src/wild_encounter.c +++ b/src/wild_encounter.c @@ -1,11 +1,15 @@ #include "global.h" +#include "wild_encounter.h" +#include "asm.h" +#include "field_player_avatar.h" +#include "safari_zone.h" +#include "battle_setup.h" #include "abilities.h" -#include "fieldmap.h" -#include "pokemon.h" #include "rng.h" #include "script.h" -#include "flag.h" -#include "var.h" +#include "event_data.h" +#include "rom4.h" +#include "metatile_behavior.h" struct WildPokemon { @@ -30,22 +34,6 @@ struct WildPokemonHeader struct WildPokemonInfo *fishingMonsInfo; }; -extern bool8 sub_805759C(u8); -extern void GetXYCoordsOneStepInFrontOfPlayer(void *, void *); -extern s16 sub_810CAE4(u8, struct Pokeblock *); -extern bool32 GetSafariZoneFlag(void); -extern u8 TestPlayerAvatarFlags(u8); -extern u8 MetatileBehavior_IsLandWildEncounter(u8); -extern u8 sub_81344CC(void); -extern u8 MetatileBehavior_IsWaterWildEncounter(u8); -extern void CheckForSafariZoneAndProceed(void); -extern u8 MetatileBehavior_IsBridge(u8); -extern void PlayerGetDestCoords(u16 *x, u16 *y); -extern void sub_80BEA50(u16); -extern void sav12_xor_increment(u8); -extern int MapGridGetMetatileBehaviorAt(int x, int y); -extern struct Pokeblock *SafariZoneGetActivePokeblock(void); - extern u16 gRoute119WaterTileData[]; extern struct WildPokemonHeader gWildMonHeaders[]; extern struct Pokemon gEnemyParty[6]; @@ -399,7 +387,7 @@ static bool8 DoWildEncounterRateDiceRoll(u16 encounterRate) static bool8 DoWildEncounterTest(u32 encounterRate, bool8 ignoreAbility) { encounterRate *= 16; - if (TestPlayerAvatarFlags(6)) + if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_MACH_BIKE | PLAYER_AVATAR_FLAG_ACRO_BIKE)) encounterRate = encounterRate * 80 / 100; ApplyFluteEncounterRateMod(&encounterRate); ApplyCleanseTagEncounterRateMod(&encounterRate); @@ -454,7 +442,7 @@ bool8 StandardWildEncounter(u16 a, u16 b) roamer = &gSaveBlock1.roamer; if (RepelCheck(roamer->level)) { - sub_8081A5C(); + StartBattle_Roamer(); return 1; } } @@ -474,7 +462,7 @@ bool8 StandardWildEncounter(u16 a, u16 b) } } else if (MetatileBehavior_IsWaterWildEncounter(a) == TRUE - || (TestPlayerAvatarFlags(8) && MetatileBehavior_IsBridge(a) == TRUE)) + || (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_SURFING) && MetatileBehavior_IsBridge(a) == TRUE)) { if (gWildMonHeaders[headerNum].waterMonsInfo) { @@ -488,7 +476,7 @@ bool8 StandardWildEncounter(u16 a, u16 b) roamer = &gSaveBlock1.roamer; if (RepelCheck(roamer->level)) { - sub_8081A5C(); + StartBattle_Roamer(); return 1; } } @@ -553,7 +541,7 @@ bool8 SweetScentWildEncounter(void) return FALSE; if (sub_81344CC() == TRUE) { - sub_8081A5C(); + StartBattle_Roamer(); return TRUE; } if (DoMassOutbreakEncounterTest() == TRUE) @@ -570,7 +558,7 @@ bool8 SweetScentWildEncounter(void) return FALSE; if (sub_81344CC() == TRUE) { - sub_8081A5C(); + StartBattle_Roamer(); return TRUE; } GenerateWildMon(wildPokemonInfo, 1, FALSE); @@ -608,7 +596,7 @@ void FishingWildEncounter(u8 rod) gWildMonHeaders[GetCurrentMapWildMonHeader()].fishingMonsInfo, rod); } - sav12_xor_increment(12); + IncrementGameStat(12); sub_80BEA50(species); CheckForSafariZoneAndProceed(); } |