Tricking Mapper 30 to do 4-way Scrolling

Bucket Mouse
Posts: 193
Joined: Wed Mar 07, 2018 2:25 am

Re: Tricking Mapper 30 to do 4-way Scrolling

Post by Bucket Mouse » Sun Apr 08, 2018 2:03 am

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.
User avatar
Kasumi
Posts: 155
Joined: Fri Mar 09, 2018 11:13 pm

Re: Tricking Mapper 30 to do 4-way Scrolling

Post by Kasumi » Sun Apr 08, 2018 7:47 am

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/smb ... 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 ... E_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/smb ... ROLL&type=

And there are a few results. One is this:

Code: Select all

	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/smb ... roll&type=

This is where the results get dense. One of the results is this, however.

Code: Select all

	.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.
Image
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: Select all

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: Select all

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!
User avatar
redantgames
Posts: 8
Joined: Wed Apr 04, 2018 4:56 pm
Location: Cold Lake, Alberta
Contact:

Re: Tricking Mapper 30 to do 4-way Scrolling

Post by redantgames » Sun Apr 08, 2018 10:22 pm

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?
Jason McMillen

Red Ant Retro -- Retro video games & hardware store
Red Ant Games -- Indie Game Development (Old website!)
User avatar
Kasumi
Posts: 155
Joined: Fri Mar 09, 2018 11:13 pm

Re: Tricking Mapper 30 to do 4-way Scrolling

Post by Kasumi » Sun Apr 08, 2018 11:26 pm

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.)
Post Reply