Subversion Repositories Kolibri OS

Rev

Rev 1728 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ; <--- description --->
  2. ; compiler:     FASM 1.50
  3. ; name:         FreeCell for MeOS
  4. ; version:      1.00
  5. ; last update:  21/07/2004
  6. ; written by:   Alexandr Gorbovets
  7. ; e-mail:       gorsash@mail.ru
  8.  
  9.  
  10. include "../../macros.inc"
  11. include "lang.inc"
  12. meos_app_start
  13.  
  14. code
  15.    call    randomize
  16.    call    draw_window
  17.  
  18.   wait_event:
  19.     mov     eax, 10
  20.     mcall
  21.  
  22.     cmp     eax, 1           ;   if event == 1
  23.     je      redraw           ;     jump to redraw handler
  24.     cmp     eax, 2           ;   else if event == 2
  25.     je      key              ;     jump to key handler
  26.     cmp     eax, 3           ;   else if event == 3
  27.     je      button           ;     jump to button handler
  28.  
  29.  
  30.     jmp     wait_event  ;else return to the start of main cycle
  31.  
  32.  
  33.   redraw:                    ; redraw event handler
  34.     call    draw_window
  35.     jmp     wait_event
  36.  
  37.  
  38.   key:                       ; key event handler
  39.     mov     eax, 2           ;   get key code
  40.     mcall
  41.  
  42.     jmp     wait_event
  43.  
  44.   button:                    ; button event handler
  45.     mov     eax, 17          ;   get button identifier
  46.     mcall
  47.  
  48.     cmp     ah, 1
  49.     je      exit_app         ;   return if button id != 1
  50.  
  51.     cmp     ah, 1 + 8
  52.     jbe     common_card      ;   if 1 < ah <= 9
  53.  
  54.     cmp     ah, 1 + 8 + 4    ;   if 9 < ah <= 13
  55.     jbe     temp_cell
  56.  
  57.     cmp     ah, 1 + 8 + 8
  58.     jbe     home_cell
  59.  
  60.     cmp     ah, 1 + 8 + 4 + 4 + 1
  61.     je      new_game_button
  62.  
  63.     cmp     ah, 1 + 8 + 4 + 4 + 2
  64.     je      exit_app
  65.  
  66.  
  67.     jmp     wait_event
  68.  
  69.  
  70.   exit_app:
  71.     mov     eax, -1          ;   exit application
  72.     mcall
  73.  
  74.   common_card:
  75.     sub     ah, 2            ;going from number of card to number of column
  76.     mov     [columnclicked], 0
  77.     mov     byte [columnclicked], ah
  78.     call    common_card_click
  79.     jmp     wait_event
  80.  
  81.   temp_cell:
  82.     sub     ah, 2 + 8
  83.     mov     [columnclicked], 0
  84.     mov     byte [columnclicked], ah
  85.     call    temp_cell_click
  86.     jmp     wait_event
  87.  
  88.  
  89.   home_cell:
  90.     sub    ah, 2 + 8 + 4
  91.     mov    [columnclicked], 0
  92.     mov    byte [columnclicked], ah
  93.     call   home_cell_click
  94.     jmp    wait_event
  95.  
  96.   new_game_button:
  97.     call   new_game_click
  98.     jmp    wait_event
  99.  
  100.  
  101. ;******************************************************************************
  102. ;                            common_card_click(columnclicked)
  103.   common_card_click:
  104.  
  105.                              ; counting code of card, that has been clicked
  106.     mov    eax, [columnclicked]
  107.     mov    [ncolumn], eax
  108.     call   get_row_of_top_card_in_column
  109.     mov    eax, [topcardrow]  ; eax = topcardrow * 8 + columnofselcard
  110.     mov    bl, 8
  111.     mul    bl
  112.     add    eax, [columnclicked]
  113.     add    eax, cards
  114.  
  115.     mov    ebx, 0
  116.     mov    bl, byte [eax]
  117.     mov    [cardclicked], ebx
  118.  
  119.  
  120.     call   get_sel_card_code_and_addr
  121.  
  122.     cmp    [selcardcode], 52
  123.     jb      .something_selected
  124.  
  125.  
  126.     cmp    [cardclicked], 52
  127.     je      .end
  128.  
  129.     mov    [whereisselcard], scCommonCells
  130.     mov    eax, [columnclicked]
  131.     mov    [columnofselcard], eax
  132.     call   draw_window
  133.     jmp    .end
  134.  
  135.  
  136.     .something_selected:
  137.  
  138.  
  139.              ; checking if selected and clicked cards are equivalent
  140.       mov     eax, [selcardcode]
  141.       cmp     [cardclicked], eax
  142.       jne     .not_same_card
  143.  
  144.       mov     [whereisselcard], scNotSelected
  145.       call    draw_window
  146.       jmp     .end
  147.  
  148.     .not_same_card:
  149.  
  150.       cmp     [cardclicked], 52
  151.       jae     .put_in_blank_cell
  152.  
  153.  
  154.       mov     eax, [selcardcode]
  155.       mov     bl, 4
  156.       div     bl
  157.  
  158.       mov     ebx, 0
  159.       mov     bl, ah
  160.       mov     [cardfamily], ebx
  161.  
  162.       mov     ecx, 0
  163.       mov     cl, al
  164.       mov     [cardrange], ecx
  165.  
  166.  
  167.       mov     eax, [cardclicked]
  168.       mov     bl, 4
  169.       div     bl                     ; reminder in ah, quotient in al
  170.  
  171.       mov     ebx, 0
  172.       mov     bl, ah
  173.       mov     [clickedcardfamily], ebx
  174.  
  175.       mov     ecx, 0
  176.       mov     cl, al
  177.       mov     [clickedcardrange], ecx
  178.  
  179.                              ; clickedcardrange must be = cardrange + 1
  180.       mov     eax, [cardrange]
  181.       inc     eax
  182.  
  183.       cmp     [clickedcardrange], eax ; eax is such as needed
  184.       jne     .end
  185.  
  186.  
  187.       cmp     [cardfamily], 1
  188.       ja             .black_card
  189.  
  190.                              ; if selected red card
  191.       cmp     [clickedcardfamily], 1
  192.       jbe     .end             ; if clicked red card (range <= 1) then exit
  193.  
  194.       jmp     .valid_cards
  195.  
  196.     .black_card:
  197.                              ; if selected black card
  198.       cmp     [clickedcardfamily], 1
  199.       ja      .end             ; if clicked black card then exit
  200.  
  201.       jmp     .valid_cards
  202.  
  203.     .valid_cards:
  204.                       ; moving card from its place on clicked card
  205.  
  206.       mov     eax, [columnclicked]
  207.       mov     [ncolumn], eax
  208.       call    get_row_of_top_card_in_column
  209.       mov     eax, [topcardrow]
  210.       inc     eax
  211.  
  212.       mov     bl, 8
  213.       mul     bl
  214.  
  215.       and     eax, $0000FFFF
  216.       add     eax, [columnclicked]
  217.       add     eax, cards
  218.  
  219.       mov     bl, byte [selcardcode]
  220.       mov     byte [eax], bl
  221.  
  222.       mov     eax, [selcardaddr]
  223.       mov     byte [eax], 52
  224.  
  225.       mov     [whereisselcard], scNotSelected
  226.  
  227.       call    draw_window
  228.  
  229.       jmp     .end
  230.  
  231.       .put_in_blank_cell:
  232.  
  233.       mov     eax, cards
  234.       add     eax, [columnclicked]
  235.       mov     bl,  byte [selcardcode]
  236.       mov     byte [eax], bl
  237.  
  238.       mov     eax, [selcardaddr]
  239.       mov     byte [eax], 52
  240.  
  241.       mov     [whereisselcard], scNotSelected
  242.  
  243.       call    draw_window
  244.  
  245.     .end:
  246.  
  247.   ret
  248.  
  249.  
  250. ;******************************************************************************
  251. ;                            temp_cell_click(columnclicked)
  252.   temp_cell_click:
  253.     call   get_sel_card_code_and_addr
  254.     cmp    [selcardcode], 52
  255.     jb     .something_selected
  256.  
  257.  
  258.     mov    [whereisselcard], scTempCells
  259.     mov    eax, [columnclicked]
  260.     mov    [columnofselcard], eax
  261.     call   draw_window
  262.     jmp    .end
  263.  
  264.     .something_selected:
  265.                              ; checking if selected and clicked cards equivalent
  266.     mov     eax, [columnclicked]
  267.     add     eax, tempcells
  268.  
  269.     mov     ebx, 0
  270.     mov     bl, byte [eax]
  271.     mov     [cardclicked], ebx
  272.  
  273.     mov     eax, [selcardcode]
  274.     cmp     [cardclicked], eax
  275.     jne     .not_same_card
  276.  
  277.     mov     [whereisselcard], scNotSelected
  278.     call    draw_window
  279.  
  280.     .not_same_card:
  281.  
  282.                              ;putting cards in temp cells
  283.  
  284.     mov     eax, [columnclicked]
  285.     add     eax, tempcells
  286.  
  287.     mov     ebx, 0
  288.     mov     bl, byte [eax]
  289.     mov     [cardclicked], ebx
  290.  
  291.  
  292.     cmp     [cardclicked], 52
  293.     jb     .end
  294.                              ; if nothing lay in this cell
  295.                              ; move selected card to temp cell
  296.     mov     eax, [columnclicked]
  297.     add     eax, tempcells
  298.     mov     bl, byte [selcardcode]
  299.     mov     byte [eax], bl
  300.  
  301.     mov     eax, [selcardaddr]
  302.     mov     byte [eax], 52
  303.  
  304.     mov     [whereisselcard], scNotSelected
  305.  
  306.     call    draw_window
  307.  
  308.  
  309.     jmp     .end
  310.  
  311.  
  312.     .end:
  313.  
  314.   ret
  315.  
  316. ;******************************************************************************
  317. ;                            home_cell_click(column_clicked)
  318.   home_cell_click:
  319.     call    get_sel_card_code_and_addr
  320.  
  321.     mov     eax, [columnclicked]
  322.     add     eax, homecells
  323.  
  324.  
  325.     mov     ebx, 0
  326.     mov     bl, byte [eax]
  327.     mov     [cardclicked], ebx
  328.  
  329.     mov     eax, [selcardcode]
  330.     mov     bl, 4
  331.     div     bl               ; reminder in ah, quotient in al
  332.  
  333.     mov     ebx, 0
  334.     mov     bl, ah
  335.     mov     [cardfamily], ebx
  336.  
  337.     mov     ecx, 0
  338.     mov     cl, al
  339.     mov     [cardrange], ecx
  340.  
  341.  
  342.     cmp     [cardclicked], 52
  343.     jb     .not_blank
  344.                              ; if nothing lay in this cell
  345.     cmp     [cardrange], 0
  346.     jne     .end
  347.                              ; move ace to home
  348.     mov     eax, [columnclicked]
  349.     add     eax, homecells
  350.     mov     bl, byte [selcardcode]
  351.     mov     byte [eax], bl
  352.  
  353.     mov     eax, [selcardaddr]
  354.     mov     byte [eax], 52
  355.  
  356.     mov     [whereisselcard], scNotSelected
  357.  
  358.     call    draw_window
  359.  
  360.  
  361.     jmp     .end
  362.  
  363.     .not_blank:
  364.  
  365.     mov     eax, [cardclicked]
  366.     mov     bl, 4
  367.     div     bl               ; reminder in ah, quotient in al
  368.  
  369.     mov     ebx, 0
  370.     mov     bl, ah
  371.     mov     [clickedcardfamily], ebx
  372.  
  373.     mov     ecx, 0
  374.     mov     cl, al
  375.     mov     [clickedcardrange], ecx
  376.  
  377.     cmp     [cardfamily], ebx
  378.     jne     .end
  379.  
  380.     inc     ecx
  381.     cmp     [cardrange], ecx
  382.     jne     .end
  383.  
  384.                       ; moving card from its place to home with replacing
  385.                       ; of old card in home
  386.     mov     eax, [columnclicked]
  387.     add     eax, homecells
  388.     mov     bl, byte [selcardcode]
  389.     mov     byte [eax], bl
  390.  
  391.     mov     eax, [selcardaddr]
  392.     mov     byte [eax], 52
  393.  
  394.     mov     [whereisselcard], scNotSelected
  395.  
  396.     call    draw_window
  397.  
  398.  
  399.  
  400.     .end:
  401.  
  402.   ret
  403.  
  404.  
  405. ;******************************************************************************
  406.   new_game_click:
  407.  
  408.       mov   [i], 0
  409.     .deleting_cards_from_common_cells:
  410.       mov   eax, cards
  411.       add   eax, [i]
  412.       mov   byte [eax], 52
  413.  
  414.  
  415.       inc   [i]
  416.       cmp   [i], 19*8
  417.       jb    .deleting_cards_from_common_cells
  418.  
  419.  
  420.     mov     [i], 0
  421.     .filling_pack:
  422.       mov   eax, pack
  423.       add   eax, [i]
  424.       mov   bl, byte [i]
  425.       mov   byte [eax], bl
  426.  
  427.       inc   [i]
  428.       cmp   [i], 52
  429.       jb    .filling_pack
  430.  
  431.       mov     [i], 0
  432.  
  433.     .putting_cards:
  434.  
  435.       mov   [range], 52
  436.       call  random
  437.       mov   eax, [random_value]
  438.       add   eax, pack
  439.  
  440.       mov   ebx, 0
  441.       mov   bl, byte [eax]
  442.       mov   [randomcard], ebx
  443.  
  444.       mov   eax, [random_value]
  445.       mov   [j], eax
  446.  
  447.       cmp   [randomcard], 52
  448.       jb    .found_card
  449.  
  450.  
  451.       mov   [range], 52
  452.       call  random
  453.       cmp   [random_value], 26
  454.       jae    .decreasing_j
  455.  
  456.     .increasing_j:
  457.       inc   [j]
  458.                              ; j mod 52
  459.       mov   eax, [j]
  460.       mov   edx, 0
  461.       mov   ebx, 52
  462.       div   ebx
  463.       mov   [j], edx
  464.  
  465.  
  466.       mov   eax, [j]
  467.       add   eax, pack
  468.       mov   ebx, 0
  469.       mov   bl, byte [eax]
  470.       mov   [randomcard], ebx
  471.       cmp   [randomcard], 52
  472.       jb    .found_card
  473.  
  474.       jmp  .increasing_j
  475.  
  476.  
  477.     .decreasing_j:
  478.       dec   [j]
  479.                              ; i mod 32
  480.       mov   eax, [j]
  481.       mov   edx, 0
  482.       mov   ebx, 52
  483.       div   ebx
  484.       mov   [j], edx
  485.  
  486.       mov   eax, [j]
  487.       add   eax, pack
  488.       mov   ebx, 0
  489.       mov   bl, byte [eax]
  490.       mov   [randomcard], ebx
  491.       cmp   [randomcard], 52
  492.       jb    .found_card
  493.  
  494.       jmp  .decreasing_j
  495.  
  496.     .found_card:
  497.                              ; putting card from pack
  498.       mov   eax, cards
  499.       add   eax, [i]
  500.       mov   bl, byte [randomcard]
  501.       mov   byte [eax], bl
  502.                              ; deleting card from pack
  503.       mov   eax, pack
  504.       add   eax, [j]
  505.       mov   byte [eax], 52
  506.  
  507.  
  508.       inc   [i]
  509.       cmp   [i], 52
  510.       jb    .putting_cards
  511.  
  512.  
  513.  
  514.  
  515.       mov   [i], 0
  516.     .deleting_cards_from_temp_cells:
  517.       mov   eax, tempcells
  518.       add   eax, [i]
  519.       mov   byte [eax], 52
  520.  
  521.  
  522.       inc   [i]
  523.       cmp   [i], 4
  524.       jb    .deleting_cards_from_temp_cells
  525.  
  526.       mov   [i], 0
  527.     .deleting_cards_from_home_cells:
  528.       mov   eax, homecells
  529.       add   eax, [i]
  530.       mov   byte [eax], 52
  531.  
  532.  
  533.       inc   [i]
  534.       cmp   [i], 4
  535.       jb    .deleting_cards_from_home_cells
  536.  
  537.  
  538.     mov     [whereisselcard], scNotSelected
  539.     call    draw_window
  540.  
  541.  
  542.   ret
  543.  
  544.  
  545. ;******************************************************************************
  546. ;                       get_sel_card_code_and_addr(): selcardcode, selcardaddr
  547. ;                       if nothing selected, then selcardcode is 52
  548.   get_sel_card_code_and_addr:
  549.     cmp     [whereisselcard], scNotSelected
  550.     jne     .something_selected
  551.  
  552.     mov     [selcardcode], 52
  553.     jmp     .end
  554.  
  555.     .something_selected:
  556.     cmp     [whereisselcard], scTempCells
  557.     je      .temp_cells_selected
  558.  
  559.                              ; common cells selected
  560.     mov     eax, [columnofselcard]
  561.     mov     [ncolumn], eax
  562.     call    get_row_of_top_card_in_column
  563.  
  564.  
  565.     mov     eax, [topcardrow]; eax = topcardrow * 8  + columnofselcard
  566.     mov     bl, 8
  567.     mul     bl                       ; result of multiplication in ax
  568.     add     eax, [columnofselcard]
  569.     add     eax, cards
  570.  
  571.  
  572.     mov     [selcardaddr], eax
  573.     xor     ebx, ebx
  574.     mov     bl, byte [eax]
  575.     mov     [selcardcode], ebx
  576.  
  577.     jmp     .end
  578.  
  579.     .temp_cells_selected:
  580.  
  581.     mov     eax, tempcells
  582.     add     eax, [columnofselcard]
  583.     mov     [selcardaddr], eax
  584.     mov     ebx, 0
  585.     mov     bl, byte [eax]
  586.     mov     [selcardcode], ebx
  587.  
  588.     .end:
  589.  
  590.   ret
  591.  
  592. ;******************************************************************************
  593. ;                            draw_window()
  594.  
  595.   draw_window:
  596.     mov  eax,48  ; get system colors
  597.     mov  ebx,3
  598.     mov  ecx,syscolors
  599.     mov  edx,sizeof.system_colors
  600.     mcall
  601.  
  602.  
  603.     mov     eax, 12          ; start drawing
  604.     mov     ebx, 1
  605.     mcall
  606.  
  607.     mov     eax, 0           ; create and draw the window
  608.     mov     ebx, 100 * 65536 + 8 * cardwidth + 10 + 7 * columnspace
  609.     mov     ecx, 100 * 65536 + 500
  610.     mov     edx, 0x13008000
  611.     mov     edi, title
  612.     mcall
  613.  
  614.     mov     eax, 9           ; getting window info
  615.     mov     ebx, process_info
  616.     mov     ecx, -1          ; we want to know info of our window
  617.     mcall
  618.  
  619.     test    [process_info.wnd_state], 0x04
  620.     jnz     draw_window.end_draw
  621.  
  622.  
  623.     mov     eax, [process_info.box.height]
  624.     mov     [WindowHeight], ax
  625.  
  626.     mov     eax, [process_info.box.width]
  627.     mov     [WindowWidth], ax
  628.  
  629. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  630.         ; draw top panel
  631.  
  632.     mov     eax, 13
  633.     mov     ebx, 5
  634.     shl     ebx, 16
  635.     add     bx, word [process_info.box.width]
  636.     sub     bx, 9
  637.     mov     ecx, 22 shl 16 + topbuttonsbarheight - 1
  638.     mov     edx, [syscolors.work_graph]
  639.     mcall
  640.  
  641.                              ; draw button "new game"
  642.  
  643.     mov     eax, 8
  644.     mov     ebx, 5 shl 16 + 80
  645.     mov     ecx, 22 shl 16 + topbuttonsbarheight - 2
  646.     mov     edx, 1 + 8 + 4 + 4 + 1 ;button id
  647.     mov     esi, [syscolors.work_button]
  648.     mcall
  649.  
  650.     mov     eax, 4
  651.     mov     ebx, 20 shl 16 + 22 + topbuttonsbarheight/2 - 4
  652.     mov     ecx, [syscolors.work_button_text]
  653.     mov     edx, new_game
  654.     mov     esi, new_game_len
  655.     mcall
  656.  
  657.  
  658.        ; draw button "exit"
  659.     mov     eax, 8
  660.     mov     ebx, (5 + 85) shl 16 + 80 + 5
  661.     mov     ecx, 22 shl 16 + topbuttonsbarheight - 2
  662.     mov     edx, 1 + 8 + 4 + 4 + 2 ;button id
  663.     mov     esi, [syscolors.work_button]
  664.     mcall
  665.  
  666.     mov     eax, 4
  667.     mov     ebx, (40 + 80) shl 16 + 22 + topbuttonsbarheight/2 - 4
  668.     mov     ecx, [syscolors.work_button_text]
  669.     mov     edx, exit
  670.     mov     esi, exit_len
  671.     mcall
  672. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  673. ;                        draw separators between home, temp and common cells
  674.     mov     eax, 13
  675.                    ; horizontal line
  676.     mov     ebx, 5
  677.     shl     ebx, 16
  678.     add     bx,  word [process_info.box.width]
  679.     sub     bx,  9
  680.     mov     ecx, (21 + topbuttonsbarheight + cardheight + columnspace) shl 16+1
  681.  
  682.     mov     edx, [syscolors.work_graph]
  683.     mcall
  684.                   ; verical line
  685.     mov     eax, [process_info.box.width]
  686.     mov     edx, 0
  687.     mov     ecx, 2
  688.     div     ecx
  689.  
  690.     mov     ebx, eax
  691.  
  692.     ;
  693.     shl     ebx, 16
  694.     add     bx,  1
  695.     mov     ecx, (21 + topbuttonsbarheight) shl 16 + cardheight + columnspace
  696.     mov     edx, [syscolors.work_graph]
  697.     mov     eax, 13
  698.     mcall
  699.  
  700. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  701. ;                            draw temp buttons
  702.  
  703.     mov     [j], 0           ;counter that loops from 0 to 51
  704.  
  705.     draw_a_temp_card:
  706.  
  707.                              ; code of card must be in ecx
  708.     mov     eax, tempcells
  709.     add     eax, [j]
  710.     xor     ecx, ecx
  711.     mov     cl, byte [eax]   ; placing in cl value from memory
  712.                              ;  with address [tempcells + j] or
  713.                              ;  j-th element of array "tempcells"
  714.  
  715.     mov     [cardcode], ecx
  716.  
  717.     mov     eax, [j]
  718.     xor     edx, edx
  719.     mov     ebx, 8
  720.     div     ebx              ; divsion by 8 (8 columns),
  721.                              ;   so in eax quotient - number of row
  722.                              ;   and in edx remainder -
  723.                              ;   number of column where lay card
  724.  
  725.     mov     [row], eax
  726.     mov     [column], edx
  727.  
  728.     mov     eax, [process_info.box.width]       ; width of window
  729.     sub     eax, 10
  730.     sub     eax, cardwidth
  731.     mov     ebx, 7
  732.     mov     edx, 0
  733.     div     ebx
  734.     mov     ebx, [column]
  735.     mul     ebx
  736.     add     eax, 5
  737.  
  738.     mov     [xpos], eax
  739.  
  740.  
  741.     mov     eax, [row]
  742.     mov     bl, rowsize
  743.     mul     bl
  744.     add     eax, 24 + topbuttonsbarheight
  745.     mov     [ypos], eax
  746.  
  747.                              ; checking, if this card selected
  748.  
  749.     mov     [negativedraw], 0
  750.  
  751.     cmp     [whereisselcard], scTempCells
  752.     jne     .this_temp_cell_isnt_selected
  753.  
  754.     mov     eax, [column]
  755.     cmp     [columnofselcard], eax
  756.     jne     .this_temp_cell_isnt_selected
  757.  
  758.     mov     [negativedraw], 1
  759.  
  760.     .this_temp_cell_isnt_selected:
  761.  
  762.     call    draw_card
  763.  
  764.                              ; define button on place of card
  765.     mov     eax, 8
  766.     mov     ebx, [xpos]
  767.     shl     ebx, 16
  768.     add     bx, cardwidth - 1
  769.     mov     ecx, [ypos]
  770.     shl     ecx, 16
  771.     add     cx, cardheight - 1
  772.     mov     edx, [column]
  773.     add     edx, 01000000000000000000000000000000b + 2 + 8;  button id = column
  774.                                            ; id = 1 reserved as close button
  775.     mcall
  776.  
  777.  
  778.     inc     [j]
  779.     cmp     [j], 4
  780.     jb      draw_a_temp_card
  781.  
  782.  
  783. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  784. ;                            draw home buttons
  785.  mov     [j], 0              ;counter that loops from 0 to 51
  786.  
  787.     draw_a_home_card:
  788.  
  789.  
  790.                              ; code of card must be in ecx
  791.     mov     eax, homecells
  792.     add     eax, [j]
  793.     xor     ecx, ecx
  794.     mov     cl, byte [eax]   ; placing in cl value from memory
  795.                              ;  with address [tempcells + j] or
  796.                              ;  j-th element of array "tempcells"
  797.  
  798.     mov     [cardcode], ecx
  799.  
  800.     mov     eax, [j]
  801.     xor     edx, edx
  802.     mov     ebx, 8
  803.     div     ebx              ; divsion by 8 (8 columns),
  804.                              ;  so in eax quotient - number of row
  805.                              ;  and in edx remainder -
  806.                              ;  number of column where lay card
  807.  
  808.     mov     [row], eax
  809.     mov     [column], edx
  810.  
  811.     mov     eax, [process_info.box.width]       ; width of window
  812.     sub     eax, 10
  813.     sub     eax, cardwidth
  814.     mov     ebx, 7
  815.     mov     edx, 0
  816.     div     ebx
  817.     mov     ebx, [column]
  818.     add     ebx, 4
  819.     mul     ebx
  820.     add     eax, 5
  821.  
  822.     mov     [xpos], eax
  823.  
  824.     mov     eax, [row]
  825.     mov     bl, rowsize
  826.     mul     bl
  827.     add     eax, 24 + topbuttonsbarheight
  828.     mov     [ypos], eax
  829.  
  830.     mov     [negativedraw], 0
  831.  
  832.     call    draw_card
  833.  
  834.                              ; define button on place of card
  835.  
  836.     mov     eax, 8
  837.     mov     ebx, [xpos]
  838.     shl     ebx, 16
  839.     add     bx, cardwidth - 1
  840.     mov     ecx, [ypos]
  841.     shl     ecx, 16
  842.     add     cx, cardheight - 1
  843.     mov     edx, [column]
  844.     add     edx, 01000000000000000000000000000000b + 2 + 8 + 4 ; button id
  845.  
  846.                              ; id = 1 reserved as close button
  847.     mcall
  848.  
  849.  
  850.     inc     [j]
  851.     cmp     [j], 4
  852.     jb       draw_a_home_card
  853.  
  854.  
  855. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  856. ;                            draw common cards
  857.  
  858.     mov     [j], 0           ;counter that loops from 0 to 8 * 19
  859.  
  860.     draw_a_card:
  861.  
  862.  
  863.                              ; code of card must be in ecx
  864.     mov     eax, cards
  865.     add     eax, [j]
  866.     xor     ecx, ecx
  867.     mov     cl, byte [eax]   ; placing in cl value from memory
  868.                              ;  with address [cards + j] or
  869.                              ;  j-th element of array "cards"
  870. ;    cmp     ecx, 52          ; if code of card >= 52 then there is no card
  871. ;    jae     no_draw
  872. ;
  873. ;    cmp     ecx, 0           ; if code of card  < 0 then there is no card
  874. ;    jb      no_draw
  875.  
  876.     mov     [cardcode], ecx
  877.  
  878.  
  879.  
  880.     mov     eax, [j]
  881.     xor     edx, edx
  882.     mov     ebx, 8
  883.     div     ebx             ; divsion by 8 (8 columns),
  884.                             ;  so in eax quotient - number of row
  885.                             ;  and in edx remainder -
  886.                             ;  number of column where lay card
  887.  
  888.     mov     [row], eax
  889.     mov     [column], edx
  890.  
  891.     mov     eax, [process_info.box.width]       ; width of window
  892.     sub     eax, 10
  893.     sub     eax, cardwidth
  894.     mov     ebx, 7
  895.     mov     edx, 0
  896.     div     ebx
  897.     mov     ebx, [column]
  898.     mul     ebx
  899.     add     eax, 5
  900.  
  901.     mov     [xpos], eax
  902.  
  903.     mov     eax, [row]
  904.     mov     bl, rowsize
  905.     mul     bl
  906.     add     eax, cardheight + 24 + topbuttonsbarheight + columnspace
  907.     mov     [ypos], eax
  908.  
  909.  
  910.     mov     [negativedraw], 0 ;checking, if this is selected card
  911.  
  912.     cmp     [whereisselcard], scCommonCells
  913.     jne     .this_card_isnt_selected
  914.  
  915.     mov     eax, [column]
  916.     cmp     [columnofselcard], eax
  917.     jne     .this_card_isnt_selected
  918.  
  919.  
  920.     mov     eax, [column]
  921.     mov     [ncolumn], eax
  922.     call    get_row_of_top_card_in_column
  923.     mov     eax, [row]
  924.     cmp     [topcardrow], eax
  925.     jne     .this_card_isnt_selected
  926.  
  927.     mov     [negativedraw], 1
  928.  
  929.     .this_card_isnt_selected:
  930.  
  931.     call    draw_card
  932.  
  933.  
  934.  
  935.                              ; now checking if it is top card in its column
  936.                              ; if it does, we'll define button on its place
  937.     mov     eax, [column]
  938.     mov     [ncolumn], eax
  939.     call    get_row_of_top_card_in_column
  940.     mov     eax, [row]
  941.     cmp     [topcardrow], eax
  942.     je       .define_button
  943.  
  944.     cmp     [topcardrow], 0
  945.     jne     .no_define_button
  946.  
  947.     cmp     [row], 0
  948.     jne     .no_define_button
  949.  
  950.  
  951.     .define_button:
  952.     mov     eax, 8
  953.     mov     ebx, [xpos]
  954.     shl     ebx, 16
  955.     add     bx, cardwidth - 1
  956.     mov     ecx, [ypos]
  957.     shl     ecx, 16
  958.     add     cx, cardheight - 1
  959.     mov     edx, [column]
  960.     add     edx, 01000000000000000000000000000000b + 2; button id = column + 2,
  961.                              ; id = 1 reserved as close button
  962.     mcall
  963.  
  964.  
  965.     .no_define_button:
  966.  
  967.     inc     [j]
  968.     cmp     [j], 8 * 19
  969.     jb       draw_a_card
  970.  
  971.  
  972.  
  973.  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  974.     draw_window.end_draw:
  975.  
  976.     mov     eax, 12          ; finish drawing
  977.     mov     ebx, 2
  978.     mcall
  979.  
  980.   ret
  981.  
  982.  
  983. ;******************************************************************************
  984. ;            get_row_of_top_card_in_column(ncolumn): topcardrow
  985.  
  986.   get_row_of_top_card_in_column:
  987.                              ; number of column in ncolumn
  988.                              ; returns in topcardrow
  989.  
  990.     mov [i], 0               ; i loops from 0 to 1, ... while card i * 8 + ncolumn
  991.                              ; is valid card (0 <= its code < 52)
  992.  
  993.     .cycle:
  994.        xor  eax, eax
  995.        mov  al, 8
  996.        mov  ebx, [i]
  997.        mul  bl
  998.        add  eax, [ncolumn]
  999.        add  eax, cards
  1000.        xor  ecx, ecx
  1001.        mov  cl, byte [eax]
  1002.  
  1003.        cmp  ecx, 52
  1004.        jae  .endcycle
  1005.  
  1006.  
  1007.        cmp  [i], 18
  1008.        ja   .endcycle
  1009.  
  1010.  
  1011.        inc  [i]
  1012.  
  1013.        jmp  .cycle
  1014.  
  1015.     .endcycle:
  1016.  
  1017.       cmp   [i], 0
  1018.       je    .dont_dec
  1019.  
  1020.       dec   [i]
  1021.  
  1022.     .dont_dec:
  1023.  
  1024.       mov   eax, [i]
  1025.       mov   [topcardrow], eax
  1026.   ret
  1027.  
  1028.  
  1029. ;******************************************************************************
  1030. ;                      invert_image_colors(imagetoinvert, sizeofimagetoinvert)
  1031.   invert_image_colors:
  1032.     mov     [i], 0
  1033.  
  1034.     .inverting:
  1035.     mov     eax, [imagetoinvert]
  1036.     add     eax, [i]
  1037.  
  1038.     mov     bl, byte [eax]
  1039.     ;xor     ebx, ebx
  1040.     ;add     ebx, 10
  1041.     not     ebx
  1042.  
  1043.     mov     byte [eax], bl
  1044.  
  1045.  
  1046.     inc     [i]
  1047.  
  1048.     mov     ecx, [sizeofimagetoinvert]
  1049.     cmp     [i], ecx
  1050.     jb      .inverting
  1051.  
  1052.     jmp   .later
  1053.  
  1054.  
  1055.     .exit:
  1056.       mov  eax, -1
  1057.       mcall
  1058.  
  1059.     .later:
  1060.  
  1061.  
  1062.   ret
  1063.  
  1064.  
  1065.  
  1066. ;******************************************************************************
  1067. ;            draw_card(xpos, ypos, cardcode, negativedraw)
  1068. ; if negativedraw = 1 then card drawn in inverted colors
  1069.  
  1070.   draw_card: ; draws card with left top corner
  1071.                     ; in point ([xpos],[ypos]),
  1072.                     ; type of card in [cardcode]
  1073.  
  1074.     cmp     [cardcode], 52   ; if code of card >= 52 then there is no card
  1075.     jae     .no_draw_card
  1076.  
  1077.  
  1078.     cmp     [negativedraw], 1
  1079.     jne     .no_invert1
  1080.                              ;doing if negativedraw
  1081.     mov     [bgcolor], $00000000
  1082.     mov     [blackcolor], $00FFFFFF
  1083.     mov     [redcolor], $0000FFFF
  1084.  
  1085.              ;inverting all images
  1086.     call invert_all_images
  1087.  
  1088.     jmp     .colors_selection_done
  1089.  
  1090.     .no_invert1:
  1091.                              ;doing if not negativedraw
  1092.     mov     [bgcolor], $00FFFFFF
  1093.     mov     [blackcolor], $00000000
  1094.     mov     [redcolor], $00FF0000
  1095.  
  1096.  
  1097.     .colors_selection_done:
  1098.  
  1099.     mov     eax, 13
  1100.  
  1101.     mov     ebx, [xpos]      ; filling card with bgcolor
  1102.                              ; (big background rectangle)
  1103.     mov     edx, [bgcolor]
  1104.     add     ebx, 2
  1105.     shl     ebx, 16
  1106.     mov     bx, cardwidth - 4
  1107.  
  1108.     mov     ecx, [ypos]
  1109.     add     ecx, 2
  1110.     shl     ecx, 16
  1111.     mov     cx, cardheight - 4
  1112.     mcall
  1113.  
  1114. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1115.  
  1116.     mov     ebx, [xpos]      ; left black line
  1117.     shl     ebx, 16
  1118.     mov     bx, 1
  1119.  
  1120.     mov     ecx, [ypos]
  1121.     add     ecx, 5
  1122.     shl     ecx, 16
  1123.     xor     cx, cx
  1124.     mov     cx, cardheight - 2 * radius - 2
  1125.     mov     edx, [blackcolor]
  1126.     mcall
  1127.  
  1128.     mov     ebx, [xpos]      ; left white line
  1129.     inc     ebx
  1130.     shl     ebx, 16
  1131.     mov     bx, 1
  1132.     mov     edx, [bgcolor]
  1133.     mcall
  1134.  
  1135.     mov     ebx, [xpos]      ; right black line
  1136.     add     ebx, cardwidth - 1
  1137.     shl     ebx, 16
  1138.     mov     bx,  1
  1139.     mov     edx, [blackcolor]
  1140.     mcall
  1141.  
  1142.     mov     ebx, [xpos]      ; right white line
  1143.     add     ebx, cardwidth - 2
  1144.     shl     ebx, 16
  1145.     mov     bx, 1
  1146.     mov     edx, [bgcolor]
  1147.     mcall
  1148.  
  1149. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1150.  
  1151.     mov     ecx, [ypos]      ; top black line
  1152.     shl     ecx, 16
  1153.     mov     cx, 1
  1154.  
  1155.     mov     ebx, [xpos]
  1156.     add     ebx, 5
  1157.     shl     ebx, 16
  1158.     mov     bx, cardwidth - 2 * radius - 2
  1159.     mov     edx, [blackcolor]
  1160.     mcall
  1161.  
  1162.     mov     ecx, [ypos]      ; top white line
  1163.     inc     ecx
  1164.     shl     ecx, 16
  1165.     mov     cx, 1
  1166.     mov     edx, [bgcolor]
  1167.     mcall
  1168.  
  1169.     mov     ecx, [ypos]      ; bottom black line
  1170.     add     ecx, cardheight - 1
  1171.     shl     ecx, 16
  1172.     mov     cx,  1
  1173.     mov     edx, [blackcolor]
  1174.     mcall
  1175.  
  1176.     mov     ecx, [ypos]      ; bottom white line
  1177.     add     ecx, cardheight - 2
  1178.     shl     ecx, 16
  1179.     mov     cx, 1
  1180.     mov     edx, [bgcolor]
  1181.     mcall
  1182.  
  1183. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1184.  
  1185.     mov    eax, 1            ; drawing points
  1186.     mov    edx, [blackcolor] ; black color for all pixels
  1187.  
  1188.     mov    ebx, [xpos]       ; draw top left corner
  1189.     mov    ecx, [ypos]
  1190.     inc    ebx
  1191.     add    ecx, 4
  1192.     mcall
  1193.  
  1194.     dec    ecx
  1195.     mcall
  1196.  
  1197.     dec    ecx
  1198.     inc    ebx
  1199.     mcall
  1200.  
  1201.     dec    ecx
  1202.     inc    ebx
  1203.     mcall
  1204.  
  1205.     inc    ebx
  1206.     mcall
  1207.  
  1208.     mov    ebx, [xpos]       ;drawing top right corner
  1209.     mov    ecx, [ypos]
  1210.     add    ebx, cardwidth - 2
  1211.     add    ecx, 4
  1212.     mcall
  1213.  
  1214.     dec    ecx
  1215.     mcall
  1216.  
  1217.     dec    ebx
  1218.     dec    ecx
  1219.     mcall
  1220.  
  1221.     dec    ebx
  1222.     dec    ecx
  1223.     mcall
  1224.  
  1225.     dec    ebx
  1226.     mcall
  1227.                              ;drawing bottom left corner
  1228.     mov    ebx, [xpos]
  1229.     mov    ecx, [ypos]
  1230.     inc    ebx
  1231.     add    ecx, cardheight - 5
  1232.     mcall
  1233.  
  1234.     inc    ecx
  1235.     mcall
  1236.  
  1237.     inc    ebx
  1238.     inc    ecx
  1239.     mcall
  1240.  
  1241.     inc    ebx
  1242.     inc    ecx
  1243.     mcall
  1244.  
  1245.     inc    ebx
  1246.     mcall
  1247.                              ;drawing bottom right corner
  1248.     mov    ebx, [xpos]
  1249.     mov    ecx, [ypos]
  1250.     add    ebx, cardwidth - 2
  1251.     add    ecx, cardheight - 5
  1252.     mcall
  1253.  
  1254.     inc    ecx
  1255.     mcall
  1256.  
  1257.     dec    ebx
  1258.     inc    ecx
  1259.     mcall
  1260.  
  1261.     dec    ebx
  1262.     inc    ecx
  1263.     mcall
  1264.  
  1265.     dec    ebx
  1266.     mcall
  1267.  
  1268.  
  1269. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1270. ;   drawing text and images
  1271.  
  1272.     mov    eax, [cardcode]
  1273.     mov    edx, 0
  1274.     mov    ebx, 4
  1275.     div    ebx
  1276.  
  1277.     mov    [cardfamily], edx
  1278.     mov    [cardrange], eax
  1279.  
  1280.                      ; counting position of small card image
  1281.     mov eax, 7
  1282.     mov ecx, 8*65536+8
  1283.     mov edx, [xpos]
  1284.     add edx, radius
  1285.     shl edx, 16
  1286.     mov dx, word [ypos]
  1287.     add dx, radius + 8
  1288.  
  1289.  
  1290.  
  1291.     cmp    [cardfamily], 0
  1292.     je     .heart
  1293.  
  1294.     cmp    [cardfamily], 1
  1295.     je     .diamond
  1296.  
  1297.     cmp    [cardfamily], 2
  1298.     je     .club
  1299.  
  1300.     cmp    [cardfamily], 3
  1301.     je     .spade
  1302.  
  1303.     .heart:
  1304.        mov esi, [redcolor]
  1305.        mov [color], esi
  1306.        mov [imageaddr], heart
  1307.        mov [imageflipaddr], heart_updown
  1308.  
  1309.        mov ebx, heart_small
  1310.        mcall
  1311.  
  1312.        jmp .selnumber
  1313.  
  1314.     .diamond:
  1315.        mov esi, [redcolor]
  1316.        mov [color], esi
  1317.        mov [imageaddr], diamond
  1318.        mov [imageflipaddr], diamond_updown
  1319.  
  1320.        mov ebx, diamond_small
  1321.        mcall
  1322.  
  1323.        jmp .selnumber
  1324.  
  1325.     .club:
  1326.       mov  esi, [blackcolor]
  1327.       mov  [color], esi
  1328.       mov  [imageaddr], club
  1329.       mov  [imageflipaddr], club_updown
  1330.  
  1331.       mov ebx, club_small
  1332.       mcall
  1333.  
  1334.       jmp  .selnumber
  1335.  
  1336.     .spade:
  1337.       mov  esi, [blackcolor]
  1338.       mov  [color], esi
  1339.       mov  [imageaddr], spade
  1340.       mov  [imageflipaddr], spade_updown
  1341.  
  1342.       mov ebx, spade_small
  1343.       mcall
  1344.  
  1345.  
  1346.  
  1347.     .selnumber:
  1348.  
  1349.     mov    ebx, [xpos]       ; counting position of text
  1350.                              ; in ebx, same for all cards
  1351.     add    ebx, radius
  1352.     shl    ebx, 16
  1353.     mov    bx,  word [ypos]
  1354.     add    bx,  radius
  1355.  
  1356.  
  1357.     mov    ecx, [color]
  1358.  
  1359.  
  1360.     cmp    [cardrange], 0
  1361.     je     .ace
  1362.  
  1363.     cmp    [cardrange], 1
  1364.     je     .two
  1365.  
  1366.     cmp    [cardrange], 2
  1367.     je     .three
  1368.  
  1369.     cmp    [cardrange], 3
  1370.     je     .four
  1371.  
  1372.     cmp    [cardrange], 4
  1373.     je     .five
  1374.  
  1375.     cmp    [cardrange], 5
  1376.     je     .six
  1377.  
  1378.     cmp    [cardrange], 6
  1379.     je     .seven
  1380.  
  1381.     cmp    [cardrange], 7
  1382.     je     .eight
  1383.  
  1384.     cmp    [cardrange], 8
  1385.     je     .nine
  1386.  
  1387.     cmp    [cardrange], 9
  1388.     je     .ten
  1389.  
  1390.     cmp    [cardrange], 10
  1391.     je     .jack
  1392.  
  1393.     cmp    [cardrange], 11
  1394.     je     .queen
  1395.  
  1396.     cmp    [cardrange], 12
  1397.     je     .king
  1398.  
  1399.     ;      +-------+-------+-------+
  1400.     ;      |   3   |   2   |   3   |   ace   = 1
  1401.     ;      +-------+-------+-------+   two   = 2
  1402.     ;      |       |       |       |   three = 2 + 1
  1403.     ;      +-------+-------+-------+   four  = 3
  1404.     ;      |       |   6   |       |   five  = 3 + 1
  1405.     ;      +-------+-------+-------+   six   = 3 + 4
  1406.     ;      |   5   |       |   5   |   seven = 3 + 4 + 6
  1407.     ;      +-------+-------+-------+   eight = 3 + 5
  1408.     ;      |   4   |   1   |   4   |   nine  = 3 + 5
  1409.     ;      +-------+-------+-------+   ten   = 3 + 5 + 6 + 7
  1410.     ;      |   5   |       |   5   |
  1411.     ;      +-------+-------+-------+
  1412.     ;      |       |   7   |       |   1 means draw_1
  1413.     ;      +-------+-------+-------+
  1414.     ;      |       |       |       |
  1415.     ;      +-------+-------+-------+
  1416.     ;      |   3   |   2   |   3   |
  1417.     ;      +-------+-------+-------+
  1418.  
  1419.  
  1420.  
  1421.     .ace:
  1422.       mov  eax, 4
  1423.       mov  [s], byte 'A'
  1424.       mov  edx, s
  1425.       mov  esi, 1
  1426.       mcall
  1427.  
  1428.       call draw_1
  1429.       jmp .end
  1430.  
  1431.     .two:
  1432.       mov  eax, 4
  1433.       mov  [s], byte '2'
  1434.       mov  edx, s
  1435.       mov  esi, 1
  1436.       mcall
  1437.  
  1438.       call draw_2
  1439.       jmp .end
  1440.  
  1441.  
  1442.     .three:
  1443.       mov  eax, 4
  1444.       mov  [s], byte '3'
  1445.       mov  edx, s
  1446.       mov  esi, 1
  1447.       mcall
  1448.  
  1449.       call draw_1
  1450.       call draw_2
  1451.  
  1452.       jmp  .end
  1453.  
  1454.     .four:
  1455.       mov  eax, 4
  1456.       mov  [s], byte '4'
  1457.       mov  edx, s
  1458.       mov  esi, 1
  1459.       mcall
  1460.  
  1461.       call draw_3
  1462.       jmp  .end
  1463.  
  1464.     .five:
  1465.       mov  eax, 4
  1466.       mov  [s], byte '5'
  1467.       mov  edx, s
  1468.       mov  esi, 1
  1469.       mcall
  1470.  
  1471.       call draw_1
  1472.       call draw_3
  1473.  
  1474.       jmp  .end
  1475.  
  1476.     .six:
  1477.       mov  eax, 4
  1478.       mov  [s], byte '6'
  1479.       mov  edx, s
  1480.       mov  esi, 1
  1481.       mcall
  1482.  
  1483.       call draw_3
  1484.       call draw_4
  1485.  
  1486.       jmp  .end
  1487.  
  1488.     .seven:
  1489.       mov  eax, 4
  1490.       mov  [s], byte '7'
  1491.       mov  edx, s
  1492.       mov  esi, 1
  1493.       mcall
  1494.  
  1495.       call draw_3
  1496.       call draw_4
  1497.       call draw_6
  1498.  
  1499.       jmp  .end
  1500.  
  1501.     .eight:
  1502.       mov  eax, 4
  1503.       mov  [s], byte '8'
  1504.       mov  edx, s
  1505.       mov  esi, 1
  1506.       mcall
  1507.  
  1508.       call draw_3
  1509.       call draw_5
  1510.  
  1511.       jmp  .end
  1512.  
  1513.     .nine:
  1514.       mov  eax, 4
  1515.       mov  [s], byte '9'
  1516.       mov  edx, s
  1517.       mov  esi, 1
  1518.       mcall
  1519.  
  1520.       call draw_3
  1521.       call draw_5
  1522.       call draw_1
  1523.  
  1524.       jmp  .end
  1525.  
  1526.     .ten:
  1527.       mov  eax, 4
  1528.       mov  [s], word '10'
  1529.       mov  edx, s
  1530.       mov  esi, 2
  1531.       mcall
  1532.  
  1533.       call draw_3
  1534.       call draw_5
  1535.       call draw_6
  1536.       call draw_7
  1537.  
  1538.       jmp  .end
  1539.  
  1540.     .jack:
  1541.       mov  eax, 4
  1542.       mov  [s], byte 'J'
  1543.       mov  edx, s
  1544.       mov  esi, 1
  1545.       mcall
  1546.  
  1547.       jmp  .end
  1548.  
  1549.     .queen:
  1550.       mov  eax, 4
  1551.       mov  [s], byte 'Q'
  1552.       mov  edx, s
  1553.       mov  esi, 1
  1554.       mcall
  1555.  
  1556.       jmp  .end
  1557.  
  1558.     .king:
  1559.       mov  eax, 4
  1560.       mov  [s], byte 'K'
  1561.       mov  edx,s
  1562.       mov  esi, 1
  1563.       mcall
  1564.  
  1565.     .end:
  1566.  
  1567.  
  1568.     cmp  [negativedraw], 1
  1569.     jne  .no_invert2
  1570.  
  1571.     call invert_all_images
  1572.  
  1573.  
  1574.     .no_invert2:
  1575.     .no_draw_card:
  1576.  
  1577.   ret
  1578.  
  1579. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1580. ;                            invert_all_images()
  1581.   invert_all_images:
  1582.     mov  [sizeofimagetoinvert], 16 * 16 * 3
  1583.     mov  [imagetoinvert], heart
  1584.     call invert_image_colors
  1585.  
  1586.     mov  [sizeofimagetoinvert], 16 * 16 * 3
  1587.     mov  [imagetoinvert], diamond
  1588.     call invert_image_colors
  1589.  
  1590.     mov  [sizeofimagetoinvert], 16 * 16 * 3
  1591.     mov  [imagetoinvert], spade
  1592.     call invert_image_colors
  1593.  
  1594.     mov  [sizeofimagetoinvert], 16 * 16 * 3
  1595.     mov  [imagetoinvert], club
  1596.     call invert_image_colors
  1597.  
  1598.  
  1599.     mov  [sizeofimagetoinvert], 16 * 16 * 3
  1600.     mov  [imagetoinvert], heart_updown
  1601.     call invert_image_colors
  1602.  
  1603.     mov  [sizeofimagetoinvert], 16 * 16 * 3
  1604.     mov  [imagetoinvert], diamond_updown
  1605.     call invert_image_colors
  1606.  
  1607.     mov  [sizeofimagetoinvert], 16 * 16 * 3
  1608.     mov  [imagetoinvert], spade_updown
  1609.     call invert_image_colors
  1610.  
  1611.     mov  [sizeofimagetoinvert], 16 * 16 * 3
  1612.     mov  [imagetoinvert], club_updown
  1613.     call invert_image_colors
  1614.  
  1615.  
  1616.     mov  [sizeofimagetoinvert], 8 * 8 * 3
  1617.     mov  [imagetoinvert], heart_small
  1618.     call invert_image_colors
  1619.  
  1620.     mov  [sizeofimagetoinvert], 8 * 8 * 3
  1621.     mov  [imagetoinvert], diamond_small
  1622.     call invert_image_colors
  1623.  
  1624.     mov  [sizeofimagetoinvert], 8 * 8 * 3
  1625.     mov  [imagetoinvert], spade_small
  1626.     call invert_image_colors
  1627.  
  1628.     mov  [sizeofimagetoinvert], 8 * 8 * 3
  1629.     mov  [imagetoinvert], club_small
  1630.     call invert_image_colors
  1631.  
  1632.  
  1633.  
  1634.   ret
  1635.  
  1636.  
  1637. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1638.  
  1639.   draw_1:
  1640.                              ;draw center image
  1641.       mov     ebx, [imageaddr]
  1642.       mov     ecx, 16 * 65536 + 16
  1643.       mov     edx, [xpos]
  1644.       add     edx, cardwidth/2 - 8
  1645.       shl     edx, 16
  1646.       mov     dx, word [ypos]
  1647.       add     dx, cardheight/2 - 8
  1648.       mov      eax, 7
  1649.       mcall
  1650.   ret
  1651.  
  1652. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1653.  
  1654.  
  1655.   draw_2:
  1656.                              ;draw top image
  1657.       mov     ebx, [imageaddr]
  1658.       mov     ecx, 16 * 65536 + 16
  1659.       mov     edx, [xpos]
  1660.       add     edx, 40 - 8
  1661.       shl     edx, 16
  1662.       mov     dx, word [ypos]
  1663.       add     dx, margin
  1664.       mov     eax, 7
  1665.       mcall
  1666.                              ;draw bottom image
  1667.       mov     ebx, [imageflipaddr]
  1668.       mov     edx, [xpos]
  1669.       add     edx, cardwidth/2 - 8
  1670.       shl     edx, 16
  1671.       mov     dx, word [ypos]
  1672.       add     dx, cardheight - 16 - margin
  1673.       mov     eax, 7
  1674.       mcall
  1675.   ret
  1676.  
  1677. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1678.  
  1679.   draw_3:
  1680.                              ;draw top left image
  1681.       mov     ebx, [imageaddr]
  1682.       mov     ecx, 16 * 65536 + 16
  1683.       mov     edx, [xpos]
  1684.       add     edx, margin
  1685.       shl     edx, 16
  1686.       mov     dx, word [ypos]
  1687.       add     dx, margin
  1688.       mov     eax, 7
  1689.       mcall
  1690.                              ;draw bottom left image
  1691.       mov     ebx, [imageflipaddr]
  1692.       mov     edx, [xpos]
  1693.       add     edx, margin
  1694.       shl     edx, 16
  1695.       mov     dx, word [ypos]
  1696.       add     dx, cardheight - margin - 16
  1697.       mov     eax, 7
  1698.       mcall
  1699.                              ;draw top right image
  1700.       mov     ebx, [imageaddr]
  1701.       mov     edx, [xpos]
  1702.       add     edx, cardwidth - margin - 16
  1703.       shl     edx, 16
  1704.       mov     dx, word [ypos]
  1705.       add     dx, margin
  1706.       mov     eax, 7
  1707.       mcall
  1708.                              ;draw bottom right image
  1709.       mov     ebx, [imageflipaddr]
  1710.       mov     edx, [xpos]
  1711.       add     edx, cardwidth - margin - 16
  1712.       shl     edx, 16
  1713.       mov     dx, word [ypos]
  1714.       add     dx, cardheight - margin - 16
  1715.       mov     eax, 7
  1716.       mcall
  1717.   ret
  1718.  
  1719. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1720.  
  1721.   draw_4:
  1722.                              ;draw center left image
  1723.       mov     ebx, [imageaddr]
  1724.       mov     ecx, 16 * 65536 + 16
  1725.       mov     edx, [xpos]
  1726.       add     edx, margin
  1727.       shl     edx, 16
  1728.       mov     dx, word [ypos]
  1729.       add     dx, cardheight/2 - 8
  1730.       mov     eax, 7
  1731.       mcall
  1732.                              ;draw center right image
  1733.       mov     edx, [xpos]
  1734.       add     edx, cardwidth - margin - 16
  1735.       shl     edx, 16
  1736.       mov     dx, word [ypos]
  1737.       add     dx, cardheight/2 - 8
  1738.       mov     eax, 7
  1739.       mcall
  1740.   ret
  1741.  
  1742. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1743.  
  1744.   draw_5:
  1745.                              ;draw top left image
  1746.       mov     ebx, [imageaddr]
  1747.       mov     ecx, 16 * 65536 + 16
  1748.       mov     edx, [xpos]
  1749.       add     edx, margin
  1750.       shl     edx, 16
  1751.       mov     dx, word [ypos]
  1752.       add     dx, cardheight * 3 / 9
  1753.       mov     eax, 7
  1754.       mcall
  1755.                              ;draw bottom left image
  1756.       mov     ebx, [imageflipaddr]
  1757.       mov     edx, [xpos]
  1758.       add     edx, 16
  1759.       shl     edx, 16
  1760.       mov     dx, word [ypos]
  1761.       add     dx, cardheight * 5 / 9
  1762.       mov     eax, 7
  1763.       mcall
  1764.                              ;draw top right image
  1765.       mov     ebx, [imageaddr]
  1766.       mov     edx, [xpos]
  1767.       add     edx, cardwidth - margin - 16
  1768.       shl     edx, 16
  1769.       mov     dx, word [ypos]
  1770.       add     dx, cardheight * 3 / 9
  1771.       mov     eax, 7
  1772.       mcall
  1773.                              ;draw bottom right image
  1774.       mov     ebx, [imageflipaddr]
  1775.       mov     edx, [xpos]
  1776.       add     edx, cardwidth - margin - 16
  1777.       shl     edx, 16
  1778.       mov     dx, word [ypos]
  1779.       add     dx, cardheight * 5 / 9
  1780.       mov     eax, 7
  1781.       mcall
  1782.   ret
  1783.  
  1784. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1785.  
  1786.   draw_6:
  1787.       mov     ebx, [imageaddr]
  1788.       mov     ecx, 16 * 65536 + 16
  1789.       mov     edx, [xpos]
  1790.       add     edx, cardwidth/2 - 8
  1791.       shl     edx, 16
  1792.       mov     dx, word [ypos]
  1793.       add     dx, cardheight * 2 / 9
  1794.       mov     eax, 7
  1795.       mcall
  1796.   ret
  1797.  
  1798.  
  1799. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1800.   draw_7:
  1801.       mov     ebx, [imageflipaddr]
  1802.       mov     ecx, 16 * 65536 + 16
  1803.       mov     edx, [xpos]
  1804.       add     edx, cardwidth/2 - 8
  1805.       shl     edx, 16
  1806.       mov     dx, word [ypos]
  1807.       add     dx, cardheight * 6 / 9
  1808.       mov     eax, 7
  1809.       mcall
  1810.   ret
  1811.  
  1812.  
  1813. ;******************************************************************************
  1814.   randomize:
  1815.     push eax
  1816.  
  1817.     mov  eax, 3
  1818.     mcall
  1819.  
  1820.     mov  ebx, $A59E3F1C
  1821.     mul  ebx
  1822.     mov  dword [randseed], eax
  1823.     pop  eax
  1824.   ret
  1825.  
  1826.  
  1827.  
  1828. ;******************************************************************************
  1829. ;          function Random(Range): RandomValue
  1830.   random:
  1831.     push ebx
  1832.  
  1833.     mov  eax, [randseed]
  1834.     mov  edx, 0
  1835.     mov  ebx, 7
  1836.     div  ebx
  1837.  
  1838.     cmp  edx, 0
  1839.     je   _0
  1840.  
  1841.     cmp  edx, 1
  1842.     je   _1
  1843.  
  1844.     cmp  edx, 2
  1845.     je   _2
  1846.  
  1847.     cmp  edx, 3
  1848.     je   _3
  1849.  
  1850.     cmp  edx, 4
  1851.     je   _4
  1852.  
  1853.     cmp  edx, 5
  1854.     je   _5
  1855.  
  1856.     cmp  edx, 6
  1857.     je   _6
  1858.  
  1859.     jmp  _end
  1860.  
  1861.  
  1862.     _0:
  1863.       ;base := base + 58 + a[8];
  1864.       mov  eax, [randseed]
  1865.       add  eax, 58
  1866.       add  eax, dword [a + 8 * 4]
  1867.       mov  [randseed], eax
  1868.       jmp  _end;
  1869.  
  1870.     _1:
  1871.       ;base := base + 1 + a[9];
  1872.       mov  eax, [randseed]
  1873.       add  eax, 1
  1874.       add  eax, dword [a + 9 * 4]
  1875.       mov  [randseed], eax
  1876.       jmp _end;
  1877.  
  1878.     _2:
  1879.       ;base := base + 4 + a[88];
  1880.       mov  eax, [randseed]
  1881.       add  eax, 4
  1882.       add  eax, dword [a + 88 * 4]
  1883.       mov  [randseed], eax
  1884.       jmp _end;
  1885.  
  1886.     _3:
  1887.       ;randseed := randseed + 79 + a[43];
  1888.       mov  eax, [randseed]
  1889.       add  eax, 79
  1890.       add  eax, dword [a + 43 * 4]
  1891.       mov  [randseed], eax
  1892.       jmp _end;
  1893.  
  1894.     _4:
  1895.       ;randseed := randseed + 3 + a[12];
  1896.       mov  eax, [randseed]
  1897.       add  eax, 3
  1898.       add  eax, dword [a + 12 * 4]
  1899.       mov  [randseed], eax
  1900.       jmp _end;
  1901.  
  1902.     _5:
  1903.       ;randseed := randseed + 2 + a[63];
  1904.       mov  eax, [randseed]
  1905.       add  eax, 2
  1906.       add  eax, dword [a + 63 * 4]
  1907.       mov  [randseed], eax
  1908.       jmp _end;
  1909.  
  1910.     _6:
  1911.       ;randseed := randseed + 151 + a[24];
  1912.       mov  eax, [randseed]
  1913.       add  eax, 151
  1914.       add  eax, dword [a + 24 * 4]
  1915.       mov  [randseed], eax
  1916.  
  1917.       _end:
  1918.  
  1919.     mov  eax, [randseed]
  1920.     mov  edx, eax
  1921.     shl  edx, 16
  1922.     mov  bx, 100
  1923.     div  bx                   ; dx = randseed mod 100
  1924.  
  1925.     mov  ax, dx               ; ax = randseed mod 100
  1926.     mov  bx, 4
  1927.     mul  bx                   ; dx:ax = (randseed mod 100) * 4
  1928.     and  eax, $0000FFFF
  1929.     shr  edx, 16
  1930.     and  edx, $FFFF0000
  1931.     or   eax, edx
  1932.  
  1933.     mov  eax, dword [a + eax] ; eax = dword[a + (randseed mod 100) * 4]
  1934.                             ; ~ a[randseed mod 100]
  1935.     mov  ebx, dword [a + 47 * 4]
  1936.     mul  ebx                  ; eax = low(a[randseed mod 100] * a[47])
  1937.  
  1938.     add  eax, [randseed]
  1939.     add  eax, $4AE783A
  1940.     mov  [randseed], eax
  1941.  
  1942.     mov  eax, dword [a + 6 * 4]
  1943.     mov  edx, 0
  1944.     mov  ebx,  100
  1945.     div  ebx
  1946.     mov  eax, edx
  1947.     mov  ebx, 4
  1948.     mul  ebx                  ; eax = (dword [a + 6 * 4] mod 100) * 4 ~ a[6] mod 100
  1949.  
  1950.  
  1951.     mov  eax, dword [a + eax] ; eax = dword [a + (dword [a + 6 * 4] mod 100) * 4
  1952.  
  1953.                             ; ~ a[a[6] mod 100]
  1954.     add  eax, [randseed]
  1955.     mov  [random_value], eax
  1956.  
  1957.     mov  edx, 0
  1958.  
  1959.     mov  ebx, [range]
  1960.     div  ebx
  1961.     mov  [random_value], edx
  1962.  
  1963.     mov  al, [TimesCalled]
  1964.     xor  ah, ah
  1965.     inc  al
  1966.     mov  bl, 100
  1967.     div  bl
  1968.     mov  [TimesCalled], ah   ; TimesCalled = (TimesCalled + 1 ) mod 100
  1969.  
  1970.     mov  al, ah
  1971.     mov  bl, 4
  1972.     mul  bl
  1973.     and  eax, $0000FFFF
  1974.  
  1975.     mov  ebx, [randseed]
  1976.     mov  dword [a + eax], ebx ; a[TimesCalled] = randseed
  1977.  
  1978.     pop  ebx
  1979.   ret
  1980.  
  1981. ;******************************************************************************
  1982.  
  1983. ; <--- initialised data --->
  1984. if lang eq ru
  1985.   title db '‘®«¨â¥à',0
  1986.  
  1987.   new_game: db "®¢ ï ¨£à "
  1988.   new_game_len = $ - new_game
  1989.  
  1990.   exit: db "‚ë室"
  1991.   exit_len = $ - exit
  1992.  
  1993.   s: db "10"
  1994.  
  1995. else
  1996.   title db 'Freecell',0
  1997.  
  1998.   new_game: db "New game"
  1999.   new_game_len = $ - new_game
  2000.  
  2001.   exit: db "Exit"
  2002.   exit_len = $ - exit
  2003.  
  2004.   s: db "10"
  2005. end if
  2006.  
  2007.   negativedraw db 0          ; for procedure draw_card
  2008.  
  2009.  
  2010.   spade          file 'Spade.bmp': 54
  2011.   spade_updown   file 'SpadeUD.bmp': 54
  2012.   spade_small    file 'SpadeSml.bmp': 54
  2013.  
  2014.   club           file 'Club.bmp': 54
  2015.   club_updown    file 'ClubUD.bmp': 54
  2016.   club_small     file 'ClubSml.bmp': 54
  2017.  
  2018.   diamond        file 'Diam.bmp': 54
  2019.   diamond_updown file 'DiamUD.bmp': 54
  2020.   diamond_small  file 'DiamSml.bmp': 54
  2021.  
  2022.   heart          file 'Heart.bmp': 54
  2023.   heart_updown   file 'HeartUD.bmp': 54
  2024.   heart_small    file 'HeartSml.bmp': 54
  2025.  
  2026.  
  2027.   scNotSelected = 0
  2028.   scCommonCells = 1
  2029.   scTempCells = 2
  2030.  
  2031.  
  2032.   whereisselcard  dd scNotSelected
  2033.   columnofselcard dd 0       ; if WhereIsSelCard = scGeneralCells
  2034.                              ;    then this can be 0 .. 7,
  2035.                              ; if scTempCells then - 0 .. 3
  2036.                              ; if scNotSelected - no matter
  2037.  
  2038.   tempcells: times 4 db 52;
  2039.   homecells: times 4 db 52 ; maximal card code is 51
  2040.   cards:     times 8 * 19 db 52; - %
  2041.   pack:      times 52 db ?
  2042.  
  2043.  
  2044.  
  2045. udata
  2046.   process_info process_information
  2047.   syscolors system_colors
  2048.  
  2049.   WindowHeight rw 1
  2050.   WindowWidth rw 1
  2051.  
  2052.   xpos rd 1
  2053.   ypos rd 1
  2054.   bgcolor rd 1
  2055.   blackcolor rd 1
  2056.   redcolor rd 1
  2057.  
  2058.  
  2059.   lastparam rd 1                  ;
  2060.  
  2061.   randomcard rd 1                ; for new_game_click
  2062.  
  2063.   columnclicked rd 1             ; used in common_card_click, temp_cell_click,
  2064.   cardclicked rd 1               ;    home_cell_click
  2065.   clickedcardrange rd 1          ;
  2066.   clickedcardfamily rd 1         ;
  2067.  
  2068.  
  2069.   selcardcode rd 1               ; for procedure get_sel_card_code_and_addr
  2070.   selcardaddr rd 1               ;
  2071.  
  2072.   column rd 1                    ; for procedure draw_window
  2073.   row rd 1                          ;
  2074.  
  2075.   imagetoinvert rd 1             ; for procedure invert_image_colors
  2076.   sizeofimagetoinvert rd 1       ;
  2077.  
  2078.   ncolumn rd 1                   ; for procedure get_row_of_top_card_in_column
  2079.   topcardrow rd 1                ;
  2080.  
  2081.  
  2082.   color rd 1                     ; for procedue draw_card
  2083.   imageaddr rd 1                 ;
  2084.   imageflipaddr rd 1             ;
  2085.  
  2086.   cardcode rd 1                  ; used in differrent procedures
  2087.   cardrange rd 1                 ; cardcode = cardrange * 4 + cardfamily
  2088.   cardfamily rd 1                ;
  2089.  
  2090.   a: times 100 rd 1              ; for function Random
  2091.   range rd 1                     ;
  2092.   random_value rd 1              ;
  2093.   randseed rd 1                  ;
  2094.   TimesCalled rb 1               ;
  2095.  
  2096.   j rd 1                         ; number of card (in array cards) drawn now
  2097.   i rd 1                         ; used in many procedures of 1-st level
  2098.   k rd 1
  2099.  
  2100.   cardwidth = 80
  2101.   cardheight = 120
  2102.   radius = 4                     ; not recommended to change
  2103.   rowsize = 30                   ; distance between top poins
  2104.                                  ;of cards in neighboring rows
  2105.   columnspace = 5                ; minimal space between cards
  2106.   margin = 14                       ; margin of every card
  2107.  
  2108.   topbuttonsbarheight = 20
  2109.  
  2110.  
  2111. meos_app_end
  2112.