Subversion Repositories Kolibri OS

Rev

Rev 551 | Rev 3484 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
31 halyavin 1
;
2
;   The famous game 15
3
;   Author: Lloyd, coded by Ivushkin Andrey
4
;   Compile with FASM
5
;
6
include 'lang.inc'
485 heavyiron 7
include '..\..\..\macros.inc' ; decreases program size (not required)
31 halyavin 8
 
9
StatusColor equ 0x02ffffff
10
StatusColor2 equ 0x02dc1e14
2681 leency 11
BgdColor equ 0x14aabbcc
31 halyavin 12
 
13
; Main window dimensions
14
XXwindow equ 200 shl 16+276
15
YYwindow equ 200 shl 16+300
16
; Status bar
17
XYstatus equ 35 shl 16+283
18
XXbar equ 35 shl 16+136
19
YYbar equ 280 shl 16+15
20
; Buttons
21
BtnTop equ 28
22
BtnLeft equ 13
23
BtnSize equ 60
24
BtnColor equ 0xafbb55
25
BtnColor2 equ 0x0228c314
26
 
27
NumColor equ 0x10000000
28
; Number shifting for nice look
29
NumShift equ 24 shl 16+27
30
NumShift2 equ 4 shl 16
31
; Shuffle button
32
XXSh equ 202 shl 16+60
33
YYSh equ 280 shl 16+12
34
XYShText equ 212 shl 16+283
35
 
36
; Conf button
37
XXCnf equ 13 shl 16+13
38
YYCnf equ 280 shl 16+12
39
XYCnfText equ 18 shl 16+283
40
 
41
; Position of the 'hole'
42
null equ (curconf+16)
43
; Amount of moves to perform shuffle
44
SH_CYCLES equ 400
45
; (Amount of tasks)-1
46
CONF_COUNT equ 2
47
 
48
use32
49
 
50
  org    0x0
51
 
52
  db     'MENUET01'
53
  dd     0x01
54
  dd     START
55
  dd     I_END
56
  dd     0x2000  ; 8 Kb
57
  dd     0x2000
58
  dd     0x0
59
  dd     0x0
60
 
61
 
62
START:
63
    mov  [cptr],CONF_COUNT  ; number of task
64
    mov  eax,3
485 heavyiron 65
    mcall
31 halyavin 66
    mov  cl,16
67
    ror  eax,cl
68
    mov  [generator],eax    ; random generator from Tetris
69
  init:
70
    mov  ecx,17
71
    movzx  eax,[cptr]
72
    inc  eax
73
    cmp  eax,CONF_COUNT
74
    jna  init_ok
75
    xor  eax,eax            ; cycling 0..CONF_COUNT
76
  init_ok:
77
    mov  [cptr],al
78
    mov  esi,eax
79
    shl  esi,4
80
    add  esi,conf
81
    add  esi,eax
82
    add  al,0x31
2681 leency 83
    mov  [txtTitle+17],al     ;task number to program title
31 halyavin 84
    mov  [task],esi
85
    mov  edi,curconf
86
    rep  movsb          ; initial configuration
87
 
88
    mov  [sts],4
89
    jmp  red
90
SHUF:
91
    call shuffle        ; immediate shuffle
92
red:                    ; window redraw
93
 
94
    call draw_window
95
 
96
still:                  ; MAIN PROGRAM CYCLE
97
 
98
    mov  eax,10         ; wait for event
485 heavyiron 99
    mcall
31 halyavin 100
 
101
    cmp  eax,1          ; redraw? -
102
    je   red            ; goto red
103
    cmp  eax,2          ; key pressed? -
104
    je   key            ; goto key
105
    cmp  eax,3          ; button pressed? -
106
    je   button         ; goto button
107
 
108
    jmp  still          ; no more events to process
109
 
110
  key:                  ; Key pressed
111
    mov  eax,2
485 heavyiron 112
    mcall
31 halyavin 113
    shr  eax,8
114
    cmp  eax,32         ;  = Shuffle
115
    je   SHUF
116
    cmp  eax,13         ;  = Choose task
117
    je   init
118
    cmp  eax,176
119
    jl   still
120
    sub  eax,176
121
    cmp  eax,3
122
    ja   still
123
    movzx eax,byte [eax+correct] ; 'delta' value from correct[]
124
    jmp  m_check
125
 
126
  button:              ; Button pressed
127
    mov  eax,17
485 heavyiron 128
    mcall
31 halyavin 129
    shr  eax,8
130
    sub  eax,2
131
 
132
    cmp  eax,-1        ; id == 1 (closeme)?
133
    jne  noclose
485 heavyiron 134
    mcall
31 halyavin 135
 
136
  noclose:
137
    jl   SHUF          ; Shuffle (id=0) pressed
138
    cmp  eax,18
139
    je   init          ; Conf button pressed
140
    sub  al,byte [null]
141
    mov  edi,correct
142
    mov  ecx,4
143
    repne scasb        ; checking for valid move-part 1
144
    jne  fail
145
  m_check:
146
    cmp  byte[sts],4 ; puzzle completed, blocking buttons
147
    ja   still
148
    call move_check    ; checking for valid move-part 2
149
    jnc  fail
150
    inc  [move_count]
151
    call draw_moves
152
fail:
153
    jmp  still          ; возвращаемся
154
 
155
;   *******************************
156
;   *******  WINDOW DRAWING *******
157
;   *******************************
158
 
159
draw_window:
2681 leency 160
 
161
    mcall 12, 1 ; begin draw
162
	mcall 0, XXwindow, YYwindow, BgdColor,, txtTitle ; CREATING WINDOW
31 halyavin 163
 
164
 
165
    mov  eax,8                     ; SHUFFLE BUTTON
166
    mov  ebx,XXSh
167
    mov  ecx,YYSh
168
    xor  edx,edx
169
    mov  esi,BtnColor
485 heavyiron 170
    mcall
31 halyavin 171
 
172
    mov  ebx,XXCnf                  ; CONF BUTTON
173
    mov  ecx,YYCnf
174
    mov  edx,20
2681 leency 175
    ;mov  esi,BtnColor
485 heavyiron 176
    mcall
31 halyavin 177
 
178
    mov  ebx, XYShText             ; SHUFFLE TEXT
179
    mov  ecx, StatusColor
180
    mov  edx,txtSh
181
    mov  esi,lenSh-txtSh
182
    mov  eax,4
485 heavyiron 183
    mcall
31 halyavin 184
 
185
    mov  ebx, XYCnfText             ; CONF TEXT
186
    mov  edx,lenVictory-1
187
    mov  esi,1
485 heavyiron 188
    mcall
31 halyavin 189
 
190
    mov  ecx, 16                   ; FIELD BUTTONS
191
  dbut:
192
    call draw_button
193
    loop dbut
194
 
195
    call draw_moves
196
 
2681 leency 197
    mcall 12, 2 ; end of drawing
31 halyavin 198
    ret
199
 
200
 
201
;   *********************************************
202
;   ******* DRAWING A FIELD BUTTON **************
203
;   *********************************************
204
;   ECX - button number
205
 
206
draw_button:
207
    pusha
208
    dec  ecx
209
  ; calculating button dimensions
210
    mov  edi, ecx
211
    lea  edx,[ecx+2]
212
    mov  ebx,ecx
213
    and  ebx,11b
214
    shr  ecx,2
215
 
216
    imul ebx,BtnSize+3
217
    add  ebx,BtnLeft
218
    shl  ebx,16
219
    add  ebx,BtnSize
220
 
221
    imul ecx,BtnSize+3
222
    add  ecx,BtnTop
223
    shl  ecx,16
224
    add  ecx,BtnSize
225
    movzx eax,byte [null]
226
    cmp  eax,edi
227
    jne   no_hole
228
 
229
    pusha
230
    inc  ebx
231
    inc  ecx
232
    mov  edx,BgdColor
233
    mov  eax,13         ; clearing - 'hole'
485 heavyiron 234
    mcall
31 halyavin 235
    popa
236
 
237
    or   edx,0x80000000 ; and removing button under it
238
no_hole:
239
    mov  al,byte[edi+curconf]
240
    mov  esi,[task]
241
    cmp  al,byte[edi+esi]
242
    je   highlight
243
    mov  esi,BtnColor
244
    jmp  s_rbutton
245
highlight:
246
    mov  esi,BtnColor2
247
s_rbutton:
248
    mov  eax,8          ; set/remove button
485 heavyiron 249
    mcall
31 halyavin 250
    movzx eax,byte [null]
251
    cmp  eax,edi
252
    je   no_text        ; no digits - that's hole
253
    mov  edx,ebx
254
    shr  ecx,16
255
    mov  dx,cx
256
    add  edx,NumShift
257
    mov  ebx,0x20000
258
    movzx  ecx,byte [edi+curconf]
259
    cmp  ecx,9
260
    ja   two_num
261
    add  edx,NumShift2    ; shift to center digits
262
    sub  ebx,0x10000
263
two_num:
264
    mov  esi,NumColor
265
    mov  eax,47
485 heavyiron 266
    mcall
31 halyavin 267
no_text:
268
    popa
269
    ret
270
 
271
 
272
;   *********************************************
273
;   ******* DRAWING STATUS LINE *****************
274
;   *********************************************
275
 
276
draw_moves:
277
    mov  eax, 13          ; clear area
278
    mov  ebx, XXbar
279
    mov  ecx, YYbar
280
    mov  edx, BgdColor
485 heavyiron 281
    mcall
31 halyavin 282
 
283
    mov  eax, 4
284
    mov  ebx, XYstatus
285
    mov  ecx, StatusColor
286
    cmp  ax, [sts]
287
    jl   report_victory
288
    jne  report_moves
289
    mov  edx,txtCnf  ; prompt to choose configuration
290
    mov  esi,lenCnf-txtCnf
291
    jmp  e_dm
292
  report_moves:
293
    mov  edx,txtMoves  ; how many moves done
294
    mov  esi,lenMoves-txtMoves
295
    mov  eax,4
485 heavyiron 296
    mcall
31 halyavin 297
    mov  esi,ecx
298
    mov  edx,ebx
299
    add  edx, 40 shl 16
300
    mov  ebx,0x030000
301
    movzx  ecx, byte[move_count]
302
    mov  eax,47
303
    jmp  e_dm
304
  report_victory:               ; puzzle completed
305
    mov  ecx,StatusColor2
306
    mov  edx,txtVictory
307
    mov  esi,lenVictory-txtVictory
308
  e_dm:
485 heavyiron 309
    mcall
31 halyavin 310
    ret
311
 
312
 
313
;   *********************************************
314
;   ********* SHUFFLE ***************************
315
;   *********************************************
316
 
317
shuffle:
318
    xor  eax,eax
319
    mov  [sts],ax
320
    mov  [move_count],ax   ; reset moves to 0
321
    mov  [sh_off],al
322
    mov  eax, [generator]
323
 
324
    mov  ecx,SH_CYCLES
325
 sh_cycle:
326
    sub  eax,0x43ab45b5    ; next random number
327
    ror  eax,1
328
    xor  eax,0x32c4324f
329
    ror  eax,1
330
    mov  [generator],eax
331
 
332
    push eax
333
    and  eax,11b           ; direction 0..3
334
    movzx eax,byte [eax+correct]
335
    call move_check
336
    pop  eax
337
    jnc  sh_cycle          ; if fails then retry
338
    loop sh_cycle
339
    inc  byte[sh_off]          ; shuffling complete
340
    ret
341
 
342
 
343
;   *********************************************
344
;   ********* MOVE VALIDITY CHECK ***************
345
;   *********************************************
346
;   AL - 'DELTA' DIRECTION
347
 
348
move_check:
349
    pusha
350
    mov  ah,byte [null]
351
    mov  bx,ax
352
    cmp  bh,3
353
    ja   no_top
354
    cmp  al,-4       ; top of field
355
    je   no_move
356
no_top:
357
    cmp  bh,12
358
    jb   no_bottom
359
    cmp  al,4        ; bottom of field
360
    je   no_move
361
no_bottom:
362
    and  bh,11b
363
    cmp  bh,0
364
    jnz  no_left
365
    cmp  al,-1       ; left of field
366
    je  no_move
367
no_left:
368
    cmp  bh,11b
369
    jnz  ok
370
    cmp  al,1        ; right of field
371
    je  no_move
372
ok:
373
    mov bx,ax
374
    add bh,bl        ; bh-new hole
375
    mov byte [null],bh
376
    movzx ecx,ah
377
    mov al,byte[ecx+curconf]
378
    movzx edx,bh
379
    mov bl,byte[edx+curconf] ; swapping button & hole
380
    mov byte[ecx+curconf],bl
381
    mov byte[edx+curconf],al
382
 
383
    cmp  byte[sh_off],0  ; if shuffle in progress,
384
    jz   no_win      ; then no redraw
385
 
386
  ; drawing button & hole
387
    inc  ecx
388
    call draw_button
389
    movzx ecx,bh
390
    inc  ecx
391
    call draw_button
392
  ; testing if task completed
393
    mov  esi,[task]
394
    mov  edi,curconf
395
    mov  ecx,16
396
    repe cmpsb
397
    cmp  ecx,0
398
    jne  no_win
399
    mov  word[sts],6  ; puzzle done. Victory!
400
no_win:
401
    popa
402
    stc
403
    ret
404
no_move:
405
    popa
406
    clc
407
    ret
408
; this is deprecated debug routine
409
;ud:
410
;    ud2
411
 
412
; These are data used by program
413
 
414
correct db 1,-4,4,-1
415
 
416
conf db 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,0,15
417
     db 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,0
418
     db 1,2,3,4,12,13,14,5,11,0,15,6,10,9,8,7,9
419
 
420
txtMoves:
421
if lang eq ru
422
     db 'Ходов:'
423
else
424
     db 'Moves:'
425
end if
426
lenMoves:
427
 
428
txtSh:
429
if lang eq ru
430
     db 'Тасовка'
431
else
432
     db 'Shuffle'
433
end if
434
lenSh:
435
 
436
txtCnf:
437
if lang eq ru
438
     db 'Выберите задачу и нажмите->'
439
else
440
     db 'Select task,  then press ->'
441
end if
442
lenCnf:
443
 
2681 leency 444
txtTitle:              ; строка заголовка
31 halyavin 445
if lang eq ru
2681 leency 446
     db   'Игра 15 - задача X', 0
31 halyavin 447
else
2681 leency 448
     db   'Game 15 - puzzle X', 0
31 halyavin 449
end if
450
 
451
txtVictory:
452
if lang eq ru
453
     db 'Вы решили задачу! Нажмите->'
454
else
455
     db 'Puzzle completed!   Press->'
456
end if
457
lenVictory:
458
 
459
arrow equ lenVictory-2
460
 
461
I_END:  ; конец программы
462
;null db ?
463
move_count dw ?
464
cptr db ?
465
sts dw ?
466
sh_off db ?
467
task dd ?
468
generator dd ?
469
curconf: