Just got a chance to play this for the first time. Amazing work, very impressive indeed! It's also awesome to see the TI get some F18A love, as well as some platforming love .
Can you share a little bit about how you manage entities (enemies) in this? I'd also be interested in hearing how you manage memory for the map, special blocks, destructible blocks, etc...
Welcome back, I was afraid you might have lost interest.
To start with the map, this is stored as 2x2 metatiles, and unlike other games where I use metatiles I use this map directly instead of expanding it to tiles first. I have a table for looking up the type of each metatile, whether it's background, brick, ground, question block, etc. There are slightly more than 32 metatiles on level 1-1, so there are two bits left in each byte that I could use for storing additional data about each metatile, e.g. what 'present' a question block contains. I haven't used this yet, instead I have just used different metatile number for each type of present.
The sprite attribute table is stored in CPU RAM and is copied to VDP RAM each frame. This is actually the biggest chunk of VDP transfer, since the scrolling only require 13 bytes each frame. The first two sprites are allocated to Mario, but the others can be allocated dynamically for enemies etc. The enemies are stored as a list of structures, each containing position (x,y), velocity (vx, xy), acceleration (ax, ay), type, pattern and color, and a pointer to the sprite attributes currently allocated to the enemy. Position, speed and acceleration are stored as 12.4 fixed point. The position is in map coordinates, and the MSB is the position in metatiles, so it's easy to look up the corresponding metatile. I iterate through the enemy list each frame, and only enemies within a certain window relative to the scroll position, which extends a bit beyond the visible screen, are processed. Basically this involves adding velocity to position, adding acceleration to velocity, and doing collision detection.
The special sprite effects when a spinning coin appears, a Goomba (mushroom) is stomped, or a brick turns into debris are not handled as 'enemies' but as something I call 'sprite animations'. A sprite animation has position, velocity, and acceleration, but no collision detection takes places. It has a duration after which the sprite is deallocated and an address of an optional callback. First I thought I needed to stored the paths for a animation, but it turns out that velocity and acceleration is enough to obtain the desired effects.
This game has an amazing richness of things you can do on just the first level, the code is already longer than any of my other games, and I'm still discovering new details. I have tried to make my engine reasonably generic without overthinking it, but when I start looking at other levels I will probably have to make major changes.