[Add] Basic Gui.

-- Minimap.
  -- Health bars.
This commit is contained in:
Allanis 2013-02-05 23:10:46 +00:00
parent 1fa45f1ff2
commit 4d7c01f078
12 changed files with 242 additions and 23 deletions

BIN
gfx/gui/frame.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

BIN
gfx/gui/frame.xcf Normal file

Binary file not shown.

View File

@ -222,10 +222,12 @@ int main(int argc, char** argv) {
if(joystick_init())
WARN("Error initializing joystick input");
if(namjoystick != NULL) {
// Use a joystick name to find joystick.
joystick_use(joystick_get(namjoystick));
free(namjoystick);
}
else if(indjoystick >= 0)
// Must be using an id instead.
joystick_use(indjoystick);
}
@ -234,6 +236,7 @@ int main(int argc, char** argv) {
WARN("Error initializing AI");
gl_fontInit(NULL, NULL, 16);
gui_init(); // Init the GUI crap.
// Data loading.
outfit_load();
@ -267,6 +270,7 @@ int main(int argc, char** argv) {
weapon_exit(); // Destroy all active weapons.
space_exit(); // Clean up the universe!!!
pilots_free(); // Free the pilots, they where locked up D:
gui_free(); // Free up the gui.
ships_free();
outfit_free();

View File

@ -3,7 +3,10 @@
#define MALLOC_L(type)(malloc(sizeof(type)))
#define CALLOC_L(type)(calloc(1, sizeof(type)))
#define ABS(X) ((X<0)?-X:X)
#define ABS(x) ((x<0)?-(x):(x))
#define MAX(x,y) (((x)>(y))?(x):(y))
#define MIN(x,y) (((x)>(y))?(y):(x))
extern char* data; // Modifiable datafile.
#define DATA data // Data file.

View File

@ -17,6 +17,10 @@
#define FONT_DEF "../gfx/fonts/FreeSans.ttf"
// offsets to Adjust the pilot's place onscreen to be in the middle, even with the GUI.
extern double gui_xoff;
extern double gui_yoff;
// The screen info, gives data of current opengl settings.
gl_info gl_screen;
@ -256,8 +260,8 @@ void gl_blitSprite(const gl_texture* sprite, const Vec2* pos, const int sx, cons
glMatrixMode(GL_PROJECTION);
glPushMatrix(); // Projection translation matrix.
glTranslated(VX(*pos) - VX(*gl_camera) - sprite->sw/2.,
VY(*pos) -VY(*gl_camera) - sprite->sh/2., 0.);
glTranslated(VX(*pos) - VX(*gl_camera) - sprite->sw/2. + gui_xoff,
VY(*pos) -VY(*gl_camera) - sprite->sh/2. + gui_yoff, 0.);
glScalef((double)gl_screen.w/SCREEN_W, (double)gl_screen.h/SCREEN_H, 0.);
// Actual blitting....
@ -293,15 +297,15 @@ void gl_blitStatic(const gl_texture* texture, const Vec2* pos) {
// Actual blitting..
glBindTexture(GL_TEXTURE_2D, texture->texture);
glBegin(GL_TRIANGLE_STRIP);
glColor4ub(1., 1., 1., 1.);
glColor4d(1., 1., 1., 1.);
glTexCoord2d(0., 0.);
glVertex2d(0., 0.);
glTexCoord2d(texture->w/texture->rw, 0.);
glVertex2d(texture->w, 0.);
glTexCoord2d(0., texture->h/texture->rh);
glVertex2d(0., texture->h);
glTexCoord2d(texture->w/texture->rw, texture->h/texture->rh);
glVertex2d(texture->w, texture->h);
glTexCoord2d(texture->sw/texture->rw, 0.);
glVertex2d(texture->sw, 0.);
glTexCoord2d(0., texture->sh/texture->rh);
glVertex2d(0., texture->sh);
glTexCoord2d(texture->sw/texture->rw, texture->sh/texture->rh);
glVertex2d(texture->sw, texture->h);
glEnd();
glPopMatrix(); // Pop the translation matrix.

View File

@ -75,12 +75,16 @@ void pilot_hit(Pilot* p, double damage_shield, double damage_armor) {
// Shields can take part of the blow.
p->armor -= p->shield/damage_shield*damage_armor;
}
else if(p->armor-damage_armor > 0.)
p->armor -= damage_armor;
else
p->armor = 0.;
}
// Render the pilot.
void pilot_render(Pilot* p) {
int sprite;
gl_texture* t = p->ship->gfx_ship;
gl_texture* t = p->ship->gfx_space;
// Get the sprite corresponding to the direction facing.
sprite = (int)(p->solid->dir / (2.0*M_PI / (t->sy * t->sx)));
@ -90,6 +94,15 @@ void pilot_render(Pilot* p) {
// Update the pilot.
static void pilot_update(Pilot* pilot, const double dt) {
// Regeneration.
if(pilot->armor < pilot->armor_max)
pilot->armor += pilot->ship->armor_regen*dt;
else
pilot->shield += pilot->ship->shield_regen*dt;
if(pilot->armor > pilot->armor_max) pilot->armor = pilot->armor_max;
if(pilot->armor > pilot->armor_max) pilot->armor = pilot->armor_max;
if((pilot->solid->dir > 2.*M_PI) || (pilot->solid->dir < 0.0))
pilot->solid->dir = fmod(pilot->solid->dir, 2.*M_PI);
@ -126,9 +139,13 @@ void pilot_init(Pilot* pilot, Ship* ship, char* name, const double dir, const Ve
pilot->solid = solid_create(ship->mass, dir, pos, vel);
// Max shields armor.
pilot->armor = ship->armor;
pilot->shield = ship->shield;
pilot->energy = ship->energy;
pilot->armor_max = ship->armor;
pilot->shield_max = ship->shield;
pilot->energy_max = ship->energy;
pilot->armor = pilot->armor_max;
pilot->shield = pilot->shield_max;
pilot->energy = pilot->energy_max;
// Initially idle.
pilot->task = NULL;

View File

@ -5,6 +5,10 @@
#include "outfit.h"
#include "ship.h"
// Aproximation for pilot size.
#define PILOT_SIZE_APROX 0.8
// Creation flags.
#define PILOT_PLAYER 1 // Pilot is a player.
typedef struct {
@ -24,6 +28,7 @@ typedef struct Pilot {
// Current health.
double armor, shield, energy;
double armor_max, shield_max, energy_max;
void (*think)(struct Pilot*); // AI thinking for the pilot.
void (*update)(struct Pilot*, const double); // Update the pilot.

View File

@ -2,8 +2,11 @@
#include "main.h"
#include "pilot.h"
#include "log.h"
#include "opengl.h"
#include "player.h"
#define POW2(x) ((x)*(x))
#define KEY_PRESS 1.
#define KEY_RELEASE -1.
@ -18,17 +21,199 @@ static Keybind** player_input; // Contains the players keybindings.
// Name of each keybinding.
const char* keybindNames[] = { "accel", "left", "right", "primary" };
// Player stuff.
Pilot* player = NULL; // extern in pilot.h
static double player_turn = 0.; // Turn velocity from input.
static double player_acc = 0.; // Accel velocity from input.
static int player_primary = 0; // Player is shooting primary weapon.
// Pilot stuff for GUI.
extern Pilot** pilot_stack;
extern int pilots;
// GUI crap.
// Need these offsets to render properly. -- Used in opengl.c
// -- Colors.
typedef struct {
double r, g, b, a;
} Color;
#define COLOR(x) (x).r, (x).g, (x).b, (x).a
Color cRadar_player = { .r = 0.4, .g = 0.8, .b = 0.9, .a = 1. };
Color cRadar_neut = { .r = 0.8, .g = 0.8, .b = 0.8, .a = 1. };
Color cShield = { .r = 0.2, .g = 0.2, .b = 0.8, .a = 1. };
Color cArmor = { .r = 0.5, .g = 0.5, .b = 0.5, .a = 1. };
Color cEnergy = { .r = 0.2, .g = 0.8, .b = 0.2, .a = 1. };
typedef enum { RADAR_RECT, RADAR_CIRCLE } RadarShape;
typedef struct {
double w,h; // Dimensions.
RadarShape shape;
double res; // Resolution.
} Radar;
typedef struct {
double w,h;
} Rect;
typedef struct {
// graphics.
gl_texture* gfx_frame;
Radar radar;
Rect shield, armor, energy;
// Positions.
Vec2 pos_frame;
Vec2 pos_radar;
Vec2 pos_shield, pos_armor, pos_energy;
} GUI;
GUI gui; // Le Gui!
double gui_xoff = 0.;
double gui_yoff = 0.;
extern void pilot_render(Pilot* pilot); // Extern is in Pilot.*
// Render the player.
void player_render(void) {
pilot_render(player);
// Render gui.
// GUI!
// -- Frame.
gl_blitStatic(gui.gfx_frame, &gui.pos_frame);
// -- Radar.
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glTranslated(VX(gui.pos_radar) - gl_screen.w/2. + gui.radar.w/2.,
VY(gui.pos_radar) - gl_screen.h/2. - gui.radar.h/2., 0.);
glBegin(GL_POINTS);
// Player.
glColor4d(COLOR(cRadar_player));
glVertex2d( 0., 2. );
glVertex2d( 0., 1. );
glVertex2d( 0., 0. );
glVertex2d( 0., -1. );
glVertex2d( 0., -2. );
glVertex2d( 2., 0. );
glVertex2d( 2., 0. );
glVertex2d( -1., 0. );
glVertex2d( -2., 0. );
int i;
double x, y, sx, sy;
Pilot* p;
switch(gui.radar.shape) {
case RADAR_RECT:
glEnd(); // Put end to those points.
for(i = 1; i < pilots; i++) {
p = pilot_stack[i];
x = (p->solid->pos.x - player->solid->pos.x) / gui.radar.res;
y = (p->solid->pos.y - player->solid->pos.y) / gui.radar.res;
sx = PILOT_SIZE_APROX/2. * p->ship->gfx_space->sw / gui.radar.res;
sy = PILOT_SIZE_APROX/2. * p->ship->gfx_space->sh / gui.radar.res;
if((ABS(x) > gui.radar.w / 2+sx) || (ABS(y) > gui.radar.h / 2. + sy))
continue; // Pilot isn't in range.
glBegin(GL_QUADS);
glColor4d(COLOR(cRadar_neut));
glVertex2d(MAX(x-sx, -gui.radar.w/2.), MIN(y+sx, gui.radar.w/2.)); // top left.
glVertex2d(MIN(x+sx, gui.radar.w/2.), MIN(y+sy, gui.radar.h/2.)); // Top right.
glVertex2d(MAX(x+sx, gui.radar.w/2.), MAX(y-sy, -gui.radar.h/2.)); // Bottom right.
glVertex2d(MAX(x-sx, -gui.radar.w/2.), MIN(y-sy, -gui.radar.h/2.)); // Bottom left.
glEnd(); // The Quads.
}
case RADAR_CIRCLE:
for(i = 1; i < pilots; i++) {
p = pilot_stack[i];
glColor4d(COLOR(cRadar_neut));
glVertex2d((p->solid->pos.x - player->solid->pos.x) / gui.radar.res,
(p->solid->pos.y - player->solid->pos.y) / gui.radar.res);
}
glEnd();
break;
}
glPopMatrix(); // GL_PROJECTION.
// Health.
glBegin(GL_QUADS); // Shield.
glColor4d(COLOR(cShield));
x = VX(gui.pos_shield) - gl_screen.w/2.;
y = VY(gui.pos_shield) - gl_screen.h/2.;
sx = player->shield / player->shield_max * gui.shield.w;
sy = gui.shield.h;
glVertex2d(x, y);
glVertex2d(x+sx, y);
glVertex2d(x+sx, y-sy);
glVertex2d(x, y-sy);
glEnd();
glBegin(GL_QUADS); // Armor.
glColor4d(COLOR(cArmor));
x = VX(gui.pos_armor) - gl_screen.w/2.;
y = VY(gui.pos_armor) - gl_screen.h/2.;
sx = player->armor / player->armor_max * gui.armor.w;
sy = gui.armor.h;
glVertex2d(x, y);
glVertex2d(x+sx, y);
glVertex2d(x+sx, y-sy);
glVertex2d(x, y-sy);
glEnd();
glBegin(GL_QUADS); // Energy.
glColor4d(COLOR(cEnergy));
x = VX(gui.pos_energy) - gl_screen.w/2.;
y = VY(gui.pos_energy) - gl_screen.h/2.;
sx = player->energy / player->energy_max * gui.energy.w;
sy = gui.energy.h;
glVertex2d(x, y);
glVertex2d(x+sx, y);
glVertex2d(x+sx, y-sy);
glVertex2d(x, y-sy);
glEnd();
}
// Init GUI.
int gui_init(void) {
// -- Frame.
gui.gfx_frame = gl_newImage("../gfx/gui/frame.png");
vect_csetmin(&gui.pos_frame,
gl_screen.w - gui.gfx_frame->w, // x.
gl_screen.h - gui.gfx_frame->h); // y.
gui_xoff = -gui.gfx_frame->w/2.; // Offset is only horizontal and on the right side.
// -- Radar.
gui.radar.res = 10.;
gui.radar.w = 128.;
gui.radar.h = 128.;
gui.radar.shape = RADAR_RECT; // RADAR_CIRCLE;
vect_csetmin(&gui.pos_radar,
VX(gui.pos_frame) + 11, // x
VY(gui.pos_frame) + gui.gfx_frame->h - 10); // y.
// -- Bars.
gui.shield.w = gui.armor.w = gui.energy.w = 128;
gui.shield.h = gui.armor.h = gui.energy.h = 10;
vect_csetmin(&gui.pos_shield,
VX(gui.pos_frame) + 10, // x
VY(gui.pos_frame) + gui.gfx_frame->h - 201); // y.
vect_csetmin(&gui.pos_armor,
VX(gui.pos_frame) + 10, // x
VY(gui.pos_frame) + gui.gfx_frame->h - 218); // y.
vect_csetmin(&gui.pos_energy,
VX(gui.pos_frame) + 10, // x
VY(gui.pos_frame) + gui.gfx_frame->h - 236); // y.
return 0;
}
// Free the GUI.
void gui_free(void) {
gl_freeTexture(gui.gfx_frame);
}
// Used in pilot.c

View File

@ -6,6 +6,9 @@ extern Pilot* pilot;
typedef enum { KEYBIND_NULL, KEYBIND_KEYBOARD, KEYBIND_JAXIS, KEYBIND_JBUTTON } KeybindType;
// Render.
int gui_init(void);
void gui_free(void);
void player_render(void);
int player_isFlag(unsigned int flag);

View File

@ -49,7 +49,7 @@ static Ship* ship_parse(xmlNodePtr parent) {
if(strcmp((char*)node->name, "GFX")==0) {
snprintf(str, strlen((char*)node->children->content)+sizeof(SHIP_GFX),
SHIP_GFX"%s", (char*)node->children->content);
tmp->gfx_ship = gl_newSprite(str, 6, 6);
tmp->gfx_space = gl_newSprite(str, 6, 6);
}
else if(strcmp((char*)node->name, "class")==0)
tmp->class = atoi((char*)node->children->content);
@ -121,7 +121,7 @@ static Ship* ship_parse(xmlNodePtr parent) {
#define MELEMENT(o,s) if(o == 0) WARN("Ship '%s' missing '"s"' element", tmp->name)
if(tmp->name == NULL) WARN("Ship '%s' missing 'name' tag", tmp->name);
if(tmp->gfx_ship == NULL) WARN("Ship '%s' missing 'GFX' element", tmp->name);
if(tmp->gfx_space == NULL) WARN("Ship '%s' missing 'GFX' element", tmp->name);
MELEMENT(tmp->thrust, "thrust");
MELEMENT(tmp->turn, "turn");
MELEMENT(tmp->speed, "speed");
@ -191,7 +191,7 @@ void ships_free(void) {
so = so->next;
free(sot);
}
gl_freeTexture((ship_stack+i)->gfx_ship);
gl_freeTexture((ship_stack+i)->gfx_space);
}
free(ship_stack);
ship_stack = NULL;

View File

@ -28,7 +28,7 @@ typedef struct {
double thrust, turn, speed;
// Graphics.
gl_texture* gfx_ship, *gfx_target;
gl_texture* gfx_space, *gfx_target;
// Characteristics.
int crew;

View File

@ -10,8 +10,6 @@
#include "pilot.h"
#include "weapon.h"
#define SIZE_APROX 0.8 // Aproximation for circle collision detection.
// Some stuff from pilot.
extern Pilot** pilot_stack;
extern int pilots;
@ -94,8 +92,8 @@ static void weapon_update(Weapon* w, const double dt, WeaponLayer layer) {
int i;
for(i = 0; i < pilots; i++) {
if((w->parent != pilot_stack[i]->id) &&
(DIST(w->solid->pos, pilot_stack[i]->solid->pos) < (SIZE_APROX +
w->outfit->gfx_space->sw/2. + pilot_stack[i]->ship->gfx_ship->sw/2.))) {
(DIST(w->solid->pos, pilot_stack[i]->solid->pos) < (PILOT_SIZE_APROX *
w->outfit->gfx_space->sw/2. + pilot_stack[i]->ship->gfx_space->sw/2.))) {
pilot_hit(pilot_stack[i], w->outfit->damage_shield, w->outfit->damage_armor);
weapon_destroy(w, layer);
return;