Subversion Repositories Kolibri OS

Rev

Rev 2023 | Go to most recent revision | Details | 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,\
136
	     0x03AABBCC, 0x805080D0, 0x005080D0
137
    mcall 4, 8*65536+8, 0x10DDEEFF, header, header_e - header
138
 
139
    mcall 8, BtnSpace*2*65536 + 83,\
140
	     (FieldSize+BtnSpace+20)*65536+ 15, 2
141
    mcall 4, (BtnSpace*2+3)*65536+(BtnSize+BtnSpace)*NofBtn+BtnSpace*4+20+4,\
142
	     0x10DDEEFF, strNew, strNew_e - strNew
143
    mcall 4, (center - 25) * 65536 + 30, 0, strMovs, strMovs_e - strMovs
144
    mcall 47, 4*65536+1, moves, (center + 2 ) * 65536 + 30, 0
145
 
146
 
147
 
148
	mov	ecx, (20+20+BtnSpace-BtnSize)*65536+BtnSize
149
	mov	edx, NofBtn	      ; идентификатор первой кнопки на поле
150
				      ; см рисунок
151
 
152
buttons:			      ; рисуем кнопочки
153
	mov	eax, edx
154
	mov	dh, NofBtn
155
	div	dh	     ; al = ax / dh, ah - остаток
156
	mov	dh, 0
157
	test	ah, ah	     ; если ah = 0, начинаем новый ряд
158
	jnz	@f
159
	add	ecx, (BtnSize+BtnSpace)*65536
160
	mov	ebx, BtnSpace*2*65536+BtnSize
161
@@:
162
	mov	esi, Color1		       ; байт по адресу
163
	cmp	byte [field-NofBtn+edx], 0	; field-NofBtn+номер_кнопки
164
	jz	@f				; говорит о ее цвете
165
	mov	esi, Color2
166
@@:
167
	mcall 8,
168
	add	ebx, (BtnSize+BtnSpace)*65536
169
	inc	edx			   ; переходим к следующей кнопке
170
	cmp	edx, NofBtn*(NofBtn+1)
171
	jb	buttons
172
 
173
    mcall 12, 2 		   ; функция 12: сообщить ОС об отрисовке окна
174
 
175
ret
176
 
177
;----------------------------------------------------------------------------
178
;               Game_Init
179
;----------------------------------------------------------------------------
180
Game_Init:
181
	and	[moves], 0	       ; обнулим количество ходов
182
 
183
	call	random		       ; в eax случайное число
184
	mov	ecx, NofBtn * NofBtn   ; в ecx кол-во кнопок на поле
185
	mov	bh, 0		       ; для каждой кнопки будем брать
186
				       ; 1 бит из eax, bh - сколько
187
button_init:			       ; бит уже использовали
188
	shr	eax, 1		 ; младший бит попадает в флаг CF
189
				 ; в зависимости от его значения
190
				 ; в bl записывается -1 или 0
191
	sbb	bl, bl
192
	mov	[field + ecx - 1], bl
193
 
194
	inc	bh
195
	cmp	bh, 32		 ; если использованы все 32 бита из eax
196
	jb	@f		 ; нао получить новое случайное число
197
	call	random
198
	mov	bh, 0
199
@@:
200
	loop	button_init
201
 
202
ret
203
 
204
;----------------------------------------------------------------------------
205
;     random - взята из тетриса
206
;----------------------------------------------------------------------------
207
random: 	mov eax,[generator]
208
		add eax,-43ab45b5h
209
		ror eax,1
210
		xor eax,32c4324fh
211
		ror eax,1
212
		mov [generator],eax
213
		; --- IVAN ---
214
		mov eax,26
215
		mov ebx,9
216
		int 0x40
217
		xor eax,0xdeadbeef
218
		add eax,[generator]
219
		; --- IVAN ---
220
		ret
221
 
222
;============================================================================
223
 
224
field		db NofBtn * NofBtn dup(0)
225
moves		dd 0
226
generator	dd 0
227
 
228
if lang eq ru
229
header		db 'Game'
230
header_e:
231
strMovs 	db 'ХОД'	; 'ХОД'
232
strMovs_e:
233
strNew		db 'Новая игра' ; 'Новая игра'
234
strNew_e:
235
else
236
header		db 'Game'
237
header_e:
238
strMovs 	db 'MOVE'
239
strMovs_e:
240
strNew		db ' New game'
241
strNew_e:
242
end if
243
 
244
 
245
 
246
I_END:				   ; метка конца программы