36b358a358
git-svn-id: svn://kolibrios.org@950 a494cfbc-eb01-0410-851d-a64ba20cac60
1409 lines
25 KiB
NASM
1409 lines
25 KiB
NASM
;=============================================================================;
|
|
; 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'
|
|
|