|
|
@ -30,35 +30,6 @@ SECTION "Map Code", ROM0 |
|
|
|
DEF INIT_SCX EQUS "((SCRN_VX - SCRN_X) / 2)" |
|
|
|
DEF INIT_SCY EQUS "((SCRN_VY - SCRN_Y) / 2)" |
|
|
|
|
|
|
|
DEF STACK_OFFSET_ROW EQU 3 |
|
|
|
DEF STACK_OFFSET_MAP EQU 1 |
|
|
|
DEF STACK_OFFSET_LEFT EQU 0 |
|
|
|
|
|
|
|
; Increments a 16-bit value located on the stack |
|
|
|
; \1 Stack offset |
|
|
|
; if carry, 14 * 4 = 56 cycles |
|
|
|
; otherwise, 8 * 4 = 32 cycles |
|
|
|
MACRO INC_STACK16 |
|
|
|
ld hl, sp + \1 ; 3 |
|
|
|
inc [hl] ; 3 |
|
|
|
jr nz, .no_carry\@ ; 3/2 |
|
|
|
|
|
|
|
inc hl ; 2 |
|
|
|
inc [hl] ; 3 |
|
|
|
|
|
|
|
.no_carry\@: |
|
|
|
ENDM |
|
|
|
|
|
|
|
; 11 * 4 = 44 cycles |
|
|
|
MACRO ZERO_ROW_TILE |
|
|
|
ld hl, sp + STACK_OFFSET_ROW ; 3 |
|
|
|
ld a, [hl+] ; 2 |
|
|
|
ld e, a ; 1 |
|
|
|
ld d, [hl] ; 2 |
|
|
|
xor a ; 1 |
|
|
|
ld [de], a ; 2 |
|
|
|
ENDM |
|
|
|
|
|
|
|
; Loads a map |
|
|
|
; @param hl Pointer to map metadata |
|
|
|
Map_Load:: |
|
|
@ -108,6 +79,10 @@ Map_Load:: |
|
|
|
.write_rows: |
|
|
|
call write_map_row |
|
|
|
inc c |
|
|
|
|
|
|
|
ld a, SCRN_VX_B |
|
|
|
ADD16 hl |
|
|
|
|
|
|
|
dec d |
|
|
|
jr nz, .write_rows |
|
|
|
|
|
|
@ -369,157 +344,30 @@ enqueue_row_write: |
|
|
|
jr nz, .zero_row_loop |
|
|
|
ret |
|
|
|
|
|
|
|
; TODO: Deduplicate with enqueue_row_write? This version is needed when |
|
|
|
; 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 |
|
|
|
; 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. |
|
|
|
; |
|
|
|
; Write a row of map data into map RAM |
|
|
|
; Write a row of map data into map RAM. |
|
|
|
; @param b Map X coordinate (signed) |
|
|
|
; @param c Map Y coordinate (signed) |
|
|
|
; @param hl Pointer into map VRAM |
|
|
|
write_map_row: |
|
|
|
push bc |
|
|
|
push de |
|
|
|
|
|
|
|
; If Y < 0, write a row of 0s |
|
|
|
bit 7, c |
|
|
|
jr nz, .zero_row |
|
|
|
|
|
|
|
; If Y >= MAP_HEIGHT, write a row of 0s |
|
|
|
ld a, [CURRENT_MAP_HEIGHT] |
|
|
|
dec a |
|
|
|
cp c |
|
|
|
jr nc, .begin_writing |
|
|
|
|
|
|
|
.zero_row: |
|
|
|
ld d, SCRN_VX_B |
|
|
|
xor a |
|
|
|
.zero_row_loop: |
|
|
|
ld [hl+], a |
|
|
|
dec d |
|
|
|
jr nz, .zero_row_loop |
|
|
|
.zero_row_done: |
|
|
|
pop de |
|
|
|
pop bc |
|
|
|
ret |
|
|
|
|
|
|
|
.begin_writing: |
|
|
|
push hl |
|
|
|
|
|
|
|
; Allocate 2 bytes for map pointer |
|
|
|
; Allocate 1 byte for number of tiles left |
|
|
|
add sp, -3 |
|
|
|
|
|
|
|
; left = number of tiles left to write |
|
|
|
ld hl, sp + STACK_OFFSET_LEFT |
|
|
|
ld [hl], SCRN_VX_B |
|
|
|
|
|
|
|
; HL = CURRENT_MAP_PTR + Y * CURRENT_MAP_WIDTH |
|
|
|
ld a, [CURRENT_MAP_PTR] |
|
|
|
ld l, a |
|
|
|
ld a, [CURRENT_MAP_PTR + 1] |
|
|
|
ld h, a |
|
|
|
|
|
|
|
.compute_map_row: |
|
|
|
ld a, c |
|
|
|
or a |
|
|
|
jr z, .compute_map_row_done |
|
|
|
|
|
|
|
ld a, [CURRENT_MAP_WIDTH] |
|
|
|
ADD16 HL |
|
|
|
dec c |
|
|
|
jr .compute_map_row |
|
|
|
|
|
|
|
; map = HL |
|
|
|
.compute_map_row_done: |
|
|
|
LD16 de, hl |
|
|
|
ld hl, sp + STACK_OFFSET_MAP |
|
|
|
ld a, e |
|
|
|
ld [hl+], a |
|
|
|
ld a, d |
|
|
|
ld [hl], a |
|
|
|
|
|
|
|
ld hl, sp + STACK_OFFSET_LEFT |
|
|
|
|
|
|
|
; While X < 0 and left > 0, write 0 to the row |
|
|
|
.pad_left: |
|
|
|
bit 7, b |
|
|
|
jr z, .copy_center |
|
|
|
|
|
|
|
ld a, [hl] |
|
|
|
or a |
|
|
|
jr z, .done |
|
|
|
|
|
|
|
; *row = 0 |
|
|
|
ZERO_ROW_TILE |
|
|
|
|
|
|
|
; row++ |
|
|
|
INC_STACK16 STACK_OFFSET_ROW |
|
|
|
|
|
|
|
; X++, left-- |
|
|
|
inc b |
|
|
|
ld hl, sp + STACK_OFFSET_LEFT |
|
|
|
dec [hl] |
|
|
|
jr .pad_left |
|
|
|
|
|
|
|
; While X < MAP_WIDTH and [SP] > 0, copy from map |
|
|
|
.copy_center: |
|
|
|
ld a, [CURRENT_MAP_WIDTH] |
|
|
|
dec a |
|
|
|
cp b |
|
|
|
jr z, .pad_right |
|
|
|
|
|
|
|
ld a, [hl] |
|
|
|
or a |
|
|
|
jr z, .done |
|
|
|
|
|
|
|
; A = *map_ptr |
|
|
|
ld hl, sp + STACK_OFFSET_MAP |
|
|
|
ld a, [hl+] |
|
|
|
ld e, a |
|
|
|
ld d, [hl] |
|
|
|
ld a, [de] |
|
|
|
|
|
|
|
; map_ptr++ |
|
|
|
INC_STACK16 STACK_OFFSET_MAP |
|
|
|
|
|
|
|
; *row = A |
|
|
|
ld hl, sp + STACK_OFFSET_ROW |
|
|
|
ld e, [hl] |
|
|
|
inc hl |
|
|
|
ld d, [hl] |
|
|
|
ld [de], a |
|
|
|
|
|
|
|
; row++ |
|
|
|
INC_STACK16 3 |
|
|
|
|
|
|
|
; X++, [SP]-- |
|
|
|
.copy_center_inc: |
|
|
|
inc b |
|
|
|
ld hl, sp + STACK_OFFSET_LEFT |
|
|
|
dec [hl] |
|
|
|
jr .copy_center |
|
|
|
|
|
|
|
; While [SP] > 0, write 0 to the row |
|
|
|
.pad_right: |
|
|
|
ld a, [hl] |
|
|
|
or a |
|
|
|
jr z, .done |
|
|
|
|
|
|
|
; *row = 0 |
|
|
|
ZERO_ROW_TILE |
|
|
|
call enqueue_row_write |
|
|
|
|
|
|
|
; row++ |
|
|
|
INC_STACK16 STACK_OFFSET_ROW |
|
|
|
ld a, [PENDING_ROW_PTR] |
|
|
|
ld c, a |
|
|
|
ld a, [PENDING_ROW_PTR + 1] |
|
|
|
ld b, a |
|
|
|
|
|
|
|
; [SP]-- |
|
|
|
.pad_right_inc: |
|
|
|
ld hl, sp + STACK_OFFSET_ROW |
|
|
|
dec [hl] |
|
|
|
jr .pad_right |
|
|
|
ld hl, PENDING_ROW_DATA |
|
|
|
ld d, SCRN_VX_B |
|
|
|
MEMCPY bc, hl, d |
|
|
|
|
|
|
|
.done: |
|
|
|
add sp, 3 |
|
|
|
pop hl |
|
|
|
pop de |
|
|
|
pop bc |
|
|
|