4-way Dragon Warrior scrolling
Moderator: Moderators
- MetalSlime
- Posts: 186
- Joined: Tue Aug 19, 2008 11:01 pm
- Location: Japan
4-way Dragon Warrior scrolling
Hello,
I'm MetalSlime. I'm a(n) NES programming newbie. I'm working on a homebrew Dragon Warrior clone and I'm looking for ideas on how to scroll the background in all four directions. As you probably know, in Dragon Warrior games, the hero sprite stays in the middle, and directional input will scroll the level/background 16 pixels in the desired direction.
Right now my little program uses vertical mirroring, which gives me nametable space to stay a step (or more) ahead for horizontal scrolling. I don't have that luxury for vertical scrolling, which seems like it could be a problem. How would you guys solve this? I the player presses "up", where (and when!) do I draw the new row of tiles, and how do I scroll to them? Just looking for ideas.
Also, if anybody happens to know, what do the actual Dragon Warrior games do? I noticed that Dragon Warrior 3 and 4 use different mirroring modes.
Thanks!
I'm MetalSlime. I'm a(n) NES programming newbie. I'm working on a homebrew Dragon Warrior clone and I'm looking for ideas on how to scroll the background in all four directions. As you probably know, in Dragon Warrior games, the hero sprite stays in the middle, and directional input will scroll the level/background 16 pixels in the desired direction.
Right now my little program uses vertical mirroring, which gives me nametable space to stay a step (or more) ahead for horizontal scrolling. I don't have that luxury for vertical scrolling, which seems like it could be a problem. How would you guys solve this? I the player presses "up", where (and when!) do I draw the new row of tiles, and how do I scroll to them? Just looking for ideas.
Also, if anybody happens to know, what do the actual Dragon Warrior games do? I noticed that Dragon Warrior 3 and 4 use different mirroring modes.
Thanks!
MetalSlime runs away.
You can always turn on a Nametable viewer, then frame advance frame by frame to see exactly what the game is doing.
For instance, I looked at what DW4 did.
When scrolling vertically, 8 frames into the movement, it writes one row to the nametables. Next frame, it writes the next row into the nametables. Next frame, it writes the attribute tables for the updated tiles.
Some games scroll in all four directions using only single screen mirroring, like Battletoads.
For instance, I looked at what DW4 did.
When scrolling vertically, 8 frames into the movement, it writes one row to the nametables. Next frame, it writes the next row into the nametables. Next frame, it writes the attribute tables for the updated tiles.
Some games scroll in all four directions using only single screen mirroring, like Battletoads.
Last edited by Dwedit on Tue Aug 19, 2008 11:52 pm, edited 1 time in total.
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!
- MetalSlime
- Posts: 186
- Joined: Tue Aug 19, 2008 11:01 pm
- Location: Japan
@Dwedit: Thanks for the quick reply! Is that why there is a graphics flicker/glitch in DW4 when you move up and down? If I understand correctly (please tell me if I'm wrong), this is what happens when the character moves down:
1) background scrolls 8 pixels. Because of vertical mirroring, the previous "top" row of tiles is temporarily seen at the bottom of the screen.
2) DW4 writes one row to the bottom of the screen, overwriting the "bad" row. This new row will have funky colors because the attribute tables aren't yet set.
3) background scrolls another 8 pixels, producing another ugly row at the bottom.
4) DW4 writes another row to the bottom of the screen. This row has funky colors too.
5) DW4 writes the attribute tables for the updated tiles and now we have pretty tiles.
Is that right?
Can you think of any other solutions that would avoid this flicker problem? Another mirroring mode? Is it possible to get another nametable to work with? (with a mapper or something?)
Also, can you recommend a Nametable viewer? I'm using the one built into FCE Ultra XD, but I don't know how to frame advance frame by frame with it.
@Celius: When I say I'm not sure "where" to draw the tiles, I'm referring specifically to scrolling vertically in vertically-mirrored mode. Since my nametable is mirrored vertically, there is nowhere to draw tiles "offscreen" above or below.
From the looks of it, I may just have to draw them "onscreen" the way DW4 does it
Thanks for the help guys! And thanks in advance for any further help that may be forthcoming
.
1) background scrolls 8 pixels. Because of vertical mirroring, the previous "top" row of tiles is temporarily seen at the bottom of the screen.
2) DW4 writes one row to the bottom of the screen, overwriting the "bad" row. This new row will have funky colors because the attribute tables aren't yet set.
3) background scrolls another 8 pixels, producing another ugly row at the bottom.
4) DW4 writes another row to the bottom of the screen. This row has funky colors too.
5) DW4 writes the attribute tables for the updated tiles and now we have pretty tiles.
Is that right?
Can you think of any other solutions that would avoid this flicker problem? Another mirroring mode? Is it possible to get another nametable to work with? (with a mapper or something?)
Also, can you recommend a Nametable viewer? I'm using the one built into FCE Ultra XD, but I don't know how to frame advance frame by frame with it.
@Celius: When I say I'm not sure "where" to draw the tiles, I'm referring specifically to scrolling vertically in vertically-mirrored mode. Since my nametable is mirrored vertically, there is nowhere to draw tiles "offscreen" above or below.
From the looks of it, I may just have to draw them "onscreen" the way DW4 does it
Thanks for the help guys! And thanks in advance for any further help that may be forthcoming
MetalSlime runs away.
Super C has similar problems, visible on the big ramp in the first level.MetalSlime wrote:@Dwedit: Thanks for the quick reply! Is that why there is a graphics flicker/glitch in DW4 when you move up and down? If I understand correctly (please tell me if I'm wrong), this is what happens when the character moves down:
Most NTSC televisions will hide roughly the top 8 pixels and the bottom 8 pixels. So if you write one row of tiles, then write the attributes, then write the other row of tiles, you can keep the dirty stuff entirely in the overscan. That won't help PAL users, for which the only clean solution is the following:Can you think of any other solutions that would avoid this flicker problem?
One of the MMC3 boards (TVROM) has a four-screen mirroring mode, but it's not all that common. I would bet that four-screen can be added to even a discrete mapper though by setting to always disable the PPU's VRAM and always enable a 16 KiB chip in the CHR RAM socket.Another mirroring mode? Is it possible to get another nametable to work with? (with a mapper or something?)
I've used Nintendulator or even PocketNES+VisualBoyAdvance.Also, can you recommend a Nametable viewer? I'm using the one built into FCE Ultra XD, but I don't know how to frame advance frame by frame with it.
Since there are only 2 nametables, when your game scrolls both horizontally and vertically you kinda have to pick one type of scroll to be glitchy by selecting a type of mirroring. A huge number of commercial games have scrolling glitches (including favorites like SMB3).
The simplest way to have no glitches at all is to use a cart with 2KB of extra RAM for nametables, for a total of 4 (so that there is no mirroring whatsoever). Carts like that are not so common though.
Another option is to use horizontal mirroring and have the NES mask off the leftmost 8 pixels and use sprites to hide the rightmost 8 pixels. Alfred Chicken does this, but even when using 8x16 sprites it's still a big waste of them, and you effectively reduce the sprites per scanline limit to 7!
There is one more option (which is the one I'm using in my game) which is using vertical mirroring and masking a total of 16 scanlines off the top and/or bottom of the screen. This can be done with timed code, sprite 0 hits or mapper IRQs. Ideally, you'd mask 8 scanlines at the top and 8 at the bottom, but doing this twice every frame is just too much trouble, so most games end up masking 16 scanlines at the top or at the bottom. Super Cars hides the top, Somari hides the bottom, but you can find tons of other games that do this. Jurassic Park does it in a pretty clever way, using blank patterns instead of disabling rendering.
As I said, I used the last method. I hide 16 scanlines at the top of the screen using the Jurassic Park method. When rendering starts, all patterns are blank. I set up a MMC3 IRQ so that by the time scanline 16 is rendered the actual patterns have all been loaded. I chose to mask the top mainly because sprites can't normally have negative Y coordinates (so now they can appear to smoothly scroll from the top), and because I break every rule of the scanline counter during the actual frame, so I couldn't possibly schedule an IRQ for the bottom of the screen.
P.S.:
The simplest way to have no glitches at all is to use a cart with 2KB of extra RAM for nametables, for a total of 4 (so that there is no mirroring whatsoever). Carts like that are not so common though.
Another option is to use horizontal mirroring and have the NES mask off the leftmost 8 pixels and use sprites to hide the rightmost 8 pixels. Alfred Chicken does this, but even when using 8x16 sprites it's still a big waste of them, and you effectively reduce the sprites per scanline limit to 7!
There is one more option (which is the one I'm using in my game) which is using vertical mirroring and masking a total of 16 scanlines off the top and/or bottom of the screen. This can be done with timed code, sprite 0 hits or mapper IRQs. Ideally, you'd mask 8 scanlines at the top and 8 at the bottom, but doing this twice every frame is just too much trouble, so most games end up masking 16 scanlines at the top or at the bottom. Super Cars hides the top, Somari hides the bottom, but you can find tons of other games that do this. Jurassic Park does it in a pretty clever way, using blank patterns instead of disabling rendering.
As I said, I used the last method. I hide 16 scanlines at the top of the screen using the Jurassic Park method. When rendering starts, all patterns are blank. I set up a MMC3 IRQ so that by the time scanline 16 is rendered the actual patterns have all been loaded. I chose to mask the top mainly because sprites can't normally have negative Y coordinates (so now they can appear to smoothly scroll from the top), and because I break every rule of the scanline counter during the actual frame, so I couldn't possibly schedule an IRQ for the bottom of the screen.
P.S.:
I don't like Nintendulator's debugging features very much... So I too use FCEUXD for that. It's true that it doesn't have a frame-by-frame option, but you can often simulate it by adding breakpoints in the debugger. Just look up the NMI vector and setup a breakpoint when that address is executed, and by hitting the "Run" button you can advance frames, since the NMI routine is executed once per frame in most games. Maybe it won't work with all games, but there is always some way to setup a similar breakpoint.tepples wrote:I've used Nintendulator or even PocketNES+VisualBoyAdvance.Also, can you recommend a Nametable viewer? I'm using the one built into FCE Ultra XD, but I don't know how to frame advance frame by frame with it.
In how many turns do you plan to flee ?I'm MetalSlime. I'm a(n) NES programming newbie.
As another persond said, it's a good idea to watch how games handle things in a nametable viewer.MetalSlime wrote: Also, can you recommend a Nametable viewer? I'm using the one built into FCE Ultra XD, but I don't know how to frame advance frame by frame with it.
I'd recommand to use VirtuaNES for that. It's not the most accurate emulator arround, but definitely not the less accurate and it has pretty nice feature when it comes to this.
As the other said, there is no way to bypass scrolling glitches on the NES when scrolling on both axises, but you can cleverly hide them with a wide variety of techniques. The simplest for a newbie is to consider the first and last 8 bits of the display as "hidden" (altough you have to remember they exists and aren't hidden on PAL machines), and to update your data "off-screen" in the hidden area.
Also, if glitches are apprearing it's better to make them appearing in the direction you're NOT scrolling so that the user is less likely watching here (for example when scrolling up, the user is likely to watch up and less likely to notice scoll glitches on the bottom).
Anyway you shouldn't get confused by this kind of stuff before first having written a simple scroller.
Useless, lumbering half-wits don't scare us.
-
Celius
- Posts: 2159
- Joined: Sun Jun 05, 2005 2:04 pm
- Location: Minneapolis, Minnesota, United States
- Contact:
Final Fantasy scrolls similarly to DW visually. I made a scrolling FF map engine before, and here's what I did.
When you press up, you'll want to first update the very bottom row of the screen. This is because when you scroll up, that bottom row will become the top row of the screen. Once you scroll 8 pixels, you want to update BOTH the attribute and the row above the row you just updated. You want to wait to update attributes until you scroll 8 pixels because on most TV's, with vertical mirroring, the top and bottom half of the attribute will be hidden, so you won't see the attribute updates.
Same thing goes for down, except you write over the topmost row and the one below it.
When you press up, you'll want to first update the very bottom row of the screen. This is because when you scroll up, that bottom row will become the top row of the screen. Once you scroll 8 pixels, you want to update BOTH the attribute and the row above the row you just updated. You want to wait to update attributes until you scroll 8 pixels because on most TV's, with vertical mirroring, the top and bottom half of the attribute will be hidden, so you won't see the attribute updates.
Same thing goes for down, except you write over the topmost row and the one below it.
-
Celius
- Posts: 2159
- Joined: Sun Jun 05, 2005 2:04 pm
- Location: Minneapolis, Minnesota, United States
- Contact:
Four Screen allows for simple scrolling in the sense that you update from the same point no matter which way you're scrolling, but updates are horribly visible. I highly recommend sticking to Vertical Mirroring if you're using NTSC, since the top/bottom rows aren't visible. Though if you'll be able to see those for any reason, horizontal mirroring + clipping is a good route too.
Celius, you should be confusing four-screen and one-screen. What you say applies to one-screen mirroring.
Anyways, if your code can scroll with four-screen mirroring, then you can switch to either vertical or horizontal, and it will look fine (with additional glitches). Expanding code to support a superior scrolling sheme should be harder, as no writes are intended in the previously unused nametables.
There is a grand total of three games that ever used 4-screen mirroring, so this is VERY uncommon to say the least. To add four-screen ability on a cart, you need to either add a 6264 8kb SRAM (but only using 4kb) above/below the CHRROM and make some rewiring (I've never done that but I bet it would work). Another alternative would be to have 6116 2kb SRAM and a 74HC139 for decoding, so that 2x2kb = 4kb.
Anyways, if your code can scroll with four-screen mirroring, then you can switch to either vertical or horizontal, and it will look fine (with additional glitches). Expanding code to support a superior scrolling sheme should be harder, as no writes are intended in the previously unused nametables.
There is a grand total of three games that ever used 4-screen mirroring, so this is VERY uncommon to say the least. To add four-screen ability on a cart, you need to either add a 6264 8kb SRAM (but only using 4kb) above/below the CHRROM and make some rewiring (I've never done that but I bet it would work). Another alternative would be to have 6116 2kb SRAM and a 74HC139 for decoding, so that 2x2kb = 4kb.
Useless, lumbering half-wits don't scare us.
This is why I think a programmer shouldn't count on TVs cropping glitches (although your TV seems to need some sort of calibration, 24 pixels is too much!). All of my TV's behave very differently from each other, and I often can see scrolling glitches if they were left there by the programmer, one way or another. Also, does anyone know what happens on the newer LCD/plasma TVs? Do they usually crop anything or just show the whole picture?Dwedit wrote:On my old TV, the top 24 pixels of the NES screen got clipped, and the full bottom of the screen was drawn, along with about 8 pixels of black vblank.