We've just updated MediaWiki and its underlying software. If anything doesn't look or work quite right, please mention it to us. --RanAS

SA-1 Pack: Difference between revisions

From SnesLab
Jump to: navigation, search
(MaxTile memory management)
Line 43: Line 43:


The simplest approach would be letting each priority have all slots available: 512 bytes main table + 128 bytes attribute table. With four priorities available, you would end up spending 2560 bytes of RAM, plus the pointers of each one. Overkill considering there are only 128 free slots and in the end a good chunk of the RAM will end up unused.
The simplest approach would be letting each priority have all slots available: 512 bytes main table + 128 bytes attribute table. With four priorities available, you would end up spending 2560 bytes of RAM, plus the pointers of each one. Overkill considering there are only 128 free slots and in the end a good chunk of the RAM will end up unused.
Another thought approach was instead of using 2560 bytes of RAM, is using 2048 bytes at $40:C000-$40:C7FF so it could be mapped to $6000-$7FFF using the $2224 and $2225 SA-1 registers. However, each there would be only enough free space for three OAM buffers for four different priorities, which we would be forced to have two or three profiles with less OAM slots available and different performance profiles would be needed to implement (one that gives more free slots to low priority, another that gives more free slots to high priority, etc.).
The chosen approach was actually using the unused bits of properties table to define sprite priority (#$00 - normal, #$40 - low, #$80 - highest, #$C0 - high), reducing the amount of required memory to 512 + 128 (main draw buffer and properties) + pointers, keeping the cycle complexity somewhat similar (four table iterations).


[[Category:Super Mario World]] [[Category:ASM]]
[[Category:Super Mario World]] [[Category:ASM]]

Revision as of 19:02, 24 November 2019

SA-1 Pack is a package of patches for activating and optimizing the SA-1 system for Super Mario World, with emphasis on eliminating slowdown, game limitations and accelerating the engine to the maximum possible. Unlike SA-1 Root, SA-1 Pack is focused for ROM hacking and it includes several features for implementing new features for the game using the chip.

Being the most complex patch made for Super Mario World, SA-1 Pack requires to all other ASM patches apply a RAM remap for warranting compatibility with the patch. However, without the RAM remap, it would have been impossible to accelerate the game because the SA-1 chip cannot access the S-CPU work memory (WRAM).

For implementation details, see SA-1 Root.

Features

  • Makes the game run up to four times faster.
  • Increase the maximum amount of sprites at once on screen to 22.
  • Increase the maximum amount of sprites on a single sub-level to 255.
  • Reduces loading time of all levels and maps.
  • Increase the maximum ROM size to 8 MB.
  • Offers enhanced bitmap and arithmetic capabilities for better graphics performance.


MaxTile System

MaxTile System or just MaxTile is a new feature introduced on SA-1 Pack v1.40 that fixes all known OAM issues involving the game, allowing custom sprites using both $0200 & $0300 area and implements a basic sprite priority system for custom resources interested in using the MaxTile API directly, while still keeping compatibility with regular and custom sprites that weren't designed for MaxTile.

How it works:

  • at the beginning of the frame, $7F:8000 is called and invalidates all OAM data.
  • $0200 - $049F can be used normally on the game.
  • when a sprite is executed, its OAM index is set to $0340.
  • when the next sprite is executed, the previous OAM tiles are copied into a new buffer and the $0340+ is freed so the next sprite can use it.
  • at the end of the frame, the entire OAM is scanned for other tiles and unused tiles are removed.
  • during the process, any tile outside screen is automatically dropped as well, maximizing free OAM slots.
  • the sprite buffer then is copied back to the OAM and all sprites are rendered to the screen.


Priority system

When working with MaxTile, you can continue storing to $0200-$02FC directly for setting your own priority (but with static tile management), you can use $0340+ for using as standard sprite priority or you can use its built-in priority system that will automatically ensure that your tiles are placed on the requested order.

The available priorities are:

  1. Maximum priority: store all tiles before the ones statically stored at $0200-$02FC. This is useful for sprite status bar or other status text.
  2. High priority: store all tiles before the ones statically stored at $0300-$033C. This is useful if you wanna make sprite appears in front of the player and yoshi like custom powerups or even additional players. It can also be useful for platforms and clouds.
  3. Standard priority: store all tiles in the same order as the sprites, so between $0340-$03FC. Useful for standard sprites that you don't really have to worry about the priority between them.
  4. Low priority: store all tiles after the ones normally written at $0340-$03FC. Useful for custom sprite backgrounds.


Memory management

Although SA-1 Pack for Super Mario World has a considerable amount of free memory on SA-1 side, it's always on concern about memory use when you are talking about SMW hacking.

The initial MaxTile idea would require only 384-400 free RAM bytes, but with the so-requested priority system, we ran into the following issue: although the OAM has only 128 sprite slots, we don't know how many slots will each priority take. It might sound impossible, but priority #2 or priority #4 can take almost all slots. Or vice-versa, priority #3 can take most of the slots or priority #1 can end up completely empty.

The simplest approach would be letting each priority have all slots available: 512 bytes main table + 128 bytes attribute table. With four priorities available, you would end up spending 2560 bytes of RAM, plus the pointers of each one. Overkill considering there are only 128 free slots and in the end a good chunk of the RAM will end up unused.

Another thought approach was instead of using 2560 bytes of RAM, is using 2048 bytes at $40:C000-$40:C7FF so it could be mapped to $6000-$7FFF using the $2224 and $2225 SA-1 registers. However, each there would be only enough free space for three OAM buffers for four different priorities, which we would be forced to have two or three profiles with less OAM slots available and different performance profiles would be needed to implement (one that gives more free slots to low priority, another that gives more free slots to high priority, etc.).

The chosen approach was actually using the unused bits of properties table to define sprite priority (#$00 - normal, #$40 - low, #$80 - highest, #$C0 - high), reducing the amount of required memory to 512 + 128 (main draw buffer and properties) + pointers, keeping the cycle complexity somewhat similar (four table iterations).