Load and draw additional layers

This commit is contained in:
Camden Dixie O'Brien 2024-12-31 13:55:34 +00:00
parent 8de374bcfb
commit 0aab456433

View File

@ -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);
}
}
}
}