home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / games / volume4 / mahjongg / part03 / event.c next >
C/C++ Source or Header  |  1988-05-31  |  20KB  |  707 lines

  1. /*
  2.  *    Copyright 1988, Mark Holm
  3.  *            Exceptions
  4.  *
  5.  *    Acknowledgments to Dorothy Robinson for her artistic
  6.  *     abilities in drawing the icons and to Jim Batch for
  7.  *     technical support and graphical concepts (which I abandoned in favor
  8.  *       of the easy way out).
  9.  *
  10.  *    Permission is given to copy and distribute for non-profit purposes.
  11.  *
  12.  */
  13.  
  14. /*      This file has the event handlers for the background and
  15.  *       tiles in the play panel
  16.  */
  17.  
  18. #include <stdio.h>
  19. #include <sys/types.h>
  20. #include <suntool/sunview.h>
  21. #include <suntool/panel.h>
  22. #include <sunwindow/notify.h>
  23. #include <pixrect/pixrect.h>
  24.  
  25. #include "mahjongg.h"
  26.  
  27. /* external definitions */
  28.  
  29. extern Frame        main_frame;
  30. extern Panel        play_panel, message_panel;
  31. extern Panel_item    TL_hundred;
  32. extern Panel_item    TL_ten;
  33. extern Panel_item    TL_one;
  34. extern Panel_item    message;
  35. extern Panel_item    tile[144];
  36. extern Panel_item    tiles_left[3];
  37. extern Panel_item    board_num;
  38. extern Cursor        play_cursor;
  39.  
  40. extern boolean        BandW;
  41. extern Tiles        *board[144];
  42. extern int        tile_count;
  43. extern int        seed;
  44. extern Selected        last_item;
  45. extern Selected        selected[2];
  46.  
  47. /* local globals */
  48.  
  49. Selected        undo_tiles[144][2];
  50. int            undo_count;
  51. boolean            help_mode = FALSE;
  52.  
  53. /*******************************************/
  54.  
  55. void help_proc(item, event)
  56. Panel_item    item;
  57. Event        *event;
  58.  
  59. {
  60. int         i;
  61. Tiles         *data[2];
  62. static int    parse[2];
  63.  
  64.     if(!(selected[0].filled)) {
  65.     if(!(help_mode)) { /* Just starting. init and recall */
  66.  
  67.         help_mode = TRUE;
  68.         parse[0] = 143;
  69.         parse[1] = 142;
  70.         help_proc(item, event);
  71.  
  72.     } else { /* find next match */
  73.         for(; parse[0] >= 0; parse[0]--) {
  74.             if (!((board[parse[0]]->top_free &&            /* uncovered */
  75.             (board[parse[0]]->left_free || board[parse[0]]->right_free) && /* open */
  76.             (!(board[parse[0]]->removed)))))  /* not already used */
  77.             continue; /* not available go to next */
  78.  
  79.         for(; parse[1] >= 0; parse[1]--) { /* check for second tile */
  80.                 if ((board[parse[0]]->value == board[parse[1]]->value) && /* right value */
  81.             (parse[0] != parse[1]) &&    /* different item */
  82.             (board[parse[1]]->top_free &&            /* uncovered */
  83.             (board[parse[1]]->left_free || board[parse[1]]->right_free) && /* open */
  84.             (!(board[parse[1]]->removed)))) { /* not already used */
  85.  
  86.             /* Found a match, show it */
  87.  
  88.             /* flag found items */
  89.             selected[0].filled = TRUE;
  90.             selected[1].filled = TRUE;
  91.  
  92.             /* fake in some data */
  93.             selected[0].item = tile[parse[0]];
  94.             selected[0].event.ie_locx = ((int) panel_get(tile[parse[0]], PANEL_ITEM_X) + 10);
  95.             selected[0].event.ie_locy = ((int) panel_get(tile[parse[0]], PANEL_ITEM_Y) + 10);
  96.             selected[0].event.ie_time.tv_sec = event->ie_time.tv_sec;
  97.             selected[0].event.ie_time.tv_usec = event->ie_time.tv_usec;
  98.  
  99.             selected[1].item = tile[parse[1]];
  100.             selected[1].event.ie_locx = ((int) panel_get(tile[parse[1]], PANEL_ITEM_X) + 10);
  101.             selected[1].event.ie_locy = ((int) panel_get(tile[parse[1]], PANEL_ITEM_Y) + 10);
  102.             selected[1].event.ie_time.tv_sec = event->ie_time.tv_sec;
  103.             selected[1].event.ie_time.tv_usec = event->ie_time.tv_usec;
  104.  
  105.             /* Muppet news flash */
  106.             panel_begin_preview(selected[0].item, selected[0].event);
  107.             panel_begin_preview(selected[1].item, selected[1].event);
  108.  
  109.                 /* show next move message */
  110.                 panel_set(message, PANEL_LABEL_STRING,
  111.                         "Show next move? [Y] [] [N]",
  112.                        PANEL_SHOW_ITEM,
  113.                         TRUE, 0);
  114.  
  115.                        window_set(message_panel, WIN_IGNORE_PICK_EVENTS,
  116.                            WIN_MOUSE_BUTTONS, 0, 0);
  117.                        window_set(message_panel, WIN_IGNORE_KBD_EVENT,
  118.                                WIN_ASCII_EVENTS, 0, 0);
  119.                    cursor_set(play_cursor, CURSOR_IMAGE, &confirm, 0);
  120.                    window_set(play_panel, WIN_CURSOR, play_cursor, 0);
  121.  
  122.             parse[1]--; /* do loop step */
  123.             return; /* all done this rotation */
  124.  
  125.             }
  126.         } /* else go to next */
  127.              
  128.         parse[1] = parse[0] - 2; /* going around again */
  129.  
  130.         }
  131.  
  132.         /* no more moves beep and show message */
  133.  
  134.         window_bell(main_frame);
  135.  
  136.         panel_set(message, PANEL_LABEL_STRING,
  137.                 "No more moves. [DONE] [] []",
  138.                PANEL_SHOW_ITEM,
  139.                 TRUE, 0);
  140.  
  141.                window_set(message_panel, WIN_IGNORE_PICK_EVENTS,
  142.                    WIN_MOUSE_BUTTONS, 0, 0);
  143.                window_set(message_panel, WIN_IGNORE_KBD_EVENT,
  144.                        WIN_ASCII_EVENTS, 0, 0);
  145.            cursor_set(play_cursor, CURSOR_IMAGE, &confirm, 0);
  146.            window_set(play_panel, WIN_CURSOR, play_cursor, 0);
  147.  
  148.         }
  149.  
  150.     } else { /* search for available match */
  151.  
  152.     data[0] = (Tiles *) panel_get(selected[0].item, PANEL_CLIENT_DATA);
  153.  
  154.     for(i = 143; i >= 0; i--) {
  155.         if ((board[i]->value == data[0]->value) && /* right value */
  156.         (tile[i] != selected[0].item) &&    /* different item */
  157.         (board[i]->top_free &&            /* uncovered */
  158.         (board[i]->left_free || board[i]->right_free) && /* open */
  159.         (!(board[i]->removed)))) { /* not already used */
  160.  
  161.         /* found one */
  162.  
  163.         /* fake in some selected data */
  164.  
  165.         selected[1].item = tile[i];
  166.         selected[1].event.ie_locx = ((int) panel_get(tile[i], PANEL_ITEM_X) + 10);
  167.         selected[1].event.ie_locy = ((int) panel_get(tile[i], PANEL_ITEM_Y) + 10);
  168.         selected[1].event.ie_time.tv_sec = 10; /*sounds good */
  169.         selected[1].event.ie_time.tv_usec = 10; /*sounds good */
  170.  
  171.         selected[1].filled = TRUE;
  172.  
  173.         /* turn on preview */
  174.  
  175.         panel_begin_preview(selected[1].item, selected[1].event);
  176.  
  177.         /* set confirm message */
  178.  
  179.         panel_set(message, PANEL_LABEL_STRING,
  180.                     "Please confirm. [Y] [] [N]",
  181.                    PANEL_SHOW_ITEM,
  182.                     TRUE, 0);
  183.  
  184.                window_set(message_panel, WIN_IGNORE_PICK_EVENTS,
  185.                        WIN_MOUSE_BUTTONS, 0, 0);
  186.                window_set(message_panel, WIN_IGNORE_KBD_EVENT,
  187.                            WIN_ASCII_EVENTS, 0, 0);
  188.            cursor_set(play_cursor, CURSOR_IMAGE, &confirm, 0);
  189.            window_set(play_panel, WIN_CURSOR, play_cursor, 0);
  190.  
  191.         /* return to sender */
  192.  
  193.         return;
  194.  
  195.         }
  196.     }
  197.  
  198.         selected[0].filled = FALSE;
  199.     panel_cancel_preview(selected[0].item, selected[0].event);
  200.     window_bell(main_frame);
  201.  
  202.     }
  203. }
  204.  
  205. void remove_tiles(REMOVE)
  206. boolean    REMOVE;
  207.  
  208. {
  209. Tiles    *data[2];
  210. int     i;
  211. int     tiles_left_hun;
  212. int     tiles_left_ten;
  213. int     tiles_left_one;
  214. Pixwin  *pw;
  215. Rect    *r;
  216.  
  217.     if (REMOVE) {
  218.     /* get data from items to be removed */
  219.     data[0] = (Tiles *) panel_get(selected[0].item, PANEL_CLIENT_DATA);
  220.     data[1] = (Tiles *) panel_get(selected[1].item, PANEL_CLIENT_DATA);
  221.  
  222.     } else {
  223.     /* get data from items to be replaced */
  224.     data[0] = (Tiles *) panel_get(undo_tiles[undo_count][0].item, PANEL_CLIENT_DATA);
  225.     data[1] = (Tiles *) panel_get(undo_tiles[undo_count][1].item, PANEL_CLIENT_DATA);
  226.     }
  227.  
  228.     /* adjust adjacent tiles */
  229.     for(i = 0; i < 2 && data[0]->left_next[i] != 999; board[data[0]->left_next[i]]->right_free = REMOVE, i++);
  230.     for(i = 0; i < 2 && data[1]->left_next[i] != 999; board[data[1]->left_next[i]]->right_free = REMOVE, i++);
  231.     for(i = 0; i < 2 && data[0]->right_next[i] != 999; board[data[0]->right_next[i]]->left_free = REMOVE, i++);
  232.     for(i = 0; i < 2 && data[1]->right_next[i] != 999; board[data[1]->right_next[i]]->left_free = REMOVE, i++);
  233.     for(i = 0; i < 4 && data[0]->covered[i] != 999; board[data[0]->covered[i]]->top_free = REMOVE, i++);
  234.     for(i = 0; i < 4 && data[1]->covered[i] != 999; board[data[1]->covered[i]]->top_free = REMOVE, i++);
  235.  
  236.     /* set removed flags */
  237.     data[0]->removed = REMOVE;
  238.     data[1]->removed = REMOVE;
  239.  
  240.     if (REMOVE) {
  241.     /* turn off preview */
  242.     panel_cancel_preview(selected[0].item, selected[0].event);
  243.     panel_cancel_preview(selected[1].item, selected[1].event);
  244.     } else  /* check to see if previewing an item and un-preview and select */
  245.     if (selected[0].filled) {
  246.         panel_cancel_preview(selected[0].item, selected[0].event);
  247.         selected[0].filled = FALSE;
  248.     }
  249.  
  250.     /* fix playing field */
  251.     pw = (Pixwin *) window_get(play_panel, WIN_PIXWIN);
  252.     r  = (Rect *)   window_get(play_panel, WIN_RECT);
  253.     pw_batch_on(pw);
  254.     pw_lock(pw, r);
  255.     panel_paint(play_panel, PANEL_NONE);
  256.     panel_set((REMOVE) ? selected[0].item : undo_tiles[undo_count][0].item, PANEL_SHOW_ITEM, !REMOVE, 0);
  257.     panel_set((REMOVE) ? selected[1].item : undo_tiles[undo_count][1].item, PANEL_SHOW_ITEM, !REMOVE, 0);
  258.     panel_paint(play_panel, PANEL_NO_CLEAR);
  259.     pw_unlock(pw);
  260.     pw_batch_off(pw);
  261.  
  262.     /* deselect tiles */
  263.     selected[0].filled = FALSE;
  264.     selected[1].filled = FALSE;
  265.  
  266.     /* fix tile counter */
  267.     tile_count += (REMOVE) ? -2 : 2;
  268.  
  269.     tiles_left_hun = tile_count / 100;
  270.     tiles_left_ten = (tile_count - (tiles_left_hun * 100)) / 10;
  271.     tiles_left_one = tile_count - (tiles_left_hun * 100) - (tiles_left_ten * 10);
  272.  
  273.     /* display hundreds tile by own status */
  274.     panel_set(TL_hundred, PANEL_SHOW_ITEM, tiles_left_hun, 0);
  275.  
  276.     /* display tens tile by own status ored with hundreds status */
  277.     panel_set(TL_ten, PANEL_SHOW_ITEM, tiles_left_hun || tiles_left_ten, 0);
  278.  
  279.     switch(tiles_left_ten) {
  280.     case 0:
  281.         panel_set(TL_ten, PANEL_LABEL_IMAGE, (BandW) ? &NUM0 : &cNUM0, 0);
  282.         break;
  283.     case 1:
  284.         panel_set(TL_ten, PANEL_LABEL_IMAGE, (BandW) ? &NUM1 : &cNUM1, 0);
  285.         break;
  286.     case 2:
  287.         panel_set(TL_ten, PANEL_LABEL_IMAGE, (BandW) ? &NUM2 : &cNUM2, 0);
  288.         break;
  289.     case 3:
  290.         panel_set(TL_ten, PANEL_LABEL_IMAGE, (BandW) ? &NUM3 : &cNUM3, 0);
  291.         break;
  292.     case 4:
  293.         panel_set(TL_ten, PANEL_LABEL_IMAGE, (BandW) ? &NUM4 : &cNUM4, 0);
  294.         break;
  295.     case 5:
  296.         panel_set(TL_ten, PANEL_LABEL_IMAGE, (BandW) ? &NUM5 : &cNUM5, 0);
  297.         break;
  298.     case 6:
  299.         panel_set(TL_ten, PANEL_LABEL_IMAGE, (BandW) ? &NUM6 : &cNUM6, 0);
  300.         break;
  301.     case 7:
  302.         panel_set(TL_ten, PANEL_LABEL_IMAGE, (BandW) ? &NUM7 : &cNUM7, 0);
  303.         break;
  304.     case 8:
  305.         panel_set(TL_ten, PANEL_LABEL_IMAGE, (BandW) ? &NUM8 : &cNUM8, 0);
  306.         break;
  307.     case 9:
  308.         panel_set(TL_ten, PANEL_LABEL_IMAGE, (BandW) ? &NUM9 : &cNUM9, 0);
  309.         break;
  310.     }
  311.  
  312.     switch(tiles_left_one) { /* only need even tiles */
  313.     case 0:
  314.         panel_set(TL_one, PANEL_LABEL_IMAGE, (BandW) ? &NUM0 : &cNUM0, 0);
  315.         break;
  316.     case 2:
  317.         panel_set(TL_one, PANEL_LABEL_IMAGE, (BandW) ? &NUM2 : &cNUM2, 0);
  318.         break;
  319.     case 4:
  320.         panel_set(TL_one, PANEL_LABEL_IMAGE, (BandW) ? &NUM4 : &cNUM4, 0);
  321.         break;
  322.     case 6:
  323.         panel_set(TL_one, PANEL_LABEL_IMAGE, (BandW) ? &NUM6 : &cNUM6, 0);
  324.         break;
  325.     case 8:
  326.         panel_set(TL_one, PANEL_LABEL_IMAGE, (BandW) ? &NUM8 : &cNUM8, 0);
  327.         break;
  328.     }
  329.  
  330.     if (REMOVE) {
  331.  
  332.     /* update undo_count */
  333.     undo_count++;
  334.  
  335.     /* update removed array */
  336.     undo_tiles[undo_count][0].item = selected[0].item;
  337.     undo_tiles[undo_count][0].event.ie_locx = selected[0].event.ie_locx;
  338.     undo_tiles[undo_count][0].event.ie_locy = selected[0].event.ie_locy;
  339.     undo_tiles[undo_count][0].event.ie_time.tv_sec = selected[0].event.ie_time.tv_sec;
  340.     undo_tiles[undo_count][0].event.ie_time.tv_usec = selected[0].event.ie_time.tv_usec;
  341.     undo_tiles[undo_count][0].filled = TRUE;
  342.  
  343.     undo_tiles[undo_count][1].item = selected[1].item;
  344.     undo_tiles[undo_count][1].event.ie_locx = selected[1].event.ie_locx;
  345.     undo_tiles[undo_count][1].event.ie_locy = selected[1].event.ie_locy;
  346.     undo_tiles[undo_count][1].event.ie_time.tv_sec = selected[1].event.ie_time.tv_sec;
  347.     undo_tiles[undo_count][1].event.ie_time.tv_usec = selected[1].event.ie_time.tv_usec;
  348.     undo_tiles[undo_count][1].filled = TRUE;
  349.  
  350.     /* remove confirm message */
  351.  
  352.     panel_set(message,PANEL_SHOW_ITEM, FALSE, 0);
  353.  
  354.     window_set(message_panel, WIN_CONSUME_PICK_EVENTS,
  355.                    WIN_MOUSE_BUTTONS, 0,
  356.                    0);
  357.     window_set(message_panel, WIN_CONSUME_KBD_EVENT,
  358.                    WIN_ASCII_EVENTS, 0, 0);
  359.     
  360.     cursor_set(play_cursor, CURSOR_IMAGE, &stick, 0);
  361.     window_set(play_panel, WIN_CURSOR, play_cursor, 0);
  362.  
  363.     /* check for clean board and congrat them */
  364.  
  365.     if ( tiles_left_hun == 0 && tiles_left_ten == 0 && tiles_left_one == 0) 
  366.         panel_set(message, PANEL_LABEL_STRING,
  367.                 "Congratulations!! Press 'AGAIN' or 'NEW'",
  368.                PANEL_SHOW_ITEM,
  369.                 TRUE, 0);
  370.  
  371.     } else { /* decrement undo_count */
  372.     undo_tiles[undo_count][0].filled = FALSE;
  373.     undo_tiles[undo_count][1].filled = FALSE;
  374.     undo_count--;
  375.     }
  376. }
  377.  
  378. void play_back_proc(where, event)
  379. Panel         where;
  380. Event        *event;
  381. {
  382.     
  383.     if (!(selected[0].filled) && help_mode) { /* stop helping */
  384.     if (event_id(event) == MS_LEFT) { /* all done */
  385.  
  386.             /* remove message */
  387.  
  388.             panel_set(message,PANEL_SHOW_ITEM, FALSE, 0);
  389.            window_set(message_panel, WIN_CONSUME_PICK_EVENTS,
  390.                        WIN_MOUSE_BUTTONS, 0,
  391.                       0);
  392.            window_set(message_panel, WIN_CONSUME_KBD_EVENT,
  393.                        WIN_ASCII_EVENTS, 0, 0);
  394.            cursor_set(play_cursor, CURSOR_IMAGE, &stick, 0);
  395.            window_set(play_panel, WIN_CURSOR, play_cursor, 0);
  396.  
  397.         /* exit help_mode */
  398.  
  399.         help_mode = FALSE;
  400.  
  401.     }
  402.     } else { /* doing confirm or next help */
  403.  
  404.     if (selected[1].filled) { /* doing confirm  or next help */
  405.  
  406.         switch (event_id(event)) {
  407.  
  408.         case MS_LEFT:
  409.             /* confirmed selection */
  410.             if (event_is_up(event)) {
  411.             if (help_mode) { /* do next help */
  412.  
  413.                 /* cancel preview of selected tiles */
  414.                 panel_cancel_preview(selected[0].item, selected[0].event);
  415.                 panel_cancel_preview(selected[1].item, selected[1].event);
  416.                 /* Clean up selected's variables */
  417.                 selected[0].filled = FALSE;
  418.                 selected[1].filled = FALSE;
  419.  
  420.                     /* remove confirm message */
  421.                     panel_set(message,PANEL_SHOW_ITEM, FALSE, 0);
  422.  
  423.                 /* do next help */
  424.                 help_proc();
  425.  
  426.             } else { /* confirmed selection. remove them */
  427.                 remove_tiles(TRUE);
  428.             }
  429.             }
  430.             break;
  431.  
  432.         case MS_RIGHT:
  433.             /* refused selection */
  434.             if (event_is_down(event)) {
  435.                 /* cancel preview of selected tiles */
  436.                 panel_cancel_preview(selected[0].item, selected[0].event);
  437.                 panel_cancel_preview(selected[1].item, selected[1].event);
  438.                 /* Clean up selected's variables */
  439.                 selected[0].filled = FALSE;
  440.                 selected[1].filled = FALSE;
  441.  
  442.                     /* remove confirm message */
  443.  
  444.                     panel_set(message,PANEL_SHOW_ITEM, FALSE, 0);
  445.                    window_set(message_panel, WIN_CONSUME_PICK_EVENTS,
  446.                                WIN_MOUSE_BUTTONS, 0,
  447.                                0);
  448.                    window_set(message_panel, WIN_CONSUME_KBD_EVENT,
  449.                                WIN_ASCII_EVENTS, 0, 0);
  450.                    cursor_set(play_cursor, CURSOR_IMAGE, &stick, 0);
  451.                    window_set(play_panel, WIN_CURSOR, play_cursor, 0);
  452.  
  453.                 /* if in help mode toggle out */
  454.                 if (help_mode) help_mode = FALSE; 
  455.  
  456.             }
  457.             break;
  458.     }
  459.     } else {
  460.  
  461.         /* check for help requests */
  462.  
  463.     if ((event_id(event) == MS_MIDDLE) && event_is_up(event) && selected[0].filled) {
  464.  
  465.         help_proc();
  466.  
  467.     } else  /* or MS_LEFT up outside of playing area */
  468.         if ((event_id(event) == MS_LEFT) && event_is_up(event) &&
  469.          last_item.filled) { /* went down on something */ 
  470.  
  471.         window_bell(main_frame);
  472.         last_item.filled = FALSE;
  473.  
  474.         if (!selected[0].filled || (selected[0].item != last_item.item)) {
  475.             /* not aborting deselection */
  476.             panel_cancel_preview(last_item.item, last_item.event);
  477.         }
  478.         }
  479.     }
  480.    }
  481. }
  482.  
  483. void play_event_proc(item, event)
  484. Panel_item         item;
  485. Event            *event;
  486.  
  487. {
  488. Tiles    *data;
  489. int    value;
  490. int    i;
  491. int    x;
  492. int    y;
  493.  
  494.     /* check to see if in help_mode */
  495.  
  496.     if (help_mode) {
  497.     play_back_proc(play_panel, event);
  498.     return;
  499.     }
  500.  
  501.     /* check to see if just confirming */
  502.  
  503.     if (selected[1].filled) {
  504.     play_back_proc(play_panel, event);
  505.     return;
  506.     }
  507.  
  508.     /* translate item to top level available */
  509.  
  510.     if ( (event_id(event) == MS_LEFT) &&
  511.          ((ROW2 - B_TILE_SHADOW) <= event->ie_locy) &&
  512.          (event->ie_locy <= (ROW2 - B_TILE_SHADOW + (6 * W_BASE_TILE))) &&
  513.          ((COL5 - S_TILE_SHADOW) <= event->ie_locx) &&
  514.      (event->ie_locx <= (COL5 - S_TILE_SHADOW + (6 * H_BASE_TILE))) ) { /* in overlap area, check for stacks */
  515.  
  516.     for(i = 143; i > 86 ; i--) { /* check from top to bottom */
  517.  
  518.         x = (int) panel_get(tile[i], PANEL_ITEM_X);
  519.         y = (int) panel_get(tile[i], PANEL_ITEM_Y);
  520.  
  521.         if ( (x <= event->ie_locx) &&
  522.          (event->ie_locx <= x + W_BASE_TILE) &&
  523.          (y <= event->ie_locy) &&
  524.          (event->ie_locy <= y + H_BASE_TILE) ) { /* right spot */
  525.  
  526.             if ( !(board[i]->removed) ) {
  527.  
  528.            item = tile[i]; /* got it */
  529.            break;
  530.  
  531.         } else { /* look on next layer down */
  532.            /* take first covered tile and add 1 for loop */
  533.            if (i != 143) i = board[i]->covered[0] + 1;
  534.         }
  535.         } /* wrong location. try again */
  536.     } /* next loop */
  537.     }
  538.  
  539.     /* get data from item selected */
  540.  
  541.     data = (Tiles *) panel_get(item, PANEL_CLIENT_DATA);
  542.     value = data->value;
  543.  
  544.     switch(event_id(event)) {
  545.  
  546.     case MS_LEFT: 
  547.         /* Left button down begin selection */
  548.         if (event_is_down(event)) {
  549.                 if ( data->top_free && (data->left_free || data->right_free)) {
  550.  
  551.             if ( !(selected[0].filled) || (last_item.item != item) ) { /* don't double up */
  552.                     panel_begin_preview(item, event);
  553.             }
  554.  
  555.                 /* file last_item slected for future reference */
  556.                 last_item.item = item;
  557.                 last_item.event.ie_locx = event->ie_locx;
  558.                 last_item.event.ie_locy = event->ie_locy;
  559.                 last_item.event.ie_time.tv_sec = event->ie_time.tv_sec;
  560.                 last_item.event.ie_time.tv_usec = event->ie_time.tv_usec;
  561.  
  562.                 last_item.filled = TRUE;
  563.  
  564.             } else { /* beep at them */
  565.  
  566.             window_bell(main_frame);
  567.  
  568.             }
  569.  
  570.         } else {
  571.  
  572.         /* button went up, check same item as down and grab it */
  573.  
  574.             if ((last_item.filled)) { /* else ignore it */
  575.  
  576.             if (item != last_item.item) { /* beep at them */
  577.  
  578.                 last_item.filled = FALSE;
  579.                 window_bell(main_frame);
  580.                 if (!selected[0].filled || (selected[0].item != last_item.item)) {
  581.                 /* not aborting deselect */
  582.                 panel_cancel_preview(last_item.item, last_item.event);
  583.  
  584.                 }
  585.  
  586.                 } else {
  587.  
  588.                 if (!(selected[0].filled)) {
  589.  
  590.                 /* fill first selection if empty */
  591.                 selected[0].item = item;
  592.                 selected[0].event.ie_locx = event->ie_locx;
  593.                 selected[0].event.ie_locy = event->ie_locy;
  594.                 selected[0].event.ie_time.tv_sec = event->ie_time.tv_sec;
  595.                 selected[0].event.ie_time.tv_usec = event->ie_time.tv_usec;
  596.  
  597.                 selected[0].filled = TRUE;
  598.  
  599.                 /* clear last item */
  600.  
  601.                 last_item.filled = FALSE;
  602.  
  603.                     } else {
  604.  
  605.                 if (item == selected[0].item) { /* deselect item */
  606.  
  607.                     panel_cancel_preview(selected[0].item, selected[0].event);
  608.  
  609.                     /* clear last item and selected[0] */
  610.  
  611.                     selected[0].filled = FALSE;
  612.                     last_item.filled   = FALSE;
  613.  
  614.                 } else {
  615.                         data = (Tiles *) panel_get(selected[0].item, PANEL_CLIENT_DATA);
  616.                     if ( value == data->value) {
  617.                         /* fill second and show confirm message */
  618.  
  619.                         selected[1].item = item;
  620.                         selected[1].event.ie_locx = event->ie_locx;
  621.                         selected[1].event.ie_locy = event->ie_locy;
  622.                         selected[1].event.ie_time.tv_sec = event->ie_time.tv_sec;
  623.                         selected[1].event.ie_time.tv_usec = event->ie_time.tv_usec;
  624.  
  625.                         selected[1].filled = TRUE;
  626.  
  627.                         /* clear last item */
  628.  
  629.                         last_item.filled = FALSE;
  630.  
  631.                     panel_set(message, PANEL_LABEL_STRING,
  632.                                 "Please confirm. [Y] [] [N]",
  633.                                PANEL_SHOW_ITEM,
  634.                                 TRUE, 0);
  635.  
  636.                            window_set(message_panel, WIN_IGNORE_PICK_EVENTS,
  637.                                    WIN_MOUSE_BUTTONS, 0, 0);
  638.                            window_set(message_panel, WIN_IGNORE_KBD_EVENT,
  639.                                    WIN_ASCII_EVENTS, 0, 0);
  640.  
  641.                        cursor_set(play_cursor, CURSOR_IMAGE, &confirm, 0);
  642.                        window_set(play_panel, WIN_CURSOR, play_cursor, 0);
  643.  
  644.                     } else { /* beep at them */
  645.  
  646.                             panel_cancel_preview(last_item.item, last_item.event);
  647.                             panel_cancel_preview(selected[0].item, selected[0].event);
  648.                         last_item.filled = FALSE;
  649.                         selected[0].filled = FALSE;
  650.                         window_bell(main_frame);
  651.  
  652.                     }
  653.                 }
  654.                 }
  655.                 }
  656.             }
  657.         }
  658.         break;
  659.  
  660.         case MS_MIDDLE:
  661.  
  662.         if (event_is_up(event) && selected[0].filled) { /* request for help */
  663.  
  664.             help_proc();
  665.         }
  666.  
  667.         break;
  668.  
  669.         /* and all else shall pass */
  670.     }
  671. }
  672.  
  673. void quit_proc()
  674. {
  675.     window_destroy(main_frame);
  676. }
  677.  
  678. void new_proc()
  679. {
  680.  
  681.     seed = random() % 20011;
  682.     build_image(FALSE);
  683.     place_tiles(FALSE);
  684. }
  685.  
  686. void again_proc()
  687. {
  688.     build_image(TRUE);
  689.     place_tiles(FALSE);
  690. }
  691.  
  692. void undo_proc()
  693.  
  694. {
  695.     if(undo_count < 0)
  696.     window_bell(main_frame);
  697.     else
  698.     remove_tiles(FALSE);
  699. }
  700.  
  701. void board_num_proc()
  702. {
  703.     sscanf((char *) panel_get(board_num, PANEL_VALUE), "%d", &seed);
  704.     build_image(FALSE);
  705.     place_tiles(FALSE);
  706. }
  707.