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