You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

320 lines
5.1 KiB

2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
  1. INCLUDE "hardware.inc"
  2. INCLUDE "oam.inc"
  3. INCLUDE "util.inc"
  4. Section "Player Data", WRAM0
  5. playerWorldX: dw
  6. playerWorldY: dw
  7. ; player data
  8. PLAYER_X:: db
  9. PLAYER_Y:: dw
  10. PLAYER_DIR:: db
  11. PLAYER_JUMPING:: db
  12. PLAYER_VY:: dw
  13. Section "Player Code", ROM0
  14. spriteData:
  15. INCBIN "png/sprite/player.2bpp"
  16. DEF SPRITE_OAM_IDX EQU 0
  17. DEF SPRITE_IDX EQU 32 ; tile index, rename later
  18. DEF SPRITE_WIDTH EQU 2
  19. DEF SPRITE_HEIGHT EQU 2
  20. DEF PLAYER_SPEED EQU 2
  21. DEF TILE_WIDTH EQU 8 ; Width of tile in bytes
  22. DEF TILE_HEIGHT EQU 8 ; Height of tile in bytes
  23. DEF TILE_SIZE EQU 16 ; Total length of tile in bytes
  24. DEF GRAVITY EQU (0 << 8) | $2e ; 0.18
  25. DEF INIT_VY EQU (3 << 8) | $99 ; 3.60
  26. DEF INIT_FALL_VY EQU ($ff << 8) | $1a ; a.b
  27. Player_Init::
  28. ; Clear player data
  29. ld hl, PLAYER_X
  30. ld [hl], 0
  31. inc hl
  32. ld [hl], SCRN_Y - SPRITE_HEIGHT * (SCRN_Y - SPRITE_HEIGHT * TILE_HEIGHT)
  33. inc hl
  34. xor a
  35. ld [hl+], a
  36. ld [hl+], a
  37. ld [hl+], a
  38. ld [hl+], a
  39. ld [hl+], a
  40. ; Copy sprite to VRAM
  41. ld bc, _VRAM8000 + SPRITE_IDX * TILE_SIZE
  42. ld hl, spriteData
  43. ld d, TILE_SIZE * (SPRITE_WIDTH * SPRITE_HEIGHT)
  44. call memcpy
  45. ; Initialize OAM entries with player state
  46. call Player_UpdateOAM
  47. ret
  48. Player_Update::
  49. ; check for jump
  50. ld a, [keys]
  51. and PADF_UP
  52. jr z, .jump_update_check
  53. ; initialize jump state if not already jumping
  54. ld a, [PLAYER_JUMPING]
  55. or a
  56. jr nz, .jump_update
  57. ld a, 1
  58. ld [PLAYER_JUMPING], a
  59. ld hl, PLAYER_VY
  60. STORE16 INIT_VY
  61. ; todo: deduplicate
  62. .jump_update_check:
  63. ld a, [PLAYER_JUMPING]
  64. or a
  65. jr z, .right
  66. .jump_update:
  67. ; load y velocity into bc
  68. ld hl, PLAYER_VY
  69. ld b, [hl]
  70. inc hl
  71. ld c, [hl]
  72. ; adjust velocity by gravity
  73. ld a, c
  74. sub LOW(GRAVITY)
  75. ld c, a
  76. ld a, b
  77. sbc HIGH(GRAVITY)
  78. ld b, a
  79. ld hl, PLAYER_VY
  80. STORE16 bc
  81. ; y -= floor(vy)
  82. ld hl, PLAYER_Y + 1
  83. ld a, [hl]
  84. sub c
  85. ld [hl-], a
  86. ld a, [hl]
  87. sbc b
  88. ld [hl], a
  89. ; roll back jump if there was a collision
  90. call player_bg_collides
  91. jr z, .jump_Player_UpdateOAM
  92. .jump_rollback:
  93. ld hl, PLAYER_VY
  94. bit 7, [hl]
  95. ld hl, PLAYER_Y
  96. jr z, .jump_rollback_down
  97. dec [hl]
  98. jr .jump_rollback_check
  99. .jump_rollback_down:
  100. inc [hl]
  101. .jump_rollback_check:
  102. call player_bg_collides
  103. jr nz, .jump_rollback
  104. ; set PLAYER_JUMPING = 0 if VY < 0 (fell into ground)
  105. ld hl, PLAYER_VY
  106. bit 7, [hl]
  107. ; either way, set VY = 0.
  108. ; NOTE: MUST USE LD HERE TO KEEP FLAGS FROM BIT TEST
  109. ld [hl], 0
  110. ld hl, PLAYER_VY + 1
  111. ld [hl], 0
  112. jr z, .jump_Player_UpdateOAM
  113. xor a
  114. ld [PLAYER_JUMPING], a
  115. .jump_Player_UpdateOAM:
  116. call Player_UpdateOAM
  117. ; check for move right
  118. .right:
  119. ld a, [keys]
  120. and PADF_RIGHT
  121. jr z, .left
  122. ; check for right boundary
  123. ld a, [PLAYER_X]
  124. add 16
  125. cp SCRN_X
  126. jr nc, .left
  127. .move_right:
  128. ld hl, PLAYER_X
  129. inc [hl]
  130. inc [hl]
  131. call player_bg_collides
  132. jr nz, .right_rollback
  133. xor a
  134. ld [PLAYER_DIR], a
  135. call Player_UpdateOAM
  136. ret
  137. .right_rollback:
  138. ld hl, PLAYER_X
  139. dec [hl]
  140. dec [hl]
  141. ret
  142. .left:
  143. ; check for left button
  144. ld hl, keys
  145. ld a, [hl]
  146. and PADF_LEFT
  147. jr z, .fall
  148. ; check for left boundary
  149. ld a, [PLAYER_X]
  150. or a
  151. jr z, .fall
  152. sub PLAYER_SPEED
  153. ld [PLAYER_X], a
  154. call player_bg_collides
  155. jr nz, .left_rollback
  156. ld a, $ff
  157. ld [PLAYER_DIR], a
  158. call Player_UpdateOAM
  159. jr .fall
  160. .left_rollback:
  161. ld hl, PLAYER_X
  162. inc [hl]
  163. inc [hl]
  164. .fall:
  165. call player_in_air
  166. ret nz
  167. ; only set jump state if not already jumping
  168. ld hl, PLAYER_JUMPING
  169. ld a, [hl]
  170. or a
  171. ret nz
  172. ld [hl], 1
  173. ld hl, PLAYER_VY
  174. STORE16 INIT_FALL_VY
  175. ret
  176. ; Update player metasprite with positional data
  177. Player_UpdateOAM::
  178. ld hl, PLAYER_DIR
  179. ld a, [hl-] ; dir (0 = right , $ff = left)
  180. and OAMF_XFLIP
  181. ld c, a
  182. dec hl ; skip fractional part
  183. ld a, [hl-] ; y
  184. add 16
  185. ld d, a
  186. ld a, [hl] ; x
  187. add 8
  188. ld b, a
  189. ld a, d
  190. ld_OAM_y hl, SPRITE_OAM_IDX
  191. ; top left sprite
  192. ld [hli], a
  193. ld [hl], b
  194. inc hl
  195. ld [hl], SPRITE_IDX
  196. inc hl
  197. ld [hl], c
  198. inc hl
  199. ; top right
  200. ld d, a
  201. ld a, b
  202. add 8
  203. ld b, a
  204. ld a, d
  205. ld [hli], a
  206. ld [hl], b
  207. inc hl
  208. ld [hl], SPRITE_IDX + 1
  209. inc hl
  210. ld [hl], c
  211. inc hl
  212. ; bottom left
  213. add 8
  214. ld d, a
  215. ld a, b
  216. sub 8
  217. ld b, a
  218. ld a, d
  219. ld [hli], a
  220. ld [hl], b
  221. inc hl
  222. ld [hl], SPRITE_IDX + 2
  223. inc hl
  224. ld [hl], c
  225. inc hl
  226. ; bottom right
  227. ld d, a
  228. ld a, b
  229. add 8
  230. ld b, a
  231. ld a, d
  232. ld [hli], a
  233. ld [hl], b
  234. inc hl
  235. ld [hl], SPRITE_IDX + 3
  236. inc hl
  237. ld [hl], c
  238. ; flip tile indices if necessary
  239. ld a, c
  240. or c
  241. jr z, .done
  242. ; TODO: Can be sped up by using LD A, [NN]
  243. ld_OAM_tile hl, SPRITE_OAM_IDX
  244. ld [hl], SPRITE_IDX + 1
  245. ld_OAM_tile hl, SPRITE_OAM_IDX + 1
  246. ld [hl], SPRITE_IDX
  247. ld_OAM_tile hl, SPRITE_OAM_IDX + 2
  248. ld [hl], SPRITE_IDX + 3
  249. ld_OAM_tile hl, SPRITE_OAM_IDX + 3
  250. ld [hl], SPRITE_IDX + 2
  251. .done:
  252. ret