Tricking Mapper 30 to do 4-way Scrolling

redantgames

New member
I know that Joe has stated over and over that the limitations of NES Maker will be directly tethered to mapper 30. Which I get and I can totally understand that a standard had to be drawn. That said I have a few projects I'd love to bring to the platform that require me to have greater than a 16x15 tile grid to portray on screen.

This limits me design-wise as I now have to work around a few technical limitations. ie. One of my games is a top-down arena-style shooter where I have a 19x19 tile grid and the same 4-8 or so enemies running around trying to find/fight the player. Besides how to handle my custom pathfinding (A*) and waypoint tracking AI and fog of war systems, which will have to involve some sneakiness, I'll have to figure out how to defeat the screen & scrolling limitations imposed by mapper 30.

I can do quite well at 16x16 sized tiles & character "sprites" but 8x8 makes them too small and will have colour palette issues. Here are my options however:

A) reduce to 8x8 sized sprites where detail makes the game hard to make nice sprites

B) find a way to scroll in 4 directions to make up the 19 x 19 sized tile grid that way

C) have 4 screens I can hop between as seamless as I can where the enemy AI can retain it's data and track the player off screen each other with a hud / mini-map

Option A is the best to match current gameplay with my existing design/concept, but the graphics would most likely be far too small.
Option C will maintain the ability to translate the graphics well enough for the platform, but possibly make the game feel far too unintuitive to be much fun.
Option B is best to maintain as much of the gameplay and graphics quality, but requires me to defeat the mapper 30 limitations not having 4 way scrolling.

Is there no way to trick mapper 30 into doing Option B at all or am I screwed until NES Maker supports a 4 way scrolling capable mapper?
 

Kasumi

New member
Mapper makes no difference at all in regards to whether 4-way scrolling is possible. Even the same hardware Super Mario Bros./Donkey Kong used (no mapper) can do it. Mappers can make having a background (rather than a sprite) HUD easier in addition to the 4 way scrolling, but that's about it.

However, 4-way scrolling is a very difficult programming task. It's not the kind of thing one makes happen in a week (maybe not even in a month or two), one has to tread very carefully. Doubly so with destructible environments added.

It is becoming a bit more common in homebrew these days, though. My game, Indivisible, does it, Super Bat Puncher does it, and Legends of Owlia does it (on very similar hardware to mapper 30).

Edit: Actually, one more thing. I understand not wanting to go to 8x8 for characters because it's pretty small but you realize you can do any size in between that and 16x16, right? You can do 4x13 or 12x12 or whatever really, as far as characters. The NES "thinks" in 8x8 tiles, but you can use transparency with sprites so it's not like you absolutely have to fill all of them. But if your game is very, very grid based, you'll still have some work cut out for you background-wise, yes.

Edit 2: I'm not sure that wording was the most clear. Your characters can be 10 by 14 (or whatever, really) but the background will still be palette locked at 16x16 no matter what you do. In theory that's only graphical, though. Collision could be whatever. In practice, plan for tile based collision as well.
 

redantgames

New member
Ok so I am going to be able to make the game scroll (within reason) in NES Maker with some modification, most likely yes?

Now I'm not trying to make a StarCraft map here, just cover a 16x16 sized tile map that'll go up to 19x19 tile spaces. Is that a reasonable goal? Maybe if Joe has time later he might be able to advise...?
 

redantgames

New member
I should mention that I'm going to need a HUD as well. I guess that will make a huge difference considering how memory restrictive the system is.
 

Kasumi

New member
Even if you only wanted to go one 16x16 tile extra in both directions it gets hard because there isn't an offscreen buffer to draw to in one of the directions. Essentially you get two screens worth of "map" to draw to. The two can be aligned vertically or the two can be aligned horizontally.

Ice Climber has the two screens arranged vertically so it can draw new tiles to scroll up and down offscreen without worry.

Super Mario Bros. has the two screens arranged horizontally so it can draw new tiles to scroll left and right offscreen without worry.

If you've ever played Metroid, you'll notice it can scroll left and right, and scroll up and down. But it can't scroll say... down+left or up+right. The game switches which axis it can scroll on when you go through a door. (It's why the game is long corridors and tall shafts.) The door transition ensures the camera is axis aligned, and then it switches the way the screens are arranged.

Super Mario Bros. 3's method would probably work for your plan. It sort of sidesteps the common issues by primarily updating columns. Instead of drawing a new 240 pixel column of the level when the camera moves, it updates a new 432 pixel column of the level. (The remaining 48 pixels are for the HUD) This gets you a level that can be up to 27 16x16 tiles tall somewhat simply. (Without the HUD you could do up to 30.) The horizontal size of the level can be basically unlimited without issue.

That method would only fall apart if a level height+HUD height were needed that was taller than two screens. Whether or not this method is reasonable in NES Maker, I do not know.

As far as pixel smooth scrolling in both directions with a level that's taller than two screens in both directions like Indivisible... I'll put it like this. I've been programming the console for a decade, and I'd dread programming 4-way scrolling again.
 

Bucket Mouse

Active member
Maybe you can just copy-paste some screen-rendering engine code from Super Mario 3.....

....okay, not really. I tried looking at the ASM of some popular games with FCEUX to see how their tricks were done....I still don't know how they were done. There appear to be over 100 ASM commands for every single frame of action. There's a button to run the game one command at a time, where pretty much nothing changes, and a button that runs the game 128 commands at a time, which gives you a new frame every two pushes. I can't learn anything from the code of other games because there's just....so much of it.
 

Kasumi

New member
It's more like 8,000 instructions in a frame. There are about 29780 "cycles" in a frame, each instruction takes 3 or 4 cycles to complete on average. 128 lines doesn't mean 128 instructions. It means 128 rows of pixels. (While the screen is being rendered by the Picture Processing Unit, the 6502 CPU is running the logic for the game. Each row of pixels takes about 113 CPU cycles to render, or 30ish instructions. So 128 lines is really about 3840 instructions.)

You probably won't learn very much by stepping through undocumented code. You can try a (not fully) commented disassembly: https://github.com/captainsouthbird/smb3/blob/master/PRG/prg031.asm (It starts at IntReset)

But even then it's not easy to follow unless you have a LOT of 6502 and NES knowledge already. Starting small (like making your own program that just gets some sprites on screen) is a good plan. As you learn more, it will start to come together how the old games work without any specific effort put toward it.
 

Bucket Mouse

Active member
This is due to all my programming experience being based in BASIC and HTML and other languages where, if you want to know how something works, you just find the specific bit of code and reverse-engineer it. When I see something on a webpage that I want to know how to do, I just right-click "Inspect Element" in Firefox and it shows me the line of instruction that did it. Usually that's transferable into my own projects.

But I guess that's not how NES works. I have a feeling I'm going to be relying on this "Code" sub-board a lot.
 

Kasumi

New member
HTML has names and comments to help understand the flow of it. (Unless it has been purposefully obfuscated.)
Code you look at in FCEUX has nothing to help you understand its intent.
So it's not that it's not how NES works, it's that you're looking at a version of the code that is in a form that's no longer meant to be human readable.
i1ehfxk.png

Same code. The left gives you context through name. Like instead of $E020 you see waitvblank, and instead of $E1BF you see joypad. $5C becomes frametimer. This isn't prepared example code, but it still gives way more context to what it's doing just from the names.

I'm not saying you can't learn from reading code at all, just
1. In FCEUX debugged code you're staring at an abyss of numbers when you don't need to.
2. Even if it is somewhat commented, rather than looking at 32 giant .asm files in that SMB3 disassembly you could read much smaller things to get the picture before the larger ones.
 

redantgames

New member
I think at the ASM level you need to heavily comment all your code or it turns into unknown chaotic stuff unless it's something VERY common and it's something you code really often.

That said, I'm glad that it is possible. And to be honest it's one of those restrictions that are just out of reach with NES Maker out of the box. But as long as it'll let me modify it enough to scroll in one direction at a time for a few tiles I can make my game projects work in the engine. I can design to the 27-ish tile limits. At least for these existing projects. I will need a hub, but that'll be just 2-3 tile rows high worth of space to place the mini-map, weapon/ammo & key card info. (think of Doom's inventory, but smaller)

I do have an adventure puzzle project that I can make use of the extra size, doesn't need a HUD, but it's still best if I can scroll within a single level than splitting it into separate "rooms."

Here is to hoping I can tweak the engine a tad within each set of project files.
 

Bucket Mouse

Active member
The big question is how easy those points will be to find. I just mentioned what a maze the average NES ROM code is, and as Kasumi pointed out it's because nothing is clearly labeled. Although NES Maker will most likely put names in place of hex addresses to some extent (you can see it in the videos), how many will be there? Remember that the whole compiling process is automated. A human isn't going in and giving names to every single thing.

Will Red Ant be able to pick out WHERE in that mountain of code to put the extra scrolling data? This is my concern too with cutscene making.
 

Kasumi

New member
They will probably be easy to find. Maybe not easy to modify. In programming, the "low level" things are defined and can't change. They can't change because they are based on what the hardware needs to properly give output and the hardware can't change once shipped.

The 6502 CPU is used by many things. It runs Asteroids and NES. Asteroids and the NES have very different graphical and sound capabilities. This is what makes Asteroids... well. Asteroids. And it's what makes the NES. Well. The NES. But since the same CPU is running them, how does it give different output? The answer is a defined list of locations, that when read from or written to, cause the hardware specific things to happen.

When I am looking at a game in the FCEUX debugger I know what those locations are and what they do having read about them previously. If you don't have the knowledge, it's not a helpful way to learn. You have to get that knowledge first. And the way to do that is reading documents and tutorial code.

To find any scrolling code, you'd look for $2005. https://github.com/captainsouthbird/smb3/search?utf8=%E2%9C%93&q=2005&type=

You'd look for $2005 because that's the defined way to make the NES scroll: https://wiki.nesdev.com/w/index.php/PPU_registers#Scroll_.28.242005.29_.3E.3E_write_x2

There's just one result in that SMB3 disassembly because the author labeled it to something else (PPU_SCROLL). Okay, fine. So we search for that: https://github.com/captainsouthbird/smb3/search?utf8=%E2%9C%93&q=PPU_SCROLL&type=

And there are a few results. One is this:
Code:
	LDA <Horz_Scroll
	STA PPU_SCROLL	; Horizontal Scroll set
	LDA <Vert_Scroll
	ADD Vert_Scroll_Off	; Apply vertical offset (used for??)
	STA PPU_SCROLL		; Vertical scroll set
The game writes a value from locations in RAM called Horz_Scroll and Vert_Scroll. So those two variables are what control scrolling, but now we are at the point where things can be done in a unique way because how Horz_Scroll and Vert_Scroll are set up could be any way. The only thing the hardware cares about is the final store to $2005. But still, let's go deeper. Let's search for that RAM.

https://github.com/captainsouthbird/smb3/search?utf8=%E2%9C%93&q=Horz_Scroll&type=

This is where the results get dense. One of the results is this, however.
Code:
	.org $F4
	Scroll_OddEven:		.ds 1	; 0 or 1, depending on what part of 8 pixels has crossed (need better description)

	Controller1Press:	.ds 1	; Player 1's controller "pressed this frame only" (see Controller1 for values)
	Controller2Press:	.ds 1	; Player 2's controller "pressed this frame only" (see Controller2 for values)
	Controller1:		.ds 1	; Player 1's controller inputs -- R01 L02 D04 U08 S10 E20 B40 A80
	Controller2:		.ds 1	; Player 2's controller inputs -- R01 L02 D04 U08 S10 E20 B40 A80

				.ds 1	; $F9 unused
				.ds 1	; $FA unused
				.ds 1	; $FB unused

	Vert_Scroll:		.ds 1	; Vertical scroll of name table; typically at $EF (239, basically showing the bottom half)
	Horz_Scroll:		.ds 1	; Horizontal scroll of name table

				.ds 1	; $FE unused

	PPU_CTL1_Copy:		.ds 1	; Holds PPU_CTL1 register data
This reserves locations in RAM for variables. We start at $F4 (the .org) Scroll_OddEven gets assigned to $F4, Controller1Press gets assigned to $F5 etc.

Horz_Scroll ends up at $FD in RAM. And Controller1 ends up at $F7 in RAM. Let's verify if what we've learned is correct.
ENHkIAR.gif

Marked in blue is $F7 (Player One's controller). Marked in red is $FD (The horizontal scroll position). Note that when buttons are pressed, the blue value changes. Note that when the game scrolls right, $FD increases in value.

That's more or less the process for figuring out code you didn't write. But if you don't have the base knowledge of the hardware, the process breaks down. I have never read anything about how to hack games. I just realized after programming for a while that I knew how to.

But I started WAY smaller than scrolling. Even one direction scrolling on NES is not that simple. To make the camera move, it's true that all you have to do is write different X and Y values to $2005. (Well... you have to write to $2000 sometimes as well, but I'll skip that for now.) But that's just the camera. You also have to write the new data to the map itself, and that's a little hairier.

Anyway, start learning (from Nerdy Nights or easy6502) right now! Time spent learning now will only increase the likelihood the knowledge you have will be sufficient to modify NES Maker by the time you get access to it! And who knows, you may even end up having a game before NES Maker gets out of beta!

And you can totally ask questions! In this forum, or on NESdev. (NESdev's the better bet. I'm good, but I'm just one guy. NESdev is filled with knowledgeable people.)

edit:
A human isn't going in and giving names to every single thing.
That's not quite true. What NES Maker seems to do is put together a bunch of individual .asm files which were TOTALLY written by humans and would TOTALLY have comments and names.

The part that's generated would be data (like the screen data or palette sets.) But even then, I'd bet they'd still have names like:
Code:
palette_set_00:
.db $00, $01, $05;... each palette index
screen_54:
.db $E1, $52, $03;... more data for the screen
And each byte wouldn't have a name, but each byte wouldn't have a name even if it was written by a human either, usually.
Like in my tool I-CHR, I totally have readable source for the actual code. The I-CHR exe just hacks the different data into the I-CHR ROM. Similar sort of thing. (Except I didn't choose to release the source for my I-CHR ROM. I've gotten the impression NES Maker will have the source to its scripts.)

The image I posted earlier was some of the I-CHR's ROM code, though.
Edit 2: As an example, here is some autogenerated content from a tool I wrote:
Code:
met16sets_bank00:
	.db $03;Offset to access 16 set $00
	.db $14;Offset to access 16 set $01
	.db $25;Offset to access 16 set $02
	.dw bank00_meta16_00_00
	.dw bank00_meta16_00_01
	.dw bank00_meta16_00_02
	.dw bank00_meta16_00_03
	.dw bank00_meta16_00_04
	.dw bank00_meta16_00_05
	.db $00;Frame Delay << 3 | Frame Count
	.db $00+bgchrstart;CHR Set 00 for frame 1
	.db $00+bgchrstart;CHR Set 01 for frame 1
	.db $01+bgchrstart;CHR Set 02 for frame 1
	.db $02+bgchrstart;CHR Set 03 for frame 1
	.dw bank00_meta16_01_00
	.dw bank00_meta16_01_01
	.dw bank00_meta16_01_02
	.dw bank00_meta16_01_03
	.dw bank00_meta16_01_04
	.dw bank00_meta16_01_05
	.db $00;Frame Delay << 3 | Frame Count
	.db $03+bgchrstart;CHR Set 00 for frame 1
	.db $04+bgchrstart;CHR Set 01 for frame 1
	.db $05+bgchrstart;CHR Set 02 for frame 1
	.db $06+bgchrstart;CHR Set 03 for frame 1
	.dw bank00_meta16_02_00
	.dw bank00_meta16_02_01
	.dw bank00_meta16_02_02
	.dw bank00_meta16_02_03
	.dw bank00_meta16_02_04
	.dw bank00_meta16_02_05
	.db $83;Frame Delay << 3 | Frame Count
	.db $07+bgchrstart;CHR Set 00 for frame 1
	.db $08+bgchrstart;CHR Set 01 for frame 1
	.db $09+bgchrstart;CHR Set 02 for frame 1
	.db $0A+bgchrstart;CHR Set 03 for frame 1
	.db $07+bgchrstart;CHR Set 00 for frame 2
	.db $08+bgchrstart;CHR Set 01 for frame 2
	.db $09+bgchrstart;CHR Set 02 for frame 2
	.db $0B+bgchrstart;CHR Set 03 for frame 2
	.db $07+bgchrstart;CHR Set 00 for frame 3
	.db $08+bgchrstart;CHR Set 01 for frame 3
	.db $09+bgchrstart;CHR Set 02 for frame 3
	.db $0C+bgchrstart;CHR Set 03 for frame 3
	.db $07+bgchrstart;CHR Set 00 for frame 4
	.db $08+bgchrstart;CHR Set 01 for frame 4
	.db $09+bgchrstart;CHR Set 02 for frame 4
	.db $0D+bgchrstart;CHR Set 03 for frame 4
It even auto generates comments describing the data!
 

redantgames

New member
I just thought of something. Without getting into the code so much, how exactly is the team going to make an RPG module without being able to scroll around the overworld map if it's difficult on mapper 30? That presents a bit of a problem doesn't it? Were they thinking of keeping with the adventure module style world and not doing an overworld? What mappers did the Dragon Quest and Final Fantasy games use?
 

Kasumi

New member
Again, Mapper 30 is not why this is difficult. It's difficult in general. Mapper is basically a non factor in the reasons why it's difficult. (Except static HUDs which most RPGs don't do. They do pop windows in the middle of the screen and that's much easier to do.)

Without going into detail why: It may be the RPG module is planned to be tile based. (Think Pokemon, Final Fantasy, Dragon Warrior, Mother/Earthbound Beginnings, Dragon Warrior...) There's a reason these types of games were locked to a grid like they were. (The reason you can't move with menus open is also a way to avoid all the difficulties that come with some of the things I've talked about.)

Edit: Easiest to hardest.
1. A game that never scrolls. (Donkey Kong)
2. A game that scrolls only up and down or a game that only scrolls left and right. (Ice Climber)
3. 2 with a background HUD (Super Mario Bros.)
4. A game that switches between horizontal and vertical scrolling at times when the screen is perfectly aligned. (Metroid)
5. 4 with a background HUD. (Uh... I can't think of one offhand.)
6. A game that switches between horizontal and vertical scrolling at times when the screen is palette aligned but not screen aligned. (Lots of RPGs)
7. 6 with a background HUD. (Radia Senki: Reimmeihen)
8. A game that can scroll horizontally and vertically in the same frame without being aligned in any way. (Indivisible on NES)
9. 8 with a background HUD. (Super Mario Bros. 3)
10. 9 with levels wider than 512 and taller than 480 (Battletoads, and maybe Kirby's Adventure. Point is Super Mario Bros. 3 doesn't hit this.)

A static background HUD gets harder without a certain type of function that's only available on some mappers. Battletoads doesn't have the thing that helps, but it still does it: https://www.youtube.com/watch?v=_3vbfsAFAgU (Which... is actually really impressive to me. But Battletoads does a lot of wildly technically impressive things. The more one learns about NES, the more one appreciates that game even if it's a bit silly as far as difficulty.)

Edit 3: The tier list isn't perfect, though. Levels wider than 256x480 or 512x240 are also the only things that make scrolling hard. though 8 is below 9 in the tier list, Indivisible's scrolling is actually harder than Super Mario Bros. 3's because of the map sizes.

Edit 2: Another thing a mapper helps with is putting a background HUD at the bottom of the screen. The HUD for Battletoads basically has to be on the top to have time to calculate other things in the frame.

Also edit 3:
Really short:

1. Mappers can help add a background HUD, and they make it possible to put said background HUD on the bottom of the screen without tying the CPU up. Other than that, they don't really help.
2. Scrolling is made easy with small levels. So long as levels are smaller than either 512x240 or 256x480 you avoid ALL the hard parts of scrolling.
3. If the levels are less than just one of those dimensions, it's only a little harder than one axis way scrolling. (Like Super Mario Bros. 3 which can be longer than 256 on X, but isn't larger than 480 on Y.)
 
Top Bottom