diff options
-rw-r--r-- | demo/main.lua | 8 | ||||
-rw-r--r-- | src/common.h | 13 | ||||
-rw-r--r-- | src/honey.c | 4 | ||||
-rw-r--r-- | src/input/input.c | 144 | ||||
-rw-r--r-- | src/input/input.h | 35 | ||||
-rw-r--r-- | src/window/window.h | 13 |
6 files changed, 186 insertions, 31 deletions
diff --git a/demo/main.lua b/demo/main.lua index 9cae165..26fabd9 100644 --- a/demo/main.lua +++ b/demo/main.lua @@ -11,10 +11,16 @@ local resize_func = function(width, height, data) print('resized!', w, h) end +local mousemove = function(x, y) + print(x, y) +end + honey.window.set_title('honey engine demo') -honey.input.bind_key(honey.input.key.a, a_func) +honey.input.key.bind(honey.input.key.a, a_func) honey.window.resize_bind(resize_func) +honey.input.mouse.set_mode( honey.input.mouse.mode.disabled ) +honey.input.mouse.bind_movement(mousemove) local focus_func = function(focus) diff --git a/src/common.h b/src/common.h index 2e6a60b..9027712 100644 --- a/src/common.h +++ b/src/common.h @@ -35,6 +35,19 @@ typedef GLFWwindow* honey_window; +typedef struct { + honey_window window; + int width; + int height; + bool fullscreen; +} honey_window_information; + +extern int honey_window_info_ref; +extern int honey_window_resize_callback_ref; +extern int honey_window_resize_callback_data_ref; +extern int honey_window_focus_callback_ref; +extern int honey_window_focus_callback_data_ref; + /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ typedef enum { diff --git a/src/honey.c b/src/honey.c index 5cf960e..9e8bc45 100644 --- a/src/honey.c +++ b/src/honey.c @@ -72,10 +72,6 @@ bool honey_setup(lua_State** L) lua_setglobal(*L, "honey"); - lua_rawgeti(*L, LUA_REGISTRYINDEX, honey_window_info_ref); - honey_window_information* info = lua_touserdata(*L, -1); - glfwSetKeyCallback(info->window, default_honey_keyboard_callback); - return true; } diff --git a/src/input/input.c b/src/input/input.c index 2fa1626..aa472b4 100644 --- a/src/input/input.c +++ b/src/input/input.c @@ -1,5 +1,14 @@ #include "input.h" +int honey_mouse_movement_callback_ref = LUA_NOREF; +int honey_mouse_movement_callback_data_ref = LUA_NOREF; + +static void honey_glfw_mouse_movement_callback(honey_window window, + double x_pos, double y_pos); +static void honey_glfw_keyboard_callback(honey_window window, + int key, int scancode, + int action, int mods); + void honey_setup_keyboard() { memset(honey_key_states, 0, sizeof(honey_key_states)); @@ -12,8 +21,15 @@ void honey_setup_keyboard() void honey_setup_input(lua_State* L) { honey_setup_keyboard(); + + lua_rawgeti(L, LUA_REGISTRYINDEX, honey_window_info_ref); + honey_window_information* info = lua_touserdata(L, -1); + lua_pop(L, 1); + + glfwSetKeyCallback(info->window, honey_glfw_keyboard_callback); + glfwSetCursorPosCallback(info->window, honey_glfw_mouse_movement_callback); - honey_lua_element keyElements[] = { + honey_lua_element key_elements[] = { { "unknown", HONEY_INT, { HONEY_KEY_UNKNOWN } }, { "space", HONEY_INT, { HONEY_KEY_SPACE } }, { "apostrophe", HONEY_INT, { HONEY_KEY_APOSTROPHE } }, @@ -135,17 +151,31 @@ void honey_setup_input(lua_State* L) { "right_alt", HONEY_INT, { HONEY_KEY_RIGHT_ALT } }, { "right_super", HONEY_INT, { HONEY_KEY_RIGHT_SUPER } }, { "menu", HONEY_INT, { HONEY_KEY_MENU } }, + { "is_down", HONEY_FUNC, { .function = honey_key_down } }, + { "bind", HONEY_FUNC, { .function = honey_key_bind } }, + { "unbind", HONEY_FUNC, { .function = honey_key_unbind } }, + { "unbind_all", HONEY_FUNC, { .function = honey_key_unbind_all } }, }; - honey_lua_element inputElements[] = { - { "key", HONEY_TABLE, { .table={ HONEY_N_KEYS, keyElements } } }, - { "is_down", HONEY_FUNC, { .function = honey_key_down } }, - { "bind_key", HONEY_FUNC, { .function = honey_key_bind } }, - { "unbind_key", HONEY_FUNC, { .function = honey_key_unbind } }, - { "unbind_all_keys", HONEY_FUNC, { .function = honey_key_unbind_all } }, + honey_lua_element mouse_mode_elements[] = { + { "normal", HONEY_INT, { .integer = HONEY_MOUSE_MODE_NORMAL } }, + { "hidden", HONEY_INT, { .integer = HONEY_MOUSE_MODE_HIDDEN } }, + { "disabled", HONEY_INT, { .integer = HONEY_MOUSE_MODE_DISABLED } }, + }; + + honey_lua_element mouse_elements[] = { + { "mode", HONEY_TABLE, { .table = { 3, mouse_mode_elements } } }, + { "set_mode", HONEY_FUNC, { .function = honey_mouse_set_mode } }, + { "bind_movement", HONEY_FUNC, { .function = honey_mouse_movement_bind } }, + { "unbind_movement", HONEY_FUNC, { .function = honey_mouse_movement_unbind } }, }; - honey_lua_create_table(L, inputElements, 5); + honey_lua_element input_elements[] = { + { "key", HONEY_TABLE, { .table={ HONEY_N_KEYS+4, key_elements } } }, + { "mouse", HONEY_TABLE, { .table={ 4, mouse_elements } } }, + }; + + honey_lua_create_table(L, input_elements, 2); } /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ @@ -194,6 +224,11 @@ int honey_key_bind(lua_State* L) lua_pushvalue(L, 3); int data = luaL_ref(L, LUA_REGISTRYINDEX); + /* avoid potential memory leak */ + lua_pushcfunction(L, honey_key_unbind); + lua_pushinteger(L, key); + honey_lua_pcall(L, 1, 0); + if (key >= 0 && key < HONEY_N_KEYS) { honey_key_callbacks[key] = callback; honey_key_callbacks_data[key] = data; @@ -238,6 +273,91 @@ int honey_key_unbind_all(lua_State* L) /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +int honey_mouse_set_mode(lua_State* L) +{ + if (!honey_lua_validate_types(L, 1, HONEY_INT)) + lua_error(L); + + int cursor_mode = lua_tointeger(L, 1); + + if (honey_window_info_ref == LUA_NOREF || + honey_window_info_ref == LUA_REFNIL) { + lua_pushstring(L, "ERROR: no window set!"); + lua_error(L); + } + + lua_rawgeti(L, LUA_REGISTRYINDEX, honey_window_info_ref); + honey_window_information* info = lua_touserdata(L, -1); + + glfwSetInputMode(info->window, GLFW_CURSOR, cursor_mode); + + return 0; +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +int honey_mouse_movement_bind(lua_State* L) +{ + if (!honey_lua_validate_types(L, 2, HONEY_FUNC, HONEY_ANY)) + lua_error(L); + + honey_mouse_movement_unbind(L); /* avoid memory leaks! */ + + lua_pushvalue(L, 1); + honey_mouse_movement_callback_ref = luaL_ref(L, LUA_REGISTRYINDEX); + lua_pushvalue(L, 2); + honey_mouse_movement_callback_data_ref = luaL_ref(L, LUA_REGISTRYINDEX); + return 0; +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +int honey_mouse_movement_unbind(lua_State* L) +{ + int callback = honey_mouse_movement_callback_ref; + int data = honey_mouse_movement_callback_data_ref; + + if (callback != LUA_NOREF || callback != LUA_REFNIL) { + lua_pushnil(L); + lua_rawseti(L, LUA_REGISTRYINDEX, callback); + } + + if (data != LUA_NOREF || data != LUA_REFNIL) { + lua_pushnil(L); + lua_rawseti(L, LUA_REGISTRYINDEX, data); + } + + honey_mouse_movement_callback_ref = LUA_NOREF; + honey_mouse_movement_callback_data_ref = LUA_NOREF; + return 0; +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +static void honey_glfw_mouse_movement_callback(honey_window window, + double x_pos, double y_pos) +{ + int callback = honey_mouse_movement_callback_ref; + int data = honey_mouse_movement_callback_data_ref; + lua_State* L = glfwGetWindowUserPointer(window); + + if (callback == LUA_NOREF || callback == LUA_REFNIL) + return; + + lua_rawgeti(L, LUA_REGISTRYINDEX, callback); + lua_pushnumber(L, x_pos); + lua_pushnumber(L, y_pos); + + if (data == LUA_NOREF || data == LUA_REFNIL) + lua_pushnil(L); + else + lua_rawgeti(L, LUA_REGISTRYINDEX, data); + + honey_lua_pcall(L, 3, 0); +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + static void execute_lua_key_callback(lua_State* L, int callback, int action, int data) { if (callback != LUA_NOREF) { @@ -253,10 +373,12 @@ static void execute_lua_key_callback(lua_State* L, int callback, int action, int /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -void default_honey_keyboard_callback(honey_window window, int key, int scancode, int action, int mods) +static void honey_glfw_keyboard_callback(honey_window window, + int key, int scancode, + int action, int mods) { int callback, data; - lua_State* L = (lua_State*) glfwGetWindowUserPointer(window); + lua_State* L = glfwGetWindowUserPointer(window); switch (key) { case GLFW_KEY_UNKNOWN: if (action == HONEY_KEY_PRESS) { honey_key_states[HONEY_KEY_UNKNOWN] = 1; } @@ -1231,5 +1353,3 @@ void default_honey_keyboard_callback(honey_window window, int key, int scancode, break; } } - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ diff --git a/src/input/input.h b/src/input/input.h index 2127417..7fd3293 100644 --- a/src/input/input.h +++ b/src/input/input.h @@ -135,10 +135,17 @@ #define HONEY_KEY_PRESS GLFW_PRESS #define HONEY_KEY_RELEASE GLFW_RELEASE +#define HONEY_MOUSE_MODE_NORMAL GLFW_CURSOR_NORMAL +#define HONEY_MOUSE_MODE_HIDDEN GLFW_CURSOR_HIDDEN +#define HONEY_MOUSE_MODE_DISABLED GLFW_CURSOR_DISABLED + unsigned int honey_key_states[HONEY_N_KEYS]; static int honey_key_callbacks[HONEY_N_KEYS]; static int honey_key_callbacks_data[HONEY_N_KEYS]; +extern int honey_mouse_movement_callback_ref; +extern int honey_mouse_movement_callback_data_ref; + /** @brief Initializes Honey's internal keyboard states. * * This function is called by honey_setup, so you shouldn't need @@ -191,6 +198,32 @@ int honey_key_unbind(lua_State* L); */ int honey_key_unbind_all(lua_State* L); -void default_honey_keyboard_callback(honey_window window, int key, int scancode, int action, int mods); +/** @brief Set the cursor mode. + * + * @param[in] mode The mouse mode (from honey.input.mouse.mode) to use. + * + * @returns Nothing. + */ +int honey_mouse_set_mode(lua_State* L); + +/** Bind a callback to mouse movement. + * + * The callback should be of the form cb(xpos, ypos, data), + * where xpos and ypos are the coordinates of the mouse relative to the + * upper left corner of the window, and data is the data parameter passed + * to this function. + * + * @param[in] callback A callback as described above. + * @param[in] data Auxilliary data to pass to the callback. + * + * @returns Nothing. + */ +int honey_mouse_movement_bind(lua_State* L); + +/** Unbind any callback that may be attached to mouse movement. + * + * @returns Nothing. + */ +int honey_mouse_movement_unbind(lua_State* L); #endif diff --git a/src/window/window.h b/src/window/window.h index fae32c1..3ac982a 100644 --- a/src/window/window.h +++ b/src/window/window.h @@ -8,19 +8,6 @@ #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; - -extern int honey_window_info_ref; -extern int honey_window_resize_callback_ref; -extern int honey_window_resize_callback_data_ref; -extern int honey_window_focus_callback_ref; -extern int honey_window_focus_callback_data_ref; - /** @brief Push the various honey.window table to the stack. * * @param[in] L The lua state to push to |