It is currently Wed Aug 15, 2018 2:27 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 10 posts ] 
Author Message
PostPosted: Sat Jan 30, 2016 11:51 pm 
Offline

Joined: Sun Jan 17, 2016 1:14 pm
Posts: 6
Scenario:
I have a sprite in the center of the screen. The background x and y scroll is updated by the controller. I allow to scroll infinitely in any direction. The background continues to repeat (which is what I want.) I've experimented with 4 way mirroring and loading the same nametable into each of the 4 nametable addresses so the image always repeats.

Problem:
I notice that when I scroll horizontal the image repeats with no issue but when I continue to scroll vertical a set of artifacts appears on the top of the screen that appear to be generated by the PPU and not from any graphics in my .chr file. When y reaches between 240-255 the artifacts appear. I believe it has something to do with x being from 0-255 and the size of the nametable for y is 0-239.

Question:
How can I scroll in any direction for any length of distance and have a background continue to repeat without seeing the artifacts I mention above?


Top
 Profile  
 
PostPosted: Sun Jan 31, 2016 12:13 am 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 7380
Location: Seattle
For this reason, a write [y] >= 240 to $2005 may appear as a "negative" scroll value, where 1 or 2 rows of attribute data will appear before the nametable's tile data is reached.

TL;DR, don't do that. On the NES for Y scrolling, 256 comes after 239.


Top
 Profile  
 
PostPosted: Sun Jan 31, 2016 2:19 am 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7469
Location: Chexbres, VD, Switzerland
"Negative scrolling" is badly worded for what happens there. A more accurate description would be "scroll into the attribute table", where the AT data is displayed on the screen as NT data. I'm not saying this feaure doesn't have any applications, but so far I didn't find any so if there is any use to this it is in extremely weird/special cases.

For instance if you badly needed a 32x32 tile map and would be ready to sacrifice coulours for it, you could set all 4 BG palettes to the same values and use AT as NT, to get the required 32x32 map.

In typically scrolling case, you do not want to do that, and want to go from 239 to 0 directly.


Top
 Profile  
 
PostPosted: Sun Jan 31, 2016 5:41 am 
Offline
User avatar

Joined: Sat Jul 25, 2015 1:22 pm
Posts: 501
Here's a good thread I found when I was dealing with this:

http://forums.nesdev.com/viewtopic.php?f=10&t=10958


Top
 Profile  
 
PostPosted: Sun Jan 31, 2016 6:16 am 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10702
Location: Rio de Janeiro - Brazil
After incrementing the Y scroll, check if it's larger than 239. If so, add 16 to force a wrap to the next screen, skipping over the attribute tables. After decrementing it, check if it underflowed below 0, and subtract 16 if that's the case.


Top
 Profile  
 
PostPosted: Mon Feb 01, 2016 2:55 am 
Offline

Joined: Sun Jan 17, 2016 1:14 pm
Posts: 6
Thanks guys. I got it to work this way during my controller reads for up and down.

Code:
player_up_update:
   lda scrolly            ; Load scrolly position
   sec
   sbc   #$01            ; Subtract from A
   stay  scrolly            ; Update scrolly position
   cmp   #$ef               ; Compare scrolly to 239
   bcs   update_scrollyup      ; If more than 239 update scrolly
   jmp   player_down_read      ; Jump to player_down_read

update_scrollyup:
   lda   scrolly
   sec
   sbc   #$10            ; Subtract 16 from scrolly position
   sta   scrolly
   rts

player_down_update:
   lda scrolly            ; Load scrolly position
   clc
   adc   #$01            ; Add from A
   stay  scrolly            ; Update scrolly position
   cmp  #$ef               ; Compare scrolly to 239
   bcs   update_scrollydown      ; If more than 239 update scrolly
   jmp   player_left_read      ; Jump to player_left_read

update_scrollydown:
   lda   scrolly
   clc
   adc   #$10            ; Add 16 to scrolly position
   sta   scrolly
   rts


Top
 Profile  
 
PostPosted: Mon Feb 01, 2016 3:34 am 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7469
Location: Chexbres, VD, Switzerland
Youre making it more complicated than needed. This is simpler :

Code:
   lda scrolly
   clc
   adc scrollyspeed
   cmp #$f0
   bcc +
   sbc #$f0
+  sta scrolly


Top
 Profile  
 
PostPosted: Mon Feb 01, 2016 5:28 am 
Offline

Joined: Mon Nov 10, 2008 3:09 pm
Posts: 433
Sl1pm0de wrote:
Thanks guys. I got it to work this way during my controller reads for up and down.

Code:
player_up_update:
   lda scrolly            ; Load scrolly position
   sec
   sbc   #$01            ; Subtract from A
   stay  scrolly            ; Update scrolly position
   cmp   #$ef               ; Compare scrolly to 239
   bcs   update_scrollyup      ; If more than 239 update scrolly
   jmp   player_down_read      ; Jump to player_down_read

update_scrollyup:
   lda   scrolly
   sec
   sbc   #$10            ; Subtract 16 from scrolly position
   sta   scrolly
   rts

player_down_update:
   lda scrolly            ; Load scrolly position
   clc
   adc   #$01            ; Add from A
   stay  scrolly            ; Update scrolly position
   cmp  #$ef               ; Compare scrolly to 239
   bcs   update_scrollydown      ; If more than 239 update scrolly
   jmp   player_left_read      ; Jump to player_left_read

update_scrollydown:
   lda   scrolly
   clc
   adc   #$10            ; Add 16 to scrolly position
   sta   scrolly
   rts


You can't use conditional branch instructions to branch to a subroutine like you're doing. Those instructions don't push a return address.


Top
 Profile  
 
PostPosted: Mon Feb 01, 2016 9:45 am 
Offline

Joined: Sun Jan 17, 2016 1:14 pm
Posts: 6
Thanks. This ended up working. I use #$ef instead of #$f0 because you start to see the attribute table starting at #$f0 (240). I had seen the + method used before but didn't understand it. Now I do. It enabled me to jump the instruction (I'm pretty new at this).

I was adding 16 to 240 or subtracting 16 from an undersigned value (<0) to make it work before. This allowed me to skip the attribute table that was showing. Can someone help me understand why adding or subtracting (depending on the controller direction) 239 to 239 works?

Thanks

Code:
player_up_update:
   lda scrolly               ; Load scrolly position
   sec
   sbc   scrollspeed            ; Advance the scroll
   cmp   #$ef               ; Compare scrolly to 239
   bcc   +
   adc   #$ef               ; Add 239 to scrolly
+   sta   scrolly               ; Update scrolly position
   jmp   player_down_read      ; Jump to player_down_read
   
player_down_update:
   lda scrolly               ; Load scrolly position
   clc
   adc   scrollspeed            ; Advance the scroll
   cmp #$ef               ; Compare scrolly to 239
   bcc   +
   sbc   #$ef               ; Subtract 239 to scrolly
+   sta   scrolly               ; Update scrolly position
   jmp   player_left_read      ; Jump to player_left_read


Top
 Profile  
 
PostPosted: Mon Feb 01, 2016 10:07 am 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 20402
Location: NE Indiana, USA (NTSC)
Adding 239 is the same as subtracting 17.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 10 posts ] 

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 4 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group