Scrolling problems...

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

Post Reply
User avatar
Vectrex2809
Posts: 97
Joined: Mon Jul 14, 2014 6:05 am
Location: Tokyo, Japan

Scrolling problems...

Post by Vectrex2809 »

I have a level that covers 2 nametables, with a sprite zero hit to make the status bar stay on nametable 0. However, after I implemented a pretty big metasprite (it's a boss level), it looks like the part of the screen before the s0 hit get the scroll value and vice-versa (the playfield goes back to $00). When looking at the RAM in FCEUX's hex editor, there are numbers that go in the stack when the glitch is happening. After a while, the game freezes (probably because it hits the buffer, which is in the $0100 page)

Here's the problematic part of the code

Code: Select all

  LDX #$00
.posxloop
  LDA Pony_Posx                        ;X position of the evil My Little Ponies (Using a variable to make them "alive" when in another Nametable
  SEC
  SBC scroll
  STA $0213,x
  CLC
  ADC #$08
  STA $0217,x
  CLC
  ADC #$08
  STA $021B,x
  CLC
  ADC #$08
  STA $021F,x
  TXA
  CLC
  ADC #$10
  TAX
  CPX #$50
  BNE .posxloop

  LDA $0210                              ;y position (problematic) - I have the Pony_Posy variable ready but even when using this, it glitches
  STA $0214
  STA $0218
  STA $021C
  CLC
  ADC #$10
  LDA $0220
  STA $0224
  STA $0228
  STA $022C
  CLC
  ADC #$08
  LDA $0230
  STA $0234
  STA $0238
  STA $023C
  CLC
  ADC #$10
  LDA $0240
  STA $0244
  STA $0248
  STA $024C
  CLC
  ADC #$10
  LDA $0250
  STA $0254
  STA $0258
  STA $025C

  LDA $0263
  STA $026B
  CLC
  ADC #$08
  STA $0267
  STA $026F

  LDA $0260
  STA $0264
  CLC
  ADC #$10
  STA $0268
  STA $026C

  JSR ReadController                                  ;Controller reads, basic stuff
  JSR Sprite_Cycling                                   ;Flickering routine, OAM at $07xx
  JSR CheckScores                                     ;Scoring, works perfectly

  LDA #$36                                               ;Don't mess with Sprite Zero
  STA $0700
  LDA #$80
  STA $0701
  LDA #$13
  STA $0702
  STA $0703

  JSR PPUCleanup

Sprite0_testone:
  BIT $2002
  BVS Sprite0_testone
Sprite0_testtwo:		;First check if Sprite Zero gets hit
  BIT $2002
  BVC Sprite0_testtwo

  LDX #$00
WaitScanline1:			;Wait to make sure you get the right scanline
  INX
  CPX #$70
  BNE WaitScanline1

  JSR PPUCleanup              ;make sure $2000 and $2001 are in their usual state
  LDA scroll
  STA $2005
  LDA #$00
  STA $2005

  JMP GameEngineDone
User avatar
tokumaru
Posts: 12106
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Scrolling problems...

Post by tokumaru »

Can't say much based on the code you posted, it's too incomplete.
Vectrex2809 wrote:after I implemented a pretty big metasprite (it's a boss level), it looks like the part of the screen before the s0 hit get the scroll value and vice-versa (the playfield goes back to $00).
Does this big sprite significantly increase the amount of processing you do every frame? Are you running your game logic inside the NMI handler, like some tutorials like to teach? If so, it could be that the extra processing is "leaking" into the visible frame before you have time to setup the scroll for the status bar.
When looking at the RAM in FCEUX's hex editor, there are numbers that go in the stack when the glitch is happening. After a while, the game freezes (probably because it hits the buffer, which is in the $0100 page)
Do all the JSRs have a matching RTSs? Does every PHA have a matching PLA? If you forget things in the stack or pull more bytes than you've pushed, the program will certainly crash. Make sure that there are no branches skipping instructions that manipulate the stack.
Here's the problematic part of the code
Like I said, this is too incomplete for us to diagnose anything. It doesn't show where the NMI handler is, when in the frame this code runs, what PPUCleanup does...
User avatar
Vectrex2809
Posts: 97
Joined: Mon Jul 14, 2014 6:05 am
Location: Tokyo, Japan

Re: Scrolling problems...

Post by Vectrex2809 »

tokumaru wrote:Can't say much based on the code you posted, it's too incomplete.
Vectrex2809 wrote:after I implemented a pretty big metasprite (it's a boss level), it looks like the part of the screen before the s0 hit get the scroll value and vice-versa (the playfield goes back to $00).
Does this big sprite significantly increase the amount of processing you do every frame? Are you running your game logic inside the NMI handler, like some tutorials like to teach? If so, it could be that the extra processing is "leaking" into the visible frame before you have time to setup the scroll for the status bar.
When looking at the RAM in FCEUX's hex editor, there are numbers that go in the stack when the glitch is happening. After a while, the game freezes (probably because it hits the buffer, which is in the $0100 page)
Do all the JSRs have a matching RTSs? Does every PHA have a matching PLA? If you forget things in the stack or pull more bytes than you've pushed, the program will certainly crash. Make sure that there are no branches skipping instructions that manipulate the stack.
Here's the problematic part of the code
Like I said, this is too incomplete for us to diagnose anything. It doesn't show where the NMI handler is, when in the frame this code runs, what PPUCleanup does...
It may be from the fact that I'm running the game logic in the NMI handler, since that's the way the Nerdy Nights taught me to do it. I'm going to remove it from the NMI handler and I'll see if something changes.
User avatar
tokumaru
Posts: 12106
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Scrolling problems...

Post by tokumaru »

Before you do that, check if this is really your problem. I suspect you're setting the scroll for the first time too late in the frame, but you can check in FCEUX debugger (there are many threads explaining how to use it).

That being said, having the game logic in the NMI handler is a legitemate way to do thing (famous games like SMB do it), but you have to do PPU updates first and game logic second (I don't know if nerdy nights does it like that, but I've seen tutorials that don't), otherwise the VBlank will end before you have processed the entire game state and the PPU updates will spill into rendering time, screwing things up.
User avatar
Vectrex2809
Posts: 97
Joined: Mon Jul 14, 2014 6:05 am
Location: Tokyo, Japan

Re: Scrolling problems...

Post by Vectrex2809 »

tokumaru wrote:Before you do that, check if this is really your problem. I suspect you're setting the scroll for the first time too late in the frame, but you can check in FCEUX debugger (there are many threads explaining how to use it).

That being said, having the game logic in the NMI handler is a legitemate way to do thing (famous games like SMB do it), but you have to do PPU updates first and game logic second (I don't know if nerdy nights does it like that, but I've seen tutorials that don't), otherwise the VBlank will end before you have processed the entire game state and the PPU updates will spill into rendering time, screwing things up.
Well, I already went to the wiki and rewrote my code according to what was said in "The Frame and NMI" page, and right now, each time I try to make a sprite zero hit, the game crashes. I actually have no idea on how to implement a sprite zero hit in this, it seems like each time the game runs the "Spritezero_test" routines, it crashes. Here's my NMI handler (The sprite zero thing is probably something really, really bad)

Code: Select all

NMI:

  PHA
  TXA
  PHA
  TYA
  PHA

  LDA needdma
  BEQ .nodma

  LDA #$00
  STA $2003  ; set the low byte (00) of the RAM address
  LDA #$07
  STA $4014  ; set the high byte (02) of the RAM address, start the transfer

.nodma

  LDA needdraw
  BEQ Buffer_Done
  LDA fadeswitch
  BEQ .nofade
  BIT $2002
  JSR Palette_Fade

  JMP Buffer_Done
.nofade

  BIT $2002
  LDX #$00
Buffer:
  LDA Buffer_Shit,x	;Determines the length of the string we will have to copy
  BEQ Buffer_Done	;If equal to zero, stop copying
  TAY			;If not, transfer to Y and prepare the start address for the PPU
  INX

  LDA Buffer_Shit,x
  STA $2006		;Here's your address, PPU
  INX
  LDA Buffer_Shit,x
  STA $2006		;*Gives address to PPU*
  INX

  LDA Buffer_Shit,x	;Are we copying stuff vertically or horizontally?
  BEQ .buffright	;(The former won't probably be used in this game, but it can be
  LDA #%10010100	;kickass for future platforming games) ;-)
  STA $2000		;Oh, this is the vert loop (with A=1)
  INX
  JMP Buffer_Loop
.buffright
  LDA #%10010000	;Enable NMI, 8x8 sprites from Pattern Table 0, background from Pattern Table 1
  STA $2000		;Horizontal draw (Do I still have this from Nerdy Nights?!)
  INX
Buffer_Loop:		;This is where the magic happens

  LDA Buffer_Shit,x
  STA $2007
  INX
  DEY
  CPY #$00
  BNE Buffer_Loop
  JMP Buffer

Buffer_Done:

  LDA needppureg
  BEQ NoPPU

  LDA gamestate
  CMP #BOSSFIGHT
  BEQ .spritezero

  LDA soft2000
  STA $2000
  LDA soft2001
  STA $2001

  BIT $2002
  LDA scroll
  STA $2005
  LDA scrolly
  STA $2005
  JMP NoPPU

.spritezero

  LDA soft2000
  STA $2000
  LDA soft2001
  STA $2001

  LDA #$00
  STA $2005
  STA $2005

Sprite0_testone:
  LDA $2002
  AND #%01000000
  BNE Sprite0_testone
Sprite0_testtwo:		;First check if Sprite Zero gets hit
  LDA $2002
  AND #%01000000
  BEQ Sprite0_testone

  LDX #$00
WaitScanline1:			;Wait to make sure you get the right scanline
  INX
  CPX #$70
  BNE WaitScanline1

  LDA soft2000
  STA $2000
  LDA soft2001
  STA $2001

  LDA scroll
  STA $2005
  LDA #$00
  STA $2005

NoPPU:

  LDA #$00
  STA sleeping

  PLA
  TAY
  PLA
  TAX
  PLA

  RTI
User avatar
Bregalad
Posts: 8036
Joined: Fri Nov 12, 2004 2:49 pm
Location: Caen, France

Re: Scrolling problems...

Post by Bregalad »

I didn't look at your code, but it sounds like you are overwriting sprite #0 with your boss metasprites. You should double check your sprite engine and make sure you have control of everything. There is a million of approaches depending on if you want to do priorities, if you want to do sprite cycling, etc...

As for the main thread in or out the NMI problem, just do as you feel like, I don't think there is a clear advantage on one over another.
User avatar
Vectrex2809
Posts: 97
Joined: Mon Jul 14, 2014 6:05 am
Location: Tokyo, Japan

Re: Scrolling problems...

Post by Vectrex2809 »

Bregalad wrote:I didn't look at your code, but it sounds like you are overwriting sprite #0 with your boss metasprites. You should double check your sprite engine and make sure you have control of everything. There is a million of approaches depending on if you want to do priorities, if you want to do sprite cycling, etc...

As for the main thread in or out the NMI problem, just do as you feel like, I don't think there is a clear advantage on one over another.
EDIT: Glitch fixed :)
Post Reply