diff --git a/games/lemm/Makefile b/games/lemm/Makefile index ef9e3d46..7e5b91c7 100644 --- a/games/lemm/Makefile +++ b/games/lemm/Makefile @@ -39,7 +39,7 @@ LEMM: lemm.o lemm.o: lemm.s zp.inc hardware.inc \ graphics/graphics_test.inc \ - intro_level1.s \ + intro_level1.s update_time.s hgr_sprite.s \ interrupt_handler.s ca65 -o lemm.o lemm.s -l lemm.lst diff --git a/games/lemm/graphics/Makefile b/games/lemm/graphics/Makefile index 47bb40a3..8b949900 100644 --- a/games/lemm/graphics/Makefile +++ b/games/lemm/graphics/Makefile @@ -3,8 +3,9 @@ PNG2GR = ../../../utils/gr-utils/png2gr PNG2HGR = ../../../utils/hgr-utils/png2hgr LZSA = ~/research/lzsa/lzsa/lzsa B2D = ../../../utils/bmp2dhr/b2d +HGR_SPRITE = ../../../utils/hgr-utils/hgr_make_sprite -all: graphics_test.inc graphics_level1.inc +all: graphics_test.inc graphics_level1.inc sprites.inc ### @@ -18,8 +19,25 @@ graphics_test.inc: \ graphics_level1.inc: \ - level1.lzsa + level1.lzsa \ + level1_preview.lzsa echo "level1_lzsa: .incbin \"level1.lzsa\"" > graphics_level1.inc + echo "level1_preview_lzsa: .incbin \"level1_preview.lzsa\"" >> graphics_level1.inc + +### + +sprites.inc: sprites.png + $(HGR_SPRITE) -s -l big0_sprite sprites.png 14 1 20 16 > sprites.inc + $(HGR_SPRITE) -s -l big1_sprite sprites.png 28 1 34 16 >> sprites.inc + $(HGR_SPRITE) -s -l big2_sprite sprites.png 42 1 48 16 >> sprites.inc + $(HGR_SPRITE) -s -l big3_sprite sprites.png 56 1 62 16 >> sprites.inc + $(HGR_SPRITE) -s -l big4_sprite sprites.png 70 1 76 16 >> sprites.inc + $(HGR_SPRITE) -s -l big5_sprite sprites.png 84 1 90 16 >> sprites.inc + $(HGR_SPRITE) -s -l big6_sprite sprites.png 98 1 104 16 >> sprites.inc + $(HGR_SPRITE) -s -l big7_sprite sprites.png 112 1 118 16 >> sprites.inc + $(HGR_SPRITE) -s -l big8_sprite sprites.png 126 1 132 16 >> sprites.inc + $(HGR_SPRITE) -s -l big9_sprite sprites.png 140 1 146 16 >> sprites.inc + ### @@ -32,6 +50,15 @@ level1.hgr: level1.png ### +level1_preview.lzsa: level1_preview.hgr + $(LZSA) -r -f2 level1_preview.hgr level1_preview.lzsa + +level1_preview.hgr: level1_preview.png + $(PNG2HGR) level1_preview.png > level1_preview.hgr + + +### + level2.lzsa: level2.hgr $(LZSA) -r -f2 level2.hgr level2.lzsa @@ -49,6 +76,6 @@ level2_actual.hgr: level2_actual.png #### clean: - rm -f *~ graphics_test.inc \ + rm -f *~ graphics_test.inc sprites.inc \ *.lzsa *.gr *.hgr diff --git a/games/lemm/graphics/sprites.png b/games/lemm/graphics/sprites.png index 5f4e13d5..75b39889 100644 Binary files a/games/lemm/graphics/sprites.png and b/games/lemm/graphics/sprites.png differ diff --git a/games/lemm/hgr_sprite.s b/games/lemm/hgr_sprite.s new file mode 100644 index 00000000..14cfd566 --- /dev/null +++ b/games/lemm/hgr_sprite.s @@ -0,0 +1,126 @@ + ;=========================================== + ; hgr draw sprite (only at 7-bit boundaries) + ;=========================================== + ; SPRITE in INL/INH + ; Location at CURSOR_X CURSOR_Y + + ; xsize, ysize in first two bytes + + ; sprite AT INL/INH + +hgr_draw_sprite: + + ; self modify to shift for odd start location + + ; SEC=$38 0b0011 1000 CLC=$18 0b0001 10000 + + lda CURSOR_X + lsr + bcc make_it_even + +make_it_odd: + lda #$18 + bne make_it_so +make_it_even: + lda #$38 +make_it_so: + sta odd_even_smc + + + ldy #0 + lda (INL),Y ; load xsize + clc + adc CURSOR_X + sta sprite_width_end_smc+1 ; self modify for end of line + + iny ; load ysize + lda (INL),Y + sta sprite_ysize_smc+1 ; self modify + + ; skip the xsize/ysize and point to sprite + clc + lda INL ; 16-bit add + adc #2 + sta sprite_smc1+1 + lda INH + adc #0 + sta sprite_smc1+2 + + ldx #0 ; X is pointer offset + + stx MASK ; actual row + +hgr_sprite_yloop: + + lda MASK ; row + + clc + adc CURSOR_Y ; add in cursor_y + + ; calc GBASL/GBASH + + tay ; get output ROW into GBASL/H + lda hposn_low,Y + sta GBASL + lda hposn_high,Y + + ; eor #$00 draws on page2 + ; eor #$60 draws on page1 +hgr_sprite_page_smc: + eor #$00 + sta GBASH + + ldy CURSOR_X + +sprite_inner_loop: + +sprite_smc1: + lda $d000 ; get sprite pattern + +; lsr + +odd_even_smc: + sec + bcs no_adjust + + asl + php + clc + lsr + plp + ror +no_adjust: + ;? Xcababab + ;X cababab? + ;? X0cababa + +; clc ; rol asl +; rol + + + + sta (GBASL),Y ; store out + + inx + iny + + + inc sprite_smc1+1 + bne sprite_noflo + inc sprite_smc1+2 +sprite_noflo: + +sprite_width_end_smc: + cpy #6 + bne sprite_inner_loop + + + inc MASK ; row + lda MASK ; row + +sprite_ysize_smc: + cmp #31 + bne hgr_sprite_yloop + + rts + diff --git a/games/lemm/hgr_tables.s b/games/lemm/hgr_tables.s new file mode 100644 index 00000000..420baa58 --- /dev/null +++ b/games/lemm/hgr_tables.s @@ -0,0 +1,141 @@ +div7_table = $bc00 +mod7_table = $bd00 +hposn_high = $be00 +hposn_low = $bf00 + + + + ;===================== + ; make /7 %7 tables + ;===================== + +hgr_make_tables: + + ldy #0 + lda #0 + ldx #0 +div7_loop: + sta div7_table,Y + + inx + cpx #7 + bne div7_not7 + + clc + adc #1 + ldx #0 +div7_not7: + iny + bne div7_loop + + + ldy #0 + lda #0 +mod7_loop: + sta mod7_table,Y + clc + adc #1 + cmp #7 + bne mod7_not7 + lda #0 +mod7_not7: + iny + bne mod7_loop + + + ; Hposn table + + lda #0 +hposn_loop: + ldy #0 + ldx #0 + pha + jsr hposn ; (Y,X),(A) + pla + tax + + lda GBASL + sta hposn_low,X + + lda GBASH + sta hposn_high,X + + inx + txa + + cmp #192 + bne hposn_loop + + rts + + ; left masks + ; in memory on screen + ; x111 1111 1111111 start at 0 + ; x111 1110 0111111 start at 1 + ; x111 1100 0011111 start at 2 + ; ... + ; x100 0000 0000001 start at 6 + +left_masks: + .byte $FF,$FE,$FC,$F8, $F0,$E0,$C0 + + ; right masks + ; in memory on screen + ; x000 0001 1000000 end at 0 + ; x000 0011 1100000 end at 1 + ; x000 0111 1110000 end at 2 + ; ... + ; 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 +hposn: +; sta HGR_Y ; save Y and X positions +; stx HGR_X +; sty HGR_X+1 + + pha ; Y pos on stack + + and #$C0 ; calc base addr for Y-pos + + sta GBASL + lsr + lsr + ora GBASL + sta GBASL + pla + + sta GBASH + asl + asl + asl + rol GBASH + asl + rol GBASH + asl + ror GBASL + lda GBASH + + and #$1F + + ora HGR_PAGE ; default is $40 in this game + sta GBASH + +; txa +; cpy #0 +; beq xpos_lessthan_256 +; ldy #35 +; adc #4 +;label_1: +; iny +;xpos_lessthan_256: +; sbc #7 +; bcs label_1 + + rts + diff --git a/games/lemm/lc_detect.s b/games/lemm/lc_detect.s new file mode 100644 index 00000000..3123a6ae --- /dev/null +++ b/games/lemm/lc_detect.s @@ -0,0 +1,40 @@ +; Code from TotalReplay by 4am and qkumba + +;------------------------------------------------------------------------------ +; Has64K +; Checks whether computer has functioning language card (64K) +; +; in: none +; out: C clear if 64K detected +; C set if 64K not detected +; all other flags and registers clobbered +; ROM in memory (not LC RAM bank) +;------------------------------------------------------------------------------ + +detect_language_card: + + ; enable language card + ; READ_RAM1_WRITE_RAM1 + + bit $C08B + bit $C08B + + lda #$AA ; test #1 for $D0 page + sta $D000 + eor $D000 + bne no_lc + lsr $D000 ; test #2 for $D0 page + lda #$55 + eor $D000 + bne no_lc + clc + bcc done_detect + +no_lc: + sec + +done_detect: + ; READ_ROM_NO_WRITE + bit $C08A + + rts diff --git a/games/lemm/lemm.s b/games/lemm/lemm.s index 8163512f..736808f7 100644 --- a/games/lemm/lemm.s +++ b/games/lemm/lemm.s @@ -211,6 +211,10 @@ zurg: ; Load Graphics ;======================= + lda #$20 + sta HGR_PAGE + jsr hgr_make_tables + bit SET_GR bit PAGE0 bit HIRES @@ -247,13 +251,28 @@ zurg: cli + ; set up time + lda #$5 + sta TIME_MINUTES + lda #$12 + sta TIME_SECONDS + + + ;=================== ;=================== ; Main Loop ;=================== + ;=================== main_loop: + jsr update_time + + lda #$ff + jsr wait + + jmp main_loop @@ -301,12 +320,15 @@ load_song_chunk_good: ; .include "print_help.s" ; .include "gr_fast_clear.s" + .include "text_print.s" -; .include "init_vars.s" -; .include "graphics_title/title_graphics.inc" .include "lc_detect.s" + .include "wait.s" + .include "hgr_tables.s" + .include "hgr_sprite.s" + .include "update_time.s" .include "intro_level1.s" ; pt3 player @@ -324,8 +346,9 @@ config_string: .byte 0,23,"APPLE II?, 48K, MOCKINGBOARD: NO, SSI: N",0 ; MOCKINGBOARD: NONE -new_title: + .include "graphics/graphics_level1.inc" +.include "graphics/sprites.inc" music_parts_h: .byte >lemm5_part1_lzsa,>lemm5_part2_lzsa,>lemm5_part3_lzsa,$00 diff --git a/games/lemm/update_time.s b/games/lemm/update_time.s new file mode 100644 index 00000000..187f4072 --- /dev/null +++ b/games/lemm/update_time.s @@ -0,0 +1,86 @@ + + ; updates the time left +update_time: + sed + + sec + lda TIME_SECONDS + sbc #1 + cmp #$99 + bne no_time_uflo + lda #$59 + dec TIME_MINUTES + +no_time_uflo: + sta TIME_SECONDS + + cld + + +draw_time: + + ; draw minute + ldy TIME_MINUTES + + lda bignums_l,Y + sta INL + lda bignums_h,Y + sta INH + + ; 246, 152 + + ldx #35 ; 245 + stx CURSOR_X + lda #152 + sta CURSOR_Y + + jsr hgr_draw_sprite + + ; draw seconds + lda TIME_SECONDS + lsr + lsr + lsr + lsr + tay + + lda bignums_l,Y + sta INL + lda bignums_h,Y + sta INH + + ldx #37 + stx CURSOR_X + lda #152 + sta CURSOR_Y + + jsr hgr_draw_sprite + + + ; draw seconds + lda TIME_SECONDS + and #$f + tay + + lda bignums_l,Y + sta INL + lda bignums_h,Y + sta INH + + ldx #38 + stx CURSOR_X + lda #152 + sta CURSOR_Y + + jsr hgr_draw_sprite + + rts + + +bignums_l: +.byte big0_sprite,>big1_sprite,>big2_sprite,>big3_sprite,>big4_sprite +.byte >big5_sprite,>big6_sprite,>big7_sprite,>big8_sprite,>big9_sprite diff --git a/games/lemm/wait.s b/games/lemm/wait.s new file mode 100644 index 00000000..12c4319c --- /dev/null +++ b/games/lemm/wait.s @@ -0,0 +1,18 @@ +; copy of ROM wait +; because we might disable ROM + + +wait: + sec +wait2: + pha +wait3: + sbc #$01 + bne wait3 + pla + sbc #$01 + bne wait2 + rts +wait_end: + +.assert (>wait_end - >wait) < 1 , error, "wait crosses page boundary" diff --git a/games/lemm/zp.inc b/games/lemm/zp.inc index 56e2e045..f907e1a7 100644 --- a/games/lemm/zp.inc +++ b/games/lemm/zp.inc @@ -51,6 +51,12 @@ CURRENT_FRAME_H = $71 BASE_FRAME_L = $72 BASE_FRAME_H = $73 CURRENT_CHUNK = $74 +TIME_MINUTES = $75 +TIME_SECONDS = $76 +CURSOR_X = $77 +CURSOR_Y = $78 +DISP_PAGE = $79 +DRAW_PAGE = $7A APPLEII_MODEL = $8B @@ -67,21 +73,11 @@ SOUND_STATUS = $DE SOUND_IN_LC = $01 ; $01 sound effects in language card SOUND_MOCKINGBOARD = $02 ; mockingboard detected -GRID_PAGE = $DF -ANIMATE_FRAME = $E0 -LEVEL_OVER = $E1 - GAME_OVER = $FF - NEXT_LEVEL = $01 -LOCATIONS_L = $E2 -LOCATIONS_H = $E3 -; temp var per-world define -LONG_FRAME = $E4 ; nibel -CURRENT_DISPLAY = $E4 ; selena -LAST_PLAYED = $E4 ; selena +HGR_PAGE = $E6 + + -DISP_PAGE = $ED ; ALL -DRAW_PAGE = $EE ; ALL ; rest of pt3_player LOOP = $F4