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