diff --git a/asm/include/overlay_29_022F73EC.inc b/asm/include/overlay_29_022F740C.inc similarity index 86% rename from asm/include/overlay_29_022F73EC.inc rename to asm/include/overlay_29_022F740C.inc index 7062ff89..783b5d91 100644 --- a/asm/include/overlay_29_022F73EC.inc +++ b/asm/include/overlay_29_022F740C.inc @@ -1,7 +1,6 @@ #pragma once .public DUNGEON_PTR .public DirectoryFileMngr_GetDirectoryFileSize -.public FloorNumberIsEven .public GendersEqualNotGenderless .public GetMonsterGender .public GetSpriteFileSize @@ -10,6 +9,5 @@ .public LoadWanTableEntryFromPack .public LoadWanTableEntryFromPackUseProvidedMemory .public MemAlloc -.public ReplaceWanFromBinFile .public WAN_TABLE .public ov29_0237C9B0 diff --git a/asm/overlay_29_022F73EC.s b/asm/overlay_29_022F740C.s similarity index 71% rename from asm/overlay_29_022F73EC.s rename to asm/overlay_29_022F740C.s index 992ab3a4..c1facba1 100644 --- a/asm/overlay_29_022F73EC.s +++ b/asm/overlay_29_022F740C.s @@ -1,21 +1,8 @@ .include "asm/macros.inc" - .include "overlay_29_022F73EC.inc" + .include "overlay_29_022F740C.inc" .text - arm_func_start GetKecleonIdToSpawnByFloor -GetKecleonIdToSpawnByFloor: ; 0x022F73EC - stmdb sp!, {r3, lr} - bl FloorNumberIsEven - cmp r0, #0 - ldrne r0, _022F7404 ; =0x000003D7 - ldreq r0, _022F7408 ; =0x0000017F - ldmia sp!, {r3, pc} - .align 2, 0 -_022F7404: .word 0x000003D7 -_022F7408: .word 0x0000017F - arm_func_end GetKecleonIdToSpawnByFloor - arm_func_start StoreSpriteFileIndexBothGenders StoreSpriteFileIndexBothGenders: ; 0x022F740C stmdb sp!, {r3, r4, r5, r6, r7, lr} @@ -163,46 +150,3 @@ _022F75C8: .word 0x00019914 _022F75CC: .word ov29_0237C9B0 _022F75D0: .word WAN_TABLE arm_func_end LoadMonsterSpriteInner - - arm_func_start SwapMonsterWanFileIndex -SwapMonsterWanFileIndex: ; 0x022F75D4 - stmdb sp!, {r3, r4, r5, r6, lr} - sub sp, sp, #4 - ldr r2, _022F764C ; =DUNGEON_PTR - mov r5, r1 - ldr r1, [r2] - mov r6, r0 -#ifdef JAPAN - add r1, r1, #0x870 - mov r0, r5 - add r4, r1, #0x19000 -#else - add r1, r1, #0x114 - mov r0, r5 - add r4, r1, #0x19800 -#endif - bl GetSpriteIndex__020526EC - mov r1, #1 - str r1, [sp] - mov r1, r6, lsl #1 - ldr r2, _022F7650 ; =WAN_TABLE - mov r3, r0 - ldrsh r1, [r4, r1] - ldr r0, [r2] - mov r2, #0 - bl ReplaceWanFromBinFile - mov r1, r0 - mov r0, r5 - bl StoreSpriteFileIndexBothGenders - mov r3, r6, lsl #1 - ldrsh r2, [r4, r3] - mov r1, r5, lsl #1 - mov r0, #0 - strh r2, [r4, r1] - strh r0, [r4, r3] - add sp, sp, #4 - ldmia sp!, {r3, r4, r5, r6, pc} - .align 2, 0 -_022F764C: .word DUNGEON_PTR -_022F7650: .word WAN_TABLE - arm_func_end SwapMonsterWanFileIndex diff --git a/include/enums.h b/include/enums.h index d36c2d12..fba9444b 100644 --- a/include/enums.h +++ b/include/enums.h @@ -2913,4 +2913,19 @@ enum mobility_type { NUM_MOBILITY_TYPES }; +enum wan_source_type { + WAN_SOURCE_NULL = 0, + WAN_SOURCE_FILE = 1, // Directly loaded from a .wan + WAN_SOURCE_PACK = 2, // Loaded from a pack file +}; + +enum pack_file_id { + PACK_ARCHIVE_MONSTER = 0, + PACK_ARCHIVE_M_ATTACK = 1, + PACK_ARCHIVE_M_GROUND = 2, + PACK_ARCHIVE_EFFECT = 3, + PACK_ARCHIVE_DUNGEON = 4, + PACK_ARCHIVE_M_LEVEL = 5, +}; + #endif //PMDSKY_ENUMS_H diff --git a/include/overlay_29_022F73B4.h b/include/overlay_29_022F73B4.h index b47b8313..8387e9da 100644 --- a/include/overlay_29_022F73B4.h +++ b/include/overlay_29_022F73B4.h @@ -4,5 +4,6 @@ #include "util.h" bool32 FloorNumberIsEven(); +s16 GetKecleonIdToSpawnByFloor(); #endif //PMDSKY_OVERLAY_29_022F73B4_H diff --git a/include/overlay_29_022F7654.h b/include/overlay_29_022F7654.h index 90faf2f9..7b90e340 100644 --- a/include/overlay_29_022F7654.h +++ b/include/overlay_29_022F7654.h @@ -2,6 +2,7 @@ #define PMDSKY_OVERLAY_29_022F7654_H #include "enums.h" +void SwapMonsterWanFileIndex(s16 src_id, s16 dst_id); void LoadMonsterSprite(s16 monster_id, u8 skip_deoxys_check); #endif //PMDSKY_OVERLAY_29_022F7654_H diff --git a/include/wan.h b/include/wan.h index 8f686ddc..14480997 100644 --- a/include/wan.h +++ b/include/wan.h @@ -11,4 +11,38 @@ struct wan_animation_frame { struct vec2_16 shadow_offset; }; -#endif //PMDSKY_WAN_H \ No newline at end of file +struct wan_table_entry { + char path[32]; // 0x0: Needs to be null-terminated. Only used for direct file. + bool8 file_externally_allocated; // 0x20: True if the iov_base shouldn’t be freed by this struct. + u8 source_type; // 0x21: 1 = direct file, 2 = pack file + s16 pack_id; // 0x22: for wan in pack file + s16 file_index; // 0x24: for wan in pack file + u8 field5_0x26; + u8 field6_0x27; + u32 iov_len; + // 0x2C: When removing a reference, if it reaches 0, the entry is removed (unless + // file_externally_allocated is true, as it is always removed even if there are remaining + // references) + s16 reference_counter; + u8 field9_0x2e; + u8 field10_0x2f; + // 0x30: pointer to the beginning of the data section of iov_base. + struct wan_header* sprite_start; + void* iov_base; // 0x34: points to a sirO +}; + +struct wan_table { + struct wan_table_entry sprites[96]; // 0x0 + void* at_decompress_scratch_space; // 0x1500 + u8 field2_0x1504; + u8 field3_0x1505; + u8 field4_0x1506; + u8 field5_0x1507; + s16 total_nb_of_entries; // 0x1508: The total number of entries. Should be equal to 0x60. + s16 next_alloc_start_pos; // 0x150A + s16 field8_0x150c; + u8 field9_0x150e; + u8 field10_0x150f; +}; + +#endif //PMDSKY_WAN_H diff --git a/main.lsf b/main.lsf index 8d2806c7..b582ac20 100644 --- a/main.lsf +++ b/main.lsf @@ -341,7 +341,7 @@ Overlay OVY_29 Object asm/overlay_29_022F62CC.o Object src/overlay_29_022F7364.o Object src/overlay_29_022F73B4.o - Object asm/overlay_29_022F73EC.o + Object asm/overlay_29_022F740C.o Object src/overlay_29_022F7654.o Object asm/overlay_29_022F7768.o Object src/dungeon_misc.o diff --git a/src/overlay_29_022F73B4.c b/src/overlay_29_022F73B4.c index 6da53405..7f62619d 100644 --- a/src/overlay_29_022F73B4.c +++ b/src/overlay_29_022F73B4.c @@ -1,11 +1,16 @@ #include "overlay_29_022F73B4.h" #include "dungeon.h" #include "util.h" - -extern struct dungeon *DUNGEON_PTR[]; +#include "enums.h" bool32 FloorNumberIsEven() { struct dungeon *dungeon = DUNGEON_PTR[0]; if (dungeon->id == DUNGEON_LABYRINTH_CAVE && dungeon->floor == 10) return 0; return (dungeon->floor & 1) == 0; } + +s16 GetKecleonIdToSpawnByFloor() +{ + if (!FloorNumberIsEven()) return MONSTER_KECLEON; + else return MONSTER_KECLEON_SECONDARY; +} diff --git a/src/overlay_29_022F7654.c b/src/overlay_29_022F7654.c index dcbd5fc7..5938a57a 100644 --- a/src/overlay_29_022F7654.c +++ b/src/overlay_29_022F7654.c @@ -1,7 +1,21 @@ #include "overlay_29_022F7654.h" #include "dungeon.h" +#include "enums.h" +#include "wan.h" + +extern struct wan_table *WAN_TABLE; +extern s16 GetSpriteIndex__020526EC(s16 monster_id); +extern s16 ReplaceWanFromBinFile(struct wan_table *wan_table, s16 wan_id, s16 pack_id, s16 file_index, bool8 compressed); +extern void StoreSpriteFileIndexBothGenders(s16 monster_id, s16 file_id); + +void SwapMonsterWanFileIndex(s16 src_id, s16 dst_id) +{ + s16 *sprite_indexes = (s16 *)DUNGEON_PTR[0]->sprite_indexes; + StoreSpriteFileIndexBothGenders(dst_id, ReplaceWanFromBinFile(WAN_TABLE, sprite_indexes[src_id], PACK_ARCHIVE_MONSTER, GetSpriteIndex__020526EC(dst_id), TRUE)); + sprite_indexes[dst_id] = sprite_indexes[src_id]; + sprite_indexes[src_id] = 0; +} -extern struct dungeon *DUNGEON_PTR[]; extern void LoadMonsterSpriteInner(s16 monster_id); void LoadMonsterSprite(s16 monster_id, u8 skip_deoxys_check) {