;=============================================================================; ; Hidnplayr's invaders for Kolibrios ; ;-----------------------------------------------------------------------------; ; ; ; Copyright (C) hidnplayr 2007-2014. All rights reserved. ; ; ; ; Invaders is distributed in the hope that it will be useful, but WITHOUT ANY ; ; WARRANTY. No author or distributor accepts responsibility to anyone for the ; ; consequences of using it or for whether it serves any particular purpose or ; ; works at all, unless he says so in writing. Refer to the GNU General Public ; ; License (the "GPL") for full details. ; ; Everyone is granted permission to copy, modify and redistribute KolibriOS, ; ; but only under the conditions described in the GPL. A copy of this license ; ; is supposed to have been given to you along with KolibriOS so you can know ; ; your rights and responsibilities. It should be in a file named COPYING. ; ; Among other things, the copyright notice and this notice must be preserved ; ; on all copies. ; ; ; ; see copying.txt ; ; ; ; contact me on hidnplayr@gmail.com ; ; ; ;-----------------------------------------------------------------------------; format binary as "" ; Screen size SCREEN_X = 640 SCREEN_Y = 480 ; Ship size SHIP_X = 32 SHIP_Y = 32 ; Ship begin position SHIP_X_POS = (SCREEN_X-SHIP_X)/2 SHIP_Y_POS = SCREEN_Y-SHIP_Y-27 ; Enemy size ENEMY_X = 32 ENEMY_Y = 32 ; Alien size and position ALIEN_X = 48 ALIEN_Y = 38 ALIEN_Y_POS = 1 ; BOUNDARY = 10 MOVEMENT = 7 ; pixels/frame TRANSPARENCY = 0x00ffffff ; color used as transparant ; Window start position WINDOW_X = 100 WINDOW_Y = 100 ; Bullet size BULLET_X = 10 BULLET_Y = 10 ; Number of stars STARS_ = 226 ; Number of star levels (depth) STARLEVELS = 3 ENEMY_STARTING_X = 25 ENEMY_STARTING_Y = 50 BULLETSPEED = 12 ; pixels/frame use32 org 0x0 db 'MENUET01' ; 8 byte id dd 0x01 ; header version dd START ; start of code dd IM_END ; size of image dd I_END+1000 ; memory for app dd I_END+1000 ; esp dd 0x0, 0x0 ; I_Param , I_Path include '../../macros.inc' include '../../proc32.inc' include '../../dll.inc' include '../../develop/libraries/libs-dev/libimg/libimg.inc' KEY_RIGHT = 179 KEY_LEFT = 176 KEY_UP = 178 KEY_P = 'p' KEY_DOWN = 177 KEY_ENTER = 13 KEY_ESC = 27 proc aimgtoimg img, x, y, canvas, acolor pusha ; Calculate offset on canvas in edi mov eax, [y] mov ecx, [canvas] mul dword[ecx] ; canvas xsize add eax, [x] lea edi, [eax*2 + eax + 8] add edi, [canvas] ; get img size in ecx and edx mov esi, [img] mov ecx, dword[esi+0] ; img x size mov edx, dword[esi+4] ; img y size ; caluclate number of bytes between 2 lines in ebx mov ebx, [canvas] mov ebx, [ebx] ; canvas xsize sub ebx, [esi] ; img xsize lea ebx, [ebx*2 + ebx] ; get image start ptr in esi add esi, 8 .loop2: push ecx edx mov edx, [acolor] .loop: mov eax, [esi] and eax, 0x00ffffff cmp eax, edx je @f mov word[edi], ax shr eax, 16 mov byte[edi+2], al @@: add esi, 3 add edi, 3 dec ecx jnz .loop pop edx ecx add edi, ebx dec edx jnz .loop2 popa ret endp proc aimgtoimg2 img, x, y, canvas, acolor pusha ; Calculate offset on canvas in edi mov eax, [y] mov ecx, [canvas] mul dword[ecx] ; canvas xsize add eax, [x] lea edi, [eax*2 + eax + 8] add edi, [canvas] ; get img size in ecx and edx mov esi, [img] mov ecx, dword[esi+0] ; img x size mov edx, dword[esi+4] ; img y size ; caluclate number of bytes between 2 lines in ebx mov ebx, [canvas] mov ebx, [ebx] ; canvas xsize sub ebx, [esi] ; img xsize lea ebx, [ebx*2 + ebx] ; get image start ptr in esi add esi, 8 .loop2: push ecx edx mov edx, [acolor] .loop: mov eax, [esi] and eax, 0x00ffffff cmp eax, edx je @f mov byte[edi+2], al shr eax, 8 mov word[edi], ax @@: add esi, 3 add edi, 3 dec ecx jnz .loop pop edx ecx add edi, ebx dec edx jnz .loop2 popa ret endp proc getimg imgsrc, x, y, xs, ys, imgdest pusha mov esi, [imgsrc] mov eax, dword[esi+0] ; xsize mov ebx, [y] mul ebx ; xsize*y add eax, [x] ; xsize*y+x lea eax, [eax+2*eax] ; (xsize*y+x)*3 mov edx, dword[esi+0] ; xsize sub edx, [xs] ; xsize-xs lea edx, [edx*2+edx] ; (xsize-xs)*3 lea esi, [esi + eax + 8] ; imgsrc + (xsize*y+x)*3 + 8 mov edi, [imgdest] mov ecx, [xs] mov dword[edi+0], ecx ; xsize mov ebx, [ys] mov dword[edi+4], ebx ; ysize add edi, 8 ; imgdest + 8 cld .loop: movsw movsb dec ecx jnz .loop add esi, edx mov ecx, [xs] dec ebx jnz .loop popa ret endp macro decodeimg source, size, dest { invoke img.decode, source, size, 0 or eax, eax jz exit push [eax + Image.Width] pop dword[dest+0] push [eax + Image.Height] pop dword[dest+4] push eax invoke img.to_rgb2, eax, dest+8 pop eax invoke img.destroy, eax } START: mcall 68, 11 stdcall dll.Load, @IMPORT or eax, eax jz @f exit: mcall -1 @@: call draw_window decodeimg gif_bullet,gif_bullet.size,img_bullet decodeimg gif_bullet2,gif_bullet2.size,img_bullet2 decodeimg gif_ship,gif_ship.size,img_ship decodeimg gif_enemy1,gif_enemy1.size,img_enemy1 decodeimg gif_enemy2,gif_enemy2.size,img_enemy2 decodeimg gif_enemy3,gif_enemy3.size,img_enemy3 decodeimg gif_enemy4,gif_enemy4.size,img_enemy4 decodeimg gif_enemy5,gif_enemy5.size,img_enemy5 decodeimg gif_alien,gif_alien.size,img_alien decodeimg gif_menu1,gif_menu1.size,img_menu1 decodeimg gif_menu2,gif_menu2.size,img_menu2 decodeimg gif_menu3,gif_menu3.size,img_menu3 decodeimg gif_menu4,gif_menu4.size,img_menu4 decodeimg gif_logo,gif_logo.size,img_logo decodeimg gif_pause,gif_pause.size,img_pause decodeimg gif_levelup,gif_levelup.size,img_levelup decodeimg gif_gameover,gif_gameover.size,img_gameover decodeimg gif_highscore,gif_highscore.size,img_highscore decodeimg gif_smallfont,gif_smallfont.size,img_smallfont decodeimg gif_bigfont,gif_bigfont.size,img_bigfont decodeimg gif_numbers,gif_numbers.size,img_numbers call init_starfield call render_frame call draw_to_screen mainloop: call render_frame call draw_to_screen call bullet_collision_detection cmp [status], 3 ; if game is paused,... jne .wait mcall 10 jmp .switch .wait: mcall 5, 1 ; wait 1/100 s mcall 11 ; check for events .switch: test eax, eax jz mainloop dec eax jz .redraw dec eax jz .key dec eax jz .button .redraw: call draw_window jmp .wait .button: mcall 17 ; get button id cmp ah, 1 jne .wait mcall -1 .key: mcall 2 ; get key code test ah, ah jz mainloop cmp [status], 1 je key_game cmp [status], 0 je key_menu cmp [status], 3 je key_pause cmp [status], 6 je key_levelup cmp [status], 7 je key_highscore cmp [status], 2 je key_gameover cmp ah, KEY_ESC jne .no_escape mov [status], 0 mov [intro], 0 .no_escape: jmp mainloop key_game: cmp ah, KEY_RIGHT jnz .no_right cmp [ship_x], SCREEN_X-SHIP_X-BOUNDARY jge mainloop add [ship_x], MOVEMENT jmp mainloop .no_right: cmp ah, KEY_LEFT jne .no_left cmp [ship_x], BOUNDARY jle mainloop sub [ship_x], MOVEMENT jmp mainloop .no_left: cmp ah, KEY_UP jne .no_up cmp [bullet_y], 1 jg mainloop mov eax, [ship_x] add eax, (SHIP_X-BULLET_X)/2 mov [bullet_x], eax mov [bullet_y], SHIP_Y_POS;-BULLET_Y jmp mainloop .no_up: cmp ah, KEY_P jne no_pause mov [status], 3 stdcall aimgtoimg, img_pause, 150, 180, vscreen, TRANSPARENCY call draw_to_screen jmp mainloop no_pause: cmp ah, KEY_ESC jne .no_escape mov [status], 0 mov [intro], 0 .no_escape: jmp mainloop key_menu: cmp ah, KEY_DOWN jne .no_down cmp [menu], 3 jne @f mov [menu], 0 jmp mainloop @@: inc [menu] jmp mainloop .no_down: cmp ah, KEY_UP jnz .no_up cmp [menu], 0 jne @f mov [menu], 3 jmp mainloop @@: dec [menu] jmp mainloop .no_up: cmp ah, KEY_ESC jne @f mcall -1 @@: cmp ah, KEY_ENTER jnz .no_enter cmp [menu], 0 ;start je new_game cmp [menu], 1 ;about jne @f mov [status], 4 jmp mainloop @@: cmp [menu], 2 ;highscores jne @f mov [status], 5 call load_highscores jmp mainloop @@: cmp byte[menu], 3 ;exit jne @f mcall -1 @@: .no_enter: jmp mainloop key_pause: cmp ah, KEY_P jnz no_pause mov [status], 1 .nopause: jmp mainloop key_levelup: cmp ah, KEY_ENTER jne .no_enter inc [level] inc byte[levelnumb+1] cmp byte[levelnumb+1], '9' jle @f mov byte[levelnumb+1], '0' inc byte[levelnumb] @@: mov eax,20 mov ah,byte[level] and ah,7 mul ah add eax,level1 mov esi,eax jmp load_level .no_enter: cmp ah, KEY_ESC jne .no_escape mov [status], 0 mov [intro], 0 .no_escape: jmp mainloop key_highscore: cmp ah, KEY_ENTER jne @f call load_highscores mov eax, [score] mov ebx, highscorebuffer+140 .findscore: cmp ebx, highscorebuffer+100 je .topscore sub ebx, 4 cmp eax, dword[ebx] jg .findscore .topscore: mov esi, name mov edi, highscorebuffer mov ecx, 10 rep movsb mov eax, [score] mov dword[highscorebuffer+100], eax call save_highscores mov [status], 5 @@: cmp ah, 14 jne @f cmp byte[namepos],0 je @f dec byte[namepos] movzx ebx,byte[namepos] add ebx,name mov byte[ebx], 0x11 ; this is a character we dont print @@: cmp byte[namepos],10 jge mainloop cmp al,'0' jl mainloop cmp al,'9' jle @f cmp al,'z' jg mainloop cmp al,'a' jge @f cmp al,'Z' jg mainloop cmp al,'A' jl mainloop @@: movzx ebx, byte[namepos] add ebx, name mov byte[ebx], al inc byte[namepos] jmp mainloop key_gameover: cmp ah, KEY_ENTER jne .no_enter ; TODO: test if score is high enough to put in highscore list... mov [status],7 jmp mainloop .no_enter: jmp mainloop new_game: mov [score], 0 mov eax, [score] call convertscore mov word[levelnumb], '01' mov esi, level1 load_level: mov [enemy_speed], 1 mov [enemy_x], ENEMY_STARTING_X mov [enemy_y], ENEMY_STARTING_Y mov edi, enemy_table mov ecx, 5 rep movsd mov [status],1 jmp mainloop draw_window: mcall 12, 1 ; Start of window draw mov ebx, WINDOW_X shl 16 + 9 + SCREEN_X ; [x start] shl 16 + [x size] mov ecx, WINDOW_Y shl 16 + 25 + SCREEN_Y ; [y start] shl 16 + [y size] mov edx, 0x64000000 ; color of work area RRGGBB mov esi, 0x805080d0 ; color of grab bar RRGGBB mov edi, 0x005080d0 ; color of frames RRGGBB mcall 0 mcall 71, 1, title call draw_to_screen mcall 12, 2 ; End of window draw ret draw_to_screen: ; Draw buffer to the screen mov ebx, vscreen+8 mov ecx, SCREEN_X shl 16 + SCREEN_Y mov edx, 0 shl 16 + 0 mcall 7 ret load_highscores: ret save_highscores: ret render_frame: mov eax, 0x00000000 call fillscreen call render_starfield cmp [status], 1 je render_game cmp [status], 2 je render_gameover cmp [status], 4 je render_about cmp [status], 6 je render_levelup cmp [status], 0 je render_menu cmp [status], 5 je render_highscorelist cmp [status], 7 je render_highscore ret render_game: call render_bullet call render_enemies ; Draw the enemies to buffer stdcall aimgtoimg, img_ship, [ship_x], SHIP_Y_POS, vscreen, TRANSPARENCY; Draw the ship to buffer mov esi, scoretext mov ebx, 0 mov ecx, SCREEN_Y-24 call printtext mov esi, leveltext mov ebx, 300 call printtext ret render_gameover: stdcall aimgtoimg, img_ship, [ship_x], SHIP_Y_POS, vscreen, TRANSPARENCY; Draw the ship to buffer mov esi, scoretext mov ebx, 0 mov ecx, SCREEN_Y-24 call printtext mov esi, leveltext mov ebx, 300 call printtext stdcall aimgtoimg, img_gameover, 150, 180, vscreen, TRANSPARENCY ret render_about: mov esi, msgAbout mov ebx, 50 mov ecx, 100 call printtext ret render_levelup: stdcall aimgtoimg, img_ship, [ship_x], SHIP_Y_POS, vscreen, TRANSPARENCY; Draw the ship to buffer mov esi, scoretext mov ebx, 0 mov ecx, SCREEN_Y-24 call printtext mov esi, leveltext mov ebx, 300 call printtext stdcall aimgtoimg, img_levelup, 150, 180, vscreen, TRANSPARENCY ret render_menu: stdcall aimgtoimg, img_logo, 50, 80, vscreen, TRANSPARENCY cmp [menu], 0 jne .menu_0 stdcall aimgtoimg2, img_menu1, 30, 200, vscreen, TRANSPARENCY jmp .menu_1 .menu_0: stdcall aimgtoimg, img_menu1, 30, 200, vscreen, TRANSPARENCY .menu_1: cmp [menu], 1 jne .menu_2 stdcall aimgtoimg2, img_menu2, 80, 250, vscreen, TRANSPARENCY jmp .menu_3 .menu_2: stdcall aimgtoimg, img_menu2, 80, 250, vscreen, TRANSPARENCY .menu_3: cmp [menu], 2 jne .menu_4 stdcall aimgtoimg2, img_menu3, 120, 300, vscreen, TRANSPARENCY jmp .menu_5 .menu_4: stdcall aimgtoimg, img_menu3, 120, 300, vscreen,TRANSPARENCY .menu_5: cmp [menu], 3 jne .menu_6 stdcall aimgtoimg2, img_menu4, 150, 350, vscreen, TRANSPARENCY jmp .menu_7 .menu_6: stdcall aimgtoimg, img_menu4, 150, 350, vscreen, TRANSPARENCY .menu_7: cmp [intro], 200 je .menu_75 inc [intro] .menu_75: cmp [intro], 0 jl .menu_8 stdcall aimgtoimg, img_enemy1, 390, 180, vscreen, TRANSPARENCY cmp [intro], 15 jl .menu_8 mov esi, points_50 mov ebx, 470 mov ecx, 180 call printtext cmp [intro],30 jl .menu_8 stdcall aimgtoimg, img_enemy2, 390, 220, vscreen, TRANSPARENCY cmp [intro], 45 jl .menu_8 mov esi, points_100 mov ebx, 450 mov ecx, 220 call printtext cmp [intro], 60 jl .menu_8 stdcall aimgtoimg, img_enemy3, 390, 260, vscreen, TRANSPARENCY cmp [intro], 75 jl .menu_8 mov esi, points_150 mov ebx, 450 mov ecx, 260 call printtext cmp [intro],90 jl .menu_8 stdcall aimgtoimg, img_enemy4, 390, 300, vscreen, TRANSPARENCY cmp [intro], 105 jl .menu_8 mov esi, points_200 mov ebx, 450 mov ecx, 300 call printtext cmp [intro], 120 jl .menu_8 stdcall aimgtoimg, img_enemy5, 390, 340, vscreen, TRANSPARENCY cmp [intro],135 jl .menu_8 mov esi, points_250 mov ebx, 450 mov ecx, 340 call printtext cmp [intro],150 jl .menu_8 stdcall aimgtoimg, img_alien, 380, 380, vscreen, TRANSPARENCY cmp [intro],165 jl .menu_8 mov esi, points_1000 mov ebx, 430 mov ecx, 380 call printtext .menu_8: ret render_highscorelist: stdcall aimgtoimg, img_highscore, 60, 40, vscreen, TRANSPARENCY mov ebx, 100 ; print names mov ecx, 120 mov esi, highscorebuffer call printtext mov edi, highscorebuffer+100 ; print scores mov esi, scorenumb mov ebx, 420 mov ecx, 120 .loop: mov eax,[edi] push ecx call convertscore pop ecx push esi call printtext pop esi add ecx, 26 add edi, 4 cmp edi, highscorebuffer+140 jl .loop ret render_highscore: stdcall aimgtoimg, img_highscore, 60, 40, vscreen, TRANSPARENCY mov ebx, 60 mov ecx, 200 mov esi, entername call printtext mov ebx, 250 mov ecx, 250 mov esi, name call printtext mov esi, scoretext mov ebx, 0 mov ecx, SCREEN_Y-24 call printtext mov esi, leveltext mov ebx, 300 call printtext ret render_enemies: ; check if direction should change test [enemy_d], 2 jz @f add [enemy_y], 5 mov eax, [enemy_y] shr eax, 5 add al, [level] mov [enemy_speed], al and [enemy_d], 1 @@: ; move the aliens to left or right movzx eax, [enemy_speed] test [enemy_d], 1 jz .other_dir sub [enemy_x], eax jmp .no_other_dir .other_dir: add [enemy_x], eax .no_other_dir: ; initialization mov [alldeadb],1 mov edi, enemy_table mov eax, [enemy_x] mov [current_enemy_x], eax mov eax, [enemy_y] mov [current_enemy_y], eax .loopit: movzx eax, byte[edi] test al, al jz .next_alien cmp al, 5 ja .next_alien dec eax mov eax, [enemy_img_list+eax*4] .drawenemy: mov [alldeadb], 0 stdcall aimgtoimg, eax, [current_enemy_x], [current_enemy_y], vscreen, TRANSPARENCY ; jmp checknext .checknext: cmp [enemy_d], 2 jge .dont_change_dir movzx eax, [enemy_speed] cmp [enemy_d], 0 jbe .change_dir cmp dword[current_enemy_x],eax jg .dont_change_dir mov [enemy_d], 2 jmp .dont_change_dir .change_dir: mov ebx, SCREEN_X-ENEMY_X sub ebx, eax cmp dword[current_enemy_x],ebx jl .dont_change_dir mov [enemy_d], 3 .dont_change_dir: cmp [current_enemy_y], SHIP_Y_POS-ENEMY_Y-BOUNDARY jle .next_alien ;;;;;; mov [status], 2 ret .next_alien: cmp edi, enemy_table+20 jge .alldead inc edi add dword[current_enemy_x],ENEMY_X+BOUNDARY mov eax,dword[current_enemy_x] sub eax,dword[enemy_x] cmp eax,5*(ENEMY_X+BOUNDARY) jl .no_newline sub [current_enemy_x], 5*(ENEMY_X+BOUNDARY) add [current_enemy_y], ENEMY_Y+BOUNDARY .no_newline: jmp .loopit .alldead: cmp [alldeadb], 0 je .enemy_end mov [status], 6 ret .enemy_end: cmp [alien_x], 5 jge @f call random_generator cmp eax,0xffffffff/50 ; one out of 500 chances that it appears during this frame jl .alien_end mov [alien_x], SCREEN_X-ALIEN_X @@: push eax mov eax, SCREEN_X ; mov eax, SCREEN_X sub eax, dword [alien_x] cmp eax, ALIEN_X jle @f mov eax, ALIEN_X @@: ; stdcall getimg, img_alien, 0, 0, 10, ALIEN_Y, img_alienpiece stdcall aimgtoimg, img_alien, [alien_x], ALIEN_Y_POS, vscreen, TRANSPARENCY sub [alien_x], 5 pop eax .alien_end: ret render_bullet: cmp [bullet_y], BULLETSPEED jl .nobullet sub [bullet_y], BULLETSPEED stdcall aimgtoimg, img_bullet, [bullet_x], [bullet_y], vscreen, TRANSPARENCY .nobullet: ret bullet_collision_detection: cmp [bullet_y], BULLETSPEED ; does the bullet hit top of the screen? jle .hidebullet ; yes, hide bullet mov edi, enemy_table mov eax, [enemy_x] mov [current_enemy_x], eax mov eax, [enemy_y] mov [current_enemy_y], eax .check: cmp byte[edi],0 ; is the enemy at this position alive? je .nextcheck ; no, try next enemy ; check if bullet hits current enemy mov eax, [current_enemy_y] ; move the enemy y position into eax cmp [bullet_y], eax ; is the bullet's y position less than eax (enemy y pos) jl .nextcheck ; yes, bullet can't be colliding, check next enemy add eax, ENEMY_Y ; add the width of the enemy to the enemy's y position (wich is still stored in eax) cmp [bullet_y], eax ; is the bullet's y position greater than eax (the end of the enemy) jg .nextcheck ; yes, bullet can't be colliding, check next enemy mov eax, [current_enemy_x] ; now do the same but for the x positions cmp [bullet_x], eax ; jl .nextcheck ; ; add eax, ENEMY_Y ; cmp [bullet_x], eax ; jg .nextcheck ; jmp .hit .nextcheck: inc edi add [current_enemy_x], ENEMY_X+BOUNDARY mov eax, [current_enemy_x] sub eax, [enemy_x] cmp eax, 5*(ENEMY_X+BOUNDARY) jl .no_newline sub [current_enemy_x], 5*(ENEMY_X+BOUNDARY) add [current_enemy_y], ENEMY_Y+BOUNDARY .no_newline: cmp edi, enemy_table+20 ; is this the last enemy? jg .nohit ; yes, none of them was hit jmp .check ; no, check if enemy is alive and draw it .hit: movzx ebx, byte[edi] ; mov the enemy number onto ebx add [score], ebx ; add this number to the score dword mov eax,[score] call convertscore mov byte[edi],0 ; hide the enemy .hidebullet: mov [bullet_y], 1 ; mov the bullet to top of screen (hide it) jmp .noalienhit .nohit: mov eax, [alien_x] ; check if we hit the big alien in the ufo cmp [bullet_x], eax jl .noalienhit add eax, ALIEN_X-BULLET_X cmp [bullet_x], eax jg .noalienhit cmp [bullet_y], ALIEN_Y_POS+ALIEN_Y jg .noalienhit add [score], 100/5 mov eax, [score] call convertscore mov [alien_x], 0 .noalienhit: ret convertscore: test al,1 jz .1 mov byte[scorenumb+5],'5' jmp .2 .1: mov byte[scorenumb+5],'0' .2: shr eax,1 mov ecx,10 xor edx,edx div ecx add dl,'0' mov byte[scorenumb+4],dl xor edx,edx div ecx add dl,'0' mov byte[scorenumb+3],dl xor edx,edx div ecx add dl,'0' mov byte[scorenumb+2],dl xor edx,edx div ecx add dl,'0' mov byte[scorenumb+1],dl xor edx,edx div ecx add dl,'0' mov byte[scorenumb+0],dl ret fillscreen: ; eax - screen color ( 0x00RRGGBB ) mov edi, vscreen+8 cld mov ecx, SCREEN_X*SCREEN_Y .lab1: mov [edi], eax add edi, 3 loop .lab1 ret printtext: push ebx .loop: lodsb test al, al jz .done cmp al, 13 je .nextline cmp al,' ' je .space cmp al,'0' jl .loop cmp al,'9' jle .usenumbers cmp al,'z' jg .loop cmp al,'a' jge .usesmallfont cmp al,'Z' jg .loop cmp al,'A' jge .usebigfont jmp .loop .usesmallfont: movzx edx, al sub edx, 'a' mov eax, 12 mul edx stdcall getimg, img_smallfont, 0, eax, 20, 12, img_char push ecx add ecx, 4 stdcall aimgtoimg, img_char, ebx, ecx, vscreen, TRANSPARENCY pop ecx add ebx, 20 jmp .loop .usebigfont: movzx edx, al sub edx, 'A' mov eax, 20 mul edx stdcall getimg, img_bigfont, 0, eax, 28, 20, img_char stdcall aimgtoimg, img_char, ebx, ecx, vscreen, TRANSPARENCY add ebx, 28 jmp .loop .usenumbers: movzx edx, al sub edx, '0' mov eax, 20 mul edx stdcall getimg, img_numbers, 0, eax, 16, 20, img_char stdcall aimgtoimg, img_char, ebx, ecx, vscreen, TRANSPARENCY add ebx, 20 jmp .loop .space: add ebx, 20 jmp .loop .nextline: pop ebx push ebx add ecx, 26 jmp .loop .done: pop ebx ret init_starfield: mov ebx, STARS .loop: cmp ebx, STARS+(STARS_*5) jge .done call random_generator and al, STARLEVELS test al,al jnz @f inc al @@: mov byte[ebx],al call random_generator and eax, SCREEN_X-1 inc eax mov word[ebx+1],ax call random_generator and eax, SCREEN_Y-1 inc eax mov word[ebx+3],ax add ebx, 5 jmp .loop .done: ret render_starfield: mov esi, STARS .loop: cmp esi, STARS+(STARS_*5) jge .done movzx eax, byte[esi] ; z (speed, brightness) movzx ebx, word[esi+1] ; x movzx ecx, word[esi+3] ; y add bx, ax cmp bx, SCREEN_X jl .moveit xor ebx, ebx inc ebx call random_generator mov ecx, [generator] and ecx, SCREEN_Y-1 inc ecx mov word[esi+3], cx call random_generator and al, STARLEVELS test al, al jnz @f inc al @@: mov [esi], al .moveit: mov word[esi+1], bx movzx eax, byte[esi] inc eax mov edx, 0xff/(STARLEVELS+1) mul edx mov ah, al shl eax, 8 mov al, ah mov ebp, eax mov eax, SCREEN_X mul ecx add eax, ebx mov edx, 3 mul edx cmp eax, SCREEN_X*SCREEN_Y*3 jg @f add eax, vscreen+8 and dword[eax], 0xff000000 or dword[eax], ebp @@: add esi, 5 jmp .loop .done: ret random_generator: ; (pseudo random, actually :) xor eax, [generator] imul eax, 214013 xor eax, 0xdeadbeef rol eax, 9 mov [generator], eax ror eax, 16 and eax, 0x7fff ret level1: db 4,4,4,4,4 db 3,3,3,3,3 db 2,2,2,2,2 db 1,1,1,1,1 level2: db 4,1,3,1,4 db 4,3,2,3,4 db 0,4,1,4,0 db 0,0,2,0,0 level3: db 1,5,5,5,1 db 1,2,2,2,1 db 3,1,2,1,3 db 4,3,1,3,4 level4: db 4,5,2,5,4 db 5,3,3,3,5 db 4,5,4,5,4 db 1,5,5,5,1 level5: db 5,4,3,4,5 db 5,4,4,4,5 db 4,5,4,5,4 db 3,5,1,5,3 level6: db 1,2,5,4,5 db 5,4,5,2,1 db 1,2,5,4,5 db 1,1,5,1,1 level7: db 1,2,3,2,1 db 1,3,3,3,1 db 3,4,3,4,3 db 5,5,5,5,5 level8: db 1,2,3,4,5 db 3,5,3,5,4 db 4,2,3,2,3 db 5,4,3,2,1 enemy_table: db 0,0,0,0,0 db 0,0,0,0,0 db 0,0,0,0,0 db 0,0,0,0,0 msgAbout db 'Hidnplayrs invaders',13,'KolibriOS version',13,13,'released under GPL',13,'make this game better',13,'if you want to',0 title db 'Invaders',0 msgdone db 'You have saved the planet!',0 entername db 'Enter your name highscorer!',0 highscorefile db 'invaders.dat',0 points_50 db '5 pt',0 points_100 db '10 pt',0 points_150 db '15 pt',0 points_200 db '20 pt',0 points_250 db '25 pt',0 points_1000 db '100 pt',0 ship_x dd SHIP_X_POS enemy_x dd 0 enemy_y dd 0 enemy_d db 0 current_enemy_x dd 0 current_enemy_y dd 0 bullet_x dd 0 bullet_y dd 1 score dd 0 alldeadb db 0 status db 0 ; status: 0=menu 1=game 2=gameover 3=paused 4=about 5=highscorelist 6=levelup 7=highscore... menu db 0 ; menu: 0=start 1=about 2=highscores 3=exit... generator dd 0x45dd4d15 alien_x dd 0 ;drawroutine dd 0 returnaddr dd 0 intro dw 0 scoretext db 'score ' scorenumb db 0,0,0,0,0,0,0 leveltext db 'level ' levelnumb db 0,0,0 lives db 0 level db 1 enemy_speed db 1 namepos db 0 name db 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x0d,0x00 enemy_img_list: dd img_enemy1 dd img_enemy2 dd img_enemy3 dd img_enemy4 dd img_enemy5 gif_bullet file 'bullet2.gif' .size = $ - gif_bullet gif_bullet2 file 'bullet2.gif' .size = $ - gif_bullet2 gif_ship file 'ship.gif' .size = $ - gif_ship gif_enemy1 file 'enemy1.gif' .size = $ - gif_enemy1 gif_enemy2 file 'enemy2.gif' .size = $ - gif_enemy2 gif_enemy3 file 'enemy3.gif' .size = $ - gif_enemy3 gif_enemy4 file 'enemy4.gif' .size = $ - gif_enemy4 gif_enemy5 file 'enemy5.gif' .size = $ - gif_enemy5 gif_alien file 'alien.gif' .size = $ - gif_alien gif_menu1 file 'menu1.gif' .size = $ - gif_menu1 gif_menu2 file 'menu2.gif' .size = $ - gif_menu2 gif_menu3 file 'menu3.gif' .size = $ - gif_menu3 gif_menu4 file 'menu4.gif' .size = $ - gif_menu3 gif_logo file 'logo.gif' .size = $ - gif_logo gif_pause file 'pause.gif' .size = $ - gif_pause gif_highscore file 'highscores.gif' .size = $ - gif_highscore gif_smallfont file 'font_small.gif' .size = $ - gif_smallfont gif_bigfont file 'font_capital.gif' .size = $ - gif_bigfont gif_numbers file 'numbers.gif' .size = $ - gif_numbers gif_levelup file 'nextlevel.gif' .size = $ - gif_levelup gif_gameover file 'gameover.gif' .size = $ - gif_gameover align 16 @IMPORT: library \ libimg , 'libimg.obj' import libimg , \ libimg.init , 'lib_init' , \ img.decode , 'img_decode' , \ img.to_rgb2 , 'img_to_rgb2', \ img.destroy , 'img_destroy' vscreen: dd SCREEN_X dd SCREEN_Y rb SCREEN_X*SCREEN_Y*3 IM_END: STARS rb STARS_*5 img_bullet rb BULLET_X*BULLET_Y*3+8 img_bullet2 rb BULLET_X*BULLET_Y*3+8 img_ship rb SHIP_X*SHIP_Y*3+8 img_enemy1 rb ENEMY_X*ENEMY_Y*3+8 img_enemy2 rb ENEMY_X*ENEMY_Y*3+8 img_enemy3 rb ENEMY_X*ENEMY_Y*3+8 img_enemy4 rb ENEMY_X*ENEMY_Y*3+8 img_enemy5 rb ENEMY_X*ENEMY_Y*3+8 img_alien rb ALIEN_X*ALIEN_Y*3+8 img_menu1 rb 220*18*3+8 img_menu2 rb 135*18*3+8 img_menu3 rb 245*18*3+8 img_menu4 rb 110*18*3+8 img_logo rb 40*540*3+8 img_pause rb 40*320*3+8 img_levelup rb 40*320*3+8 img_gameover rb 40*320*3+8 img_highscore rb 40*530*3+8 img_smallfont rb 20*312*3+8 img_bigfont rb 28*520*3+8 img_numbers rb 16*200*3+8 img_char rb 28*20*3+8 img_alienpiece rb ALIEN_X*ALIEN_Y*3+8 highscorebuffer rb 1024 I_END: