Subversion Repositories Kolibri OS

Rev

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