|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T x
Length: 12861 (0x323d)
Types: TextFile
Names: »xpuzzle.c«
└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987
└─⟦this⟧ »EUUGD18/X/Xpuzzle/xpuzzle.c«
static char SCCSID[] = "@(#)xpuzzle.c 1.1 88/05/31";
/*
* Copyright 1988 by Siemens
* All Rights Reserved
*
* Permission to use, copy, modify and distribute this software is
* hereby granted, provided that this copyright notice appear in all
* copies and that the copyright notice appear in supporting
* documentation.
*
* written Feb 1988 by claus gittinger
* based on puzzletool by Jiang-Hsing Chu (jchu@mimsy.umd.edu)
*
* Email: ...!decvax!unido!athen!claus
*
*/
#include "X11/Xlib.h"
#include <stdio.h>
#include <X11/Xatom.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/cursorfont.h>
/*
* you may have to modify this for your system
*/
#ifndef ATT
# define strchr index
#endif
#define PIECE_COLS 4 /* No of columns of pieces. */
#define PIECE_H 32 /* Number of pixels for height. */
#define PIECE_ROWS 5 /* No of rows of pieces. */
#define PIECE_W 32 /* No of pixels for width. */
#define DISPLAY 30 /* Calculators numerical display. */
#define MAXLINE 80 /* Length of character strings. */
#define TOTAL_HEIGHT (PIECE_ROWS * PIECE_H)
#define TOTAL_WIDTH (PIECE_COLS * PIECE_W)
Display *dpy;
int screen;
GC gc;
Window rootWindow, puzzleWindow;
long FgPixel, BgPixel, BdPixel;
#include "piece0.bit"
#include "piece1.bit"
#include "piece2.bit"
#include "piece3.bit"
#include "icon.bit"
int ncolumn,column ; /* Column number of key pressed. */
int m,n ; /* mouse and index */
int nrow,row ; /* Row number of key pressed. */
int step=0;
#define NPIECES 10
#define EMPTY -1
#define BORDER -2
#define SMALLPIECE 0
#define SMALLPIECE1 (SMALLPIECE+0)
#define SMALLPIECE2 (SMALLPIECE+1)
#define SMALLPIECE3 (SMALLPIECE+2)
#define SMALLPIECE4 (SMALLPIECE+3)
#define VLONGPIECE 4
#define VLONGPIECE1 (VLONGPIECE+0)
#define VLONGPIECE2 (VLONGPIECE+1)
#define VLONGPIECE3 (VLONGPIECE+2)
#define VLONGPIECE4 (VLONGPIECE+3)
#define HLONGPIECE 8
#define BIGPIECE 9
int board[PIECE_ROWS+2][PIECE_COLS+2]= {
{BORDER, BORDER, BORDER, BORDER, BORDER, BORDER},
{BORDER, VLONGPIECE1, BIGPIECE, BIGPIECE, VLONGPIECE2, BORDER},
{BORDER, VLONGPIECE1, BIGPIECE, BIGPIECE, VLONGPIECE2, BORDER},
{BORDER, VLONGPIECE3, HLONGPIECE, HLONGPIECE, VLONGPIECE4, BORDER},
{BORDER, VLONGPIECE3, SMALLPIECE1, SMALLPIECE2, VLONGPIECE4, BORDER},
{BORDER, EMPTY, SMALLPIECE3, SMALLPIECE4, EMPTY, BORDER},
{BORDER, BORDER, BORDER, BORDER, BORDER, BORDER}
};
#define empty(row, col) (board[row][col]==EMPTY)
Pixmap piece0_bitmap = NULL,
piece1_bitmap = NULL,
piece2_bitmap = NULL,
piece3_bitmap = NULL;
struct pieceStruct {
int pType;
int pX, pY;
int pWidth, pHeight;
Pixmap pPixmap;
} pieces[NPIECES] = {
{SMALLPIECE, 2, 4, 1, 1, NULL},
{SMALLPIECE, 3, 4, 1, 1, NULL},
{SMALLPIECE, 2, 5, 1, 1, NULL},
{SMALLPIECE, 3, 5, 1, 1, NULL},
{VLONGPIECE, 1, 1, 1, 2, NULL},
{VLONGPIECE, 4, 1, 1, 2, NULL},
{VLONGPIECE, 1, 3, 1, 2, NULL},
{VLONGPIECE, 4, 3, 1, 2, NULL},
{HLONGPIECE, 2, 3, 2, 1, NULL},
{BIGPIECE, 2, 1, 2, 2, NULL}
};
#define pieceType(p) (pieces[p].pType)
#define pieceX(p) ((pieces[p].pX-1)*PIECE_W)
#define pieceY(p) ((pieces[p].pY-1)*PIECE_H)
#define pieceWidth(p) (pieces[p].pWidth*PIECE_W)
#define pieceHeight(p) (pieces[p].pHeight*PIECE_H)
#define piecePixmap(p) (pieces[p].pPixmap)
main(argc,argv)
int argc ;
char *argv[] ;
{
int i;
Visual visual;
XGCValues xgcv;
XSetWindowAttributes xswa;
XSizeHints sizehints;
char *ProgName, *server, *geom, *borderColor;
char *foreGround, *backGround;
int borderWidth = 1;
server = "";
geom = "";
borderColor = "black";
foreGround = "black";
backGround = "white";
ProgName = argv[0];
/********************************/
/** parse command line options **/
/********************************/
for (i=1; i<argc; i++) {
if (argv[i][0] == '=')
geom = argv[i];
else if (strchr(argv[i],':') != NULL)
server = argv[i];
else if (strcmp(argv[i], "-fg") == 0)
foreGround = argv[++i];
else if (strcmp(argv[i], "-bg") == 0)
backGround = argv[++i];
else if (strcmp(argv[i], "-bd") == 0)
borderColor = argv[++i];
else if (strcmp(argv[i], "-bw") == 0)
sscanf(argv[++i], "%d", &borderWidth);
else
usage(ProgName);
}
dpy = XOpenDisplay(server);
if (dpy == NULL) {
fprintf(stderr, "can't open display \"%s\"\n",server);
exit(1);
}
screen = DefaultScreen(dpy);
FgPixel = requestColor(foreGround);
BgPixel = requestColor(backGround);
BdPixel = requestColor(borderColor);
/*************************************/
/** configure the window size hints **/
/*************************************/
sizehints.flags = PMinSize | PMaxSize | PPosition | PSize;
sizehints.min_width = TOTAL_WIDTH;
sizehints.min_height = TOTAL_HEIGHT;
sizehints.max_width = TOTAL_WIDTH;
sizehints.max_height = TOTAL_HEIGHT;
sizehints.width = TOTAL_WIDTH;
sizehints.height = TOTAL_HEIGHT;
sizehints.x = 100;
sizehints.y = 300;
if (geom && strlen(geom)) {
int width, height, flags;
flags = XParseGeometry(geom, &sizehints.x, &sizehints.y,
&width, &height);
if (flags & (XValue | YValue))
sizehints.flags |= USPosition;
}
/*******************************************************************/
/** create the puzzle main window and set its standard properties **/
/*******************************************************************/
xswa.event_mask = ExposureMask | ButtonPressMask |
ButtonReleaseMask | KeyPressMask;
xswa.background_pixel = BgPixel;
xswa.border_pixel = BdPixel;
xswa.cursor = XCreateFontCursor(dpy, XC_hand1);
visual.visualid = CopyFromParent;
rootWindow = RootWindow(dpy, screen);
puzzleWindow = XCreateWindow(dpy, rootWindow,
sizehints.x, sizehints.y,
sizehints.width, sizehints.height,
borderWidth,
DefaultDepth(dpy,screen),
InputOutput,
&visual,
CWCursor | CWEventMask | CWBackPixel | CWBorderPixel,
&xswa);
/*******************************************************************/
/** define its name and icon-bitmap **/
/*******************************************************************/
XSetStandardProperties(dpy, puzzleWindow, "puzzle","Puzzle",
XCreateBitmapFromData(dpy, rootWindow,
icon_bits,
icon_width, icon_height),
argv, argc, &sizehints);
XMapWindow(dpy, puzzleWindow);
xgcv.foreground = FgPixel;
xgcv.background = BgPixel;
xgcv.line_width = 0;
gc = XCreateGC(dpy, puzzleWindow,
GCForeground|GCBackground|GCLineWidth,
&xgcv);
make_bitmaps();
eventloop();
exit(0) ;
}
make_bitmaps() {
int p;
piece0_bitmap = XCreateBitmapFromData(dpy, rootWindow,
piece0_bits, piece0_width, piece0_height);
piece1_bitmap = XCreateBitmapFromData(dpy, rootWindow,
piece1_bits, piece1_width, piece1_height);
piece2_bitmap = XCreateBitmapFromData(dpy, rootWindow,
piece2_bits, piece2_width, piece2_height);
piece3_bitmap = XCreateBitmapFromData(dpy, rootWindow,
piece3_bits, piece3_width, piece3_height);
if (piece0_bitmap==NULL || piece1_bitmap==NULL ||
piece2_bitmap==NULL ||
piece3_bitmap==NULL) {
fprintf(stderr, "cannot allocated bitmaps\n");
finish();
}
for (p=SMALLPIECE1; p <= SMALLPIECE4; p++)
pieces[p].pPixmap = piece0_bitmap;
for (p=VLONGPIECE1; p <= VLONGPIECE4; p++)
pieces[p].pPixmap = piece1_bitmap;
pieces[HLONGPIECE].pPixmap = piece2_bitmap;
pieces[BIGPIECE].pPixmap = piece3_bitmap;
}
finish() {
if (piece0_bitmap != NULL)
XFreePixmap(dpy, piece0_bitmap);
if (piece1_bitmap != NULL)
XFreePixmap(dpy, piece1_bitmap);
if (piece2_bitmap != NULL)
XFreePixmap(dpy, piece2_bitmap);
if (piece3_bitmap != NULL)
XFreePixmap(dpy, piece3_bitmap);
exit(1);
}
usage(name)
char *name;
{
fprintf(stderr, "usage: %s [geometry] [display]\n", name);
fprintf(stderr, " [-fg color] [-bg color]\n");
fprintf(stderr, " [-bd color] [-bw number]\n");
exit(1);
}
requestColor(name)
char *name;
{
XColor truecolor, availcolor;
if (XAllocNamedColor(dpy,
DefaultColormap(dpy, DefaultScreen(dpy)),
name, &availcolor, &truecolor) == 0) {
fprintf(stderr, "Color '%s' unknown\n", name);
exit(1);
}
if (truecolor.red != availcolor.red ||
truecolor.green != availcolor.green ||
truecolor.blue != availcolor.blue) {
fprintf(stderr, "Warning: %s color bay be wrong\n", name);
}
return availcolor.pixel;
}
eventloop() {
XEvent event;
XExposeEvent *ee = (XExposeEvent *)&event;
XKeyPressedEvent *ke = (XKeyPressedEvent *)&event;
XButtonPressedEvent *be = (XButtonPressedEvent *)&event;
char keybuff[10];
int nchar;
while(1) {
XNextEvent(dpy, &event);
switch(event.type) {
case KeyPress:
nchar = XLookupString(ke, keybuff, 1, NULL, NULL);
if (nchar > 0) {
switch (keybuff[0]) {
case 'q':
case 'Q':
finish();
}
}
break;
case ButtonPress:
column = be->x / PIECE_W ;
row = be->y / PIECE_H ;
n = board[row+1][column+1] ;
m=0;
break;
case ButtonRelease:
if (n>=0) {
ncolumn = be->x / PIECE_W;
nrow = be->y / PIECE_H ;
if (! empty(nrow+1, ncolumn+1)) break;
if (ncolumn > column) m=0;
if (nrow<row) m=1;
if (ncolumn<column) m=2;
if (nrow>row) m=3;
do_move();
}
break;
case Expose:
if (! ee->count)
repaint();
break;
default:
break;
}
}
}
repaint() {
int p;
XClearWindow(dpy, puzzleWindow);
for(p=0; p < NPIECES; p++)
XCopyPlane(dpy, piecePixmap(p), puzzleWindow, gc,
0, 0, pieceWidth(p), pieceHeight(p),
pieceX(p), pieceY(p), 1) ;
}
do_move() {
int ox,oy,nx,ny;
ox=pieces[n].pX;
oy=pieces[n].pY;
switch(pieceType(n)){
case SMALLPIECE:
switch(m){
case 0:
if (empty(ny=oy, nx=ox+1)) break;
return;
case 1:
if (empty(ny=oy-1, nx=ox)) break;
return;
case 2:
if (empty(ny=oy, nx=ox-1)) break;
return;
case 3:
if (empty(ny=oy+1, nx=ox)) break;
return;
}
break;
case VLONGPIECE:
switch(m){
case 0:
if (empty(oy, ox+1) && empty(oy+1, ox+1)) {
nx=ox+1; ny=oy;
break;
}
return;
case 1:
if (empty(oy-1, ox)) {
nx=ox; ny=oy-1;
break;
}
return;
case 2:
if (empty(oy, ox-1) && empty(oy+1, ox-1)) {
nx=ox-1; ny=oy;
break;
}
return;
case 3:
if (empty(oy+2, ox)) {
nx=ox; ny=oy+1;
break;
}
return;
}
break;
case HLONGPIECE:
switch(m){
case 0:
if (empty(oy, ox+2)) {
nx=ox+1; ny=oy;
break;
}
return;
case 1:
if (empty(oy-1, ox) && empty(oy-1, ox+1)) {
nx=ox; ny=oy-1;
break;
}
return;
case 2:
if (empty(oy, ox-1)) {
nx=ox-1; ny=oy;
break;
}
return;
case 3:
if (empty(oy+1, ox) && empty(oy+1, ox+1)) {
nx=ox; ny=oy+1;
break;
}
return;
}
break;
case BIGPIECE:
switch(m){
case 0:
if (empty(oy, ox+2) && empty(oy+1, ox+2)) {
nx=ox+1; ny=oy;
break;
}
return;
case 1:
if (empty(oy-1, ox) && empty(oy-1, ox+1)) {
nx=ox; ny=oy-1;
break;
}
return;
case 2:
if (empty(oy, ox-1) && empty(oy+1, ox-1)) {
nx=ox-1; ny=oy;
break;
}
return;
case 3:
if (empty(oy+2, ox) && empty(oy+2, ox+1)) {
nx=ox; ny=oy+1;
break;
}
return;
}
break;
}
#ifdef LATER
{
char display[MAXLINE]; /* Current number of moves display. */
sprintf(display, "%d", ++step);
XDrawImageString(dpy, displayWindow, gc,
0, 0, display, strlen(display));
}
#endif LATER
pieces[n].pX=nx; /* move the piece */
pieces[n].pY=ny;
XClearArea(dpy, puzzleWindow,
(ox-1)*PIECE_W, (oy-1)*PIECE_H,
pieceWidth(n), pieceHeight(n), 0);
switch(pieceType(n)){
case SMALLPIECE:
board[oy][ox]= EMPTY;
board[ny][nx]= n;
break;
case VLONGPIECE:
board[oy][ox]=board[oy+1][ox]= EMPTY;
board[ny][nx]=board[ny+1][nx]=n;
break;
case HLONGPIECE:
board[oy][ox]=board[oy][ox+1]= EMPTY;
board[ny][nx]=board[ny][nx+1]=n;
break;
case BIGPIECE:
board[oy][ox]=board[oy][ox+1]=board[oy+1][ox]=board[oy+1][ox+1]= EMPTY;
board[ny][nx]=board[ny][nx+1]=board[ny+1][nx]=board[ny+1][nx+1]=n;
break;
}
XCopyPlane(dpy, piecePixmap(n), puzzleWindow, gc,
0, 0, pieceWidth(n), pieceHeight(n),
pieceX(n), pieceY(n), 1) ;
}