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