Load object bounding box from objectsprites XML

This commit is contained in:
Camden Dixie O'Brien 2025-01-04 16:10:14 +00:00
parent 3f8ac4f890
commit 48ae6b7873

View File

@ -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