;############## CMonster by Patrick Davidson - level loading and rendering Load_Level: #ifdef TI84CE ld de,0 #else ld d,0 #endif ld e,a #ifdef TI84CE push de pop hl #else ld h,d ld l,e #endif add hl,hl add hl,hl add hl,de ; HL = 5 * level number add hl,hl add hl,hl add hl,hl add hl,hl add hl,hl ; HL = 160 * level number ld de,levelData-320 add hl,hl add hl,de ; HL -> map ld de,map ld bc,320 ldir ret Draw_Map: ld c,15 Draw_Map_Partial: ld b,19 loop_draw_board: push bc call Draw_Brick pop bc dec b jp p,loop_draw_board dec c jp p,Draw_Map_Partial ret ;############## Find brick value ; Input C = brick Y coordinate (0-15) ; Input B = brick X coordinate (0-19) ; Output A = brick value Find_Brick_BC: ld a,c cp 16 jr nc,below_brick_area ld hl,map #ifdef TI84CE ld de,0 #else ld d,0 #endif add a,a add a,a add a,c ; A = 5 * Y add a,a ; A = 10 * Y ld e,a add hl,de add hl,de ; HL -> map + 20 * Y (start of row) ld e,b add hl,de ; HL -> relevant brick in map ld a,(hl) ret below_brick_area: xor a ret ;############## Detect if brick is present and update for bounce ; Input E = brick Y coordinate (0-15) ; Input D = brick X coordinate (0-19) ; Output zero flag set if no bounce, clear if we should bounce Bounce_Brick_DE: ld a,e cp 16 jr nc,below_brick_area ld hl,map #ifdef TI84CE ld bc,0 #else ld b,0 #endif add a,a add a,a add a,e ; A = 5 * Y add a,a ; A = 10 * Y ld c,a add hl,bc add hl,bc ; HL -> map + 20 * Y (start of row) ld c,d add hl,bc ; HL -> relevant brick in map ld a,(hl) and 15 add a,a ld (brick_hit_dispatch+1),a brick_hit_dispatch: jr brick_hit_dispatch ret ; no brick, return with Z set ret jr hit_normal_brick jr hit_double_brick jr to_solid_brick jr hit_triple_brick jr solid_brick to_solid_brick: jr solid_brick jr hit_double_upper jr hit_double_lower jr hit_quad_upperleft jr hit_quad_upperright jr hit_quad_lowerright jr hit_quad_lowerleft hit_quad_upperleft: push de inc e ld bc,20 add hl,bc call hit_quad_lowerleft pop de ret hit_quad_upperright: push de inc e dec d ld bc,19 add hl,bc call hit_quad_lowerleft pop de ret hit_quad_lowerright: push de dec d dec hl call hit_quad_lowerleft pop de ret hit_double_lower: push de ld a,(hl) sub 7 ld (hl),a push de push af push hl call Draw_Brick_ADE pop hl ld bc,-20 add hl,bc pop af ld (hl),a pop de dec e call Draw_Brick_ADE pop de ret hit_double_upper: push de ld a,(hl) sub 6 ld (hl),a push de push af push hl call Draw_Brick_ADE pop hl ld bc,20 add hl,bc pop af ld (hl),a pop de inc e call Draw_Brick_ADE pop de ret hit_triple_brick: dec (hl) hit_double_brick: dec (hl) ; change to single ld a,(hl) push de call Draw_Brick_ADE pop de ret hit_normal_brick: xor a ld (hl),a push de call Draw_Brick_ADE jr collect_points solid_brick: ld hl,since_bounce inc (hl) ret hit_quad_lowerleft: push de ld a,(hl) and %11110000 inc a ld (hl),a push hl push de call Draw_Brick_ADE pop de pop hl inc hl inc d ld a,(hl) and %11110000 inc a ld (hl),a push hl push de call Draw_Brick_ADE pop de pop hl ld bc,-20 add hl,bc dec e ld a,(hl) and %11110000 inc a ld (hl),a push hl push de call Draw_Brick_ADE pop de pop hl dec d dec hl ld a,(hl) and %11110000 inc a ld (hl),a call Draw_Brick_ADE pop de ret collect_points: ld hl,(brick_count) dec hl ld (brick_count),hl ld hl,bounce_count ld a,(hl) cp 10 jr z,max_bounce inc a ld (hl),a max_bounce: ld b,a add_score_loop: push bc call add_score pop bc djnz add_score_loop pop de call Check_Drop_Bonus xor a ; make sure zero flag is clear (NZ) inc a ret add_score: ld hl,score+6 ; and increment the score ld de,score_increment+5 ld a,(score_inc) ld (de),a inc de Add_6_Digits_BCD: ld b,6 loop_add_nocarry: xor a loop_add: dec hl dec de ld a,(de) adc a,(hl) sub '0' ; '0' was added twice because both ASCII cp '0'+10 jr c,loop_add_nocarry_end sub 10 ccf ld (hl),a djnz loop_add ret loop_add_nocarry_end: ld (hl),a djnz loop_add_nocarry ret score_increment: .db "000001" brick_results: .db 0,1,3,2,5,6 ;############## Draw brick using images below ; ; B = X coordinate (0-19) ; C = Y coordinate (0-29) Draw_Brick_If_Nonzero: push bc push hl push bc call Find_Brick_BC pop de or a call nz,Draw_Brick_ADE pop hl pop bc ret Draw_Brick: push bc call Find_Brick_BC pop de Draw_Brick_ADE: push af ld hl,packed_brick_images add a,a add a,a add a,a add a,a #ifdef TI84CE ld bc,0 #else ld b,0 #endif ld c,a add hl,bc add hl,bc ; HL -> brick image pop af rra and %1111000 ; A = palette image offset #ifdef TI84CE inc a ; second color byte copied first on 84+CE ld (smc_offset_1+1),a ld (smc_offset_2+1),a ld (smc_offset_3+1),a ld (smc_offset_4+1),a push hl ld a,e add a,a add a,a add a,a ; A = pixel Y coordinate of top of brick ld hl,0 ld l,a push hl pop bc add hl,hl add hl,hl ; HL = 4 * Y add hl,bc ; HL = 5 * Y add hl,hl add hl,hl ; HL = 20 * Y ld c,d add hl,bc ; HL = 20 * Y + brick X add hl,hl add hl,hl add hl,hl ; HL = 160 * Y + X add hl,hl add hl,hl ; HL = 640 * Y + 4 * X ld de,$D40000 add hl,de ; HL -> start pixel ex de,hl ; DE -> start pixel pop bc ; BC -> image data ld a,8 draw_brick_outer: push af ld a,4 ld hl,brick_palettes+1 draw_brick_inner: push af ld a,(bc) rlca rlca rlca and %110 smc_offset_1: or %11 ld l,a ld a,(hl) ld (de),a dec hl inc de ld a,(hl) ld (de),a inc de ld a,(bc) rra rra rra and %110 smc_offset_2: or %11 ld l,a ld a,(hl) ld (de),a dec hl inc de ld a,(hl) ld (de),a inc de ld a,(bc) rra and %110 smc_offset_3: or %11 ld l,a ld a,(hl) ld (de),a dec hl inc de ld a,(hl) ld (de),a inc de ld a,(bc) add a,a and %110 smc_offset_4: or %11 ld l,a ld a,(hl) ld (de),a dec hl inc de ld a,(hl) ld (de),a inc de inc bc pop af dec a jr nz,draw_brick_inner ld hl,640-32 add hl,de push hl pop de pop af dec a jr nz,draw_brick_outer inc a ; so that zero flag is clear ret #else ld (smc_offset_1+1),a ld (smc_offset_2+1),a ld (smc_offset_3+1),a ld (smc_offset_4+1),a push hl ld a,e add a,a add a,a add a,a ; A = pixel Y coordinate of top of brick ld h,0 ld l,a ld a,$50 ; set minimum Y call Write_Display_Control ld a,$20 ; set current Y call Write_Display_control_C11 ld a,d add a,a add a,a add a,a ; A = brick X * 8 ld l,a ld h,0 add hl,hl ; HL = pixel X = brick X * 16 ld a,$52 ; set minimum X call Write_Display_Control_C11 ld a,$21 ; set current X call Write_Display_Control_C11 ld a,l add a,15 ld l,a ld a,$53 ; set maximum X call Write_Display_Control_C11 ld a,$22 out ($10),a out ($10),a pop de ; DE -> brick image ld b,(32*(1+8))&255 ; loop 32 times, but 8 outis per loop ld hl,brick_palettes loop_draw_brick: ld a,(de) rlca rlca rlca and %110 smc_offset_1: or %11 ld l,a outi outi ld a,(de) rra rra rra and %110 smc_offset_2: or %11 ld l,a outi outi ld a,(de) rra and %110 smc_offset_3: or %11 ld l,a outi outi ld a,(de) add a,a and %110 smc_offset_4: or %11 ld l,a outi outi inc de djnz loop_draw_brick #endif ret