**************************************************************************** **************************************************************************** ** ** Platinum (Specific enemy control code) ** ** This software is in the public domain. There is no warranty. ** ** by Patrick Davidson (pad@calc.org, http://pad.calc.org/) ** ** Last updated July 21, 2001 ** **************************************************************************** **************************************************************************** ******************************************** FIGURE-FOLLOWING ENEMY C_FIGURE: move.w e_path(a4),d0 ; D0 = relative path pointer lea C_FIGURE(pc,d0.w),a0 ; A0 -> path data move.b (a0)+,d2 ; X movement ext.w d2 bsr Div_D2_By_4 add.w d2,e_x(a4) move.b (a0)+,d2 ; Y movement ext.w d2 bsr Div_D2_By_4 add.w d2,e_y(a4) subq.w #1,e_timer(a4) ; decrement time left in this stage bne.s \no_next_stage move.w (a0)+,e_timer(a4) ; load time for next stage bne.s \no_goto move.w (a0)+,d0 ; load next stage pointer move.w C_FIGURE+2(pc,d0.w),e_timer(a4) move.w d0,e_path(a4) \no_goto: addq.w #4,e_path(a4) ; adjust path pointer \no_next_stage: cmp.w #30,e_y(a4) blt.s \1 moveq #127,d0 bsr random tst.w d0 bne.s \1 bsr fire_enemy_cannon_top \1: bra spin_pic ******************************************** RANDOM MOVING X C_RANDOM_X: move.w #OPERATOR_FLYING,(a4) move.w #128,d0 bsr random add.w #64,d0 move.w d0,e_x(a4) move.w #90,d0 bsr random sub.w #90,d0 move.w d0,e_y(a4) rts ******************************************** WHEEL ENEMY C_WHEEL_WAIT: ; Wheel waiting to enter subq.w #1,e_data(a4) beq.s ww_enter rts ww_enter: move.w #WHEEL_ENTER,(a4) move.w #29,e_x(a4) move.w #0,e_y(a4) rts C_MWHEEL_WAIT: ; Wheel waiting to enter subq.w #1,e_data(a4) beq.s mww_enter rts mww_enter: move.w #MWHEEL_1,(a4) move.w #57,e_x(a4) move.w #0,e_y(a4) rts C_WHEEL_ENTER: bsr wheel_general addq.w #1,e_x(a4) addq.w #2,e_y(a4) cmp.w #50,e_y(a4) beq.s ww_main rts ww_main: move.w #WHEEL_1,(a4) move.w #64,e_data(A4) rts C_WHEEL_1: bsr wheel_general addq.w #2,e_x(a4) btst #0,cycle_counter+3(a5) beq.s cw1n subq.w #1,e_y(a4) cw1n: subq.w #1,e_data(a4) ble.s cw1c rts cw1c: move.w #WHEEL_2,(A4) move.w #16,e_data(A4) rts C_WHEEL_2: bsr.s wheel_general addq.w #2,e_y(a4) btst #0,cycle_counter+3(a5) beq.s cw2n addq.w #1,e_x(A4) cw2n: subq.w #1,e_data(a4) ble.s cw2c rts cw2c: move.w #WHEEL_3,(A4) move.w #64,e_data(a4) rts C_WHEEL_3: bsr.s wheel_general subq.w #2,e_x(A4) btst #0,cycle_counter+3(a5) beq.s cw3n addq.w #1,e_y(a4) cw3n: subq.w #1,e_data(a4) ble.s cw3c rts cw3c: move.w #WHEEL_4,(a4) move.w #16,e_data(a4) rts wheel_general: move.w cycle_counter+2(a5),d0 and.w #31,d0 cmp.w d7,d0 bne.s no_ws move.w e_x(a4),d1 move.w e_y(A4),D2 addq.w #6,d1 addq.w #6,d2 bsr fire_enemy_bubble no_ws: add.w #in_Wheel_2-in_Wheel_1,e_image(a4) cmp.w #in_Wheel_4,e_image(a4) bgt.s rotate_start rts rotate_start: move.w #in_Wheel_1,e_image(a4) rts C_WHEEL_4: bsr.s wheel_general subq.w #2,e_y(a4) btst #0,cycle_counter+3(a5) beq.s cw4n subq.w #1,e_x(a4) cw4n: subq.w #1,e_data(A4) ble.s cw4c rts cw4c: move.w #WHEEL_1,(a4) move.w #64,e_data(a4) rts C_MWHEEL_1: bsr.s wheel_general addq.w #1,e_y(a4) cmp.w #72,e_y(a4) beq.s cmw1c rts cmw1c: move.w #MWHEEL_2,(A4) rts C_MWHEEL_2: bsr.s wheel_general addq.w #1,e_x(a4) cmp.w #185,e_x(a4) beq.s cmw2c rts cmw2c: move.w #MWHEEL_3,(A4) rts C_MWHEEL_3: bsr wheel_general subq.w #1,e_y(a4) cmp.w #20,e_y(a4) beq.s cmw3c rts cmw3c: move.w #MWHEEL_4,(A4) rts C_MWHEEL_4: bsr wheel_general subq.w #1,e_x(a4) cmp.w #57,e_x(a4) beq.s cmw4c rts cmw4c: move.w #MWHEEL_1,(A4) rts ******************************************** TRIANGLE ENEMIES C_TRIANGLE: move.w e_x(a4),d1 cmp.w #-300,d1 bne.s Triangle_Entered move.w #1,e_y(a4) ; Set-up new enemy moveq #127,d0 bsr random moveq #64,d1 add.w d0,d1 move.w d0,e_x(a4) Triangle_Entered: ; X-Movement move.b e_data(a4),d0 ext.w d0 add.w d0,d1 move.w d1,e_x(a4) cmp.w #64,d1 bge.s TC_nle moveq #3,d0 bsr random addq.w #1,d0 move.b d0,e_data(a4) bra.s Triangle_Y TC_nle: cmp.w #192,d1 ble.s Triangle_Y moveq #2,d0 bsr random not.w d0 move.b d0,e_data(a4) Triangle_Y: ; Y-Movement move.b e_data+1(a4),d2 ext.w d2 add.w e_y(a4),d2 move.w d2,e_y(a4) cmp.w #20,d2 bge.s TC_nt moveq #3,d0 bsr random addq.w #1,d0 move.b d0,e_data+1(a4) bra.s Triangle_Shoot TC_nt: cmp.w #80,d2 ble.s Triangle_Shoot moveq #2,d0 bsr random not.w d0 move.b d0,e_data+1(a4) Triangle_Shoot: ; Firing tst.b cycle_counter+3(a5) beq.s Triangle_Do_Shoot rts Triangle_Do_Shoot: addq.w #4,d1 addq.w #3,d2 bra fire_enemy_bubble ******************************************** SPINNING ENEMIES MOVEMENT C_SPINNERM: bsr spin_pic moveq #64,d0 bsr random move.w d0,d6 btst #0,d7 beq.s Operator_No_Shoot bsr random tst.w d0 bne.s Operator_No_Shoot bsr fire_enemy_cannon_top bra.s Operator_No_Shoot ******************************************** THE OPERATORS C_OPERATOR_LOCATING: move.w #OPERATOR_ENTERING,(a4) move.w #128,d0 bsr random add.w #64,d0 move.w d0,e_x(a4) move.w #32,d0 bsr random add.w #52,d0 move.w d0,e_y(a4) rts C_OPERATOR_ENTERING: btst #0,cycle_counter+3(a5) beq.s operator_rts sub.w #30,e_image(a4) cmp.w #in_Enemy_0,e_image(a4) beq.s go_fly rts go_fly: move.w #OPERATOR_FLYING,(a4) move.w #$101,e_data(a4) operator_rts: rts X_Operator_Entry: addq.w #1,e_y(a4) rts C_OPERATOR_FLYING: cmp.w #50,d0 blt.s X_Operator_Entry btst #0,d7 beq.s Operator_No_Shoot smct: moveq #64,d0 bsr random move.w d0,d6 subq.w #1,d0 bne.s Operator_No_Shoot bsr fire_enemy_cannon_top Operator_No_Shoot: move.b e_data(a4),d0 ext.w d0 add.w e_y(a4),d0 move.w d0,e_y(a4) cmp.w #86,d0 bge.s Operator_Up cmp.w #50,d0 ble.s Operator_Down cmp.w #68,d0 bne.s Operator_FlyX btst #1,d6 beq.s Operator_Up Operator_Down: move.b #1,e_data(a4) bra.s Operator_FlyX Operator_Up: st e_data(a4) Operator_FlyX: move.b e_data+1(a4),d1 ext.w d1 add.w e_x(a4),d1 move.w d1,e_x(a4) cmp.w #64,d1 ble.s Operator_Right cmp.w #192,d1 bge.s Operator_Left and.w #31,d1 beq.s Operator_XRand rts Operator_XRand: btst #3,d6 beq.s Operator_Right Operator_Left: st e_data+1(a4) rts Operator_Right: move.b #1,e_data+1(a4) rts ******************************************** ENEMY EXPLOSION CODE C_EXPLODE2: move.w #32767,e_dmg(a4) bchg #0,e_data(a4) beq no_increment move.w e_image(a4),d0 cmp.w #in_LExplosion9,d0 beq.s enemy_lexploded lea image_table(pc),a0 move.w 0(a0,d0.w),d1 add.w d1,d1 add.w d1,d1 addq.w #6,d0 add.w d1,d0 move.w d0,e_image(a4) rts enemy_lexploded: cmp.w #16,e_w(a4) ble.s enemy_exploded moveq #2,d0 bsr random tst.w d0 beq.s kill_enemy move.w #in_Cash_100,d6 move.w #$8100,d5 cmp.w #1,difficulty(a5) beq.s k_half enemy_lne: moveq #10,d3 bsr deploy_bonus bra.s kill_enemy k_half: moveq #2,d0 k_calc: bsr random tst.w d0 beq.s enemy_lne move.w #$8500,d5 move.w #in_Cash_1000,d6 bra.s enemy_lne C_EXPLODE: move.w #32767,e_dmg(a4) bchg #0,e_data(a4) beq.s no_increment move.w e_image(a4),d0 cmp.w #in_Explosion8,d0 beq.s enemy_exploded lea image_table(pc),a0 move.w 0(a0,d0.w),d1 add.w d1,d1 add.w d1,d1 addq.w #6,d0 add.w d1,d0 move.w d0,e_image(a4) no_increment: rts enemy_exploded: moveq #15,d0 bsr random tst.w d0 bne.s kill_enemy move.w #in_Cash_10,d6 move.w #$8050,d5 moveq #5,d3 bsr deploy_bonus ******************************************** DELETE AN ENEMY kill_enemy: subq.w #1,enemies_remaining(a5) clr.w (a4) rts ******************************************** LEFT SIDE OF SUPER-BOSS C_SUPERBOSS_L: move.w -(e_size)+e_x(a4),d1 move.w d1,e_x(a4) move.w -(e_size)+e_y(a4),d2 move.w d2,e_y(a4) move.w cycle_counter+2(a5),d0 addq.w #1,d0 sbc: add.w #5,d1 ble.s ns_sl and.w #63,d0 cmp.w d7,d0 bne.s ns_sl addq.w #8,d2 lea esdata_ball(pc),a1 bra enemy_cannon_common ns_sl: rts ******************************************** RIGHT SIDE OF SUPER-BOSS C_SUPERBOSS_R: move.w -(2*e_size)+e_x(a4),d1 add.w #17,d1 move.w d1,e_x(a4) move.w -(2*e_size)+e_y(a4),d2 move.w d2,e_y(a4) move.w cycle_counter+2(a5),d0 bra.s sbc ******************************************** INVINCIBLE FAKE BOSS C_FAKE2: move.w #32767,e_dmg(a4) ******************************************** PRIMARY BOSS CODE C_BOSS_MAIN: move.b e_data(a4),d1 ext.w d1 add.w e_x(a4),d1 move.w d1,e_x(a4) move.w #205,d2 sub.w e_w(a4),d2 cmp.w d2,d1 beq.s mbc_goleft cmp.w #50,d1 beq.s mbc_goright move.w cycle_counter+2(a5),d0 lsr.b #1,d0 bcc.s no_y_adjust move.b e_data+1(a4),d2 ext.w d2 add.w e_y(a4),d2 move.w d2,e_y(a4) cmp.w #20,d2 beq.s mbc_godown cmp.w #40,d2 beq.s mbc_goup mbc_rts: rts mbc_goup: st e_data+1(a4) rts mbc_godown: move.b #1,e_data+1(a4) rts mbc_goleft: st e_data(a4) rts mbc_goright: move.b #1,e_data(a4) rts no_y_adjust: and.w #31,d0 bne.s mbc_rts cmp.w #33,e_w(a4) beq.s rts_3 move.w e_y(a4),d2 addq.w #8,d2 bsr fire_enemy_cannon move.w e_x(a4),d1 move.w e_y(a4),d2 add.w #14,d1 addq.w #8,d2 bsr fire_enemy_cannon rts_3: rts ******************************************** ENTERING FAKE BOSS C_FAKE1: move.w #32767,e_dmg(a4) moveq #24,d5 bra.s boss_common ******************************************** ENTERING BOSS CODE C_BOSS: moveq #6,d5 boss_common: move.w e_data(a4),d6 blt.s insert_boss boss_descending: move.w e_y(a4),d0 addq.w #1,d0 move.w d0,e_y(a4) cmp.w #20,d0 beq.s boss_enter rts boss_enter: move.w #BOSS_MAIN,(a4) move.w #$0101,e_data(a4) rts insert_boss: addq.w #1,e_data(a4) bne.s not_ready_to_insert move.w #68,e_x(a4) move.w #0,e_y(a4) not_ready_to_insert: rts ********************************************* SWOOPING ENEMY C_SWOOP: tst.w e_y(a4) blt.s swoop_entering move.w cycle_counter+2(a5),d0 ; Select image lsr.w #1,d0 bcc.s swoop_image_2 move.w #in_Swoop1,e_image(a4) bra.s swoop_is_done swoop_image_2: move.w #in_Swoop2,e_image(a4) move.w cycle_counter+2(a5),d0 ; Shoot approx every 4 seconds and.w #63,d0 cmp.w d7,d0 bne.s swoop_is_done move.w e_x(a4),d1 move.w e_y(a4),d2 addq.w #6,d1 addq.w #4,d2 lea esdata_normal(pc),a1 cmp.w #4,difficulty(a5) bne.s swoop_no_expert lea esdata_ball(pc),a1 subq.w #2,d1 swoop_no_expert: bsr enemy_cannon_common swoop_is_done: move.w e_data(a4),d2 lea swoop_data+8(pc,d2.w),a3 move.w e_x(a4),d0 cmp.w -(a3),d0 bne.s swoop_not_up subq.w #1,e_y(a4) rts swoop_not_up: move.w e_y(a4),d1 cmp.w -(a3),d1 bne.s swoop_not_sideways add.w -(a3),d0 move.w d0,e_x(a4) rts swoop_not_sideways: addq.w #1,e_y(a4) rts swoop_entering: move.w cycle_counter+2(a5),d0 and.w #31,d0 bne.s swoop_rts moveq #4,d0 bsr random bset d0,flags(a5) bne.s swoop_rts lsl.w #3,d0 clr.w e_y(a4) move.w swoop_data(pc,d0.w),e_x(a4) move.w d0,e_data(a4) swoop_rts: rts swoop_data: ; Entry X, XV, Slide Y, Exit X dc.w 50,1,83,190 dc.w 170,-1,70,70 dc.w 90,1,57,150 dc.w 130,-1,44,110 ********************************************* ENEMY TYPES * * The ETYPE macro assigns an eneny type value to each type of enemy in the * game. The only argument is the enemy "name"; this symbol is assigned to * the offset of the enemy's code, which is at C_name. This enemy type is a * relative pointer to the enemy's code. * * As this table is only used to set symbols to equal the offsets, this table * takes absolutely no space in the executable code. * ******** ETYPE MACRO \1 equ C_\1-Move_Enemies ENDM ETYPE EXPLODE2 ETYPE EXPLODE ETYPE BOSS ETYPE BOSS_MAIN ETYPE SUPERBOSS_L ETYPE SUPERBOSS_R ETYPE FAKE1 ETYPE FAKE2 ETYPE OPERATOR_LOCATING ETYPE OPERATOR_ENTERING ETYPE OPERATOR_FLYING ETYPE TRIANGLE ETYPE RANDOM_X ETYPE WHEEL_WAIT ETYPE WHEEL_ENTER ETYPE WHEEL_1 ETYPE WHEEL_2 ETYPE WHEEL_3 ETYPE WHEEL_4 ETYPE MWHEEL_WAIT ETYPE MWHEEL_1 ETYPE MWHEEL_2 ETYPE MWHEEL_3 ETYPE MWHEEL_4 ETYPE SPINNERM ETYPE SWOOP ETYPE FIGURE