From 41ac253f743e464194587c3ecc0f2547c95d924d Mon Sep 17 00:00:00 2001 From: sanine-a Date: Sat, 24 Oct 2020 21:35:14 -0500 Subject: add window module and fullscreen toggle --- src/common.h | 21 ++++++++++------ src/honey.c | 41 ++++++++----------------------- src/honey.h | 3 ++- src/honey_lua.c | 43 ++++++++++++++++++++++++++++++++ src/input/input.c | 2 +- src/main.c | 10 ++++++-- src/window/window.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/window/window.h | 36 +++++++++++++++++++++++++++ 8 files changed, 184 insertions(+), 43 deletions(-) create mode 100644 src/window/window.c create mode 100644 src/window/window.h (limited to 'src') diff --git a/src/common.h b/src/common.h index 63962db..2e6a60b 100644 --- a/src/common.h +++ b/src/common.h @@ -1,3 +1,5 @@ +/** @file */ + #ifndef HONEY_COMMON_H #define HONEY_COMMON_H @@ -101,6 +103,8 @@ typedef enum { HONEY_FUNC, HONEY_TABLE, HONEY_NIL, + HONEY_USERDATA, + HONEY_LIGHTUSERDATA, HONEY_ANY } honey_lua_type; @@ -120,14 +124,15 @@ typedef struct honey_lua_element { char* name; honey_lua_type type; union { - int integer; - double number; - char* string; - int (*function)(lua_State*); - struct { - int n_elements; - struct honey_lua_element* elements; - } table; + int integer; + double number; + char* string; + int (*function)(lua_State*); + struct { + int n_elements; + struct honey_lua_element* elements; + } table; + void* pointer; } data; } honey_lua_element; diff --git a/src/honey.c b/src/honey.c index 0bd5b25..cfc5bc7 100644 --- a/src/honey.c +++ b/src/honey.c @@ -55,45 +55,24 @@ bool honey_parse_options(honey_options* options, int argc, char** argv) /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -bool honey_setup(lua_State** L, honey_window* window) +bool honey_setup(lua_State** L) { - /* set up glfw */ - glfwInit(); - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); - glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); - - *window = glfwCreateWindow(640, 480, "honey", NULL, NULL); - if (*window == NULL) { - fprintf(stderr, "[honey] ERROR: failed to create window!\n"); - glfwTerminate(); - return false; - } - - glfwMakeContextCurrent(*window); - - if (!gladLoadGLLoader((GLADloadproc) glfwGetProcAddress)) { - fprintf(stderr, "[honey] ERROR: failed to initialize GLAD!\n"); - glfwTerminate(); - return false; - } - - honey_setup_keyboard(); - glfwSetKeyCallback(*window, default_honey_keyboard_callback); - - // Enable blending - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - /* set up lua and honey lua bindings */ *L = luaL_newstate(); luaL_openlibs(*L); - glfwSetWindowUserPointer(*window, *L); lua_createtable(*L, 0, 1); + if (!honey_setup_window(*L)) + return false; + + lua_getfield(*L, -1, "internal"); + honey_window_information* info = lua_touserdata(*L, -1); + lua_pop(*L, 1); + lua_setfield(*L, -2, "window"); + honey_setup_input(*L); + glfwSetKeyCallback(info->window, default_honey_keyboard_callback); lua_setfield(*L, -2, "input"); lua_setglobal(*L, "honey"); diff --git a/src/honey.h b/src/honey.h index b349475..974136a 100644 --- a/src/honey.h +++ b/src/honey.h @@ -16,6 +16,7 @@ #include "primitives/primitives.h" #include "shader/shader.h" #include "texture/texture.h" +#include "window/window.h" /** @struct Helper struct to wrap command-line options. */ typedef struct { @@ -48,7 +49,7 @@ bool honey_parse_options(honey_options* options, int argc, char** argv); * * @returns true on a success; false otherwise. */ -bool honey_setup(lua_State** L, honey_window* window); +bool honey_setup(lua_State** L); /** @brief The main game loop. * diff --git a/src/honey_lua.c b/src/honey_lua.c index ded2a91..4dd0667 100644 --- a/src/honey_lua.c +++ b/src/honey_lua.c @@ -132,6 +132,36 @@ bool honey_lua_validate_types(lua_State* L, } break; + case HONEY_USERDATA: + if (!lua_isuserdata(L, i+1)) { + result = honey_format_string(&error_message, + "Expected userdata in position %d", + i); + if (result != HONEY_OK) + lua_pushstring(L, "Expected userdata; allocation error occurred for more detailed message."); + else { + lua_pushstring(L, error_message); + free(error_message); + } + return false; + } + break; + + case HONEY_LIGHTUSERDATA: + if (!lua_islightuserdata(L, i+1)) { + result = honey_format_string(&error_message, + "Expected C pointer in position %d", + i); + if (result != HONEY_OK) + lua_pushstring(L, "Expected C pointer; allocation error occurred for more detailed message."); + else { + lua_pushstring(L, error_message); + free(error_message); + } + return false; + } + break; + case HONEY_ANY: break; @@ -185,6 +215,19 @@ void honey_lua_push_element(lua_State* L, honey_lua_element element) element.data.table.n_elements); break; + case HONEY_NIL: + lua_pushnil(L); + break; + + case HONEY_USERDATA: + /* cannot push userdata, push nil */ + lua_pushnil(L); + break; + + case HONEY_LIGHTUSERDATA: + lua_pushlightuserdata(L, element.data.pointer); + break; + default: // this should never happen break; diff --git a/src/input/input.c b/src/input/input.c index c231157..5624269 100644 --- a/src/input/input.c +++ b/src/input/input.c @@ -12,7 +12,7 @@ void honey_setup_keyboard() void honey_setup_input(lua_State* L) { honey_setup_keyboard(); - + honey_lua_element keyElements[] = { { "unknown", HONEY_INT, { HONEY_KEY_UNKNOWN } }, { "space", HONEY_INT, { HONEY_KEY_SPACE } }, diff --git a/src/main.c b/src/main.c index 8d710a7..9b83a8f 100644 --- a/src/main.c +++ b/src/main.c @@ -7,12 +7,18 @@ int main(int argc, char** argv) return 0; } - honey_window window; lua_State* L; - if (!honey_setup(&L, &window)) + if (!honey_setup(&L)) return 1; + lua_getglobal(L, "honey"); + lua_getfield(L, -1, "window"); + lua_getfield(L, -1, "internal"); + honey_window_information* info = lua_touserdata(L, -1); + lua_pop(L, 2); + honey_window window = info->window; + char* script; honey_result res = honey_format_string(&script, "%s/main.lua", diff --git a/src/window/window.c b/src/window/window.c new file mode 100644 index 0000000..bb371cd --- /dev/null +++ b/src/window/window.c @@ -0,0 +1,71 @@ +#include "window.h" + +bool honey_setup_window(lua_State* L) +{ + honey_window_information* info = malloc(sizeof(honey_window_information)); + if (info == NULL) { + fprintf(stderr, "[honey] ERROR: failed to allocate memory for window information!\n"); + return false; + } + + glfwInit(); + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + + info->window = glfwCreateWindow(640, 480, "honey", NULL, NULL); + if (info->window == NULL) { + fprintf(stderr, "[honey] ERROR: failed to create window!\n"); + glfwTerminate(); + return false; + } + /* store lua state in window, so it's accessible from GLFW callbacks */ + glfwSetWindowUserPointer(info->window, L); + glfwMakeContextCurrent(info->window); + + if (!gladLoadGLLoader((GLADloadproc) glfwGetProcAddress)) { + fprintf(stderr, "[honey] ERROR: failed to initialize GLAD!\n"); + glfwTerminate(); + return false; + } + + // Enable blending + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + honey_lua_element window_elements[] = { + { "internal", HONEY_LIGHTUSERDATA, { .pointer = info } }, + { "set_fullscreen", HONEY_FUNC, { .function = honey_window_set_fullscreen } }, + }; + + honey_lua_create_table(L, window_elements, 2); + return true; +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +int honey_window_set_fullscreen(lua_State* L) +{ + if (!honey_lua_validate_types(L, 1, HONEY_BOOL)) + lua_error(L); + + bool fullscreen = lua_toboolean(L, 1); + + lua_getglobal(L, "honey"); + lua_getfield(L, -1, "window"); + lua_getfield(L, -1, "internal"); + honey_window_information* info = lua_touserdata(L, -1); + lua_pop(L, 2); + + if (fullscreen) { + glfwGetWindowSize(info->window, &(info->width), &(info->height)); + + GLFWmonitor* monitor = glfwGetPrimaryMonitor(); + const GLFWvidmode* mode = glfwGetVideoMode(monitor); + glfwSetWindowMonitor(info->window, monitor, 0, 0, mode->width, mode->height, mode->refreshRate); + } + else { + glfwSetWindowMonitor(info->window, NULL, 20, 20, info->width, info->height, 0); + } + return 0; +} diff --git a/src/window/window.h b/src/window/window.h new file mode 100644 index 0000000..c0083ba --- /dev/null +++ b/src/window/window.h @@ -0,0 +1,36 @@ +/** @file */ + +#ifndef HONEY_WINDOW_H +#define HONEY_WINDOW_H + +#include "../common.h" + +#define HONEY_WINDOW_DEFAULT_WIDTH 640 +#define HONEY_WINDOW_DEFAULT_HEIGHT 480 + +typedef struct { + honey_window window; + int width; + int height; + bool fullscreen; +} honey_window_information; + +/** @brief Push the various honey.window table to the stack. + * + * @param[in] L The lua state to push to + * @param[in] window The window created by honey_setup() + * + * @returns Nothing. + */ +bool honey_setup_window(lua_State* L); + +/** @brief Set whether or not the window is fullscreen. + * + * Lua parameters: + * @param[in] fullscreen Boolean set to true if the window is to be fullscreen and false otherwise. + * + * @returns Nothing. + */ +int honey_window_set_fullscreen(lua_State* L); + +#endif -- cgit v1.2.1