Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
1806 yogev_ezra 1
; SOKOBAN FOR MENUET v0.1
2
; Written in pure assembler by Ivushkin Andrey aka Willow
3
;
4
; Last changed: July 2, 2004
5
;
6
; Main idea, art & graphics
7
;   Sokofun for Windows 95 by Games 4 Brains
8
;   and Sokoban 2.3 by BjЎrn Kфllmark
9
;
10
; Level designers:
11
;
12
;   Alberto Garcia, Aymeric du Peloux, Brian Kent, David Holland,
13
;   David W Skinner, Erim Sever, Evgeniy Grigoriev, Franчois Marques,
14
;   Frantisek Pokorny, Howard Abed,J franklin Mentzer, Jaques Duthen,
15
;   John C Davis, John Polhemus, Kobus Theron, Lee Haywood, Mario Bonenfant,
16
;   Martin P Holland, Mic (Jan Reineke), Phil Shapiro, Richard Weston,
17
;   Sven Egevad, Ken'ichiro Takahashi (takaken), Thinking Rabbit,
18
;   Yoshio Murase, ZICO (Zbigniew Kornas)
19
;
20
; Special thanks to Hirohiko Nakamiya
21
;
22
; More credits:
23
;   Masato Hiramatsu, Kazuo Fukushima, Klaus Clemens
24
;
25
; Game uses its own format of levelset files *.LEV
26
;   with simple run-length compression
27
 
28
; COMPILE WITH FASM
29
 
1934 yogev_ezra 30
include '../../../macros.inc'    ; decrease code size (optional)
31
include 'CELLTYPE.INC'  ; object identifiers
32
;include 'debug.inc'
33
;lang equ ru             ; russian interface; english if undefined
34
include 'lang.inc'
1806 yogev_ezra 35
 
1934 yogev_ezra 36
;CUR_DIR equ '/HD/1/MENUETOS/' ; change it to appropriate path
37
 
1806 yogev_ezra 38
SKIN_SIZE equ 11520         ; size of skin file (16x240)
39
 
40
; field dimensions
41
FLD_LEFT equ 43
42
FLD_LEFT2 equ FLD_LEFT shl 16
43
FLD_TOP equ 40
44
FLD_TOP2 equ FLD_TOP shl 16
45
IMG_SIZE equ 16 shl 16+16
46
SHIFT equ (16 shl 16)
47
WND_COLOR equ 0x03aabbcc
48
 
49
; level list dimensions
50
LEVLIST_XY equ FLD_TOP shl 16+45
51
LEVLIST_SPACING equ 10
52
LEVWND_X equ 320
53
LEVWND_Y equ 200
54
 
55
; input line dimensions
56
INP_X equ 10 shl 16+300
57
INP_Y equ 160 shl 16+16
58
INP_XY equ 15 shl 16+164
59
 
60
; load button dimensions
61
LOAD_X equ 130 shl 16+65
62
LOAD_Y equ 180 shl 16+14
63
LOAD_XY equ 135 shl 16+184
64
CHOOSE_XY equ 40 shl 16+148
65
 
66
 
67
WIN_XY equ 135 shl 16+25
68
 
69
; workmode constants, more defs in CELLTYPE.INC
70
WM_WINNER  equ 0x10
71
WM_READSET equ 0
72
WM_LOSE    equ 0x20
73
 
74
use32
75
  org    0x0
76
  db     'MENUET01'
77
  dd     0x01
78
  dd     START
79
  dd     I_END
80
  dd     0x100000
81
  dd     0x7fff0
82
  dd     0x0
83
  dd     0x0
84
 
85
START:
86
    mov  eax,58         ; load skin image-it is in RAW 16x240 BGR
87
    mov  ebx,file_info  ; IrfanView recommended
88
    int  0x40
89
    test ebx,ebx
90
;    jmp load_level
91
;    jz   close
92
  load_fail:            ; clear input line, also if levelset load failed
93
    mov  [inp_pos],0
94
  load_std:
95
    mov  esi,stdlev
96
    mov  edi,path_end
97
    mov  ecx,stdlev_len-stdlev
98
    rep  movsb
99
    mov  ecx,10
100
  reset_fi:
101
    mov  dword[cnf_level],level_start
102
    xor  eax,eax
103
    mov  [levpage],eax
104
    mov  word[ll_num],'00'   ; reset some counters
105
  read_cnf:
106
    mov  eax,58
107
    mov  ebx,file_info
108
    int  0x40
109
    test ebx,ebx        ; load standard levels SOKO-?.LEV instead of custom
110
    jz   nxt_cnf
111
    add  dword[cnf_level],ebx
112
  nxt_cnf:
113
    test ecx,ecx        ; this check is for loading a custom levelset
114
    jz   no_increase
115
    inc  byte[file_num] ; next standard levelset
116
    loop read_cnf
117
  no_increase:
118
    cmp  dword[cnf_level],level_start
119
    jne  go_on
120
    test ecx,ecx
121
    jz   load_fail
122
    jmp  close          ; missing standard levels & exiting
123
  go_on:
124
    mov  eax,[cnf_level]
125
    mov  byte[eax],0xf0 ; end-of-levels mark
126
 
127
    call read_levelset
128
  backto_set:
129
    mov  byte[workmode],WM_READSET
130
    mov  byte[winmode],0
131
    jmp  red
132
restart_level:
133
    call decode_field   ; uncompress level
134
 
135
red:
136
    call draw_window
137
 
138
still:
139
 
140
    mov  eax,10
141
    int  0x40
142
    cmp  byte[winmode],WM_WINNER
143
    je   backto_set
144
    cmp  byte[winmode],WM_LOSE
145
    je   backto_set
146
    cmp  eax,1
147
    je   red
148
    cmp  eax,2
149
    je   key
150
    cmp  eax,3
151
    je   button
152
 
153
    jmp  still
154
 
155
  key:
156
    mov  eax,2
157
    int  0x40
158
 
159
    cmp  byte[workmode],WM_READSET
160
    jne  key_move
161
    cmp  ah,32          ; Space moves focus to input line
162
    je   is_input
163
    cmp  ah,184
164
    jne  no_prev
165
    cmp  [levpage],0    ; PgUp
166
    jz   still
167
    sub  [levpage],10
168
    cmp  byte[ll_num+1],'0'
169
    jnz  _pu
170
    dec  byte[ll_num]
171
    mov  byte[ll_num+1],'9'+1
172
  _pu:
173
    dec  byte[ll_num+1]
174
    jmp  red
175
  no_prev:
176
    cmp  ah,183         ; PgDn
177
    jne  no_next
178
    mov  eax,[levpage]
179
    add  eax,10
180
    cmp  eax,[levelcount]
181
    jae  still
182
    mov  [levpage],eax
183
    cmp  byte[ll_num+1],'9'
184
    jnz  _pd
185
    inc  byte[ll_num]
186
    mov  byte[ll_num+1],'0'-1
187
  _pd:
188
    inc  byte[ll_num+1]
189
    jmp  red
190
  no_next:
191
    sub  ah,48
192
    cmp  ah,9
193
    ja   still
194
    movzx eax,ah        ; user selects a level
195
    add  eax,[levpage]
196
    cmp  eax,[levelcount]
197
    jae  still
198
    mov  eax,[levelmap+eax*4]
199
    mov  [levptr],eax   ; current level pointer
200
    mov  al,byte[eax]
201
    mov  byte[workmode],al
202
    jmp  restart_level
203
 
204
    ; we're already in game
205
  key_move:
206
    cmp  ah,180        ; Home
207
    je   backto_set
208
    cmp  ah,176
209
    jb   no_arrows
210
    sub  ah,176
211
    cmp  ah,3
212
    ja   no_arrows
213
    movzx ecx,ah
214
    movzx edx,[player]
215
    inc  ch
216
    call valid_move
217
    cmp  byte[winmode],WM_WINNER
218
    jne  no_winner
219
    mov  ecx,0x20ac0000
220
    mov  edx,win_msg
221
    mov  esi,win_msg_end-win_msg   ; print victory congratulations
222
  print_msg:
223
    mov  ebx,WIN_XY
224
    mov  eax,4
225
    int  0x40
226
    jmp  d_f
227
  no_winner:
228
    cmp  byte[winmode],WM_LOSE
229
    jne  d_f
230
  no_loser:
231
    test  al,al         ; no move accepted
232
    jnz   still
233
  d_f:
234
    call draw_field     ; move performed-redraw
235
    jmp  still
236
  no_arrows:
237
    cmp  ah,27
238
    je   restart_level
239
 
240
    jmp  still
241
 
242
  button:
243
    mov  eax,17
244
    int  0x40
245
 
246
    cmp  ah,1
247
    jne  noclose
248
  close:
249
    xor  eax,eax
250
    dec  eax
251
    int  0x40           ; shutdown.
252
 
253
  noclose:
254
    cmp  ah,2
255
    jne  no_input
256
  is_input:             ; simple input line with backspace feature
257
    mov  ebx,[entered]  ; sorry - no cursor
258
    test ebx,ebx
259
    jnz  wait_input
260
    mov  [inp_pos],ebx
261
    inc  [entered]
262
  wait_input:
263
    call draw_input
264
    mov  eax,10
265
    int  0x40
266
    cmp  eax,2
267
    jne  still
268
    mov  edi,[inp_pos]
269
    mov  eax,2
270
    int  0x40
271
    shr  eax,8
272
    cmp  eax,27
273
    je   still
274
    cmp  eax,13
275
    je   load_level
276
    cmp  eax,8
277
    je   backsp
278
    mov  [fn_input+edi],al
279
    inc  [inp_pos]
280
    jmp  wait_input
281
  backsp:
282
    test edi,edi
283
    jz   wait_input
284
    dec  [inp_pos]
285
    jmp  wait_input
286
  no_input:
287
    cmp  ah,3
288
    jne  no_load
289
  load_level:
290
    mov  ecx,[inp_pos]
291
    test ecx,ecx
292
    je   load_std
293
    mov  esi,fn_input
294
    mov  byte[esi+ecx],0
295
    inc  ecx
296
    mov  edi,path_end
297
    rep  movsb
298
    jmp  reset_fi
299
  no_load:
300
    jmp  still
301
 
302
 
303
;   *********************************************
304
;   ** FILLS LEVEL POINTER MAP ******************
305
;   *********************************************
306
read_levelset:
307
 
308
    mov  dword[wnd_width],LEVWND_X
309
    mov  dword[wnd_height],LEVWND_Y
310
    mov  [levelcount],0
311
    mov  edi,level_start
312
    mov  esi,levelmap
313
    mov  al,0xff
314
  rls_cycle:
315
    cmp  byte[edi],EOF
316
    je   end_of_levelset
317
    mov  [esi],edi
318
    add  esi,4
319
    mov  ecx,1024
320
    inc  [levelcount]
321
    repne scasb
322
    jecxz eol  ;end_of_levelset
323
    jmp  rls_cycle
324
  end_of_levelset:
325
    mov  eax,[levelcount]
326
;    debug_print_dec eax
327
    ret
328
  eol:
329
;   debug_print '*** '
330
    jmp  end_of_levelset
331
 
332
;   *********************************************
333
;   *******  DEFINE & DRAW WINDOW & OTHER STUFF *
334
;   *********************************************
335
 
336
draw_window:
337
 
338
    mov  eax,12
339
    mov  ebx,1
340
    int  0x40
341
 
342
    mov  eax,0
343
    mov  ebx,150*65536
344
    add  ebx,[wnd_width]
345
    mov  ecx,50*65536
346
    add  ecx,[wnd_height]
347
    mov  edx,WND_COLOR
348
    mov  esi,0x805080d0
349
    mov  edi,0x005080d0
350
    int  0x40
351
 
352
    mov  eax,4
353
    mov  ebx,8*65536+8
354
    mov  ecx,0x10ddeeff
355
    mov  edx,zagolovok
356
    mov  esi,zag_konets-zagolovok
357
    int  0x40
358
 
359
    cmp  byte[workmode],WM_READSET
360
    je   list_levels
361
 
362
    mov  edi,[levptr]   ; print custom level filename
363
    add  ebx,170*65536
364
    lea  edx,[edi+4]
365
    movzx  esi,byte[edi+3]
366
    int  0x40
367
 
368
    call draw_field
369
    cmp  [entered],0
370
    jz   end_of_draw
371
    mov  edx,fn_input   ; print input line text
372
    mov  esi,[inp_pos]
373
    mov  ebx,FLD_LEFT2+FLD_TOP-15
374
    jmp  draw_level_file
375
 
376
  list_levels:
377
 
378
    call draw_input
379
 
380
    mov  eax,8          ; draw load button
381
    mov  ebx,LOAD_X
382
    mov  ecx,LOAD_Y
383
    mov  edx,3
384
    mov  esi,WND_COLOR
385
    int  0x40
386
 
387
    mov  eax,4
388
    mov  ecx,0x20107a30
389
    mov  ebx,LOAD_XY
390
    mov  edx,load_char
391
    mov  esi,loadlen-load_char
392
    int  0x40
393
 
394
    mov  ebx,LEVLIST_XY
395
    mov  edi,0x204e00e7
396
    xor  esi,esi
397
    mov  ecx,10
398
  ll_cycle:
399
    push ecx esi ebx esi
400
    lea  ecx,[esi+'0']
401
    mov  [ll_num+2],cl
402
    mov  ecx,edi
403
    mov  edx,ll_num
404
    mov  esi,4
405
    int  0x40
406
    add  ebx,25 shl 16
407
    pop  esi
408
    add  esi,[levpage]
409
    mov  edx,[levelmap+esi*4]
410
    add  edx,4
411
    movzx esi,byte[edx-1]
412
    int  0x40
413
    pop  ebx esi ecx
414
    inc  esi
415
    mov  edx,[levelcount]
416
    sub  edx,[levpage]
417
    cmp  edx,esi
418
    jbe  choose_print
419
    add  ebx,LEVLIST_SPACING
420
    loop ll_cycle
421
  choose_print:
422
    mov  edx,ll_msg
423
    mov  esi,ll_msg_end-ll_msg
424
    mov  ebx,CHOOSE_XY
425
  draw_level_file:
426
    mov  eax,4
427
    int  0x40
428
 
429
  end_of_draw:
430
    mov  eax,12
431
    mov  ebx,2
432
    int  0x40
433
 
434
    ret
435
 
436
;   *********************************************
437
;   ******* DRAW CELL IMAGES WITHIN FIELD *******
438
;   *********************************************
439
 
440
draw_field:
441
    cmp  byte[workmode],sSokonex
442
    jne  no_chl
443
    call check_lasers   ; Sokonex game
444
  no_chl:
445
    mov  eax,13         ; clear field area
446
    mov  edx,WND_COLOR
447
    mov  edi,[levptr]
448
    movzx ebx,byte[edi+1]
449
    shl  ebx,4
450
    lea  ebx, [FLD_LEFT2+ebx]
451
    movzx ecx,byte[edi+2]
452
    shl  ecx,4
453
    lea  ecx, [FLD_TOP shl 16+ecx]
454
    int  0x40
455
 
456
    mov  edx, FLD_LEFT2+FLD_TOP
457
    movzx edi,byte[edi+1]
458
    shl  edi,20
459
    add  edi, FLD_LEFT2
460
 
461
    xor  eax,eax
462
    mov  ecx,[fld_size]
463
    mov  esi,field
464
  fld_cycle:
465
    lodsb
466
    call draw_img
467
    add  edx,SHIFT
468
    cmp  edx,edi
469
    jl  no_nl
470
    add  edx,16
471
    and  edx,0xffff
472
    add  edx,FLD_LEFT2
473
  no_nl:
474
    loop fld_cycle
475
    cmp  byte[workmode],sSokonex
476
    jne  end_of_df
477
    call draw_lasers
478
  end_of_df:
479
    ret
480
 
481
;   *********************************************
482
;   *********** DRAW CELL IMAGE *****************
483
;   *********************************************
484
 
485
draw_img:               ; in: eax-object index, edx-coordinates
486
    pusha
487
    cmp  eax,tWall
488
    jbe  no_adjust
489
    cmp  [workmode],sSokolor
490
    jne  no_di_color
491
    add  eax,pm_col-pm_nex
492
    jmp  no_adjust
493
  no_di_color:
494
    cmp  [workmode],sSokonex
495
    jne  no_adjust
496
    inc  eax
497
  no_adjust:
498
    movzx  ebx,byte [pic_map+eax]
499
    cmp  ebx,0xf
500
    je   no_img
501
  bl_place:
502
    mov  ecx, IMG_SIZE
503
    imul ebx, 256*3
504
    add  ebx,strip
505
    mov  eax,7          ; draw_image sysfunc
506
    int  0x40
507
  no_img:
508
    popa
509
    ret
510
 
511
;****************************************
512
;******* DRAW CONTENTS OF INPUT LINE ****
513
;****************************************
514
draw_input:
515
    push edi
516
    cmp  eax,4
517
    jne  highlight
518
    mov  esi,WND_COLOR
519
    jmp  di_draw
520
  highlight:
521
    mov  esi,0xe0e0e0
522
  di_draw:
523
    mov  eax,8
524
    mov  ebx,INP_X
525
    mov  ecx,INP_Y
526
    mov  edx,2
527
    int  0x40
528
    mov  eax,4
529
    mov  ecx,0x00107a30            ; шрифт 1 и цвет ( 0xF0RRGGBB )
530
    mov  ebx,INP_XY
531
    mov  edx,fn_input
532
    mov  esi,[inp_pos]
533
    int  0x40
534
    pop  edi
535
    ret
536
 
537
;   ********************************************************
538
;   * DECOMPRESS LEVEL & FILL SOME TABLES TO CHECK VICTORY *
539
;   ********************************************************
540
 
541
decode_field:
542
;    debug_print <13,10>
543
    xor  eax,eax
544
    mov  dword[checkpoint],eax
545
    mov  dword[checkpoint+4],eax
546
    mov  byte[checkcount],al
547
    mov  edi,[levptr]
548
    mov  dl,[edi]
549
    mov  [workmode],dl
550
    movzx  edx,byte[edi+1]
551
    mov  esi,edx
552
    shl  esi,4
553
    add  esi,FLD_LEFT*2-25
554
    mov  [wnd_width],esi
555
    neg  edx
556
    mov  [move_map+8],edx
557
    neg  edx
558
    mov  [move_map+4],edx
559
    movzx eax,byte[edi+2]
560
    mov  esi,eax
561
    shl  esi,4
562
    add  esi,FLD_TOP*2-18
563
    mov  [wnd_height],esi
564
    imul edx,eax
565
    mov  [fld_size],edx
566
    lea  esi,[edi+4]
567
    movzx ecx,byte[edi+3]
568
    add  esi,ecx
569
    cmp  byte[esi],0xff
570
    je   backto_set
571
    xor  edi,edi
572
    cld
573
 dec_cycle:
574
    lodsb
575
    movzx ecx,al
576
    and  ecx,0xf                   ; ecx-count of objects
577
    shr  al,4                      ; eax-index of object
578
    inc  ecx
579
    sub  edx,ecx
580
  dc_cycle:
581
    mov  [field+edi],al
582
    call chk_win_obj
583
    jne  no_register
584
    push eax ecx esi
585
    movzx ecx,al
586
    shl  eax,12
587
    or   eax,edi
588
    inc  byte[checkcount]
589
    cmp  [workmode],sSokolor
590
    jne  chk_sokoban
591
;    debug_print ':'
592
;    debug_print_dec ecx
593
    sub  ecx,tRedB
594
    shl  ecx,1
595
    cmp  word[checkpoint+ecx],0
596
    jnz  no_new_check
597
    mov  [checkpoint+ecx],ax
598
    and  eax,0xfff
599
;    debug_print_dec eax
600
    jmp  no_new_check
601
  chk_sokoban:
602
    cmp  [workmode],sSokonex
603
    jne  no_nex
604
    cmp  byte[checkcount],1
605
    ja   no_new_check
606
  no_nex:
607
    movzx ecx,byte[checkcount]
608
    mov  word[checkpoint-2+ecx*2],ax
609
  no_new_check:
610
    pop  esi ecx eax
611
  no_register:
612
    inc  edi
613
    loop dc_cycle
614
    cmp  edx,0
615
    jg   dec_cycle
616
    mov  ecx,[fld_size]
617
    xor  edx,edx
618
  fp_cycle:
619
    mov  al,[field+edx]
620
    and  al,0xfe
621
    cmp  al,tPlayer
622
    je   pl_found
623
    inc  edx
624
    loop fp_cycle
625
  pl_found:
626
    mov  [player],dx
627
    movzx eax,byte[checkcount]
628
;    debug_print_dec eax
629
    ret
630
 
631
;   *********************************************
632
;   * WHETHER OBJECT IS VICTORY DEPENDENT *******
633
;   *********************************************
634
 
635
chk_win_obj:             ; al-object in a cell
636
    push ecx eax
637
    and  al,0xf
638
    mov  cl,[workmode]
639
    cmp  cl,sSokoban
640
    jne  nota_sokoban
641
    cmp  al,tBlock
642
    jmp  cwo_exit
643
  nota_sokoban:
644
    cmp  cl,sSokonex
645
    jne  nota_sokonex
646
    cmp  al,tConnect
647
    je   cwo_exit
648
    cmp  al,tStConnect
649
    jmp  cwo_exit
650
  nota_sokonex:
651
    push eax
652
    and  eax,tRedB
653
    cmp  eax,tRedB
654
    pop  eax
655
  cwo_exit:
656
    pop  eax ecx
657
    ret
658
 
659
;   *********************************************
660
;   ***** GET CELL AT CERTAIN DIRECTION *********
661
;   *********************************************
662
 
663
get_cell_at:            ; in:  dx - current cell, cl - direction
664
    mov  ebx,edx        ; out: al - object at direction, bx - new position
665
    movzx eax,cl
666
    and  eax,11b
667
    mov  eax, [move_map+eax*4]
668
    add  ebx,eax
669
    mov  al,[field+ebx]
670
    ret
671
 
672
;   *********************************************
673
;   *** WHETHER A MOVE CAN BE DONE, & DO IT *****
674
;   *********************************************
675
 
676
valid_move:                         ; in:  dx - current cell, cl - direction
677
    push edx esi
678
    call get_cell_at                ; if ch>0 perform all moves
679
    cmp  al,tWall
680
    jb   result_ok
681
    je   vm_exit
682
    cmp  [workmode],sSokonex
683
    jne  n_vm_nex
684
    cmp  al,tStConnect
685
    je   vm_exit
686
    cmp  al,tHole
687
    je   vm_exit
688
  n_vm_nex:
689
    push edx ebx
690
    mov  edx,ebx
691
    movzx esi,al
692
    call get_cell_at
693
    cmp  al,tPlace
694
    jbe  push_it
695
    cmp  [workmode],sSokonex
696
    jne  no_plate
697
    cmp  al,tHole
698
    jne  no_plate
699
    cmp  esi,tBroken
700
    jae  vm_sink
701
    cmp  esi,tPlate
702
    jne  no_plate
703
    and  byte[field+ebx],0
704
  vm_sink:
705
    and  byte[field+edx],0
706
    jmp  vm_hole
707
  no_plate:
708
    pop  ebx edx esi edx
709
    ret
710
  push_it:
711
    call do_move
712
  vm_hole:
713
    pop  ebx edx
714
  result_ok:
715
    call do_move
716
    xor  al,al
717
  vm_exit:
718
    pop  esi edx
719
    ret
720
 
721
;   *********************************************
722
;   ******* ACTUALLY PERFORM MOVES **************
723
;   *********************************************
724
 
725
do_move:                            ; in: dx - source cell
726
    test ch,ch                      ;     bx - target cell
727
    jz   dm_exit                    ;     ch = 0 don't perform moves
728
    mov  al,byte[field+edx]
729
    cmp  byte[workmode],sSokoban
730
    jne  no_dm_ban
731
    and  al,0xfe
732
  no_dm_ban:
733
    xor  byte[field+edx],al
734
    or   byte[field+ebx],al
735
    call chk_win_obj
736
    jne  no_check_win
737
    pusha
738
    movzx ecx,byte[checkcount]
739
    xor  edi,edi
740
  dm_cycle:
741
    movzx esi,word[checkpoint+edi*2]
742
    and  esi,0xfff
743
    and  edx,0xfff
744
    cmp  esi,edx
745
    jnz  not_an_obj
746
    movzx eax,dl
747
    movzx eax,byte[field+ebx]
748
    shl  eax,12
749
    or   eax,ebx
750
    mov  word[checkpoint+edi*2],ax
751
    jmp  dm_ex
752
  not_an_obj:
753
    inc  edi
754
    loop dm_cycle
755
  dm_ex:
756
    popa
757
    call check_win
758
    jne  no_check_win
759
    mov  byte[winmode],WM_WINNER
760
  no_check_win:
761
    cmp  al,tPlayer
762
    jne  dm_exit
763
    mov  [player],bx
764
  dm_exit:
765
    ret
766
 
767
;   *********************************************
768
;   ******* CHECK VICTORY CONDITIONS ************
769
;   *********************************************
770
 
771
check_win:
772
;    debug_print <13,10>
773
    push eax ebx ecx esi
774
    xor  eax,eax
775
    movzx ecx,byte[checkcount]
776
    mov  esi,checkpoint
777
    mov  bl,byte[workmode]
778
    xor  bh,bh
779
    mov  [colcount],bh
780
    cld
781
  cw_cycle:
782
    lodsw
783
    cmp  bl,sSokoban
784
    jne  nocw_sokoban
785
    test ax,1 shl 12
786
    jz   cw_not_inplace
787
    inc  bh
788
  cw_not_inplace:
789
    loop cw_cycle
790
;    movzx eax,bh
791
    cmp  [checkcount],bh
792
    jmp  cw_exit
793
  nocw_sokoban:
794
    cmp  bl,sSokonex
795
    jne  nocw_sokonex
796
    mov  dx,ax
797
    call scan_root
798
    cmp  al,[checkcount]
799
    jmp  cw_exit
800
 
801
  nocw_sokonex:
802
    cmp  esi,checkpoint+8
803
    ja   cwlor_exit
804
;    debug_print '*'
805
    test ax,ax
806
    jz   cw_cycle
807
    mov  dx,ax
808
    call scan_root
809
    add  [colcount],al
810
;    debug_print '*->'
811
;    debug_print_dec eax
812
    jmp  cw_cycle
813
  cwlor_exit:
814
    mov  al,[colcount]
815
    cmp  al,[checkcount]
816
  cw_exit:
817
;    debug_print <13,10>
818
    pop esi ecx ebx eax
819
    ret
820
 
821
;   *********************************************
822
;   **** WHETHER LASERS DESTROY SOMETHING *******
823
;   *********************************************
824
 
825
check_lasers:
826
    pusha
827
    xor  edx,edx
828
    mov  ecx,[fld_size]
829
  cl_loop:
830
    push ecx edx
831
    mov  cl,[field+edx]
832
    sub  cl,tLaserW
833
    jl   cl_exit
834
  cl_begin:
835
    call get_cell_at
836
    cmp  al,tLaserW
837
    jae  cl_destroy
838
    cmp  al,tBroken
839
    je   cl_destroy
840
    cmp  al,tEmpty
841
    je   no_cl_destroy
842
    cmp  al,tHole
843
    je   no_cl_destroy
844
    cmp  al,tPlayer
845
    jne  cl_exit
846
    mov  ecx,0x20ac0000
847
    mov  edx,lose_msg
848
    mov  esi,lose_msg_end-lose_msg  ; print loose message
849
    mov  byte[winmode],WM_LOSE
850
    mov  ebx,WIN_XY
851
    mov  eax,4
852
    int  0x40
853
    jmp  cl_exit
854
  cl_destroy:
855
    mov  byte[field+ebx],0
856
  no_cl_destroy:
857
    mov  edx,ebx
858
    jmp  cl_begin
859
  cl_exit:
860
    pop  edx ecx
861
    inc  edx
862
    loop cl_loop
863
    popa
864
    ret
865
 
866
;   *********************************************
867
;   *** USED BY CHECK_WIN IN SOKONEX & SOKOLOR **
868
;   *********************************************
869
 
870
scan_root:                ; input:   dx-beginning cell, ebx-what to search
871
    push esi
872
    mov  edi,srch         ; output:  eax-number of win_obj found
873
    mov  eax,0xfff
874
    movzx ecx,[checkcount]
875
    inc  ecx
876
    cld
877
    rep  stosw            ; clearing area for scan
878
    movzx ebx,dx
879
    and  edx,eax          ; dx-cell number to compare with
880
    shr  ebx,12           ; bl-obj id
881
    mov  [color],bl
882
    mov  esi,srch
883
    mov  edi,eax          ; mask to extract cell
884
    mov  word[srch],dx
885
  sr_loop:
886
    lodsw
887
    push esi              ; saving scan pointer
888
       movzx edx,ax       ; edx-[dirs*4][cell*12]
889
       and  edx,edi
890
;       debug_print ' >'
891
       mov  ecx,4
892
  sr_dir_loop1:
893
;       debug_print '.'
894
       push ecx           ; saving dir counter
895
         lea  ebx,[ecx+11]
896
         bts  word[esi-2],bx
897
         jc   sr_endloop      ; this entry is already processed
898
;         debug_print '^'
899
         dec  ecx             ; cl-direction
900
         call get_cell_at     ; bx-new position, al-object
901
;         cmp  [workmode],sSokonex
902
;         jne  no_sr_nex
903
         call chk_win_obj
904
         jne  sr_endloop      ; not a win_obj there
905
;         debug_print '@'
906
         cmp  [workmode],sSokolor
907
         jne  no_sr_lor
908
         cmp  al,[color]
909
         jne  sr_endloop
910
       no_sr_lor:
911
         push esi
912
         mov  esi,srch        ; let us search for existing entries
913
       sr_loop1:
914
         lodsw
915
         and  eax,edi         ; eax-cell w/o dirs
916
         cmp  eax,ebx
917
         je   sr_foundentry   ; this is the entry we're seeking for
918
         cmp  word[esi],0xfff
919
         jnz  sr_loop1        ; next entry
920
    ; we reached empty area
921
         mov  [esi],bx
922
         add  esi,2
923
       sr_foundentry:
924
         mov  eax,15
925
         sub  eax,ecx
926
         bts  [esi-2],ax      ; mark entry as used
927
         pop  esi
928
;         inc  [e_fnd]         ; one more obj found
929
     sr_endloop:
930
       pop  ecx
931
       loop sr_dir_loop1
932
;       jmp  tttt
933
;     sr_dir_loop:
934
;       jmp  sr_dir_loop1
935
;     tttt:
936
    pop esi
937
    cmp  word[esi],0xfff
938
    jne  sr_loop
939
    mov  eax,esi
940
    sub  eax,srch
941
    shr  eax,1
942
    pop  esi
943
;    debug_print_dec eax
944
    ret
945
 
946
;   *********************************************
947
;   *** SPECIAL ROUTINE TO DRAW LASERS **********
948
;   *********************************************
949
 
950
draw_lasers:
951
    xor  edx,edx
952
    mov  ecx,[fld_size]
953
  dl_loop:
954
    push ecx edx
955
    mov  cl,[field+edx]
956
    sub  cl,tLaserW
957
    jl   dl_eloop
958
    inc  ch
959
  dl_gca:
960
    call get_cell_at
961
    cmp  al,tEmpty
962
    je   dl_draw
963
    cmp  al,tHole
964
    jne  dl_eloop
965
  dl_draw:
966
    call draw_beams
967
    mov  edx,ebx
968
    jmp  dl_gca
969
  dl_eloop:
970
    pop  edx
971
    inc  edx
972
    pop  ecx
973
    loop dl_loop
974
    ret
975
 
976
;   *********************************************
977
;   *** DRAWS LASER BEAMS IN CERTAIN DIRECTION **
978
;   *********************************************
979
 
980
draw_beams:
981
    pusha
982
    mov esi,[levptr]
983
    movzx esi,byte[esi+1]
984
    mov  eax,ebx
985
    xor  edx,edx
986
    div  esi
987
    movzx esi,cl
988
    dec  esi
989
    shr  esi,1
990
    and  esi,1
991
    shl  edx,20
992
    mov  ebx,edx
993
    shl  eax,20
994
    mov  ecx,eax
995
    add  ebx,dword[beam_xy+esi*8]
996
    add  ecx,dword[beam_xy+esi*8+4]
997
    mov  edx,0xe9e25c
998
    mov  eax,13
999
    int  0x40
1000
    popa
1001
    ret
1002
 
1003
ud:
1004
   ud2  ; debugging purposes only
1005
 
1006
 
1007
;   *********************************************
1008
;   *** COMPRESS LEVEL - NOT READY YET **********
1009
;   *********************************************
1010
 
1011
;    push    esi ebx ;ecx
1012
;    xchg    ebx,edi
1013
;    mov     esi,edi                 ; esi,edi - beginning
1014
;; ebx - end of unpacked field
1015
;  first_enc:
1016
;    lodsb                           ; al - first byte
1017
;    shl     ax,8                    ; ah - this byte, al=0
1018
;  next_enc:
1019
;    cmp     esi,ebx
1020
;    jae     exit_enc
1021
;;    movzx   ecx,byte[esi]
1022
;;    debug_print_dec ecx
1023
;    cmp     ah,byte[esi]
1024
;    jne     newchar
1025
;    inc     esi
1026
;    inc     al
1027
;    cmp     al,15
1028
;    jb      next_enc
1029
;  newchar:
1030
;    shl     al,4
1031
;    shr     ax,4
1032
;    stosb
1033
;    jmp     first_enc
1034
;  exit_enc:
1035
;    shl     al,4
1036
;    shr     ax,4
1037
;    stosb
1038
;    mov     al,0xff
1039
;    stosb
1040
;    pop     ebx esi ecx
1041
;
1042
;    dec     ecx
1043
;    jcxz    outcycle
1044
;    jmp     next_lev
1045
;  outcycle:
1046
 
1047
 
1048
; Здесь находятся данные программы:
1049
 
1050
; интерфейс программы двуязычный - задайте язык в macros.inc
1051
load_char:
1052
if lang eq ru
1053
     db 'Загрузить'
1054
else
1055
     db 'Open file'
1056
end if
1057
loadlen:
1058
 
1059
ll_msg:
1060
if lang eq ru
1061
     db 'Выберите уровень'
1062
else
1063
     db 'Choose a level'
1064
end if
1065
     db ' (0-9, PgUp, PgDn)'
1066
ll_msg_end:
1067
 
1068
fn_input:
1069
;   db 'cnf'
1070
;    db 'soko-4.lev'
1071
if lang eq ru
1072
     db 'или введите имя файла'
1073
else
1074
     db 'or enter a filename'
1075
end if
1076
inp_end:
1077
     rb 256-(inp_end-fn_input)
1078
 
1079
win_msg:
1080
if lang eq ru
1081
     db 'Ура!!! Вы прошли уровень!'
1082
else
1083
     db "You've completed the level!"
1084
end if
1085
win_msg_end:
1086
 
1087
lose_msg:
1088
if lang eq ru
1089
     db 'Вы парализованы! Проигрыш...'
1090
else
1091
     db "You're paralized! Game over..."
1092
end if
1093
lose_msg_end:
1094
 
1095
zagolovok:               ; строка заголовка
1096
if lang eq ru
1097
     db   'СОКОБАН ДЛЯ'
1098
else
1099
     db   'SOKOBAN FOR'
1100
end if
1101
     db   ' MENUET'
1102
zag_konets:              ; и её конец
1103
 
1104
pic_map:
1105
    db 0xf,9,0,0,1,1,5,6
1106
pm_nex:
1107
    db 2,7,8,3,4,0xa,0xa,0xa,0xa
1108
pm_col:
1109
    db 0xb,0xc,0xd,0xe
1110
 
1111
beam_xy:
1112
    dd (FLD_LEFT+7) shl 16+2, FLD_TOP2+16
1113
    dd FLD_LEFT2+16, (FLD_TOP+7) shl 16+2
1114
 
1115
ll_num db '00x.'
1116
 
1117
move_map dd -1,+0,-0,1      ; 0 - W, 1 - S, 2 - N, 3 - E
1118
 
1119
stdlev     db 'SOKO-0.LEV',0
1120
stdlev_len:
1121
 
1122
inp_pos    dd inp_end-fn_input
1123
entered    dd 0
1124
 
1125
file_info:
1126
           dd 0
1127
           dd 0
1128
           dd 0x100
1129
cnf_level  dd strip
1130
           dd workarea
1131
file_name  db CUR_DIR
1132
path_end   db 'SKIN.'
1133
file_num   db 'RAW',0
1134
 
1135
           rb 256-($-file_name)
1136
 
1137
I_END:  ; конец программы
1138
 
1139
winmode db ?
1140
scanptr dd ?
1141
levpage dd ?
1142
workmode db ?
1143
player dw ?
1144
fld_size dd ?
1145
levptr dd ?
1146
wnd_height dd ?
1147
wnd_width dd ?
1148
color  db ?
1149
colcount db ?
1150
levelcount dd ?
1151
checkcount db ?
1152
checkpoint:
1153
    times 256 dw ?
1154
levelmap:
1155
    times 1024 dd ?
1156
strip rb SKIN_SIZE
1157
 
1158
workarea:
1159
  srch  rb 0x10000-($-workarea)
1160
 
1161
level_start rb 0x20000
1162
field: