Decomp CopySpawnEntriesOnce. Ensure 100% matches by localising DUNGEON_PTR externs with slightly different definitions.

This commit is contained in:
slaw-22
2026-05-19 20:03:27 +00:00
parent 2c72e4bec7
commit 6b29ad6aff
48 changed files with 104 additions and 45 deletions

View File

@@ -710,7 +710,7 @@ _022DF574:
bl ov29_022E8708
bl ov29_022DD5B4
bl ov29_023369F8
bl ov29_022E7CFC
bl CopySpawnEntriesOnce
bl ov29_022F7130
cmp r5, #0
bne _022DF5C4

View File

@@ -5618,37 +5618,4 @@ _022E7CF4: .word DUNGEON_PTR
_022E7CF8: .word 0x0002C966
#endif
arm_func_end MonsterSpawnListPartialCopy
arm_func_start ov29_022E7CFC
ov29_022E7CFC: ; 0x022E7CFC
#ifdef JAPAN
#define OV29_022E7CFC_OFFSET -0xA4
#else
#define OV29_022E7CFC_OFFSET 0
#endif
stmdb sp!, {r3, lr}
ldr r1, _022E7D48 ; =DUNGEON_PTR
ldr r0, [r1]
add r0, r0, #0x3000
ldrb r2, [r0, #0xe28 + OV29_022E7CFC_OFFSET]
cmp r2, #0
ldmneia sp!, {r3, pc}
mov r2, #1
strb r2, [r0, #0xe28 + OV29_022E7CFC_OFFSET]
ldr r0, [r1]
mov r1, #0
#ifdef JAPAN
add r0, r0, #0x124
#else
add r0, r0, #0x174
#endif
add r0, r0, #0x3800
bl CopySpawnEntriesMaster
ldr r1, _022E7D48 ; =DUNGEON_PTR
ldr r1, [r1]
add r1, r1, #0x3000
str r0, [r1, #0xe20 + OV29_022E7CFC_OFFSET]
ldmia sp!, {r3, pc}
.align 2, 0
_022E7D48: .word DUNGEON_PTR
arm_func_end ov29_022E7CFC

View File

@@ -12,8 +12,6 @@
#define DUNGEON_MAX_SIZE_Y 32
#define CORRIDOR_ROOM 0xFF
extern struct dungeon *DUNGEON_PTR[];
enum terrain_type
{
// These 3 seem to indicate the 'main' type of the terrain. See helper functions for how they're set.
@@ -1217,9 +1215,8 @@ struct dungeon {
u8 field_0x3e25;
u8 field_0x3e26;
u8 field_0x3e27;
// 0x3E28: Related in some way to the spawn entries on the floor. Does something about them
// if false, then set to true.
bool8 unk_spawn_entry_id_check;
// 0x3E28: Set to true after spawn entries are copied. Prevents copying spawn entries more than once.
bool8 spawn_entries_copied;
u8 field_0x3e29;
u8 field_0x3e2a;
u8 field_0x3e2b;

6
include/spawn_1.h Normal file
View File

@@ -0,0 +1,6 @@
#ifndef PMDSKY_SPAWN_1_H
#define PMDSKY_SPAWN_1_H
void CopySpawnEntriesOnce();
#endif //PMDSKY_SPAWN_1_H

View File

@@ -1,5 +1,5 @@
#ifndef PMDSKY_SPAWN_H
#define PMDSKY_SPAWN_H
#ifndef PMDSKY_SPAWN_2_H
#define PMDSKY_SPAWN_2_H
// Weight type index is 0 for normal spawns and 1 for monster house spawns.
// Returns a monster ID.
@@ -7,4 +7,4 @@ s32 GetMonsterIdToSpawn(s32 weight_type_idx);
s32 GetMonsterLevelToSpawn(s32 monster_id);
s32 IsOnMonsterSpawnList(s32 monster_id);
#endif //PMDSKY_SPAWN_H
#endif //PMDSKY_SPAWN_2_H

View File

@@ -506,7 +506,8 @@ Overlay OVY_29
Object asm/overlay_29_022E335C.o
Object src/dg_effect.o
Object asm/overlay_29_022E37DC.o
Object src/spawn.o
Object src/spawn_1.o
Object src/spawn_2.o
Object asm/overlay_29_022E7EC4.o
Object src/position_util.o
Object asm/overlay_29_rodata_02351628.o

View File

@@ -6,6 +6,8 @@
// file starts at 0x022e26b68
extern struct dungeon *DUNGEON_PTR[];
bool8 EntityIsValid__022E32E8(struct entity *entity)
{
if (entity == NULL)

View File

@@ -4,6 +4,7 @@
// file starts at 0x022e9020
extern struct dungeon *DUNGEON_PTR[];
extern struct entity *LEADER_PTR;
struct entity* GetLeader()

View File

@@ -24,6 +24,8 @@
#define WATCHING_CAREFULLY_MESSAGE 0xDEE
#endif
extern struct dungeon *DUNGEON_PTR[];
extern void EndFrozenClassStatus(struct entity *user, struct entity *target, bool8 log);
extern void SubstitutePlaceholderStringTags(u8 *string_id, struct entity *entity, u32 param_3);
extern void LogMessageByIdWithPopupCheckUser(struct entity *user, u32 message_id);

View File

@@ -27,6 +27,7 @@
bool8 AI_CAN_ATTACK_IN_DIRECTION[NUM_DIRECTIONS] = {0};
u8 AI_POTENTIAL_ATTACK_TARGET_DIRECTIONS[NUM_DIRECTIONS] = {0};
extern struct dungeon *DUNGEON_PTR[];
// AI_POTENTIAL_ATTACK_TARGET_WEIGHTS is defined twice within AiConsiderMove, so it needs two separate symbols in ASM until the function is matched.
#ifdef NONMATCHING

View File

@@ -29,6 +29,8 @@
#define REGULAR_ATTACK_INDEX 4
extern struct dungeon *DUNGEON_PTR[];
// https://decomp.me/scratch/zg7V6
#ifdef NONMATCHING
void ChooseAiMove(struct entity *monster)

View File

@@ -16,6 +16,7 @@
// This needs to be marked as non-volatile here to match GetPossibleAiThrownItemDirections,
// but AiDecideUseItem needs it to be volatile to match.
extern s32 AI_THROWN_ITEM_ACTION_CHOICE_COUNT;
extern struct dungeon *DUNGEON_PTR[];
void GetPossibleAiThrownItemDirections(struct entity *entity, s32 ally_or_enemy, struct item *item, bool8 always_add)
{

View File

@@ -40,6 +40,8 @@
#define TURN_RIGHT_90 4
#define TURN_LEFT_135 5
extern struct dungeon *DUNGEON_PTR[];
struct can_move_in_direction_info
{
bool8 try_turn;

View File

@@ -16,6 +16,8 @@
#include "secondary_terrain_types.h"
#include "targeting.h"
extern struct dungeon *DUNGEON_PTR[];
bool8 CanMonsterMoveOrSwapWithAllyInAnyDirection(struct entity *monster)
{
for (u8 i = 0; i < NUM_DIRECTIONS; i++)

View File

@@ -12,6 +12,8 @@
#define NUM_EFFECTIVENESS 4
extern struct dungeon *DUNGEON_PTR[];
s32 WeightWeakTypePicker(struct entity *user, struct entity *target, enum type_id move_type)
{
s32 weight = 1;

View File

@@ -9,6 +9,8 @@
#include "overlay_29_023000E4.h"
#include "special_move_types.h"
extern struct dungeon *DUNGEON_PTR[];
extern s32 GetMoveBasePower(struct move*);
bool8 CanSeeTeammate(struct entity *monster)

View File

@@ -6,6 +6,8 @@
#include "fixed_room_data_1.h"
#include "util.h"
extern struct dungeon *DUNGEON_PTR[];
bool8 IsMonsterLoneOutlaw(struct monster* monster_info)
{
return IsBehaviorLoneOutlaw(monster_info->monster_behavior);

View File

@@ -1,6 +1,7 @@
#include "dungeon_map_access.h"
#include "dungeon.h"
extern struct dungeon *DUNGEON_PTR[];
extern struct tile DEFAULT_TILE_COPY;
extern struct tile* DEFAULT_TILE;

View File

@@ -4,6 +4,8 @@
#include "secondary_terrain_types.h"
#include "tileset.h"
extern struct dungeon *DUNGEON_PTR[];
bool8 IsTileGround(struct tile *tile)
{
bool8 is_ground = FALSE;

View File

@@ -11,6 +11,8 @@
#include "progression.h"
#include "pokemon.h"
extern struct dungeon *DUNGEON_PTR[];
bool8 CanSeeInvisibleMonsters(struct entity *entity)
{
if (GetEntInfo(entity)->blinker_class_status.blinded == STATUS_BLINKER_EYEDROPS)

View File

@@ -20,6 +20,8 @@
#define CURVED_PROJECTILE_LOG_MESSAGE_3 0xbe3
#endif
extern struct dungeon *DUNGEON_PTR[];
extern bool8 ov29_022E2CA0(struct position *pos);
extern void ov29_0234B4CC(bool8 val);
extern s32 SinAbs4096(s32 x);

View File

@@ -5,6 +5,8 @@
#include "dungeon_range_2.h"
#include "main_0208655C.h"
extern struct dungeon *DUNGEON_PTR[];
bool8 IsPositionActuallyInSight(struct position *origin, struct position *target, bool8 user_has_dropeye)
{
s16 visibility = GetVisibilityRange();

View File

@@ -33,6 +33,7 @@ extern const s16 ROCK_HORN_RECRUIT_BOOST;
extern const s16 GRASS_CORNET_RECRUIT_BOOST;
extern const s16 SKY_MELODICA_RECRUIT_BOOST;
extern struct dungeon *DUNGEON_PTR[];
extern s16 RECRUITMENT_LEVEL_BOOST_TABLE[];
bool8 SpecificRecruitCheck(u32 monster_id)

View File

@@ -2,6 +2,8 @@
#include "dungeon.h"
extern struct dungeon *DUNGEON_PTR[];
bool8 IsFullFloorFixedRoom()
{
u8 fixed_room_id = DUNGEON_PTR[0]->gen_info.fixed_room_id;

View File

@@ -17,6 +17,8 @@
#include "trap.h"
#include "weather.h"
extern struct dungeon *DUNGEON_PTR[];
extern bool8 GendersEqualNotGenderless(s16 monster1, s16 monster2);
// https://decomp.me/scratch/TnODN

View File

@@ -11,6 +11,8 @@ void sub_020091B0(s32, s32);
void StartFadeDungeonWrapper(s32, s32, s32);
void ov29_0234C738(s32);
extern struct dungeon *DUNGEON_PTR[];
struct dungeon* DungeonAlloc(void)
{
#ifdef JAPAN

View File

@@ -4,6 +4,8 @@
#include "util.h"
#include "main_02051760.h"
extern struct dungeon *DUNGEON_PTR[];
bool8 EntityIsValid__022F7364(struct entity *entity)
{
if (entity == NULL)

View File

@@ -3,6 +3,8 @@
#include "util.h"
#include "enums.h"
extern struct dungeon *DUNGEON_PTR[];
bool32 FloorNumberIsEven() {
struct dungeon *dungeon = DUNGEON_PTR[0];
if (dungeon->id == DUNGEON_LABYRINTH_CAVE && dungeon->floor == 10) return 0;

View File

@@ -3,6 +3,7 @@
#include "enums.h"
#include "wan.h"
extern struct dungeon *DUNGEON_PTR[];
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);

View File

@@ -7,6 +7,8 @@
#include "overlay_29_02336428.h"
#include "position_util.h"
extern struct dungeon *DUNGEON_PTR[];
bool8 ShouldMonsterHeadToStairs(struct entity *entity)
{
u8 stairs_room = GetStairsRoom();

View File

@@ -5,6 +5,8 @@
#include "overlay_29_022F7364.h"
#include "targeting.h"
extern struct dungeon *DUNGEON_PTR[];
extern u8 GetScenarioBalanceVeneer();
extern u32 GetSpawnThreshold();

View File

@@ -3,6 +3,8 @@
#include "dungeon_util_static.h"
#include "overlay_29_022F7364.h"
extern struct dungeon *DUNGEON_PTR[];
struct entity* FindMonsterWithBehavior(enum monster_behavior monster_behavior)
{
for (s32 i = 0; i < DUNGEON_MAX_POKEMON; i++)

View File

@@ -1,6 +1,8 @@
#include "overlay_29_023000E4.h"
#include "dungeon_util_static.h"
extern struct dungeon *DUNGEON_PTR[];
bool8 EntityIsValid__023000E4(struct entity *entity)
{
if (entity == NULL)

View File

@@ -3,6 +3,8 @@
#include "dungeon_pokemon_attributes.h"
#include "dungeon_util_static.h"
extern struct dungeon *DUNGEON_PTR[];
bool8 ScrappyShouldActivate(struct entity *attacker, struct entity *defender, enum type_id attack_type)
{
for (s16 i = 0; i < 2; i++)

View File

@@ -2,6 +2,8 @@
#include "dungeon.h"
#include "dungeon_map_access.h"
extern struct dungeon *DUNGEON_PTR[];
u8 GetStairsRoom()
{
return GetTile(DUNGEON_PTR[0]->gen_info.stairs_pos.x, DUNGEON_PTR[0]->gen_info.stairs_pos.y)->room;

View File

@@ -3,6 +3,8 @@
#include "main_0200330C.h"
#include "overlay_29_02337CA8.h"
extern struct dungeon *DUNGEON_PTR[];
extern void LogMessageByIdWithPopupCheckUser(struct entity *user, u32 message_id);
extern void ov29_02306D54(struct entity *);

View File

@@ -3,6 +3,8 @@
#include "dungeon.h"
#include "dungeon_mode.h"
extern struct dungeon *DUNGEON_PTR[];
extern void TryRevealAttackedTrap(struct position* pos, int param1);
extern bool32 PositionIsOnHiddenStairs(struct position* pos);
extern void HiddenStairsTrigger(bool32 param0);

View File

@@ -2,6 +2,8 @@
#include "dungeon.h"
extern struct dungeon *DUNGEON_PTR[];
bool8 TeamMemberHasExclusiveItemEffectActive(u8);
bool8 ShouldBoostKecleonShopSpawnChance(void)

View File

@@ -2,6 +2,7 @@
#include "dungeon.h"
#include "fixed_room_data_1.h"
extern struct dungeon *DUNGEON_PTR[];
extern u16 ov29_02352B5C[2];
void ov29_02344E88(s16 *param_1);

View File

@@ -2,6 +2,8 @@
#include "dungeon.h"
extern struct dungeon *DUNGEON_PTR[];
bool8 IsSecretBazaar()
{
return DUNGEON_PTR[0]->gen_info.fixed_room_id==FIXED_SECRET_BAZAAR;

View File

@@ -6,6 +6,8 @@
#include "weather.h"
#include "main_02001188.h"
extern struct dungeon *DUNGEON_PTR[];
extern const u8 DUNGEON_MENU_SWITCH_STR1[];// = "[dungeon:0]";
extern struct struct_1* OVERLAY31_UNKNOWN_POINTER__NA_238A260[2];

View File

@@ -3,6 +3,7 @@
#include "dungeon_map_access.h"
#include "overlay_29_022E1610.h"
extern struct dungeon *DUNGEON_PTR[];
extern struct loc_struct* OVERLAY31_UNKNOWN_POINTER__NA_238A26C;
extern struct bag_items* BAG_ITEMS_PTR_MIRROR;
extern u32 OVERLAY31_UNKNOWN_STRUCT__NA_2389EF0;

View File

@@ -4,6 +4,7 @@
#include "overlay_31_02383478.h"
#include "main_02001188.h"
extern struct dungeon *DUNGEON_PTR[];
extern struct loc_struct* OVERLAY31_UNKNOWN_POINTER__NA_238A26C;
extern u8 PositionHasItem(struct position* pos);

View File

@@ -2,6 +2,8 @@
#include "dungeon.h"
#include "overlay_10_022C2574.h"
extern struct dungeon *DUNGEON_PTR[];
bool8 IsCurrentTilesetBackground()
{
return IsBackgroundTileset(DUNGEON_PTR[0]->gen_info.tileset_id);

View File

@@ -2,6 +2,8 @@
#include "dungeon.h"
#include "enums.h"
extern struct dungeon *DUNGEON_PTR[];
bool8 IsBossFight(enum fixed_room_id fixed_room_id)
{
if (fixed_room_id != FIXED_NONE && fixed_room_id < FIXED_ZERO_ISLE_NORTH)

15
src/spawn_1.c Normal file
View File

@@ -0,0 +1,15 @@
#include "dungeon.h"
#include "spawn_1.h"
extern s32 CopySpawnEntriesMaster(struct monster_spawn_entry[], s32);
extern struct dungeon *DUNGEON_PTR;
void CopySpawnEntriesOnce() {
if (DUNGEON_PTR->spawn_entries_copied != FALSE) {
return;
}
DUNGEON_PTR->spawn_entries_copied = 1;
DUNGEON_PTR->monster_spawn_entries_length =
CopySpawnEntriesMaster(DUNGEON_PTR->spawn_entries, 0);
}

View File

@@ -1,7 +1,9 @@
#include "dg_random.h"
#include "dungeon.h"
#include "overlay_29_022F73B4.h"
#include "spawn.h"
#include "spawn_2.h"
extern struct dungeon *DUNGEON_PTR[];
extern s32 GetMonsterIdFromSpawnEntry(struct monster_spawn_entry *);
extern s32 GetMonsterLevelFromSpawnEntry(struct monster_spawn_entry *);

View File

@@ -3,6 +3,8 @@
#include "dungeon_items.h"
#include "dungeon_pokemon_attributes.h"
extern struct dungeon *DUNGEON_PTR[];
enum weather_id GetApparentWeather(struct entity *entity)
{
if (entity != NULL)