Multidirectional scrolling

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems.

Moderator: Moderators

User avatar
Bregalad
Posts: 8036
Joined: Fri Nov 12, 2004 2:49 pm
Location: Caen, France

Post by Bregalad »

Oh I forget to mention it but I'd be interested in the tutorial too.

I can also share with my failed attempts sources if anyone is interested.
Useless, lumbering half-wits don't scare us.
User avatar
tokumaru
Posts: 12106
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Post by tokumaru »

In my honest opinion, the ONLY thing that complicates free scrolling is the fact that there are only 2 nametables. Once you decide how to handle that (there are 3 options: use 4-screen mirroring; hide the scrolling artifacts using various tricks; concentrate the artifacts in locations less likely to be noticed), it gets really simple.

I always hide the scrolling artifacts, either by masking the top 16 scanlines or the leftmost and rightmost 8 columns. Once that's decided, you know where the seams will go ("under" the masked area).
User avatar
MottZilla
Posts: 2835
Joined: Wed Dec 06, 2006 8:18 pm

Post by MottZilla »

tokumaru wrote:
I'm not sure if anyone else has better methods, but with low CPU costs. Does anyone use a RAM table for collision on the background so you don't have to read the PPU?
I doubt anyone reads the PPU for collision. If they do, they certainly shouldn't. VBlank time is already too short if you're only writing to VRAM, imagine if you also had to read it in order to make game decisions...

I'm not sure if RAM tables are the best option either, because they wouldn't work well with slopes and blocks more complex than solid/empty unless they used much more than 60 bytes of RAM.

For collision decisions I just read directly from the level map. Once I have a metatile's index I have access to all of its collision information.

Now I really really think it's time for a split!
Mario Bros does read the PPU for collision. I discovered this in early emulator development as I ran the game before adding the ability for $2007 reads to actually return information.

RAM tables were used in some commercial games. Ninja Gaiden is one of them.
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Post by tepples »

Super Mario Bros. uses a 32x13-metatile (two screen) sliding window in RAM for its collision map. Anything with a destructible playfield (collected coins, broken blocks, etc.) will need to use some sort of collision map in RAM, and that's why SMB1 doesn't have backtracking: so that it can expire columns of the collision map.

Backtracking, destructibility, no PRG RAM: pick two. Or restrict the level geometry slightly and pick one and two halves.
User avatar
MottZilla
Posts: 2835
Joined: Wed Dec 06, 2006 8:18 pm

Post by MottZilla »

On that thought, has anyone ever explored expanding the built in ram to fill the entire 8k of space it responds to? Not just explored it hardware wise but also tried implementing it in an emulator and seeing if it breaks any existing games that might rely on mirroring. It seems like that might be relatively easy to do and it would give you a nice boost in memory.
kuja killer
Posts: 124
Joined: Mon May 25, 2009 2:20 pm

Post by kuja killer »

http://www.youtube.com/watch?v=v5fXMly_ ... ideo_title

i tried to do this a few years ago for megaman 3 (my rom hack)...and it was turning out pretty good as you can see, but i could never ever figure out how to deal with enemies ex-cluding megaman. :( notice at the end of the video how the spiky thing wraps around to both the top and bottom of the screens.

It was just too hard and i gave up and quit. :(
User avatar
tokumaru
Posts: 12106
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Post by tokumaru »

Hacking a game to include multi-directional scrolling is certainly harder than programming it from scratch, because you're messing with a finalized architecture.
User avatar
Bregalad
Posts: 8036
Joined: Fri Nov 12, 2004 2:49 pm
Location: Caen, France

Post by Bregalad »

tokumaru wrote:In my honest opinion, the ONLY thing that complicates free scrolling is the fact that there are only 2 nametables. Once you decide how to handle that (there are 3 options: use 4-screen mirroring; hide the scrolling artifacts using various tricks; concentrate the artifacts in locations less likely to be noticed), it gets really simple.
I'm pretty sure this wasn't my problem. I made a system so I adress all metatile by a (row, column) system, and it gets converted to a VRAM adress with a loockup table. (Up to 32 columns and 15 rows are supported for vertical mirroring). I made a system that delays the row updates when scrolling vertically so it hides them in the overscan area, but you're right that this might the problem : The horizontal scrolling routine "ignores" this delays and assume the data here is already updated. If the user change his mind for example when scrolling down, and scrolls up again, the vertical scrolling routine will "cancel" the delayed update, but the horizontal scrolling routine will ignore that and still act as if the bottom row was updated. I'm not sure if this was my problem, but it was something in the like.

I use $2007 reads for attribute tables in my (other) game project, so that I can modify only the top or bottom half of the 32x32 block by RMW operations.
For my (non-working) scrolling attempt I used a completely different system where it mirrors attribute tables in RAM, and again the table would only be adressed by (row, column) pointer and would be converted by a loockup table.
Useless, lumbering half-wits don't scare us.
3gengames
Formerly 65024U
Posts: 2281
Joined: Sat Mar 27, 2010 12:57 pm

Post by 3gengames »

If you can expand the 60 byte RAM table, you could add slopes. One bit for solidity and two for 4 possible slope types. But I don't think I'll be dealing with slopes soon so it's probably a idea I'd personally like to explore and mess with.
strat
Posts: 396
Joined: Mon Apr 07, 2008 6:08 pm
Location: Missouri

Post by strat »

I just made an 8-way scrolling engine that uses vertical mirroring so it's limited to two screens wide with many screens vertically. Right now it can decode tile chunks that are written to the row buffer every 8-pixels, followed by copying the buffer to the nametable. The tile chunks only store flat surfaces and slopes where the objects will stand; it still needs a way to fill the space between the ground. It will also support limited brick smashing.

It also keeps a 128-byte copy of both attribute tables, which I'm not crazy about but it's the easiest way to overwrite only the palette that must be changed while keeping the other palettes in the same byte. Reading back the attributes in vram will eat up more vblank time that can't be wasted, since I've got some ambitious split screen ideas in the works.

With extra prg-ram, I don't see why free scrolling can't be done in vertical mirroring without artifacts (on ntsc) unless you need a status bar (So I can see why Mario 3 and Kirby stuck with horizontal mirroring and ate the artifacts).
UncleSporky
Posts: 388
Joined: Sat Nov 17, 2007 8:44 pm

Post by UncleSporky »

tepples wrote:Backtracking, destructibility, no PRG RAM: pick two.
I still think this is a really defeatist mantra. There are all sorts of ways to achieve all three.

"Backtracking" in the sense that you're using it must be clarified that you imply "backtracking throughout the entire level." It's quite easy to design levels to have large vertical dropoffs partway through, or other various methods of one-way doors.

You also have to clarify that by "destructibility" you mean "wholly persistent destructibility throughout the entire level." Would people accept blocks respawning 5 screens behind them? Why would that be a problem? In Zelda dungeons the enemies stay dead for only a few screens, then the old rooms repopulate. In a large number of games, enemies respawn off screen constantly. Why not then do the same for destructible blocks?

If your game is focused on blocks and their destructibility, it also shouldn't be a problem. You won't need the RAM for other objects and enemies and can devote all of it to saving a level's worth of destruction. Naturally you design the levels around the amount of destruction that could reasonably be saved.

Is it completely impossible to do any compressing/decompressing on the fly as the player moves around? This ought to be especially easy in "screen flipping" games like Battle Kid where a pause is expected at every room edge, but obviously this topic is for 8 way scrolling. I still think it should be possible, though.

Essentially, the statement should be "pick two unless you don't mind a slight headache, and who in NES development would?"
User avatar
tokumaru
Posts: 12106
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Post by tokumaru »

strat wrote:With extra prg-ram, I don't see why free scrolling can't be done in vertical mirroring without artifacts (on ntsc)
I have been able to see glitches at the top and bottom of the screen using several TVs and NTSC consoles. I simply don't believe the common notion that the glitched scanlines are conveniently cropped in NTSC.

Also, PRG-RAM shouldn't have anything to do with the actual scrolling, like I said before. PRG-RAM simply makes fetching the tiles easier, but you can still fetch them in many other ways, even directly from ROM.
UncleSporky wrote:Essentially, the statement should be "pick two unless you don't mind a slight headache, and who in NES development would?"
I agree with everything you said!
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Post by tepples »

UncleSporky wrote:defeatist
You appear to have misunderstood what I meant by "one and two halves". I meant one, half of a second, and half of a third. Restrict backtracking partially and restrict destructibility partially, and things can be made to fit. Please allow me to elaborate:
UncleSporky wrote:It's quite easy to design levels to have large vertical dropoffs partway through
Hence "restrict the level geometry slightly and pick one and two halves." If you're going to have an obvious gravity barrier every four screens to purge the persistence of destroyed game objects, then a limit on backtracking is obviously one of the "two halves".
UncleSporky wrote:You also have to clarify that by "destructibility" you mean "wholly persistent destructibility throughout the entire level."
Which brings me to restricting level geometry. Assume that the portion of a 2-way scrolling map through which destruction persists is 32 screens long, or 512 columns of 16-pixel-wide metatiles. If only one thing in each column is allowed to be persistently destroyed, the destruction buffer takes 64 bytes.
UncleSporky wrote:Would people accept blocks respawning 5 screens behind them? Why would that be a problem?
In some games, players are supposed to backtrack and "farm" for a resource by killing enemies. In Mega Man, it's energy. In Zelda, it's cash. In a DW/FF style role-playing game, it's experience.

But in other games, farming is not expected. Is Mario supposed to hit a block, get the mushroom, go five screens away, come back, hit the same block, and get a fire flower? Or run back and collect the same coins over and over?

And then there's the other kind of farming, Harvest Moon/Animal Crossing style. If you have a huge plot of land, and you can plant things in each grid cell, the game needs to save what crop is planted in each cell and how long until it's mature.
UncleSporky wrote:In a large number of games, enemies respawn off screen constantly.
And players got frustrated with it when they would defeat an enemy to clear the path, walk offscreen to get a running start to make the jump, and then the enemy would respawn, again blocking the path, and knock the player back into a bottomless pit. See the list of most annoying examples at "Knockback" on TV Tropes.
UncleSporky wrote:Is it completely impossible to do any compressing/decompressing on the fly as the player moves around?
It's possible. Games like Sonic the Hedgehog, Blaster Master, and tokumaru's pet project use multiple layers of metatiles to accomplish this.
3gengames
Formerly 65024U
Posts: 2281
Joined: Sat Mar 27, 2010 12:57 pm

Post by 3gengames »

Enemies are just objects in most cases. Just keep track of all objects that have been killed in a 2 screen area of the screen you're on. And then also have separate objects that never ever get cleared, coins and blocks and such. That way you can have objects that respawn and objects that don't.
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Post by tepples »

3gengames wrote:Enemies are just objects in most cases. Just keep track of all objects that have been killed in a 2 screen area of the screen you're on. And then also have separate objects that never ever get cleared, coins and blocks and such.
Which breaks for cases such as 1-2 from SMB1. See previous discussion about persistent destruction.
Post Reply