URL
                    https://opencores.org/ocsvn/or1k/or1k/trunk
                
            Subversion Repositories or1k
[/] [or1k/] [trunk/] [mw/] [src/] [demos/] [nxroach/] [nxroach.x] - Rev 1765
Compare with Previous | Blame | View Log
/*Xroach - A game of skill. Try to find the roaches under your windows.Copyright 1991 by J.T. Andersonjta@locus.comThis program may be freely distributed provided that allcopyright notices are retained.To build:cc -o xroach roach.c -lX11 [-lsocketorwhatever] [-lm] [-l...]Dedicated to Greg McFarlane. (gregm@otc.otca.oz.au)*///#include <X11/Xlib.h>//#include <X11/Xutil.h>//#include <X11/Xos.h>#include <stdio.h>#include <math.h>#include <signal.h>#include <stdlib.h>#include <time.h>#define MWINCLUDECOLORS#include "nano-X.h"#include "XtoNX.h"char Copyright[] = "Xroach\nCopyright 1991 J.T. Anderson";#include "roachmap.h"typedef unsigned long Pixel;typedef int ErrorHandler();#define SCAMPER_EVENT 99 // LASTEvent+1?#if !defined(GRAB_SERVER)#define GRAB_SERVER 0#endifSTATIC_FUNCTIONS;Display *display;int screen;Window rootWin;unsigned int display_width, display_height;int center_x, center_y;GC gc;char *display_name = NULL;Pixel black, white;int done = 0;int eventBlock = 0;int errorVal = 0;typedef struct Roach {RoachMap *rp;int index;float x;float y;int intX;int intY;int hidden;int turnLeft;int steps;} Roach;Roach *roaches;int maxRoaches = 10;int curRoaches = 0;float roachSpeed = 20.0;Region rootVisible = 0;void Usage(void);void SigHandler(int sig);void AddRoach(void);void MoveRoach(int Rx);void DrawRoaches(void);void CoverRoot(void);int CalcRootVisible(void);int MarkHiddenRoaches(void);//Pixel AllocNamedColor();intmain(int ac, char **av){//XGCValues xgcv;int ax;char *arg;RoachMap *rp;int rx;float angle;XEvent ev;char *roachColor = "black";int nVis;int needCalc;/*Process command line options.*/for (ax=1; ax<ac; ax++) {arg = av[ax];if (strcmp(arg, "-display") == 0) {display_name = av[++ax];}else if (strcmp(arg, "-rc") == 0) {roachColor = av[++ax];}else if (strcmp(arg, "-speed") == 0) {roachSpeed = atof(av[++ax]);}else if (strcmp(arg, "-roaches") == 0) {maxRoaches = strtol(av[++ax], (char **)NULL, 0);}else {Usage();}}srand((int)time((long *)NULL));/*Catch some signals so we can erase any visible roaches.*/signal(SIGKILL, SigHandler);signal(SIGINT, SigHandler);signal(SIGTERM, SigHandler);signal(SIGHUP, SigHandler);display = XOpenDisplay(display_name);if (display == NULL) {if (display_name == NULL) display_name = getenv("DISPLAY");(void) fprintf(stderr, "%s: cannot connect to server %s\n", av[0],display_name ? display_name : "(default)");exit(1);}screen = DefaultScreen(display);rootWin = RootWindow(display, screen);black = BlackPixel(display, screen);white = WhitePixel(display, screen);display_width = DisplayWidth(display, screen);display_height = DisplayHeight(display, screen);center_x = display_width / 2;center_y = display_height / 2;/*Create roach pixmaps at several orientations.*/for (ax=0; ax<360; ax+=ROACH_ANGLE) {rx = ax / ROACH_ANGLE;angle = rx * 0.261799387799;rp = &roachPix[rx];//rp->pixmap = XCreateBitmapFromData(display, rootWin,//rp->roachBits, rp->width, rp->height);rp->pixmap = XCreatePixmapFromBitmapData(display, rootWin,rp->roachBits, rp->width, rp->height, BLACK, CYAN, 1); //FIXMErp->sine = sin(angle);rp->cosine = cos(angle);}roaches = (Roach *)malloc(sizeof(Roach) * maxRoaches);gc = XCreateGC(display, rootWin, 0L, &xgcv);//XSetForeground(display, gc, AllocNamedColor(roachColor, black));//XSetFillStyle(display, gc, FillStippled);while (curRoaches < maxRoaches)AddRoach();XSelectInput(display, rootWin, ExposureMask | SubstructureNotifyMask);needCalc = 1;while (!done) {if (XPending(display)) {XNextEvent(display, &ev);}else {if (needCalc) {needCalc = CalcRootVisible();}nVis = MarkHiddenRoaches();if (nVis) {ev.type = SCAMPER_EVENT;}else {DrawRoaches();GrDelay(100);eventBlock = 1;XNextEvent(display, &ev);eventBlock = 0;}}switch (ev.type) {case SCAMPER_EVENT:for (rx=0; rx<curRoaches; rx++) {if (!roaches[rx].hidden)MoveRoach(rx);}DrawRoaches();GrDelay(100);XSync(display, False);break;case Expose://case MapNotify://case UnmapNotify:case ConfigureNotify:needCalc = 1;break;}}CoverRoot();XCloseDisplay(display);return 0;}#define USEPRT(msg) fprintf(stderr, msg)voidUsage(void){USEPRT("Usage: nxroach [options]\n\n");USEPRT("Options:\n");USEPRT(" -display displayname\n");USEPRT(" -rc roachcolor\n");USEPRT(" -roaches numroaches\n");USEPRT(" -speed roachspeed\n");exit(1);}voidSigHandler(int sig){/*If we are blocked, no roaches are visible and we can just bailout. If we are not blocked, then let the main procedure cleanup the root window.*/if (eventBlock) {XCloseDisplay(display);exit(0);}else {done = 1;}}/*Generate random integer between 0 and maxVal-1.*/intRandInt(int maxVal){return rand() % maxVal;}/*Check for roach completely in specified rectangle.*/intRoachInRect(roach, rx, ry, x, y, width, height)Roach *roach;int rx;int ry;int x;int y;unsigned int width;unsigned int height;{if (rx < x) return 0;if ((rx + roach->rp->width) > (x + width)) return 0;if (ry < y) return 0;if ((ry + roach->rp->height) > (y + height)) return 0;return 1;}/*Check for roach overlapping specified rectangle.*/intRoachOverRect(roach, rx, ry, x, y, width, height)Roach *roach;int rx;int ry;int x;int y;unsigned int width;unsigned int height;{if (rx >= (x + width)) return 0;if ((rx + roach->rp->width) <= x) return 0;if (ry >= (y + height)) return 0;if ((ry + roach->rp->height) <= y) return 0;return 1;}/*Give birth to a roach.*/voidAddRoach(void){Roach *r;if (curRoaches < maxRoaches) {r = &roaches[curRoaches++];r->index = RandInt(ROACH_HEADINGS);r->rp = &roachPix[r->index];r->x = RandInt(display_width - r->rp->width);r->y = RandInt(display_height - r->rp->height);r->intX = -1;r->intY = -1;r->hidden = 0;r->steps = RandInt(200);r->turnLeft = RandInt(100) >= 50;}}/*Turn a roach.*/voidTurnRoach(roach)Roach *roach;{if (roach->index != (roach->rp - roachPix)) return;if (roach->turnLeft) {roach->index += (RandInt(30) / 10) + 1;if (roach->index >= ROACH_HEADINGS)roach->index -= ROACH_HEADINGS;}else {roach->index -= (RandInt(30) / 10) + 1;if (roach->index < 0)roach->index += ROACH_HEADINGS;}}/*Move a roach.*/voidMoveRoach(int rx){Roach *roach;Roach *r2;float newX;float newY;int ii;roach = &roaches[rx];newX = roach->x + (roachSpeed * roach->rp->cosine);newY = roach->y - (roachSpeed * roach->rp->sine);if (RoachInRect(roach, (int)newX, (int)newY,0, 0, display_width, display_height)) {roach->x = newX;roach->y = newY;if (roach->steps-- <= 0) {TurnRoach(roach);roach->steps = RandInt(200);}for (ii=rx+1; ii<curRoaches; ii++) {r2 = &roaches[ii];if (RoachOverRect(roach, (int)newX, (int)newY,r2->intX, r2->intY, r2->rp->width, r2->rp->height)) {TurnRoach(roach);}}}else {TurnRoach(roach);}}/*Draw all roaches.*/voidDrawRoaches(void){Roach *roach;int rx;for (rx=0; rx<curRoaches; rx++) {roach = &roaches[rx];if (roach->intX >= 0) {XClearArea(display, rootWin, roach->intX, roach->intY,roach->rp->width, roach->rp->height, False);}}for (rx=0; rx<curRoaches; rx++) {roach = &roaches[rx];if (!roach->hidden) {roach->intX = roach->x;roach->intY = roach->y;roach->rp = &roachPix[roach->index];//XSetStipple(display, gc, roach->rp->pixmap);//XSetTSOrigin(display, gc, roach->intX, roach->intY);//XFillRectangle(display, rootWin, gc,//roach->intX, roach->intY, roach->rp->width, roach->rp->height);GrCopyArea(GR_ROOT_WINDOW_ID, gc, roach->intX, roach->intY,roach->rp->width, roach->rp->height, roach->rp->pixmap, 0, 0,MWROP_SRCCOPY);}else {roach->intX = -1;}}}/*Cover root window to erase roaches.*/voidCoverRoot(void){//XSetWindowAttributes xswa;//long wamask;Window roachWin;#define CopyFromParent 0#define InputOutput 0//xswa.background_pixmap = ParentRelative;//xswa.override_redirect = True;//wamask = CWBackPixmap | CWOverrideRedirect;roachWin = XCreateWindow(display, rootWin, 0, 0,display_width, display_height, 0, CopyFromParent,InputOutput, CopyFromParent, wamask, &xswa);XLowerWindow(display, roachWin);XMapWindow(display, roachWin);XFlush(display);}#if !GRAB_SERVER#if 0intRoachErrors(dpy, err)Display *dpy;XErrorEvent *err;{errorVal = err->error_code;return 0;}#endif#endif /* GRAB_SERVER *//*Calculate Visible region of root window.*/intCalcRootVisible(void){Region covered;Region visible;Window *children;int nChildren;Window dummy;//XWindowAttributes wa;int wx;XRectangle rect;int winX, winY;unsigned int winHeight, winWidth;unsigned int borderWidth;unsigned int depth;GR_WINDOW_INFO info;/*If we don't grab the server, the XGetWindowAttribute or XGetGeometrycalls can abort us. On the other hand, the server grabs can make forsome annoying delays.*/#if GRAB_SERVER//XGrabServer(display);#else//XSetErrorHandler(RoachErrors);#endif/*Get children of root.*/XQueryTree(display, rootWin, &dummy, &dummy, &children, &nChildren);/*For each mapped child, add the window rectangle to the coveredregion.*/covered = XCreateRegion();for (wx=0; wx<nChildren; wx++) {//if (XEventsQueued(display, QueuedAlready)) return 1;//errorVal = 0;//XGetWindowAttributes(display, children[wx], &wa);//if (errorVal) continue;GrGetWindowInfo(children[wx], &info);//if (wa.map_state == IsViewable) {if (info.unmapcount == 0) {//XGetGeometry(display, children[wx], &dummy, &winX, &winY,//&winWidth, &winHeight, &borderWidth, &depth);//if (errorVal) continue;rect.x = info.x;rect.y = info.y;//rect.width = winWidth + (borderWidth * 2);//rect.height = winHeight + (borderWidth * 2);rect.width = info.width;rect.height = info.height;XUnionRectWithRegion(&rect, covered, covered);}}XFree((char *)children);#if GRAB_SERVER//XUngrabServer(display);#else//XSetErrorHandler((ErrorHandler *)NULL);#endif/*Subtract the covered region from the root window region.*/visible = XCreateRegion();rect.x = 0;rect.y = 0;rect.width = display_width;rect.height = display_height;XUnionRectWithRegion(&rect, visible, visible);XSubtractRegion(visible, covered, visible);XDestroyRegion(covered);/*Save visible region globally.*/if (rootVisible)XDestroyRegion(rootVisible);rootVisible = visible;/*Mark all roaches visible.*/for (wx=0; wx<curRoaches; wx++)roaches[wx].hidden = 0;return 0;}/*Mark hidden roaches.*/intMarkHiddenRoaches(void){int rx;Roach *r;int nVisible;nVisible = 0;for (rx=0; rx<curRoaches; rx++) {r = &roaches[rx];if (!r->hidden) {if (r->intX > 0 && XRectInRegion(rootVisible, r->intX, r->intY,r->rp->width, r->rp->height) == RectangleOut) {r->hidden = 1;}else {nVisible++;}}}return nVisible;}#if 0/*Allocate a color by name.*/PixelAllocNamedColor(colorName, dfltPix)char *colorName;Pixel dfltPix;{Pixel pix;XColor scrncolor;XColor exactcolor;if (XAllocNamedColor(display, DefaultColormap(display, screen),colorName, &scrncolor, &exactcolor)) {pix = scrncolor.pixel;}else {pix = dfltPix;}return pix;}#endif
