From 35f405581191a23babc3d8657e65e37d3b43763b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Romain=20Tarti=C3=A8re?= Date: Wed, 14 Feb 2018 08:08:49 +0000 Subject: [PATCH] Resurrect, unbreak and modernize games/xroach Submitter is also taking maintainership. PR: 225867 Submitted by: kidon@posteo.de --- games/xroach/Makefile | 32 + games/xroach/distinfo | 3 + games/xroach/files/patch-xroach.c | 1300 +++++++++++++++++++++++++++++ games/xroach/pkg-descr | 4 + 4 files changed, 1339 insertions(+) create mode 100644 games/xroach/Makefile create mode 100644 games/xroach/distinfo create mode 100644 games/xroach/files/patch-xroach.c create mode 100644 games/xroach/pkg-descr diff --git a/games/xroach/Makefile b/games/xroach/Makefile new file mode 100644 index 000000000000..51b11df34688 --- /dev/null +++ b/games/xroach/Makefile @@ -0,0 +1,32 @@ +# Created by: markm +# $FreeBSD$ + +PORTNAME= xroach +PORTVERSION= 4.4 +PORTREVISION= 2 +CATEGORIES= games +MASTER_SITES= https://cyber.dabamos.de/pub/distfiles/ +DISTNAME= ${PORTNAME} + +MAINTAINER= kidon@posteo.de +COMMENT= Cockroaches hide under your windows + +DPADD+= ${LOCALBASE}/lib/libX11.a ${LIBM} +CFLAGS+= -I${LOCALBASE}/include +LDADD+= -L${LOCALBASE}/lib -lX11 -lm + +MANDIR= ${LOCALBASE}/man/man + +BINOWN= bin +BINDIR= ${LOCALBASE}/bin +BINMODE= 755 + +USES= imake +USE_XORG= x11 xext +PLIST_FILES= bin/xroach man/man6/xroach.6.gz + +do-install: + ${INSTALL_PROGRAM} -s ${WRKSRC}/xroach ${STAGEDIR}${PREFIX}/bin + ${INSTALL_MAN} ${WRKSRC}/${PORTNAME}.man ${STAGEDIR}${MAN6PREFIX}/man/man6/${PORTNAME}.6 + +.include diff --git a/games/xroach/distinfo b/games/xroach/distinfo new file mode 100644 index 000000000000..ac409b530077 --- /dev/null +++ b/games/xroach/distinfo @@ -0,0 +1,3 @@ +TIMESTAMP = 1518595646 +SHA256 (xroach.tar.gz) = 819ee19f8c333d9adaa4ab58829445112e1865b85a6ca82296d66399af344e07 +SIZE (xroach.tar.gz) = 21694 diff --git a/games/xroach/files/patch-xroach.c b/games/xroach/files/patch-xroach.c new file mode 100644 index 000000000000..e4fecca608e8 --- /dev/null +++ b/games/xroach/files/patch-xroach.c @@ -0,0 +1,1300 @@ +--- xroach.c.orig 1991-06-06 12:12:07 UTC ++++ xroach.c +@@ -1,23 +1,31 @@ + /* + Xroach - A game of skill. Try to find the roaches under your windows. +- ++ + Copyright 1991 by J.T. Anderson + + jta@locus.com +- ++ + This program may be freely distributed provided that all + copyright notices are retained. + + To build: +- cc -o xroach roach.c -lX11 [-lsocketorwhatever] [-lm] [-l...] ++ cc -o xroach -lX11 -lm -I/usr/local/include/ -L/usr/local/lib xroach.c ++ ++ To run: ++ ./xroach -speed 2 -squish -rc brown -rgc yellowgreen ++ ++ Dedicated to Greg McFarlane (gregm@otc.otca.oz.au). ++ ++ Squish option contributed by Rick Petkiewizc (rick@locus.com). + +- Dedicated to Greg McFarlane. (gregm@otc.otca.oz.au) +- +- Squish option contributed by Rick Petkiewizc (rick@locus.com) +- + Virtual root code adapted from patch sent by Colin Rafferty who +- borrowed it from Tom LaStrange. Several other folks sent similar ++ borrowed it from Tom LaStrange. Several other folks sent similar + fixes. ++ ++ Some glitches removed by patch from Guus Sliepen (guus@sliepen.warande.net) ++ in 2001 (see https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=102668#5). ++ ++ Last update: 2018-JAN-22 + */ + + /* @(#)xroach.c 1.5 4/2/91 11:53:31 */ +@@ -28,17 +36,9 @@ + #include + + #include +-#include +-#include +-#include +- +-#if __STDC__ + #include +-#else +-long strtol(); +-double strtod(); +-char *getenv(); +-#endif ++#include ++#include + + char Copyright[] = "Xroach\nCopyright 1991 J.T. Anderson"; + +@@ -47,30 +47,31 @@ char Copyright[] = "Xroach\nCopyright 19 + typedef unsigned long Pixel; + typedef int ErrorHandler(); + +-#define SCAMPER_EVENT (LASTEvent + 1) ++#define SCAMPER_EVENT (LASTEvent + 1) + + #if !defined(GRAB_SERVER) +-#define GRAB_SERVER 0 ++#define GRAB_SERVER 0 + #endif + ++char *display_name = NULL; + Display *display; +-int screen; +-Window rootWin; +-unsigned int display_width, display_height; +-int center_x, center_y; + GC gc; + GC gutsGC; +-char *display_name = NULL; +-Pixel black, white; ++int screen; ++Pixel black; ++unsigned int display_height; ++unsigned int display_width; ++Window rootWin; + ++Bool squishRoach = False; ++Bool squishWinUp = False; + int done = 0; +-int eventBlock = 0; + int errorVal = 0; +-Bool squishRoach = False; ++int eventBlock = 0; + Pixmap squishMap; +-Bool squishWinUp = False; + +-typedef struct Roach { ++typedef struct Roach ++{ + RoachMap *rp; + int index; + float x; +@@ -86,69 +87,72 @@ Roach *roaches; + int maxRoaches = 10; + int curRoaches = 0; + float roachSpeed = 20.0; ++float turnSpeed = 10.0; + + Region rootVisible = NULL; + + void Usage(); + void SigHandler(); ++Window FindRootWindow(); ++int RandInt(int maxVal); ++int RoachInRect(Roach *roach, int rx, int ry, int x, int y, unsigned int width, unsigned int height); ++int RoachOverRect(Roach *roach, int rx, int ry, int x, int y, unsigned int width, unsigned int height); + void AddRoach(); +-void MoveRoach(); ++void TurnRoach(Roach *roach); ++void MoveRoach(int rx); + void DrawRoaches(); + void CoverRoot(); ++int RoachErrors(XErrorEvent *err); + int CalcRootVisible(); + int MarkHiddenRoaches(); +-Pixel AllocNamedColor(); +-Window FindRootWindow(); ++Pixel AllocNamedColor(char *colorName, Pixel dfltPix); ++void checkSquish(XButtonEvent *buttonEvent); + +-void +-main(ac, av) +-int ac; +-char *av[]; ++int main(int ac, char *av[]) + { +- XGCValues xgcv; +- int ax; + char *arg; +- RoachMap *rp; +- int rx; +- float angle; +- XEvent ev; +- char *roachColor = "black"; + char *gutsColor = NULL; +- int nVis; ++ char *roachColor = "black"; ++ float angle; + int needCalc; ++ int nVis; ++ RoachMap *rp; + Window squishWin; ++ XEvent ev; ++ XGCValues xgcv; + XSetWindowAttributes xswa; +- ++ + /* + Process command line options. + */ +- for (ax=1; axpixmap = XCreateBitmapFromData(display, rootWin, +- rp->roachBits, rp->width, rp->height); +- rp->sine = sin(angle); +- rp->cosine = cos(angle); ++ for (int ax = 0; ax < 360; ax += ROACH_ANGLE) ++ { ++ int rx = ax / ROACH_ANGLE; ++ angle = (float) (rx * 0.261799387799); ++ rp = &roachPix[rx]; ++ rp->pixmap = XCreateBitmapFromData(display, ++ rootWin, ++ rp->roachBits, ++ (unsigned int) rp->width, ++ (unsigned int) rp->height); ++ rp->sine = (float) sin(angle); ++ rp->cosine = (float) cos(angle); + } + + /* + Create the squished pixmap + */ +- if (squishRoach) { +- squishMap = XCreateBitmapFromData(display, rootWin, +- squish_bits, squish_width, squish_height); +- } ++ if (squishRoach) ++ squishMap = XCreateBitmapFromData(display, ++ rootWin, ++ squish_bits, ++ squish_width, ++ squish_height); + +- roaches = (Roach *)malloc(sizeof(Roach) * maxRoaches); ++ roaches = (Roach *) malloc(sizeof(Roach) * maxRoaches); + + gc = XCreateGC(display, rootWin, 0L, &xgcv); + XSetForeground(display, gc, AllocNamedColor(roachColor, black)); + XSetFillStyle(display, gc, FillStippled); + +- if (squishRoach && gutsColor != NULL) { ++ if (squishRoach && gutsColor != NULL) ++ { + gutsGC = XCreateGC(display, rootWin, 0L, &xgcv); + XSetForeground(display, gutsGC, AllocNamedColor(gutsColor, black)); + XSetFillStyle(display, gutsGC, FillStippled); + } + else +- gutsGC = gc; +- ++ { ++ gutsGC = gc; ++ } ++ + while (curRoaches < maxRoaches) +- AddRoach(); +- ++ AddRoach(); ++ + XSelectInput(display, rootWin, ExposureMask | SubstructureNotifyMask); + +- if (squishRoach) { +- xswa.event_mask = ButtonPressMask; +- xswa.override_redirect = True; +- squishWin = XCreateWindow(display, rootWin, 0, 0, +- display_width, display_height, 0, +- CopyFromParent, InputOnly, CopyFromParent, +- CWOverrideRedirect | CWEventMask, &xswa); +- XLowerWindow(display, squishWin); ++ if (squishRoach) ++ { ++ xswa.event_mask = ButtonPressMask; ++ xswa.override_redirect = True; ++ squishWin = XCreateWindow(display, ++ rootWin, ++ 0, 0, ++ display_width, display_height, ++ 0, ++ CopyFromParent, InputOnly, CopyFromParent, ++ CWOverrideRedirect | CWEventMask, ++ &xswa); ++ XLowerWindow(display, squishWin); + } +- ++ + needCalc = 1; +- while (!done) { +- if (XPending(display)) { +- XNextEvent(display, &ev); +- } +- else { +- if (needCalc) { +- needCalc = CalcRootVisible(); +- } +- if (needCalc) +- nVis = 0; +- else +- nVis = MarkHiddenRoaches(); +- if (nVis) { +- ev.type = SCAMPER_EVENT; +- if (!squishWinUp && squishRoach) { +- XMapWindow(display, squishWin); +- squishWinUp = True; +- } +- } +- else { +- if (squishWinUp && squishRoach) { +- XUnmapWindow(display, squishWin); +- squishWinUp = False; +- } +- if (needCalc == 0) +- DrawRoaches(); +- eventBlock = 1; +- XNextEvent(display, &ev); +- eventBlock = 0; +- } +- } +- +- switch (ev.type) { +- +- case SCAMPER_EVENT: +- for (rx=0; rx= 1) { +- rootWin = *newRoot; +- } +- if (newRoot) { +- XFree(newRoot); +- } +- } +- if (rootWin != realRoot) break; ++ XQueryTree(display, ++ rootWin, ++ &rootReturn, ++ &parentReturn, ++ &children, ++ &numChildren); ++ ++ for (int cx = 0; cx < numChildren; cx++) ++ { ++ newRoot = NULL; ++ nItems = 0; ++ ++ if (XGetWindowProperty(display, ++ children[cx], ++ swmVroot, ++ 0, ++ 1, ++ False, ++ XA_WINDOW, ++ &actualType, ++ &actualFormat, ++ &nItems, ++ &bytesAfter, ++ &newRoot) == Success && actualFormat != None) ++ { ++ if (nItems >= 1) ++ rootWin = *newRoot; ++ ++ if (newRoot) ++ XFree(newRoot); ++ } ++ ++ if (rootWin != realRoot) ++ break; + } ++ + XFree(children); +- ++ + return rootWin; + } + + /* + Generate random integer between 0 and maxVal-1. + */ +-int +-RandInt(maxVal) +-int maxVal; ++int RandInt(int maxVal) + { +- return rand() % maxVal; ++ return rand() % maxVal; + } + + /* + Check for roach completely in specified rectangle. + */ +-int +-RoachInRect(roach, rx, ry, x, y, width, height) +-Roach *roach; +-int rx; +-int ry; +-int x; +-int y; +-unsigned int width; +-unsigned int height; ++int RoachInRect(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; +- ++ 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. + */ +-int +-RoachOverRect(roach, rx, ry, x, y, width, height) +-Roach *roach; +-int rx; +-int ry; +-int x; +-int y; +-unsigned int width; +-unsigned int height; ++int RoachOverRect(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; +- ++ 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. + */ +-void +-AddRoach() ++void AddRoach() + { + 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; ++ ++ 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((int) turnSpeed); ++ r->turnLeft = RandInt(100) >= 50; + } + } + + /* + Turn a roach. + */ +-void +-TurnRoach(roach) +-Roach *roach; ++void TurnRoach(Roach *roach) + { +- if (roach->index != (roach->rp - roachPix)) return; ++ 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; ++ 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. + */ +-void +-MoveRoach(rx) +-int rx; ++void MoveRoach(int rx) + { +- Roach *roach; +- Roach *r2; + float newX; + float newY; +- int ii; +- ++ Roach *roach; ++ + 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); +- } ++ if (RoachInRect(roach, ++ (int) newX, (int) newY, ++ 0, 0, ++ display_width, display_height)) ++ { ++ roach->x = newX; ++ roach->y = newY; + +- for (ii=rx+1; iiintX, r2->intY, r2->rp->width, r2->rp->height)) { +- +- TurnRoach(roach); +- } +- } ++ if (roach->steps-- <= 0) ++ { ++ TurnRoach(roach); ++ roach->steps = RandInt((int) turnSpeed); ++ ++ /* ++ Previously, roaches would just go around in circles. ++ This makes their movement more interesting (and disgusting too!). ++ */ ++ if (RandInt(100) >= 80) ++ roach->turnLeft ^= 1; ++ } ++ ++ /* This is a kind of anti-collision algorithm which doesn't do what it is supposed to do, ++ it eats CPU time and sometimes makes roaches spin around very crazy. Therefore it is ++ commented out. ++ ++ for (int ii = rx + 2; ii < curRoaches; ii++) { ++ r2 = &roaches[ii]; ++ ++ if (RoachOverRect(roach, ++ (int) newX, (int) newY, ++ r2->intX, r2->intY, ++ (unsigned int) r2->rp->width, (unsigned int) r2->rp->height)) ++ TurnRoach(roach); ++ ++ } ++ */ + } +- else { +- TurnRoach(roach); ++ else ++ { ++ TurnRoach(roach); + } + } +- ++ + /* + Draw all roaches. + */ +-void +-DrawRoaches() ++void DrawRoaches() + { + Roach *roach; +- int rx; +- +- for (rx=0; rxintX >= 0 && roach->rp != NULL) { +- XClearArea(display, rootWin, roach->intX, roach->intY, +- roach->rp->width, roach->rp->height, False); +- } +- } +- +- for (rx=0; rxhidden) { +- 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); +- } +- else { +- roach->intX = -1; +- } ++ ++ for (int rx = 0; rx < curRoaches; rx++) ++ { ++ roach = &roaches[rx]; ++ ++ if (!roach->hidden) ++ { ++ XClearArea(display, ++ rootWin, ++ roach->intX, ++ roach->intY, ++ (unsigned int) roach->rp->width, ++ (unsigned int) roach->rp->height, ++ False); ++ ++ roach->intX = (int) roach->x; ++ roach->intY = (int) 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, ++ (unsigned int) roach->rp->width, ++ (unsigned int) roach->rp->height); ++ } ++ else ++ { ++ roach->intX = -1; ++ } + } + } + + /* + Cover root window to erase roaches. + */ +-void +-CoverRoot() ++void CoverRoot() + { +- XSetWindowAttributes xswa; + long wamask; + Window roachWin; +- ++ XSetWindowAttributes xswa; ++ + 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); ++ roachWin = XCreateWindow(display, rootWin, ++ 0, 0, ++ display_width, display_height, ++ 0, ++ CopyFromParent, InputOutput, CopyFromParent, ++ (unsigned long) wamask, &xswa); + XLowerWindow(display, roachWin); + XMapWindow(display, roachWin); + XFlush(display); +-} ++} + + #if !GRAB_SERVER +- +-int +-RoachErrors(dpy, err) +-Display *dpy; +-XErrorEvent *err; ++int RoachErrors(XErrorEvent *err) + { + errorVal = err->error_code; +- ++ + return 0; + } +- + #endif /* GRAB_SERVER */ + + /* +- Calculate Visible region of root window. ++ Calculate visible region of root window. + */ +-int +-CalcRootVisible() ++int CalcRootVisible() + { ++ int winX, winY; + Region covered; + Region visible; ++ unsigned int borderWidth; ++ unsigned int depth; ++ unsigned int nChildren; ++ unsigned int winHeight, winWidth; + 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; +- ++ XWindowAttributes wa; ++ + /* + If we don't grab the server, the XGetWindowAttribute or XGetGeometry + calls can abort us. On the other hand, the server grabs can make for +@@ -628,64 +699,83 @@ CalcRootVisible() + Get children of root. + */ + XQueryTree(display, rootWin, &dummy, &dummy, &children, &nChildren); +- ++ + /* + For each mapped child, add the window rectangle to the covered + region. + */ + covered = XCreateRegion(); +- for (wx=0; wx