Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion config/symbol_addrs.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3671,7 +3671,7 @@ g_unkblot6 = 0x26dfc8; // size:0x280
g_unkblot7 = 0x26e248; // size:0x280
g_unkblot8 = 0x26e4e0; // size:0x280
g_unkblot9 = 0x26e760; // size:0x280
g_note = 0x26e9f8; // size:0x280
g_note = 0x26e9f8; // size:0x278
g_unkblot11 = 0x26eed0; // size:0x268
g_unkblot12 = 0x26ec70;
g_totals = 0x26f138; // size:0x18
Expand Down
22 changes: 19 additions & 3 deletions include/game.h
Original file line number Diff line number Diff line change
Expand Up @@ -235,11 +235,21 @@ struct GAME
/**
* @brief Used to locate level data by its location on the disc.
*
* @todo implement
* @todo verify unknown fields.
*/
struct LevelLoadData
{
// ...
uint unk_00;
uint unk_04;
uint unk_08;
uint unk_0C;
uint unk_10;
uint unk_14;
uint unk_18;
uint unk_1C;
int level_id;
const char *pchzFriendly;
uint unk_28;
};

extern const LevelLoadData *D_00247AB0[];
Expand All @@ -251,7 +261,13 @@ void StartupGame();

// LevelLoadData * search_level_by_load_data(LevelLoadData *search_level);

// LevelLoadData * search_level_by_id(int search_id);
/**
* @brief Finds the level data associated with a level ID.
*
* @param search_id Level ID to search for.
* @return Pointer to the matching LevelLoadData, or NULL if no match is found.
*/
extern "C" LevelLoadData *search_level_by_id(int search_id);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need to mangle the name instead of treating it as C code. Take a look at the config/symbol_addrs.txt file and find the entry for search_level_by_id. Change it to search_level_by_id__Fi and then remove the extern "C" from the declaration.


/**
* @brief Gets the friendly name of a level from its world ID.
Expand Down
23 changes: 22 additions & 1 deletion src/P2/game.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,28 @@ JUNK_WORD(0x0000102D);

INCLUDE_ASM("asm/nonmatchings/P2/game", search_level_by_load_data);

INCLUDE_ASM("asm/nonmatchings/P2/game", search_level_by_id);
extern LevelLoadData D_00247AF0[46];

LevelLoadData *search_level_by_id(int search_id)
{
LevelLoadData *level = D_00247AF0;
LevelLoadData *end = D_00247AF0 + 46;

loop:
if (search_id != level->level_id)
{
level++;

if (level < end)
{
goto loop;
}

return NULL;
}
Comment on lines +46 to +57

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this could be done with a while loop? It's unlikely that they used goto in the original code.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I originally tried, and retested today, rewriting the function using more common loop constructs, such as a while loop, but was only able to produce a matching build using goto. Yes, I agree - odd...

@545u 545u Jul 25, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I managed to get a full match with a for loop. Do a for loop for each LevelLoadData then in the body get a pointer to the current data. Return that pointer if the id matches. If the end of the function is reached return NULL.

LevelLoadData *search_level_by_id(int search_id)
{
    for (uint i = 0; i < sizeof(D_00247AF0) / sizeof(LevelLoadData); i++)
    {
        LevelLoadData *level = &D_00247AF0[i];
        if (search_id == level->level_id)
        {
            return level;
        }
    }

    return NULL;
}


return level;
}

INCLUDE_ASM("asm/nonmatchings/P2/game", PchzFriendlyFromWid);

Expand Down
Loading