Subversion Repositories Kolibri OS

Compare Revisions

No changes between revisions

Regard whitespace Rev 108 → Rev 109

/programs/games/15/trunk/15.ASM
0,0 → 1,489
;
; The famous game 15
; Author: Lloyd, coded by Ivushkin Andrey
; Compile with FASM
;
include 'lang.inc'
include 'macros.inc' ; decreases program size (not required)
 
BgdColor equ 0x02aabbcc
StatusColor equ 0x02ffffff
StatusColor2 equ 0x02dc1e14
BgdColor equ 0x03aabbcc
 
; Main window dimensions
XXwindow equ 200 shl 16+276
YYwindow equ 200 shl 16+300
; Status bar
XYstatus equ 35 shl 16+283
XXbar equ 35 shl 16+136
YYbar equ 280 shl 16+15
; Buttons
BtnTop equ 28
BtnLeft equ 13
BtnSize equ 60
BtnColor equ 0xafbb55
BtnColor2 equ 0x0228c314
 
NumColor equ 0x10000000
; Number shifting for nice look
NumShift equ 24 shl 16+27
NumShift2 equ 4 shl 16
; Shuffle button
XXSh equ 202 shl 16+60
YYSh equ 280 shl 16+12
XYShText equ 212 shl 16+283
 
; Conf button
XXCnf equ 13 shl 16+13
YYCnf equ 280 shl 16+12
XYCnfText equ 18 shl 16+283
 
; Position of the 'hole'
null equ (curconf+16)
; Amount of moves to perform shuffle
SH_CYCLES equ 400
; (Amount of tasks)-1
CONF_COUNT equ 2
 
use32
 
org 0x0
 
db 'MENUET01'
dd 0x01
dd START
dd I_END
dd 0x2000 ; 8 Kb
dd 0x2000
dd 0x0
dd 0x0
 
 
START:
mov [cptr],CONF_COUNT ; number of task
mov eax,3
int 0x40
mov cl,16
ror eax,cl
mov [generator],eax ; random generator from Tetris
init:
mov ecx,17
movzx eax,[cptr]
inc eax
cmp eax,CONF_COUNT
jna init_ok
xor eax,eax ; cycling 0..CONF_COUNT
init_ok:
mov [cptr],al
mov esi,eax
shl esi,4
add esi,conf
add esi,eax
add al,0x31
mov [lenTitle-1],al ;task number to program title
mov [task],esi
mov edi,curconf
rep movsb ; initial configuration
 
mov [sts],4
jmp red
SHUF:
call shuffle ; immediate shuffle
red: ; window redraw
 
call draw_window
 
still: ; MAIN PROGRAM CYCLE
 
mov eax,10 ; wait for event
int 0x40
 
cmp eax,1 ; redraw? -
je red ; goto red
cmp eax,2 ; key pressed? -
je key ; goto key
cmp eax,3 ; button pressed? -
je button ; goto button
 
jmp still ; no more events to process
 
key: ; Key pressed
mov eax,2
int 0x40
shr eax,8
cmp eax,32 ; <Space> = Shuffle
je SHUF
cmp eax,13 ; <Enter> = Choose task
je init
cmp eax,176
jl still
sub eax,176
cmp eax,3
ja still
movzx eax,byte [eax+correct] ; 'delta' value from correct[]
jmp m_check
 
button: ; Button pressed
mov eax,17
int 0x40
shr eax,8
sub eax,2
 
cmp eax,-1 ; id == 1 (closeme)?
jne noclose
int 0x40
 
noclose:
jl SHUF ; Shuffle (id=0) pressed
cmp eax,18
je init ; Conf button pressed
sub al,byte [null]
mov edi,correct
mov ecx,4
repne scasb ; checking for valid move-part 1
jne fail
m_check:
cmp byte[sts],4 ; puzzle completed, blocking buttons
ja still
call move_check ; checking for valid move-part 2
jnc fail
inc [move_count]
call draw_moves
fail:
jmp still ; ¢®§¢à é ¥¬áï
 
; *******************************
; ******* WINDOW DRAWING *******
; *******************************
 
draw_window:
mov eax,12
mov ebx,1 ; begin draw
int 0x40
 
; CREATING WINDOW
mov eax,0
mov ebx,XXwindow
mov ecx,YYwindow
mov edx,BgdColor
mov esi,0x805080d0
mov edi,0x005080d0
int 0x40
 
; PROGRAM TITLE
mov eax,4
mov ebx,8*65536+8
mov ecx,0x10ddeeff
mov edx,txtTitle
mov esi,lenTitle-txtTitle
int 0x40
 
mov eax,8 ; SHUFFLE BUTTON
mov ebx,XXSh
mov ecx,YYSh
xor edx,edx
mov esi,BtnColor
int 0x40
 
mov ebx,XXCnf ; CONF BUTTON
mov ecx,YYCnf
mov edx,20
mov esi,BtnColor
int 0x40
 
mov ebx, XYShText ; SHUFFLE TEXT
mov ecx, StatusColor
mov edx,txtSh
mov esi,lenSh-txtSh
mov eax,4
int 0x40
 
mov ebx, XYCnfText ; CONF TEXT
mov edx,lenVictory-1
mov esi,1
int 0x40
 
mov ecx, 16 ; FIELD BUTTONS
dbut:
call draw_button
loop dbut
 
call draw_moves
 
mov eax,12
mov ebx,2 ; end of drawing
int 0x40
ret
 
 
; *********************************************
; ******* DRAWING A FIELD BUTTON **************
; *********************************************
; ECX - button number
 
draw_button:
pusha
dec ecx
; calculating button dimensions
mov edi, ecx
lea edx,[ecx+2]
mov ebx,ecx
and ebx,11b
shr ecx,2
 
imul ebx,BtnSize+3
add ebx,BtnLeft
shl ebx,16
add ebx,BtnSize
 
imul ecx,BtnSize+3
add ecx,BtnTop
shl ecx,16
add ecx,BtnSize
movzx eax,byte [null]
cmp eax,edi
jne no_hole
 
pusha
inc ebx
inc ecx
mov edx,BgdColor
mov eax,13 ; clearing - 'hole'
int 0x40
popa
 
or edx,0x80000000 ; and removing button under it
no_hole:
mov al,byte[edi+curconf]
mov esi,[task]
cmp al,byte[edi+esi]
je highlight
mov esi,BtnColor
jmp s_rbutton
highlight:
mov esi,BtnColor2
s_rbutton:
mov eax,8 ; set/remove button
int 0x40
movzx eax,byte [null]
cmp eax,edi
je no_text ; no digits - that's hole
mov edx,ebx
shr ecx,16
mov dx,cx
add edx,NumShift
mov ebx,0x20000
movzx ecx,byte [edi+curconf]
cmp ecx,9
ja two_num
add edx,NumShift2 ; shift to center digits
sub ebx,0x10000
two_num:
mov esi,NumColor
mov eax,47
int 0x40
no_text:
popa
ret
 
 
; *********************************************
; ******* DRAWING STATUS LINE *****************
; *********************************************
 
draw_moves:
mov eax, 13 ; clear area
mov ebx, XXbar
mov ecx, YYbar
mov edx, BgdColor
int 0x40
 
mov eax, 4
mov ebx, XYstatus
mov ecx, StatusColor
cmp ax, [sts]
jl report_victory
jne report_moves
mov edx,txtCnf ; prompt to choose configuration
mov esi,lenCnf-txtCnf
jmp e_dm
report_moves:
mov edx,txtMoves ; how many moves done
mov esi,lenMoves-txtMoves
mov eax,4
int 0x40
mov esi,ecx
mov edx,ebx
add edx, 40 shl 16
mov ebx,0x030000
movzx ecx, byte[move_count]
mov eax,47
jmp e_dm
report_victory: ; puzzle completed
mov ecx,StatusColor2
mov edx,txtVictory
mov esi,lenVictory-txtVictory
e_dm:
int 0x40
ret
 
 
; *********************************************
; ********* SHUFFLE ***************************
; *********************************************
 
shuffle:
xor eax,eax
mov [sts],ax
mov [move_count],ax ; reset moves to 0
mov [sh_off],al
mov eax, [generator]
 
mov ecx,SH_CYCLES
sh_cycle:
sub eax,0x43ab45b5 ; next random number
ror eax,1
xor eax,0x32c4324f
ror eax,1
mov [generator],eax
 
push eax
and eax,11b ; direction 0..3
movzx eax,byte [eax+correct]
call move_check
pop eax
jnc sh_cycle ; if fails then retry
loop sh_cycle
inc byte[sh_off] ; shuffling complete
ret
 
 
; *********************************************
; ********* MOVE VALIDITY CHECK ***************
; *********************************************
; AL - 'DELTA' DIRECTION
 
move_check:
pusha
mov ah,byte [null]
mov bx,ax
cmp bh,3
ja no_top
cmp al,-4 ; top of field
je no_move
no_top:
cmp bh,12
jb no_bottom
cmp al,4 ; bottom of field
je no_move
no_bottom:
and bh,11b
cmp bh,0
jnz no_left
cmp al,-1 ; left of field
je no_move
no_left:
cmp bh,11b
jnz ok
cmp al,1 ; right of field
je no_move
ok:
mov bx,ax
add bh,bl ; bh-new hole
mov byte [null],bh
movzx ecx,ah
mov al,byte[ecx+curconf]
movzx edx,bh
mov bl,byte[edx+curconf] ; swapping button & hole
mov byte[ecx+curconf],bl
mov byte[edx+curconf],al
 
cmp byte[sh_off],0 ; if shuffle in progress,
jz no_win ; then no redraw
 
; drawing button & hole
inc ecx
call draw_button
movzx ecx,bh
inc ecx
call draw_button
; testing if task completed
mov esi,[task]
mov edi,curconf
mov ecx,16
repe cmpsb
cmp ecx,0
jne no_win
mov word[sts],6 ; puzzle done. Victory!
no_win:
popa
stc
ret
no_move:
popa
clc
ret
; this is deprecated debug routine
;ud:
; ud2
 
; These are data used by program
 
correct db 1,-4,4,-1
 
conf db 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,0,15
db 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,0
db 1,2,3,4,12,13,14,5,11,0,15,6,10,9,8,7,9
 
txtMoves:
if lang eq ru
db '•®¤®¢:'
else
db 'Moves:'
end if
lenMoves:
 
txtSh:
if lang eq ru
db '’ á®¢ª '
else
db 'Shuffle'
end if
lenSh:
 
txtCnf:
if lang eq ru
db '‚ë¡¥à¨â¥ § ¤ çã ¨ ­ ¦¬¨â¥->'
else
db 'Select task, then press ->'
end if
lenCnf:
 
txtTitle: ; áâப  § £®«®¢ª 
if lang eq ru
db 'ˆ£à  15 - § ¤ ç  X'
else
db 'Game 15 - puzzle X'
end if
lenTitle: ; ¨ ¥ñ ª®­¥æ
 
txtVictory:
if lang eq ru
db '‚ë à¥è¨«¨ § ¤ çã!  ¦¬¨â¥->'
else
db 'Puzzle completed! Press->'
end if
lenVictory:
 
arrow equ lenVictory-2
 
I_END: ; ª®­¥æ ¯à®£à ¬¬ë
;null db ?
move_count dw ?
cptr db ?
sts dw ?
sh_off db ?
task dd ?
generator dd ?
curconf:
/programs/games/15/trunk/build_en.bat
0,0 → 1,4
@erase lang.inc
@echo lang fix en >lang.inc
@fasm 15.asm 15
@pause
/programs/games/15/trunk/build_ru.bat
0,0 → 1,4
@erase lang.inc
@echo lang fix ru >lang.inc
@fasm 15.asm 15
@pause
/programs/games/15/trunk/macros.inc
0,0 → 1,266
; new application structure
macro meos_app_start
{
use32
org 0x0
 
db 'MENUET01'
dd 0x01
dd __start
dd __end
dd __memory
dd __stack
 
if used __params & ~defined __params
dd __params
else
dd 0x0
end if
 
dd 0x0
}
MEOS_APP_START fix meos_app_start
 
macro code
{
__start:
}
CODE fix code
 
macro data
{
__data:
}
DATA fix data
 
macro udata
{
if used __params & ~defined __params
__params:
db 0
__end:
rb 255
else
__end:
end if
__udata:
}
UDATA fix udata
 
macro meos_app_end
{
align 32
rb 2048
__stack:
__memory:
}
MEOS_APP_END fix meos_app_end
 
 
; macro for defining multiline text data
struc mstr [sstring]
{
forward
local ssize
virtual at 0
db sstring
ssize = $
end virtual
dd ssize
db sstring
common
dd -1
}
 
 
; strings
macro sz name,[data] { ; from MFAR [mike.dld]
common
if used name
label name
end if
forward
if used name
db data
end if
common
if used name
.size = $-name
end if
}
 
macro lsz name,[lng,data] { ; from MFAR [mike.dld]
common
if used name
label name
end if
forward
if (used name)&(lang eq lng)
db data
end if
common
if used name
.size = $-name
end if
}
 
 
 
; easy system call macro
macro mpack dest, hsrc, lsrc
{
if (hsrc eqtype 0) & (lsrc eqtype 0)
mov dest, (hsrc) shl 16 + lsrc
else
if (hsrc eqtype 0) & (~lsrc eqtype 0)
mov dest, (hsrc) shl 16
add dest, lsrc
else
mov dest, hsrc
shl dest, 16
add dest, lsrc
end if
end if
}
 
macro __mov reg,a,b { ; mike.dld
if (~a eq)&(~b eq)
mpack reg,a,b
else if (~a eq)&(b eq)
mov reg,a
end if
}
 
macro mcall a,b,c,d,e,f { ; mike.dld
__mov eax,a
__mov ebx,b
__mov ecx,c
__mov edx,d
__mov esi,e
__mov edi,f
int 0x40
}
 
 
 
 
 
 
; optimize the code for size
__regs fix <eax,ebx,ecx,edx,esi,edi,ebp,esp>
 
macro add arg1,arg2
{
if (arg2 eqtype 0)
if (arg2) = 1
inc arg1
else
add arg1,arg2
end if
else
add arg1,arg2
end if
}
 
macro sub arg1,arg2
{
if (arg2 eqtype 0)
if (arg2) = 1
dec arg1
else
sub arg1,arg2
end if
else
sub arg1,arg2
end if
}
 
macro mov arg1,arg2
{
if (arg1 in __regs) & (arg2 eqtype 0)
if (arg2) = 0
xor arg1,arg1
else if (arg2) = 1
xor arg1,arg1
inc arg1
else if (arg2) = -1
or arg1,-1
else if (arg2) > -128 & (arg2) < 128
push arg2
pop arg1
else
mov arg1,arg2
end if
else
mov arg1,arg2
end if
}
 
 
macro struct name
{
virtual at 0
name name
sizeof.#name = $ - name
end virtual
}
 
; structures used in MeOS
struc process_information
{
.cpu_usage dd ? ; +0
.window_stack_position dw ? ; +4
.window_stack_value dw ? ; +6
.not_used1 dw ? ; +8
.process_name rb 12 ; +10
.memory_start dd ? ; +22
.used_memory dd ? ; +26
.PID dd ? ; +30
.x_start dd ? ; +34
.y_start dd ? ; +38
.x_size dd ? ; +42
.y_size dd ? ; +46
.slot_state dw ? ; +50
rb (1024-52)
}
struct process_information
 
struc system_colors
{
.frame dd ?
.grab dd ?
.grab_button dd ?
.grab_button_text dd ?
.grab_text dd ?
.work dd ?
.work_button dd ?
.work_button_text dd ?
.work_text dd ?
.work_graph dd ?
}
struct system_colors
 
 
; constants
 
; events
EV_IDLE = 0
EV_TIMER = 0
EV_REDRAW = 1
EV_KEY = 2
EV_BUTTON = 3
EV_EXIT = 4
EV_BACKGROUND = 5
EV_MOUSE = 6
EV_IPC = 7
EV_STACK = 8
 
; event mask bits for function 40
EVM_REDRAW = 1b
EVM_KEY = 10b
EVM_BUTTON = 100b
EVM_EXIT = 1000b
EVM_BACKGROUND = 10000b
EVM_MOUSE = 100000b
EVM_IPC = 1000000b
EVM_STACK = 10000000b
Property changes:
Added: svn:eol-style
+native
\ No newline at end of property