Skip to content

Actor: Start list of actor types, add .data to Actor init, document some types, parse more spawn tables.#35

Open
blackgamma7 wants to merge 28 commits into
Drahsid:masterfrom
blackgamma7:ActorInit
Open

Actor: Start list of actor types, add .data to Actor init, document some types, parse more spawn tables.#35
blackgamma7 wants to merge 28 commits into
Drahsid:masterfrom
blackgamma7:ActorInit

Conversation

@blackgamma7

@blackgamma7 blackgamma7 commented Jun 29, 2026

Copy link
Copy Markdown
Contributor
  • create list of Actor Types in actorype.h.
    • includes list of overlay id's in high byte to be filled out
  • add .data to actor_init.c, with list of cooresponding actor types.
  • document behavior of several actor types.
    • Warp gate (aka Warp Star)
    • Clanpot
    • Spikeballs
  • parse more actor spawn tables in Overlay 4 scripts.
  • ID or doc more actor fields.
    • 2 are used in clanpot code as inventory check function pointers.
    • one is used to hold warp gate's destination.
    • one is likely the index of the parent actor.
    • 0x110 is another "general purpose" field, set as a param on some init's.
    • 0xD8 is another "general purpose" field, set as a param on some init's.
  • add more labels to actor-related code.
  • use (u)intptr_t when pointer-as-int is needed to match.
  • add #define for Marina player actor
  • cleanup/proofreading.

blackgamma7 and others added 28 commits June 16, 2026 00:06
text script for later.
id actor types

@Drahsid Drahsid 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.

Maybe worth doing a small cleanup pass for whitespace, but otherwise insanely good work!

This one is pretty big, so I probably missed something, @queueRAM care to take a second look?

Comment thread include/actor.h
Comment on lines +198 to +200
// NOTE: trying to use unions for these variables for different datatypes (u8[4],u16[2])
// may cause mismatch due to "narrowing"

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.

I know this is the same comment as below, but moved, but it may be worth better explaining the issue: narrowing is when a wider data type is truncated to fit a smaller data type, ex: s32 -> s16

iirc the discussion on this previously was about a circumstance of 16/8 -> 32 -> 16/8 implied that the source type the compiler saw was smaller, but a literal resulted in int-promotion (ex: lhs is 16 bit but the literal is inherently 32-bit, so it promotes the lhs to 32 bit) which then immediately got narrowed. The tricky part about this is that it caused confusion about the field type because the conversion and odd scheduling around the implicit cast.

Comment thread include/actorTypes.h

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.

the spacing around {} and // and = are inconsistent

Comment thread include/inttypes.h
Comment on lines +11 to +12
typedef s32 intptr_t; // sometimes, pointers need to be treated as int's to match.
typedef u32 uintptr_t; // sometimes, pointers need to be treated as int's to match.

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.

Suggested change
typedef s32 intptr_t; // sometimes, pointers need to be treated as int's to match.
typedef u32 uintptr_t; // sometimes, pointers need to be treated as int's to match.
typedef s32 sptr; // sometimes, pointers need to be treated as int's to match.
typedef u32 uptr; // sometimes, pointers need to be treated as int's to match.

I think this reads better and is more consistent with existing primitive type typedefs

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I looked through the other decomp projects - they also used the intptr_t typedef. I think using would make it more consistent with them.

Comment thread include/Scene.h
#define SCENE_BEESTHEONE 0x4E
#define SCENE_INNERSTRUGGLE 0x4F
#define SCENE_UNK80 0x50 // crash. data suggest more stages were planned for world 5.
#define SCENE_UNK80 0x50 // crash. data suggest more stages were planned for world 5. Also index of "level clear" graphics.

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.

There are 88 scenes. I'm pretty sure this one is a valid scene. Maybe it requires a certain gamestate? It has mostly valid data anyway.

This is what I see in the data at least:

  • It's actual collision data is set up coherently
  • The functions which are called when the scene is loaded are not null
  • It builds the scene collision with collision pages 0000, 0001, 0002 (these blank pages)
  • asset rows are populated (besides 4/5, which is unusual I guess)

Since the collision is just pages of zero-bytes, I suspect if you load in with the player, you either get a 'missing 0xC0 blocks' crash or some sort of render crash with bogus assets.

Comment thread include/actor.h
#define PLAYER_INDEX 0

// actor 0 is always the player character, Marina
#define gMarina gActors[PLAYER_INDEX]

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.

Suggested change
#define gMarina gActors[PLAYER_INDEX]
#define gPlayerActor gActors[PLAYER_INDEX]

the PC isn't always Marina. Teran also uses this slot (as well as a couple more,) so 'player actor' is probably the better name here.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I looked at the memory in that area while playing Teran's levels - the type and HP remained Marina's. I think there's some not-yet documented trickery to hide them and give to control to Teran.

@queueRAM

queueRAM commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

This one is pretty big, so I probably missed something, @queueRAM care to take a second look?

This is beautiful. I skimmed through all your changes and no issues stood out. I agree that gPlayerActor makes sense for gActors[0]. Note, I think there are some instances of gActors-> in the codebase that should also be changed, but i've seen this will sometimes no longer match when switching to gActors[0]. If you hit this, I'm happy to help look into it.

@blackgamma7

blackgamma7 commented Jul 1, 2026

Copy link
Copy Markdown
Contributor Author

I agree that gPlayerActor makes sense for gActors[0].

As noted in a previous comment, gActors[0] retains its HP and type during Teran's stages, plus the GemCollect() code suggests it will also change behavior if D_800D2950 is non-zero, suggesting this is the index of the "guest" player character.

Note, I think there are some instances of gActors-> in the codebase that should also be changed, but i've seen this will sometimes no longer match when switching to gActors[0]. If you hit this, I'm happy to help look into it.

Yeah, I didn't want to touch those just yet, lest I break something.

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