diff --git a/dat/planet.xml b/dat/planet.xml index a8c8f85..569185a 100644 --- a/dat/planet.xml +++ b/dat/planet.xml @@ -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> diff --git a/gfx/planet/konosphere.png b/gfx/planet/exterior/konosphere.png similarity index 100% rename from gfx/planet/konosphere.png rename to gfx/planet/exterior/konosphere.png diff --git a/gfx/planet/saracraft.png b/gfx/planet/exterior/saracraft.png similarity index 100% rename from gfx/planet/saracraft.png rename to gfx/planet/exterior/saracraft.png diff --git a/gfx/planet/space/konosphere.png b/gfx/planet/space/konosphere.png new file mode 100644 index 0000000..20ccb16 Binary files /dev/null and b/gfx/planet/space/konosphere.png differ diff --git a/gfx/planet/space/saracraft.png b/gfx/planet/space/saracraft.png new file mode 100644 index 0000000..20ccb16 Binary files /dev/null and b/gfx/planet/space/saracraft.png differ diff --git a/src/colour.c b/src/colour.c index 3afd8cd..8f37e08 100644 --- a/src/colour.c +++ b/src/colour.c @@ -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 }; diff --git a/src/colour.h b/src/colour.h index 295086e..fb16e1a 100644 --- a/src/colour.h +++ b/src/colour.h @@ -22,5 +22,6 @@ extern glColour cGrey20; extern glColour cGrey10; extern glColour cGreen; +extern glColour cDarkRed; extern glColour cRed; diff --git a/src/land.c b/src/land.c index 3a6d76b..688733e 100644 --- a/src/land.c +++ b/src/land.c @@ -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; } diff --git a/src/opengl.c b/src/opengl.c index 45803db..7f8df98 100644 --- a/src/opengl.c +++ b/src/opengl.c @@ -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(); diff --git a/src/opengl.h b/src/opengl.h index 56b0807..01c1c5f 100644 --- a/src/opengl.h +++ b/src/opengl.h @@ -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. diff --git a/src/pilot.c b/src/pilot.c index e1e91d8..2a93a43 100644 --- a/src/pilot.c +++ b/src/pilot.c @@ -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. diff --git a/src/player.c b/src/player.c index 82905f3..c848add 100644 --- a/src/player.c +++ b/src/player.c @@ -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) { @@ -227,16 +226,19 @@ void player_render(void) { if(pilot_isDisabled(p)) c = &cInert; else if(pilot_isFlag(p, PILOT_HOSTILE)) c = &cHostile; else c = &cNeutral; + + 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. - 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->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) { @@ -244,23 +246,27 @@ void player_render(void) { if(areEnemies(player->faction, planet->faction)) c = &cHostile; else c = &cNeutral; + + 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. - 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. } // 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, diff --git a/src/space.c b/src/space.c index 54ec5df..7fccac7 100644 --- a/src/space.c +++ b/src/space.c @@ -11,22 +11,26 @@ #include "pause.h" #include "player.h" -#define XML_PLANET_ID "Planets" -#define XML_PLANET_TAG "planet" +#define XML_PLANET_ID "Planets" +#define XML_PLANET_TAG "planet" -#define XML_SYSTEM_ID "Systems" -#define XML_SYSTEM_TAG "ssys" +#define XML_SYSTEM_ID "Systems" +#define XML_SYSTEM_TAG "ssys" -#define PLANET_DATA "../dat/planet.xml" -#define SYSTEM_DATA "../dat/ssys.xml" +#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. #define FLAG_XSET (1<<0) #define FLAG_YSET (1<<1) -#define FLAG_ASTEROIDSSET (1<<2) +#define FLAG_ASTEROIDSSET (1<<2) #define FLAG_INTEFERENCESET (1<<3) static StarSystem* systems = NULL; @@ -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,10 +305,12 @@ 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(flags&FLAG_XSET, "x"); - MELEMENT(flags&FLAG_YSET, "y"); - MELEMENT(tmp->class, "class"); - MELEMENT(tmp->faction, "faction"); + 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"); + MELEMENT(tmp->faction, "faction"); #undef MELEMENT } else WARN("No planet found matching name '%s'", name); @@ -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); } diff --git a/src/space.h b/src/space.h index ae8a164..a1640a4 100644 --- a/src/space.h +++ b/src/space.h @@ -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. diff --git a/src/toolkit.c b/src/toolkit.c index 82bca35..f5b0574 100644 --- a/src/toolkit.c +++ b/src/toolkit.c @@ -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. @@ -178,9 +200,17 @@ unsigned int window_create(const int x, const int y, const int w, const int h) { // Destroy a widget. 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,78 +348,79 @@ static void window_render(Window* w) { glBegin(GL_LINE_LOOP); // Left side. COLOUR(*c); - glVertex2d(x+21., y); - glVertex2d(x+15., y+1.); - glVertex2d(x+10., y+3.); - glVertex2d(x+6., y+6.); - glVertex2d(x+3., y+10.); - glVertex2d(x+1., y+15.); - glVertex2d(x, y+21.); + 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, 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+15., y+w->h-1.); - glVertex2d(x+21., y+w->h); + 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., y+w->h); - 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-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. + 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, y+21.); - glVertex2d(x+w->w-1., y+15.); - glVertex2d(x+w->w-3., y+10.); - glVertex2d(x+w->w-6., y+6.); - glVertex2d(x+w->w-10., y+3.); - glVertex2d(x+w->w-15., y+1.); - glVertex2d(x+w->w-21., y); - glVertex2d(x+21., y); + 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_SMOOTH); + glShadeModel(GL_FLAT); 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.); + glVertex2d(x+21., y); + glVertex2d(x+15., y+1.); + glVertex2d(x+10., y+3.); + glVertex2d(x+6., y+6.); + glVertex2d(x+3., y+10.); + glVertex2d(x+1., y+15.); + glVertex2d(x, y+21.); + 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-3.); + glVertex2d(x+15., y+w->h-1.); + glVertex2d(x+21., y+w->h); // 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+w->w-21., y+w->h); + 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-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. + glVertex2d(x+w->w, y+21.); + glVertex2d(x+w->w-1., y+15.); + glVertex2d(x+w->w-3., y+10.); + glVertex2d(x+w->w-6., y+6.); + glVertex2d(x+w->w-10., y+3.); + glVertex2d(x+w->w-15., y+1.); + glVertex2d(x+w->w-21., y); + 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); - // Left. - glBegin(GL_LINES); + glBegin(GL_LINE_LOOP); + // Left. 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); + // Top. glVertex2d(x+btn->w, y+btn->h); - glEnd(); - - glShadeModel(GL_FLAT); - // Bottom. - glBegin(GL_LINES); + // Right. 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); + // 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. diff --git a/src/toolkit.h b/src/toolkit.h index aa097a3..9e1f2e9 100644 --- a/src/toolkit.h +++ b/src/toolkit.h @@ -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); diff --git a/src/weapon.c b/src/weapon.c index d975393..b059eff 100644 --- a/src/weapon.c +++ b/src/weapon.c @@ -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.