Subversion Repositories Kolibri OS

Rev

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