Subversion Repositories Kolibri OS

Rev

Rev 2681 | Go to most recent revision | 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 0x02ffffff
  11. StatusColor2 equ 0x02dc1e14
  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 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.     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.