2022-12-13 12:32:36 -06:00
|
|
|
#include "window.h"
|
2021-11-30 21:29:18 -06:00
|
|
|
#include <string.h>
|
2022-01-19 16:43:21 -06:00
|
|
|
#include "texture.h"
|
2021-11-30 21:29:18 -06:00
|
|
|
#include "log.h"
|
2022-02-06 10:14:57 -06:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdio.h>
|
2022-06-30 10:31:23 -05:00
|
|
|
#include "input.h"
|
2022-08-14 18:10:29 -05:00
|
|
|
#include "script.h"
|
|
|
|
#include "nuke.h"
|
2021-11-30 21:29:18 -06:00
|
|
|
|
2022-12-14 13:01:42 -06:00
|
|
|
#include "openglrender.h"
|
|
|
|
|
2022-08-26 09:19:17 -05:00
|
|
|
#include "stb_ds.h"
|
|
|
|
|
2022-11-03 16:58:03 -05:00
|
|
|
struct window *mainwin;
|
2022-06-27 14:12:26 -05:00
|
|
|
|
2022-11-03 16:58:03 -05:00
|
|
|
static struct window *windows = NULL;
|
2022-08-26 09:19:17 -05:00
|
|
|
|
2022-06-27 14:12:26 -05:00
|
|
|
struct Texture *icon = NULL;
|
2021-11-30 21:29:18 -06:00
|
|
|
|
2022-11-03 16:58:03 -05:00
|
|
|
int is_win(struct window *s, GLFWwindow *w)
|
2022-06-30 10:31:23 -05:00
|
|
|
{
|
|
|
|
return s->window == w;
|
|
|
|
}
|
|
|
|
|
2022-12-14 13:01:42 -06:00
|
|
|
void window_size_callback(GLFWwindow *w, int width, int height)
|
2022-06-30 10:31:23 -05:00
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-11-03 16:58:03 -05:00
|
|
|
struct window *winfind(GLFWwindow *w)
|
2022-10-24 15:19:48 -05:00
|
|
|
{
|
|
|
|
for (int i = 0; i < arrlen(windows); i++) {
|
|
|
|
if (windows[i].window == w)
|
|
|
|
return &windows[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2022-06-30 10:31:23 -05:00
|
|
|
void window_iconify_callback(GLFWwindow *w, int iconified)
|
|
|
|
{
|
2022-11-03 16:58:03 -05:00
|
|
|
struct window *win = winfind(w);
|
2022-06-30 10:31:23 -05:00
|
|
|
win->iconified = iconified;
|
|
|
|
}
|
|
|
|
|
|
|
|
void window_focus_callback(GLFWwindow *w, int focused)
|
|
|
|
{
|
2022-11-03 16:58:03 -05:00
|
|
|
struct window *win = winfind(w);
|
2023-04-28 20:55:24 -05:00
|
|
|
win->mouseFocus = focused;
|
|
|
|
}
|
2022-06-30 10:31:23 -05:00
|
|
|
|
|
|
|
void window_maximize_callback(GLFWwindow *w, int maximized)
|
|
|
|
{
|
2022-11-03 16:58:03 -05:00
|
|
|
struct window *win = winfind(w);
|
2022-06-30 10:31:23 -05:00
|
|
|
win->minimized = !maximized;
|
|
|
|
}
|
|
|
|
|
|
|
|
void window_framebuffer_size_cb(GLFWwindow *w, int width, int height)
|
|
|
|
{
|
2022-11-03 16:58:03 -05:00
|
|
|
struct window *win = winfind(w);
|
2022-06-30 10:31:23 -05:00
|
|
|
win->width = width;
|
|
|
|
win->height = height;
|
|
|
|
window_makecurrent(win);
|
|
|
|
win->render = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
void window_close_callback(GLFWwindow *w)
|
|
|
|
{
|
2022-12-16 11:54:05 -06:00
|
|
|
quit();
|
2022-06-30 10:31:23 -05:00
|
|
|
}
|
|
|
|
|
2022-08-07 01:43:45 -05:00
|
|
|
|
|
|
|
|
2022-11-03 16:58:03 -05:00
|
|
|
struct window *MakeSDLWindow(const char *name, int width, int height, uint32_t flags)
|
2021-11-30 21:29:18 -06:00
|
|
|
{
|
2022-08-26 09:19:17 -05:00
|
|
|
if (arrcap(windows) == 0)
|
|
|
|
arrsetcap(windows, 5);
|
2022-06-27 14:12:26 -05:00
|
|
|
|
2022-08-26 09:19:17 -05:00
|
|
|
GLFWwindow *sharewin = mainwin == NULL ? NULL : mainwin->window;
|
2022-08-12 14:03:56 -05:00
|
|
|
|
2023-05-04 17:07:00 -05:00
|
|
|
if (sharewin) return sharewin;
|
|
|
|
|
|
|
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR,3);
|
|
|
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR,3);
|
|
|
|
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
|
|
|
|
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
|
|
|
|
2022-11-03 16:58:03 -05:00
|
|
|
struct window w = {
|
2022-08-26 09:19:17 -05:00
|
|
|
.width = width,
|
|
|
|
.height = height,
|
|
|
|
.id = arrlen(windows),
|
|
|
|
.window = glfwCreateWindow(width, height, name, NULL, sharewin) };
|
2022-08-12 14:03:56 -05:00
|
|
|
|
2022-06-27 14:12:26 -05:00
|
|
|
|
2022-08-26 09:19:17 -05:00
|
|
|
if (!w.window) {
|
|
|
|
YughError("Couldn't make GLFW window\n", 1);
|
|
|
|
return NULL;
|
|
|
|
}
|
2022-06-27 14:12:26 -05:00
|
|
|
|
2022-08-26 09:19:17 -05:00
|
|
|
glfwMakeContextCurrent(w.window);
|
2023-05-04 17:07:00 -05:00
|
|
|
// int version = gladLoadGL(glfwGetProcAddress);
|
|
|
|
// if (!version) {
|
|
|
|
// YughError("Failed to initialize OpenGL context.");
|
|
|
|
// exit(1);
|
|
|
|
// }
|
|
|
|
YughInfo("Loaded OpenGL %d.%d", 3,3);
|
2022-06-27 14:12:26 -05:00
|
|
|
glfwSwapInterval(1);
|
2022-06-25 23:19:29 -05:00
|
|
|
|
2022-06-30 10:31:23 -05:00
|
|
|
// Set callbacks
|
2022-08-26 09:19:17 -05:00
|
|
|
glfwSetWindowCloseCallback(w.window, window_close_callback);
|
|
|
|
glfwSetWindowSizeCallback(w.window, window_size_callback);
|
|
|
|
glfwSetFramebufferSizeCallback(w.window, window_framebuffer_size_cb);
|
|
|
|
glfwSetWindowFocusCallback(w.window, window_focus_callback);
|
|
|
|
glfwSetKeyCallback(w.window, win_key_callback);
|
|
|
|
|
2023-05-04 17:07:00 -05:00
|
|
|
// nuke_init(&w);
|
2022-08-07 01:43:45 -05:00
|
|
|
|
2022-08-26 09:19:17 -05:00
|
|
|
arrput(windows, w);
|
2022-08-07 01:43:45 -05:00
|
|
|
|
2022-08-26 09:19:17 -05:00
|
|
|
if (arrlen(windows) == 1)
|
|
|
|
mainwin = &windows[0];
|
2021-11-30 21:29:18 -06:00
|
|
|
|
2022-08-26 09:19:17 -05:00
|
|
|
return &arrlast(windows);
|
2021-11-30 21:29:18 -06:00
|
|
|
}
|
|
|
|
|
2022-06-27 14:12:26 -05:00
|
|
|
void window_set_icon(const char *png)
|
|
|
|
{
|
2023-03-24 14:01:01 -05:00
|
|
|
icon = texture_pullfromfile(png);
|
|
|
|
window_seticon(mainwin, icon);
|
2022-06-27 14:12:26 -05:00
|
|
|
}
|
|
|
|
|
2022-11-03 16:58:03 -05:00
|
|
|
void window_destroy(struct window *w)
|
2021-11-30 21:29:18 -06:00
|
|
|
{
|
2022-02-06 10:14:57 -06:00
|
|
|
glfwDestroyWindow(w->window);
|
2022-08-26 09:19:17 -05:00
|
|
|
arrdelswap(windows, w->id);
|
2022-02-06 10:14:57 -06:00
|
|
|
}
|
|
|
|
|
2022-11-03 16:58:03 -05:00
|
|
|
struct window *window_i(int index) {
|
2022-08-26 09:19:17 -05:00
|
|
|
return &windows[index];
|
2022-08-07 01:43:45 -05:00
|
|
|
}
|
2022-06-30 10:31:23 -05:00
|
|
|
|
2022-11-03 16:58:03 -05:00
|
|
|
void window_handle_event(struct window *w)
|
2022-02-06 10:14:57 -06:00
|
|
|
{
|
|
|
|
/*
|
2021-11-30 21:29:18 -06:00
|
|
|
if (e->type == SDL_WINDOWEVENT && e->window.windowID == w->id) { // TODO: Check ptr direct?
|
|
|
|
switch (e->window.event) {
|
|
|
|
case SDL_WINDOWEVENT_SHOWN:
|
|
|
|
YughLog(0, SDL_LOG_PRIORITY_INFO, "Showed window %d.", w->id);
|
|
|
|
w->shown = true;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SDL_WINDOWEVENT_HIDDEN:
|
|
|
|
w->shown = false;
|
|
|
|
YughLog(0, SDL_LOG_PRIORITY_INFO, "Hid window %d.", w->id);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SDL_WINDOWEVENT_SIZE_CHANGED:
|
|
|
|
|
|
|
|
w->width = e->window.data1;
|
|
|
|
w->height = e->window.data2;
|
|
|
|
YughLog(0, SDL_LOG_PRIORITY_INFO,
|
|
|
|
"Changed size of window %d: width %d, height %d.",
|
|
|
|
w->id, w->width, w->height);
|
|
|
|
window_makecurrent(w);
|
|
|
|
w->render = true;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SDL_WINDOWEVENT_EXPOSED:
|
|
|
|
YughLog(0, SDL_LOG_PRIORITY_INFO, "Exposed window %d.", w->id);
|
|
|
|
w->render = true;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SDL_WINDOWEVENT_ENTER:
|
|
|
|
YughLog(0, SDL_LOG_PRIORITY_INFO, "Entered window %d.", w->id);
|
|
|
|
w->mouseFocus = true;
|
|
|
|
SDL_RaiseWindow(w->window);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SDL_WINDOWEVENT_LEAVE:
|
|
|
|
YughLog(0, SDL_LOG_PRIORITY_INFO, "Left window %d.", w->id);
|
|
|
|
w->mouseFocus = false;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SDL_WINDOWEVENT_FOCUS_LOST:
|
|
|
|
YughLog(0, SDL_LOG_PRIORITY_INFO,
|
|
|
|
"Lost focus on window %d.", w->id);
|
|
|
|
w->keyboardFocus = false;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SDL_WINDOWEVENT_FOCUS_GAINED:
|
|
|
|
YughLog(0, SDL_LOG_PRIORITY_INFO,
|
|
|
|
"Gained focus on window %d.", w->id);
|
|
|
|
w->keyboardFocus = true;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SDL_WINDOWEVENT_MINIMIZED:
|
|
|
|
YughLog(0, SDL_LOG_PRIORITY_INFO,
|
|
|
|
"Minimized window %d.", w->id);
|
|
|
|
w->minimized = true;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SDL_WINDOWEVENT_MAXIMIZED:
|
|
|
|
YughLog(0, SDL_LOG_PRIORITY_INFO,
|
|
|
|
"Maximized window %d.", w->id);
|
|
|
|
w->minimized = false;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SDL_WINDOWEVENT_RESTORED:
|
|
|
|
YughLog(0, SDL_LOG_PRIORITY_INFO,
|
|
|
|
"Restored window %d.", w->id);
|
|
|
|
w->minimized = false;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SDL_WINDOWEVENT_CLOSE:
|
|
|
|
YughLog(0, SDL_LOG_PRIORITY_INFO, "Closed window %d.", w->id);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2022-02-06 10:14:57 -06:00
|
|
|
*/
|
2021-11-30 21:29:18 -06:00
|
|
|
}
|
|
|
|
|
2022-02-06 10:14:57 -06:00
|
|
|
void window_all_handle_events()
|
2022-01-19 16:43:21 -06:00
|
|
|
{
|
2022-12-28 16:50:54 -06:00
|
|
|
for (int i = 0; i < arrlen(windows); i++)
|
|
|
|
window_handle_event(&windows[i]);
|
2022-01-19 16:43:21 -06:00
|
|
|
}
|
|
|
|
|
2022-11-03 16:58:03 -05:00
|
|
|
void window_makefullscreen(struct window *w)
|
2021-11-30 21:29:18 -06:00
|
|
|
{
|
2022-08-12 14:03:56 -05:00
|
|
|
if (!w->fullscreen)
|
|
|
|
window_togglefullscreen(w);
|
|
|
|
}
|
|
|
|
|
2022-11-03 16:58:03 -05:00
|
|
|
void window_unfullscreen(struct window *w)
|
2022-08-12 14:03:56 -05:00
|
|
|
{
|
|
|
|
if (w->fullscreen)
|
|
|
|
window_togglefullscreen(w);
|
2021-11-30 21:29:18 -06:00
|
|
|
}
|
|
|
|
|
2022-11-03 16:58:03 -05:00
|
|
|
void window_togglefullscreen(struct window *w)
|
2021-11-30 21:29:18 -06:00
|
|
|
{
|
|
|
|
w->fullscreen = !w->fullscreen;
|
|
|
|
|
|
|
|
if (w->fullscreen) {
|
2022-08-12 14:03:56 -05:00
|
|
|
glfwMaximizeWindow(w->window);
|
2021-11-30 21:29:18 -06:00
|
|
|
} else {
|
2022-02-06 10:14:57 -06:00
|
|
|
glfwRestoreWindow(w->window);
|
2021-11-30 21:29:18 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-11-03 16:58:03 -05:00
|
|
|
void window_makecurrent(struct window *w)
|
2021-11-30 21:29:18 -06:00
|
|
|
{
|
2022-06-23 11:05:47 -05:00
|
|
|
|
|
|
|
if (w->window != glfwGetCurrentContext())
|
|
|
|
glfwMakeContextCurrent(w->window);
|
2021-11-30 21:29:18 -06:00
|
|
|
glViewport(0, 0, w->width, w->height);
|
2022-06-23 11:05:47 -05:00
|
|
|
|
2021-11-30 21:29:18 -06:00
|
|
|
}
|
|
|
|
|
2022-08-12 14:03:56 -05:00
|
|
|
|
|
|
|
|
2022-11-03 16:58:03 -05:00
|
|
|
void window_swap(struct window *w)
|
2021-11-30 21:29:18 -06:00
|
|
|
{
|
2022-02-06 10:14:57 -06:00
|
|
|
glfwSwapBuffers(w->window);
|
2021-11-30 21:29:18 -06:00
|
|
|
}
|
2022-01-19 16:43:21 -06:00
|
|
|
|
2022-11-03 16:58:03 -05:00
|
|
|
void window_seticon(struct window *w, struct Texture *icon)
|
2022-01-19 16:43:21 -06:00
|
|
|
{
|
2022-06-23 11:05:47 -05:00
|
|
|
|
|
|
|
static GLFWimage images[1];
|
|
|
|
images[0].width = icon->width;
|
|
|
|
images[0].height = icon->height;
|
2023-03-24 14:01:01 -05:00
|
|
|
images[0].pixels = icon->data;
|
2022-02-06 10:14:57 -06:00
|
|
|
glfwSetWindowIcon(w->window, 1, images);
|
2022-01-19 16:43:21 -06:00
|
|
|
}
|
|
|
|
|
2022-11-03 16:58:03 -05:00
|
|
|
int window_hasfocus(struct window *w)
|
2022-01-19 16:43:21 -06:00
|
|
|
{
|
2022-02-06 10:14:57 -06:00
|
|
|
return glfwGetWindowAttrib(w->window, GLFW_FOCUSED);
|
|
|
|
}
|
|
|
|
|
2022-11-03 16:58:03 -05:00
|
|
|
void window_render(struct window *w) {
|
2022-08-07 01:43:45 -05:00
|
|
|
window_makecurrent(w);
|
|
|
|
openglRender(w);
|
|
|
|
window_swap(w);
|
2022-02-06 10:14:57 -06:00
|
|
|
}
|
2022-06-23 11:05:47 -05:00
|
|
|
|
2022-08-07 01:43:45 -05:00
|
|
|
void window_renderall() {
|
2022-10-24 15:19:48 -05:00
|
|
|
//arrwalk(windows, window_render);
|
|
|
|
for (int i = 0; i < arrlen(windows); i++)
|
|
|
|
window_render(&windows[i]);
|
2022-11-25 07:12:31 -06:00
|
|
|
}
|