Video Mode 3: Difference between revisions

From Uzebox Wiki
Jump to navigation Jump to search
(New page: ==Implementation== Mode 3 uses a "restore buffer" in addition to a byte VRAM array. This buffer has as many slots as there is ramtiles. Each slot is composed of a VRAM address (2 bytes) an...)
 
Line 8: Line 8:
When rendering begins, the tile indexes in the restore buffer are updated with the current VRAM values. This is required since the main program may have updated the VRAM between VSYNC and rendering. So for each slot in the restore buffer, we check if the tile index in the matching VRAM location is < RAM_TILES_COUNT. If not we know there has been an update and we store the new VRAM tile index in the restore buffer and write the restore buffer's slot index into that VRAM location.
When rendering begins, the tile indexes in the restore buffer are updated with the current VRAM values. This is required since the main program may have updated the VRAM between VSYNC and rendering. So for each slot in the restore buffer, we check if the tile index in the matching VRAM location is < RAM_TILES_COUNT. If not we know there has been an update and we store the new VRAM tile index in the restore buffer and write the restore buffer's slot index into that VRAM location.


The main rendering loop then goes through the VRAM tile by tile. Two separate "sub loops" handles flash and ram tiles. Once frame rendering is finished, the VRAM is restored using the "restore buffer" values.
The main rendering loop then goes through the VRAM tile by tile. Two separate "sub loops" handles flash and ram tiles. When using scrolling there was no cycles left in the flash inner loop to perform X wrapping so we have to pre-wrap the current tile row into a "linear" buffer so I don't need to check during rendering. This unfortunately adds overhead to each scanline and reduced the displayable tile from 30 to 28.
 
Once frame rendering is finished, the VRAM is restored using the "restore buffer" values.


==Ramtiles==
==Ramtiles==

Revision as of 21:49, 5 January 2010

Implementation

Mode 3 uses a "restore buffer" in addition to a byte VRAM array. This buffer has as many slots as there is ramtiles. Each slot is composed of a VRAM address (2 bytes) and a tile index (1 byte). At the beginning of each frame (during VSYNC), sprites are processed. For each 8x8 pixels sprite, we compute which VRAM background tile(s) are overlapped (up to 4 tiles can be overlapped, so 4 tests are done). Two cases can then arise:

1) the VRAM tile index is >=RAM_TILES_COUNT which indicates the sprite will overlap a regular flash tile. In this case, we check if we still have unallocated ramtiles. If so, the overlapped flash tile's pixels are copied into the newly allocated ramtile. The new ramtile index in set in VRAM (the previous VRAM value & adress is preserved in the restore buffer). The sprite is blitted against this ramtile (which contains only the flash tile pixels at this point). If no more ramtiles were available, the sprite blitting against this VRAM location is clipped/ignored.

2) the VRAM tile index is < RAM_TILES_COUNT which indicates the sprite will overlap a previously allocated ramtile. The sprite is blitted against this ramtile (which contains the bg flash tile pixels overlaid with perhaps one or more sprites pixels).

When rendering begins, the tile indexes in the restore buffer are updated with the current VRAM values. This is required since the main program may have updated the VRAM between VSYNC and rendering. So for each slot in the restore buffer, we check if the tile index in the matching VRAM location is < RAM_TILES_COUNT. If not we know there has been an update and we store the new VRAM tile index in the restore buffer and write the restore buffer's slot index into that VRAM location.

The main rendering loop then goes through the VRAM tile by tile. Two separate "sub loops" handles flash and ram tiles. When using scrolling there was no cycles left in the flash inner loop to perform X wrapping so we have to pre-wrap the current tile row into a "linear" buffer so I don't need to check during rendering. This unfortunately adds overhead to each scanline and reduced the displayable tile from 30 to 28.

Once frame rendering is finished, the VRAM is restored using the "restore buffer" values.

Ramtiles

The number of ramtiles is related to the number of sprites you expect to have on screen. The point of ramtiles is to make the rendering engine able to render both tiles and sprites at a higher resolution than the old mode 2, with the added benefit of handling overlapping sprites. mode 2 has to run at a lower resolution than mode 1 because of the extra time used up by checking for sprites and handling sprite transparency. ramtiles are a way of allowing some of the rendering tasks to be done during VBL rather than while actually outputting scanlines. It works by finding where sprites are on the screen, looking at what tiles would be under those sprites, then compositing the sprite onto the tiles and storing the result in RAM. That way when it's time to output pixels on a scanline, it can just fetch the pre-rendered images from RAM rather than having to do the sprite compositing on the fly. This saves enough cycles to allow for better resolution, and as a side effect we get nifty things like overlapping sprites and sprite flipping. The tradeoff is that games have less RAM to work with, as well as fewer CPU cycles for running game logic. (plus additional limitations on sound channels, if I remember correctly.)[1]

MAX_SPRITES really controls the allocation of memory for the sprites structure and also slighly speeds ups the blitting of sprites. RAM_TILES_COUNT controls the allocation of memory for the ramtiles. I.e.: Your 12 sprites 'megasprite' will consume up to 20 ramtiles if allowed to move freely.[2]