Subversion Repositories Kolibri OS

Rev

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