diff --git a/asm/sprite.s b/asm/sprite.s index 11097902e..69cd5112c 100644 --- a/asm/sprite.s +++ b/asm/sprite.s @@ -5,26 +5,6 @@ .text - thumb_func_start sub_80053AC -sub_80053AC: - push {r4-r6,lr} - sub sp, 0xC - ldr r5, [sp, 0x1C] - ldr r6, [sp, 0x20] - ldr r4, [sp, 0x24] - lsls r4, 24 - lsrs r4, 24 - ldr r1, [r1, 0x4] - str r5, [sp] - str r6, [sp, 0x4] - str r4, [sp, 0x8] - bl sub_80053D0 - add sp, 0xC - pop {r4-r6} - pop {r0} - bx r0 - thumb_func_end sub_80053AC - thumb_func_start sub_80053D0 sub_80053D0: push {r4-r7,lr} diff --git a/include/axdata.h b/include/axdata.h index 5391ac5d8..e6c8d8971 100644 --- a/include/axdata.h +++ b/include/axdata.h @@ -54,13 +54,13 @@ struct ax_anim // size: 0x3C struct axdata { - /* 0x0 */ u16 flags; - /* 0x2 */ u16 animFrames; - /* 0x4 */ u16 animWaitFrames; - /* 0x6 */ s16 totalFrames; + /* 0x0 */ u16 flags; // 0x8000 - animating, 0x2000 finished? 0x1000 continue + /* 0x2 */ u16 animFrames; // frames left in the current animation frame + /* 0x4 */ u16 animWaitFrames; // frames to not update the animation for + /* 0x6 */ s16 totalFrames; // max 30000 /* 0x8 */ struct axdata1 sub1; - /* 0x28 */ struct ax_anim *nextAnimData; - /* 0x2C */ struct ax_anim *activeAnimData; + /* 0x28 */ struct ax_anim *nextAnimData; // next animation data (if flags&0x1000) + /* 0x2C */ struct ax_anim *activeAnimData; // current animation data /* 0x30 */ void *paletteData; // ? /* 0x34 */ struct ax_pose *poseData; /* 0x38 */ struct UnkSpriteMem **spriteData; diff --git a/include/code_805D8C8.h b/include/code_805D8C8.h new file mode 100644 index 000000000..3bab54c02 --- /dev/null +++ b/include/code_805D8C8.h @@ -0,0 +1,13 @@ +#ifndef GUARD_CODE_805D8C8_H +#define GUARD_CODE_805D8C8_H + +#include "sprite.h" + +extern struct Dungeon_Sub17B44 *sub_80687D0(s16); +/*struct Dungeon_Sub17B44 *sub_80687D0(s16 species) +{ + s32 species32 = species; + return gDungeon->sub17B44[species32]; +}*/ + +#endif // GUARD_CODE_805D8C8_H \ No newline at end of file diff --git a/include/constants/monster.h b/include/constants/monster.h index 8d6a466a8..3d4c09296 100644 --- a/include/constants/monster.h +++ b/include/constants/monster.h @@ -1,8 +1,6 @@ #ifndef GUARD_CONSTANTS_MONSTER_H #define GUARD_CONSTANTS_MONSTER_H -#define NUM_MONSTERS 413 - #define MONSTER_NONE 0 #define MONSTER_BULBASAUR 1 #define MONSTER_IVYSAUR 2 @@ -429,4 +427,7 @@ #define MONSTER_STATUE 422 #define MONSTER_RAYQUAZA_CUTSCENE 423 -#endif // GUARD_CONSTANTS_MONSTER_H +#define NUM_MONSTERS MONSTER_JIRACHI +#define MONSTER_MAX MONSTER_RAYQUAZA_CUTSCENE + +#endif // GUARD_CONSTANTS_MONSTER_H \ No newline at end of file diff --git a/include/dungeon_entity.h b/include/dungeon_entity.h index c2e281578..7d9c9f448 100644 --- a/include/dungeon_entity.h +++ b/include/dungeon_entity.h @@ -5,6 +5,7 @@ #include "constants/move.h" #include "item.h" #include "position.h" +#include "sprite.h" #define MAX_STAT_STAGE 20 #define STAT_MULTIPLIER_THRESHOLD 63 @@ -270,32 +271,8 @@ struct Entity // The global spawn index counter starts at 10. Each Pokémon that spawns increments the counter and // gets assigned the current counter value as its spawn index. /* 0x26 */ u16 spawnGenID; - u8 fill28[0x2A - 0x28]; - // 0x2A and 0x2E seem to be related to the sprite animation, though not sure how they're related. - /* 0x2A */ u16 spriteAnimationCounter; - // Each animation has a few different sprites that it transitions between. - // This is the index of the currently displayed sprite within the animation. - // Differs from 0x34 as this index is only between the sprites used by the animation, - // while 0x34 is a shared index among all sprites. - /* 0x2C */ u16 spriteAnimationIndex; - /* 0x2E */ u16 spriteAnimationCounter2; - // The position of the sprite within the tile. The animation may change the position slightly. - /* 0x30 */ struct Position spritePos; - // Offset of the sprite from its position at the start of the animation. Changes alongside spritePos. - /* 0x34 */ struct Position spritePosOffset; - u8 fill38[0x48 - 0x38]; - // The sprite index to display, among the Pokémon's possible sprites. - /* 0x48 */ u16 spriteIndexForEntity; - /* 0x4A */ u16 spriteIndexForEntity2; - u8 unk4C[0x50 - 0x4C]; - // Some kind of base sprite index depending on which way the Pokémon is facing. - // and which animation is playing (e.g., idle, moving). - // Compared to 0x48, 0x50 and 0x54 are much larger and could be global indexes among all sprites in the game. - /* 0x50 */ u16 spriteBaseForDirection; - u8 fill52[0x54 - 0x52]; - /* 0x54 */ u16 spriteGlobalIndex; - u8 fill56[0x64 - 0x56]; - u32 unk64; + /* 0x28*/ struct Entity_Sub28 sub28; + struct Dungeon_Sub17B44 *unk64; s16 unk68; u8 unk6A; u8 unk6B; diff --git a/include/dungeon_global_data.h b/include/dungeon_global_data.h index 27823b476..9ee9762cf 100644 --- a/include/dungeon_global_data.h +++ b/include/dungeon_global_data.h @@ -6,6 +6,7 @@ #include "global.h" #include "map.h" #include "position.h" +#include "sprite.h" #define DUNGEON_MAX_SIZE_X 56 #define DUNGEON_MAX_SIZE_Y 32 @@ -197,7 +198,9 @@ struct Dungeon /* 0x17B34 */ u8 fillunk1734[0x17B38 - 0x17B34]; /* 0x17B38 */ u32 unk17B38; /* 0x17B3C */ u32 unk17B3C; - u8 fill17B40[0x181E8 - 0x17B40]; + u8 fill17B40[0x17B44 - 0x17B40]; + struct Dungeon_Sub17B44 *sub17B44[MONSTER_MAX]; // Assuming MONSTER_MAX since the highest value I've seen read is MONSTER_DECOY + u8 fill181E0[0x181E8 - 0x181E0]; /* 0x181E8 */ struct Position cameraPos; /* 0x181EC */ struct Position cameraPosMirror; /* 0x181F0 */ struct Position cameraPixelPos; diff --git a/include/sprite.h b/include/sprite.h index 2da322198..1716a4be5 100644 --- a/include/sprite.h +++ b/include/sprite.h @@ -40,6 +40,53 @@ struct unkStruct_20266B0 /* 0x8 */ void *dest; }; +// size: ? 0x3C for now +struct Entity_Sub28 +{ + u16 unk0; + // 0x2 and 0x6 seem to be related to the sprite animation, though not sure how they're related. + /* 0x2 */ u16 spriteAnimationCounter; + // Each animation has a few different sprites that it transitions between. + // This is the index of the currently displayed sprite within the animation. + // Differs from 0xC as this index is only between the sprites used by the animation, + // while 0xC is a shared index among all sprites. + /* 0x4 */ u16 spriteAnimationIndex; + /* 0x6 */ u16 spriteAnimationCounter2; + // The position of the sprite within the tile. The animation may change the position slightly. + /* 0x8 */ struct Position spritePos; + // Offset of the sprite from its position at the start of the animation. Changes alongside spritePos. + /* 0xC */ struct Position spritePosOffset; + u8 fill10[0x20 - 0x10]; + // The sprite index to display, among the Pokémon's possible sprites. + /* 0x20 */ u16 spriteIndexForEntity; + /* 0x22 */ u16 spriteIndexForEntity2; + u8 unk24[0x28 - 0x24]; + // Some kind of base sprite index depending on which way the Pokémon is facing. + // and which animation is playing (e.g., idle, moving). + // Compared to 0x20, 0x28 and 0x2C are much larger and could be global indexes among all sprites in the game. + /* 0x28 */ u16 spriteBaseForDirection; + u8 fill2A[0x2C - 0x2A]; + /* 0x2C */ u16 spriteGlobalIndex; + u8 fill2E[0x3C - 0x2E]; +}; + +// size: ? +struct Dungeon_Sub17B44_Sub4 +{ + u32 unk0; + u32 unk4; + u8 fill8[0xC - 0x8]; + u32 unkC; + u32 unk10; +}; + +// size: ? +struct Dungeon_Sub17B44 +{ + u8 fill0[0x4 - 0x0]; + struct Dungeon_Sub17B44_Sub4 *unk4; +}; + void AddSprite(struct unkSprite *, s32, struct UnkSpriteMem *, struct unkStruct_2039DB0 *); void BlinkSavingIcon(void); void CopySpritesToOam(void); @@ -49,5 +96,7 @@ void SetSavingIconCoords(struct Position *); void sub_8004E8C(struct unkStruct_2039DB0 *); void sub_8005180(void); void sub_8005304(void); +void sub_80053AC(struct Entity_Sub28 *, struct Dungeon_Sub17B44 *, u32, u32, u32, u32, bool8); +extern void sub_80053D0(struct Entity_Sub28 *a0, struct Dungeon_Sub17B44_Sub4 *a1, u32 a2, u32 a3, u32 a4, u32 spriteAnimIndex, bool8 a6); #endif // GUARD_SPRITE_H \ No newline at end of file diff --git a/src/code_806CD90.c b/src/code_806CD90.c index 7e8cba71e..1b8998fc1 100644 --- a/src/code_806CD90.c +++ b/src/code_806CD90.c @@ -1,20 +1,20 @@ #include "global.h" +#include "code_805D8C8.h" #include "constants/direction.h" #include "constants/status.h" #include "dungeon_entity.h" #include "dungeon_global_data.h" #include "dungeon_util.h" #include "pokemon.h" -#include "tile_types.h" #include "random.h" +#include "sprite.h" +#include "tile_types.h" extern u8 sub_806CEBC(struct Entity *); extern void sub_806CCB4(struct Entity *, u8); extern void sub_803E46C(u32); extern bool8 sub_808DA44(s32 a1_, u32 a2_); extern u32 sub_806CF98(struct Entity *); -extern u32 sub_80687D0(s16); -void sub_80053AC(u8 *, s32, u32, u32, u32, u32, u8); void sub_806CDD4(struct Entity *, u8, u32); extern const u8 gUnknown_8106EEF[]; @@ -53,28 +53,29 @@ void sub_806CC70(void) void sub_806CCB4(struct Entity *entity, u8 param_2) { - s32 sVar1; - bool8 flag; - struct EntityInfo *info; + s32 sVar1; + bool8 flag; + struct EntityInfo *info; - info = entity->info; - flag = gDungeon->hallucinating; - if (entity == gDungeon->cameraTarget) { - flag = FALSE; - } - entity->unk6B = param_2; - entity->unk6A = param_2; - entity->direction2 = info->action.direction; - entity->direction = info->action.direction; - entity->unk6F = 0; - sVar1 = entity->unk68; - if ((info->waitingStatus != STATUS_DECOY) && (!flag)) { - sub_80053AC(entity->fill28,entity->unk64,entity->unk6A,entity->direction,sVar1,Rand32Bit() & 3,0); - } - else { - sub_80053AC(entity->fill28,sub_80687D0(0x1a5),entity->unk6A,entity->direction,sVar1,Rand32Bit() & 3,0); - } - entity->unk6E = 0; + info = entity->info; + flag = gDungeon->hallucinating; + + if (entity == gDungeon->cameraTarget) + flag = FALSE; + + entity->unk6B = param_2; + entity->unk6A = param_2; + entity->direction2 = info->action.direction; + entity->direction = info->action.direction; + entity->unk6F = 0; + sVar1 = entity->unk68; + + if (info->waitingStatus != STATUS_DECOY && !flag) + sub_80053AC(&entity->sub28, entity->unk64, entity->unk6A, entity->direction, sVar1, Rand32Bit() & 3, FALSE); + else + sub_80053AC(&entity->sub28, sub_80687D0(MONSTER_DECOY), entity->unk6A, entity->direction, sVar1, Rand32Bit() & 3, FALSE); + + entity->unk6E = 0; } void sub_806CD90(void) diff --git a/src/code_8077274_1.c b/src/code_8077274_1.c index f9f81e35b..fa2340e40 100644 --- a/src/code_8077274_1.c +++ b/src/code_8077274_1.c @@ -17,6 +17,7 @@ #include "move_effects_target.h" #include "pokemon.h" #include "status_checks_1.h" +#include "code_805D8C8.h" extern u8 gAvailablePokemonNames[0x58]; extern u8 gUnknown_202DFE8[0x58]; @@ -173,7 +174,6 @@ extern void EntityUpdateStatusSprites(struct Entity *); extern void sub_8042A74(struct Entity *r0); extern void sub_807EC28(u32); extern s32 sub_8069F54(struct Entity *param_1, s16 param_2); -extern u32 sub_80687D0(s16); extern void sub_806A898(struct Entity *, u32, u32); extern void HealTargetHP(struct Entity *pokemon, struct Entity *r1, s16, s16, u32); extern void sub_806CE68(struct Entity *, s32); @@ -236,62 +236,61 @@ void MuzzleTarget(struct Entity *pokemon, struct Entity *target) } } -// TODO: still gross but does match void sub_8078E18(struct Entity * pokemon, struct Entity * target) { - s16 species; - s32 iVar5; - s32 apparentID; - s16 apparentID_s16; - s32 index; - struct EntityInfo *entityInfo; - s32 iVar9; - struct PokemonStruct *auStack544[128]; - + s16 species; + s32 iVar5; + s32 apparentID; + s16 apparentID_s16; + s32 index; + struct EntityInfo *entityInfo; + struct Dungeon_Sub17B44 *iVar9; + struct PokemonStruct *auStack544[128]; + + if (!EntityExists(target)) + return; - if (EntityExists(target)) { entityInfo = target->info; - if (entityInfo->transformStatus == STATUS_TRANSFORMED) { - sub_80522F4(pokemon,target,*gUnknown_80FBF04); - } - else { - SetMessageArgument(gAvailablePokemonNames,target,0); - iVar5 = sub_803D870(auStack544,0); - if (iVar5 == 0) { - goto print; - } - else - { - iVar9 = 0; - for(index = 0; index < DUNGEON_MAX_POKEMON; index++) - { - species = ExtractSpeciesIndex(&auStack544[DungeonRandInt(iVar5) << 1]); - apparentID_s16 = sub_8069F54(target, species); - apparentID = apparentID_s16; - if (((apparentID != entityInfo->apparentID) && (sub_806AA0C(apparentID, 1))) && - (iVar9 = sub_80687D0(apparentID), iVar9 != 0)) break; + if (entityInfo->transformStatus == STATUS_TRANSFORMED) + sub_80522F4(pokemon, target, *gUnknown_80FBF04); + else { + SetMessageArgument(gAvailablePokemonNames, target, 0); + iVar5 = sub_803D870(auStack544, 0); + + if (iVar5 == 0) + sub_80522F4(pokemon, target, *gUnknown_80FBEE4); + else { + iVar9 = NULL; + + for (index = 0; index < DUNGEON_MAX_POKEMON; index++) { + species = ExtractSpeciesIndex(&auStack544[DungeonRandInt(iVar5) * 2]); + apparentID_s16 = sub_8069F54(target, species); + apparentID = apparentID_s16; + + if (apparentID != entityInfo->apparentID && sub_806AA0C(apparentID, 1)) { + iVar9 = sub_80687D0(apparentID); + if (iVar9 != NULL) + break; + } + } + + if (index == DUNGEON_MAX_POKEMON || iVar9 == NULL) + sub_80522F4(pokemon, target, *gUnknown_80FBEE4); + else { + entityInfo->apparentID = apparentID; + target->unk64 = iVar9; + entityInfo->transformStatus = STATUS_TRANSFORMED; + entityInfo->transformStatusTurns = CalculateStatusTurns(target, gUnknown_80F4EFC, TRUE) + 1; + sub_806CF98(target); + nullsub_87(target); + sub_806CCB4(target, sub_806CEBC(target)); + CopyCyanMonsterNametoBuffer(gUnknown_202DFE8, entityInfo->apparentID); + sub_80522F4(pokemon, target, *gUnknown_80FBEC0); + EntityUpdateStatusSprites(target); + } } - if ((index == DUNGEON_MAX_POKEMON) || (iVar9 == 0)) { -print: - sub_80522F4(pokemon,target,*gUnknown_80FBEE4); - } - else - { - entityInfo->apparentID = apparentID; - target->unk64 = iVar9; - entityInfo->transformStatus = STATUS_TRANSFORMED; - entityInfo->transformStatusTurns = CalculateStatusTurns(target,gUnknown_80F4EFC,TRUE) + 1; - sub_806CF98(target); - nullsub_87(target); - sub_806CCB4(target, sub_806CEBC(target)); - CopyCyanMonsterNametoBuffer(gUnknown_202DFE8, entityInfo->apparentID); - sub_80522F4(pokemon,target,*gUnknown_80FBEC0); - EntityUpdateStatusSprites(target); - } - } } - } } void MobileStatusTarget(struct Entity * pokemon, struct Entity * target) diff --git a/src/code_80958E8.c b/src/code_80958E8.c index 4ee39320f..6b4f3cba5 100644 --- a/src/code_80958E8.c +++ b/src/code_80958E8.c @@ -100,14 +100,14 @@ bool8 ValidateWonderMail(struct WonderMail *data) if(data->clientSpecies == MONSTER_NONE) return FALSE; - if(data->clientSpecies > MONSTER_RAYQUAZA_CUTSCENE) + if(data->clientSpecies > MONSTER_MAX) return FALSE; if(data->clientSpecies != GetBaseSpecies(data->clientSpecies)) return FALSE; if(!sub_803C0DC(data->clientSpecies)) return FALSE; - if(data->targetSpecies > MONSTER_RAYQUAZA_CUTSCENE) + if(data->targetSpecies > MONSTER_MAX) return FALSE; if(data->targetSpecies != GetBaseSpecies(data->targetSpecies)) return FALSE; diff --git a/src/pokemon_mid.c b/src/pokemon_mid.c index 17f4205a2..7f30686c2 100644 --- a/src/pokemon_mid.c +++ b/src/pokemon_mid.c @@ -880,7 +880,7 @@ s32 sub_808E400(s32 _species, s16* _a2, s32 _a3, s32 _a4) register s16* a2 asm("r6"); i = 1; a2 = _a2; - for (i = 1; i <= MONSTER_RAYQUAZA_CUTSCENE; i++) { + for (i = 1; i <= MONSTER_MAX; i++) { register s32 current asm("r8") = (s16)i; if (species != GetPokemonEvolveFrom(i)) { continue; diff --git a/src/rescue_password_menu.c b/src/rescue_password_menu.c index 2bde7231c..fb00a6581 100644 --- a/src/rescue_password_menu.c +++ b/src/rescue_password_menu.c @@ -636,7 +636,7 @@ u32 sub_8039068(u32 mailMode, u8 *passwordBuffer, struct unkStruct_203B480 *para { if ( (!sub_803D204(passwordBuffer, param_3)) || (WONDER_MAIL_TYPE_OKD < param_3->mailType) || (param_3->dungeon.floor >= GetDungeonFloorCount(param_3->dungeon.id)) || - (param_3->clientSpecies == MONSTER_NONE) || (MONSTER_RAYQUAZA_CUTSCENE < param_3->clientSpecies) || + (param_3->clientSpecies == MONSTER_NONE) || (MONSTER_MAX < param_3->clientSpecies) || (IsInvalidItemReward(param_3->item.id))) { return PASSWORD_ENTRY_INCORRECT_PASSWORD; } diff --git a/src/sprite.c b/src/sprite.c index 3a09f14e9..fe6e0949c 100644 --- a/src/sprite.c +++ b/src/sprite.c @@ -883,4 +883,9 @@ void sub_800533C(struct ax_pose **a0, struct UnkSpriteMem **a1, struct axdata1 * sub_8004EA8(r4, a2, mem, spriteMasks); } +} + +void sub_80053AC(struct Entity_Sub28 *a0, struct Dungeon_Sub17B44 *a1, u32 a2, u32 a3, u32 a4, u32 spriteAnimIndex, bool8 a6) +{ + sub_80053D0(a0, a1->unk4, a2, a3, a4, spriteAnimIndex, a6); } \ No newline at end of file