[Add] Now you can define parts of the GUI as semi-transparent.

This commit is contained in:
Allanis 2014-08-07 19:59:58 +01:00
parent 0b3869c831
commit 0202391edb
2 changed files with 96 additions and 90 deletions

View File

@ -4,10 +4,10 @@
<offset x="0" y="0" /> <offset x="0" y="0" />
<radar type="circle" w="82" x="83" y="90" /> <radar type="circle" w="82" x="83" y="90" />
<health> <health>
<shield w="103" h="7" x="68" y="185" /> <shield alpha = "0.70" w="103" h="7" x="68" y="185" />
<armour w="103" h="7" x="68" y="199" /> <armour alpha = "0.70" w="103" h="7" x="68" y="199" />
<energy w="0" h="0" x="97" y="177">minimal_energy</energy> <energy alpha = "0.70" w="0" h="0" x="97" y="177">minimal_energy</energy>
<fuel w="0" h="0" x="95" y="78">minimal_fuel</fuel> <fuel alpha = "0.70" w="0" h="0" x="95" y="78">minimal_fuel</fuel>
</health> </health>
<nav w="110" h="40" x="60" y="220" /> <nav w="110" h="40" x="60" y="220" />
<weapon w="110" h="32" x="60" y="274" /> <weapon w="110" h="32" x="60" y="274" />

170
src/gui.c
View File

@ -96,6 +96,12 @@ typedef struct Rect_ {
double h; /**< Height. */ double h; /**< Height. */
} Rect; } Rect;
typedef struct HealthBar_ {
Rect rect;
glColour col;
glTexture* gfx;
} HealthBar;
/** /**
* @struct GUI * @struct GUI
* *
@ -115,14 +121,10 @@ typedef struct GUI_ {
/* Navigation. */ /* Navigation. */
Rect nav; /**< Navigation computer. */ Rect nav; /**< Navigation computer. */
/* Health. */ /* Health. */
Rect shield; /**< Shield bar. */ HealthBar shield; /**< Shield bar. */
glTexture* gfx_shield; /**< Shield bar texture if applicable. */ HealthBar armour; /**< Armour bar. */
Rect armour; /**< Armour bar. */ HealthBar energy; /**< Energy bar. */
glTexture* gfx_armour; /**< Armour bar texture if applicable. */ HealthBar fuel; /**< Fuel bar. */
Rect energy; /**< Energy bar. */
glTexture* gfx_energy; /**< Energy bar texture if applicable. */
Rect fuel; /**< Fuel bar. */
glTexture* gfx_fuel; /**< Fuel bar texture if applicable. */
/* Weapon. */ /* Weapon. */
Rect weapon; /**< Weapon targetting system. */ Rect weapon; /**< Weapon targetting system. */
/* Targetting. */ /* Targetting. */
@ -177,13 +179,14 @@ static void rect_parseParam(const xmlNodePtr parent,
char* name, double* param); char* name, double* param);
static void rect_parse(const xmlNodePtr parent, static void rect_parse(const xmlNodePtr parent,
double* x, double* y, double* w, double* h); double* x, double* y, double* w, double* h);
static int gui_parseBar(xmlNodePtr parent, HealthBar* bar, const glColour* col);
static int gui_parse(const xmlNodePtr parent, const char* name); static int gui_parse(const xmlNodePtr parent, const char* name);
static void gui_cleanupBar(HealthBar* bar);
/* Render GUI. */ /* Render GUI. */
static void gui_renderRadar(double dt); static void gui_renderRadar(double dt);
static void gui_renderMessages(double dt); static void gui_renderMessages(double dt);
static void gui_renderPilot(const Pilot* p); static void gui_renderPilot(const Pilot* p);
static void gui_renderHealth(const glColour* c, static void gui_renderHealth(const HealthBar* bar, const double w);
const Rect* r, const glTexture* tex, const double w);
static void gui_renderInterference(double dt); static void gui_renderInterference(double dt);
/** /**
@ -392,14 +395,10 @@ void gui_render(double dt) {
} }
/* Health. */ /* Health. */
gui_renderHealth(&cShield, &gui.shield, gui.gfx_shield, gui_renderHealth(&gui.shield, player->shield / player->shield_max);
player->shield / player->shield_max); gui_renderHealth(&gui.armour, player->armour / player->armour_max);
gui_renderHealth(&cArmour, &gui.armour, gui.gfx_armour, gui_renderHealth(&gui.energy, player->energy / player->energy_max);
player->armour / player->armour_max); gui_renderHealth(&gui.fuel, player->fuel / player->fuel_max);
gui_renderHealth(&cEnergy, &gui.energy, gui.gfx_energy,
player->energy / player->energy_max);
gui_renderHealth(&cFuel, &gui.fuel, gui.gfx_fuel,
player->fuel / player->fuel_max);
/* Weapon. */ /* Weapon. */
if(player->secondary == NULL) { /* No secondary weapon. */ if(player->secondary == NULL) { /* No secondary weapon. */
@ -761,20 +760,22 @@ static void gui_renderPilot(const Pilot* p) {
/** /**
* @brief Render a health bar. * @brief Render a health bar.
* @param bar Health bar to render.
* @param w Width of the health bar.
*/ */
static void gui_renderHealth(const glColour* c, static void gui_renderHealth(const HealthBar* bar, const double w) {
const Rect* r, const glTexture* tex, const double w) {
double x,y, sx,sy, tx,ty; double x,y, sx,sy, tx,ty;
/* Set the colour. */ /* Set the colour. */
COLOUR(*c); COLOUR(bar->col);
if(tex == NULL) { /* Just create a bar. */
x = r->x - SCREEN_W/2.; if(bar->gfx == NULL) {
y = r->y - SCREEN_H/2.; /* Set the position values. */
sx = w * r->w; x = bar->rect.x - SCREEN_W/2.;
sy = r->h; y = bar->rect.x - SCREEN_H/2.;
sx = w * bar->rect.w;
sy = bar->rect.h;
glBegin(GL_QUADS); glBegin(GL_QUADS);
glVertex2d(x, y); glVertex2d(x, y);
@ -783,16 +784,16 @@ static void gui_renderHealth(const glColour* c,
glVertex2d(x, y-sy); glVertex2d(x, y-sy);
glEnd(); /* GL_QUADS. */ glEnd(); /* GL_QUADS. */
} else { /* Render the texture. */ } else { /* Render the texture. */
x = r->x - SCREEN_W/2.; x = bar->rect.x - SCREEN_W/2.;
y = r->y - SCREEN_H/2. + tex->sh; y = bar->rect.y - SCREEN_H/2. + bar->gfx->sh;
sx = w * tex->sw; sx = w *bar->gfx->sw;
sy = tex->sh; sy = bar->gfx->sh;
tx = tex->sw / tex->rw; tx = bar->gfx->sw / bar->gfx->rw;
ty = tex->sh / tex->rh; ty = bar->gfx->sh / bar->gfx->rh;
/* Draw the image. */ /* Draw the image. */
glEnable(GL_TEXTURE_2D); glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, tex->texture); glBindTexture(GL_TEXTURE_2D, bar->gfx->texture);
glBegin(GL_QUADS); glBegin(GL_QUADS);
glTexCoord2d(0., ty); glTexCoord2d(0., ty);
glVertex2d(x, y); glVertex2d(x, y);
@ -996,6 +997,36 @@ static void gui_createInterference(void) {
} }
} }
/**
* @brief Parses a healthbar.
* @param parent Parent node of the healthbar.
* @param bar Bar to load into.
* @param col Default colour to use.
*/
static int gui_parseBar(xmlNodePtr parent, HealthBar* bar, const glColour* col) {
char* tmp, buf[PATH_MAX];
/* Parse the rectangle. */
rect_parse(parent, &bar->rect.x, &bar->rect.y,
&bar->rect.w, &bar->rect.h);
/* Load the colour. */
memcpy(&bar->col, col, sizeof(glColour));
xmlr_attr(parent, "alpha", tmp);
if(tmp != NULL) {
bar->col.a = atof(tmp);
free(tmp);
}
/* Check for graphics. */
tmp = xml_get(parent);
if(tmp != NULL) {
snprintf(buf, PATH_MAX, GUI_GFX"%s.png", tmp);
bar->gfx = gl_newImage(buf, 0);
}
return 0;
}
#define RELATIVIZE(a) \ #define RELATIVIZE(a) \
{(a).x += VX(gui.frame); (a).y = VY(gui.frame)+gui.gfx_frame->h-(a).y;} {(a).x += VX(gui.frame); (a).y = VY(gui.frame)+gui.gfx_frame->h-(a).y;}
@ -1080,44 +1111,20 @@ static int gui_parse(const xmlNodePtr parent, const char* name) {
cur = node->children; cur = node->children;
do { do {
if(xml_isNode(cur, "shield")) { if(xml_isNode(cur, "shield")) {
rect_parse(cur, &gui.shield.x, &gui.shield.y, gui_parseBar(cur, &gui.shield, &cShield);
&gui.shield.w, &gui.shield.h); RELATIVIZE(gui.shield.rect);
tmp = xml_get(cur);
if(tmp != NULL) {
snprintf(buf, PATH_MAX, GUI_GFX"%s.png", tmp);
gui.gfx_shield = gl_newImage(buf, 0);
}
RELATIVIZE(gui.shield);
} }
if(xml_isNode(cur, "armour")) { if(xml_isNode(cur, "armour")) {
rect_parse(cur, &gui.armour.x, &gui.armour.y, gui_parseBar(cur, &gui.armour, &cArmour);
&gui.armour.w, &gui.armour.h); RELATIVIZE(gui.armour.rect);
tmp = xml_get(cur);
if(tmp != NULL) {
snprintf(buf, PATH_MAX, GUI_GFX"%s.png", tmp);
gui.gfx_armour = gl_newImage(buf, 0);
}
RELATIVIZE(gui.armour);
} }
if(xml_isNode(cur, "energy")) { if(xml_isNode(cur, "energy")) {
rect_parse(cur, &gui.energy.x, &gui.energy.y, gui_parseBar(cur, &gui.energy, &cEnergy);
&gui.energy.w, &gui.energy.h); RELATIVIZE(gui.energy.rect);
tmp = xml_get(cur);
if(tmp != NULL) {
snprintf(buf, PATH_MAX, GUI_GFX"%s.png", tmp);
gui.gfx_energy = gl_newImage(buf, 0);
}
RELATIVIZE(gui.energy);
} }
if(xml_isNode(cur, "fuel")) { if(xml_isNode(cur, "fuel")) {
rect_parse(cur, &gui.fuel.x, &gui.fuel.y, gui_parseBar(cur, &gui.fuel, &cFuel);
&gui.fuel.w, &gui.fuel.h); RELATIVIZE(gui.fuel.rect);
tmp = xml_get(cur);
if(tmp != NULL) {
snprintf(buf, PATH_MAX, GUI_GFX"%s.png", tmp);
gui.gfx_fuel = gl_newImage(buf, 0);
}
RELATIVIZE(gui.fuel);
} }
} while(xml_nextNode(cur)); } while(xml_nextNode(cur));
} }
@ -1171,6 +1178,16 @@ static int gui_parse(const xmlNodePtr parent, const char* name) {
} }
#undef RELATIVIZE #undef RELATIVIZE
/**
* @brief Clean up a health bar.
*/
static void gui_cleanupBar(HealthBar* bar) {
if(bar->gfx != NULL) {
gl_freeTexture(bar->gfx);
bar->gfx = NULL;
}
}
/* /*
* @brief Clean up the GUI. * @brief Clean up the GUI.
*/ */
@ -1190,22 +1207,11 @@ void gui_cleanup(void) {
gui.gfx_targetPlanet = NULL; gui.gfx_targetPlanet = NULL;
} }
/* Health textures. */ /* Health textures. */
if(gui.gfx_shield != NULL) { gui_cleanupBar(&gui.shield);
gl_freeTexture(gui.gfx_shield); gui_cleanupBar(&gui.armour);
gui.gfx_shield = NULL; gui_cleanupBar(&gui.energy);
} gui_cleanupBar(&gui.fuel);
if(gui.gfx_armour != NULL) {
gl_freeTexture(gui.gfx_armour);
gui.gfx_armour = NULL;
}
if(gui.gfx_energy != NULL) {
gl_freeTexture(gui.gfx_energy);
gui.gfx_energy = NULL;
}
if(gui.gfx_fuel != NULL) {
gl_freeTexture(gui.gfx_fuel);
gui.gfx_fuel = NULL;
}
for(i = 0; i < INTERFERENCE_LAYERS; i++) { for(i = 0; i < INTERFERENCE_LAYERS; i++) {
if(gui.radar.interference[i] != NULL) { if(gui.radar.interference[i] != NULL) {
gl_freeTexture(gui.radar.interference[i]); gl_freeTexture(gui.radar.interference[i]);