keen1: initial mostly working proof
This commit is contained in:
parent
2cf26ac28d
commit
a091e8e7ec
|
@ -0,0 +1,98 @@
|
|||
include ../../Makefile.inc
|
||||
|
||||
DOS33 = ../../utils/dos33fs-utils/dos33
|
||||
DOS33_RAW = ../../utils/dos33fs-utils/dos33_raw
|
||||
B2D = ../../utils/bmp2dhr/b2d
|
||||
PNG2GR = ../../utils/gr-utils/png2gr
|
||||
LZSA = ~/research/lzsa/lzsa/lzsa
|
||||
TOKENIZE = ../../utils/asoft_basic-utils/tokenize_asoft
|
||||
EMPTY_DISK = ../../empty_disk/empty.dsk
|
||||
|
||||
|
||||
all: keen.dsk
|
||||
|
||||
keen.dsk: HELLO LOADER KEEN_TITLE KEEN_LEVEL1
|
||||
#KEEN_LEVEL2
|
||||
cp $(EMPTY_DISK) keen.dsk
|
||||
$(DOS33) -y keen.dsk SAVE A HELLO
|
||||
$(DOS33) -y keen.dsk BSAVE -a 0x1000 LOADER
|
||||
$(DOS33) -y keen.dsk BSAVE -a 0x4000 KEEN_TITLE
|
||||
$(DOS33) -y keen.dsk BSAVE -a 0x2000 KEEN_LEVEL1
|
||||
# $(DOS33) -y keen.dsk BSAVE -a 0x2000 KEEN_LEVEL2
|
||||
|
||||
|
||||
###
|
||||
|
||||
HELLO: hello.bas
|
||||
$(TOKENIZE) < hello.bas > HELLO
|
||||
|
||||
####
|
||||
|
||||
LOADER: loader.o
|
||||
ld65 -o LOADER loader.o -C ../../linker_scripts/apple2_1000.inc
|
||||
|
||||
loader.o: loader.s
|
||||
ca65 -o loader.o loader.s -l loader.lst
|
||||
|
||||
####
|
||||
|
||||
KEEN_TITLE: keen_title.o
|
||||
ld65 -o KEEN_TITLE keen_title.o -C ../../linker_scripts/apple2_4000.inc
|
||||
|
||||
keen_title.o: keen_title.s zp.inc hardware.inc init_vars.s \
|
||||
zx02_optim.s \
|
||||
graphics/keen1_title.hgr.zx02
|
||||
ca65 -o keen_title.o keen_title.s -l keen_title.lst
|
||||
|
||||
####
|
||||
|
||||
KEEN_LEVEL1: keen_level1.o
|
||||
ld65 -o KEEN_LEVEL1 keen_level1.o -C ../../linker_scripts/apple2_2000.inc
|
||||
|
||||
keen_level1.o: keen_level1.s zp.inc hardware.inc \
|
||||
print_help.s gr_fast_clear.s quit_yn.s text_drawbox.s level_end.s \
|
||||
enemies_level1.s actions_level1.s item_level1.s \
|
||||
graphics/keen_graphics.inc \
|
||||
maps/level1_map.lzsa \
|
||||
status_bar.s draw_keen.s move_keen.s gr_putsprite_crop.s \
|
||||
draw_tilemap.s \
|
||||
sound_effects.s speaker_tone.s \
|
||||
keyboard.s handle_laser.s
|
||||
ca65 -o keen_level1.o keen_level1.s -l keen_level1.lst
|
||||
|
||||
####
|
||||
|
||||
KEEN_LEVEL2: keen_level2.o
|
||||
ld65 -o KEEN_LEVEL2 keen_level2.o -C ../../linker_scripts/apple2_2000.inc
|
||||
|
||||
keen_level2.o: keen_level2.s zp.inc hardware.inc \
|
||||
print_help.s gr_fast_clear.s quit_yn.s text_drawbox.s level_end.s \
|
||||
enemies_level2.s actions_level2.s item_level2.s \
|
||||
graphics/keen_graphics.inc keen_sprites.inc \
|
||||
maps/level2_map.lzsa \
|
||||
status_bar.s draw_keen.s move_keen.s gr_putsprite_crop.s \
|
||||
draw_tilemap.s \
|
||||
sound_effects.s speaker_tone.s \
|
||||
keyboard.s handle_laser.s
|
||||
ca65 -o keen_level2.o keen_level2.s -l keen_level2.lst
|
||||
|
||||
|
||||
####
|
||||
|
||||
graphics/keen1_title.hgr.zx02:
|
||||
cd graphics && make
|
||||
|
||||
graphics/keen_graphics.inc:
|
||||
cd graphics && make
|
||||
|
||||
maps/level1_map.lzsa:
|
||||
cd maps && make
|
||||
|
||||
####
|
||||
|
||||
clean:
|
||||
rm -f *~ *.o *.lst HELLO KEEN_TITLE KEEN_LEVEL1
|
||||
cd graphics && make clean
|
||||
cd maps && make clean
|
||||
# cd title && make clean
|
||||
|
|
@ -0,0 +1,204 @@
|
|||
|
||||
; someone pressed UP
|
||||
|
||||
up_action:
|
||||
|
||||
|
||||
; set X and Y value
|
||||
; convert tile values to X,Y
|
||||
; X=((KEEN_X/2)-1)+TILEX
|
||||
|
||||
lda KEEN_X
|
||||
lsr
|
||||
sec
|
||||
sbc #1
|
||||
clc
|
||||
adc TILEMAP_X
|
||||
sta XPOS
|
||||
|
||||
; Y = (KEENY/4)+TILEY
|
||||
lda KEEN_Y
|
||||
lsr
|
||||
lsr
|
||||
clc
|
||||
adc TILEMAP_Y
|
||||
sta YPOS
|
||||
|
||||
; $39,$22 = 57,34
|
||||
|
||||
; check if it's a key slot
|
||||
check_red_keyhole:
|
||||
|
||||
|
||||
; key slot is 280,148
|
||||
; 280,148 (-80,-12) -> 200,136 -> (/4,/4) -> 50,34
|
||||
|
||||
lda XPOS
|
||||
cmp #50
|
||||
beq redkey_x
|
||||
cmp #51
|
||||
bne check_if_exit
|
||||
|
||||
redkey_x:
|
||||
|
||||
lda YPOS
|
||||
cmp #34
|
||||
bne check_if_exit
|
||||
|
||||
; check that we have the key
|
||||
lda INVENTORY
|
||||
and #INV_RED_KEY
|
||||
bne open_the_wall
|
||||
|
||||
no_red_key:
|
||||
jsr buzzer_noise
|
||||
jmp done_up_action
|
||||
|
||||
; open the red wall
|
||||
; there has to be a more efficient way of doing this
|
||||
open_the_wall:
|
||||
; reset smc
|
||||
lda #>BIG_TILEMAP
|
||||
sta rwr_smc1+2
|
||||
sta rwr_smc2+2
|
||||
|
||||
remove_red_wall_outer:
|
||||
ldx #0
|
||||
remove_red_wall_loop:
|
||||
rwr_smc1:
|
||||
lda BIG_TILEMAP,X
|
||||
cmp #49 ; red key tile
|
||||
bne not_red_tile
|
||||
lda #2 ; lblue bg tile
|
||||
rwr_smc2:
|
||||
sta BIG_TILEMAP,X
|
||||
not_red_tile:
|
||||
inx
|
||||
bne remove_red_wall_loop
|
||||
|
||||
inc rwr_smc1+2
|
||||
inc rwr_smc2+2
|
||||
|
||||
lda rwr_smc1+2
|
||||
cmp #(>BIG_TILEMAP)+40
|
||||
bne remove_red_wall_outer
|
||||
|
||||
; refresh local tilemap
|
||||
|
||||
jsr copy_tilemap_subset
|
||||
|
||||
jsr rumble_noise
|
||||
|
||||
jmp done_up_action
|
||||
|
||||
|
||||
; check if it's the exit
|
||||
check_if_exit:
|
||||
|
||||
; exit is 296,148
|
||||
; 296,148 (-80,-12) -> 216,136 -> (/4,/4) -> 54,34
|
||||
|
||||
lda XPOS
|
||||
cmp #54
|
||||
beq exit_x
|
||||
|
||||
cmp #55
|
||||
bne done_up_action
|
||||
|
||||
exit_x:
|
||||
lda YPOS
|
||||
cmp #34
|
||||
bne done_up_action
|
||||
|
||||
; check that we have the key
|
||||
lda INVENTORY
|
||||
and #INV_RED_KEY
|
||||
beq done_up_action
|
||||
|
||||
lda #1
|
||||
sta DOOR_ACTIVATED
|
||||
|
||||
sta FRAMEL ; restart timer
|
||||
|
||||
done_up_action:
|
||||
|
||||
rts
|
||||
|
||||
|
||||
;==========================
|
||||
; open the door, end level
|
||||
;==========================
|
||||
check_open_door:
|
||||
lda DOOR_ACTIVATED
|
||||
beq done_open_door
|
||||
|
||||
asl
|
||||
tay
|
||||
lda door_opening,Y
|
||||
sta INL
|
||||
lda door_opening+1,Y
|
||||
sta INH
|
||||
|
||||
; need to find actual door location
|
||||
; it's at 54,34
|
||||
; Y is going to be at 20 unless something weird is going on
|
||||
; X is going to be ((54-TILE_X)+2)*2
|
||||
|
||||
lda #56
|
||||
sec
|
||||
sbc TILEMAP_X
|
||||
asl
|
||||
sta XPOS
|
||||
|
||||
lda #20
|
||||
sta YPOS
|
||||
|
||||
jsr put_sprite_crop
|
||||
|
||||
lda FRAMEL
|
||||
and #$7
|
||||
bne done_open_door
|
||||
|
||||
; increment
|
||||
|
||||
inc DOOR_ACTIVATED
|
||||
lda DOOR_ACTIVATED
|
||||
cmp #6
|
||||
bne done_open_door
|
||||
|
||||
jsr level_end
|
||||
|
||||
done_open_door:
|
||||
rts
|
||||
|
||||
|
||||
|
||||
door_opening:
|
||||
.word door_sprite0
|
||||
.word door_sprite0
|
||||
.word door_sprite1
|
||||
.word door_sprite2
|
||||
.word door_sprite1
|
||||
.word door_sprite0
|
||||
|
||||
door_sprite0:
|
||||
.byte 4,4
|
||||
.byte $15,$55,$55,$f5
|
||||
.byte $55,$f5,$5f,$55
|
||||
.byte $25,$25,$25,$25
|
||||
.byte $55,$55,$55,$55
|
||||
|
||||
door_sprite1:
|
||||
.byte 4,4
|
||||
.byte $51,$f5,$f5,$5f
|
||||
.byte $55,$05,$05,$50
|
||||
.byte $05,$50,$50,$55
|
||||
.byte $52,$55,$55,$52
|
||||
|
||||
door_sprite2:
|
||||
.byte 4,4
|
||||
.byte $f5,$05,$05,$f0
|
||||
.byte $55,$00,$00,$55
|
||||
.byte $55,$00,$00,$55
|
||||
.byte $05,$50,$50,$25
|
||||
|
|
@ -0,0 +1,120 @@
|
|||
|
||||
;=========================
|
||||
; draw keen
|
||||
;=========================
|
||||
draw_keen:
|
||||
|
||||
lda KEEN_X
|
||||
sta XPOS
|
||||
lda KEEN_Y
|
||||
sta YPOS
|
||||
|
||||
lda KEEN_DIRECTION
|
||||
bmi keen_facing_left
|
||||
|
||||
;=========================
|
||||
; facing right
|
||||
|
||||
keen_facing_right:
|
||||
|
||||
check_falling_right:
|
||||
lda KEEN_FALLING
|
||||
beq check_jumping_right
|
||||
draw_falling_right:
|
||||
ldx #<keen_sprite_falling_right
|
||||
lda #>keen_sprite_falling_right
|
||||
jmp actually_draw_keen
|
||||
|
||||
check_jumping_right:
|
||||
lda KEEN_JUMPING
|
||||
beq check_shooting_right
|
||||
draw_jumping_right:
|
||||
ldx #<keen_sprite_jumping_right
|
||||
lda #>keen_sprite_jumping_right
|
||||
jmp actually_draw_keen
|
||||
|
||||
check_shooting_right:
|
||||
lda KEEN_SHOOTING
|
||||
beq check_walking_right
|
||||
draw_shooting_right:
|
||||
ldx #<keen_sprite_shooting_right
|
||||
lda #>keen_sprite_shooting_right
|
||||
dec KEEN_SHOOTING
|
||||
jmp actually_draw_keen
|
||||
|
||||
check_walking_right:
|
||||
lda KEEN_WALKING
|
||||
beq draw_standing_right
|
||||
draw_walking_right:
|
||||
lda FRAMEL
|
||||
and #$02
|
||||
beq draw_standing_right
|
||||
|
||||
ldx #<keen_sprite_walking_right
|
||||
lda #>keen_sprite_walking_right
|
||||
jmp actually_draw_keen
|
||||
|
||||
draw_standing_right:
|
||||
ldx #<keen_sprite_stand_right
|
||||
lda #>keen_sprite_stand_right
|
||||
jmp actually_draw_keen
|
||||
|
||||
|
||||
;==================
|
||||
; facing left
|
||||
keen_facing_left:
|
||||
|
||||
check_falling_left:
|
||||
lda KEEN_FALLING
|
||||
beq check_jumping_left
|
||||
draw_falling_left:
|
||||
ldx #<keen_sprite_falling_left
|
||||
lda #>keen_sprite_falling_left
|
||||
jmp actually_draw_keen
|
||||
|
||||
check_jumping_left:
|
||||
lda KEEN_JUMPING
|
||||
beq check_shooting_left
|
||||
draw_jumping_left:
|
||||
ldx #<keen_sprite_jumping_left
|
||||
lda #>keen_sprite_jumping_left
|
||||
jmp actually_draw_keen
|
||||
|
||||
check_shooting_left:
|
||||
lda KEEN_SHOOTING
|
||||
beq check_walking_left
|
||||
draw_shooting_left:
|
||||
ldx #<keen_sprite_shooting_left
|
||||
lda #>keen_sprite_shooting_left
|
||||
dec KEEN_SHOOTING
|
||||
jmp actually_draw_keen
|
||||
|
||||
check_walking_left:
|
||||
lda KEEN_WALKING
|
||||
beq draw_standing_left
|
||||
draw_walking_left:
|
||||
lda FRAMEL
|
||||
and #$02
|
||||
beq draw_standing_left
|
||||
|
||||
ldx #<keen_sprite_walking_left
|
||||
lda #>keen_sprite_walking_left
|
||||
jmp actually_draw_keen
|
||||
|
||||
draw_standing_left:
|
||||
ldx #<keen_sprite_stand_left
|
||||
lda #>keen_sprite_stand_left
|
||||
jmp actually_draw_keen
|
||||
|
||||
|
||||
;====================
|
||||
; actually draw
|
||||
|
||||
actually_draw_keen:
|
||||
stx INL
|
||||
sta INH
|
||||
jsr put_sprite_crop
|
||||
|
||||
rts
|
||||
|
||||
|
|
@ -0,0 +1,143 @@
|
|||
;================================
|
||||
; draw local tilemap to screen
|
||||
;================================
|
||||
|
||||
draw_tilemap:
|
||||
ldy #0 ; Y on screen currently drawing
|
||||
sty tiley ; we draw two at a time
|
||||
|
||||
ldx #1 ; offset in current screen
|
||||
stx tilemap_offset ; tilemap
|
||||
|
||||
lda #0 ; init odd/even
|
||||
sta tile_odd
|
||||
|
||||
tilemap_outer_loop:
|
||||
ldy tiley ; setup pointer to current Y
|
||||
lda gr_offsets,Y
|
||||
sta GBASL
|
||||
lda gr_offsets+1,Y
|
||||
clc
|
||||
adc DRAW_PAGE
|
||||
sta GBASH
|
||||
|
||||
ldy #6 ; we draw in window 6->34
|
||||
tilemap_loop:
|
||||
ldx tilemap_offset ; get actual tile
|
||||
lda TILEMAP,X
|
||||
|
||||
asl ; *4 ; get offset in tile
|
||||
asl
|
||||
tax
|
||||
|
||||
lda tile_odd
|
||||
beq not_odd_line
|
||||
inx
|
||||
inx
|
||||
not_odd_line:
|
||||
|
||||
lda TILES,X ; draw two tiles
|
||||
cmp #$AA ; transparency
|
||||
beq skip_tile1
|
||||
sta (GBASL),Y
|
||||
skip_tile1:
|
||||
|
||||
iny
|
||||
lda TILES+1,X
|
||||
cmp #$AA
|
||||
beq skip_tile2
|
||||
sta (GBASL),Y
|
||||
skip_tile2:
|
||||
iny
|
||||
|
||||
inc tilemap_offset
|
||||
|
||||
cpy #34 ; until done
|
||||
bne tilemap_loop
|
||||
|
||||
; move to next line
|
||||
lda tile_odd ; toggle odd/even
|
||||
eor #$1 ; (should we just add/mask?)
|
||||
sta tile_odd
|
||||
bne move_to_odd_line
|
||||
|
||||
move_to_even_line:
|
||||
lda tilemap_offset
|
||||
clc
|
||||
adc #2
|
||||
jmp done_move_to_line
|
||||
|
||||
move_to_odd_line:
|
||||
lda tilemap_offset
|
||||
sec
|
||||
sbc #14
|
||||
|
||||
done_move_to_line:
|
||||
sta tilemap_offset
|
||||
|
||||
ldy tiley ; move to next line
|
||||
iny
|
||||
iny
|
||||
sty tiley
|
||||
|
||||
cpy #40 ; check if at end
|
||||
bne tilemap_outer_loop
|
||||
|
||||
rts
|
||||
|
||||
; these should probably be in the zero page
|
||||
tilemap_offset: .byte $00
|
||||
tile_odd: .byte $00
|
||||
tiley: .byte $00
|
||||
|
||||
|
||||
;===================================
|
||||
; copy tilemap
|
||||
;===================================
|
||||
; want to copy a 16x10 area from global tileset to local
|
||||
|
||||
; default at first we want to start at 128,88
|
||||
; which is 13, 20???
|
||||
|
||||
copy_tilemap_subset:
|
||||
|
||||
; set start
|
||||
lda TILEMAP_Y
|
||||
clc
|
||||
adc #>BIG_TILEMAP
|
||||
sta cptl1_smc+2 ; set proper row in big tilemap
|
||||
adc #$10
|
||||
sta cptl3_smc+1 ; set loop limit
|
||||
|
||||
; reset row
|
||||
lda #<TILEMAP
|
||||
sta cptl2_smc+1 ; set small tilemap to row0
|
||||
|
||||
cp_tilemap_outer_loop:
|
||||
|
||||
ldx TILEMAP_X
|
||||
ldy #0
|
||||
cp_tilemap_inner_loop:
|
||||
|
||||
cptl1_smc:
|
||||
lda $9400,X
|
||||
cptl2_smc:
|
||||
sta $BC00,Y
|
||||
iny
|
||||
inx
|
||||
cpy #16
|
||||
bne cp_tilemap_inner_loop
|
||||
|
||||
; next line
|
||||
inc cptl1_smc+2 ; incremement page
|
||||
clc
|
||||
lda cptl2_smc+1 ; increment row
|
||||
adc #$10
|
||||
sta cptl2_smc+1
|
||||
|
||||
lda cptl1_smc+2
|
||||
cptl3_smc:
|
||||
cmp #$a
|
||||
bne cp_tilemap_outer_loop
|
||||
|
||||
rts
|
|
@ -0,0 +1,339 @@
|
|||
NUM_ENEMIES = 4
|
||||
|
||||
;=======================
|
||||
; laser enemies
|
||||
;=======================
|
||||
; see if laser hits any enemies
|
||||
laser_enemies:
|
||||
|
||||
ldy #0
|
||||
laser_enemies_loop:
|
||||
|
||||
; see if out
|
||||
|
||||
lda enemy_data+ENEMY_DATA_OUT,Y
|
||||
beq done_laser_enemy
|
||||
|
||||
; get local tilemap co-ord
|
||||
sec
|
||||
lda enemy_data+ENEMY_DATA_TILEX,Y
|
||||
sbc TILEMAP_X
|
||||
|
||||
sta TILE_TEMP
|
||||
|
||||
sec
|
||||
lda enemy_data+ENEMY_DATA_TILEY,Y
|
||||
sbc TILEMAP_Y
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
clc
|
||||
adc TILE_TEMP
|
||||
|
||||
cmp LASER_TILE
|
||||
bne done_laser_enemy
|
||||
|
||||
; hit something
|
||||
hit_something:
|
||||
lda #0
|
||||
sta LASER_OUT
|
||||
sta FRAMEL
|
||||
; sta enemy_data+ENEMY_DATA_OUT,Y
|
||||
lda #1
|
||||
sta enemy_data+ENEMY_DATA_EXPLODING,Y
|
||||
|
||||
jsr enemy_noise
|
||||
|
||||
jsr inc_score_by_10
|
||||
|
||||
jmp exit_laser_enemy
|
||||
|
||||
done_laser_enemy:
|
||||
|
||||
tya
|
||||
clc
|
||||
adc #8
|
||||
tay
|
||||
cpy #(NUM_ENEMIES*8)
|
||||
bne laser_enemies_loop
|
||||
exit_laser_enemy:
|
||||
rts
|
||||
|
||||
|
||||
|
||||
;=======================
|
||||
; move enemy
|
||||
;=======================
|
||||
; which one is in Y
|
||||
move_enemy:
|
||||
|
||||
lda enemy_data+ENEMY_DATA_TYPE,Y
|
||||
and #$fc
|
||||
|
||||
cmp #ENEMY_CAMERA
|
||||
beq aim_camera
|
||||
|
||||
; FIXME: actually move them
|
||||
move_bot:
|
||||
move_crawler:
|
||||
lda FRAMEL
|
||||
and #$f
|
||||
bne done_move_enemy
|
||||
|
||||
lda enemy_data+ENEMY_DATA_TYPE,Y
|
||||
eor #$2
|
||||
sta enemy_data+ENEMY_DATA_TYPE,Y
|
||||
jmp done_move_enemy
|
||||
|
||||
aim_camera:
|
||||
lda KEEN_X
|
||||
lsr
|
||||
clc
|
||||
adc TILEMAP_X
|
||||
|
||||
cmp enemy_data+ENEMY_DATA_TILEX,Y
|
||||
bcc aim_camera_left
|
||||
|
||||
aim_camera_right:
|
||||
lda #2
|
||||
sta enemy_data+ENEMY_DATA_TYPE,Y
|
||||
jmp done_move_enemy
|
||||
aim_camera_left:
|
||||
lda #0
|
||||
sta enemy_data+ENEMY_DATA_TYPE,Y
|
||||
|
||||
done_move_enemy:
|
||||
rts
|
||||
|
||||
|
||||
|
||||
;=======================
|
||||
; draw and move enemies
|
||||
;=======================
|
||||
draw_enemies:
|
||||
|
||||
ldy #0
|
||||
draw_enemies_loop:
|
||||
|
||||
; see if out
|
||||
|
||||
lda enemy_data+ENEMY_DATA_OUT,Y
|
||||
beq done_draw_enemy
|
||||
|
||||
; check if on screen
|
||||
|
||||
lda TILEMAP_X
|
||||
cmp enemy_data+ENEMY_DATA_TILEX,Y
|
||||
bcs done_draw_enemy
|
||||
|
||||
clc
|
||||
adc #14
|
||||
cmp enemy_data+ENEMY_DATA_TILEX,Y
|
||||
bcc done_draw_enemy
|
||||
|
||||
lda TILEMAP_Y
|
||||
cmp enemy_data+ENEMY_DATA_TILEY,Y
|
||||
bcs done_draw_enemy
|
||||
|
||||
clc
|
||||
adc #10
|
||||
cmp enemy_data+ENEMY_DATA_TILEY,Y
|
||||
bcc done_draw_enemy
|
||||
|
||||
; set X and Y value
|
||||
; convert tile values to X,Y
|
||||
; X = (ENEMY_TILE_X-TILEX)*2 + 6
|
||||
lda enemy_data+ENEMY_DATA_TILEX,Y
|
||||
sec
|
||||
sbc TILEMAP_X
|
||||
asl
|
||||
clc
|
||||
adc #4
|
||||
sta XPOS
|
||||
|
||||
; Y = (ENEMY_TILE_Y-TILEY)*4
|
||||
lda enemy_data+ENEMY_DATA_TILEY,Y
|
||||
sec
|
||||
sbc TILEMAP_Y
|
||||
asl
|
||||
asl
|
||||
sta YPOS
|
||||
|
||||
; see if exploding
|
||||
lda enemy_data+ENEMY_DATA_EXPLODING,Y
|
||||
beq draw_proper_enemy
|
||||
draw_exploding_enemy:
|
||||
asl
|
||||
tax
|
||||
lda enemy_explosion_sprites,X
|
||||
sta INL
|
||||
lda enemy_explosion_sprites+1,X
|
||||
sta INH
|
||||
|
||||
lda FRAMEL
|
||||
and #$3
|
||||
bne done_exploding
|
||||
|
||||
; move to next frame
|
||||
lda enemy_data+ENEMY_DATA_EXPLODING,Y
|
||||
clc
|
||||
adc #1
|
||||
sta enemy_data+ENEMY_DATA_EXPLODING,Y
|
||||
|
||||
cmp #4
|
||||
bne done_exploding
|
||||
lda #0
|
||||
sta enemy_data+ENEMY_DATA_OUT,Y
|
||||
|
||||
done_exploding:
|
||||
jmp draw_enemy
|
||||
|
||||
; otherwise draw proper sprite
|
||||
draw_proper_enemy:
|
||||
lda enemy_data+ENEMY_DATA_TYPE,Y
|
||||
tax
|
||||
lda enemy_sprites,X
|
||||
sta INL
|
||||
lda enemy_sprites+1,X
|
||||
sta INH
|
||||
|
||||
draw_enemy:
|
||||
tya
|
||||
pha
|
||||
|
||||
jsr put_sprite_crop
|
||||
|
||||
pla
|
||||
tay
|
||||
|
||||
jsr move_enemy
|
||||
|
||||
done_draw_enemy:
|
||||
|
||||
tya
|
||||
clc
|
||||
adc #8
|
||||
tay
|
||||
cpy #(NUM_ENEMIES*8)
|
||||
beq exit_draw_enemy
|
||||
jmp draw_enemies_loop
|
||||
|
||||
exit_draw_enemy:
|
||||
rts
|
||||
|
||||
enemy_sprites:
|
||||
.word enemy_camera_sprite1
|
||||
.word enemy_camera_sprite2
|
||||
.word enemy_crawler_sprite1
|
||||
.word enemy_crawler_sprite2
|
||||
.word enemy_bot_sprite1
|
||||
.word enemy_bot_sprite2
|
||||
|
||||
|
||||
|
||||
enemy_bot_sprite1:
|
||||
.byte 2,2
|
||||
.byte $Ae,$e3
|
||||
.byte $6e,$0e
|
||||
|
||||
enemy_bot_sprite2:
|
||||
.byte 2,2
|
||||
.byte $e3,$Ae
|
||||
.byte $0e,$6e
|
||||
|
||||
enemy_crawler_sprite1:
|
||||
.byte 2,2
|
||||
.byte $f5,$cA
|
||||
.byte $f5,$Ac
|
||||
|
||||
enemy_crawler_sprite2:
|
||||
.byte 2,2
|
||||
.byte $5f,$cA
|
||||
.byte $5f,$Ac
|
||||
|
||||
|
||||
enemy_camera_sprite1:
|
||||
.byte 2,2
|
||||
.byte $AA,$76
|
||||
.byte $f7,$A5
|
||||
|
||||
enemy_camera_sprite2:
|
||||
.byte 2,2
|
||||
.byte $76,$AA
|
||||
.byte $A5,$f7
|
||||
|
||||
enemy_explosion_sprites:
|
||||
.word enemy_explosion_sprite1
|
||||
.word enemy_explosion_sprite1
|
||||
.word enemy_explosion_sprite2
|
||||
.word enemy_explosion_sprite3
|
||||
|
||||
enemy_explosion_sprite1:
|
||||
.byte 2,2
|
||||
.byte $d9,$d9
|
||||
.byte $9d,$9d
|
||||
|
||||
enemy_explosion_sprite2:
|
||||
.byte 2,2
|
||||
.byte $9A,$9A
|
||||
.byte $A9,$A9
|
||||
|
||||
enemy_explosion_sprite3:
|
||||
.byte 2,2
|
||||
.byte $7A,$5A
|
||||
.byte $A5,$A7
|
||||
|
||||
ENEMY_CAMERA = 0
|
||||
ENEMY_CRAWLER = 4
|
||||
ENEMY_BOT = 8
|
||||
|
||||
ENEMY_DATA_OUT = 0
|
||||
ENEMY_DATA_EXPLODING = 1
|
||||
ENEMY_DATA_TYPE = 2
|
||||
ENEMY_DATA_DIRECTION = 3
|
||||
ENEMY_DATA_TILEX = 4
|
||||
ENEMY_DATA_TILEY = 5
|
||||
ENEMY_DATA_X = 6
|
||||
ENEMY_DATA_Y = 7
|
||||
|
||||
|
||||
enemy_data:
|
||||
|
||||
enemy0:
|
||||
; 156,92 (-80,-12) -> 76,80 -> (/4,/4) -> 19,20
|
||||
.byte 1 ; out
|
||||
.byte 0 ; exploding
|
||||
.byte ENEMY_CAMERA ; type
|
||||
.byte $ff ; direction
|
||||
.byte 19,20 ; tilex,tiley
|
||||
.byte 0,0 ; x,y
|
||||
|
||||
enemy1:
|
||||
; 272,92 (-80,-12) -> 192,80 -> (/4,/4) -> 48,20
|
||||
.byte 1 ; out
|
||||
.byte 0 ; exploding
|
||||
.byte ENEMY_CAMERA ; type
|
||||
.byte $ff ; direction
|
||||
.byte 48,20 ; tilex,tiley
|
||||
.byte 0,0 ; x,y
|
||||
|
||||
enemy2:
|
||||
; 156,112 (-80,-12) -> 76,100 -> (/4,/4) -> 19,25
|
||||
.byte 1 ; out
|
||||
.byte 0 ; exploding
|
||||
.byte ENEMY_CRAWLER ; type
|
||||
.byte $ff ; direction
|
||||
.byte 19,25 ; tilex,tiley
|
||||
.byte 0,0 ; x,y
|
||||
|
||||
enemy3:
|
||||
; 184,116 (-80,-12) -> 104,104 -> (/4,/4) -> 26,26
|
||||
.byte 1 ; out
|
||||
.byte 0 ; exploding
|
||||
.byte ENEMY_BOT ; type
|
||||
.byte $ff ; direction
|
||||
.byte 26,26 ; tilex,tiley
|
||||
.byte 0,0 ; x,y
|
||||
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
gr_offsets:
|
||||
.word $400,$480,$500,$580,$600,$680,$700,$780
|
||||
.word $428,$4a8,$528,$5a8,$628,$6a8,$728,$7a8
|
||||
.word $450,$4d0,$550,$5d0,$650,$6d0,$750,$7d0
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
;==========
|
||||
; page_flip
|
||||
;==========
|
||||
|
||||
page_flip:
|
||||
lda DISP_PAGE ; 3
|
||||
beq page_flip_show_1 ; 2nt/3
|
||||
page_flip_show_0:
|
||||
bit PAGE0 ; 4
|
||||
lda #4 ; 2
|
||||
sta DRAW_PAGE ; DRAW_PAGE=1 ; 3
|
||||
lda #0 ; 2
|
||||
sta DISP_PAGE ; DISP_PAGE=0 ; 3
|
||||
rts ; 6
|
||||
page_flip_show_1:
|
||||
bit PAGE1 ; 4
|
||||
sta DRAW_PAGE ; DRAW_PAGE=0 ; 3
|
||||
lda #1 ; 2
|
||||
sta DISP_PAGE ; DISP_PAGE=1 ; 3
|
||||
rts ; 6
|
||||
;====================
|
||||
; DISP_PAGE=0 26
|
||||
; DISP_PAGE=1 24
|
||||
|
|
@ -0,0 +1,359 @@
|
|||
;=============================================
|
||||
; put_sprite_crop
|
||||
;=============================================
|
||||
; Sprite to display in INH,INL
|
||||
; Location is XPOS,YPOS
|
||||
; Note, only works if YPOS is multiple of two
|
||||
|
||||
; transparent color is $A (grey #2)
|
||||
; this means we can have black ($0) in a sprite
|
||||
|
||||
; FIXME: force YPOS to be even?
|
||||
|
||||
put_sprite_crop:
|
||||
|
||||
ldy #0 ; byte 0 is xsize ; 2
|
||||
lda (INL),Y ; 5
|
||||
sta CH ; xsize is in CH ; 3
|
||||
iny ; 2
|
||||
clc
|
||||
adc XPOS
|
||||
sta XMAX
|
||||
|
||||
lda (INL),Y ; byte 1 is ysize ; 5
|
||||
sta CV ; ysize is in CV ; 3
|
||||
iny ; 2
|
||||
|
||||
lda YPOS ; make a copy of ypos ; 3
|
||||
sta TEMPY ; as we modify it ; 3
|
||||
;===========
|
||||
; 28
|
||||
put_sprite_crop_loop:
|
||||
sty TEMP ; save sprite pointer ; 3
|
||||
ldy TEMPY ; 3
|
||||
|
||||
bpl put_sprite_crop_pos ; if < 0, skip to next
|
||||
|
||||
clc ; skip line in sprite too
|
||||
lda TEMP
|
||||
adc CH
|
||||
tay
|
||||
|
||||
bne crop_increment_y
|
||||
|
||||
put_sprite_crop_pos:
|
||||
|
||||
psc_smc1:
|
||||
cpy #48 ; bge if >= 48, done sprite
|
||||
bcs crop_sprite_done
|
||||
|
||||
|
||||
lda gr_offsets,Y ; lookup low-res memory address ; 4
|
||||
clc ; 2
|
||||
adc XPOS ; add in xpos ; 3
|
||||
sta OUTL ; store out low byte of addy ; 3
|
||||
clc ; never wraps, handle negative
|
||||
lda gr_offsets+1,Y ; look up high byte ; 4
|
||||
adc DRAW_PAGE ; ; 3
|
||||
sta OUTH ; and store it out ; 3
|
||||
ldy TEMP ; restore sprite pointer ; 3
|
||||
|
||||
; OUTH:OUTL now points at right place
|
||||
|
||||
ldx XPOS ; load xposition into x ; 3
|
||||
;===========
|
||||
; 34
|
||||
crop_put_sprite_pixel:
|
||||
lda (INL),Y ; get sprite colors ; 5
|
||||
iny ; increment sprite pointer ; 2
|
||||
sty TEMP ; save sprite pointer ; 3
|
||||
|
||||
|
||||
cpx #0 ; if off-screen left, skip draw
|
||||
bmi skip_drawing
|
||||
cpx #40
|
||||
bcs skip_drawing ; if off-screen right, skip draw
|
||||
|
||||
ldy #$0 ; 2
|
||||
|
||||
; check if completely transparent
|
||||
; if so, skip
|
||||
|
||||
cmp #$aa ; if all zero, transparent ; 2
|
||||
beq crop_put_sprite_done_draw ; don't draw it ; 2nt/3
|
||||
;==============
|
||||
; 16/17
|
||||
|
||||
sta COLOR ; save color for later ; 3
|
||||
|
||||
; check if top pixel transparent
|
||||
|
||||
and #$f0 ; check if top nibble zero ; 2
|
||||
cmp #$a0
|
||||
bne crop_put_sprite_bottom ; if not skip ahead ; 2nt/3
|
||||
;==============
|
||||
; 7/8
|
||||
|
||||
lda COLOR
|
||||
and #$0f
|
||||
sta COLOR
|
||||
|
||||
lda #$f0 ; setup mask ; 2
|
||||
sta MASK ; 3
|
||||
bmi crop_put_sprite_mask ; always? ; 3
|
||||
;=============
|
||||
; 8
|
||||
|
||||
crop_put_sprite_bottom:
|
||||
lda COLOR ; re-load color ; 3
|
||||
and #$0f ; check if bottom nibble zero ; 2
|
||||
cmp #$0a
|
||||
bne crop_put_sprite_all ; if not, skip ahead ; 2nt/3
|
||||
;=============
|
||||
; 7/8
|
||||
|
||||
lda COLOR
|
||||
and #$f0
|
||||
sta COLOR
|
||||
lda #$0f ; 2
|
||||
sta MASK ; setup mask ; 3
|
||||
;===========
|
||||
; 5
|
||||
|
||||
crop_put_sprite_mask:
|
||||
lda (OUTL),Y ; get color at output ; 5
|
||||
and MASK ; mask off unneeded part ; 3
|
||||
ora COLOR ; or the color in ; 3
|
||||
sta (OUTL),Y ; store it back ; 6
|
||||
|
||||
jmp crop_put_sprite_done_draw ; we are done ; 3
|
||||
;===========
|
||||
; 20
|
||||
|
||||
crop_put_sprite_all:
|
||||
lda COLOR ; load color ; 3
|
||||
sta (OUTL),Y ; and write it out ; 6
|
||||
;============
|
||||
; 9
|
||||
|
||||
crop_put_sprite_done_draw:
|
||||
skip_drawing:
|
||||
|
||||
ldy TEMP ; restore sprite pointer ; 3
|
||||
|
||||
inc OUTL ; increment output pointer ; 5
|
||||
inx ; increment x counter ; 2
|
||||
cpx XMAX
|
||||
bne crop_put_sprite_pixel ; if not done, keep looping ; 2nt/3
|
||||
;==============
|
||||
; 12/13
|
||||
crop_increment_y:
|
||||
|
||||
inc TEMPY ; each line has two y vars ; 5
|
||||
inc TEMPY ; 5
|
||||
dec CV ; decemenet total y count ; 5
|
||||
bne put_sprite_crop_loop ; loop if not done ; 2nt/3
|
||||
;==============
|
||||
; 17/18
|
||||
crop_sprite_done:
|
||||
rts ; return ; 6
|
||||
|
||||
|
||||
|
||||
; 0,0 = 400+0
|
||||
; -1,0 = 400+ff=4ff, inc=400
|
||||
|
||||
; sprite: 5x4
|
||||
;
|
||||
; -2,0 Xstart=0, sprite_offset=2, xsize=3
|
||||
; -1,0, Xstart=0, sprite_offset=1, xsize=4
|
||||
; 0,0, Xstrat=0, sprite_offset=0, xsize=5
|
||||
; 1,0, Xstart=1, sprite_offset=0, xsize=5
|
||||
;
|
||||
; 39,0 Xstart=39, sprite_offset=0, xsize=1
|
||||
;
|
||||
;
|
||||
;
|
||||
;
|
||||
|
||||
|
||||
.if 0
|
||||
;=============================================
|
||||
; put_sprite_flipped_crop
|
||||
;=============================================
|
||||
; Sprite to display in INH,INL
|
||||
; Location is XPOS,YPOS
|
||||
; Note, only works if YPOS is multiple of two
|
||||
|
||||
; transparent color is $A (grey #2)
|
||||
; this means we can have black ($0) in a sprite
|
||||
|
||||
|
||||
put_sprite_flipped_crop:
|
||||
|
||||
ldy #0 ; byte 0 is xsize ; 2
|
||||
lda (INL),Y ; 5
|
||||
sta CH ; xsize is in CH ; 3
|
||||
iny ; 2
|
||||
|
||||
|
||||
lda (INL),Y ; byte 1 is ysize ; 5
|
||||
sta CV ; ysize is in CV ; 3
|
||||
dey ; make Y zero again ; 2
|
||||
|
||||
lda INH ; ???
|
||||
sta ppfc_smc+2
|
||||
clc
|
||||
lda INL
|
||||
adc #1 ; add one (not two) because X counts
|
||||
; from CH to 1 (not CH-1 to 0)
|
||||
sta ppfc_smc+1
|
||||
bcc psfc16
|
||||
inc ppfc_smc+2
|
||||
psfc16:
|
||||
|
||||
|
||||
lda YPOS ; make a copy of ypos ; 3
|
||||
|
||||
sta TEMPY ; as we modify it ; 3
|
||||
;===========
|
||||
; 28
|
||||
|
||||
|
||||
|
||||
put_spritefc_loop:
|
||||
; sty TEMP ; save sprite pointer ; 3
|
||||
ldy TEMPY ; 3
|
||||
|
||||
bmi fcrop_increment_y ; if < 0, skip to next
|
||||
psc_smc2:
|
||||
cpy #48 ; bge if >= 48, done sprite
|
||||
bcs fcrop_sprite_done
|
||||
|
||||
|
||||
lda gr_offsets,Y ; lookup low-res memory address ; 4
|
||||
clc ; 2
|
||||
adc XPOS ; add in xpos ; 3
|
||||
sta OUTL ; store out low byte of addy ; 3
|
||||
lda gr_offsets+1,Y ; look up high byte ; 4
|
||||
clc
|
||||
adc DRAW_PAGE ; ; 3
|
||||
sta OUTH ; and store it out ; 3
|
||||
; ldy TEMP ; restore sprite pointer ; 3
|
||||
|
||||
; OUTH:OUTL now points at right place
|
||||
|
||||
ldx CH ; load xsize into x ; 3
|
||||
;===========
|
||||
; 34
|
||||
put_spritefc_pixel:
|
||||
|
||||
clc
|
||||
txa ; want (CH-X-1)+XPOS
|
||||
eor #$ff
|
||||
adc CH
|
||||
adc XPOS
|
||||
|
||||
bmi cskip_drawing
|
||||
cmp #40
|
||||
|
||||
bcs cskip_drawing ; if off-screen right, skip draw
|
||||
|
||||
ppfc_smc:
|
||||
lda $C000,X ; get sprite colors ; 5
|
||||
; iny ; increment sprite pointer ; 2
|
||||
; sty TEMP ; save sprite pointer ; 3
|
||||
ldy #$0 ; 2
|
||||
|
||||
; check if completely transparent
|
||||
; if so, skip
|
||||
|
||||
cmp #$aa ; if all zero, transparent ; 2
|
||||
beq put_spritefc_done_draw ; don't draw it ; 2nt/3
|
||||
;==============
|
||||
; 16/17
|
||||
|
||||
sta COLOR ; save color for later ; 3
|
||||
|
||||
; check if top pixel transparent
|
||||
|
||||
and #$f0 ; check if top nibble zero ; 2
|
||||
cmp #$a0
|
||||
bne put_spritefc_bottom ; if not skip ahead ; 2nt/3
|
||||
;==============
|
||||
; 7/8
|
||||
|
||||
lda COLOR
|
||||
and #$0f
|
||||
sta COLOR
|
||||
|
||||
lda #$f0 ; setup mask ; 2
|
||||
sta MASK ; 3
|
||||
bmi put_spritefc_mask ; always? ; 3
|
||||
;=============
|
||||
; 8
|
||||
|
||||
put_spritefc_bottom:
|
||||
lda COLOR ; re-load color ; 3
|
||||
and #$0f ; check if bottom nibble zero ; 2
|
||||
cmp #$0a
|
||||
bne put_spritefc_all ; if not, skip ahead ; 2nt/3
|
||||
;=============
|
||||
; 7/8
|
||||
|
||||
lda COLOR
|
||||
and #$f0
|
||||
sta COLOR
|
||||
lda #$0f ; 2
|
||||
sta MASK ; setup mask ; 3
|
||||
;===========
|
||||
; 5
|
||||
|
||||
put_spritefc_mask:
|
||||
lda (OUTL),Y ; get color at output ; 5
|
||||
and MASK ; mask off unneeded part ; 3
|
||||
ora COLOR ; or the color in ; 3
|
||||
sta (OUTL),Y ; store it back ; 6
|
||||
|
||||
jmp put_spritefc_done_draw ; we are done ; 3
|
||||
;===========
|
||||
; 20
|
||||
|
||||
put_spritefc_all:
|
||||
lda COLOR ; load color ; 3
|
||||
sta (OUTL),Y ; and write it out ; 6
|
||||
;============
|
||||
; 9
|
||||
|
||||
put_spritefc_done_draw:
|
||||
cskip_drawing:
|
||||
; ldy TEMP ; restore sprite pointer ; 3
|
||||
|
||||
inc OUTL ; increment output pointer ; 5
|
||||
dex ; decrement x counter ; 2
|
||||
bne put_spritefc_pixel ; if not done, keep looping ; 2nt/3
|
||||
;==============
|
||||
; 12/13
|
||||
fcrop_increment_y:
|
||||
inc TEMPY ; each line has two y vars ; 5
|
||||
inc TEMPY ; 5
|
||||
|
||||
lda CH
|
||||
clc
|
||||
adc ppfc_smc+1
|
||||
sta ppfc_smc+1
|
||||
bcc psfco
|
||||
inc ppfc_smc+2
|
||||
psfco:
|
||||
|
||||
dec CV ; decemenet total y count ; 5
|
||||
beq fcrop_sprite_done ; loop if not done ; 2nt/3
|
||||
jmp put_spritefc_loop
|
||||
;==============
|
||||
; 17/18
|
||||
|
||||
fcrop_sprite_done:
|
||||
rts ; return ; 6
|
||||
|
||||
|
||||
.endif
|
|
@ -10,7 +10,7 @@ PNG2GR = ../../../utils/gr-utils/png2gr
|
|||
PNG2SPRITES = ../../../utils/gr-utils/png2sprites
|
||||
HGR_SPRITE = ../../../utils/hgr-utils/hgr_make_sprite
|
||||
|
||||
all: keen1_title.hgr.zx02
|
||||
all: keen1_title.hgr.zx02 level1_bg.gr.zx02
|
||||
|
||||
####
|
||||
|
||||
|
@ -27,6 +27,15 @@ keen1_title.hgr: keen1_title.png
|
|||
|
||||
####
|
||||
|
||||
level1_bg.gr.zx02: level1_bg.gr
|
||||
$(ZX02) level1_bg.gr level1_bg.gr.zx02
|
||||
|
||||
level1_bg.gr: level1_bg.png
|
||||
$(PNG2GR) level1_bg.png level1_bg.gr
|
||||
|
||||
|
||||
####
|
||||
|
||||
clean:
|
||||
rm -f *~ *.o *.lst *.zx02 *.hgr
|
||||
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 14 KiB |
|
@ -0,0 +1,100 @@
|
|||
; draw/move laser
|
||||
|
||||
; o/~ carrying a laser, down the road that I must travel o/~
|
||||
; o/~ carrying a laser, in the darkness of the night o/~
|
||||
|
||||
;====================
|
||||
; move laser
|
||||
;====================
|
||||
move_laser:
|
||||
lda LASER_OUT
|
||||
beq done_move_laser
|
||||
|
||||
lda LASER_X
|
||||
clc
|
||||
adc LASER_DIRECTION
|
||||
sta LASER_X
|
||||
|
||||
laser_check_tiles:
|
||||
; collision detect with tiles
|
||||
|
||||
; laser location is roughly
|
||||
; (y/4)*16 + (x/2) - 2
|
||||
lda LASER_Y
|
||||
lsr
|
||||
lsr
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
sta LASER_TILE
|
||||
lda LASER_X
|
||||
lsr
|
||||
clc
|
||||
adc LASER_TILE
|
||||
sec
|
||||
sbc #2
|
||||
sta LASER_TILE
|
||||
|
||||
ldx LASER_TILE
|
||||
lda TILEMAP,X
|
||||
cmp #HARD_TILES
|
||||
bcs destroy_laser
|
||||
|
||||
|
||||
laser_check_enemies:
|
||||
; collision detect with enemies
|
||||
|
||||
jsr laser_enemies
|
||||
|
||||
|
||||
; detect if off screen
|
||||
laser_check_right:
|
||||
lda LASER_X
|
||||
cmp #31
|
||||
bcc laser_check_left ; not_too_far_right
|
||||
bcs destroy_laser
|
||||
|
||||
laser_check_left:
|
||||
cmp #6
|
||||
bcs done_move_laser
|
||||
bcc destroy_laser
|
||||
|
||||
destroy_laser:
|
||||
lda #0
|
||||
sta LASER_OUT
|
||||
|
||||
done_move_laser:
|
||||
rts
|
||||
|
||||
;====================
|
||||
; draw laser
|
||||
;====================
|
||||
|
||||
draw_laser:
|
||||
|
||||
lda LASER_OUT
|
||||
beq done_draw_laser
|
||||
|
||||
lda LASER_X
|
||||
sta XPOS
|
||||
lda LASER_Y
|
||||
sta YPOS
|
||||
|
||||
; lda LASER_DIRECTION
|
||||
|
||||
|
||||
lda #<laser_sideways_sprite
|
||||
sta INL
|
||||
lda #>laser_sideways_sprite
|
||||
sta INH
|
||||
jsr put_sprite_crop
|
||||
|
||||
done_draw_laser:
|
||||
rts
|
||||
|
||||
laser_sideways_sprite:
|
||||
.byte 4,1
|
||||
; .byte $3A,$cA,$3A,$cA
|
||||
.byte $A3,$Ac,$A3,$Ac
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
5 HOME
|
||||
10 PRINT "LOADING KEEN V0.01"
|
||||
20 PRINT " KEEN1 PROOF-OF-CONCEPT DEMAKE"
|
||||
30 PRINT:PRINT
|
||||
70 PRINT "BASED ON KEEN1 BY ID"
|
||||
75 PRINT:PRINT
|
||||
80 PRINT "APPLE II PORT: VINCE WEAVER"
|
||||
90 PRINT "DISK CODE : QKUMBA"
|
||||
95 PRINT
|
||||
100 PRINT " ______"
|
||||
110 PRINT " A \/\/\/ SOFTWARE PRODUCTION"
|
||||
115 PRINT
|
||||
120 PRINT " HTTP://WWW.DEATER.NET/WEAVE/VMWPROD"
|
||||
130 PRINT CHR$(4);"BRUN LOADER"
|
|
@ -9,16 +9,16 @@ init_vars:
|
|||
sta FRAMEH
|
||||
sta DISP_PAGE
|
||||
sta JOYSTICK_ENABLED
|
||||
sta DUKE_WALKING
|
||||
sta DUKE_JUMPING
|
||||
sta KEEN_WALKING
|
||||
sta KEEN_JUMPING
|
||||
sta LEVEL_OVER
|
||||
sta LASER_OUT
|
||||
sta DUKE_XL
|
||||
sta KEEN_XL
|
||||
sta SCORE0
|
||||
sta SCORE1
|
||||
sta SCORE2
|
||||
sta DUKE_FALLING
|
||||
sta DUKE_SHOOTING
|
||||
sta KEEN_FALLING
|
||||
sta KEEN_SHOOTING
|
||||
sta KICK_UP_DUST
|
||||
sta DOOR_ACTIVATED
|
||||
sta INVENTORY
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
|
||||
;==================
|
||||
; check for items
|
||||
;==================
|
||||
; X holds ??
|
||||
check_item:
|
||||
|
||||
|
||||
check_red_key:
|
||||
lda TILEMAP,X
|
||||
cmp #31 ; red key
|
||||
bne check_blue_key
|
||||
|
||||
jsr pickup_noise
|
||||
lda INVENTORY
|
||||
ora #INV_RED_KEY
|
||||
sta INVENTORY
|
||||
|
||||
; erase red key (304,96)
|
||||
lda #0
|
||||
sta $A938 ; hack
|
||||
|
||||
jsr copy_tilemap_subset
|
||||
|
||||
jsr update_status_bar
|
||||
|
||||
jmp done_check_item
|
||||
|
||||
check_blue_key:
|
||||
cmp #30 ; blue key
|
||||
bne done_check_item
|
||||
|
||||
jsr pickup_noise
|
||||
lda INVENTORY
|
||||
ora #INV_BLUE_KEY
|
||||
sta INVENTORY
|
||||
|
||||
; erase blue key
|
||||
lda #0
|
||||
sta $970c ; hack
|
||||
|
||||
jsr copy_tilemap_subset
|
||||
|
||||
jsr update_status_bar
|
||||
|
||||
jmp keen_check_head
|
||||
|
||||
done_check_item:
|
||||
rts
|
|
@ -0,0 +1,46 @@
|
|||
; Oliver Schmidt
|
||||
; comp.sys.apple2.programmer
|
||||
|
||||
; Call with joystick number (0 or 1) in A.
|
||||
; Results are stored in value0 and value1.
|
||||
; UPPER_THRESHOLD is the paddle value you want to consider as "right enough" /
|
||||
; "down enough".
|
||||
|
||||
UPPER_THRESHOLD = 128
|
||||
|
||||
;PTRIG = $c070
|
||||
PADDL1 = $C065
|
||||
|
||||
handle_joystick:
|
||||
lda #0
|
||||
|
||||
; Read both paddles simultaneously
|
||||
asl ; Joystick number -> paddle number
|
||||
tax
|
||||
ldy #$00
|
||||
sty value0
|
||||
sty value1
|
||||
lda PTRIG ; Trigger paddles
|
||||
loop: lda PADDL0,x ; Read paddle (0 or 2)
|
||||
bmi set0 ; Cycles: 2 3
|
||||
nop ; Cycles: 2
|
||||
bpl nop0 ; Cycles: 3
|
||||
set0: sty value0 ; Cycles: 4
|
||||
nop0: ; - -
|
||||
; Cycles: 7 7
|
||||
lda PADDL1,x ; Read paddle (1 or 3)
|
||||
bmi set1 ; Cycles: 2 3
|
||||
nop ; Cycles: 2
|
||||
bpl nop1 ; Cycles: 3
|
||||
set1: sty value1 ; Cycles: 4
|
||||
nop1: ; - -
|
||||
; Cycles: 7 7
|
||||
iny
|
||||
cpy #UPPER_THRESHOLD+1
|
||||
bne loop
|
||||
|
||||
rts
|
||||
|
||||
value0: .byte $00
|
||||
value1: .byte $00
|
||||
|
|
@ -0,0 +1,243 @@
|
|||
; Keen PoC Level 1
|
||||
|
||||
; by deater (Vince Weaver) <vince@deater.net>
|
||||
|
||||
; Zero Page
|
||||
.include "zp.inc"
|
||||
.include "hardware.inc"
|
||||
.include "common_defines.inc"
|
||||
|
||||
keen_start:
|
||||
;===================
|
||||
; init screen
|
||||
jsr TEXT
|
||||
jsr HOME
|
||||
bit KEYRESET
|
||||
|
||||
bit SET_GR
|
||||
bit PAGE0
|
||||
bit LORES
|
||||
bit TEXTGR
|
||||
|
||||
jsr clear_top ; avoid grey stripes at load
|
||||
|
||||
;=====================
|
||||
; init vars
|
||||
;=====================
|
||||
|
||||
lda #0
|
||||
sta ANIMATE_FRAME
|
||||
sta FRAMEL
|
||||
sta FRAMEH
|
||||
sta DISP_PAGE
|
||||
sta JOYSTICK_ENABLED
|
||||
sta KEEN_WALKING
|
||||
sta KEEN_JUMPING
|
||||
sta LEVEL_OVER
|
||||
sta LASER_OUT
|
||||
sta KEEN_XL
|
||||
sta SCORE0
|
||||
sta SCORE1
|
||||
sta SCORE2
|
||||
sta KEEN_FALLING
|
||||
sta KEEN_SHOOTING
|
||||
sta KICK_UP_DUST
|
||||
sta DOOR_ACTIVATED
|
||||
sta INVENTORY
|
||||
|
||||
lda #<enemy_data
|
||||
sta ENEMY_DATAL
|
||||
lda #>enemy_data
|
||||
sta ENEMY_DATAH
|
||||
|
||||
; FIXME: temporary
|
||||
; lda INVENTORY
|
||||
; ora #INV_RED_KEY
|
||||
; sta INVENTORY
|
||||
|
||||
; lda #$10
|
||||
; sta SCORE0
|
||||
|
||||
lda #1
|
||||
sta FIREPOWER
|
||||
|
||||
lda #2 ; draw twice (both pages)
|
||||
sta UPDATE_STATUS
|
||||
|
||||
lda #7
|
||||
sta HEALTH
|
||||
|
||||
lda #4
|
||||
sta DRAW_PAGE
|
||||
|
||||
lda #18
|
||||
sta KEEN_X
|
||||
lda #0
|
||||
sta KEEN_Y
|
||||
lda #1
|
||||
sta KEEN_DIRECTION
|
||||
|
||||
|
||||
jsr update_status_bar
|
||||
|
||||
;====================================
|
||||
; load level1 background
|
||||
;====================================
|
||||
|
||||
lda #<level1_bg_zx02
|
||||
sta ZX0_src
|
||||
lda #>level1_bg_zx02
|
||||
sta ZX0_src+1
|
||||
|
||||
lda #$c ; load to page $c00
|
||||
|
||||
jsr full_decomp
|
||||
|
||||
|
||||
;====================================
|
||||
; load level1 tilemap
|
||||
;====================================
|
||||
|
||||
lda #<level1_data_zx02
|
||||
sta ZX0_src
|
||||
lda #>level1_data_zx02
|
||||
sta ZX0_src+1
|
||||
lda #$90 ; load to page $9000
|
||||
jsr full_decomp
|
||||
|
||||
;====================================
|
||||
; copy in tilemap subset
|
||||
;====================================
|
||||
lda #28
|
||||
sta TILEMAP_X
|
||||
lda #0
|
||||
sta TILEMAP_Y
|
||||
|
||||
jsr copy_tilemap_subset
|
||||
|
||||
;====================================
|
||||
;====================================
|
||||
; Main LOGO loop
|
||||
;====================================
|
||||
;====================================
|
||||
|
||||
keen_loop:
|
||||
|
||||
; copy over background
|
||||
|
||||
jsr gr_copy_to_current
|
||||
|
||||
; draw tilemap
|
||||
|
||||
jsr draw_tilemap
|
||||
|
||||
; draw enemies
|
||||
|
||||
jsr draw_enemies
|
||||
|
||||
; draw laser
|
||||
|
||||
jsr draw_laser
|
||||
|
||||
; draw keen
|
||||
|
||||
jsr draw_keen
|
||||
|
||||
; handle door opening
|
||||
|
||||
jsr check_open_door
|
||||
|
||||
; draw a status bar
|
||||
|
||||
jsr draw_status_bar
|
||||
|
||||
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
|
||||
beq do_keen_loop
|
||||
|
||||
jmp done_with_keen
|
||||
|
||||
|
||||
|
||||
|
||||
do_keen_loop:
|
||||
|
||||
; delay
|
||||
; lda #200
|
||||
; jsr WAIT
|
||||
|
||||
jmp keen_loop
|
||||
|
||||
|
||||
done_with_keen:
|
||||
bit KEYRESET ; clear keypress
|
||||
|
||||
|
||||
lda #LOAD_KEEN2
|
||||
sta WHICH_LOAD
|
||||
|
||||
rts ; exit back
|
||||
|
||||
|
||||
;==========================
|
||||
; includes
|
||||
;==========================
|
||||
|
||||
; level graphics
|
||||
level1_bg_zx02:
|
||||
.incbin "graphics/level1_bg.gr.zx02"
|
||||
|
||||
.include "text_print.s"
|
||||
.include "gr_offsets.s"
|
||||
.include "gr_fast_clear.s"
|
||||
.include "gr_copy.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 "print_help.s"
|
||||
.include "quit_yn.s"
|
||||
.include "level_end.s"
|
||||
|
||||
.include "draw_keen.s"
|
||||
.include "keen_sprites.inc"
|
||||
.include "move_keen.s"
|
||||
.include "handle_laser.s"
|
||||
.include "draw_tilemap.s"
|
||||
.include "enemies_level1.s"
|
||||
.include "actions_level1.s"
|
||||
.include "item_level1.s"
|
||||
|
||||
.include "sound_effects.s"
|
||||
.include "speaker_tone.s"
|
||||
|
||||
level1_data_zx02:
|
||||
.incbin "maps/level1_map.zx02"
|
|
@ -186,7 +186,7 @@ done_intro:
|
|||
;============================
|
||||
; set up initial location
|
||||
|
||||
lda #LOAD_DUKE1
|
||||
lda #LOAD_KEEN1
|
||||
sta WHICH_LOAD ; start at first level
|
||||
|
||||
rts
|
||||
|
|
|
@ -0,0 +1,251 @@
|
|||
JUMP_HEIGHT = 8
|
||||
|
||||
;==============================
|
||||
; Handle Keypress
|
||||
;==============================
|
||||
handle_keypress:
|
||||
|
||||
; first handle joystick
|
||||
lda JOYSTICK_ENABLED
|
||||
beq actually_handle_keypress
|
||||
|
||||
; only check joystick every-other frame
|
||||
lda FRAMEL
|
||||
and #$1
|
||||
beq actually_handle_keypress
|
||||
|
||||
check_button:
|
||||
lda PADDLE_BUTTON0
|
||||
bpl button_clear
|
||||
|
||||
lda JS_BUTTON_STATE
|
||||
bne js_check
|
||||
|
||||
lda #1
|
||||
sta JS_BUTTON_STATE
|
||||
lda #' '
|
||||
jmp check_sound
|
||||
|
||||
button_clear:
|
||||
lda #0
|
||||
sta JS_BUTTON_STATE
|
||||
|
||||
js_check:
|
||||
jsr handle_joystick
|
||||
|
||||
js_check_left:
|
||||
lda value0
|
||||
cmp #$20
|
||||
bcs js_check_right ; if less than 32, left
|
||||
lda #'A'
|
||||
bne check_sound
|
||||
|
||||
js_check_right:
|
||||
cmp #$40
|
||||
bcc js_check_up
|
||||
lda #'D'
|
||||
bne check_sound
|
||||
|
||||
js_check_up:
|
||||
lda value1
|
||||
cmp #$20
|
||||
bcs js_check_down
|
||||
lda #'W'
|
||||
|
||||
bne check_sound
|
||||
|
||||
js_check_down:
|
||||
cmp #$40
|
||||
bcc done_joystick
|
||||
lda #'S'
|
||||
bne check_sound
|
||||
|
||||
|
||||
done_joystick:
|
||||
|
||||
|
||||
|
||||
actually_handle_keypress:
|
||||
lda KEYPRESS
|
||||
bmi keypress
|
||||
|
||||
jmp no_keypress
|
||||
|
||||
keypress:
|
||||
and #$7f ; clear high bit
|
||||
cmp #' '
|
||||
beq check_sound ; make sure not to lose space
|
||||
and #$df ; convert uppercase to lower case
|
||||
|
||||
check_sound:
|
||||
cmp #$14 ; control-T
|
||||
bne check_help
|
||||
|
||||
lda SOUND_STATUS
|
||||
eor #SOUND_DISABLED
|
||||
sta SOUND_STATUS
|
||||
jmp done_keypress
|
||||
|
||||
check_help:
|
||||
cmp #'H' ; H (^H is same as left)
|
||||
bne check_joystick
|
||||
|
||||
jsr print_help
|
||||
jmp done_keypress
|
||||
|
||||
; can't be ^J as that's the same as down
|
||||
check_joystick:
|
||||
cmp #'J' ; J
|
||||
bne check_left
|
||||
|
||||
lda JOYSTICK_ENABLED
|
||||
eor #1
|
||||
sta JOYSTICK_ENABLED
|
||||
jmp done_keypress
|
||||
|
||||
check_left:
|
||||
cmp #'A'
|
||||
beq left_pressed
|
||||
cmp #8 ; left key
|
||||
bne check_right
|
||||
left_pressed:
|
||||
|
||||
lda KEEN_DIRECTION
|
||||
cmp #$ff ; check if facing left
|
||||
bne face_left
|
||||
|
||||
lda #1
|
||||
sta KEEN_WALKING
|
||||
jmp done_left_pressed
|
||||
|
||||
face_left:
|
||||
lda #$ff
|
||||
sta KEEN_DIRECTION
|
||||
lda #0
|
||||
sta KEEN_WALKING
|
||||
|
||||
done_left_pressed:
|
||||
jmp done_keypress
|
||||
|
||||
check_right:
|
||||
cmp #'D'
|
||||
beq right_pressed
|
||||
cmp #$15 ; right key
|
||||
bne check_up
|
||||
right_pressed:
|
||||
lda KEEN_DIRECTION
|
||||
cmp #$1 ; check if facing right
|
||||
bne face_right
|
||||
|
||||
lda #1
|
||||
sta KEEN_WALKING
|
||||
jmp done_left_pressed
|
||||
|
||||
face_right:
|
||||
lda #$1
|
||||
sta KEEN_DIRECTION
|
||||
lda #0
|
||||
sta KEEN_WALKING
|
||||
|
||||
done_right_pressed:
|
||||
jmp done_keypress
|
||||
|
||||
check_up:
|
||||
cmp #'W'
|
||||
beq up_pressed
|
||||
cmp #$0B ; up key
|
||||
bne check_down
|
||||
up_pressed:
|
||||
|
||||
jsr up_action
|
||||
|
||||
done_up_pressed:
|
||||
jmp done_keypress
|
||||
|
||||
check_down:
|
||||
cmp #'S'
|
||||
beq down_pressed
|
||||
cmp #$0A
|
||||
bne check_space
|
||||
down_pressed:
|
||||
|
||||
done_down_pressed:
|
||||
jmp done_keypress
|
||||
|
||||
check_space:
|
||||
cmp #' '
|
||||
bne check_return
|
||||
space_pressed:
|
||||
|
||||
; jump
|
||||
lda KEEN_JUMPING
|
||||
bne done_keypress ; don't jump if already jumping
|
||||
|
||||
lda KEEN_FALLING
|
||||
bne done_keypress ; don't jump if falling
|
||||
|
||||
lda #JUMP_HEIGHT
|
||||
sta KEEN_JUMPING
|
||||
|
||||
jsr jump_noise
|
||||
|
||||
jmp done_keypress
|
||||
|
||||
check_return:
|
||||
cmp #13
|
||||
bne check_escape
|
||||
|
||||
return_pressed:
|
||||
|
||||
; shoot
|
||||
lda LASER_OUT
|
||||
bne done_return
|
||||
|
||||
jsr laser_noise
|
||||
|
||||
lda KEEN_DIRECTION
|
||||
sta LASER_DIRECTION
|
||||
|
||||
lda #2
|
||||
sta KEEN_SHOOTING
|
||||
|
||||
cmp #1
|
||||
beq laser_right
|
||||
laser_left:
|
||||
lda KEEN_X
|
||||
sec
|
||||
sbc #1
|
||||
jmp laser_assign
|
||||
|
||||
laser_right:
|
||||
lda KEEN_X
|
||||
clc
|
||||
adc #2
|
||||
|
||||
laser_assign:
|
||||
sta LASER_X
|
||||
|
||||
lda KEEN_Y
|
||||
clc
|
||||
adc #4
|
||||
sta LASER_Y
|
||||
|
||||
inc LASER_OUT
|
||||
|
||||
done_return:
|
||||
jmp no_keypress
|
||||
|
||||
check_escape:
|
||||
cmp #27
|
||||
bne done_keypress
|
||||
|
||||
jsr print_quit
|
||||
|
||||
jmp done_keypress
|
||||
|
||||
|
||||
|
||||
done_keypress:
|
||||
no_keypress:
|
||||
bit KEYRESET
|
||||
rts
|
|
@ -0,0 +1,65 @@
|
|||
; Print bonuses
|
||||
|
||||
level_end:
|
||||
bit KEYRESET ; clear keyboard
|
||||
bit SET_TEXT
|
||||
|
||||
lda #12
|
||||
sta drawbox_x1
|
||||
lda #26
|
||||
sta drawbox_x2
|
||||
lda #19
|
||||
sta drawbox_y1
|
||||
lda #23
|
||||
sta drawbox_y2
|
||||
|
||||
lda #21
|
||||
sta bonus_text+1
|
||||
|
||||
scroll_bonus_loop:
|
||||
lda #' '|$80
|
||||
sta clear_all_color+1
|
||||
jsr clear_all
|
||||
|
||||
jsr drawbox
|
||||
|
||||
jsr normal_text
|
||||
|
||||
lda #<bonus_text
|
||||
sta OUTL
|
||||
lda #>bonus_text
|
||||
sta OUTH
|
||||
jsr move_and_print_list
|
||||
|
||||
jsr page_flip
|
||||
|
||||
lda #220
|
||||
jsr WAIT
|
||||
lda #220
|
||||
jsr WAIT
|
||||
|
||||
level_end_wait:
|
||||
lda KEYPRESS
|
||||
bmi really_end_level
|
||||
|
||||
dec drawbox_y1
|
||||
dec drawbox_y2
|
||||
dec bonus_text+1
|
||||
|
||||
lda drawbox_y1
|
||||
bmi really_end_level
|
||||
|
||||
jmp scroll_bonus_loop
|
||||
|
||||
really_end_level:
|
||||
bit KEYRESET
|
||||
lda #NEXT_LEVEL
|
||||
sta LEVEL_OVER
|
||||
|
||||
jsr clear_all
|
||||
|
||||
rts
|
||||
|
||||
bonus_text:
|
||||
.byte 14,10,"BONUS: NONE",0
|
||||
.byte 255
|
|
@ -0,0 +1,3 @@
|
|||
Urgh I've completely forgotten all of this
|
||||
|
||||
Fall through tiles that are < HARD_TILES which defaults to 32
|
|
@ -0,0 +1,34 @@
|
|||
CC = gcc
|
||||
CFLAGS = -g -Wall -O2
|
||||
|
||||
ZX02 = ~/research/6502_compression/zx02.git/build/zx02 -f
|
||||
|
||||
all: level1_map.zx02 png2map
|
||||
|
||||
###
|
||||
|
||||
level1_map.zx02: level1_map.inc
|
||||
$(ZX02) level1_map.inc level1_map.zx02
|
||||
|
||||
level1_map.inc: level1_map.png png2map
|
||||
./png2map level1_map.png level1_map.inc
|
||||
|
||||
###
|
||||
|
||||
loadpng.o: loadpng.c loadpng.h
|
||||
$(CC) $(CFLAGS) -c loadpng.c
|
||||
|
||||
rle_common.o: rle_common.c rle_common.h
|
||||
$(CC) $(CFLAGS) -c rle_common.c
|
||||
###
|
||||
|
||||
png2map: png2map.o loadpng.o
|
||||
$(CC) $(LFLAGS) -o png2map png2map.o loadpng.o -lpng
|
||||
|
||||
png2map.o: png2map.c loadpng.h
|
||||
$(CC) $(CFLAGS) -c png2map.c
|
||||
|
||||
###
|
||||
|
||||
clean:
|
||||
rm -f *~ *.o *.inc png2map
|
Binary file not shown.
After Width: | Height: | Size: 9.0 KiB |
|
@ -0,0 +1,236 @@
|
|||
/* Loads a 80x48 (or 40x48) PNG image into a 40x48 Apple II layout */
|
||||
/* It's not interleaved like an actual Apple II */
|
||||
/* But the top/bottom are pre-packed into a naive 40x24 array */
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <png.h>
|
||||
#include "loadpng.h"
|
||||
|
||||
static int convert_color(int color, char *filename) {
|
||||
|
||||
int c=0;
|
||||
|
||||
switch(color) {
|
||||
case 0x000000: c=0; break; /* black */
|
||||
case 0xe31e60: c=1; break; /* magenta */
|
||||
case 0x604ebd: c=2; break; /* dark blue */
|
||||
case 0xff44fd: c=3; break; /* purple */
|
||||
case 0x00a360: c=4; break; /* dark green */
|
||||
case 0x9c9c9c: c=5; break; /* grey 1 */
|
||||
case 0x14cffd: c=6; break; /* medium blue */
|
||||
case 0xd0c3ff: c=7; break; /* light blue */
|
||||
case 0x607203: c=8; break; /* brown */
|
||||
case 0xff6a3c: c=9; break; /* orange */
|
||||
case 0x9d9d9d: c=10; break; /* grey 2 */
|
||||
case 0xffa0d0: c=11; break; /* pink */
|
||||
case 0x14f53c: c=12; break; /* bright green */
|
||||
case 0xd0dd8d: c=13; break; /* yellow */
|
||||
case 0x72ffd0: c=14; break; /* aqua */
|
||||
case 0xffffff: c=15; break; /* white */
|
||||
default:
|
||||
fprintf(stderr,"Unknown color %x, file %s\n",
|
||||
color,filename);
|
||||
exit(-1);
|
||||
break;
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
/* expects a PNG where the xsize is either 1280x200 */
|
||||
|
||||
int loadpng(char *filename, unsigned char **image_ptr, int *xsize, int *ysize,
|
||||
int png_type) {
|
||||
|
||||
int x,y,ystart,yadd,xadd;
|
||||
int color;
|
||||
FILE *infile;
|
||||
int debug=0;
|
||||
unsigned char *image,*out_ptr;
|
||||
int width, height;
|
||||
int a2_color;
|
||||
|
||||
png_byte bit_depth;
|
||||
png_structp png_ptr;
|
||||
png_infop info_ptr;
|
||||
png_bytep *row_pointers;
|
||||
png_byte color_type;
|
||||
|
||||
unsigned char header[8];
|
||||
|
||||
/* open file and test for it being a png */
|
||||
infile = fopen(filename, "rb");
|
||||
if (infile==NULL) {
|
||||
fprintf(stderr,"Error! Could not open %s\n",filename);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Check the header */
|
||||
fread(header, 1, 8, infile);
|
||||
if (png_sig_cmp(header, 0, 8)) {
|
||||
fprintf(stderr,"Error! %s is not a PNG file\n",filename);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* initialize stuff */
|
||||
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||||
if (!png_ptr) {
|
||||
fprintf(stderr,"Error create_read_struct\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
info_ptr = png_create_info_struct(png_ptr);
|
||||
if (!info_ptr) {
|
||||
fprintf(stderr,"Error png_create_info_struct\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
png_init_io(png_ptr, infile);
|
||||
png_set_sig_bytes(png_ptr, 8);
|
||||
|
||||
png_read_info(png_ptr, info_ptr);
|
||||
|
||||
width = png_get_image_width(png_ptr, info_ptr);
|
||||
height = png_get_image_height(png_ptr, info_ptr);
|
||||
|
||||
if (width==1280) {
|
||||
*xsize=1280;
|
||||
xadd=1;
|
||||
}
|
||||
else {
|
||||
fprintf(stderr,"Unsupported width %d\n",width);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (png_type==PNG_WHOLETHING) {
|
||||
*ysize=height;
|
||||
ystart=0;
|
||||
yadd=1;
|
||||
}
|
||||
else {
|
||||
fprintf(stderr,"Unknown type\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
color_type = png_get_color_type(png_ptr, info_ptr);
|
||||
bit_depth = png_get_bit_depth(png_ptr, info_ptr);
|
||||
|
||||
if (debug) {
|
||||
printf("PNG: width=%d height=%d depth=%d\n",width,height,bit_depth);
|
||||
if (color_type==PNG_COLOR_TYPE_RGB) printf("Type RGB\n");
|
||||
else if (color_type==PNG_COLOR_TYPE_RGB_ALPHA) printf("Type RGBA\n");
|
||||
else if (color_type==PNG_COLOR_TYPE_PALETTE) printf("Type palette\n");
|
||||
printf("Generating output size %d x %d\n",*xsize,*ysize);
|
||||
}
|
||||
|
||||
// number_of_passes = png_set_interlace_handling(png_ptr);
|
||||
png_read_update_info(png_ptr, info_ptr);
|
||||
|
||||
row_pointers = (png_bytep*) malloc(sizeof(png_bytep) * height);
|
||||
for (y=0; y<height; y++) {
|
||||
/* FIXME: do we ever free these? */
|
||||
row_pointers[y] = (png_byte*) malloc(png_get_rowbytes(png_ptr,info_ptr));
|
||||
}
|
||||
|
||||
png_read_image(png_ptr, row_pointers);
|
||||
|
||||
fclose(infile);
|
||||
|
||||
image=calloc(width*height,sizeof(unsigned char));
|
||||
if (image==NULL) {
|
||||
fprintf(stderr,"Memory error!\n");
|
||||
return -1;
|
||||
}
|
||||
out_ptr=image;
|
||||
|
||||
if (color_type==PNG_COLOR_TYPE_RGB_ALPHA) {
|
||||
for(y=ystart;y<height;y+=yadd) {
|
||||
for(x=0;x<width;x+=xadd) {
|
||||
|
||||
/* top color */
|
||||
color= (row_pointers[y][x*xadd*4]<<16)+
|
||||
(row_pointers[y][x*xadd*4+1]<<8)+
|
||||
(row_pointers[y][x*xadd*4+2]);
|
||||
if (debug) {
|
||||
printf("%x ",color);
|
||||
}
|
||||
|
||||
a2_color=convert_color(color,filename);
|
||||
|
||||
*out_ptr=a2_color;
|
||||
out_ptr++;
|
||||
}
|
||||
if (debug) printf("\n");
|
||||
}
|
||||
}
|
||||
else if (color_type==PNG_COLOR_TYPE_PALETTE) {
|
||||
for(y=ystart;y<height;y+=yadd) {
|
||||
for(x=0;x<width;x+=xadd) {
|
||||
|
||||
if (bit_depth==8) {
|
||||
/* top color */
|
||||
a2_color=row_pointers[y][x];
|
||||
|
||||
/* bottom color */
|
||||
// color=row_pointers[y+(yadd/2)][x];
|
||||
|
||||
// a2_color|=(color<<4);
|
||||
|
||||
if (debug) {
|
||||
printf("%x ",a2_color);
|
||||
}
|
||||
|
||||
*out_ptr=a2_color;
|
||||
out_ptr++;
|
||||
}
|
||||
else if (bit_depth==4) {
|
||||
/* top color */
|
||||
a2_color=row_pointers[y][x/2];
|
||||
if (x%2==0) {
|
||||
a2_color=(a2_color>>4);
|
||||
}
|
||||
a2_color&=0xf;
|
||||
|
||||
// /* bottom color */
|
||||
// color=row_pointers[y+(yadd/2)][x/2];
|
||||
// if (x%2==0) {
|
||||
// color=(color>>4);
|
||||
// }
|
||||
// color&=0xf;
|
||||
|
||||
// a2_color|=(color<<4);
|
||||
|
||||
if (debug) {
|
||||
printf("%x ",a2_color);
|
||||
}
|
||||
|
||||
*out_ptr=a2_color;
|
||||
out_ptr++;
|
||||
|
||||
}
|
||||
}
|
||||
if (debug) printf("\n");
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf("Unknown color type\n");
|
||||
}
|
||||
|
||||
*image_ptr=image;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
#define PNG_WHOLETHING 0
|
||||
#define PNG_ODDLINES 1
|
||||
#define PNG_EVENLINES 2
|
||||
|
||||
int loadpng(char *filename, unsigned char **image_ptr, int *xsize, int *ysize,
|
||||
int png_type);
|
||||
int loadpng80(char *filename, unsigned char **image_ptr, int *xsize, int *ysize,
|
||||
int png_type);
|
||||
|
|
@ -0,0 +1,188 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "loadpng.h"
|
||||
|
||||
|
||||
/* converts a png of map to format by our duke engine */
|
||||
|
||||
/* 1280x200 image */
|
||||
/* 256 sprites of size 2x4 in a 16x16 grid at 8,4 */
|
||||
|
||||
|
||||
static unsigned char tiles[256][2][4];
|
||||
static unsigned char tilemap[256][40];
|
||||
static unsigned char temp_tile[2][4];
|
||||
|
||||
static int ascii_output=0;
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
int i,j,x,y;
|
||||
int numtiles=0,found_tile;
|
||||
|
||||
unsigned char *image;
|
||||
int xsize,ysize;
|
||||
FILE *outfile;
|
||||
|
||||
if (argc<3) {
|
||||
fprintf(stderr,"Usage:\t%s INFILE OUTFILE\n\n",argv[0]);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
outfile=fopen(argv[2],"w");
|
||||
if (outfile==NULL) {
|
||||
fprintf(stderr,"Error! Could not open %s\n",argv[2]);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (loadpng(argv[1],&image,&xsize,&ysize,PNG_WHOLETHING)<0) {
|
||||
fprintf(stderr,"Error loading png!\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
fprintf(stderr,"Loaded image %d by %d\n",xsize,ysize);
|
||||
|
||||
// for(x=0;x<128;x++) {
|
||||
// for(y=0;y<64;y++) {
|
||||
// printf("%02X,",image[(y*xsize)+x]);
|
||||
// }
|
||||
// printf("\n");
|
||||
// }
|
||||
|
||||
/* loading tiles */
|
||||
for(x=0;x<16;x++) {
|
||||
for(y=0;y<16;y++) {
|
||||
tiles[(y*16)+x][0][0]=image[((y*4+4)*xsize)+8+(x*4)];
|
||||
tiles[(y*16)+x][1][0]=image[((y*4+4)*xsize)+8+(x*4)+2];
|
||||
tiles[(y*16)+x][0][1]=image[((y*4+5)*xsize)+8+(x*4)];
|
||||
tiles[(y*16)+x][1][1]=image[((y*4+5)*xsize)+8+(x*4)+2];
|
||||
tiles[(y*16)+x][0][2]=image[((y*4+6)*xsize)+8+(x*4)];
|
||||
tiles[(y*16)+x][1][2]=image[((y*4+6)*xsize)+8+(x*4)+2];
|
||||
tiles[(y*16)+x][0][3]=image[((y*4+7)*xsize)+8+(x*4)];
|
||||
tiles[(y*16)+x][1][3]=image[((y*4+7)*xsize)+8+(x*4)+2];
|
||||
}
|
||||
}
|
||||
|
||||
i=0;
|
||||
for(j=0;j<256;j++) {
|
||||
if ((tiles[j][0][0]!=0) ||
|
||||
(tiles[j][1][0]!=0) ||
|
||||
(tiles[j][0][1]!=0) ||
|
||||
(tiles[j][1][1]!=0) ||
|
||||
(tiles[j][0][2]!=0) ||
|
||||
(tiles[j][1][2]!=0) ||
|
||||
(tiles[j][0][3]!=0) ||
|
||||
(tiles[j][1][3]!=0)) {
|
||||
numtiles=j+1;
|
||||
}
|
||||
}
|
||||
|
||||
printf("Found %d tiles\n",numtiles);
|
||||
|
||||
if (ascii_output) {
|
||||
fprintf(outfile,"tiles:\n");
|
||||
for(i=0;i<numtiles;i++) {
|
||||
fprintf(outfile,"tile%02x:\t.byte ",i);
|
||||
fprintf(outfile,"$%02x,",tiles[i][0][0]+(tiles[i][0][1]<<4));
|
||||
fprintf(outfile,"$%02x,",tiles[i][1][0]+(tiles[i][1][1]<<4));
|
||||
fprintf(outfile,"$%02x,",tiles[i][0][2]+(tiles[i][0][3]<<4));
|
||||
fprintf(outfile,"$%02x" ,tiles[i][1][2]+(tiles[i][1][3]<<4));
|
||||
fprintf(outfile,"\n");
|
||||
}
|
||||
}
|
||||
else {
|
||||
for(i=0;i<256;i++) {
|
||||
fputc(tiles[i][0][0]+(tiles[i][0][1]<<4),outfile);
|
||||
fputc(tiles[i][1][0]+(tiles[i][1][1]<<4),outfile);
|
||||
fputc(tiles[i][0][2]+(tiles[i][0][3]<<4),outfile);
|
||||
fputc(tiles[i][1][2]+(tiles[i][1][3]<<4),outfile);
|
||||
}
|
||||
}
|
||||
|
||||
if (ascii_output) fprintf(outfile,"\n");
|
||||
|
||||
/* loading tilemap */
|
||||
|
||||
/* starts at 80,12 */
|
||||
|
||||
for(x=0;x<256;x++) {
|
||||
for(y=0;y<40;y++) {
|
||||
/* get temp tile */
|
||||
temp_tile[0][0]=image[((y*4+12)*xsize)+80+(x*4)];
|
||||
temp_tile[1][0]=image[((y*4+12)*xsize)+80+(x*4)+2];
|
||||
temp_tile[0][1]=image[((y*4+13)*xsize)+80+(x*4)];
|
||||
temp_tile[1][1]=image[((y*4+13)*xsize)+80+(x*4)+2];
|
||||
temp_tile[0][2]=image[((y*4+14)*xsize)+80+(x*4)];
|
||||
temp_tile[1][2]=image[((y*4+14)*xsize)+80+(x*4)+2];
|
||||
temp_tile[0][3]=image[((y*4+15)*xsize)+80+(x*4)];
|
||||
temp_tile[1][3]=image[((y*4+15)*xsize)+80+(x*4)+2];
|
||||
|
||||
/* find tile */
|
||||
|
||||
found_tile=-1;
|
||||
|
||||
/* if all black, assume transparent */
|
||||
if ((temp_tile[0][0]==0) &&
|
||||
(temp_tile[1][0]==0) &&
|
||||
(temp_tile[0][1]==0) &&
|
||||
(temp_tile[1][1]==0) &&
|
||||
(temp_tile[0][2]==0) &&
|
||||
(temp_tile[1][2]==0) &&
|
||||
(temp_tile[0][3]==0) &&
|
||||
(temp_tile[1][3]==0)) {
|
||||
found_tile=0;
|
||||
}
|
||||
else for(i=0;i<numtiles;i++) {
|
||||
|
||||
if ((temp_tile[0][0]==tiles[i][0][0]) &&
|
||||
(temp_tile[1][0]==tiles[i][1][0]) &&
|
||||
(temp_tile[0][1]==tiles[i][0][1]) &&
|
||||
(temp_tile[1][1]==tiles[i][1][1]) &&
|
||||
(temp_tile[0][2]==tiles[i][0][2]) &&
|
||||
(temp_tile[1][2]==tiles[i][1][2]) &&
|
||||
(temp_tile[0][3]==tiles[i][0][3]) &&
|
||||
(temp_tile[1][3]==tiles[i][1][3])) {
|
||||
found_tile=i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
tilemap[x][y]=found_tile;
|
||||
if (found_tile==-1) {
|
||||
printf("Error! Unknown tile at %d,%d\n",
|
||||
80+(x*4),12+(y*4));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ascii_output) {
|
||||
fprintf(outfile,"tilemap:\n");
|
||||
|
||||
for(j=0;j<40;j++) {
|
||||
fprintf(outfile,"\t.byte ");
|
||||
for(i=0;i<256;i++) {
|
||||
fprintf(outfile,"$%02x",tilemap[i][j]);
|
||||
if (i!=255) fprintf(outfile,",");
|
||||
}
|
||||
fprintf(outfile,"\n");
|
||||
}
|
||||
|
||||
fprintf(outfile,"\n");
|
||||
}
|
||||
else {
|
||||
for(j=0;j<40;j++) {
|
||||
for(i=0;i<256;i++) {
|
||||
fputc(tilemap[i][j],outfile);
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose(outfile);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,394 @@
|
|||
|
||||
KEEN_SPEED = $80
|
||||
|
||||
YDEFAULT = 20
|
||||
|
||||
HARD_TILES = 32 ; start at 32
|
||||
|
||||
;=========================
|
||||
; move keen
|
||||
;=========================
|
||||
move_keen:
|
||||
|
||||
lda #0
|
||||
sta SUPPRESS_WALK
|
||||
|
||||
jsr keen_get_feet_location ; get location of feet
|
||||
|
||||
jsr check_falling ; check for/handle falling
|
||||
|
||||
jsr keen_collide ; check for right/left collision
|
||||
|
||||
jsr handle_jumping ; handle jumping
|
||||
|
||||
lda KEEN_WALKING
|
||||
beq done_move_keen
|
||||
|
||||
lda SUPPRESS_WALK
|
||||
bne done_move_keen
|
||||
|
||||
lda KEEN_DIRECTION
|
||||
bmi move_left
|
||||
|
||||
lda KEEN_X
|
||||
cmp #22
|
||||
bcc keen_walk_right
|
||||
|
||||
keen_scroll_right:
|
||||
|
||||
clc
|
||||
lda KEEN_XL
|
||||
adc #KEEN_SPEED
|
||||
sta KEEN_XL
|
||||
bcc skip_keen_scroll_right
|
||||
|
||||
inc TILEMAP_X
|
||||
|
||||
jsr copy_tilemap_subset
|
||||
|
||||
skip_keen_scroll_right:
|
||||
|
||||
jmp done_move_keen
|
||||
|
||||
keen_walk_right:
|
||||
lda KEEN_XL
|
||||
clc
|
||||
adc #KEEN_SPEED
|
||||
sta KEEN_XL
|
||||
bcc dwr_noflo
|
||||
inc KEEN_X
|
||||
dwr_noflo:
|
||||
jmp done_move_keen
|
||||
|
||||
move_left:
|
||||
|
||||
lda KEEN_X
|
||||
cmp #14
|
||||
bcs keen_walk_left
|
||||
|
||||
keen_scroll_left:
|
||||
|
||||
sec
|
||||
lda KEEN_XL
|
||||
sbc #KEEN_SPEED
|
||||
sta KEEN_XL
|
||||
bcs skip_keen_scroll_left
|
||||
|
||||
dec TILEMAP_X
|
||||
|
||||
jsr copy_tilemap_subset
|
||||
|
||||
skip_keen_scroll_left:
|
||||
|
||||
jmp done_move_keen
|
||||
|
||||
keen_walk_left:
|
||||
|
||||
lda KEEN_XL
|
||||
sec
|
||||
sbc #KEEN_SPEED
|
||||
sta KEEN_XL
|
||||
bcs dwl_noflo
|
||||
dec KEEN_X
|
||||
dwl_noflo:
|
||||
jmp done_move_keen
|
||||
|
||||
done_move_keen:
|
||||
|
||||
rts
|
||||
|
||||
|
||||
|
||||
;=========================
|
||||
; keen collide
|
||||
;=========================
|
||||
|
||||
keen_collide:
|
||||
;==================
|
||||
; check for item
|
||||
;==================
|
||||
keen_check_item:
|
||||
lda KEEN_FOOT_OFFSET
|
||||
sec
|
||||
sbc #16
|
||||
tax
|
||||
|
||||
jsr check_item
|
||||
|
||||
|
||||
;===================
|
||||
; collide with head
|
||||
;===================
|
||||
keen_check_head:
|
||||
; only check above head if jumping
|
||||
lda KEEN_JUMPING
|
||||
beq collide_left_right
|
||||
|
||||
lda KEEN_FOOT_OFFSET
|
||||
sec
|
||||
sbc #16 ; above head is -2 rows
|
||||
tax
|
||||
|
||||
lda TILEMAP,X
|
||||
|
||||
; if tile# < HARD_TILES then we are fine
|
||||
cmp #HARD_TILES
|
||||
bcc collide_left_right ; blt
|
||||
|
||||
lda #0
|
||||
sta KEEN_JUMPING
|
||||
lda #1
|
||||
sta KEEN_FALLING
|
||||
|
||||
jsr head_noise
|
||||
|
||||
collide_left_right:
|
||||
;===================
|
||||
; collide left/right
|
||||
;===================
|
||||
|
||||
lda KEEN_DIRECTION
|
||||
beq done_keen_collide
|
||||
|
||||
bmi check_left_collide
|
||||
|
||||
check_right_collide:
|
||||
lda KEEN_FOOT_OFFSET
|
||||
clc
|
||||
adc #1 ; right is one to right
|
||||
|
||||
tax
|
||||
lda TILEMAP,X
|
||||
|
||||
; if tile# < HARD_TILES then we are fine
|
||||
cmp #HARD_TILES
|
||||
bcc done_keen_collide ; blt
|
||||
|
||||
lda #1 ;
|
||||
sta SUPPRESS_WALK
|
||||
jmp done_keen_collide
|
||||
|
||||
check_left_collide:
|
||||
|
||||
lda KEEN_FOOT_OFFSET
|
||||
sec
|
||||
sbc #2 ; left is one to left
|
||||
; +1 fudge factor
|
||||
tax
|
||||
lda TILEMAP,X
|
||||
|
||||
; if tile# < HARD_TILES then we are fine
|
||||
cmp #HARD_TILES
|
||||
bcc done_keen_collide ; blt
|
||||
|
||||
lda #1
|
||||
sta SUPPRESS_WALK
|
||||
jmp done_keen_collide
|
||||
|
||||
done_keen_collide:
|
||||
rts
|
||||
|
||||
|
||||
|
||||
;=========================
|
||||
; check_jumping
|
||||
;=========================
|
||||
handle_jumping:
|
||||
|
||||
lda KEEN_JUMPING
|
||||
beq done_handle_jumping
|
||||
|
||||
lda KEEN_Y
|
||||
beq dont_wrap_jump
|
||||
|
||||
dec KEEN_Y
|
||||
dec KEEN_Y
|
||||
|
||||
dont_wrap_jump:
|
||||
dec KEEN_JUMPING
|
||||
bne done_handle_jumping
|
||||
lda #1 ; avoid gap before falling triggered
|
||||
sta KEEN_FALLING
|
||||
|
||||
|
||||
done_handle_jumping:
|
||||
rts
|
||||
|
||||
|
||||
|
||||
|
||||
;=======================
|
||||
; keen_get_feet_location
|
||||
;=======================
|
||||
|
||||
; xx 0
|
||||
; xx 1
|
||||
;------ -----
|
||||
; xx 0 xx 2
|
||||
; xx 1 xx 3
|
||||
; xx 2 xx 4
|
||||
; xx 3 xx 5
|
||||
;------ -------
|
||||
; xx 4 xx 6
|
||||
; xx 5 xx 7
|
||||
; xx 6
|
||||
; xx 7
|
||||
;-----------------------
|
||||
|
||||
|
||||
; YY = block
|
||||
;========================
|
||||
; YYYY YYYY
|
||||
; -XX- -XX-
|
||||
; -XX- -XX-
|
||||
; left, foot = (X+1)/2
|
||||
; right, foot = (X+2)/2
|
||||
keen_get_feet_location:
|
||||
|
||||
; + 1 is because sprite is 4 pixels wide?
|
||||
|
||||
; screen is 16 wide, but offset 4 in
|
||||
|
||||
; to get to feet add 6 to Y?
|
||||
|
||||
; block index of foot is (feet approximately 6 lower than Y)
|
||||
; INT((y+4)/4)*16 + (x-4+1/2)
|
||||
|
||||
; FIXME: if 18,18 -> INT(26/4)*16 = 96 + 7 = 103 = 6R7
|
||||
|
||||
; 0 = 32 (2)
|
||||
; 1 = 32 (2)
|
||||
; 2 = 32 (2)
|
||||
; 3 = 32 (2)
|
||||
; 4 = 48 (3)
|
||||
; 5 = 48 (3)
|
||||
; 6 = 48 (3)
|
||||
; 7 = 48 (3)
|
||||
|
||||
lda KEEN_Y
|
||||
|
||||
clc
|
||||
adc #4 ; +4
|
||||
|
||||
lsr ; / 4 (INT)
|
||||
lsr
|
||||
|
||||
asl ; *4
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
|
||||
sta KEEN_FOOT_OFFSET
|
||||
|
||||
; lda KEEN_DIRECTION
|
||||
; bmi foot_left
|
||||
|
||||
foot_right:
|
||||
|
||||
lda KEEN_X
|
||||
clc
|
||||
adc #2
|
||||
; jmp foot_done
|
||||
|
||||
;foot_left:
|
||||
; lda KEEN_X
|
||||
; sec
|
||||
; sbc #1
|
||||
|
||||
foot_done:
|
||||
lsr
|
||||
|
||||
; offset by two block at edge of screen
|
||||
sec
|
||||
sbc #2
|
||||
|
||||
clc
|
||||
adc KEEN_FOOT_OFFSET
|
||||
sta KEEN_FOOT_OFFSET
|
||||
|
||||
rts
|
||||
|
||||
|
||||
;=========================
|
||||
; check_falling
|
||||
;=========================
|
||||
check_falling:
|
||||
|
||||
lda KEEN_JUMPING
|
||||
bne done_check_falling ; don't check falling if jumping
|
||||
|
||||
lda KEEN_FOOT_OFFSET
|
||||
clc
|
||||
adc #16 ; underfoot is on next row (+16)
|
||||
|
||||
tax
|
||||
lda TILEMAP,X
|
||||
|
||||
; if tile# < HARD_TILES then we fall
|
||||
cmp #HARD_TILES
|
||||
bcs feet_on_ground ; bge
|
||||
|
||||
;=======================
|
||||
; falling
|
||||
|
||||
lda #1
|
||||
sta KEEN_FALLING
|
||||
|
||||
; scroll but only if Y>=20 (YDEFAULT)
|
||||
|
||||
lda KEEN_Y
|
||||
cmp #YDEFAULT
|
||||
bcs scroll_fall ; bge
|
||||
|
||||
inc KEEN_Y
|
||||
inc KEEN_Y
|
||||
jmp done_check_falling
|
||||
|
||||
|
||||
scroll_fall:
|
||||
inc TILEMAP_Y
|
||||
|
||||
jsr copy_tilemap_subset
|
||||
jmp done_check_falling
|
||||
|
||||
feet_on_ground:
|
||||
|
||||
;===========================
|
||||
; if had been falling
|
||||
; kick up dust, make noise
|
||||
; stop walking?
|
||||
|
||||
lda KEEN_FALLING
|
||||
beq was_not_falling
|
||||
|
||||
; clear falling
|
||||
lda #0
|
||||
sta KEEN_FALLING
|
||||
|
||||
lda #2
|
||||
sta KICK_UP_DUST
|
||||
|
||||
lda #0
|
||||
sta KEEN_WALKING
|
||||
|
||||
jsr land_noise
|
||||
|
||||
was_not_falling:
|
||||
; check to see if Y still hi, if so scroll back down
|
||||
|
||||
lda KEEN_Y
|
||||
cmp #YDEFAULT
|
||||
bcs done_check_falling ; bge
|
||||
|
||||
; too high up on screen, adjust down and also adjust tilemap down
|
||||
|
||||
inc KEEN_Y
|
||||
inc KEEN_Y
|
||||
dec TILEMAP_Y ; share w above?
|
||||
jsr copy_tilemap_subset
|
||||
|
||||
done_check_falling:
|
||||
rts
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
; Quit? Are you sure?
|
||||
|
||||
print_quit:
|
||||
bit KEYRESET ; clear keyboard
|
||||
bit SET_TEXT
|
||||
|
||||
lda #' '|$80
|
||||
sta clear_all_color+1
|
||||
jsr clear_all
|
||||
|
||||
lda #6
|
||||
sta drawbox_x1
|
||||
lda #33
|
||||
sta drawbox_x2
|
||||
lda #8
|
||||
sta drawbox_y1
|
||||
lda #13
|
||||
sta drawbox_y2
|
||||
jsr drawbox
|
||||
|
||||
jsr normal_text
|
||||
|
||||
lda #<quit_text
|
||||
sta OUTL
|
||||
lda #>quit_text
|
||||
sta OUTH
|
||||
jsr move_and_print_list
|
||||
|
||||
jsr page_flip
|
||||
|
||||
query_quit:
|
||||
lda KEYPRESS
|
||||
bpl query_quit
|
||||
bit KEYRESET
|
||||
|
||||
cmp #'Y'|$80
|
||||
beq really_quit
|
||||
cmp #'y'|$80
|
||||
beq really_quit
|
||||
|
||||
bit SET_GR
|
||||
rts
|
||||
|
||||
really_quit:
|
||||
lda #GAME_OVER
|
||||
sta LEVEL_OVER
|
||||
|
||||
lda #LOAD_TITLE
|
||||
sta WHICH_LOAD
|
||||
|
||||
rts
|
||||
|
||||
quit_text:
|
||||
.byte 8,10,"ARE YOU SURE YOU WANT TO",0
|
||||
.byte 14,11,"QUIT? (Y/N)",0
|
||||
.byte 255
|
|
@ -0,0 +1,149 @@
|
|||
;======================
|
||||
; noise when jump
|
||||
jump_noise:
|
||||
|
||||
lda SOUND_STATUS
|
||||
bmi done_jump_noise
|
||||
|
||||
; bit $C030
|
||||
|
||||
done_jump_noise:
|
||||
rts
|
||||
|
||||
|
||||
;======================
|
||||
; noise when bump head
|
||||
head_noise:
|
||||
|
||||
lda SOUND_STATUS
|
||||
bmi done_head_noise
|
||||
|
||||
lda #NOTE_D3
|
||||
sta speaker_frequency
|
||||
lda #5
|
||||
sta speaker_duration
|
||||
jsr speaker_tone
|
||||
|
||||
|
||||
; bit $C030
|
||||
; bit $C030
|
||||
|
||||
done_head_noise:
|
||||
rts
|
||||
|
||||
|
||||
;======================
|
||||
; noise when land after jump
|
||||
land_noise:
|
||||
|
||||
lda SOUND_STATUS
|
||||
bmi done_land_noise
|
||||
|
||||
; bit $C030
|
||||
|
||||
done_land_noise:
|
||||
rts
|
||||
|
||||
|
||||
;======================
|
||||
; rumble noise
|
||||
rumble_noise:
|
||||
|
||||
lda SOUND_STATUS
|
||||
bmi done_rumble_noise
|
||||
|
||||
ldx #50
|
||||
rumble_red:
|
||||
bit $C030
|
||||
lda #100
|
||||
jsr WAIT
|
||||
dex
|
||||
bne rumble_red
|
||||
|
||||
done_rumble_noise:
|
||||
rts
|
||||
|
||||
|
||||
;======================
|
||||
; pickup noise
|
||||
; C, two octaves+C?
|
||||
pickup_noise:
|
||||
|
||||
lda SOUND_STATUS
|
||||
bmi done_pickup_noise
|
||||
|
||||
lda #NOTE_C3
|
||||
sta speaker_frequency
|
||||
lda #25
|
||||
sta speaker_duration
|
||||
jsr speaker_tone
|
||||
|
||||
lda #NOTE_C5
|
||||
sta speaker_frequency
|
||||
lda #20
|
||||
sta speaker_duration
|
||||
jsr speaker_tone
|
||||
|
||||
done_pickup_noise:
|
||||
rts
|
||||
|
||||
|
||||
;======================
|
||||
; buzzer noise
|
||||
; C, two octaves+C?
|
||||
buzzer_noise:
|
||||
|
||||
lda SOUND_STATUS
|
||||
bmi done_buzzer_noise
|
||||
|
||||
lda #NOTE_C3
|
||||
sta speaker_frequency
|
||||
lda #10
|
||||
sta speaker_duration
|
||||
jsr speaker_tone
|
||||
|
||||
done_buzzer_noise:
|
||||
rts
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
;======================
|
||||
; enemy noise
|
||||
enemy_noise:
|
||||
|
||||
lda SOUND_STATUS
|
||||
bmi done_enemy_noise
|
||||
|
||||
lda #NOTE_A3
|
||||
sta speaker_frequency
|
||||
lda #20
|
||||
sta speaker_duration
|
||||
jsr speaker_tone
|
||||
|
||||
lda #NOTE_A4
|
||||
sta speaker_frequency
|
||||
lda #10
|
||||
sta speaker_duration
|
||||
jsr speaker_tone
|
||||
|
||||
done_enemy_noise:
|
||||
rts
|
||||
|
||||
;======================
|
||||
; laser noise
|
||||
laser_noise:
|
||||
|
||||
lda SOUND_STATUS
|
||||
bmi done_enemy_noise
|
||||
|
||||
lda #NOTE_D4
|
||||
sta speaker_frequency
|
||||
lda #15
|
||||
sta speaker_duration
|
||||
jsr speaker_tone
|
||||
|
||||
done_laser_noise:
|
||||
rts
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
; based on code from here
|
||||
; http://eightbitsoundandfury.ld8.org/programming.html
|
||||
|
||||
; A,X,Y trashed
|
||||
; duration also trashed
|
||||
|
||||
NOTE_C3 = 255
|
||||
NOTE_CSHARP3 = 241
|
||||
NOTE_D3 = 227
|
||||
NOTE_DSHARP3 = 214
|
||||
NOTE_E3 = 202
|
||||
NOTE_F3 = 191
|
||||
NOTE_FSHARP3 = 180
|
||||
NOTE_G3 = 170
|
||||
NOTE_GSHARP3 = 161
|
||||
NOTE_A3 = 152
|
||||
NOTE_ASHARP3 = 143
|
||||
NOTE_B3 = 135
|
||||
|
||||
NOTE_C4 = 128
|
||||
NOTE_CSHARP4 = 121
|
||||
NOTE_D4 = 114
|
||||
NOTE_DSHARP4 = 108
|
||||
NOTE_E4 = 102
|
||||
NOTE_F4 = 96
|
||||
NOTE_FSHARP4 = 91
|
||||
NOTE_G4 = 85
|
||||
NOTE_GSHARP4 = 81
|
||||
NOTE_A4 = 76
|
||||
NOTE_ASHARP4 = 72
|
||||
NOTE_B4 = 68
|
||||
|
||||
NOTE_C5 = 64
|
||||
NOTE_CSHARP5 = 60
|
||||
NOTE_D5 = 57
|
||||
NOTE_DSHARP5 = 54
|
||||
NOTE_E5 = 51
|
||||
NOTE_F5 = 48
|
||||
NOTE_FSHARP5 = 45
|
||||
NOTE_G5 = 43
|
||||
NOTE_GSHARP5 = 40
|
||||
NOTE_A5 = 38
|
||||
NOTE_ASHARP5 = 36
|
||||
NOTE_B5 = 34
|
||||
|
||||
|
||||
|
||||
speaker_tone:
|
||||
lda $C030 ; click speaker
|
||||
speaker_loop:
|
||||
dey ; y never set?
|
||||
bne slabel1 ; duration roughly 256*?
|
||||
dec speaker_duration ; (Duration)
|
||||
beq done_tone
|
||||
slabel1:
|
||||
dex
|
||||
bne speaker_loop
|
||||
ldx speaker_frequency ; (Frequency)
|
||||
jmp speaker_tone
|
||||
done_tone:
|
||||
rts
|
||||
|
||||
speaker_duration:
|
||||
.byte $00
|
||||
speaker_frequency:
|
||||
.byte $00
|
||||
|
|
@ -0,0 +1,177 @@
|
|||
; Draw Status Bar
|
||||
|
||||
;===========================
|
||||
; inc_score_by_10
|
||||
;===========================
|
||||
; FIXME: make sure interrupt routine handles d flag properly
|
||||
inc_score_by_10:
|
||||
|
||||
sed
|
||||
lda SCORE0
|
||||
clc
|
||||
adc #$10
|
||||
sta SCORE0
|
||||
|
||||
lda SCORE1
|
||||
adc #0
|
||||
sta SCORE1
|
||||
|
||||
lda SCORE2
|
||||
adc #0
|
||||
sta SCORE2
|
||||
cld
|
||||
|
||||
jsr update_score
|
||||
|
||||
rts
|
||||
|
||||
;===========================
|
||||
; update score
|
||||
;===========================
|
||||
|
||||
update_score:
|
||||
|
||||
lda SCORE0
|
||||
and #$f
|
||||
ora #$b0 ; 0 -> $b0
|
||||
sta status_string+6
|
||||
|
||||
lda SCORE0
|
||||
lsr
|
||||
lsr
|
||||
lsr
|
||||
lsr
|
||||
ora #$b0 ; 0 -> $b0
|
||||
sta status_string+5
|
||||
|
||||
lda SCORE1
|
||||
and #$f
|
||||
ora #$b0 ; 0 -> $b0
|
||||
sta status_string+4
|
||||
|
||||
lda SCORE1
|
||||
lsr
|
||||
lsr
|
||||
lsr
|
||||
lsr
|
||||
ora #$b0 ; 0 -> $b0
|
||||
sta status_string+3
|
||||
|
||||
lda SCORE2
|
||||
and #$f
|
||||
ora #$b0 ; 0 -> $b0
|
||||
sta status_string+2
|
||||
|
||||
lda #2
|
||||
sta UPDATE_STATUS
|
||||
|
||||
rts
|
||||
|
||||
|
||||
;===========================
|
||||
; update health
|
||||
;===========================
|
||||
|
||||
update_health:
|
||||
|
||||
ldx #0
|
||||
update_health_loop:
|
||||
cpx HEALTH
|
||||
bcc health_on
|
||||
lda #'_'|$80
|
||||
bne done_health
|
||||
health_on:
|
||||
lda #' '
|
||||
done_health:
|
||||
sta status_string+9,X
|
||||
|
||||
inx
|
||||
cpx #8
|
||||
bne update_health_loop
|
||||
|
||||
rts
|
||||
|
||||
;===========================
|
||||
; update items
|
||||
;===========================
|
||||
|
||||
update_items:
|
||||
|
||||
lda INVENTORY
|
||||
|
||||
and #INV_RED_KEY
|
||||
beq done_red_key
|
||||
|
||||
lda #'R'&$3f
|
||||
sta status_string+33
|
||||
|
||||
done_red_key:
|
||||
|
||||
lda INVENTORY
|
||||
|
||||
and #INV_BLUE_KEY
|
||||
beq done_blue_key
|
||||
|
||||
lda #'B'&$3f
|
||||
sta status_string+35
|
||||
|
||||
done_blue_key:
|
||||
|
||||
rts
|
||||
|
||||
|
||||
|
||||
|
||||
;===========================
|
||||
; update the status bar
|
||||
;===========================
|
||||
update_status_bar:
|
||||
|
||||
jsr update_score
|
||||
|
||||
jsr update_health
|
||||
|
||||
jsr update_items
|
||||
|
||||
lda #2
|
||||
sta UPDATE_STATUS
|
||||
|
||||
rts
|
||||
|
||||
;===========================
|
||||
; draw the status bar
|
||||
;===========================
|
||||
draw_status_bar:
|
||||
|
||||
; to improve frame rate, only draw if update status set?
|
||||
; not implemented yet
|
||||
|
||||
jsr inverse_text ; print help node
|
||||
lda #<help_string
|
||||
sta OUTL
|
||||
lda #>help_string
|
||||
sta OUTH
|
||||
jsr move_and_print
|
||||
|
||||
jsr normal_text ; (normal)
|
||||
jsr move_and_print ; print explain text
|
||||
jsr raw_text
|
||||
jsr move_and_print ; print status line
|
||||
rts
|
||||
|
||||
|
||||
help_string:
|
||||
.byte 3,20," PRESS 'H' FOR HELP ",0
|
||||
|
||||
score_string:
|
||||
; 012456789012345678901234567890123456789
|
||||
.byte 0,22,"SCORE HEALTH FIREPOWER INVENTORY",0
|
||||
status_string:
|
||||
; .byte 0,23,"ZZZZZ XXXXXXXX =- ",0
|
||||
.byte 0,23,"ZZZZZ"
|
||||
.byte ' '|$80,' '|$80
|
||||
.byte "XXXXXXXX"
|
||||
.byte ' '|$80,' '|$80
|
||||
.byte '='|$80,'-'|$80,' '|$80,' '|$80,' '|$80,' '|$80,' '|$80,' '|$80,' '|$80,' '|$80
|
||||
.byte ' '|$80,' '|$80,' '|$80,' '|$80,' '|$80,' '|$80,' '|$80,' '|$80,' '|$80,' '|$80,' '|$80,' '|$80,0
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
; draw inverse box on text screen
|
||||
|
||||
; we could use HLIN/VLIN instead?
|
||||
|
||||
; note Y should be in text coords (0..23) not GR (0..47)
|
||||
|
||||
drawbox:
|
||||
lda drawbox_y1
|
||||
jsr text_hlin
|
||||
lda drawbox_y2
|
||||
jsr text_hlin
|
||||
|
||||
jsr text_vlins
|
||||
|
||||
rts
|
||||
|
||||
;========================
|
||||
; text hlin
|
||||
;========================
|
||||
; draw from x1,A to x2,A
|
||||
|
||||
text_hlin:
|
||||
asl
|
||||
tay
|
||||
|
||||
lda gr_offsets,Y
|
||||
sta OUTL
|
||||
|
||||
lda gr_offsets+1,Y
|
||||
clc
|
||||
adc DRAW_PAGE
|
||||
sta OUTH
|
||||
|
||||
lda #' '
|
||||
ldy drawbox_x1
|
||||
drawbox_hlin_loop:
|
||||
sta (OUTL),Y
|
||||
iny
|
||||
cpy drawbox_x2
|
||||
bne drawbox_hlin_loop
|
||||
|
||||
rts
|
||||
|
||||
;========================
|
||||
; text vlin
|
||||
;========================
|
||||
; draw from A,y1 to A,y2
|
||||
|
||||
text_vlins:
|
||||
|
||||
ldx drawbox_y1
|
||||
|
||||
text_vlins_loop:
|
||||
txa
|
||||
asl
|
||||
tay
|
||||
lda gr_offsets,Y
|
||||
sta OUTL
|
||||
|
||||
lda gr_offsets+1,Y
|
||||
clc
|
||||
adc DRAW_PAGE
|
||||
sta OUTH
|
||||
|
||||
lda #' '
|
||||
|
||||
ldy drawbox_x1
|
||||
sta (OUTL),Y
|
||||
ldy drawbox_x2
|
||||
sta (OUTL),Y
|
||||
|
||||
inx
|
||||
cpx drawbox_y2
|
||||
bcc text_vlins_loop
|
||||
beq text_vlins_loop ; ble
|
||||
|
||||
rts
|
||||
|
||||
|
||||
drawbox_x1: .byte $00
|
||||
drawbox_x2: .byte $00
|
||||
drawbox_y1: .byte $00
|
||||
drawbox_y2: .byte $00
|
||||
|
|
@ -88,12 +88,12 @@ PATTERN_H = $7F
|
|||
|
||||
WHICH_LOAD = $80 ; which file to load
|
||||
|
||||
DUKE_XL = $81
|
||||
DUKE_X = $82 ; location of protagonist
|
||||
DUKE_Y = $83
|
||||
DUKE_DIRECTION = $84
|
||||
DUKE_WALKING = $85
|
||||
DUKE_JUMPING = $86
|
||||
KEEN_XL = $81
|
||||
KEEN_X = $82 ; location of protagonist
|
||||
KEEN_Y = $83
|
||||
KEEN_DIRECTION = $84
|
||||
KEEN_WALKING = $85
|
||||
KEEN_JUMPING = $86
|
||||
|
||||
LASER_OUT = $87
|
||||
LASER_X = $88
|
||||
|
@ -102,7 +102,7 @@ LASER_DIRECTION = $8A
|
|||
TILEMAP_X = $8B
|
||||
TILEMAP_Y = $8C
|
||||
|
||||
DUKE_FOOT_OFFSET = $8D
|
||||
KEEN_FOOT_OFFSET = $8D
|
||||
|
||||
FIREPOWER = $8E
|
||||
INVENTORY = $8F
|
||||
|
@ -116,8 +116,8 @@ SCORE1 = $92
|
|||
SCORE2 = $93
|
||||
UPDATE_STATUS = $94
|
||||
|
||||
DUKE_FALLING = $95
|
||||
DUKE_SHOOTING = $96
|
||||
KEEN_FALLING = $95
|
||||
KEEN_SHOOTING = $96
|
||||
KICK_UP_DUST = $97
|
||||
SUPPRESS_WALK = $98
|
||||
ENEMY_DATAL = $99
|
||||
|
|
Loading…
Reference in New Issue