0,0 → 1,711 |
LEVELCONV equ 10 |
SQ equ 8 |
FLDSIZE equ 49 |
FLDSIZE2 equ FLDSIZE*8 |
DELAY equ 20 |
TICKS equ 10 |
LEV_START equ 1 |
MOBILITY equ 9;13 |
|
use32 |
org 0x0 |
|
db 'MENUET01' ; 8 byte id |
dd 0x01 ; header version |
dd run ; start of code |
dd I_END ; size of image |
dd stak+0x400 ; memory for app |
dd stak+0x400 ; esp |
dd 0x0 , 0x0 ; I_Param , I_Icon |
include "lang.inc" |
include "MACROS.INC" |
;include "DEBUG.INC" |
|
run: |
if LEVELCONV eq 1 |
call compress_levels |
jmp close |
end if |
mcall 3 |
mov cl,16 |
ror eax,cl |
mov [generator],eax ; random generator from Tetris |
reset: |
mov [levptr],level |
mov [levnum],LEV_START |
if ~ LEV_START eq 1 |
mov ecx,[levnum] |
dec ecx |
mov esi,[levptr] |
jecxz start |
.lp: |
movzx eax,word[esi] |
and eax,0x7fff |
add esi,eax ; limit |
loop .lp |
mov [levptr],esi |
; sub esi,level |
; dpd esi |
end if |
start: |
mov ecx,[generator] |
and ecx,0xff |
.shuf: |
call random |
loop .shuf |
xor eax,eax |
and [locked],eax |
and [captured],eax |
mov [ticks],TICKS |
mov [mode],-1 |
mov ebx,FLDSIZE |
mov eax,[generator] |
xor edx,edx |
div ebx |
mov cl,dl |
call random |
mov eax,[generator] |
xor edx,edx |
div ebx |
mov ch,dl |
xchg eax,ecx |
movzx ecx,al |
imul cx,bx |
shr ax,8 |
add cx,ax |
mov esi,[levptr] |
mov [dot],ecx |
call decompress_level |
mov ebx,8 |
call nokey |
red: |
call draw_window |
; and [event],0 |
|
still: |
|
.flush: |
mcall 2 |
test al,al |
jz .flush |
|
mov ebx,DELAY |
mov eax,[levnum] |
shr eax,1 |
sub ebx,eax |
mov eax,23 |
cmp [mode],0 |
jl .wait |
mov eax,10 |
.wait: |
mcall |
.evt: |
mov ebx,8 |
test eax,eax |
jne .ev_yes |
dec [ticks] |
jne still |
; mov [ticks],TICKS |
; cmp al,[event] |
jmp key.ex |
; and [event],al |
; jmp still |
.ev_yes: |
cmp eax,2 |
je key |
cmp eax,1 ; redraw request ? |
je red |
cmp eax,3 ; button in buffer ? |
je button |
key: |
; mov [event],al |
mcall 2 |
cmp ah,13 |
je button.mode |
cmp ah,27 |
je button.mode |
cmp [mode],-1 |
jne still |
cmp ah,104 |
jne .nohelp |
mov [mode],4 |
jmp red |
.nohelp: |
cmp ah,112 |
jne .nopau |
mov [mode],3 |
jmp red |
.nopau: |
shr eax,8 |
; dpd eax |
cmp eax,' ' |
je .ex |
cmp eax,176 |
jb still |
cmp eax,179 |
ja still |
cmp [locked],0 |
jnz still |
lea ebx,[eax-176] |
.ex: |
mov [ticks],TICKS |
call nokey |
call evolution |
call red_field |
jmp still |
|
button: ; BUTTON - only close supported |
mcall 17 |
cmp ah,2 |
jne close |
mcall 8,,,2+1 shl 31 |
; mov [event],2 |
.mode: |
mov [ticks],TICKS |
mov al,[mode] |
cmp al,1 |
je reset |
cmp al,2 |
je reset |
mov [mode],-1 |
test al,al |
jnz .no0 |
inc [levnum] |
jmp start |
.no0: |
jmp red |
close: |
or eax,-1 |
int 0x40 |
|
; ********************************************* |
; ******* WINDOW DEFINITIONS AND DRAW ******** |
; ********************************************* |
draw_window: |
mov [ticks],TICKS |
mcall 12,1 |
mcall 0,<100,FLDSIZE2+16>,<100,FLDSIZE2+38>,0x04008000 |
mcall 4,<8,8>,0x10ffffff,header,header.size |
mov esi,ecx |
if lang eq ru |
mcall 47,0x20000,[levnum],<165,8> |
else |
mcall 47,0x20000,[levnum],<145,8> |
end if |
call red_field |
cmp [mode],0 |
jl .edraw |
mov ecx,(FLDSIZE2-20) shl 16+20 |
cmp [mode],4 |
jne .nohelp |
mov ecx,100 shl 16+FLDSIZE2-35-100+38 |
.nohelp: |
mcall 13,<5+8,FLDSIZE2-8>,,0xf5deb3;0xffff00 |
mcall 8,<FLDSIZE2-40,35>,<FLDSIZE2-18,15>,2,0xc0c000 |
mcall 4,<363,FLDSIZE2-20+6>,0x100000ff,msg_ok,2 |
mov ebx,(5+8+35)shl 16+FLDSIZE2-20+6 |
movzx ecx,[mode] |
mov edx,messages+4 |
cmp ecx,4 |
jne .nxt |
mov edx,desc+4 |
xor ecx,ecx |
mov ebx,20 shl 16+110 |
.nxt: |
mov esi,[edx-4] |
jecxz .drw |
dec ecx |
lea edx,[edx+esi+4] |
jmp .nxt |
.drw: |
cmp esi,-1 |
je .edraw |
mcall ,,0x000000ff |
mov ecx,1 |
add ebx,18 |
cmp [mode],4 |
je .nxt |
.edraw: |
mcall 12,2 |
ret |
|
red_field: |
mov edi,field |
mov ebp,28 shl 16+SQ ; y |
mov ecx,FLDSIZE |
.lp1: |
push ecx |
mov ecx,FLDSIZE |
mov ebx,8 shl 16+SQ ; x |
.lp2: |
push ecx |
mov edx,0x8000 |
cmp byte[edi],0 |
je .zero |
cmp byte[edi],2 |
jne .nored |
mov edx,0xff0000 |
cmp [locked],0 |
jz .zero |
mov edx,0xa00000 |
jmp .zero |
.nored: |
mov edx,0 |
.zero: |
mcall 13,,ebp |
inc edi |
pop ecx |
add ebx,8 shl 16 |
loop .lp2 |
pop ecx |
add ebp,8 shl 16 |
loop .lp1 |
|
mov eax,[dot] |
mov cl,FLDSIZE |
div cl |
|
; movzx ebx,ah |
; shl ebx,19 |
; add ebx,8 shl 16+7 |
; movzx ecx,al |
; shl ecx,19 |
; add ecx,28 shl 16+7 |
; push eax |
; mcall 13,,,0xff |
; pop eax |
|
movzx ebx,ah |
shl ebx,19 |
add ebx,8 shl 16 |
shld edx,ebx,16 |
add dx,SQ-1 |
mov bx,dx |
movzx ecx,al |
shl ecx,19 |
add ecx,28 shl 16 |
shld edx,ecx,16 |
add dx,SQ-1 |
mov cx,dx |
mcall 38,,,0xffffff |
ror ecx,16 |
mcall |
ret |
|
nokey: |
xor eax,eax |
mov edi,buff |
mov ecx,FLDSIZE*FLDSIZE+3 |
push ecx edi |
rep stosb |
pop edi |
;mov esi,field |
mov edi,field |
mov edx,FLDSIZE |
pop ecx |
.llp: |
mov eax,2 |
repne scasb |
jecxz .exx |
and byte[edi-1],0 |
push ecx |
lea eax,[edi-field-1] |
div dl |
call get_cell |
mov byte[buff+ecx],2 |
pop ecx |
loop .llp |
.exx: |
mov edi,field |
mov esi,buff |
mov ecx,FLDSIZE*FLDSIZE |
.lp4: |
lodsb |
cmp al,2 |
jne .skip3 |
mov [edi],al |
.skip3: |
inc edi |
loop .lp4 |
|
ret |
|
get_cell: |
; ax - source cell [x][y] |
; ebx - direction |
; 4 2 5 |
; 0 . 3 |
; 6 1 7 |
; out - ecx cell ptr |
|
push eax ebx |
add ax,[ebx*2+dirs] |
mov ebx,FLDSIZE |
.c0: |
cmp al,bl |
jb .c1 |
sub al,bl |
jmp .c0 |
.c1: |
cmp ah,bl |
jb .c2 |
sub ah,bl |
jmp .c1 |
.c2: |
movzx ecx,al |
imul cx,bx |
shr ax,8 |
add cx,ax |
pop ebx eax |
ret |
|
evolution: |
xor edi,edi |
and [locked],edi |
mov edx,FLDSIZE |
mov ecx,FLDSIZE*FLDSIZE |
.l1: |
push ecx |
mov eax,edi |
div dl |
mov ecx,8 |
xor ebx,ebx |
mov word[neib],bx ; neighbour count |
.l2: |
push ecx |
call get_cell |
movzx esi,byte[field+ecx] |
test esi,esi ; 0? |
jz .skip2 |
inc byte[neib-1+esi] |
.skip2: |
inc ebx |
pop ecx |
loop .l2 |
mov cl,[neib] |
add cl,[neib+1] |
cmp cl,2 |
jne .no2 |
mov al,[field+edi] |
jmp .writebuf |
.no2: |
xor al,al |
cmp cl,3 |
jne .writebuf |
inc al |
mov cl,[neib+1] |
cmp cl,[neib] |
jb .writebuf |
inc al |
.writebuf: |
mov [buff+edi],al |
pop ecx |
inc edi |
loop .l1 |
|
mov esi,buff |
mov edi,field |
mov ecx,FLDSIZE*FLDSIZE |
rep movsb |
call square_check |
call dot_move |
ret |
|
square_check: |
mov ecx,FLDSIZE*FLDSIZE+3 |
mov edx,FLDSIZE |
mov edi,field |
xor eax,eax |
pusha |
and dword[cells],eax |
and [locked],eax |
.nored: |
mov al,[edi] |
inc edi |
dec ecx |
jecxz .ex1 |
test al,al |
jz .nored |
inc [cells-2+eax*2] |
jmp .nored |
.ex1: |
mov ax,[cells+2] |
cmp ax,[cells] |
ja dot_move.next_lev |
cmp [cells+2],4 |
je .sq_check |
add esp,32 |
cmp [cells+2],0 |
jne .loc |
mov [mode],1 |
mov dword[esp+4],red |
.loc: |
inc [locked] |
ret |
.sq_check: |
popa |
.nored2: |
mov eax,2 |
repne scasb |
jecxz .loc |
lea eax,[edi-field-1] |
div dl |
xor dh,dh |
push ecx |
mov ebx,1 |
call get_cell |
add dh,[field+ecx] |
mov ebx,3 |
call get_cell |
add dh,[field+ecx] |
mov ebx,7 |
call get_cell |
add dh,[field+ecx] |
pop ecx |
cmp dh,6 |
jne .nored2 |
ret |
|
random: |
mov eax, [generator] |
sub eax,0x43ab45b5 ; next random number |
ror eax,1 |
xor eax,0x32c4324f |
ror eax,1 |
mov [generator],eax |
ret |
|
dot_move: |
call random |
mov eax,[generator] |
xor edx,edx |
mov ebx,MOBILITY |
div ebx |
cmp edx,8 |
jb .nostay |
mov edx,16 |
.nostay: |
mov ebx,edx |
shr ebx,1 |
mov eax,[dot] |
; dpd eax |
mov cl,FLDSIZE |
div cl |
call get_cell |
mov [dot],ecx |
cmp byte[field+ecx],2 |
jne .nocap |
inc [captured] |
cmp [captured],2 |
jne .ex |
.next_lev: |
mov [mode],0 |
pop eax |
mov eax,[levptr] |
cmp word[eax],0 |
jne .nxt |
mov [mode],2 |
.nxt: |
mov dword[esp],red |
ret |
.nocap: |
and [captured],0 |
.ex: |
ret |
|
if LEVELCONV eq 1 |
fileinfo: |
|
dd 2 |
dd 0x0 |
dd 0x0 |
.fsize dd 10000 |
.ptr dd 0x20000 |
db '/sys/newlev.bin',0 |
|
macro flush |
{ |
mov [edi],dh |
inc edi |
} |
|
compress_levels: |
mov esi,raw_level |
mov edi,I_END |
mov [fileinfo.ptr],edi |
mov ecx,(raw_level_size-raw_level)/(FLDSIZE*FLDSIZE*4) ; 19 |
.lp1: |
push ecx |
mov ecx,FLDSIZE*FLDSIZE |
mov ebx,edi |
mov eax,[esi] |
; movzx eax,byte[esi] |
movzx edx,al |
dpd edx |
shl eax,15 |
stosw |
.lp2: |
lodsd ;lodsb |
cmp al,0xd |
jne .nored |
flush |
xor al,al |
stosb |
add esi,4 |
dec ecx |
xor dh,dh |
jmp .eloop |
.nored: |
cmp al,dl |
jne .change |
inc dh |
cmp dh,0xff |
jb .eloop |
flush |
xor dh,dh |
jmp .eloop |
.change: |
flush |
xor dl,1 |
mov dh,1 |
.eloop: |
loop .lp2 |
flush |
mov eax,edi |
sub eax,ebx |
add [ebx],ax |
pop ecx |
loop .lp1 |
xor eax,eax |
stosw |
sub edi,I_END |
mov [fileinfo.fsize],edi |
mcall 70,fileinfo |
ret |
|
raw_level: |
file 'noname1.dat' |
raw_level_size: |
|
end if |
|
decompress_level: |
; esi - level begin |
mov edi,field |
movzx edx,word[esi] |
xor ecx,ecx |
mov eax,edx |
and edx,0x7fff |
add edx,esi ; limit |
mov [levptr],edx |
add esi,2 |
shr eax,15 |
.next: |
cmp esi,edx |
jae .exloop |
movzx ebx,byte[esi] |
inc esi |
test ebx,ebx |
jne .nored |
rep stosb |
xor al,1 |
mov word[edi],0x0202 |
add edi,2 |
jmp .next |
.nored: |
add ecx,ebx |
cmp ebx,0xff |
je .next |
rep stosb |
xor al,1 |
jmp .next |
.exloop: |
rep stosb |
ret |
|
; DATA AREA |
|
FS1 equ (FLDSIZE-1) |
dirs dw FS1 shl 8,\ |
1,\ |
FS1,\ |
1 shl 8,\ |
FS1 shl 8+FS1,\ |
1 shl 8+FS1,\ |
FS1 shl 8+1,\ |
1 shl 8+1,\ |
0 |
level: |
file 'rlevels.bin' |
|
msg_ok db 'OK' |
if lang eq ru |
header db 'Red Square - ஢¥ì h - ®¬®éì, p - 㧠' |
.size = $ - header |
messages mstr '⫨ç®! ë ¯¥à¥å®¤¨â¥ á«¥¤ãî騩 ã஢¥ì.',\ |
'à áë¥ ª«¥âª¨ ã¨ç⮦¥ë. ë ¯à®¨£à «¨.',\ |
'ë ¯à®è«¨ ¢á¥ ã஢¨. ®§¤à ¢«ï¥¬!',\ |
'£à ¯à¨®áâ ®¢«¥ ...' |
|
desc mstr ' ë ¨£à ¥â¥ ªà áë¬ ª¢ ¤à ⨪®¬. ¥«ì ¨£àë - ¢ë¦¨âì á।¨',\ |
'à §¢¨¢ îé¨åáï ç¥àëå ª«¥â®ª.
᫨ ¬ 㤠áâáï ¯®©¬ âì ¡¥«ë©',\ |
'ªà¥á⨪, ë ¯à®©¤¥â¥ ã஢¥ì.',\ |
' â®¡ë ¯®©¬ âì ¡¥«ë© ªà¥á⨪, ® ¤®«¦¥ ¡ëâì ªàëâ ®¤®©',\ |
'¨§ ªà áëå ª«¥â®ª ¯à®â殮¨¨ 2 ¯®ª®«¥¨© ¯®¤àï¤.',\ |
'
᫨ ªà áë© ª¢ ¤à â à §àãè¥, íâ® ¥é¥ ¥ ¯à®¨£àëè. ®¦¥â',\ |
'¡ëâì, ¬ ¯®¢¥§¥â ¨ ¥á«¨ ¢ ¯à®æ¥áá¥ í¢®«î樨 ª®«¨ç¥á⢮ è¨å',\ |
'ªà áëå ª«¥â®ª á⠥⠡®«ìè¥, 祬 ç¥àëå, ã஢¥ì ¡ã¤¥â',\ |
"¯à®©¤¥.",\ |
'---',\ |
'¦® ®àâ® ®ãí© ¨§®¡à¥« ¯à¥ªà áãî ¨£àã. ®ç⨠ª ¦¤ë©',\ |
'¯à®£à ¬¬¨áâ ç¨ ¥â á¢®î ¯à ªâ¨ªã á ¥¥. ¤ ª® ॠ«ìë¥',\ |
'¢®§¬®¦®á⨠í⮩ ¨£àë ¥é¥ ¯«®å® ¨§ãç¥ë.',\ |
'---',\ |
'ਣ¨ « ¨£àë ¯®¤ Win32 ¯¨á « « ¤¨¬¨à ਢ «®¢, 2002',\ |
' ¯à®£à ¬¬¨à®¢ « áᥬ¡«¥à¥ Willow, 2005' |
else |
header db 'Red Square - Level h - Help, p - Pause' |
.size = $ - header |
messages mstr 'Well done! You are on the next level',\ |
'Your red cells are vanished! Game over.',\ |
"You've completed the game. Congratulations!",\ |
'Game paused...' |
|
desc mstr ' The main goal of the game for your red square is to stay',\ |
'alive going through the evolving black cells. If you manage to',\ |
'catch the white cross, you will pass the level.',\ |
' To catch the white cross, it must be covered by red cell',\ |
'during 2 generations.',\ |
" If your red square is corrupted, you haven't lost yet. You",\ |
'may have a luck, and if your red cells is developing and the',\ |
'quantity of black cells is bigger than that of black cells,',\ |
"you'll pass the level.",\ |
'---',\ |
'John Horton Conway has created a great game. Almost every',\ |
'programmer begins his professional work from it. But the real',\ |
'possibilities of this game have not discovered yet.',\ |
'---',\ |
'Original game under Win32 by Vladimir Privalov, 2002',\ |
'Programmed in assembly by Willow, 2005' |
end if |
I_END: |
neib db ?,? |
cells dw ?,? |
mode db ? |
levptr dd ? |
levnum dd ? |
reds dd ? |
locked dd ? |
generator dd ? |
dot dd ? |
ticks dd ? |
captured dd ? |
if LEVELCONV eq 1 |
os_work rb 4096 |
end if |
field: |
rb FLDSIZE*FLDSIZE |
rd 1 |
buff: |
rb FLDSIZE*FLDSIZE |
stak: |