Rev 7134 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1805 | yogev_ezra | 1 | ; SQ_game for MenuetOS |
2 | ; Author: Alexei Ershov aka ealex |
||
3 | ; E-mail: e-al[at]yandex[dot]ru |
||
4 | ; Fidonet: 2:469/335.38 |
||
7373 | leency | 5 | ; slightly updated by leency and renamed to Lights |
6 | ; https://en.wikipedia.org/wiki/Lights_Out_(game) |
||
1805 | yogev_ezra | 7 | ; slightly optimized by diamond |
8 | ; english translation by diamond (two strings in end of source) |
||
9 | |||
10 | |||
7373 | leency | 11 | BtnSize equ 36 ; размер кнопки |
12 | BtnSpace equ 0 ; промежуток между кнопками |
||
1805 | yogev_ezra | 13 | NofBtn equ 4 ; размер поля (3-15) |
14 | Color1 equ 0xcc0000 |
||
15 | Color2 equ 0x00cc00 |
||
16 | |||
17 | FieldSize = (BtnSize+BtnSpace)*NofBtn + BtnSpace*3 |
||
18 | center = FieldSize / 2 |
||
7373 | leency | 19 | margin = 20 |
1805 | yogev_ezra | 20 | |
21 | |||
22 | use32 ; включить 32-битный режим ассемблера |
||
23 | org 0x0 ; адресация с нуля |
||
24 | |||
25 | db 'MENUET01' ; 8-байтный идентификатор MenuetOS |
||
26 | dd 0x01 ; версия заголовка (всегда 1) |
||
27 | dd START ; адрес первой команды |
||
28 | dd I_END ; размер программы |
||
29 | dd 0x1000 ; количество памяти |
||
30 | dd 0x1000 ; адрес вершины стэка |
||
31 | dd 0x0 ; адрес буфера для параметров (не используется) |
||
32 | dd 0x0 ; зарезервировано |
||
33 | |||
7373 | leency | 34 | include '../../../macros.inc' ; макросы облегчают жизнь ассемблерщиков! |
1805 | yogev_ezra | 35 | |
36 | |||
37 | START: |
||
38 | call Game_Init |
||
39 | red: |
||
40 | call Draw_Window |
||
41 | |||
42 | still: |
||
43 | mcall 10 ; функция 10 - ждать события |
||
44 | dec eax |
||
45 | jz red |
||
46 | dec eax |
||
47 | jnz button |
||
48 | |||
49 | key: ; нажата клавиша на клавиатуре |
||
50 | mov al, 2 |
||
51 | int 0x40 |
||
52 | jmp still |
||
53 | ;--------------------------------------------------------------------- |
||
54 | |||
55 | button: |
||
56 | mov al, 17 ; 17 - получить идентификатор нажатой кнопки |
||
57 | int 0x40 |
||
58 | cmp ah, 1 ; если нажата кнопка с номером 1, выходим |
||
59 | je .exit |
||
60 | |||
61 | cmp ah, 2 ; если нажата кнопка 2, начинаем новую игру |
||
62 | je START |
||
63 | |||
64 | ; Нажа кнопка на поле |
||
65 | inc dword [moves] ; увеличиваем число ходов |
||
66 | |||
67 | shr eax, 8 ; в eax идентификатор нажатой кнопки |
||
68 | |||
69 | mov dh, NofBtn |
||
70 | div dh ; al = ax(номер кнопки) / NofBtn |
||
71 | ; ah = остаток (см. рисунок) |
||
72 | mov ebx, eax ; сохраним частное и остаток в ebx |
||
73 | |||
74 | ; al\ah 0 1 2 3 |
||
75 | ; +-+ +-+ +-+ +-+ |
||
76 | ; 1 |4| |5| |6| |7| |
||
77 | ; +-+ +-+ +-+ +-+ |
||
78 | |||
79 | ; +-+ +-+ +-+ +-+ |
||
80 | ; 2 |8| |9| |10 |11 |
||
81 | ; +-+ +-+ +-+ +-+ |
||
82 | |||
83 | ; +-+ +-+ +-+ +-+ |
||
84 | ; 3 |12 |13 |14 |15 |
||
85 | ; +-+ +-+ +-+ +-+ |
||
86 | |||
87 | ; +-+ +-+ +-+ +-+ |
||
88 | ; 4 |16 |17 |18 |19 |
||
89 | ; +-+ +-+ +-+ +-+ |
||
90 | |||
91 | ; Меняем цвет столбика |
||
92 | shr eax, 8 ; eax = ah |
||
93 | mov edi, field |
||
94 | add edi, eax ; edi указвыет на первую кнопку и искомом стлбце |
||
95 | mov ecx, NofBtn |
||
96 | @@: |
||
97 | not byte[edi] ; меняем цвет во всем столбике |
||
98 | dec ecx |
||
99 | add edi, NofBtn |
||
100 | test ecx, ecx |
||
101 | jnz @r |
||
102 | |||
103 | ; Меняем цвет строки |
||
104 | mov eax, ebx ; восстанавливаем eax |
||
105 | dec eax |
||
106 | mov dl, NofBtn |
||
107 | mul dl ; ax = al * NofBtn |
||
108 | mov edi, field |
||
109 | add edi, eax ; edi указвыет на первую кнопку в искомой строке |
||
110 | mov ecx, NofBtn |
||
111 | @@: |
||
112 | not byte [edi] ; меняем цвет во всей строке |
||
113 | dec ecx |
||
114 | inc edi |
||
115 | test ecx, ecx |
||
116 | jnz @r |
||
117 | ; Цвет нажатой кнопки менялся 2 раза (когда обрабатывали строку и столбец), |
||
118 | ; т.е. остался первоначалным |
||
119 | ; Меняем цвет нажатой кнопки |
||
120 | shr ebx, 8 ; ebx = остаток (ah на рисунке) |
||
121 | not byte [field+eax+ebx] |
||
122 | jmp red |
||
123 | |||
124 | |||
125 | |||
126 | .exit: |
||
127 | mcall -1 ; иначе конец программы |
||
128 | |||
129 | |||
130 | ;---------------------------------------------------------------------------- |
||
131 | ; Draw_Window |
||
132 | ;---------------------------------------------------------------------------- |
||
133 | Draw_Window: |
||
134 | |||
135 | mcall 12, 1 |
||
7373 | leency | 136 | mcall 0, 200*65536+FieldSize+margin*2,\ |
137 | 200*65536+FieldSize+28+margin*3,\ |
||
138 | 0x14DDD7CF, 0x805080D0, header |
||
1805 | yogev_ezra | 139 | |
7373 | leency | 140 | mcall 8, (BtnSpace*2+margin)*65536 + 83,\ |
141 | (FieldSize+BtnSpace+margin*2+10)*65536+ 22, 2 |
||
142 | mcall 4, (BtnSpace*2+3+margin)*65536+(FieldSize+BtnSpace+margin*2)+14,\ |
||
143 | 0x90DDEEFF, strNew |
||
144 | mcall 4, (center - 25+margin) * 65536 + 30, 0x80000000, strMovs |
||
145 | mcall 47, 4*65536+1, moves, (center + 2+margin ) * 65536 + 30, 0 |
||
1805 | yogev_ezra | 146 | |
147 | |||
148 | |||
149 | mov ecx, (20+20+BtnSpace-BtnSize)*65536+BtnSize |
||
150 | mov edx, NofBtn ; идентификатор первой кнопки на поле |
||
151 | ; см рисунок |
||
152 | |||
153 | buttons: ; рисуем кнопочки |
||
154 | mov eax, edx |
||
155 | mov dh, NofBtn |
||
156 | div dh ; al = ax / dh, ah - остаток |
||
157 | mov dh, 0 |
||
158 | test ah, ah ; если ah = 0, начинаем новый ряд |
||
159 | jnz @f |
||
160 | add ecx, (BtnSize+BtnSpace)*65536 |
||
7373 | leency | 161 | mov ebx, (BtnSpace*2+margin)*65536+BtnSize+1 |
1805 | yogev_ezra | 162 | @@: |
163 | mov esi, Color1 ; байт по адресу |
||
164 | cmp byte [field-NofBtn+edx], 0 ; field-NofBtn+номер_кнопки |
||
165 | jz @f ; говорит о ее цвете |
||
166 | mov esi, Color2 |
||
167 | @@: |
||
168 | mcall 8, |
||
169 | add ebx, (BtnSize+BtnSpace)*65536 |
||
170 | inc edx ; переходим к следующей кнопке |
||
171 | cmp edx, NofBtn*(NofBtn+1) |
||
172 | jb buttons |
||
173 | |||
174 | mcall 12, 2 ; функция 12: сообщить ОС об отрисовке окна |
||
175 | |||
176 | ret |
||
177 | |||
178 | ;---------------------------------------------------------------------------- |
||
179 | ; Game_Init |
||
180 | ;---------------------------------------------------------------------------- |
||
181 | Game_Init: |
||
182 | and [moves], 0 ; обнулим количество ходов |
||
183 | |||
184 | call random ; в eax случайное число |
||
185 | mov ecx, NofBtn * NofBtn ; в ecx кол-во кнопок на поле |
||
186 | mov bh, 0 ; для каждой кнопки будем брать |
||
187 | ; 1 бит из eax, bh - сколько |
||
188 | button_init: ; бит уже использовали |
||
189 | shr eax, 1 ; младший бит попадает в флаг CF |
||
190 | ; в зависимости от его значения |
||
191 | ; в bl записывается -1 или 0 |
||
192 | sbb bl, bl |
||
193 | mov [field + ecx - 1], bl |
||
194 | |||
195 | inc bh |
||
196 | cmp bh, 32 ; если использованы все 32 бита из eax |
||
197 | jb @f ; нао получить новое случайное число |
||
198 | call random |
||
199 | mov bh, 0 |
||
200 | @@: |
||
201 | loop button_init |
||
202 | |||
203 | ret |
||
204 | |||
205 | ;---------------------------------------------------------------------------- |
||
206 | ; random - взята из тетриса |
||
207 | ;---------------------------------------------------------------------------- |
||
208 | random: mov eax,[generator] |
||
209 | add eax,-43ab45b5h |
||
210 | ror eax,1 |
||
211 | xor eax,32c4324fh |
||
212 | ror eax,1 |
||
213 | mov [generator],eax |
||
214 | ; --- IVAN --- |
||
215 | mov eax,26 |
||
216 | mov ebx,9 |
||
217 | int 0x40 |
||
218 | xor eax,0xdeadbeef |
||
219 | add eax,[generator] |
||
220 | ; --- IVAN --- |
||
221 | ret |
||
222 | |||
223 | ;============================================================================ |
||
224 | |||
225 | field db NofBtn * NofBtn dup(0) |
||
226 | moves dd 0 |
||
227 | generator dd 0 |
||
228 | |||
7373 | leency | 229 | header db 'Lights',0 |
230 | |||
1805 | yogev_ezra | 231 | if lang eq ru |
7373 | leency | 232 | strMovs db 'ХОД',0 |
233 | strNew db 'Новая игра',0 |
||
1805 | yogev_ezra | 234 | else |
7373 | leency | 235 | strMovs db 'MOVE',0 |
236 | strNew db ' New game',0 |
||
1805 | yogev_ezra | 237 | end if |
238 | |||
239 | |||
240 | |||
241 | I_END: ; метка конца программы |