[Add] Basic toolkit for window/widget rendering etc.
[Add] Landing.
This commit is contained in:
parent
9899458f91
commit
14e525078e
@ -153,6 +153,7 @@ int conf_loadConfig(const char* file) {
|
|||||||
} else {
|
} else {
|
||||||
// Failed to load the config file..
|
// Failed to load the config file..
|
||||||
DEBUG("Config file '%s' not found.", file);
|
DEBUG("Config file '%s' not found.", file);
|
||||||
|
lua_close(L);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
lua_close(L);
|
lua_close(L);
|
||||||
|
12
src/input.c
12
src/input.c
@ -2,6 +2,7 @@
|
|||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "player.h"
|
#include "player.h"
|
||||||
#include "pause.h"
|
#include "pause.h"
|
||||||
|
#include "toolkit.h"
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
|
|
||||||
#define KEY_PRESS ( 1.)
|
#define KEY_PRESS ( 1.)
|
||||||
@ -53,7 +54,7 @@ void input_setDefault(void) {
|
|||||||
input_setKeybind("mapzoomin", KEYBIND_KEYBOARD, SDLK_UP, 0);
|
input_setKeybind("mapzoomin", KEYBIND_KEYBOARD, SDLK_UP, 0);
|
||||||
input_setKeybind("mapzoomout", KEYBIND_KEYBOARD, SDLK_DOWN, 0);
|
input_setKeybind("mapzoomout", KEYBIND_KEYBOARD, SDLK_DOWN, 0);
|
||||||
input_setKeybind("screenshot", KEYBIND_KEYBOARD, SDLK_F12, 0);
|
input_setKeybind("screenshot", KEYBIND_KEYBOARD, SDLK_F12, 0);
|
||||||
input_setKeybind("pause", KEYBIND_KEYBOARD, SDLK_p, 0);
|
input_setKeybind("pause", KEYBIND_KEYBOARD, SDLK_F1, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialization/exit functions (does not assign keys).
|
// Initialization/exit functions (does not assign keys).
|
||||||
@ -99,7 +100,7 @@ void input_setKeybind(char* keybind, KeybindType type, int key, int reverse) {
|
|||||||
// value : Value of keypress (defined above).
|
// value : Value of keypress (defined above).
|
||||||
// abs : Whether or not it's an abs value (For those pesky joysticks.
|
// abs : Whether or not it's an abs value (For those pesky joysticks.
|
||||||
// =====================================================================
|
// =====================================================================
|
||||||
#define KEY(s) strcmp(input_keybinds[keynum]->name, s)==0
|
#define KEY(s) (strcmp(input_keybinds[keynum]->name, s)==0)
|
||||||
static void input_key(int keynum, double value, int abs) {
|
static void input_key(int keynum, double value, int abs) {
|
||||||
// Accelerating.
|
// Accelerating.
|
||||||
if(KEY("accel")) {
|
if(KEY("accel")) {
|
||||||
@ -198,6 +199,7 @@ static void input_key(int keynum, double value, int abs) {
|
|||||||
// Pause the game.
|
// Pause the game.
|
||||||
if(KEY("pause")) {
|
if(KEY("pause")) {
|
||||||
if(value == KEY_PRESS) {
|
if(value == KEY_PRESS) {
|
||||||
|
if(!toolkit)
|
||||||
if(paused) unpause();
|
if(paused) unpause();
|
||||||
} else pause();
|
} else pause();
|
||||||
}
|
}
|
||||||
@ -292,6 +294,12 @@ void input_handle(SDL_Event* event) {
|
|||||||
case SDL_KEYUP:
|
case SDL_KEYUP:
|
||||||
input_keyup(event->key.keysym.sym);
|
input_keyup(event->key.keysym.sym);
|
||||||
break;
|
break;
|
||||||
|
// Toolkit.
|
||||||
|
case SDL_MOUSEMOTION:
|
||||||
|
case SDL_MOUSEBUTTONDOWN:
|
||||||
|
case SDL_MOUSEBUTTONUP:
|
||||||
|
if(toolkit) toolkit_mouseEvent(event);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
30
src/land.c
Normal file
30
src/land.c
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
#include "toolkit.h"
|
||||||
|
#include "pause.h"
|
||||||
|
#include "land.h"
|
||||||
|
|
||||||
|
int landed = 0;
|
||||||
|
|
||||||
|
static int land_wid = 0;
|
||||||
|
static Planet* planet = NULL;
|
||||||
|
|
||||||
|
// Land the player.
|
||||||
|
void land(Planet* p) {
|
||||||
|
if(landed) return;
|
||||||
|
|
||||||
|
planet = p;
|
||||||
|
pause();
|
||||||
|
land_wid = window_create(-1, -1, 400, 300);
|
||||||
|
window_addButton(land_wid, 400-80-20, 20, 80, 40, "takeoff", "Takeoff", (void(*)(char*))takeoff);
|
||||||
|
landed = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Takeoff from the planet.
|
||||||
|
void takeoff(void) {
|
||||||
|
if(!landed) return;
|
||||||
|
|
||||||
|
planet = NULL;
|
||||||
|
unpause();
|
||||||
|
window_destroy(land_wid);
|
||||||
|
landed = 0;
|
||||||
|
}
|
||||||
|
|
8
src/land.h
Normal file
8
src/land.h
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "space.h"
|
||||||
|
|
||||||
|
extern int landed;
|
||||||
|
|
||||||
|
void land(Planet* p);
|
||||||
|
void takeoff(void);
|
||||||
|
|
19
src/main.c
19
src/main.c
@ -51,6 +51,7 @@ static void display_fps(const double dt);
|
|||||||
static void window_caption(void);
|
static void window_caption(void);
|
||||||
static void data_name(void);
|
static void data_name(void);
|
||||||
// Update.
|
// Update.
|
||||||
|
static void fps_control(void);
|
||||||
static void update_space(void);
|
static void update_space(void);
|
||||||
static void render_space(void);
|
static void render_space(void);
|
||||||
|
|
||||||
@ -152,6 +153,7 @@ int main(int argc, char** argv) {
|
|||||||
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
|
fps_control(); // Who doesn't love FPS control?
|
||||||
if(!paused) update_space(); // Update the game.
|
if(!paused) update_space(); // Update the game.
|
||||||
|
|
||||||
render_space();
|
render_space();
|
||||||
@ -186,24 +188,21 @@ int main(int argc, char** argv) {
|
|||||||
// Updates the game.
|
// Updates the game.
|
||||||
static double fps_dt = 1.;
|
static double fps_dt = 1.;
|
||||||
static double dt = 0.;
|
static double dt = 0.;
|
||||||
static void update_space(void) {
|
static void fps_control(void) {
|
||||||
// dt in ms/1000.
|
// dt in ms/1000.
|
||||||
dt = (double)(SDL_GetTicks() - gtime) / 1000.;
|
dt = (double)(SDL_GetTicks() - gtime) / 1000.;
|
||||||
gtime = SDL_GetTicks();
|
gtime = SDL_GetTicks();
|
||||||
|
|
||||||
// TODO: This could use some work.
|
// If the fps is limited..
|
||||||
if(dt > MINIMUM_FPS) {
|
if((max_fps != 0) && (dt < 1./max_fps)) {
|
||||||
Vec2 pos;
|
|
||||||
vect_csetmin(&pos, 10., (double)(gl_screen.h-40));
|
|
||||||
SDL_GL_SwapBuffers();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// If FPS is limited.
|
|
||||||
else if((max_fps != 0) && (dt < 1./max_fps)) {
|
|
||||||
double delay = 1./max_fps - dt;
|
double delay = 1./max_fps - dt;
|
||||||
SDL_Delay(delay);
|
SDL_Delay(delay);
|
||||||
fps_dt += delay; // Make sure it displays the propper FPS.
|
fps_dt += delay; // Make sure it displays the propper FPS.
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the game.
|
||||||
|
static void update_space(void) {
|
||||||
weapons_update(dt);
|
weapons_update(dt);
|
||||||
pilots_update(dt);
|
pilots_update(dt);
|
||||||
}
|
}
|
||||||
|
13
src/opengl.c
13
src/opengl.c
@ -19,8 +19,11 @@
|
|||||||
#define FONT_DEF "../gfx/fonts/font.ttf"
|
#define FONT_DEF "../gfx/fonts/font.ttf"
|
||||||
|
|
||||||
// Default colors.
|
// Default colors.
|
||||||
glColour cGrey = { .r = 0.75, .g = 0.75, .b = 0.75, .a = 1 };
|
gl_colour cLightGrey = { .r = 0.80, .g = 0.80, .b = 0.80, .a = 1 };
|
||||||
glColour cGreen = { .r = 0.20, .g = 0.80, .b = 0.20, .a = 1 };
|
gl_colour cGrey = { .r = 0.65, .g = 0.65, .b = 0.65, .a = 1 };
|
||||||
|
gl_colour cDarkGrey = { .r = 0.50, .g = 0.50, .b = 0.50, .a = 1 };
|
||||||
|
gl_colour cGreen = { .r = 0.20, .g = 0.80, .b = 0.20, .a = 1 };
|
||||||
|
gl_colour cRed = { .r = 0.80, .g = 0.20, .b = 0.20, .a = 1 };
|
||||||
|
|
||||||
// offsets to Adjust the pilot's place onscreen to be in the middle, even with the GUI.
|
// offsets to Adjust the pilot's place onscreen to be in the middle, even with the GUI.
|
||||||
extern double gui_xoff;
|
extern double gui_xoff;
|
||||||
@ -349,7 +352,7 @@ void gl_getSpriteFromDir(int* x, int* y, const gl_texture* t, const double dir)
|
|||||||
// ================
|
// ================
|
||||||
|
|
||||||
// Blit the sprite at given position.
|
// Blit the sprite at given position.
|
||||||
void gl_blitSprite(const gl_texture* sprite, const Vec2* pos, const int sx, const int sy, const glColour* c) {
|
void gl_blitSprite(const gl_texture* sprite, const Vec2* pos, const int sx, const int sy, const gl_colour* c) {
|
||||||
// Don't bother drawing if offscreen -- waste of cycles.
|
// 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 ||
|
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)
|
fabs(VY(*pos) -VY(*gl_camera)+gui_yoff) > gl_screen.h / 2 + sprite->sh / 2)
|
||||||
@ -391,7 +394,7 @@ void gl_blitSprite(const gl_texture* sprite, const Vec2* pos, const int sx, cons
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Just straight out blit the thing at position.
|
// Just straight out blit the thing at position.
|
||||||
void gl_blitStatic(const gl_texture* texture, const Vec2* pos, const glColour* c) {
|
void gl_blitStatic(const gl_texture* texture, const Vec2* pos, const gl_colour* c) {
|
||||||
glEnable(GL_TEXTURE_2D);
|
glEnable(GL_TEXTURE_2D);
|
||||||
glMatrixMode(GL_PROJECTION);
|
glMatrixMode(GL_PROJECTION);
|
||||||
glPushMatrix(); // Set up translation matrix.
|
glPushMatrix(); // Set up translation matrix.
|
||||||
@ -425,7 +428,7 @@ void gl_bindCamera(const Vec2* pos) {
|
|||||||
|
|
||||||
// Print text on screen! YES!!!! Just like printf! But different!
|
// Print text on screen! YES!!!! Just like printf! But different!
|
||||||
// Defaults ft_font to gl_defFont if NULL.
|
// Defaults ft_font to gl_defFont if NULL.
|
||||||
void gl_print(const gl_font* ft_font, const Vec2* pos, const glColour* c, const char* fmt, ...) {
|
void gl_print(const gl_font* ft_font, const Vec2* pos, const gl_colour* c, const char* fmt, ...) {
|
||||||
//float h = ft_font->h / .63; // Slightly increases font size.
|
//float h = ft_font->h / .63; // Slightly increases font size.
|
||||||
char text[256];
|
char text[256];
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
15
src/opengl.h
15
src/opengl.h
@ -30,12 +30,15 @@ extern gl_info gl_screen; // Local structure set with gl_init etc.
|
|||||||
// Colours.
|
// Colours.
|
||||||
typedef struct {
|
typedef struct {
|
||||||
double r, g, b, a;
|
double r, g, b, a;
|
||||||
} glColour;
|
} gl_colour;
|
||||||
#define COLOUR(x) glColor4d((x).r, (x).g, (x).b, (x).a)
|
#define COLOUR(x) glColor4d((x).r, (x).g, (x).b, (x).a)
|
||||||
|
|
||||||
// Default colors.
|
// Default colors.
|
||||||
extern glColour cGrey;
|
extern gl_colour cLightGrey;
|
||||||
extern glColour cGreen;
|
extern gl_colour cGrey;
|
||||||
|
extern gl_colour cDarkGrey;
|
||||||
|
extern gl_colour cGreen;
|
||||||
|
extern gl_colour cRed;
|
||||||
|
|
||||||
// Spritesheet info.
|
// Spritesheet info.
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -69,11 +72,11 @@ void gl_freeTexture(gl_texture* texture);
|
|||||||
|
|
||||||
// Rendering.
|
// Rendering.
|
||||||
void gl_blitSprite(const gl_texture* sprite, const Vec2* pos,
|
void gl_blitSprite(const gl_texture* sprite, const Vec2* pos,
|
||||||
const int sx, const int sy, const glColour* c);
|
const int sx, const int sy, const gl_colour* c);
|
||||||
|
|
||||||
void gl_blitStatic(const gl_texture* texture, const Vec2* pos, const glColour* c);
|
void gl_blitStatic(const gl_texture* texture, const Vec2* pos, const gl_colour* c);
|
||||||
void gl_bindCamera(const Vec2* pos);
|
void gl_bindCamera(const Vec2* pos);
|
||||||
void gl_print(const gl_font* ft_font, const Vec2* pos, const glColour* c, const char* fmt, ...);
|
void gl_print(const gl_font* ft_font, const Vec2* pos, const gl_colour* c, const char* fmt, ...);
|
||||||
int gl_printWidth(const gl_font* ft_font, const char* fmt, ...);
|
int gl_printWidth(const gl_font* ft_font, const char* fmt, ...);
|
||||||
|
|
||||||
// Initialize/cleanup.
|
// Initialize/cleanup.
|
||||||
|
@ -278,8 +278,8 @@ int outfit_load(void) {
|
|||||||
void outfit_free(void) {
|
void outfit_free(void) {
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < outfits; i++) {
|
for(i = 0; i < outfits; i++) {
|
||||||
if(outfit_isWeapon(&outfit_stack[i]) && outfit_stack[i].gfx_space)
|
// Free graphics.
|
||||||
gl_freeTexture(outfit_stack[i].gfx_space);
|
if(outfit_stack[i].gfx_space) gl_freeTexture(outfit_stack[i].gfx_space);
|
||||||
|
|
||||||
if(outfit_isLauncher(&outfit_stack[i]) && outfit_stack[i].ammo)
|
if(outfit_isLauncher(&outfit_stack[i]) && outfit_stack[i].ammo)
|
||||||
free(outfit_stack[i].ammo);
|
free(outfit_stack[i].ammo);
|
||||||
|
@ -20,7 +20,6 @@ static void pilots_unpause(void);
|
|||||||
void pause(void) {
|
void pause(void) {
|
||||||
if(paused) return; // Well well.. We are paused already.
|
if(paused) return; // Well well.. We are paused already.
|
||||||
|
|
||||||
gtime -= SDL_GetTicks();
|
|
||||||
pilots_pause();
|
pilots_pause();
|
||||||
weapons_pause();
|
weapons_pause();
|
||||||
|
|
||||||
@ -30,7 +29,6 @@ void pause(void) {
|
|||||||
void unpause(void) {
|
void unpause(void) {
|
||||||
if(!paused) return; // We are unpaused already.
|
if(!paused) return; // We are unpaused already.
|
||||||
|
|
||||||
gtime += SDL_GetTicks();
|
|
||||||
pilots_unpause();
|
pilots_unpause();
|
||||||
weapons_unpause();
|
weapons_unpause();
|
||||||
|
|
||||||
|
37
src/player.c
37
src/player.c
@ -8,6 +8,7 @@
|
|||||||
#include "xml.h"
|
#include "xml.h"
|
||||||
#include "space.h"
|
#include "space.h"
|
||||||
#include "rng.h"
|
#include "rng.h"
|
||||||
|
#include "land.h"
|
||||||
#include "player.h"
|
#include "player.h"
|
||||||
|
|
||||||
#define XML_GUI_ID "GUIs" // XML section identifier.
|
#define XML_GUI_ID "GUIs" // XML section identifier.
|
||||||
@ -39,20 +40,20 @@ extern int pilots;
|
|||||||
|
|
||||||
// -- Colours.
|
// -- Colours.
|
||||||
// Standard colors.
|
// Standard colors.
|
||||||
glColour cConsole = { .r = 0.5, .g = 0.8, .b = 0.5, .a = 1. };
|
gl_colour cConsole = { .r = 0.5, .g = 0.8, .b = 0.5, .a = 1. };
|
||||||
|
|
||||||
glColour cInert = { .r = 0.6, .g = 0.6, .b = 0.6, .a = 1. };
|
gl_colour cInert = { .r = 0.6, .g = 0.6, .b = 0.6, .a = 1. };
|
||||||
glColour cNeutral = { .r = 0.9, .g = 1.0, .b = 0.3, .a = 1. };
|
gl_colour cNeutral = { .r = 0.9, .g = 1.0, .b = 0.3, .a = 1. };
|
||||||
glColour cFriend = { .r = 0.0, .g = 1.0, .b = 0.0, .a = 1. };
|
gl_colour cFriend = { .r = 0.0, .g = 1.0, .b = 0.0, .a = 1. };
|
||||||
glColour cHostile = { .r = 0.9, .g = 0.2, .b = 0.2, .a = 1. };
|
gl_colour cHostile = { .r = 0.9, .g = 0.2, .b = 0.2, .a = 1. };
|
||||||
|
|
||||||
glColour cRadar_player = { .r = 0.4, .g = 0.8, .b = 0.4, .a = 1. };
|
gl_colour cRadar_player = { .r = 0.4, .g = 0.8, .b = 0.4, .a = 1. };
|
||||||
glColour cRadar_targ = { .r = 0.0, .g = 0.7, .b = 1.0, .a = 1. };
|
gl_colour cRadar_targ = { .r = 0.0, .g = 0.7, .b = 1.0, .a = 1. };
|
||||||
glColour cRadar_weap = { .r = 0.8, .g = 0.2, .b = 0.2, .a = 1. };
|
gl_colour cRadar_weap = { .r = 0.8, .g = 0.2, .b = 0.2, .a = 1. };
|
||||||
// Bars.
|
// Bars.
|
||||||
glColour cShield = { .r = 0.2, .g = 0.2, .b = 0.8, .a = 1. };
|
gl_colour cShield = { .r = 0.2, .g = 0.2, .b = 0.8, .a = 1. };
|
||||||
glColour cArmor = { .r = 0.5, .g = 0.5, .b = 0.5, .a = 1. };
|
gl_colour cArmor = { .r = 0.5, .g = 0.5, .b = 0.5, .a = 1. };
|
||||||
glColour cEnergy = { .r = 0.2, .g = 0.8, .b = 0.2, .a = 1. };
|
gl_colour cEnergy = { .r = 0.2, .g = 0.8, .b = 0.2, .a = 1. };
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
double w,h; // Dimensions.
|
double w,h; // Dimensions.
|
||||||
@ -115,7 +116,7 @@ extern void planets_minimap(const double res, const double w, const double h, co
|
|||||||
static void rect_parse(const xmlNodePtr parent, double* x, double* y, double* w, double* h);
|
static void rect_parse(const xmlNodePtr parent, double* x, double* y, double* w, double* h);
|
||||||
static int gui_parse(const xmlNodePtr parent, const char* name);
|
static int gui_parse(const xmlNodePtr parent, const char* name);
|
||||||
static void gui_renderPilot(const Pilot* p);
|
static void gui_renderPilot(const Pilot* p);
|
||||||
static void gui_renderBar(const glColour* c, const Vec2* p, const Rect* r, const double w);
|
static void gui_renderBar(const gl_colour* c, const Vec2* p, const Rect* r, const double w);
|
||||||
|
|
||||||
// Create a new player.
|
// Create a new player.
|
||||||
void player_new(void) {
|
void player_new(void) {
|
||||||
@ -216,7 +217,7 @@ void player_render(void) {
|
|||||||
Pilot* p;
|
Pilot* p;
|
||||||
Planet* planet;
|
Planet* planet;
|
||||||
Vec2 v;
|
Vec2 v;
|
||||||
glColour* c;
|
gl_colour* c;
|
||||||
gl_font* f;
|
gl_font* f;
|
||||||
|
|
||||||
// Render the player target graphics.
|
// Render the player target graphics.
|
||||||
@ -467,7 +468,7 @@ static void gui_renderPilot(const Pilot* p) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Render a bar.
|
// Render a bar.
|
||||||
static void gui_renderBar(const glColour* c, const Vec2* p, const Rect* r, const double w) {
|
static void gui_renderBar(const gl_colour* c, const Vec2* p, const Rect* r, const double w) {
|
||||||
int x, y, sx, sy;
|
int x, y, sx, sy;
|
||||||
|
|
||||||
glBegin(GL_QUADS);
|
glBegin(GL_QUADS);
|
||||||
@ -858,6 +859,11 @@ void player_targetPlanet(void) {
|
|||||||
|
|
||||||
// Attempt to land or target closest planet if no land target.
|
// Attempt to land or target closest planet if no land target.
|
||||||
void player_land(void) {
|
void player_land(void) {
|
||||||
|
if(landed) {
|
||||||
|
// Player is already landed.
|
||||||
|
takeoff();
|
||||||
|
return;
|
||||||
|
}
|
||||||
Planet* planet = &cur_system->planets[planet_target];
|
Planet* planet = &cur_system->planets[planet_target];
|
||||||
if(planet_target >= 0) {
|
if(planet_target >= 0) {
|
||||||
if(vect_dist(&player->solid->vel, &planet->pos) > planet->gfx_space->sw) {
|
if(vect_dist(&player->solid->vel, &planet->pos) > planet->gfx_space->sw) {
|
||||||
@ -868,8 +874,7 @@ void player_land(void) {
|
|||||||
player_message("You are going too fast to land on %s", planet->name);
|
player_message("You are going too fast to land on %s", planet->name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// TODO: Landing.
|
land(planet); // Land the player.
|
||||||
player_message("D'aww.. Allanis was too lazy to do it properly.");
|
|
||||||
} else {
|
} else {
|
||||||
// Get nearest planet target.
|
// Get nearest planet target.
|
||||||
int i;
|
int i;
|
||||||
|
@ -191,8 +191,9 @@ void ships_free(void) {
|
|||||||
ShipOutfit* so, *sot;
|
ShipOutfit* so, *sot;
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < ships; i++) {
|
for(i = 0; i < ships; i++) {
|
||||||
if((ship_stack+i)->name) // Free the name.
|
// Free stored strings.
|
||||||
free((ship_stack+i)->name);
|
if((ship_stack+i)->name) free(ship_stack[i].name);
|
||||||
|
if((ship_stack+i)->gui) free(ship_stack[i].gui);
|
||||||
so = (ship_stack+i)->outfit;
|
so = (ship_stack+i)->outfit;
|
||||||
while(so) { // free the ship outfit.
|
while(so) { // free the ship outfit.
|
||||||
sot = so;
|
sot = so;
|
||||||
|
264
src/toolkit.c
264
src/toolkit.c
@ -1,14 +1,41 @@
|
|||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "pause.h"
|
#include "pause.h"
|
||||||
|
#include "opengl.h"
|
||||||
#include "toolkit.h"
|
#include "toolkit.h"
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
WIDGET_NULL,
|
||||||
|
WIDGET_BUTTON,
|
||||||
|
WIDGET_TEXT
|
||||||
|
} WidgetType;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
WIDGET_STATUS_NORMAL,
|
||||||
|
WIDGET_STATUS_MOUSEOVER,
|
||||||
|
WIDGET_STATUS_MOUSEDOWN,
|
||||||
|
} WidgetStatus;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char* name; // Widget name.
|
||||||
|
WidgetType type; // type..
|
||||||
|
|
||||||
|
double x,y; // Position.
|
||||||
|
double w,h; // Dimensions.
|
||||||
|
|
||||||
|
WidgetStatus status;
|
||||||
|
|
||||||
|
void(*fptr) (char*); // Callback.
|
||||||
|
char* string; // Stored text.
|
||||||
|
} Widget;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned int id; // Unique identifier.
|
unsigned int id; // Unique identifier.
|
||||||
|
|
||||||
double x,y; // Position.
|
double x,y; // Position.
|
||||||
double w,h; // Dimensions.
|
double w,h; // Dimensions.
|
||||||
|
|
||||||
gl_texture* t; // Possible texture.
|
Widget* widgets; // Widget storage.
|
||||||
|
int nwidgets; // Total number of widgets.
|
||||||
} Window;
|
} Window;
|
||||||
|
|
||||||
static unsigned int genwid = 0; // Generate unique id.
|
static unsigned int genwid = 0; // Generate unique id.
|
||||||
@ -16,46 +43,109 @@ static unsigned int genwid = 0; // Generate unique id.
|
|||||||
int toolkit = 0;
|
int toolkit = 0;
|
||||||
|
|
||||||
#define MIN_WINDOWS 3
|
#define MIN_WINDOWS 3
|
||||||
static Window** windows = NULL;
|
static Window* windows = NULL;
|
||||||
static int nwindows = 0;
|
static int nwindows = 0;
|
||||||
static int mwindows = 0;
|
static int mwindows = 0;
|
||||||
|
|
||||||
|
static Widget* window_newWidget(const unsigned int wid);
|
||||||
|
static void widget_cleanup(Widget* widget);
|
||||||
|
static void window_render(Window* w);
|
||||||
|
|
||||||
|
// Add a button that when pressed will trigger call, passing it's name as the
|
||||||
|
// only parameter.
|
||||||
|
void window_addButton(const unsigned int wid, const int x, const int y, const int w,
|
||||||
|
const int h, char* name, char* display, void (*call)(char*)) {
|
||||||
|
|
||||||
|
Widget* widget = window_newWidget(wid);
|
||||||
|
|
||||||
|
widget->type = WIDGET_BUTTON;
|
||||||
|
widget->name = strdup(name);
|
||||||
|
widget->string = strdup(display);
|
||||||
|
|
||||||
|
// Set the properties.
|
||||||
|
widget->x = (double) x;
|
||||||
|
widget->y = (double) y;
|
||||||
|
widget->w = (double) w;
|
||||||
|
widget->h = (double) h;
|
||||||
|
widget->fptr = call;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return pointer to newly allocated widget.
|
||||||
|
static Widget* window_newWidget(const unsigned int wid) {
|
||||||
|
int i;
|
||||||
|
for(i = 0; i < nwindows; i++)
|
||||||
|
if(windows[i].id == wid)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if(i == nwindows) return NULL;
|
||||||
|
|
||||||
|
Widget* w = NULL;
|
||||||
|
|
||||||
|
windows[i].widgets = realloc(windows[i].widgets, sizeof(Widget)*(++windows[i].nwidgets));
|
||||||
|
if(windows[i].widgets == NULL) WARN("Out of memory");
|
||||||
|
|
||||||
|
w = &windows[i].widgets[windows[i].nwidgets - 1];
|
||||||
|
|
||||||
|
w->type = WIDGET_NULL;
|
||||||
|
w->status = WIDGET_STATUS_NORMAL;
|
||||||
|
return w;
|
||||||
|
}
|
||||||
|
|
||||||
// Create a window.
|
// Create a window.
|
||||||
unsigned int window_create(int x, int y, int w, int h, gl_texture* t) {
|
unsigned int window_create(const int x, const int y, const int w, const int h) {
|
||||||
Window* wtmp = NULL;
|
if(nwindows >= mwindows) {
|
||||||
if(nwindows == mwindows) {
|
// We have reached our memory limit.
|
||||||
// We have reached the memory limit.
|
windows = realloc(windows, sizeof(Window)*(++mwindows));
|
||||||
windows = realloc(windows, sizeof(Window*)*(++mwindows));
|
|
||||||
if(windows == NULL) WARN("Out of memory");
|
if(windows == NULL) WARN("Out of memory");
|
||||||
}
|
}
|
||||||
wtmp = malloc(sizeof(Window));
|
|
||||||
if(wtmp == NULL) WARN("Out of memory");
|
|
||||||
|
|
||||||
int wid = (++genwid); // Unique id
|
const int wid = (++genwid); // Unique id
|
||||||
|
|
||||||
wtmp->id = wid;
|
windows[nwindows].id = wid;
|
||||||
|
|
||||||
wtmp->x = x;
|
windows[nwindows].w = (double) w;
|
||||||
wtmp->y = y;
|
windows[nwindows].h = (double) h;
|
||||||
wtmp->h = h;
|
if((x == -1) && (y == -1)) {
|
||||||
wtmp->w = w;
|
// Center.
|
||||||
wtmp->t = t;
|
windows[nwindows].x = windows[nwindows].w/2.;
|
||||||
|
windows[nwindows].y = windows[nwindows].h/2.;
|
||||||
|
} else {
|
||||||
|
windows[nwindows].x = (double) x;
|
||||||
|
windows[nwindows].y = (double) y;
|
||||||
|
}
|
||||||
|
|
||||||
windows[nwindows++] = wtmp;
|
windows[nwindows].widgets = NULL;
|
||||||
|
windows[nwindows].nwidgets = 0;
|
||||||
|
|
||||||
if(toolkit == 0) toolkit = 1; // Enable the toolkit.
|
nwindows++;
|
||||||
|
|
||||||
|
if(toolkit == 0) {
|
||||||
|
// Toolkit is enabled.
|
||||||
|
SDL_ShowCursor(SDL_ENABLE);
|
||||||
|
toolkit = 1; // Enable it.
|
||||||
|
}
|
||||||
|
|
||||||
return wid;
|
return wid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Destroy a widget.
|
||||||
|
static void widget_cleanup(Widget* widget) {
|
||||||
|
if(widget->name) free(widget->name);
|
||||||
|
|
||||||
|
if((widget->type == WIDGET_TEXT) && widget->string)
|
||||||
|
free(widget->string);
|
||||||
|
}
|
||||||
|
|
||||||
// Destroy a window.
|
// Destroy a window.
|
||||||
void window_destroy(unsigned int wid) {
|
void window_destroy(unsigned int wid) {
|
||||||
int i;
|
int i, j;
|
||||||
|
|
||||||
// Destroy the window.
|
// Destroy the window.
|
||||||
for(i = 0; i < nwindows; i++)
|
for(i = 0; i < nwindows; i++)
|
||||||
if(windows[i]->id == wid) {
|
if(windows[i].id == wid) {
|
||||||
free(windows[i]);
|
for(j = 0; j < windows[i].nwidgets; j++)
|
||||||
|
widget_cleanup(&windows[i].widgets[j]);
|
||||||
|
free(windows[i].widgets);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Move the other windows down a layer.
|
// Move the other windows down a layer.
|
||||||
@ -63,12 +153,138 @@ void window_destroy(unsigned int wid) {
|
|||||||
windows[i] = windows[i+1];
|
windows[i] = windows[i+1];
|
||||||
|
|
||||||
nwindows--;
|
nwindows--;
|
||||||
if(nwindows == 0) toolkit = 0; // Disable the toolkit.
|
if(nwindows == 0) {
|
||||||
|
// No windows left.
|
||||||
|
SDL_ShowCursor(SDL_DISABLE);
|
||||||
|
toolkit = 0; // Disable the toolkit.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render a window.
|
||||||
|
static void window_render(Window* w) {
|
||||||
|
int i, j;
|
||||||
|
double x, y;
|
||||||
|
Widget* wgt;
|
||||||
|
Vec2 v;
|
||||||
|
|
||||||
|
x = w->x - (double)gl_screen.w/2.;
|
||||||
|
y = w->y - (double)gl_screen.h/2.;
|
||||||
|
|
||||||
|
// Translate to window position (bottom left).
|
||||||
|
glMatrixMode(GL_PROJECTION);
|
||||||
|
glPushMatrix(); // Projection translation matrix.
|
||||||
|
glTranslated(x, y, 0.);
|
||||||
|
|
||||||
|
// Window background.
|
||||||
|
glBegin(GL_TRIANGLE_STRIP);
|
||||||
|
COLOUR(cLightGrey);
|
||||||
|
|
||||||
|
glVertex2d(0., 0.);
|
||||||
|
glVertex2d(w->w, 0.);
|
||||||
|
glVertex2d(0., w->h);
|
||||||
|
glVertex2d(w->w, w->h);
|
||||||
|
glEnd();
|
||||||
|
|
||||||
|
glPopMatrix(); // Gl Projection.
|
||||||
|
|
||||||
|
// Widgets.
|
||||||
|
for(i = 0; i < w->nwidgets; i++) {
|
||||||
|
wgt = &w->widgets[i];
|
||||||
|
|
||||||
|
switch(wgt->type) {
|
||||||
|
case WIDGET_NULL:
|
||||||
|
break;
|
||||||
|
case WIDGET_BUTTON:
|
||||||
|
glMatrixMode(GL_PROJECTION);
|
||||||
|
glPushMatrix(); // Projection matrix.
|
||||||
|
glTranslated(x + wgt->x, y + wgt->y, 0.);
|
||||||
|
|
||||||
|
glBegin(GL_TRIANGLE_STRIP);
|
||||||
|
switch(wgt->status) {
|
||||||
|
// Set the colour.
|
||||||
|
case WIDGET_STATUS_NORMAL: COLOUR(cDarkGrey); break;
|
||||||
|
case WIDGET_STATUS_MOUSEOVER: COLOUR(cGrey); break;
|
||||||
|
case WIDGET_STATUS_MOUSEDOWN: COLOUR(cGreen); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
glVertex2d(0., 0.);
|
||||||
|
glVertex2d(wgt->w, 0.);
|
||||||
|
glVertex2d(0., wgt->h);
|
||||||
|
glVertex2d(wgt->w, wgt->h);
|
||||||
|
glEnd();
|
||||||
|
glPopMatrix();
|
||||||
|
|
||||||
|
j = gl_printWidth(NULL, wgt->string);
|
||||||
|
vect_csetmin(&v, w->x + wgt->x + (wgt->w - (double)j)/2.,
|
||||||
|
w->y + wgt->y + (wgt->h - gl_defFont.h)/2.);
|
||||||
|
gl_print(NULL, &v, &cRed, wgt->string);
|
||||||
|
break;
|
||||||
|
case WIDGET_TEXT:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render the window.
|
// Render the window.
|
||||||
void toolkit_render(void) {
|
void toolkit_render(void) {
|
||||||
|
int i;
|
||||||
|
for(i = 0; i < nwindows; i++)
|
||||||
|
window_render(&windows[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Input.
|
||||||
|
static int mouse_down = 0;
|
||||||
|
void toolkit_mouseEvent(SDL_Event* event) {
|
||||||
|
int i;
|
||||||
|
double x, y;
|
||||||
|
Window* w;
|
||||||
|
Widget* wgt;
|
||||||
|
|
||||||
|
// Set mouse button status.
|
||||||
|
if(event->type == SDL_MOUSEBUTTONDOWN) mouse_down = 1;
|
||||||
|
else if(event->type == SDL_MOUSEBUTTONUP) mouse_down = 0;
|
||||||
|
// Ignore movements if mouse is down.
|
||||||
|
else if((event->type == SDL_MOUSEMOTION) && mouse_down) return;
|
||||||
|
|
||||||
|
// Absolute positions.
|
||||||
|
if(event->type == SDL_MOUSEMOTION) {
|
||||||
|
x = (double)event->motion.x;
|
||||||
|
y = gl_screen.h - (double)event->motion.y;
|
||||||
|
}
|
||||||
|
else if((event->type == SDL_MOUSEBUTTONDOWN) || (event->type == SDL_MOUSEBUTTONUP)) {
|
||||||
|
x = (double)event->button.x;
|
||||||
|
y = gl_screen.h - (double)event->motion.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
w = &windows[nwindows-1];
|
||||||
|
|
||||||
|
if((x < w->x) || (x > (w->x + w->w)) || (y < w->y) || (y > (w->y + w->h)))
|
||||||
|
return; // Not in current window.
|
||||||
|
|
||||||
|
// Relative positions.
|
||||||
|
x -= w->x;
|
||||||
|
y -= w->y;
|
||||||
|
|
||||||
|
for(i = 0; i < w->nwidgets; i++) {
|
||||||
|
wgt = &w->widgets[i];
|
||||||
|
if((x > wgt->x) && (x < (wgt->x + wgt->w)) && (y > wgt->y) && (y < (wgt->y + wgt->h))) {
|
||||||
|
switch(event->type) {
|
||||||
|
case SDL_MOUSEMOTION:
|
||||||
|
wgt->status = WIDGET_STATUS_MOUSEOVER;
|
||||||
|
break;
|
||||||
|
case SDL_MOUSEBUTTONDOWN:
|
||||||
|
wgt->status = WIDGET_STATUS_MOUSEDOWN;
|
||||||
|
break;
|
||||||
|
case SDL_MOUSEBUTTONUP:
|
||||||
|
if(wgt->status == WIDGET_STATUS_MOUSEDOWN) {
|
||||||
|
if(wgt->type == WIDGET_BUTTON) (*wgt->fptr)(wgt->name);
|
||||||
|
}
|
||||||
|
wgt->status = WIDGET_STATUS_NORMAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
wgt->status = WIDGET_STATUS_NORMAL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init.
|
// Init.
|
||||||
@ -76,7 +292,7 @@ int toolkit_init(void) {
|
|||||||
windows = malloc(sizeof(Window)*MIN_WINDOWS);
|
windows = malloc(sizeof(Window)*MIN_WINDOWS);
|
||||||
nwindows = 0;
|
nwindows = 0;
|
||||||
mwindows = MIN_WINDOWS;
|
mwindows = MIN_WINDOWS;
|
||||||
|
SDL_ShowCursor(SDL_DISABLE);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,7 +300,7 @@ int toolkit_init(void) {
|
|||||||
void toolkit_exit(void) {
|
void toolkit_exit(void) {
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < nwindows; i++) {
|
for(i = 0; i < nwindows; i++) {
|
||||||
window_destroy(windows[i]->id);
|
window_destroy(windows[i].id);
|
||||||
free(windows);
|
free(windows);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,25 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "opengl.h"
|
#include "opengl.h"
|
||||||
|
#include "SDL.h"
|
||||||
|
|
||||||
extern int toolkit;
|
extern int toolkit;
|
||||||
|
|
||||||
// Creation.
|
// Creation.
|
||||||
unsigned int window_create(int x, int y, int w, int h, gl_texture* t);
|
unsigned int window_create(const int x, const int y, const int w, const int h);
|
||||||
|
|
||||||
|
void window_addButton(const unsigned int wid, const int x, const int y,
|
||||||
|
const int w, const int h, char* name, char* display,
|
||||||
|
void(*call)(char*));
|
||||||
|
|
||||||
// Destroy window.
|
// Destroy window.
|
||||||
void window_destroy(unsigned int wid);
|
void window_destroy(const unsigned int wid);
|
||||||
|
|
||||||
// Render.
|
// Render.
|
||||||
void toolkit_render(void);
|
void toolkit_render(void);
|
||||||
|
|
||||||
|
// Input.
|
||||||
|
void toolkit_mouseEvent(SDL_Event* event);
|
||||||
|
|
||||||
// Init/Exit.
|
// Init/Exit.
|
||||||
int toolkit_init(void);
|
int toolkit_init(void);
|
||||||
void toolkit_exit(void);
|
void toolkit_exit(void);
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
// Get the property s of node n. This mallocs.
|
// Get the property s of node n. This mallocs.
|
||||||
#define xml_nodeProp(n,s) (char*)xmlGetProp(n, (xmlChar*)s)
|
#define xml_nodeProp(n,s) (char*)xmlGetProp(n, (xmlChar*)s)
|
||||||
|
|
||||||
#define xml_get(n) (char*)(n)->children->content
|
#define xml_get(n) ((char*)(n)->children->content)
|
||||||
#define xml_getInt(n) atoi((char*)(n)->children->content)
|
#define xml_getInt(n) (atoi((char*)(n)->children->content))
|
||||||
#define xml_getFloat(n) atof((char*)(n)->children->content)
|
#define xml_getFloat(n) (atof((char*)(n)->children->content))
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user