First off, this requires understanding of 16bit math.
You'd add how far to scroll to the low and high byte of the scroll variable.
You'd load the new column data and write it to a buffer. (That's the hardest part. Figuring out where and how NES Maker stores its screens and what format its buffer requires. Or adding a buffer if it doesn't have one sufficient for the task.)
This includes collision info because objects that are near the border between screens need access to both screen's data.
Update the general background collision subroutines to safely access this data. (Possibly not even required, it depends how all the buffers are set up.)
You write a 0 to $2005 twice in your NMI, then clear the lowest two bits of $2000. (To keep the HUD from moving).
You wait a specific amount of time (perhaps with sprite 0), and then fix the scroll for the rest of the level. This isn't too bad for horizontal only scrolling. I believe you just need to write the low byte of your 16bit scrolling variable to $2005, then use the lowest bit of the high scroll byte for the lowest bits of $2000. (Tweaking the timing may help it look slightly less glitchy, but you can also do it on the last black line of the HUD and there will be no visual errors if I'm understanding the wiki correctly.)
Change all sprite position's to 16bit (if this was not already done in preparation for scrolling being added.)
An object's final on screen position is just its position minus the scroll.
Fix sprite/sprite collision detection to work with the new 16bit positions. I recommend this algorithm: http://atariage.com/forums/topic/71120-6502-killer-hacks/page__st__50#entry1054049
To extend it to 16 bits, just add a high byte operation to each step.
Edit2: Oh yeah.
Add code to properly destroy things when they go off screen.
Add code to properly spawn things when they're scrolled on screen.
Add code that avoids spawning multiple copies of the same object. (If you're into preventing that.)
CutterCross said:
having both Horizontal and Vertical scrolling would be VERY complicated, and not be as optimized as well as other mappers that can switch mirroring types on the fly.
It's only really harder if you do both at the same time (like in the same frame, not just in the same game). The thing that makes "8-way" scrolling hard is the nametables (individual screens that map up the internal map) not being aligned. Metroid's mapper does allow mirroring to be switched, but it doesn't make anything
too much easier than if it couldn't. What it does do is allow easier hiding of "color glitches" that you can usually see at the edges of one axis of scrolling in games.
Samus goes through a door and the scrolling direction switches, but since the width and height of each room is the same as the screen the nametables are always aligned.
Vertical scrolling is a bit harder if one has a background HUD, though. (Even if you
only do vertical scrolling.) Changing the hardware vertical scroll position mid screen requires
way more math and understanding of the hardware than just writing to $2005.
You also have to track things a bit differently because the screen is 240 pixels tall rather than 256. My own data is stored in 256x256 "screens" rather than 256x240 screens so that this affects much less in the engine.
Edit:
TheNew8bitHeroes said:
If you ARE ready to run, then you could perfectly figure out how to manipulate what's there to make scrolling work...
I disagree with the spirit of this statement. If it's not supported by the tool, you would not be manipulating what's there, so much as writing the entire thing by yourself in a way that no longer makes the actual tool helpful. It's similar to adding DPCM. Even if I know how, adding it makes the music import part of the tool stop being useful, which is relied on for setting which music plays in the first place on the screens. As well, (and my main issue) is that future updates will always break it. Once I make a large change, when the next asm pack comes I have to make the changes again and again. Users can add small things, but you kind of have to add this big stuff officially or the tool gets in the way of progress rather than helping it.
softerimage said:
BTW, would anyone be able to exactly go into detail about what different scrolling types there are and exactly what "compromises" there are for each?
Sure. If you scroll one way like Super Mario Bros. you get access to LOTS of destructibility. In the underground levels you can destroy absolutely every block and the CPU doesn't really have to "remember" what you did once it goes offscreen because you can't go back. If you could go back, you'd need more RAM (or be okay with the CPU "forgetting" what you did there). It also lets you compress the levels in a way that doesn't require "random" access which can make data smaller.
Most games are not as destructible as Super Mario Bros. and its one way scrolling is why.
If you scroll in two directions, like Metroid, you lose out on some of that extreme destructibility. (Or you have to add RAM to get it, which Metroid does.) You also lose out on certain ways to store levels since you have to be able to access level data at an arbitrary place. Beyond that it's not really different from Super Mario Bros.
If you scroll in all directions, your level format may get larger. You can no longer easily avoid color issues on at least one border of the screen. Even then it's not terribly different from two directions, it's just much harder to get working without issue. (Leaving half updated tiles in the middle of the screen and things like that.) One difference is that it makes accessing collision data a little slower (usually), because the point can be on any one of four screen rather than just any one of two. This means every point that every object checks takes more time to access, which means you have to be more careful about optimization throughout.
Shorter:
If you want EXTREME destructibility you want 1 way scrolling. (Or extra RAM.)
If you want scrolling, but don't want to spend a month or two getting it working, you want 2 way scrolling. It also lets you be a little lazy about optimization.
8 way scrolling will keep you on your toes throughout the entire project, and just getting it working (not entirely bug free) in the first place is a hassle.
Edit: Scrolling vertically with a background HUD is harder than scrolling horizontally with a background HUD. Scrolling vertically is a little harder in general. Checking when things goes above 255 (the width of the screen minus one) is a feature of the CPU. Checking when things go above 239 (the height of the screen minus one) is not. It sounds simple, but that has further reaching consequences than it seems when you get down to it.