NintendoAge http://nintendoage.com/forum/ -Sqooner Advanced Nerdy Nights #4 http://nintendoage.com/forum/messageview.cfm?catid=22&threadid=36969 2013-10-15T12:24:24 -05.00 bunnyboy 9 So I guess I have to improve my dev skills in order to implement such stuffs ^_^ ]]> Advanced Nerdy Nights #4 http://nintendoage.com/forum/messageview.cfm?catid=22&threadid=36969 2013-10-15T10:58:29 -05.00 bunnyboy 9
Independent scroll of top and bottom parts of the screen is possible. But it is not really related to the Sprite 0 hit, as it is only one of methods of catching specific scanline. The same could be done with well timed code, or with a mapper with scanline IRQ. ]]>
Advanced Nerdy Nights #4 http://nintendoage.com/forum/messageview.cfm?catid=22&threadid=36969 2013-10-15T09:34:21 -05.00 bunnyboy 9 Or is it a bad practice?

What I am trying to do is to evaluate the ability to put the sprite 0 in the middle of the screen, and then manage the top and the bottom part to scroll independantly.
I don't know if it is possible.

Thanks.


]]>
Advanced Nerdy Nights #4 http://nintendoage.com/forum/messageview.cfm?catid=22&threadid=36969 2013-10-15T08:55:56 -05.00 bunnyboy 9 Advanced Nerdy Nights #4 http://nintendoage.com/forum/messageview.cfm?catid=22&threadid=36969 2013-10-15T05:37:50 -05.00 bunnyboy 9
When we get out of the loop that tests if sprite 0 have been hit, we are outside the vblank period, right ?

WaitSprite0:
  lda $2002
  and #%01000000
  beq WaitSprite0      ; wait until sprite 0 is hit

So, it is actually possible to do graphics update in real time, even if the ppu is rendering?
Or maybe, at this exact moment, all we can do is only update Scroll registers?

Any help or futher information would be very appreciated
Thanks a lot. ]]>
Advanced Nerdy Nights #4 http://nintendoage.com/forum/messageview.cfm?catid=22&threadid=36969 2010-08-04T12:18:57 -05.00 bunnyboy 9 Advanced Nerdy Nights #4 http://nintendoage.com/forum/messageview.cfm?catid=22&threadid=36969 2010-08-04T06:54:00 -05.00 bunnyboy 9 Advanced Nerdy Nights #4 http://nintendoage.com/forum/messageview.cfm?catid=22&threadid=36969 2010-08-04T02:13:05 -05.00 bunnyboy 9 Advanced Nerdy Nights #4 http://nintendoage.com/forum/messageview.cfm?catid=22&threadid=36969 2010-08-04T02:06:34 -05.00 bunnyboy 9 This Week: After scrolling this tutorial should be pretty simple. Sprite 0 has a special PPU flag associated with it. Here it will be used to do split screen scrolling to enable a static status bar on the top of the screen.

Sprite 0 Hit Flag
Sprite 0 has a special flag in the PPU status register at bit 6. When a non transparent pixel of sprite 0 overlaps a non transparent pixel of the background, the flag is set. In the SMB example, sprite 0 is placed at the bottom of the coin icon. That is one part of the status bar that does not move.

 

In our example we first set the scroll registers to 0 for the static status bar. The nametable is also set to 0. That makes sure that the background and sprite 0 will overlap in the correct place.
NMI:

  ; all graphics updating code goes here

  LDA #$00
  STA $2006        ; clean up PPU address registers
  STA $2006
  
  LDA #$00         ; start with no scroll for status bar
  STA $2005
  STA $2005
  
  LDA #%10010000   ; enable NMI, sprites from Pattern Table 0, background from Pattern Table 1
  STA $2000        ; start with nametable = 0 for status bar

  LDA #%00011110   ; enable sprites, enable background, no clipping on left side
  STA $2001
Next we make sure the sprite 0 hit flag is clear, to avoid it being tripped from the previous frame. The flag is cleared at the end of vblank, so once it equals 0 you know the next frame has started.
WaitNotSprite0:
  lda $2002
  and #%01000000
  bne WaitNotSprite0   ; wait until sprite 0 not hit

Now we wait until the sprite 0 is hit. How long this takes depends on how far down the screen your sprite 0 is placed.
WaitSprite0:
  lda $2002
  and #%01000000
  beq WaitSprite0      ; wait until sprite 0 is hit

When that loop finishes, the PPU is drawing the first pixels of sprite 0 that overlap pixels on the background. We add a small wait loop so the rest of the status bar is drawn, and then change the scroll registers. The rest of the screen down is drawn using those settings.
  ldx #$10
WaitScanline:
  dex
  bne WaitScanline
  
  LDA scroll
  STA $2005        ; write the horizontal scroll count register
  LDA #$00         ; no vertical scrolling
  STA $2005
    
  LDA #%10010000   ; enable NMI, sprites from Pattern Table 0, background from Pattern Table 1
  ORA nametable    ; select correct nametable for bit 0
  STA $2000

So the order is:
  1 - set scroll to 0 for status bar
  2 - wait for sprite 0 hit = 0
  3 - wait for sprite 0 hit = 1
  4 - delay so scanline finishes drawing
  5 - set scroll for level background

The only other change is to make sure your graphics updating code does not draw over the status bar. The previous DrawNewColumn function handles the graphics updates so it has a few small differences. The starting address is increased by $80 to skip the first 4 rows of background. Then the source address is increased by $04 for the same reason.

Putting It All Together
Download and unzip the sprite0.zip sample files. sprite0.asm is the same as the previous scrolling5.asm file plus the changes covered here. This is another good one to watch in an emulator.
]]>