From 5d3ba6d7cbf847f2f784300e66c2fd3b94a61470 Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Mon, 14 Mar 2022 12:16:40 -0400 Subject: [PATCH] lemm: add hlin support --- games/lemm/Makefile | 1 + games/lemm/hgr_hlin.s | 218 +++++++++++++++++++++++++++++++++ games/lemm/hgr_tables.s | 7 +- games/lemm/keyboard.s | 2 + games/lemm/lemm.s | 2 + games/lemm/update_menu.s | 17 +++ games/lemm/zp.inc | 3 +- graphics/hgr/lines/hgr_hlin.s | 78 +++++++----- graphics/hgr/lines/hlin_test.s | 9 +- 9 files changed, 300 insertions(+), 37 deletions(-) create mode 100644 games/lemm/hgr_hlin.s create mode 100644 games/lemm/update_menu.s diff --git a/games/lemm/Makefile b/games/lemm/Makefile index 97da2bc6..5de4d115 100644 --- a/games/lemm/Makefile +++ b/games/lemm/Makefile @@ -41,6 +41,7 @@ lemm.o: lemm.s zp.inc hardware.inc \ graphics/graphics_test.inc graphics/sprites.inc \ intro_level1.s update_time.s hgr_sprite.s draw_flames.s \ draw_door.s move_lemming.s draw_lemming.s \ + hgr_hlin.s update_menu.s \ interrupt_handler.s keyboard.s draw_pointer.s \ pointer_sprites.inc \ level1.s diff --git a/games/lemm/hgr_hlin.s b/games/lemm/hgr_hlin.s new file mode 100644 index 00000000..c4b19775 --- /dev/null +++ b/games/lemm/hgr_hlin.s @@ -0,0 +1,218 @@ + ;================================= + ; Simple Horizontal LINE + ;================================= + ; line from (x,a) to (x+y,a) + ; todo: use Carry to say if X>255 + +hgr_hlin: + + ; get ROW into (GBASL) + + sty xrun_save + stx x1_save + + ; X1 already in X + ; Y1 already in A ; Y1 into A + ;ldy #0 ; always 0 + ;jsr HPOSN ; (Y,X),(A) (values stores in HGRX,XH,Y) + ; important part is row is in GBASL/GBASH + ; HPOSN also shifts color odd/even for us + ; HPOSN also puts X1/7 into Y + + tay ; get row info for Y1 into GBASL/GBASH + lda hposn_high,Y + sta GBASH + lda hposn_low,Y + sta GBASL + + lda div7_table,X ; put X1/7 into Y + tay + + and #$1 ; only shift if in odd column? + beq hlin_no_shift_colors + jsr shift_colors +hlin_no_shift_colors: + + ; check if narrow corner case where begin and end same block + ; if RX%7 + XRUN < 7 + + ldx x1_save + lda mod7_table,X + clc + adc xrun_save + cmp #7 + bcs not_same_block + + ;==================================== + ; special case if all in one block +same_block: + ; want to use MASK of left_mask (MOD7) ANDed with ~left_mask (MOD7+XRUN) + + + lda mod7_table,X ; get x1%7 + tax ; put in X + lda left_masks,X ; get left mask + sta same_block_mask_smc+1 + + txa ; x1%7 + clc + adc xrun_save ; (x1%7)+xrun + tax + lda left_masks,X ; get left mask + + eor #$7f + and same_block_mask_smc+1 + sta same_block_mask_smc+1 + + lda (GBASL),Y + eor HGR_BITS +same_block_mask_smc: + and #$dd + eor (GBASL),Y + sta (GBASL),Y + + rts + +not_same_block: + + ; see if not starting on boundary + ; X still has X1 in it + lda mod7_table,X + beq draw_run + + ; handle not full left border +handle_ragged_left: + tax + lda (GBASL),Y + eor HGR_BITS + and left_masks,X + eor (GBASL),Y + sta (GBASL),Y + + iny ; move to next + + ; adjust RUN length by 7- mod7 + txa ; load mod7 + eor #$ff + sec + adc #7 + eor #$ff + sec + adc xrun_save + sta xrun_save + + jsr shift_colors + + ; draw run of same values +draw_run: + lda xrun_save + tax + lda mod7_table,X ; get right partial value + sta right_mask_smc+1 + lda div7_table,X ; get run length + tax +; cmp #7 +; bcc draw_right ; blt + +draw_run_loop: + beq draw_right + lda HGR_BITS ; get color + sta (GBASL),Y ; store out + + iny ; move to next block + + jsr shift_colors + + dex + jmp draw_run_loop + + ; draw rightmost +draw_right: + +right_mask_smc: + ldx #$dd + beq done_hgr_hlin + + ; see if not starting on boundary +; ldx xrun_save +; tax + + lda (GBASL),Y + eor HGR_BITS +;right_mask_smc: +; and #$dd + and right_masks,X + eor (GBASL),Y + sta (GBASL),Y + +done_hgr_hlin: + + rts + + + +x1_save: .byte $00 +xrun_save: .byte $00 + + +;right_masks: +; .byte $80,$81,$83,$87, $8F,$9F,$BF + +;left_masks: +; .byte $FF,$FE,$FC,$F8, $F0,$E0,$C0 + + + ;========================== + ; shift colors + ;========================== + ; 00000000 and 10000000 => no change (black) + ; 01111111 and 11111111 => no change? (white) + ; 01010101 => invert 00101010 +shift_colors: + lda HGR_BITS + asl + cmp #$C0 + bpl done_shift_colors + lda HGR_BITS + eor #$7f + sta HGR_BITS +done_shift_colors: + rts + + ;========================== + ; set color + ;========================== + ; color in X +set_hcolor: + lda hgr_colortbl,X + sta HGR_COLOR + rts + + ; lives at $F6F6 in Applesoft ROM +hgr_colortbl: + .byte $00,$2A,$55,$7F + .byte $80,$AA,$D5,$FF + +; notes + ; 4+3 + ; 0000 CCCC 0000 1111 + ; 0000 000C 0000 0001 + +; 4000 = 80 80 +; 4400 = 81 81 +; 4800 = 83 83 +; 4C00 = 87 87 +; 5000 = 8F 8F +; 5400 = 9F 9F +; 5800 = BF BF +;---- +; 5C00 = FF FF +; 4080 = ff 81 FF 81 +; 4480 = ff 83 +; 4880 = ff 87 +; 4c80 = ff 8F +; 5080 = ff 9f +; 5480 = ff bf +;----------- +; 5880 = ff ff +; 5c80 = ff ff 81 diff --git a/games/lemm/hgr_tables.s b/games/lemm/hgr_tables.s index 420baa58..c201e699 100644 --- a/games/lemm/hgr_tables.s +++ b/games/lemm/hgr_tables.s @@ -76,6 +76,9 @@ hposn_loop: ; ... ; x100 0000 0000001 start at 6 +right_masks: + .byte $80,$81,$83,$87, $8F,$9F,$BF + left_masks: .byte $FF,$FE,$FC,$F8, $F0,$E0,$C0 @@ -87,10 +90,6 @@ left_masks: ; ... ; x011 1111 1111110 end at 5 ; x111 1111 1111111 end at 6 -right_masks: - .byte $81,$83,$87, $8F,$9F,$BF,$FF - - ; from the Apple II firmware diff --git a/games/lemm/keyboard.s b/games/lemm/keyboard.s index 1d59f70a..9cc18075 100644 --- a/games/lemm/keyboard.s +++ b/games/lemm/keyboard.s @@ -190,6 +190,8 @@ check_return: return_pressed: + jsr update_menu + ; first check if over lemming lda OVER_LEMMING diff --git a/games/lemm/lemm.s b/games/lemm/lemm.s index 5c7d755d..d431013a 100644 --- a/games/lemm/lemm.s +++ b/games/lemm/lemm.s @@ -272,6 +272,8 @@ load_song_chunk_good: .include "draw_flames.s" .include "draw_door.s" .include "wait.s" + .include "hgr_hlin.s" + .include "update_menu.s" ; pt3 player diff --git a/games/lemm/update_menu.s b/games/lemm/update_menu.s new file mode 100644 index 00000000..f9bb5237 --- /dev/null +++ b/games/lemm/update_menu.s @@ -0,0 +1,17 @@ +; + +update_menu: + lda #7 + jsr set_hcolor + + lda #168 + ldx #144 + ldy #15 + jsr hgr_hlin ; (x,a) to (x+y,a) + + lda #191 + ldx #144 + ldy #15 + jsr hgr_hlin ; (x,a) to (x+y,a) + + rts diff --git a/games/lemm/zp.inc b/games/lemm/zp.inc index 7a3d1c92..fab1765b 100644 --- a/games/lemm/zp.inc +++ b/games/lemm/zp.inc @@ -5,6 +5,7 @@ NIBCOUNT = $00 ;; Zero page monitor routines addresses +HGR_BITS= $1C WNDLFT = $20 WNDWDTH = $21 WNDTOP = $22 @@ -82,7 +83,7 @@ SOUND_STATUS = $DE SOUND_IN_LC = $01 ; $01 sound effects in language card SOUND_MOCKINGBOARD = $02 ; mockingboard detected - +HGR_COLOR = $E4 HGR_PAGE = $E6 diff --git a/graphics/hgr/lines/hgr_hlin.s b/graphics/hgr/lines/hgr_hlin.s index 3c6a7c66..08212160 100644 --- a/graphics/hgr/lines/hgr_hlin.s +++ b/graphics/hgr/lines/hgr_hlin.s @@ -16,9 +16,8 @@ hgr_hlin: ldy #0 ; always 0 jsr HPOSN ; (Y,X),(A) (values stores in HGRX,XH,Y) ; important part is row is in GBASL/GBASH - ; also shifts color for us - - ; Y is already the RX1/7 + ; HPOSN also shifts color odd/even for us + ; HPOSN also puts X1/7 into Y ; check if narrow corner case where begin and end same block ; if RX%7 + XRUN < 7 @@ -30,25 +29,11 @@ hgr_hlin: cmp #7 bcs not_same_block + ;==================================== + ; special case if all in one block same_block: ; want to use MASK of left_mask (MOD7) ANDed with ~left_mask (MOD7+XRUN) - ; 4+3 - ; 0000 CCCC 0000 1111 - ; 0000 000C 0000 0001 - -; 4000 = 80 80 -; 4400 = 81 81 -; 4800 = 83 83 -; 4C00 = 87 87 -; 5000 = 8F 8F -; 5400 = 9F 9F -; 5800 = BF BF -;---- -; 5C00 = FF FF -; 4080 = ff 81 FF 81 -; 4480 = ff 83 -; 4880 = ff 87 lda mod7_table,X ; get x1%7 tax ; put in X @@ -104,13 +89,19 @@ handle_ragged_left: jsr shift_colors - - ; draw common + ; draw run of same values draw_run: lda xrun_save - cmp #7 - bcc draw_right ; blt + tax + lda mod7_table,X ; get right partial value + sta right_mask_smc+1 + lda div7_table,X ; get run length + tax +; cmp #7 +; bcc draw_right ; blt +draw_run_loop: + beq draw_right lda HGR_BITS ; get color sta (GBASL),Y ; store out @@ -118,24 +109,24 @@ draw_run: jsr shift_colors - lda xrun_save ; take 7 off the run - sec - sbc #7 - sta xrun_save - - jmp draw_run + dex + jmp draw_run_loop ; draw rightmost draw_right: +right_mask_smc: + ldx #$dd beq done_hgr_hlin ; see if not starting on boundary - ldx xrun_save - tax +; ldx xrun_save +; tax lda (GBASL),Y eor HGR_BITS +;right_mask_smc: +; and #$dd and right_masks,X eor (GBASL),Y sta (GBASL),Y @@ -182,3 +173,28 @@ set_hcolor: lda COLORTBL,X sta HGR_COLOR rts + + +; notes + ; 4+3 + ; 0000 CCCC 0000 1111 + ; 0000 000C 0000 0001 + +; 4000 = 80 80 +; 4400 = 81 81 +; 4800 = 83 83 +; 4C00 = 87 87 +; 5000 = 8F 8F +; 5400 = 9F 9F +; 5800 = BF BF +;---- +; 5C00 = FF FF +; 4080 = ff 81 FF 81 +; 4480 = ff 83 +; 4880 = ff 87 +; 4c80 = ff 8F +; 5080 = ff 9f +; 5480 = ff bf +;----------- +; 5880 = ff ff +; 5c80 = ff ff 81 diff --git a/graphics/hgr/lines/hlin_test.s b/graphics/hgr/lines/hlin_test.s index 9dc6b55d..b39704b4 100644 --- a/graphics/hgr/lines/hlin_test.s +++ b/graphics/hgr/lines/hlin_test.s @@ -15,6 +15,7 @@ KEYRESET = $C010 HGR2 = $F3D8 ; clear PAGE2 to 0 HGR = $F3E2 ; set hires page1 and clear $2000-$3fff +BKGND0 = $F3F4 ; clear screen to A HPOSN = $F411 ; (Y,X),(A) (values stores in HGRX,XH,Y) COLOR_SHIFT = $F47E COLORTBL = $F6F6 @@ -97,7 +98,13 @@ loop2: ; test 3 - jsr HGR2 +; jsr HGR2 + + ; note, clear to bgcolor=black2 or else edge looks a bit + ; ragged when $FF touches $00 + + lda #$80 + jsr BKGND0 ; draw lines ldy #0