From 8de374bcfb2ec7aa946ca239d49ec0b2c562fd67 Mon Sep 17 00:00:00 2001 From: Camden Dixie O'Brien Date: Tue, 31 Dec 2024 13:15:57 +0000 Subject: [PATCH] Extract map logic into functions --- app/main.c | 196 +++++++++++++++++++++++++++-------------------------- 1 file changed, 101 insertions(+), 95 deletions(-) diff --git a/app/main.c b/app/main.c index c40cf1f..4339722 100644 --- a/app/main.c +++ b/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); }