oam.asm 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. PrepareOAMData:
  2. ; Determine OAM data for currently visible
  3. ; sprites and write it to wOAMBuffer.
  4. ld a, [wUpdateSpritesEnabled]
  5. dec a
  6. jr z, .updateEnabled
  7. cp -1
  8. ret nz
  9. ld [wUpdateSpritesEnabled], a
  10. jp HideSprites
  11. .updateEnabled
  12. xor a
  13. ld [hOAMBufferOffset], a
  14. .spriteLoop
  15. ld [hSpriteOffset2], a
  16. ld d, wSpriteStateData1 / $100
  17. ld a, [hSpriteOffset2]
  18. ld e, a
  19. ld a, [de] ; c1x0
  20. and a
  21. jp z, .nextSprite
  22. inc e
  23. inc e
  24. ld a, [de] ; c1x2 (facing/anim)
  25. ld [wd5cd], a
  26. cp $ff ; off-screen (don't draw)
  27. jr nz, .visible
  28. call GetSpriteScreenXY
  29. jr .nextSprite
  30. .visible
  31. cp $a0 ; is the sprite unchanging like an item ball or boulder?
  32. jr c, .usefacing
  33. ; unchanging
  34. and $f
  35. add $10 ; skip to the second half of the table which doesn't account for facing direction
  36. jr .next
  37. .usefacing
  38. and $f
  39. .next
  40. ld l, a
  41. ; get sprite priority
  42. push de
  43. inc d
  44. ld a, e
  45. add $5
  46. ld e, a
  47. ld a, [de] ; c2x7
  48. and $80
  49. ld [hSpritePriority], a ; temp store sprite priority
  50. pop de
  51. ; read the entry from the table
  52. ld h, 0
  53. ld bc, SpriteFacingAndAnimationTable
  54. add hl, hl
  55. add hl, hl
  56. add hl, bc
  57. ld a, [hli]
  58. ld c, a
  59. ld a, [hli]
  60. ld b, a
  61. ld a, [hli]
  62. ld h, [hl]
  63. ld l, a
  64. call GetSpriteScreenXY
  65. ld a, [hOAMBufferOffset]
  66. ld e, a
  67. ld d, wOAMBuffer / $100
  68. .tileLoop
  69. ld a, [hSpriteScreenY] ; temp for sprite Y position
  70. add $10 ; Y=16 is top of screen (Y=0 is invisible)
  71. add [hl] ; add Y offset from table
  72. ld [de], a ; write new sprite OAM Y position
  73. inc hl
  74. ld a, [hSpriteScreenX] ; temp for sprite X position
  75. add $8 ; X=8 is left of screen (X=0 is invisible)
  76. add [hl] ; add X offset from table
  77. inc e
  78. ld [de], a ; write new sprite OAM X position
  79. inc e
  80. ld a, [bc] ; read pattern number offset (accommodates orientation (offset 0,4 or 8) and animation (offset 0 or $80))
  81. inc bc
  82. push bc
  83. ld b, a
  84. ld a, [wd5cd] ; temp copy of c1x2
  85. swap a ; high nybble determines sprite used (0 is always player sprite, next are some npcs)
  86. and $f
  87. ; Sprites $a and $b have one face (and therefore 4 tiles instead of 12).
  88. ; As a result, sprite $b's tile offset is less than normal.
  89. cp $b
  90. jr nz, .notFourTileSprite
  91. ld a, $a * 12 + 4
  92. jr .next2
  93. .notFourTileSprite
  94. ; a *= 12
  95. sla a
  96. sla a
  97. ld c, a
  98. sla a
  99. add c
  100. .next2
  101. add b ; add the tile offset from the table (based on frame and facing direction)
  102. pop bc
  103. ld [de], a ; tile id
  104. inc hl
  105. inc e
  106. ld a, [hl]
  107. bit 1, a ; is the tile allowed to set the sprite priority bit?
  108. jr z, .skipPriority
  109. ld a, [hSpritePriority]
  110. or [hl]
  111. .skipPriority
  112. inc hl
  113. ld [de], a
  114. inc e
  115. bit 0, a ; OAMFLAG_ENDOFDATA
  116. jr z, .tileLoop
  117. ld a, e
  118. ld [hOAMBufferOffset], a
  119. .nextSprite
  120. ld a, [hSpriteOffset2]
  121. add $10
  122. cp $100 % $100
  123. jp nz, .spriteLoop
  124. ; Clear unused OAM.
  125. ld a, [hOAMBufferOffset]
  126. ld l, a
  127. ld h, wOAMBuffer / $100
  128. ld de, $4
  129. ld b, $a0
  130. ld a, [wd736]
  131. bit 6, a ; jumping down ledge or fishing animation?
  132. ld a, $a0
  133. jr z, .clear
  134. ; Don't clear the last 4 entries because they are used for the shadow in the
  135. ; jumping down ledge animation and the rod in the fishing animation.
  136. ld a, $90
  137. .clear
  138. cp l
  139. ret z
  140. ld [hl], b
  141. add hl, de
  142. jr .clear
  143. GetSpriteScreenXY:
  144. inc e
  145. inc e
  146. ld a, [de] ; c1x4
  147. ld [hSpriteScreenY], a
  148. inc e
  149. inc e
  150. ld a, [de] ; c1x6
  151. ld [hSpriteScreenX], a
  152. ld a, 4
  153. add e
  154. ld e, a
  155. ld a, [hSpriteScreenY]
  156. add 4
  157. and $f0
  158. ld [de], a ; c1xa (y)
  159. inc e
  160. ld a, [hSpriteScreenX]
  161. and $f0
  162. ld [de], a ; c1xb (x)
  163. ret