Automatic scrolling

Are you new to 6502, NES, or even programming in general? Post any of your questions here. Remember - the only dumb question is the question that remains unasked.

Moderator: Moderators

Roth
Posts: 400
Joined: Wed Aug 03, 2005 3:15 pm
Contact:

Automatic scrolling

Post by Roth »

I'm working on a simple shooter game right now, and decided instead of the background standing still, I would try implementing a simple scrolling of the same nametable. I am wanting the player to scroll upwards (make the background move downwards).

On the wiki about $2005, it says to read from $2002 first. What I don't understand is how do you actually use/implement PPUSCROLL?
User avatar
Bregalad
Posts: 8036
Joined: Fri Nov 12, 2004 2:49 pm
Location: Caen, France

Post by Bregalad »

Code: Select all

lda $2002
lda HScroll
sta $2005
lda VScroll
sta $2005
Roth
Posts: 400
Joined: Wed Aug 03, 2005 3:15 pm
Contact:

Post by Roth »

I have those two allotted now at $1fe and $1ff respectively, which I _think_ is an alright place to put them. Then I have a jsr to scroll_it in my nmi. Now, where exactly would I put what the values of those are? Would it be okay to initialize them to something right after my init code? I'm trying something like that, but now nothing happens, and there is only half of my nametable showing.
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Post by tepples »

Roth wrote:I have those two allotted now at $1fe and $1ff respectively, which I _think_ is an alright place to put them.
Those locations are within the stack. When you first TXS, which value are you loading into the stack pointer?

Oh, and setting the scroll should be done after you finish loading the nametables. The register inside the PPU that holds the X/Y scroll position is the same register that holds the VRAM read/write address.
Roth
Posts: 400
Joined: Wed Aug 03, 2005 3:15 pm
Contact:

Post by Roth »

I've changed them out of the stack to avoid conflicts ($00fe, $00ff). So, here are some snippits:

I made a seperate routine to place the values, which takes place after my background is pulled in (I'm not sure what values to use, honestly):

Code: Select all

scroll_values:
	lda #$20
	sta VScroll
	lda #$00
	sta HScroll
This is early coding, so nothing else is in the nmi

Code: Select all

nmi:
	pha
	txa
	pha
	tya
	pha
	jsr scroll_it
end_nmi:	
	pla
	tay
	pla
	tax
	pla
	rti
This is the routine called in nmi:

Code: Select all

scroll_it:
	bit $2007
	lda HScroll
	sta $2005
	lda VScroll
	sta $2005
	rts

This is a bit different than I thought it'd be. I figured it would just start the scrolling. It looks like all it did is shift the nametable. If it makes any difference, right now I'm using vertical mirroring, though I have switched the header to reflect horizontal and gotten the same kind of effect (shifted nametable).
User avatar
Bregalad
Posts: 8036
Joined: Fri Nov 12, 2004 2:49 pm
Location: Caen, France

Post by Bregalad »

- You should read $2002, not $2007 before setting the scroll values
- It's possible to place variables at $1fe and $1ff, but then you have to make sure you place your stack pointer somewhere else... As long as you have enough RAM free I'd say avoid putting everything in $100-$1ff, but use this pace as extra RAM if you run out of it.
Also consider $2000.0 to be the "9th H scrolling bit" and $2000.1 the "9th V scrolling bit", it often help understanding. Only one of these is significant, depending on the mirroring.
I recommand writing to $2000 each VBlank after setting $2005 (you technically don't have to, but that's the way everyone handles it).
Roth
Posts: 400
Joined: Wed Aug 03, 2005 3:15 pm
Contact:

Post by Roth »

Bregalad wrote:- You should read $2002, not $2007 before setting the scroll values
Oops, 2007 wasn't intended, but now fixed. Just a brain fart while typing.

I'm still at a loss. Am I supposed to be coding some increments or something to get this to scroll, or is it just supposed to move on it's own? If it's the latter, it sure isn't right now. I feel like this shouldn't be that difficult. I must be overlooking something.
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Post by tepples »

The value written to the background scroll registers is like a camera position. Every few frames, you need to change this camera position.
Roth
Posts: 400
Joined: Wed Aug 03, 2005 3:15 pm
Contact:

Post by Roth »

tepples wrote:The value written to the background scroll registers is like a camera position. Every few frames, you need to change this camera position.
Thank you! Now, just one more thing about scrolling this same nametable. I have that working with a decrement:

Code: Select all

scroll_values:
   	lda #$00
   	sta VScroll
   	sta HScroll
   	rts

scroll_it:
	bit $2002
	lda HScroll
	sta $2005
	lda VScroll
	sta $2005
	dec VScroll
	rts
Towards either the end or beginning (I can't really tell which), it jumps a tad. I'm guessing this has to do with what it says on the wiki?
"Normal" vertical offsets range from 0 to 239. (Values of 240 to 255 are treated as -16 through -1 in a way, pulling tile data from the attribute table.)
To see what I'm talking about with the skipping, here's the ROM:

http://roth.zhxhome.net/games/original/ ... hooter.nes
User avatar
Bregalad
Posts: 8036
Joined: Fri Nov 12, 2004 2:49 pm
Location: Caen, France

Post by Bregalad »

Towards either the end or beginning (I can't really tell which), it jumps a tad. I'm guessing this has to do with what it says on the wiki?
Yes. The correct way to do is when it's zero and you want to decrement it directly write $ef for proper scrolling.

Code: Select all

 lda VScroll
 sec
 sbc #$01
 bcs +
 lda #$ef
+sta VScroll
Also I'd recommand switching to vertical mirroring if you want the same background scrolling over and over again, or fill the nametable #2 with something. Also it's the first time I see a ROM with 4KB CHRROM.
Roth
Posts: 400
Joined: Wed Aug 03, 2005 3:15 pm
Contact:

Post by Roth »

Bregalad wrote:Yes. The correct way to do is when it's zero and you want to decrement it directly write $ef for proper scrolling.

Code: Select all

 lda VScroll
 sec
 sbc #$01
 bcs +
 lda #$ef
+sta VScroll
What compiler syntax is that for? It doesn't seem to work in ca65. Let me know so I can check the documentation for the compiler you use and I can convert it to the syntax for mine.
Also I'd recommand switching to vertical mirroring if you want the same background scrolling over and over again, or fill the nametable #2 with something.
It actually is set to vertical mirroring. Is there something I'm missing here?
Also it's the first time I see a ROM with 4KB CHRROM.
Well, I was going to make a little something in the 4KB range for the mini-game competition, so I was putting both background and sprites in the same tileset to bring down the size (I'm guessing it would help). I was planning on using the competition to learn how to do some compression. It was down originally, but now it seems to be up again (the page for the competition, that is). I doubt I'm going to submit anything to it now because I'd rather just get a game that's more than a basic demo, regardless of size. We'll see though. I guess it's a good thing that lines can be commented out and such, great for experimenting ;)
Roth
Posts: 400
Joined: Wed Aug 03, 2005 3:15 pm
Contact:

Post by Roth »

Hey, sorry about the double post, but I was able to figure out the correct syntax. For anyone using ca65 that was reading this and didn't know, here it is:

Code: Select all

 	lda VScroll
 	sec
 	sbc #$01
 	bcs :+
 	lda #$ef
:	sta VScroll
EDIT: Oh, and thank you very much Bregalad. This gives me more food for thought about how to go about things :)
Celius
Posts: 2159
Joined: Sun Jun 05, 2005 2:04 pm
Location: Minneapolis, Minnesota, United States
Contact:

Post by Celius »

Oh my, I must have missed something. This may be a bit of a surprise, but I didn't know you had to read from $2002 before setting the scroll. Why is this necessary?
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Post by tepples »

Celius wrote:Oh my, I must have missed something. This may be a bit of a surprise, but I didn't know you had to read from $2002 before setting the scroll. Why is this necessary?
You don't have to read PPUSTATUS. It's just recommended for these reasons:
  1. Reading PPUSTATUS acknowledges the NMI.
  2. A flag inside the PPU tells it whether to expect a first write or a second write, and reading PPUSTATUS sets this flag to a known state.
Celius
Posts: 2159
Joined: Sun Jun 05, 2005 2:04 pm
Location: Minneapolis, Minnesota, United States
Contact:

Post by Celius »

Okay, good. It's just that I wrote this scrolling engine a while ago, and it was pretty big since I included attribute updates and whatnot, and I did not read before updating scrolls or writing to $2006. I was just hoping that my whole engine wasn't now unreliable and sloppy since I didn't do that. But that's good to know. Thanks.
Post Reply