115 lines
2.7 KiB
C
115 lines
2.7 KiB
C
#include "util.h"
|
|
#include "config.h"
|
|
#include <epoxy/gl.h>
|
|
|
|
// Workaround to figure out if we have proper OpenGL support.
|
|
// Otherwise the application would crash after our GtkGlArea is realized
|
|
// and the context it uses is a legacy OpenGL 1.4 context because
|
|
// GTK3 calls OpenGL 2.0+ functions on it.
|
|
bool test_gl_support(void) {
|
|
gboolean result = false;
|
|
|
|
GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
|
g_signal_connect(window, "realize", G_CALLBACK(gl_check_realize), &result);
|
|
gtk_widget_realize(window);
|
|
gtk_widget_destroy(window);
|
|
window = NULL;
|
|
|
|
return result;
|
|
}
|
|
|
|
// The main function for the OpenGL version check workaround
|
|
void gl_check_realize(GtkWidget *w, gpointer user_data_ptr) {
|
|
gboolean *result = (gboolean *) user_data_ptr;
|
|
|
|
GError *error = NULL;
|
|
GdkWindow *gdk_window = gtk_widget_get_window(w);
|
|
GdkGLContext *context = gdk_window_create_gl_context(gdk_window, &error);
|
|
|
|
if (error != NULL) {
|
|
g_warning("Failed to create context: %s", error->message);
|
|
g_error_free(error);
|
|
*result = false;
|
|
}
|
|
else {
|
|
gdk_gl_context_make_current(context);
|
|
int version = epoxy_gl_version();
|
|
|
|
g_object_run_dispose(G_OBJECT(context));
|
|
g_object_unref(context);
|
|
context = NULL;
|
|
|
|
gdk_gl_context_clear_current();
|
|
|
|
g_debug("OpenGL version: %d", version);
|
|
|
|
*result = version >= 32;
|
|
}
|
|
}
|
|
|
|
void replace_extension(const char *src, size_t length, char *dest, const char *ext) {
|
|
memcpy(dest, src, length);
|
|
dest[length] = 0;
|
|
|
|
/* Remove extension */
|
|
for (size_t i = length; i--;) {
|
|
if (dest[i] == '/') break;
|
|
if (dest[i] == '.') {
|
|
dest[i] = 0;
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* Add new extension */
|
|
strcat(dest, ext);
|
|
}
|
|
|
|
double clamp_double(double min, double max, double value) {
|
|
if (value < min) return min;
|
|
if (value > max) return max;
|
|
return value;
|
|
}
|
|
|
|
double max_double(double a, double b) {
|
|
if (a > b) return a;
|
|
return b;
|
|
}
|
|
|
|
double min_double(double a, double b) {
|
|
if (a < b) return a;
|
|
return b;
|
|
}
|
|
|
|
uint32_t convert_color(uint16_t color) {
|
|
const uint8_t r = ((uint16_t)(color & 0x1F) * 255) / 31;
|
|
const uint8_t g = ((uint16_t)((color >> 5) & 0x1F) * 255) / 31;
|
|
const uint8_t b = ((uint16_t)((color >> 10) & 0x1F) * 255) / 31;
|
|
|
|
return (r << 16) | (g << 8) | b;
|
|
}
|
|
|
|
uint32_t rgb_encode(GB_gameboy_t *gb, uint8_t r, uint8_t g, uint8_t b) {
|
|
return 0xFF000000 | (r << 16) | (g << 8) | b;
|
|
}
|
|
|
|
GB_model_t config_get_model_type(GuiData *gui_data) {
|
|
if (gui_data->cli_options.model != -1) {
|
|
return gui_data->cli_options.model;
|
|
}
|
|
|
|
return config_get_model();
|
|
}
|
|
|
|
GtkWidget *menubar_to_menu(GtkMenuBar *menubar) {
|
|
GtkWidget *menu = gtk_menu_new();
|
|
g_autoptr(GList) iter = gtk_container_get_children(GTK_CONTAINER(menubar));
|
|
|
|
while (iter) {
|
|
GtkWidget *item = GTK_WIDGET(iter->data);
|
|
gtk_widget_reparent(item, menu);
|
|
iter = iter->next;
|
|
}
|
|
|
|
return menu;
|
|
}
|