Extract map logic into functions
This commit is contained in:
parent
b39189b6d1
commit
8de374bcfb
196
app/main.c
196
app/main.c
@ -122,6 +122,103 @@ static inline bool tilepassable(int x, int y)
|
||||
return true;
|
||||
}
|
||||
|
||||
static void mapload(const char *path)
|
||||
{
|
||||
// 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;
|
||||
while (NULL != node
|
||||
&& xmlStrcmp(node->name, (const xmlChar *)"data") != 0)
|
||||
node = node->next;
|
||||
assert(NULL != node);
|
||||
|
||||
// Iterate through chunks and populate map array.
|
||||
xmlNodePtr chunk_contents;
|
||||
for (node = node->xmlChildrenNode; NULL != node; node = node->next) {
|
||||
if (0 != xmlStrcmp(node->name, (const xmlChar *)"chunk"))
|
||||
continue;
|
||||
|
||||
xmlChar *x_attr, *y_attr;
|
||||
x_attr = xmlGetProp(node, (const xmlChar *)"x");
|
||||
y_attr = xmlGetProp(node, (const xmlChar *)"y");
|
||||
const int chunk_x = atoi((const char *)x_attr);
|
||||
const int chunk_y = atoi((const char *)y_attr);
|
||||
|
||||
chunk_contents = node->xmlChildrenNode;
|
||||
assert(
|
||||
0 == xmlStrcmp(chunk_contents->name, (const xmlChar *)"text"));
|
||||
int x = chunk_x + MAPSHIFTX, y = chunk_y + MAPSHIFTY;
|
||||
xmlChar buf[10];
|
||||
const xmlChar *p, *q;
|
||||
q = chunk_contents->content;
|
||||
while (isspace((const char)*q))
|
||||
++q;
|
||||
p = q;
|
||||
while ('\0' != *q) {
|
||||
switch (*q) {
|
||||
case (xmlChar)',':
|
||||
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);
|
||||
++x;
|
||||
p = ++q;
|
||||
break;
|
||||
case (xmlChar)'\n':
|
||||
if (x < MAPWIDTH) {
|
||||
memset(buf, 0, sizeof(buf));
|
||||
memcpy(buf, p, sizeof(xmlChar) * (q - p));
|
||||
assert(y < MAPHEIGHT);
|
||||
map[x][y] = (unsigned)atoi((const char *)buf);
|
||||
}
|
||||
x = chunk_x + MAPSHIFTX;
|
||||
++y;
|
||||
p = ++q;
|
||||
break;
|
||||
default:
|
||||
++q;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void entityupdate(entity_t *e, double dt)
|
||||
{
|
||||
if (0 == e->speed)
|
||||
@ -193,76 +290,11 @@ int main(int argc, char *argv[])
|
||||
renderer = SDL_CreateRenderer(window, -1, 0);
|
||||
assert(NULL != renderer);
|
||||
|
||||
// Find chunk nodes in map XML
|
||||
xmlDocPtr doc;
|
||||
xmlNodePtr node;
|
||||
// Load map
|
||||
assert(strlen(argv[1]) + strlen(MAP_ASSET) < MAX_PATH_LEN);
|
||||
strcpy(path, argv[1]);
|
||||
strcat(path, MAP_ASSET);
|
||||
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;
|
||||
while (NULL != node
|
||||
&& xmlStrcmp(node->name, (const xmlChar *)"data") != 0)
|
||||
node = node->next;
|
||||
assert(NULL != node);
|
||||
|
||||
// Iterate through chunks and populate map array.
|
||||
xmlNodePtr chunk_contents;
|
||||
for (node = node->xmlChildrenNode; NULL != node; node = node->next) {
|
||||
if (0 != xmlStrcmp(node->name, (const xmlChar *)"chunk"))
|
||||
continue;
|
||||
|
||||
xmlChar *x_attr, *y_attr;
|
||||
x_attr = xmlGetProp(node, (const xmlChar *)"x");
|
||||
y_attr = xmlGetProp(node, (const xmlChar *)"y");
|
||||
const int chunk_x = atoi((const char *)x_attr);
|
||||
const int chunk_y = atoi((const char *)y_attr);
|
||||
|
||||
chunk_contents = node->xmlChildrenNode;
|
||||
assert(
|
||||
0 == xmlStrcmp(chunk_contents->name, (const xmlChar *)"text"));
|
||||
int x = chunk_x + MAPSHIFTX, y = chunk_y + MAPSHIFTY;
|
||||
xmlChar buf[10];
|
||||
const xmlChar *p, *q;
|
||||
q = chunk_contents->content;
|
||||
while (isspace((const char)*q))
|
||||
++q;
|
||||
p = q;
|
||||
while ('\0' != *q) {
|
||||
switch (*q) {
|
||||
case (xmlChar)',':
|
||||
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);
|
||||
++x;
|
||||
p = ++q;
|
||||
break;
|
||||
case (xmlChar)'\n':
|
||||
if (x < MAPWIDTH) {
|
||||
memset(buf, 0, sizeof(buf));
|
||||
memcpy(buf, p, sizeof(xmlChar) * (q - p));
|
||||
assert(y < MAPHEIGHT);
|
||||
map[x][y] = (unsigned)atoi((const char *)buf);
|
||||
}
|
||||
x = chunk_x + MAPSHIFTX;
|
||||
++y;
|
||||
p = ++q;
|
||||
break;
|
||||
default:
|
||||
++q;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
mapload(path);
|
||||
|
||||
// Load tileset
|
||||
assert(strlen(argv[1]) + strlen(TSASSET) < MAX_PATH_LEN);
|
||||
@ -354,7 +386,7 @@ int main(int argc, char *argv[])
|
||||
break;
|
||||
}
|
||||
|
||||
// Calculate and apply velocity
|
||||
// Calculate player velocity and update player
|
||||
p.dir.x = (input.left ? -1 : 0) + (input.right ? 1 : 0);
|
||||
p.dir.y = (input.up ? -1 : 0) + (input.down ? 1 : 0);
|
||||
const double dmag = mag(p.dir);
|
||||
@ -386,34 +418,8 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
SDL_RenderClear(renderer);
|
||||
|
||||
// Draw map
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
// Draw player
|
||||
mapdraw();
|
||||
entitydraw(&p, t);
|
||||
|
||||
SDL_RenderPresent(renderer);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user