From 1af3d32d9c0e44c770de442be8dad7be05ae02d4 Mon Sep 17 00:00:00 2001 From: P. J. McDermott Date: Sun, 08 Aug 2021 16:59:35 -0400 Subject: maze: Optionally hide unseen walls --- (limited to 'src/maze.c') 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; } -- cgit v0.9.1