From d246207c9539a3f255960e027454a52daf6483c1 Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Fri, 19 Apr 2024 01:30:17 -0400 Subject: [PATCH] keen: work on generic engine --- games/keen/Makefile | 32 ++-- games/keen/NOTES | 15 +- games/keen/draw_tilemap.s | 2 +- games/keen/engine.s | 329 +++++++++++++++++++++++++++++++++ games/keen/handle_laser.s | 4 +- games/keen/level1.s | 293 +++-------------------------- games/keen/level1_data.inc | 15 -- games/keen/level1_enemies.s | 10 +- games/keen/level1_items.s | 2 +- games/keen/level1_orig.s | 280 ++++++++++++++++++++++++++++ games/keen/loader.s | 38 +++- games/keen/maps/Makefile | 9 + games/keen/maps/level3_map.png | Bin 0 -> 14261 bytes games/keen/mars.s | 2 +- games/keen/mars_keyboard.s | 4 +- games/keen/move_keen.s | 21 ++- games/keen/zp.inc | 10 + 17 files changed, 738 insertions(+), 328 deletions(-) create mode 100644 games/keen/engine.s delete mode 100644 games/keen/level1_data.inc create mode 100644 games/keen/level1_orig.s create mode 100644 games/keen/maps/level3_map.png diff --git a/games/keen/Makefile b/games/keen/Makefile index 4cde7354..1afee0ca 100644 --- a/games/keen/Makefile +++ b/games/keen/Makefile @@ -11,14 +11,15 @@ EMPTY_DISK = ../../empty_disk/empty.dsk all: keen1_lores.dsk -keen1_lores.dsk: HELLO LOADER TITLE MARS LEVEL1 LEVEL2 +keen1_lores.dsk: HELLO LOADER TITLE ENGINE MARS LEVEL1 cp $(EMPTY_DISK) keen1_lores.dsk $(DOS33) -y keen1_lores.dsk SAVE A HELLO $(DOS33) -y keen1_lores.dsk BSAVE -a 0x1000 LOADER $(DOS33) -y keen1_lores.dsk BSAVE -a 0x4000 TITLE - $(DOS33) -y keen1_lores.dsk BSAVE -a 0x2000 MARS - $(DOS33) -y keen1_lores.dsk BSAVE -a 0x2000 LEVEL1 - $(DOS33) -y keen1_lores.dsk BSAVE -a 0x2000 LEVEL2 + $(DOS33) -y keen1_lores.dsk BSAVE -a 0x4000 ENGINE + $(DOS33) -y keen1_lores.dsk BSAVE -a 0x4000 MARS + $(DOS33) -y keen1_lores.dsk BSAVE -a 0x6000 LEVEL1 +# $(DOS33) -y keen1_lores.dsk BSAVE -a 0x2000 LEVEL2 ### @@ -47,7 +48,7 @@ title.o: title.s zp.inc hardware.inc \ #### MARS: mars.o - ld65 -o MARS mars.o -C ../../linker_scripts/apple2_2000.inc + ld65 -o MARS mars.o -C ../../linker_scripts/apple2_4000.inc mars.o: mars.s zp.inc hardware.inc game_over.s \ gr_fade.s \ @@ -60,18 +61,27 @@ mars.o: mars.s zp.inc hardware.inc game_over.s \ #### LEVEL1: level1.o - ld65 -o LEVEL1 level1.o -C ../../linker_scripts/apple2_2000.inc + ld65 -o LEVEL1 level1.o -C ../../linker_scripts/apple2_6000.inc -level1.o: level1.s zp.inc hardware.inc \ +level1.o: level1.s \ + maps/level1_map.zx02 + ca65 -o level1.o level1.s -l level1.lst + +#### + +ENGINE: engine.o + ld65 -o ENGINE engine.o -C ../../linker_scripts/apple2_4000.inc + +engine.o: engine.s zp.inc hardware.inc \ text_help.s gr_fast_clear.s text_quit_yn.s text_drawbox.s \ level1_enemies.s level1_items.s \ graphics/keen_graphics.inc sprites/keen_sprites.inc \ - maps/level1_map.zx02 \ status_bar.s draw_keen.s move_keen.s gr_putsprite_crop.s \ draw_tilemap.s tilemap_lookup.s \ - level1_sfx.s longer_sound.s level1_data.inc \ + level1_sfx.s longer_sound.s \ keyboard.s handle_laser.s - ca65 -o level1.o level1.s -l level1.lst + ca65 -o engine.o engine.s -l engine.lst + #### @@ -106,7 +116,7 @@ maps/level1_map.lzsa: #### clean: - rm -f *~ *.o *.lst HELLO LOADER TITLE MARS LEVEL1 LEVEL2 + rm -f *~ *.o *.lst HELLO LOADER TITLE ENGINE MARS LEVEL1 LEVEL2 cd graphics && make clean cd maps && make clean # cd title && make clean diff --git a/games/keen/NOTES b/games/keen/NOTES index 8e1e3304..dc5af90a 100644 --- a/games/keen/NOTES +++ b/games/keen/NOTES @@ -10,9 +10,18 @@ Memory map: $1000-$1fff = loader $2000-$3fff = code (8k? currently 5k) - $9000-$93ff = tiles (1k) - $9400-????? = big_tilemap (10k) - $BC00-????? = tilemap (1k) 10x16 + ; MARS = 6k + ; LEVEL1 = 6k + ; TITLE = 4k + + ; LOAD engine at $4000 + ; $4000 - $5fff = 8k worst case + ; LOAD level data at $6000 + ; $6000 - $7fff = 8k worst case + + $9000-$93FF = tiles (1k) + $9400-$BBFF = big_tilemap (10k) 128x80 + $BC00-$BCFF = small tilemap (256B) 20x12 tiles are 2x4, or 4 bytes each so in theory can have up to 256 of them diff --git a/games/keen/draw_tilemap.s b/games/keen/draw_tilemap.s index 4fddee97..df17fb9a 100644 --- a/games/keen/draw_tilemap.s +++ b/games/keen/draw_tilemap.s @@ -207,7 +207,7 @@ done_tilemap_subset: ; activate yorps ;========================== - ldx #NUM_ENEMIES + ldx NUM_ENEMIES beq done_yorps clc diff --git a/games/keen/engine.s b/games/keen/engine.s new file mode 100644 index 00000000..f12857a8 --- /dev/null +++ b/games/keen/engine.s @@ -0,0 +1,329 @@ +; Game Engine for Apple II Commander Keen + +; by deater (Vince Weaver) + +; Zero Page + .include "zp.inc" + .include "hardware.inc" + .include "common_defines.inc" + +; .include "level1_data.inc" + +level_data = $6000 + max_tile_x = level_data+0 + max_tile_y = level_data+1 + start_keen_tilex= level_data+2 + start_keen_tiley= level_data+3 + start_tilemap_x = level_data+4 + start_tilemap_y = level_data+5 + num_enemies = level_data+6 + hardtop_tiles = level_data+7 + allhard_tiles = level_data+8 + + + +;enemy_data = $6100 +oracle_message = $6200 +level_data_zx02 = $6300 + +level_start: + ;=================== + ; init screen + + bit KEYRESET + + bit SET_GR + bit PAGE1 + bit LORES + bit FULLGR + + jsr clear_top ; avoid grey stripes at load + + ;===================== + ; init vars + ;===================== + + lda max_tile_x + sta MAX_TILE_X + sec + sbc #20 + sta max_tilex_minus_20_smc+1 + lda MAX_TILE_X + sec + sbc #1 + sta max_tilex_minus_1_smc+1 + + lda max_tile_y + sta MAX_TILE_Y + sec + sbc #6 + sta max_tiley_minus_6_smc+1 + +; lda start_keen_tilex +; sta START_KEEN_TILEX +; lda start_keen_tiley +; sta START_KEEN_TILEY +; lda start_tilemap_x +; sta START_TILEMAP_X +; lda start_tilemap_y +; sta START_TILEMAP_Y + + lda num_enemies + sta NUM_ENEMIES + lda hardtop_tiles + sta HARDTOP_TILES + lda allhard_tiles + sta ALLHARD_TILES + + lda #0 + sta ANIMATE_FRAME + sta FRAMEL + sta FRAMEH + sta KEEN_WALKING + sta KEEN_JUMPING + sta LEVEL_OVER + sta LASER_OUT + sta KEEN_XL + sta KEEN_FALLING + sta KEEN_SHOOTING + sta KEYCARDS + + ; debug + +; lda #9 +; sta RAYGUNS + + lda #4 + sta DRAW_PAGE + + ; set starting location + + lda start_keen_tilex + sta KEEN_TILEX + lda start_keen_tiley + sta KEEN_TILEY + + lda #0 ; offset from tile location + sta KEEN_X + sta KEEN_Y + + lda #RIGHT ; direction + sta KEEN_DIRECTION + + + ;==================================== + ; load level1 tilemap + ;==================================== + + lda #level_data_zx02 + sta ZX0_src+1 + lda #$90 ; load to page $9000 + jsr full_decomp + + ;==================================== + ; copy in tilemap subset + ;==================================== + ; we copy in full screen, 40x48 = 20x12 tiles + ; we start out assuming position is 0,5 + + lda start_tilemap_x + sta TILEMAP_X + lda start_tilemap_y + sta TILEMAP_Y + + jsr copy_tilemap_subset + + ;==================================== + ;==================================== + ; Main loop + ;==================================== + ;==================================== + +keen_loop: + + ; draw tilemap + + jsr draw_tilemap + + ; draw enemies + + jsr draw_enemies + + ; draw laser + + jsr draw_laser + + ; draw keen + + jsr draw_keen + + jsr page_flip + + jsr handle_keypress + + jsr move_keen + + jsr move_enemies + + jsr move_laser + + + ;======================== + ; increment frame count + ;======================== + + inc FRAMEL + bne no_frame_oflo + inc FRAMEH +no_frame_oflo: + + ;=========================== + ; check end of level + ;=========================== + + lda LEVEL_OVER + bne done_with_keen + + ;=========================== + ; delay + ;=========================== + +; lda #200 +; jsr WAIT + + + jmp keen_loop + + +done_with_keen: + bit KEYRESET ; clear keypress + + ; three reasons we could get here + ; NEXT_LEVEL = finished level by exiting door + ; GAME_OVER = hit ESC and said Y to QUIT + ; TOUCHED_ENEMY = touched an enemy + + lda LEVEL_OVER + cmp #NEXT_LEVEL + beq level1_levelover + + cmp #GAME_OVER + beq level1_gameover + + ; got here, touched enemy + + + ;============================ + ; end animation + ;============================ + + lda #1 + sta PLAY_END_SOUND + + inc KEEN_TILEY ; move down + + sec + lda KEEN_TILEX + sbc TILEMAP_X + asl + clc + adc KEEN_X + sta XPOS + + sec + lda KEEN_TILEY + sbc TILEMAP_Y + asl + asl + clc + adc KEEN_Y + sta YPOS + +level_end_animation: + jsr draw_tilemap + + ldx #keen_sprite_squish + stx INL + sta INH + jsr put_sprite_crop + + jsr page_flip + + lda PLAY_END_SOUND + beq skip_end_sound + + ldy #SFX_KEENDIESND + jsr play_sfx + + dec PLAY_END_SOUND +skip_end_sound: + + + lda #50 + jsr WAIT + + dec YPOS + dec YPOS + + bpl level_end_animation + + + dec KEENS + bpl level1_levelover + +level1_gameover: + + ; mars plays the sound + + lda #GAME_OVER + sta LEVEL_OVER + +level1_levelover: + + lda #LOAD_MARS + sta WHICH_LOAD + + rts ; exit back + + + ;========================== + ; includes + ;========================== + + .include "text_print.s" + .include "gr_offsets.s" + .include "gr_fast_clear.s" + .include "gr_pageflip.s" + .include "gr_putsprite_crop.s" + .include "zx02_optim.s" + + .include "status_bar.s" + .include "keyboard.s" + .include "joystick.s" + + .include "text_drawbox.s" + .include "text_help.s" + .include "text_quit_yn.s" + + .include "draw_keen.s" + .include "sprites/keen_sprites.inc" + .include "move_keen.s" + .include "handle_laser.s" + .include "draw_tilemap.s" + .include "level1_enemies.s" + .include "level1_items.s" + + .include "level1_sfx.s" + .include "longer_sound.s" + + .include "random16.s" + + .include "tilemap_lookup.s" + +;level1_data_zx02: +; .incbin "maps/level1_map.zx02" + +;oracle_message: diff --git a/games/keen/handle_laser.s b/games/keen/handle_laser.s index 4cd481d9..eee9f9cd 100644 --- a/games/keen/handle_laser.s +++ b/games/keen/handle_laser.s @@ -39,7 +39,7 @@ laser_check_tiles: ldy #0 lda (INL),Y - cmp #ALLHARD_TILES + cmp ALLHARD_TILES bcs destroy_laser @@ -165,7 +165,7 @@ hit_something: done_laser_enemy: iny - cpy #NUM_ENEMIES + cpy NUM_ENEMIES bne laser_enemies_loop exit_laser_enemy: diff --git a/games/keen/level1.s b/games/keen/level1.s index 996caf01..150c2749 100644 --- a/games/keen/level1.s +++ b/games/keen/level1.s @@ -1,280 +1,37 @@ -; Keen PoC Level 1 (Border Town) +; Level 1 (Border Town) -; by deater (Vince Weaver) +; at $6000 -; Zero Page - .include "zp.inc" - .include "hardware.inc" - .include "common_defines.inc" +level1_data: +.byte 116 ;MAX_TILE_X = 116 ; 116 wide +.byte 16 ;MAX_TILE_Y = 16 ; 16 tall - .include "level1_data.inc" +.byte 1 ;START_KEEN_TILEX = 1 +.byte 13 ;START_KEEN_TILEY = 13 -level1_start: - ;=================== - ; init screen +.byte 0 ;START_TILEMAP_X = 0 +.byte 5 ;START_TILEMAP_Y = 5 - bit KEYRESET +.byte 8 ;NUM_ENEMIES = 8 - bit SET_GR - bit PAGE1 - bit LORES - bit FULLGR +.byte 32 ;HARDTOP_TILES = 32 ; start at 32 +.byte 40 ;ALLHARD_TILES = 40 ; start at 40 - jsr clear_top ; avoid grey stripes at load - ;===================== - ; init vars - ;===================== +.align $100 - lda #0 - sta ANIMATE_FRAME - sta FRAMEL - sta FRAMEH - sta KEEN_WALKING - sta KEEN_JUMPING - sta LEVEL_OVER - sta LASER_OUT - sta KEEN_XL - sta KEEN_FALLING - sta KEEN_SHOOTING - sta KEYCARDS +; at $6100 +enemy_data: +.byte $0 - ; debug - -; lda #9 -; sta RAYGUNS - - lda #4 - sta DRAW_PAGE - - ; set starting location - - lda #START_KEEN_TILEX - sta KEEN_TILEX - lda #START_KEEN_TILEY - sta KEEN_TILEY - - lda #0 ; offset from tile location - sta KEEN_X - sta KEEN_Y - - lda #RIGHT ; direction - sta KEEN_DIRECTION - - - ;==================================== - ; load level1 tilemap - ;==================================== - - lda #level1_data_zx02 - sta ZX0_src+1 - lda #$90 ; load to page $9000 - jsr full_decomp - - ;==================================== - ; copy in tilemap subset - ;==================================== - ; we copy in full screen, 40x48 = 20x12 tiles - ; we start out assuming position is 0,5 - - lda #START_TILEMAP_X - sta TILEMAP_X - lda #START_TILEMAP_Y - sta TILEMAP_Y - - jsr copy_tilemap_subset - - ;==================================== - ;==================================== - ; Main loop - ;==================================== - ;==================================== - -keen_loop: - - ; draw tilemap - - jsr draw_tilemap - - ; draw enemies - - jsr draw_enemies - - ; draw laser - - jsr draw_laser - - ; draw keen - - jsr draw_keen - - jsr page_flip - - jsr handle_keypress - - jsr move_keen - - jsr move_enemies - - jsr move_laser - - - ;======================== - ; increment frame count - ;======================== - - inc FRAMEL - bne no_frame_oflo - inc FRAMEH -no_frame_oflo: - - ;=========================== - ; check end of level - ;=========================== - - lda LEVEL_OVER - bne done_with_keen - - ;=========================== - ; delay - ;=========================== - -; lda #200 -; jsr WAIT - - - jmp keen_loop - - -done_with_keen: - bit KEYRESET ; clear keypress - - ; three reasons we could get here - ; NEXT_LEVEL = finished level by exiting door - ; GAME_OVER = hit ESC and said Y to QUIT - ; TOUCHED_ENEMY = touched an enemy - - lda LEVEL_OVER - cmp #NEXT_LEVEL - beq level1_levelover - - cmp #GAME_OVER - beq level1_gameover - - ; got here, touched enemy - - - ;============================ - ; end animation - ;============================ - - lda #1 - sta PLAY_END_SOUND - - inc KEEN_TILEY ; move down - - sec - lda KEEN_TILEX - sbc TILEMAP_X - asl - clc - adc KEEN_X - sta XPOS - - sec - lda KEEN_TILEY - sbc TILEMAP_Y - asl - asl - clc - adc KEEN_Y - sta YPOS - -level_end_animation: - jsr draw_tilemap - - ldx #keen_sprite_squish - stx INL - sta INH - jsr put_sprite_crop - - jsr page_flip - - lda PLAY_END_SOUND - beq skip_end_sound - - ldy #SFX_KEENDIESND - jsr play_sfx - - dec PLAY_END_SOUND -skip_end_sound: - - - lda #50 - jsr WAIT - - dec YPOS - dec YPOS - - bpl level_end_animation - - - dec KEENS - bpl level1_levelover - -level1_gameover: - - ; mars plays the sound - - lda #GAME_OVER - sta LEVEL_OVER - -level1_levelover: - - lda #LOAD_MARS - sta WHICH_LOAD - - rts ; exit back - - - ;========================== - ; includes - ;========================== - - .include "text_print.s" - .include "gr_offsets.s" - .include "gr_fast_clear.s" - .include "gr_pageflip.s" - .include "gr_putsprite_crop.s" - .include "zx02_optim.s" - - .include "status_bar.s" - .include "keyboard.s" - .include "joystick.s" - - .include "text_drawbox.s" - .include "text_help.s" - .include "text_quit_yn.s" - - .include "draw_keen.s" - .include "sprites/keen_sprites.inc" - .include "move_keen.s" - .include "handle_laser.s" - .include "draw_tilemap.s" - .include "level1_enemies.s" - .include "level1_items.s" - - .include "level1_sfx.s" - .include "longer_sound.s" - - .include "random16.s" - - .include "tilemap_lookup.s" - -level1_data_zx02: - .incbin "maps/level1_map.zx02" +.align $100 +; at $6200\ oracle_message: +.byte $0 + +.align $100 + +; at $6300 +level1_data_zx02: + .incbin "maps/level1_map.zx02" diff --git a/games/keen/level1_data.inc b/games/keen/level1_data.inc deleted file mode 100644 index 9e2479dd..00000000 --- a/games/keen/level1_data.inc +++ /dev/null @@ -1,15 +0,0 @@ -; Level 1 (Border Town) - -MAX_TILE_X = 116 ; 116 wide -MAX_TILE_Y = 16 ; 16 tall - -START_KEEN_TILEX = 1 -START_KEEN_TILEY = 13 - -START_TILEMAP_X = 0 -START_TILEMAP_Y = 5 - -NUM_ENEMIES = 8 - -HARDTOP_TILES = 32 ; start at 32 -ALLHARD_TILES = 40 ; start at 40 diff --git a/games/keen/level1_enemies.s b/games/keen/level1_enemies.s index aab087ac..6489abf7 100644 --- a/games/keen/level1_enemies.s +++ b/games/keen/level1_enemies.s @@ -45,7 +45,7 @@ enemy_is_out: load_foot1_smc: lda small_tilemap,Y - cmp #HARDTOP_TILES + cmp HARDTOP_TILES bcs no_enemy_fall ; if hardtop tile, don't fall inc enemy_data_tiley,X ; fall one tiles worth @@ -144,7 +144,7 @@ enemy_facing_right: iny ; to the right load_right_foot_smc: lda small_tilemap,Y - cmp #ALLHARD_TILES + cmp ALLHARD_TILES bcc no_right_barrier ; skip if no right barrier ; hit right barrier @@ -202,7 +202,7 @@ enemy_facing_left: dey ; look to the left load_left_foot_smc: lda small_tilemap,Y - cmp #ALLHARD_TILES + cmp ALLHARD_TILES bcc no_left_barrier ; skip if no right barrier ; hit left barrier @@ -242,7 +242,7 @@ move_left_noflo: done_move_enemy: inx - cpx #NUM_ENEMIES + cpx NUM_ENEMIES beq totally_done_move_enemies jmp move_enemies_loop @@ -365,7 +365,7 @@ draw_enemy: done_draw_enemy: iny - cpy #NUM_ENEMIES + cpy NUM_ENEMIES beq exit_draw_enemy jmp draw_enemies_loop diff --git a/games/keen/level1_items.s b/games/keen/level1_items.s index 9c4683b1..3e813229 100644 --- a/games/keen/level1_items.s +++ b/games/keen/level1_items.s @@ -306,7 +306,7 @@ yes_yorp_stomp: no_yorp_stomp: inx - cpx #NUM_ENEMIES + cpx NUM_ENEMIES bne check_yorp_loop done_check_yorp: diff --git a/games/keen/level1_orig.s b/games/keen/level1_orig.s new file mode 100644 index 00000000..996caf01 --- /dev/null +++ b/games/keen/level1_orig.s @@ -0,0 +1,280 @@ +; Keen PoC Level 1 (Border Town) + +; by deater (Vince Weaver) + +; Zero Page + .include "zp.inc" + .include "hardware.inc" + .include "common_defines.inc" + + .include "level1_data.inc" + +level1_start: + ;=================== + ; init screen + + bit KEYRESET + + bit SET_GR + bit PAGE1 + bit LORES + bit FULLGR + + jsr clear_top ; avoid grey stripes at load + + ;===================== + ; init vars + ;===================== + + lda #0 + sta ANIMATE_FRAME + sta FRAMEL + sta FRAMEH + sta KEEN_WALKING + sta KEEN_JUMPING + sta LEVEL_OVER + sta LASER_OUT + sta KEEN_XL + sta KEEN_FALLING + sta KEEN_SHOOTING + sta KEYCARDS + + ; debug + +; lda #9 +; sta RAYGUNS + + lda #4 + sta DRAW_PAGE + + ; set starting location + + lda #START_KEEN_TILEX + sta KEEN_TILEX + lda #START_KEEN_TILEY + sta KEEN_TILEY + + lda #0 ; offset from tile location + sta KEEN_X + sta KEEN_Y + + lda #RIGHT ; direction + sta KEEN_DIRECTION + + + ;==================================== + ; load level1 tilemap + ;==================================== + + lda #level1_data_zx02 + sta ZX0_src+1 + lda #$90 ; load to page $9000 + jsr full_decomp + + ;==================================== + ; copy in tilemap subset + ;==================================== + ; we copy in full screen, 40x48 = 20x12 tiles + ; we start out assuming position is 0,5 + + lda #START_TILEMAP_X + sta TILEMAP_X + lda #START_TILEMAP_Y + sta TILEMAP_Y + + jsr copy_tilemap_subset + + ;==================================== + ;==================================== + ; Main loop + ;==================================== + ;==================================== + +keen_loop: + + ; draw tilemap + + jsr draw_tilemap + + ; draw enemies + + jsr draw_enemies + + ; draw laser + + jsr draw_laser + + ; draw keen + + jsr draw_keen + + jsr page_flip + + jsr handle_keypress + + jsr move_keen + + jsr move_enemies + + jsr move_laser + + + ;======================== + ; increment frame count + ;======================== + + inc FRAMEL + bne no_frame_oflo + inc FRAMEH +no_frame_oflo: + + ;=========================== + ; check end of level + ;=========================== + + lda LEVEL_OVER + bne done_with_keen + + ;=========================== + ; delay + ;=========================== + +; lda #200 +; jsr WAIT + + + jmp keen_loop + + +done_with_keen: + bit KEYRESET ; clear keypress + + ; three reasons we could get here + ; NEXT_LEVEL = finished level by exiting door + ; GAME_OVER = hit ESC and said Y to QUIT + ; TOUCHED_ENEMY = touched an enemy + + lda LEVEL_OVER + cmp #NEXT_LEVEL + beq level1_levelover + + cmp #GAME_OVER + beq level1_gameover + + ; got here, touched enemy + + + ;============================ + ; end animation + ;============================ + + lda #1 + sta PLAY_END_SOUND + + inc KEEN_TILEY ; move down + + sec + lda KEEN_TILEX + sbc TILEMAP_X + asl + clc + adc KEEN_X + sta XPOS + + sec + lda KEEN_TILEY + sbc TILEMAP_Y + asl + asl + clc + adc KEEN_Y + sta YPOS + +level_end_animation: + jsr draw_tilemap + + ldx #keen_sprite_squish + stx INL + sta INH + jsr put_sprite_crop + + jsr page_flip + + lda PLAY_END_SOUND + beq skip_end_sound + + ldy #SFX_KEENDIESND + jsr play_sfx + + dec PLAY_END_SOUND +skip_end_sound: + + + lda #50 + jsr WAIT + + dec YPOS + dec YPOS + + bpl level_end_animation + + + dec KEENS + bpl level1_levelover + +level1_gameover: + + ; mars plays the sound + + lda #GAME_OVER + sta LEVEL_OVER + +level1_levelover: + + lda #LOAD_MARS + sta WHICH_LOAD + + rts ; exit back + + + ;========================== + ; includes + ;========================== + + .include "text_print.s" + .include "gr_offsets.s" + .include "gr_fast_clear.s" + .include "gr_pageflip.s" + .include "gr_putsprite_crop.s" + .include "zx02_optim.s" + + .include "status_bar.s" + .include "keyboard.s" + .include "joystick.s" + + .include "text_drawbox.s" + .include "text_help.s" + .include "text_quit_yn.s" + + .include "draw_keen.s" + .include "sprites/keen_sprites.inc" + .include "move_keen.s" + .include "handle_laser.s" + .include "draw_tilemap.s" + .include "level1_enemies.s" + .include "level1_items.s" + + .include "level1_sfx.s" + .include "longer_sound.s" + + .include "random16.s" + + .include "tilemap_lookup.s" + +level1_data_zx02: + .incbin "maps/level1_map.zx02" + +oracle_message: diff --git a/games/keen/loader.s b/games/keen/loader.s index b99edd59..c6795026 100644 --- a/games/keen/loader.s +++ b/games/keen/loader.s @@ -93,14 +93,30 @@ print_model_done: which_load_loop: - - ; update the which-file error message ; lda WHICH_LOAD ; tay ; lda which_disk,Y ; sta error_string+19 + ; 0 = TITLE + ; 1 = MARS + ; LEVEL = WHICH_LOAD-3 + + lda WHICH_LOAD + cmp #2 + bcc skip_engine_load +engine_load: + + lda #engine_filename + sta OUTH + + jsr opendir_filename + +skip_engine_load: + lda WHICH_LOAD asl @@ -110,21 +126,21 @@ which_load_loop: lda filenames+1,Y sta OUTH - lda WHICH_LOAD - bne load_other +; lda WHICH_LOAD +; bne load_other load_intro: lda #<$4000 sta entry_smc+1 lda #>$4000 sta entry_smc+2 - jmp actual_load +; jmp actual_load -load_other: - lda #<$2000 - sta entry_smc+1 - lda #>$2000 - sta entry_smc+2 +;load_other: +; lda #<$2000 +; sta entry_smc+1 +; lda #>$2000 +; sta entry_smc+2 actual_load: @@ -185,6 +201,8 @@ filenames: .word keen1_filename .word keen2_filename +engine_filename: + .byte "ENGINE",0 title_filename: .byte "TITLE",0 mars_filename: diff --git a/games/keen/maps/Makefile b/games/keen/maps/Makefile index d08f0220..45ad7f50 100644 --- a/games/keen/maps/Makefile +++ b/games/keen/maps/Makefile @@ -7,6 +7,7 @@ PNG2GR = ../../../utils/gr-utils/png2gr all: png2map \ level1_map.zx02 level2_map.zx02 \ + level3_map.zx02 \ mars_map.zx02 ### @@ -25,6 +26,14 @@ level2_map.zx02: level2_map.inc level2_map.inc: level2_map.png png2map ./png2map level2_map.png level2_map.inc +### + +level3_map.zx02: level3_map.inc + $(ZX02) level3_map.inc level3_map.zx02 + +level3_map.inc: level3_map.png png2map + ./png2map level3_map.png level3_map.inc + ### diff --git a/games/keen/maps/level3_map.png b/games/keen/maps/level3_map.png new file mode 100644 index 0000000000000000000000000000000000000000..2544a405d62d710d77656032e5ab99a8badbf78d GIT binary patch literal 14261 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 max_tile, keen_fall lda TILEMAP_Y - cmp #(MAX_TILE_Y-6) +max_tiley_minus_6_smc: + cmp #$DD bcs keen_fall ; bge diff --git a/games/keen/zp.inc b/games/keen/zp.inc index c362cd76..bd4384d4 100644 --- a/games/keen/zp.inc +++ b/games/keen/zp.inc @@ -146,6 +146,16 @@ APPLEII_MODEL = $A6 CURRENT_LEVEL = $A7 ORACLE_SPOKEN = $A8 +MAX_TILE_X = $A9 +MAX_TILE_Y = $AA +;START_KEEN_TILEX = $AB +;START_KEEN_TILEY = $AC +;START_TILEMAP_X = $AD +;START_TILEMAP_Y = $AE +NUM_ENEMIES = $AF +HARDTOP_TILES = $B0 +ALLHARD_TILES = $B1 + WHICH_SLOT = $DA JS_BUTTON_STATE = $DB CURRENT_DISK = $DC