Subversion Repositories Kolibri OS

Rev

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