From 48ae6b7873225d0c69738aeae02cf281db4480b0 Mon Sep 17 00:00:00 2001 From: Camden Dixie O'Brien Date: Sat, 4 Jan 2025 16:10:14 +0000 Subject: [PATCH] Load object bounding box from objectsprites XML --- game/main.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 55 insertions(+), 6 deletions(-) diff --git a/game/main.c b/game/main.c index e02c0cf..639c5c8 100644 --- a/game/main.c +++ b/game/main.c @@ -32,6 +32,8 @@ #define MAPMINY (TILESIZE * (-32)) #define MAPMAXY (TILESIZE * 32) +#define OBJSPRITES "/objectsprites.tsx" + #define TSASSET "/overworld.png" #define TSCOLS 40 @@ -118,12 +120,14 @@ typedef struct { unsigned animframes; SDL_Rect src; SDL_Texture *tex; + dbox_t bbox; } objtype_t; typedef struct { entity_t e; unsigned type; ivec_t pos; + dbox_t bbox; } objentity_t; typedef struct { @@ -240,8 +244,9 @@ static void load_layer(map_t map, xmlNodePtr layernode, int layeridx) } } -static unsigned -load_objtype(gamestate_t *state, const char *templ, SDL_Renderer *renderer) +static unsigned load_objtype( + gamestate_t *state, const char *templ, SDL_Renderer *renderer, + xmlNodePtr sprites) { static char buf[MAX_PATH_LEN]; assert(strlen(state->assetdir) + strlen(templ) + 1 < MAX_PATH_LEN); @@ -249,18 +254,23 @@ load_objtype(gamestate_t *state, const char *templ, SDL_Renderer *renderer) strcat(buf, "/"); strcat(buf, templ); - // Identify object type ID + // Identify object type ID and sprite ID xmlDocPtr doc = xmlParseFile(buf); assert(NULL != doc); xmlNodePtr node = xmlDocGetRootElement(doc); assert(NULL != node); assert(xmlStrcmp(node->name, (const xmlChar *)"template") == 0); node = node->xmlChildrenNode; + while (node != NULL + && xmlStrcmp(node->name, (const xmlChar *)"tileset") != 0) + node = node->next; + assert(NULL != node); + const int sidoff = prop_int(node, "firstgid"); while (node != NULL && xmlStrcmp(node->name, (const xmlChar *)"object") != 0) node = node->next; assert(NULL != node); - unsigned id = prop_int(node, "gid"); + const unsigned id = prop_int(node, "type"); assert(id < MAXOBJTYPES); // Populate objtype struct if not already loaded @@ -270,6 +280,31 @@ load_objtype(gamestate_t *state, const char *templ, SDL_Renderer *renderer) state->objtypes[id].src.w = prop_int(node, "width"); state->objtypes[id].src.h = prop_int(node, "height"); + // Load bounding box from sprites document + const int sid = prop_int(node, "gid") - sidoff; + xmlNodePtr snode = sprites->xmlChildrenNode; + while (snode + && (xmlStrcmp(snode->name, (const xmlChar *)"tile") != 0 + || prop_int(snode, "id") != sid)) + snode = snode->next; + assert(snode); + snode = snode->xmlChildrenNode; + while (snode + && xmlStrcmp(snode->name, (const xmlChar *)"objectgroup") + != 0) + snode = snode->next; + assert(snode); + snode = snode->xmlChildrenNode; + while (snode + && xmlStrcmp(snode->name, (const xmlChar *)"object") != 0) + snode = snode->next; + assert(snode); + state->objtypes[id].bbox.off.x = (double)prop_int(snode, "x"); + state->objtypes[id].bbox.off.y = (double)prop_int(snode, "y"); + state->objtypes[id].bbox.ext.x = (double)prop_int(snode, "width"); + state->objtypes[id].bbox.ext.y = (double)prop_int(snode, "height"); + + // Load custom properties node = node->xmlChildrenNode; while (node != NULL && xmlStrcmp(node->name, (const xmlChar *)"properties") != 0) @@ -307,6 +342,13 @@ load_objtype(gamestate_t *state, const char *templ, SDL_Renderer *renderer) static void load_objects(gamestate_t *state, xmlNodePtr node, SDL_Renderer *renderer) { + char path[MAX_PATH_LEN]; + assert(strlen(state->assetdir) + strlen(OBJSPRITES) < MAX_PATH_LEN); + strcpy(path, state->assetdir); + strcat(path, OBJSPRITES); + xmlDocPtr spritesdoc = xmlParseFile(path); + xmlNodePtr sprites = xmlDocGetRootElement(spritesdoc); + state->objcol.n = 0; state->objcol.cap = INITOBJCOLCAP; state->objcol.buf = malloc(sizeof(objentity_t) * state->objcol.cap); @@ -331,13 +373,20 @@ load_objects(gamestate_t *state, xmlNodePtr node, SDL_Renderer *renderer) // Load object type xmlChar *templ = xmlGetProp(node, (const xmlChar *)"template"); assert(templ); - o->type = load_objtype(state, (const char *)templ, renderer); + o->type + = load_objtype(state, (const char *)templ, renderer, sprites); xmlFree(templ); + const objtype_t *type = state->objtypes + o->type; // Load object location o->pos.x = prop_int(node, "x"); - o->pos.y = prop_int(node, "y"); + o->pos.y = prop_int(node, "y") - type->src.h; + + // Load bounding box from object type + o->bbox = type->bbox; } while ((node = node->next) != NULL); + + xmlFreeDoc(spritesdoc); } static void