summaryrefslogtreecommitdiffstats
path: root/src/maze.c
diff options
context:
space:
mode:
authorP. J. McDermott <pj@pehjota.net>2021-08-08 16:59:35 (EDT)
committer P. J. McDermott <pj@pehjota.net>2021-08-08 17:00:19 (EDT)
commit1af3d32d9c0e44c770de442be8dad7be05ae02d4 (patch)
treefb3dc4408559bc96086b7a685df624053e7ccadc /src/maze.c
parentc234b317843200c5059c57c16621fb722f579fb0 (diff)
downloadmazefight-1af3d32d9c0e44c770de442be8dad7be05ae02d4.zip
mazefight-1af3d32d9c0e44c770de442be8dad7be05ae02d4.tar.gz
mazefight-1af3d32d9c0e44c770de442be8dad7be05ae02d4.tar.bz2
maze: Optionally hide unseen walls
Diffstat (limited to 'src/maze.c')
-rw-r--r--src/maze.c69
1 files changed, 64 insertions, 5 deletions
diff --git a/src/maze.c b/src/maze.c
index 028e940..d991328 100644
--- a/src/maze.c
+++ b/src/maze.c
@@ -24,7 +24,9 @@
struct mf_maze {
int w;
int h;
+ int show_all;
unsigned int *walls;
+ unsigned int *show;
unsigned int *visited;
};
@@ -69,6 +71,47 @@ mf_maze_is_wall(struct mf_maze *m, int x, int y, int dx, int dy)
& 1 << (i % (sizeof(*m->walls)*8)));
}
+void
+mf_maze_reveal_wall(struct mf_maze *m, int x, int y, int dx, int dy)
+{
+ int i;
+
+ if (x + dx < 0 || x + dx >= m->w || y + dy < 0 || y + dy >= m->h) {
+ return;
+ }
+
+ if (dx < 0) --x;
+ if (dy < 0) --y;
+ i = y * m->w + x;
+ i *= 2;
+ if (dx == 0) ++i; /* Moving vertically */
+
+ m->show[i / (sizeof(*m->show)*8)] |= 1 << (i % (sizeof(*m->show)*8));
+}
+
+static int
+_mf_maze_revealed_wall(struct mf_maze *m, int x, int y, int dx, int dy)
+{
+ int i;
+
+ if (m->show_all) {
+ return 1;
+ }
+
+ if (x + dx < 0 || x + dx >= m->w || y + dy < 0 || y + dy >= m->h) {
+ return 1;
+ }
+
+ if (dx < 0) --x;
+ if (dy < 0) --y;
+ i = y * m->w + x;
+ i *= 2;
+ if (dx == 0) ++i; /* Moving vertically */
+
+ return m->show[i / (sizeof(*m->show)*8)]
+ & 1 << (i % (sizeof(*m->show)*8));
+}
+
static void
_mf_maze_visit(struct mf_maze *m, int x, int y)
{
@@ -128,7 +171,7 @@ _mf_maze_carve(struct mf_maze *m, int x, int y)
}
struct mf_maze *
-mf_maze_new(int s, int w, int h)
+mf_maze_new(int s, int w, int h, int show_all)
{
struct mf_maze *m;
int x;
@@ -147,19 +190,30 @@ mf_maze_new(int s, int w, int h)
free(m);
return NULL;
}
+ m->show = calloc(
+ (w * h * 2 + sizeof(*m->show)*8 - 1) /
+ (sizeof(*m->show)*8),
+ sizeof(*m->show));
+ if (m->show == NULL) {
+ free(m->walls);
+ free(m);
+ return NULL;
+ }
m->visited = calloc(
((w+2) * (h+2) + sizeof(*m->visited)*8 - 1) /
(sizeof(*m->visited)*8),
sizeof(*m->visited));
if (m->visited == NULL) {
+ free(m->show);
free(m->walls);
free(m);
return NULL;
}
/* Initialize parameters */
- m->w = w;
- m->h = h;
+ m->w = w;
+ m->h = h;
+ m->show_all = show_all;
/* Mark edges as visited */
for (x = -1; x <= w; ++x) {
@@ -198,7 +252,8 @@ mf_maze_render(struct mf_maze *m, SDL_Renderer *renderer, SDL_Color *color,
}
for (y = 0; y < m->h; ++y) {
for (x = 0; x < m->w; ++x) {
- if (y < m->h - 1 && mf_maze_is_wall(m, x, y, 0, 1)) {
+ if (y < m->h - 1 && mf_maze_is_wall(m, x, y, 0, 1) &&
+ _mf_maze_revealed_wall(m, x, y, 0, 1)) {
/* Draw h line */
if (SDL_RenderDrawLine(renderer,
(x ) * cw, (y+1) * cw,
@@ -211,7 +266,8 @@ mf_maze_render(struct mf_maze *m, SDL_Renderer *renderer, SDL_Color *color,
e = -1;
}
}
- if (x < m->w - 1 && mf_maze_is_wall(m, x, y, 1, 0)) {
+ if (x < m->w - 1 && mf_maze_is_wall(m, x, y, 1, 0) &&
+ _mf_maze_revealed_wall(m, x, y, 1, 0)) {
/* Draw v line */
if (SDL_RenderDrawLine(renderer,
(x+1) * cw, (y ) * cw,
@@ -243,6 +299,9 @@ mf_maze_destroy(struct mf_maze **m_p)
if (m->walls != NULL) {
free(m->walls);
}
+ if (m->show != NULL) {
+ free(m->show);
+ }
free(m);
m = NULL;
}