Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  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         ; <Space> = Shuffle
  116.     je   SHUF
  117.     cmp  eax,13         ; <Enter> = 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: