;############## Calcuzap by Patrick Davidson - enemies ;############## Move/draw enemies ; Calls the code specified by the enemy 'type'. The 'type', which must ; be a multiple of 3, is an index into the table of jumps for enemy code. ; Enemy routines should move the enemy and draw its image. They are ; called with HL pointing to the enemy entry, and can change all registers. process_enemies: ld hl,enemies ld b,e_count ld a,b ld (enemies_left),a loop_enemies: ld a,(hl) push hl push bc call do_enemy pop bc pop hl ld de,e_size add hl,de djnz loop_enemies ld hl,enemy_delay ld a,(hl) or a jr z,no_enemy_delay dec (hl) ret nz ld hl,(enemy_entry) jp (hl) no_enemy_delay: ld a,(enemies_left) or a jp z,next_level cp 13 ret nc ld a,(flag_spin) or a ret z ld hl,enemies ld b,e_count loop_go_on_rampage: ld a,(hl) or a jr z,skip_rampage cp 13 jr nc,skip_rampage ld (hl),30 push hl ld de,e_misc add hl,de push hl call get_rand pop hl and 6 ld (hl),a pop hl skip_rampage: ld de,e_size add hl,de djnz loop_go_on_rampage ret do_enemy: #ifdef TI84CE push hl ld bc,0 ld c,a ld hl,no_enemy add hl,bc ld hl,(hl) ex (sp),hl ret #else ld (smc_do_enemy+1),a smc_do_enemy: jr point_to_enemy_code point_to_enemy_code: #endif ;############## Enemy table starts here no_enemy: #ifdef TI84CE .dl null_enemy ; 0 = no enemy here .dl enemy_down ; 3 = enemy in process of entering .dl enemy_right .dl enemy_up .dl enemy_left .dl exploding_enemy ; 15 = exploding enemy .dl boss_entering ; 18 = basic boss entering .dl boss_main ; 21 = boss main .dl triangle_right ; 24 = triangle going right .dl triangle_left ; 27 = triangle going left .dl rampaging_enemy ; 30 = enemy bouncing randomly #else jp null_enemy ; 0 = no enemy here jp enemy_down ; 3 = enemy in process of entering jp enemy_right jp enemy_up jp enemy_left jp exploding_enemy ; 15 = exploding enemy jp boss_entering ; 18 = basic boss entering jp boss_main ; 21 = boss main jp triangle_right ; 24 = triangle going right jp triangle_left ; 27 = triangle going left #endif rampaging_enemy: call enemy_shoot_maybe inc hl ld d,(hl) ; D = X push hl inc hl ld a,(hl) ; A = Y inc hl inc hl #ifdef TI84CE inc hl #endif inc hl ; HL -> e_misc cp 15 jr c,rampage_force_down cp 99 ld a,d jr nc,rampage_force_up cp 48 jr z,rampage_force_right cp 48+160-7 jr z,rampage_force_left ld a,(hl) ld (do_rampage+1),a do_rampage: jr point_to_rampage_direction point_to_rampage_direction: jr rampage_downright ;0 jr rampage_upright ;2 jr rampage_downleft ;4 ;6 rampage_upleft_set: ld (hl),6 rampage_upleft: pop hl call maybe_spin ld bc,$FFFE jp move_up_left rampage_force_left: push hl call get_rand pop hl add a,a jr c,rampage_upleft_set jr rampage_downleft_set rampage_force_down: ld a,d cp 48 jr z,rampage_downright_set cp 48+160-7 jr z,rampage_downleft_set push hl call get_rand pop hl add a,a jr c,rampage_downright_set rampage_downleft_set: ld (hl),4 rampage_downleft: pop hl call maybe_spin ld bc,$FF02 jp move_down_left rampage_force_right: push hl call get_rand pop hl add a,a jr c,rampage_upright_set rampage_downright_set: ld (hl),0 rampage_downright: pop hl call maybe_spin ld bc,$102 jp move_down_right rampage_force_up: cp 48 jr z,rampage_upright_set cp 48+160-7 jr z,rampage_upleft_set push hl call get_rand pop hl add a,a jr c,rampage_upleft_set rampage_upright_set: ld (hl),2 rampage_upright: pop hl call maybe_spin ld bc,$1FE jp move_up_right triangle_left: call triangle_common ld b,-1 jp nz,move_up_left jp move_down_left triangle_right: call triangle_common ld b,1 jp nz,move_up_right jp move_down_right triangle_common: push hl call diagonal_shoot_maybe pop hl inc hl ; HL -> X ld a,(hl) cp 48+160-7-2 jr c,no_right_edge_triangle dec hl ld (hl),27 inc hl no_right_edge_triangle: cp 50 jr nc,no_left_edge_triangle dec hl ld (hl),24 inc hl no_left_edge_triangle: push hl inc hl ld a,(hl) ; A = Y coordinate inc hl inc hl inc hl #ifdef TI84CE inc hl #endif cp 14 jr nc,no_top_triangle push hl call get_rand pop hl and 1 inc a ld (hl),a jr no_bottom_triangle no_top_triangle: cp 92 jr c,no_bottom_triangle push hl call get_rand pop hl and 1 sub 2 ld (hl),a no_bottom_triangle: ld c,(hl) ; C = Y velocity pop hl ; HL -> X bit 7,c ret boss_main: call boss_shoot_maybe ld de,e_misc add hl,de ld a,(hl) dec hl dec hl #ifdef TI84CE dec hl #endif dec hl dec hl ; HL -> X add a,a ; double speed and test if negative push hl jr c,boss_going_left call move_right pop hl ld a,(hl) ; A = X coordinate of boss cp 48+160-12 ; compare with right edge ret nz inc hl inc hl inc hl #ifdef TI84CE inc hl #endif inc hl ; HL -> e_misc ld (hl),-1 ; set X velocity to -1 (go left) ret boss_going_left: call move_left pop hl ld a,(hl) ; A = X coordinate of boss cp 48 ; compare with left edge ret nz inc hl #ifdef TI84CE inc hl #endif inc hl inc hl inc hl ; HL -> e_misc ld (hl),1 ;set X velocity to 1 (go right) ret boss_entering: ld a,1 inc hl ; HL -> e_x push hl call move_down pop hl inc hl inc hl inc hl #ifdef TI84CE inc hl #endif inc hl dec (hl) ret nz ; still in descent countdown ld (hl),1 ld bc,-e_misc add hl,bc ; HL -> e_type ld (hl),21 ret exploding_enemy: inc hl ld b,(hl) ; X coordinate inc hl ld c,(hl) ; Y coordinate inc hl #ifdef TI84CE ld de,(hl) inc hl inc hl #else ld e,(hl) inc hl ld d,(hl) ; DE = image pointer #endif ld a,(de) or a jr z,enemy_gone push hl push de ld l,c call Draw_Sprite_Packed pop de pop hl inc hl dec (hl) ; decrement next frame counter ret nz ld (hl),2 ; 2 cycles to next frame ex de,hl ; HL -> image ld bc,394 add hl,bc ; HL -> next image ex de,hl dec hl #ifdef TI84CE dec hl dec hl ld (hl),de #else ld (hl),d ; store updated image pointer dec hl ld (hl),e #endif ret enemy_gone: dec hl dec hl dec hl #ifdef TI84CE dec hl #endif dec hl ld (hl),0 push bc call drop_bonus_maybe pop bc ld de,(7*256)+14 jp Erase_Rectangle enemy_down: push de call enemy_shoot_maybe pop de inc hl ld a,1 push hl call maybe_spin call move_down jr enemy_change_direction enemy_up: push de call enemy_shoot_maybe pop de inc hl ld a,-1 push hl call maybe_spin call move_up jr enemy_change_direction enemy_right: push de call enemy_shoot_maybe pop de inc hl ld a,1 push hl call maybe_spin call move_right jr enemy_change_direction enemy_left: push de call enemy_shoot_maybe pop de inc hl ld a,-1 push hl call maybe_spin call move_left enemy_change_direction: pop hl ; HL -> e_x inc hl inc hl #ifdef TI84CE inc hl #endif inc hl inc hl ; HL -> e_misc dec (hl) ; remaining duration this direction ret nz ld (hl),25 ld bc,-e_misc add hl,bc ld a,(hl) add a,3 ld (hl),a cp 15 ret nz ld (hl),3 ret maybe_spin: push af ld a,(flag_spin) add a,a jr z,dont_spin push hl ld hl,(enemy_image) ld de,394 ld a,(frame_count) and 3 jr z,first_frame ld b,a loop_spin: add hl,de djnz loop_spin first_frame: ex de,hl pop hl inc hl inc hl #ifdef TI84CE ld (hl),de #else ld (hl),e inc hl ld (hl),d dec hl #endif dec hl dec hl dont_spin: pop af ret null_enemy: ld hl,enemies_left dec (hl) ret