diff --git a/src/main.s b/src/main.s index 6930237..9db92d4 100644 --- a/src/main.s +++ b/src/main.s @@ -153,21 +153,9 @@ start: .vbl: halt - ; BC = *PENDING_ROW_PTR - ld a, [PENDING_ROW_PTR] - ld c, a - ld a, [PENDING_ROW_PTR + 1] - ld b, a - - ; Write pending row if enqueued - or c - jr z, .dma_oam - ld hl, PENDING_ROW_DATA - ld d, SCRN_VX_B - MEMCPY bc, hl, d + call Map_Update ; ~160 cycles -.dma_oam: ld a, HIGH(_OAM) call DMA_Start diff --git a/src/map.s b/src/map.s index 64e5bf0..ca6431d 100644 --- a/src/map.s +++ b/src/map.s @@ -3,26 +3,26 @@ INCLUDE "util.inc" SECTION "Map Data", WRAM0 -PAGEX:: DB -PAGEY:: DB +PAGEX:: DB ; X coordinate to enqueue map column at +PAGEY:: DB ; Y coordinate to enqueue map row at -LAST_SCX:: DB -LAST_SCY:: DB +LAST_SCX:: DB ; Value of SCX last frame +LAST_SCY:: DB ; Value of SCY last frame -PENDING_ROW_PTR:: DW -PENDING_ROW_DATA:: DS SCRN_VX_B +PENDING_ROW_PTR:: DW ; Where to write pending row data (0 = no write) +PENDING_ROW_DATA:: DS SCRN_VX_B ; Row to be written CURRENT_DATA_START:: -CURRENT_TILE_PTR:: DW -CURRENT_TILE_SIZE:: DB -CURRENT_MAP_PTR:: DW -CURRENT_MAP_COLLISION:: DW -CURRENT_MAP_WIDTH:: DB -CURRENT_MAP_HEIGHT:: DB -CURRENT_SPAWN_X:: DB -CURRENT_SPAWN_Y:: DB -CURRENT_CAMERA_X:: DB -CURRENT_CAMERA_Y:: DB +CURRENT_TILE_PTR:: DW ; Location of tile data +CURRENT_TILE_SIZE:: DB ; Length of tile data (num_tiles * 8) +CURRENT_MAP_PTR:: DW ; Location of map data +CURRENT_MAP_COLLISION:: DW ; Location of map collision data +CURRENT_MAP_WIDTH:: DB ; Width of map in tiles +CURRENT_MAP_HEIGHT:: DB ; Height of map in tiles +CURRENT_SPAWN_X:: DB ; X coordinate to spawn player at +CURRENT_SPAWN_Y:: DB ; Y coordinate to spawn player at +CURRENT_CAMERA_X:: DB ; X coordinate of camera (top left of viewport) +CURRENT_CAMERA_Y:: DB ; Y coordinate of camera (top left of viewport) CURRENT_DATA_END:: SECTION "Map Code", ROM0 @@ -118,14 +118,14 @@ Map_Load:: ; Update map state based on SCX/SCY Map_Scroll:: ; If SCY = PAGEY, write map row - ; map coords = CURRENT_CAMERA_X, CURRENT_CAMERA_Y - 2 - ; HL = _SCRN0 + 32 * (32 - page_y/8 - 2) - ; TODO: WTF does this shit even do... ld hl, PAGEY ld a, [rSCY] cp [hl] jr nz, .scroll_down_check + ; map coords = CURRENT_CAMERA_X, CURRENT_CAMERA_Y - 2 + ; HL = _SCRN0 + 32 * (32 - page_y/8 - 2) + ; TODO: WTF does this shit even do... ld a, [rSCX] ld b, a ld a, [CURRENT_CAMERA_X] @@ -180,10 +180,28 @@ Map_Scroll:: jr .done .scroll_down_check: - ; If SCY = SCRN_Y - PAGEY, write map row - ; map coords = CURRENT_CAMERA_X, CURRENT_CAMERA_Y + 21 - ; HL = _SCRN0 + 32 * ((32 - page_y) - 1) - ; TODO: Check math on these + ; Check SCY + SCRN_Y = PAGEY + ld a, [PAGEY] + sub SCRN_Y + ld hl, rSCY + cp [hl] + jr nz, .done + + ld a, [CURRENT_CAMERA_X] + ld b, a + + ld a, [CURRENT_CAMERA_Y] + add SCRN_X_B + 1 + ld c, a + + call compute_vram_ptr + call enqueue_row_write + + ld a, [PAGEY] + add 8 + ld [PAGEY], a + + jr .done ; If SCX = PAGEX, write map col ; If SCX = SCRN_X - PAGEX, write map col @@ -195,10 +213,45 @@ Map_Scroll:: ret +Map_Update:: + ; Skip update if PENDING_ROW_PTR is 0 + ld a, [PENDING_ROW_PTR] + ld c, a + ld a, [PENDING_ROW_PTR + 1] + ld b, a + or c + ret z + + ld hl, PENDING_ROW_DATA + ld d, SCRN_VX_B + MEMCPY bc, hl, d + + ret + +; Computes the offset into map RAM +; @param e The map RAM y-coordinate +; @return hl Pointer into map RAM +compute_vram_ptr: + push bc + ld hl, _SCRN0 + ld b, 0 + ld c, SCRN_VX_B + ld a, e +.loop: + or a + jr z, .done + add hl, bc + dec a + jr .loop +.done: + pop bc + ret + ; Write a row of map data into row buffer ; @param b Map X coordinate (signed) ; @param c Map Y coordinate (signed) ; @param hl Where to write the row in map VRAM +; @destroy All registers enqueue_row_write: ; PENDING_ROW_PTR = HL ld a, l @@ -306,7 +359,8 @@ enqueue_row_write: ret ; TODO: Deduplicate with enqueue_row_write? This version is needed when -; loading a map, which happens synchronously while LCD is disabled +; loading a map, which happens synchronously while LCD is disabled. One trick to +; achieve this would be to call enqueue_row_write then Map_Update ; ; Write a row of map data into map RAM ; @param b Map X coordinate (signed)