renamed most files and added proper headers instead of duplicating the

2008-03-31  Michael Natterer  <mitch@gimp.org>

	* plug-ins/maze/*: renamed most files and added proper headers
	instead of duplicating the prototypes in each .c file that uses
	them. Indentation, spacing, formatting, some general cleanup.


svn path=/trunk/; revision=25324
This commit is contained in:
Michael Natterer 2008-03-31 18:38:29 +00:00 committed by Michael Natterer
parent a346d25c40
commit 0a1f444c2f
11 changed files with 871 additions and 757 deletions

View File

@ -1,3 +1,9 @@
2008-03-31 Michael Natterer <mitch@gimp.org>
* plug-ins/maze/*: renamed most files and added proper headers
instead of duplicating the prototypes in each .c file that uses
them. Indentation, spacing, formatting, some general cleanup.
2008-03-31 Michael Natterer <mitch@gimp.org>
* app/widgets/gimpbrusheditor.c (gimp_brush_editor_notify_brush):

View File

@ -19,11 +19,14 @@ libexecdir = $(gimpplugindir)/plug-ins
libexec_PROGRAMS = maze
maze_SOURCES = \
algorithms.c \
handy.c \
maze.c \
maze.h \
maze_face.c
maze.c \
maze.h \
maze-algorithms.c \
maze-algorithms.h \
maze-dialog.c \
maze-dialog.h \
maze-utils.c \
maze-utils.h
INCLUDES = \
-I$(top_srcdir) \

View File

@ -1,603 +0,0 @@
/* $Id$
* Contains routines for generating mazes, somewhat intertwined with
* Gimp plug-in-maze specific stuff.
*
* Kevin Turner <acapnotic@users.sourceforge.net>
* http://gimp-plug-ins.sourceforge.net/maze/
*/
/* mazegen code from rec.games.programmer's maze-faq:
* * maz.c - generate a maze
* *
* * algorithm posted to rec.games.programmer by jallen@ic.sunysb.edu
* * program cleaned and reorganized by mzraly@ldbvax.dnet.lotus.com
* *
* * don't make people pay for this, or I'll jump up and down and
* * yell and scream and embarass you in front of your friends...
*/
/* I've put a HTMLized version of the FAQ up at
* http://www.poboxes.com/kevint/gimp/maze-faq/maze-faq.html
*/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include "config.h"
#include <stdlib.h>
#include "libgimp/gimp.h"
#include "libgimp/gimpui.h"
#include "libgimp/stdplugins-intl.h"
#include "maze.h"
extern MazeValues mvals;
extern GRand *gr;
void mazegen(gint pos,
gchar *maz,
gint x,
gint y,
gint rnd);
void mazegen_tileable(gint pos,
gchar *maz,
gint x,
gint y,
gint rnd);
void prim(gint pos,
gchar *maz,
guint x,
guint y);
void prim_tileable(gchar *maz,
guint x,
guint y);
#define ABSMOD(A,B) ( ((A) < 0) ? (((B) + (A)) % (B)) : ((A) % (B)) )
/* Since we are using a 1D array on 2D space, we need to do our own
calculations. (Ok, so there are ways of doing dynamically allocated
2D arrays, but we started this way, so let's stick with it. */
/* The difference between CELL_* and WALL_* is that cell moves two spaces,
while wall moves one. */
/* Macros assume that x and y will be defined where they are used. */
/* A return of -1 means "no such place, don't go there". */
#define CELL_UP(POS) ((POS) < (x*2) ? -1 : (POS) - x - x)
#define CELL_DOWN(POS) ((POS) >= x*(y-2) ? -1 : (POS) + x + x)
#define CELL_LEFT(POS) (((POS) % x) <= 1 ? -1 : (POS) - 2)
#define CELL_RIGHT(POS) (((POS) % x) >= (x - 2) ? -1 : (POS) + 2)
/* With walls, we don't need to check for boundaries, since we are
assured that there *is* a valid cell on the other side of the
wall. */
#define WALL_UP(POS) ((POS) - x)
#define WALL_DOWN(POS) ((POS) + x)
#define WALL_LEFT(POS) ((POS) - 1)
#define WALL_RIGHT(POS) ((POS) + 1)
/***** For tileable mazes *****/
#define CELL_UP_TILEABLE(POS) ((POS) < (x*2) ? x*(y-2)+(POS) : (POS) - x - x)
#define CELL_DOWN_TILEABLE(POS) ((POS) >= x*(y-2) ? (POS) - x*(y-2) : (POS) + x + x)
#define CELL_LEFT_TILEABLE(POS) (((POS) % x) <= 1 ? (POS) + x - 2 : (POS) - 2)
#define CELL_RIGHT_TILEABLE(POS) (((POS) % x) >= (x - 2) ? (POS) + 2 - x : (POS) + 2)
/* Up and left need checks, but down and right should never have to
wrap on an even sized maze. */
#define WALL_UP_TILEABLE(POS) ((POS) < x ? x*(y-1)+(POS) : (POS) - x)
#define WALL_DOWN_TILEABLE(POS) ((POS) + x)
#define WALL_LEFT_TILEABLE(POS) (((POS) % x) == 0 ? (POS) + x - 1 : (POS) - 1)
#define WALL_RIGHT_TILEABLE(POS) ((POS) + 1)
/* Down and right with checks.
#define WALL_DOWN_TILEABLE(POS) ((POS) >= x*(y-1) ? (POS) - x * (y-1) : (POS) + x)
#define WALL_RIGHT_TILEABLE(POS) (((POS) % x) == (x - 1) ? (POS) + 1 - x : (POS) + 1)
*/
/* The Incredible Recursive Maze Generation Routine */
/* Ripped from rec.programmers.games maze-faq */
/* Modified and commented by me, Kevin Turner. */
void
mazegen(gint pos, gchar *maz, gint x, gint y, gint rnd)
{
gchar d, i;
gint c=0, j=1;
/* Punch a hole here... */
maz[pos] = IN;
/* If there is a wall two rows above us, bit 1 is 1. */
while((d= (pos <= (x * 2) ? 0 : (maz[pos - x - x ] ? 0 : 1))
/* If there is a wall two rows below us, bit 2 is 1. */
| (pos >= x * (y - 2) ? 0 : (maz[pos + x + x] ? 0 : 2))
/* If there is a wall two columns to the right, bit 3 is 1. */
| (pos % x == x - 2 ? 0 : (maz[pos + 2] ? 0 : 4))
/* If there is a wall two colums to the left, bit 4 is 1. */
| ((pos % x == 1 ) ? 0 : (maz[pos-2] ? 0 : 8)))) {
/* Note if all bits are 0, d is false, we don't do this
while loop, we don't call ourselves again, so this branch
is done. */
/* I see what this loop does (more or less), but I don't know
_why_ it does it this way... I also haven't figured out exactly
which values of multiple will work and which won't. */
do {
rnd = (rnd * mvals.multiple + mvals.offset);
i = 3 & (rnd / d);
if (++c > 100) { /* Break and try to salvage something */
i=99; /* if it looks like we're going to be */
break; /* here forever... */
}
} while ( !(d & ( 1 << i) ) );
/* ...While there's *not* a wall in direction i. */
/* (stop looping when there is) */
switch (i) { /* This is simple enough. */
case 0: /* Go in the direction we just figured . . . */
j= -x;
break;
case 1:
j = x;
break;
case 2:
j=1;
break;
case 3:
j= -1;
break;
case 99:
return; /* Hey neat, broken mazes! */
break; /* (Umm... Wow... Yeah, neat.) */
default:
g_warning("maze: mazegen: Going in unknown direction.\n"
"i: %d, d: %d, seed: %d, mw: %d, mh: %d, mult: %d, offset: %d\n",
i, d,mvals.seed, x, y, mvals.multiple, mvals.offset);
break;
}
/* And punch a hole there. */
maz[pos + j] = 1;
/* Now, start again just past where we punched the hole... */
mazegen(pos + 2 * j, maz, x, y, rnd);
} /* End while(d=...) Loop */
/* This routine is quite quick, even for rather large mazes.
For that reason, it doesn't need a progress bar. */
return;
}
/* Tileable mazes are my creation, based on the routine above. */
void
mazegen_tileable(gint pos, gchar *maz, gint x, gint y, gint rnd)
{
gchar d, i;
gint c=0, npos=2;
/* Punch a hole here... */
maz[pos] = IN;
/* If there is a wall two rows above us, bit 1 is 1. */
while((d= (maz[CELL_UP_TILEABLE(pos)] ? 0 : 1)
/* If there is a wall two rows below us, bit 2 is 1. */
| (maz[CELL_DOWN_TILEABLE(pos)] ? 0 : 2)
/* If there is a wall two columns to the right, bit 3 is 1. */
| (maz[CELL_RIGHT_TILEABLE(pos)] ? 0 : 4)
/* If there is a wall two colums to the left, bit 4 is 1. */
| (maz[CELL_LEFT_TILEABLE(pos)] ? 0 : 8))) {
/* Note if all bits are 0, d is false, we don't do this
while loop, we don't call ourselves again, so this branch
is done. */
/* I see what this loop does (more or less), but I don't know
_why_ it does it this way... I also haven't figured out exactly
which values of multiple will work and which won't. */
do {
rnd = (rnd * mvals.multiple + mvals.offset);
i = 3 & (rnd / d);
if (++c > 100) { /* Break and try to salvage something */
i=99; /* if it looks like we're going to be */
break; /* here forever... */
}
} while ( !(d & ( 1 << i) ) );
/* ...While there's *not* a wall in direction i. */
/* (stop looping when there is) */
switch (i) { /* This is simple enough. */
case 0: /* Go in the direction we just figured . . . */
maz[WALL_UP_TILEABLE(pos)]=IN;
npos = CELL_UP_TILEABLE(pos);
break;
case 1:
maz[WALL_DOWN_TILEABLE(pos)]=IN;
npos = CELL_DOWN_TILEABLE(pos);
break;
case 2:
maz[WALL_RIGHT_TILEABLE(pos)]=IN;
npos = CELL_RIGHT_TILEABLE(pos);
break;
case 3:
maz[WALL_LEFT_TILEABLE(pos)]=IN;
npos = CELL_LEFT_TILEABLE(pos);
break;
case 99:
return; /* Hey neat, broken mazes! */
break; /* (Umm... Wow... Yeah, neat.) */
default:
g_warning("maze: mazegen_tileable: Going in unknown direction.\n"
"i: %d, d: %d, seed: %d, mw: %d, mh: %d, mult: %d, offset: %d\n",
i, d,mvals.seed, x, y, mvals.multiple, mvals.offset);
break;
}
/* Now, start again just past where we punched the hole... */
mazegen_tileable(npos, maz, x, y, rnd);
} /* End while(d=...) Loop */
return;
}
#if 0
static void
print_glist(gpointer data, gpointer user_data)
{
g_print("%d ",(guint)data);
}
#endif
/* This function (as well as prim_tileable) make use of the somewhat
unclean practice of storing ints as pointers. I've been informed
that this may cause problems with 64-bit stuff. However, hopefully
it will be okay, since the only values stored are positive. If it
does break, let me know, and I'll go cry in a corner for a while
before I get up the strength to re-code it. */
void
prim(gint pos, gchar *maz, guint x, guint y)
{
GSList *front_cells=NULL;
guint current;
gint up, down, left, right; /* Not unsigned, because macros return -1. */
guint progress=0, max_progress;
char d, i;
guint c=0;
gint rnd = mvals.seed;
g_rand_set_seed (gr, rnd);
gimp_progress_init (_("Constructing maze using Prim's Algorithm"));
/* OUT is zero, so we should be already initalized. */
max_progress=x*y/4;
/* Starting position has already been determined by the calling function. */
maz[pos]=IN;
/* For now, repeating everything four times seems manageable. But when
Gimp is extended to drawings in n-dimensional space instead of 2D,
this will require a bit of a re-write. */
/* Add frontier. */
up=CELL_UP(pos);
down=CELL_DOWN(pos);
left=CELL_LEFT(pos);
right=CELL_RIGHT(pos);
if (up >= 0) {
maz[up]=FRONTIER;
front_cells=g_slist_append(front_cells,GINT_TO_POINTER(up));
}
if (down >= 0) {
maz[down]=FRONTIER;
front_cells=g_slist_append(front_cells,GINT_TO_POINTER(down));
}
if (left >= 0) {
maz[left]=FRONTIER;
front_cells=g_slist_append(front_cells,GINT_TO_POINTER(left));
}
if (right >= 0) {
maz[right]=FRONTIER;
front_cells=g_slist_append(front_cells,GINT_TO_POINTER(right));
}
/* While frontier is not empty do the following... */
while(g_slist_length(front_cells) > 0) {
/* Remove one cell at random from frontier and place it in IN. */
current = g_rand_int_range (gr, 0, g_slist_length(front_cells));
pos = GPOINTER_TO_INT(g_slist_nth(front_cells,current)->data);
front_cells=g_slist_remove(front_cells,GINT_TO_POINTER(pos));
maz[pos]=IN;
/* If the cell has any neighbors in OUT, remove them from
OUT and place them in FRONTIER. */
up=CELL_UP(pos);
down=CELL_DOWN(pos);
left=CELL_LEFT(pos);
right=CELL_RIGHT(pos);
d=0;
if (up>=0) {
switch (maz[up]) {
case OUT:
maz[up]=FRONTIER;
front_cells=g_slist_prepend(front_cells,
GINT_TO_POINTER(up));
break;
case IN:
d=1;
break;
default:
;
}
}
if (down>=0) {
switch (maz[down]) {
case OUT:
maz[down]=FRONTIER;
front_cells=g_slist_prepend(front_cells,
GINT_TO_POINTER(down));
break;
case IN:
d=d|2;
break;
default:
;
}
}
if (left>=0) {
switch (maz[left]) {
case OUT:
maz[left]=FRONTIER;
front_cells=g_slist_prepend(front_cells,
GINT_TO_POINTER(left));
break;
case IN:
d=d|4;
break;
default:
;
}
}
if (right>=0) {
switch (maz[right]) {
case OUT:
maz[right]=FRONTIER;
front_cells=g_slist_prepend(front_cells,
GINT_TO_POINTER(right));
break;
case IN:
d=d|8;
break;
default:
;
}
}
/* The cell is guaranteed to have at least one neighbor in
IN (otherwise it would not have been in FRONTIER); pick
one such neighbor at random and connect it to the new
cell (ie knock out a wall). */
if (!d) {
g_warning("maze: prim: Lack of neighbors.\n"
"seed: %d, mw: %d, mh: %d, mult: %d, offset: %d\n",
mvals.seed, x, y, mvals.multiple, mvals.offset);
break;
}
c=0;
do {
rnd = (rnd * mvals.multiple + mvals.offset);
i = 3 & (rnd / d);
if (++c > 100) { /* Break and try to salvage something */
i=99; /* if it looks like we're going to be */
break; /* here forever... */
}
} while ( !(d & ( 1 << i) ) );
switch (i) {
case 0:
maz[WALL_UP(pos)]=IN;
break;
case 1:
maz[WALL_DOWN(pos)]=IN;
break;
case 2:
maz[WALL_LEFT(pos)]=IN;
break;
case 3:
maz[WALL_RIGHT(pos)]=IN;
break;
case 99:
break;
default:
g_warning("maze: prim: Going in unknown direction.\n"
"i: %d, d: %d, seed: %d, mw: %d, mh: %d, mult: %d, offset: %d\n",
i, d, mvals.seed, x, y, mvals.multiple, mvals.offset);
}
if (progress++ % PRIMS_PROGRESS_UPDATE)
gimp_progress_update ((double) progress / (double) max_progress);
} /* while front_cells */
g_slist_free(front_cells);
} /* prim */
void
prim_tileable(gchar *maz, guint x, guint y)
{
GSList *front_cells=NULL;
guint current, pos;
guint up, down, left, right;
guint progress=0, max_progress;
char d, i;
guint c=0;
gint rnd = mvals.seed;
g_rand_set_seed (gr, rnd);
gimp_progress_init (_("Constructing tileable maze using Prim's Algorithm"));
/* OUT is zero, so we should be already initalized. */
max_progress=x*y/4;
/* Pick someplace to start. */
pos = x * 2 * g_rand_int_range (gr, 0, y/2) + 2 * g_rand_int_range(gr, 0, x/2);
maz[pos]=IN;
/* Add frontier. */
up=CELL_UP_TILEABLE(pos);
down=CELL_DOWN_TILEABLE(pos);
left=CELL_LEFT_TILEABLE(pos);
right=CELL_RIGHT_TILEABLE(pos);
maz[up]=maz[down]=maz[left]=maz[right]=FRONTIER;
front_cells=g_slist_append(front_cells,GINT_TO_POINTER(up));
front_cells=g_slist_append(front_cells,GINT_TO_POINTER(down));
front_cells=g_slist_append(front_cells,GINT_TO_POINTER(left));
front_cells=g_slist_append(front_cells,GINT_TO_POINTER(right));
/* While frontier is not empty do the following... */
while(g_slist_length(front_cells) > 0) {
/* Remove one cell at random from frontier and place it in IN. */
current = g_rand_int_range (gr, 0, g_slist_length(front_cells));
pos = GPOINTER_TO_UINT(g_slist_nth(front_cells,current)->data);
front_cells=g_slist_remove(front_cells,GUINT_TO_POINTER(pos));
maz[pos]=IN;
/* If the cell has any neighbors in OUT, remove them from
OUT and place them in FRONTIER. */
up=CELL_UP_TILEABLE(pos);
down=CELL_DOWN_TILEABLE(pos);
left=CELL_LEFT_TILEABLE(pos);
right=CELL_RIGHT_TILEABLE(pos);
d=0;
switch (maz[up]) {
case OUT:
maz[up]=FRONTIER;
front_cells=g_slist_append(front_cells,GINT_TO_POINTER(up));
break;
case IN:
d=1;
break;
default:
;
}
switch (maz[down]) {
case OUT:
maz[down]=FRONTIER;
front_cells=g_slist_append(front_cells,GINT_TO_POINTER(down));
break;
case IN:
d=d|2;
break;
default:
;
}
switch (maz[left]) {
case OUT:
maz[left]=FRONTIER;
front_cells=g_slist_append(front_cells,GINT_TO_POINTER(left));
break;
case IN:
d=d|4;
break;
default:
;
}
switch (maz[right]) {
case OUT:
maz[right]=FRONTIER;
front_cells=g_slist_append(front_cells,GINT_TO_POINTER(right));
break;
case IN:
d=d|8;
break;
default:
;
}
/* The cell is guaranteed to have at least one neighbor in
IN (otherwise it would not have been in FRONTIER); pick
one such neighbor at random and connect it to the new
cell (ie knock out a wall). */
if (!d) {
g_warning("maze: prim's tileable: Lack of neighbors.\n"
"seed: %d, mw: %d, mh: %d, mult: %d, offset: %d\n",
mvals.seed, x, y, mvals.multiple, mvals.offset);
break;
}
c=0;
do {
rnd = (rnd * mvals.multiple + mvals.offset);
i = 3 & (rnd / d);
if (++c > 100) { /* Break and try to salvage something */
i=99; /* if it looks like we're going to be */
break; /* here forever... */
}
} while ( !(d & ( 1 << i) ) );
switch (i) {
case 0:
maz[WALL_UP_TILEABLE(pos)]=IN;
break;
case 1:
maz[WALL_DOWN_TILEABLE(pos)]=IN;
break;
case 2:
maz[WALL_LEFT_TILEABLE(pos)]=IN;
break;
case 3:
maz[WALL_RIGHT_TILEABLE(pos)]=IN;
break;
case 99:
break;
default:
g_warning("maze: prim's tileable: Going in unknown direction.\n"
"i: %d, d: %d, seed: %d, mw: %d, mh: %d, mult: %d, offset: %d\n",
i, d, mvals.seed, x, y, mvals.multiple, mvals.offset);
}
if (progress++ % PRIMS_PROGRESS_UPDATE)
gimp_progress_update ((double) progress / (double) max_progress);
} /* while front_cells */
g_slist_free(front_cells);
}

View File

@ -0,0 +1,645 @@
/* $Id$
* Contains routines for generating mazes, somewhat intertwined with
* Gimp plug-in-maze specific stuff.
*
* Kevin Turner <acapnotic@users.sourceforge.net>
* http://gimp-plug-ins.sourceforge.net/maze/
*/
/* mazegen code from rec.games.programmer's maze-faq:
* * maz.c - generate a maze
* *
* * algorithm posted to rec.games.programmer by jallen@ic.sunysb.edu
* * program cleaned and reorganized by mzraly@ldbvax.dnet.lotus.com
* *
* * don't make people pay for this, or I'll jump up and down and
* * yell and scream and embarass you in front of your friends...
*/
/* I've put a HTMLized version of the FAQ up at
* http://www.poboxes.com/kevint/gimp/maze-faq/maze-faq.html
*/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include "config.h"
#include <stdlib.h>
#include "libgimp/gimp.h"
#include "maze.h"
#include "maze-algorithms.h"
#include "libgimp/stdplugins-intl.h"
#define ABSMOD(A,B) (((A) < 0) ? (((B) + (A)) % (B)) : ((A) % (B)))
/* Since we are using a 1D array on 2D space, we need to do our own
calculations. (Ok, so there are ways of doing dynamically allocated
2D arrays, but we started this way, so let's stick with it. */
/* The difference between CELL_* and WALL_* is that cell moves two spaces,
while wall moves one. */
/* Macros assume that x and y will be defined where they are used. */
/* A return of -1 means "no such place, don't go there". */
#define CELL_UP(POS) ((POS) < (x*2) ? -1 : (POS) - x - x)
#define CELL_DOWN(POS) ((POS) >= x*(y-2) ? -1 : (POS) + x + x)
#define CELL_LEFT(POS) (((POS) % x) <= 1 ? -1 : (POS) - 2)
#define CELL_RIGHT(POS) (((POS) % x) >= (x - 2) ? -1 : (POS) + 2)
/* With walls, we don't need to check for boundaries, since we are
assured that there *is* a valid cell on the other side of the
wall. */
#define WALL_UP(POS) ((POS) - x)
#define WALL_DOWN(POS) ((POS) + x)
#define WALL_LEFT(POS) ((POS) - 1)
#define WALL_RIGHT(POS) ((POS) + 1)
/***** For tileable mazes *****/
#define CELL_UP_TILEABLE(POS) ((POS) < (x*2) ? x*(y-2)+(POS) : (POS) - x - x)
#define CELL_DOWN_TILEABLE(POS) ((POS) >= x*(y-2) ? (POS) - x*(y-2) : (POS) + x + x)
#define CELL_LEFT_TILEABLE(POS) (((POS) % x) <= 1 ? (POS) + x - 2 : (POS) - 2)
#define CELL_RIGHT_TILEABLE(POS) (((POS) % x) >= (x - 2) ? (POS) + 2 - x : (POS) + 2)
/* Up and left need checks, but down and right should never have to
wrap on an even sized maze. */
#define WALL_UP_TILEABLE(POS) ((POS) < x ? x*(y-1)+(POS) : (POS) - x)
#define WALL_DOWN_TILEABLE(POS) ((POS) + x)
#define WALL_LEFT_TILEABLE(POS) (((POS) % x) == 0 ? (POS) + x - 1 : (POS) - 1)
#define WALL_RIGHT_TILEABLE(POS) ((POS) + 1)
/* Down and right with checks.
#define WALL_DOWN_TILEABLE(POS) ((POS) >= x*(y-1) ? (POS) - x * (y-1) : (POS) + x)
#define WALL_RIGHT_TILEABLE(POS) (((POS) % x) == (x - 1) ? (POS) + 1 - x : (POS) + 1)
*/
/* The Incredible Recursive Maze Generation Routine */
/* Ripped from rec.programmers.games maze-faq */
/* Modified and commented by me, Kevin Turner. */
void
mazegen (gint pos,
guchar *maz,
gint x,
gint y,
gint rnd)
{
gchar d, i;
gint c = 0;
gint j = 1;
/* Punch a hole here... */
maz[pos] = IN;
/* If there is a wall two rows above us, bit 1 is 1. */
while ((d= (pos <= (x * 2) ? 0 : (maz[pos - x - x ] ? 0 : 1))
/* If there is a wall two rows below us, bit 2 is 1. */
| (pos >= x * (y - 2) ? 0 : (maz[pos + x + x] ? 0 : 2))
/* If there is a wall two columns to the right, bit 3 is 1. */
| (pos % x == x - 2 ? 0 : (maz[pos + 2] ? 0 : 4))
/* If there is a wall two colums to the left, bit 4 is 1. */
| ((pos % x == 1 ) ? 0 : (maz[pos-2] ? 0 : 8))))
{
/* Note if all bits are 0, d is false, we don't do this
while loop, we don't call ourselves again, so this branch
is done. */
/* I see what this loop does (more or less), but I don't know
_why_ it does it this way... I also haven't figured out exactly
which values of multiple will work and which won't. */
do
{
rnd = (rnd * mvals.multiple + mvals.offset);
i = 3 & (rnd / d);
if (++c > 100)
{ /* Break and try to salvage something */
i=99; /* if it looks like we're going to be */
break; /* here forever... */
}
}
while (!(d & (1 << i)));
/* ...While there's *not* a wall in direction i. */
/* (stop looping when there is) */
switch (i)
{
case 0: /* Go in the direction we just figured . . . */
j = -x;
break;
case 1:
j = x;
break;
case 2:
j = 1;
break;
case 3:
j = -1;
break;
case 99:
return; /* Hey neat, broken mazes! */
break; /* (Umm... Wow... Yeah, neat.) */
default:
g_warning ("maze: mazegen: Going in unknown direction.\n"
"i: %d, d: %d, seed: %d, mw: %d, mh: %d, mult: %d, offset: %d\n",
i, d,mvals.seed, x, y, mvals.multiple, mvals.offset);
break;
}
/* And punch a hole there. */
maz[pos + j] = 1;
/* Now, start again just past where we punched the hole... */
mazegen (pos + 2 * j, maz, x, y, rnd);
}
return;
}
/* Tileable mazes are my creation, based on the routine above. */
void
mazegen_tileable (gint pos,
guchar *maz,
gint x,
gint y,
gint rnd)
{
gchar d, i;
gint c = 0;
gint npos = 2;
/* Punch a hole here... */
maz[pos] = IN;
/* If there is a wall two rows above us, bit 1 is 1. */
while ((d= (maz[CELL_UP_TILEABLE(pos)] ? 0 : 1)
/* If there is a wall two rows below us, bit 2 is 1. */
| (maz[CELL_DOWN_TILEABLE(pos)] ? 0 : 2)
/* If there is a wall two columns to the right, bit 3 is 1. */
| (maz[CELL_RIGHT_TILEABLE(pos)] ? 0 : 4)
/* If there is a wall two colums to the left, bit 4 is 1. */
| (maz[CELL_LEFT_TILEABLE(pos)] ? 0 : 8)))
{
/* Note if all bits are 0, d is false, we don't do this
while loop, we don't call ourselves again, so this branch
is done. */
/* I see what this loop does (more or less), but I don't know
_why_ it does it this way... I also haven't figured out exactly
which values of multiple will work and which won't. */
do
{
rnd = (rnd * mvals.multiple + mvals.offset);
i = 3 & (rnd / d);
if (++c > 100)
{ /* Break and try to salvage something */
i=99; /* if it looks like we're going to be */
break; /* here forever... */
}
}
while (!(d & (1 << i)));
/* ...While there's *not* a wall in direction i. */
/* (stop looping when there is) */
switch (i)
{
case 0: /* Go in the direction we just figured . . . */
maz[WALL_UP_TILEABLE (pos)] = IN;
npos = CELL_UP_TILEABLE (pos);
break;
case 1:
maz[WALL_DOWN_TILEABLE (pos)] = IN;
npos = CELL_DOWN_TILEABLE (pos);
break;
case 2:
maz[WALL_RIGHT_TILEABLE (pos)] = IN;
npos = CELL_RIGHT_TILEABLE (pos);
break;
case 3:
maz[WALL_LEFT_TILEABLE (pos)] = IN;
npos = CELL_LEFT_TILEABLE (pos);
break;
case 99:
return; /* Hey neat, broken mazes! */
break; /* (Umm... Wow... Yeah, neat.) */
default:
g_warning ("maze: mazegen_tileable: Going in unknown direction.\n"
"i: %d, d: %d, seed: %d, mw: %d, mh: %d, mult: %d, offset: %d\n",
i, d,mvals.seed, x, y, mvals.multiple, mvals.offset);
break;
}
/* Now, start again just past where we punched the hole... */
mazegen_tileable (npos, maz, x, y, rnd);
}
return;
}
/* This function (as well as prim_tileable) make use of the somewhat
unclean practice of storing ints as pointers. I've been informed
that this may cause problems with 64-bit stuff. However, hopefully
it will be okay, since the only values stored are positive. If it
does break, let me know, and I'll go cry in a corner for a while
before I get up the strength to re-code it. */
void
prim (gint pos,
guchar *maz,
guint x,
guint y)
{
GSList *front_cells = NULL;
guint current;
gint up, down, left, right; /* Not unsigned, because macros return -1. */
guint progress = 0;
guint max_progress;
char d, i;
guint c = 0;
gint rnd = mvals.seed;
g_rand_set_seed (gr, rnd);
gimp_progress_init (_("Constructing maze using Prim's Algorithm"));
/* OUT is zero, so we should be already initalized. */
max_progress = x * y / 4;
/* Starting position has already been determined by the calling function. */
maz[pos] = IN;
/* For now, repeating everything four times seems manageable. But when
Gimp is extended to drawings in n-dimensional space instead of 2D,
this will require a bit of a re-write. */
/* Add frontier. */
up = CELL_UP (pos);
down = CELL_DOWN (pos);
left = CELL_LEFT (pos);
right = CELL_RIGHT (pos);
if (up >= 0)
{
maz[up] = FRONTIER;
front_cells = g_slist_append (front_cells, GINT_TO_POINTER (up));
}
if (down >= 0)
{
maz[down] = FRONTIER;
front_cells = g_slist_append (front_cells, GINT_TO_POINTER (down));
}
if (left >= 0)
{
maz[left] = FRONTIER;
front_cells = g_slist_append (front_cells, GINT_TO_POINTER (left));
}
if (right >= 0)
{
maz[right] = FRONTIER;
front_cells = g_slist_append (front_cells, GINT_TO_POINTER (right));
}
/* While frontier is not empty do the following... */
while (g_slist_length (front_cells) > 0)
{
/* Remove one cell at random from frontier and place it in IN. */
current = g_rand_int_range (gr, 0, g_slist_length (front_cells));
pos = GPOINTER_TO_INT (g_slist_nth (front_cells, current)->data);
front_cells = g_slist_remove (front_cells, GINT_TO_POINTER (pos));
maz[pos] = IN;
/* If the cell has any neighbors in OUT, remove them from
OUT and place them in FRONTIER. */
up = CELL_UP (pos);
down = CELL_DOWN (pos);
left = CELL_LEFT (pos);
right = CELL_RIGHT (pos);
d = 0;
if (up >= 0)
{
switch (maz[up])
{
case OUT:
maz[up] = FRONTIER;
front_cells = g_slist_prepend (front_cells,
GINT_TO_POINTER (up));
break;
case IN:
d = 1;
break;
default:
break;
}
}
if (down >= 0)
{
switch (maz[down])
{
case OUT:
maz[down] = FRONTIER;
front_cells = g_slist_prepend (front_cells,
GINT_TO_POINTER (down));
break;
case IN:
d = d | 2;
break;
default:
break;
}
}
if (left >= 0)
{
switch (maz[left])
{
case OUT:
maz[left] = FRONTIER;
front_cells = g_slist_prepend (front_cells,
GINT_TO_POINTER (left));
break;
case IN:
d = d | 4;
break;
default:
break;
}
}
if (right >= 0)
{
switch (maz[right])
{
case OUT:
maz[right] = FRONTIER;
front_cells = g_slist_prepend (front_cells,
GINT_TO_POINTER (right));
break;
case IN:
d = d | 8;
break;
default:
break;
}
}
/* The cell is guaranteed to have at least one neighbor in
IN (otherwise it would not have been in FRONTIER); pick
one such neighbor at random and connect it to the new
cell (ie knock out a wall). */
if (!d)
{
g_warning ("maze: prim: Lack of neighbors.\n"
"seed: %d, mw: %d, mh: %d, mult: %d, offset: %d\n",
mvals.seed, x, y, mvals.multiple, mvals.offset);
break;
}
c = 0;
do
{
rnd = (rnd * mvals.multiple + mvals.offset);
i = 3 & (rnd / d);
if (++c > 100)
{ /* Break and try to salvage something */
i = 99; /* if it looks like we're going to be */
break; /* here forever... */
}
}
while (!(d & (1 << i)));
switch (i)
{
case 0:
maz[WALL_UP (pos)] = IN;
break;
case 1:
maz[WALL_DOWN (pos)] = IN;
break;
case 2:
maz[WALL_LEFT (pos)] = IN;
break;
case 3:
maz[WALL_RIGHT (pos)] = IN;
break;
case 99:
break;
default:
g_warning ("maze: prim: Going in unknown direction.\n"
"i: %d, d: %d, seed: %d, mw: %d, mh: %d, mult: %d, offset: %d\n",
i, d, mvals.seed, x, y, mvals.multiple, mvals.offset);
}
if (progress++ % PRIMS_PROGRESS_UPDATE)
gimp_progress_update ((double) progress / (double) max_progress);
}
g_slist_free (front_cells);
}
void
prim_tileable (guchar *maz,
guint x,
guint y)
{
GSList *front_cells=NULL;
guint current, pos;
guint up, down, left, right;
guint progress = 0;
guint max_progress;
char d, i;
guint c = 0;
gint rnd = mvals.seed;
g_rand_set_seed (gr, rnd);
gimp_progress_init (_("Constructing tileable maze using Prim's Algorithm"));
/* OUT is zero, so we should be already initalized. */
max_progress = x * y / 4;
/* Pick someplace to start. */
pos = x * 2 * g_rand_int_range (gr, 0, y/2) + 2 * g_rand_int_range(gr, 0, x/2);
maz[pos] = IN;
/* Add frontier. */
up = CELL_UP_TILEABLE (pos);
down = CELL_DOWN_TILEABLE (pos);
left = CELL_LEFT_TILEABLE (pos);
right = CELL_RIGHT_TILEABLE (pos);
maz[up] = maz[down] = maz[left] = maz[right] = FRONTIER;
front_cells = g_slist_append (front_cells, GINT_TO_POINTER (up));
front_cells = g_slist_append (front_cells, GINT_TO_POINTER (down));
front_cells = g_slist_append (front_cells, GINT_TO_POINTER (left));
front_cells = g_slist_append (front_cells, GINT_TO_POINTER (right));
/* While frontier is not empty do the following... */
while (g_slist_length (front_cells) > 0)
{
/* Remove one cell at random from frontier and place it in IN. */
current = g_rand_int_range (gr, 0, g_slist_length (front_cells));
pos = GPOINTER_TO_UINT (g_slist_nth (front_cells, current)->data);
front_cells = g_slist_remove (front_cells, GUINT_TO_POINTER (pos));
maz[pos] = IN;
/* If the cell has any neighbors in OUT, remove them from
OUT and place them in FRONTIER. */
up = CELL_UP_TILEABLE (pos);
down = CELL_DOWN_TILEABLE (pos);
left = CELL_LEFT_TILEABLE (pos);
right = CELL_RIGHT_TILEABLE (pos);
d = 0;
switch (maz[up])
{
case OUT:
maz[up] = FRONTIER;
front_cells = g_slist_append (front_cells, GINT_TO_POINTER (up));
break;
case IN:
d = 1;
break;
default:
break;
}
switch (maz[down])
{
case OUT:
maz[down] = FRONTIER;
front_cells = g_slist_append (front_cells, GINT_TO_POINTER (down));
break;
case IN:
d = d | 2;
break;
default:
break;
}
switch (maz[left])
{
case OUT:
maz[left] = FRONTIER;
front_cells = g_slist_append (front_cells, GINT_TO_POINTER (left));
break;
case IN:
d = d | 4;
break;
default:
break;
}
switch (maz[right])
{
case OUT:
maz[right] = FRONTIER;
front_cells = g_slist_append (front_cells, GINT_TO_POINTER (right));
break;
case IN:
d = d | 8;
break;
default:
break;
}
/* The cell is guaranteed to have at least one neighbor in
IN (otherwise it would not have been in FRONTIER); pick
one such neighbor at random and connect it to the new
cell (ie knock out a wall). */
if (!d)
{
g_warning ("maze: prim's tileable: Lack of neighbors.\n"
"seed: %d, mw: %d, mh: %d, mult: %d, offset: %d\n",
mvals.seed, x, y, mvals.multiple, mvals.offset);
break;
}
c = 0;
do
{
rnd = (rnd * mvals.multiple + mvals.offset);
i = 3 & (rnd / d);
if (++c > 100)
{ /* Break and try to salvage something */
i = 99; /* if it looks like we're going to be */
break; /* here forever... */
}
}
while (!(d & (1 << i)));
switch (i)
{
case 0:
maz[WALL_UP_TILEABLE (pos)] = IN;
break;
case 1:
maz[WALL_DOWN_TILEABLE (pos)] = IN;
break;
case 2:
maz[WALL_LEFT_TILEABLE (pos)] = IN;
break;
case 3:
maz[WALL_RIGHT_TILEABLE (pos)] = IN;
break;
case 99:
break;
default:
g_warning ("maze: prim's tileable: Going in unknown direction.\n"
"i: %d, d: %d, seed: %d, mw: %d, mh: %d, mult: %d, offset: %d\n",
i, d, mvals.seed, x, y, mvals.multiple, mvals.offset);
}
if (progress++ % PRIMS_PROGRESS_UPDATE)
gimp_progress_update ((double) progress / (double) max_progress);
}
g_slist_free (front_cells);
}

View File

@ -0,0 +1,42 @@
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifndef __MAZE_ALGORITHMS_H__
#define __MAZE_ALGORITHMS_H__
void mazegen (gint pos,
guchar *maz,
gint x,
gint y,
gint rnd);
void mazegen_tileable (gint pos,
guchar *maz,
gint x,
gint y,
gint rnd);
void prim (gint pos,
guchar *maz,
guint x,
guint y);
void prim_tileable (guchar *maz,
guint x,
guint y);
#endif /* __MAZE_ALGORITHMS_H__ */

View File

@ -32,6 +32,7 @@
#include <libgimp/gimpui.h>
#include "maze.h"
#include "maze-dialog.h"
#include "libgimp/stdplugins-intl.h"
@ -51,7 +52,8 @@
#define MORE 1
#define LESS -1
typedef void (* EntscaleIntCallback) (gint value, gpointer data);
typedef void (* EntscaleIntCallback) (gint value,
gpointer data);
typedef struct
{
@ -69,10 +71,6 @@ typedef struct
static gchar buffer[BUFSIZE];
gboolean maze_dialog (void);
static void maze_message (const gchar *message);
/* Looking back, it would probably have been easier to completely
* re-write the whole entry/scale thing to work with the divbox stuff.
* It would undoubtably be cleaner code. But since I already *had*
@ -117,43 +115,39 @@ static void maze_message (const gchar *message);
gtk_signal_handler_block (). (Sven)
*/
static void div_button_callback (GtkWidget *button, GtkWidget *entry);
static void div_entry_callback (GtkWidget *entry, GtkWidget *friend);
static void height_width_callback (gint width, GtkWidget **div_entry);
static void maze_message (const gchar *message);
static void div_button_callback (GtkWidget *button,
GtkWidget *entry);
static void div_entry_callback (GtkWidget *entry,
GtkWidget *friend);
static void height_width_callback (gint width,
GtkWidget **div_entry);
static GtkWidget* divbox_new (guint *max,
GtkWidget *friend,
GtkWidget **div_entry);
#if 0
static void div_buttonl_callback (GtkObject *object);
static void div_buttonr_callback (GtkObject *object);
#endif
static GtkWidget * divbox_new (guint *max,
GtkWidget *friend,
GtkWidget **div_entry);
/* entscale stuff begin */
static GtkWidget * entscale_int_new (GtkWidget *table,
gint x,
gint y,
const gchar *caption,
gint *intvar,
gint min,
gint max,
gboolean constraint,
EntscaleIntCallback callback,
gpointer data);
static GtkWidget * entscale_int_new (GtkWidget *table,
gint x,
gint y,
const gchar *caption,
gint *intvar,
gint min,
gint max,
gboolean constraint,
EntscaleIntCallback callback,
gpointer data);
static void entscale_int_scale_update (GtkAdjustment *adjustment,
gpointer data);
static void entscale_int_entry_update (GtkWidget *widget,
gpointer data);
static void entscale_int_scale_update (GtkAdjustment *adjustment,
gpointer data);
static void entscale_int_entry_update (GtkWidget *widget,
gpointer data);
#define ISODD(X) ((X) & 1)
/* entscale stuff end */
extern MazeValues mvals;
extern guint sel_w, sel_h;
static GtkWidget *msg_label;
gboolean
@ -175,7 +169,7 @@ maze_dialog (void)
gimp_ui_init (PLUG_IN_BINARY, FALSE);
dialog = gimp_dialog_new (_(MAZE_TITLE), PLUG_IN_BINARY,
dialog = gimp_dialog_new (_("Maze"), PLUG_IN_BINARY,
NULL, 0,
gimp_standard_help_func, PLUG_IN_PROC,

View File

@ -0,0 +1,25 @@
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifndef __MAZE_DIALOG_H__
#define __MAZE_DIALOG_H__
gboolean maze_dialog (void);
#endif /* __MAZE_DIALOG_H__ */

View File

@ -29,7 +29,7 @@
#include "libgimp/gimp.h"
#include "maze.h"
#include "maze-utils.h"
/* get_colors Returns the current foreground and background colors in
@ -51,7 +51,7 @@ get_colors (GimpDrawable *drawable,
fg[0] = fg[1] = fg[2] = fg[3] = 255;
bg[0] = bg[1] = bg[2] = bg[3] = 255;
switch ( gimp_drawable_type (drawable->drawable_id) )
switch (gimp_drawable_type (drawable->drawable_id))
{
case GIMP_RGB_IMAGE:
case GIMP_RGBA_IMAGE:
@ -106,57 +106,51 @@ get_colors (GimpDrawable *drawable,
* We could keep a row of each color on hand so we wouldn't have to
* re-fill it every time... */
#include "config.h"
#include <stdlib.h>
#include "libgimp/gimp.h"
#include "maze.h"
void
drawbox( GimpPixelRgn *dest_rgn,
guint x, guint y, guint w, guint h,
guint8 clr[4])
drawbox (GimpPixelRgn *dest_rgn,
guint x,
guint y,
guint w,
guint h,
guint8 clr[4])
{
const guint bpp = dest_rgn->bpp;
const guint x_min = x * bpp;
const guint bpp = dest_rgn->bpp;
const guint x_min = x * bpp;
/* x_max = dest_rgn->bpp * MIN(dest_rgn->w, (x + w)); */
/* rowsize = x_max - x_min */
const guint rowsize = bpp * MIN(dest_rgn->w, (x + w)) - x_min;
/* x_max = dest_rgn->bpp * MIN(dest_rgn->w, (x + w)); */
/* rowsize = x_max - x_min */
const guint rowsize = bpp * MIN (dest_rgn->w, (x + w)) - x_min;
/* The maximum [xy] value is that of the far end of the box, or
* the edge of the region, whichever comes first. */
const guint y_max = dest_rgn->rowstride * MIN(dest_rgn->h, (y + h));
/* The maximum [xy] value is that of the far end of the box, or
* the edge of the region, whichever comes first. */
const guint y_max = dest_rgn->rowstride * MIN (dest_rgn->h, (y + h));
static guint8 *rowbuf;
static guint high_size = 0;
static guint8 *rowbuf;
static guint high_size = 0;
guint xx, yy;
guint xx, yy;
/* Does the row buffer need to be (re)allocated? */
if (high_size == 0)
{
rowbuf = g_new (guint8, rowsize);
}
else if (rowsize > high_size)
{
rowbuf = g_renew (guint8, rowbuf, rowsize);
}
/* Does the row buffer need to be (re)allocated? */
if (high_size == 0)
{
rowbuf = g_new (guint8, rowsize);
}
else if (rowsize > high_size)
{
rowbuf = g_renew (guint8, rowbuf, rowsize);
}
high_size = MAX(high_size, rowsize);
high_size = MAX (high_size, rowsize);
/* Fill the row buffer with the color. */
for (xx = 0; xx < rowsize; xx += bpp)
{
memcpy (&rowbuf[xx], clr, bpp);
}
/* Fill the row buffer with the color. */
for (xx = 0; xx < rowsize; xx += bpp)
{
memcpy (&rowbuf[xx], clr, bpp);
}
/* Fill in the box in the region with rows... */
for (yy = dest_rgn->rowstride * y; yy < y_max; yy += dest_rgn->rowstride)
{
memcpy (&dest_rgn->data[yy + x_min], rowbuf, rowsize);
}
/* Fill in the box in the region with rows... */
for (yy = dest_rgn->rowstride * y; yy < y_max; yy += dest_rgn->rowstride)
{
memcpy (&dest_rgn->data[yy + x_min], rowbuf, rowsize);
}
}

View File

@ -0,0 +1,32 @@
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __MAZE_UTILS_H__
#define __MAZE_UTILS_H__
void get_colors (GimpDrawable *drawable,
guint8 *fg,
guint8 *bg);
void drawbox (GimpPixelRgn *dest_rgn,
guint x,
guint y,
guint w,
guint h,
guint8 clr[4]);
#endif /* __MAZE_UTILS_H__ */

View File

@ -43,6 +43,9 @@
#include "libgimp/gimpui.h"
#include "maze.h"
#include "maze-algorithms.h"
#include "maze-dialog.h"
#include "maze-utils.h"
#include "libgimp/stdplugins-intl.h"
@ -67,40 +70,6 @@ static void mask_maze (gint32 selection_ID,
gint deadx,
gint deady);
/* In maze_face.c */
extern gint maze_dialog (void);
/* In algorithms.c */
extern void mazegen (gint pos,
guchar *maz,
gint x,
gint y,
gint rnd);
extern void mazegen_tileable (gint pos,
guchar *maz,
gint x,
gint y,
gint rnd);
extern void prim (guint pos,
guchar *maz,
guint x,
guint y);
extern void prim_tileable (guchar *maz,
guint x,
guint y);
/* In handy.c */
extern void get_colors (GimpDrawable *drawable,
guint8 *fg,
guint8 *bg);
extern void drawbox (GimpPixelRgn *dest_rgn,
guint x,
guint y,
guint w,
guint h,
guint8 clr[4]);
const GimpPlugInInfo PLUG_IN_INFO =
{
@ -124,7 +93,8 @@ MazeValues mvals =
GRand *gr;
guint sel_w, sel_h;
guint sel_w;
guint sel_h;
MAIN ()
@ -258,8 +228,10 @@ run (const gchar *name,
gimp_displays_flush ();
if (run_mode == GIMP_RUN_INTERACTIVE ||
(run_mode == GIMP_RUN_WITH_LAST_VALS))
gimp_set_data (PLUG_IN_PROC, &mvals, sizeof (MazeValues));
run_mode == GIMP_RUN_WITH_LAST_VALS)
{
gimp_set_data (PLUG_IN_PROC, &mvals, sizeof (MazeValues));
}
}
else
{
@ -268,13 +240,16 @@ run (const gchar *name,
values[0].data.d_status = status;
g_rand_free (gr);
gimp_drawable_detach (drawable);
g_rand_free (gr);
}
#ifdef MAZE_DEBUG
void
maze_dump (guchar *maz, gint mw, gint mh)
maze_dump (guchar *maz,
gint mw,
gint mh)
{
short xx, yy;
int foo = 0;
@ -288,7 +263,9 @@ maze_dump (guchar *maz, gint mw, gint mh)
}
void
maze_dumpX (guchar *maz, gint mw, gint mh)
maze_dumpX (guchar *maz,
gint mw,
gint mh)
{
short xx, yy;
int foo = 0;
@ -339,7 +316,7 @@ maze (GimpDrawable * drawable)
/* On the other hand, tileable mazes must be even. */
mw -= (mw & 1);
mh -= (mh & 1);
};
}
/* It will really suck if your tileable maze ends up with this dead
space around it. Oh well, life is hard. */
@ -562,21 +539,35 @@ maze (GimpDrawable * drawable)
* writing comments I haven't left enough to implement the code. :)
* Right now we only sample one point. */
static void
mask_maze (gint32 drawable_ID, guchar *maz, guint mw, guint mh,
gint x1, gint x2, gint y1, gint y2, gint deadx, gint deady)
mask_maze (gint32 drawable_ID,
guchar *maz,
guint mw,
guint mh,
gint x1,
gint x2,
gint y1,
gint y2,
gint deadx,
gint deady)
{
gint32 selection_ID;
gint32 selection_ID;
GimpPixelRgn sel_rgn;
gint xx0=0, yy0=0, xoff, yoff;
guint xx=0, yy=0;
guint foo=0;
gint xx0 = 0;
gint yy0 = 0;
gint xoff;
gint yoff;
guint xx = 0;
guint yy = 0;
guint foo = 0;
gint cur_row, cur_col;
gint x1half, x2half, y1half, y2half;
guchar *linebuf;
gint cur_row, cur_col;
gint x1half, x2half, y1half, y2half;
guchar *linebuf;
if ((selection_ID =
gimp_image_get_selection (gimp_drawable_get_image (drawable_ID))) == -1)
selection_ID =
gimp_image_get_selection (gimp_drawable_get_image (drawable_ID));
if (selection_ID == -1)
return;
gimp_pixel_rgn_init (&sel_rgn, gimp_drawable_get (selection_ID),
@ -749,7 +740,7 @@ mask_maze (gint32 drawable_ID, guchar *maz, guint mw, guint mh,
maz_row += mw;
}
} /* next pr sel_rgn tile thing */
}
#ifdef MAZE_DEBUG
/* maze_dump(maz,mw,mh); */
#endif

View File

@ -19,10 +19,6 @@
#define __MAZE_H__
#define MAZE_TITLE N_("Maze")
#define HELP_OPENS_NEW_WINDOW FALSE
/* The "divbox" really should look and act more like a spinbutton.
This flag is a small step in the direction toward the former, the
latter leaves much to be desired. */
@ -36,8 +32,6 @@
this value in the selection channel. */
#define MAZE_ALPHA_THRESHOLD 127
#include "glib.h"
#define PLUG_IN_PROC "plug-in-maze"
#define PLUG_IN_BINARY "maze"
@ -66,18 +60,9 @@ enum CellTypes {
};
extern MazeValues mvals;
extern guint sel_w, sel_h;
extern guint sel_w;
extern guint sel_h;
extern GRand *gr;
void get_colors (GimpDrawable *drawable,
guint8 *fg,
guint8 *bg);
void drawbox (GimpPixelRgn *dest_rgn,
guint x,
guint y,
guint w,
guint h,
guint8 clr[4]);
#endif /* __MAZE_H__ */