Subpixels

This commit is contained in:
RochesterX
2026-02-18 15:04:42 -05:00
parent 0100b05291
commit 7a8fb73f84
2 changed files with 215 additions and 229 deletions

BIN
plat.nes

Binary file not shown.

444
plat.s
View File

@@ -218,72 +218,6 @@ ppu_off:
rts rts
ppu_address_tile:
lda $2002
tya
lsr
lsr
lsr
ora #$20
sta $2006
tya
asl
asl
asl
asl
asl
sta temp
txa
ora temp
sta $2006
rts
ppu_update_tile:
pha
txa
pha
ldx nmt_update_len
tya
lsr
lsr
lsr
ora #$20
sta nmt_update, X
inx
tya
asl
asl
asl
asl
asl
sta temp
pla
ora temp
sta nmt_update, X
inx
pla
sta nmt_update, X
inx
stx nmt_update_len
rts
ppu_update_byte:
pha
tya
pha
ldy nmt_update_len
txa
sta nmt_update, Y
iny
pla
sta nmt_update, Y
iny
pla
sta nmt_update, Y
iny
sty nmt_update_len
rts
PAD_A = $01 PAD_A = $01
PAD_B = $02 PAD_B = $02
@@ -336,37 +270,32 @@ level:
.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 .byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 .byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
.byte 0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0 .byte 0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0
.byte 0,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0
.byte 0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0
.byte 0,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0
.byte 0,0,1,0,0,0,0,1,0,0,0,1,0,1,0,0
.byte 0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0
.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 .byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
block_x: .res 1 .byte 0,0,0,0,0,0,0,0,0,0,0,10,10,10,10,10
block_y: .res 1 .byte 0,0,1,0,0,0,0,1,0,0,0,11,11,11,11,11
block_w: .res 1 .byte 0,1,2,3,4,5,6,7,8,9,0,11,11,11,11,11
block_h: .res 1 .byte 0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11
metatiles: metatiles:
.byte 0,0,0,0,0 .byte 0,0,0,0,0
.byte $14,$15,$16,$17,1 ; Full block .byte $14,$15,$16,$17,1 ; Full block
.byte $14,$18,$1B,$0,1 ; up / left .byte $14,$18,$1B,$00,0 ; up / left
.byte $18,$15,$0,$19,1 ; up / right .byte $18,$15,$00,$19,0 ; up / right
.byte $1B,$0,$16,$1A,1 ; down / left .byte $1B,$00,$16,$1A,0 ; down / left
.byte $0,$19,$1A,$17,1 ; down / right .byte $00,$19,$1A,$17,0 ; down / right
.byte $1B,$0,$1B,$0,1 ; left .byte $1B,$00,$1B,$00,0 ; left
.byte $18,$18,$0,$0,1 ; up .byte $18,$18,$00,$00,0 ; up
.byte $0,$0,$1A,$1A,1 ; down .byte $00,$00,$1A,$1A,0 ; down
.byte $0,$19,$0,$19,1 ; right .byte $00,$19,$00,$19,0 ; right
.byte 3,3,3,3,0 .byte $10,$11,$12,$13,2
.byte 3,4,5,6,0 .byte $12,$12,$12,$12,2
example_palette: example_palette:
.byte $0F,$00,$3D,$20 ; greyscale .byte $0F,$00,$3D,$20 ; greyscale
.byte $0F,$3D,$30,$00 ; whitescale
.byte $0F,$09,$1A,$16 ; grass .byte $0F,$09,$1A,$16 ; grass
.byte $0F,$15,$26,$37 ; bg0 purple/pink .byte $0F,$15,$26,$37 ; bg0 purple/pink
.byte $0F,$09,$19,$29 ; bg1 green
.byte $0F,$2D,$10,$3D ; reboot bottom .byte $0F,$2D,$10,$3D ; reboot bottom
.byte $0F,$2D,$10,$2C ; reboot eye .byte $0F,$2D,$10,$2C ; reboot eye
.byte $0F,$01,$11,$21 ; bg2 blue .byte $0F,$01,$11,$21 ; bg2 blue
@@ -381,11 +310,14 @@ buttons: .res 1
player_pos_x: .res 1 player_pos_x: .res 1
player_pos_y: .res 1 player_pos_y: .res 1
player_vel_x: .res 1 player_subpos_x: .res 1 ; XXXXYYYY | first 4 bits X subposition, last 4 bits Y
player_vel_y: .res 1 player_subpos_y: .res 1 ; XXXXYYYY | first 4 bits X subposition, last 4 bits Y
player_vel_x: .res 1 ; +PPPSSSS | first bit sign, next 3 pixels, last subpixels
player_vel_y: .res 1 ; in subpixels
player_status: .res 1 ; 76543210 | 0: facing (0 right, 1 left) player_status: .res 1 ; 76543210 | 0: facing (0 right, 1 left)
; | 7: talking ; | 7: talking
horizontal_speed: .res 1
cursor_x: .res 1 cursor_x: .res 1
cursor_y: .res 1 cursor_y: .res 1
@@ -424,17 +356,19 @@ main:
sta last_frame_jumped sta last_frame_jumped
jsr init_objects jsr init_objects
@loop: @loop:
lda $2002
lda frame_counter lda frame_counter
clc clc
adc #1 adc #1
sta frame_counter sta frame_counter
jsr controller jsr controller
jsr movement jsr movement
@draw: @draw:
jsr update_background
jsr draw_player jsr draw_player
jsr ppu_update jsr ppu_update
@@ -543,13 +477,8 @@ init_objects:
sta player_vel_y sta player_vel_y
sta player_status sta player_status
lda #64 lda #32
sta block_x sta horizontal_speed
sta block_y
lda #16
sta block_w
sta block_h
rts rts
@@ -579,7 +508,7 @@ movement:
cmp #0 cmp #0
beq :+ beq :+
ldx #1 ldx #1
lda #2 lda horizontal_speed
sta player_vel_x sta player_vel_x
lda player_status lda player_status
@@ -591,7 +520,8 @@ movement:
cmp #0 cmp #0
beq :+ beq :+
ldx #1 ldx #1
lda #254 lda horizontal_speed
ora #%10000000
sta player_vel_x sta player_vel_x
lda player_status lda player_status
@@ -612,15 +542,17 @@ movement:
; If player_vel_x > 0, decrement ; If player_vel_x > 0, decrement
bpl :+ bpl :+
ldx player_vel_x lda player_vel_x
dex sec
sbc #16
stx player_vel_x stx player_vel_x
jmp @end jmp @end
: :
; Else if player_vel_x < 0, increment ; Else if player_vel_x < 0, increment
ldx player_vel_x lda player_vel_x
inx clc
stx player_vel_x adc #16
sta player_vel_x
@end: @end:
; Jump ; Jump
@@ -664,11 +596,84 @@ movement:
sta player_pos_y sta player_pos_y
; Apply X velocity ; Apply X velocity
; Position
lda player_vel_x
and #%10000000
cmp #0
bne :+
; 0: right
lda player_vel_x
and #%01110000
clc
ror
clc
ror
clc
ror
clc
ror
sta var_n ; pixels
lda player_vel_x
and #%00001111
sta var_m ; subpixels
; A contains signed subpixels
clc
adc player_subpos_x ; add subposition and velocity subpixels
and #%00001111
cmp player_subpos_x ; if A (result) is less than current subpos, overflow occurred
bpl @end_add_subpos ; so skip if subpos is smaller than result
ldx player_pos_x
inx
stx player_pos_x
@end_add_subpos:
jmp :++
:
; 1: left
lda player_vel_x
and #%01110000
clc
ror
clc
ror
clc
ror
clc
ror
eor #%11111111
clc
adc #1
sta var_n ; pixels
lda player_vel_x
and #%00001111
eor #%00001111
clc
adc #1
and #%00001111
; A contains signed subpixels
clc
adc player_subpos_x ; add subposition and velocity subpixels
and #%00001111
cmp player_subpos_x ; if A (result) is greater than current subpos, underflow occurred
bmi @end_sub_subpos ; so skip if subpos is bigger than result
ldx player_pos_x
dex
stx player_pos_x
@end_sub_subpos:
:
lda player_pos_x lda player_pos_x
clc clc
adc player_vel_x adc var_n ; add pixels
sta player_pos_x sta player_pos_x
; load x pos, filter blocks, check up and down ; load x pos, filter blocks, check up and down
lda player_vel_y lda player_vel_y
@@ -708,23 +713,6 @@ movement:
rts rts
update_background:
rts
;lda $2002
;lda #$20
;sta $2006
;lda #$00
;sta $2006
ldx #1
ldy #1
jsr ppu_update_tile
lda #1
sta $2007
rts
setup_background: setup_background:
lda $2002 ; reset latch lda $2002 ; reset latch
lda #$20 lda #$20
@@ -814,117 +802,115 @@ setup_background:
; clear attributes ; clear attributes
lda #0 ;lda #0
ldx #64 ; 64 bytes ;ldx #64 ; 64 bytes
: ;:
lda #%11100100 ; lda #%11100100
;
; sta $2007
; dex
; bne :-
sta $2007 lda #0
dex sta $50
bne :-
ldy #0
:
tya
pha
ldx #0
:
tya
pha
txa
pha
tya
asl
asl
asl
asl
asl
sta temp_y
txa
asl
clc
adc temp_y
tax
lda level, X
tay
lda #5
jsr mul_y
tay
lda metatiles+4, Y
sta temp_x
lda level+1, X
tay
lda #5
jsr mul_y
tay
lda metatiles+4, Y
asl
asl
adc temp_x
sta temp_x
lda level+16, X
tay
lda #5
jsr mul_y
tay
lda metatiles+4, Y
asl
asl
asl
asl
adc temp_x
sta temp_x
lda level+17, X
tay
lda #5
jsr mul_y
tay
lda metatiles+4, Y
asl
asl
asl
asl
asl
asl
adc temp_x
sta $2007
ldx $50
inx
stx $50
sta $60, X
pla
tax
pla
tay
inx
cpx #8
bne :-
pla
tay
iny
cpy #8
bne :--
rts rts
lda $2002 ; reset latch
lda #$20
sta $2006
lda #$00
sta $2006
; empty nametable
lda #0
ldy #30 ; 30 rows
:
ldx #32 ; 32 columns
:
sta $2007
dex
bne :-
dey
bne :--
; set all attributes to 0
lda #0
ldx #64 ; 64 bytes
:
txa
and #%00000011
asl
asl
asl
asl
sta temp
txa
and #%00000011
ora temp
lda #0
sta $2007
dex
bne :-
; fill in an area in the middle with 1/2 checkerboard
lda #1
ldy #0 ; start at row 8
:
pha ; temporarily store A, it will be clobbered by ppu_address_tile routine
ldx #8 ; start at column 8
jsr ppu_address_tile
pla ; recover A
ldx #8
:
sta $2007
eor #$3
inx
cpx #(32-8)
bcc :-
eor #$3
iny
cpy #(30-8)
bcc :--
lda #$24
sta $2006
lda #$00
sta $2006
lda #$00
ldy #30
:
ldx #32
:
sta $2007
clc
adc #1
and #3
dex
bne :-
clc
adc #1
and #3
dey
bne :--
lda #0
ldy #4
:
ldx #16
:
sta $2007
dex
bne :-
clc
adc #%01010101
dey
bne :--
rts
mul_x: mul_x:
cmp #0 cmp #0
beq @zero beq @zero