games@tekred.TEK.COM (06/01/88)
Submitted by: tektronix!tessi!exc!markh (Mark Holm)
Comp.sources.games: Volume 4, Issue 29
Archive-name: mahjongg/Part03
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of archive 3 (of 3)."
# Contents: event.c mahjongg.c
# Wrapped by billr@saab on Tue May 31 11:44:04 1988
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f event.c -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"event.c\"
else
echo shar: Extracting \"event.c\" \(20252 characters\)
sed "s/^X//" >event.c <<'END_OF_event.c'
X/*
X * Copyright 1988, Mark Holm
X * Exceptions
X *
X * Acknowledgments to Dorothy Robinson for her artistic
X * abilities in drawing the icons and to Jim Batch for
X * technical support and graphical concepts (which I abandoned in favor
X * of the easy way out).
X *
X * Permission is given to copy and distribute for non-profit purposes.
X *
X */
X
X/* This file has the event handlers for the background and
X * tiles in the play panel
X */
X
X#include <stdio.h>
X#include <sys/types.h>
X#include <suntool/sunview.h>
X#include <suntool/panel.h>
X#include <sunwindow/notify.h>
X#include <pixrect/pixrect.h>
X
X#include "mahjongg.h"
X
X/* external definitions */
X
Xextern Frame main_frame;
Xextern Panel play_panel, message_panel;
Xextern Panel_item TL_hundred;
Xextern Panel_item TL_ten;
Xextern Panel_item TL_one;
Xextern Panel_item message;
Xextern Panel_item tile[144];
Xextern Panel_item tiles_left[3];
Xextern Panel_item board_num;
Xextern Cursor play_cursor;
X
Xextern boolean BandW;
Xextern Tiles *board[144];
Xextern int tile_count;
Xextern int seed;
Xextern Selected last_item;
Xextern Selected selected[2];
X
X/* local globals */
X
XSelected undo_tiles[144][2];
Xint undo_count;
Xboolean help_mode = FALSE;
X
X/*******************************************/
X
Xvoid help_proc(item, event)
XPanel_item item;
XEvent *event;
X
X{
Xint i;
XTiles *data[2];
Xstatic int parse[2];
X
X if(!(selected[0].filled)) {
X if(!(help_mode)) { /* Just starting. init and recall */
X
X help_mode = TRUE;
X parse[0] = 143;
X parse[1] = 142;
X help_proc(item, event);
X
X } else { /* find next match */
X for(; parse[0] >= 0; parse[0]--) {
X if (!((board[parse[0]]->top_free && /* uncovered */
X (board[parse[0]]->left_free || board[parse[0]]->right_free) && /* open */
X (!(board[parse[0]]->removed))))) /* not already used */
X continue; /* not available go to next */
X
X for(; parse[1] >= 0; parse[1]--) { /* check for second tile */
X if ((board[parse[0]]->value == board[parse[1]]->value) && /* right value */
X (parse[0] != parse[1]) && /* different item */
X (board[parse[1]]->top_free && /* uncovered */
X (board[parse[1]]->left_free || board[parse[1]]->right_free) && /* open */
X (!(board[parse[1]]->removed)))) { /* not already used */
X
X /* Found a match, show it */
X
X /* flag found items */
X selected[0].filled = TRUE;
X selected[1].filled = TRUE;
X
X /* fake in some data */
X selected[0].item = tile[parse[0]];
X selected[0].event.ie_locx = ((int) panel_get(tile[parse[0]], PANEL_ITEM_X) + 10);
X selected[0].event.ie_locy = ((int) panel_get(tile[parse[0]], PANEL_ITEM_Y) + 10);
X selected[0].event.ie_time.tv_sec = event->ie_time.tv_sec;
X selected[0].event.ie_time.tv_usec = event->ie_time.tv_usec;
X
X selected[1].item = tile[parse[1]];
X selected[1].event.ie_locx = ((int) panel_get(tile[parse[1]], PANEL_ITEM_X) + 10);
X selected[1].event.ie_locy = ((int) panel_get(tile[parse[1]], PANEL_ITEM_Y) + 10);
X selected[1].event.ie_time.tv_sec = event->ie_time.tv_sec;
X selected[1].event.ie_time.tv_usec = event->ie_time.tv_usec;
X
X /* Muppet news flash */
X panel_begin_preview(selected[0].item, selected[0].event);
X panel_begin_preview(selected[1].item, selected[1].event);
X
X /* show next move message */
X panel_set(message, PANEL_LABEL_STRING,
X "Show next move? [Y] [] [N]",
X PANEL_SHOW_ITEM,
X TRUE, 0);
X
X window_set(message_panel, WIN_IGNORE_PICK_EVENTS,
X WIN_MOUSE_BUTTONS, 0, 0);
X window_set(message_panel, WIN_IGNORE_KBD_EVENT,
X WIN_ASCII_EVENTS, 0, 0);
X cursor_set(play_cursor, CURSOR_IMAGE, &confirm, 0);
X window_set(play_panel, WIN_CURSOR, play_cursor, 0);
X
X parse[1]--; /* do loop step */
X return; /* all done this rotation */
X
X }
X } /* else go to next */
X
X parse[1] = parse[0] - 2; /* going around again */
X
X }
X
X /* no more moves beep and show message */
X
X window_bell(main_frame);
X
X panel_set(message, PANEL_LABEL_STRING,
X "No more moves. [DONE] [] []",
X PANEL_SHOW_ITEM,
X TRUE, 0);
X
X window_set(message_panel, WIN_IGNORE_PICK_EVENTS,
X WIN_MOUSE_BUTTONS, 0, 0);
X window_set(message_panel, WIN_IGNORE_KBD_EVENT,
X WIN_ASCII_EVENTS, 0, 0);
X cursor_set(play_cursor, CURSOR_IMAGE, &confirm, 0);
X window_set(play_panel, WIN_CURSOR, play_cursor, 0);
X
X }
X
X } else { /* search for available match */
X
X data[0] = (Tiles *) panel_get(selected[0].item, PANEL_CLIENT_DATA);
X
X for(i = 143; i >= 0; i--) {
X if ((board[i]->value == data[0]->value) && /* right value */
X (tile[i] != selected[0].item) && /* different item */
X (board[i]->top_free && /* uncovered */
X (board[i]->left_free || board[i]->right_free) && /* open */
X (!(board[i]->removed)))) { /* not already used */
X
X /* found one */
X
X /* fake in some selected data */
X
X selected[1].item = tile[i];
X selected[1].event.ie_locx = ((int) panel_get(tile[i], PANEL_ITEM_X) + 10);
X selected[1].event.ie_locy = ((int) panel_get(tile[i], PANEL_ITEM_Y) + 10);
X selected[1].event.ie_time.tv_sec = 10; /*sounds good */
X selected[1].event.ie_time.tv_usec = 10; /*sounds good */
X
X selected[1].filled = TRUE;
X
X /* turn on preview */
X
X panel_begin_preview(selected[1].item, selected[1].event);
X
X /* set confirm message */
X
X panel_set(message, PANEL_LABEL_STRING,
X "Please confirm. [Y] [] [N]",
X PANEL_SHOW_ITEM,
X TRUE, 0);
X
X window_set(message_panel, WIN_IGNORE_PICK_EVENTS,
X WIN_MOUSE_BUTTONS, 0, 0);
X window_set(message_panel, WIN_IGNORE_KBD_EVENT,
X WIN_ASCII_EVENTS, 0, 0);
X cursor_set(play_cursor, CURSOR_IMAGE, &confirm, 0);
X window_set(play_panel, WIN_CURSOR, play_cursor, 0);
X
X /* return to sender */
X
X return;
X
X }
X }
X
X selected[0].filled = FALSE;
X panel_cancel_preview(selected[0].item, selected[0].event);
X window_bell(main_frame);
X
X }
X}
X
Xvoid remove_tiles(REMOVE)
Xboolean REMOVE;
X
X{
XTiles *data[2];
Xint i;
Xint tiles_left_hun;
Xint tiles_left_ten;
Xint tiles_left_one;
XPixwin *pw;
XRect *r;
X
X if (REMOVE) {
X /* get data from items to be removed */
X data[0] = (Tiles *) panel_get(selected[0].item, PANEL_CLIENT_DATA);
X data[1] = (Tiles *) panel_get(selected[1].item, PANEL_CLIENT_DATA);
X
X } else {
X /* get data from items to be replaced */
X data[0] = (Tiles *) panel_get(undo_tiles[undo_count][0].item, PANEL_CLIENT_DATA);
X data[1] = (Tiles *) panel_get(undo_tiles[undo_count][1].item, PANEL_CLIENT_DATA);
X }
X
X /* adjust adjacent tiles */
X for(i = 0; i < 2 && data[0]->left_next[i] != 999; board[data[0]->left_next[i]]->right_free = REMOVE, i++);
X for(i = 0; i < 2 && data[1]->left_next[i] != 999; board[data[1]->left_next[i]]->right_free = REMOVE, i++);
X for(i = 0; i < 2 && data[0]->right_next[i] != 999; board[data[0]->right_next[i]]->left_free = REMOVE, i++);
X for(i = 0; i < 2 && data[1]->right_next[i] != 999; board[data[1]->right_next[i]]->left_free = REMOVE, i++);
X for(i = 0; i < 4 && data[0]->covered[i] != 999; board[data[0]->covered[i]]->top_free = REMOVE, i++);
X for(i = 0; i < 4 && data[1]->covered[i] != 999; board[data[1]->covered[i]]->top_free = REMOVE, i++);
X
X /* set removed flags */
X data[0]->removed = REMOVE;
X data[1]->removed = REMOVE;
X
X if (REMOVE) {
X /* turn off preview */
X panel_cancel_preview(selected[0].item, selected[0].event);
X panel_cancel_preview(selected[1].item, selected[1].event);
X } else /* check to see if previewing an item and un-preview and select */
X if (selected[0].filled) {
X panel_cancel_preview(selected[0].item, selected[0].event);
X selected[0].filled = FALSE;
X }
X
X /* fix playing field */
X pw = (Pixwin *) window_get(play_panel, WIN_PIXWIN);
X r = (Rect *) window_get(play_panel, WIN_RECT);
X pw_batch_on(pw);
X pw_lock(pw, r);
X panel_paint(play_panel, PANEL_NONE);
X panel_set((REMOVE) ? selected[0].item : undo_tiles[undo_count][0].item, PANEL_SHOW_ITEM, !REMOVE, 0);
X panel_set((REMOVE) ? selected[1].item : undo_tiles[undo_count][1].item, PANEL_SHOW_ITEM, !REMOVE, 0);
X panel_paint(play_panel, PANEL_NO_CLEAR);
X pw_unlock(pw);
X pw_batch_off(pw);
X
X /* deselect tiles */
X selected[0].filled = FALSE;
X selected[1].filled = FALSE;
X
X /* fix tile counter */
X tile_count += (REMOVE) ? -2 : 2;
X
X tiles_left_hun = tile_count / 100;
X tiles_left_ten = (tile_count - (tiles_left_hun * 100)) / 10;
X tiles_left_one = tile_count - (tiles_left_hun * 100) - (tiles_left_ten * 10);
X
X /* display hundreds tile by own status */
X panel_set(TL_hundred, PANEL_SHOW_ITEM, tiles_left_hun, 0);
X
X /* display tens tile by own status ored with hundreds status */
X panel_set(TL_ten, PANEL_SHOW_ITEM, tiles_left_hun || tiles_left_ten, 0);
X
X switch(tiles_left_ten) {
X case 0:
X panel_set(TL_ten, PANEL_LABEL_IMAGE, (BandW) ? &NUM0 : &cNUM0, 0);
X break;
X case 1:
X panel_set(TL_ten, PANEL_LABEL_IMAGE, (BandW) ? &NUM1 : &cNUM1, 0);
X break;
X case 2:
X panel_set(TL_ten, PANEL_LABEL_IMAGE, (BandW) ? &NUM2 : &cNUM2, 0);
X break;
X case 3:
X panel_set(TL_ten, PANEL_LABEL_IMAGE, (BandW) ? &NUM3 : &cNUM3, 0);
X break;
X case 4:
X panel_set(TL_ten, PANEL_LABEL_IMAGE, (BandW) ? &NUM4 : &cNUM4, 0);
X break;
X case 5:
X panel_set(TL_ten, PANEL_LABEL_IMAGE, (BandW) ? &NUM5 : &cNUM5, 0);
X break;
X case 6:
X panel_set(TL_ten, PANEL_LABEL_IMAGE, (BandW) ? &NUM6 : &cNUM6, 0);
X break;
X case 7:
X panel_set(TL_ten, PANEL_LABEL_IMAGE, (BandW) ? &NUM7 : &cNUM7, 0);
X break;
X case 8:
X panel_set(TL_ten, PANEL_LABEL_IMAGE, (BandW) ? &NUM8 : &cNUM8, 0);
X break;
X case 9:
X panel_set(TL_ten, PANEL_LABEL_IMAGE, (BandW) ? &NUM9 : &cNUM9, 0);
X break;
X }
X
X switch(tiles_left_one) { /* only need even tiles */
X case 0:
X panel_set(TL_one, PANEL_LABEL_IMAGE, (BandW) ? &NUM0 : &cNUM0, 0);
X break;
X case 2:
X panel_set(TL_one, PANEL_LABEL_IMAGE, (BandW) ? &NUM2 : &cNUM2, 0);
X break;
X case 4:
X panel_set(TL_one, PANEL_LABEL_IMAGE, (BandW) ? &NUM4 : &cNUM4, 0);
X break;
X case 6:
X panel_set(TL_one, PANEL_LABEL_IMAGE, (BandW) ? &NUM6 : &cNUM6, 0);
X break;
X case 8:
X panel_set(TL_one, PANEL_LABEL_IMAGE, (BandW) ? &NUM8 : &cNUM8, 0);
X break;
X }
X
X if (REMOVE) {
X
X /* update undo_count */
X undo_count++;
X
X /* update removed array */
X undo_tiles[undo_count][0].item = selected[0].item;
X undo_tiles[undo_count][0].event.ie_locx = selected[0].event.ie_locx;
X undo_tiles[undo_count][0].event.ie_locy = selected[0].event.ie_locy;
X undo_tiles[undo_count][0].event.ie_time.tv_sec = selected[0].event.ie_time.tv_sec;
X undo_tiles[undo_count][0].event.ie_time.tv_usec = selected[0].event.ie_time.tv_usec;
X undo_tiles[undo_count][0].filled = TRUE;
X
X undo_tiles[undo_count][1].item = selected[1].item;
X undo_tiles[undo_count][1].event.ie_locx = selected[1].event.ie_locx;
X undo_tiles[undo_count][1].event.ie_locy = selected[1].event.ie_locy;
X undo_tiles[undo_count][1].event.ie_time.tv_sec = selected[1].event.ie_time.tv_sec;
X undo_tiles[undo_count][1].event.ie_time.tv_usec = selected[1].event.ie_time.tv_usec;
X undo_tiles[undo_count][1].filled = TRUE;
X
X /* remove confirm message */
X
X panel_set(message,PANEL_SHOW_ITEM, FALSE, 0);
X
X window_set(message_panel, WIN_CONSUME_PICK_EVENTS,
X WIN_MOUSE_BUTTONS, 0,
X 0);
X window_set(message_panel, WIN_CONSUME_KBD_EVENT,
X WIN_ASCII_EVENTS, 0, 0);
X
X cursor_set(play_cursor, CURSOR_IMAGE, &stick, 0);
X window_set(play_panel, WIN_CURSOR, play_cursor, 0);
X
X /* check for clean board and congrat them */
X
X if ( tiles_left_hun == 0 && tiles_left_ten == 0 && tiles_left_one == 0)
X panel_set(message, PANEL_LABEL_STRING,
X "Congratulations!! Press 'AGAIN' or 'NEW'",
X PANEL_SHOW_ITEM,
X TRUE, 0);
X
X } else { /* decrement undo_count */
X undo_tiles[undo_count][0].filled = FALSE;
X undo_tiles[undo_count][1].filled = FALSE;
X undo_count--;
X }
X}
X
Xvoid play_back_proc(where, event)
XPanel where;
XEvent *event;
X{
X
X if (!(selected[0].filled) && help_mode) { /* stop helping */
X if (event_id(event) == MS_LEFT) { /* all done */
X
X /* remove message */
X
X panel_set(message,PANEL_SHOW_ITEM, FALSE, 0);
X window_set(message_panel, WIN_CONSUME_PICK_EVENTS,
X WIN_MOUSE_BUTTONS, 0,
X 0);
X window_set(message_panel, WIN_CONSUME_KBD_EVENT,
X WIN_ASCII_EVENTS, 0, 0);
X cursor_set(play_cursor, CURSOR_IMAGE, &stick, 0);
X window_set(play_panel, WIN_CURSOR, play_cursor, 0);
X
X /* exit help_mode */
X
X help_mode = FALSE;
X
X }
X } else { /* doing confirm or next help */
X
X if (selected[1].filled) { /* doing confirm or next help */
X
X switch (event_id(event)) {
X
X case MS_LEFT:
X /* confirmed selection */
X if (event_is_up(event)) {
X if (help_mode) { /* do next help */
X
X /* cancel preview of selected tiles */
X panel_cancel_preview(selected[0].item, selected[0].event);
X panel_cancel_preview(selected[1].item, selected[1].event);
X /* Clean up selected's variables */
X selected[0].filled = FALSE;
X selected[1].filled = FALSE;
X
X /* remove confirm message */
X panel_set(message,PANEL_SHOW_ITEM, FALSE, 0);
X
X /* do next help */
X help_proc();
X
X } else { /* confirmed selection. remove them */
X remove_tiles(TRUE);
X }
X }
X break;
X
X case MS_RIGHT:
X /* refused selection */
X if (event_is_down(event)) {
X /* cancel preview of selected tiles */
X panel_cancel_preview(selected[0].item, selected[0].event);
X panel_cancel_preview(selected[1].item, selected[1].event);
X /* Clean up selected's variables */
X selected[0].filled = FALSE;
X selected[1].filled = FALSE;
X
X /* remove confirm message */
X
X panel_set(message,PANEL_SHOW_ITEM, FALSE, 0);
X window_set(message_panel, WIN_CONSUME_PICK_EVENTS,
X WIN_MOUSE_BUTTONS, 0,
X 0);
X window_set(message_panel, WIN_CONSUME_KBD_EVENT,
X WIN_ASCII_EVENTS, 0, 0);
X cursor_set(play_cursor, CURSOR_IMAGE, &stick, 0);
X window_set(play_panel, WIN_CURSOR, play_cursor, 0);
X
X /* if in help mode toggle out */
X if (help_mode) help_mode = FALSE;
X
X }
X break;
X }
X } else {
X
X /* check for help requests */
X
X if ((event_id(event) == MS_MIDDLE) && event_is_up(event) && selected[0].filled) {
X
X help_proc();
X
X } else /* or MS_LEFT up outside of playing area */
X if ((event_id(event) == MS_LEFT) && event_is_up(event) &&
X last_item.filled) { /* went down on something */
X
X window_bell(main_frame);
X last_item.filled = FALSE;
X
X if (!selected[0].filled || (selected[0].item != last_item.item)) {
X /* not aborting deselection */
X panel_cancel_preview(last_item.item, last_item.event);
X }
X }
X }
X }
X}
X
Xvoid play_event_proc(item, event)
XPanel_item item;
XEvent *event;
X
X{
XTiles *data;
Xint value;
Xint i;
Xint x;
Xint y;
X
X /* check to see if in help_mode */
X
X if (help_mode) {
X play_back_proc(play_panel, event);
X return;
X }
X
X /* check to see if just confirming */
X
X if (selected[1].filled) {
X play_back_proc(play_panel, event);
X return;
X }
X
X /* translate item to top level available */
X
X if ( (event_id(event) == MS_LEFT) &&
X ((ROW2 - B_TILE_SHADOW) <= event->ie_locy) &&
X (event->ie_locy <= (ROW2 - B_TILE_SHADOW + (6 * W_BASE_TILE))) &&
X ((COL5 - S_TILE_SHADOW) <= event->ie_locx) &&
X (event->ie_locx <= (COL5 - S_TILE_SHADOW + (6 * H_BASE_TILE))) ) { /* in overlap area, check for stacks */
X
X for(i = 143; i > 86 ; i--) { /* check from top to bottom */
X
X x = (int) panel_get(tile[i], PANEL_ITEM_X);
X y = (int) panel_get(tile[i], PANEL_ITEM_Y);
X
X if ( (x <= event->ie_locx) &&
X (event->ie_locx <= x + W_BASE_TILE) &&
X (y <= event->ie_locy) &&
X (event->ie_locy <= y + H_BASE_TILE) ) { /* right spot */
X
X if ( !(board[i]->removed) ) {
X
X item = tile[i]; /* got it */
X break;
X
X } else { /* look on next layer down */
X /* take first covered tile and add 1 for loop */
X if (i != 143) i = board[i]->covered[0] + 1;
X }
X } /* wrong location. try again */
X } /* next loop */
X }
X
X /* get data from item selected */
X
X data = (Tiles *) panel_get(item, PANEL_CLIENT_DATA);
X value = data->value;
X
X switch(event_id(event)) {
X
X case MS_LEFT:
X /* Left button down begin selection */
X if (event_is_down(event)) {
X if ( data->top_free && (data->left_free || data->right_free)) {
X
X if ( !(selected[0].filled) || (last_item.item != item) ) { /* don't double up */
X panel_begin_preview(item, event);
X }
X
X /* file last_item slected for future reference */
X last_item.item = item;
X last_item.event.ie_locx = event->ie_locx;
X last_item.event.ie_locy = event->ie_locy;
X last_item.event.ie_time.tv_sec = event->ie_time.tv_sec;
X last_item.event.ie_time.tv_usec = event->ie_time.tv_usec;
X
X last_item.filled = TRUE;
X
X } else { /* beep at them */
X
X window_bell(main_frame);
X
X }
X
X } else {
X
X /* button went up, check same item as down and grab it */
X
X if ((last_item.filled)) { /* else ignore it */
X
X if (item != last_item.item) { /* beep at them */
X
X last_item.filled = FALSE;
X window_bell(main_frame);
X if (!selected[0].filled || (selected[0].item != last_item.item)) {
X /* not aborting deselect */
X panel_cancel_preview(last_item.item, last_item.event);
X
X }
X
X } else {
X
X if (!(selected[0].filled)) {
X
X /* fill first selection if empty */
X selected[0].item = item;
X selected[0].event.ie_locx = event->ie_locx;
X selected[0].event.ie_locy = event->ie_locy;
X selected[0].event.ie_time.tv_sec = event->ie_time.tv_sec;
X selected[0].event.ie_time.tv_usec = event->ie_time.tv_usec;
X
X selected[0].filled = TRUE;
X
X /* clear last item */
X
X last_item.filled = FALSE;
X
X } else {
X
X if (item == selected[0].item) { /* deselect item */
X
X panel_cancel_preview(selected[0].item, selected[0].event);
X
X /* clear last item and selected[0] */
X
X selected[0].filled = FALSE;
X last_item.filled = FALSE;
X
X } else {
X data = (Tiles *) panel_get(selected[0].item, PANEL_CLIENT_DATA);
X if ( value == data->value) {
X /* fill second and show confirm message */
X
X selected[1].item = item;
X selected[1].event.ie_locx = event->ie_locx;
X selected[1].event.ie_locy = event->ie_locy;
X selected[1].event.ie_time.tv_sec = event->ie_time.tv_sec;
X selected[1].event.ie_time.tv_usec = event->ie_time.tv_usec;
X
X selected[1].filled = TRUE;
X
X /* clear last item */
X
X last_item.filled = FALSE;
X
X panel_set(message, PANEL_LABEL_STRING,
X "Please confirm. [Y] [] [N]",
X PANEL_SHOW_ITEM,
X TRUE, 0);
X
X window_set(message_panel, WIN_IGNORE_PICK_EVENTS,
X WIN_MOUSE_BUTTONS, 0, 0);
X window_set(message_panel, WIN_IGNORE_KBD_EVENT,
X WIN_ASCII_EVENTS, 0, 0);
X
X cursor_set(play_cursor, CURSOR_IMAGE, &confirm, 0);
X window_set(play_panel, WIN_CURSOR, play_cursor, 0);
X
X } else { /* beep at them */
X
X panel_cancel_preview(last_item.item, last_item.event);
X panel_cancel_preview(selected[0].item, selected[0].event);
X last_item.filled = FALSE;
X selected[0].filled = FALSE;
X window_bell(main_frame);
X
X }
X }
X }
X }
X }
X }
X break;
X
X case MS_MIDDLE:
X
X if (event_is_up(event) && selected[0].filled) { /* request for help */
X
X help_proc();
X }
X
X break;
X
X /* and all else shall pass */
X }
X}
X
Xvoid quit_proc()
X{
X window_destroy(main_frame);
X}
X
Xvoid new_proc()
X{
X
X seed = random() % 20011;
X build_image(FALSE);
X place_tiles(FALSE);
X}
X
Xvoid again_proc()
X{
X build_image(TRUE);
X place_tiles(FALSE);
X}
X
Xvoid undo_proc()
X
X{
X if(undo_count < 0)
X window_bell(main_frame);
X else
X remove_tiles(FALSE);
X}
X
Xvoid board_num_proc()
X{
X sscanf((char *) panel_get(board_num, PANEL_VALUE), "%d", &seed);
X build_image(FALSE);
X place_tiles(FALSE);
X}
END_OF_event.c
if test 20252 -ne `wc -c <event.c`; then
echo shar: \"event.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f mahjongg.c -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"mahjongg.c\"
else
echo shar: Extracting \"mahjongg.c\" \(26139 characters\)
sed "s/^X//" >mahjongg.c <<'END_OF_mahjongg.c'
X/*
X * Copyright 1988, Mark Holm
X * Exceptions
X *
X * Acknowledgments to Dorothy Robinson for her artistic
X * abilities in drawing the icons and to Jim Batch for
X * technical support and graphical concepts (which I abandoned in favor
X * of the easy way out).
X *
X * Permission is given to copy and distribute for non-profit purposes.
X *
X */
X
X#ifndef lint
Xstatic char *rcs = "$header$ Copyright 1988 Mark Holm";
X#endif !lint
X
X/*
X * $log$
X */
X
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/time.h>
X#include <sys/ioctl.h>
X#include <sys/file.h>
X#include <sun/fbio.h>
X#include <suntool/sunview.h>
X#include <suntool/panel.h>
X#include <suntool/canvas.h>
X#include <suntool/icon.h>
X#include <sunwindow/notify.h>
X#include <pixrect/pixrect.h>
X
X#include "mahjongg.h"
X
Xvoid die();
Xvoid build_image();
Xvoid place_tiles();
XPixrect *color_button();
X
X
X/* Black and white closed icon image */
X
Xstatic short icon_image[] = {
X#include "mahjongg.icon"
X};
XDEFINE_ICON_FROM_IMAGE(icon, icon_image); /* Black and white icon */
Xstruct icon *cicon; /* storage for color icon */
X
X/* externals */
X
Xextern void quit_proc();
Xextern void undo_proc();
Xextern void new_proc();
Xextern void again_proc();
Xextern void help_proc();
Xextern void board_num_proc();
Xextern void play_back_proc();
Xextern void play_event_proc();
X
Xextern short stick_image[];
Xextern int undo_count;
X
X/* overlap globals */
X
X
XFrame main_frame;
XPanel play_panel, message_panel;
XPanel_item TL_hundred;
XPanel_item TL_ten;
XPanel_item TL_one;
XPanel_item message;
XPanel_item tile[144];
XPanel_item tiles_left[3];
XCursor play_cursor;
Xboolean BandW = FALSE;
XTiles *board[144];
XSelected selected[2];
XSelected last_item;
Xint tile_count;
Xchar state[256];
X
X/* local globals */
X
XPixwin *frame_pw;
XPanel_item tile_message;
XPanel_item cp1;
XPanel_item cp2;
XPanel_item cp3;
XPanel_item cp4;
XPanel_item help;
XPanel_item again;
XPanel_item new;
XPanel_item quit;
XPanel_item undo;
XPanel_item board_num;
Xstruct timeval *tp;
Xstruct timezone *tz;
Xint seed;
X
X/* define color map */
X
X#include "color.h"
X
Xmain(argc, argv)
Xint argc;
Xchar **argv;
X{
X struct pixfont *panel_font;
X struct pixfont *dummy_font;
X int i;
X int middle;
X struct fbtype fb;
X int open_stat;
X
X /* determine type of frame buffer and set BandW accordingly */
X
X open_stat = open("/dev/fb", O_RDONLY);
X (void) ioctl(open_stat, FBIOGTYPE, &fb);
X
X if ( (fb.fb_type == FBTYPE_SUN1BW) ||
X (fb.fb_type == FBTYPE_SUN2BW) ||
X (fb.fb_type == FBTYPE_SUN3BW) ||
X (fb.fb_type == FBTYPE_SUN4BW) )
X BandW = TRUE;
X
X /* initialize random number generator seed */
X
X tp = (struct timeval *) malloc(sizeof(struct timeval));
X tz = (struct timezone *) malloc(sizeof(struct timezone));
X gettimeofday(tp, tz);
X (void) initstate((unsigned) (tp->tv_sec % 255), state, 256); /* initialize random state array */
X seed = RANDOM(20011);
X free(tp);
X free(tz);
X
X /* create main frame */
X
X main_frame = window_create(NULL, FRAME,
X FRAME_SHOW_LABEL, FALSE,
X FRAME_SUBWINDOWS_ADJUSTABLE, FALSE,
X FRAME_ICON, &icon,
X FRAME_ARGC_PTR_ARGV, &argc, argv,
X WIN_HEIGHT, FRAME_Y_MAX,
X WIN_WIDTH, FRAME_X_MAX,
X 0);
X
X /* parse arguments */
X for(argc--, argv++; argc > 0; argc--, argv++)
X if (argv[0][0] = '-')
X switch (argv[0][1]) {
X case 'c': /* force color */
X BandW = FALSE;
X break;
X case 'b': /* force black and white */
X BandW = TRUE;
X break;
X case 'n': /* set board number */
X if(argc-- == 0)
X die("Usage: mahjongg [-b] [-c] [-n #]\n", 0);
X argv++;
X sscanf(argv[0] , "%d", &seed);
X if (seed > 20011) {
X printf("Board numbers must be < 20011");
X seed %= 20011;
X }
X break;
X default:
X die("Usage: mahjongg [-b] [-c] [-n #]\n", 0);
X break;
X }
X else
X die("Usage: mahjongg [-b] [-c] [-n #]\n", 0);
X
X /* if color then apply color icon to window icon */
X
X if(!BandW) {
X cicon = (struct icon *) window_get(main_frame, FRAME_ICON);
X cicon->ic_mpr = &cicon_image;
X }
X
X /* get pixwin to apply color maps */
X
X frame_pw = (Pixwin *) window_get(main_frame, WIN_PIXWIN, 0);
X
X /* apply color maps to frame pixwin */
X
X pw_setcmsname(frame_pw, "mahjongg");
X pw_putcolormap(frame_pw, 0, MAX_COLORS+1, red, green, blue);
X if (BandW)
X pw_putcolormap(frame_pw, 0, 1, &(red[WHITE]), &(green[WHITE]), &(blue[WHITE]));
X
X /* set inheritable colors */
X
X window_set(main_frame, FRAME_INHERIT_COLORS, TRUE, 0);
X
X /* set up the panel on the right hand side */
X
X dummy_font = pf_open("/usr/lib/fonts/fixedwidthfonts/screen.r.7");
X panel_font = pf_open("/usr/lib/fonts/fixedwidthfonts/screen.b.14");
X message_panel = window_create(main_frame, PANEL,
X WIN_HEIGHT, MESS_Y_MAX,
X WIN_WIDTH, MESS_X_MAX,
X WIN_X, 0,
X WIN_Y, 0,
X WIN_FONT, dummy_font,
X 0);
X
X /* determine middle of panel */
X
X middle = (MESS_X_MAX / 2);
X
X /* create tile counters */
X
X TL_hundred = panel_create_item(message_panel, PANEL_MESSAGE,
X PANEL_LABEL_IMAGE,
X (BandW) ? &NUM1 : &cNUM1,
X PANEL_ITEM_Y, ATTR_ROW(7),
X PANEL_ITEM_X, X_LOC,
X 0);
X TL_ten = panel_create_item(message_panel, PANEL_MESSAGE,
X PANEL_LABEL_IMAGE,
X (BandW) ? &NUM4 : &cNUM4,
X PANEL_ITEM_Y, ATTR_ROW(7),
X PANEL_ITEM_X, X_LOC + W_BASE_TILE,
X 0);
X TL_one = panel_create_item(message_panel, PANEL_MESSAGE,
X PANEL_LABEL_IMAGE,
X (BandW) ? &NUM4 : &cNUM4,
X PANEL_ITEM_Y, ATTR_ROW(7),
X PANEL_ITEM_X, X_LOC + (W_BASE_TILE * 2),
X 0);
X
X /* create game label messages */
X
X cp1 = panel_create_item(message_panel, PANEL_MESSAGE,
X PANEL_LABEL_FONT, panel_font,
X PANEL_LABEL_STRING, "MAHJONGG",
X PANEL_ITEM_Y, ATTR_ROW(1) - 11,
X PANEL_ITEM_X, middle - 65,
X 0);
X cp2 = panel_create_item(message_panel, PANEL_MESSAGE,
X PANEL_LABEL_FONT, dummy_font,
X PANEL_LABEL_STRING, "Copyright 1988",
X PANEL_ITEM_Y, ATTR_ROW(2),
X PANEL_ITEM_X, middle - 70,
X 0);
X cp3 = panel_create_item(message_panel, PANEL_MESSAGE,
X PANEL_LABEL_FONT, dummy_font,
X PANEL_LABEL_STRING, "Mark A. Holm",
X PANEL_ITEM_Y, ATTR_ROW(3),
X PANEL_ITEM_X, middle - 65,
X 0);
X cp3 = panel_create_item(message_panel, PANEL_MESSAGE,
X PANEL_LABEL_FONT, dummy_font,
X PANEL_LABEL_STRING, "Exceptions",
X PANEL_ITEM_Y, ATTR_ROW(4),
X PANEL_ITEM_X, middle - 60,
X 0);
X tile_message = panel_create_item(message_panel, PANEL_MESSAGE,
X PANEL_LABEL_FONT, panel_font,
X PANEL_LABEL_STRING, "Tiles Remaining",
X PANEL_ITEM_Y, ATTR_ROW(5),
X PANEL_ITEM_X, X_LOC + 20,
X 0);
X
X /* create seed item */
X
X board_num = panel_create_item(message_panel, PANEL_TEXT,
X PANEL_LABEL_FONT, panel_font,
X PANEL_VALUE_FONT, panel_font,
X PANEL_LABEL_STRING, "Board Number : ",
X PANEL_VALUE, "",
X PANEL_ITEM_Y, ATTR_ROW(6),
X PANEL_ITEM_X, middle,
X PANEL_NOTIFY_PROC, board_num_proc,
X 0);
X
X /* create control buttons */
X
X help = panel_create_item(message_panel, PANEL_BUTTON,
X PANEL_ITEM_Y, ATTR_ROW(8),
X PANEL_ITEM_X, middle,
X PANEL_LABEL_IMAGE,
X color_button(panel_button_image(message_panel,
X "HELP",
X 6,
X panel_font),
X CYAN),
X PANEL_NOTIFY_PROC, help_proc,
X 0);
X
X again = panel_create_item(message_panel, PANEL_BUTTON,
X PANEL_LABEL_IMAGE,
X color_button(panel_button_image(message_panel,
X "AGAIN",
X 6,
X panel_font),
X YELLOW),
X PANEL_NOTIFY_PROC, again_proc,
X 0);
X
X new = panel_create_item(message_panel, PANEL_BUTTON,
X PANEL_LABEL_IMAGE,
X color_button(panel_button_image(message_panel,
X "NEW",
X 6,
X panel_font),
X GREEN),
X PANEL_NOTIFY_PROC, new_proc,
X 0);
X
X undo = panel_create_item(message_panel, PANEL_BUTTON,
X PANEL_LABEL_IMAGE,
X color_button(panel_button_image(message_panel,
X "UNDO",
X 6,
X panel_font),
X MAGENTA),
X PANEL_NOTIFY_PROC, undo_proc,
X PANEL_SHOW_ITEM, TRUE,
X 0);
X
X quit = panel_create_item(message_panel, PANEL_BUTTON,
X PANEL_LABEL_IMAGE,
X color_button(panel_button_image(message_panel,
X "QUIT",
X 6,
X panel_font),
X RED),
X PANEL_NOTIFY_PROC, quit_proc,
X 0);
X
X /* place conceled message */
X
X message = panel_create_item(message_panel, PANEL_MESSAGE,
X PANEL_LABEL_FONT, panel_font,
X PANEL_ITEM_Y, ATTR_ROW(10),
X PANEL_ITEM_X, middle,
X PANEL_LABEL_STRING, "",
X PANEL_SHOW_ITEM, FALSE,
X 0);
X
X /* create cursor for play panel*/
X
X play_cursor = cursor_create(CURSOR_IMAGE, &stick,
X CURSOR_XHOT, 8,
X CURSOR_YHOT, 8,
X 0);
X
X if (!BandW) {
X
X /* invert the icon because we are reverse video */
X for (i = 0; i < sizeof(stick_image)/sizeof(short); i++)
X stick_image[i] ^= 0xFFFF;
X
X cursor_set(play_cursor, CURSOR_OP,
X (PIX_SRC^PIX_DST) | PIX_COLOR( YELLOW ),
X 0);
X }
X
X /* set up panel for the play */
X
X play_panel = window_create(main_frame, PANEL,
X WIN_CONSUME_PICK_EVENTS,
X WIN_NO_EVENTS, WIN_MOUSE_BUTTONS, WIN_UP_EVENTS, WIN_LEFT_KEYS, 0,
X WIN_HEIGHT, PLAY_Y_MAX,
X WIN_WIDTH, PLAY_X_MAX,
X WIN_X, 0,
X WIN_Y, MESS_Y_MAX + BORDER,
X WIN_CURSOR, play_cursor,
X PANEL_PAINT, PANEL_NONE,
X PANEL_BACKGROUND_PROC, play_back_proc,
X PANEL_EVENT_PROC, play_event_proc,
X CANVAS_RETAINED, TRUE,
X 0);
X
X window_set(message_panel, WIN_INPUT_DESIGNEE,
X window_get(play_panel, WIN_DEVICE_NUMBER),
X 0);
X
X /* build board image */
X
X build_image(FALSE);
X place_tiles(TRUE);
X
X /* start main processing */
X
X window_main_loop(main_frame);
X exit(0);
X}
X
X
X/* die because of some UNIX error */
Xvoid die(message, pperr)
Xchar *message;
Xint pperr;
X{
X fprintf(stderr, message);
X if (pperr)
X perror("mahjongg");
X exit(1);
X}
X
Xvoid place_tiles(newboard)
Xboolean newboard;
X
X{
X int i;
X int j;
X int k;
X int x_loc;
X int y_loc;
X
X /* check if not new and destroy existing panel buttons */
X
X if (!newboard)
X for(i = 0; i < 144; i++)
X panel_destroy_item(tile[i]);
X
X /* place tiles */
X
X /* row 1 level 1 */
X
X for(i = 0,
X x_loc = COL2;
X i < 12;
X i++,
X x_loc += W_BASE_TILE)
X
X tile[i] = panel_create_item(play_panel, PANEL_BUTTON,
X PANEL_LABEL_IMAGE,
X board[i]->image,
X PANEL_ITEM_X,
X x_loc,
X PANEL_ITEM_Y,
X ROW1,
X PANEL_SHOW_ITEM,
X TRUE,
X PANEL_CLIENT_DATA,
X (caddr_t) board[i],
X 0);
X
X /* row 2 level 1 */
X
X for(x_loc = COL4,
X j = 0;
X j < 8;
X j++,
X i++,
X x_loc += W_BASE_TILE)
X
X tile[i] = panel_create_item(play_panel, PANEL_BUTTON,
X PANEL_LABEL_IMAGE,
X board[i]->image,
X PANEL_ITEM_X,
X x_loc,
X PANEL_ITEM_Y,
X ROW2,
X PANEL_SHOW_ITEM,
X TRUE,
X PANEL_CLIENT_DATA,
X (caddr_t) board[i],
X 0);
X
X /* row 3 level 1 */
X
X for(x_loc = COL3,
X j = 0;
X j < 10;
X j++,
X i++,
X x_loc += W_BASE_TILE)
X
X tile[i] = panel_create_item(play_panel, PANEL_BUTTON,
X PANEL_LABEL_IMAGE,
X board[i]->image,
X PANEL_ITEM_X,
X x_loc,
X PANEL_ITEM_Y,
X ROW3,
X PANEL_SHOW_ITEM,
X TRUE,
X PANEL_CLIENT_DATA,
X (caddr_t) board[i],
X 0);
X
X /* row 4 1/2 level 1 */
X
X /* Left */
X
X tile[i] = panel_create_item(play_panel, PANEL_BUTTON,
X PANEL_LABEL_IMAGE,
X board[i]->image,
X PANEL_ITEM_X,
X COL1,
X PANEL_ITEM_Y,
X ROW4pt5,
X PANEL_SHOW_ITEM,
X TRUE,
X PANEL_CLIENT_DATA,
X (caddr_t) board[i],
X 0);
X
X i++; /* increment tile counter */
X
X /* row 4 level 1 */
X
X for(x_loc = COL2,
X j = 0;
X j < 12;
X j++,
X i++,
X x_loc += W_BASE_TILE)
X
X tile[i] = panel_create_item(play_panel, PANEL_BUTTON,
X PANEL_LABEL_IMAGE,
X board[i]->image,
X PANEL_ITEM_X,
X x_loc,
X PANEL_ITEM_Y,
X ROW4,
X PANEL_SHOW_ITEM,
X TRUE,
X PANEL_CLIENT_DATA,
X (caddr_t) board[i],
X 0);
X
X /* row 5 level 1 */
X
X for(x_loc = COL2,
X j = 0;
X j < 12;
X j++,
X i++,
X x_loc += W_BASE_TILE)
X
X tile[i] = panel_create_item(play_panel, PANEL_BUTTON,
X PANEL_LABEL_IMAGE,
X board[i]->image,
X PANEL_ITEM_X,
X x_loc,
X PANEL_ITEM_Y,
X ROW5,
X PANEL_SHOW_ITEM,
X TRUE,
X PANEL_CLIENT_DATA,
X (caddr_t) board[i],
X 0);
X /* row 4 1/2 level 1 */
X
X /* Right */
X
X tile[i] = panel_create_item(play_panel, PANEL_BUTTON,
X PANEL_LABEL_IMAGE,
X board[i]->image,
X PANEL_ITEM_X,
X COL14,
X PANEL_ITEM_Y,
X ROW4pt5,
X PANEL_SHOW_ITEM,
X TRUE,
X PANEL_CLIENT_DATA,
X (caddr_t) board[i],
X 0);
X
X i++; /* increment tile counter */
X
X tile[i] = panel_create_item(play_panel, PANEL_BUTTON,
X PANEL_LABEL_IMAGE,
X board[i]->image,
X PANEL_ITEM_X,
X COL15,
X PANEL_ITEM_Y,
X ROW4pt5,
X PANEL_SHOW_ITEM,
X TRUE,
X PANEL_CLIENT_DATA,
X (caddr_t) board[i],
X 0);
X
X i++; /* increment tile counter */
X
X /* row 6 level 1 */
X
X for(x_loc = COL3,
X j = 0;
X j < 10;
X j++,
X i++,
X x_loc += W_BASE_TILE)
X
X tile[i] = panel_create_item(play_panel, PANEL_BUTTON,
X PANEL_LABEL_IMAGE,
X board[i]->image,
X PANEL_ITEM_X,
X x_loc,
X PANEL_ITEM_Y,
X ROW6,
X PANEL_SHOW_ITEM,
X TRUE,
X PANEL_CLIENT_DATA,
X (caddr_t) board[i],
X 0);
X
X /* row 7 level 1 */
X
X for(x_loc = COL4,
X j = 0;
X j < 8;
X j++,
X i++,
X x_loc += W_BASE_TILE)
X
X tile[i] = panel_create_item(play_panel, PANEL_BUTTON,
X PANEL_LABEL_IMAGE,
X board[i]->image,
X PANEL_ITEM_X,
X x_loc,
X PANEL_ITEM_Y,
X ROW7,
X PANEL_SHOW_ITEM,
X TRUE,
X PANEL_CLIENT_DATA,
X (caddr_t) board[i],
X 0);
X
X /* row 8 level 1 */
X
X for(j = 0,
X x_loc = COL2;
X j < 12;
X j++,
X i++,
X x_loc += W_BASE_TILE)
X
X tile[i] = panel_create_item(play_panel, PANEL_BUTTON,
X PANEL_LABEL_IMAGE,
X board[i]->image,
X PANEL_ITEM_X,
X x_loc,
X PANEL_ITEM_Y,
X ROW8,
X PANEL_SHOW_ITEM,
X TRUE,
X PANEL_CLIENT_DATA,
X (caddr_t) board[i],
X 0);
X
X /* rows 1-6 level 2 */
X
X for(y_loc = ROW2 - B_TILE_SHADOW,
X j = 0;
X j < 6;
X j++,
X y_loc += H_BASE_TILE)
X
X for(x_loc = COL5 - S_TILE_SHADOW,
X k = 0;
X k < 6;
X i++,
X k++,
X x_loc += W_BASE_TILE)
X
X tile[i] = panel_create_item(play_panel, PANEL_BUTTON,
X PANEL_LABEL_IMAGE,
X board[i]->image,
X PANEL_ITEM_X,
X x_loc,
X PANEL_ITEM_Y,
X y_loc,
X PANEL_SHOW_ITEM,
X TRUE,
X PANEL_CLIENT_DATA,
X (caddr_t) board[i],
X 0);
X
X /* rows 1-4 level 3 */
X
X for(y_loc = ROW3 - (B_TILE_SHADOW * 2),
X j = 0;
X j < 4;
X j++,
X y_loc += H_BASE_TILE)
X
X for(x_loc = COL6 - (S_TILE_SHADOW * 2),
X k = 0;
X k < 4;
X i++,
X k++,
X x_loc += W_BASE_TILE)
X
X tile[i] = panel_create_item(play_panel, PANEL_BUTTON,
X PANEL_LABEL_IMAGE,
X board[i]->image,
X PANEL_ITEM_X,
X x_loc,
X PANEL_ITEM_Y,
X y_loc,
X PANEL_SHOW_ITEM,
X TRUE,
X PANEL_CLIENT_DATA,
X (caddr_t) board[i],
X 0);
X
X /* rows 1-2 level 4 */
X /* special case make messages instead of buttons */
X
X for(y_loc = ROW4 - (B_TILE_SHADOW * 3),
X j = 0;
X j < 2;
X j++,
X y_loc += H_BASE_TILE)
X
X for(x_loc = COL7 - (S_TILE_SHADOW * 3),
X k = 0;
X k < 2;
X i++,
X k++,
X x_loc += W_BASE_TILE)
X
X tile[i] = panel_create_item(play_panel, PANEL_BUTTON,
X PANEL_LABEL_IMAGE,
X board[i]->image,
X PANEL_ITEM_X,
X x_loc,
X PANEL_ITEM_Y,
X y_loc,
X PANEL_SHOW_ITEM,
X TRUE,
X PANEL_CLIENT_DATA,
X (caddr_t) board[i],
X 0);
X
X /* Cap tile */
X
X tile[i] = panel_create_item(play_panel, PANEL_BUTTON,
X PANEL_LABEL_IMAGE,
X board[i]->image,
X PANEL_ITEM_X,
X COL7pt5 - (S_TILE_SHADOW * 4),
X PANEL_ITEM_Y,
X ROW4pt5 - (B_TILE_SHADOW * 4),
X PANEL_SHOW_ITEM,
X TRUE,
X PANEL_CLIENT_DATA,
X (caddr_t) board[i],
X 0);
X
X /* paint panel */
X
X panel_paint(play_panel, PANEL_NO_CLEAR);
X
X /* clear stand_by message and release input mask */
X
X panel_set(message, PANEL_SHOW_ITEM,
X FALSE,
X 0);
X
X window_set(message_panel, WIN_CONSUME_PICK_EVENTS,
X WIN_MOUSE_BUTTONS, 0,
X 0);
X window_set(message_panel, WIN_CONSUME_KBD_EVENT,
X WIN_ASCII_EVENTS, 0, 0);
X
X cursor_set(play_cursor, CURSOR_IMAGE, &stick, 0);
X window_set(play_panel, WIN_CURSOR, play_cursor, 0);
X
X}
X
Xvoid build_image(oldimage)
Xboolean oldimage;
X
X{
Xint i;
Xint j;
Xint pool[42];
Xboolean ok;
Xboolean dir;
Xchar seed_text[80];
X
X /* initialize selected structures */
X
X selected[0].filled = FALSE;
X selected[1].filled = FALSE;
X last_item.filled = FALSE;
X undo_count = -1;
X
X panel_set(message, PANEL_SHOW_ITEM,
X FALSE,
X 0);
X panel_set(TL_hundred, PANEL_LABEL_IMAGE,
X (BandW) ? &NUM1 : &cNUM1,
X PANEL_SHOW_ITEM,
X TRUE,
X 0);
X panel_set(TL_ten , PANEL_LABEL_IMAGE,
X (BandW) ? &NUM4 : &cNUM4,
X PANEL_SHOW_ITEM,
X TRUE,
X 0);
X panel_set(TL_one , PANEL_LABEL_IMAGE,
X (BandW) ? &NUM4 : &cNUM4,
X 0);
X
X /* display current seed in text item */
X
X sprintf(seed_text, "%d", seed);
X panel_set(board_num, PANEL_VALUE, seed_text, 0);
X
X /* show stand_by message while building image and grab all input */
X
X panel_set(message, PANEL_LABEL_STRING,
X "Building board. Please wait.",
X PANEL_SHOW_ITEM,
X TRUE, 0);
X
X window_set(message_panel, WIN_IGNORE_PICK_EVENTS,
X WIN_MOUSE_BUTTONS, 0, 0);
X window_set(message_panel, WIN_IGNORE_KBD_EVENT,
X WIN_ASCII_EVENTS, 0, 0);
X cursor_set(play_cursor, CURSOR_IMAGE, &wait, 0);
X window_set(play_panel, WIN_CURSOR, play_cursor, 0);
X
X /* initialize random number counter */
X
X (void) srandom(seed);
X
X tile_count = 144;
X
X /* initialize tile pool */
X for(i = 0; i < 34; i++) pool[i] = 4;
X for(; i < 42; i++) pool[i] = 1;
X
X /* assign values to each location. Board is built from upper left *
X * to lower right, bottom to top. Exception are left tile for row *
X * 4pt5 is before rows 4 and 5, and right tiles for row 4.5 are *
X * after rows 4 and 5 */
X
X for(j = 0; j < 144; j++) {
X if (board[j] == NULL) /* intialize array */
X board[j] = (Tiles *) malloc(sizeof(Tiles));
X
X if (!oldimage) { /* not repeating last board */
X
X /* Randomly seed index into pool. Randomly *
X * run up or down list until unused tile *
X * is found or end of list. If end of *
X * list reseed and run in opposite *
X * direction in list until unused tile is *
X * found. If beginning of list found, *
X * start over. */
X
X ok = FALSE;
X while (ok == FALSE) {
X i = RANDOM(41);
X /* Up, up, up! */
X dir = random()&01;
X while ((i < 42 || i >=0) && pool[i] == 0) (dir) ? i++ : i--;
X if (i == 42 || i < 0) { /* Thud! Reverse march! */
X i = RANDOM(41);
X while ((i < 42 || i >= 0) && pool[i] == 0) (dir) ? i-- : i++;
X }
X if (i == 42 || i < 0) continue; /* Missed! try again */
X pool[i]--;
X ok = TRUE;
X }
X
X /* all flowers and all seasons */
X
X board[j]->value = (i >= 34) ? ((i >= 38) ? 35 : 34) : i;
X switch(i) {
X
X case 0: board[j]->image = (BandW) ? &DOT1 : &cDOT1;
X break;
X case 1: board[j]->image = (BandW) ? &DOT2 : &cDOT2;
X break;
X case 2: board[j]->image = (BandW) ? &DOT3 : &cDOT3;
X break;
X case 3: board[j]->image = (BandW) ? &DOT4 : &cDOT4;
X break;
X case 4: board[j]->image = (BandW) ? &DOT5 : &cDOT5;
X break;
X case 5: board[j]->image = (BandW) ? &DOT6 : &cDOT6;
X break;
X case 6: board[j]->image = (BandW) ? &DOT7 : &cDOT7;
X break;
X case 7: board[j]->image = (BandW) ? &DOT8 : &cDOT8;
X break;
X case 8: board[j]->image = (BandW) ? &DOT9 : &cDOT9;
X break;
X case 9: board[j]->image = (BandW) ? &BAM1 : &cBAM1;
X break;
X case 10: board[j]->image = (BandW) ? &BAM2 : &cBAM2;
X break;
X case 11: board[j]->image = (BandW) ? &BAM3 : &cBAM3;
X break;
X case 12: board[j]->image = (BandW) ? &BAM4 : &cBAM4;
X break;
X case 13: board[j]->image = (BandW) ? &BAM5 : &cBAM5;
X break;
X case 14: board[j]->image = (BandW) ? &BAM6 : &cBAM6;
X break;
X case 15: board[j]->image = (BandW) ? &BAM7 : &cBAM7;
X break;
X case 16: board[j]->image = (BandW) ? &BAM8 : &cBAM8;
X break;
X case 17: board[j]->image = (BandW) ? &BAM9 : &cBAM9;
X break;
X case 18: board[j]->image = (BandW) ? &CHA1 : &cCHA1;
X break;
X case 19: board[j]->image = (BandW) ? &CHA2 : &cCHA2;
X break;
X case 20: board[j]->image = (BandW) ? &CHA3 : &cCHA3;
X break;
X case 21: board[j]->image = (BandW) ? &CHA4 : &cCHA4;
X break;
X case 22: board[j]->image = (BandW) ? &CHA5 : &cCHA5;
X break;
X case 23: board[j]->image = (BandW) ? &CHA6 : &cCHA6;
X break;
X case 24: board[j]->image = (BandW) ? &CHA7 : &cCHA7;
X break;
X case 25: board[j]->image = (BandW) ? &CHA8 : &cCHA8;
X break;
X case 26: board[j]->image = (BandW) ? &CHA9 : &cCHA9;
X break;
X case 27: board[j]->image = (BandW) ? &GRED : &cGRED;
X break;
X case 28: board[j]->image = (BandW) ? &REDD : &cREDD;
X break;
X case 29: board[j]->image = (BandW) ? &WHTD : &cWHTD;
X break;
X case 30: board[j]->image = (BandW) ? &EAST : &cEAST;
X break;
X case 31: board[j]->image = (BandW) ? &WEST : &cWEST;
X break;
X case 32: board[j]->image = (BandW) ? &SOUT : &cSOUT;
X break;
X case 33: board[j]->image = (BandW) ? &NORT : &cNORT;
X break;
X case 34: board[j]->image = (BandW) ? &AUT : &cAUT;
X break;
X case 35: board[j]->image = (BandW) ? &SUM : &cSUM;
X break;
X case 36: board[j]->image = (BandW) ? &SPR : &cSPR;
X break;
X case 37: board[j]->image = (BandW) ? &WIN : &cWIN;
X break;
X case 38: board[j]->image = (BandW) ? &ORC : &cORC;
X break;
X case 39: board[j]->image = (BandW) ? &MUM : &cMUM;
X break;
X case 40: board[j]->image = (BandW) ? &BAM : &cBAM;
X break;
X case 41: board[j]->image = (BandW) ? &PLM : &cPLM;
X break;
X }
X
X }
X /* establish default values */
X
X board[j]->left_free = FALSE;
X board[j]->right_free = FALSE;
X board[j]->top_free = TRUE;
X board[j]->left_next[0] = j - 1;
X board[j]->left_next[1] = 999;
X board[j]->right_next[0] = j + 1;
X board[j]->right_next[1] = 999;
X board[j]->covered[0] = 999;
X board[j]->covered[1] = 999;
X board[j]->covered[2] = 999;
X board[j]->covered[3] = 999;
X board[j]->removed = FALSE;
X
X /* setup special cases */
X
X switch (j) {
X case 139:
X case 141:
X board[j]->top_free = FALSE;
X case 0:
X case 12:
X case 20:
X case 30:
X case 57:
X case 67:
X case 75:
X case 87:
X case 93:
X case 99:
X case 105:
X case 111:
X case 117:
X case 123:
X case 127:
X case 131:
X case 135:
X board[j]->left_free = TRUE;
X board[j]->left_next[0] = 999;
X break;
X case 140:
X case 142:
X board[j]->top_free = FALSE;
X case 11:
X case 19:
X case 29:
X case 56:
X case 66:
X case 74:
X case 86:
X case 92:
X case 98:
X case 104:
X case 110:
X case 116:
X case 122:
X case 126:
X case 130:
X case 134:
X case 138:
X board[j]->right_free = TRUE;
X board[j]->right_next[0] = 999;
X break;
X case 143:
X board[j]->right_free = TRUE;
X board[j]->left_next[0] = 999;
X board[j]->left_free = TRUE;
X board[j]->right_next[0] = 999;
X board[j]->covered[0] = 139;
X board[j]->covered[1] = 140;
X board[j]->covered[2] = 141;
X board[j]->covered[3] = 142;
X break;
X case 42:
X board[j]->right_next[0] = 55;
X break;
X case 43:
X board[j]->left_next[0] = 30;
X break;
X case 55:
X board[j]->left_next[1] = 42;
X break;
X }
X
X }
X
X /* special case (did not fit in above) */
X
X board[30]->right_next[1] = 43;
X
X /* set top_free flags and covered pointers */
X
X for(i = 87, j = 13; i < 143; i++, j++) {
X board[i]->covered[0] = j;
X board[j]->top_free = FALSE;
X switch(j) {
X case 97:
X case 103:
X case 109:
X case 129:
X j += 2;
X break;
X case 18:
X case 64:
X j += 3;
X break;
X case 27:
X case 39:
X j += 6;
X break;
X case 51:
X j += 7;
X break;
X case 73:
X j += 20;
X break;
X case 115:
X j += 12;
X break;
X }
X }
X}
X
X/* This is the routine that returns the colored button image */
X
XPixrect *color_button(pr,color)
X struct pixrect *pr;
X int color;
X{
X struct pixrect *color_pr;
X
X if(pr == NULL)
X return(NULL);
X
X /* if running in b/w mode return same pixrect */
X if (BandW)
X return(pr);
X
X /* make new pixrect */
X color_pr = mem_create(pr->pr_size.x, pr->pr_size.y, 8);
X
X /* copy pr to color_pr with color added */
X pr_rop(color_pr, 0, 0, pr->pr_size.x, pr->pr_size.y,
X PIX_SRC | PIX_COLOR( color ),
X pr,0,0);
X
X return(color_pr);
X}
END_OF_mahjongg.c
if test 26139 -ne `wc -c <mahjongg.c`; then
echo shar: \"mahjongg.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of archive 3 \(of 3\).
cp /dev/null ark3isdone
MISSING=""
for I in 1 2 3 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 3 archives.
rm -f ark[1-9]isdone
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0