Here is a modification to MapSprite2. This operates somewhat like MapSprite2 but the map comes from ram. The tilemap looks similar too except the tile ids are vram ids. That means that flash tiles are += RAM_TILES_COUNT. The SPRITE_RAM flag will be set if the tile is a ram tile. Otherwise, it is the same.
** edit:: CODE HAS BEEN CORRECTED. If the sprite_bank for the flash tiles is NOT 0 then you must specify it. Also, I make sure to clear the sprite_bank flags if the tile is a ram tile.
Code: Select all
void MapSprite2_nra( unsigned char startSprite, const char *map, u8 spriteFlags ) {
// Similar syntax to MapSprite2. Supports all sprite flags such as: SPRITE_FLIP_X, SPRITE_FLIP_Y, SPRITE_OFF.
// The map uses vram ids (not the normal tile ids.)
// SPRITE_RAM is set automatically as determined by the value of the vram id.
// If an individual tile is < RAM_TILES_COUNT then SPRITE_RAM in spriteFlags will be set for that tile.
// The map is expected to be from ram.
// After being mapped, MoveSprite can be used as expected.
u8 mapWidth = map[0]; // Tilemap width.
u8 mapHeight = map[1]; // Tilemap height.
u8 x; // Starting X origin.
u8 y; // Starting Y origin.
s8 dx; // Destination X position.
s8 dy; // Destination t position.
u8 t; // Tile id.
// SPRITE_FLIP_X and SPRITE_FLIP_Y are used to determine the draw order of the map.
// The kernel will take care of the actual sprite flipping on x and/or y.
if(spriteFlags & SPRITE_FLIP_X){ x=(mapWidth-1); dx=-1; }
else{ x=0; dx=1; }
if(spriteFlags & SPRITE_FLIP_Y){ y=(mapHeight-1); dy=-1; }
else{ y=0; dy=1; }
// Go through the map and adjust the values in the sprites array.
for(u8 cy=0;cy<mapHeight;cy++){
for(u8 cx=0;cx<mapWidth;cx++){
// Get the vram tile id.
t=map[ (y * mapWidth) +x +2 ] ;
// Set the tile id and the sprite flags.
// Is this a ram tile?
if( t < RAM_TILES_COUNT ){
// Set the tile id to be the tileIndex of this sprite entry.
sprites[startSprite].tileIndex=t;
// Set the SPRITE_RAM flag in spriteFlags of this sprite entry based on the value of the tile id.
// Make sure that a spritebank is NOT set for this.
sprites[startSprite].flags = spriteFlags | SPRITE_RAM & ~(
SPRITE_BANK0 |
SPRITE_BANK1 |
SPRITE_BANK2 |
SPRITE_BANK3
) ;
}
// This is a flash tile. Use the specified spriteFlags (which should also include the SPRITE_BANK if it is not SPRITE_BANK0.)
else{
sprites[startSprite].tileIndex=t-RAM_TILES_COUNT;
sprites[startSprite].flags = spriteFlags ;
}
// Advance x.
x+=dx;
// Advance to the next sprite.
startSprite++;
}
// Advance y.
y+=dy;
// Set the next x position.
x = (spriteFlags & SPRITE_FLIP_X) ? (mapWidth-1) : (0);
}
}
Looking at kernel/videoMode3/videoMode3core.s on line 1152 I see an #if. It looks like BlitSpritePart can do do ram tile sourced or flash tile sourced, but not both. Am I correct? What I do is copy a vram region to get tile ids and I prepend the width and height value. Some of those tiles are flash and some are ram tiles.
Could a modification be made that would allow for usage of the kernel sprite blitter AND be able to source sprite tiles from EITHER flash or ram?