v09i021: xmahjongg, Part01/05
Jeff Young
jsy at poplar.cray.com
Wed Sep 12 18:20:45 AEST 1990
Submitted-by: jsy at poplar.cray.com (Jeff Young)
Posting-number: Volume 9, Issue 21
Archive-name: xmahjongg/part01
Here is the first of 5 shar files for an updated xmahjongg. It is
almost totally rewritten, so that I am just submitting sources instead of
patches.
Jeff Young
jsy at cray.com
#! /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
# If this archive is complete, you will see the following message at the end:
# "End of archive 1 (of 5)."
#
# Contents:
# draw.c event.c initial.c packet.c play.c random.c sysdep.c
# variables.c xmahjongg.c
#
# Wrapped by jsy at cray.com on Sun Sep 9 12:43:56 1990
#
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f draw.c -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"draw.c\"
else
echo shar: Extracting \"draw.c\" \(7171 characters\)
sed "s/^X//" >draw.c <<'END_OF_draw.c'
X/*
X ******************************************************************************
X * *
X * Copyright (c) 1990 by Jeff S. Young. All rights reserved under the *
X * copyright laws of the United States. *
X * *
X ******************************************************************************
X */
X
X#include <stdio.h>
X#include <X11/Xlib.h>
X#include <X11/Xutil.h>
X#include <sys/time.h>
X#include "xmahjongg.h"
X#include "variables.h"
X
X#define DRAW_NAME(pp) { \
X int xpos = X_NAMES; \
X \
X sprintf((char *)buffer, "%8.8s", pp->name); \
X draw_string((char *)buffer, xpos, pp->y, XGameTextGC[0]); \
X}
X
X#define DRAW_BOARD(pp, pos) { \
X int xpos = X_BOARD+50*pos; \
X \
X sprintf((char *)buffer, "%5.5d", pp->board[pos]); \
X draw_string((char *)buffer, xpos, Y_BOARD, XGameTextGC[0]); \
X}
X
X#define DRAW_SCORE(pp, pos) { \
X int itmp; \
X int xpos = pp->x+50*pos; \
X int score = pp->tiles[pos]; \
X \
X if (score < 0) score *= -1; \
X itmp = (pp->tiles[pos] > 0) ? 0 : 1; \
X sprintf((char *)buffer, " %3.3d ", score); \
X draw_string((char *)buffer, xpos, pp->y, XGameTextGC[itmp]); \
X}
X
X#define DRAW_TOTAL(pp, pos) { \
X int itmp; \
X int xpos = X_BOARD+50*pos; \
X \
X sprintf((char *)buffer, "TOTAL"); \
X draw_string((char *)buffer, xpos, Y_BOARD, XGameTextGC[0]); \
X xpos = pp->x + 50*pos; \
X itmp = (pp->quit == 0) ? 0 : 1; \
X sprintf((char *)buffer, " %3.3d ", pp->total); \
X draw_string((char *)buffer, xpos, pp->y, XGameTextGC[itmp]); \
X}
X
Xchar copy[] = "(c) 1990 by Jeff Young. ";
Xchar rights[] = "All rights reserved. ";
X
Xdraw_user(pp, type)
XPlayer *pp;
Xint type;
X{
X int i;
X char buffer[20];
X GC userGC;
X
X if (type == GAME_START) {
X DRAW_NAME(pp);
X
X for (i = 0; i < MAX_BOARDS; i++) {
X if (pp->tiles[i] > TILES) break;
X DRAW_BOARD(pp, i);
X DRAW_SCORE(pp, i);
X };
X
X DRAW_TOTAL(pp, num_games);
X } else if (type == GAME_PLAY) {
X DRAW_BOARD(pp, pp->done);
X DRAW_SCORE(pp, pp->done);
X DRAW_TOTAL(pp, num_games);
X } else if (type == GAME_DONE) {
X DRAW_BOARD(pp, pp->done);
X DRAW_SCORE(pp, pp->done);
X } else if (type == GAME_QUIT) {
X DRAW_BOARD(pp, pp->done);
X DRAW_SCORE(pp, pp->done);
X DRAW_TOTAL(pp, num_games);
X } else {
X fprintf(stderr, "bad draw_user type (%d)\n", type);
X exit(1);
X };
X
X return(0);
X}
X
Xdraw_data()
X{
X int i, j, x, y;
X char string[2];
X
X/*
X * Display the tiles on the screen before the start of the game. Order:
X * dragons, seasons, plants, directions, circles, bamboos, ideographs.
X * The 'if' statement below is just a way to figure out the x and y
X * coordinates of the tiles.
X *
X */
X for (i = 10; i <= 51; i++) {
X if ((10 <= i) && (i <= 12)) {
X j = 6;
X x = 2*(i%9);
X y = 198;
X } else if ((13 <= i) && (i <= 16)) {
X j = 5;
X x = (2*i + 7)%8;
X y = 278 + 80*((i-13)/4);
X } else if ((17 <= i) && (i <= 20)) {
X j = 4;
X x = (2*i + 7)%8;
X y = 278 + 80*((i-13)/4);
X } else if ((21 <= i) && (i <= 24)) {
X j = 3;
X x = (2*i + 7)%8;
X y = 278 + 80*((i-13)/4);
X } else if ((25 <= i) && (i <= 33)) {
X j = 1;
X x = (i+2)%9;
X y = 278 + 80*((i+2)/9);
X } else if ((34 <= i) && (i <= 42)) {
X j = 0;
X x = (i+2)%9;
X y = 278 + 80*((i+2)/9);
X } else if ((43 <= i) && (i <= 51)) {
X j = 2;
X x = (i+2)%9;
X y = 278 + 80*((i+2)/9);
X };
X
X x = 42 + 106*x;
X string[0] = tile_data[i];
X XDrawImageString(XGameDisplay, XGameWindow,
X XGameTileGC[j][0], x, y, string, 1);
X };
X
X return(0);
X}
X
Xdraw_tiles()
X{
X int i, j, k;
X char string[2];
X Tile *tp;
X
X XClearWindow(XGameDisplay, XGamePlayWindow);
X
X XCopyArea(XGameDisplay, XGamePlayWindow, XGamePixmap, XGameTextGC[0],
X 0, 0, PLAY_WIDTH, PLAY_HEIGHT, 0, 0);
X
X for (i = 0, tp = order[0]; i < TILES; i++, tp = order[i]) {
X if (tp == NULL) break;
X if (tp->state != USED) continue;
X string[0] = tp->data;
X j = (tp != tile1p) ? 0 : 1;
X k = (color_type == 0) ? tp->lev : (tp->data/16) - 1;
X XDrawImageString(XGameDisplay, XGamePixmap,
X XGameTileGC[k][j], tp->x, tp->y, string, 1);
X
X draw_border(tp->x, tp->y);
X };
X
X XCopyArea(XGameDisplay, XGamePixmap, XGamePlayWindow, XGameTextGC[0],
X 0, 0, PLAY_WIDTH, PLAY_HEIGHT, 0, 0);
X
X XFlush(XGameDisplay);
X
X return(0);
X}
X
Xdraw_count()
X{
X char string[4];
X int count = (done_count != 0) ? done_count : tiles_remaining;
X
X string[0] = count/100;
X string[1] = (count/10)%10;
X string[2] = count%10;
X
X XDrawImageString(XGameDisplay, XGameCountWindow, XGameOtherGC[0],
X 0, 0, string, 3);
X
X XFlush(XGameDisplay);
X
X return(0);
X}
X
Xdraw_border(x, y)
Xint x;
Xint y;
X{
X int i;
X
X for (i = 0; i < 12; i++) {
X XGamePoint[i].x += x;
X XGamePoint[i].y += y;
X };
X
X XDrawLines(XGameDisplay, XGamePixmap, XGameBorderGC, XGamePoint,
X 12, CoordModeOrigin);
X
X for (i = 0; i < 12; i++) {
X XGamePoint[i].x -= x;
X XGamePoint[i].y -= y;
X };
X
X return(0);
X}
X
Xdraw_letter(index, x, y)
Xint index;
Xint x;
Xint y;
X{
X char string[2];
X
X string[0] = index;
X string[1] = index+16;
X
X XDrawImageString(XGameDisplay, XGameWindow, XGameOtherGC[0],
X x, y+00, &string[0], 1);
X XDrawImageString(XGameDisplay, XGameWindow, XGameOtherGC[0],
X x, y+64, &string[1], 1);
X
X XFlush(XGameDisplay);
X
X return(0);
X}
X
Xdraw_window()
X{
X int i, k, x, y;
X char string[64];
X
X k = XGameTextFont->ascent + XGameTextFont->descent + 1;
X x = 55;
X y = (Y_COUNT-4*k)/2;
X
X/*
X * Print out the strings in the upper window
X */
X XClearWindow(XGameDisplay, XGameWindow);
X
X sprintf(string, "Board number: %5d", seed);
X draw_string(copy, x, y+0*k, XGameTextGC[1]);
X draw_string(rights, x, y+1*k, XGameTextGC[1]);
X draw_string(string, x, y+3*k, XGameTextGC[1]);
X
X draw_matches();
X
X/*
X * If in tournament mode, then reprint the current scores
X */
X if (tourn_flag != 0) {
X for (i = 0, pp = player; i < num_players; i++, pp++) {
X pp->y = Y_SCORE+i*k;
X draw_user(pp, GAME_START);
X };
X };
X
X XFlush(XGameDisplay);
X
X return(0);
X}
X
Xdraw_option(index, window)
Xint index;
XWindow window;
X{
X int i;
X char string[2];
X
X
X string[0] = index;
X i = ((window == XGameDoneWindow) && (done_count != 0)) ? 1 : 0;
X XDrawImageString(XGameDisplay, window, XGameOtherGC[i],
X 0, 0, string, 1);
X XFlush(XGameDisplay);
X
X return(0);
X}
X
Xdraw_string(data, x, y, imageGC)
Xchar *data;
Xint x, y;
XGC imageGC;
X{
X
X XDrawImageString(XGameDisplay, XGameWindow, imageGC,
X x, y, data, strlen(data));
X
X XFlush(XGameDisplay);
X
X return(0);
X}
X
Xdraw_matches() {
X int i, j, k;
X int matches = 0;
X char string[80];
X Tile *t1p, *t2p;
X
X if (done_count == 0) return(0);
X
X/*
X * Count the number of matches remaining.
X */
X for(i = 0, t1p = &tiles[0][0][0]; i < ROWS*COLS*LEVS-1; i++, t1p++) {
X if (t1p->state != USED) continue;
X if (not_free(t1p->row, t1p->col, t1p->lev)) continue;
X
X for(j = i+1, t2p = t1p+1; j < ROWS*COLS*LEVS; j++, t2p++) {
X if (t2p->state != USED) continue;
X if (not_free(t2p->row, t2p->col, t2p->lev)) continue;
X if (t1p->type == t2p->type) matches++;
X };
X };
X
X/*
X * Display the number of matches.
X */
X i = XGameTextFont->ascent;
X j = XGameTextFont->descent;
X k = (184-Y_DONE-OPTION_HEIGHT-i-j)/2;
X sprintf(string, " Matches remaining = %3d ", matches);
X draw_string(string, 800, Y_DONE+OPTION_HEIGHT+k+i, XGameTextGC[1]);
X XFlush(XGameDisplay);
X
X return(0);
X}
END_OF_draw.c
if test 7171 -ne `wc -c <draw.c`; then
echo shar: \"draw.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
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\" \(8545 characters\)
sed "s/^X//" >event.c <<'END_OF_event.c'
X/*
X ******************************************************************************
X * *
X * Copyright (c) 1990 by Jeff S. Young. All rights reserved under the *
X * copyright laws of the United States. *
X * *
X ******************************************************************************
X */
X
X#include <stdio.h>
X#include <signal.h>
X#include <sys/time.h>
X#include <X11/Xlib.h>
X#include <X11/Xutil.h>
X#include "xmahjongg.h"
X#include "variables.h"
X
Xevent_process() {
X int readfds;
X
X/*
X * Wait for an event and then process it.
X */
X event_wait();
X
Xnext_event:
X XNextEvent(XGameDisplay, &XGameEvent);
X switch (XGameEvent.type) {
X case Expose:
X if (XGameEvent.xexpose.count != 0) goto next_event;
X event_expose();
X break;
X case ButtonPress:
X event_button();
X break;
X default:
X break;
X };
X
X return(0);
X}
X
Xevent_packet(readfds)
Xint readfds;
X{
X int i;
X
X for (i = 0, pp = player; i < num_players; i++, pp++) {
X if (pp->type == 'M') continue;
X if ((readfds & (1 << pp->fd)) != 0) {
X packet_recv(pp->fd);
X };
X };
X
X return(0);
X}
X
Xevent_expose() {
X
X if (XGameEvent.xexpose.window == XGameWindow) {
X draw_window();
X } else if (XGameEvent.xexpose.window == XGameNewWindow) {
X draw_option(INDEX_NEW, XGameNewWindow);
X } else if (XGameEvent.xexpose.window == XGameDoneWindow) {
X draw_option(INDEX_DONE, XGameDoneWindow);
X } else if (XGameEvent.xexpose.window == XGameQuitWindow) {
X draw_option(INDEX_QUIT, XGameQuitWindow);
X } else if (XGameEvent.xexpose.window == XGameSameWindow) {
X draw_option(INDEX_SAME, XGameSameWindow);
X } else if (XGameEvent.xexpose.window == XGamePlayWindow) {
X draw_tiles();
X } else if (XGameEvent.xexpose.window == XGameCountWindow) {
X draw_count();
X };
X
X return(0);
X}
X
Xevent_button() {
X int i, j, k;
X
X if (XGameEvent.xbutton.window == XGameNewWindow) {
X event_new();
X } else if (XGameEvent.xbutton.window == XGameDoneWindow) {
X event_done();
X } else if (XGameEvent.xbutton.window == XGameSameWindow) {
X event_same();
X } else if (XGameEvent.xbutton.window == XGameQuitWindow) {
X event_quit();
X } else if (XGameEvent.xbutton.window == XGamePlayWindow) {
X event_play();
X };
X
X return(0);
X}
X
Xevent_new() {
X int i, j, k;
X
X/*
X * If this is a tournament, the the user can't go to a new board
X * unless this is not the last game in the series.
X */
X if ((tourn_flag != 0) && (mypp->done == num_games-1)) {
X XBell(XGameDisplay, 100);
X XFlush(XGameDisplay);
X return(0);
X };
X
X/*
X * If this is setup mode, then clear all of the tiles.
X */
X if (setup_flag != 0) {
X for (i = 0; i < TILES; i++) {
X order[i] = NULL;
X };
X
X for (i = 0; i < ROWS; i++) {
X for (j = 0; j < COLS; j++) {
X for (k = 0; k < LEVS; k++) {
X tiles[i][j][k].state = FREE;
X };
X };
X };
X };
X
X/*
X * Clear all the windows.
X */
X keep_playing = 0;
X packet_send(GAME_DONE);
X XClearArea(XGameDisplay, XGameWindow, 0, 0, 0, 0, True);
X XClearArea(XGameDisplay, XGameNewWindow, 0, 0, 0, 0, True);
X XClearArea(XGameDisplay, XGameDoneWindow, 0, 0, 0, 0, True);
X XClearArea(XGameDisplay, XGameSameWindow, 0, 0, 0, 0, True);
X XClearArea(XGameDisplay, XGameQuitWindow, 0, 0, 0, 0, True);
X XClearArea(XGameDisplay, XGamePlayWindow, 0, 0, 0, 0, True);
X XClearArea(XGameDisplay, XGameCountWindow, 0, 0, 0, 0, True);
X XFlush(XGameDisplay);
X
X return(0);
X}
X
Xevent_same() {
X
X/*
X * If this is a tournament, then the user can't play the same board
X * twice. If this is setup mode, then do nothing;
X */
X if ((num_games != 0) || (setup_flag != 0)) {
X XBell(XGameDisplay, 100);
X XFlush(XGameDisplay);
X } else {
X seed = -seed;
X keep_playing = 0;
X XClearArea(XGameDisplay, XGameWindow, 0, 0, 0, 0, True);
X XClearArea(XGameDisplay, XGameNewWindow, 0, 0, 0, 0, True);
X XClearArea(XGameDisplay, XGameDoneWindow, 0, 0, 0, 0, True);
X XClearArea(XGameDisplay, XGameSameWindow, 0, 0, 0, 0, True);
X XClearArea(XGameDisplay, XGameQuitWindow, 0, 0, 0, 0, True);
X XClearArea(XGameDisplay, XGamePlayWindow, 0, 0, 0, 0, True);
X XClearArea(XGameDisplay, XGameCountWindow, 0, 0, 0, 0, True);
X XFlush(XGameDisplay);
X };
X
X return(0);
X}
X
Xevent_done() {
X int i;
X FILE *stdconf;
X
X/*
X * If this is not setup mode, then mark the game as done and display
X * the matches remaining.
X */
X if (setup_flag == 0) {
X if (done_count == 0) {
X done_count = tiles_remaining;
X packet_send(GAME_DONE);
X };
X
X draw_option(INDEX_DONE, XGameDoneWindow);
X draw_matches();
X return(0);
X };
X
X/*
X * For setup mode, we must check to be sure that all the tiles have
X * been placed. If they have, then write out the configuration file.
X */
X if (tiles_remaining != 0) {
X XBell(XGameDisplay, 100);
X XFlush(XGameDisplay);
X return(0);
X };
X
X/*
X * Open the configuration file.
X */
X if (layout != NULL) {
X if ((stdconf = fopen(layout, "w")) == NULL) {
X fprintf(stderr, "can't open layout file\n");
X exit(1);
X };
X } else {
X stdconf = stdout;
X };
X
X/*
X * Dump out the configuration.
X */
X for (i = 0; i < TILES; i++) {
X fprintf(stdconf, "%3d %3d %3d\n",
X order[i]->row, order[i]->col, order[i]->lev);
X };
X
X fclose(stdconf);
X event_quit();
X
X return(0);
X}
X
Xevent_quit() {
X int i;
X
X packet_send(GAME_QUIT);
X
X/*
X * Free all of the X resources which we grabbed.
X */
X XUnloadFont(XGameDisplay, XGameTextFont->fid);
X XUnloadFont(XGameDisplay, XGameTileFont->fid);
X
X XFreeGC(XGameDisplay, XGameBorderGC);
X XFreeGC(XGameDisplay, XGameTextGC[0]);
X XFreeGC(XGameDisplay, XGameTextGC[1]);
X XFreeGC(XGameDisplay, XGameOtherGC[0]);
X XFreeGC(XGameDisplay, XGameOtherGC[1]);
X
X for (i = 0; i < LEVS; i++) {
X XFreeGC(XGameDisplay, XGameTileGC[i][0]);
X XFreeGC(XGameDisplay, XGameTileGC[i][1]);
X };
X
X XFreeCursor(XGameDisplay, XGameCursor);
X XFreePixmap(XGameDisplay, XGamePixmap);
X
X XCloseDisplay(XGameDisplay);
X
X exit(0);
X}
X
Xevent_play() {
X int i, j, k;
X int x, y;
X
X x_coor = XGameEvent.xbutton.x;
X y_coor = XGameEvent.xbutton.y;
X
X/*
X * If we are in setup mode, then call the routine which will create a
X * new tile or delete one from the board.
X */
X if (setup_flag != 0) {
X if (XGameEvent.xbutton.button == Button1) {
X event_create();
X } else {
X event_delete();
X };
X
X return(0);
X };
X
X/*
X * We are in play mode. Check the make sure the button was pushed on a
X * tile.
X */
X for (k = LEVS-1; k >= 0; k--) {
X x = (y_coor - Y_TILE + (4*k))/(TILE_SIDE/2);
X y = (x_coor - X_TILE - (4*k))/(TILE_SIDE/2);
X
X for (i = 0; i < 2; i++) {
X for (j = 0; j < 2; j++) {
X if (in_bounds(x-i, y-j)) {
X if (tiles[x-i][y-j][k].state == USED) {
X play_tile(&tiles[x-i][y-j][k]);
X return(0);
X };
X };
X };
X };
X };
X
X/*
X * The button was pushed in a bad area. We beep the bell and continue.
X */
X XBell(XGameDisplay, 100);
X XFlush(XGameDisplay);
X
X return(0);
X}
X
Xevent_create() {
X int i, j, k;
X int x, y;
X
X if (tiles_remaining == 0) {
X XBell(XGameDisplay, 100);
X XFlush(XGameDisplay);
X return(0);
X } else if (x_coor < X_TILE) {
X XBell(XGameDisplay, 100);
X XFlush(XGameDisplay);
X return(0);
X } else if (y_coor < Y_TILE) {
X XBell(XGameDisplay, 100);
X XFlush(XGameDisplay);
X return(0);
X };
X
X/*
X * Check the make sure the button was pushed on a tile.
X */
X for (k = 0; k < LEVS; k++) {
X x = (y_coor - Y_TILE + (4*k))/(TILE_SIDE/2);
X y = (x_coor - X_TILE - (4*k))/(TILE_SIDE/2);
X
X for (i = 0; i < 2; i++) {
X for (j = 0; j < 2; j++) {
X if (in_bounds(x-i, y-j) == 0) continue;
X if (ok_below(x-i, y-j, k) != 0) continue;
X if (tiles[x-i][y-j][k].state == USED) continue;
X create_tile(&tiles[x-i][y-j][k]);
X return(0);
X };
X };
X };
X
X/*
X * The button was pushed in a bad area. We beep the bell and continue.
X */
X XBell(XGameDisplay, 100);
X XFlush(XGameDisplay);
X
X return(0);
X}
X
Xevent_delete() {
X int i, j, k;
X int x, y;
X
X if (tiles_remaining == TILES) {
X XBell(XGameDisplay, 100);
X XFlush(XGameDisplay);
X return(0);
X } else if (x_coor < X_TILE) {
X XBell(XGameDisplay, 100);
X XFlush(XGameDisplay);
X return(0);
X } else if (y_coor < Y_TILE) {
X XBell(XGameDisplay, 100);
X XFlush(XGameDisplay);
X return(0);
X };
X
X/*
X * Check the make sure the button was pushed on a tile.
X */
X for (k = LEVS-1; k >= 0; k--) {
X x = (y_coor - Y_TILE + (4*k))/(TILE_SIDE/2);
X y = (x_coor - X_TILE - (4*k))/(TILE_SIDE/2);
X
X for (i = 0; i < 2; i++) {
X for (j = 0; j < 2; j++) {
X if (in_bounds(x-i, y-j) == 0) continue;
X if (ok_above(x-i, y-j, k) != 0) continue;
X if (tiles[x-i][y-j][k].state == FREE) continue;
X delete_tile(&tiles[x-i][y-j][k]);
X return(0);
X };
X };
X };
X
X/*
X * The button was pushed in a bad area. We beep the bell and continue.
X */
X XBell(XGameDisplay, 100);
X XFlush(XGameDisplay);
X
X return(0);
X}
END_OF_event.c
if test 8545 -ne `wc -c <event.c`; then
echo shar: \"event.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f initial.c -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"initial.c\"
else
echo shar: Extracting \"initial.c\" \(19579 characters\)
sed "s/^X//" >initial.c <<'END_OF_initial.c'
X/*
X ******************************************************************************
X * *
X * Copyright (c) 1990 by Jeff S. Young. All rights reserved under the *
X * copyright laws of the United States. *
X * *
X ******************************************************************************
X */
X
X#include <netdb.h>
X#include <stdio.h>
X#include <signal.h>
X#include <sys/time.h>
X#include <sys/types.h>
X#include <sys/socket.h>
X#include <netinet/in.h>
X#include <X11/Xlib.h>
X#include <X11/Xutil.h>
X#include <X11/cursorfont.h>
X#include "xmahjongg.h"
X#include "variables.h"
X#include "icon.h"
X
Xint initial_flag = 0;
Xchar copyright[] = " Copyright (c) 1990 by Jeff Young (exceptions). All rights reserved. ";
X
Xinitialize() {
X
X initialize_conf();
X initialize_data();
X initialize_pool();
X initialize_tiles();
X initialize_socket();
X initialize_window();
X
X return(0);
X}
X
Xinitialize_conf() {
X int i, j, k;
X int cnt, row, col, lev;
X char line[128], file[128];
X FILE *stdconf;
X
X if (initial_flag != 0) return(0);
X if (setup_flag != 0) return(0);
X
X/*
X * Set all tiles to FREE before reading in the configuration.
X */
X for (i = 0; i < ROWS; i++) {
X for (j = 0; j < COLS; j++) {
X for (k = 0; k < LEVS; k++) {
X tiles[i][j][k].init = FREE;
X tiles[i][j][k].state = FREE;
X };
X };
X };
X
X/*
X * Open the file containing the specified layout.
X */
X cnt = 0;
X if (layout == NULL) {
X sprintf(file, "%s/default", LAYOUT);
X } else if ((layout[0] != '/') && (layout[0] != '.')) {
X sprintf(file, "%s/%s", LAYOUT, layout);
X } else {
X strcpy(file, layout);
X };
X
X if ((stdconf = fopen(file, "r")) == NULL) {
X fprintf(stderr, "can't open layout file \n");
X exit(1);
X };
X
X/*
X * Read in the row, col, lev lines
X */
X while (fgets(line, 127, stdconf) != NULL) {
X if (line[0] == '#') continue;
X
X sscanf(line, "%d %d %d", &row, &col, &lev);
X tiles[row][col][lev].init = USED;
X tiles[row][col][lev].state = USED;
X order[cnt++] = &tiles[row][col][lev];
X };
X
X fclose(stdconf);
X
X/*
X * Do a rudimentary check on the number of tiles read
X */
X if (cnt != TILES) {
X fprintf(stderr, "invalid layout file (%d)\n", cnt);
X exit(1);
X };
X
X return(0);
X}
X
Xinitialize_data() {
X int i, j, k, l;
X int dx, dy, dz;
X Tile *tp, *temp;
X
X done_count = 0;
X tiles_remaining = TILES;
X if (initial_flag != 0) return(0);
X
X/*
X * Initialize the bitmap pointers for shuffling into the pool.
X */
X tile_data[ 0] = INDEX_NUMBER + 0;
X tile_data[ 1] = INDEX_NUMBER + 1;
X tile_data[ 2] = INDEX_NUMBER + 2;
X tile_data[ 3] = INDEX_NUMBER + 3;
X tile_data[ 4] = INDEX_NUMBER + 4;
X tile_data[ 5] = INDEX_NUMBER + 5;
X tile_data[ 6] = INDEX_NUMBER + 6;
X tile_data[ 7] = INDEX_NUMBER + 7;
X tile_data[ 8] = INDEX_NUMBER + 8;
X tile_data[ 9] = INDEX_NUMBER + 9;
X tile_data[10] = INDEX_DRAGON + 0;
X tile_data[11] = INDEX_DRAGON + 1;
X tile_data[12] = INDEX_DRAGON + 2;
X tile_data[13] = INDEX_SEASON + 0;
X tile_data[14] = INDEX_SEASON + 1;
X tile_data[15] = INDEX_SEASON + 2;
X tile_data[16] = INDEX_SEASON + 3;
X tile_data[17] = INDEX_PLANT + 0;
X tile_data[18] = INDEX_PLANT + 1;
X tile_data[19] = INDEX_PLANT + 2;
X tile_data[20] = INDEX_PLANT + 3;
X tile_data[21] = INDEX_DIRECTION + 0;
X tile_data[22] = INDEX_DIRECTION + 1;
X tile_data[23] = INDEX_DIRECTION + 2;
X tile_data[24] = INDEX_DIRECTION + 3;
X tile_data[25] = INDEX_CIRCLE + 0;
X tile_data[26] = INDEX_CIRCLE + 1;
X tile_data[27] = INDEX_CIRCLE + 2;
X tile_data[28] = INDEX_CIRCLE + 3;
X tile_data[29] = INDEX_CIRCLE + 4;
X tile_data[30] = INDEX_CIRCLE + 5;
X tile_data[31] = INDEX_CIRCLE + 6;
X tile_data[32] = INDEX_CIRCLE + 7;
X tile_data[33] = INDEX_CIRCLE + 8;
X tile_data[34] = INDEX_BAMBOO + 0;
X tile_data[35] = INDEX_BAMBOO + 1;
X tile_data[36] = INDEX_BAMBOO + 2;
X tile_data[37] = INDEX_BAMBOO + 3;
X tile_data[38] = INDEX_BAMBOO + 4;
X tile_data[39] = INDEX_BAMBOO + 5;
X tile_data[40] = INDEX_BAMBOO + 6;
X tile_data[41] = INDEX_BAMBOO + 7;
X tile_data[42] = INDEX_BAMBOO + 8;
X tile_data[43] = INDEX_IDEOGRAPH + 0;
X tile_data[44] = INDEX_IDEOGRAPH + 1;
X tile_data[45] = INDEX_IDEOGRAPH + 2;
X tile_data[46] = INDEX_IDEOGRAPH + 3;
X tile_data[47] = INDEX_IDEOGRAPH + 4;
X tile_data[48] = INDEX_IDEOGRAPH + 5;
X tile_data[49] = INDEX_IDEOGRAPH + 6;
X tile_data[50] = INDEX_IDEOGRAPH + 7;
X tile_data[51] = INDEX_IDEOGRAPH + 8;
X
X/*
X * Initialize the coordinates for all the tiles.
X */
X l = TILE_SIDE/2;
X for (i = 0; i < ROWS; i++) {
X for (j = 0; j < COLS; j++) {
X for (k = 0; k < LEVS; k++) {
X tiles[i][j][k].row = i;
X tiles[i][j][k].col = j;
X tiles[i][j][k].lev = k;
X tiles[i][j][k].x = X_TILE+(j*l)+(4*k);
X tiles[i][j][k].y = Y_TILE+(i*l)-(4*k);
X if (setup_flag != 0) {
X tiles[i][j][k].state = FREE;
X };
X };
X };
X };
X
X/*
X * Put the randomized images into the tiles and sort them according
X * to the drawing order.
X */
X if (setup_flag == 0) {
X for (i = 0; i < TILES-1; i++) {
X for (j = i+1; j < TILES; j++) {
X dx = order[i]->row - order[j]->row;
X dy = order[i]->col - order[j]->col;
X dz = order[i]->lev - order[j]->lev;
X
X if (dz < 0) continue;
X
X if (dz > 0) {
X temp = order[i];
X order[i] = order[j];
X order[j] = temp;
X } else if (dy < dx) {
X temp = order[i];
X order[i] = order[j];
X order[j] = temp;
X } else if ((dy == dx) && (dy > 0)) {
X temp = order[i];
X order[i] = order[j];
X order[j] = temp;
X };
X };
X
X order[i]->value = i;
X };
X
X order[TILES-1]->value = TILES-1;
X };
X
X return(0);
X}
X
Xinitialize_pool() {
X int i, j, k;
X int seed1, seed2;
X long save;
X
X if (setup_flag != 0) return(0);
X
X/*
X * Set up the randomness for the game
X */
X get_seed();
X random_init(seed);
X
X/*
X * Place the circle, bamboo, and ideograph tiles in the pool
X */
X for (j = 0, k = 0; j < 4; j++) {
X for (i = 21; i <= 51; i++) {
X buffer[k++] = i;
X };
X };
X
X/*
X * Place the dragon tiles in the pool
X */
X for (j = 0; j < 4; j++) {
X for (i = 10; i <= 12; i++) {
X buffer[k++] = i;
X };
X };
X
X/*
X * Place the season and plant tiles in the pool
X */
X for (i = 13; i <= 20; i++) {
X buffer[k++] = i;
X };
X
X/*
X * Shuffle the pool of tiles
X */
X for (i = 0; i < 16384; i++) {
X seed1 = (random_next() & 0xfffffff)%TILES;
X seed2 = (random_next() & 0xfffffff)%TILES;
X save = buffer[seed1];
X buffer[seed1] = buffer[seed2];
X buffer[seed2] = save;
X };
X
X return(0);
X}
X
Xinitialize_tiles() {
X int i;
X int s1_tile = tile_data[13];
X int s2_tile = tile_data[16];
X int p1_tile = tile_data[17];
X int p2_tile = tile_data[20];
X Tile *tp;
X
X if (setup_flag != 0) return(0);
X
X/*
X * Put the randomized images into the tiles and sort them according
X * to the drawing order.
X */
X for (i = 0, tp = order[0]; i < TILES; i++, tp = order[i]) {
X tp->state = tp->init;
X tp->data = tile_data[get_tile()];
X if ((s1_tile <= tp->data) && (tp->data <= s2_tile)) {
X tp->type = s1_tile;
X } else if ((p1_tile <= tp->data) && (tp->data <= p2_tile)) {
X tp->type = p1_tile;
X } else {
X tp->type = tp->data;
X };
X
X };
X
X/*
X * Set the tile pointers to NULL for starters.
X */
X tile1p = NULL;
X tile2p = NULL;
X
X return(0);
X}
X
Xinitialize_socket() {
X int i, s;
X int sizeon;
X int namelen;
X int on = 1;
X struct sockaddr_in name;
X struct hostent *hp, *gethostbyname();
X
X if (setup_flag != 0) return(0);
X if (tourn_flag != 1) return(0);
X printf("attempting connections\n");
X
X/*
X * Attempt connects
X */
X i = 0;
X for (pp = &player[num_players-1]; pp >= player; pp--, i++) {
X if (pp->type != 'C') continue;
X
X namelen = sizeof(name);
X name.sin_family = AF_INET;
X name.sin_port = htons(pp->port);
X hp = gethostbyname(pp->machine);
X bcopy(hp->h_addr, (char *)&name.sin_addr, hp->h_length);
X
X while (1) {
X if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
X sleep(1);
X } else if (connect(s, (char *)&name, namelen) < 0) {
X close(s);
X sleep(1);
X } else {
X pp->fd = s;
X break;
X };
X };
X };
X
X/*
X * Attempt accepts
X */
X name.sin_family = AF_INET;
X name.sin_port = htons(mypp->port);
X name.sin_addr.s_addr = 0;
X namelen = sizeof(name);
X sizeon = sizeof(on);
X
X if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
X perror("can't open socket");
X exit(1);
X } else if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeon) < 0) {
X perror("can't reset socket");
X exit(1);
X } else if (bind(s, (char *)&name, namelen) < 0) {
X perror("can't bind socket");
X exit(1);
X } else if (listen(s, 5) < 0) {
X perror("can't listen socket");
X exit(1);
X };
X
X for (i = 0, pp = player; i < num_players; i++, pp++) {
X if (pp->type != 'A') continue;
X namelen = sizeof(name);
X
X if ((pp->fd = accept(s, (char *)&name, &namelen)) < 0) {
X sleep(1);
X };
X };
X
X for (i = 0, pp = player; i < num_players; i++, pp++) {
X if (pp->type != 'M') playfds |= (1 << pp->fd);
X };
X
X tourn_flag = 2;
X printf("connections established\n");
X
X return(0);
X}
X
Xinitialize_window() {
X int color[9];
X int i, j, k, x, y;
X int init_x, init_y;
X int other_fore_color;
X int other_back_color;
X int window_fore_color;
X int window_back_color;
X int border_fore_color;
X int border_back_color;
X XWMHints XGameWMHints;
X
X/*
X * Only initialize the window if the initial_flag is zero
X */
X if (initial_flag != 0) return(0);
X
X/*
X * Open up the display.
X */
X if ((XGameDisplay = XOpenDisplay(display_name)) == NULL) {
X fprintf(stderr, "can't connect to display\n");
X exit(1);
X };
X
X/*
X * Set some default variables from the server.
X */
X XGameScreen = DefaultScreen(XGameDisplay);
X XGameColormap = DefaultColormap(XGameDisplay, XGameScreen);
X XGameVisual = DefaultVisual(XGameDisplay, XGameScreen);
X XGameDepth = DefaultDepth(XGameDisplay, XGameScreen);
X XGameFD = ConnectionNumber(XGameDisplay);
X
X/*
X * Get the colors that we need.
X */
X if (XGameDepth > 1) {
X XGameBlack = setup_color(0x0000, 0x0000, 0x0000);
X XGameWhite = setup_color(0xffff, 0xffff, 0xffff);
X XGameGrey = setup_color(0x7fff, 0x7fff, 0x7fff);
X
X color[0] = setup_color(0x0000, 0x8fff, 0xffff);
X color[1] = setup_color(0x0000, 0xffff, 0xffff);
X color[2] = setup_color(0x0000, 0xffff, 0x0000);
X color[3] = setup_color(0xffff, 0xffff, 0x0000);
X color[4] = setup_color(0xffff, 0x7fff, 0x0000);
X color[5] = setup_color(0xffff, 0x0000, 0x0000);
X color[6] = setup_color(0xffff, 0x0000, 0xafff);
X
X for (i = 0; i < LEVS; i++) {
X fore_colors[i] = XGameBlack;
X back_colors[i] = color[i];
X };
X
X if (reverse_video == 0) {
X other_fore_color = XGameBlack;
X other_back_color = XGameWhite;
X border_fore_color = XGameGrey;
X border_back_color = XGameGrey;
X window_fore_color = XGameBlack;
X window_back_color = XGameWhite;
X } else {
X other_fore_color = XGameWhite;
X other_back_color = XGameBlack;
X border_fore_color = XGameGrey;
X border_back_color = XGameGrey;
X window_fore_color = XGameWhite;
X window_back_color = XGameBlack;
X };
X } else {
X XGameBlack = BlackPixel(XGameDisplay, XGameScreen);
X XGameWhite = WhitePixel(XGameDisplay, XGameScreen);
X
X if (reverse_video == 0) {
X for (i = 0; i < LEVS; i++) {
X fore_colors[i] = XGameBlack;
X back_colors[i] = XGameWhite;
X };
X
X other_fore_color = XGameBlack;
X other_back_color = XGameWhite;
X border_fore_color = XGameWhite;
X border_back_color = XGameBlack;
X window_fore_color = XGameBlack;
X window_back_color = XGameWhite;
X } else {
X for (i = 0; i < LEVS; i++) {
X fore_colors[i] = XGameWhite;
X back_colors[i] = XGameBlack;
X };
X
X other_fore_color = XGameWhite;
X other_back_color = XGameBlack;
X border_fore_color = XGameBlack;
X border_back_color = XGameWhite;
X window_fore_color = XGameWhite;
X window_back_color = XGameBlack;
X };
X
X color_type = 0;
X };
X
X/*
X * Get the font for text printing and tile printing.
X */
X if ((XGameTextFont = XLoadQueryFont(XGameDisplay, TEXT_FONT)) == NULL) {
X fprintf(stderr, "can't load text font %s\n", TEXT_FONT);
X exit(1);
X };
X
X if ((XGameTileFont = XLoadQueryFont(XGameDisplay, tile_font)) == NULL) {
X fprintf(stderr, "can't load tile font %s\n", tile_font);
X exit(1);
X };
X
X/*
X * Define an icon for the game
X */
X XGameIcon = XCreateBitmapFromData(
X XGameDisplay, DefaultRootWindow(XGameDisplay),
X icon_tiles_bits, ICON_WIDTH, ICON_HEIGHT);
X
X/*
X * Open the main window.
X */
X init_x = (DisplayWidth(XGameDisplay, XGameScreen)-WINDOW_WIDTH)/2;
X init_y = (DisplayHeight(XGameDisplay, XGameScreen)-WINDOW_HEIGHT)/2;
X
X XGameWindow = XCreateSimpleWindow(
X XGameDisplay, DefaultRootWindow(XGameDisplay),
X init_x, init_y, WINDOW_WIDTH, WINDOW_HEIGHT,
X BORDER_WIDTH, window_fore_color, window_back_color);
X
X if (XGameWindow == 0) {
X fprintf(stderr, "can't open main window");
X exit(1);
X };
X
X/*
X * Open the subwindows
X */
X XGameCountWindow = XCreateSimpleWindow(
X XGameDisplay, XGameWindow,
X X_COUNT, Y_COUNT, COUNT_WIDTH, COUNT_HEIGHT,
X BORDER_WIDTH, window_fore_color, window_back_color);
X
X if (XGameCountWindow == 0) {
X fprintf(stderr, "can't open COUNT window");
X exit(1);
X };
X
X XGamePlayWindow = XCreateSimpleWindow(
X XGameDisplay, XGameWindow,
X X_PLAY, Y_PLAY, PLAY_WIDTH, PLAY_HEIGHT,
X BORDER_WIDTH, window_fore_color, window_back_color);
X
X if (XGamePlayWindow == 0) {
X fprintf(stderr, "can't open PLAY window");
X exit(1);
X };
X
X XGameDoneWindow = XCreateSimpleWindow(
X XGameDisplay, XGameWindow,
X X_DONE, Y_DONE, OPTION_WIDTH, OPTION_HEIGHT,
X BORDER_WIDTH, window_fore_color, window_back_color);
X
X if (XGameDoneWindow == 0) {
X fprintf(stderr, "can't open DONE window");
X exit(1);
X };
X
X XGameQuitWindow = XCreateSimpleWindow(
X XGameDisplay, XGameWindow,
X X_QUIT, Y_QUIT, OPTION_WIDTH, OPTION_HEIGHT,
X BORDER_WIDTH, window_fore_color, window_back_color);
X
X if (XGameQuitWindow == 0) {
X fprintf(stderr, "can't open QUIT window");
X exit(1);
X };
X
X XGameSameWindow = XCreateSimpleWindow(
X XGameDisplay, XGameWindow,
X X_SAME, Y_SAME, OPTION_WIDTH, OPTION_HEIGHT,
X BORDER_WIDTH, window_fore_color, window_back_color);
X
X if (XGameSameWindow == 0) {
X fprintf(stderr, "can't open SAME window");
X exit(1);
X };
X
X XGameNewWindow = XCreateSimpleWindow(
X XGameDisplay, XGameWindow,
X X_NEW, Y_NEW, OPTION_WIDTH, OPTION_HEIGHT,
X BORDER_WIDTH, window_fore_color, window_back_color);
X
X if (XGameNewWindow == 0) {
X fprintf(stderr, "can't open NEW window");
X exit(1);
X };
X
X/*
X * Tell the window manager about us
X */
X XSetStandardProperties(
X XGameDisplay, XGameWindow,
X "xmahjongg", NULL,
X XGameIcon, NULL, 0,
X &XGameHints);
X
X XGameWMHints.flags = IconPixmapHint | StateHint;
X XGameWMHints.icon_pixmap = XGameIcon;
X XGameWMHints.initial_state = (iconic_start) ? IconicState : NormalState;
X XSetWMHints(XGameDisplay, XGameWindow, &XGameWMHints);
X
X/*
X * Create a pixmap for tile image copying.
X */
X XGamePixmap = XCreatePixmap(XGameDisplay, XGameWindow,
X PLAY_WIDTH, PLAY_HEIGHT, XGameDepth);
X
X/*
X * Setup the offsets for the border drawing.
X */
X XGamePoint[ 0].x = -1; XGamePoint[ 0].y = 1;
X XGamePoint[ 1].x = -1; XGamePoint[ 1].y = 64;
X XGamePoint[ 2].x = 62; XGamePoint[ 2].y = 64;
X XGamePoint[ 3].x = 61; XGamePoint[ 3].y = 65;
X XGamePoint[ 4].x = -2; XGamePoint[ 4].y = 65;
X XGamePoint[ 5].x = -2; XGamePoint[ 5].y = 2;
X XGamePoint[ 6].x = -3; XGamePoint[ 6].y = 3;
X XGamePoint[ 7].x = -3; XGamePoint[ 7].y = 66;
X XGamePoint[ 8].x = 60; XGamePoint[ 8].y = 66;
X XGamePoint[ 9].x = 59; XGamePoint[ 9].y = 67;
X XGamePoint[10].x = -4; XGamePoint[10].y = 67;
X XGamePoint[11].x = -4; XGamePoint[11].y = 4;
X
X/*
X * Setup the GCs for the text and tiles
X */
X XGameBorderGC = XCreateGC(XGameDisplay, XGameWindow, 0, 0);
X XSetForeground(XGameDisplay, XGameBorderGC, border_back_color);
X XSetBackground(XGameDisplay, XGameBorderGC, border_fore_color);
X XSetFont(XGameDisplay, XGameBorderGC, XGameTileFont->fid);
X
X XGameTextGC[0] = XCreateGC(XGameDisplay, XGameWindow, 0, 0);
X XSetForeground(XGameDisplay, XGameTextGC[0], other_fore_color);
X XSetBackground(XGameDisplay, XGameTextGC[0], other_back_color);
X XSetFont(XGameDisplay, XGameTextGC[0], XGameTextFont->fid);
X
X XGameTextGC[1] = XCreateGC(XGameDisplay, XGameWindow, 0, 0);
X XSetForeground(XGameDisplay, XGameTextGC[1], other_back_color);
X XSetBackground(XGameDisplay, XGameTextGC[1], other_fore_color);
X XSetFont(XGameDisplay, XGameTextGC[1], XGameTextFont->fid);
X
X XGameOtherGC[0] = XCreateGC(XGameDisplay, XGameWindow, 0, 0);
X XSetForeground(XGameDisplay, XGameOtherGC[0], other_fore_color);
X XSetBackground(XGameDisplay, XGameOtherGC[0], other_back_color);
X XSetFont(XGameDisplay, XGameOtherGC[0], XGameTileFont->fid);
X
X XGameOtherGC[1] = XCreateGC(XGameDisplay, XGameWindow, 0, 0);
X XSetForeground(XGameDisplay, XGameOtherGC[1], other_back_color);
X XSetBackground(XGameDisplay, XGameOtherGC[1], other_fore_color);
X XSetFont(XGameDisplay, XGameOtherGC[1], XGameTileFont->fid);
X
X for (i = 0; i < LEVS; i++) {
X XGameTileGC[i][0] = XCreateGC(XGameDisplay, XGameWindow, 0, 0);
X XSetForeground(XGameDisplay, XGameTileGC[i][0], fore_colors[i]);
X XSetBackground(XGameDisplay, XGameTileGC[i][0], back_colors[i]);
X XSetFont(XGameDisplay, XGameTileGC[i][0], XGameTileFont->fid);
X
X XGameTileGC[i][1] = XCreateGC(XGameDisplay, XGameWindow, 0, 0);
X XSetForeground(XGameDisplay, XGameTileGC[i][1], back_colors[i]);
X XSetBackground(XGameDisplay, XGameTileGC[i][1], fore_colors[i]);
X XSetFont(XGameDisplay, XGameTileGC[i][1], XGameTileFont->fid);
X };
X
X/*
X * Define the cursor for the game
X */
X XGameCursor = XCreateFontCursor(XGameDisplay, XC_left_ptr);
X XDefineCursor(XGameDisplay, XGameWindow, XGameCursor);
X
X/*
X * Select window exposure events to see if the contents of the window
X * have been erased or altered.
X */
X XSelectInput(XGameDisplay, XGameWindow, XGameEvents);
X XSelectInput(XGameDisplay, XGameNewWindow, XGameEvents);
X XSelectInput(XGameDisplay, XGameDoneWindow, XGameEvents);
X XSelectInput(XGameDisplay, XGameQuitWindow, XGameEvents);
X XSelectInput(XGameDisplay, XGameSameWindow, XGameEvents);
X XSelectInput(XGameDisplay, XGamePlayWindow, XGameEvents);
X XSelectInput(XGameDisplay, XGameCountWindow, XGameEvents);
X
X/*
X * Map the game window to the screen.
X */
X XMapRaised(XGameDisplay, XGameWindow);
X while (1) {
X XNextEvent(XGameDisplay, &XGameEvent);
X if (XGameEvent.type == Expose) break;
X };
X
X/*
X * Display the game name.
X */
X XDrawLine(XGameDisplay, XGameWindow, XGameTextGC[0], 0, 184, 1000, 184);
X
X draw_letter(INDEX_X, 42, 50);
X draw_letter(INDEX_M, 148, 50);
X draw_letter(INDEX_A, 254, 50);
X draw_letter(INDEX_H, 360, 50);
X draw_letter(INDEX_J, 466, 50);
X draw_letter(INDEX_O, 572, 50);
X draw_letter(INDEX_N, 678, 50);
X draw_letter(INDEX_G, 784, 50);
X draw_letter(INDEX_G, 890, 50);
X
X/*
X * Display the copyright notice
X */
X i = strlen(copyright);
X j = XGameTextFont->max_bounds.width;
X k = XGameTextFont->ascent;
X
X j = (WINDOW_WIDTH - i*j)/2;
X k = (174 - k);
X draw_string(copyright, j, k, XGameTextGC[1]);
X
X/*
X * Display the tiles on the screen before the start of the game. Order:
X * dragons, seasons, plants, directions, circles, bamboos, ideographs
X */
X draw_data();
X
X XFlush(XGameDisplay);
X sleep(5);
X
X/*
X * Find the maximum file descriptor for the select system call and set
X * the initialization flag.
X */
X initial_flag++;
X maxfds = 31;
X
X/*
X * Map the subwindows
X */
X XClearArea(XGameDisplay, XGameWindow, 0, 0, 0, 0, True);
X XMapSubwindows(XGameDisplay, XGameWindow);
X XFlush(XGameDisplay);
X return(0);
X}
X
Xsetup_color(r, g, b)
Xint r;
Xint g;
Xint b;
X{
X XColor XGameColor;
X
X XGameColor.red = r;
X XGameColor.green = g;
X XGameColor.blue = b;
X
X if (XAllocColor(XGameDisplay,XGameColormap, &XGameColor) == 0) {
X fprintf(stderr, "can't allocate color\n");
X exit(1);
X };
X
X return(XGameColor.pixel);
X}
X
Xget_tile() {
X int i, j;
X
X i = random_next()%TILES;
X j = ((random_next()%2) == 0) ? 1 : -1;
X
X/*
X * Walk through the tile pool looking for an unused tile
X */
X while (buffer[i] == 0) {
X i = (i+j)%TILES;
X if (i < 0) i = TILES-1;
X };
X
X j = buffer[i];
X buffer[i] = 0;
X
X return(j);
X}
X
END_OF_initial.c
if test 19579 -ne `wc -c <initial.c`; then
echo shar: \"initial.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f packet.c -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"packet.c\"
else
echo shar: Extracting \"packet.c\" \(3553 characters\)
sed "s/^X//" >packet.c <<'END_OF_packet.c'
X/*
X ******************************************************************************
X * *
X * Copyright (c) 1990 by Jeff S. Young. All rights reserved under the *
X * copyright laws of the United States. *
X * *
X ******************************************************************************
X */
X
X#include <stdio.h>
X#include <signal.h>
X#include <sys/time.h>
X#include <sys/types.h>
X#include <sys/socket.h>
X#include <X11/Xlib.h>
X#include <X11/Xutil.h>
X#include <netinet/in.h>
X#include "xmahjongg.h"
X#include "variables.h"
X
Xpacket_send(type)
Xint type;
X{
X int i;
X int packetlen = sizeof(Packet);
X char ascii[24];
X
X if (tourn_flag == 0) return(0);
X i = mypp->done;
X
X/*
X * Update the information on my board
X */
X if (type == GAME_START) {
X mypp->done++;
X mypp->tiles[mypp->done] = TILES;
X mypp->board[mypp->done] = seed;
X if ((i >= 0) && (mypp->tiles[i] > 0)) mypp->tiles[i] *= -1;
X draw_user(mypp, GAME_START);
X } else if (type == GAME_PLAY) {
X mypp->total -= 2;
X mypp->tiles[i] = tiles_remaining;
X draw_user(mypp, GAME_PLAY);
X } else if (type == GAME_DONE) {
X if (mypp->tiles[i] > 0) mypp->tiles[i] *= -1;
X draw_user(mypp, GAME_DONE);
X } else if (type == GAME_QUIT) {
X draw_user(mypp, GAME_QUIT);
X } else {
X fprintf(stderr, "bad packet type = %d\n", type);
X exit(1);
X };
X
X/*
X * Send the information to the other players
X */
X packet.type = htons(type);
X packet.port = htons(mypp->port);
X packet.tiles = htons(tiles_remaining);
X packet.board = htonl(seed);
X strcpy(packet.name, mypp->name);
X
X for (i = 0, pp = player; i < num_players; i++, pp++) {
X if ((pp->fd < 0) || (pp->type == 'M')) continue;
X if (write(pp->fd, (char *)&packet, packetlen) != packetlen) {
X fprintf(stderr, "can't send to %s\n", pp->name);
X playfds ^= (1 << pp->fd);
X close(pp->fd);
X pp->fd = -1;
X };
X };
X
X return(0);
X}
X
Xpacket_recv(fd)
Xint fd;
X{
X int i;
X int readfds = 1 << fd;
X int packetlen = sizeof(Packet);
X struct timeval timeout;
X char ascii[32];
X char *cp;
X
X/*
X * Read in the packet which is waiting for us.
X */
X timeout.tv_sec = 0L;
X timeout.tv_usec = 0L;
X
X if (select(maxfds, &readfds, NULL, NULL, &timeout) <= 0) {
X return(0);
X } else if ((i = read(fd, (char *)&packet, packetlen)) != packetlen) {
X fprintf(stderr, "can't read from %s\n", pp->name);
X playfds ^= (1 << pp->fd);
X close(pp->fd);
X pp->fd = -1;
X return(0);
X };
X
X/*
X * Find this players structure.
X */
X packet.type = ntohs(packet.type);
X packet.port = ntohs(packet.port);
X packet.tiles = ntohs(packet.tiles);
X packet.board = ntohl(packet.board);
X
X for (i = 0, pp = player; i < num_players; i++, pp++) {
X if (pp->port == packet.port) break;
X };
X
X if (i == num_players) {
X fprintf(stderr, "****** BAD PACKET ******\n");
X fprintf(stderr, "packet name = %s port=%d\n",
X packet.name, packet.port);
X return(0);
X };
X
X i = pp->done;
X
X switch (packet.type) {
X case GAME_START:
X pp->done++;
X pp->board[i+1] = packet.board;
X pp->tiles[i+1] = packet.tiles;
X if ((i >= 0) && (pp->tiles[i] > 0)) pp->tiles[i] *= -1;
X draw_user(pp, GAME_START);
X break;
X case GAME_PLAY:
X pp->total -= 2;
X pp->tiles[i] = packet.tiles;
X draw_user(pp, GAME_PLAY);
X break;
X case GAME_DONE:
X if (pp->tiles[i] > 0) pp->tiles[i] *= -1;
X draw_user(pp, GAME_DONE);
X break;
X case GAME_QUIT:
X pp->tiles[i] = -packet.tiles;
X pp->quit = 1;
X draw_user(pp, GAME_QUIT);
X playfds ^= (1 << pp->fd);
X close(pp->fd);
X pp->fd = -1;
X break;
X default:
X fprintf(stderr, "bad switch (%d)\n", packet.type);
X exit(1);
X break;
X };
X
X return(0);
X}
END_OF_packet.c
if test 3553 -ne `wc -c <packet.c`; then
echo shar: \"packet.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f play.c -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"play.c\"
else
echo shar: Extracting \"play.c\" \(7196 characters\)
sed "s/^X//" >play.c <<'END_OF_play.c'
X/*
X ******************************************************************************
X * *
X * Copyright (c) 1990 by Jeff S. Young. All rights reserved under the *
X * copyright laws of the United States. *
X * *
X ******************************************************************************
X */
X
X#include <stdio.h>
X#include <sys/time.h>
X#include <X11/Xlib.h>
X#include <X11/Xutil.h>
X#include "xmahjongg.h"
X#include "variables.h"
X
Xextern int initial_flag;
Xint x_dist[] = { 0, -1, 1, 0, -1, 1, -1, 0, 1, -1, 0, 1, -1, 0, 1};
Xint y_dist[] = { 2, 2, 2, -2, -2, -2, -1, -1, -1, 0, 0, 0, 1, 1, 1};
Xint z_dist[] = { 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1};
X
Xplay_tile(tp)
XTile *tp;
X{
X
X if (not_free(tp->row, tp->col, tp->lev)) {
X XBell(XGameDisplay, 100);
X XFlush(XGameDisplay);
X } else if (tile1p == NULL) {
X invert_tile(tp, 1);
X tile1p = tp;
X } else if (tp == tile1p) {
X invert_tile(tp, 0);
X tile1p = NULL;
X } else if (tp->type == tile1p->type) {
X tiles_remaining -= 2;
X remove_tile(tile1p);
X remove_tile(tp);
X tile1p = NULL;
X draw_count();
X draw_matches();
X if (done_count == 0) packet_send(GAME_PLAY);
X } else {
X XBell(XGameDisplay, 100);
X XFlush(XGameDisplay);
X };
X
X return(0);
X}
X
Xinvert_tile(tp, type)
XTile *tp;
Xint type;
X{
X
X redraw_tile(tp, type);
X XFlush(XGameDisplay);
X
X return(0);
X}
X
Xremove_tile(tp)
XTile *tp;
X{
X
X tp->state = FREE;
X redraw_tile(tp, 0);
X XFlush(XGameDisplay);
X
X return(0);
X}
X
Xcreate_tile(tp)
XTile *tp;
X{
X int i, j;
X int dx, dy, dz;
X
X for (i = 0; i < TILES; i++) {
X if (order[i] == NULL) break;
X
X dx = order[i]->row - tp->row;
X dy = order[i]->col - tp->col;
X dz = order[i]->lev - tp->lev;
X
X if (dz < 0) continue;
X
X if (dz > 0) break;
X if (dy < dx) break;
X if ((dy == dx) && (dy > 0)) break;
X };
X
X for (j = TILES - tiles_remaining; j > i; j--) {
X order[j] = order[j-1];
X };
X
X order[i] = tp;
X tiles_remaining--;
X draw_count();
X
X tp->data = tp->lev;
X tp->state = USED;
X redraw_tile(tp, 0);
X XFlush(XGameDisplay);
X
X return(0);
X}
X
Xdelete_tile(tp)
XTile *tp;
X{
X int i, j;
X
X for (i = 0; i < TILES; i++) {
X if (order[i] == NULL) break;
X if (order[i]->row != tp->row) continue;
X if (order[i]->col != tp->col) continue;
X if (order[i]->lev != tp->lev) continue;
X
X for (j = i; j < TILES-1; j++) {
X order[j] = order[j+1];
X };
X
X order[TILES-1] = 0;
X break;
X };
X
X tiles_remaining++;
X draw_count();
X
X tp->state = FREE;
X redraw_tile(tp, 0);
X XFlush(XGameDisplay);
X
X return(0);
X}
X
Xredraw_tile(tp, type)
XTile *tp;
Xint type;
X{
X int x_src, y_src;
X int x_dst, y_dst;
X int row, col, lev;
X int i, j, k, l, x, y, rv;
X char string[4];
X Tile *xp[144];
X GC gc;
X
X/*
X * Copy the tiles into the pixmap and then dump the pixmap into
X * the window.
X */
X row = tp->row;
X col = tp->col;
X lev = tp->lev;
X
X string[0] = 127;
X string[1] = 127;
X string[2] = 127;
X XDrawImageString(XGameDisplay, XGamePixmap, XGameOtherGC[0],
X 0, 0*TILE_SIDE, string, 3);
X XDrawImageString(XGameDisplay, XGamePixmap, XGameOtherGC[0],
X 0, 1*TILE_SIDE, string, 3);
X XDrawImageString(XGameDisplay, XGamePixmap, XGameOtherGC[0],
X 0, 2*TILE_SIDE, string, 3);
X
X l = load_tiles(xp, row, col);
X
X for (i = 0; i < l; i++) {
X rv = (xp[i] == tp) ? type : 0;
X k = (color_type == 0) ? xp[i]->lev : (xp[i]->data/16) - 1;
X
X string[0] = xp[i]->data;
X x = (xp[i]->col + 2-col)*(TILE_SIDE/2) + 4*xp[i]->lev;
X y = (xp[i]->row + 2-row)*(TILE_SIDE/2) - 4*xp[i]->lev;
X XDrawImageString(XGameDisplay, XGamePixmap,
X XGameTileGC[k][rv], x, y, string, 1);
X
X draw_border(x, y);
X };
X
X x_src = TILE_SIDE + 4*(lev-1);
X y_src = TILE_SIDE - 4*(lev-0);
X x_dst = tp->x - 4;
X y_dst = tp->y + 0;
X
X XCopyArea(XGameDisplay, XGamePixmap, XGamePlayWindow, XGameTextGC[0],
X x_src, y_src, TILE_SIDE+4, TILE_SIDE+4, x_dst, y_dst);
X
X return(0);
X}
X
Xnot_free(row, col, lev)
Xint row, col, lev;
X{
X int i, mask;
X int r1, c1, l1;
X
X for (i = 0, mask = 0; i < 15; i++) {
X r1 = row+x_dist[i];
X c1 = col+y_dist[i];
X l1 = lev+z_dist[i];
X if ((r1 < 0) || (r1 >= ROWS)) continue;
X if ((c1 < 0) || (c1 >= COLS)) continue;
X if ((l1 < 0) || (l1 >= LEVS)) continue;
X
X if (tiles[r1][c1][l1].state == USED) {
X mask |= (1 << i);
X };
X };
X
X if ((mask & 077700) != 0) {
X return(1);
X } else if ((mask & 000070) == 0) {
X return(0);
X } else if ((mask & 000007) != 0) {
X return(1);
X } else {
X return(0);
X };
X}
X
Xload_tiles(xp, row, col)
XTile *xp[];
Xint row;
Xint col;
X{
X register int i, m;
X register int dx, dy;
X register Tile *tp;
X
X m = 0;
X
X for (i = 0, tp = order[0]; i < TILES; i++, tp = order[i]) {
X if (tp == NULL) break;
X if (tp->state != USED) continue;
X
X dx = tp->row - row;
X dy = tp->col - col;
X
X if (dx < 0) dx = -dx;
X if (dy < 0) dy = -dy;
X
X if ((dx <= 2) && (dy <= 2)) xp[m++] = tp;
X };
X
X return(m);
X}
X
Xok_below(x, y, z)
Xint x;
Xint y;
Xint z;
X{
X int i, j, k;
X
X/*
X * Check this level to be sure that this tile will not overlap another
X * tile.
X */
X for (i = x-1; i <= x+1; i++) {
X for (j = y-1; j <= y+1; j++) {
X if ((i < 0) || (i >= ROWS)) continue;
X if ((j < 0) || (j >= COLS)) continue;
X if ((i == x) && (j == y)) continue;
X if (tiles[i][j][z].state == USED) return(-1);
X };
X };
X
X if (z == 0) return(0);
X
X/*
X * Check the level below this tile to be sure that all four quadrants are
X * covered.
X */
Xquadrant1:
X if (tiles[x-1][y-1][z-1].state == USED) goto quadrant2;
X if (tiles[x-1][y-0][z-1].state == USED) goto quadrant2;
X if (tiles[x-0][y-1][z-1].state == USED) goto quadrant2;
X if (tiles[x-0][y-0][z-1].state == USED) goto quadrant2;
X return(-1);
X
Xquadrant2:
X if (tiles[x-1][y-0][z-1].state == USED) goto quadrant3;
X if (tiles[x-1][y+1][z-1].state == USED) goto quadrant3;
X if (tiles[x-0][y-0][z-1].state == USED) goto quadrant3;
X if (tiles[x-0][y+1][z-1].state == USED) goto quadrant3;
X return(-1);
X
Xquadrant3:
X if (tiles[x-0][y-1][z-1].state == USED) goto quadrant4;
X if (tiles[x-0][y-0][z-1].state == USED) goto quadrant4;
X if (tiles[x+1][y-1][z-1].state == USED) goto quadrant4;
X if (tiles[x+1][y-0][z-1].state == USED) goto quadrant4;
X return(-1);
X
Xquadrant4:
X if (tiles[x-0][y-0][z-1].state == USED) goto quadrant5;
X if (tiles[x-0][y+1][z-1].state == USED) goto quadrant5;
X if (tiles[x+1][y-0][z-1].state == USED) goto quadrant5;
X if (tiles[x+1][y+1][z-1].state == USED) goto quadrant5;
X return(-1);
X
Xquadrant5:
X return(0);
X}
X
Xok_above(x, y, z)
Xint x;
Xint y;
Xint z;
X{
X int i, j, k;
X
X if (z == (LEVS-1)) return(0);
X
X/*
X * Check the level above this tile to be sure that all four quadrants are
X * free.
X */
X for (i = -1; i <= 1; i++) {
X for (j = -1; j <= 1; j++) {
X if (((x+i) < 0) || ((x+i) >= ROWS)) continue;
X if (((y+j) < 0) || ((y+j) >= COLS)) continue;
X if (tiles[x+i][y+i][z+1].state == USED) return(-1);
X };
X };
X
X/*
X if (tiles[x-1][y-1][z+1].state == USED) return(-1);
X if (tiles[x-1][y-0][z+1].state == USED) return(-1);
X if (tiles[x-1][y+1][z+1].state == USED) return(-1);
X
X if (tiles[x-0][y-1][z+1].state == USED) return(-1);
X if (tiles[x-0][y-0][z+1].state == USED) return(-1);
X if (tiles[x-0][y+1][z+1].state == USED) return(-1);
X
X if (tiles[x+1][y-1][z+1].state == USED) return(-1);
X if (tiles[x+1][y-0][z+1].state == USED) return(-1);
X if (tiles[x+1][y+1][z+1].state == USED) return(-1);
X*/
X
X return(0);
X}
END_OF_play.c
if test 7196 -ne `wc -c <play.c`; then
echo shar: \"play.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f random.c -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"random.c\"
else
echo shar: Extracting \"random.c\" \(1155 characters\)
sed "s/^X//" >random.c <<'END_OF_random.c'
X/*
X ******************************************************************************
X * *
X * Copyright (c) 1990 by Jeff S. Young. All rights reserved under the *
X * copyright laws of the United States. *
X * *
X ******************************************************************************
X */
X
X#include <stdio.h>
X#include <sys/time.h>
X
X#define POLY_SIZE 31
X#define TAP_1 0
X#define TAP_2 3
X#define TAP_3 POLY_SIZE
X
Xlong poly[POLY_SIZE+1];
Xlong *p1 = &poly[TAP_1];
Xlong *p2 = &poly[TAP_2];
Xlong *p3 = &poly[TAP_3];
X
Xlong random_init(x)
Xint x;
X{
X int i;
X
X poly[0] = x;
X for (i = 1; i < POLY_SIZE; i++) {
X poly[i] = 3234846615*poly[i-1] + 47027;
X };
X
X p1 = &poly[TAP_1];
X p2 = &poly[TAP_2];
X p3 = &poly[TAP_3];
X
X for (i = 0; i < 2*POLY_SIZE; i++) {
X random();
X };
X
X return(0L);
X}
X
Xlong random_next()
X{
X long x;
X
X *p3 = (*p2 + *p1);
X x = (*p3 >> 1) & 0x7fffffff;
X
X if (p3 == &poly[POLY_SIZE]) {
X p3 = poly;
X p2++;
X p1++;
X } else if (p2 == &poly[POLY_SIZE]) {
X p3++;
X p2 = poly;
X p1++;
X } else if (p1 == &poly[POLY_SIZE]) {
X p3++;
X p2++;
X p1 = poly;
X } else {
X p3++;
X p2++;
X p1++;
X };
X
X return(x);
X}
END_OF_random.c
if test 1155 -ne `wc -c <random.c`; then
echo shar: \"random.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f sysdep.c -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"sysdep.c\"
else
echo shar: Extracting \"sysdep.c\" \(2001 characters\)
sed "s/^X//" >sysdep.c <<'END_OF_sysdep.c'
X/*
X ******************************************************************************
X * *
X * Copyright (c) 1990 by Jeff S. Young. All rights reserved under the *
X * copyright laws of the United States. *
X * *
X ******************************************************************************
X */
X
X#ifndef VMS
X
X#include <pwd.h>
X#include <stdio.h>
X#include <string.h>
X#include <sys/time.h>
X#include <X11/Xlib.h>
X#include <X11/Xutil.h>
X#include "xmahjongg.h"
X#include "variables.h"
X
Xget_user(name)
Xchar *name;
X{
X struct passwd *pwp;
X
X if ((pwp = getpwuid(getuid())) == NULL) {
X fprintf(stderr, "can't getpwuid\n");
X exit(1);
X } else {
X strcpy(name, pwp->pw_name);
X };
X
X return(0);
X}
X
Xget_seed()
X{
X struct timeval tv;
X struct timezone tz;
X
X if (seed == 0) {
X gettimeofday(&tv, &tz);
X seed = 1 + (tv.tv_sec%100000);
X } else if (seed < 0) {
X seed = (-seed)%100000;
X } else {
X seed = 1 + (random_next(seed)%100000);
X };
X
X return(0);
X}
X
Xevent_wait()
X{
X int readfds;
X
X/*
X * If there are no events pending, then sleep until one occurs.
X */
X while (XEventsQueued(XGameDisplay, QueuedAfterReading) == 0) {
X readfds = (1 << XGameFD) | playfds;
X select(maxfds, &readfds, NULL, NULL, NULL);
X
X if ((readfds & playfds) != 0) {
X event_packet(readfds);
X };
X };
X
X return(0);
X}
X
X#else
X
X#include <stdio.h>
X#include <string.h>
X#include <sys/time.h>
X#include <X11/Xlib.h>
X#include <X11/Xutil.h>
X#include "xmahjongg.h"
X#include "variables.h"
X
X
Xget_user(name)
Xchar *name;
X{
X
X if (cuserid(name) == NULL) {
X fprintf(stderr, "can't cuserid\n");
X exit(1);
X };
X
X return(0);
X}
X
Xget_seed()
X{
X struct tm *tv;
X time_t clock_time;
X
X if (seed == 0) {
X time(&clock_time);
X tv = localtime(&clock_time);
X seed = 1 + (tv->tm_sec%100000);
X } else if (seed < 0) {
X seed = (-seed)%100000;
X } else {
X seed = 1 + (random_next(seed)%100000);
X };
X
X return(0);
X}
X
Xevent_wait()
X{
X
X/*
X * Since VMS doesn't have tournament mode, this is really a dummy
X * routine.
X */
X
X return(0);
X}
X
X#endif
END_OF_sysdep.c
if test 2001 -ne `wc -c <sysdep.c`; then
echo shar: \"sysdep.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f variables.c -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"variables.c\"
else
echo shar: Extracting \"variables.c\" \(567 characters\)
sed "s/^X//" >variables.c <<'END_OF_variables.c'
X/*
X ******************************************************************************
X * *
X * Copyright (c) 1990 by Jeff S. Young. All rights reserved under the *
X * copyright laws of the United States. *
X * *
X ******************************************************************************
X */
X
X#ifdef GLOBAL
X#undef GLOBAL
X#endif
X#define GLOBAL
X
X#include <pwd.h>
X#include <stdio.h>
X#include <string.h>
X#include <X11/Xlib.h>
X#include <X11/Xutil.h>
X#include "xmahjongg.h"
X#include "variables.h"
X
Xvariables()
X{
X
X return(0);
X}
END_OF_variables.c
if test 567 -ne `wc -c <variables.c`; then
echo shar: \"variables.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f xmahjongg.c -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"xmahjongg.c\"
else
echo shar: Extracting \"xmahjongg.c\" \(3724 characters\)
sed "s/^X//" >xmahjongg.c <<'END_OF_xmahjongg.c'
X/*
X ******************************************************************************
X * *
X * Copyright (c) 1990 by Jeff S. Young. All rights reserved under the *
X * copyright laws of the United States. *
X * *
X ******************************************************************************
X */
X
X#include <stdio.h>
X#include <string.h>
X#include <X11/Xlib.h>
X#include <X11/Xutil.h>
X#include "xmahjongg.h"
X#include "variables.h"
X
Xmain(argc, argv)
Xint argc;
Xchar *argv[];
X{
X
X get_parameters(argc, argv);
X
X while(1) {
X initialize();
X keep_playing = 1;
X packet_send(GAME_START);
X
X while(keep_playing != 0) {
X event_process();
X };
X };
X}
X
Xget_parameters(argc, argv)
Xint argc;
Xchar *argv[];
X{
X int i, j, c;
X char username[32];
X char *cp, hostname[HOSTNAMELEN];
X Player tmp, *pp = player;
X
X/*
X * Parse the arguments.
X */
X layout = NULL;
X tile_font = TILE_FONT;
X
X while ((c = getopt(argc, argv, "icrsb:d:f:l:n:p:")) != EOF) {
X switch (c) {
X case 'b':
X seed = -atoi(optarg);
X break;
X case 'c':
X color_type = 1;
X break;
X case 'd':
X display_name = optarg;
X break;
X case 'f':
X tile_font = optarg;
X break;
X case 'i':
X iconic_start = 1;
X break;
X case 'l':
X layout = optarg;
X break;
X case 'n':
X num_games = atoi(optarg);
X break;
X case 'p':
X tourn_flag = 1;
X cp = strchr(optarg, '@');
X if (cp == NULL) usage(BAD_USERNAME);
X strncpy(pp->name, optarg, cp-optarg);
X strcpy(pp->machine, cp+1);
X num_players++;
X pp++;
X break;
X case 'r':
X reverse_video = 1;
X break;
X case 's':
X setup_flag = 1;
X break;
X default:
X usage(NULL);
X break;
X };
X };
X
X/*
X * Check to see if we are in setup mode. If we are only certain param-
X * eters are valid.
X */
X if (setup_flag != 0) {
X if (seed < 0) usage(BAD_SEED);
X if (num_games != 0) usage(BAD_GAMES);
X if (tourn_flag != 0) usage(BAD_TOURN);
X if (color_type != 0) usage(BAD_COLOR);
X
X return(0);
X };
X
X/*
X * Set up the tournament if requested.
X */
X if (num_players == 0) return(0);
X if (num_games == 0) num_games = 3;
X
X get_user(username);
X gethostname(hostname, sizeof(hostname));
X mypp = &player[num_players++];
X strcpy(mypp->name, username);
X strcpy(mypp->machine, hostname);
X
X for (i = 0; i < num_players-1; i++) {
X for (j = i+1; j < num_players; j++) {
X if (strcmp(player[i].name, player[j].name) > 0) {
X tmp = player[i];
X player[i] = player[j];
X player[j] = tmp;
X };
X };
X
X };
X
X for (i = 0; i < num_players; i++) {
X player[i].x = X_SCORE;
X player[i].y = Y_SCORE+15*i;
X player[i].port = XPORT+i;
X player[i].done = -1;
X player[i].total = 144*num_games;
X
X for (j = 0; j < MAX_BOARDS; j++) {
X player[i].tiles[j] = 2*TILES;
X };
X
X if (strcmp(player[i].name, username) < 0) {
X player[i].type = 'C';
X } else if (strcmp(player[i].name, username) > 0) {
X player[i].type = 'A';
X } else {
X mypp = &player[i];
X player[i].type = 'M';
X };
X };
X
X return(0);
X}
X
Xusage(s)
Xchar *s;
X{
X
X if (s != NULL) fprintf(stderr, "xmahjongg: %s\n\n", s);
X
X fprintf(stderr, "xmahjongg \n");
X fprintf(stderr, " [-b #] - board number\n");
X fprintf(stderr, " [-c] - color tiles by group\n");
X fprintf(stderr, " [-d display] - display name\n");
X fprintf(stderr, " [-f fontname] - font name\n");
X fprintf(stderr, " [-i] - iconic start\n");
X fprintf(stderr, " [-l file] - board layout file\n");
X fprintf(stderr, " [-n #] - # of games (tournament)\n");
X fprintf(stderr, " [-p nx at mx] - another player\n");
X fprintf(stderr, " [-r] - reverse video\n");
X fprintf(stderr, " [-s] - setup mode\n");
X exit(1);
X}
END_OF_xmahjongg.c
if test 3724 -ne `wc -c <xmahjongg.c`; then
echo shar: \"xmahjongg.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of archive 1 \(of 5\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 2 3 4 5 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 5 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
dan
----------------------------------------------------
O'Reilly && Associates argv at sun.com / argv at ora.com
Opinions expressed reflect those of the author only.
More information about the Comp.sources.x
mailing list