diff --git a/common.asm b/common.asm index a4874b2..68aa2a9 100644 --- a/common.asm +++ b/common.asm @@ -60,6 +60,68 @@ row_ptr: sta colhi rts +; ---- charset_init: copy the ROM charset into RAM and patch +; in the custom road / tree glyphs (multicolor bit pairs, see +; defs.asm); runs once at boot ---- +charset_init: + lda #$33 ; char ROM in at $d000 (IO banked out) + sta $01 + lda #0 + sta scrlo + sta collo + lda #$d0 + sta scrhi + lda #>CHSET + sta colhi + ldx #8 ; the full 2K uppercase/graphics set + ldy #0 +chs_copy: + lda (scrlo),y + sta (collo),y + iny + bne chs_copy + inc scrhi + inc colhi + dex + bne chs_copy + lda #$37 ; IO back in + sta $01 + ldx #7 ; overlay the five custom glyphs +chs_patch: + lda gl_edgel,x + sta CHSET+CH_EDGEL*8,x + lda gl_edger,x + sta CHSET+CH_EDGER*8,x + lda gl_road,x + sta CHSET+CH_ROADF*8,x + lda gl_leaf,x + sta CHSET+CH_LEAF*8,x + lda gl_trunk,x + sta CHSET+CH_TRUNK*8,x + dex + bpl chs_patch + lda #$1e ; VIC: screen at $0400, charset at CHSET + sta VMEM + lda #COL_LEAF + sta CHAR_MC1 + lda #COL_ROAD + sta CHAR_MC2 + rts + +; the custom glyphs: 4 double-wide pixels per row as 2-bit +; pairs (%00 background, %01 CHAR_MC1, %10 CHAR_MC2, %11 the +; cell's color RAM bits 0-2) +gl_edgel: ; grass | white line \ road grey + !byte $03, $03, $0e, $0e, $3a, $3a, $ea, $ea +gl_edger: ; road grey / white line | grass + !byte $c0, $c0, $b0, $b0, $ac, $ac, $ab, $ab +gl_road: ; solid road surface: all %10 pairs + !byte $aa, $aa, $aa, $aa, $aa, $aa, $aa, $aa +gl_leaf: ; foliage ball: %01 pairs + !byte $14, $55, $55, $55, $55, $55, $14, $00 +gl_trunk: ; trunk: %11 pairs, red via color RAM + !byte $3c, $3c, $3c, $3c, $3c, $3c, $3c, $3c + ; ---- the road: grey surface between two painted edge lines, ; from the horizon apex down to the screen corners, then the ; trees along both shoulders ---- @@ -88,25 +150,25 @@ road_row: sbc road_off,x tay sty drleft - lda #$4e ; '/' diagonal + lda #CH_EDGEL ; grass, white line and road in one cell sta (scrlo),y - lda #COL_EDGE + lda #MCOL_EDGE sta (collo),y lda #20 clc adc road_off,x tay - lda #$4d ; '\' diagonal + lda #CH_EDGER sta (scrlo),y - lda #COL_EDGE + lda #MCOL_EDGE sta (collo),y dey ; fill the surface between the edges rr_fill: cpy drleft beq rr_done - lda #$a0 ; inverse space: solid block + lda #CH_ROADF ; solid road surface sta (scrlo),y - lda #COL_ROAD + lda #MCOL_ROAD sta (collo),y dey jmp rr_fill @@ -153,9 +215,9 @@ draw_tree: jsr row_ptr ldy tcol iny - lda #$5d ; trunk + lda #CH_TRUNK sta (scrlo),y - lda #BROWN + lda #MCOL_TRUNK sta (collo),y rts @@ -187,9 +249,9 @@ erase_tree: rts tree_ball: - lda #$51 ; foliage ball + lda #CH_LEAF sta (scrlo),y - lda #LGREEN + lda #MCOL_LEAF sta (collo),y rts diff --git a/defs.asm b/defs.asm index 7e88f97..4d1eb30 100644 --- a/defs.asm +++ b/defs.asm @@ -5,9 +5,12 @@ ; ---- hardware registers ---- RASTER = $d012 ; current raster line -XCTRL = $d016 ; horizontal fine scroll + 38/40 column mode +XCTRL = $d016 ; fine scroll + 38/40 cols + text multicolor +VMEM = $d018 ; VIC memory pointers: screen + charset BORDER = $d020 ; border color register BG = $d021 ; background color register +CHAR_MC1 = $d022 ; text multicolor 1 (bit pair %01) +CHAR_MC2 = $d023 ; text multicolor 2 (bit pair %10) SCREEN = $0400 ; screen RAM (40x25 chars) COLRAM = $d800 ; color RAM SPRPTR = $07f8 ; sprite pointers (screen RAM + $3f8) @@ -80,8 +83,23 @@ LGREY = 15 ; ---- scene palette ---- COL_SKY = LBLUE ; background above the horizon COL_GRASS = GREEN ; background below it -COL_ROAD = MGREY ; road surface (inverse-space fill) -COL_EDGE = WHITE ; painted road edge lines +COL_ROAD = MGREY ; road surface (via CHAR_MC2) +COL_LEAF = LGREEN ; tree foliage (via CHAR_MC1) + +; ---- RAM charset: ROM copy + custom multicolor glyphs ---- +; the road and the trees render as multicolor text cells +; (color RAM bit 3 set): pair %01 = CHAR_MC1 (foliage green), +; %10 = CHAR_MC2 (road grey), %11 = color RAM bits 0-2 +CHSET = $3800 ; RAM charset location (VIC bank 0) +CH_EDGEL = $4e ; left road edge: grass|white line|road +CH_EDGER = $4d ; right road edge, mirrored +CH_ROADF = $6d ; solid road surface fill +CH_LEAF = $6e ; tree foliage ball +CH_TRUNK = $6f ; tree trunk +MCOL_EDGE = 8 + WHITE ; bit 3 turns the cell multicolor +MCOL_ROAD = 8 +MCOL_LEAF = 8 +MCOL_TRUNK = 8 + RED ; ---- joystick port 2 bits (after read_joy, active high) ---- JOY_LEFT = 4 diff --git a/main.asm b/main.asm index fa9f854..bd0689a 100644 --- a/main.asm +++ b/main.asm @@ -68,6 +68,7 @@ sprcol: sta SPR_YEX sta framectr sta fheld + jsr charset_init ; RAM charset with the road/tree glyphs jsr sfx_init !ifdef AUTOPLAY { ; test builds boot straight into the game @@ -133,3 +134,6 @@ wf_hit: !src "sound.asm" !src "music.asm" !src "tables.asm" +!if * > CHSET { + !error "program ran into the RAM charset at $3800" +} diff --git a/over.asm b/over.asm index e4c7aef..48c3763 100644 --- a/over.asm +++ b/over.asm @@ -7,6 +7,8 @@ over_init: lda #BLACK ; clean card, the playfield is gone sta bg_top sta bg_bot + lda #$c8 ; plain text mode again + sta XCTRL lda #0 sta SPR_EN jsr clear_screen diff --git a/play.asm b/play.asm index 1533a21..e398c22 100644 --- a/play.asm +++ b/play.asm @@ -10,6 +10,8 @@ play_init: sta bg_top lda #COL_GRASS sta bg_bot + lda #$d8 ; text multicolor on: road + tree cells + sta XCTRL jsr clear_screen jsr draw_road diff --git a/tables.asm b/tables.asm index 12fbbfc..f41c4a8 100644 --- a/tables.asm +++ b/tables.asm @@ -47,8 +47,8 @@ sprxreg: sprbit: !byte 2, 4, 8, 16, 32, 64, 128 -; road edge offset per row (0-18): perspective curve -; wider at the horizon (offset 2) so it looks like a real road, -; not a sharp pyramid; only delta 0/1 steps, no visible jumps +; road edge offset per row (0-18): exactly one column per row, +; so the 45-degree edge glyphs join into one unbroken line on +; both sides, from the apex down to the screen corners road_off: - !byte 2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 17, 18 + !byte 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18