Subversion Repositories Kolibri OS

Rev

Rev 485 | 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
551 spraid 11
BgdColor equ 0x04aabbcc
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
83
    mov  [lenTitle-1],al     ;task number to program title
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:
160
    mov  eax,12
161
    mov  ebx,1                     ; begin draw
485 heavyiron 162
    mcall
31 halyavin 163
 
164
                                   ; CREATING WINDOW
165
    mov  eax,0
166
    mov  ebx,XXwindow
167
    mov  ecx,YYwindow
168
    mov  edx,BgdColor
169
    mov  esi,0x805080d0
170
    mov  edi,0x005080d0
485 heavyiron 171
    mcall
31 halyavin 172
 
173
                                   ; PROGRAM TITLE
174
    mov  eax,4
175
    mov  ebx,8*65536+8
485 heavyiron 176
    mov  ecx,0x10000000
31 halyavin 177
    mov  edx,txtTitle
178
    mov  esi,lenTitle-txtTitle
485 heavyiron 179
    mcall
31 halyavin 180
 
181
    mov  eax,8                     ; SHUFFLE BUTTON
182
    mov  ebx,XXSh
183
    mov  ecx,YYSh
184
    xor  edx,edx
185
    mov  esi,BtnColor
485 heavyiron 186
    mcall
31 halyavin 187
 
188
    mov  ebx,XXCnf                  ; CONF BUTTON
189
    mov  ecx,YYCnf
190
    mov  edx,20
191
    mov  esi,BtnColor
485 heavyiron 192
    mcall
31 halyavin 193
 
194
    mov  ebx, XYShText             ; SHUFFLE TEXT
195
    mov  ecx, StatusColor
196
    mov  edx,txtSh
197
    mov  esi,lenSh-txtSh
198
    mov  eax,4
485 heavyiron 199
    mcall
31 halyavin 200
 
201
    mov  ebx, XYCnfText             ; CONF TEXT
202
    mov  edx,lenVictory-1
203
    mov  esi,1
485 heavyiron 204
    mcall
31 halyavin 205
 
206
    mov  ecx, 16                   ; FIELD BUTTONS
207
  dbut:
208
    call draw_button
209
    loop dbut
210
 
211
    call draw_moves
212
 
213
    mov  eax,12
214
    mov  ebx,2                     ; end of drawing
485 heavyiron 215
    mcall
31 halyavin 216
    ret
217
 
218
 
219
;   *********************************************
220
;   ******* DRAWING A FIELD BUTTON **************
221
;   *********************************************
222
;   ECX - button number
223
 
224
draw_button:
225
    pusha
226
    dec  ecx
227
  ; calculating button dimensions
228
    mov  edi, ecx
229
    lea  edx,[ecx+2]
230
    mov  ebx,ecx
231
    and  ebx,11b
232
    shr  ecx,2
233
 
234
    imul ebx,BtnSize+3
235
    add  ebx,BtnLeft
236
    shl  ebx,16
237
    add  ebx,BtnSize
238
 
239
    imul ecx,BtnSize+3
240
    add  ecx,BtnTop
241
    shl  ecx,16
242
    add  ecx,BtnSize
243
    movzx eax,byte [null]
244
    cmp  eax,edi
245
    jne   no_hole
246
 
247
    pusha
248
    inc  ebx
249
    inc  ecx
250
    mov  edx,BgdColor
251
    mov  eax,13         ; clearing - 'hole'
485 heavyiron 252
    mcall
31 halyavin 253
    popa
254
 
255
    or   edx,0x80000000 ; and removing button under it
256
no_hole:
257
    mov  al,byte[edi+curconf]
258
    mov  esi,[task]
259
    cmp  al,byte[edi+esi]
260
    je   highlight
261
    mov  esi,BtnColor
262
    jmp  s_rbutton
263
highlight:
264
    mov  esi,BtnColor2
265
s_rbutton:
266
    mov  eax,8          ; set/remove button
485 heavyiron 267
    mcall
31 halyavin 268
    movzx eax,byte [null]
269
    cmp  eax,edi
270
    je   no_text        ; no digits - that's hole
271
    mov  edx,ebx
272
    shr  ecx,16
273
    mov  dx,cx
274
    add  edx,NumShift
275
    mov  ebx,0x20000
276
    movzx  ecx,byte [edi+curconf]
277
    cmp  ecx,9
278
    ja   two_num
279
    add  edx,NumShift2    ; shift to center digits
280
    sub  ebx,0x10000
281
two_num:
282
    mov  esi,NumColor
283
    mov  eax,47
485 heavyiron 284
    mcall
31 halyavin 285
no_text:
286
    popa
287
    ret
288
 
289
 
290
;   *********************************************
291
;   ******* DRAWING STATUS LINE *****************
292
;   *********************************************
293
 
294
draw_moves:
295
    mov  eax, 13          ; clear area
296
    mov  ebx, XXbar
297
    mov  ecx, YYbar
298
    mov  edx, BgdColor
485 heavyiron 299
    mcall
31 halyavin 300
 
301
    mov  eax, 4
302
    mov  ebx, XYstatus
303
    mov  ecx, StatusColor
304
    cmp  ax, [sts]
305
    jl   report_victory
306
    jne  report_moves
307
    mov  edx,txtCnf  ; prompt to choose configuration
308
    mov  esi,lenCnf-txtCnf
309
    jmp  e_dm
310
  report_moves:
311
    mov  edx,txtMoves  ; how many moves done
312
    mov  esi,lenMoves-txtMoves
313
    mov  eax,4
485 heavyiron 314
    mcall
31 halyavin 315
    mov  esi,ecx
316
    mov  edx,ebx
317
    add  edx, 40 shl 16
318
    mov  ebx,0x030000
319
    movzx  ecx, byte[move_count]
320
    mov  eax,47
321
    jmp  e_dm
322
  report_victory:               ; puzzle completed
323
    mov  ecx,StatusColor2
324
    mov  edx,txtVictory
325
    mov  esi,lenVictory-txtVictory
326
  e_dm:
485 heavyiron 327
    mcall
31 halyavin 328
    ret
329
 
330
 
331
;   *********************************************
332
;   ********* SHUFFLE ***************************
333
;   *********************************************
334
 
335
shuffle:
336
    xor  eax,eax
337
    mov  [sts],ax
338
    mov  [move_count],ax   ; reset moves to 0
339
    mov  [sh_off],al
340
    mov  eax, [generator]
341
 
342
    mov  ecx,SH_CYCLES
343
 sh_cycle:
344
    sub  eax,0x43ab45b5    ; next random number
345
    ror  eax,1
346
    xor  eax,0x32c4324f
347
    ror  eax,1
348
    mov  [generator],eax
349
 
350
    push eax
351
    and  eax,11b           ; direction 0..3
352
    movzx eax,byte [eax+correct]
353
    call move_check
354
    pop  eax
355
    jnc  sh_cycle          ; if fails then retry
356
    loop sh_cycle
357
    inc  byte[sh_off]          ; shuffling complete
358
    ret
359
 
360
 
361
;   *********************************************
362
;   ********* MOVE VALIDITY CHECK ***************
363
;   *********************************************
364
;   AL - 'DELTA' DIRECTION
365
 
366
move_check:
367
    pusha
368
    mov  ah,byte [null]
369
    mov  bx,ax
370
    cmp  bh,3
371
    ja   no_top
372
    cmp  al,-4       ; top of field
373
    je   no_move
374
no_top:
375
    cmp  bh,12
376
    jb   no_bottom
377
    cmp  al,4        ; bottom of field
378
    je   no_move
379
no_bottom:
380
    and  bh,11b
381
    cmp  bh,0
382
    jnz  no_left
383
    cmp  al,-1       ; left of field
384
    je  no_move
385
no_left:
386
    cmp  bh,11b
387
    jnz  ok
388
    cmp  al,1        ; right of field
389
    je  no_move
390
ok:
391
    mov bx,ax
392
    add bh,bl        ; bh-new hole
393
    mov byte [null],bh
394
    movzx ecx,ah
395
    mov al,byte[ecx+curconf]
396
    movzx edx,bh
397
    mov bl,byte[edx+curconf] ; swapping button & hole
398
    mov byte[ecx+curconf],bl
399
    mov byte[edx+curconf],al
400
 
401
    cmp  byte[sh_off],0  ; if shuffle in progress,
402
    jz   no_win      ; then no redraw
403
 
404
  ; drawing button & hole
405
    inc  ecx
406
    call draw_button
407
    movzx ecx,bh
408
    inc  ecx
409
    call draw_button
410
  ; testing if task completed
411
    mov  esi,[task]
412
    mov  edi,curconf
413
    mov  ecx,16
414
    repe cmpsb
415
    cmp  ecx,0
416
    jne  no_win
417
    mov  word[sts],6  ; puzzle done. Victory!
418
no_win:
419
    popa
420
    stc
421
    ret
422
no_move:
423
    popa
424
    clc
425
    ret
426
; this is deprecated debug routine
427
;ud:
428
;    ud2
429
 
430
; These are data used by program
431
 
432
correct db 1,-4,4,-1
433
 
434
conf db 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,0,15
435
     db 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,0
436
     db 1,2,3,4,12,13,14,5,11,0,15,6,10,9,8,7,9
437
 
438
txtMoves:
439
if lang eq ru
440
     db 'Ходов:'
441
else
442
     db 'Moves:'
443
end if
444
lenMoves:
445
 
446
txtSh:
447
if lang eq ru
448
     db 'Тасовка'
449
else
450
     db 'Shuffle'
451
end if
452
lenSh:
453
 
454
txtCnf:
455
if lang eq ru
456
     db 'Выберите задачу и нажмите->'
457
else
458
     db 'Select task,  then press ->'
459
end if
460
lenCnf:
461
 
462
txtTitle:               ; строка заголовка
463
if lang eq ru
464
     db   'Игра 15 - задача X'
465
else
466
     db   'Game 15 - puzzle X'
467
end if
468
lenTitle:                ; и её конец
469
 
470
txtVictory:
471
if lang eq ru
472
     db 'Вы решили задачу! Нажмите->'
473
else
474
     db 'Puzzle completed!   Press->'
475
end if
476
lenVictory:
477
 
478
arrow equ lenVictory-2
479
 
480
I_END:  ; конец программы
481
;null db ?
482
move_count dw ?
483
cptr db ?
484
sts dw ?
485
sh_off db ?
486
task dd ?
487
generator dd ?
488
curconf: