wwf-wrestlemania/ROBO.ASM

5105 lines
86 KiB
NASM
Raw Permalink Normal View History

2021-04-06 15:21:54 -07:00
**************************************************************
*
* Software: Jason Skiles
* Initiated: 4 Oct 93
*
* COPYRIGHT (C) 1993 WILLIAMS ELECTRONICS GAMES, INC.
*
*.Last mod - 12/8/93 11:15
**************************************************************
.file "robo.asm"
.title "robotron game"
.width 132
.option b,d,l,t
.mnolist
.include "mproc.equ" ;Mproc equates
.include "display.equ" ;Display proc equates
.include "gsp.equ" ;Gsp asm equates
.include "sys.equ"
.include "game.equ"
.include "audit.equ"
.include "macros.h"
.include "link.equ"
; .include "roboimg.glo"
.include "roboimg.tbl"
.include "fontsimg.glo"
;kludge
.ref robo_p
#*****************************************************************************
;from ADJUST.ASM
.ref BINBCD
;from COLL2.ASM
.ref collisions,CCCCount
;from DCSSOUND.ASM
.ref nosounds,SNDSND
;from DISPLAY.ASM
.ref pal_getf,STOPOBJS,fg2bg
;from MAIN.ASM
.ref dpageflip,IRQSKYE
;from MPROC.ASM
.ref KIL1C
;from STRING.ASM
.ref setup_message,print_string_R,mess_objid,copy_string
.ref dec_to_asc
;from UTIL.ASM
.ref get_all_buttons_cur,get_stick_val_cur,RNDRNG0,get_start_cur
.ref WIPEOUT,CYCLE_TABLE,civani,civanic
;from WRESTLE.ASM
.if DEBUG
.ref CPULEFT
.endif
.ref HALT,PCNT
;for WRESTLE.ASM
.def RE_DEADPLAYER,RE_WAVEDONE,RE_ABORT,RE_BACKUP
.ref _switch_addr,_switch2_addr,ADD_VOICE
#*****************************************************************************
BSSX robo_end, 16 ;reason for wave end
BSSX robotron_score, 32 ;UHL score
.bss player_dead, 16
.bss starts_down, 16 ;are both starts down?
.bss player_object, 32 ;pointer to char1 obj
.bss gun_proc, 32 ;gun process address
.bss robo_wave, 16 ;which wave to perform?
.bss live_badguys, 16 ;wave-preserving badguy count
.bss forward, 16 ;skip wave
.bss backward, 16 ;drop back a wave
#*****************************************************************************
ROBO_DEBUG equ 0
WAVE_CONTROL equ 0
BOG_MONITOR equ 0
ROBO_PAGE equ 0*256
ROBJ_MOM equ 1
ROBJ_DAD equ 2
ROBJ_KID equ 3
;termination causes
RE_DEADPLAYER equ 1
RE_WAVEDONE equ 2
RE_ABORT equ 3
RE_BACKUP equ 4
#*****************************************************************************
******************************************************************************
******************************************************************************
.ref robo_icon_trigger
.ref p1icon_total
.ref p2icon_total
SUBR robo_check
.if DEBUG
jruc #robo_ok
.endif
jruc #robo_end
move @p1icon_total,a0,L
move @robo_icon_trigger,a14
cmp a0,a14
jrle #robo_ok
move @p2icon_total,a0,L
cmp a0,a14
jrgt #robo_end
#robo_ok
sll 1,a14
move a14,@robo_icon_trigger
callr reset_roboscore
callr robo_sound_init
; movi -1,a0
; calla ADD_VOICE
clr a0
#robo_loop
JSRP robo_game
move @robo_end,a14
cmpi RE_DEADPLAYER,a14
jreq #player_died
cmpi RE_WAVEDONE,a14
jreq #wave_successful
cmpi RE_ABORT,a14
jreq #wave_aborted
cmpi RE_BACKUP,a14
jreq #back_up
jruc #robo_end
#player_died
jruc #robo_loop
#wave_successful
inc a0
cmpi 16,a0
jrne #robo_loop
jruc #robo_end
#wave_aborted
jruc #robo_end
#back_up
dec a0
jrnn #robo_loop
clr a0
jruc #robo_loop
#robo_end
RETP
#*****************************************************************************
******************************************************************************
******************************************************************************
SUBRP reset_roboscore
clr a14
move a14,@robotron_score,L
rets
#*****************************************************************************
******************************************************************************
******************************************************************************
SUBR robo_game
sla 4,a0
move a0,@robo_wave,W
calla display_blank
calla WIPEOUT ;CLEAN SYSTEM OUT
clr a0
move a0,@HALT
move a0,@dtype ;2d mode
move a0,@IRQSKYE
move a0,@CCCCount
movk 1,a0 ;page flipping on
move a0,@dpageflip
SLEEPK 1
movi SCRNEND,a0 ;[256,405]
move a0,@SCRNLR,L
clr a0
move a0,@WORLDTLX,L
move a0,@WORLDTLY,L
SLEEPK 2
calla nosounds ;kill the select music
;draw the frame
move @robo_wave,a0
addi #border_colors,a0
move *a0,a0,W
callr draw_frame
movk 1,a0
move a0,@DISPLAYON
SLEEPK 2
clr a14
move a14,@player_dead,W ;clear the done flag
;initialize the robo palette color cycles
callr robo_pal_cycles
;initialize the badguy count
clr a14
move a14,@live_badguys,W
;place the wave count
callr wave_count
;create the score monitor
CREATE ROBOSCORE_PID,score
;set up the player object
CREATE ROBOMAN_PID,our_hero ;start the little guy up
CREATE PLYRGUN_PID,player_gun ;give him a weapon
move a0,@gun_proc,L ;save the address
;set up some grunts
move @robo_wave,a0
addi #wave_grunts,a0
move *a0,a0,W
move @robo_wave,a2
addi #grunt_speeds,a2
move *a2,a2,W
callr make_grunts
;make some hulks
move @robo_wave,a0
addi #wave_hulks,a0
move *a0,a0,W
callr make_hulks
;sphereoids
move @robo_wave,a0
addi #wave_sphereoids,a0
move *a0,a0,W
callr make_sphereoids
;quarks
move @robo_wave,a0
addi #wave_quarks,a0
move *a0,a0,W
callr make_quarks
;make a few posts
move @robo_wave,a0
addi #wave_posts,a0
move *a0,a0,W
move @robo_wave,a1
addi #post_types,a1
move *a1,a1,W
move @robo_wave,a2
addi #post_colors,a2
move *a2,a2,W
callr make_posts
;and some people
move @robo_wave,a0
move a0,a1
move a0,a2
addi #wave_moms,a0
addi #wave_dads,a1
addi #wave_kids,a2
move *a0,a0,W
move *a1,a1,W
move *a2,a2,W
callr make_humans
;start the collision checker
CREATE COLL_PID,collisions
;create the both-start-btn watcher
clr a0
move a0,@starts_down,W
move a0,@forward,W
move a0,@backward,W
CREATE MISC_PID,watch_both_starts
.if WAVE_CONTROL
CREATE MISC_PID,wave_mover
.endif
.if DEBUG
.if BOG_MONITOR
CREATE MISC_PID,bog_o_meter
.endif
.endif
calla display_unblank
#not_done
SLEEPK 1
move @live_badguys,a14
jrz #wave_done
move @player_dead,a14
jrnz #dead_hero
move @starts_down,a14
jrnz #wave_abort
move @forward,a14
jrnz #wave_done
move @backward,a14
jrnz #back_up
jruc #not_done
#wave_done
movi RE_WAVEDONE,a14
jruc #quit
#dead_hero
movi RE_DEADPLAYER,a14
jruc #quit
#wave_abort
movi RE_ABORT,a14
jruc #quit
#back_up
movi RE_BACKUP,a14
jruc #quit
#quit
move a14,@robo_end,W
;put the wave back in a0 just like we found it
move @robo_wave,a0,W
sra 4,a0
RETP
#border_colors
.if ROBO_DEBUG
.word 1
.endif
.word 01,06,01,14,07,03,02,08
.word 00,10,01,06,01,14,07,03
#wave_grunts
.if ROBO_DEBUG
.word 4
.endif
; .word 15,17,22,34,20,30,00,30
; .word 30,25,30,00,30,27,25,30
.word 15,17,22,34,20,32,00,35
.word 60,25,35,00,35,27,25,35
#grunt_speeds
.if ROBO_DEBUG
.word 1000
.endif
.word 20,15,15,15,15,15,15,15
.word 15,15,14,14,14,14,14,13
#wave_posts
.if ROBO_DEBUG
.word 15
.endif
.word 05,15,25,25,20,25,00,25
.word 00,20,25,00,25,05,20,25
#post_types
.if ROBO_DEBUG
.word 0
.endif
.word 0,1,3,8,4,2,0,7
.word 0,5,0,1,3,8,4,2
#post_colors
.if ROBO_DEBUG
.word 0Fh
.endif
.word 15,14,11,13,14,15,14,11
.word 14,10,15,14,11,13,14,15
#wave_hulks
.if ROBO_DEBUG
.word 0
.endif
.word 00,05,06,07,00,07,12,08
.word 04,00,08,13,08,20,02,03
#wave_sphereoids
.if ROBO_DEBUG
.word 0
.endif
.word 00,01,03,04,01,04,00,05
.word 05,01,05,00,05,02,01,05
#wave_quarks
.if ROBO_DEBUG
.word 0
.endif
.word 00,00,00,00,00,00,10,00
.word 00,00,00,12,00,00,00,00
#wave_moms
.if ROBO_DEBUG
.word 2
.endif
.word 01,01,02,02,15,03,04,03
.word 03,00,03,03,03,05,00,03
#wave_dads
.if ROBO_DEBUG
.word 2
.endif
.word 01,01,02,02,00,03,04,03
.word 03,22,03,03,03,05,00,03
#wave_kids
.if ROBO_DEBUG
.word 2
.endif
.word 00,01,02,02,01,03,04,03
.word 03,00,03,03,03,05,22,03
#*****************************************************************************
******************************************************************************
******************************************************************************
*
* PLAYER SECTION
*
;reg use
; a4 - current position in animation script
; a5 - head of current animation script
; a6 - tail of current animation script
; a8 - player object
; a9 - motion count accumulator
; a10 - direction of motion
SUBRP our_hero
;create the player object
movi [#start_x,0],a0
movi [#start_y,0],a1
movi man_d1,a2
clr a3
movi DMAWNZ,a4
movi CLSPLYR|TYPPLYR,a5
clr a6
clr a7
calla BEGINOBJW
;set the global pointer
move a8,@player_object,L
; initiailize direction of motion
clr a10
#not_done
PUSHP a4,a5,a6
SLEEPK 1
PULLP a4,a5,a6
; move him first
callr #move_player
; change his animation frame, if neccesary
callr #change_frame
jruc #not_done
#player_dead
;kill the gun process
move @gun_proc,a0,L
calla KILL
movi BULLET_PID,a0
calla KIL1C
movi GRUNT_PID,a0
calla KIL1C
movi HULK_PID,a0
calla KIL1C
movi HUMAN_PID,a0
calla KIL1C
movi SPHEREOID_PID,a0
calla KIL1C
movi ENFORCER_PID,a0
calla KIL1C
movi SPARK_PID,a0
calla KIL1C
movi QUARK_PID,a0
calla KIL1C
movi TANK_PID,a0
calla KIL1C
movi SHELL_PID,a0
calla KIL1C
calla STOPOBJS
;switch frames
movi robo_dead,a0,L
calla civanic
;death sound
movi RS_DIE,a0
calla robo_sound
SLEEP 120
movk 1,a14
move a14,@player_dead,W
DIE
******************************************************************************
*
* player move routine
*
SUBRP #move_player
clr a0
calla get_stick_val_cur
btst JOYDN,a0
jrnz #move_down
btst JOYUP,a0
jrnz #move_up
btst JOYRGT,a0
jrnz #move_right
btst JOYLFT,a0
jrnz #move_left
jruc #no_move
#move_down
btst JOYRGT,a0
jrnz #move_downright
btst JOYLFT,a0
jrnz #move_downleft
;increment Y
move *a8(OYPOS),a14,W
inc a14
move a14,*a8(OYPOS),W
jruc #move_done
#move_up
btst JOYRGT,a0
jrnz #move_upright
btst JOYLFT,a0
jrnz #move_upleft
;decrement Y
move *a8(OYPOS),a14,W
dec a14
move a14,*a8(OYPOS),W
jruc #move_done
#move_right
;increment X
move *a8(OXPOS),a14,W
inc a14
move a14,*a8(OXPOS),W
jruc #move_done
#move_left
;decrement X
move *a8(OXPOS),a14,W
dec a14
move a14,*a8(OXPOS),W
jruc #move_done
#move_upright
; decrement Y and increment X
move *a8(OYPOS),a14,W
dec a14
move a14,*a8(OYPOS),W
move *a8(OXPOS),a14,W
inc a14
move a14,*a8(OXPOS),W
jruc #move_done
#move_upleft
; decrement Y and decrement X
move *a8(OYPOS),a14,W
dec a14
move a14,*a8(OYPOS),W
move *a8(OXPOS),a14,W
dec a14
move a14,*a8(OXPOS),W
jruc #move_done
#move_downright
; increment Y and increment X
move *a8(OYPOS),a14,W
inc a14
move a14,*a8(OYPOS),W
move *a8(OXPOS),a14,W
inc a14
move a14,*a8(OXPOS),W
jruc #move_done
#move_downleft
; increment Y and decrement X
move *a8(OYPOS),a14,W
inc a14
move a14,*a8(OYPOS),W
move *a8(OXPOS),a14,W
dec a14
move a14,*a8(OXPOS),W
jruc #move_done
#move_done
; check bounds
move *a8(OXPOS),a14,W
cmpi #low_x,a14,W
jrgt #not_lowx
; too low on x
inc a14
move a14,*a8(OXPOS),W
#not_lowx
cmpi #high_x,a14,W
jrle #not_highx
; too high on x
dec a14
move a14,*a8(OXPOS),W
#not_highx
move *a8(OYPOS),a14,W
cmpi #low_y,a14,W
jrgt #not_lowy
; too low on y
inc a14
move a14,*a8(OYPOS),W
#not_lowy
cmpi #high_y,a14,W
jrle #not_highy
; too high on y
dec a14
move a14,*a8(OYPOS),W
#not_highy
#no_move
#done_moving
rets
******************************************************************************
*
* player animation routine
*
SUBRP #change_frame
;reg use
; a0 scratch
; a1 sctatch
; a3 new direction of motion
; a10 old direction of motion - update
clr a0
clr a2
calla get_stick_val_cur
move a0,a3
cmp a0,a10
jreq #same_direction
jruc #new_direction
#new_direction
; start a new script. first use the joystick bits to compute an
; offset into the script table.
X32 a0 ;multiply by 32
addi #script_map,a0 ;add the address of the script table
move *a0,a0,L ;get the address of the script
; get the tail and head of the image list for this script
move *a0+,a6,L
move a0,a5
;a5 now points to the first image in the script. change to it.
move *a5,a0,L
calla civanic
;set the new direction thingie and script pointer
move a3,a10
move a5,a4
;set the motion count
movi #motion_count,a9
jruc #done_changing
#same_direction
;check the motion count
dec a9
jrnz #done_changing
;reset the motion count
movi #motion_count,a9
;increment the pointer, wrap if neccesary
addi 20h,a4
cmp a4,a6
jrne #no_wrap
move a5,a4
#no_wrap
;a4 is the new image. change to it.
move *a4,a0,L
calla civanic
jruc #done_changing
#done_changing
rets
******************************************************************************
*
* player collision routines
*
SUBR player_die
PUSH a1,a7
;we hit some kind of bad guy and are dead
movi CLSDEAD,a14
move a14,*a8(OID),W
move *a8(OPLINK),a0,L
movi DEADPLAYER_PID,a1
movi #player_dead,a7
calla XFERPROC
PULL a1,a7
rets
******************************************************************************
*
* player configuration data
*
;start position
#start_x equ 197
#start_y equ 123
; motion boundaries
#low_x equ 53
#high_x equ 347-7
#low_y equ 45
#high_y equ 231-12
;motion count - controls animation speed
#motion_count equ 2 ;there will be trouble if this is zero
; walking animation scripts
#ani_holdstill
.long #ani_holdstillx
.long man_d1
#ani_holdstillx
#ani_walkup
.long #ani_walkupx
.long man_u1
.long man_u2
.long man_u1
.long man_u3
#ani_walkupx
#ani_walkdown
.long #ani_walkdownx
.long man_d1
.long man_d2
.long man_d1
.long man_d3
#ani_walkdownx
#ani_walkright
.long #ani_walkrightx
.long man_r1
.long man_r2
.long man_r1
.long man_r3
#ani_walkrightx
#ani_walkleft
.long #ani_walkleftx
.long man_l1
.long man_l2
.long man_l1
.long man_l3
#ani_walkleftx
#ani_bad
.long #ani_badx
.long robo_bad
#ani_badx
; direction - script mappings: use AND combo of joy bits as index
#script_map
.long #ani_holdstill
.long #ani_walkup
.long #ani_walkdown
.long #ani_bad
.long #ani_walkleft
.long #ani_walkleft
.long #ani_walkleft
.long #ani_bad
.long #ani_walkright
.long #ani_walkright
.long #ani_walkright
.long #ani_bad
.long #ani_bad
.long #ani_bad
.long #ani_bad
.long #ani_bad
#script_mapx
#*****************************************************************************
*
* player gun process
*
;reg use
;a9 time till next shot is allowed
SUBRP player_gun
clr a9
jruc #sleep
#check_shot
movk 1,a0
calla get_stick_val_cur
jrz #sleep ;no shot
;fire in the indicated direction
move a0,a10
CREATE BULLET_PID,bullet
movi #rate_of_fire,a9
;shoot sound
movi RS_SHOOT,a0
callr robo_sound
jruc #sleep
#too_soon
dec a9
jruc #sleep
#sleep
SLEEPK 1
move a9,a9
jrnz #too_soon
jruc #check_shot
#done
DIE
#rate_of_fire equ 6 ;min ticks between shots
#*****************************************************************************
*
* player bullet process
*
;reg use
; a4 velocity accumulator (used to pick the correct bullet)
; a5 vert indicator
; a8 bullet object
;a10 (in) stick bits
SUBRP bullet
;create a bullet object
movi [500,0],a0
clr a1
movi bullet_hrz,a2
clr a3
movi DMAWNZ,a4
movi CLSPLYR|TYPBULLET,a5
clr a6
clr a7
calla BEGINOBJW
;set the speed and start position
move @player_object,a9,L
clr a4
clr a5
move *a9(OXPOS),a0,W
addk #bstart_xoff,a0
move a0,*a8(OXPOS),W
move *a9(OYPOS),a0,W
addk #bstart_yoff,a0
move a0,*a8(OYPOS),W
btst JOYRGT,a10
jrz #not_right
move *a8(OXPOS),a14,W ;pos
addi #bstart_radj,a14
move a14,*a8(OXPOS),W
movi #bullet_speed,a0 ;speed
move a0,*a8(OXVEL),L
inc a4
#not_right
btst JOYLFT,a10
jrz #not_left
move *a8(OXPOS),a14,W ;pos
addi #bstart_ladj,a14
move a14,*a8(OXPOS),W
movi -#bullet_speed,a0 ;speed
move a0,*a8(OXVEL),L
dec a4
#not_left
btst JOYUP,a10
jrz #not_up
move *a8(OYPOS),a14,W ;pos
addi #bstart_uadj,a14
move a14,*a8(OYPOS),W
movi -#bullet_speed,a0 ;speed
move a0,*a8(OYVEL),L
dec a4
inc a5
#not_up
btst JOYDN,a10
jrz #not_down
move *a8(OYPOS),a14,W ;pos
addi #bstart_dadj,a14
move a14,*a8(OYPOS),W
movi #bullet_speed,a0 ;speed
move a0,*a8(OYVEL),L
inc a4
inc a5
#not_down
;set the image
movi bullet_hrz,a0
move a5,a5
jrz #horiz
movi bullet_vrt,a0
#horiz
;vert/horz is set. check for diagonal instead
cmpi 1,a4
jreq #image_set
cmpi -1,a4
jreq #image_set
;it's a diagonal. if a4 is 0, use frontslash
move a4,a4
jrz #front_slash
movi bullet_bck,a0
jruc #image_set
#front_slash
movi bullet_fnt,a0
#image_set
calla civanic
#loop
callr bounds_check
move a0,a0
jrnz #hit_wall
SLEEPK 1
jruc #loop
#hit_wall
;zoinks! We've hit a wall. back up to be flush against it.
; a2 holds the number of pixels we have to back up.
;well, we can overlap on the wall a LITTLE. say, 2 pixels.
subk 2,a2
move *a8(OXVEL),a0,L
jrz #y_adjust
jrn #neg_xvel
move *a8(OXPOS),a0,W
sub a2,a0
move a0,*a8(OXPOS),W
jruc #y_adjust
#neg_xvel
move *a8(OXPOS),a0,W
add a2,a0
move a0,*a8(OXPOS),W
#y_adjust
move *a8(OYVEL),a0,L
jrz #kill_bullet
jrn #neg_yvel
move *a8(OYPOS),a0,W
sub a2,a0
move a0,*a8(OYPOS),W
jruc #kill_bullet
#neg_yvel
move *a8(OYPOS),a0,W
add a2,a0
move a0,*a8(OYPOS),W
#kill_bullet
SLEEPK 1
calla DELOBJA8
DIE
******************************************************************************
*
* player bullet collision routines
*
SUBR bullet_die
PUSH a1,a7,a9,a10,a11
;we hit some kind of bad guy and are stopped.
movi CLSDEAD,a14
move a14,*A8(OID)
move *a8(OPLINK),a0,L
movi DEADBULLET_PID,a1
movi #kill_bullet,a7
calla XFERPROC
PULL a1,a7,a9,a10,a11
rets
#bullet_speed equ 00080000h ;pixels per frame
#low_x equ 53
#high_x equ 346
#low_y equ 45
#high_y equ 230
;hero anim point is top left. bullet anim point is center. use these to
; adjust the starting position of the bullet.
; No. The bullet anim points are gone now. Unk.
#bstart_xoff equ 3
#bstart_yoff equ 5
#bstart_radj equ 7
#bstart_ladj equ -13
#bstart_uadj equ -14
#bstart_dadj equ 8
#*****************************************************************************
******************************************************************************
******************************************************************************
*
* GRUNT SECTION
*
;reg use
; a0 (in) # of grunts
; a1 scratch
; a2 (in) initial speed
SUBRP make_grunts
move a0,a0
jrz #done
#another_grunt
PUSHP a0
#get_pos
movi #max_x-#min_x,a0
calla RNDRNG0
move a0,a9
movi #max_y-#min_y,a0
calla RNDRNG0
move a0,a10
addi #min_x,a9
addi #min_y,a10
cmpi #mid_x1,a9
jrle #place_grunt
cmpi #mid_x2,a9
jrge #place_grunt
cmpi #mid_y1,a10
jrle #place_grunt
cmpi #mid_y2,a10
jrge #place_grunt
jruc #get_pos
#place_grunt
;assign a random starting position
move a2,a11
CREATE GRUNT_PID,grunt
PULLP a0
dsj a0,#another_grunt
#done
rets
#min_x equ 53 ;grunt start outer boundaries
#max_x equ 347-9
#min_y equ 45
#max_y equ 231-13
#mid_x1 equ 200-60 ;grunt start inner boundaries
#mid_x2 equ 200+60
#mid_y1 equ 138-60
#mid_y2 equ 138+60
#*****************************************************************************
*
* grunt process
*
STRUCTPD
WORD #ACCEL_TIMER ;UHW accelerator count
LONG #DEATH_SEQUENCE ;UHL anim to use when dying
; (set by coll routines)
;reg use
; a8 object handle
; a9 (in) starting x
; a9 (use) ticks between moves
;a10 (in) starting y
;a10 (use) ticks until next move
;a11 (in) initial speed
;a11 (use) frame count
SUBRP grunt
;increment the badguy count
move @live_badguys,a14,W
inc a14
move a14,@live_badguys,W
;create a grunt object
move a9,a0
sla 16,a0
move a10,a1
sla 16,a1
movi grunt_1,a2
clr a3
movi DMAWNZ,a4
movi CLSENMY|TYPGRUNT,a5
clr a6
clr a7
calla BEGINOBJW
;initialize move timer
move a11,a9
;initialize time till next move
move a9,a0
calla RNDRNG0
add a11,a0
move a0,a10
;initialize accel counter
movi #acceleration,a14
move a14,*a13(#ACCEL_TIMER),W
;initialize frame counter
clr a11
#loop
move *a13(#ACCEL_TIMER),a14,W
dec a14
jrnz #no_accel
movi #acceleration,a14
cmpi #top_speed,a9
jreq #no_accel
dec a9
#no_accel
move a14,*a13(#ACCEL_TIMER),W
SLEEPK 1
dsj a10,#loop
callr #move_grunt
move a9,a10
jruc #loop
#die
;we've croaked
;decrement the badguy count
move @live_badguys,a14,W
dec a14
move a14,@live_badguys,W
;set up the animation
move *a13(#DEATH_SEQUENCE),a9,L
move *a8(OCTRL),a0
#dieloop
move *a9+,a0,L
jrz #dead_n_buried
calla civanic
sleepk #death_speed
jruc #dieloop
#dead_n_buried
calla DELOBJA8
DIE
******************************************************************************
*
* grunt move routine
*
SUBRP #move_grunt
move @player_object,a14,L
;move in X
move *a14(OXPOS),a0,W
move *a8(OXPOS),a1,W
sub a1,a0
jrz #done_movex
jrn #move_left
jruc #move_right
#move_left
move *a8(OXPOS),a1,W
addi -#xmotion_inc,a1
move a1,*a8(OXPOS),W
jruc #done_movex
#move_right
move *a8(OXPOS),a1,W
addi #xmotion_inc,a1
move a1,*a8(OXPOS),W
jruc #done_movex
#done_movex
move *a14(OYPOS),a0,W
move *a8(OYPOS),a1,W
sub a1,a0
jrz #done_movey
jrn #move_up
jruc #move_down
#move_up
move *a8(OYPOS),a1,W
addi -#ymotion_inc,a1
move a1,*a8(OYPOS),W
jruc #done_movey
#move_down
move *a8(OYPOS),a1,W
addi #ymotion_inc,a1
move a1,*a8(OYPOS),W
jruc #done_movey
#done_movey
;step through the animation
inc a11
cmpi 4,a11
jrne #no_wrap
clr a11
#no_wrap
move a11,a14
X32 a14
addi #walk_script,a14
move *a14,a0,L
calla civanic
;sound
movi RS_GRUNT,a0
callr robo_sound
rets
******************************************************************************
*
* grunt collision routines
*
SUBR grunt_shot
;hit by player gunfire
PUSH a1,a7
;jeepers. we're dead.
movi CLSDEAD,a14
move a14,*a8(OID),W
move *a0(OXVEL),a14,L
jrz #vert_bullet
move *a0(OYVEL),a1,L
jrz #horz_bullet
add a1,a14
jrz #diag_13
jruc #diag_24
#horz_bullet
movi #die_vert,a14
jruc #death_set
#vert_bullet
movi #die_horz,a14
jruc #death_set
#diag_13
movi #die_diag24,a14
jruc #death_set
#diag_24
movi #die_diag13,a14
jruc #death_set
#death_set
move *a8(OPLINK),a0,L
move a14,*a0(#DEATH_SEQUENCE),L
movi DEADGRUNT_PID,a1
movi #die,a7
move *a0(PA9),a9,L
move *a0(PA10),a10,L
calla XFERPROC
movi #grunt_points,a0
callr score_points
;die sound
movi RS_HIT,a0
calla robo_sound
PULL a1,a7
rets
SUBR grunt_die
;hit a mine or something
PUSH a1,a7
movi CLSDEAD,a14
move a14,*a8(OID),W
move *a8(OPLINK),a0,L
movi #die_vert,a14
move a14,*a0(#DEATH_SEQUENCE),L
movi DEADGRUNT_PID,a1
movi #die,a7
move *a0(PA9),a9,L
move *a0(PA10),a10,L
calla XFERPROC
PULL a1,a7
rets
******************************************************************************
*
* grunt configuration data
*
#walk_script
.long grunt_1
.long grunt_2
.long grunt_1
.long grunt_3
#walk_scriptx
#die_vert
.long grunt_xv1
.long grunt_xv2
.long grunt_xv3
.long grunt_xv4
.long 0
#die_vertx
#die_horz
.long grunt_xh1
.long grunt_xh2
.long grunt_xh3
.long grunt_xh4
.long 0
#die_horzx
#die_diag13
.long grunt_xdf1
.long grunt_xdf2
.long grunt_xdf3
.long grunt_xdf4
.long 0
#die_diag13x
#die_diag24
.long grunt_xdb1
.long grunt_xdb2
.long grunt_xdb3
.long grunt_xdb4
.long 0
#die_diag24x
#death_speed equ 3 ;death seq anim speed
#acceleration equ 100 ;decrement motion clock every X cycles
#top_speed equ 3 ;as fast as they get
#xmotion_inc equ 0004h
#ymotion_inc equ 0004h
#grunt_points equ 100 ;points for killing a grunt
#*****************************************************************************
******************************************************************************
******************************************************************************
*
* POST SECTION
*
;reg use
; a0 - (in) # of posts to create
; a1 - (in) type (0-8)
; a2 - (in) color (0-F)
SUBRP make_posts
move a0,a9 ;move the inputs to safer spots
jrz #done
move a1,a10 ;type
move a2,a11 ;color
sla 8,a11
or a2,a11
#another_post
#get_pos
movi #max_y-#min_y,a0
calla RNDRNG0
move a0,a2 ;hide a0
movi #max_x-#min_x,a0
calla RNDRNG0
move a2,a1 ;put it back
addi #min_x,a0
addi #min_y,a1
cmpi #mid_x1,a0
jrle #place_post
cmpi #mid_x2,a0
jrge #place_post
cmpi #mid_y1,a1
jrle #place_post
cmpi #mid_y2,a1
jrge #place_post
jruc #get_pos
#place_post
sla 16,a0 ;X pos
sla 16,a1 ;Y pos
;create the post object
move a10,a14
X32 a14
addi #post_types,a14
move *a14,a14,L
move *a14,a2,L ;DON'T advance
clr a3
movi DMACNZ,a4
movi CLSNEUT|TYPPOST,a5
clr a6
clr a7
calla BEGINOBJW
move a10,*a8(OMISC),W ;stuff the type in the object
move a11,*a8(OCONST),W
movi robo_p,a0
calla pal_getf
move a0,*a8(OPAL),W
dsj a9,#another_post
#done
rets
#min_x equ 53 ;post start outer boundaries
#max_x equ 347-17
#min_y equ 45
#max_y equ 231-10
#mid_x1 equ 200-50 ;post start inner boundaries
#mid_x2 equ 200+50
#mid_y1 equ 138-50
#mid_y2 equ 138+50
******************************************************************************
*
* post collision routines
*
SUBR post_die
movi CLSDEAD,a14
move a14,*a8(OID),W
CREATE DEADPOST_PID,kill_post
rets
;reg use
; a8 - * image
; a9 - anim pointer
SUBR kill_post
move *a8(OMISC),a0,W
X32 a0
addi #post_types,a0
move *a0,a9,L
move *a8(OCTRL),a14,W
xori DMACNZ,a14
ori DMAWNZ,a14
move a14,*a8(OCTRL),W
#kploop
move *a9+,a0,L
jrz #kpdone
calla civanic
SLEEPK #die_speed
jruc #kploop
#kpdone
calla DELOBJA8
DIE
#die_speed equ 3
#post_types
.long #star ;0
.long #crystal ;1
.long #diamond ;2
.long #square ;3
.long #rectangle ;4
.long #R2084 ;5
.long #pcube ;6
.long #spiral ;7
.long #triangle ;8
.long 0
#post_typesx
#star
.long star_1,star_2,star_3,0
#crystal
.long crystal_1,crystal_2,crystal_3,0
#diamond
.long diamond_1,diamond_2,diamond_3,0
#square
.long square_1,square_2,square_3,0
#rectangle
.long rectangle_1,rectangle_2,rectangle_3,0
#R2084
.long R2084_1,R2084_2,R2084_3,0
#pcube
.long pcube_1,pcube_2,pcube_3,0
#spiral
.long spiral_1,spiral_2,spiral_3,0
#triangle
.long triangle_1,triangle_2,triangle_3,0
#*****************************************************************************
******************************************************************************
******************************************************************************
*
* HUMAN SECTION
*
.bss humans_saved, 16
;reg use
; a0 # of moms
; a1 # of dads
; a2 # of kids
SUBRP make_humans
;initialize the savecount
clr a14
move a14,@humans_saved,W
;first make the moms
move a0,a0
jrz #skip_moms
#mom_loop
PUSHP a0,a1,a2
callr #rand_position
movi ROBJ_MOM,a9
CREATE HUMAN_PID,human
PULLP a0,a1,a2
dsj a0,#mom_loop
#skip_moms
;dads
move a1,a1
jrz #skip_dads
#dad_loop
PUSHP a1,a2
callr #rand_position
movi ROBJ_DAD,a9
CREATE HUMAN_PID,human
PULLP a1,a2
dsj a1,#dad_loop
#skip_dads
;kids
move a2,a2
jrz #skip_kids
#kid_loop
PUSHP a2
callr #rand_position
movi ROBJ_KID,a9
CREATE HUMAN_PID,human
PULLP a2
dsj a2,#kid_loop
#skip_kids
rets
;reg use
; no input
;a10 - (ret) an X val
;a11 - (ret) a Y val
SUBRP #rand_position
movi #max_x-#min_x,a0
calla RNDRNG0
move a0,a10
addi #min_x,a10
movi #max_y-#min_y,a0
calla RNDRNG0
move a0,a11
addi #min_y,a11
rets
******************************************************************************
*
* human process
*
STRUCTPD
LONG #HITPOST ;UHL post we've hit
;reg use
; a8 - hObject
; a9 - (in) OID
; a9 - (use) image table address (#mom_table, #dad_table...)
;a10 - (in) x
;a10 - (use) direction of motion (1-8)
;a11 - (in) y
;a11 - (use) frame index (0-3)
SUBRP human
cmpi ROBJ_MOM,a9
jreq #init_mom
cmpi ROBJ_DAD,a9
jreq #init_dad
cmpi ROBJ_KID,a9
jreq #init_kid
LOCKUP ;bad objid
#init_mom
movi #mom_table,a9
jruc #make_obj
#init_dad
movi #dad_table,a9
jruc #make_obj
#init_kid
movi #kid_table,a9
jruc #make_obj
#make_obj
;cweate a widdle people object
move a10,a0
sla 16,a0
move a11,a1
sla 16,a1
move *a9(#walk_down),a2,L
clr a3
movi DMAWNZ,a4
movi CLSNEUT|TYPHUMAN,a5
clr a6
clr a7
calla BEGINOBJW
;choose a direction of motion
movi 7,a0
calla RNDRNG0
inc a0
move a0,a10
;set the frame index
movi 3,a11
callr #advance_frame
#move_loop
SLEEPK #sleep_time
callr #rand_dirchange
callr #move_onestep
move a0,a0
jrnz #hit_wall
callr #advance_frame
jruc #move_loop
#hit_wall
;sleep first because: If you move and bump into both a wall and a
; post at the same time (could happen), and then you immediately
; reverse direction, you'll then get flipped AGAIN when you hit
; the post and get forwarded right through the wall. yuck. so
; instead when you hit a wall, wait a frame and let the post
; collisions sort themselves out, THEN change direction.
SLEEPK 1
callr #reverse_direction
callr #advance_frame
jruc #move_loop
#hit_post
callr post_adjust
callr #advance_frame
jruc #move_loop
#saved
;sound
movi RS_RESCUE,a0
callr robo_sound
;increment the save count
move @humans_saved,a14,W
inc a14
move a14,@humans_saved,W
cmpi 5,a14
jrle #no_cap
movi 5,a14
#no_cap
dec a14
PUSH a14
sla 4,a14
addi #score_table,a14
move *a14,a0,W
callr score_points
PULL a14
X32 a14
addi #saved_table,a14
move *a14,a0,L
calla civanic
SLEEP 120
calla DELOBJA8
jruc #done
#killed
movi skull,a0
calla civanic
SLEEP 120
calla DELOBJA8
; jruc #done ;fall through
#done
DIE
******************************************************************************
* Human has bounced into or started inside a post. Make it better.
* Do this by reversing the direction of the human and moving it forward
* in the new direction until it's clear of the post.
*
;reg use
; a0 - X overlap
; a1 - Y overlap
SUBRP post_adjust
PUSH a0,a1,a2,a3,a7
move *a13(#HITPOST),a7,L
callr #reverse_direction
;calculate degree of X and Y overlap
move a10,a2
X32 a2
addi #walk_increments,a2
move *a2+,a3,W ;y vel
jrn #yvel_neg
jrz #yvel_zero
#yvel_pos
move *a7(OYPOS),a1
move *a7(OSIZEY),a14
add a14,a1
move *a8(OYPOS),a14
sub a14,a1
jruc #do_xvel
#yvel_zero
movi 100h,a1
jruc #do_xvel
#yvel_neg
move *a8(OYPOS),a1
move *a8(OSIZEY),a14
add a14,a1
move *a7(OYPOS),a14
sub a14,a1
; jruc #do_xvel
#do_xvel
move *a2,a3,W ;x vel
jrn #xvel_neg
jrz #xvel_zero
#xvel_pos
move *a7(OXPOS),a0
move *a7(OSIZEX),a14
add a14,a0
move *a8(OXPOS),a14
sub a14,a0
jruc #ovlap_done
#xvel_zero
movi 100h,a0
jruc #ovlap_done
#xvel_neg
move *a8(OXPOS),a0
move *a8(OSIZEX),a14
add a14,a0
move *a7(OXPOS),a14
sub a14,a0
; jruc #ovlap_done
#ovlap_done
;a0 and a1 are the X and Y overlaps, respectively. We need only
; worry about the smallest of the two and move that many steps. Note
; that if velocity in a given direction is zero, the overlap is
; set to some outrageously large value so that the other direction
; is all that counts.
cmp a1,a0
jrle #low_set
move a1,a0
#low_set
;a0 is now the smallest.
move a0,a1
move a10,a2
X32 a2
addi #walk_increments,a2
move *a2+,a3,W ;y vel
mpys a3,a1
move *a2,a3,W ;x vel
mpys a0,a3
move a3,a0
;a0 and a1 now hold X and Y adjustments, respectively.
move *a8(OXPOS),a14
add a0,a14
move a14,*a8(OXPOS)
move *a8(OYPOS),a14
add a1,a14
move a14,*a8(OYPOS)
PULL a0,a1,a2,a3,a7
rets
******************************************************************************
*
* human movement/animation routine
*
;reg use
; a0 - scratch
; a0 (out) - walls hit (0-2)
; a1 - scratch
; a8 - (in) hObject
; a9 - (in) image table address (#mom_table, #dad_table...)
;a10 - (in) direction of motion (1-8)
;a11 - (in) frame index (0-3)
SUBRP #move_onestep
;move the object
move a10,a1
X32 a1
addi #walk_increments,a1
move *a1+,a14,W
move *a8(OYPOS),a0,W
add a14,a0
move a0,*a8(OYPOS),W
move *a1+,a14,W
move *a8(OXPOS),a0,W
add a14,a0
move a0,*a8(OXPOS),W
clr a1
move *a8(OXPOS),a0,W
cmpi #min_x,a0
jrge #not_lowx
;low x
inc a1
movi #min_x,a0
move a0,*a8(OXPOS),W
#not_lowx
cmpi #max_x,a0
jrle #not_highx
;high x
inc a1
movi #max_x,a0
move a0,*a8(OXPOS),W
#not_highx
move *a8(OYPOS),a0,W
cmpi #min_y,a0
jrge #not_lowy
;low y
inc a1
movi #min_y,a0
move a0,*a8(OYPOS),W
#not_lowy
cmpi #max_y,a0
jrle #not_highy
;high y
inc a1
movi #max_y,a0
move a0,*a8(OYPOS),W
#not_highy
move a1,a0
rets
******************************************************************************
* Changes direction one time in #dirchange_chance.
*
SUBRP #rand_dirchange
;1 chance in #dirchange_chance of spontaneously switching direction
movi #dirchange_chance,a0
calla RNDRNG0
move a0,a0
jrnz #dirchange_done
movi 7,a0
calla RNDRNG0
inc a0
move a0,a10
#dirchange_done
rets
******************************************************************************
* Reverses direction
*
SUBRP #reverse_direction
;reverse direction of motion
subi 4,a10
jrp #rd_done
addi 8,a10
#rd_done
rets
******************************************************************************
* Advances the frame
*
SUBRP #advance_frame
;advance the frame and set the new image
inc a11
cmpi 4,a11
jrne #no_wrap
;wraparound. reset to start
clr a11
#no_wrap
;calculate the next frame
move a9,a0
move a10,a1
sla 4,a1 ;mult by 10h
addi #motion_table,a1
;a1 now points to one of the entries in #motion table
move *a1,a1,W
add a1,a0
;a0 now points to an entry in #xxx_table
move a11,a1
X32 a1 ;mult by 20h
add a1,a0
move *a0,a0,L
calla civanic
rets
******************************************************************************
*
* human collision routines
*
SUBR human_saved
PUSH a1,a7
;change the obj id
movi CLSDEAD,a14
move a14,*a8(OID),W
move *a8(OPLINK),a0,L
movi SAVEDHUMAN_PID,a1
movi #saved,a7
calla XFERPROC
PULL a1,a7
rets
SUBR human_killed
PUSH a1,a7
movi CLSDEAD,a14
move a14,*a8(OID),W
move *a8(OPLINK),a0,L
movi DEADHUMAN_PID,a1
movi #killed,a7
calla XFERPROC
PULL a1,a7
rets
SUBR human_hitpost
PUSH a1,a7
move a0,a1
move *a8(OPLINK),a0,L
move a1,*a0(#HITPOST),L
move *a0(PA8),a8,L
move *a0(PA9),a9,L
move *a0(PA10),a10,L
move *a0(PA11),a11,L
movi HUMAN_PID,a1
movi #hit_post,a7
calla XFERPROC
PULL a1,a7
rets
******************************************************************************
*
* human configuration data
*
#min_x equ 53 ;human start/motion outer boundaries
#max_x equ 347-11
#min_y equ 45
#max_y equ 231-13
#sleep_time equ 7
#x_step equ 1
#y_step equ 1
#dirchange_chance equ 40
#walk_increments
.word 0,0 ;because direction is 1-8, not 0-7
.word -#y_step,0
.word -#y_step,#x_step
.word 0,#x_step
.word #y_step,#x_step
.word #y_step,0
.word #y_step,-#x_step
.word 0,-#x_step
.word -#y_step,-#x_step
#walk_incrementsx
#motion_table
.word 0 ;because direction is 1-8, not 0-7
.word #walk_up
.word #walk_right
.word #walk_right
.word #walk_right
.word #walk_down
.word #walk_left
.word #walk_left
.word #walk_left
#motion_tablex
;image table direction offsets
#walk_left equ 0000h
#walk_right equ #walk_left + (4 * 20h)
#walk_up equ #walk_right + (4 * 20h)
#walk_down equ #walk_up + (4 * 20h)
#score_table
.word 1000,2000,3000,4000,5000
#score_tablex
;image tables
#mom_table
.long mom_l1
.long mom_l2
.long mom_l1
.long mom_l3
.long mom_r1
.long mom_r2
.long mom_r1
.long mom_r3
.long mom_u1
.long mom_u2
.long mom_u1
.long mom_u3
.long mom_d1
.long mom_d2
.long mom_d1
.long mom_d3
#mom_tablex
#dad_table
.long dad_l1
.long dad_l2
.long dad_l1
.long dad_l3
.long dad_r1
.long dad_r2
.long dad_r1
.long dad_r3
.long dad_u1
.long dad_u2
.long dad_u1
.long dad_u3
.long dad_d1
.long dad_d2
.long dad_d1
.long dad_d3
#dad_tablex
#kid_table
.long kid_l1
.long kid_l2
.long kid_l1
.long kid_l3
.long kid_r1
.long kid_r2
.long kid_r1
.long kid_r3
.long kid_u1
.long kid_u2
.long kid_u1
.long kid_u3
.long kid_d1
.long kid_d2
.long kid_d1
.long kid_d3
#kid_tablex
#saved_table
.long one_k
.long two_k
.long three_k
.long four_k
.long five_k
#saved_tablex
#*****************************************************************************
******************************************************************************
******************************************************************************
*
* HULK SECTION
*
;reg use
; a0 - (in) # of hulks
SUBRP make_hulks
move a0,a0
jrz #done
#another_hulk
PUSHP a0
#get_pos
movi #max_x-#min_x,a0
calla RNDRNG0
move a0,a9
movi #max_y-#min_y,a0
calla RNDRNG0
move a0,a10
addi #min_x,a9
addi #min_y,a10
cmpi #mid_x1,a9
jrle #place_hulk
cmpi #mid_x2,a9
jrge #place_hulk
cmpi #mid_y1,a10
jrle #place_hulk
cmpi #mid_y2,a10
jrge #place_hulk
jruc #get_pos
#place_hulk
;assign a random starting position
CREATE HULK_PID,hulk
PULLP a0
dsj a0,#another_hulk
#done
rets
#min_x equ 53 ;hulk start outer boundaries
#max_x equ 347-13
#min_y equ 45
#max_y equ 231-16
#mid_x1 equ 200-50 ;hulk start inner boundaries
#mid_x2 equ 200+50
#mid_y1 equ 138-50
#mid_y2 equ 138+50
#*****************************************************************************
*
* hulk process
*
STRUCTPD
LONG #PD_SCRIPT ;UHL script head
WORD #PD_FRAME_NDX ;UHW frame index
;reg use
; a8 - object handle
; a9 - (in) starting x
; a9 - (use) frame change count
;a10 - (in) starting y
;a11 - direction of motion (0-3)
SUBRP hulk
;choose a direction of motion
movi 3,a0
calla RNDRNG0
move a0,a11
X32 a0
addi #anim_list,a0
move *a0,a6,L
move a6,*a13(#PD_SCRIPT),L
clr a7
move a7,*a13(#PD_FRAME_NDX),W
;create the hulk object
move a9,a0 ;x pos
sla 16,a0
move a10,a1 ;y pos
sla 16,a1
move a7,a14 ;img
X32 a14
add a6,a14
move *a14,a2,L
clr a3
movi DMAWNZ,a4
movi CLSENMY|TYPHULK,a5
clr a6
clr a7
calla BEGINOBJW
;set the move counter
movi #move_freq/2,a0
calla RNDRNG0
addi #move_freq,a0
move a0,a9
#loop
SLEEPK 1
dsj a9,#loop
callr #move_hulk
movi #move_freq,a9
jruc #loop
#been_shot ;we immediately wake up here if we've been hit and moved
; by a player bullet.
callr #do_bounds_check
jruc #loop
DIE
******************************************************************************
*
* hulk move routine
*
;reg use
; a0 scratch
; a1 scratch
; a8 object handle
;a11 direction of motion (0-3)
SUBRP #move_hulk
;move him
move a11,a14
X32 a14
addi #move_table,a14
move *a14+,a0,W
move *a14,a1,W
move *a8(OXPOS),a14,W
add a0,a14
move a14,*a8(OXPOS),W
move *a8(OYPOS),a14,W
add a1,a14
move a14,*a8(OYPOS),W
;
;note the fall-through here
;
;bounds check
SUBRP #do_bounds_check
clr a1
clr a0
move *a8(OXPOS),a0,W
cmpi #low_x,a0
jrlt #too_left
cmpi #high_x,a0
jrgt #too_right
jruc #vert_check
#too_left
movi #low_x,a14
move a14,*A8(OXPOS),W
ori M_HIT_LEFT,a1
jruc #vert_check
#too_right
movi #high_x,a14
move a14,*A8(OXPOS),W
ori M_HIT_RIGHT,a1
; jruc #vert_check
#vert_check
clr a0
move *a8(OYPOS),a0,W
cmpi #low_y,a0
jrlt #too_high
cmpi #high_y,a0
jrgt #too_low
jruc #done_boundcheck
#too_high
movi #low_y,a14
move a14,*A8(OYPOS),W
ori M_HIT_TOP,a1
jruc #done_boundcheck
#too_low
movi #high_y,a14
move a14,*A8(OYPOS),W
ori M_HIT_BOTTOM,a1
jruc #done_boundcheck
#done_boundcheck
move a1,a1
jrnz #change_direction
#no_wallhit
movi #turn_prob,a0
PUSH a1
calla RNDRNG0
PULL a1
move a0,a0
jrnz #done_moving
;spontaneous direction change. random for now
; jruc #change_direction ;fall through
#change_direction
;turn 90 degrees by randomly incrementing or decrementing direction
movi 1,a0
PUSH a1
calla RNDRNG0
PULL a1
move a0,a0
jrz #inc_direction
dec a11
jruc #dir_rangecheck
#inc_direction
inc a11
#dir_rangecheck
cmpi -1,a11
jrne #dir_notlow
movi 3,a11
#dir_notlow
cmpi 4,a11
jrne #dir_changed
clr a11
#dir_changed
;verify that this is a good direction
cmpi 0,a11
jreq #validate_up
cmpi 1,a11
jreq #validate_right
cmpi 2,a11
jreq #validate_down
cmpi 3,a11
jreq #validate_left
#validate_up
andi M_HIT_TOP,a1
jrnz #change_direction
jruc #valid_dir
#validate_right
andi M_HIT_RIGHT,a1
jrnz #change_direction
jruc #valid_dir
#validate_down
andi M_HIT_BOTTOM,a1
jrnz #change_direction
jruc #valid_dir
#validate_left
andi M_HIT_LEFT,a1
jrnz #change_direction
jruc #valid_dir
#valid_dir
move a11,a0
X32 a0
addi #anim_list,a0
move *a0,a0,L
move a0,*a13(#PD_SCRIPT),L
#done_moving
#new_frame
move *a13(#PD_FRAME_NDX),a14,W
move *a13(#PD_SCRIPT),a6,L
inc a14
cmpi 4,a14
jrne #no_wrap
clr a14
#no_wrap
move a14,*a13(#PD_FRAME_NDX),W
X32 a14
add a6,a14
move *a14,a0,L
calla civanic
rets
******************************************************************************
*
* hulk collision routines
*
SUBR hulk_pushback
PUSH a1,a7,a9,a10,a11,a13
;immediately move the hulk in the direction of the bullet's motion
move *a0(OXVEL),a14,L
sra 17,a14
move *a8(OXPOS),a1,W
add a14,a1
move a1,*a8(OXPOS),W
move *a0(OYVEL),a14,L
sra 17,a14
move *a8(OYPOS),a1,W
add a14,a1
move a1,*a8(OYPOS),W
;wake up at the collision check
move *a8(OPLINK),a0,L
move *a0(PA9),a9,L
move *a0(PA10),a10,L
move *a0(PA11),a11,L
movi HULK_PID,a1
movi #been_shot,a7
calla XFERPROC
PULL a1,a7,a9,a10,a11,a13
rets
******************************************************************************
*
* hulk configuration data
*
#step_x equ 4
#step_y equ 4
#low_x equ 53 ;hulk move boundaries
#high_x equ 347-13
#low_y equ 45
#high_y equ 231-16
#move_freq equ 8 ;frames between moves
#turn_prob equ 30 ;chance per frame of spontaneously changing
;direction
#move_table
.word 0,-#step_y
.word #step_x,0
.word 0,#step_y
.word -#step_x,0
#move_tablex
#anim_list
.long #anim_vert
.long #anim_right
.long #anim_vert
.long #anim_left
#anim_listx
#anim_vert
.long hulk_ud1
.long hulk_ud2
.long hulk_ud1
.long hulk_ud3
#anim_vertx
#anim_left
.long hulk_l1
.long hulk_l2
.long hulk_l1
.long hulk_l3
#anim_leftx
#anim_right
.long hulk_r1
.long hulk_r2
.long hulk_r1
.long hulk_r3
#anim_rightx
#*****************************************************************************
******************************************************************************
******************************************************************************
*
* SPHEREOID SECTION
*
;reg use
; a0 - (in) # of sphereoids
SUBRP make_sphereoids
move a0,a0
jrz #done
#another_sphereoid
PUSHP a0
#get_pos
movi #max_x-#min_x,a0
calla RNDRNG0
move a0,a9
movi #max_y-#min_y,a0
calla RNDRNG0
move a0,a10
addi #min_x,a9
addi #min_y,a10
cmpi #mid_x1,a9
jrle #place_sphereoid
cmpi #mid_x2,a9
jrge #place_sphereoid
cmpi #mid_y1,a10
jrle #place_sphereoid
cmpi #mid_y2,a10
jrge #place_sphereoid
jruc #get_pos
#place_sphereoid
;assign a random starting position
CREATE SPHEREOID_PID,sphereoid
PULLP a0
dsj a0,#another_sphereoid
#done
rets
#mid_x1 equ 200-80 ;sphereoid start inner boundaries
#mid_x2 equ 200+80
#mid_y1 equ 138-80
#mid_y2 equ 138+80
*******************************************************************************
*
* sphereoid process
*
STRUCTPD
LONG #OXACC ;UHL x acceleration
LONG #OYACC ;UHL y acceleration
WORD #OCHILDREN ;UHW # of children left to spawn
WORD #OSTAGE ;UHW stage in life cycle
;reg use
; a7 (use) event timer (related to #OSTAGE)
; a8 (use) * object
; a9 (in) x pos
; a9 (use) anim counter
;a10 (in) y pos
;a10 (use) frame pointer
;a11 (use) time until next vel change
SUBRP sphereoid
;increment the badguy count
move @live_badguys,a14,W
inc a14
move a14,@live_badguys,W
;create the sphereoid object
move a9,a0 ;x pos
sll 16,a0
move a10,a1 ;y pos
sll 16,a1
movi #standard_script,a10
move *a10+,a2,L ;img
clr a3
movi DMAWNZ,a4
movi CLSENMY|TYPSPHEREOID,a5
clr a6
clr a7
calla BEGINOBJW
;initialize anim counter
movi #anim_speed,a9
;set initial velocities and accelerations
callr #set_va
;initialize life cycle and event timer
movi #STAGE_YOUTH,a14
move a14,*a13(#OSTAGE),W
movi #youth_time/2,a0
calla RNDRNG0
addi #youth_time*3/4,a0
move a0,a7
#loop
PUSHP a7
SLEEPK 1
PULLP a7
dec a9
jrnz #no_anim
;advance the frame
move *a10+,a0,L
jrnz #newframe
;reset script. depends on the stage
move *a13(#OSTAGE),a14,W
cmpi #STAGE_PARENT,a14
jreq #set_parent_script
movi #standard_script,a10
jruc #script_set
#set_parent_script
movi #parent_script,a10
#script_set
move *a10+,a0,L
#newframe
calla civanic
;reset the counter
movi #anim_speed,a9
#no_anim
;adjust velocities
callr #acc_add
;bounds check
callr #in_bounds
;adjust vel and acc if it's time
dec a11
jrnz #no_va_change
callr #set_va
#no_va_change
;do event?
dec a7
jrnz #no_event
;event. depends on the stage in the life cycle
move *a13(#OSTAGE),a14,W
cmpi #STAGE_YOUTH,a14
jreq #youth_event
cmpi #STAGE_PARENT,a14
jreq #parent_event
;default
jruc #dotage_event
#youth_event
;switch to middle age
movi #STAGE_PARENT,a14
move a14,*a13(#OSTAGE),W
;set the number of kids to be spawned
movi #max_kids-#min_kids,a0
calla RNDRNG0
addi #min_kids,a0
move a0,*a13(#OCHILDREN),W
;set the spawn timer
movi #spawn_time/2,a0
calla RNDRNG0
addi #spawn_time*3/4,a0
move a0,a7
jruc #no_event
#parent_event
;spawn a brat
PUSHP a10,a11
move *a8(OXVAL),a10,L
move *a8(OYVAL),a11,L
CREATE ENFORCER_PID,enforcer
PULLP a10,a11
;decrement the kid count
move *a13(#OCHILDREN),a14,W
dec a14
jrz #barren
move a14,*a13(#OCHILDREN),W
movi #spawn_time/2,a0
calla RNDRNG0
addi #spawn_time*3/4,a0
move a0,a7
jruc #no_event
#barren
;that was the last kid. age
movi #STAGE_DOTAGE,a14
move a14,*a13(#OSTAGE),W
movi #old_age_time,a7
jruc #no_event
#dotage_event
;nothing fancy. just die.
jruc #die_peacefully
#no_event
jruc #loop
#been_shot
;crud. we've been shot. score the points
movi #sphereoid_points,a0
callr score_points
;decrement the badguy count
move @live_badguys,a14,W
dec a14
move a14,@live_badguys,W
;clear the velocity
clr a14
move a14,*a8(OXVEL),L
move a14,*a8(OYVEL),L
;go through the death routine
movi #parent_script,a10,L
move *a8(OCTRL),a14,W
xori DMAWNZ,a14
ori DMACNZ,a14
move a14,*a8(OCTRL),W
movi #diecolor,a14
move a14,*a8(OCONST),W
movi robo_p,a0
calla pal_getf
move a0,*a8(OPAL),W
#die_loop
SLEEPK #anim_speed
move *a10+,a0,L
jrz #score_msg
calla civanic
jruc #die_loop
#score_msg
movi #score_image,a0
move *a8(OCTRL),a1,W
xori DMACNZ,a1
ori DMAWNZ,a1
calla civani
movi #score_xoff,a14
move a14,*a8(ODXOFF),W
movi #score_yoff,a14
move a14,*a8(ODYOFF),W
SLEEP #score_time
jruc #expire
#die_peacefully
;decrement the badguy count
move @live_badguys,a14,W
dec a14
move a14,@live_badguys,W
#expire
calla DELOBJA8
DIE
SUBRP #set_va
movi #high_v*2,a0
calla RNDRNG0
subi #high_v,a0
move a0,*a8(OXVEL),L
movi #high_v*2,a0
calla RNDRNG0
subi #high_v,a0
move a0,*a8(OYVEL),L
movi #high_a*2,a0
calla RNDRNG0
subi #high_a,a0
move a0,*a13(#OXACC),L
movi #high_a*2,a0
calla RNDRNG0
subi #high_a,a0
move a0,*a13(#OYACC),L
movi #va_change_time,a0
calla RNDRNG0
inc a0
move a0,a11
rets
SUBRP #acc_add
move *a13(#OXACC),a14,L
move *a8(OXVEL),a0,L
add a14,a0
move a0,*a8(OXVEL),L
move *a13(#OYACC),a14,L
move *a8(OYVEL),a0,L
add a14,a0
move a0,*a8(OYVEL),L
rets
SUBRP #in_bounds
move *a8(OXPOS),a14,W
movi #min_x,a0
cmp a0,a14
jrlt #x_adjust
movi #max_x,a0
cmp a0,a14
jrgt #x_adjust
jruc #y_check
#x_adjust
move a0,*a8(OXPOS),W
clr a0
move a0,*a8(OXVEL),L
move a0,*a13(#OXACC),L
#y_check
move *a8(OYPOS),a14,W
movi #min_y,a0
cmp a0,a14
jrlt #y_adjust
movi #max_y,a0
cmp a0,a14
jrgt #y_adjust
jruc #done_check
#y_adjust
move a0,*a8(OYPOS),W
clr a0
move a0,*a8(OYVEL),L
move a0,*a13(#OYACC),L
#done_check
rets
******************************************************************************
*
* sphereoid collision routines
*
SUBR sphereoid_die
PUSH a1,a7
movi CLSDEAD,a14
move a14,*a8(OID),W
move *a8(OPLINK),a0,L
movi DEADSPHERE_PID,a1
movi #been_shot,a7
calla XFERPROC
PULL a1,a7
rets
******************************************************************************
*
* sphereoid configuration data
*
#anim_speed equ 3
#va_change_time equ 180
#sphereoid_points equ 1000
#youth_time equ 180 ;time before we have kids
#spawn_time equ 120 ;time between kids
#old_age_time equ 180 ;time between last kid and natural death
#min_kids equ 3 ;lower limit on spawned enforcers
#max_kids equ 7 ;upper limit
#high_v equ 00004000h
#high_a equ 00000C00h
#min_x equ 53 ;sphereoid move bounds
#max_x equ 347-15
#min_y equ 45
#max_y equ 231-15
#score_image equ one_k ;image on being shot
#diecolor equ 0909h ;color on being shot
#score_time equ 60 ;time to display score value
#score_xoff equ -3 ;shotimage offset
#score_yoff equ -5
;life cycle stages
#STAGE_YOUTH equ 0000h
#STAGE_PARENT equ 0001h
#STAGE_DOTAGE equ 0002h
#standard_script
.long circle_1
.long circle_2
.long circle_3
.long circle_4
.long circle_5
.long 0
#parent_script
.long circle_1
.long circle_2
.long circle_3
.long circle_4
.long circle_5
.long circle_6
.long circle_7
.long circle_8
.long 0
#*****************************************************************************
******************************************************************************
******************************************************************************
*
* ENFORCER SECTION
*
.bss num_enforcers, 16 ;active enforcers
.bss picket_duty, 32 ;*img of picket enforcer
;reg use
; a8 (use) *img
; a9 (use) next move timer (move/fire phase)
; a9 (use) frame pointer (death phase)
; a10 (in) initial X
; a10 (use) frame pointer (grow phase)
; a11 (in) initial Y
; a11 (use) next shot timer (move/fire phase)
SUBRP enforcer
;increment the badguy count
move @live_badguys,a14,W
inc a14
move a14,@live_badguys,W
move @num_enforcers,a14,W
inc a14
move a14,@num_enforcers,W
;create the enforcer object
move a10,a0
move a11,a1
movi #grow_script,a10
move *a10+,a2,L
clr a3
movi DMAWNZ,a4
movi CLSENMY|TYPENFORCER,a5
clr a6
clr a7
calla BEGINOBJW
;grow phase
#grow_loop
SLEEPK #grow_speed
move *a10+,a0,L
jrz #mf_phase
calla civanic
jruc #grow_loop
#mf_phase
;begin move/fire phase. set initial course
callr #new_course
movi #turn_time,a9
movi #fire_time/2,a0
calla RNDRNG0
addi #fire_time*3/4,a0
move a0,a11
#main_loop
SLEEPK 1
dec a9
jrnz #no_turn
;picket phase
;two cases: we're on picket duty, or we're not.
move @picket_duty,a14,L
cmp a14,a8
jreq #on_picket
;we're not on picket duty
;if we're the only enforcer, quit now.
move @num_enforcers,a14,W
cmpi 1,a14
jreq #picket_done
;there are multiple enforcers. If there is no picket, see if we
; take the job. If there is, quit.
move @picket_duty,a14,L
jrnz #picket_done
;there is no picket.
movi #picket_prob,a0
calla RNDRNG0
move a0,a0
jrnz #picket_done
;we're going to take picket duty
move a8,@picket_duty,L
jruc #picket_done
#on_picket
;we are on picket duty
;if we're the only enforcer, see if we leave picket mode.
move @num_enforcers,a14,W
cmpi 1,a14
jrne #multiple_enforcers
;we're the only enforcer
movi #stand_down_prob,a0
calla RNDRNG0
move a0,a0
jrnz #picket_done
;and we've decided to stand down.
; clr a0 ;unneccesary. it's already 0 from above.
move a0,@picket_duty,L
jruc #picket_done
#multiple_enforcers
;we may abandon our post
movi #abandon_post_prob,a0
calla RNDRNG0
move a0,a0
jrnz #picket_done
;yep. we quit.
; clr a0 ;unneccesary. it's already 0 from above.
move a0,@picket_duty,L
; jruc #picket_done
#picket_done
;change course
callr #new_course
movi #turn_time,a9
#no_turn
dec a11
jrnz #no_shot
;fire a spark
PUSHP a10
move *a8(OXVAL),a10,L
move *a8(OYVAL),a11,L
CREATE SPARK_PID,spark
PULLP a10
movi #fire_time/2,a0
calla RNDRNG0
addi #fire_time*3/4,a0
move a0,a11
#no_shot
;bounds check
callr #in_bounds
jruc #main_loop
#die
;decrement the badguy count
move @live_badguys,a14,W
dec a14
move a14,@live_badguys,W
move @num_enforcers,a14,W
dec a14
move a14,@num_enforcers,W
;zero our velocity
clr a14
move a14,*a8(OXVEL),L
move a14,*a8(OYVEL),L
;set up the animation
#dieloop
move *a9+,a0,L
jrz #dead_n_buried
calla civanic
sleepk #death_speed
jruc #dieloop
#dead_n_buried
calla DELOBJA8
DIE
SUBRP #new_course
;two cases. picket or !picket
move @picket_duty,a14,L
cmp a8,a14
jrne #nc_notpicket
#nc_picket
;we're on picket duty. if we're not against a wall, move toward the
; nearest one. if we are against a wall but not in a corner, move
; toward the nearest corner. if we're in a corner, sit tight.
; jruc #nc_done
#nc_notpicket
;velocity is the distance between enforcer and player / 64 / 2
move @player_object,a0,L
move *a0(OXVAL),a14,L
move *a8(OXVAL),a1,L
sub a1,a14
sra 7,a14
move a14,*a8(OXVEL),L
move *a0(OYVAL),a14,L
move *a8(OYVAL),a1,L
sub a1,a14
sra 7,a14
move a14,*a8(OYVEL),L
#nc_done
rets
SUBRP #in_bounds
move *a8(OXPOS),a14,W
movi #min_x,a0
cmp a0,a14
jrlt #x_adjust
movi #max_x,a0
cmp a0,a14
jrgt #x_adjust
jruc #y_check
#x_adjust
move a0,*a8(OXPOS),W
clr a0
move a0,*a8(OXVEL),L
#y_check
move *a8(OYPOS),a14,W
movi #min_y,a0
cmp a0,a14
jrlt #y_adjust
movi #max_y,a0
cmp a0,a14
jrgt #y_adjust
jruc #done_check
#y_adjust
move a0,*a8(OYPOS),W
clr a0
move a0,*a8(OYVEL),L
#done_check
rets
******************************************************************************
*
* enforcer collision routines
*
SUBR enforcer_die
;hit by player gunfire
PUSH a1,a7
;jeepers. we're dead.
movi CLSDEAD,a14
move a14,*a8(OID),W
move *a0(OXVEL),a14,L
jrz #vert_bullet
move *a0(OYVEL),a1,L
jrz #horz_bullet
add a1,a14
jrz #diag_13
jruc #diag_24
#horz_bullet
movi #die_vert,a9
jruc #death_set
#vert_bullet
movi #die_horz,a9
jruc #death_set
#diag_13
movi #die_diag24,a9
jruc #death_set
#diag_24
movi #die_diag13,a9
jruc #death_set
#death_set
move *a8(OPLINK),a0,L
movi DEADNFORCER_PID,a1
movi #die,a7
move *a0(PA10),a10,L
calla XFERPROC
movi #enforcer_points,a0
callr score_points
PULL a1,a7
rets
******************************************************************************
*
* enforcer configuration data
*
#enforcer_points equ 100
#picket_prob equ 4 ;one chance in X of becoming the picket if
; there are multiple enforcers and none is
; on the job already.
#stand_down_prob equ 4 ;one chance in X of leaving picket duty if
; we're the only enforcer left.
#abandon_post_prob equ 8 ;one chance in X of leaving picket duty if
; there are other enforcers around.
#turn_time equ 150
#fire_time equ 90
#grow_speed equ 6
#min_x equ 53 ;enforcer move bounds
#max_x equ 347-9
#min_y equ 45
#max_y equ 231-11
#grow_script
.long enf_g1
.long enf_g2
.long enf_g3
.long enf_g4
.long enf_g5
.long enf_1
.long 0
#grow_scriptx
#die_vert
.long enf_xv1
.long enf_xv2
.long enf_xv3
.long enf_xv4
.long enf_xv5
.long 0
#die_vertx
#die_horz
.long enf_xh1
.long enf_xh2
.long enf_xh3
.long enf_xh4
.long 0
#die_horzx
#die_diag13
.long enf_xf1
.long enf_xf2
.long enf_xf3
.long enf_xf4
.long 0
#die_diag13x
#die_diag24
.long enf_xb1
.long enf_xb2
.long enf_xb3
.long enf_xb4
.long 0
#die_diag24x
#death_speed equ 3 ;death seq anim speed
#*****************************************************************************
******************************************************************************
******************************************************************************
*
* SPARK SECTION
*
;reg use
; a6 (use) x acc
; a7 (use) y acc
; a8 (use) *image
; a9 (use) anim timer
; a10 (in) initial X
; a10 (use) anim pointer
; a11 (in) initial Y
; a11 (use) life timer
SUBRP spark
;create a spark object
move a10,a0
move a11,a1
movi #script,a10
move *a10+,a2,L
clr a3
movi DMAWNZ,a4
movi CLSENMY|TYPSPARK,a5
clr a6
clr a7
calla BEGINOBJW
;set the initial velocity.
move @player_object,a0,L
move *a0(OXVAL),a1,L
move *a8(OXVAL),a2,L
sub a2,a1
sra 5,a1
move a1,*a8(OXVEL),L
move *a0(OYVAL),a1,L
move *a8(OYVAL),a2,L
sub a2,a1
sra 5,a1
move a1,*a8(OYVEL),L
;and then add a little 'spin' by giving them some acceleration
movi #high_acc*2,a0
calla RNDRNG0
subi #high_acc,a0
move a0,a6
movi #high_acc*2,a0
calla RNDRNG0
subi #high_acc,a0
move a0,a7
movi #anim_time,a9
movi #life_time,a11
#loop
PUSHP a6,a7
SLEEPK 1
PULLP a6,a7
;bounds check
callr #in_bounds
;apply accelerations
move *a8(OXVEL),a14,L
add a6,a14
move a14,*a8(OXVEL),L
move *a8(OYVEL),a14,L
add a7,a14
move a14,*a8(OYVEL),L
dec a9
jrnz #no_anim
move *a10+,a0,L
jrnz #no_wrap
movi #script,a10
move *a10+,a0,L
#no_wrap
calla civanic
movi #anim_time,a9
#no_anim
dec a11
jrz #expire
jruc #loop
#expire
calla DELOBJA8
DIE
SUBRP #in_bounds
move *a8(OXPOS),a14,W
movi #min_x,a0
cmp a0,a14
jrlt #x_adjust
movi #max_x,a0
cmp a0,a14
jrgt #x_adjust
jruc #y_check
#x_adjust
move a0,*a8(OXPOS),W
clr a6
move a6,*a8(OXVEL),L
#y_check
move *a8(OYPOS),a14,W
movi #min_y,a0
cmp a0,a14
jrlt #y_adjust
movi #max_y,a0
cmp a0,a14
jrgt #y_adjust
jruc #done_check
#y_adjust
move a0,*a8(OYPOS),W
clr a7
move a7,*a8(OYVEL),L
#done_check
rets
******************************************************************************
*
* spark collision routines
*
SUBR spark_die
PUSH a1,a7
movi CLSDEAD,a14
move a14,*a8(OID),W
move *a8(OPLINK),a0,L
movi DEADSPARK_PID,a1
movi #expire,a7
calla XFERPROC
PULL a1,a7
rets
******************************************************************************
*
* spark configuration data
*
#life_time equ 180 ;how long they last
#anim_time equ 3 ;frame rate
#high_acc equ 00000200h ;top acceleration
#min_x equ 53 ;spark move bounds
#max_x equ 347-7
#min_y equ 45
#max_y equ 231-7
#script
.long spark_1
.long spark_2
.long spark_3
.long spark_4
.long 0
#*****************************************************************************
******************************************************************************
******************************************************************************
*
* QUARK SECTION
*
;reg use
; a0 - (in) # of quarks
SUBRP make_quarks
move a0,a0
jrz #done
#another_quark
PUSHP a0
#get_pos
;assign a random starting position
movi #max_x-#min_x,a0
calla RNDRNG0
move a0,a9
movi #max_y-#min_y,a0
calla RNDRNG0
move a0,a10
addi #min_x,a9
addi #min_y,a10
cmpi #mid_x1,a9
jrle #place_quark
cmpi #mid_x2,a9
jrge #place_quark
cmpi #mid_y1,a10
jrle #place_quark
cmpi #mid_y2,a10
jrge #place_quark
jruc #get_pos
#place_quark
CREATE QUARK_PID,quark
PULLP a0
dsj a0,#another_quark
#done
rets
#mid_x1 equ 200-60 ;quark start inner boundaries
#mid_x2 equ 200+60
#mid_y1 equ 138-60
#mid_y2 equ 138+60
*******************************************************************************
*
* quark process
*
STRUCTPD
WORD #OCHILDREN ;UHW # of children left to spawn
WORD #OSTAGE ;UHW stage in life cycle
;reg use
; a7 (use) event timer (related to #OSTAGE)
; a8 (use) * object
; a9 (in) x pos
; a9 (use) anim counter
;a10 (in) y pos
;a10 (use) frame pointer
;a11 (use) time until next vel change
SUBRP quark
;increment the badguy count
move @live_badguys,a14,W
inc a14
move a14,@live_badguys,W
;create the quark object
move a9,a0 ;x pos
sll 16,a0
move a10,a1 ;y pos
sll 16,a1
movi #standard_script,a10
move *a10+,a2,L ;img
clr a3
movi DMAWNZ,a4
movi CLSENMY|TYPQUARK,a5
clr a6
clr a7
calla BEGINOBJW
;initialize anim counter
movi #anim_speed,a9
;set initial velocities and accelerations
callr #set_v
;initialize life cycle and event timer
movi #STAGE_YOUTH,a14
move a14,*a13(#OSTAGE),W
movi #youth_time,a7
#loop
PUSHP a7
SLEEPK 1
PULLP a7
dec a9
jrnz #no_anim
;advance the frame
move *a10+,a0,L
jrnz #newframe
;reset script. depends on the stage
move *a13(#OSTAGE),a14,W
cmpi #STAGE_PARENT,a14
jreq #set_parent_script
movi #standard_script,a10
jruc #script_set
#set_parent_script
movi #parent_script,a10
#script_set
move *a10+,a0,L
#newframe
calla civanic
;reset the counter
movi #anim_speed,a9
#no_anim
;bounds check
callr #in_bounds
;adjust vel if it's time
dec a11
jrnz #no_v_change
callr #set_v
#no_v_change
;do event?
dec a7
jrnz #no_event
;event. depends on the stage in the life cycle
move *a13(#OSTAGE),a14
cmpi #STAGE_YOUTH,a14
jreq #youth_event
cmpi #STAGE_PARENT,a14
jreq #parent_event
;default
jruc #dotage_event
#youth_event
;switch to middle age
movi #STAGE_PARENT,a14
move a14,*a13(#OSTAGE),W
;set the number of kids to be spawned
movi #max_kids-#min_kids,a0
calla RNDRNG0
addi #min_kids,a0
move a0,*a13(#OCHILDREN),W
;set the spawn timer
movi #spawn_time,a7
jruc #no_event
#parent_event
;spawn a brat
PUSHP a10,a11
move *a8(OXVAL),a10,L
move *a8(OYVAL),a11,L
CREATE TANK_PID,tank
PULLP a10,a11
;decrement the kid count
move *a13(#OCHILDREN),a14,W
dec a14
jrz #barren
move a14,*a13(#OCHILDREN),W
movi #spawn_time,a7
jruc #no_event
#barren
;that was the last kid. age
movi #STAGE_DOTAGE,a14
move a14,*a13(#OSTAGE),W
movi #old_age_time,a7
jruc #no_event
#dotage_event
;nothing fancy. just die.
jruc #die_peacefully
#no_event
jruc #loop
#been_shot
;crud. we've been shot
#die_peacefully
;decrement the badguy count
move @live_badguys,a14,W
dec a14
move a14,@live_badguys,W
calla DELOBJA8
DIE
SUBRP #set_v
movi #high_v,a0
calla RNDRNG0
cmpi #high_v/2,a0
jrgt #positive_x
subi #high_v,a0
#positive_x
move a0,*a8(OXVEL),L
movi #high_v,a0
calla RNDRNG0
cmpi #high_v/2,a0
jrgt #positive_y
subi #high_v,a0
#positive_y
move a0,*a8(OYVEL),L
movi #v_change_time/2,a0
calla RNDRNG0
addi #v_change_time/2,a0
move a0,a11
rets
SUBRP #in_bounds
move *a8(OXPOS),a1,W
movi #min_x,a0
move *a8(ODXOFF),a14,W
add a14,a0
cmp a0,a1
jrlt #x_adjust
move *a8(OSIZEX),a0,W
neg a0
move *a8(ODXOFF),a14,W
add a14,a0
addi #max_x,a0
cmp a0,a1
jrgt #x_adjust
jruc #y_check
#x_adjust
move a0,*a8(OXPOS),W
move *a8(OXVEL),a0,L
neg a0
move a0,*a8(OXVEL),L
#y_check
move *a8(OYPOS),a1,W
movi #min_y,a0
move *a8(ODYOFF),a14,W
add a14,a0
cmp a0,a1
jrlt #y_adjust
move *a8(OSIZEY),a0,W
neg a0
move *a8(ODYOFF),a14,W
add a14,a0
addi #max_y,a0
cmp a0,a1
jrgt #y_adjust
jruc #done_check
#y_adjust
move a0,*a8(OYPOS),W
move *a8(OYVEL),a0,L
neg a0
move a0,*a8(OYVEL),L
#done_check
rets
******************************************************************************
*
* quark collision routines
*
SUBR quark_die
PUSH a1,a7
movi CLSDEAD,a14
move a14,*a8(OID),W
move *a8(OPLINK),a0,L
movi DEADQUARK_PID,a1
movi #been_shot,a7
calla XFERPROC
PULL a1,a7
rets
******************************************************************************
*
* quark configuration data
*
#anim_speed equ 3
#v_change_time equ 600 ;time between random course changes
#youth_time equ 90 ;time before we have kids
#spawn_time equ 90 ;time between kids
#old_age_time equ 120 ;time between last kid and natural death
#min_kids equ 3 ;lower limit on spawned tanks
#max_kids equ 7 ;upper limit
#high_v equ 0001C000h
#min_x equ 53 ;quark move bounds
#max_x equ 347-0
#min_y equ 45
#max_y equ 231-0
;life cycle stages
#STAGE_YOUTH equ 0000h
#STAGE_PARENT equ 0001h
#STAGE_DOTAGE equ 0002h
#standard_script
.long quark_1
.long quark_1
.long quark_2
.long quark_3
.long quark_4
.long 0
#parent_script
.long quark_1
.long quark_2
.long quark_3
.long quark_4
.long quark_5
.long quark_6
.long quark_7
.long quark_8
.long 0
#*****************************************************************************
******************************************************************************
******************************************************************************
*
* TANK SECTION
*
STRUCTPD
WORD #OSHOTS ;UHW shots left to be fired
;reg use
; a7 (use) anim timer
; a8 (use) *img
; a9 (use) next move timer (move/fire phase)
; a9 (use) frame pointer (death phase)
; a10 (in) initial X
; a10 (use) frame pointer (grow + move/fire phases)
; a11 (in) initial Y
; a11 (use) next shot timer (move/fire phase)
SUBRP tank
;increment the badguy count
move @live_badguys,a14,W
inc a14
move a14,@live_badguys,W
;create the tank object
move a10,a0
move a11,a1
movi #grow_script,a10
move *a10+,a2,L
clr a3
movi DMAWNZ,a4
movi CLSENMY|TYPTANK,a5
clr a6
clr a7
calla BEGINOBJW
;grow phase
#grow_loop
SLEEPK #grow_speed
move *a10+,a0,L
jrz #mf_phase
calla civanic
jruc #grow_loop
#mf_phase
;begin move/fire phase. set initial course
callr #set_v
movi #anim_time,a7
movi #right_script,a10
movi #fire_time/2,a0
calla RNDRNG0
addi #fire_time*3/4,a0
move a0,a11
movi #num_shots,a14
move a14,*a13(#OSHOTS),W
#main_loop
PUSHP a7
SLEEPK 1
PULLP a7
dec a9
jrnz #no_turn
;change course
callr #set_v
#no_turn
dec a11
jrnz #no_shot
move *a13(#OSHOTS),a14,W
jrz #no_shot
;fire a shell
PUSHP a7,a10,a11
move *a8(OXVAL),a10,L
move *a8(OYVAL),a11,L
create SHELL_PID,tank_shell
PULLP a7,a10,a11
movi #fire_time/2,a0
calla RNDRNG0
addi #fire_time*3/4,a0
move a0,a11
#no_shot
;bounds check
callr #in_bounds
;animate?
dec a7
jrnz #no_anim
move *a10+,a0,L
jrnz #no_wrap
movi #right_script,a10
move *a10+,a0,L
#no_wrap
calla civanic
movi #anim_time,a7
#no_anim
jruc #main_loop
#die
;decrement the badguy count
move @live_badguys,a14,W
dec a14
move a14,@live_badguys,W
;zero our velocity
clr a14
move a14,*a8(OXVEL),L
move a14,*a8(OYVEL),L
;set up the animation
#dieloop
move *a9+,a0,L
jrz #dead_n_buried
calla civanic
sleepk #death_speed
jruc #dieloop
#dead_n_buried
calla DELOBJA8
DIE
SUBRP #set_v
movi #high_v,a0
calla RNDRNG0
cmpi #high_v/2,a0
jrgt #positive_x
subi #high_v,a0
#positive_x
move a0,*a8(OXVEL),L
movi #high_v,a0
calla RNDRNG0
cmpi #high_v/2,a0
jrgt #positive_y
subi #high_v,a0
#positive_y
move a0,*a8(OYVEL),L
movi #v_change_time/2,a0
calla RNDRNG0
addi #v_change_time/2,a0
move a0,a9
rets
SUBRP #in_bounds
move *a8(OXPOS),a14,W
movi #min_x,a0
cmp a0,a14
jrlt #x_adjust
movi #max_x,a0
cmp a0,a14
jrgt #x_adjust
jruc #y_check
#x_adjust
move a0,*a8(OXPOS),W
move *a8(OXVEL),a0,L
neg a0
move a0,*a8(OXVEL),L
#y_check
move *a8(OYPOS),a14,W
movi #min_y,a0
cmp a0,a14
jrlt #y_adjust
movi #max_y,a0
cmp a0,a14
jrgt #y_adjust
jruc #done_check
#y_adjust
move a0,*a8(OYPOS),W
move *a8(OYVEL),a0,L
neg a0
move a0,*a8(OYVEL),L
#done_check
rets
******************************************************************************
*
* tank collision routines
*
SUBR tank_die
;hit by player gunfire
PUSH a1,a7
;jeepers. we're dead.
movi CLSDEAD,a14
move a14,*a8(OID),W
move *a0(OXVEL),a14,L
jrz #vert_bullet
move *a0(OYVEL),a1,L
jrz #horz_bullet
add a1,a14
jrz #diag_13
jruc #diag_24
#horz_bullet
movi #die_vert,a9
jruc #death_set
#vert_bullet
movi #die_horz,a9
jruc #death_set
#diag_13
movi #die_diag24,a9
jruc #death_set
#diag_24
movi #die_diag13,a9
jruc #death_set
#death_set
move *a8(OPLINK),a0,L
movi DEADTANK_PID,a1
movi #die,a7
move *a0(PA10),a10,L
calla XFERPROC
movi #tank_points,a0
callr score_points
PULL a1,a7
rets
******************************************************************************
*
* tank configuration data
*
#tank_points equ 200
#num_shots equ 21
#v_change_time equ 250
#fire_time equ 90
#high_v equ 00010000h
#grow_speed equ 6
#anim_time equ 2
#min_x equ 53 ;tank move bounds
#max_x equ 347-13
#min_y equ 45
#max_y equ 231-16
#grow_script
.long tank_g1
.long tank_g2
.long tank_g3
.long tank_g4
.long tank_1
.long 0
#right_script
.long tank_1
.long tank_2
.long tank_3
.long tank_4
.long 0
#die_vert
.long enf_xv1
.long enf_xv2
.long enf_xv3
.long enf_xv4
.long enf_xv5
.long 0
#die_horz
.long enf_xh1
.long enf_xh2
.long enf_xh3
.long enf_xh4
.long 0
#die_diag13
.long enf_xf1
.long enf_xf2
.long enf_xf3
.long enf_xf4
.long 0
#die_diag24
.long enf_xb1
.long enf_xb2
.long enf_xb3
.long enf_xb4
.long 0
#death_speed equ 3 ;death seq anim speed
#*****************************************************************************
******************************************************************************
******************************************************************************
*
* SHELL SECTION
*
;reg use
; a8 (use) *image
; a10 (in) initial X
; a11 (in) initial Y
; a11 (use) life timer
SUBRP tank_shell
;create a shell object
move a10,a0
move a11,a1
movi shell,a2
clr a3
movi DMAWNZ,a4
movi CLSENMY|TYPSHELL,a5
clr a6
clr a7
calla BEGINOBJW
;set the initial velocity.
move @player_object,a0,L
move *a0(OXVAL),a1,L
move *a8(OXVAL),a2,L
sub a2,a1
sra 5,a1
move a1,*a8(OXVEL),L
move *a0(OYVAL),a1,L
move *a8(OYVAL),a2,L
sub a2,a1
sra 5,a1
move a1,*a8(OYVEL),L
movi #life_time,a11
#loop
PUSHP a6,a7
SLEEPK 1
PULLP a6,a7
;bounds check
callr #in_bounds
dsj a11,#loop
#expire
calla DELOBJA8
DIE
SUBRP #in_bounds
move *a8(OXPOS),a14,W
movi #min_x,a0
cmp a0,a14
jrlt #x_adjust
movi #max_x,a0
cmp a0,a14
jrgt #x_adjust
jruc #y_check
#x_adjust
move a0,*a8(OXPOS),W
move *a8(OXVEL),a0,L
neg a0
move a0,*a8(OXVEL),L
#y_check
move *a8(OYPOS),a14
movi #min_y,a0
cmp a0,a14
jrlt #y_adjust
movi #max_y,a0
cmp a0,a14
jrgt #y_adjust
jruc #done_check
#y_adjust
move a0,*a8(OYPOS),W
move *a8(OYVEL),a0,L
neg a0
move a0,*a8(OYVEL),L
#done_check
rets
******************************************************************************
*
* shell collision routines
*
SUBR shell_die
PUSH a1,a7
movi CLSDEAD,a14
move a14,*a8(OID),W
move *a8(OPLINK),a0,L
movi DEADSHELL_PID,a1
movi #expire,a7
calla XFERPROC
PULL a1,a7
rets
******************************************************************************
*
* shell configuration data
*
#life_time equ 240 ;how long they last
#min_x equ 53 ;shell move bounds
#max_x equ 347-7
#min_y equ 45
#max_y equ 231-7
#*****************************************************************************
******************************************************************************
******************************************************************************
*
* color cycling processes
*
SUBRP robo_pal_cycles
;laser flash cycle
movi [0Ah,1],a8 ;cycle color A
movi robo_p,a9 ;pal name
movi COLTAB_LFLASH,a10 ;use the LFLASH table
movk 1,a11 ;cycle speed
CREATE CYCPID,CYCLE_TABLE
;rgb cycle
movi [0Bh,1],a8 ;cycle color B
movi robo_p,a9 ;pal name
movi COLTAB_RGB,a10 ;use the RGB table
movk 8,a11 ;cycle speed
CREATE CYCPID,CYCLE_TABLE
;decay cycle
movi [0Ch,1],a8 ;cycle color C
movi robo_p,a9 ;pal name
movi COLTAB_DECAY,a10 ;use the DECAY table
movk 2,a11 ;cycle speed
CREATE CYCPID,CYCLE_TABLE
;laser cycle
movi [0Dh,1],a8 ;cycle color D
movi robo_p,a9 ;pal name
movi COLTAB_LASER,a10 ;use the LASER table
movk 20,a11 ;cycle speed
CREATE CYCPID,CYCLE_TABLE
;blue-purple-red cycle
movi [0Eh,1],a8 ;cycle color E
movi robo_p,a9 ;pal name
movi COLTAB_BLUPURRED,a10 ;use the BPR table
movk 1,a11 ;cycle speed
CREATE CYCPID,CYCLE_TABLE
;red-gold cycle
movi [0Fh,1],a8 ;cycle color F
movi robo_p,a9 ;pal name
movi COLTAB_REDGOLD,a10 ;use the RED-GOLD table
movk 10,a11 ;cycle speed
CREATE CYCPID,CYCLE_TABLE
rets
COLTAB_LFLASH
.WORD 0380H,1380H,2380H,3380H,4380H,5380H,6380H,7380H,7300H
.WORD 7280H,7200H,7180H,7080H,7008H,7008H,7010H,7010H,701CH
.WORD 701CH,601CH,501CH,409CH,309CH,209CH,219CH,029CH,039CH
.WORD 139CH,239CH,339CH,539CH,739CH,7390H,7380H,6380H,4380H
.word -1
; .word 7C00h,7FFFh,7FFFh,03E0h,7FFFh,7FFFh,001Fh,7FFFh,7FFFh
COLTAB_RGB
.WORD 07C00H,001FH,77A0h,741Ah
.word -1
; .word 7C00h,03E0h,001Fh
COLTAB_DECAY
.WORD 001CH,001CH,011CH,021CH,031CH,039CH,239CH,2390H,2388H
.WORD 2380H,4300H,5280H,7180H,6180H,7080H,7000H,6000H,5000H
.WORD 4000H,3000H,2000H,1000H
.word -1
; .word 7FFFh,6F7Bh,5EF7h,4E73h,3DEFh,2D6Bh,1CE7h,0C63h,0000h
COLTAB_LASER
.word 7C1Fh,7FFFh,7F00h
.word -1
COLTAB_BLUPURRED
.WORD 001CH,101CH,201CH,301CH,401CH,501CH,601CH,701CH,7010H
.WORD 7010H,7008H,7008H,7000H,7000H,7008H,7008H,7010H,7010H
.WORD 701CH,701CH,601CH,501CH,401CH,301CH,201CH,101CH
; .word 001Fh,7C1Fh,7C00h
.word -1
COLTAB_REDGOLD
.word 7C00h,7F00h
.word -1
#*****************************************************************************
******************************************************************************
******************************************************************************
*
* score stuff
*
;reg use
; a11 score
SUBRP score
;initialize score
move @robotron_score,a11,L
callr #print_score
#loop
SLEEPK 1
move @robotron_score,a14,L
cmp a11,a14
jrne #score_change
jruc #loop
#score_change
move a14,a11
callr #zorch_score
callr #print_score
jruc #loop
DIE
SUBRP #zorch_score
movi TYPTEXT|SUBSCOR,a0
calla obj_del1c
rets
SUBRP #print_score
movi #score_setup,a2
calla setup_message
movi TYPTEXT|SUBSCOR,a14
move a14,@mess_objid
move @robotron_score,a0,L
movi #max_score,a1
calla dec_to_asc
calla copy_string
calla print_string_R
rets
#score_setup
JAM_STR robotron_ascii,3,1,#score_xpos,#score_ypos,robo_p,0
.even
#max_score .equ 9999999 ;that's all dec_to_asc can handle
******************************************************************************
* adds to score
* >a0 amount to add
SUBRP score_points
move @robotron_score,a14,L
add a0,a14
move a14,@robotron_score,L
rets
#score_ypos .equ 36
#score_xpos .equ 130
#*****************************************************************************
******************************************************************************
******************************************************************************
*
* miscellaneous functions / processes
*
******************************************************************************
* Draws the frame
* >a0=color value
*
SUBRP draw_frame
move a0,a9
sla 8,a9
or a0,a9
movi robo_p,a0
calla pal_getf
move a0,a10
movi #frame_data,a11
#loop
move *a11+,a0,L
jrz #done
move *a11+,a1,L
movi #frame_image,a2
movi 100,a3 ;z pos
movi DMACAL,a4 ;DMA flags
movi CLSDEAD,a5 ;object ID
clr a6 ;x vel
clr a7 ;y vel
calla BEGINOBJ
move a8,a0
calla fg2bg
move *a11+,a14,W
move a14,*a8(OSIZEX),W
move *a11+,a14,W
move a14,*a8(OSIZEY),W
move a9,*a8(OCONST),W
move a10,*a8(OPAL),W
jruc #loop
#done
rets
#frame_image equ man_d1
#frame_data
.long [53,0],[43,0] ;position X,Y
.word 294,2 ;size X,Y
.long [53,0],[231,0] ;position X,Y
.word 294,2 ;size X,Y
.long [50,0],[43,0] ;position X,Y
.word 3,190 ;size X,Y
.long [347,0],[43,0] ;position X,Y
.word 3,190 ;size X,Y
.long 0
#frame_datax
#*****************************************************************************
* Draws the wave indicator
*
SUBRP wave_count
;wave text
movi [#wave_x,0],a0 ;x pos
movi [#wave_y,0],a1 ;y pos
movi wave_text,a2 ;* image
clr a3 ;z pos
movi DMAWNZ,a4 ;DMA flags
clr a5 ;object ID
clr a6 ;x vel
clr a7 ;y vel
calla BEGINOBJ
;ones digit
; move @robo_wave,a2,W
; addi HEXTODEC+0010h,a2 ;extra 10 cuz we count from 0
; move *a2,a2,W
; andi 00FFh,a2
move @robo_wave,a0,W
sra 4,a0
inc a0
calla BINBCD
move a0,a2
andi 0Fh,a2
X32 a2
addi #wave_font,a2
movi [#wave_onesx,0],a0 ;x pos
movi [#wave_y,0],a1 ;y pos
move *a2,a2,L ;* image
clr a3 ;z pos
movi DMAWNZ,a4 ;DMA flags
clr a5 ;object ID
clr a6 ;x vel
clr a7 ;y vel
calla BEGINOBJ
;tens digit
move @robo_wave,a0,W
sra 4,a0
inc a0
calla BINBCD
move a0,a2
srl 4,a2
andi 0Fh,a2
jrz #done
X32 a2
addi #wave_font,a2
movi [#wave_tensx,0],a0 ;x pos
movi [#wave_y,0],a1 ;y pos
move *a2,a2,L ;* image
clr a3 ;z pos
movi DMAWNZ,a4 ;DMA flags
clr a5 ;object ID
clr a6 ;x vel
clr a7 ;y vel
calla BEGINOBJ
#done
rets
#wave_y .equ 234
#wave_x .equ 198
#wave_tensx .equ 184
#wave_onesx .equ 188
#wave_font
.long rsmall_0
.long rsmall_1
.long rsmall_2
.long rsmall_3
.long rsmall_4
.long rsmall_5
.long rsmall_6
.long rsmall_7
.long rsmall_8
.long rsmall_9
#wave_fontx
#*****************************************************************************
* Check to see if an object is completely on the playfield
* a8=OBJ
* >a0=walls hit (bit 0=top, 1=right, 2=bottom, 3=left)
* >a2=degree of overlap (in pixels)
* Trashes scratch
SUBRP bounds_check
PUSH a1,a3
clr a0
clr a2
clr a3
;check for hit top
move *a8(OYPOS),a1
move *a8(ODYOFF),a14
sub a14,a1
cmpi #low_y,a1
jrgt #not_high
movi #low_y,a2
sub a1,a2
ori M_HIT_TOP,a0
jruc #not_low ;assume won't be both high and low
#not_high
;check for hit bottom
move *a8(ODYOFF),a14 ;subtract the offset AGAIN because
sub a14,a1 ; we assume the anim point is there
move *a8(OSIZEY),a14 ; to center the object.
add a14,a1
cmpi #high_y,a1
jrlt #not_low
move a1,a2
subi #high_y,a2
ori M_HIT_BOTTOM,a0
#not_low
;check for hit left
move *a8(OXPOS),a1
move *a8(ODXOFF),a14
sub a14,a1
cmpi #low_x,a1
jrgt #not_left
movi #low_x,a3
sub a1,a3
ori M_HIT_LEFT,a0
jruc #done ;assume won't be both right and left
#not_left
move *a8(ODXOFF),a14
sub a14,a1
move *a8(OSIZEX),a14
add a14,a1
cmpi #high_x,a1
jrlt #done
move a1,a3
subi #high_x,a3
ori M_HIT_RIGHT,a0
#done
;a2 is y overlap, a3 is x overlap. a2 should be greatest of the two.
cmp a2,a3
jrn #retval_set
move a3,a2
#retval_set
PULL a1,a3
rets
;boundaries
#low_x equ 53
#high_x equ 346
#low_y equ 45
#high_y equ 230
;ret values
B_HIT_TOP equ 0
B_HIT_BOTTOM equ 2
B_HIT_LEFT equ 3
B_HIT_RIGHT equ 1
M_HIT_TOP equ 0001h
M_HIT_BOTTOM equ 0004h
M_HIT_LEFT equ 0008h
M_HIT_RIGHT equ 0002h
#*****************************************************************************
* If ever both start buttons are down, this proc sets the robo_done flag
* and dies.
*
SUBRP watch_both_starts
#loop
SLEEPK 4 ;no need to check EVERY frame
clr a0
calla get_start_cur
jrz #loop
movk 1,a0
calla get_start_cur
jrz #loop
;both starts are down.
movk 1,a0
move a0,@starts_down
DIE
#*****************************************************************************
* Watches for wave advance/back up key combo.
*
SUBRP wave_mover
#loop
SLEEPK 4
calla get_all_buttons_cur
jrz #loop
cmpi 1,a0
jreq #back
cmpi 2,a0
jreq #fwd
jruc #loop
#back
move a0,@backward
jruc #done
#fwd
move a0,@forward
#done
DIE
.if DEBUG
#*****************************************************************************
* Makes bog meters
*
SUBRP bog_o_meter
movi robo_p,a0
calla pal_getf
move a0,a9
;create the background
movi [360,0],a0
movi [192,0],a1
movi man_d1,a2
clr a3
movi DMACAL|M_FLIPV,a4
movi CLSDEAD,a5
clr a6
clr a7
calla BEGINOBJW
move a9,*a8(OPAL)
movi 0707h,a14
move a14,*a8(OCONST)
movi 8,a0
move a0,*a8(OSIZEX)
movi 128,a0
move a0,*a8(OSIZEY)
move a8,a10
;create the foreground
movi [360,0],a0
movi [65,0],a1
movi man_d1,a2
movi 1,a3
movi DMACAL,a4
movi CLSDEAD,a5
clr a6
clr a7
calla BEGINOBJW
move a9,*a8(OPAL)
movi 0808h,a14
move a14,*a8(OCONST)
movi 8,a0
move a0,*a8(OSIZEX)
movi #scale,a9
#loop
SLEEPK 2
move @CPULEFT,a1
jrnz #nobog
;BOG!!
nop
#nobog
mpyu a9,a1
srl 16,a1
move a1,*a8(OSIZEY)
cmpi 10h,a1
jrle #red
movi 0707h,a0
move a0,*a10(OCONST)
jruc #loop
#red
movi 0101h,a0
move a0,*a10(OCONST)
jruc #loop
DIE
#scale equ 800000h/03DCh
.endif
#*****************************************************************************
robotron_ascii
.long 0,0,0,0,0,0,0,0 ;$00
.long 0,0,0,0,0,0,0,0 ;$08
.long 0,0,0,0,0,0,0,0 ;$10
.long 0,0,0,0,0,0,0,0 ;$18
.long 0,rfont_exc,0,0,0,0,0,0 ;$20 SP! " # $ % & '
.long rfont_lparens,rfont_rparens,0,0,rfont_comma,0,rfont_period,rfont_fslash ;$28 ( ) * + , - . /
.long rfont_0,rfont_1,rfont_2,rfont_3,rfont_4,rfont_5,rfont_6,rfont_7 ;$30 0 1 2 3 4 5 6 7
.long rfont_8,rfont_9,0,0,0,0,0,0 ;$38 8 9 : ; < - > ?
.long 0,rfont_a,rfont_b,rfont_c,rfont_d,rfont_e,rfont_f,rfont_g ;$40 @ A B C D E F G
.long rfont_h,rfont_i,rfont_j,rfont_k,rfont_l,rfont_m,rfont_n,rfont_o ;$48 H I J K L M N O
.long rfont_p,rfont_q,rfont_r,rfont_s,rfont_t,rfont_u,rfont_v,rfont_w ;$50 P Q R S T U V W
.long rfont_x,rfont_y,rfont_z,0,0,0,0,0 ;$58 X Y Z [ \ ] ^ _
.long 0,rfont_a,rfont_b,rfont_c,rfont_d,rfont_e,rfont_f,rfont_g ;$60 ` a b c d e f g
.long rfont_h,rfont_i,rfont_j,rfont_k,rfont_l,rfont_m,rfont_n,rfont_o ;$68 h i j k l m n o
.long rfont_p,rfont_q,rfont_r,rfont_s,rfont_t,rfont_u,rfont_v,rfont_w ;$70 p q r s t u v w
.long rfont_x,rfont_y,rfont_z,0,0,0,0,0 ;$78 x y z { | } ~
#*****************************************************************************
*
* Sound section
* >a0 = snd call
RS_GRUNT .equ 0
RS_DIE .equ 1
RS_RESCUE .equ 2
RS_SHOOT .equ 3
RS_HIT .equ 4
sp_grunt .equ 1<<8
sp_shoot .equ 2<<8
sp_hit .equ 3<<8
sp_rescue .equ 4<<8
sp_die .equ 5<<8
robosnd_tbl
; duration, call#
.word sp_grunt|6,96 ;0 = grunt footstep
.word sp_die|96,98 ;1 = die
.word sp_rescue|39,99 ;2 = rescue
.word sp_shoot|17,102 ;3 = shoot
.word sp_hit|23,100 ;4 = hit
robosnd_end
.bss rs_snd,16 ;current sound call (0-3)
.bss rs_time,32 ;timeout on current call (long)PCNT
.bss rs_pri,16 ;priority on current call
.bss last_grunt_snd,32 ;PCNT of last grunt footstep
SUBRP robo_sound_init
clr a14
move a14,@rs_snd
move a14,@rs_time,L
move a14,@last_grunt_snd,L
rets
SUBRP robo_sound
PUSH a2,a3,a4
;reggies:
;a0 = call index
;a1 = priority
;a2 = duration
;a3 = call #
;decode table index
move a0,a14
X32 a14
addi robosnd_tbl,a14
move *a14,a1,W
srl 8,a1
move *a14+,a2,W
andi 0FFh,a2
move *a14,a3,W
;check old duration - if there's nothing going on, do the sound.
move @rs_time,a4
move @PCNT,a14,L
cmp a4,a14
jrgt #dosnd
;old sound still going. check for an override
TEST a0
jrnz #ng
move @rs_snd,a14
jrz #grxgr ;special grunt-overriding-grunt case
#ng move @rs_pri,a14
cmp a14,a1
jrge #dosnd
jruc #done
#grxgr ;do new call if old one has 3 or fewer ticks to live
move @rs_time,a14,L
move @PCNT,a4,L
sub a4,a14
cmpi 3,a4
jrle #dosnd
jruc #done
#dosnd calla SNDSND
move a0,@rs_snd
move @PCNT,a14,L
add a2,a14
move a14,@rs_time,L
move a1,@rs_pri
#done PULL a2,a3,a4
rets
******************************************************************************
.end