It is currently Mon Dec 11, 2017 6:30 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 5 posts ] 
Author Message
PostPosted: Thu Sep 10, 2015 7:49 pm 
Offline
User avatar

Joined: Mon Dec 29, 2014 1:46 pm
Posts: 750
Location: New York, NY
I was considering enhancing the wiki with some pseudocode to further the details on PPU sprite evaluation. But, there are 2 parts marked with question marks that I am unsure about:

Code:
readCycle = (scanlineCycle AND 1) == 1
if scanlineCycle == 0
  if scanline == PRE_RENDER_SCANLINE and ((4 * primarySprite + primaryVar) AND $F8) != 0
    copy OAM[primarySprite AND $FE][0..3] to OAM[0][0..3]
    copy OAM[(primarySprite AND $FE) + 1][0..3] to OAM[1][0..3] 
  primarySprite = 0
  primaryVar = 0
  secondarySprite = 0
  secondaryVar = 0
else if scanlineCycle <= 64
  if readCycle
    oamValue = $FF
  else
    SOAM[secondarySprite][secondaryVar] = oamValue
    secondaryVar = secondaryVar + 1
    if secondaryVar == 4
      secondaryVar = 0
      secondarySprite = secondarySprite + 1
  if scanlineCycle == 64
    secondarySprite = 0
    secondaryVar = 0
    state = STATE_COPY_Y
else if scanlineCycle <= 256 
  if readCycle
    oamValue = OAM[primarySprite][primaryVar]
  else
    if state == STATE_COPY_Y
      SOAM[secondarySprite][secondaryVar] = oamValue
      if scanline >= oamValue and scanline <= (oamValue + spriteBottomOffset)
        state = STATE_COPY_REMAINING
        primaryVar = primaryVar + 1
        if primaryVar == 4
          primaryVar = 0
          primarySprite = primarySprite + 1
          if primarySprite == 64
            primarySprite = 0
        secondaryVar = secondaryVar + 1
        if secondaryVar == 4
          secondaryVar = 0
          secondarySprite = secondarySprite + 1
          if secondarySprite == 8
            secondarySprite = 0
      else
        primarySprite = primarySprite + 1
        if primarySprite == 64
          primarySprite = 0         
          state = STATE_SPIN
    else if state == STATE_COPY_REMAINING
      SOAM[secondarySprite][secondaryVar] = oamValue
      primaryVar = primaryVar + 1
      if primaryVar == 4
        primaryVar = 0
        primarySprite = primarySprite + 1
        if primarySprite == 64
          primarySprite = 0
      secondaryVar = secondaryVar + 1
      if secondaryVar == 4
        secondaryVar = 0
        secondarySprite = secondarySprite + 1
        if secondarySprite == 8
          secondarySprite = 0
          state = STATE_SPRITE_8_Y
        else if primarySprite == 0
          state = STATE_SPIN           
        else
          state = STATE_COPY_Y
    else if state == STATE_SPRITE_8_Y
      if scanline >= oamValue and scanline <= (oamValue + spriteBottomOffset)
        state = STATE_SPRITE_8_REMAINING
        spriteOverflow = true
        primaryVar = primaryVar + 1
      if primaryVar == 4
        primaryVar = 0
        primarySprite = primarySprite + 1
        if primarySprite == 64
          primarySprite = 0
          secondaryVar = 1         
        else
 
          // ?? 1 ??

            state = STATE_SPIN
    else if state == STATE_SPRITE_8_REMAINING
      primaryVar = primaryVar + 1
      if primaryVar == 4
        primaryVar = 0
        primarySprite = primarySprite + 1
        if primarySprite == 64
          primarySprite = 0
          secondaryVar = secondaryVar + 1
          if secondaryVar == 4
            secondaryVar = 0
            secondarySprite = secondarySprite + 1

             // ?? 2 ??

             state = STATE_SPIN
    else if state == STATE_SPIN
      primarySprite = primarySprite + 1
      if primarySprite == 64
        primarySprite = 0
else if scanlineCycle <= 320
  if scanlineCycle == 257
    primarySprite = 0
    primaryVar = 0
    secondarySprite = 0
    secondaryVar = 0
  if ((scanlineCycle - 1) AND $04) < 4
    secondaryVar = secondaryVar + 1
    if secondaryVar == 4
      secondaryVar = 0
      secondarySprite = secondarySprite + 1
      if secondarySprite == 8
        secondarySprite = 0


Top
 Profile  
 
PostPosted: Sat Sep 12, 2015 7:19 pm 
Offline
User avatar

Joined: Mon Dec 29, 2014 1:46 pm
Posts: 750
Location: New York, NY
On the wiki, what does "without carry" in the following line mean?

"3b. If the value is not in range, increment n and m (without carry). If n overflows to 0, go to 4; otherwise go to 3"


Top
 Profile  
 
PostPosted: Sat Sep 12, 2015 7:29 pm 
Offline
User avatar

Joined: Sun Sep 19, 2004 10:59 pm
Posts: 1393
zeroone wrote:
On the wiki, what does "without carry" in the following line mean?

"3b. If the value is not in range, increment n and m (without carry). If n overflows to 0, go to 4; otherwise go to 3"

It means increment 'n' and 'm' separately and do not increment 'n' if 'm' overflows (compared to step 3a, which does do that).

_________________
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.


Top
 Profile  
 
PostPosted: Sat Sep 12, 2015 7:36 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19322
Location: NE Indiana, USA (NTSC)
It means sequences such as the following, where the display list entry (bits 7-2) and offset within an entry (bits 1-0) are incremented separately.

36 | 001001 00
41 | 001010 01
46 | 001011 10
51 | 001100 11
52 | 001101 00
57 | 001110 01
62 | 001111 10
67 | 010000 11
68 | 010001 00

This produces a sequence of +5, +5, +5, +1, where the result after a +1 is a multiple of 4.

Code:
OAMADDR += (OAMADDR & 3) == 3 ? 1 : 5;


Top
 Profile  
 
PostPosted: Sat Sep 12, 2015 8:36 pm 
Offline
User avatar

Joined: Mon Dec 29, 2014 1:46 pm
Posts: 750
Location: New York, NY
Thanks Quietust and tepples. I'll use that to fill in the second comment of missing pseudocode.

The first comment of missing code referred to this line:

"3a. If the value is in range, set the sprite overflow flag in $2002 and read the next 3 entries of OAM (incrementing 'm' after each byte and incrementing 'n' when 'm' overflows); if m = 3, increment n"

But, it sounds like this is just increment with overflow.

@ tepples That's a brilliant observation. It should be added to the wiki. In addition, the pseudocode could be rewritten using single indices into primary and secondary OAM instead of dual-indices.


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

All times are UTC - 7 hours


Who is online

Users browsing this forum: Bing [Bot], Jarhmander, Yahoo [Bot] and 5 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