mirror of
https://github.com/robmcmullen/fujirun.git
synced 2024-12-29 14:33:23 +00:00
354 lines
8.5 KiB
ArmAsm
354 lines
8.5 KiB
ArmAsm
level_enemies .byte 55, 4, 5, 6, 7, 8 ;# level starts counting from 1, so dummy zeroth level info
|
|
level_speed_l .byte 255, 200, 210, 220, 230, 240 ;# increment of fractional pixel per game frame
|
|
level_speed_h .byte 2, 2, 2, 2, 2, 2
|
|
;level_speed_h .byte 0, 0, 0, 0, 0, 0
|
|
player_score_row .byte 2, 7, 12, 17
|
|
player_lives_row .byte 3, 8, 13, 18
|
|
player_score_l .byte 0, 0, 0, 0
|
|
player_score_m .byte 0, 0, 0, 0
|
|
player_score_h .byte 0, 0, 0, 0
|
|
|
|
|
|
PLAYER_TYPE = 0
|
|
ORBITER_TYPE = 1
|
|
AMIDAR_TYPE = 2
|
|
actor_type .byte PLAYER_TYPE, PLAYER_TYPE, PLAYER_TYPE, PLAYER_TYPE
|
|
.byte ORBITER_TYPE, AMIDAR_TYPE, AMIDAR_TYPE, AMIDAR_TYPE
|
|
.byte AMIDAR_TYPE, AMIDAR_TYPE, AMIDAR_TYPE, AMIDAR_TYPE
|
|
.byte AMIDAR_TYPE, AMIDAR_TYPE, AMIDAR_TYPE, AMIDAR_TYPE
|
|
actor_init_func_l .byte <init_player, <init_orbiter, <init_amidar
|
|
actor_init_func_h .byte >init_player, >init_orbiter, >init_amidar
|
|
|
|
; Sprite data is interleaved so a simple indexed mode can be used. This is not
|
|
; convenient to set up but makes faster accessing because you don't have to
|
|
; increment the index register. For example, all the info about sprite #2 can
|
|
; be indexed using Y = 2 on the indexed operators, e.g. "lda sprite_active,y",
|
|
; "lda sprite_x,y", etc.
|
|
;
|
|
; Number of sprites must be a power of 2
|
|
|
|
source_actor_active .byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 , $ff ; 1 = active, 0 = skip
|
|
|
|
source_actor_l
|
|
.byte <APPLE_SPRITE9X11
|
|
.byte <APPLE_SPRITE9X11
|
|
.byte <APPLE_SPRITE9X11
|
|
.byte <APPLE_SPRITE9X11
|
|
.byte <ATARI_SPRITE9X11
|
|
.byte <ATARI_SPRITE9X11
|
|
.byte <ATARI_SPRITE9X11
|
|
.byte <ATARI_SPRITE9X11
|
|
.byte <ATARI_SPRITE9X11
|
|
.byte <ATARI_SPRITE9X11
|
|
.byte <ATARI_SPRITE9X11
|
|
.byte <ATARI_SPRITE9X11
|
|
.byte <ATARI_SPRITE9X11
|
|
.byte <ATARI_SPRITE9X11
|
|
.byte <ATARI_SPRITE9X11
|
|
.byte <ATARI_SPRITE9X11
|
|
|
|
source_actor_h
|
|
.byte >APPLE_SPRITE9X11
|
|
.byte >APPLE_SPRITE9X11
|
|
.byte >APPLE_SPRITE9X11
|
|
.byte >APPLE_SPRITE9X11
|
|
.byte >ATARI_SPRITE9X11
|
|
.byte >ATARI_SPRITE9X11
|
|
.byte >ATARI_SPRITE9X11
|
|
.byte >ATARI_SPRITE9X11
|
|
.byte >ATARI_SPRITE9X11
|
|
.byte >ATARI_SPRITE9X11
|
|
.byte >ATARI_SPRITE9X11
|
|
.byte >ATARI_SPRITE9X11
|
|
.byte >ATARI_SPRITE9X11
|
|
.byte >ATARI_SPRITE9X11
|
|
.byte >ATARI_SPRITE9X11
|
|
.byte >ATARI_SPRITE9X11
|
|
|
|
source_actor_x
|
|
.byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 , $ff
|
|
|
|
source_actor_y
|
|
.byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 , $ff
|
|
|
|
source_end .byte $ff
|
|
|
|
;
|
|
;# Scores
|
|
;
|
|
DOT_SCORE = $01
|
|
box_score .byte 0, $20, $40, $60, $80, $100, $120
|
|
|
|
add_score nop
|
|
sed
|
|
clc
|
|
adc player_score_l,x
|
|
sta player_score_l,x
|
|
lda player_score_m,x
|
|
adc #0
|
|
sta player_score_m,x
|
|
lda player_score_h,x
|
|
adc #0
|
|
sta player_score_h,x
|
|
cld
|
|
|
|
jsr update_score
|
|
|
|
rts
|
|
|
|
|
|
init_actors_once nop
|
|
ldx #0
|
|
?1 lda source_actor_active,x
|
|
sta actor_active,x
|
|
inx
|
|
cpx #source_end-source_actor_active
|
|
bcc ?1
|
|
rts
|
|
|
|
init_players nop
|
|
sta config_num_players
|
|
|
|
|
|
;
|
|
init_level nop
|
|
ldx level
|
|
lda level_enemies,x
|
|
tay
|
|
lda #$ff
|
|
sta actor_active+FIRST_AMIDAR,y
|
|
lda #1
|
|
?1 sta actor_active+FIRST_AMIDAR-1,y
|
|
dey
|
|
bne ?1
|
|
|
|
; clear active players
|
|
ldy #0
|
|
lda #1
|
|
?2 cpy config_num_players
|
|
bcs ?3
|
|
sta actor_active,y
|
|
iny
|
|
bne ?2
|
|
?3 lda #0
|
|
cpy #MAX_PLAYERS
|
|
bcs ?4
|
|
sta actor_active,y
|
|
iny
|
|
bne ?3
|
|
?4 rts
|
|
|
|
|
|
;
|
|
;##### Gameplay initialization
|
|
;
|
|
;def init_actor():
|
|
; # Common initialization params for all actors
|
|
; actor_col[zp.current_actor] = MAZE_LEFT_COL
|
|
; actor_xpixel[zp.current_actor] = 3
|
|
; actor_xfrac[zp.current_actor] = 0
|
|
; actor_xspeed[zp.current_actor] = 0
|
|
; actor_row[zp.current_actor] = MAZE_BOT_ROW
|
|
; actor_ypixel[zp.current_actor] = 3
|
|
; actor_yfrac[zp.current_actor] = 0
|
|
; actor_yspeed[zp.current_actor] = 0
|
|
; actor_input_dir[zp.current_actor] = 0
|
|
; actor_updown[zp.current_actor] = TILE_UP
|
|
; actor_dir[zp.current_actor] = TILE_UP
|
|
; actor_status[zp.current_actor] = NOT_VISIBLE
|
|
; actor_frame_counter[zp.current_actor] = 0
|
|
; actor_target_col[zp.current_actor] = 0
|
|
; actor_input_dir[zp.current_actor] = 0
|
|
|
|
; actor in X
|
|
init_common nop
|
|
lda #MAZE_LEFT_COL
|
|
sta actor_col,x
|
|
lda #3
|
|
sta actor_xpixel,x
|
|
sta actor_ypixel,x
|
|
lda #0
|
|
sta actor_xfrac,x
|
|
sta actor_xspeed_l,x
|
|
sta actor_xspeed_h,x
|
|
sta actor_yfrac,x
|
|
sta actor_yspeed_l,x
|
|
sta actor_yspeed_h,x
|
|
sta actor_input_dir,x
|
|
sta actor_turn_zone,x
|
|
lda #MAZE_BOT_ROW
|
|
sta actor_row,x
|
|
lda #TILE_UP
|
|
sta actor_updown,x
|
|
sta actor_dir,x
|
|
rts
|
|
|
|
init_actor nop
|
|
jsr init_common
|
|
lda #0
|
|
sta actor_frame_counter,x
|
|
sta actor_target_col,x
|
|
lda #NOT_VISIBLE
|
|
sta actor_status,x
|
|
lda #1
|
|
sta actor_active,x
|
|
rts
|
|
|
|
|
|
;def init_orbiter():
|
|
; init_actor()
|
|
; actor_col[zp.current_actor] = ORBITER_START_COL
|
|
; actor_row[zp.current_actor] = ORBITER_START_ROW
|
|
; actor_dir[zp.current_actor] = TILE_UP
|
|
; actor_status[zp.current_actor] = ORBITER_NORMAL
|
|
; set_speed(TILE_UP)
|
|
|
|
; actor in X
|
|
init_orbiter nop
|
|
jsr init_actor
|
|
lda #ORBITER_START_COL
|
|
sta actor_col,x
|
|
lda #ORBITER_START_ROW
|
|
sta actor_row,x
|
|
lda #TILE_UP
|
|
sta actor_updown,x
|
|
sta actor_dir,x
|
|
jsr set_speed
|
|
lda #ORBITER_NORMAL
|
|
sta actor_status,x
|
|
rts
|
|
|
|
|
|
|
|
;def init_amidar():
|
|
; init_actor()
|
|
; amidar_index = zp.current_actor - FIRST_AMIDAR - 1 # orbiter always 1st enemy
|
|
; actor_col[zp.current_actor] = amidar_start_col[amidar_index]
|
|
; actor_row[zp.current_actor] = MAZE_TOP_ROW
|
|
; actor_ypixel[zp.current_actor] = 4
|
|
; actor_updown[zp.current_actor] = TILE_DOWN
|
|
; actor_dir[zp.current_actor] = TILE_DOWN
|
|
; actor_status[zp.current_actor] = AMIDAR_NORMAL
|
|
; set_speed(TILE_DOWN)
|
|
|
|
; actor in X
|
|
init_amidar nop
|
|
jsr init_actor
|
|
txa
|
|
sec
|
|
sbc #FIRST_AMIDAR
|
|
sbc #1
|
|
tay
|
|
lda amidar_start_col,y
|
|
sta actor_col,x
|
|
lda #MAZE_TOP_ROW
|
|
sta actor_row,x
|
|
lda #4
|
|
sta actor_ypixel,x
|
|
lda #TILE_DOWN
|
|
sta actor_updown,x
|
|
sta actor_dir,x
|
|
jsr set_speed
|
|
lda #AMIDAR_NORMAL
|
|
sta actor_status,x
|
|
rts
|
|
|
|
|
|
;def init_player():
|
|
; init_actor()
|
|
; addr = player_start_col[zp.num_players]
|
|
; actor_col[zp.current_actor] = addr[zp.current_actor]
|
|
; actor_row[zp.current_actor] = MAZE_BOT_ROW
|
|
; actor_status[zp.current_actor] = PLAYER_ALIVE
|
|
init_player_common
|
|
lda config_num_players ; 4 players max,
|
|
asl a
|
|
asl a
|
|
clc
|
|
adc current_actor
|
|
tay
|
|
;lda player_start_col,y
|
|
lda #16
|
|
sta actor_col,x
|
|
lda #MAZE_BOT_ROW
|
|
sta actor_row,x
|
|
rts
|
|
|
|
init_player nop
|
|
jsr init_actor
|
|
jsr init_player_common
|
|
lda #PLAYER_ALIVE
|
|
sta actor_status,x
|
|
; player_lives[zp.current_actor] = STARTING_LIVES
|
|
; player_next_target_score[zp.current_actor] = BONUS_LIFE
|
|
lda #STARTING_LIVES
|
|
sta player_lives,x
|
|
lda #BONUS_LIFE
|
|
sta player_next_target_score,x
|
|
lda #$99
|
|
sta player_score_l
|
|
sta player_score_m
|
|
sta player_score_h
|
|
rts
|
|
|
|
next_life jsr clear_input
|
|
jsr init_common
|
|
jsr init_player_common
|
|
rts
|
|
|
|
;def init_actors():
|
|
init_actors nop
|
|
; get_col_randomizer(amidar_start_col)
|
|
lda #<amidar_start_col
|
|
sta scratch_addr
|
|
lda #>amidar_start_col
|
|
sta scratch_addr+1
|
|
jsr get_col_randomizer
|
|
; get_col_randomizer(round_robin_up)
|
|
lda #<round_robin_up
|
|
sta scratch_addr
|
|
lda #>round_robin_up
|
|
sta scratch_addr+1
|
|
jsr get_col_randomizer
|
|
; get_col_randomizer(round_robin_down)
|
|
lda #<round_robin_down
|
|
sta scratch_addr
|
|
lda #>round_robin_down
|
|
sta scratch_addr+1
|
|
jsr get_col_randomizer
|
|
|
|
lda #0
|
|
sta round_robin_index
|
|
sta round_robin_index+1
|
|
|
|
; zp.current_actor = 0
|
|
; while zp.current_actor <= zp.last_enemy:
|
|
; if zp.current_actor <= LAST_PLAYER:
|
|
; if zp.current_actor < zp.num_players:
|
|
; init_player()
|
|
; player_lives[zp.current_actor] = STARTING_LIVES
|
|
; player_next_target_score[zp.current_actor] = BONUS_LIFE
|
|
; else:
|
|
; if zp.current_actor == FIRST_AMIDAR:
|
|
; init_orbiter()
|
|
; else:
|
|
; init_amidar()
|
|
; zp.current_actor += 1
|
|
; zp.round_robin_index[:] = [0, 0]
|
|
lda #$ff
|
|
sta current_actor
|
|
init_actors_loop inc current_actor
|
|
ldx current_actor
|
|
lda actor_active,x
|
|
bpl ?2 ; negative = end
|
|
rts
|
|
?2 beq init_actors_loop ; zero = skip
|
|
lda actor_type,x
|
|
tay
|
|
lda actor_init_func_l,y
|
|
sta init_actors_smc+1
|
|
lda actor_init_func_h,y
|
|
sta init_actors_smc+2
|
|
init_actors_smc jsr $ffff
|
|
jmp init_actors_loop
|