Browse Source

Begin simplifying map API

master
Forest Belton 2 years ago
parent
commit
9a8394122f
3 changed files with 195 additions and 173 deletions
  1. +0
    -10
      inc/dir.inc
  2. +9
    -127
      src/main.s
  3. +186
    -36
      src/map.s

+ 0
- 10
inc/dir.inc View File

@ -1,10 +0,0 @@
DEF DIRF_UP EQU (1 << 0)
DEF DIRF_RIGHT EQU (1 << 1)
DEF DIRF_DOWN EQU (1 << 2)
DEF DIRF_LEFT EQU (1 << 3)
RSRESET
DEF DIRB_UP RB 1
DEF DIRB_RIGHT RB 1
DEF DIRB_DOWN RB 1
DEF DIRB_LEFT RB 1

+ 9
- 127
src/main.s View File

@ -1,4 +1,3 @@
INCLUDE "dir.inc"
INCLUDE "hardware.inc"
INCLUDE "util.inc"
@ -57,13 +56,6 @@ start:
call Keys_Update
; Clear pending map state
xor a
ld [PENDING_ROW_PTR], a
ld [PENDING_ROW_PTR + 1], a
ld [PENDING_COL_PTR], a
ld [PENDING_COL_PTR + 1], a
call scroll_update
; wait for vblank
@ -77,42 +69,15 @@ start:
jp .loop
; TODO: remove once scrolling is implemented
; TODO: Move into player movement routine
scroll_update:
; scroll map with arrow keys
ld a, [keys]
and PADF_UP
jr z, .down
; don't scroll up if on last tile
ld hl, rSCY
ld a, [hl]
and %111
jr nz, .update_up
ld hl, CURRENT_CAMERA_Y
ld a, [hl]
or a
ret z
.update_up:
ld hl, rSCY
dec [hl]
ld a, DIRB_UP
ld [SCROLL_DIR], a
ld a, [hl]
and %111
cp %111
jr nz, .update_up_map
ld a, [CURRENT_CAMERA_Y]
dec a
ld [CURRENT_CAMERA_Y], a
.update_up_map:
call Map_Scroll
ld d, 1
call Map_ScrollUp
ret
.down:
@ -120,35 +85,8 @@ scroll_update:
and PADF_DOWN
jr z, .right
; don't scroll down if on last tile
ld a, [rSCY]
and %111
jr nz, .update_down
ld a, [CURRENT_MAP_HEIGHT]
ld b, a
ld a, [CURRENT_CAMERA_Y]
add 18
cp b
ret z
.update_down:
ld hl, rSCY
inc [hl]
ld a, DIRB_DOWN
ld [SCROLL_DIR], a
ld a, [hl]
and %111
jr nz, .update_down_map
ld a, [CURRENT_CAMERA_Y]
inc a
ld [CURRENT_CAMERA_Y], a
.update_down_map:
call Map_Scroll
ld d, 1
call Map_ScrollDown
ret
.right:
@ -156,36 +94,8 @@ scroll_update:
and PADF_RIGHT
jr z, .left
; don't scroll right if on last tile
ld hl, rSCX
ld a, [hl]
and %111
jr nz, .update_right
ld a, [CURRENT_MAP_WIDTH]
ld b, a
ld a, [CURRENT_CAMERA_X]
add SCRN_X_B
cp b
ret z
.update_right:
ld hl, rSCX
inc [hl]
ld a, DIRB_RIGHT
ld [SCROLL_DIR], a
ld a, [hl]
and %111
jr nz, .update_right_map
ld a, [CURRENT_CAMERA_X]
inc a
ld [CURRENT_CAMERA_X], a
.update_right_map:
call Map_Scroll
ld d, 1
call Map_ScrollRight
ret
.left:
@ -193,33 +103,5 @@ scroll_update:
and PADF_LEFT
ret z
; don't scroll left if on last tile
ld hl, rSCX
ld a, [hl]
and %111
jr nz, .update_left
ld hl, CURRENT_CAMERA_X
ld a, [hl]
or a
ret z
.update_left:
ld hl, rSCX
dec [hl]
ld a, DIRB_LEFT
ld [SCROLL_DIR], a
ld a, [hl]
and %111
cp %111
jr nz, .update_left_map
ld a, [CURRENT_CAMERA_X]
dec a
ld [CURRENT_CAMERA_X], a
.update_left_map:
call Map_Scroll
ret
ld d, 1
call Map_ScrollLeft

+ 186
- 36
src/map.s View File

@ -1,4 +1,3 @@
INCLUDE "dir.inc"
INCLUDE "hardware.inc"
INCLUDE "util.inc"
@ -7,8 +6,6 @@ SECTION "Map Data", WRAM0
DEF ROW_BUFFER_SIZE EQUS "SCRN_X_B + 4"
DEF COL_BUFFER_SIZE EQUS "SCRN_Y_B + 4"
SCROLL_DIR:: DB
PENDING_ROW_PTR:: DW ; Where to write pending row data (0 = no write)
PENDING_ROW_DATA:: DS ROW_BUFFER_SIZE ; Row to be written
@ -33,6 +30,8 @@ SECTION "Map Code", ROM0
DEF INIT_SCX EQUS "((SCRN_VX - SCRN_X) / 2)"
DEF INIT_SCY EQUS "((SCRN_VY - SCRN_Y) / 2)"
; Loads a map
; @param hl Pointer to map metadata
Map_Load::
@ -85,27 +84,35 @@ Map_Load::
ret
; Update map state based on SCX/SCY
Map_Scroll::
; Check scroll up/down
ld a, [SCROLL_DIR]
and DIRF_UP | DIRF_DOWN
jr nz, .scroll_horiz
; Check SCY % 8 = 0
; Scroll the map upwards
; @param d The amount to scroll by (0 < d < 8)
Map_ScrollUp::
; Check whether we crossed tile boundary
ld a, [rSCY]
and %111
ret nz
cp d
jr nc, .done
; Don't scroll if at top tile
ld a, [CURRENT_CAMERA_Y]
or a
ret z
ld a, [rSCY]
sub d
ld [rSCY], a
; CAMERA_Y -= 1
dec a
ld [CURRENT_CAMERA_Y], a
; B = CAMERA_X - 2
ld a, [CURRENT_CAMERA_X]
sub 2
ld b, a
ld a, [SCROLL_DIR]
cp DIRB_UP
jr nz, .scroll_down
; C = CAMERA_Y - 2
ld a, [CURRENT_CAMERA_Y]
sub 2
@ -116,9 +123,65 @@ Map_Scroll::
srln a, 3
sub 2
jr .write_row
jr Map_ScrollRow
.done:
ld a, [rSCY]
sub d
ld [rSCY], a
ret
Map_ScrollDown::
; Don't scroll if at bottom tile
ld a, [CURRENT_CAMERA_Y]
add SCRN_Y_B
ld hl, CURRENT_MAP_HEIGHT
cp [hl]
jr nz, .down
ld a, [rSCY]
add d
and %111
ld [rSCY], a
ret
; Check whether we crossed tile boundary
.down:
ld a, [rSCY]
and %111
add d
cp 8
jr c, .done
; TODO:
; if CAMERA_Y + 18 = MAP_HEIGHT {
; if SCY % 8 != 0 {
; SCY += MIN(D, 8 - SCY % 8)
; }
; return
; }
; if SCY % 8 + D > 8 {
; SCY += D
; LOAD_COLUMN(CAMERA_X - 2, CAMERA_Y + 18 + 1);
; } else {
; SCY += D
; }
ld a, [rSCY]
add d
ld [rSCY], a
; CAMERA_Y += 1
inc a
ld [CURRENT_CAMERA_Y], a
; B = CAMERA_X - 2
ld a, [CURRENT_CAMERA_X]
sub 2
ld b, a
.scroll_down:
; C = CAMERA_Y + 18 + 1
ld a, [CURRENT_CAMERA_Y]
add SCRN_Y_B + 1
@ -129,7 +192,21 @@ Map_Scroll::
srln a, 3
add SCRN_Y_B + 1
.write_row:
jr Map_ScrollRow
.done:
ld a, [rSCY]
add d
ld [rSCY], a
ret
; Scroll in a new row
; @param a Map VRAM Y-coordinate
; @param b Data X-coordinate
; @param c Data Y-coordinate
Map_ScrollRow:
and %11111
call get_row_ptr
@ -145,16 +222,21 @@ Map_Scroll::
call enqueue_row_write
ret
.scroll_horiz:
; Check SCX % 8 = 0
Map_ScrollLeft::
; Check whether we crossed tile boundary
ld a, [rSCX]
and %111
ret nz
cp d
jr nc, .done
; C = CAMERA_Y - 2
ld a, [CURRENT_CAMERA_Y]
sub 2
ld c, a
ld a, [rSCX]
sub d
ld [rSCX], a
; Don't scroll if at left tile
ld a, [CURRENT_CAMERA_X]
or a
ret z
ld a, [rSCY]
sub 16
@ -163,42 +245,91 @@ Map_Scroll::
srl a
call get_row_ptr
ld a, [SCROLL_DIR]
cp DIRB_LEFT
jr nz, .scroll_right
; B = CAMERA_X - 2
ld a, [CURRENT_CAMERA_X]
sub 2
ld b, a
; HL = VRAM + (SCX/8 - 2)
; E = VRAM + (SCX/8 - 2)
ld a, [rSCX]
srln a, 3
sub 2
jr .write_col
jr Map_ScrollColumn
.done:
ld a, [rSCX]
sub d
ld [rSCX], a
ret
Map_ScrollRight::
; Check whether we crossed tile boundary
ld a, [rSCX]
and %111
add d
cp 8
jr nc, .done
ld a, [rSCX]
add d
ld [rSCX], a
; Don't scroll if at bottom tile
ld a, [CURRENT_CAMERA_X]
inc a
ld hl, CURRENT_MAP_WIDTH
cp [hl]
ret z
; CAMERA_X += 1
inc a
ld [CURRENT_CAMERA_X], a
ld a, [rSCY]
sub 16
srl a
srl a
srl a
call get_row_ptr
.scroll_right:
; B = CAMERA_X + 20 + 1
ld a, [CURRENT_CAMERA_X]
add SCRN_X_B + 1
ld b, a
; HL = VRAM + SCX/8 + SCRN_X_B + 1
; E = VRAM + SCX/8 + SCRN_X_B + 1
ld a, [rSCX]
srl a
srl a
srl a
add SCRN_X_B + 1
ld e, a
.write_col:
and %11111
ADD16 hl
jr Map_ScrollColumn
.done:
ld a, [rSCX]
add d
ld [rSCX], a
ret
Map_ScrollColumn:
; C = CAMERA_Y - 2
ld a, [CURRENT_CAMERA_Y]
sub 2
ld c, a
call enqueue_col_write
ret
Map_Update::
; Skip row update if PENDING_ROW_PTR is 0
ld a, [PENDING_ROW_PTR]
@ -232,6 +363,11 @@ Map_Update::
dec d
jr nz, .copy_row
; Reset PENDING_ROW_PTR
xor a
ld [PENDING_ROW_PTR], a
ld [PENDING_ROW_PTR + 1], a
.update_col:
; Skip column update if PENDING_COL_PTR is 0
ld a, [PENDING_COL_PTR]
@ -259,8 +395,15 @@ Map_Update::
dec d
jr nz, .update_col_loop
; Reset PENDING_COL_PTR
xor a
ld [PENDING_COL_PTR], a
ld [PENDING_COL_PTR + 1], a
ret
; Computes the offset into map RAM
; @param a The map RAM y-coordinate
; @return hl Pointer into map RAM
@ -276,6 +419,8 @@ get_row_ptr:
pop de
ret
; Write a row of map data into row buffer
; @param b Map X coordinate (signed)
; @param c Map Y coordinate (signed)
@ -398,6 +543,8 @@ enqueue_row_write:
jr nz, .zero_row_loop
ret
; NOTE: This works by enqueueing a row to write, and then immediately flushing
; the queue. The subroutine could be sped up by writing to map RAM directly, but
; this is simpler to write and saves on code size.
@ -419,6 +566,8 @@ write_map_row:
ret
; Write a column of map data into column buffer
; @param b Map X coordinate (signed)
; @param c Map Y coordinate (signed)
@ -545,6 +694,7 @@ enqueue_col_write:
ret
; Basically enqueue_col_write but for entire row, used during map load
; TODO: Deduplicate
; @param b Map X coordinate (signed)

Loading…
Cancel
Save