[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:
parent
268b5dcaa0
commit
074e60afa5
17
src/conf.c
17
src/conf.c
@ -65,7 +65,7 @@ void conf_setDefaults(void) {
|
||||
// GL.
|
||||
gl_screen.w = 800;
|
||||
gl_screen.h = 640;
|
||||
gl_screen.fullscreen = 0;
|
||||
gl_screen.flags = 0;
|
||||
// Joystick.
|
||||
indjoystick = -1;
|
||||
namjoystick = NULL;
|
||||
@ -75,7 +75,7 @@ void conf_setDefaults(void) {
|
||||
|
||||
// Ok.. Parse a config file plox.
|
||||
int conf_loadConfig(const char* file) {
|
||||
int i;
|
||||
int i = 0;
|
||||
|
||||
lua_State* L = luaL_newstate();
|
||||
if(luaL_dofile(L, file) == 0) {
|
||||
@ -86,7 +86,16 @@ int conf_loadConfig(const char* file) {
|
||||
// OpenGL properties..
|
||||
conf_loadInt("width", gl_screen.w);
|
||||
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_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) {
|
||||
switch(c) {
|
||||
case 'f':
|
||||
gl_screen.fullscreen = 1;
|
||||
gl_screen.flags |= OPENGL_FULLSCREEN;
|
||||
break;
|
||||
case 'F':
|
||||
max_fps = atoi(optarg);
|
||||
|
@ -12,7 +12,6 @@ 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;
|
||||
@ -23,7 +22,6 @@ void takeoff(void) {
|
||||
if(!landed) return;
|
||||
|
||||
planet = NULL;
|
||||
unpause();
|
||||
window_destroy(land_wid);
|
||||
landed = 0;
|
||||
}
|
||||
|
140
src/opengl.c
140
src/opengl.c
@ -19,11 +19,21 @@
|
||||
#define FONT_DEF "../gfx/fonts/font.ttf"
|
||||
|
||||
// Default colors.
|
||||
glColour cLightGrey = { .r = 0.80, .g = 0.80, .b = 0.80, .a = 1 };
|
||||
glColour cGrey = { .r = 0.65, .g = 0.65, .b = 0.65, .a = 1 };
|
||||
glColour cDarkGrey = { .r = 0.50, .g = 0.50, .b = 0.50, .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 };
|
||||
glColour cWhite = { .r = 1.00, .g = 1.00, .b = 1.00, .a = 1 };
|
||||
glColour cGrey90 = { .r = 0.90, .g = 0.90, .b = 0.90, .a = 1 };
|
||||
glColour cGrey80 = { .r = 0.80, .g = 0.80, .b = 0.80, .a = 1 };
|
||||
glColour cGrey70 = { .r = 0.70, .g = 0.70, .b = 0.70, .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.
|
||||
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);
|
||||
}
|
||||
|
||||
// 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.
|
||||
int gl_printWidth(const glFont* ft_font, const char* fmt, ...) {
|
||||
int i, n;
|
||||
@ -621,10 +734,10 @@ void gl_freeFont(glFont* font) {
|
||||
|
||||
// Initialize SDL/OpenGL etc.
|
||||
int gl_init(void) {
|
||||
int depth, i, supported = 0;
|
||||
int doublebuf, depth, i, supported = 0;
|
||||
SDL_Rect** modes;
|
||||
int flags = SDL_OPENGL;
|
||||
flags |= SDL_FULLSCREEN * gl_screen.fullscreen;
|
||||
flags |= SDL_FULLSCREEN * (gl_has(OPENGL_FULLSCREEN) ? 1: 0);
|
||||
|
||||
// Initializes video.
|
||||
if(SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) {
|
||||
@ -632,12 +745,8 @@ int gl_init(void) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// FFUUUU Ugly cursor thing.
|
||||
// -- Ok, Maybe for now.
|
||||
//SDL_ShowCursor(SDL_DISABLE);
|
||||
|
||||
// Get available fullscreen modes.
|
||||
if(gl_screen.fullscreen) {
|
||||
if(gl_has(OPENGL_FULLSCREEN)) {
|
||||
modes = SDL_ListModes(NULL, SDL_OPENGL | SDL_FULLSCREEN);
|
||||
if(modes == NULL) { // Could happen, but rare.
|
||||
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_BLUE_SIZE, &gl_screen.b);
|
||||
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;
|
||||
|
||||
// Debug heaven.
|
||||
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,
|
||||
gl_screen.doublebuf ? "yes" : "no");
|
||||
(gl_has(OPENGL_DOUBLEBUF)) ? "yes" : "no");
|
||||
DEBUG("Renderer: %s", glGetString(GL_RENDERER));
|
||||
|
||||
// Some openGL options.
|
||||
|
35
src/opengl.h
35
src/opengl.h
@ -18,12 +18,17 @@
|
||||
#define RGBMASK RMASK,GMASK,BMASK,AMASK
|
||||
|
||||
// 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 {
|
||||
int w, h; // Window dimensions.
|
||||
int depth; // Depth in bpp.
|
||||
int fullscreen; // 1 = fullscreen, 0 = windowed.
|
||||
int r, g, b, a; // Framebuffer values in bits.
|
||||
int doublebuf; // Double buffer.
|
||||
int flags; // Store different properties.
|
||||
} glInfo;
|
||||
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)
|
||||
|
||||
// Default colors.
|
||||
extern glColour cLightGrey;
|
||||
extern glColour cGrey;
|
||||
extern glColour cDarkGrey;
|
||||
// -- Greyscale.
|
||||
extern glColour cWhite;
|
||||
#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 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_bindCamera(const Vec2* pos);
|
||||
|
||||
void gl_print(const glFont* ft_font, const double x, const double y,
|
||||
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, ...);
|
||||
|
||||
// Initialize/cleanup.
|
||||
|
46
src/player.c
46
src/player.c
@ -311,21 +311,16 @@ void player_render(void) {
|
||||
// Nav.
|
||||
if(planet_target >= 0) {
|
||||
// Planet landing target.
|
||||
i = gl_printWidth(NULL, "Land");
|
||||
gl_print(NULL, gui.nav.x + (gui.nav.w - i)/2.,
|
||||
gui.nav.y - 5, &cConsole, "Land");
|
||||
i = gl_printWidth(&gui.smallFont, "%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);
|
||||
gl_printMid(NULL, (int)gui.nav.w, gui.nav.x, gui.nav.y - 5, &cConsole, "Land");
|
||||
|
||||
gl_printMid(&gui.smallFont, (int)gui.nav.w, gui.nav.x, gui.nav.y - 10 - gui.smallFont.h,
|
||||
NULL, "%s", cur_system->planets[planet_target].name);
|
||||
}
|
||||
else if(planet_target == -1) {
|
||||
// No planet target.
|
||||
i = gl_printWidth(NULL, "Navigation");
|
||||
gl_print(NULL, gui.nav.x + (gui.nav.w - i)/2.,
|
||||
gl_printMid(NULL, (int)gui.nav.w, gui.nav.x,
|
||||
gui.nav.y - 5, &cConsole, "Navigation");
|
||||
i = gl_printWidth(&gui.smallFont, "Off");
|
||||
gl_print(&gui.smallFont, gui.nav.x + (gui.nav.w - i)/2.,
|
||||
gl_printMid(&gui.smallFont, (int)gui.nav.w, gui.nav.x,
|
||||
gui.nav.y - 10 - gui.smallFont.h, &cGrey, "Off");
|
||||
}
|
||||
|
||||
@ -336,39 +331,34 @@ void player_render(void) {
|
||||
|
||||
// Weapon.
|
||||
if(player->secondary == NULL) {
|
||||
i = gl_printWidth(NULL, "Secondary");
|
||||
gl_print(NULL, gui.weapon.x + (gui.weapon.w - i)/2.,
|
||||
gl_printMid(NULL, (int)gui.weapon.w, gui.weapon.x,
|
||||
gui.weapon.y - 5, &cConsole, "Secondary");
|
||||
i = gl_printWidth(&gui.smallFont, "None");
|
||||
gl_print(&gui.smallFont, gui.weapon.x + (gui.weapon.w - i)/2.,
|
||||
gl_printMid(&gui.smallFont, (int)gui.weapon.w, gui.weapon.x,
|
||||
gui.weapon.y - 10 - gl_defFont.h, &cGrey, "None");
|
||||
} else {
|
||||
f = &gl_defFont;
|
||||
if(player->ammo == NULL) {
|
||||
i = gl_printWidth(f, "%s", player->secondary->outfit->name);
|
||||
if(i > gui.weapon.w) {
|
||||
if(i > (int)gui.weapon.w)
|
||||
// Font is too big.
|
||||
f = &gui.smallFont;
|
||||
i = gl_printWidth(f, "%s", player->secondary->outfit->name);
|
||||
}
|
||||
gl_print(f, gui.weapon.x + (gui.weapon.w - i)/2.,
|
||||
|
||||
gl_printMid(f, (int)gui.weapon.w, gui.weapon.x,
|
||||
gui.weapon.y - (gui.weapon.h - f->h)/2.,
|
||||
&cConsole, "%s", player->secondary->outfit->name);
|
||||
} else {
|
||||
// Use the ammunitions name.
|
||||
i = gl_printWidth(f, "%s", player->secondary->outfit->name);
|
||||
if(i > gui.weapon.w) {
|
||||
if(i > gui.weapon.w)
|
||||
// Font is too big.
|
||||
f = &gui.smallFont;
|
||||
i = gl_printWidth(f, "%s", player->ammo->outfit->name);
|
||||
}
|
||||
gl_print(f, gui.weapon.x + (gui.weapon.w - i)/2.,
|
||||
|
||||
gl_printMid(f, (int)gui.weapon.w, gui.weapon.x,
|
||||
gui.weapon.y - 5,
|
||||
&cConsole, "%s", player->ammo->outfit->name);
|
||||
|
||||
// Print ammo underneath to the left.
|
||||
i = gl_printWidth(&gui.smallFont, "%d", player->ammo->quantity);
|
||||
gl_print(&gui.smallFont, gui.weapon.x + (gui.weapon.w - i)/2.,
|
||||
gl_printMid(&gui.smallFont, gui.weapon.w, gui.weapon.x,
|
||||
gui.weapon.y - 10 - gl_defFont.h,
|
||||
NULL, "%d", player->ammo->quantity);
|
||||
}
|
||||
@ -401,10 +391,9 @@ void player_render(void) {
|
||||
NULL, "%s: %.0f%%", "Armor", p->armour/p->armour_max*100.);
|
||||
} else {
|
||||
// No target.
|
||||
i = gl_printWidth(NULL, "No Target");
|
||||
gl_print(NULL, gui.target.x + (SHIP_TARGET_W - i)/2.,
|
||||
gl_printMid(NULL, SHIP_TARGET_W, gui.target.x,
|
||||
gui.target.y + (SHIP_TARGET_H - gl_defFont.h)/2.,
|
||||
&cGrey, "No Target");
|
||||
&cGrey80, "No Target");
|
||||
}
|
||||
|
||||
// Misc.
|
||||
@ -891,6 +880,7 @@ void player_screenshot(void) {
|
||||
char filename[20];
|
||||
// TODO not overwirte old screenshots.
|
||||
strncpy(filename, "screenshot.png", 20);
|
||||
DEBUG("SCREENSHOT!");
|
||||
gl_screenshot(filename);
|
||||
}
|
||||
|
||||
|
325
src/toolkit.c
325
src/toolkit.c
@ -23,9 +23,19 @@ typedef struct {
|
||||
double w,h; // Dimensions.
|
||||
|
||||
WidgetStatus status;
|
||||
|
||||
void(*fptr) (char*); // Callback.
|
||||
char* string; // Stored text.
|
||||
|
||||
union {
|
||||
// Widget button.
|
||||
struct {
|
||||
void(*fptr) (char*); // Callback.
|
||||
char* string; // Stored text.
|
||||
};
|
||||
// Widget text.
|
||||
struct {
|
||||
glFont* font;
|
||||
glColour* colour;
|
||||
};
|
||||
};
|
||||
} Widget;
|
||||
|
||||
typedef struct {
|
||||
@ -52,24 +62,42 @@ static void widget_cleanup(Widget* widget);
|
||||
// Render.
|
||||
static void window_render(Window* w);
|
||||
static void toolkit_renderButton(Widget* btn, double bx, double by);
|
||||
static void toolkit_renderText(Widget* txt, double bx, double by);
|
||||
|
||||
// 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* wgt = window_newWidget(wid);
|
||||
|
||||
widget->type = WIDGET_BUTTON;
|
||||
widget->name = strdup(name);
|
||||
widget->string = strdup(display);
|
||||
wgt->type = WIDGET_BUTTON;
|
||||
wgt->name = strdup(name);
|
||||
wgt->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;
|
||||
wgt->x = (double) x;
|
||||
wgt->y = (double) y;
|
||||
wgt->w = (double) w;
|
||||
wgt->h = (double) h;
|
||||
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.
|
||||
@ -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;
|
||||
if((x == -1) && (y == -1)) {
|
||||
// Center.
|
||||
windows[nwindows].x = windows[nwindows].w/2.;
|
||||
windows[nwindows].y = windows[nwindows].h/2.;
|
||||
windows[nwindows].x = gl_screen.w/2. - windows[nwindows].w/2.;
|
||||
windows[nwindows].y = gl_screen.h/2. - windows[nwindows].h/2.;
|
||||
} else {
|
||||
windows[nwindows].x = (double) x;
|
||||
windows[nwindows].y = (double) y;
|
||||
@ -159,6 +187,7 @@ void window_destroy(unsigned int wid) {
|
||||
// No windows left.
|
||||
SDL_ShowCursor(SDL_DISABLE);
|
||||
toolkit = 0; // Disable the toolkit.
|
||||
if(paused) unpause();
|
||||
}
|
||||
}
|
||||
|
||||
@ -166,18 +195,163 @@ void window_destroy(unsigned int wid) {
|
||||
static void window_render(Window* w) {
|
||||
int i;
|
||||
double x, y;
|
||||
glColour *lc, *c, *dc, *oc;
|
||||
|
||||
// Position.
|
||||
x = w->x - (double)gl_screen.w/2.;
|
||||
y = w->y - (double)gl_screen.h/2.;
|
||||
|
||||
// Window background.
|
||||
glBegin(GL_QUADS);
|
||||
COLOUR(cLightGrey);
|
||||
// Colours.
|
||||
lc = &cGrey90;
|
||||
c = &cGrey70;
|
||||
dc = &cGrey50;
|
||||
oc = &cGrey30;
|
||||
|
||||
glVertex2d(x, y);
|
||||
glVertex2d(x + w->w, y);
|
||||
glVertex2d(x + w->w, y + w->h);
|
||||
glVertex2d(x, y + w->h);
|
||||
// Window shaded background.
|
||||
// Main body.
|
||||
glShadeModel(GL_SMOOTH);
|
||||
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();
|
||||
|
||||
// Widgets.
|
||||
@ -189,13 +363,14 @@ static void window_render(Window* w) {
|
||||
toolkit_renderButton(&w->widgets[i], x, y);
|
||||
break;
|
||||
case WIDGET_TEXT:
|
||||
toolkit_renderText(&w->widgets[i], x, y);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void toolkit_renderButton(Widget* btn, double bx, double by) {
|
||||
glColour* c;
|
||||
glColour* c, *dc, *oc, *lc;
|
||||
double x, y;
|
||||
int j;
|
||||
|
||||
@ -204,32 +379,118 @@ static void toolkit_renderButton(Widget* btn, double bx, double by) {
|
||||
|
||||
switch(btn->status) {
|
||||
// Set the color.
|
||||
case WIDGET_STATUS_NORMAL: c = &cDarkGrey; break;
|
||||
case WIDGET_STATUS_MOUSEOVER: c = &cGrey; break;
|
||||
case WIDGET_STATUS_MOUSEDOWN: c = &cGreen; break;
|
||||
case WIDGET_STATUS_NORMAL:
|
||||
lc = &cGrey80;
|
||||
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);
|
||||
glBegin(GL_QUADS);
|
||||
COLOUR(*dc);
|
||||
glVertex2d(x, y+2/3*btn->h);
|
||||
glVertex2d(x+btn->w, y+2/3*btn->h);
|
||||
COLOUR(*c);
|
||||
glVertex2d(x, y + 2/3*btn->h);
|
||||
glVertex2d(x + btn->w, y + 2/3*btn->h);
|
||||
glVertex2d(x + btn->w, y + btn->h);
|
||||
glVertex2d(x, y + btn->h);
|
||||
glVertex2d(x+btn->w, y+0.6*btn->h);
|
||||
glVertex2d(x, y+0.6*btn->h);
|
||||
glEnd();
|
||||
|
||||
j = gl_printWidth(NULL, btn->string);
|
||||
gl_print(NULL,
|
||||
bx + (double)gl_screen.w/2. + btn->x + (btn->w - (double)j)/2,
|
||||
glShadeModel(GL_FLAT);
|
||||
glBegin(GL_QUADS);
|
||||
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.,
|
||||
&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.
|
||||
void toolkit_render(void) {
|
||||
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++)
|
||||
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.
|
||||
|
@ -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,
|
||||
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.
|
||||
void window_destroy(const unsigned int wid);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user