; SQ_game for MenuetOS
; Author: Alexei Ershov aka ealex
; E-mail: e-al[at]yandex[dot]ru
; Fidonet: 2:469/335.38
; slightly updated by leency and renamed to Lights
; https://en.wikipedia.org/wiki/Lights_Out_(game)
; slightly optimized by diamond
; english translation by diamond (two strings in end of source)
BtnSize equ 36 ; à §¬¥à ª®¯ª¨
BtnSpace equ 0 ; ¯à®¬¥¦ã⮪ ¬¥¦¤ã ª®¯ª ¬¨
NofBtn equ 4 ; à §¬¥à ¯®«ï (3-15)
Color1 equ 0xcc0000
Color2 equ 0x00cc00
FieldSize = (BtnSize+BtnSpace)*NofBtn + BtnSpace*3
center = FieldSize / 2
margin = 20
use32 ; ¢ª«îç¨âì 32-¡¨âë© à¥¦¨¬ áᥬ¡«¥à
org 0x0 ; ¤à¥á æ¨ï á ã«ï
db 'MENUET01' ; 8-¡ ©âë© ¨¤¥â¨ä¨ª â®à MenuetOS
dd 0x01 ; ¢¥àá¨ï § £®«®¢ª (¢á¥£¤ 1)
dd START ; ¤à¥á ¯¥à¢®© ª®¬ ¤ë
dd I_END ; à §¬¥à ¯à®£à ¬¬ë
dd 0x1000 ; ª®«¨ç¥á⢮ ¯ ¬ïâ¨
dd 0x1000 ; ¤à¥á ¢¥àè¨ë áâíª
dd 0x0 ; ¤à¥á ¡ãä¥à ¤«ï ¯ à ¬¥â஢ (¥ ¨á¯®«ì§ã¥âáï)
dd 0x0 ; § १¥à¢¨à®¢ ®
include '../../../macros.inc' ; ¬ ªà®áë ®¡«¥£ç îâ ¦¨§ì áᥬ¡«¥à騪®¢!
START:
call Game_Init
red:
call Draw_Window
still:
mcall 10 ; äãªæ¨ï 10 - ¦¤ âì ᮡëâ¨ï
dec eax
jz red
dec eax
jnz button
key: ; ¦ â ª« ¢¨è ª« ¢¨ âãà¥
mov al, 2
int 0x40
jmp still
;---------------------------------------------------------------------
button:
mov al, 17 ; 17 - ¯®«ãç¨âì ¨¤¥â¨ä¨ª â®à ¦ ⮩ ª®¯ª¨
int 0x40
cmp ah, 1 ; ¥á«¨ ¦ â ª®¯ª á ®¬¥à®¬ 1, ¢ë室¨¬
je .exit
cmp ah, 2 ; ¥á«¨ ¦ â ª®¯ª 2, ç¨ ¥¬ ®¢ãî ¨£àã
je START
; ¦ ª®¯ª ¯®«¥
inc dword [moves] ; 㢥«¨ç¨¢ ¥¬ ç¨á«® 室®¢
shr eax, 8 ; ¢ eax ¨¤¥â¨ä¨ª â®à ¦ ⮩ ª®¯ª¨
mov dh, NofBtn
div dh ; al = ax(®¬¥à ª®¯ª¨) / NofBtn
; ah = ®áâ ⮪ (á¬. à¨á㮪)
mov ebx, eax ; á®åà ¨¬ ç á⮥ ¨ ®áâ ⮪ ¢ ebx
; al\ah 0 1 2 3
; +-+ +-+ +-+ +-+
; 1 |4| |5| |6| |7|
; +-+ +-+ +-+ +-+
; +-+ +-+ +-+ +-+
; 2 |8| |9| |10 |11
; +-+ +-+ +-+ +-+
; +-+ +-+ +-+ +-+
; 3 |12 |13 |14 |15
; +-+ +-+ +-+ +-+
; +-+ +-+ +-+ +-+
; 4 |16 |17 |18 |19
; +-+ +-+ +-+ +-+
; ¥ï¥¬ 梥â á⮫¡¨ª
shr eax, 8 ; eax = ah
mov edi, field
add edi, eax ; edi 㪠§¢ë¥â ¯¥à¢ãî ª®¯ªã ¨ ¨áª®¬®¬ áâ«¡æ¥
mov ecx, NofBtn
@@:
not byte[edi] ; ¬¥ï¥¬ 梥⠢® ¢á¥¬ á⮫¡¨ª¥
dec ecx
add edi, NofBtn
test ecx, ecx
jnz @r
; ¥ï¥¬ 梥â áâப¨
mov eax, ebx ; ¢®ááâ ¢«¨¢ ¥¬ eax
dec eax
mov dl, NofBtn
mul dl ; ax = al * NofBtn
mov edi, field
add edi, eax ; edi 㪠§¢ë¥â ¯¥à¢ãî ª®¯ªã ¢ ¨áª®¬®© áâப¥
mov ecx, NofBtn
@@:
not byte [edi] ; ¬¥ï¥¬ 梥⠢® ¢á¥© áâப¥
dec ecx
inc edi
test ecx, ecx
jnz @r
; ¢¥â ¦ ⮩ ª®¯ª¨ ¬¥ï«áï 2 à § (ª®£¤ ®¡à ¡ âë¢ «¨ áâப㠨 á⮫¡¥æ),
; â.¥. ®áâ «áï ¯¥à¢® ç «ë¬
; ¥ï¥¬ 梥⠦ ⮩ ª®¯ª¨
shr ebx, 8 ; ebx = ®áâ ⮪ (ah à¨á㪥)
not byte [field+eax+ebx]
jmp red
.exit:
mcall -1 ; ¨ ç¥ ª®¥æ ¯à®£à ¬¬ë
;----------------------------------------------------------------------------
; Draw_Window
;----------------------------------------------------------------------------
Draw_Window:
mcall 12, 1
mcall 0, 200*65536+FieldSize+margin*2,\
200*65536+FieldSize+28+margin*3,\
0x14DDD7CF, 0x805080D0, header
mcall 8, (BtnSpace*2+margin)*65536 + 83,\
(FieldSize+BtnSpace+margin*2+10)*65536+ 22, 2
mcall 4, (BtnSpace*2+3+margin)*65536+(FieldSize+BtnSpace+margin*2)+14,\
0x90DDEEFF, strNew
mcall 4, (center - 25+margin) * 65536 + 30, 0x80000000, strMovs
mcall 47, 4*65536+1, moves, (center + 2+margin ) * 65536 + 30, 0
mov ecx, (20+20+BtnSpace-BtnSize)*65536+BtnSize
mov edx, NofBtn ; ¨¤¥â¨ä¨ª â®à ¯¥à¢®© ª®¯ª¨ ¯®«¥
; ᬠà¨á㮪
buttons: ; à¨á㥬 ª®¯®çª¨
mov eax, edx
mov dh, NofBtn
div dh ; al = ax / dh, ah - ®áâ ⮪
mov dh, 0
test ah, ah ; ¥á«¨ ah = 0, ç¨ ¥¬ ®¢ë© àï¤
jnz @f
add ecx, (BtnSize+BtnSpace)*65536
mov ebx, (BtnSpace*2+margin)*65536+BtnSize+1
@@:
mov esi, Color1 ; ¡ ©â ¯® ¤à¥áã
cmp byte [field-NofBtn+edx], 0 ; field-NofBtn+®¬¥à_ª®¯ª¨
jz @f ; £®¢®à¨â ® ¥¥ 梥â¥
mov esi, Color2
@@:
mcall 8,
add ebx, (BtnSize+BtnSpace)*65536
inc edx ; ¯¥à¥å®¤¨¬ ª á«¥¤ãî饩 ª®¯ª¥
cmp edx, NofBtn*(NofBtn+1)
jb buttons
mcall 12, 2 ; äãªæ¨ï 12: á®®¡é¨âì ®¡ ®âà¨á®¢ª¥ ®ª
ret
;----------------------------------------------------------------------------
; Game_Init
;----------------------------------------------------------------------------
Game_Init:
and [moves], 0 ; ®¡ã«¨¬ ª®«¨ç¥á⢮ 室®¢
call random ; ¢ eax á«ãç ©®¥ ç¨á«®
mov ecx, NofBtn * NofBtn ; ¢ ecx ª®«-¢® ª®¯®ª ¯®«¥
mov bh, 0 ; ¤«ï ª ¦¤®© ª®¯ª¨ ¡ã¤¥¬ ¡à âì
; 1 ¡¨â ¨§ eax, bh - ᪮«ìª®
button_init: ; ¡¨â 㦥 ¨á¯®«ì§®¢ «¨
shr eax, 1 ; ¬« ¤è¨© ¡¨â ¯®¯ ¤ ¥â ¢ ä« £ CF
; ¢ § ¢¨á¨¬®á⨠®â ¥£® § 票ï
; ¢ bl § ¯¨áë¢ ¥âáï -1 ¨«¨ 0
sbb bl, bl
mov [field + ecx - 1], bl
inc bh
cmp bh, 32 ; ¥á«¨ ¨á¯®«ì§®¢ ë ¢á¥ 32 ¡¨â ¨§ eax
jb @f ; ® ¯®«ãç¨âì ®¢®¥ á«ãç ©®¥ ç¨á«®
call random
mov bh, 0
@@:
loop button_init
ret
;----------------------------------------------------------------------------
; random - ¢§ïâ ¨§ â¥âà¨á
;----------------------------------------------------------------------------
random: mov eax,[generator]
add eax,-43ab45b5h
ror eax,1
xor eax,32c4324fh
ror eax,1
mov [generator],eax
; --- IVAN ---
mov eax,26
mov ebx,9
int 0x40
xor eax,0xdeadbeef
add eax,[generator]
; --- IVAN ---
ret
;============================================================================
field db NofBtn * NofBtn dup(0)
moves dd 0
generator dd 0
header db 'Lights',0
if lang eq ru
strMovs db '',0
strNew db '®¢ ï ¨£à ',0
else
strMovs db 'MOVE',0
strNew db ' New game',0
end if
I_END: ; ¬¥âª ª®æ ¯à®£à ¬¬ë