Multidirectional scrolling
Moderator: Moderators
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).
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).
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.tokumaru wrote: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 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'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!
RAM tables were used in some commercial games. Ninja Gaiden is one of them.
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.
Backtracking, destructibility, no PRG RAM: pick two. Or restrict the level geometry slightly and pick one and two halves.
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
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.
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.
It was just too hard and i gave up and quit.
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.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 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.
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).
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
I still think this is a really defeatist mantra. There are all sorts of ways to achieve all three.tepples wrote:Backtracking, destructibility, no PRG RAM: pick two.
"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?"
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.strat wrote:With extra prg-ram, I don't see why free scrolling can't be done in vertical mirroring without artifacts (on 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.
I agree with everything you said!UncleSporky wrote:Essentially, the statement should be "pick two unless you don't mind a slight headache, and who in NES development would?"
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:defeatist
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:It's quite easy to design levels to have large vertical dropoffs partway through
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:You also have to clarify that by "destructibility" you mean "wholly persistent destructibility throughout the entire level."
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.UncleSporky wrote:Would people accept blocks respawning 5 screens behind them? Why would that be a problem?
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.
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:In a large number of games, enemies respawn off screen constantly.
It's possible. Games like Sonic the Hedgehog, Blaster Master, and tokumaru's pet project use multiple layers of metatiles to accomplish this.UncleSporky wrote:Is it completely impossible to do any compressing/decompressing on the fly as the player moves around?
Which breaks for cases such as 1-2 from SMB1. See previous discussion about persistent destruction.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.