From 12604b6d65cce7c1c994ce9dc18a4ad94691737c Mon Sep 17 00:00:00 2001 From: Forest Belton <65484+forestbelton@users.noreply.github.com> Date: Mon, 12 Jul 2021 03:11:47 -0400 Subject: [PATCH] Implement scrolling right --- src/main.s | 3 +- src/map.s | 244 +++++++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 210 insertions(+), 37 deletions(-) diff --git a/src/main.s b/src/main.s index 198ec9b..20605c3 100644 --- a/src/main.s +++ b/src/main.s @@ -158,8 +158,7 @@ scroll_update: ld a, [CURRENT_MAP_WIDTH] ld b, a ld a, [CURRENT_CAMERA_X] - inc a - ; add 18 + add SCRN_X_B cp b ret z diff --git a/src/map.s b/src/map.s index 8a675e3..3209d7d 100644 --- a/src/map.s +++ b/src/map.s @@ -101,52 +101,35 @@ Map_Scroll:: ; B = CAMERA_X - SCX/8 ld a, [rSCX] + srl a + srl a + srl a ld b, a ld a, [CURRENT_CAMERA_X] - srl b - srl b - srl b sub b ld b, a - ; TODO: WTF does this shit even do... + ; C = CAMERA_Y - 2 ld a, [CURRENT_CAMERA_Y] - cp 2 - jr c, .done - sub 2 ld c, a - ; a = scy/8 + (scy/8 < 2 ? 30 : -2) - + ; HL = _SCRN0 + 32 * (SCY/8 - 2) +.find_vram_ptr: ld a, [rSCY] + sub 16 srl a srl a srl a - - cp 2 - jr nc, .loop0 - add 32 - -.loop0: - sub 2 - - ; HL = _SCRN0 + 32 * (32 - page_y/8 - 2) - ; HL = _SCRN0 + 32 * A - ld e, a + ld d, a + ld e, 32 ld hl, _SCRN0 -.loop: - ld a, e - or a - jr z, .write_up - - ld a, 32 +.0: + ld a, d ADD16 hl - dec e - jr .loop + jr nz, .0 -.write_up: call enqueue_row_write ld a, [PAGEY] @@ -161,7 +144,7 @@ Map_Scroll:: sub SCRN_Y + 16 ld hl, rSCY cp [hl] - jr nz, .done + jr nz, .scroll_right_check ld a, [PAGEY] srl a @@ -182,8 +165,6 @@ Map_Scroll:: ld b, a ; C = CAMERA_Y + 18 + 1 - ; TODO: Figure out if a similar method to this one is sufficient for - ; whatever the fuck the scroll up check is doing ld a, [CURRENT_CAMERA_Y] add SCRN_Y_B + 1 ld c, a @@ -197,7 +178,47 @@ Map_Scroll:: jr .done ; If SCX = PAGEX, write map col +.scroll_left_check: + ; If SCX = SCRN_X - PAGEX, write map col +.scroll_right_check: + ; Check SCX + (SCRN_X + 16) = PAGEX + ld a, [PAGEX] + sub SCRN_X + 16 + ld hl, rSCX + cp [hl] + jr nz, .done + + ; HL = VRAM + PAGEX/8 + ld hl, _SCRN0 + ld a, [PAGEX] + srl a + srl a + srl a + dec a + ADD16 hl + + ; B = CAMERA_X + 20 + ld a, [CURRENT_CAMERA_X] + add SCRN_X_B + 1 + ld b, a + + ; C = CAMERA_Y - SCY/8 + ld a, [rSCY] + ld c, a + ld a, [CURRENT_CAMERA_Y] + srl c + srl c + srl c + sub c + ; dec a + ld c, a + + call enqueue_col_write + + ld a, [PAGEX] + add 8 + ld [PAGEX], a .done: ld hl, LAST_SCY @@ -220,7 +241,7 @@ Map_Update:: MEMCPY bc, hl, d .update_col: - ; Skip update if PENDING_COL_PTR is 0 + ; Skip column update if PENDING_COL_PTR is 0 ld a, [PENDING_COL_PTR] ld c, a ld a, [PENDING_COL_PTR + 1] @@ -228,7 +249,7 @@ Map_Update:: or c ret z - ld d, SCRN_VX_B + ld d, SCRN_VY_B ld hl, PENDING_COL_DATA .update_col_loop: ld a, [hl+] @@ -360,7 +381,7 @@ enqueue_row_write: ; X++, BYTES_LEFT-- inc b dec c - jr .pad_left + jr .pad_right .zero_row: ld hl, PENDING_ROW_DATA @@ -401,3 +422,156 @@ write_map_row: pop bc ret + +; Write a column of map data into column buffer +; @param b Map X coordinate (signed) +; @param c Map Y coordinate (signed) +; @param hl Where to write the column in map VRAM +; @destroy All registers +enqueue_col_write: + ; PENDING_COL_PTR = HL + ld a, l + ld [PENDING_COL_PTR], a + ld a, h + ld [PENDING_COL_PTR + 1], a + + ; If X < 0, write 0s + bit 7, b + jr nz, .zero_row + + ; If X >= MAP_WIDTH, write 0s + ld a, [CURRENT_MAP_WIDTH] + dec a + cp c + jr c, .zero_row + + ; HL = CURRENT_MAP_PTR + ld a, [CURRENT_MAP_PTR] + ld l, a + ld a, [CURRENT_MAP_PTR + 1] + ld h, a + + ; HL = CURRENT_MAP_PTR + Y * MAP_WIDTH + X + ld d, 0 + ld a, [CURRENT_MAP_WIDTH] + ld e, a + ld a, c + +.get_map_col_ptr: + or a + jr z, .copy_map_column + add hl, de + dec a + jr .get_map_col_ptr + +.copy_map_column: + ld a, b + ADD16 hl + + ; B = BYTES_LEFT + ld b, SCRN_VY_B + ld de, PENDING_COL_DATA + + ; Note: Can skip checking BYTES_LEFT > 0 in this loop. If there were + ; SCRN_VY_B zeros to write, then X would be 1 greater and we would have + ; jumped into .zero_row before reaching this code +.pad_left: + ; Check Y < 0 + bit 7, c + jr z, .copy_middle + + ; *ROW++ = 0 + xor a + ld [de], a + inc de + + ; Y++, BYTES_LEFT-- + inc c + dec b + jr .pad_left + +.copy_middle: + ; Check Y < MAP_HEIGHT + ld a, [CURRENT_MAP_HEIGHT] + dec a + cp c + jr c, .pad_right + + ; Check BYTES_LEFT > 0 + ld a, b + or a + ret z + + ; *ROW++ = *MAP + ld a, [hl] + ld [de], a + inc de + + ; MAP += MAP_WIDTH + ld a, [CURRENT_MAP_WIDTH] + ADD16 hl + + ; Y++, BYTES_LEFT-- + inc c + dec b + jr .copy_middle + +.pad_right: + ; Check BYTES_LEFT > 0 + ld a, b + or a + ret z + + ; *ROW++ = 0 + xor a + ld [de], a + inc de + + ; X++, BYTES_LEFT-- + inc c + dec b + jr .pad_right + +.zero_row: + ld hl, PENDING_COL_DATA + xor a + ld c, SCRN_VY_B +.zero_row_loop: + ld [hl+], a + dec c + jr nz, .zero_row_loop + ret + +; Compute the distance (modulo 32) between two values +; @param b Value 1 +; @param c Value 2 +mmd2: + push bc + + ld a, b + sub c + + cpl + ld b, a + cpl + + bit 7, b + jr z, .0 + + ld b, a + +.0: + ld a, 32 + sub b + + cp b + jr nc, .1 + + pop bc + ret + +.1: + ld a, b + + pop bc + ret