[Add] Basic toolkit for window/widget rendering etc.

[Add] Landing.
This commit is contained in:
Allanis 2013-02-17 19:51:31 +00:00
parent 9899458f91
commit 14e525078e
14 changed files with 356 additions and 76 deletions

View File

@ -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);

View File

@ -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
View 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
View File

@ -0,0 +1,8 @@
#pragma once
#include "space.h"
extern int landed;
void land(Planet* p);
void takeoff(void);

View File

@ -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);
} }

View File

@ -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;

View File

@ -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.

View File

@ -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);

View File

@ -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();

View File

@ -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;

View File

@ -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;

View File

@ -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);
} }
} }

View File

@ -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);

View File

@ -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))