[Change] Special effects are no longer hardcoded.

This commit is contained in:
Allanis 2014-07-20 21:18:53 +01:00
parent 405cf65b83
commit 39435c6330
2 changed files with 138 additions and 40 deletions

44
dat/spfx.xml Normal file
View File

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<spfxs>
<spfx name="ExpS">
<gfx x="6" y="5">exps</gfx>
<anim>400</anim>
</spfx>
<spfx name="ExpM">
<gfx x="6" y="5">expm</gfx>
<anim>450</anim>
</spfx>
<spfx name="ExpL">
<gfx x="6" y="5">expl</gfx>
<anim>500</anim>
</spfx>
<spfx name="cargo">
<gfx x="6" y="6">cargo</gfx>
<ttl>15000</ttl>
<anim>5000</anim>
</spfx>
<spfx name="EmpS">
<gfx x="6" y="5">emps</gfx>
<anim>400</anim>
</spfx>
<spfx name="EmpM">
<gfx x="6" y="5">empm</gfx>
<anim>450</anim>
</spfx>
<spfx name="ShiS">
<gfx x="6" y="5">shis</gfx>
<anim>400</anim>
</spfx>
<spfx name="ShiM">
<gfx x="6" y="5">shim</gfx>
<anim>450</anim>
</spfx>
<spfx name="PlaS">
<gfx x="6" y="5">plas</gfx>
<anim>400</anim>
</spfx>
<spfx name="PlaM">
<gfx x="6" y="5">plam</gfx>
<anim>450</anim>
</spfx>
</spfxs>

View File

@ -16,13 +16,22 @@
#include "opengl.h" #include "opengl.h"
#include "pause.h" #include "pause.h"
#include "rng.h" #include "rng.h"
#include "ldata.h"
#include "lxml.h"
#include "spfx.h" #include "spfx.h"
#define SPFX_GFX "../gfx/spfx/" /**< Graphics location. */ #define SPFX_XML_ID "spfxs" /**< XML Document tag. */
#define SPFX_CHUNK 32 /**< Chunk to allocate when needed. */ #define SPFX_XML_TAG "spfx" /**< SPFX XML node tag. */
#define SHAKE_VEL_MOD 0.0008 /**< Shake modifier. */
#define HAPTIC_UPDATE_INTERVAL 0.1 /**< Time between haptic updates. */ #define SPFX_DATA "../dat/spfx.xml" /**< Location of the spfx datafile. */
#define SPFX_GFX_PRE "../gfx/spfx/" /**< Location of the graphic. */
#define SPFX_GFX_SUF ".png" /**< Suffix of graphics. */
#define CHUNK_SIZE 32 /**< Chunk size to allocate spfx bases. */
#define SPFX_CHUNK 32 /**< Chunk to allocate when needed. */
#define SHAKE_VEL_MOD 0.0008 /**< Shake modifier. */
#define HAPTIC_UPDATE_INTERVAL 0.1 /**< Time between haptic updates. */
/* Special hardcoded effects.. */ /* Special hardcoded effects.. */
@ -81,7 +90,7 @@ static int spfx_nstack_back = 0; /**< Number of special effects in the
static int spfx_mstack_back = 0; /**< Memory allocated for special effects in back. */ static int spfx_mstack_back = 0; /**< Memory allocated for special effects in back. */
/* General. */ /* General. */
static int spfx_base_load(char* name, int ttl, int anim, char* gfx, int sx, int sy); static int spfx_base_parse(SPFX_Base* tmp, const xmlNodePtr parent);
static void spfx_base_free(SPFX_Base* effect); static void spfx_base_free(SPFX_Base* effect);
static void spfx_destroy(SPFX* layer, int* nlayer, int spfx); static void spfx_destroy(SPFX* layer, int* nlayer, int spfx);
static void spfx_update_layer(SPFX* layer, int* nlayer, const double dt); static void spfx_update_layer(SPFX* layer, int* nlayer, const double dt);
@ -90,28 +99,42 @@ static int spfx_hapticInit(void);
static void spfx_hapticRumble(double mod); static void spfx_hapticRumble(double mod);
/** /**
* @brief Load an SPFX_Base into the stack based on some params. * @brief Parse an xml node containing an spfx.
* @param name Name of the spfx. * @param tmp Address to load sfx into.
* @param ttl Time to live of the spfx. * @param parent XML node containing the spfx data.
* @param gfx Name of the graphic effect to use.
* @param sx Number of x sprites in the graphic.
* @param sy Number of y sprites in the graphic.
* @return 0 on success. * @return 0 on success.
*/ */
static int spfx_base_load(char* name, int ttl, int anim, char* gfx, int sx, int sy) { static int spfx_base_parse(SPFX_Base* tmp, const xmlNodePtr parent) {
SPFX_Base* cur; xmlNodePtr node;
char buf[PATH_MAX];
/* Create new effect. */ /* Clear data. */
spfx_effects = realloc(spfx_effects, ++spfx_neffects*sizeof(SPFX_Base)); memset(tmp, 0, sizeof(SPFX_Base));
cur = &spfx_effects[spfx_neffects-1];
/* Fill it with the data. */ /* Get the name (mallocs). */
cur->name = strdup(name); tmp->name = xml_nodeProp(parent, "name");
cur->anim = (double)anim / 1000.;
cur->ttl = (double)ttl / 1000.; /* Extract the data. */
snprintf(buf, PATH_MAX, SPFX_GFX"%s", gfx); node = parent->xmlChildrenNode;
cur->gfx = gl_newSprite(buf, sx, sy, 0); do {
xmlr_float(node, "anim", tmp->anim);
xmlr_float(node, "ttl", tmp->ttl);
if(xml_isNode(node, "gfx"))
tmp->gfx = xml_parseTexture(node,
SPFX_GFX_PRE"%s"SPFX_GFX_SUF, 6, 5, 0);
} while(xml_nextNode(node));
/* Convert from ms to s. */
tmp->anim /= 1000.;
tmp->ttl /= 1000.;
if(tmp->ttl == 0.)
tmp->ttl = tmp->anim;
#define MELEMENT(o,s) \
if(o) WARN("SPFX '%s' missing/invalid '"s"' element", tmp->name) /**< Define to help check for data errors. */
MELEMENT(tmp->anim == 0., "anim");
MELEMENT(tmp->ttl == 0., "ttl");
MELEMENT(tmp->gfx == NULL, "gfx");
#undef ELEMENT
return 0; return 0;
} }
@ -121,8 +144,14 @@ static int spfx_base_load(char* name, int ttl, int anim, char* gfx, int sx, int
* @param effect SPFX_Base to free. * @param effect SPFX_Base to free.
*/ */
static void spfx_base_free(SPFX_Base* effect) { static void spfx_base_free(SPFX_Base* effect) {
if(effect->name != NULL) free(effect->name); if(effect->name != NULL) {
if(effect->gfx != NULL) gl_freeTexture(effect->gfx); free(effect->name);
effect->name = NULL;
}
if(effect->gfx != NULL) {
gl_freeTexture(effect->gfx);
effect->gfx = NULL;
}
} }
/** /**
@ -146,22 +175,47 @@ int spfx_get(char* name) {
* @todo Make spfx not hardcoded. * @todo Make spfx not hardcoded.
*/ */
int spfx_load(void) { int spfx_load(void) {
/* Standard explosion effects. */ int mem;
spfx_base_load("ExpS", 400, 400, "exps.png", 6, 5); uint32_t bufsize;
spfx_base_load("ExpM", 450, 450, "expm.png", 6, 5); char* buf;
spfx_base_load("ExpL", 500, 500, "expl.png", 6, 5); xmlNodePtr node;
/* Cargo Rotation. */ xmlDocPtr doc;
spfx_base_load("cargo", 15000, 5000, "cargo.png", 6, 6);
/* EMP Blasts. */
spfx_base_load("EmpS", 400, 400, "emps.png", 6, 5);
spfx_base_load("EmpM", 450, 450, "empm.png", 6, 5);
/* Shield hits. */
spfx_base_load("ShiS", 400, 400, "shis.png", 6, 5);
spfx_base_load("ShiM", 450, 450, "shim.png", 6, 5);
/* Plasma hits. */
spfx_base_load("PlaS", 400, 400, "plas.png", 6, 5);
spfx_base_load("PlaM", 450, 450, "plam.png", 6, 5);
/* Load and read the data. */
buf = ldata_read(SPFX_DATA, &bufsize);
doc = xmlParseMemory(buf, bufsize);
/* Check to see if document exists. */
node = doc->xmlChildrenNode;
if(!xml_isNode(node, SPFX_XML_ID)) {
ERR("Malformed '"SPFX_DATA"' file: missing root element '"SPFX_XML_ID"'");
return -1;
}
/* Check to see if it's populated. */
node = node->xmlChildrenNode; /* First system node. */
if(node == NULL) {
ERR("Malformed '"SPFX_DATA"' file: does not contain elements");
return -1;
}
/* First pass, loads up ammunition. */
mem = 0;
do {
if(xml_isNode(node, SPFX_XML_TAG)) {
spfx_neffects++;
if(spfx_neffects > mem) {
mem += CHUNK_SIZE;
spfx_effects = realloc(spfx_effects, sizeof(SPFX_Base)*mem);
}
spfx_base_parse(&spfx_effects[spfx_neffects-1], node);
}
} while(xml_nextNode(node));
/* Shrink back to minimum - shouldn't change ever. */
spfx_effects = realloc(spfx_effects, sizeof(SPFX_Base) * spfx_neffects);
/* Now initialize force feedback. */
spfx_hapticInit(); spfx_hapticInit();
return 0; return 0;