home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / games / volume4 / mahjongg / part03 / mahjongg.c < prev   
C/C++ Source or Header  |  1988-05-31  |  26KB  |  1,111 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. #ifndef lint
  15. static char *rcs = "$header$ Copyright 1988 Mark Holm";
  16. #endif !lint
  17.  
  18. /*
  19.  * $log$
  20.  */
  21.  
  22. #include <stdio.h>
  23. #include <sys/types.h>
  24. #include <sys/time.h>
  25. #include <sys/ioctl.h>
  26. #include <sys/file.h>
  27. #include <sun/fbio.h>
  28. #include <suntool/sunview.h>
  29. #include <suntool/panel.h>
  30. #include <suntool/canvas.h>
  31. #include <suntool/icon.h>
  32. #include <sunwindow/notify.h>
  33. #include <pixrect/pixrect.h>
  34.  
  35. #include "mahjongg.h"
  36.  
  37. void            die();
  38. void            build_image();
  39. void            place_tiles();
  40. Pixrect            *color_button();
  41.  
  42.  
  43. /* Black and white closed icon image */
  44.  
  45. static short        icon_image[] = {
  46. #include "mahjongg.icon"
  47. };
  48. DEFINE_ICON_FROM_IMAGE(icon, icon_image); /* Black and white icon */
  49. struct icon    *cicon;              /* storage for color icon */
  50.  
  51. /* externals */
  52.  
  53. extern void        quit_proc();
  54. extern void        undo_proc();
  55. extern void        new_proc();
  56. extern void        again_proc();
  57. extern void        help_proc();
  58. extern void        board_num_proc();
  59. extern void        play_back_proc();
  60. extern void        play_event_proc();
  61.  
  62. extern short        stick_image[];
  63. extern int        undo_count;
  64.  
  65. /* overlap globals */
  66.  
  67.  
  68. Frame            main_frame;
  69. Panel            play_panel, message_panel;
  70. Panel_item        TL_hundred;
  71. Panel_item        TL_ten;
  72. Panel_item        TL_one;
  73. Panel_item        message;
  74. Panel_item        tile[144];
  75. Panel_item        tiles_left[3];
  76. Cursor            play_cursor;
  77. boolean            BandW = FALSE;
  78. Tiles            *board[144];
  79. Selected        selected[2];
  80. Selected        last_item;
  81. int            tile_count;
  82. char            state[256];
  83.  
  84. /* local globals */
  85.  
  86. Pixwin            *frame_pw;
  87. Panel_item        tile_message;
  88. Panel_item        cp1;
  89. Panel_item        cp2;
  90. Panel_item        cp3;
  91. Panel_item        cp4;
  92. Panel_item        help;
  93. Panel_item        again;
  94. Panel_item        new;
  95. Panel_item        quit;
  96. Panel_item        undo;
  97. Panel_item        board_num;
  98. struct timeval        *tp;
  99. struct timezone        *tz;
  100. int            seed;
  101.  
  102. /* define color map */
  103.  
  104. #include "color.h"
  105.  
  106. main(argc, argv)
  107. int argc;
  108. char **argv;
  109. {
  110.     struct pixfont    *panel_font;
  111.     struct pixfont    *dummy_font;
  112.        int         i;
  113.        int         middle;
  114.     struct fbtype     fb;
  115.        int         open_stat;
  116.  
  117.     /* determine type of frame buffer and set BandW accordingly */
  118.  
  119.     open_stat = open("/dev/fb", O_RDONLY);
  120.     (void) ioctl(open_stat, FBIOGTYPE, &fb);
  121.  
  122.     if ( (fb.fb_type == FBTYPE_SUN1BW) ||
  123.      (fb.fb_type == FBTYPE_SUN2BW) ||
  124.      (fb.fb_type == FBTYPE_SUN3BW) ||
  125.      (fb.fb_type == FBTYPE_SUN4BW) )
  126.         BandW = TRUE;
  127.  
  128.     /* initialize random number generator seed */
  129.  
  130.     tp = (struct timeval *) malloc(sizeof(struct timeval));
  131.     tz = (struct timezone *) malloc(sizeof(struct timezone));
  132.     gettimeofday(tp, tz);
  133.     (void) initstate((unsigned) (tp->tv_sec % 255), state, 256); /* initialize random state array */
  134.     seed = RANDOM(20011);
  135.     free(tp);
  136.     free(tz);
  137.  
  138.     /* create main frame */
  139.    
  140.     main_frame = window_create(NULL, FRAME,
  141.                    FRAME_SHOW_LABEL, FALSE,
  142.                    FRAME_SUBWINDOWS_ADJUSTABLE, FALSE,
  143.                    FRAME_ICON, &icon,
  144.                    FRAME_ARGC_PTR_ARGV, &argc, argv,
  145.                    WIN_HEIGHT, FRAME_Y_MAX,
  146.                    WIN_WIDTH, FRAME_X_MAX,
  147.                    0);
  148.  
  149.     /* parse arguments */
  150.     for(argc--, argv++; argc > 0; argc--, argv++)
  151.     if (argv[0][0] = '-')
  152.         switch (argv[0][1]) {
  153.         case 'c': /* force color */
  154.         BandW = FALSE;
  155.         break;
  156.         case 'b': /* force black and white */
  157.         BandW = TRUE;
  158.         break;
  159.         case 'n': /* set board number */
  160.         if(argc-- == 0)
  161.             die("Usage: mahjongg [-b] [-c] [-n #]\n", 0);
  162.         argv++;
  163.             sscanf(argv[0] , "%d", &seed);
  164.         if (seed > 20011) {
  165.             printf("Board numbers must be < 20011");
  166.             seed %= 20011;
  167.         }
  168.         break;
  169.         default:
  170.         die("Usage: mahjongg [-b] [-c] [-n #]\n", 0);
  171.         break;
  172.         }
  173.     else
  174.         die("Usage: mahjongg [-b] [-c] [-n #]\n", 0);
  175.         
  176.     /* if color then apply color icon to window icon */
  177.  
  178.     if(!BandW) {
  179.     cicon = (struct icon *) window_get(main_frame, FRAME_ICON);
  180.     cicon->ic_mpr = &cicon_image;
  181.      }
  182.  
  183.     /* get pixwin to apply color maps */
  184.  
  185.     frame_pw  = (Pixwin *) window_get(main_frame, WIN_PIXWIN, 0);
  186.  
  187.     /* apply color maps to frame pixwin */
  188.  
  189.     pw_setcmsname(frame_pw, "mahjongg");
  190.     pw_putcolormap(frame_pw, 0, MAX_COLORS+1, red, green, blue);
  191.     if (BandW)
  192.         pw_putcolormap(frame_pw, 0, 1, &(red[WHITE]), &(green[WHITE]), &(blue[WHITE]));
  193.  
  194.     /* set inheritable colors */
  195.  
  196.     window_set(main_frame, FRAME_INHERIT_COLORS, TRUE, 0);
  197.  
  198.     /* set up the panel on the right hand side */
  199.     
  200.     dummy_font = pf_open("/usr/lib/fonts/fixedwidthfonts/screen.r.7");
  201.     panel_font = pf_open("/usr/lib/fonts/fixedwidthfonts/screen.b.14");
  202.     message_panel = window_create(main_frame, PANEL,
  203.               WIN_HEIGHT, MESS_Y_MAX,
  204.               WIN_WIDTH, MESS_X_MAX,
  205.               WIN_X, 0,
  206.               WIN_Y, 0,
  207.               WIN_FONT, dummy_font,
  208.               0);
  209.  
  210.     /* determine middle of panel */
  211.  
  212.     middle = (MESS_X_MAX / 2);
  213.  
  214.     /* create tile counters */
  215.  
  216.     TL_hundred = panel_create_item(message_panel, PANEL_MESSAGE,
  217.                  PANEL_LABEL_IMAGE,
  218.                    (BandW) ? &NUM1 : &cNUM1,
  219.                  PANEL_ITEM_Y, ATTR_ROW(7),
  220.                  PANEL_ITEM_X, X_LOC,
  221.                  0);
  222.     TL_ten = panel_create_item(message_panel, PANEL_MESSAGE,
  223.                  PANEL_LABEL_IMAGE,
  224.                    (BandW) ? &NUM4 : &cNUM4,
  225.                  PANEL_ITEM_Y, ATTR_ROW(7),
  226.                  PANEL_ITEM_X, X_LOC +  W_BASE_TILE,
  227.                  0);
  228.     TL_one = panel_create_item(message_panel, PANEL_MESSAGE,
  229.                  PANEL_LABEL_IMAGE,
  230.                    (BandW) ? &NUM4 : &cNUM4,
  231.                  PANEL_ITEM_Y, ATTR_ROW(7),
  232.                  PANEL_ITEM_X, X_LOC + (W_BASE_TILE * 2),
  233.                  0);
  234.  
  235.     /* create game label messages */
  236.  
  237.     cp1 = panel_create_item(message_panel, PANEL_MESSAGE,
  238.                  PANEL_LABEL_FONT, panel_font,
  239.                  PANEL_LABEL_STRING, "MAHJONGG",
  240.                  PANEL_ITEM_Y, ATTR_ROW(1) - 11,
  241.                  PANEL_ITEM_X, middle - 65,
  242.                  0);
  243.     cp2 = panel_create_item(message_panel, PANEL_MESSAGE,
  244.                  PANEL_LABEL_FONT, dummy_font,
  245.                  PANEL_LABEL_STRING, "Copyright 1988",
  246.                  PANEL_ITEM_Y, ATTR_ROW(2),
  247.                  PANEL_ITEM_X, middle - 70,
  248.                  0);
  249.     cp3 = panel_create_item(message_panel, PANEL_MESSAGE,
  250.                  PANEL_LABEL_FONT, dummy_font,
  251.                  PANEL_LABEL_STRING, "Mark A. Holm",
  252.                  PANEL_ITEM_Y, ATTR_ROW(3),
  253.                  PANEL_ITEM_X, middle - 65,
  254.                  0);
  255.     cp3 = panel_create_item(message_panel, PANEL_MESSAGE,
  256.                  PANEL_LABEL_FONT, dummy_font,
  257.                  PANEL_LABEL_STRING, "Exceptions",
  258.                  PANEL_ITEM_Y, ATTR_ROW(4),
  259.                  PANEL_ITEM_X, middle - 60,
  260.                  0);
  261.     tile_message = panel_create_item(message_panel, PANEL_MESSAGE,
  262.                                      PANEL_LABEL_FONT, panel_font,
  263.                                      PANEL_LABEL_STRING, "Tiles Remaining",
  264.                                      PANEL_ITEM_Y, ATTR_ROW(5),
  265.                                      PANEL_ITEM_X,  X_LOC + 20,
  266.                                      0);
  267.  
  268.     /* create seed item */
  269.  
  270.     board_num = panel_create_item(message_panel, PANEL_TEXT,
  271.                                      PANEL_LABEL_FONT, panel_font,
  272.                                      PANEL_VALUE_FONT, panel_font,
  273.                                      PANEL_LABEL_STRING, "Board Number : ",
  274.                      PANEL_VALUE, "",
  275.                                      PANEL_ITEM_Y, ATTR_ROW(6),
  276.                                      PANEL_ITEM_X,  middle,
  277.                      PANEL_NOTIFY_PROC, board_num_proc,
  278.                                      0);
  279.  
  280.     /* create control buttons */
  281.  
  282.     help = panel_create_item(message_panel, PANEL_BUTTON,
  283.                  PANEL_ITEM_Y, ATTR_ROW(8),
  284.                  PANEL_ITEM_X, middle,
  285.                                  PANEL_LABEL_IMAGE,
  286.                                    color_button(panel_button_image(message_panel,
  287.                                   "HELP",
  288.                                   6,
  289.                                                            panel_font),
  290.                         CYAN),
  291.                  PANEL_NOTIFY_PROC, help_proc,
  292.                  0);
  293.  
  294.     again = panel_create_item(message_panel, PANEL_BUTTON,
  295.                                  PANEL_LABEL_IMAGE,
  296.                                    color_button(panel_button_image(message_panel,
  297.                                   "AGAIN",
  298.                                   6,
  299.                                                            panel_font),
  300.                         YELLOW),
  301.                  PANEL_NOTIFY_PROC, again_proc,
  302.                  0);
  303.  
  304.     new = panel_create_item(message_panel, PANEL_BUTTON,
  305.                                  PANEL_LABEL_IMAGE,
  306.                                    color_button(panel_button_image(message_panel,
  307.                                   "NEW",
  308.                                   6,
  309.                                                            panel_font),
  310.                         GREEN),
  311.                  PANEL_NOTIFY_PROC, new_proc,
  312.                  0);
  313.  
  314.     undo = panel_create_item(message_panel, PANEL_BUTTON,
  315.                                  PANEL_LABEL_IMAGE,
  316.                                    color_button(panel_button_image(message_panel,
  317.                                   "UNDO",
  318.                                   6,
  319.                                                            panel_font),
  320.                         MAGENTA),
  321.                  PANEL_NOTIFY_PROC, undo_proc,
  322.                  PANEL_SHOW_ITEM, TRUE,
  323.                  0);
  324.  
  325.     quit = panel_create_item(message_panel, PANEL_BUTTON,
  326.                                  PANEL_LABEL_IMAGE,
  327.                                    color_button(panel_button_image(message_panel,
  328.                                   "QUIT",
  329.                                   6,
  330.                                                            panel_font),
  331.                         RED),
  332.                  PANEL_NOTIFY_PROC, quit_proc,
  333.                  0);
  334.  
  335.     /* place conceled message */
  336.  
  337.     message = panel_create_item(message_panel, PANEL_MESSAGE,
  338.                                  PANEL_LABEL_FONT, panel_font,
  339.                                  PANEL_ITEM_Y, ATTR_ROW(10),
  340.                  PANEL_ITEM_X, middle,
  341.                  PANEL_LABEL_STRING, "",
  342.                  PANEL_SHOW_ITEM, FALSE,
  343.                  0);
  344.  
  345.      /* create cursor for play panel*/
  346.  
  347.     play_cursor = cursor_create(CURSOR_IMAGE, &stick,
  348.                 CURSOR_XHOT, 8,
  349.                 CURSOR_YHOT, 8,
  350.                 0);
  351.  
  352.     if (!BandW) {
  353.  
  354.     /* invert the icon because we are reverse video */
  355.         for (i = 0; i < sizeof(stick_image)/sizeof(short); i++)
  356.             stick_image[i] ^= 0xFFFF;
  357.  
  358.     cursor_set(play_cursor, CURSOR_OP,
  359.                  (PIX_SRC^PIX_DST) | PIX_COLOR( YELLOW ),
  360.                 0);
  361.      }
  362.  
  363.     /* set up panel for the play */
  364.     
  365.     play_panel = window_create(main_frame, PANEL,
  366.                WIN_CONSUME_PICK_EVENTS,
  367.                 WIN_NO_EVENTS, WIN_MOUSE_BUTTONS, WIN_UP_EVENTS, WIN_LEFT_KEYS, 0,
  368.                WIN_HEIGHT, PLAY_Y_MAX,
  369.                WIN_WIDTH, PLAY_X_MAX,
  370.                WIN_X, 0,
  371.                WIN_Y, MESS_Y_MAX + BORDER,
  372.                WIN_CURSOR, play_cursor,
  373.                PANEL_PAINT, PANEL_NONE,
  374.                PANEL_BACKGROUND_PROC, play_back_proc,
  375.                PANEL_EVENT_PROC, play_event_proc,
  376.                CANVAS_RETAINED, TRUE,
  377.                0);
  378.  
  379.     window_set(message_panel, WIN_INPUT_DESIGNEE,
  380.                window_get(play_panel, WIN_DEVICE_NUMBER),
  381.                0);
  382.  
  383.     /* build board image */
  384.  
  385.     build_image(FALSE);
  386.     place_tiles(TRUE);
  387.  
  388.     /* start main processing */
  389.               
  390.     window_main_loop(main_frame);
  391.     exit(0);
  392. }
  393.  
  394.  
  395. /* die because of some UNIX error */
  396. void die(message, pperr)
  397. char *message;
  398. int pperr;
  399. {
  400.     fprintf(stderr, message);
  401.     if (pperr)
  402.     perror("mahjongg");
  403.     exit(1);
  404. }
  405.  
  406. void place_tiles(newboard)
  407. boolean        newboard;
  408.  
  409. {
  410.     int     i;
  411.     int     j;
  412.     int     k;
  413.     int     x_loc;
  414.     int     y_loc;
  415.  
  416.     /* check if not new and destroy existing panel buttons */
  417.  
  418.     if (!newboard)
  419.     for(i = 0; i < 144; i++)
  420.         panel_destroy_item(tile[i]);
  421.  
  422.     /* place tiles */
  423.  
  424.         /* row 1 level 1 */
  425.  
  426.     for(i = 0,
  427.         x_loc = COL2;
  428.         i < 12;
  429.         i++,
  430.         x_loc += W_BASE_TILE) 
  431.  
  432.             tile[i] = panel_create_item(play_panel, PANEL_BUTTON,
  433.                         PANEL_LABEL_IMAGE,
  434.                          board[i]->image,
  435.                         PANEL_ITEM_X,
  436.                          x_loc,
  437.                          PANEL_ITEM_Y,
  438.                          ROW1,
  439.                         PANEL_SHOW_ITEM,
  440.                          TRUE,
  441.                         PANEL_CLIENT_DATA,
  442.                          (caddr_t) board[i],
  443.                          0);
  444.  
  445.     /* row 2 level 1 */
  446.  
  447.     for(x_loc = COL4,
  448.         j = 0;
  449.         j < 8;
  450.         j++,
  451.         i++,
  452.         x_loc += W_BASE_TILE) 
  453.  
  454.             tile[i] = panel_create_item(play_panel, PANEL_BUTTON,
  455.                         PANEL_LABEL_IMAGE,
  456.                          board[i]->image,
  457.                         PANEL_ITEM_X,
  458.                          x_loc,
  459.                          PANEL_ITEM_Y,
  460.                          ROW2,
  461.                         PANEL_SHOW_ITEM,
  462.                          TRUE,
  463.                         PANEL_CLIENT_DATA,
  464.                          (caddr_t) board[i],
  465.                          0);
  466.  
  467.     /* row 3 level 1 */
  468.  
  469.     for(x_loc = COL3,
  470.         j = 0;
  471.         j < 10;
  472.         j++,
  473.         i++,
  474.         x_loc += W_BASE_TILE) 
  475.  
  476.             tile[i] = panel_create_item(play_panel, PANEL_BUTTON,
  477.                         PANEL_LABEL_IMAGE,
  478.                          board[i]->image,
  479.                         PANEL_ITEM_X,
  480.                          x_loc,
  481.                          PANEL_ITEM_Y,
  482.                          ROW3,
  483.                         PANEL_SHOW_ITEM,
  484.                          TRUE,
  485.                         PANEL_CLIENT_DATA,
  486.                          (caddr_t) board[i],
  487.                          0);
  488.  
  489.     /* row 4 1/2 level 1 */
  490.  
  491.     /* Left */
  492.  
  493.             tile[i] = panel_create_item(play_panel, PANEL_BUTTON,
  494.                         PANEL_LABEL_IMAGE,
  495.                          board[i]->image,
  496.                         PANEL_ITEM_X,
  497.                          COL1,
  498.                          PANEL_ITEM_Y,
  499.                          ROW4pt5,
  500.                         PANEL_SHOW_ITEM,
  501.                          TRUE,
  502.                         PANEL_CLIENT_DATA,
  503.                          (caddr_t) board[i],
  504.                          0);
  505.  
  506.         i++; /* increment tile counter */
  507.  
  508.     /* row 4 level 1 */
  509.  
  510.     for(x_loc = COL2,
  511.         j = 0;
  512.         j < 12;
  513.         j++,
  514.         i++,
  515.         x_loc += W_BASE_TILE) 
  516.  
  517.             tile[i] = panel_create_item(play_panel, PANEL_BUTTON,
  518.                         PANEL_LABEL_IMAGE,
  519.                          board[i]->image,
  520.                         PANEL_ITEM_X,
  521.                          x_loc,
  522.                          PANEL_ITEM_Y,
  523.                          ROW4,
  524.                         PANEL_SHOW_ITEM,
  525.                          TRUE,
  526.                         PANEL_CLIENT_DATA,
  527.                          (caddr_t) board[i],
  528.                          0);
  529.  
  530.     /* row 5 level 1 */
  531.  
  532.     for(x_loc = COL2,
  533.         j = 0;
  534.         j < 12;
  535.         j++,
  536.         i++,
  537.         x_loc += W_BASE_TILE) 
  538.  
  539.             tile[i] = panel_create_item(play_panel, PANEL_BUTTON,
  540.                         PANEL_LABEL_IMAGE,
  541.                          board[i]->image,
  542.                         PANEL_ITEM_X,
  543.                          x_loc,
  544.                          PANEL_ITEM_Y,
  545.                          ROW5,
  546.                         PANEL_SHOW_ITEM,
  547.                          TRUE,
  548.                         PANEL_CLIENT_DATA,
  549.                          (caddr_t) board[i],
  550.                          0);
  551.     /* row 4 1/2 level 1 */
  552.  
  553.     /* Right */
  554.  
  555.             tile[i] = panel_create_item(play_panel, PANEL_BUTTON,
  556.                         PANEL_LABEL_IMAGE,
  557.                          board[i]->image,
  558.                         PANEL_ITEM_X,
  559.                          COL14,
  560.                          PANEL_ITEM_Y,
  561.                          ROW4pt5,
  562.                         PANEL_SHOW_ITEM,
  563.                          TRUE,
  564.                         PANEL_CLIENT_DATA,
  565.                          (caddr_t) board[i],
  566.                          0);
  567.  
  568.         i++; /* increment tile counter */
  569.  
  570.             tile[i] = panel_create_item(play_panel, PANEL_BUTTON,
  571.                         PANEL_LABEL_IMAGE,
  572.                          board[i]->image,
  573.                         PANEL_ITEM_X,
  574.                          COL15,
  575.                          PANEL_ITEM_Y,
  576.                          ROW4pt5,
  577.                         PANEL_SHOW_ITEM,
  578.                          TRUE,
  579.                         PANEL_CLIENT_DATA,
  580.                          (caddr_t) board[i],
  581.                          0);
  582.  
  583.         i++; /* increment tile counter */
  584.  
  585.     /* row 6 level 1 */
  586.  
  587.     for(x_loc = COL3,
  588.         j = 0;
  589.         j < 10;
  590.         j++,
  591.         i++,
  592.         x_loc += W_BASE_TILE) 
  593.  
  594.             tile[i] = panel_create_item(play_panel, PANEL_BUTTON,
  595.                         PANEL_LABEL_IMAGE,
  596.                          board[i]->image,
  597.                         PANEL_ITEM_X,
  598.                          x_loc,
  599.                          PANEL_ITEM_Y,
  600.                          ROW6,
  601.                         PANEL_SHOW_ITEM,
  602.                          TRUE,
  603.                         PANEL_CLIENT_DATA,
  604.                          (caddr_t) board[i],
  605.                          0);
  606.  
  607.     /* row 7 level 1 */
  608.  
  609.     for(x_loc = COL4,
  610.         j = 0;
  611.         j < 8;
  612.         j++,
  613.         i++,
  614.         x_loc += W_BASE_TILE) 
  615.  
  616.             tile[i] = panel_create_item(play_panel, PANEL_BUTTON,
  617.                         PANEL_LABEL_IMAGE,
  618.                          board[i]->image,
  619.                         PANEL_ITEM_X,
  620.                          x_loc,
  621.                          PANEL_ITEM_Y,
  622.                          ROW7,
  623.                         PANEL_SHOW_ITEM,
  624.                          TRUE,
  625.                         PANEL_CLIENT_DATA,
  626.                          (caddr_t) board[i],
  627.                          0);
  628.  
  629.         /* row 8 level 1 */
  630.  
  631.     for(j = 0,
  632.         x_loc = COL2;
  633.         j < 12;
  634.         j++,
  635.         i++,
  636.         x_loc += W_BASE_TILE) 
  637.  
  638.             tile[i] = panel_create_item(play_panel, PANEL_BUTTON,
  639.                         PANEL_LABEL_IMAGE,
  640.                          board[i]->image,
  641.                         PANEL_ITEM_X,
  642.                          x_loc,
  643.                          PANEL_ITEM_Y,
  644.                          ROW8,
  645.                         PANEL_SHOW_ITEM,
  646.                          TRUE,
  647.                         PANEL_CLIENT_DATA,
  648.                          (caddr_t) board[i],
  649.                          0);
  650.  
  651.     /* rows 1-6 level 2 */
  652.  
  653.     for(y_loc = ROW2 - B_TILE_SHADOW,
  654.         j = 0;
  655.         j < 6;
  656.         j++,
  657.         y_loc += H_BASE_TILE) 
  658.  
  659.         for(x_loc = COL5 - S_TILE_SHADOW,
  660.             k = 0;
  661.             k < 6;
  662.             i++,
  663.             k++,
  664.             x_loc += W_BASE_TILE) 
  665.  
  666.                 tile[i] = panel_create_item(play_panel, PANEL_BUTTON,
  667.                             PANEL_LABEL_IMAGE,
  668.                              board[i]->image,
  669.                             PANEL_ITEM_X,
  670.                              x_loc,
  671.                              PANEL_ITEM_Y,
  672.                              y_loc,
  673.                             PANEL_SHOW_ITEM,
  674.                              TRUE,
  675.                             PANEL_CLIENT_DATA,
  676.                              (caddr_t) board[i],
  677.                              0);
  678.  
  679.     /* rows 1-4 level 3 */
  680.  
  681.     for(y_loc = ROW3 - (B_TILE_SHADOW * 2),
  682.         j = 0;
  683.         j < 4;
  684.         j++,
  685.         y_loc += H_BASE_TILE) 
  686.  
  687.         for(x_loc = COL6 - (S_TILE_SHADOW * 2),
  688.             k = 0;
  689.             k < 4;
  690.             i++,
  691.             k++,
  692.             x_loc += W_BASE_TILE) 
  693.  
  694.                 tile[i] = panel_create_item(play_panel, PANEL_BUTTON,
  695.                             PANEL_LABEL_IMAGE,
  696.                              board[i]->image,
  697.                             PANEL_ITEM_X,
  698.                              x_loc,
  699.                              PANEL_ITEM_Y,
  700.                              y_loc,
  701.                             PANEL_SHOW_ITEM,
  702.                              TRUE,
  703.                             PANEL_CLIENT_DATA,
  704.                              (caddr_t) board[i],
  705.                              0);
  706.  
  707.     /* rows 1-2 level 4 */
  708.     /* special case make messages instead of buttons */
  709.  
  710.     for(y_loc = ROW4 - (B_TILE_SHADOW * 3),
  711.         j = 0;
  712.         j < 2;
  713.         j++,
  714.         y_loc += H_BASE_TILE) 
  715.  
  716.         for(x_loc = COL7 - (S_TILE_SHADOW * 3),
  717.             k = 0;
  718.             k < 2;
  719.             i++,
  720.             k++,
  721.             x_loc += W_BASE_TILE) 
  722.  
  723.                 tile[i] = panel_create_item(play_panel, PANEL_BUTTON,
  724.                             PANEL_LABEL_IMAGE,
  725.                              board[i]->image,
  726.                             PANEL_ITEM_X,
  727.                              x_loc,
  728.                              PANEL_ITEM_Y,
  729.                              y_loc,
  730.                             PANEL_SHOW_ITEM,
  731.                              TRUE,
  732.                             PANEL_CLIENT_DATA,
  733.                              (caddr_t) board[i],
  734.                              0);
  735.  
  736.     /* Cap tile */
  737.  
  738.             tile[i] = panel_create_item(play_panel, PANEL_BUTTON,
  739.                         PANEL_LABEL_IMAGE,
  740.                          board[i]->image,
  741.                         PANEL_ITEM_X,
  742.                          COL7pt5 - (S_TILE_SHADOW * 4),
  743.                          PANEL_ITEM_Y,
  744.                          ROW4pt5 - (B_TILE_SHADOW * 4),
  745.                         PANEL_SHOW_ITEM,
  746.                          TRUE,
  747.                         PANEL_CLIENT_DATA,
  748.                          (caddr_t) board[i],
  749.                          0);
  750.  
  751.     /* paint panel */
  752.  
  753.     panel_paint(play_panel, PANEL_NO_CLEAR);
  754.  
  755.    /* clear stand_by message  and release input mask */
  756.  
  757.    panel_set(message,   PANEL_SHOW_ITEM,
  758.                      FALSE,
  759.              0);
  760.  
  761.    window_set(message_panel, WIN_CONSUME_PICK_EVENTS,
  762.                   WIN_MOUSE_BUTTONS, 0,
  763.                   0);
  764.    window_set(message_panel, WIN_CONSUME_KBD_EVENT,
  765.                   WIN_ASCII_EVENTS, 0, 0);
  766.  
  767.    cursor_set(play_cursor, CURSOR_IMAGE, &stick, 0);
  768.    window_set(play_panel, WIN_CURSOR, play_cursor, 0);
  769.  
  770. }
  771.  
  772. void build_image(oldimage)
  773. boolean oldimage;
  774.  
  775. {
  776. int     i;
  777. int     j;
  778. int    pool[42];
  779. boolean ok;
  780. boolean dir;
  781. char    seed_text[80];
  782.  
  783.     /* initialize selected structures */
  784.  
  785.         selected[0].filled = FALSE;
  786.         selected[1].filled = FALSE;
  787.         last_item.filled   = FALSE;
  788.         undo_count          = -1;
  789.  
  790.         panel_set(message,   PANEL_SHOW_ITEM,
  791.                    FALSE,
  792.                   0);
  793.         panel_set(TL_hundred, PANEL_LABEL_IMAGE,
  794.                    (BandW) ? &NUM1 : &cNUM1,
  795.                   PANEL_SHOW_ITEM,
  796.                    TRUE,
  797.                   0);
  798.         panel_set(TL_ten    , PANEL_LABEL_IMAGE,
  799.                    (BandW) ? &NUM4 : &cNUM4,
  800.                   PANEL_SHOW_ITEM,
  801.                    TRUE,
  802.                   0);
  803.         panel_set(TL_one    , PANEL_LABEL_IMAGE,
  804.                    (BandW) ? &NUM4 : &cNUM4,
  805.                   0);
  806.  
  807.     /* display current seed in text item */
  808.  
  809.         sprintf(seed_text, "%d", seed);
  810.         panel_set(board_num, PANEL_VALUE, seed_text, 0);
  811.  
  812.     /* show stand_by message while building image  and grab all input */
  813.  
  814.     panel_set(message, PANEL_LABEL_STRING,
  815.                 "Building board. Please wait.",
  816.                PANEL_SHOW_ITEM,
  817.                 TRUE, 0);
  818.  
  819.        window_set(message_panel, WIN_IGNORE_PICK_EVENTS,
  820.                   WIN_MOUSE_BUTTONS, 0, 0);
  821.        window_set(message_panel, WIN_IGNORE_KBD_EVENT,
  822.                   WIN_ASCII_EVENTS, 0, 0);
  823.        cursor_set(play_cursor, CURSOR_IMAGE, &wait, 0);
  824.        window_set(play_panel, WIN_CURSOR, play_cursor, 0);
  825.  
  826.     /* initialize random number counter */
  827.  
  828.     (void) srandom(seed);
  829.  
  830.     tile_count = 144;
  831.  
  832.     /* initialize tile pool */
  833.     for(i = 0; i < 34; i++) pool[i] = 4;
  834.     for(; i < 42; i++) pool[i] = 1;
  835.  
  836.     /* assign values to each location. Board is built from upper left *
  837.      * to lower right, bottom to top. Exception are left tile for row *
  838.      * 4pt5 is before rows 4 and 5, and right tiles for row 4.5 are   *
  839.      * after rows 4 and 5                                             */
  840.  
  841.     for(j = 0; j < 144; j++) {
  842.         if (board[j] == NULL) /* intialize array */
  843.         board[j] = (Tiles *) malloc(sizeof(Tiles));
  844.  
  845.         if (!oldimage) { /* not repeating last board */
  846.  
  847.         /* Randomly seed index into pool. Randomly *
  848.          *  run up or down list until unused tile  *
  849.          *  is found or end of list. If end of     *
  850.          *  list reseed and run in opposite        *
  851.          *  direction in list until unused tile is *
  852.          *  found. If beginning of list found,     *
  853.          *  start over.                */
  854.  
  855.         ok = FALSE;
  856.         while (ok == FALSE) {
  857.             i = RANDOM(41);
  858.             /* Up, up, up! */
  859.             dir = random()&01;
  860.             while ((i < 42 || i >=0) && pool[i] == 0) (dir) ? i++ : i--;
  861.             if (i == 42 || i < 0) { /* Thud! Reverse march! */
  862.                 i = RANDOM(41);
  863.                 while ((i < 42 || i >= 0) && pool[i] == 0) (dir) ? i-- : i++;
  864.             }
  865.             if (i == 42 || i < 0) continue; /* Missed! try again */
  866.             pool[i]--;
  867.             ok = TRUE;
  868.         }
  869.  
  870.         /* all flowers and all seasons */
  871.  
  872.         board[j]->value = (i >= 34) ? ((i >= 38) ? 35 : 34) : i;
  873.         switch(i) {
  874.  
  875.         case 0: board[j]->image = (BandW) ? &DOT1 : &cDOT1;
  876.             break;
  877.         case 1: board[j]->image = (BandW) ? &DOT2 : &cDOT2;
  878.             break;
  879.         case 2: board[j]->image = (BandW) ? &DOT3 : &cDOT3;
  880.             break;
  881.         case 3: board[j]->image = (BandW) ? &DOT4 : &cDOT4;
  882.             break;
  883.         case 4: board[j]->image = (BandW) ? &DOT5 : &cDOT5;
  884.             break;
  885.         case 5: board[j]->image = (BandW) ? &DOT6 : &cDOT6;
  886.             break;
  887.         case 6: board[j]->image = (BandW) ? &DOT7 : &cDOT7;
  888.             break;
  889.         case 7: board[j]->image = (BandW) ? &DOT8 : &cDOT8;
  890.             break;
  891.         case 8: board[j]->image = (BandW) ? &DOT9 : &cDOT9;
  892.             break;
  893.         case 9: board[j]->image = (BandW) ? &BAM1 : &cBAM1;
  894.             break;
  895.         case 10: board[j]->image = (BandW) ? &BAM2 : &cBAM2;
  896.             break;
  897.         case 11: board[j]->image = (BandW) ? &BAM3 : &cBAM3;
  898.             break;
  899.         case 12: board[j]->image = (BandW) ? &BAM4 : &cBAM4;
  900.             break;
  901.         case 13: board[j]->image = (BandW) ? &BAM5 : &cBAM5;
  902.             break;
  903.         case 14: board[j]->image = (BandW) ? &BAM6 : &cBAM6;
  904.             break;
  905.         case 15: board[j]->image = (BandW) ? &BAM7 : &cBAM7;
  906.             break;
  907.         case 16: board[j]->image = (BandW) ? &BAM8 : &cBAM8;
  908.             break;
  909.         case 17: board[j]->image = (BandW) ? &BAM9 : &cBAM9;
  910.             break;
  911.         case 18: board[j]->image = (BandW) ? &CHA1 : &cCHA1;
  912.             break;
  913.         case 19: board[j]->image = (BandW) ? &CHA2 : &cCHA2;
  914.             break;
  915.         case 20: board[j]->image = (BandW) ? &CHA3 : &cCHA3;
  916.             break;
  917.         case 21: board[j]->image = (BandW) ? &CHA4 : &cCHA4;
  918.             break;
  919.         case 22: board[j]->image = (BandW) ? &CHA5 : &cCHA5;
  920.             break;
  921.         case 23: board[j]->image = (BandW) ? &CHA6 : &cCHA6;
  922.             break;
  923.         case 24: board[j]->image = (BandW) ? &CHA7 : &cCHA7;
  924.             break;
  925.         case 25: board[j]->image = (BandW) ? &CHA8 : &cCHA8;
  926.             break;
  927.         case 26: board[j]->image = (BandW) ? &CHA9 : &cCHA9;
  928.             break;
  929.         case 27: board[j]->image = (BandW) ? &GRED : &cGRED;
  930.             break;
  931.         case 28: board[j]->image = (BandW) ? &REDD : &cREDD;
  932.             break;
  933.         case 29: board[j]->image = (BandW) ? &WHTD : &cWHTD;
  934.             break;
  935.         case 30: board[j]->image = (BandW) ? &EAST : &cEAST;
  936.             break;
  937.         case 31: board[j]->image = (BandW) ? &WEST : &cWEST;
  938.             break;
  939.         case 32: board[j]->image = (BandW) ? &SOUT : &cSOUT;
  940.             break;
  941.         case 33: board[j]->image = (BandW) ? &NORT : &cNORT;
  942.             break;
  943.         case 34: board[j]->image = (BandW) ? &AUT : &cAUT;
  944.             break;
  945.         case 35: board[j]->image = (BandW) ? &SUM : &cSUM;
  946.             break;
  947.         case 36: board[j]->image = (BandW) ? &SPR : &cSPR;
  948.             break;
  949.         case 37: board[j]->image = (BandW) ? &WIN : &cWIN;
  950.             break;
  951.         case 38: board[j]->image = (BandW) ? &ORC : &cORC;
  952.             break;
  953.         case 39: board[j]->image = (BandW) ? &MUM : &cMUM;
  954.             break;
  955.         case 40: board[j]->image = (BandW) ? &BAM : &cBAM;
  956.             break;
  957.         case 41: board[j]->image = (BandW) ? &PLM : &cPLM;
  958.             break;
  959.         }
  960.  
  961.     }
  962.     /* establish default values */
  963.  
  964.         board[j]->left_free     = FALSE;
  965.         board[j]->right_free    = FALSE;
  966.         board[j]->top_free      = TRUE;
  967.         board[j]->left_next[0]  = j - 1;
  968.         board[j]->left_next[1]  = 999;
  969.         board[j]->right_next[0] = j + 1;
  970.         board[j]->right_next[1] = 999;
  971.         board[j]->covered[0]    = 999;
  972.         board[j]->covered[1]    = 999;
  973.         board[j]->covered[2]    = 999;
  974.         board[j]->covered[3]    = 999;
  975.         board[j]->removed       = FALSE;
  976.  
  977.     /* setup special cases */
  978.  
  979.         switch (j) {
  980.         case 139:
  981.         case 141: 
  982.             board[j]->top_free = FALSE;
  983.         case 0:
  984.         case 12:
  985.         case 20:
  986.         case 30:
  987.         case 57:
  988.         case 67:
  989.         case 75:
  990.         case 87:
  991.         case 93:
  992.         case 99:
  993.         case 105:
  994.         case 111:
  995.         case 117:
  996.         case 123:
  997.         case 127:
  998.         case 131:
  999.         case 135:
  1000.             board[j]->left_free = TRUE;
  1001.             board[j]->left_next[0] = 999;
  1002.             break;
  1003.         case 140:
  1004.         case 142:
  1005.             board[j]->top_free = FALSE;
  1006.         case 11:
  1007.         case 19:
  1008.         case 29:
  1009.         case 56:
  1010.         case 66:
  1011.         case 74:
  1012.         case 86:
  1013.         case 92:
  1014.         case 98:
  1015.         case 104:
  1016.         case 110:
  1017.         case 116:
  1018.         case 122:
  1019.         case 126:
  1020.         case 130:
  1021.         case 134:
  1022.         case 138:
  1023.             board[j]->right_free = TRUE;
  1024.             board[j]->right_next[0] = 999;
  1025.             break;
  1026.         case 143:
  1027.             board[j]->right_free = TRUE;
  1028.             board[j]->left_next[0] = 999;
  1029.             board[j]->left_free = TRUE;
  1030.             board[j]->right_next[0] = 999;
  1031.             board[j]->covered[0] = 139;
  1032.             board[j]->covered[1] = 140;
  1033.             board[j]->covered[2] = 141;
  1034.             board[j]->covered[3] = 142;
  1035.             break;
  1036.         case 42:
  1037.             board[j]->right_next[0] = 55;
  1038.             break;
  1039.         case 43:
  1040.             board[j]->left_next[0] = 30;
  1041.             break;
  1042.         case 55:
  1043.             board[j]->left_next[1] = 42;
  1044.             break;
  1045.         }
  1046.             
  1047.     }
  1048.  
  1049.     /* special case (did not fit in above) */
  1050.  
  1051.     board[30]->right_next[1] = 43;
  1052.  
  1053.     /* set top_free flags  and covered pointers */
  1054.  
  1055.     for(i = 87, j = 13; i < 143; i++, j++) {
  1056.         board[i]->covered[0] = j;
  1057.         board[j]->top_free = FALSE;
  1058.         switch(j) {
  1059.             case 97:
  1060.             case 103:
  1061.             case 109:
  1062.             case 129:
  1063.                  j += 2;
  1064.                  break;
  1065.             case 18:
  1066.             case 64:
  1067.                  j += 3;
  1068.                  break;
  1069.             case 27:
  1070.             case 39:
  1071.                  j += 6;
  1072.                  break;
  1073.             case 51:
  1074.                  j += 7;
  1075.                  break;
  1076.             case 73:
  1077.                  j += 20;
  1078.                  break;
  1079.             case 115:
  1080.                  j += 12;
  1081.                  break;
  1082.         }
  1083.     }
  1084. }
  1085.  
  1086. /* This is the routine that returns the colored button image */
  1087.  
  1088. Pixrect *color_button(pr,color)
  1089.   struct pixrect *pr;
  1090.   int color;
  1091. {
  1092.   struct pixrect *color_pr;
  1093.  
  1094.   if(pr == NULL)
  1095.         return(NULL);
  1096.  
  1097.   /* if running in b/w mode return same pixrect */
  1098.   if (BandW)
  1099.         return(pr);
  1100.  
  1101.   /* make new pixrect */
  1102.   color_pr = mem_create(pr->pr_size.x, pr->pr_size.y, 8);
  1103.  
  1104.   /* copy pr to color_pr with color added */
  1105.   pr_rop(color_pr, 0, 0, pr->pr_size.x, pr->pr_size.y,
  1106.         PIX_SRC | PIX_COLOR( color ),
  1107.         pr,0,0);
  1108.  
  1109.   return(color_pr);
  1110. }
  1111.