* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#include <glib.h>
-#include <glib/gi18n.h>
-
#include "main_bd.h"
GD_OBJECT_LEVEL5
};
-/* bdcff text description of object. caller should free string. */
+// bdcff text description of object. caller should free string.
char *gd_object_get_bdcff(const GdObject *object)
{
- GString *str;
+ char *str = NULL;
int j;
const char *type;
switch (object->type)
{
case GD_POINT:
- return g_strdup_printf("Point=%d %d %s",
- object->x1, object->y1,
- gd_elements[object->element].filename);
+ return getStringPrint("Point=%d %d %s", object->x1, object->y1, gd_elements[object->element].filename);
case GD_LINE:
- return g_strdup_printf("Line=%d %d %d %d %s",
- object->x1, object->y1, object->x2, object->y2,
- gd_elements[object->element].filename);
+ return getStringPrint("Line=%d %d %d %d %s", object->x1, object->y1, object->x2, object->y2, gd_elements[object->element].filename);
case GD_RECTANGLE:
- return g_strdup_printf("Rectangle=%d %d %d %d %s",
- object->x1, object->y1, object->x2, object->y2,
- gd_elements[object->element].filename);
+ return getStringPrint("Rectangle=%d %d %d %d %s", object->x1, object->y1, object->x2, object->y2, gd_elements[object->element].filename);
case GD_FILLED_RECTANGLE:
- /* if elements are not the same */
- if (object->fill_element != object->element)
- return g_strdup_printf("FillRect=%d %d %d %d %s %s",
- object->x1, object->y1, object->x2, object->y2,
- gd_elements[object->element].filename,
- gd_elements[object->fill_element].filename);
-
- /* they are the same */
- return g_strdup_printf("FillRect=%d %d %d %d %s",
- object->x1, object->y1, object->x2, object->y2,
- gd_elements[object->element].filename);
+ // if elements are not the same
+ if (object->fill_element!=object->element)
+ return getStringPrint("FillRect=%d %d %d %d %s %s", object->x1, object->y1, object->x2, object->y2, gd_elements[object->element].filename, gd_elements[object->fill_element].filename);
+ // they are the same
+ return getStringPrint("FillRect=%d %d %d %d %s", object->x1, object->y1, object->x2, object->y2, gd_elements[object->element].filename);
case GD_RASTER:
- return g_strdup_printf("Raster=%d %d %d %d %d %d %s",
- object->x1, object->y1,
- (object->x2 - object->x1) / object->dx + 1,
- (object->y2 - object->y1) / object->dy + 1,
- object->dx, object->dy,
- gd_elements[object->element].filename);
+ return getStringPrint("Raster=%d %d %d %d %d %d %s", object->x1, object->y1, (object->x2-object->x1)/object->dx+1, (object->y2-object->y1)/object->dy+1, object->dx, object->dy, gd_elements[object->element].filename);
case GD_JOIN:
- return g_strdup_printf("Add=%d %d %s %s",
- object->dx, object->dy,
- gd_elements[object->element].filename,
- gd_elements[object->fill_element].filename);
+ return getStringPrint("Add=%d %d %s %s", object->dx, object->dy, gd_elements[object->element].filename, gd_elements[object->fill_element].filename);
case GD_FLOODFILL_BORDER:
- return g_strdup_printf("BoundaryFill=%d %d %s %s",
- object->x1, object->y1,
- gd_elements[object->fill_element].filename,
- gd_elements[object->element].filename);
+ return getStringPrint("BoundaryFill=%d %d %s %s", object->x1, object->y1, gd_elements[object->fill_element].filename, gd_elements[object->element].filename);
case GD_FLOODFILL_REPLACE:
- return g_strdup_printf("FloodFill=%d %d %s %s",
- object->x1, object->y1,
- gd_elements[object->fill_element].filename,
- gd_elements[object->element].filename);
+ return getStringPrint("FloodFill=%d %d %s %s", object->x1, object->y1, gd_elements[object->fill_element].filename, gd_elements[object->element].filename);
case GD_MAZE:
case GD_MAZE_UNICURSAL:
case GD_MAZE_BRAID:
- switch (object->type)
+ switch(object->type)
{
- case GD_MAZE: type = "perfect"; break;
- case GD_MAZE_UNICURSAL: type = "unicursal"; break;
- case GD_MAZE_BRAID: type = "braid"; break;
- default: break;
+ case GD_MAZE:
+ type = "perfect";
+ break;
+
+ case GD_MAZE_UNICURSAL:
+ type = "unicursal";
+ break;
+
+ case GD_MAZE_BRAID:
+ type = "braid";
+ break;
+
+ default:
+ // never reached
+ break;
}
- return g_strdup_printf("Maze=%d %d %d %d %d %d %d %d %d %d %d %d %s %s %s",
- object->x1, object->y1, object->x2, object->y2,
- object->dx, object->dy,
- object->horiz,
- object->seed[0],
- object->seed[1],
- object->seed[2],
- object->seed[3],
- object->seed[4],
- gd_elements[object->element].filename,
- gd_elements[object->fill_element].filename, type);
+ return getStringPrint("Maze=%d %d %d %d %d %d %d %d %d %d %d %d %s %s %s", object->x1, object->y1, object->x2, object->y2, object->dx, object->dy, object->horiz, object->seed[0], object->seed[1], object->seed[2], object->seed[3], object->seed[4], gd_elements[object->element].filename, gd_elements[object->fill_element].filename, type);
case GD_RANDOM_FILL:
- str = g_string_new(NULL);
- /* seed and initial fill */
- g_string_append_printf(str, "%s=%d %d %d %d %d %d %d %d %d %s",
- object->c64_random ? "RandomFillC64" : "RandomFill",
- object->x1, object->y1, object->x2, object->y2,
- object->seed[0],
- object->seed[1],
- object->seed[2],
- object->seed[3],
- object->seed[4],
- gd_elements[object->fill_element].filename);
+ appendStringPrint(&str, "%s=%d %d %d %d %d %d %d %d %d %s", object->c64_random?"RandomFillC64":"RandomFill", object->x1, object->y1, object->x2, object->y2, object->seed[0], object->seed[1], object->seed[2], object->seed[3], object->seed[4], gd_elements[object->fill_element].filename);
+ // seed and initial fill
for (j = 0; j < 4; j++)
- {
if (object->random_fill_probability[j] != 0)
- g_string_append_printf(str, " %s %d",
- gd_elements[object->random_fill[j]].filename,
- object->random_fill_probability[j]);
- }
+ appendStringPrint(&str, " %s %d", gd_elements[object->random_fill[j]].filename, object->random_fill_probability[j]);
- if (object->element!=O_NONE)
- g_string_append_printf(str, " %s",
- gd_elements[object->element].filename);
+ if (object->element != O_NONE)
+ appendStringPrint(&str, " %s", gd_elements[object->element].filename);
- /* free string but do not free char *; return char *. */
- return g_string_free(str, FALSE);
+ return str;
case GD_COPY_PASTE:
- return g_strdup_printf("CopyPaste=%d %d %d %d %d %d %s %s",
- object->x1, object->y1, object->x2, object->y2,
- object->dx, object->dy,
- object->mirror ? "mirror" : "nomirror",
- object->flip?"flip":"noflip");
+ return getStringPrint("CopyPaste=%d %d %d %d %d %d %s %s", object->x1, object->y1, object->x2, object->y2, object->dx, object->dy, object->mirror?"mirror":"nomirror", object->flip?"flip":"noflip");
case NONE:
+ // never reached
break;
}
return NULL;
}
-/* create an INDIVIDUAL POINT CAVE OBJECT */
+// create an INDIVIDUAL POINT CAVE OBJECT
GdObject *gd_object_new_point(GdObjectLevels levels, int x, int y, GdElement elem)
{
GdObject *newobj = checked_calloc(sizeof(GdObject));
return newobj;
}
-/* create a LINE OBJECT */
+// create a LINE OBJECT
GdObject *gd_object_new_line(GdObjectLevels levels, int x1, int y1, int x2, int y2,
GdElement elem)
{
return newobj;
}
-/* create a RECTANGLE OBJECT */
+// create a RECTANGLE OBJECT
GdObject *gd_object_new_rectangle(GdObjectLevels levels, int x1, int y1, int x2, int y2,
GdElement elem)
{
return newobj;
}
-/* create a RECTANGLE OBJECT */
+// create a RECTANGLE OBJECT
GdObject *gd_object_new_filled_rectangle(GdObjectLevels levels, int x1, int y1, int x2, int y2,
GdElement elem, GdElement fill_elem)
{
return newobj;
}
-/* create a raster object */
+// create a raster object
GdObject *gd_object_new_raster(GdObjectLevels levels, int x1, int y1, int x2, int y2,
int dx, int dy, GdElement elem)
{
return newobj;
}
-/* create a raster object */
+// create a raster object
GdObject *gd_object_new_join(GdObjectLevels levels, int dx, int dy,
GdElement search, GdElement replace)
{
return newobj;
}
-/* create a new boundary fill object */
+// create a new boundary fill object
GdObject *gd_object_new_floodfill_border(GdObjectLevels levels, int x1, int y1,
GdElement fill, GdElement border)
{
GdObject *gd_object_new_maze(GdObjectLevels levels, int x1, int y1, int x2, int y2,
int wall_w, int path_w, GdElement wall_e, GdElement path_e,
- int horiz_percent, const gint32 seed[5])
+ int horiz_percent, const int seed[5])
{
int i;
GdObject *newobj = checked_calloc(sizeof(GdObject));
GdObject *gd_object_new_maze_unicursal(GdObjectLevels levels, int x1, int y1, int x2, int y2,
int wall_w, int path_w, GdElement wall_e, GdElement path_e,
- int horiz_percent, const gint32 seed[5])
+ int horiz_percent, const int seed[5])
{
int i;
GdObject *newobj = checked_calloc(sizeof(GdObject));
GdObject *gd_object_new_maze_braid(GdObjectLevels levels, int x1, int y1, int x2, int y2,
int wall_w, int path_w, GdElement wall_e, GdElement path_e,
- int horiz_percent, const gint32 seed[5])
+ int horiz_percent, const int seed[5])
{
int i;
GdObject *newobj = checked_calloc(sizeof(GdObject));
}
GdObject *gd_object_new_random_fill(GdObjectLevels levels, int x1, int y1, int x2, int y2,
- const gint32 seed[5], GdElement initial,
- const GdElement random[4], const gint32 prob[4],
+ const int seed[5], GdElement initial,
+ const GdElement random[4], const int prob[4],
GdElement replace_only, boolean c64)
{
int i;
return newobj;
}
-/* create new object from bdcff description.
- return new object if ok; return null if failed.
- */
+// create new object from bdcff description.
+// return new object if ok; return null if failed.
GdObject *gd_object_new_from_string(char *str)
{
char *equalsign;
if (!equalsign)
return NULL;
- /* split string by replacing the equal sign with zero */
+ // split string by replacing the equal sign with zero
*equalsign = '\0';
name = str;
param = equalsign + 1;
- /* INDIVIDUAL POINT CAVE OBJECT */
+ // INDIVIDUAL POINT CAVE OBJECT
if (strcasecmp(name, "Point") == 0)
{
object.type = GD_POINT;
{
object.element = gd_get_element_from_string(elem0);
- return g_memdup(&object, sizeof (GdObject));
+ return get_memcpy(&object, sizeof (GdObject));
}
return NULL;
}
- /* LINE OBJECT */
+ // LINE OBJECT
if (strcasecmp(name, "Line") == 0)
{
object.type = GD_LINE;
{
object.element = gd_get_element_from_string(elem0);
- return g_memdup(&object, sizeof (GdObject));
+ return get_memcpy(&object, sizeof (GdObject));
}
return NULL;
}
- /* RECTANGLE OBJECT */
+ // RECTANGLE OBJECT
if (strcasecmp(name, "Rectangle") == 0)
{
if (sscanf(param, "%d %d %d %d %s", &object.x1, &object.y1, &object.x2, &object.y2, elem0) == 5)
object.type = GD_RECTANGLE;
object.element = gd_get_element_from_string (elem0);
- return g_memdup(&object, sizeof (GdObject));
+ return get_memcpy(&object, sizeof (GdObject));
}
return NULL;
}
- /* FILLED RECTANGLE OBJECT */
+ // FILLED RECTANGLE OBJECT
if (strcasecmp(name, "FillRect") == 0)
{
int paramcount;
object.element = gd_get_element_from_string (elem0);
object.fill_element = gd_get_element_from_string (elem1);
- return g_memdup(&object, sizeof (GdObject));
+ return get_memcpy(&object, sizeof (GdObject));
}
if (paramcount == 5)
{
object.element = object.fill_element = gd_get_element_from_string (elem0);
- return g_memdup(&object, sizeof (GdObject));
+ return get_memcpy(&object, sizeof (GdObject));
}
return NULL;
}
- /* RASTER */
+ // RASTER
if (strcasecmp(name, "Raster") == 0)
{
int nx, ny;
object.type = GD_RASTER;
object.element = gd_get_element_from_string (elem0);
- return g_memdup(&object, sizeof (GdObject));
+ return get_memcpy(&object, sizeof (GdObject));
}
return NULL;
}
- /* JOIN */
+ // JOIN
if (strcasecmp(name, "Join") == 0 ||
strcasecmp(name, "Add") == 0)
{
object.element = gd_get_element_from_string (elem0);
object.fill_element = gd_get_element_from_string (elem1);
- return g_memdup(&object, sizeof (GdObject));
+ return get_memcpy(&object, sizeof (GdObject));
}
return NULL;
}
- /* FILL TO BORDER OBJECT */
+ // FILL TO BORDER OBJECT
if (strcasecmp(name, "BoundaryFill") == 0)
{
if (sscanf(param, "%d %d %s %s", &object.x1, &object.y1, elem0, elem1) == 4)
object.fill_element = gd_get_element_from_string (elem0);
object.element = gd_get_element_from_string (elem1);
- return g_memdup(&object, sizeof (GdObject));
+ return get_memcpy(&object, sizeof (GdObject));
}
return NULL;
}
- /* REPLACE FILL OBJECT */
+ // REPLACE FILL OBJECT
if (strcasecmp(name, "FloodFill") == 0)
{
if (sscanf(param, "%d %d %s %s", &object.x1, &object.y1, elem0, elem1) == 4)
object.fill_element = gd_get_element_from_string (elem0);
object.element = gd_get_element_from_string (elem1);
- return g_memdup(&object, sizeof (GdObject));
+ return get_memcpy(&object, sizeof (GdObject));
}
return NULL;
}
- /* MAZE OBJECT */
- /* MAZE UNICURSAL OBJECT */
- /* BRAID MAZE OBJECT */
+ // MAZE OBJECT
+ // MAZE UNICURSAL OBJECT
+ // BRAID MAZE OBJECT
if (strcasecmp(name, "Maze") == 0)
{
char type[100] = "perfect";
object.element = gd_get_element_from_string (elem0);
object.fill_element = gd_get_element_from_string (elem1);
- return g_memdup(&object, sizeof (GdObject));
+ return get_memcpy(&object, sizeof (GdObject));
}
return NULL;
}
- /* RANDOM FILL OBJECT */
+ // RANDOM FILL OBJECT
if (strcasecmp(name, "RandomFill") == 0 ||
strcasecmp(name, "RandomFillC64") == 0)
{
object.type = GD_RANDOM_FILL;
if (strcasecmp(name, "RandomFillC64") == 0)
- /* totally the same, but uses c64 random generator */
+ // totally the same, but uses c64 random generator
object.c64_random = TRUE;
else
object.c64_random = FALSE;
return NULL;
if (words)
- g_strfreev(words);
+ freeStringArray(words);
words = getSplitStringArray(param, " ", -1);
- l = g_strv_length(words);
+ l = getStringArrayLength(words);
if (l < 10 || l > 19)
return NULL;
if (l > 10 && l % 2 == 1)
object.element = gd_get_element_from_string(words[l - 1]);
- return g_memdup(&object, sizeof (GdObject));
+ return get_memcpy(&object, sizeof (GdObject));
}
- /* COPY PASTE OBJECT */
+ // COPY PASTE OBJECT
if (strcasecmp(name, "CopyPaste") == 0)
{
char mirror[100] = "nomirror";
if (sscanf(param, "%d %d %d %d %d %d %s %s", &object.x1, &object.y1, &object.x2, &object.y2, &object.dx, &object.dy, mirror, flip) < 6)
return NULL;
- /* MIRROR PROPERTY */
+ // MIRROR PROPERTY
if (strcasecmp(mirror, "mirror") == 0)
object.mirror = TRUE;
else if (strcasecmp(mirror, "nomirror") == 0)
else
Warn("invalid setting for copypaste mirror property: %s", mirror);
- /* FLIP PROPERTY */
+ // FLIP PROPERTY
if (strcasecmp(flip, "flip") == 0)
object.flip = TRUE;
else if (strcasecmp(flip, "noflip") == 0)
else
Warn("invalid setting for copypaste flip property: %s", flip);
- return g_memdup(&object, sizeof(GdObject));
+ return get_memcpy(&object, sizeof(GdObject));
}
return NULL;
}
-/** drawing a line, using bresenham's */
+// drawing a line, using bresenham's
static void draw_line (GdCave *cave, const GdObject *object)
{
int x, y, x1, y1, x2, y2;
static void draw_fill_replace_proc(GdCave *cave, int x, int y, const GdObject *object)
{
- /* fill with border so we do not come back */
+ // fill with border so we do not come back
gd_cave_store_rc(cave, x, y, object->fill_element, object);
if (x > 0 && gd_cave_get_rc(cave, x - 1, y) == object->element)
static void draw_fill_replace (GdCave *cave, const GdObject *object)
{
- /* check bounds */
+ // check bounds
if (object->x1 < 0 ||
object->y1 < 0 ||
object->x1 >= cave->w ||
if (object->element == object->fill_element)
return;
- /* this procedure fills the area with the object->element. */
+ // this procedure fills the area with the object->element.
draw_fill_replace_proc(cave, object->x1, object->y1, object);
}
static void draw_fill_border_proc (GdCave *cave, int x, int y, const GdObject *object)
{
- /* fill with border so we do not come back */
+ // fill with border so we do not come back
gd_cave_store_rc(cave, x, y, object->element, object);
if (x > 0 && gd_cave_get_rc(cave, x - 1, y) != object->element)
{
int x, y;
- /* check bounds */
+ // check bounds
if (object->x1 < 0 ||
object->y1 < 0 ||
object->x1 >= cave->w ||
object->y1 >= cave->h)
return;
- /* this procedure fills the area with the object->element. */
+ // this procedure fills the area with the object->element.
draw_fill_border_proc(cave, object->x1, object->y1, object);
- /* after the fill, we change all filled cells to the fill_element. */
- /* we find those by looking at the object_order[][] */
+ // after the fill, we change all filled cells to the fill_element.
+ // we find those by looking at the object_order[][]
for (y = 0; y < cave->h; y++)
for (x = 0; x < cave->w; x++)
if (cave->objects_order[y][x] == object)
cave->map[y][x] = object->fill_element;
}
-/* rectangle, frame only */
+// rectangle, frame only
static void draw_rectangle(GdCave *cave, const GdObject *object)
{
int x1, y1, x2, y2, x, y;
- /* reorder coordinates if not drawing from northwest to southeast */
+ // reorder coordinates if not drawing from northwest to southeast
x1 = object->x1;
y1 = object->y1, x2 = object->x2;
y2 = object->y2;
}
}
-/* rectangle, filled one */
+// rectangle, filled one
static void draw_filled_rectangle(GdCave *cave, const GdObject *object)
{
int x1, y1, x2, y2, x, y;
- /* reorder coordinates if not drawing from northwest to southeast */
+ // reorder coordinates if not drawing from northwest to southeast
x1 = object->x1;
y1 = object->y1, x2 = object->x2;
y2 = object->y2;
x == object->x2) ? object->element : object->fill_element, object);
}
-/* something like ordered fill, increment is dx and dy. */
+// something like ordered fill, increment is dx and dy.
static void draw_raster(GdCave *cave, const GdObject *object)
{
int x, y, x1, y1, x2, y2;
int dx, dy;
- /* reorder coordinates if not drawing from northwest to southeast */
+ // reorder coordinates if not drawing from northwest to southeast
x1 = object->x1;
y1 = object->y1;
x2 = object->x2;
gd_cave_store_rc(cave, x, y, object->element, object);
}
-/* find every object, and put fill_element next to it. relative coordinates dx,dy */
+// find every object, and put fill_element next to it. relative coordinates dx,dy
static void draw_join(GdCave *cave, const GdObject *object)
{
int x, y;
{
int nx = x + object->dx;
int ny = y + object->dy;
- /* this one implements wraparound for joins.
- it is needed by many caves in profi boulder series */
+ // this one implements wraparound for joins.
+ // it is needed by many caves in profi boulder series
while (nx >= cave->w)
nx -= cave->w, ny++;
}
}
-/* create a maze in a boolean **maze. */
-/* recursive algorithm. */
-static void mazegen(GRand *rand, boolean **maze, int width, int height, int x, int y, int horiz)
+// create a maze in a boolean **maze.
+// recursive algorithm.
+static void mazegen(GdRand *rand, boolean **maze, int width, int height, int x, int y, int horiz)
{
int dirmask = 15;
{
int dir;
- /* horiz or vert */
- dir = g_rand_int_range(rand, 0, 100) <horiz ? 2 : 0;
+ // horiz or vert
+ dir = gd_rand_int_range(rand, 0, 100) < horiz ? 2 : 0;
- /* if no horizontal movement possible, choose vertical */
+ // if no horizontal movement possible, choose vertical
if (dir == 2 && (dirmask & 12) == 0)
dir = 0;
- else if (dir == 0 && (dirmask&3) == 0) /* and vice versa */
+ else if (dir == 0 && (dirmask & 3) == 0) // and vice versa
dir = 2;
- dir += g_rand_int_range(rand, 0, 2); /* dir */
+ dir += gd_rand_int_range(rand, 0, 2); // dir
if (dirmask & (1 << dir))
{
dirmask &= ~(1 << dir);
switch (dir)
{
- case 0: /* up */
+ case 0: // up
if (y >= 2 && !maze[y - 2][x])
{
maze[y - 1][x] = TRUE;
}
break;
- case 1: /* down */
+ case 1: // down
if (y < height-2 && !maze[y + 2][x]) {
maze[y + 1][x] = TRUE;
mazegen(rand, maze, width, height, x, y + 2, horiz);
}
break;
- case 2: /* left */
+ case 2: // left
if (x >= 2 && !maze[y][x - 2]) {
maze[y][x - 1] = TRUE;
mazegen(rand, maze, width, height, x - 2, y, horiz);
}
break;
- case 3: /* right */
+ case 3: // right
if (x < width - 2 && !maze[y][x + 2]) {
maze[y][x + 1] = TRUE;
mazegen(rand, maze, width, height, x + 2, y, horiz);
}
}
-static void braidmaze(GRand *rand, boolean **maze, int w, int h)
+static void braidmaze(GdRand *rand, boolean **maze, int w, int h)
{
int x, y;
int closed = 0, dirs = 0;
int closed_dirs[4];
- /* if it is the edge of the map, OR no path carved, then we can't go in that direction. */
+ // if it is the edge of the map, OR no path carved, then we can't go in that direction.
if (x < 1 || !maze[y][x - 1])
{
- /* closed from this side. */
+ // closed from this side.
closed++;
- /* if not the edge, we might open this wall (carve a path) to remove a dead end */
+ // if not the edge, we might open this wall (carve a path) to remove a dead end
if (x > 0)
closed_dirs[dirs++] = GD_MV_LEFT;
}
- /* other 3 directions similar */
+ // other 3 directions similar
if (y < 1 || !maze[y - 1][x])
{
closed++;
closed_dirs[dirs++] = GD_MV_DOWN;
}
- /* if closed from 3 sides, then it is a dead end. also check dirs != 0,
- that might fail for a 1x1 maze :) */
+ // if closed from 3 sides, then it is a dead end. also check dirs != 0,
+ // that might fail for a 1x1 maze :)
if (closed == 3 && dirs != 0)
{
- /* make up a random direction, and open in that direction, so dead end is removed */
- int dir = closed_dirs[g_rand_int_range(rand, 0, dirs)];
+ // make up a random direction, and open in that direction, so dead end is removed
+ int dir = closed_dirs[gd_rand_int_range(rand, 0, dirs)];
switch (dir)
{
int y2 = object->y2;
int w, h, path, wall;
int xk, yk;
- GRand *rand;
+ GdRand *rand;
int i,j;
- /* change coordinates if not in correct order */
+ // change coordinates if not in correct order
if (y1 > y2)
{
y = y1;
if (path < 1)
path = 1;
- /* calculate the width and height of the maze.
- n = number of passages, path = path width, wall = wall width, maze = maze width.
- if given the number of passages, the width of the maze is:
+ /*
+ calculate the width and height of the maze.
+ n = number of passages, path = path width, wall = wall width, maze = maze width.
+ if given the number of passages, the width of the maze is:
- n * path + (n - 1) * wall = maze
- n * path + n * wall - wall = maze
- n * (path + wall) = maze + wall
- n = (maze + wall) / (path + wall)
+ n * path + (n - 1) * wall = maze
+ n * path + n * wall - wall = maze
+ n * (path + wall) = maze + wall
+ n = (maze + wall) / (path + wall)
*/
- /* number of passages for each side */
+ // number of passages for each side
w = (x2 - x1 + 1 + wall) / (path + wall);
h = (y2 - y1 + 1 + wall) / (path + wall);
- /* and we calculate the size of the internal map */
+ // and we calculate the size of the internal map
if (object->type == GD_MAZE_UNICURSAL)
{
- /* for unicursal maze, width and height must be mod2 = 0,
- and we will convert to paths & walls later */
+ // for unicursal maze, width and height must be mod2 = 0,
+ // and we will convert to paths & walls later
w = w / 2 * 2;
h = h / 2 * 2;
}
else
{
- /* for normal maze */
+ // for normal maze
w = 2 * (w - 1) + 1;
h = 2 * (h - 1) + 1;
}
- /* twodimensional boolean array to generate map in */
+ // twodimensional boolean array to generate map in
map = checked_malloc((h) * sizeof(boolean *));
for (y = 0; y < h; y++)
map[y] = checked_calloc(w * sizeof(boolean));
- /* start generation, if map is big enough.
- otherwise the application would crash, as the editor places maze objects
- during mouse click & drag that have no sense */
- rand = g_rand_new_with_seed(object->seed[level] == -1 ?
- g_rand_int(cave->random) : object->seed[level]);
+ // start generation, if map is big enough.
+ // otherwise the application would crash, as the editor places maze objects
+ // during mouse click & drag that have no sense
+ rand = gd_rand_new_with_seed(object->seed[level] == -1 ?
+ gd_rand_int(cave->random) : object->seed[level]);
if (w >= 1 && h >= 1)
mazegen(rand, map, w, h, 0, 0, object->horiz);
if (object->type == GD_MAZE_BRAID)
braidmaze(rand, map, w, h);
- g_rand_free(rand);
+ gd_rand_free(rand);
if (w >= 1 && h >= 1 && object->type == GD_MAZE_UNICURSAL)
{
boolean **unicursal;
- /* convert to unicursal maze */
+ // convert to unicursal maze
/* original:
xxx x
x x
}
}
- /* free original map */
+ // free original map
for (y = 0; y < h; y++)
free(map[y]);
free(map);
- /* change to new map - the unicursal maze */
+ // change to new map - the unicursal maze
map = unicursal;
h = h * 2 - 1;
w = w * 2 - 1;
}
- /* copy map to cave with correct elements and size */
+ // copy map to cave with correct elements and size
/* now copy the map into the cave. the copying works like this...
pwpwp
xxxxx p
for (j = 0; j < (x % 2 == 0 ? path : wall); j++)
gd_cave_store_rc(cave, xk++, yk, map[y][x] ? object->fill_element : object->element, object);
- /* if width is smaller than requested, fill with wall */
+ // if width is smaller than requested, fill with wall
for(x = xk; x <= x2; x++)
gd_cave_store_rc(cave, x, yk, object->element, object);
}
}
- /* if height is smaller than requested, fill with wall */
+ // if height is smaller than requested, fill with wall
for (y = yk; y <= y2; y++)
for (x = x1; x <= x2; x++)
gd_cave_store_rc(cave, x, y, object->element, object);
- /* free map */
+ // free map
for (y = 0; y < h; y++)
free(map[y]);
free(map);
int y1 = object->y1;
int x2 = object->x2;
int y2 = object->y2;
- GRand *rand;
+ GdRand *rand;
GdC64RandomGenerator c64_rand;
- guint32 seed;
+ unsigned int seed;
- /* -1 means that it should be different every time played. */
+ // -1 means that it should be different every time played.
if (object->seed[level] == -1)
- seed = g_rand_int(cave->random);
+ seed = gd_rand_int(cave->random);
else
seed = object->seed[level];
- rand = g_rand_new_with_seed(seed);
- /* for c64 random, use the 2*8 lsb. */
+ rand = gd_rand_new_with_seed(seed);
+ // for c64 random, use the 2*8 lsb.
gd_c64_random_set_seed(&c64_rand, seed / 256 % 256, seed % 256);
- /* change coordinates if not in correct order */
+ // change coordinates if not in correct order
if (y1 > y2)
{
y = y1;
GdElement element;
if (object->c64_random)
- /* use c64 random generator */
+ // use c64 random generator
randm = gd_c64_random(&c64_rand);
else
- /* use the much better glib random generator */
- randm = g_rand_int_range(rand, 0, 256);
+ // use the much better glib random generator
+ randm = gd_rand_int_range(rand, 0, 256);
element = object->fill_element;
if (randm < object->random_fill_probability[0])
if (randm < object->random_fill_probability[3])
element = object->random_fill[3];
- if (object->element==O_NONE ||
+ if (object->element == O_NONE ||
gd_cave_get_rc(cave, x, y) == object->element)
gd_cave_store_rc(cave, x, y, element, object);
}
}
- g_rand_free(rand);
+ gd_rand_free(rand);
}
static void draw_copy_paste(GdCave *cave, const GdObject *object)
{
int x1 = object->x1, y1 = object->y1, x2 = object->x2, y2 = object->y2;
- int x, y; /* iterators */
+ int x, y; // iterators
int w, h;
GdElement *clipboard;
- /* reorder coordinates if not drawing from northwest to southeast */
+ // reorder coordinates if not drawing from northwest to southeast
if (x2 < x1)
{
x = x2;
clipboard = checked_malloc((w * h) * sizeof(GdElement));
- /* copy to "clipboard" */
+ // copy to "clipboard"
for (y = 0; y < h; y++)
for (x = 0; x < w; x++)
clipboard[y * w + x] = gd_cave_get_rc(cave, x + x1, y + y1);
xdest = object->mirror ? w - 1 - x : x;
- /* dx and dy are used here are "paste to" coordinates */
+ // dx and dy are used here are "paste to" coordinates
gd_cave_store_rc(cave, object->dx + xdest, object->dy + ydest,
clipboard[y * w + x], object);
}
free(clipboard);
}
-/* draw the specified game object into cave's data.
- also remember, which cell was set by which cave object. */
+// draw the specified game object into cave's data.
+// also remember, which cell was set by which cave object.
void gd_cave_draw_object(GdCave *cave, const GdObject *object, int level)
{
switch (object->type)
{
case GD_POINT:
- /* single point */
+ // single point
gd_cave_store_rc(cave, object->x1, object->y1, object->element, object);
break;
}
}
-/* load cave to play... also can be called rendering the cave elements */
-GdCave *gd_cave_new_rendered(const GdCave *data, const int level, const guint32 seed)
+// load cave to play... also can be called rendering the cave elements
+GdCave *gd_cave_new_rendered(const GdCave *data, const int level, const unsigned int seed)
{
GdCave *cave;
GdElement element;
int x, y;
- GList *iter;
+ List *iter;
- /* make a copy */
+ // make a copy
cave = gd_cave_new_from_cave(data);
cave->rendered = level + 1;
cave->render_seed = seed;
- cave->random = g_rand_new_with_seed(cave->render_seed);
+ cave->random = gd_rand_new_with_seed(cave->render_seed);
- /* maps needed during drawing and gameplay */
- cave->objects_order = gd_cave_map_new(cave, gpointer);
+ // maps needed during drawing and gameplay
+ cave->objects_order = gd_cave_map_new(cave, void *);
cave->time = data->level_time[level];
cave->timevalue = data->level_timevalue[level];
if (!cave->map)
{
- /* if we have no map, fill with predictable random generator. */
+ // if we have no map, fill with predictable random generator.
cave->map = gd_cave_map_new(cave, GdElement);
- /* IF CAVE HAS NO MAP, USE THE RANDOM NUMBER GENERATOR */
- /* init c64 randomgenerator */
+ // IF CAVE HAS NO MAP, USE THE RANDOM NUMBER GENERATOR
+ // init c64 randomgenerator
if (data->level_rand[level] < 0)
- gd_cave_c64_random_set_seed(cave, g_rand_int_range(cave->random, 0, 256),
- g_rand_int_range(cave->random, 0, 256));
+ gd_cave_c64_random_set_seed(cave, gd_rand_int_range(cave->random, 0, 256),
+ gd_rand_int_range(cave->random, 0, 256));
else
gd_cave_c64_random_set_seed(cave, 0, data->level_rand[level]);
- /* generate random fill
- * start from row 1 (0 skipped), and fill also the borders on left and right hand side,
- * as c64 did. this way works the original random generator the right way.
- * also, do not fill last row, that is needed for the random seeds to be correct
- * after filling! predictable slime will use it. */
+ // generate random fill
+ //
+ // start from row 1 (0 skipped), and fill also the borders on left and right hand side,
+ // as c64 did. this way works the original random generator the right way.
+ // also, do not fill last row, that is needed for the random seeds to be correct
+ // after filling! predictable slime will use it.
for (y = 1; y < cave->h - 1; y++)
{
for (x = 0; x < cave->w; x++)
unsigned int randm;
if (data->level_rand[level] < 0)
- /* use the much better glib random generator */
- randm = g_rand_int_range(cave->random, 0, 256);
+ // use the much better glib random generator
+ randm = gd_rand_int_range(cave->random, 0, 256);
else
- /* use c64 */
+ // use c64
randm = gd_cave_c64_random(cave);
element = data->initial_fill;
}
}
- /* draw initial border */
+ // draw initial border
for (y = 0; y < cave->h; y++)
{
gd_cave_store_rc(cave, 0, y, cave->initial_border, NULL);
gd_cave_store_rc(cave, x, 0, cave->initial_border, NULL);
gd_cave_store_rc(cave, x, cave->h - 1, cave->initial_border, NULL);
}
+
+ // store if random number generator needs correction for static random seed
+ cave->slime_correct_random = (data->level_rand[level] >= 0);
}
else
{
- /* IF CAVE HAS A MAP, SIMPLY USE IT... no need to fill with random elements */
+ // IF CAVE HAS A MAP, SIMPLY USE IT... no need to fill with random elements
- /* initialize c64 predictable random for slime.
- the values were taken from afl bd, see docs/internals.txt */
+ // initialize c64 predictable random for slime.
+ // the values were taken from afl bd, see docs/internals.txt
gd_cave_c64_random_set_seed(cave, 0, 0x1e);
+
+ // correct random number generator if cave was rendered with static random seed
+ if (cave->slime_correct_random)
+ {
+ int i;
+
+ // set static random seed used when rendering the cave
+ gd_cave_c64_random_set_seed(cave, 0, data->level_rand[level]);
+
+ for (i = 0; i < cave->w * (cave->h - 2); i++)
+ gd_cave_c64_random(cave);
+ }
}
if (data->level_slime_seed_c64[level] != -1)
{
- /* if a specific slime seed is requested, change it now. */
+ // if a specific slime seed is requested, change it now.
gd_cave_c64_random_set_seed(cave,
data->level_slime_seed_c64[level] / 256,
data->level_slime_seed_c64[level] % 256);
}
- /* render cave objects above random data or map */
- for (iter = data->objects; iter; iter = g_list_next(iter))
+ // render cave objects above random data or map
+ for (iter = data->objects; iter; iter = list_next(iter))
{
GdObject *object = (GdObject *)iter->data;
gd_cave_draw_object(cave, iter->data, level);
}
- /* check if we use c64 ckdelay or milliseconds for timing */
+ // check if we use c64 ckdelay or milliseconds for timing
if (cave->scheduling == GD_SCHEDULING_MILLISECONDS)
- cave->speed = data->level_speed[level]; /* exact timing */
+ cave->speed = data->level_speed[level]; // exact timing
else
{
- /* delay loop based timing... set something for first iteration,
- then later it will be calculated */
+ // delay loop based timing... set something for first iteration,
+ // then later it will be calculated
cave->speed = 120;
- /* this one may be used by iterate routine to calculate actual delay
- if c64scheduling is selected */
+ // this one may be used by iterate routine to calculate actual delay
+ // if c64scheduling is selected
cave->c64_timing = data->level_ckdelay[level];
}
}
/*
- render cave at specified level.
- copy result to the map; remove objects.
- the cave will be map-based.
- */
+ render cave at specified level.
+ copy result to the map; remove objects.
+ the cave will be map-based.
+*/
void gd_flatten_cave(GdCave *cave, const int level)
{
GdCave *rendered;
if (cave == NULL)
return;
- /* render cave at specified level to obtain map. seed = 0 */
+ // render cave at specified level to obtain map. seed = 0
rendered = gd_cave_new_rendered(cave, level, 0);
- /* forget old map without objects */
+ // forget old map without objects
gd_cave_map_free(cave->map);
- /* copy new map to cave */
+ // copy new map to cave
cave->map = gd_cave_map_dup(rendered, map);
gd_cave_free(rendered);
- /* forget objects */
- g_list_foreach(cave->objects, (GFunc) free, NULL);
+ // forget objects
+ list_foreach(cave->objects, (list_fn) free, NULL);
cave->objects = NULL;
}