Subversion Repositories Kolibri OS

Rev

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