|
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) ; }