; --------- ; Space Jam ; --------- ; ; programmer: ; ; Jennie Chin ; Zheng-Yang Zhang title game : use for testing all objects extrn init_vga : near ; initialize color graphics extrn plot_pixel_xy_dbuffer : near ; copy to double buffer extrn show_double_buffer : near extrn rtn_to_text_mode : near ; return to dos mode extrn get_palette_register : near extrn set_palette_register : near extrn pcx_load : near ; load graphics file extrn update_color_register : near extrn draw_sprite : near extrn pcx_grap_bitmap : near extrn get_sprite_background : near extrn keyboard_int : near extrn timer_tick : near extrn setup_int : near extrn draw_background : near public scan_code public timer_flag public key_flag .model compact .stack 500h .data double_buffer db 64000d dup(0) logo_file db 'logo.dat',0 filename db 'shuttle.dat',0 filename2 db 'graphics.dat', 0 handle dw ? back_file db 'new-3.pcx',0 instruct_file db 'instruct.dat',0 sprite_file db 'sprite4.pcx',0 data db 0 counter dw 0 counter2 dw 0 x_off dw 0 y_off dw 0 scan_code db 0 timer_flag db 0 key_flag db 0 main_counter dw 0 grab_x dw 0 grab_y dw 0 far_segment dw 0 asteroid_counter db 0 wait_period dw 0d crash db 0d ; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ast_speed dw 100d; <-----INC THIS NUMBER TO SLOW THE ASTEROID SPEED new_timer_vec dw ?,?; DEC THIS NUMBER TO SPEED UP THE SPEED! old_timer_vec dw ?,?; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! new_key_vec dw ?,? old_key_vec dw ?,? up_arrow = 72 down_arrow = 80 esc_key = 1 hold dw 0; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! max_hold dw 10d; <-----INC THIS NUMBER TO SLOW THE MOTION OF EXPLOSION hold2 dw 0 ; OR DEC THIS NUMBER TO SPEED UP THE MOTION! max_hold2 dw 65000d; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .fardata image1 sprite0 db 576d dup(0) ; asteroid sprite0b db 576d dup(0) ; background sprite0x dw 0 ; spaceship location sprite0y dw 0 sprite1 db 576d dup(0) explosion1 db 576 dup (0) explosion2 db 576 dup (0) explosion3 db 576 dup (0) explosion4 db 576 dup (0) explosion5 db 576 dup (0) aster_array01 db 0 ; array of 12 asteroids dw 0 dw 0 db 576d dup(0) db 0 dw 0 dw 0 db 576d dup(0) db 0 dw 0 dw 0 db 576d dup(0) db 0 dw 0 dw 0 db 576d dup(0) db 0 dw 0 dw 0 db 576d dup(0) db 0 dw 0 dw 0 db 576d dup(0) aster_array07 db 0 dw 0 dw 0 db 576d dup(0) aster_array08 db 0 dw 0 dw 0 db 576d dup(0) aster_array09 db 0 dw 0 dw 0 db 576d dup(0) aster_array10 db 0 dw 0 dw 0 db 576d dup(0) aster_array11 db 0 dw 0 dw 0 db 576d dup(0) aster_array12 db 0 dw 0 dw 0 db 576d dup(0) include macros.asm .code main proc mov far_segment, seg image1 mov ax, seg image1 mov es, ax assume es : image1 mov ax, @data ; initialize ds mov ds, ax mov sprite0x, 30d ; move spaceship at 30,100 mov sprite0y, 100d call init_vga ; initialize graphic card to vga call load_logo1 ; load space jam logo call load_logo2 ; load instructions call setup_ints ; setup keyboard and timer interrupts. call setup_sprites ; load sprites call setup_background ; load background call get_spaceship_background call draw_spaceship lea bx, double_buffer push bx call show_double_buffer test_key: ; test the key is pressed or not cmp key_flag, 1 ; check flag jne test_key_no ; not set, go to timer flag mov key_flag, 0 ; clear flag key cmp scan_code, esc_key ; esc key? jne test_key_up ; no, check down arrow jmp done test_key_no : mov ax, 0 call spaceship_move jmp test_timer test_key_up: ; test the key is up? cmp scan_code, up_arrow ; arrow key? jne test_key_down mov ax, -7 ; move pixels call spaceship_move jmp test_timer test_key_down: ; test the key is down? cmp scan_code, down_arrow ; down arrow key? jne test_timer mov ax, 7 ; move pixel call spaceship_move jmp test_timer test_timer: cmp timer_flag, 1 jne test_key mov timer_flag, 0 lea bx, double_buffer push bx call show_double_buffer cmp crash, 1d ; is there a crash? je done jmp test_timer done: call reset_ints ; restore original interrupt settings cmp crash, 1d ; is there a crash jne escape call explosion escape : call rtn_to_text_mode ; put the video to text mode. dos_rtn 0 ; return to dos. main endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; load_logo1 proc ; purpose : load the logo and wait for a while. push main_counter ; load the backgroud/image file push counter lea bx, data ; initialize bx push bx xor bx, bx lea bx, double_buffer push bx push handle xor bx, bx lea bx, logo_file push bx call pcx_load ; load the logo push counter lea bx, data push bx push handle xor bx, bx lea bx, logo_file ; put logo file onto screen push bx call update_color_register ; update_color_register lea bx, double_buffer ; this is used to put the double buffer onto push bx ; the screen. call show_double_buffer push bx mov bx, 64000d ; put a color on the entire screen. while_loop : mov byte ptr [double_buffer+bx], 0d dec bx cmp bx, 0d ; empty? jump.... ja while_loop mov byte ptr [double_buffer+0], 0d pop bx mov al, 0h ; wait for a key mov ah, 01h int 21h lea bx, double_buffer ; this is used to put the double buffer onto push bx ; the screen. call show_double_buffer ret load_logo1 endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; load_logo2 proc ; loads the second logo, which is a simple instructions for the player push main_counter ; load the backgroud/image file push counter lea bx, data push bx xor bx, bx lea bx, double_buffer ; load double buffer onto screen push bx push handle xor bx, bx lea bx, instruct_file ; load instruction file push bx call pcx_load ; activate!!!! push counter lea bx, data push bx push handle xor bx, bx lea bx, instruct_file ; load instuction file push bx call update_color_register ; update_color_register lea bx, double_buffer ; this is used to put the double buffer onto push bx ; the screen. call show_double_buffer push bx mov bx, 64000d ; this is the testing portion which is ; for put a color on the whole screen. while_loop_2 : mov byte ptr [double_buffer+bx], 0d dec bx cmp bx, 0d ja while_loop_2 mov byte ptr [double_buffer+0], 0d pop bx mov al, 0h ; wait for a key mov ah, 01h int 21h lea bx, double_buffer ; this is used to put the double buffer onto push bx ; the screen. call show_double_buffer ret load_logo2 endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; setup_ints proc ; this procedure sets 2 interrupts, timer_tick and new_key_vec mov new_timer_vec, offset timer_tick mov new_timer_vec+2, cs mov al, 1ch lea di, old_timer_vec lea si, new_timer_vec call setup_int mov new_key_vec, offset keyboard_int mov new_key_vec+2, cs mov al, 9h lea di, old_key_vec lea si, new_key_vec call setup_int ret setup_ints endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; reset_ints proc ; similar to setup_ints lea di, new_timer_vec lea si, old_timer_vec mov al, 1ch call setup_int lea di, new_key_vec lea si, old_key_vec mov al, 9h call setup_int ret reset_ints endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; setup_sprites proc ; get and set graphic picture push main_counter ; load the backgroud/image file push counter lea bx, data push bx xor bx, bx lea bx, double_buffer ; load double buffer push bx push handle xor bx, bx lea bx, sprite_file ; load sprite file push bx call pcx_load ; activate.... push counter lea bx, data push bx push handle xor bx, bx lea bx, sprite_file push bx call update_color_register ; update_color_register push counter2 ; cut a square of picture and paste it else where push counter push y_off push x_off lea bx, sprite0 ; load spaceship push bx mov grab_x, 0 mov grab_y, 0 push grab_y push grab_x lea bx, double_buffer ; load double buffer push bx call pcx_grap_bitmap push counter2 ; cut a square of picture and paste it else where push counter push y_off push x_off lea bx, sprite1 ; load asteroid push bx mov grab_x, 1 mov grab_y, 0 push grab_y push grab_x lea bx, double_buffer push bx call pcx_grap_bitmap push counter2 ; cut a square of picture and paste it else where push counter push y_off push x_off lea bx, explosion1 ; load explosion push bx mov grab_x, 6 mov grab_y, 0 push grab_y push grab_x lea bx, double_buffer push bx call pcx_grap_bitmap push counter2 ; cut a square of picture and paste it else where push counter push y_off push x_off lea bx, explosion2 ; load explosion push bx mov grab_x, 5 mov grab_y, 0 push grab_y push grab_x lea bx, double_buffer push bx call pcx_grap_bitmap push counter2 ; cut a square of picture and paste it else where push counter push y_off push x_off lea bx, explosion3 ; load explosion push bx mov grab_x, 4 mov grab_y, 0 push grab_y push grab_x lea bx, double_buffer push bx call pcx_grap_bitmap push counter2 ; cut a square of picture and paste it else where push counter push y_off push x_off lea bx, explosion4 ; load explosion push bx mov grab_x, 3 mov grab_y, 0 push grab_y push grab_x lea bx, double_buffer push bx call pcx_grap_bitmap push counter2 ; cut a square of picture and paste it else where push counter push y_off push x_off lea bx, explosion5 ; load explosion push bx mov grab_x, 2 mov grab_y, 0 push grab_y push grab_x lea bx, double_buffer push bx call pcx_grap_bitmap ret setup_sprites endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; spaceship_move proc ; obviously, this continously cuts and paste the spaceship when arrow ; keys are activated inc wait_period mov bx, ax ; copy in bx mov cx, ax cmp cx, 0 je spaceship_stay cmp ax, 0 ; negative, move up jl spaceship_move_up cmp sprite0y, 170d ; compare the spaceship with 170 jge spaceship_move_done_temp ; can not move, go to done jmp spaceship_move_update ; else, continue spaceship_stay: jmp spaceship_move_update spaceship_move_up: cmp sprite0y, 6d ; compare spaceship at the very top jle spaceship_move_done_temp spaceship_move_update: call draw_spaceship_background ; erase spaceship mov cx, ast_speed ; compare asteroid speed with cmp wait_period, cx ; wait period.. jb ssm_1 ; jump below to spaceship move call asteroid_manager1 call asteroid_manager1half1st ssm_1: add sprite0y, bx call get_spaceship_background ; get spaceship background mov cx, ast_speed cmp wait_period, cx ; again, compare asteroid speed and jb ssm_2 ; and wait period call asteroid_manager2 ssm_2: ; else, go to spaceship move 2 call draw_spaceship ; draw spaceship mov cx, ast_speed cmp wait_period, cx jb ssm_3 call asteroid_manager3 ; jump to spaceship move 3 ssm_3: jmp regular spaceship_move_done_temp: jmp spaceship_move_done regular: mov cx, ast_speed cmp wait_period, cx jb ssm_4 ; jump to spaceship move 4 mov wait_period, 0d ssm_4: spaceship_move_done: push ax ; test crash between push bx ; the spaceship and asteroids push si push di push dx push cx mov asteroid_counter, 0 asteroid_loop1half2: mov si, offset aster_array01 ; get offset of the starting array mov ax, 581d xor dx, dx xor ch, ch mov cl, asteroid_counter ; times the loop number and goes to the first mul cx ; byte of the array mov bx, ax mov di, 0 ; put the starting byte of the record in di add di, si add di, bx cmp byte ptr es:[si+bx], 0 je asteroid_done1half2 mov cx, word ptr es:[si+bx+1] sub cx, sprite0x ; substract movement of spaceship mov ax, cx cmp ax, 0d jge not_neg neg cx not_neg: cmp cx, 18d jg no_crash ; crash? jump if false mov cx, word ptr es:[si+bx+3] ; similar as above sub cx, sprite0y mov ax, cx cmp ax, 0d jge not_neg2 neg cx not_neg2: cmp cx, 18d jg no_crash mov crash, 1d no_crash : asteroid_done1half2: inc asteroid_counter cmp asteroid_counter, 12d jl asteroid_loop1half2 pop dx pop di pop si pop bx pop ax pop cx ret spaceship_move endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; get_spaceship_background proc ; again, get file of spaceship push bx push x_off push y_off lea bx, double_buffer ; load double buffer push bx push counter push counter2 lea bx, sprite0b ; load background of spaceship push bx push sprite0x ; spaceship pop grab_x push sprite0y pop grab_y push grab_y push grab_x call get_sprite_background pop bx ret get_spaceship_background endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; draw_spaceship proc ; don't think we actually draw the spaceship, did you? push bx push x_off push y_off lea bx, double_buffer ; load double buffer push bx push counter push counter2 lea bx, sprite0 ; image of the spaceship push bx push sprite0x ; spaceship pop grab_x push sprite0y pop grab_y push grab_y push grab_x call draw_sprite pop bx ret draw_spaceship endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; draw_spaceship_background proc ; don't think we actually draw the background as well, right? push bx push x_off push y_off lea bx, double_buffer ; load double buffer push bx push counter push counter2 lea bx, sprite0b ; spaceship background push bx push sprite0x ; spaceship pop grab_x push sprite0y pop grab_y push grab_y push grab_x call draw_background pop bx ret draw_spaceship_background endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; setup_background proc ; general background for the actually game. ; you'll see it later push main_counter ; load the background/image file push counter lea bx, data push bx xor bx, bx lea bx, double_buffer ; load double buffer push bx push handle xor bx, bx lea bx, back_file ; load back_file push bx call pcx_load ; activate..... push counter lea bx, data push bx push handle xor bx, bx lea bx, back_file ; load back file push bx call update_color_register ; update_color_register ret setup_background endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; asteroid_manager1 proc ; purpose = give new life to the asteroids if they are deactived. if they are ; active, then erase it by drawing the background on top of them push ax ; save the following registers push bx push si push di push dx mov asteroid_counter, 0 asteroid_loop1: mov si, offset aster_array01 ; get offset of the starting array mov ax, 581d ; why 581? the asteroids will be coming xor dx, dx ; the left side of the screen xor ch, ch mov cl, asteroid_counter ; times the loop number and goes to the first mul cx mov bx, ax ; byte of the array mov di, 0 ; put the starting byte of the record in di add di, si add di, bx cmp byte ptr es:[si+bx], 0 jne asteroid_not_zero mov ax, 1000d ; the program makes a new asteroid int 62h ; random interrupt cmp ax, 999d ; no significance to #, wanted to jl asteroid_temp_loop_3 ; compare with large # mov ax, 150d int 62h add ax, 20d ; position of asteroid mov byte ptr es:[si+bx], 1 ; asteroid becomes active mov word ptr es:[si+bx+1], 296d ; put in x value mov word ptr es:[si+bx+3], ax ; put in y value add si, bx add si, 5d ; go to background address jmp asteroid_done asteroid_not_zero: push bx ; draw background push x_off push y_off lea bx, double_buffer ; load double buffer push bx push counter push counter2 lea bx, byte ptr es:[di+5] ; load background push bx mov ax, word ptr es:[di+1] ; mov x into grab_x mov grab_x, ax mov ax, word ptr es:[di+3] ; mov y into grab_y mov grab_y, ax push grab_y push grab_x call draw_background pop bx jmp asteroid_done asteroid_temp_loop_3: jmp asteroid_done asteroid_temp_loop_1: jmp asteroid_loop1 asteroid_done: inc asteroid_counter cmp asteroid_counter, 12d jl asteroid_temp_loop_1 pop dx ; restore registers pop di pop si pop bx pop ax ret asteroid_manager1 endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; asteroid_manager1half1st proc ; purpose = test the asteroid is at the left edge of the screen or not ; if true, then deactive it. push ax ; save registers push bx push si push di push dx mov asteroid_counter, 0 asteroid_loop1half1st: mov si, offset aster_array01 ; get offset of the starting array mov ax, 581d xor dx, dx xor ch, ch mov cl, asteroid_counter ; times the loop number and goes to the first mul cx mov bx, ax ; byte of the array mov di, 0 ; put the starting byte of the record in di add di, si add di, bx cmp byte ptr es:[si+bx], 0 ; is the asteroid active? je asteroid_done1half1st cmp word ptr es:[si+bx+1], 5 jg asteroid_done1half1st mov byte ptr es:[si+bx], 0d ; if the asteroid reach the left edge ; deactive it. asteroid_done1half1st: inc asteroid_counter cmp asteroid_counter, 12d jl asteroid_loop1half1st pop dx ; restore registers pop di pop si pop bx pop ax ret asteroid_manager1half1st endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; asteroid_manager2 proc ; purpose = update the coordination of asteroids and grab the new location's ; background. ; similar as the above procedure push ax ; save registers push bx push si push di push dx mov asteroid_counter, 0 asteroid_loop1half: mov si, offset aster_array01 ; get offset of the starting array mov ax, 581d xor dx, dx xor ch, ch mov cl, asteroid_counter ; times the loop number and goes to the first mul cx mov bx, ax ; byte of the array mov di, 0 ; put the starting byte of the record in di add di, si add di, bx cmp byte ptr es:[si+bx], 0 je asteroid_done1half_temp push ax ; the following is the speed of the asteroids push dx push bx xor dx, dx xor ah, ah mov al, asteroid_counter mov bx, 3d div bx cmp dx, 0 je a_speed_two cmp dx, 1 je a_speed_three add word ptr es:[di+1], -1d ; update x jmp a_speed_end a_speed_two : add word ptr es:[di+1], -2d ; update x jmp a_speed_end a_speed_three : add word ptr es:[di+1], -3d ; update x a_speed_end: pop bx ; restore registers pop dx pop ax push ax ; the following does random for asteroids push dx push bx xor dx, dx xor ah, ah mov al, asteroid_counter mov bx, 3d div bx cmp dx, 0 jne a_random_move mov ax, word ptr es:[di+3] cmp ax, sprite0y ; sapceship of y axis je chase_end cmp ax, sprite0y jg chase_mov_down add word ptr es:[di+3], 1d jmp chase_end chase_mov_down : ; this loop "chases" the spaceship add word ptr es:[di+3], -1d ; cool, no? jmp chase_end asteroid_done1half_temp : jmp asteroid_done1half chase_end: add word ptr es:[di+1], 1d ; update x pop bx ; restore registers pop dx pop ax jmp regular2 a_random_move: pop bx pop dx pop ax push ax ; random y into -2 or 2 mov ax, 4d int 62h ; random interrupt cmp ax, 2d je two cmp ax, 1d je one jmp random_done one : cmp word ptr es:[di+3], 5d ; speed of 5 jle random_done sub word ptr es:[di+3], 2d ; speed of 2 jmp random_done two : cmp word ptr es:[di+3], 171d ; compares the the top boundary jg random_done ; so the asteroid will not go out of range add word ptr es:[di+3], 2d random_done: ; random y complete. pop ax jmp regular2 temp1111: jmp asteroid_loop1half regular2: push bx ; get_sprite_background push x_off push y_off lea bx, double_buffer ; load double buffer push bx push counter push counter2 lea bx, byte ptr es:[di+5] ; load background push bx mov ax, word ptr es:[di+1] ; mov x into grab_x mov grab_x, ax mov ax, word ptr es:[di+3] ; mov y into grab_y mov grab_y, ax push grab_y push grab_x call get_sprite_background pop bx ; restore bx asteroid_done1half: inc asteroid_counter cmp asteroid_counter, 12d jl temp1111 pop dx ; restore the following registers pop di pop si pop bx pop ax ret asteroid_manager2 endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; asteroid_manager3 proc ; purpose = draw all asteroids onto the screen. push ax ; save registers push bx push si push di push dx mov asteroid_counter, 0 asteroid_loop2: mov si, offset aster_array01 ; get offset of the starting array mov ax, 581d xor dx, dx xor ch, ch mov cl, asteroid_counter ; times the loop number and goes to the first mul cx mov bx, ax ; byte of the array mov di, 0 ; put the starting byte of the record in di add di, si add di, bx cmp byte ptr es:[si+bx], 0 je asteroid_done2 jmp loop2_temp_2 loop2_temp_1: jmp asteroid_loop2 loop2_temp_2: push bx ; this loop draws the asteroid push x_off push y_off lea bx, double_buffer push bx push counter push counter2 lea bx, sprite1 ; asteroid push bx mov ax, word ptr es:[di+1] ; mov x into grab_x mov grab_x, ax mov ax, word ptr es:[di+3] ; mov y into grab_y mov grab_y, ax push grab_y push grab_x call draw_sprite pop bx asteroid_done2: inc asteroid_counter cmp asteroid_counter, 12d jl loop2_temp_1 pop dx ; restore the following registers pop di pop si pop bx pop ax ret asteroid_manager3 endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; explosion proc ; and finally..... ; the wonderful explosion push bx push x_off push y_off lea bx, double_buffer ; load double buffer push bx push counter push counter2 lea bx, explosion1 ; first explosion push bx push sprite0x ; along with the spaceship pop grab_x push sprite0y pop grab_y push grab_y push grab_x call draw_sprite pop bx lea bx, double_buffer push bx call show_double_buffer mov hold, 0 explosion_loop1: ; first appearance of an EXPLOSION mov hold2, 0 explosion_loop1a: ; purpose of this loop is to extend inc hold2 ; the time of the explosions mov ax, hold2 cmp ax, max_hold2 jb explosion_loop1a inc hold mov ax, hold cmp ax, max_hold jb explosion_loop1 push bx push x_off push y_off lea bx, double_buffer ; load double buffer push bx push counter push counter2 lea bx, explosion2 ; second explosion push bx push sprite0x ; along with the spaceship pop grab_x push sprite0y pop grab_y push grab_y push grab_x call draw_sprite pop bx mov hold, 0 explosion_loop2: ; third appearance of an EXPLOSION mov hold2, 0 explosion_loop2a: ; extend the time for explosion inc hold2 mov ax, hold2 cmp ax, max_hold2 jb explosion_loop2a inc hold mov ax, hold cmp ax, max_hold jb explosion_loop2 lea bx, double_buffer ; load double buffer push bx call show_double_buffer ; activate push bx push x_off push y_off lea bx, double_buffer push bx push counter push counter2 lea bx, explosion3 ; third explosion push bx push sprite0x ; along with spaceship pop grab_x push sprite0y pop grab_y push grab_y push grab_x call draw_sprite pop bx lea bx, double_buffer ; load double buffer push bx call show_double_buffer mov hold, 0 explosion_loop3: ; fourth appearance of an EXPLOSION mov hold2, 0 explosion_loop3a: inc hold2 mov ax, hold2 cmp ax, max_hold2 jb explosion_loop3a inc hold mov ax, hold cmp ax, max_hold jb explosion_loop3 push bx push x_off push y_off lea bx, double_buffer ; load double buffer push bx push counter push counter2 lea bx, explosion4 ; fourth explosion push bx push sprite0x ; along with spaceship pop grab_x push sprite0y pop grab_y push grab_y push grab_x call draw_sprite pop bx lea bx, double_buffer push bx call show_double_buffer mov hold, 0 explosion_loop4: ; fifth ppearance of an EXPLOSION mov hold2, 0 explosion_loop4a: inc hold2 mov ax, hold2 cmp ax, max_hold2 jb explosion_loop4a inc hold ; extend the time of this explosion mov ax, hold cmp ax, max_hold jb explosion_loop4 push bx push x_off push y_off lea bx, double_buffer push bx push counter push counter2 lea bx, explosion5 ; fifth explosion push bx push sprite0x ; along with spaceship pop grab_x push sprite0y pop grab_y push grab_y push grab_x call draw_sprite pop bx lea bx, double_buffer push bx call show_double_buffer mov al, 0h ; wait for a key mov ah, 01h int 21h ret explosion endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; end main