[Add] Support for images of planets within toolkit.

[Change] blit functions use doubles instead of vectors.
[Change] Took some time out to clean up space.c bringing it up to xml.h standards.
This commit is contained in:
Allanis 2013-02-19 00:10:57 +00:00
parent d19f8c4ae8
commit bf9d422150
17 changed files with 334 additions and 196 deletions

View File

@ -12,7 +12,10 @@
<tech>0</tech>
<commodities>1</commodities>
</general>
<GFX>konosphere.png</GFX>
<GFX>
<space>konosphere.png</space>
<exterior>konosphere.png</exterior>
</GFX>
</planet>
<planet name="SaraCraft">
<pos>
@ -26,6 +29,9 @@
<tech>0</tech>
<commodities>1</commodities>
</general>
<GFX>saracraft.png</GFX>
<GFX>
<space>saracraft.png</space>
<exterior>saracraft.png</exterior>
</GFX>
</planet>
</Planets>

View File

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

View File

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

@ -14,5 +14,6 @@ glColour cGrey10 = { .r = 0.10, .g = 0.10, .b = 0.10, .a = 1 };
glColour cBlack = { .r = 0.00, .g = 0.00, .b = 0.00, .a = 1 };
glColour cGreen = { .r = 0.20, .g = 0.80, .b = 0.20, .a = 1 };
glColour cDarkRed = { .r = 0.60, .g = 0.10, .b = 0.10, .a = 1 };
glColour cRed = { .r = 0.80, .g = 0.20, .b = 0.20, .a = 1 };

View File

@ -22,5 +22,6 @@ extern glColour cGrey20;
extern glColour cGrey10;
extern glColour cGreen;
extern glColour cDarkRed;
extern glColour cRed;

View File

@ -2,8 +2,8 @@
#include "pause.h"
#include "land.h"
#define LAND_WIDTH 500
#define LAND_HEIGHT 400
#define LAND_WIDTH 700
#define LAND_HEIGHT 600
#define BUTTON_WIDTH 80
#define BUTTON_HEIGHT 40
@ -19,10 +19,11 @@ void land(Planet* p) {
land_wid = window_create(-1, -1, LAND_WIDTH, LAND_HEIGHT);
// Pretty display.
window_addText(land_wid, 0., -20., LAND_WIDTH, 1, p->name, NULL, &cBlack);
window_addText(land_wid, 0., -20., LAND_WIDTH, 1, "txtPlanet", NULL, &cBlack, p->name);
//window_addImage(land_wid, 20., -440, "imgPlanet", p->gfx_exterior);
// Buttons.
window_addButton(land_wid, -20, 20, BUTTON_WIDTH, BUTTON_HEIGHT,
"takeoff", "Takeoff", (void(*)(char*))takeoff);
"btnTakeoff", "Takeoff", (void(*)(char*))takeoff);
landed = 1;
}

View File

@ -345,23 +345,25 @@ void gl_getSpriteFromDir(int* x, int* y, const glTexture* t, const double dir) {
// ================
// Blit the sprite at given position.
void gl_blitSprite(const glTexture* sprite, const Vec2* pos, const int sx, const int sy, const glColour* c) {
void gl_blitSprite(const glTexture* sprite, const double bx, const double by,
const int sx, const int sy, const glColour* c) {
// Don't bother drawing if offscreen -- waste of cycles.
if(fabs(VX(*pos) -VX(*gl_camera)+gui_xoff) > gl_screen.w / 2 + sprite->sw / 2 ||
fabs(VY(*pos) -VY(*gl_camera)+gui_yoff) > gl_screen.h / 2 + sprite->sh / 2)
if(fabs(bx-VX(*gl_camera)+gui_xoff) > gl_screen.w / 2 + sprite->sw / 2 ||
fabs(by-VY(*gl_camera)+gui_yoff) > gl_screen.h / 2 + sprite->sh / 2)
return;
double x, y, tx, ty;
glEnable(GL_TEXTURE_2D);
x = VX(*pos) - VX(*gl_camera) - sprite->sw/2. + gui_xoff;
y = VY(*pos) - VY(*gl_camera) - sprite->sh/2. + gui_yoff;
x = bx - VX(*gl_camera) - sprite->sw/2. + gui_xoff;
y = by - VY(*gl_camera) - sprite->sh/2. + gui_yoff;
tx = sprite->sw * (double)(sx)/sprite->rw;
ty = sprite->sh * (sprite->sy-(double)sy-1)/sprite->rh;
// Actual blitting....
glShadeModel(GL_FLAT);
glBindTexture(GL_TEXTURE_2D, sprite->texture);
glBegin(GL_QUADS);
if(c == NULL) glColor4d(1., 1., 1., 1.);
@ -385,12 +387,12 @@ void gl_blitSprite(const glTexture* sprite, const Vec2* pos, const int sx, const
}
// Just straight out blit the thing at position.
void gl_blitStatic(const glTexture* texture, const Vec2* pos, const glColour* c) {
void gl_blitStatic(const glTexture* texture, const double bx, const double by, const glColour* c) {
double x, y;
glEnable(GL_TEXTURE_2D);
x = VX(*pos) - (double)gl_screen.w/2.;
y = VY(*pos) - (double)gl_screen.h/2.;
x = bx - (double)gl_screen.w/2.;
y = by - (double)gl_screen.h/2.;
// Actual blitting..
glBindTexture(GL_TEXTURE_2D, texture->texture);
@ -798,6 +800,7 @@ int gl_init(void) {
//glEnable(GL_TEXTURE_2D); // Don't enable globally, it will break non-texture blits.
glDisable(GL_LIGHTING); // No lighting, it is done when rendered.
glEnable(GL_BLEND);
glShadeModel(GL_FLAT); // Default shade model. Functions should keep this when done..
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();

View File

@ -66,21 +66,30 @@ glTexture* gl_newSprite(const char* path, const int sx, const int sy);
void gl_freeTexture(glTexture* texture);
// Rendering.
void gl_blitSprite(const glTexture* sprite, const Vec2* pos,
// Blits a sprite.
void gl_blitSprite(const glTexture* sprite, const double bx, const double by,
const int sx, const int sy, const glColour* c);
void gl_blitStatic(const glTexture* texture, const Vec2* pos, const glColour* c);
// Blit the entire image.
void gl_blitStatic(const glTexture* texture, const double bx, const double by,
const glColour* c);
// Bind the camera to a vector.
void gl_bindCamera(const Vec2* pos);
// Print text.
void gl_print(const glFont* ft_font, const double x, const double y,
const glColour* c, const char* fmt, ...);
// Print text to a max length.
int gl_printMax(const glFont* ft_font, const int max, const double x, const double y,
const glColour* c, const char* fmt, ...);
// Print text centered in width at x.
int gl_printMid(const glFont* ft_font, const int width, double x, const double y,
const glColour* c, const char* fmt, ...);
// Get the width of the text that you wish to print.
int gl_printWidth(const glFont* ft_font, const char* fmt, ...);
// Initialize/cleanup.

View File

@ -200,7 +200,7 @@ void pilot_render(Pilot* p) {
// Get the sprite corresponding to the direction facing.
gl_getSpriteFromDir(&sx, &sy, p->ship->gfx_space, p->solid->dir);
gl_blitSprite(p->ship->gfx_space, &p->solid->pos, sx, sy, NULL);
gl_blitSprite(p->ship->gfx_space, p->solid->pos.x, p->solid->pos.y, sx, sy, NULL);
}
// Update the pilot.

View File

@ -218,7 +218,6 @@ void player_render(void) {
Planet* planet;
glColour* c;
glFont* f;
Vec2 v;
// Render the player target graphics.
if(player_target != PLAYER_ID) {
@ -228,15 +227,18 @@ void player_render(void) {
else if(pilot_isFlag(p, PILOT_HOSTILE)) c = &cHostile;
else c = &cNeutral;
vect_csetmin(&v, VX(p->solid->pos) - p->ship->gfx_space->sw * PILOT_SIZE_APROX/2.,
VY(p->solid->pos) + p->ship->gfx_space->sh * PILOT_SIZE_APROX/2.);
gl_blitSprite(gui.gfx_targetPilot, &v, 0, 0, c); // Top left.
VX(v) += p->ship->gfx_space->sw * PILOT_SIZE_APROX;
gl_blitSprite(gui.gfx_targetPilot, &v, 1, 0, c); // Top right.
VY(v) -= p->ship->gfx_space->sh * PILOT_SIZE_APROX;
gl_blitSprite(gui.gfx_targetPilot, &v, 1, 1, c); // Bottom right.
VX(v) -= p->ship->gfx_space->sw * PILOT_SIZE_APROX;
gl_blitSprite(gui.gfx_targetPilot, &v, 0, 1, c); // Bottom left.
x = p->solid->pos.x - p->ship->gfx_space->sw * PILOT_SIZE_APROX/2.;
y = p->solid->pos.y + p->ship->gfx_space->sh * PILOT_SIZE_APROX/2.;
gl_blitSprite(gui.gfx_targetPilot, x, y, 0, 0, c); // Top left.
x += p->ship->gfx_space->sw * PILOT_SIZE_APROX;
gl_blitSprite(gui.gfx_targetPilot, x, y, 1, 0, c); // Top right.
y -= p->ship->gfx_space->sh * PILOT_SIZE_APROX;
gl_blitSprite(gui.gfx_targetPilot, x, y, 1, 1, c); // Bottom right.
x -= p->ship->gfx_space->sw * PILOT_SIZE_APROX;
gl_blitSprite(gui.gfx_targetPilot, x, y, 0, 1, c); // Bottom left.
}
// Render the planet target graphics.
if(planet_target >= 0) {
@ -245,22 +247,26 @@ void player_render(void) {
if(areEnemies(player->faction, planet->faction)) c = &cHostile;
else c = &cNeutral;
vect_csetmin(&v, VX(planet->pos) - planet->gfx_space->sw/2.,
VY(planet->pos) + planet->gfx_space->sh/2.);
gl_blitSprite(gui.gfx_targetPlanet, &v, 0, 0, c); // Top left.
VX(v) += planet->gfx_space->sw;
gl_blitSprite(gui.gfx_targetPlanet, &v, 1, 0, c); // Top right.
VY(v) -= planet->gfx_space->sh;
gl_blitSprite(gui.gfx_targetPlanet, &v, 1, 1, c); // Bottom right.
VX(v) -= planet->gfx_space->sw;
gl_blitSprite(gui.gfx_targetPlanet, &v, 0, 1, c); // Bottom left.
x = p->solid->pos.x - p->ship->gfx_space->sw * PILOT_SIZE_APROX/2.;
y = p->solid->pos.y + p->ship->gfx_space->sh * PILOT_SIZE_APROX/2.;
gl_blitSprite(gui.gfx_targetPlanet, x, y, 0, 0, c); // Top left.
x += p->ship->gfx_space->sw * PILOT_SIZE_APROX;
gl_blitSprite(gui.gfx_targetPlanet, x, y, 1, 0, c); // Top right.
y -= p->ship->gfx_space->sh * PILOT_SIZE_APROX;
gl_blitSprite(gui.gfx_targetPlanet, x, y, 1, 1, c); // Bottom right.
x -= p->ship->gfx_space->sw * PILOT_SIZE_APROX;
gl_blitSprite(gui.gfx_targetPlanet, x, y, 0, 1, c); // Bottom left.
}
// Render the player.
pilot_render(player);
// GUI!
// -- Frame.
gl_blitStatic(gui.gfx_frame, &gui.frame, NULL);
gl_blitStatic(gui.gfx_frame, gui.frame.x, gui.frame.y, NULL);
// -- Radar.
glMatrixMode(GL_PROJECTION);
glPushMatrix();
@ -368,7 +374,7 @@ void player_render(void) {
if(player_target != PLAYER_ID) {
p = pilot_get(player_target);
gl_blitStatic(p->ship->gfx_target, &gui.target, NULL);
gl_blitStatic(p->ship->gfx_target, gui.target.x, gui.target.y, NULL);
// Target name.
gl_print(NULL, gui.target_name.x, gui.target_name.y,

View File

@ -20,7 +20,11 @@
#define PLANET_DATA "../dat/planet.xml"
#define SYSTEM_DATA "../dat/ssys.xml"
#define PLANET_GFX "../gfx/planet/"
#define PLANET_GFX_SPACE "../gfx/planet/space/"
#define PLANET_GFX_EXTERIOR "../gfx/planer/exterior/"
#define PLANET_GFX_EXTERIOR_W 400
#define PLANET_GFX_EXTERIOR_H 400
// Overcome warning due to zero value.
@ -239,8 +243,8 @@ static Planet* planet_get(const char* name) {
}
do {
if(node->type == XML_NODE_START && strcmp((char*)node->name, XML_PLANET_TAG)==0) {
tstr = (char*)xmlGetProp(node, (xmlChar*)"name");
if(xml_isNode(node, XML_PLANET_TAG)) {
tstr = xml_nodeProp(node, "name");
if(strcmp(tstr, name)==0) { // Found.
tmp = CALLOC_L(Planet);
tmp->name = tstr;
@ -248,34 +252,43 @@ static Planet* planet_get(const char* name) {
node = node->xmlChildrenNode;
do {
if(strcmp((char*)node->name, "GFX")==0) {
cur = node->children;
if(strcmp((char*)cur->name, "text")==0) {
snprintf(str, strlen((char*)cur->content)+sizeof(PLANET_GFX),
PLANET_GFX"%s", (char*)cur->content);
tmp->gfx_space = gl_newImage(str);
}
}
else if(strcmp((char*)node->name, "pos")==0) {
if(xml_isNode(node, "GFX")) {
cur = node->children;
do {
if(strcmp((char*)cur->name, "x")==0) {
flags |= FLAG_XSET;
tmp->pos.x = atof((char*)cur->children->content);
if(xml_isNode(cur, "space")) {
// Load space gfx.
snprintf(str, strlen(xml_get(cur))+sizeof(PLANET_GFX_SPACE),
PLANET_GFX_SPACE"%s", xml_get(cur));
tmp->gfx_space = gl_newImage(str);
}
else if(strcmp((char*)cur->name, "y")==0) {
flags |= FLAG_YSET;
tmp->pos.y = atof((char*)cur->children->content);
else if(xml_isNode(cur, "exterior")) {
// Load land gfx.
snprintf(str, strlen(xml_get(cur))+sizeof(PLANET_GFX_EXTERIOR),
PLANET_GFX_EXTERIOR"%s", xml_get(cur));
tmp->gfx_exterior = gl_newImage(str);
}
} while((cur = cur->next));
}
else if(strcmp((char*)node->name, "general")==0) {
else if(xml_isNode(node, "pos")) {
cur = node->children;
do {
if(strcmp((char*)cur->name, "class")==0)
if(xml_isNode(cur, "x")) {
flags |= FLAG_XSET;
tmp->pos.x = xml_getFloat(cur);
}
else if(xml_isNode(cur, "y")) {
flags |= FLAG_YSET;
tmp->pos.y = xml_getFloat(cur);
}
} while((cur = cur->next));
}
else if(xml_isNode(node, "general")) {
cur = node->children;
do {
if(xml_isNode(cur, "class"))
tmp->class = planetclass_get(cur->children->content[0]);
else if(strcmp((char*)cur->name, "faction")==0)
tmp->faction = faction_get((char*)cur->children->content);
else if(xml_isNode(cur, "faction"))
tmp->faction = faction_get(xml_get(cur));
} while((cur = cur->next));
}
} while((node = node->next));
@ -292,6 +305,8 @@ static Planet* planet_get(const char* name) {
// Check elements.
if(tmp) {
#define MELEMENT(o,s) if((o) == 0) WARN("Planet '%s' missing '"s"' element", tmp->name)
MELEMENT(tmp->gfx_space, "GFX_space");
MELEMENT(tmp->gfx_exterior, "GFX_exterior");
MELEMENT(flags&FLAG_XSET, "x");
MELEMENT(flags&FLAG_YSET, "y");
MELEMENT(tmp->class, "class");
@ -314,45 +329,46 @@ static StarSystem* system_parse(const xmlNodePtr parent) {
uint32_t flags;
tmp->name = (char*)xmlGetProp(parent, (xmlChar*)"name"); // Already mallocs.
tmp->name = xml_nodeProp(parent, "name"); // Already mallocs.
node = parent->xmlChildrenNode;
do {
// Load all the things!
if(strcmp((char*)node->name, "pos")==0) {
if(xml_isNode(node, "pos")) {
cur = node->children;
do {
if(strcmp((char*)cur->name, "x")==0) {
if(xml_isNode(cur, "x")) {
flags |= FLAG_XSET;
tmp->pos.x = atof((char*)cur->children->content);
tmp->pos.x = xml_getFloat(cur);
}
if(strcmp((char*)cur->name, "y")==0) {
if(xml_isNode(cur, "y")) {
flags |= FLAG_YSET;
tmp->pos.y = atof((char*)cur->children->content);
tmp->pos.y = xml_getFloat(cur);
}
} while((cur = cur->next));
}
else if(strcmp((char*)node->name, "general")==0) {
else if(xml_isNode(node, "general")) {
cur = node->children;
do {
if(strcmp((char*)cur->name, "stars")==0) // Non-zero.
tmp->stars = atoi((char*)cur->children->content);
else if(strcmp((char*)cur->name, "asteroids")==0) {
if(xml_isNode(cur, "stars")) // Non-zero.
tmp->stars = xml_getInt(cur);
else if(xml_isNode(cur, "asteroids")) {
flags |= FLAG_ASTEROIDSSET;
tmp->asteroids = atoi((char*)cur->children->content);
tmp->asteroids = xml_getInt(cur);
}
else if(strcmp((char*)cur->name, "interference")==0) {
else if(xml_isNode(cur, "interference")) {
flags |= FLAG_INTEFERENCESET;
tmp->interference = atof((char*)cur->children->content);
tmp->interference = xml_getFloat(cur)/100;
}
}while((cur = cur->next));
}
// Load all the planets.
else if(strcmp((char*)node->name, "planets")==0) {
else if(xml_isNode(node, "planets")) {
cur = node->children;
do {
if(strcmp((char*)cur->name, "planet")==0) {
if(xml_isNode(cur, "planet")) {
planet = planet_get(xml_get(cur));
planet = planet_get((const char*)cur->children->content);
tmp->planets = realloc(tmp->planets, sizeof(Planet)*(++tmp->nplanets));
memcpy(tmp->planets+(tmp->nplanets-1), planet, sizeof(Planet));
@ -361,16 +377,16 @@ static StarSystem* system_parse(const xmlNodePtr parent) {
} while((cur = cur->next));
}
// Load all the fleets.
else if(strcmp((char*)node->name, "fleets")==0) {
else if(xml_isNode(node, "fleets")) {
cur = node->children;
do {
if(strcmp((char*)cur->name, "fleet")==0) {
if(xml_isNode(cur, "fleet")) {
fleet = CALLOC_L(SystemFleet);
fleet->fleet = fleet_get((const char*)cur->children->content);
fleet->fleet = fleet_get(xml_get(cur));
if(fleet->fleet == NULL)
WARN("Fleet %s for Star System %s not found", (char*)cur->children->content, tmp->name);
WARN("Fleet %s for Star System %s not found", xml_get(cur), tmp->name);
ptrc = (char*)xmlGetProp(cur, (xmlChar*)"chance"); // Malloc ptrc.
ptrc = xml_nodeProp(cur, "chance"); // Malloc ptrc.
fleet->chance = atoi(ptrc);
if(fleet->chance == 0)
WARN("Fleet %s for Star System %s has 0%% chance to appear",
@ -408,7 +424,7 @@ int space_load(void) {
xmlDocPtr doc = xmlParseMemory(buf, bufsize);
node = doc->xmlChildrenNode;
if(strcmp((char*)node->name, XML_SYSTEM_ID)) {
if(!xml_isNode(node, XML_SYSTEM_ID)) {
ERR("Malformed "SYSTEM_DATA" file: missing root element '"XML_SYSTEM_ID"'");
return -1;
}
@ -418,7 +434,7 @@ int space_load(void) {
return -1;
}
do {
if(node->type == XML_NODE_START && strcmp((char*)node->name, XML_SYSTEM_TAG)==0) {
if(xml_isNode(node, XML_SYSTEM_TAG)) {
tmp = system_parse(node);
systems = realloc(systems, sizeof(StarSystem)*(++nsystems));
memcpy(systems+nsystems-1, tmp, sizeof(StarSystem));
@ -436,9 +452,6 @@ int space_load(void) {
// Render the system. -- Just playing god now.
void space_render(double dt) {
int i;
glMatrixMode(GL_PROJECTION);
glPushMatrix(); // Projection translation matrix.
glTranslated(-(double)gl_screen.w/2., -(double)gl_screen.h/2., 0.);
glBegin(GL_POINTS);
for(i = 0; i < nstars; i++) {
if(!paused) {
@ -453,17 +466,18 @@ void space_render(double dt) {
}
// Render.
glColor4d(1., 1., 1., stars[i].brightness);
glVertex2d(stars[i].x, stars[i].y);
glVertex2d(stars[i].x - (double)gl_screen.w/2.,
stars[i].y - (double)gl_screen.h/2.);
}
glEnd();
glPopMatrix(); // Projection translation matrix.
}
// Render the planets.
void planets_render(void) {
int i;
for(i = 0; i < cur_system->nplanets; i++)
gl_blitSprite(cur_system->planets[i].gfx_space, &cur_system->planets[i].pos, 0, 0, NULL);
gl_blitSprite(cur_system->planets[i].gfx_space,
cur_system->planets[i].pos.x, cur_system->planets[i].pos.y, 0, 0, NULL);
}
// Clean up the system.
@ -475,6 +489,8 @@ void space_exit(void) {
free(systems[i].planets[j].name);
if(systems[i].planets[j].gfx_space)
gl_freeTexture(systems[i].planets[j].gfx_space);
if(systems[i].planets[j].gfx_exterior)
gl_freeTexture(systems[i].planets[j].gfx_exterior);
if(systems[i].fleets)
free(systems[i].fleets);
}

View File

@ -41,6 +41,7 @@ typedef struct {
PlanetClass class; // Planet type.
Faction* faction; // Planet faction.
glTexture* gfx_space; // Graphics in space.
glTexture* gfx_exterior; // Graphics in the exterior.
} Planet;
// Star systems.

View File

@ -29,17 +29,18 @@ typedef struct {
// Widget button.
struct {
void(*fptr) (char*); // Callback.
char* string; // Stored text.
char* display; // Stored text.
};
// Widget text.
struct {
char* text;
glFont* font;
glColour* colour;
int centered;
};
struct {
// Widget image.
glTexture* texture;
glTexture* image;
};
};
} Widget;
@ -70,6 +71,7 @@ static Window* window_get(const unsigned int wid);
static void window_render(Window* w);
static void toolkit_renderButton(Widget* btn, double bx, double by);
static void toolkit_renderText(Widget* txt, double bx, double by);
static void toolkit_renderImage(Widget* img, double bx, double by);
// Add a button that when pressed will trigger call, passing it's name as the
// only parameter.
@ -81,7 +83,7 @@ void window_addButton(const unsigned int wid, const int x, const int y, const in
wgt->type = WIDGET_BUTTON;
wgt->name = strdup(name);
wgt->string = strdup(display);
wgt->display = strdup(display);
// Set the properties.
wgt->w = (double) w;
@ -93,8 +95,10 @@ void window_addButton(const unsigned int wid, const int x, const int y, const in
wgt->fptr = call;
}
void window_addText(const unsigned int wid, const int x, const int y, const int w,
const int centered, char* name, glFont* font, glColour* colour) {
// Add text to the window.
void window_addText(const unsigned int wid, const int x, const int y,
const int w, const int centered, char* name,
glFont* font, glColour* colour, char* string) {
Window* wdw = window_get(wid);
Widget* wgt = window_newWidget(wdw);
@ -108,11 +112,29 @@ void window_addText(const unsigned int wid, const int x, const int y, const int
else wgt->font = font;
if(x < 0) wgt->x = wdw->w - wgt->w + x;
else wgt->x = (double)x;
if(y < 0) wgt->y = wdw->h - wgt->font->h + y;
if(y < 0) wgt->y = wdw->h + y;
else wgt->y = (double) y;
wgt->colour = colour;
wgt->centered = centered;
wgt->text = strdup(string);
}
// Add a graphic to the window.
void window_addImage(const unsigned int wid, const int x, const int y,
char* name, glTexture* image) {
Window* wdw = window_get(wid);
Widget* wgt = window_newWidget(wdw);
wgt->type = WIDGET_IMAGE;
wgt->name = strdup(name);
// Set the propertied.
wgt->image = image;
if(x < 0) wgt->x = wdw->w - wgt->image->sw + x;
else wgt->x = (double)x;
if(y < 0) wgt->y = wdw->h + y;
else wgt->y = (double)y;
}
// Return pointer to newly allocated widget.
@ -179,8 +201,16 @@ unsigned int window_create(const int x, const int y, const int w, const int h) {
static void widget_cleanup(Widget* widget) {
if(widget->name) free(widget->name);
if((widget->type == WIDGET_BUTTON) && widget->string)
free(widget->string);
switch(widget->type) {
case WIDGET_BUTTON:
if(widget->display) free(widget->display);
break;
case WIDGET_TEXT:
if(widget->text) free(widget->text);
break;
default:
break;
}
}
// Destroy a window.
@ -208,6 +238,27 @@ void window_destroy(unsigned int wid) {
}
}
void window_destroyWidget(unsigned int wid, const char* wgtname) {
Window* w = window_get(wid);
int i;
for(i = 0; i < w->nwidgets; i++)
if(strcmp(wgtname, w->widgets[i].name)==0)
break;
if(i >= w->nwidgets) {
DEBUG("Widget '%s' not found in window '%d'", wgtname, wid);
return;
}
widget_cleanup(&w->widgets[i]);
if(i < w->nwidgets-1)
// This isn't the last widget.
w->widgets[i] = w->widgets[i-1];
w->nwidgets--; // Not that we don't actually realloc the space..
}
// Render a window.
static void window_render(Window* w) {
int i;
@ -297,6 +348,47 @@ static void window_render(Window* w) {
glBegin(GL_LINE_LOOP);
// Left side.
COLOUR(*c);
glVertex2d(x+21.+1., y);
glVertex2d(x+15.+1., y+1.+1.);
glVertex2d(x+10.+1., y+3.+1.);
glVertex2d(x+6.+1., y+6.+1.);
glVertex2d(x+3.+1., y+10.+1.);
glVertex2d(x+1.+1., y+15.+1.);
glVertex2d(x+1., y+21.+1.);
COLOUR(*lc);
glVertex2d(x+1., y+0.6*w->h); // Front of center.
glVertex2d(x+1., y+w->h-21.-1.);
glVertex2d(x+1.+1., y+w->h-15.-1.);
glVertex2d(x+3.+1., y+w->h-10.-1.);
glVertex2d(x+6.+1., y+w->h-6.-1.);
glVertex2d(x+10.+1., y+w->h-2.-1.);
glVertex2d(x+15.+1., y+w->h-1.-1.);
glVertex2d(x+21.+1., y+w->h-1.);
// Switch to right via top.
glVertex2d(x+w->w-21.-1., y+w->h);
glVertex2d(x+w->w-15.-1., y+w->h-1.-1.);
glVertex2d(x+w->w-10.-1., y+w->h-3.-1.);
glVertex2d(x+w->w-6.-1., y+w->h-6.-1.);
glVertex2d(x+w->w-2.-1., y+w->h-10.-1.);
glVertex2d(x+w->w-1.-1., y+w->h-15.-1.);
glVertex2d(x+w->w-.1, y+w->h-21.-1.);
glVertex2d(x+w->w-1., y+0.6*w->h); // Front of center.
COLOUR(*c);
glVertex2d(x+w->w-1., y+21.+1.);
glVertex2d(x+w->w-1.-1., y+15.+1.);
glVertex2d(x+w->w-3.-1., y+10.+1.);
glVertex2d(x+w->w-6.-1., y+6.+1.);
glVertex2d(x+w->w-10.-1., y+3.+1.);
glVertex2d(x+w->w-15.-1., y+1.+1.);
glVertex2d(x+w->w-21.-1., y+1.);
glVertex2d(x+21.+1., y+1.);
glEnd();
// Outter outline.
glShadeModel(GL_FLAT);
glBegin(GL_LINE_LOOP);
// Left side.
COLOUR(*oc);
glVertex2d(x+21., y);
glVertex2d(x+15., y+1.);
glVertex2d(x+10., y+3.);
@ -304,13 +396,12 @@ static void window_render(Window* w) {
glVertex2d(x+3., y+10.);
glVertex2d(x+1., y+15.);
glVertex2d(x, y+21.);
COLOUR(*lc);
glVertex2d(x, y+0.6*w->h); // Front of center.
glVertex2d(x, y+w->h-21.);
glVertex2d(x+1., y+w->h-15.);
glVertex2d(x+3., y+w->h-10.);
glVertex2d(x+6., y+w->h-6.);
glVertex2d(x+10., y+w->h-2.);
glVertex2d(x+10., y+w->h-3.);
glVertex2d(x+15., y+w->h-1.);
glVertex2d(x+21., y+w->h);
// Switch to right via top.
@ -318,11 +409,10 @@ static void window_render(Window* w) {
glVertex2d(x+w->w-15., y+w->h-1.);
glVertex2d(x+w->w-10., y+w->h-3.);
glVertex2d(x+w->w-6., y+w->h-6.);
glVertex2d(x+w->w-2., y+w->h-10.);
glVertex2d(x+w->w-3., y+w->h-10.);
glVertex2d(x+w->w-1., y+w->h-15.);
glVertex2d(x+w->w, y+w->h-21.);
glVertex2d(x+w->w, y+0.6*w->h); // Front of center.
COLOUR(*c);
glVertex2d(x+w->w, y+21.);
glVertex2d(x+w->w-1., y+15.);
glVertex2d(x+w->w-3., y+10.);
@ -330,45 +420,7 @@ static void window_render(Window* w) {
glVertex2d(x+w->w-10., y+3.);
glVertex2d(x+w->w-15., y+1.);
glVertex2d(x+w->w-21., y);
glVertex2d(x+21., y);
glEnd();
// Outter outline.
glShadeModel(GL_SMOOTH);
glBegin(GL_LINE_LOOP);
// Left side.
COLOUR(*oc);
glVertex2d(x+21.-1., y-1.);
glVertex2d(x+15.-1., y+1.-1.);
glVertex2d(x+10.-1., y+3.-1.);
glVertex2d(x+6.-1., y+6.-1.);
glVertex2d(x+3.-1., y+10.-1.);
glVertex2d(x+1.-1., y+15.-1.);
glVertex2d(x-1., y+21.-1.);
glVertex2d(x-1., y+0.6*w->h); // Front of center.
glVertex2d(x-1., y+w->h-21.+1.);
glVertex2d(x+1.-1., y+w->h-15.+1.);
glVertex2d(x+3.-1., y+w->h-10.+1.);
glVertex2d(x+6.-1., y+w->h-6.+1.);
glVertex2d(x+10.-1., y+w->h-3.+1.);
glVertex2d(x+15.-1., y+w->h-1.+1.);
glVertex2d(x+21.-1., y+w->h+1.);
// Switch to right via top.
glVertex2d(x+w->w-21.+1., y+w->h+1.);
glVertex2d(x+w->w-15.+1., y+w->h-1.+1.);
glVertex2d(x+w->w-10.+1., y+w->h-3.+1.);
glVertex2d(x+w->w-6.+1., y+w->h-6.+1.);
glVertex2d(x+w->w-3.+1., y+w->h-10.+1.);
glVertex2d(x+w->w-1.+1., y+w->h-15.+1.);
glVertex2d(x+w->w+1., y+w->h-21.+1.);
glVertex2d(x+w->w+1., y+0.6*w->h); // Front of center.
glVertex2d(x+w->w-1.+1., y+21.-1.);
glVertex2d(x+w->w-3.+1., y+15.-1.);
glVertex2d(x+w->w-6.+1., y+6.-1.);
glVertex2d(x+w->w-10.+1., y+3.-1.);
glVertex2d(x+w->w-15.+1., y+1.-1.);
glVertex2d(x+w->w-21.+1., y-1.);
glVertex2d(x+21.-1., y-1.); // Back to beginning.
glVertex2d(x+21., y); // Back to beginning.
glEnd();
// Widgets.
@ -383,6 +435,7 @@ static void window_render(Window* w) {
toolkit_renderText(&w->widgets[i], x, y);
break;
case WIDGET_IMAGE:
toolkit_renderImage(&w->widgets[i], x, y);
break;
}
}
@ -439,36 +492,23 @@ static void toolkit_renderButton(Widget* btn, double bx, double by) {
// Inner outline.
glShadeModel(GL_SMOOTH);
glBegin(GL_LINE_LOOP);
// Left.
glBegin(GL_LINES);
COLOUR(*c);
glVertex2d(x, y);
COLOUR(*lc);
glVertex2d(x, y+btn->h);
glEnd();
// Right.
glBegin(GL_LINES);
COLOUR(*c);
glVertex2d(x+btn->w, y);
COLOUR(*lc);
glVertex2d(x+btn->w, y+btn->h);
glEnd();
glShadeModel(GL_FLAT);
// Bottom.
glBegin(GL_LINES);
COLOUR(*c);
glVertex2d(x, y);
glVertex2d(x+btn->w, y);
glEnd();
// Top.
glBegin(GL_LINES);
COLOUR(*lc);
glVertex2d(x, y+btn->h);
glVertex2d(x+btn->w, y+btn->h);
// Right.
COLOUR(*c);
glVertex2d(x+btn->w, y);
// Bottom.
glVertex2d(x, y);
glEnd();
// Outter outline.
glShadeModel(GL_FLAT);
glBegin(GL_LINE_LOOP);
COLOUR(cBlack);
// Left.
@ -483,12 +523,13 @@ static void toolkit_renderButton(Widget* btn, double bx, double by) {
// Bottom.
glVertex2d(x+btn->w, y-1.);
glVertex2d(x, y-1.);
glVertex2d(x-1, y);
glEnd();
gl_printMid(NULL, (int)btn->w,
bx + (double)gl_screen.w/2. + btn->x,
by + (double)gl_screen.h/2. + btn->y + (btn->h - gl_defFont.h)/2.,
&cRed, btn->string);
&cDarkRed, btn->display);
}
static void toolkit_renderText(Widget* txt, double bx, double by) {
@ -496,12 +537,61 @@ static void toolkit_renderText(Widget* txt, double bx, double by) {
gl_printMid(txt->font, txt->w,
bx + (double)gl_screen.w/2. + txt->x,
by + (double)gl_screen.h/2. + txt->y,
txt->colour, txt->name);
txt->colour, txt->text);
else
gl_printMax(txt->font, txt->w,
bx + (double)gl_screen.w/2. + txt->x,
by + (double)gl_screen.h/2. + txt->y,
txt->colour, txt->name);
txt->colour, txt->text);
}
// Render the image.
static void toolkit_renderImage(Widget* img, double bx, double by) {
glColour* lc, *c, *oc;
double x, y;
x = bx + img->x;
y = by + img->y;
lc = &cGrey90;
c = &cGrey70;
oc = &cGrey30;
// Image.
gl_blitStatic(img->image,
x + (double)gl_screen.w/2.,
y + (double)gl_screen.h/2., NULL);
// Inner outline (outwards).
glShadeModel(GL_SMOOTH);
glBegin(GL_LINE_LOOP);
COLOUR(*lc);
// Top.
glVertex2d(x-1, y+img->image->sh+1.);
glVertex2d(x+img->image->sw, y+img->image->sh+1.);
// Right.
COLOUR(*c);
glVertex2d(x+img->image->sw, y);
// Bottom.
glVertex2d(x-1., y);
// Left.
COLOUR(*lc);
glVertex2d(x-1., y+img->image->sh+1.);
glEnd();
// Outter outline.
glShadeModel(GL_SMOOTH);
glBegin(GL_LINE_LOOP);
COLOUR(*oc);
// Top.
glVertex2d(x-2., y+img->image->sh+2.);
glVertex2d(x+img->image->sw+1., y+img->image->sh+2.);
// Right.
glVertex2d(x+img->image->sw+1., y-1.);
// Bottom.
glVertex2d(x-2., y-1.);
// Left.
glVertex2d(x-2., y+img->image->sh+2.);
glEnd();
}
// Render the window.

View File

@ -12,11 +12,15 @@ void window_addButton(const unsigned int wid, const int x, const int y,
void(*call)(char*));
void window_addText(const unsigned int wid, const int x, const int y,
const int w, const int cenetered,
char* name, glFont* font, glColour* colour);
const int w, const int cenetered, char* name,
glFont* font, glColour* colour, char* string);
void window_addImage(const unsigned int wid, const int x, const int y,
char* name, glTexture* image);
// Destroy window.
void window_destroy(const unsigned int wid);
void window_destroyWidget(unsigned wid, const char* wgtname);
// Render.
void toolkit_render(void);

View File

@ -193,7 +193,7 @@ static void weapon_render(const Weapon* w) {
// Get the sprite corresponding to the direction facing.
gl_getSpriteFromDir(&sx, &sy, w->outfit->gfx_space, w->solid->dir);
gl_blitSprite(w->outfit->gfx_space, &w->solid->pos, sx, sy, NULL);
gl_blitSprite(w->outfit->gfx_space, w->solid->pos.x, w->solid->pos.y, sx, sy, NULL);
}
// Update the weapon.