Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 949 → Rev 950

/programs/games/invaders/invaders.asm
0,0 → 1,1408
;=============================================================================;
; Hidnplayr's invaders, Compilable for DexOs and Kolibrios ;
;-----------------------------------------------------------------------------;
; ;
; Copyright (C) hidnplayr 2007. 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 ;
; ;
;-----------------------------------------------------------------------------;
 
 
SCREEN_X equ 640
SCREEN_Y equ 480
 
SHIP_X equ 32
SHIP_Y equ 32
 
SHIP_X_POS equ (SCREEN_X-SHIP_X)/2
SHIP_Y_POS equ SCREEN_Y-SHIP_Y-27
 
ENEMY_X equ 32
ENEMY_Y equ 32
 
ALIEN_X equ 48
ALIEN_Y equ 38
ALIEN_Y_POS equ 1
 
BOUNDARY equ 10
MOVEMENT equ 7
 
TRANSPARENCY equ 0x00000000
 
WINDOW_X equ 100
WINDOW_Y equ 100
 
BULLET_X equ 10
BULLET_Y equ 10
 
STARS_ equ 226
STARLEVELS equ 3
 
ENEMY_STARTING_X equ 25
ENEMY_STARTING_Y equ 50
 
BULLETSPEED equ 12
 
SCREEN_X_POS equ 5
SCREEN_Y_POS equ 25
 
gif_hash_offset = gif_hash_area
 
include 'ascgl.inc'
include 'invaders_kolibri.inc'
 
decodegif:
giftoimg gif_bullet,bullet
giftoimg gif_bullet2,bullet2
giftoimg gif_ship,ship
giftoimg gif_enemy1,enemy1
giftoimg gif_enemy2,enemy2
giftoimg gif_enemy3,enemy3
giftoimg gif_enemy4,enemy4
giftoimg gif_enemy5,enemy5
giftoimg gif_alien,alien
giftoimg gif_menu1,menu1
giftoimg gif_menu2,menu2
giftoimg gif_menu3,menu3
giftoimg gif_menu4,menu4
giftoimg gif_logo,logo
giftoimg gif_pause,pause_
giftoimg gif_levelup,levelup
giftoimg gif_gameover,gameover
giftoimg gif_highscore,highscore
giftoimg gif_smallfont,smallfont
giftoimg gif_bigfont,bigfont
giftoimg gif_numbers,numbers
 
call createstars
call drawit
call [drawroutine]
 
mainloop:
 
cmp byte[status],3 ; if game is paused,...
je waitfordraw
 
call drawit
call [drawroutine]
call checkbullet
 
waitfordraw:
 
call waitandgetkey ;;;
test ah,ah
jz mainloop
 
cmp byte[status],1 ;
jne nogame
 
cmp ah, KEY_RIGHT
jnz noright
cmp dword[ship_x],SCREEN_X-SHIP_X-BOUNDARY
jge mainloop
add dword[ship_x],MOVEMENT
 
jmp mainloop
 
noright:
cmp ah, KEY_LEFT
jnz noleft
cmp dword[ship_x],BOUNDARY
jle mainloop
sub dword[ship_x],MOVEMENT
 
jmp mainloop
 
noleft:
cmp ah, KEY_UP
jnz noup
 
cmp dword[bullet_y],1
jg mainloop
 
mov eax,dword[ship_x]
add eax,(SHIP_X-BULLET_X)/2
mov dword[bullet_x],eax
mov dword[bullet_y],SHIP_Y_POS;-BULLET_Y
 
jmp mainloop
 
noup:
cmp ah,KEY_P
jnz no_pause1
 
mov byte[status],3
aimgtoimg pause_,150,180,vscreen,TRANSPARENCY,0
call [drawroutine]
 
jmp mainloop
 
no_pause1:
 
nogame:
cmp byte[status],0
jne nomenu
 
cmp ah, KEY_DOWN
jnz no_down
 
cmp byte[menu],3
jne no_menu1
 
mov byte[menu],0
jmp nomenu
 
no_menu1:
inc byte[menu]
 
no_down:
cmp ah, KEY_UP
jnz no_up
 
cmp byte[menu],0
jne no_menu0
 
mov byte[menu],3
jmp nomenu
 
no_menu0:
dec byte[menu]
 
no_up:
 
cmp ah, KEY_ESC
je exit
 
no_esc:
cmp ah, KEY_ENTER
jnz no_enter
 
exemenu:
cmp byte[menu],0 ;start
jne exemenu1
 
new_game:
mov dword[score],0
mov eax,[score]
call convertscore
 
mov esi, level1
mov word[levelnumb],'01'
load_level:
mov byte[enemy_speed],1
mov dword[enemy_x], ENEMY_STARTING_X
mov dword[enemy_y], ENEMY_STARTING_Y
 
mov edi, enemy_table
mov ecx, 5
rep movsd
 
mov byte[status],1
 
jmp mainloop
 
exemenu1:
cmp byte[menu],1 ;about
jne exemenu2
mov byte[status],4
jmp mainloop
 
exemenu2:
cmp byte[menu],2 ;highscores
jne exemenu3
mov byte[status],5
call load_highscores
jmp mainloop
 
exemenu3:
cmp byte[menu],3 ;exit
je exit
 
no_enter:
nomenu:
cmp byte[status],3
jne nopause
 
cmp ah, KEY_P
jnz nopause
 
mov byte[status],1
 
nopause:
cmp byte[status],6
jne nolevelup
 
cmp ah, KEY_ENTER
jne nolevelup
 
inc byte[level]
 
; cmp byte[level],5
; jne @f
; mov byte[level],0
 
;@@:
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
 
nolevelup:
cmp byte[status],7
jne nohighscore
 
cmp ah, KEY_ENTER
jne @f
 
call load_highscores
mov eax,dword[score]
mov ebx,gif_hash_area+140
.findscore:
cmp ebx,gif_hash_area+100
je .topscore
sub ebx,4
cmp eax,dword[ebx]
jg .findscore
 
.topscore:
mov esi,name
mov edi,gif_hash_area
mov ecx,10
rep movsb
 
mov eax,dword[score]
mov dword[gif_hash_area+100],eax
 
call save_highscores
mov byte[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 nohighscore
 
cmp al,'0'
jl nohighscore
cmp al,'9'
jle @f
 
cmp al,'z'
jg nohighscore
cmp al,'a'
jge @f
 
cmp al,'Z'
jg nohighscore
cmp al,'A'
jl nohighscore
@@:
 
movzx ebx,byte[namepos]
add ebx,name
mov byte[ebx],al
 
inc byte[namepos]
 
jmp mainloop
 
nohighscore:
cmp byte[status],2 ; gameover
jne nogameover
 
cmp ah, KEY_ENTER
jne nogameover
 
; test if score is high enough to put in highscore list...
mov byte[status],7
 
jmp mainloop
 
nogameover:
cmp byte[status],0
je mainloop
 
cmp ah, KEY_ESC
jnz mainloop
 
mov byte[status],0
mov word[intro],0
 
jmp mainloop
 
;----------------------------------------------------;
; Drawing routine: create image in buffer ;
;----------------------------------------------------;
drawit:
mov eax,0x00000000
call fillscreen
call drawstars
 
cmp byte[status],1
jne @f
 
call drawbullet
call drawenemys ; Draw the enemy's to buffer
aimgtoimg ship,dword[ship_x],SHIP_Y_POS,vscreen,TRANSPARENCY,0 ; 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
 
@@:
cmp byte[status],2 ; game over, dude !
jne @f
 
aimgtoimg ship,dword[ship_x],SHIP_Y_POS,vscreen,TRANSPARENCY,0 ; 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
aimgtoimg gameover,150,180,vscreen,TRANSPARENCY,0
 
ret
 
@@:
cmp byte[status],4 ; about screen
jne @f
 
mov esi,msgAbout
mov ebx,50
mov ecx,100
call printtext
 
ret
 
@@:
cmp byte[status],6 ; level up!
jne @f
aimgtoimg ship,dword[ship_x],SHIP_Y_POS,vscreen,TRANSPARENCY,0 ; 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
aimgtoimg levelup,150,180,vscreen,TRANSPARENCY,0
 
ret
 
@@:
cmp byte[status],0 ; menu!
jne @f
 
aimgtoimg logo,50,80,vscreen,TRANSPARENCY,0
 
 
cmp byte[menu],0
jne .menu_0
aimgtoimg menu1,30,200,vscreen,TRANSPARENCY,1
jmp .menu_1
.menu_0:
aimgtoimg menu1,30,200,vscreen,TRANSPARENCY,0
.menu_1:
cmp byte[menu],1
jne .menu_2
aimgtoimg menu2,80,250,vscreen,TRANSPARENCY,1
jmp .menu_3
.menu_2:
aimgtoimg menu2,80,250,vscreen,TRANSPARENCY,0
.menu_3:
cmp byte[menu],2
jne .menu_4
aimgtoimg menu3,120,300,vscreen,TRANSPARENCY,1
jmp .menu_5
.menu_4:
aimgtoimg menu3,120,300,vscreen,TRANSPARENCY,0
.menu_5:
cmp byte[menu],3
jne .menu_6
aimgtoimg menu4,150,350,vscreen,TRANSPARENCY,1
jmp .menu_7
.menu_6:
aimgtoimg menu4,150,350,vscreen,TRANSPARENCY,0
.menu_7:
 
cmp word[intro],200
je .menu_75
inc word[intro]
 
.menu_75:
cmp word[intro],0
jl .menu_8
aimgtoimg enemy1,390,180,vscreen,TRANSPARENCY,0
 
cmp word[intro],15
jl .menu_8
mov esi,points_50
mov ebx,470
mov ecx,180
call printtext
 
cmp word[intro],30
jl .menu_8
aimgtoimg enemy2,390,220,vscreen,TRANSPARENCY,0
 
cmp word[intro],45
jl .menu_8
mov esi,points_100
mov ebx,450
mov ecx,220
call printtext
 
cmp word[intro],60
jl .menu_8
aimgtoimg enemy3,390,260,vscreen,TRANSPARENCY,0
 
cmp word[intro],75
jl .menu_8
mov esi,points_150
mov ebx,450
mov ecx,260
call printtext
 
cmp word[intro],90
jl .menu_8
aimgtoimg enemy4,390,300,vscreen,TRANSPARENCY,0
 
cmp word[intro],105
jl .menu_8
mov esi,points_200
mov ebx,450
mov ecx,300
call printtext
 
cmp word[intro],120
jl .menu_8
aimgtoimg enemy5,390,340,vscreen,TRANSPARENCY,0
 
cmp word[intro],135
jl .menu_8
mov esi,points_250
mov ebx,450
mov ecx,340
call printtext
 
cmp word[intro],150
jl .menu_8
aimgtoimg alien,380,380,vscreen,TRANSPARENCY,0
 
cmp word[intro],165
jl .menu_8
mov esi,points_1000
mov ebx,430
mov ecx,380
call printtext
 
.menu_8:
ret
@@:
cmp byte[status],5 ;highscorelist
jne @f
 
aimgtoimg highscore,60,40,vscreen,TRANSPARENCY,0
 
mov ebx,100 ; print names
mov ecx,120
mov esi,gif_hash_area
call printtext
 
mov edi,gif_hash_area+100 ; print scores
mov esi,scorenumb
mov ebx,420
mov ecx,120
 
.highscoreloop:
mov eax,[edi]
push ecx
call convertscore
pop ecx
push esi
call printtext
pop esi
add ecx,26
add edi,4
cmp edi,gif_hash_area+140
jl .highscoreloop
 
@@:
cmp byte[status],7 ;highscore
jne @f
 
aimgtoimg highscore,60,40,vscreen,TRANSPARENCY,0
 
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
 
 
drawenemys:
; check if direction should change
test byte[enemy_d],2
jz @f
 
add dword[enemy_y],5
 
mov eax,[enemy_y]
shr eax,5
add al, byte[level]
mov byte[enemy_speed],al
 
and byte[enemy_d],1
 
@@:
; move the aliens to left or right
movzx eax,byte[enemy_speed]
test byte[enemy_d],1
jz other_dir
 
sub dword[enemy_x],eax
jmp no_other_dir
 
other_dir:
add dword[enemy_x],eax
no_other_dir:
 
; initialization
mov byte[alldeadb],1
mov edi,enemy_table
mov eax,dword[enemy_x]
mov dword[current_enemy_x],eax
mov eax,dword[enemy_y]
mov dword[current_enemy_y],eax
 
loopit:
cmp byte[edi],1
je drawenemy1
 
cmp byte[edi],2
je drawenemy2
 
cmp byte[edi],3
je drawenemy3
 
cmp byte[edi],4
je drawenemy4
 
cmp byte[edi],5
je drawenemy5
 
jmp dead_alien
 
drawenemy1:
mov byte[alldeadb],0
pusha
aimgtoimg enemy1,dword[current_enemy_x],dword[current_enemy_y],vscreen,TRANSPARENCY,0
popa
 
jmp checknext
 
drawenemy2:
mov byte[alldeadb],0
pusha
aimgtoimg enemy2,dword[current_enemy_x],dword[current_enemy_y],vscreen,TRANSPARENCY,0
popa
 
jmp checknext
 
drawenemy3:
mov byte[alldeadb],0
pusha
aimgtoimg enemy3,dword[current_enemy_x],dword[current_enemy_y],vscreen,TRANSPARENCY,0
popa
 
jmp checknext
 
drawenemy4:
mov byte[alldeadb],0
pusha
aimgtoimg enemy4,dword[current_enemy_x],dword[current_enemy_y],vscreen,TRANSPARENCY,0
popa
 
jmp checknext
 
drawenemy5:
mov byte[alldeadb],0
pusha
aimgtoimg enemy5,dword[current_enemy_x],dword[current_enemy_y],vscreen,TRANSPARENCY,0
popa
 
; jmp checknext
 
checknext:
cmp byte[enemy_d],2
jge dont_change_dir
 
movzx eax,byte[enemy_speed]
 
cmp byte[enemy_d],0
jbe change_dir
 
cmp dword[current_enemy_x],eax
jg dont_change_dir
 
mov byte[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 byte[enemy_d],3
 
dont_change_dir:
cmp dword[current_enemy_y],SHIP_Y_POS-ENEMY_Y-BOUNDARY
je gameover_
 
dead_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 dword[current_enemy_x],5*(ENEMY_X+BOUNDARY)
add dword[current_enemy_y],ENEMY_Y+BOUNDARY
no_newline:
jmp loopit
 
alldead:
cmp byte[alldeadb],0
je enemy_end
 
mov byte[status],6
jmp mainloop
 
enemy_end:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
cmp dword[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 dword [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
@@:
 
getimg alien,0,0,10,ALIEN_Y,alienpiece
aimgtoimg alien,dword [alien_x],ALIEN_Y_POS,vscreen,TRANSPARENCY,0
sub dword[alien_x],5 ;
;
pop eax ;
;
alien_end: ;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ret
 
drawbullet:
cmp dword[bullet_y],BULLETSPEED
jl nobullet
sub dword[bullet_y],BULLETSPEED
 
aimgtoimg bullet,dword[bullet_x],dword[bullet_y],vscreen,TRANSPARENCY,0
 
nobullet:
ret
 
checkbullet:
cmp dword[bullet_y],BULLETSPEED ; does the bullet hit top of the screen?
jle hidebullet ; yes, hide bullet
 
; ; check if bullet is inside the enemy field (you can disble this if you want)
; mov eax,dword[enemy_y]
; cmp dword[bullet_y],eax
; jl nohit
;
; add eax,4*(ENEMY_Y+BOUNDARY)
; cmp dword[bullet_y],eax
; jg nohit
;
; mov eax,dword[enemy_x]
; cmp dword[bullet_x],eax
; jl nohit
;
; add eax,5*(ENEMY_Y+BOUNDARY)
; cmp dword[bullet_x],eax
; jg nohit
;
mov edi,enemy_table
mov eax,dword[enemy_x]
mov dword[current_enemy_x],eax
mov eax,dword[enemy_y]
mov dword[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,dword[current_enemy_y] ; move the enemy y position into eax
cmp dword[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 dword[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,dword[current_enemy_x] ; now do the same but for the x positions
cmp dword[bullet_x],eax ;
jl nextcheck ;
;
add eax,ENEMY_Y ;
cmp dword[bullet_x],eax ;
jg nextcheck ;
 
jmp hit
 
nextcheck:
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 dword[current_enemy_x],5*(ENEMY_X+BOUNDARY)
add dword[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 dword[score],ebx ; add this number to the score dword
 
mov eax,[score]
call convertscore
 
mov byte[edi],0 ; hide the enemy
hidebullet:
mov dword[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 dword[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
 
loadbyte:
movzx eax, byte[esi]
test eax, eax
jnz checkbyte
 
pop ebx
 
ret
 
checkbyte:
cmp al,13
je nextline
cmp al,' '
je space
 
cmp al,'0'
jl nextchar
cmp al,'9'
jle usenumbers
 
cmp al,'z'
jg nextchar
cmp al,'a'
jge usesmallfont
 
cmp al,'Z'
jg nextchar
cmp al,'A'
jge usebigfont
 
jmp nextchar
 
 
usesmallfont:
mov edx,eax
sub edx,'a'
mov eax,12
mul edx
mov edx,eax
 
pusha
getimg smallfont,0,edx,20,12,char
popa
 
pusha
add ecx,4
aimgtoimg char,ebx,ecx,vscreen,TRANSPARENCY,0
popa
 
add ebx,20
 
jmp nextchar
 
usebigfont:
mov edx,eax
sub edx,'A'
mov eax,20
mul edx
mov edx,eax
 
pusha
getimg bigfont,0,edx,28,20,char
popa
 
pusha
aimgtoimg char,ebx,ecx,vscreen,TRANSPARENCY,0
popa
 
add ebx,28
 
jmp nextchar
 
usenumbers:
mov edx,eax
sub edx,'0'
mov eax,20
mul edx
mov edx,eax
 
pusha
getimg numbers,0,edx,16,20,char
popa
 
pusha
aimgtoimg char,ebx,ecx,vscreen,TRANSPARENCY,0
popa
 
add ebx,20
 
jmp nextchar
 
space:
add ebx,20
 
nextchar:
inc esi
 
jmp loadbyte
 
nextline:
pop ebx
push ebx
add ecx,26
inc esi
 
jmp loadbyte
 
gameover_:
mov byte[status],2
 
ret
 
 
drawstars:
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
 
 
createstars:
 
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
 
 
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
 
 
msg1 db 'Vesa mode not supported',13,'Press any key to exit.',13,0
msgAbout db 'Hidnplayrs invaders',13,'DexOS version',13,13,'released under GPL',13,'make this game better',13,'if you want to',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
 
 
gif_bullet file 'bullet2.gif'
rb 4
 
gif_bullet2 file 'bullet2.gif'
rb 4
 
gif_ship file 'ship.gif'
rb 4
 
gif_enemy1 file 'enemy1.gif'
rb 4
 
gif_enemy2 file 'enemy2.gif'
rb 4
 
gif_enemy3 file 'enemy3.gif'
rb 4
 
gif_enemy4 file 'enemy4.gif'
rb 4
 
gif_enemy5 file 'enemy5.gif'
rb 4
 
gif_alien file 'alien.gif'
rb 4
 
gif_menu1 file 'menu1.gif'
rb 4
 
gif_menu2 file 'menu2.gif'
rb 4
 
gif_menu3 file 'menu3.gif'
rb 4
 
gif_menu4 file 'menu4.gif'
rb 4
 
gif_logo file 'logo.gif'
rb 4
 
gif_pause file 'pause.gif'
rb 4
 
gif_highscore file 'highscores.gif'
rb 4
 
gif_smallfont file 'font_small.gif'
rb 4
 
gif_bigfont file 'font_capital.gif'
rb 4
 
gif_numbers file 'numbers.gif'
rb 4
 
gif_levelup file 'nextlevel.gif'
rb 4
 
gif_gameover file 'gameover.gif'
rb 4
 
vscreen:
dd SCREEN_X
dd SCREEN_Y
rb SCREEN_X*SCREEN_Y*3+10
 
IM_END:
 
STARS:
rb STARS_*5
 
bullet:
rb BULLET_X*BULLET_Y*3+8+10
 
bullet2:
rb BULLET_X*BULLET_Y*3+8+10
 
ship:
rb SHIP_X*SHIP_Y*3+10
 
enemy1:
rb ENEMY_X*ENEMY_Y*3+10
 
enemy2:
rb ENEMY_X*ENEMY_Y*3+10
 
enemy3:
rb ENEMY_X*ENEMY_Y*3+10
 
enemy4:
rb ENEMY_X*ENEMY_Y*3+10
 
enemy5:
rb ENEMY_X*ENEMY_Y*3+10
 
alien:
rb ALIEN_X*ALIEN_Y*3+10
 
menu1:
rb 220*18*3+10
 
menu2:
rb 135*18*3+10
 
menu3:
rb 245*18*3+10
 
menu4:
rb 110*18*3+10
 
logo:
rb 40*540*3+10
 
pause_:
rb 40*320*3+10
 
levelup:
rb 40*320*3+10
 
gameover:
rb 40*320*3+10
 
highscore:
rb 40*530*3+10
 
smallfont:
rb 20*312*3+10
 
bigfont:
rb 28*520*3+10
 
numbers:
rb 16*200*3+10
 
char:
rb 28*20*3+20 ; biggest char's are 28x20
 
alienpiece:
rb ALIEN_X*ALIEN_Y*3+20
 
gif_hash_area:
rd 4096+1 ;hash area size for unpacking GIF
 
I_END:
 
;include 'dex.inc'