gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

Coding > Hblank, multiplexed sprites and emulators

#35927 - gadget - Sun Feb 13, 2005 2:07 am

I've been trying to get a small bit of code working for the past six hours. I'm trying to use hblank to up 6 sprites in OAM. Each of these six sprites represent a row of blocks for a puzzle game. I'm trying to draw the entire board as sprites since otherwise it would require greater than the 128 available.

Since the task requires two steps, determining which sprites are needed and updating shadow OAM and then secondly, dma'ing that information to OAM, i'm splitting these tasks on different hblanks. The problem i'm running into is consistency with emulators. VBA and NO$GBA will show the sprites displayed properly, but on hardware I get a blank line between rows of sprites. I've adjusted the lines on which the hblanks occur but I can't seem to get a timing that will work across both emulators and hardware.

Does anyone have any information how to properly multiplex sprites?

#35928 - AnthC - Sun Feb 13, 2005 2:26 am

Just my 2c you could DMA half the OAM in each line so that the next line is DMA'ed in on the current line, and ensure you only use half of your sprites on each line.

#35929 - poslundc - Sun Feb 13, 2005 2:59 am

gadget wrote:
Since the task requires two steps, determining which sprites are needed and updating shadow OAM and then secondly, dma'ing that information to OAM, i'm splitting these tasks on different hblanks. The problem i'm running into is consistency with emulators. VBA and NO$GBA will show the sprites displayed properly, but on hardware I get a blank line between rows of sprites. I've adjusted the lines on which the hblanks occur but I can't seem to get a timing that will work across both emulators and hardware.


1. VBA (not sure about NO$GBA) does not accurately emulate memory access cycle timings. So you could be running out of cycles before HBlank ends.

2. You need to set the HBlank Interval Free bit in REG_DISPCNT in order to be able to access OAM during the HBlank period on hardware. It is quite possible that emulators may let you get away with it where hardware won't.

I get the impression from your wording that you are doing calculations and setting up your shadow-OAM during the HBlank period... if so, that is wrong, wrong, wrong. HBlank is extremely short; just enough time to copy some quick data (either with an interrupt or DMA) and bail out of there. Prepare all of your shadow-data during the previous frame or VBlank and have it all ready to load in when HBlank arrives.

Quote:
Does anyone have any information how to properly multiplex sprites?


There are a number of strategies that depend on the nature of what your game is doing. For a text-based system where you'll be switching sprites at a consistent interval, a workable strategy would be to use an HBlank interrupt alongside a VCOUNT interrupt. The line before you want to switch, have the VCOUNT interrupt update a flag that tells the HBlank interrupt that it has work to do, then have the HBlank interrupt copy the necessary data and clear the flag.

Dan.

#35937 - gadget - Sun Feb 13, 2005 8:56 am

poslundc wrote:

I get the impression from your wording that you are doing calculations and setting up your shadow-OAM during the HBlank period... if so, that is wrong, wrong, wrong. HBlank is extremely short; just enough time to copy some quick data (either with an interrupt or DMA) and bail out of there. Prepare all of your shadow-data during the previous frame or VBlank and have it all ready to load in when HBlank arrives.


There are two steps to what i'm doing. Firstly, i'm building six OMA entries into shadow during one hblank step. Second, i'm copying the bit of shadow into OAM during a second hblank. The array that the data resides in is updated during the main loop before vblank. When I build the six oam entries I do so by changing only the character the oam points to and the palette it uses. The rest of the sprite characteristics remain the same from frame to frame.

#35956 - tepples - Sun Feb 13, 2005 4:57 pm

On real GBA hardware, there is a delay between when you write to sprite memory and when it actually takes effect, as the PPU does some pipelined processing during one or more previous scanlines. This has been true of every Nintendo sprite engine since the NES.

Super Puzzle Fighter II uses a technique like what you mention, and I'm pretty sure it uses two rows of sprites to represent the playfield so that it can copy one while the other is displaying.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#36010 - gadget - Mon Feb 14, 2005 4:46 am

tepples wrote:
On real GBA hardware, there is a delay between when you write to sprite memory and when it actually takes effect, as the PPU does some pipelined processing during one or more previous scanlines. This has been true of every Nintendo sprite engine since the NES.

Super Puzzle Fighter II uses a technique like what you mention, and I'm pretty sure it uses two rows of sprites to represent the playfield so that it can copy one while the other is displaying.


That's the key I was looking for. I didn't realize the OAM was updated immediately which caused the blank lines I was seeing. I double the amount of OAM entries I was using to allow odd/even updating and that worked beautifully. It now works across both emulators and the hardware (SP and GBA player).

By the way, i'm writing a semi-clone of puzzle fighter, as I absolutely love that game.

Thanks so much for the help!