X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=hacks%2Fmaze.c;h=ba80e835e399d43893942063531318d25123831e;hb=3f438031d610c7e15fd33876a879b97e290e05fb;hp=2593f235dad23be6df40b8f27a368a6dc5cfe9f3;hpb=481b95e2617b69e6fd4444432747d7e1e0c3dc85;p=xscreensaver diff --git a/hacks/maze.c b/hacks/maze.c index 2593f235..ba80e835 100644 --- a/hacks/maze.c +++ b/hacks/maze.c @@ -1,6 +1,10 @@ /****************************************************************************** * [ maze ] ... * + * modified: [ 1-04-00 ] Johannes Keukelaar + * Added -ignorant option (not the default) to remove knowlege + * of the direction in which the exit lies. + * * modified: [ 6-28-98 ] Zack Weinberg * * Made the maze-solver somewhat more intelligent. There are @@ -35,7 +39,7 @@ * Added bridge option. * modified: [ 8-11-95 ] Ed James * added fill of dead-end box to solve_maze while loop. - * modified: [ 3-7-93 ] Jamie Zawinski + * modified: [ 3-7-93 ] Jamie Zawinski * added the XRoger logo, cleaned up resources, made * grid size a parameter. * modified: [ 3-3-93 ] Jim Randell @@ -80,21 +84,22 @@ #include "screenhack.h" #include "erase.h" -#define XROGER +#define XSCREENSAVER_LOGO static int solve_delay, pre_solve_delay, post_solve_delay; #include #include #include -#ifndef VMS -# include -#else /* VMS */ -# include "sys$common:[decw$include.bitmaps]gray1.xbm" -#endif /* VMS */ -#define MAX_MAZE_SIZE_X 500 -#define MAX_MAZE_SIZE_Y 500 +/* #include */ +#define gray1_width 2 +#define gray1_height 2 +static char gray1_bits[] = { 0x01, 0x02 }; + + +#define MAX_MAZE_SIZE_X 1000 +#define MAX_MAZE_SIZE_Y 1000 #define MOVE_LIST_SIZE (MAX_MAZE_SIZE_X * MAX_MAZE_SIZE_Y) @@ -129,9 +134,9 @@ static int solve_delay, pre_solve_delay, post_solve_delay; static int logo_x, logo_y; -#ifdef XROGER -# define logo_width 128 -# define logo_height 128 +#ifdef XSCREENSAVER_LOGO +# define logo_width 54 +# define logo_height 54 #else # include # define logo_width xlogo64_width @@ -142,8 +147,8 @@ static int logo_x, logo_y; static unsigned short maze[MAX_MAZE_SIZE_X][MAX_MAZE_SIZE_Y]; static struct { - unsigned char x; - unsigned char y; + unsigned short x; + unsigned short y; unsigned char dir, ways; } move_list[MOVE_LIST_SIZE], save_path[MOVE_LIST_SIZE], path[MOVE_LIST_SIZE]; @@ -159,7 +164,7 @@ static GC gc, cgc, tgc, sgc, ugc, logo_gc, erase_gc; static Pixmap logo_map; static int x = 0, y = 0, restart = 0, stop = 1, state = 1, max_length; -static int sync_p, bridge_p; +static int sync_p, bridge_p, ignorant_p; static int check_events (void) /* X event handler [ rhess ] */ @@ -201,6 +206,9 @@ check_events (void) /* X event handler [ rhess ] */ case Expose: restart = 1; break; + default: + screenhack_handle_event(dpy, &e); + break; } return(1); } @@ -1121,11 +1129,32 @@ draw_maze_border (void) /* draw the maze outline */ Window r; int x, y; unsigned int w, h, bw, d; + + /* round up to grid size */ + int ww = ((logo_width / grid_width) + 1) * grid_width; + int hh = ((logo_height / grid_height) + 1) * grid_height; + XGetGeometry (dpy, logo_map, &r, &x, &y, &w, &h, &bw, &d); - XCopyPlane (dpy, logo_map, win, logo_gc, - 0, 0, w, h, - border_x + 3 + grid_width * logo_x, - border_y + 3 + grid_height * logo_y, 1); + +# ifdef XSCREENSAVER_LOGO + /* kludge: if the logo "hole" is around the same size as the logo, + don't center it (since the xscreensaver logo image is a little + off center... But do center if if the hole/gridsize is large. */ + if (ww < logo_width + 5) ww = w; + if (hh < logo_height + 5) hh = h; +# endif /* XSCREENSAVER_LOGO */ + + if (d == 1) + XCopyPlane (dpy, logo_map, win, logo_gc, + 0, 0, w, h, + border_x + 3 + grid_width * logo_x + ((ww - w) / 2), + border_y + 3 + grid_height * logo_y + ((hh - h) / 2), + 1); + else + XCopyArea (dpy, logo_map, win, logo_gc, + 0, 0, w, h, + border_x + 3 + grid_width * logo_x + ((ww - w) / 2), + border_y + 3 + grid_height * logo_y + ((hh - h) / 2)); } draw_solid_square (start_x, start_y, WALL_TOP >> start_dir, tgc); draw_solid_square (end_x, end_y, WALL_TOP >> end_dir, tgc); @@ -1245,27 +1274,27 @@ draw_solid_square(int i, int j, /* draw a solid square in a square */ switch (dir) { case WALL_TOP: XFillRectangle(dpy, win, gc, - border_x + bw + grid_width * i, - border_y - bw + grid_height * j, - grid_width - (bw+bw), grid_height); + border_x + bw+(bw==0?1:0) + grid_width * i, + border_y - bw-(bw==0?1:0) + grid_height * j, + grid_width - (bw+bw+(bw==0?1:0)), grid_height); break; case WALL_RIGHT: XFillRectangle(dpy, win, gc, - border_x + bw + grid_width * i, - border_y + bw + grid_height * j, - grid_width, grid_height - (bw+bw)); + border_x + bw+(bw==0?1:0) + grid_width * i, + border_y + bw+(bw==0?1:0) + grid_height * j, + grid_width, grid_height - (bw+bw+(bw==0?1:0))); break; case WALL_BOTTOM: XFillRectangle(dpy, win, gc, - border_x + bw + grid_width * i, - border_y + bw + grid_height * j, - grid_width - (bw+bw), grid_height); + border_x + bw+(bw==0?1:0) + grid_width * i, + border_y + bw+(bw==0?1:0) + grid_height * j, + grid_width - (bw+bw+(bw==0?1:0)), grid_height); break; case WALL_LEFT: XFillRectangle(dpy, win, gc, - border_x - bw + grid_width * i, - border_y + bw + grid_height * j, - grid_width, grid_height - (bw+bw)); + border_x - bw-(bw==0?1:0) + grid_width * i, + border_y + bw+(bw==0?1:0) + grid_height * j, + grid_width, grid_height - (bw+bw+(bw==0?1:0))); break; } XSync (dpy, False); @@ -1348,7 +1377,9 @@ find_dead_regions(void) if((x < logo_x || x > logo_x + logo_width / grid_width) || (y < logo_y || y > logo_y + logo_height / grid_height)) { - if (!maze[x][y] & WALL_ANY) + /* if we are completely surrounded by walls, just draw the + inside part */ + if ((maze[x][y] & WALL_ANY) == WALL_ANY) XFillRectangle(dpy, win, ugc, border_x + bw + grid_width * x, border_y + bw + grid_height * y, @@ -1367,13 +1398,13 @@ find_dead_regions(void) } } } - XSync(dpy, 0); + XSync(dpy, False); } static void solve_maze (void) /* solve it with graphical feedback */ { - int i, dir, from, x, y, ways, bt; + int i, dir, from, x, y, ways, bt = 0; /* plug up the surrounding wall */ maze[end_x][end_y] |= (WALL_TOP >> end_dir); @@ -1431,44 +1462,60 @@ solve_maze (void) /* solve it with graphical feedback */ if(!ways) goto backtrack; - - x = path[i].x - start_x; - y = path[i].y - start_y; - /* choice one */ - if(abs(y) <= abs(x)) - dir = (x > 0) ? WALL_LEFT : WALL_RIGHT; - else - dir = (y > 0) ? WALL_TOP : WALL_BOTTOM; - - if(dir & ways) - goto found; - - /* choice two */ - switch(dir) - { - case WALL_LEFT: - case WALL_RIGHT: - dir = (y > 0) ? WALL_TOP : WALL_BOTTOM; break; - case WALL_TOP: - case WALL_BOTTOM: - dir = (x > 0) ? WALL_LEFT : WALL_RIGHT; - } - - if(dir & ways) - goto found; - - /* choice three */ - - dir = (dir << 2 & WALL_ANY) | (dir >> 2 & WALL_ANY); - if(dir & ways) - goto found; - - /* choice four */ - dir = ways; - if(!dir) - goto backtrack; - found: + if (!ignorant_p) + { + x = path[i].x - start_x; + y = path[i].y - start_y; + /* choice one */ + if(abs(y) <= abs(x)) + dir = (x > 0) ? WALL_LEFT : WALL_RIGHT; + else + dir = (y > 0) ? WALL_TOP : WALL_BOTTOM; + + if(dir & ways) + goto found; + + /* choice two */ + switch(dir) + { + case WALL_LEFT: + case WALL_RIGHT: + dir = (y > 0) ? WALL_TOP : WALL_BOTTOM; break; + case WALL_TOP: + case WALL_BOTTOM: + dir = (x > 0) ? WALL_LEFT : WALL_RIGHT; + } + + if(dir & ways) + goto found; + + /* choice three */ + + dir = (dir << 2 & WALL_ANY) | (dir >> 2 & WALL_ANY); + if(dir & ways) + goto found; + + /* choice four */ + dir = ways; + if(!dir) + goto backtrack; + + found: ; + } + else + { + if(ways&WALL_TOP) + dir = WALL_TOP; + else if(ways&WALL_LEFT) + dir = WALL_LEFT; + else if(ways&WALL_BOTTOM) + dir = WALL_BOTTOM; + else if(ways&WALL_RIGHT) + dir = WALL_RIGHT; + else + goto backtrack; + } bt = 0; ways &= ~dir; /* tried this one */ @@ -1495,7 +1542,7 @@ solve_maze (void) /* solve it with graphical feedback */ return; } - if(!bt) + if(!bt && !ignorant_p) find_dead_regions(); bt = 1; from = path[i-1].dir; @@ -1533,7 +1580,7 @@ enter_square (int n) /* move into a neighboring square */ /* - * jmr additions for Jamie Zawinski's screensaver stuff, + * jmr additions for Jamie Zawinski's screensaver stuff, * note that the code above this has probably been hacked about in some * arbitrary way. */ @@ -1555,17 +1602,18 @@ char *defaults[] = { "*maxLength: 5", "*syncDraw: False", "*bridge: False", -#ifdef XROGER - "*logoColor: red3", -#endif 0 }; XrmOptionDescRec options[] = { + { "-ignorant", ".ignorant", XrmoptionNoArg, "True" }, + { "-no-ignorant", ".ignorant", XrmoptionNoArg, "False" }, { "-grid-size", ".gridSize", XrmoptionSepArg, 0 }, { "-solve-delay", ".solveDelay", XrmoptionSepArg, 0 }, { "-pre-delay", ".preDelay", XrmoptionSepArg, 0 }, { "-post-delay", ".postDelay", XrmoptionSepArg, 0 }, + { "-bg-color", ".background", XrmoptionSepArg, 0 }, + { "-fg-color", ".foreground", XrmoptionSepArg, 0 }, { "-live-color", ".liveColor", XrmoptionSepArg, 0 }, { "-dead-color", ".deadColor", XrmoptionSepArg, 0 }, { "-skip-color", ".skipColor", XrmoptionSepArg, 0 }, @@ -1577,17 +1625,13 @@ XrmOptionDescRec options[] = { { 0, 0, 0, 0 } }; -#ifdef XROGER -extern void skull (Display *, Window, GC, GC, int, int, int, int); -#endif - void screenhack(Display *display, Window window) { Pixmap gray; int size, root, generator, this_gen; XWindowAttributes xgwa; - unsigned long bg, fg, pfg, pbg, lfg, sfg, ufg; + unsigned long bg, fg, pfg, pbg, sfg, ufg; size = get_integer_resource ("gridSize", "Dimension"); root = get_boolean_resource("root", "Boolean"); @@ -1597,6 +1641,7 @@ screenhack(Display *display, Window window) generator = get_integer_resource("generator", "Integer"); max_length = get_integer_resource("maxLength", "Integer"); bridge_p = get_boolean_resource("bridge", "Boolean"); + ignorant_p = get_boolean_resource("ignorant", "Boolean"); if (size < 2) size = 7 + (random () % 30); grid_width = grid_height = size; @@ -1612,7 +1657,12 @@ screenhack(Display *display, Window window) set_maze_sizes (xgwa.width, xgwa.height); if (! root) - XSelectInput (dpy, win, ExposureMask|ButtonPressMask|StructureNotifyMask); + { + XWindowAttributes xgwa; + XGetWindowAttributes (dpy, window, &xgwa); + XSelectInput (dpy, win, + xgwa.your_event_mask | ExposureMask | ButtonPressMask); + } gc = XCreateGC(dpy, win, 0, 0); cgc = XCreateGC(dpy, win, 0, 0); @@ -1626,17 +1676,10 @@ screenhack(Display *display, Window window) bg = get_pixel_resource ("background","Background", dpy, xgwa.colormap); fg = get_pixel_resource ("foreground","Foreground", dpy, xgwa.colormap); - lfg = get_pixel_resource ("logoColor", "Foreground", dpy, xgwa.colormap); pfg = get_pixel_resource ("liveColor", "Foreground", dpy, xgwa.colormap); pbg = get_pixel_resource ("deadColor", "Foreground", dpy, xgwa.colormap); sfg = get_pixel_resource ("skipColor", "Foreground", dpy, xgwa.colormap); ufg = get_pixel_resource ("surroundColor", "Foreground", dpy, xgwa.colormap); - if (mono_p) lfg = pfg = fg; - - if (lfg == bg) - lfg = ((bg == WhitePixel (dpy, DefaultScreen (dpy))) - ? BlackPixel (dpy, DefaultScreen (dpy)) - : WhitePixel (dpy, DefaultScreen (dpy))); XSetForeground (dpy, gc, fg); XSetBackground (dpy, gc, bg); @@ -1648,7 +1691,7 @@ screenhack(Display *display, Window window) XSetBackground (dpy, sgc, bg); XSetForeground (dpy, ugc, ufg); XSetBackground (dpy, ugc, bg); - XSetForeground (dpy, logo_gc, lfg); + XSetForeground (dpy, logo_gc, fg); XSetBackground (dpy, logo_gc, bg); XSetForeground (dpy, erase_gc, bg); XSetBackground (dpy, erase_gc, bg); @@ -1660,23 +1703,14 @@ screenhack(Display *display, Window window) XSetStipple (dpy, ugc, gray); XSetFillStyle (dpy, ugc, FillOpaqueStippled); -#ifdef XROGER +#ifdef XSCREENSAVER_LOGO { - int w, h; - XGCValues gcv; - GC draw_gc, erase_gc; - /* round up to grid size */ - w = ((logo_width / grid_width) + 1) * grid_width; - h = ((logo_height / grid_height) + 1) * grid_height; - logo_map = XCreatePixmap (dpy, win, w, h, 1); - gcv.foreground = 1L; - draw_gc = XCreateGC (dpy, logo_map, GCForeground, &gcv); - gcv.foreground = 0L; - erase_gc= XCreateGC (dpy, logo_map, GCForeground, &gcv); - XFillRectangle (dpy, logo_map, erase_gc, 0, 0, w, h); - skull (dpy, logo_map, draw_gc, erase_gc, 5, 0, w-10, h-10); - XFreeGC (dpy, draw_gc); - XFreeGC (dpy, erase_gc); + unsigned long *pixels; /* ignored - unfreed */ + int npixels; + logo_map = xscreensaver_logo (xgwa.screen, xgwa.visual, win, + xgwa.colormap, bg, + &pixels, &npixels, 0, + logo_width > 150); } #else if (!(logo_map = XCreateBitmapFromData (dpy, win, logo_bits,