/* * Copyright (c) Camden Dixie O'Brien * SPDX-License-Identifier: AGPL-3.0-only */ #include #include #include #include #include #define TILESIZE 32 #define WINWIDTH 30 #define WINHEIGHT 20 #define MAX_PATH_LEN 128 #define MAP_ASSET "/map.tmx" #define MAPWIDTH 112 #define MAPHEIGHT 112 #define MAPSHIFTX 48 #define MAPSHIFTY 48 static SDL_Window *window; static SDL_Renderer *renderer; static unsigned map[MAPWIDTH][MAPHEIGHT]; int main(int argc, char *argv[]) { char path[MAX_PATH_LEN]; if (2 != argc) { fprintf(stderr, "Usage: %s ASSETS-DIR\n", argv[0]); return 1; } int err = SDL_Init(SDL_INIT_VIDEO); assert(0 == err); window = SDL_CreateWindow( "2D Game", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, TILESIZE * WINWIDTH, TILESIZE * WINHEIGHT, 0); assert(NULL != window); renderer = SDL_CreateRenderer(window, -1, 0); assert(NULL != renderer); xmlDocPtr doc; xmlNodePtr node; 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); 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; } } } SDL_Event event; SDL_RenderClear(renderer); while (1) { SDL_PollEvent(&event); switch (event.type) { case SDL_QUIT: goto quit; default: break; } } quit: SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); SDL_Quit(); return 0; }