;############## Calcuzap by Patrick Davidson ;#define TIME_INDICATOR ;#define SLOW_BULLETS ;############## Initialization of game variables main: ld hl,saved_flag ld a,(hl) or a ld (hl),0 jr nz,variables_ready ld hl,$b080 ld (p_x),hl ld hl,img_player ld (p_image),hl ld hl,score ld de,score+1 ld bc,5 ld (hl),'0' ldir call Show_Title_Screen dec c ret z ld a,(hard_flag) add a,2 ld (lives),a ; ld a,90 ; ld (lives),a ; ld a,2 ; ld (p_weapon),a variables_ready: #ifdef TI84CE ld b,NUM_STARS ld hl,starfield fill_stars_loop: push hl call get_rand_full pop hl xor b and %11111110 ld (hl),a inc hl push hl call get_rand_full pop hl xor b ld (hl),a inc hl push hl call get_rand_full pop hl and %11 or $d4 ld (hl),a inc hl djnz fill_stars_loop #endif call Clear_Screen ld hl,title_messages call Draw_Strings call Show_Lives ld a,(level) call Show_Level ld hl,$c000 ld (wait_count),hl ld a,1 ld (score_changed),a call timer_wait_done main_loop: ld hl,bonus_countdown ld a,(hl) or a jr z,bonus_countdown_done dec (hl) bonus_countdown_done: ld a,(score+4) or 1 ld hl,rand_inc add a,(hl) ld (hl),a ld hl,(frame_count) inc hl ld (frame_count),hl ld bc,33*4*256+232 ld hl,score_changed ld a,(hl) ld (hl),0 ld hl,score or a call nz,Draw_String #ifndef TI84CE ld a,%10111111 ; mask most keys (allow 2nd) out (1),a #endif call timer_delay ld hl,fire_pressed #ifdef TI84CE call GET_KEY ld a,(getkeylastdata+6) bit 5,a jr z,no_fire #else in a,(1) ; shoot if 2nd is pressed bit 5,a jr nz,no_fire #endif ld a,(hl) or a jr nz,fire_done inc (hl) call fire_bullet jr fire_done no_fire: xor a ld (hl),a fire_done: #ifdef TI84CE ld b,NUM_STARS ld hl,starfield draw_stars_loop: push hl ld hl,(hl) ; pointer to position in vram ld de,$D40000+(320*232*2) call _cpHLDE jr nc,star_done ; invalid stars skipped ld a,(hl) ; check if star color still present cp %11011111 jr nz,no_erase_star inc hl ld a,(hl) cp %11111111 dec hl jr nz,no_erase_star inc hl ld (hl),0 dec hl ld (hl),0 no_erase_star: push bc bit 3,b ; change star speed based on index ld bc,320*2 jr z,star_is_slow ld bc,320*2*2 star_is_slow: add hl,bc ; advance one/two lines call _cpHLDE ; check if this goes below the bottom jr c,valid_after_move ld bc,-(320*232*2) add hl,bc ld a,b and %1111110 ; reverse position in column for variation xor l ld l,a valid_after_move: ld a,(hl) ; check if background is black here inc hl or (hl) dec hl jr nz,no_draw_star ld (hl),%11011111 ; draw star at new position inc hl ld (hl),%11111111 dec hl no_draw_star: pop bc star_done: ex de,hl ; DE = new star position pop hl ld (hl),de inc hl inc hl inc hl djnz draw_stars_loop #endif call player_bullets call process_enemies call hit_enemy call process_enemy_bullets ld a,(ghost_timer) or a jr z,not_ghost_phase dec a ld (ghost_timer),a ld hl,img_player jr z,ghost_image_selected cp 30 jr nc,not_ghost_phase ld hl,img_player_ghost2 ghost_image_selected: ld (p_image),hl not_ghost_phase: #ifndef TI84CE ld a,%11111110 out (1),a ; mask most keys (allow arrows) #endif ld hl,player_move_done ; ret from move jumps here push hl #ifdef TI84CE ld a,(getkeylastdata) cpl #else in a,(1) #endif and %1111 cp 15 jr z,not_moving ld hl,$c000 ld (wait_count),hl not_moving: ld hl,p_x add a,a ld (do_player+1),a #ifndef TI84CE ld a,%10111111 ; mask out most keys (allows DEL and MODE) out (1),a #endif ld a,(player_cd) or a jr z,do_player player_exploding: inc a ld (player_cd),a rra jr nc,player_no_move push hl ld hl,(p_image) ld de,394 add hl,de ld (p_image),hl ld a,(hl) inc a pop hl jr nz,player_no_move player_explode_done: xor a ld (player_cd),a ld a,(lives) or a jp z,check_highscore_lose ld de,img_enemy_explode ld (p_image),de push hl call erase_object_x ld hl,img_player ld a,(hard_flag) or a jr nz,dont_enter_ghost_phase ld a,40 ld (ghost_timer),a ld hl,img_player_ghost1 dont_enter_ghost_phase: ld (p_image),hl pop hl jr player_no_move do_player: jr point_to_player_code point_to_player_code: jr player_no_move ; 0000 all arrows pressed jr player_up ; all arrows pressed but down jr player_right ; all arrows pressed but left jr player_up_right jr player_left ; 0100 all arrows pressed but right jr player_up_left jr player_no_move ; up and down pressed jr player_up jr player_down ; 1000 all arrows pressed but up jr player_no_move ; left and right pressed jr player_down_right jr player_right jr player_down_left ; 1100 jr player_left jr player_down ; nothing pressed player_no_move: xor a jp move_up player_up: inc hl ld a,(hl) cp 160 ret z dec hl ld a,-4 jp move_up player_up_right: inc hl ld a,(hl) dec hl cp 160 ; check if at the top jr z,player_right ; if so, switch to right only ld a,(hl) cp 160+48-8 ; check if at right edge jr z,player_up ; if so, switch to up only ld bc,$02FC jp move_up_right player_up_left: inc hl ld a,(hl) dec hl cp 160 ; check if at the top jr z,player_left ; if so, switch to left only ld a,(hl) cp 48 ; check if at left edge jr z,player_up ; if so, switch to up only ld bc,$FEFC jp move_up_left player_down_left: inc hl ld a,(hl) dec hl cp 240 ; check if at the bottom jr z,player_left ; if so, switch to left only ld a,(hl) cp 48 ; check if at left edge jr z,player_down ; if so, switch to down only ld bc,$FE04 jp move_down_left player_down: inc hl ld a,(hl) cp 240 ret z dec hl ld a,4 jp move_down player_left: ld a,(hl) cp 48 ret z ld a,-2 jp move_left player_right: ld a,(hl) cp 160+48-8 ret z ld a,2 jp move_right player_down_right: inc hl ld a,(hl) dec hl cp 240 ; check if at the bottom jr z,player_right ; if so, switch to right only ld a,(hl) cp 160+48-8 ; check if at right edge jr z,player_down ; if so, switch to down only ld bc,$0204 jp move_down_right player_move_done: ld hl,(wait_count) inc hl ld (wait_count),hl ld a,h or l jr z,save_the_game #ifdef TI84CE ld a,(getkeylastdata+6) add a,a ret c add a,a jp nc,main_loop inc a #else in a,(1) add a,a ret nc add a,a jp c,main_loop #endif save_the_game: ld hl,saved_flag set 7,(hl) ret title_messages: .db 0,232 title_message: .db "CALCUZAP LIVES -- LEVEL -- SCORE",0 .db -1 timer_delay: #ifdef TI84CE #ifdef TIME_INDICATOR ld a,($F20001) or a jr nz,timer_loop inc a ld (score_changed),a ld hl,score inc (hl) jr timer_wait_done #endif timer_loop: ld a,($F20001) or a jr nz,timer_loop timer_wait_done: ld hl,$F20030 res 0,(hl) ; disable timer set 1,(hl) ; set frequency to 32768Hz res 2,(hl) ; no interrupt inc hl res 1,(hl) ; count down ld a,(delay_amount) ld hl,2 ld ($F20004),hl ld l,a add hl,hl add hl,hl add hl,hl add hl,hl inc h ld ($F20000),hl ; value to count down from xor a ld ($F20003),a ld ($F20006),a ld hl,$F20030 set 0,(hl) ; re-enable timer #else #ifdef TIME_INDICATOR in a,(4) bit 5,a jr z,timer_loop ld (score_changed),a ld hl,score inc (hl) jr timer_wait_done #endif timer_loop: in a,(4) bit 5,a jr z,timer_loop timer_wait_done: xor a out ($31),a ld a,(delay_amount) out ($32),a ; restart timer #endif ret