[Add] Finished the basic toolkit by rounding off corners, adding gl_printMax and gl_printMid.

[Add] Use flag system with gl_screen.
  -- Optional AA for primitives.
This commit is contained in:
Allanis 2013-02-18 17:12:35 +00:00
parent 268b5dcaa0
commit 074e60afa5
7 changed files with 482 additions and 86 deletions

View File

@ -65,7 +65,7 @@ void conf_setDefaults(void) {
// GL. // GL.
gl_screen.w = 800; gl_screen.w = 800;
gl_screen.h = 640; gl_screen.h = 640;
gl_screen.fullscreen = 0; gl_screen.flags = 0;
// Joystick. // Joystick.
indjoystick = -1; indjoystick = -1;
namjoystick = NULL; namjoystick = NULL;
@ -75,7 +75,7 @@ void conf_setDefaults(void) {
// Ok.. Parse a config file plox. // Ok.. Parse a config file plox.
int conf_loadConfig(const char* file) { int conf_loadConfig(const char* file) {
int i; int i = 0;
lua_State* L = luaL_newstate(); lua_State* L = luaL_newstate();
if(luaL_dofile(L, file) == 0) { if(luaL_dofile(L, file) == 0) {
@ -86,7 +86,16 @@ int conf_loadConfig(const char* file) {
// OpenGL properties.. // OpenGL properties..
conf_loadInt("width", gl_screen.w); conf_loadInt("width", gl_screen.w);
conf_loadInt("height", gl_screen.h); conf_loadInt("height", gl_screen.h);
conf_loadBool("fullscreen", gl_screen.fullscreen); conf_loadBool("fullscreen", i);
if(i)gl_screen.flags |= OPENGL_FULLSCREEN;
conf_loadBool("aa", i);
if(i)gl_screen.flags |= OPENGL_AA_POINT | OPENGL_AA_LINE || OPENGL_AA_POLYGON;
conf_loadBool("aa_point", i);
if(i)gl_screen.flags |= OPENGL_AA_POINT;
conf_loadBool("aa_line", i)
if(i)gl_screen.flags |= OPENGL_AA_LINE;
conf_loadBool("aa_polygon", i);
if(i)gl_screen.flags |= OPENGL_AA_POLYGON;
conf_loadBool("showfps", show_fps); conf_loadBool("showfps", show_fps);
conf_loadInt("maxfps", max_fps); conf_loadInt("maxfps", max_fps);
@ -178,7 +187,7 @@ void conf_parseCLI(int argc, char** argv) {
while((c = getopt_long(argc, argv, "fF:d:J:j:hv", long_options, &option_index)) != -1) { while((c = getopt_long(argc, argv, "fF:d:J:j:hv", long_options, &option_index)) != -1) {
switch(c) { switch(c) {
case 'f': case 'f':
gl_screen.fullscreen = 1; gl_screen.flags |= OPENGL_FULLSCREEN;
break; break;
case 'F': case 'F':
max_fps = atoi(optarg); max_fps = atoi(optarg);

View File

@ -12,7 +12,6 @@ void land(Planet* p) {
if(landed) return; if(landed) return;
planet = p; planet = p;
pause();
land_wid = window_create(-1, -1, 400, 300); land_wid = window_create(-1, -1, 400, 300);
window_addButton(land_wid, 400-80-20, 20, 80, 40, "takeoff", "Takeoff", (void(*)(char*))takeoff); window_addButton(land_wid, 400-80-20, 20, 80, 40, "takeoff", "Takeoff", (void(*)(char*))takeoff);
landed = 1; landed = 1;
@ -23,7 +22,6 @@ void takeoff(void) {
if(!landed) return; if(!landed) return;
planet = NULL; planet = NULL;
unpause();
window_destroy(land_wid); window_destroy(land_wid);
landed = 0; landed = 0;
} }

View File

@ -19,11 +19,21 @@
#define FONT_DEF "../gfx/fonts/font.ttf" #define FONT_DEF "../gfx/fonts/font.ttf"
// Default colors. // Default colors.
glColour cLightGrey = { .r = 0.80, .g = 0.80, .b = 0.80, .a = 1 }; glColour cWhite = { .r = 1.00, .g = 1.00, .b = 1.00, .a = 1 };
glColour cGrey = { .r = 0.65, .g = 0.65, .b = 0.65, .a = 1 }; glColour cGrey90 = { .r = 0.90, .g = 0.90, .b = 0.90, .a = 1 };
glColour cDarkGrey = { .r = 0.50, .g = 0.50, .b = 0.50, .a = 1 }; glColour cGrey80 = { .r = 0.80, .g = 0.80, .b = 0.80, .a = 1 };
glColour cGreen = { .r = 0.20, .g = 0.80, .b = 0.20, .a = 1 }; glColour cGrey70 = { .r = 0.70, .g = 0.70, .b = 0.70, .a = 1 };
glColour cRed = { .r = 0.80, .g = 0.20, .b = 0.20, .a = 1 }; glColour cGrey60 = { .r = 0.60, .g = 0.60, .b = 0.60, .a = 1 };
glColour cGrey50 = { .r = 0.50, .g = 0.50, .b = 0.50, .a = 1 };
glColour cGrey40 = { .r = 0.40, .g = 0.40, .b = 0.40, .a = 1 };
glColour cGrey30 = { .r = 0.30, .g = 0.30, .b = 0.30, .a = 1 };
glColour cGrey20 = { .r = 0.20, .g = 0.20, .b = 0.20, .a = 1 };
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 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;
@ -461,6 +471,109 @@ void gl_print(const glFont* ft_font, const double x, const double y,
glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_2D);
} }
// Acts just like gl_print, but prints to a max length of max.
// Return the amount of characters we had to suppress.
int gl_printMax(const glFont* ft_font, const int max, const double x, const double y,
const glColour* c, const char* fmt, ...) {
//float h = ft_font->h / .63; // Slightly increases font size.
char text[256];
va_list ap;
int i, n, len, ret;
if(ft_font == NULL) ft_font = &gl_defFont;
if(fmt == NULL) return -1;
else {
// convert the symbols to text.
va_start(ap, fmt);
vsprintf(text, fmt, ap);
va_end(ap);
}
// Limit the size.
len = (int)strlen(text);
for(n = 0, i = 0; i < len; i++) {
n += ft_font->w[(int)text[i]];
if(n > max) {
ret = len - i; // Difference.
text[i] = '\0';
break;
}
}
// Display the text.
glEnable(GL_TEXTURE_2D);
glListBase(ft_font->list_base);
glMatrixMode(GL_MODELVIEW); // Projection gets full fast using modelview.
glPushMatrix(); // Translation matrix.
glTranslated(x - (double)gl_screen.w/2., y - (double)gl_screen.h/2., 0);
if(c == NULL) glColor4d(1., 1., 1., 1.);
else COLOUR(*c);
glCallLists(i, GL_UNSIGNED_BYTE, &text);
glPopMatrix(); // Translation matrix.
glDisable(GL_TEXTURE_2D);
return ret;
}
// Acts just like gl_printMax, but centers the text in the width.
int gl_printMid(const glFont* ft_font, const int width, double x, const double y,
const glColour* c, const char* fmt, ...) {
//float h = ft_font->h / .63; // Slightly increases font size.
char text[256];
va_list ap;
int i, n, len, ret;
ret = 0; // Default return value.
if(ft_font == NULL) ft_font = &gl_defFont;
if(fmt == NULL) return -1;
else {
// convert the symbols to text.
va_start(ap, fmt);
vsprintf(text, fmt, ap);
va_end(ap);
}
// Limit the size.
len = (int)strlen(text);
for(n = 0, i = 0; i < len; i++) {
n += ft_font->w[(int)text[i]];
if(n > width) {
ret = len - i; // Difference.
n -= ft_font->w[(int)text[i]]; // Actual size.
text[i] = '\0';
break;
}
}
x += (double)(width-n)/2.;
// Display the text.
glEnable(GL_TEXTURE_2D);
glListBase(ft_font->list_base);
glMatrixMode(GL_MODELVIEW); // Projection gets full fast using modelview.
glPushMatrix(); // Translation matrix.
glTranslated(x - (double)gl_screen.w/2., y - (double)gl_screen.h/2., 0);
if(c == NULL) glColor4d(1., 1., 1., 1.);
else COLOUR(*c);
glCallLists(i, GL_UNSIGNED_BYTE, &text);
glPopMatrix(); // Translation matrix.
glDisable(GL_TEXTURE_2D);
return ret;
}
// Get the width of the text about to be printed. // Get the width of the text about to be printed.
int gl_printWidth(const glFont* ft_font, const char* fmt, ...) { int gl_printWidth(const glFont* ft_font, const char* fmt, ...) {
int i, n; int i, n;
@ -621,10 +734,10 @@ void gl_freeFont(glFont* font) {
// Initialize SDL/OpenGL etc. // Initialize SDL/OpenGL etc.
int gl_init(void) { int gl_init(void) {
int depth, i, supported = 0; int doublebuf, depth, i, supported = 0;
SDL_Rect** modes; SDL_Rect** modes;
int flags = SDL_OPENGL; int flags = SDL_OPENGL;
flags |= SDL_FULLSCREEN * gl_screen.fullscreen; flags |= SDL_FULLSCREEN * (gl_has(OPENGL_FULLSCREEN) ? 1: 0);
// Initializes video. // Initializes video.
if(SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) { if(SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) {
@ -632,12 +745,8 @@ int gl_init(void) {
return -1; return -1;
} }
// FFUUUU Ugly cursor thing.
// -- Ok, Maybe for now.
//SDL_ShowCursor(SDL_DISABLE);
// Get available fullscreen modes. // Get available fullscreen modes.
if(gl_screen.fullscreen) { if(gl_has(OPENGL_FULLSCREEN)) {
modes = SDL_ListModes(NULL, SDL_OPENGL | SDL_FULLSCREEN); modes = SDL_ListModes(NULL, SDL_OPENGL | SDL_FULLSCREEN);
if(modes == NULL) { // Could happen, but rare. if(modes == NULL) { // Could happen, but rare.
WARN("No fullscreen modes available"); WARN("No fullscreen modes available");
@ -689,14 +798,15 @@ int gl_init(void) {
SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &gl_screen.g); SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &gl_screen.g);
SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &gl_screen.b); SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &gl_screen.b);
SDL_GL_GetAttribute(SDL_GL_ALPHA_SIZE, &gl_screen.a); SDL_GL_GetAttribute(SDL_GL_ALPHA_SIZE, &gl_screen.a);
SDL_GL_GetAttribute(SDL_GL_DOUBLEBUFFER, &gl_screen.doublebuf); SDL_GL_GetAttribute(SDL_GL_DOUBLEBUFFER, &doublebuf);
if(doublebuf) gl_screen.flags |= OPENGL_DOUBLEBUF;
gl_screen.depth = gl_screen.r + gl_screen.g + gl_screen.b + gl_screen.a; gl_screen.depth = gl_screen.r + gl_screen.g + gl_screen.b + gl_screen.a;
// Debug heaven. // Debug heaven.
DEBUG("OpenGL Window Created: %dx%d@%dbpp %s", gl_screen.w, gl_screen.h, gl_screen.depth, DEBUG("OpenGL Window Created: %dx%d@%dbpp %s", gl_screen.w, gl_screen.h, gl_screen.depth,
gl_screen.fullscreen ? "fullscreen" : "window"); (gl_has(OPENGL_FULLSCREEN)) ? "fullscreen" : "window");
DEBUG("r: %d, g: %d, b: %d, a: %d, doublebuffer: %s", gl_screen.r, gl_screen.g, gl_screen.b, gl_screen.a, DEBUG("r: %d, g: %d, b: %d, a: %d, doublebuffer: %s", gl_screen.r, gl_screen.g, gl_screen.b, gl_screen.a,
gl_screen.doublebuf ? "yes" : "no"); (gl_has(OPENGL_DOUBLEBUF)) ? "yes" : "no");
DEBUG("Renderer: %s", glGetString(GL_RENDERER)); DEBUG("Renderer: %s", glGetString(GL_RENDERER));
// Some openGL options. // Some openGL options.

View File

@ -18,12 +18,17 @@
#define RGBMASK RMASK,GMASK,BMASK,AMASK #define RGBMASK RMASK,GMASK,BMASK,AMASK
// Info about opengl screen. // Info about opengl screen.
#define OPENGL_FULLSCREEN (1<<0)
#define OPENGL_DOUBLEBUF (1<<1)
#define OPENGL_AA_POINT (1<<2)
#define OPENGL_AA_LINE (1<<3)
#define OPENGL_AA_POLYGON (1<<4)
#define gl_has(f) (gl_screen.flags & (f)) // Check for the flag.
typedef struct { typedef struct {
int w, h; // Window dimensions. int w, h; // Window dimensions.
int depth; // Depth in bpp. int depth; // Depth in bpp.
int fullscreen; // 1 = fullscreen, 0 = windowed.
int r, g, b, a; // Framebuffer values in bits. int r, g, b, a; // Framebuffer values in bits.
int doublebuf; // Double buffer. int flags; // Store different properties.
} glInfo; } glInfo;
extern glInfo gl_screen; // Local structure set with gl_init etc. extern glInfo gl_screen; // Local structure set with gl_init etc.
@ -34,9 +39,21 @@ typedef struct {
#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 cLightGrey; // -- Greyscale.
extern glColour cGrey; extern glColour cWhite;
extern glColour cDarkGrey; #define cGrey cGrey70
extern glColour cBlack;
extern glColour cGrey90;
extern glColour cGrey80;
extern glColour cGrey70;
extern glColour cGrey60;
extern glColour cGrey50;
extern glColour cGrey40;
extern glColour cGrey30;
extern glColour cGrey20;
extern glColour cGrey10;
extern glColour cGreen; extern glColour cGreen;
extern glColour cRed; extern glColour cRed;
@ -76,8 +93,16 @@ void gl_blitSprite(const glTexture* sprite, const Vec2* pos,
void gl_blitStatic(const glTexture* texture, const Vec2* pos, const glColour* c); void gl_blitStatic(const glTexture* texture, const Vec2* pos, const glColour* c);
void gl_bindCamera(const Vec2* pos); void gl_bindCamera(const Vec2* pos);
void gl_print(const glFont* ft_font, const double x, const double y, void gl_print(const glFont* ft_font, const double x, const double y,
const glColour* c, const char* fmt, ...); const glColour* c, const char* fmt, ...);
int gl_printMax(const glFont* ft_font, const int max, const double x, const double y,
const glColour* c, const char* fmt, ...);
int gl_printMid(const glFont* ft_font, const int width, double x, const double y,
const glColour* c, const char* fmt, ...);
int gl_printWidth(const glFont* ft_font, const char* fmt, ...); int gl_printWidth(const glFont* ft_font, const char* fmt, ...);
// Initialize/cleanup. // Initialize/cleanup.

View File

@ -311,21 +311,16 @@ void player_render(void) {
// Nav. // Nav.
if(planet_target >= 0) { if(planet_target >= 0) {
// Planet landing target. // Planet landing target.
i = gl_printWidth(NULL, "Land"); gl_printMid(NULL, (int)gui.nav.w, gui.nav.x, gui.nav.y - 5, &cConsole, "Land");
gl_print(NULL, gui.nav.x + (gui.nav.w - i)/2.,
gui.nav.y - 5, &cConsole, "Land"); gl_printMid(&gui.smallFont, (int)gui.nav.w, gui.nav.x, gui.nav.y - 10 - gui.smallFont.h,
i = gl_printWidth(&gui.smallFont, "%s", cur_system->planets[planet_target].name); NULL, "%s", cur_system->planets[planet_target].name);
gl_print(&gui.smallFont, gui.nav.x + (gui.nav.w - i)/2.,
gui.nav.y - 10 - gui.smallFont.h, NULL,
"%s", cur_system->planets[planet_target].name);
} }
else if(planet_target == -1) { else if(planet_target == -1) {
// No planet target. // No planet target.
i = gl_printWidth(NULL, "Navigation"); gl_printMid(NULL, (int)gui.nav.w, gui.nav.x,
gl_print(NULL, gui.nav.x + (gui.nav.w - i)/2.,
gui.nav.y - 5, &cConsole, "Navigation"); gui.nav.y - 5, &cConsole, "Navigation");
i = gl_printWidth(&gui.smallFont, "Off"); gl_printMid(&gui.smallFont, (int)gui.nav.w, gui.nav.x,
gl_print(&gui.smallFont, gui.nav.x + (gui.nav.w - i)/2.,
gui.nav.y - 10 - gui.smallFont.h, &cGrey, "Off"); gui.nav.y - 10 - gui.smallFont.h, &cGrey, "Off");
} }
@ -336,39 +331,34 @@ void player_render(void) {
// Weapon. // Weapon.
if(player->secondary == NULL) { if(player->secondary == NULL) {
i = gl_printWidth(NULL, "Secondary"); gl_printMid(NULL, (int)gui.weapon.w, gui.weapon.x,
gl_print(NULL, gui.weapon.x + (gui.weapon.w - i)/2.,
gui.weapon.y - 5, &cConsole, "Secondary"); gui.weapon.y - 5, &cConsole, "Secondary");
i = gl_printWidth(&gui.smallFont, "None"); gl_printMid(&gui.smallFont, (int)gui.weapon.w, gui.weapon.x,
gl_print(&gui.smallFont, gui.weapon.x + (gui.weapon.w - i)/2.,
gui.weapon.y - 10 - gl_defFont.h, &cGrey, "None"); gui.weapon.y - 10 - gl_defFont.h, &cGrey, "None");
} else { } else {
f = &gl_defFont; f = &gl_defFont;
if(player->ammo == NULL) { if(player->ammo == NULL) {
i = gl_printWidth(f, "%s", player->secondary->outfit->name); i = gl_printWidth(f, "%s", player->secondary->outfit->name);
if(i > gui.weapon.w) { if(i > (int)gui.weapon.w)
// Font is too big. // Font is too big.
f = &gui.smallFont; f = &gui.smallFont;
i = gl_printWidth(f, "%s", player->secondary->outfit->name);
} gl_printMid(f, (int)gui.weapon.w, gui.weapon.x,
gl_print(f, gui.weapon.x + (gui.weapon.w - i)/2.,
gui.weapon.y - (gui.weapon.h - f->h)/2., gui.weapon.y - (gui.weapon.h - f->h)/2.,
&cConsole, "%s", player->secondary->outfit->name); &cConsole, "%s", player->secondary->outfit->name);
} else { } else {
// Use the ammunitions name. // Use the ammunitions name.
i = gl_printWidth(f, "%s", player->secondary->outfit->name); i = gl_printWidth(f, "%s", player->secondary->outfit->name);
if(i > gui.weapon.w) { if(i > gui.weapon.w)
// Font is too big. // Font is too big.
f = &gui.smallFont; f = &gui.smallFont;
i = gl_printWidth(f, "%s", player->ammo->outfit->name);
} gl_printMid(f, (int)gui.weapon.w, gui.weapon.x,
gl_print(f, gui.weapon.x + (gui.weapon.w - i)/2.,
gui.weapon.y - 5, gui.weapon.y - 5,
&cConsole, "%s", player->ammo->outfit->name); &cConsole, "%s", player->ammo->outfit->name);
// Print ammo underneath to the left. // Print ammo underneath to the left.
i = gl_printWidth(&gui.smallFont, "%d", player->ammo->quantity); gl_printMid(&gui.smallFont, gui.weapon.w, gui.weapon.x,
gl_print(&gui.smallFont, gui.weapon.x + (gui.weapon.w - i)/2.,
gui.weapon.y - 10 - gl_defFont.h, gui.weapon.y - 10 - gl_defFont.h,
NULL, "%d", player->ammo->quantity); NULL, "%d", player->ammo->quantity);
} }
@ -401,10 +391,9 @@ void player_render(void) {
NULL, "%s: %.0f%%", "Armor", p->armour/p->armour_max*100.); NULL, "%s: %.0f%%", "Armor", p->armour/p->armour_max*100.);
} else { } else {
// No target. // No target.
i = gl_printWidth(NULL, "No Target"); gl_printMid(NULL, SHIP_TARGET_W, gui.target.x,
gl_print(NULL, gui.target.x + (SHIP_TARGET_W - i)/2.,
gui.target.y + (SHIP_TARGET_H - gl_defFont.h)/2., gui.target.y + (SHIP_TARGET_H - gl_defFont.h)/2.,
&cGrey, "No Target"); &cGrey80, "No Target");
} }
// Misc. // Misc.
@ -891,6 +880,7 @@ void player_screenshot(void) {
char filename[20]; char filename[20];
// TODO not overwirte old screenshots. // TODO not overwirte old screenshots.
strncpy(filename, "screenshot.png", 20); strncpy(filename, "screenshot.png", 20);
DEBUG("SCREENSHOT!");
gl_screenshot(filename); gl_screenshot(filename);
} }

View File

@ -23,9 +23,19 @@ typedef struct {
double w,h; // Dimensions. double w,h; // Dimensions.
WidgetStatus status; WidgetStatus status;
void(*fptr) (char*); // Callback. union {
char* string; // Stored text. // Widget button.
struct {
void(*fptr) (char*); // Callback.
char* string; // Stored text.
};
// Widget text.
struct {
glFont* font;
glColour* colour;
};
};
} Widget; } Widget;
typedef struct { typedef struct {
@ -52,24 +62,42 @@ static void widget_cleanup(Widget* widget);
// Render. // Render.
static void window_render(Window* w); static void window_render(Window* w);
static void toolkit_renderButton(Widget* btn, double bx, double by); static void toolkit_renderButton(Widget* btn, double bx, double by);
static void toolkit_renderText(Widget* txt, double bx, double by);
// Add a button that when pressed will trigger call, passing it's name as the // Add a button that when pressed will trigger call, passing it's name as the
// only parameter. // only parameter.
void window_addButton(const unsigned int wid, const int x, const int y, const int w, 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*)) { const int h, char* name, char* display, void (*call)(char*)) {
Widget* widget = window_newWidget(wid); Widget* wgt = window_newWidget(wid);
widget->type = WIDGET_BUTTON; wgt->type = WIDGET_BUTTON;
widget->name = strdup(name); wgt->name = strdup(name);
widget->string = strdup(display); wgt->string = strdup(display);
// Set the properties. // Set the properties.
widget->x = (double) x; wgt->x = (double) x;
widget->y = (double) y; wgt->y = (double) y;
widget->w = (double) w; wgt->w = (double) w;
widget->h = (double) h; wgt->h = (double) h;
widget->fptr = call; wgt->fptr = call;
}
void window_addText(const unsigned int wid, const int x, const int y, const int w,
const int h, char* name, glFont* font, glColour* colour) {
Widget* wgt = window_newWidget(wid);
wgt->type = WIDGET_TEXT;
wgt->name = strdup(name); // Display the widgets name.
// Set the properties.
wgt->x = (double) x;
wgt->y = (double) y;
wgt->w = (double) w;
wgt->h = (double) h;
wgt->font = font;
wgt->colour = colour;
} }
// Return pointer to newly allocated widget. // Return pointer to newly allocated widget.
@ -109,8 +137,8 @@ unsigned int window_create(const int x, const int y, const int w, const int h) {
windows[nwindows].h = (double) h; windows[nwindows].h = (double) h;
if((x == -1) && (y == -1)) { if((x == -1) && (y == -1)) {
// Center. // Center.
windows[nwindows].x = windows[nwindows].w/2.; windows[nwindows].x = gl_screen.w/2. - windows[nwindows].w/2.;
windows[nwindows].y = windows[nwindows].h/2.; windows[nwindows].y = gl_screen.h/2. - windows[nwindows].h/2.;
} else { } else {
windows[nwindows].x = (double) x; windows[nwindows].x = (double) x;
windows[nwindows].y = (double) y; windows[nwindows].y = (double) y;
@ -159,6 +187,7 @@ void window_destroy(unsigned int wid) {
// No windows left. // No windows left.
SDL_ShowCursor(SDL_DISABLE); SDL_ShowCursor(SDL_DISABLE);
toolkit = 0; // Disable the toolkit. toolkit = 0; // Disable the toolkit.
if(paused) unpause();
} }
} }
@ -166,18 +195,163 @@ void window_destroy(unsigned int wid) {
static void window_render(Window* w) { static void window_render(Window* w) {
int i; int i;
double x, y; double x, y;
glColour *lc, *c, *dc, *oc;
// Position.
x = w->x - (double)gl_screen.w/2.; x = w->x - (double)gl_screen.w/2.;
y = w->y - (double)gl_screen.h/2.; y = w->y - (double)gl_screen.h/2.;
// Window background. // Colours.
glBegin(GL_QUADS); lc = &cGrey90;
COLOUR(cLightGrey); c = &cGrey70;
dc = &cGrey50;
oc = &cGrey30;
glVertex2d(x, y); // Window shaded background.
glVertex2d(x + w->w, y); // Main body.
glVertex2d(x + w->w, y + w->h); glShadeModel(GL_SMOOTH);
glVertex2d(x, y + w->h); glBegin(GL_QUADS);
COLOUR(*dc);
glVertex2d(x+21., y);
glVertex2d(x+w->w-21., y);
COLOUR(*c);
glVertex2d(x+w->w-21, y+0.6*w->h);
glVertex2d(x+21, y+0.6*w->h);
glEnd();
glShadeModel(GL_FLAT);
glBegin(GL_QUADS);
COLOUR(*c);
glVertex2d(x+21., y+0.6*w->h);
glVertex2d(x+w->w-21., y+0.6*w->h);
glVertex2d(x+w->w-21., y+w->h);
glVertex2d(x+21., y+w->h);
glEnd();
glShadeModel(GL_SMOOTH);
// Left side.
glBegin(GL_POLYGON);
COLOUR(*c);
glVertex2d(x+21., y+0.6*w->h); // Center.
COLOUR(*dc);
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.);
glVertex2s(x, y+21.);
COLOUR(*c);
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);
glEnd();
// Right side.
glBegin(GL_POLYGON);
COLOUR(*c);
glVertex2d(x+w->w-21., y+0.6*w->h); // Center.
COLOUR(*dc);
glVertex2d(x+w->w-21., y);
glVertex2d(x+w->w-15., y+1.);
glVertex2d(x+w->w-10., y+3.);
glVertex2d(x+w->w-6., y+6.);
glVertex2d(x+w->w-3., y+10.);
glVertex2d(x+w->w-1., y+15.);
glVertex2d(x+w->w, y+21.);
COLOUR(*c);
glVertex2d(x+w->w, y+0.6*w->h); // Front of center.
glVertex2d(x+w->w, y+w->h-21.);
glVertex2d(x+w->w-1., y+w->h-15.);
glVertex2d(x+w->w-3., y+w->h-10.);
glVertex2d(x+w->w-6., y+w->h-6.);
glVertex2d(x+w->w-10., y+w->h-3.);
glVertex2d(x+w->w-15., y+w->h-1.);
glVertex2d(x+w->w-21., y+w->h);
glEnd();
// Inner outline.
glShadeModel(GL_SMOOTH);
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.);
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);
// 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.
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);
glEnd();
// Outter outline.
glShadeModel(GL_SMOOTH);
glBegin(GL_LINE_LOOP);
// Left side.
COLOUR(*oc);
glVertex2d(x+21.-1., y-1.);
glVertex2d(x+15.-1., y+1.-1.);
glVertex2d(x+10.-1., y+3.-1.);
glVertex2d(x+6.-1., y+6.-1.);
glVertex2d(x+3.-1., y+10.-1.);
glVertex2d(x+1.-1., y+15.-1.);
glVertex2d(x-1., y+21.-1.);
glVertex2d(x-1., y+0.6*w->h); // Front of center.
glVertex2d(x-1., y+w->h-21.+1.);
glVertex2d(x+1.-1., y+w->h-15.+1.);
glVertex2d(x+3.-1., y+w->h-10.+1.);
glVertex2d(x+6.-1., y+w->h-6.+1.);
glVertex2d(x+10.-1., y+w->h-3.+1.);
glVertex2d(x+15.-1., y+w->h-1.+1.);
glVertex2d(x+21.-1., y+w->h+1.);
// Switch to right via top.
glVertex2d(x+w->w-21.+1., y+w->h+1.);
glVertex2d(x+w->w-15.+1., y+w->h-1.+1.);
glVertex2d(x+w->w-10.+1., y+w->h-3.+1.);
glVertex2d(x+w->w-6.+1., y+w->h-6.+1.);
glVertex2d(x+w->w-3.+1., y+w->h-10.+1.);
glVertex2d(x+w->w-1.+1., y+w->h-15.+1.);
glVertex2d(x+w->w+1., y+w->h-21.+1.);
glVertex2d(x+w->w+1., y+0.6*w->h); // Front of center.
glVertex2d(x+w->w-1.+1., y+21.-1.);
glVertex2d(x+w->w-3.+1., y+15.-1.);
glVertex2d(x+w->w-6.+1., y+6.-1.);
glVertex2d(x+w->w-10.+1., y+3.-1.);
glVertex2d(x+w->w-15.+1., y+1.-1.);
glVertex2d(x+w->w-21.+1., y-1.);
glVertex2d(x+21.-1., y-1.); // Back to beginning.
glEnd(); glEnd();
// Widgets. // Widgets.
@ -189,13 +363,14 @@ static void window_render(Window* w) {
toolkit_renderButton(&w->widgets[i], x, y); toolkit_renderButton(&w->widgets[i], x, y);
break; break;
case WIDGET_TEXT: case WIDGET_TEXT:
toolkit_renderText(&w->widgets[i], x, y);
break; break;
} }
} }
} }
static void toolkit_renderButton(Widget* btn, double bx, double by) { static void toolkit_renderButton(Widget* btn, double bx, double by) {
glColour* c; glColour* c, *dc, *oc, *lc;
double x, y; double x, y;
int j; int j;
@ -204,32 +379,118 @@ static void toolkit_renderButton(Widget* btn, double bx, double by) {
switch(btn->status) { switch(btn->status) {
// Set the color. // Set the color.
case WIDGET_STATUS_NORMAL: c = &cDarkGrey; break; case WIDGET_STATUS_NORMAL:
case WIDGET_STATUS_MOUSEOVER: c = &cGrey; break; lc = &cGrey80;
case WIDGET_STATUS_MOUSEDOWN: c = &cGreen; break; c = &cGrey60;
dc = &cGrey40;
oc = &cGrey20;
break;
case WIDGET_STATUS_MOUSEOVER:
lc = &cWhite;
c = &cGrey80;
dc = &cGrey60;
oc = &cGrey40;
break;
case WIDGET_STATUS_MOUSEDOWN:
lc = &cGreen;
c = &cGreen;
dc = &cGrey40;
oc = &cGrey20;
break;
} }
// Shaded base.
glShadeModel(GL_SMOOTH); glShadeModel(GL_SMOOTH);
glBegin(GL_QUADS); glBegin(GL_QUADS);
COLOUR(*dc);
glVertex2d(x, y+2/3*btn->h);
glVertex2d(x+btn->w, y+2/3*btn->h);
COLOUR(*c); COLOUR(*c);
glVertex2d(x, y + 2/3*btn->h); glVertex2d(x+btn->w, y+0.6*btn->h);
glVertex2d(x + btn->w, y + 2/3*btn->h); glVertex2d(x, y+0.6*btn->h);
glVertex2d(x + btn->w, y + btn->h);
glVertex2d(x, y + btn->h);
glEnd(); glEnd();
j = gl_printWidth(NULL, btn->string); glShadeModel(GL_FLAT);
gl_print(NULL, glBegin(GL_QUADS);
bx + (double)gl_screen.w/2. + btn->x + (btn->w - (double)j)/2, COLOUR(*c);
glVertex2d(x, y+0.6*btn->h);
glVertex2d(x+btn->w, y+0.6*btn->h);
glVertex2d(x+btn->w, y+btn->h);
glVertex2d(x, y+btn->h);
glEnd();
// Inner outline.
glShadeModel(GL_SMOOTH);
// Left.
glBegin(GL_LINES);
COLOUR(*c);
glVertex2d(x, y);
COLOUR(*lc);
glVertex2d(x, y+btn->h);
glEnd();
// Right.
glBegin(GL_LINES);
COLOUR(*c);
glVertex2d(x+btn->w, y);
COLOUR(*lc);
glVertex2d(x+btn->w, y+btn->h);
glEnd();
glShadeModel(GL_FLAT);
// Bottom.
glBegin(GL_LINES);
COLOUR(*c);
glVertex2d(x, y);
glVertex2d(x+btn->w, y);
glEnd();
// Top.
glBegin(GL_LINES);
COLOUR(*lc);
glVertex2d(x, y+btn->h);
glVertex2d(x+btn->w, y+btn->h);
glEnd();
// Outter outline.
glBegin(GL_LINE_LOOP);
COLOUR(cBlack);
// Left.
glVertex2d(x-1., y);
glVertex2d(x-1., y+btn->h);
// Top.
glVertex2d(x, y+btn->h+1.);
glVertex2d(x+btn->w, y+btn->h+1.);
// Right.
glVertex2d(x+btn->w+1., y+btn->h);
glVertex2d(x+btn->w+1., y);
// Bottom.
glVertex2d(x+btn->w, y-1.);
glVertex2d(x, y-1.);
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., by + (double)gl_screen.h/2. + btn->y + (btn->h - gl_defFont.h)/2.,
&cRed, btn->string); &cRed, btn->string);
} }
static void toolkit_renderText(Widget* txt, double bx, double by) {
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);
}
// Render the window. // Render the window.
void toolkit_render(void) { void toolkit_render(void) {
int i; int i;
if(gl_has(OPENGL_AA_LINE)) glEnable(GL_LINE_SMOOTH);
if(gl_has(OPENGL_AA_POLYGON)) glEnable(GL_POLYGON_SMOOTH);
for(i = 0; i < nwindows; i++) for(i = 0; i < nwindows; i++)
window_render(&windows[i]); window_render(&windows[i]);
if(gl_has(OPENGL_AA_LINE)) glDisable(GL_LINE_SMOOTH);
if(gl_has(OPENGL_AA_POLYGON)) glDisable(GL_POLYGON_SMOOTH);
} }
// Input. // Input.

View File

@ -11,6 +11,9 @@ void window_addButton(const unsigned int wid, const int x, const int y,
const int w, const int h, char* name, char* display, const int w, const int h, char* name, char* display,
void(*call)(char*)); void(*call)(char*));
void window_addText(const unsigned int wid, const int x, const int y,
const int w, const int h, char* name, glFont* font, glColour* colour);
// Destroy window. // Destroy window.
void window_destroy(const unsigned int wid); void window_destroy(const unsigned int wid);