Automatic scrolling
Moderator: Moderators
Automatic scrolling
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?
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?
Code: Select all
lda $2002
lda HScroll
sta $2005
lda VScroll
sta $2005
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.
Those locations are within the stack. When you first TXS, which value are you loading into the stack pointer?Roth wrote:I have those two allotted now at $1fe and $1ff respectively, which I _think_ is an alright place to put them.
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.
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):
This is early coding, so nothing else is in the nmi
This is the routine called in nmi:
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).
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 HScrollCode: Select all
nmi:
pha
txa
pha
tya
pha
jsr scroll_it
end_nmi:
pla
tay
pla
tax
pla
rtiCode: Select all
scroll_it:
bit $2007
lda HScroll
sta $2005
lda VScroll
sta $2005
rtsThis 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).
- 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).
- 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).
Oops, 2007 wasn't intended, but now fixed. Just a brain fart while typing.Bregalad wrote:- You should read $2002, not $2007 before setting the scroll values
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.
Thank you! Now, just one more thing about scrolling this same nametable. I have that working with a decrement: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.
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
rtsTo see what I'm talking about with the skipping, here's the ROM:"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.)
http://roth.zhxhome.net/games/original/ ... hooter.nes
Yes. The correct way to do is when it's zero and you want to decrement it directly write $ef for proper scrolling.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?
Code: Select all
lda VScroll
sec
sbc #$01
bcs +
lda #$ef
+sta VScrollWhat 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.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
It actually is set to vertical mirroring. Is there something I'm missing here?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.
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 ;)Also it's the first time I see a ROM with 4KB CHRROM.
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:
EDIT: Oh, and thank you very much Bregalad. This gives me more food for thought about how to go about things :)
Code: Select all
lda VScroll
sec
sbc #$01
bcs :+
lda #$ef
: sta VScrollYou don't have to read PPUSTATUS. It's just recommended for these reasons: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?
- Reading PPUSTATUS acknowledges the NMI.
- 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:
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.