Skip to content

Decompiled search_level_by_id and fixed a symbol metadata issue that was preventing a matching rebuild. - #267

Open
MarkoGutierro wants to merge 4 commits into
TheOnlyZac:mainfrom
MarkoGutierro:Working-Branch
Open

Decompiled search_level_by_id and fixed a symbol metadata issue that was preventing a matching rebuild.#267
MarkoGutierro wants to merge 4 commits into
TheOnlyZac:mainfrom
MarkoGutierro:Working-Branch

Conversation

@MarkoGutierro

@MarkoGutierro MarkoGutierro commented Jul 20, 2026

Copy link
Copy Markdown
  • src/P2/game.c: Replaced the INCLUDE_ASM stub for search_level_by_id with a byte-matching C implementation reverse engineered from the original assembly.

  • include/game.h: Add the search_level_by_id declaration to include/game.h while keeping LevelLoadData forward-declared.

  • config/symbol_addrs.txt: Corrected g_note's size from 0x280 to 0x278 to match the actual symbol boundary and restore a checksum-clean build.

Correct g_note's size from 0x280 to 0x278 to match the actual symbol boundary. This restores a checksum-clean build by ensuring the symbol metadata matches the original binary.
Replace the INCLUDE_ASM stub with a byte-matching C implementation reverse engineered from the original assembly.
Add the search_level_by_id declaration to include/game.h while keeping LevelLoadData forward-declared.

@TheOnlyZac TheOnlyZac left a comment

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.

Thank you for the PR! I would just ask you to make a few tweaks, please let me know if you run into any issues.

Comment thread include/game.h Outdated
Comment on lines +251 to +259
#ifdef __cplusplus
extern "C" {
#endif

LevelLoadData *search_level_by_id(int search_id);

#ifdef __cplusplus
}
#endif

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.

This function should be C++ so you can delete everything here except the function signature.

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.

The function name appears to mangle when I try to run it without stating to use C linkage. Condensed the code to take up less space.

Comment thread include/game.h Outdated
{
// ...
};
struct LevelLoadData;

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.

Please re-add the braces, even though the struct is empty, to indicate that the struct eventually needs to be defined here.

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 had originally defined this struct in the src/P2/game.c file. I moved the definition to the header file.

Comment thread src/P2/game.c Outdated
uint unk_18;
uint unk_1C;
int level_id;
const char *friendly;

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.

Rename to achzFriendly to adhere to style guide.

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.

Renamed to pchzFriendly. Used 'p' instead of 'a' to indicate pointer instead of array.

Comment thread src/P2/game.c
Comment on lines +67 to +78
loop:
if (search_id != level->level_id)
{
level++;

if (level < end)
{
goto loop;
}

return NULL;
}

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;
}

Move the full LevelLoadData struct definition from game.c into game.h so the type and its fields are defined in the header.

Rename the friendly string field to pchzFriendly for project naming consistency.

Replace the multi-line extern "C" wrapper for search_level_by_id with a single-line declaration to reduce header space while preserving C linkage and avoiding C++ name mangling.

Keep the goto-based implementation after verifying equivalent while-loop rewrites do not produce a matching build.

Move the search_level_by_id documentation to game.h alongside its declaration and remove the duplicate comment from game.c.
Comment thread include/game.h
* @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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants