diff --git a/app/main.c b/app/main.c index 4339722..699d264 100644 --- a/app/main.c +++ b/app/main.c @@ -21,6 +21,7 @@ #define MAX_PATH_LEN 128 #define MAP_ASSET "/map.tmx" +#define MAPNLAYERS 2 #define MAPWIDTH 64 #define MAPHEIGHT 64 #define MAPSHIFTX 32 @@ -86,7 +87,7 @@ typedef struct { static SDL_Window *window; static SDL_Renderer *renderer; -static unsigned map[MAPWIDTH][MAPHEIGHT]; +static unsigned map[MAPNLAYERS][MAPWIDTH][MAPHEIGHT]; static SDL_Texture *tstex, *pidle, *pwalk; static input_state_t input; static dvec_t vpos = { -128, -96 }; @@ -102,19 +103,19 @@ static inline double dot(dvec_t v, dvec_t u) return v.x * u.x + v.y * u.y; } -static inline unsigned tileat(double x, double y) +static inline unsigned tileat(int layeridx, double x, double y) { const unsigned row = (unsigned)floor(x / TILESIZE) + MAPSHIFTX; const unsigned col = (unsigned)floor(y / TILESIZE) + MAPSHIFTY; if (row >= MAPWIDTH || col >= MAPHEIGHT) return 0; else - return map[row][col]; + return map[layeridx][row][col]; } static inline bool tilepassable(int x, int y) { - const unsigned id = tileat(x, y); + const unsigned id = tileat(0, x, y); for (unsigned i = 0; i < NELEMS(impassable); ++i) { if (impassable[i] == id) return false; @@ -122,21 +123,9 @@ static inline bool tilepassable(int x, int y) return true; } -static void mapload(const char *path) +static void maploadlayer(xmlNodePtr layernode, int layeridx) { - // Find chunk nodes in map XML - xmlDocPtr doc; - xmlNodePtr node; - doc = xmlParseFile(path); - assert(NULL != doc); - node = xmlDocGetRootElement(doc); - assert(0 == xmlStrcmp(node->name, (const xmlChar *)"map")); - node = node->xmlChildrenNode; - while (NULL != node - && xmlStrcmp(node->name, (const xmlChar *)"layer") != 0) - node = node->next; - assert(NULL != node); - node = node->xmlChildrenNode; + xmlNodePtr node = layernode->xmlChildrenNode; while (NULL != node && xmlStrcmp(node->name, (const xmlChar *)"data") != 0) node = node->next; @@ -170,7 +159,7 @@ static void mapload(const char *path) memset(buf, 0, sizeof(buf)); memcpy(buf, p, sizeof(xmlChar) * (q - p)); assert(x < MAPWIDTH && y < MAPHEIGHT); - map[x][y] = (unsigned)atoi((const char *)buf); + map[layeridx][x][y] = (unsigned)atoi((const char *)buf); ++x; p = ++q; break; @@ -179,7 +168,7 @@ static void mapload(const char *path) memset(buf, 0, sizeof(buf)); memcpy(buf, p, sizeof(xmlChar) * (q - p)); assert(y < MAPHEIGHT); - map[x][y] = (unsigned)atoi((const char *)buf); + map[layeridx][x][y] = (unsigned)atoi((const char *)buf); } x = chunk_x + MAPSHIFTX; ++y; @@ -193,28 +182,49 @@ static void mapload(const char *path) } } +static void mapload(const char *path) +{ + xmlDocPtr doc; + xmlNodePtr node; + doc = xmlParseFile(path); + assert(NULL != doc); + node = xmlDocGetRootElement(doc); + assert(0 == xmlStrcmp(node->name, (const xmlChar *)"map")); + node = node->xmlChildrenNode; + for (int l = 0; l < MAPNLAYERS; ++l) { + do + node = node->next; + while (NULL != node + && xmlStrcmp(node->name, (const xmlChar *)"layer") != 0); + assert(NULL != node); + maploadlayer(node, l); + } +} + static void mapdraw(void) { const int startx = TILESIZE * floor(vpos.x / TILESIZE); const int starty = TILESIZE * floor(vpos.y / TILESIZE); - for (int y = starty; y < vpos.y + VIEWHEIGHT; y += TILESIZE) { - for (int x = startx; x < vpos.x + VIEWWIDTH; x += TILESIZE) { - const unsigned tileid = tileat(x, y); - if (0 == tileid) - continue; - const SDL_Rect src = { - .x = TILESIZE * ((tileid - 1) % TSCOLS), - .y = TILESIZE * ((tileid - 1) / TSCOLS), - .w = TILESIZE, - .h = TILESIZE, - }; - const SDL_Rect dest = { - .x = SCALE * (x - vpos.x), - .y = SCALE * (y - vpos.y), - .w = SCALE * TILESIZE, - .h = SCALE * TILESIZE, - }; - SDL_RenderCopy(renderer, tstex, &src, &dest); + for (int l = 0; l < MAPNLAYERS; ++l) { + for (int y = starty; y < vpos.y + VIEWHEIGHT; y += TILESIZE) { + for (int x = startx; x < vpos.x + VIEWWIDTH; x += TILESIZE) { + const unsigned tileid = tileat(l, x, y); + if (0 == tileid) + continue; + const SDL_Rect src = { + .x = TILESIZE * ((tileid - 1) % TSCOLS), + .y = TILESIZE * ((tileid - 1) / TSCOLS), + .w = TILESIZE, + .h = TILESIZE, + }; + const SDL_Rect dest = { + .x = SCALE * (x - vpos.x), + .y = SCALE * (y - vpos.y), + .w = SCALE * TILESIZE, + .h = SCALE * TILESIZE, + }; + SDL_RenderCopy(renderer, tstex, &src, &dest); + } } } }