mirror of https://github.com/GNOME/gimp.git
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:
parent
a346d25c40
commit
0a1f444c2f
|
@ -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):
|
||||
|
|
|
@ -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) \
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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__ */
|
|
@ -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,
|
||||
|
|
@ -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__ */
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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__ */
|
|
@ -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
|
||||
|
|
|
@ -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__ */
|
||||
|
|
Loading…
Reference in New Issue