Granular scroll nametable updating, buffering and pointers, etc.

This commit is contained in:
RochesterX
2026-05-15 11:23:10 -04:00
parent ea31c0836b
commit 551aa135ec
2 changed files with 101 additions and 25 deletions

BIN
plat.nes

Binary file not shown.

126
plat.s
View File

@@ -408,6 +408,8 @@ var_m: .res 1
var_n: .res 1
var_o: .res 1
var_p: .res 1
var_wide1:.res 2
var_wide2:.res 2
jump_pressed_last_frame: .res 1
@@ -415,15 +417,15 @@ frame_counter: .res 1
last_frame_jumped: .res 1
last_frame_moving: .res 1
column_pattern: .res 1
tile_update_pos_r: .res 1
tile_update_pos_l: .res 1
column_pattern_pointer: .res 2
tile_update_pos: .res 1
pointer: .res 2
.segment "BSS"
level: .res 240
level2: .res 240
room_buffer: .res 240
.segment "CODE"
main:
@@ -448,6 +450,8 @@ main:
jsr init_objects
jsr update_room_buffer
@loop:
lda $2002
lda frame_counter
@@ -695,7 +699,7 @@ init_objects:
lda #0
sta camera_speed
sta tile_update_pos_r
sta tile_update_pos
rts
@@ -1474,30 +1478,58 @@ check_column_update:
lsr
lsr
cmp tile_update_pos_r
; Thought: Level layout will be decoded from somewhere into the room_buffer_r or _l buffers, then they will be indexed into by this to load their column patterns
cmp tile_update_pos
bne :+
; Load column pattern
lda tile_update_pos_r
sta column_pattern
jsr load_column_pattern
; Apply pattern
jsr update_nmt_column
; Increment tile_update_pos_r
lda tile_update_pos_r
; Increment tile_update_pos
lda tile_update_pos
clc
adc #1
and #%00011111
sta tile_update_pos_r
sta tile_update_pos
:
rts
load_column_pattern:
; Based on tile update pos r, use that row to index in to the room buffer. Columns in the room buffer are stored as rows for sequential access.
;
; IDEA: Do we only need one tile update position? If for example we're going right and updating there, we don't need to do anything going left until that point is reached again on the left side. But it's the same point. It's the "seam" in the level. Maybe just an offset by one or something.
lda #<room_buffer
sta column_pattern_pointer
lda #>room_buffer
sta column_pattern_pointer+1
; Since column pattern pointer points to the current column we need to draw, we start it at the beginning of the room buffer (which stores columns as rows), then we add 16 (going to the next "row" in memory which is the next column in reality) how many ever times in column_pattern_pointer to point to the correct row. From there, anything can just loop 16 times from that pointer to get the currently drawing row.
lda tile_update_pos
and #%00001111
tax
:
lda column_pattern_pointer
clc
adc #16
sta column_pattern_pointer
lda column_pattern_pointer+1
adc #0
sta column_pattern_pointer+1
dex
cpx #0
bne :-
rts
update_nmt_column:
; X represents the row of the current tile being updated
ldx #0
@row_loop:
lda tile_update_pos_r
lda tile_update_pos
clc
; Add offset in tiles from left edge of screen
adc #16
@@ -1543,22 +1575,56 @@ update_nmt_column:
; Specifies what tile gets written to the column
lda column_pattern
rol
stx var_m
:
ror
dec var_m
dec var_m
bpl :-
;
; T------>
;lda column_pattern
;ror
;sta var_wide1
; >-----BX
;lda column_pattern+1
;ror
;sta var_wide1+1
and #%00000001
cmp #0
beq :+
ora #%10000000
:
;stx var_m
;:
;lda var_wide1+1
;rol
;sta var_wide1+1
;lda var_wide1
;rol
;sta var_wide1
;dec var_m
;bpl :-
;lda var_wide1
;and #%10000000
;cmp #0
;beq :+
; What metatile do we load for a non-empty shape?
;lda #%10000001
;:
; Preserve Y (our index in to level)
tya
pha
; Transfer X to Y (our current row in the updated column)
txa
tay
; Instead of all that nonsense constructing the tile that we want to draw, just index in to the column_pattern_pointer
; Storing in var wide 1 because I know it's not used
lda (column_pattern_pointer), Y
sta var_wide1
; Restore Y
pla
tay
; Write our new metatile to level (for collision mostly)
lda var_wide1
sta (pointer), Y
; ...and actually perform a nametable update
and #%01111111
ldy #5
jsr mul_y
@@ -1619,6 +1685,16 @@ update_nmt_column:
rts
update_room_buffer:
ldx #0
:
lda default_level2, X
sta room_buffer, X
inx
cpx #240
bne :-
rts
mul_x:
cmp #0
beq @zero