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.

262 lines
4.2 KiB

  1. INCLUDE "hardware.inc"
  2. INCLUDE "util.inc"
  3. SECTION "Map Data", WRAM0
  4. PAGEX:: DB
  5. PAGEY:: DB
  6. CURRENT_DATA_START::
  7. CURRENT_TILE_PTR:: DW
  8. CURRENT_TILE_SIZE:: DB
  9. CURRENT_MAP_PTR:: DW
  10. CURRENT_MAP_COLLISION:: DW
  11. CURRENT_MAP_WIDTH:: DB
  12. CURRENT_MAP_HEIGHT:: DB
  13. CURRENT_SPAWN_X:: DB
  14. CURRENT_SPAWN_Y:: DB
  15. CURRENT_CAMERA_X:: DB
  16. CURRENT_CAMERA_Y:: DB
  17. CURRENT_DATA_END::
  18. SECTION "Map Code", ROM0
  19. DEF INIT_SCX EQUS "((SCRN_VX - SCRN_X) / 2)"
  20. DEF INIT_SCY EQUS "((SCRN_VY - SCRN_Y) / 2)"
  21. DEF PAGE_SIZE EQU 2
  22. DEF STACK_OFFSET_ROW EQU 3
  23. DEF STACK_OFFSET_MAP EQU 1
  24. DEF STACK_OFFSET_LEFT EQU 0
  25. ; TODO: Don't hardcode
  26. DEF CAMERAX EQU 0
  27. DEF CAMERAY EQU 14
  28. ; Increments a 16-bit value located on the stack
  29. ; \1 Stack offset
  30. MACRO INC_STACK16
  31. ld hl, sp + \1
  32. inc [hl]
  33. jr nz, .no_carry\@
  34. inc hl
  35. inc [hl]
  36. .no_carry\@:
  37. ENDM
  38. MACRO ZERO_ROW_TILE
  39. ld hl, sp + STACK_OFFSET_ROW
  40. ld a, [hl+]
  41. ld e, a
  42. ld d, [hl]
  43. xor a
  44. ld [de], a
  45. ENDM
  46. ; Loads a map
  47. ; @param hl Pointer to map metadata
  48. Map_Load::
  49. ; Initialize scroll state
  50. ld a, INIT_SCX
  51. ld [rSCX], a
  52. ld a, INIT_SCY
  53. ld [rSCY], a
  54. xor a
  55. ld [PAGEX], a
  56. ld [PAGEY], a
  57. ; Store metadata
  58. ld bc, CURRENT_DATA_START
  59. ld d, CURRENT_DATA_END - CURRENT_DATA_START
  60. call memcpy
  61. ; Write tiles to VRAM
  62. ld hl, CURRENT_TILE_PTR
  63. ld a, [hl+]
  64. ld c, a
  65. ld a, [hl+]
  66. ld b, a
  67. ld a, [CURRENT_TILE_SIZE]
  68. ld d, a
  69. ld hl, _VRAM
  70. MEMCPY hl, bc, d
  71. ; Write initial map data
  72. ld hl, _SCRN0
  73. ld a, [CURRENT_CAMERA_X]
  74. sub INIT_SCX / 8
  75. ld b, a
  76. ld a, [CURRENT_CAMERA_Y]
  77. sub INIT_SCY / 8
  78. ld c, a
  79. ld d, SCRN_VY_B
  80. .write_rows:
  81. call write_map_row
  82. inc c
  83. dec d
  84. jr nz, .write_rows
  85. ret
  86. ; Write a row of map data into map RAM
  87. ; @param b Map X coordinate (signed)
  88. ; @param c Map Y coordinate (signed)
  89. ; @param hl Start of the row to write
  90. write_map_row:
  91. push bc ; sp + 7
  92. push de ; sp + 5
  93. push hl ; sp + 3
  94. ; If Y < 0, write a row of 0s
  95. bit 7, c
  96. jr nz, .zero_row
  97. ; If Y >= MAP_HEIGHT, write a row of 0s
  98. ld a, [CURRENT_MAP_HEIGHT]
  99. dec a
  100. cp c
  101. jr nc, .begin_writing
  102. .zero_row:
  103. ld d, SCRN_VX_B
  104. xor a
  105. .zero_row_loop:
  106. ld a, [hl+]
  107. dec d
  108. jr nz, .zero_row_loop
  109. .zero_row_done:
  110. pop hl
  111. pop de
  112. pop bc
  113. ret
  114. .begin_writing:
  115. ; Allocate 2 bytes for map pointer
  116. ; Allocate 1 byte for number of tiles left
  117. add sp, -3
  118. ; left = number of tiles left to write
  119. ld hl, sp + STACK_OFFSET_LEFT
  120. ld [hl], SCRN_VX_B
  121. ; HL = CURRENT_MAP_PTR + Y * CURRENT_MAP_HEIGHT
  122. ld a, [CURRENT_MAP_PTR]
  123. ld l, a
  124. ld a, [CURRENT_MAP_PTR + 1]
  125. ld h, a
  126. .compute_map_row:
  127. ld a, c
  128. or a
  129. jr z, .compute_map_row_done
  130. ld a, [CURRENT_MAP_HEIGHT]
  131. ADD16 HL
  132. dec c
  133. jr .compute_map_row
  134. ; map = HL
  135. .compute_map_row_done:
  136. LD16 de, hl
  137. ld hl, sp + STACK_OFFSET_MAP
  138. ld a, e
  139. ld [hl+], a
  140. ld a, d
  141. ld [hl], a
  142. ld hl, sp + STACK_OFFSET_LEFT
  143. ; While X < 0 and left > 0, write 0 to the row
  144. .pad_left:
  145. bit 7, b
  146. jr z, .copy_center
  147. ld a, [hl]
  148. or a
  149. jr z, .done
  150. ; *row = 0
  151. ZERO_ROW_TILE
  152. ; row++
  153. INC_STACK16 STACK_OFFSET_ROW
  154. ; X++, left--
  155. inc b
  156. ld hl, sp + STACK_OFFSET_LEFT
  157. dec [hl]
  158. jr .pad_left
  159. ; While X < MAP_WIDTH and [SP] > 0, copy from map
  160. .copy_center:
  161. ld a, [CURRENT_MAP_WIDTH]
  162. dec a
  163. cp b
  164. jr z, .pad_right
  165. ld a, [hl]
  166. or a
  167. jr z, .done
  168. ; A = *map_ptr
  169. ld hl, sp + STACK_OFFSET_MAP
  170. ld a, [hl+]
  171. ld e, a
  172. ld d, [hl]
  173. ld a, [de]
  174. ; map_ptr++
  175. INC_STACK16 STACK_OFFSET_MAP
  176. ; *row = A
  177. ld hl, sp + STACK_OFFSET_ROW
  178. ld e, [hl]
  179. inc hl
  180. ld d, [hl]
  181. ld [de], a
  182. ; row++
  183. INC_STACK16 3
  184. ; X++, [SP]--
  185. .copy_center_inc:
  186. inc b
  187. ld hl, sp + STACK_OFFSET_LEFT
  188. dec [hl]
  189. jr .copy_center
  190. ; While [SP] > 0, write 0 to the row
  191. .pad_right:
  192. ld a, [hl]
  193. or a
  194. jr z, .done
  195. ; *row = 0
  196. ZERO_ROW_TILE
  197. ; row++
  198. INC_STACK16 STACK_OFFSET_ROW
  199. ; [SP]--
  200. .pad_right_inc:
  201. ld hl, sp + STACK_OFFSET_ROW
  202. dec [hl]
  203. jr .pad_right
  204. .done:
  205. add sp, 3
  206. pop hl
  207. pop de
  208. pop bc
  209. ret