Subversion Repositories Kolibri OS

Rev

Rev 7134 | 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
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:				   ; метка конца программы