Subversion Repositories Kolibri OS

Rev

Rev 485 | 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. include 'lang.inc'
  7. include '..\..\..\macros.inc' ; decreases program size (not required)
  8.  
  9. StatusColor equ 0x02ffffff
  10. StatusColor2 equ 0x02dc1e14
  11. BgdColor equ 0x04aabbcc
  12.  
  13. ; Main window dimensions
  14. XXwindow equ 200 shl 16+276
  15. YYwindow equ 200 shl 16+300
  16. ; Status bar
  17. XYstatus equ 35 shl 16+283
  18. XXbar equ 35 shl 16+136
  19. YYbar equ 280 shl 16+15
  20. ; Buttons
  21. BtnTop equ 28
  22. BtnLeft equ 13
  23. BtnSize equ 60
  24. BtnColor equ 0xafbb55
  25. BtnColor2 equ 0x0228c314
  26.  
  27. NumColor equ 0x10000000
  28. ; Number shifting for nice look
  29. NumShift equ 24 shl 16+27
  30. NumShift2 equ 4 shl 16
  31. ; Shuffle button
  32. XXSh equ 202 shl 16+60
  33. YYSh equ 280 shl 16+12
  34. XYShText equ 212 shl 16+283
  35.  
  36. ; Conf button
  37. XXCnf equ 13 shl 16+13
  38. YYCnf equ 280 shl 16+12
  39. XYCnfText equ 18 shl 16+283
  40.  
  41. ; Position of the 'hole'
  42. null equ (curconf+16)
  43. ; Amount of moves to perform shuffle
  44. SH_CYCLES equ 400
  45. ; (Amount of tasks)-1
  46. CONF_COUNT equ 2
  47.  
  48. use32
  49.  
  50.   org    0x0
  51.  
  52.   db     'MENUET01'
  53.   dd     0x01
  54.   dd     START
  55.   dd     I_END
  56.   dd     0x2000  ; 8 Kb
  57.   dd     0x2000
  58.   dd     0x0
  59.   dd     0x0
  60.  
  61.  
  62. START:
  63.     mov  [cptr],CONF_COUNT  ; number of task
  64.     mov  eax,3
  65.     mcall
  66.     mov  cl,16
  67.     ror  eax,cl
  68.     mov  [generator],eax    ; random generator from Tetris
  69.   init:
  70.     mov  ecx,17
  71.     movzx  eax,[cptr]
  72.     inc  eax
  73.     cmp  eax,CONF_COUNT
  74.     jna  init_ok
  75.     xor  eax,eax            ; cycling 0..CONF_COUNT
  76.   init_ok:
  77.     mov  [cptr],al
  78.     mov  esi,eax
  79.     shl  esi,4
  80.     add  esi,conf
  81.     add  esi,eax
  82.     add  al,0x31
  83.     mov  [lenTitle-1],al     ;task number to program title
  84.     mov  [task],esi
  85.     mov  edi,curconf
  86.     rep  movsb          ; initial configuration
  87.  
  88.     mov  [sts],4
  89.     jmp  red
  90. SHUF:
  91.     call shuffle        ; immediate shuffle
  92. red:                    ; window redraw
  93.  
  94.     call draw_window
  95.  
  96. still:                  ; MAIN PROGRAM CYCLE
  97.  
  98.     mov  eax,10         ; wait for event
  99.     mcall
  100.  
  101.     cmp  eax,1          ; redraw? -
  102.     je   red            ; goto red
  103.     cmp  eax,2          ; key pressed? -
  104.     je   key            ; goto key
  105.     cmp  eax,3          ; button pressed? -
  106.     je   button         ; goto button
  107.  
  108.     jmp  still          ; no more events to process
  109.  
  110.   key:                  ; Key pressed
  111.     mov  eax,2
  112.     mcall
  113.     shr  eax,8
  114.     cmp  eax,32         ; <Space> = Shuffle
  115.     je   SHUF
  116.     cmp  eax,13         ; <Enter> = Choose task
  117.     je   init
  118.     cmp  eax,176
  119.     jl   still
  120.     sub  eax,176
  121.     cmp  eax,3
  122.     ja   still
  123.     movzx eax,byte [eax+correct] ; 'delta' value from correct[]
  124.     jmp  m_check
  125.  
  126.   button:              ; Button pressed
  127.     mov  eax,17
  128.     mcall
  129.     shr  eax,8
  130.     sub  eax,2
  131.  
  132.     cmp  eax,-1        ; id == 1 (closeme)?
  133.     jne  noclose
  134.     mcall
  135.  
  136.   noclose:
  137.     jl   SHUF          ; Shuffle (id=0) pressed
  138.     cmp  eax,18
  139.     je   init          ; Conf button pressed
  140.     sub  al,byte [null]
  141.     mov  edi,correct
  142.     mov  ecx,4
  143.     repne scasb        ; checking for valid move-part 1
  144.     jne  fail
  145.   m_check:
  146.     cmp  byte[sts],4 ; puzzle completed, blocking buttons
  147.     ja   still
  148.     call move_check    ; checking for valid move-part 2
  149.     jnc  fail
  150.     inc  [move_count]
  151.     call draw_moves
  152. fail:
  153.     jmp  still          ; возвращаемся
  154.  
  155. ;   *******************************
  156. ;   *******  WINDOW DRAWING *******
  157. ;   *******************************
  158.  
  159. draw_window:
  160.     mov  eax,12
  161.     mov  ebx,1                     ; begin draw
  162.     mcall
  163.  
  164.                                    ; CREATING WINDOW
  165.     mov  eax,0
  166.     mov  ebx,XXwindow
  167.     mov  ecx,YYwindow
  168.     mov  edx,BgdColor
  169.     mov  esi,0x805080d0
  170.     mov  edi,0x005080d0
  171.     mcall
  172.  
  173.                                    ; PROGRAM TITLE
  174.     mov  eax,4
  175.     mov  ebx,8*65536+8
  176.     mov  ecx,0x10000000
  177.     mov  edx,txtTitle
  178.     mov  esi,lenTitle-txtTitle
  179.     mcall
  180.  
  181.     mov  eax,8                     ; SHUFFLE BUTTON
  182.     mov  ebx,XXSh
  183.     mov  ecx,YYSh
  184.     xor  edx,edx
  185.     mov  esi,BtnColor
  186.     mcall
  187.  
  188.     mov  ebx,XXCnf                  ; CONF BUTTON
  189.     mov  ecx,YYCnf
  190.     mov  edx,20
  191.     mov  esi,BtnColor
  192.     mcall
  193.  
  194.     mov  ebx, XYShText             ; SHUFFLE TEXT
  195.     mov  ecx, StatusColor
  196.     mov  edx,txtSh
  197.     mov  esi,lenSh-txtSh
  198.     mov  eax,4
  199.     mcall
  200.  
  201.     mov  ebx, XYCnfText             ; CONF TEXT
  202.     mov  edx,lenVictory-1
  203.     mov  esi,1
  204.     mcall
  205.  
  206.     mov  ecx, 16                   ; FIELD BUTTONS
  207.   dbut:
  208.     call draw_button
  209.     loop dbut
  210.  
  211.     call draw_moves
  212.  
  213.     mov  eax,12
  214.     mov  ebx,2                     ; end of drawing
  215.     mcall
  216.     ret
  217.  
  218.  
  219. ;   *********************************************
  220. ;   ******* DRAWING A FIELD BUTTON **************
  221. ;   *********************************************
  222. ;   ECX - button number
  223.  
  224. draw_button:
  225.     pusha
  226.     dec  ecx
  227.   ; calculating button dimensions
  228.     mov  edi, ecx
  229.     lea  edx,[ecx+2]
  230.     mov  ebx,ecx
  231.     and  ebx,11b
  232.     shr  ecx,2
  233.  
  234.     imul ebx,BtnSize+3
  235.     add  ebx,BtnLeft
  236.     shl  ebx,16
  237.     add  ebx,BtnSize
  238.  
  239.     imul ecx,BtnSize+3
  240.     add  ecx,BtnTop
  241.     shl  ecx,16
  242.     add  ecx,BtnSize
  243.     movzx eax,byte [null]
  244.     cmp  eax,edi
  245.     jne   no_hole
  246.  
  247.     pusha
  248.     inc  ebx
  249.     inc  ecx
  250.     mov  edx,BgdColor
  251.     mov  eax,13         ; clearing - 'hole'
  252.     mcall
  253.     popa
  254.  
  255.     or   edx,0x80000000 ; and removing button under it
  256. no_hole:
  257.     mov  al,byte[edi+curconf]
  258.     mov  esi,[task]
  259.     cmp  al,byte[edi+esi]
  260.     je   highlight
  261.     mov  esi,BtnColor
  262.     jmp  s_rbutton
  263. highlight:
  264.     mov  esi,BtnColor2
  265. s_rbutton:
  266.     mov  eax,8          ; set/remove button
  267.     mcall
  268.     movzx eax,byte [null]
  269.     cmp  eax,edi
  270.     je   no_text        ; no digits - that's hole
  271.     mov  edx,ebx
  272.     shr  ecx,16
  273.     mov  dx,cx
  274.     add  edx,NumShift
  275.     mov  ebx,0x20000
  276.     movzx  ecx,byte [edi+curconf]
  277.     cmp  ecx,9
  278.     ja   two_num
  279.     add  edx,NumShift2    ; shift to center digits
  280.     sub  ebx,0x10000
  281. two_num:
  282.     mov  esi,NumColor
  283.     mov  eax,47
  284.     mcall
  285. no_text:
  286.     popa
  287.     ret
  288.  
  289.  
  290. ;   *********************************************
  291. ;   ******* DRAWING STATUS LINE *****************
  292. ;   *********************************************
  293.  
  294. draw_moves:
  295.     mov  eax, 13          ; clear area
  296.     mov  ebx, XXbar
  297.     mov  ecx, YYbar
  298.     mov  edx, BgdColor
  299.     mcall
  300.  
  301.     mov  eax, 4
  302.     mov  ebx, XYstatus
  303.     mov  ecx, StatusColor
  304.     cmp  ax, [sts]
  305.     jl   report_victory
  306.     jne  report_moves
  307.     mov  edx,txtCnf  ; prompt to choose configuration
  308.     mov  esi,lenCnf-txtCnf
  309.     jmp  e_dm
  310.   report_moves:
  311.     mov  edx,txtMoves  ; how many moves done
  312.     mov  esi,lenMoves-txtMoves
  313.     mov  eax,4
  314.     mcall
  315.     mov  esi,ecx
  316.     mov  edx,ebx
  317.     add  edx, 40 shl 16
  318.     mov  ebx,0x030000
  319.     movzx  ecx, byte[move_count]
  320.     mov  eax,47
  321.     jmp  e_dm
  322.   report_victory:               ; puzzle completed
  323.     mov  ecx,StatusColor2
  324.     mov  edx,txtVictory
  325.     mov  esi,lenVictory-txtVictory
  326.   e_dm:
  327.     mcall
  328.     ret
  329.  
  330.  
  331. ;   *********************************************
  332. ;   ********* SHUFFLE ***************************
  333. ;   *********************************************
  334.  
  335. shuffle:
  336.     xor  eax,eax
  337.     mov  [sts],ax
  338.     mov  [move_count],ax   ; reset moves to 0
  339.     mov  [sh_off],al
  340.     mov  eax, [generator]
  341.  
  342.     mov  ecx,SH_CYCLES
  343.  sh_cycle:
  344.     sub  eax,0x43ab45b5    ; next random number
  345.     ror  eax,1
  346.     xor  eax,0x32c4324f
  347.     ror  eax,1
  348.     mov  [generator],eax
  349.  
  350.     push eax
  351.     and  eax,11b           ; direction 0..3
  352.     movzx eax,byte [eax+correct]
  353.     call move_check
  354.     pop  eax
  355.     jnc  sh_cycle          ; if fails then retry
  356.     loop sh_cycle
  357.     inc  byte[sh_off]          ; shuffling complete
  358.     ret
  359.  
  360.  
  361. ;   *********************************************
  362. ;   ********* MOVE VALIDITY CHECK ***************
  363. ;   *********************************************
  364. ;   AL - 'DELTA' DIRECTION
  365.  
  366. move_check:
  367.     pusha
  368.     mov  ah,byte [null]
  369.     mov  bx,ax
  370.     cmp  bh,3
  371.     ja   no_top
  372.     cmp  al,-4       ; top of field
  373.     je   no_move
  374. no_top:
  375.     cmp  bh,12
  376.     jb   no_bottom
  377.     cmp  al,4        ; bottom of field
  378.     je   no_move
  379. no_bottom:
  380.     and  bh,11b
  381.     cmp  bh,0
  382.     jnz  no_left
  383.     cmp  al,-1       ; left of field
  384.     je  no_move
  385. no_left:
  386.     cmp  bh,11b
  387.     jnz  ok
  388.     cmp  al,1        ; right of field
  389.     je  no_move
  390. ok:
  391.     mov bx,ax
  392.     add bh,bl        ; bh-new hole
  393.     mov byte [null],bh
  394.     movzx ecx,ah
  395.     mov al,byte[ecx+curconf]
  396.     movzx edx,bh
  397.     mov bl,byte[edx+curconf] ; swapping button & hole
  398.     mov byte[ecx+curconf],bl
  399.     mov byte[edx+curconf],al
  400.  
  401.     cmp  byte[sh_off],0  ; if shuffle in progress,
  402.     jz   no_win      ; then no redraw
  403.  
  404.   ; drawing button & hole
  405.     inc  ecx
  406.     call draw_button
  407.     movzx ecx,bh
  408.     inc  ecx
  409.     call draw_button
  410.   ; testing if task completed
  411.     mov  esi,[task]
  412.     mov  edi,curconf
  413.     mov  ecx,16
  414.     repe cmpsb
  415.     cmp  ecx,0
  416.     jne  no_win
  417.     mov  word[sts],6  ; puzzle done. Victory!
  418. no_win:
  419.     popa
  420.     stc
  421.     ret
  422. no_move:
  423.     popa
  424.     clc
  425.     ret
  426. ; this is deprecated debug routine
  427. ;ud:
  428. ;    ud2
  429.  
  430. ; These are data used by program
  431.  
  432. correct db 1,-4,4,-1
  433.  
  434. conf db 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,0,15
  435.      db 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,0
  436.      db 1,2,3,4,12,13,14,5,11,0,15,6,10,9,8,7,9
  437.  
  438. txtMoves:
  439. if lang eq ru
  440.      db 'Ходов:'
  441. else
  442.      db 'Moves:'
  443. end if
  444. lenMoves:
  445.  
  446. txtSh:
  447. if lang eq ru
  448.      db 'Тасовка'
  449. else
  450.      db 'Shuffle'
  451. end if
  452. lenSh:
  453.  
  454. txtCnf:
  455. if lang eq ru
  456.      db 'Выберите задачу и нажмите->'
  457. else
  458.      db 'Select task,  then press ->'
  459. end if
  460. lenCnf:
  461.  
  462. txtTitle:               ; строка заголовка
  463. if lang eq ru
  464.      db   'Игра 15 - задача X'
  465. else
  466.      db   'Game 15 - puzzle X'
  467. end if
  468. lenTitle:                ; и её конец
  469.  
  470. txtVictory:
  471. if lang eq ru
  472.      db 'Вы решили задачу! Нажмите->'
  473. else
  474.      db 'Puzzle completed!   Press->'
  475. end if
  476. lenVictory:
  477.  
  478. arrow equ lenVictory-2
  479.  
  480. I_END:  ; конец программы
  481. ;null db ?
  482. move_count dw ?
  483. cptr db ?
  484. sts dw ?
  485. sh_off db ?
  486. task dd ?
  487. generator dd ?
  488. curconf: