Subversion Repositories Kolibri OS

Rev

Rev 1934 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

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