From 1b72ba842c491dea8766e08ecbd4b628f95dbe2f Mon Sep 17 00:00:00 2001 From: bog Date: Sun, 29 Oct 2023 23:35:26 +0100 Subject: [PATCH] :sparkles: pressed?, just-pressed and mouse-x, mouse-y functions. --- src/Game.cpp | 75 +++++++++++++++++++++++++++++++ src/Game.hpp | 8 ++++ src/Script.cpp | 117 ++++++++++++++++++++++++++++++++++++++----------- src/Script.hpp | 8 ++++ 4 files changed, 182 insertions(+), 26 deletions(-) diff --git a/src/Game.cpp b/src/Game.cpp index ae4d4b4..a7a4c82 100644 --- a/src/Game.cpp +++ b/src/Game.cpp @@ -1,5 +1,7 @@ #include #include "Game.hpp" +#include "SDL_events.h" +#include "SDL_keyboard.h" #include namespace d2 @@ -105,4 +107,77 @@ namespace d2 m_scenes.pop_back(); } } + + bool Game::is_key_pressed(std::string const& keyname) const + { + SDL_Keycode key = SDL_GetKeyFromName(keyname.c_str()); + SDL_Scancode scan = SDL_GetScancodeFromKey(key); + Uint8 const* keys = SDL_GetKeyboardState(nullptr); + + return keys[scan]; + } + + bool Game::is_key_just_pressed(std::string const& keyname) const + { + static bool prev = false; + + bool pressed = is_key_pressed(keyname); + + if (pressed != prev) + { + prev = pressed; + return pressed; + } + + return false; + } + + bool Game::is_mouse_pressed(std::string const& btn_name) const + { + Uint32 btns = SDL_GetMouseState(nullptr, nullptr); + + if (btn_name == "left") + { + return btns & SDL_BUTTON(SDL_BUTTON_LEFT); + } + else if (btn_name == "middle") + { + return btns & SDL_BUTTON(SDL_BUTTON_MIDDLE); + } + else if (btn_name == "right") + { + return btns & SDL_BUTTON(SDL_BUTTON_RIGHT); + } + + throw game_error {"Unknown mosue button '" + btn_name + "'."}; + } + + bool Game::is_mouse_just_pressed(std::string const& btn_name) const + { + static bool prev = false; + bool new_val = is_mouse_pressed(btn_name); + + if (new_val != prev) + { + prev = new_val; + return new_val; + } + + return false; + } + + int Game::mouse_x() const + { + int x; + SDL_GetMouseState(&x, nullptr); + return x; + } + + int Game::mouse_y() const + { + int y; + SDL_GetMouseState(&y, nullptr); + return y; + } + } diff --git a/src/Game.hpp b/src/Game.hpp index 4aee529..57c34db 100644 --- a/src/Game.hpp +++ b/src/Game.hpp @@ -25,6 +25,14 @@ namespace d2 void push(Args... args); void pop(); + bool is_key_pressed(std::string const& keyname) const; + bool is_key_just_pressed(std::string const& keyname) const; + + bool is_mouse_pressed(std::string const& btn_name) const; + bool is_mouse_just_pressed(std::string const& btn_name) const; + int mouse_x() const; + int mouse_y() const; + private: SDL_Window* m_window = nullptr; SDL_GLContext m_context; diff --git a/src/Script.cpp b/src/Script.cpp index ef3d17e..7c0dfd3 100644 --- a/src/Script.cpp +++ b/src/Script.cpp @@ -10,6 +10,11 @@ namespace d2 scm_init_guile(); scm_c_define_gsubr("winconf", 3, 0, 0, reinterpret_cast(&fn_winconf)); + // Drawing + // ------- + scm_c_define_gsubr("rect", 4, 0, 0, reinterpret_cast(&fn_rect)); + scm_c_define_gsubr("color!", 4, 0, 0, + reinterpret_cast(&fn_set_color)); // Scenes // ------ @@ -19,11 +24,19 @@ namespace d2 scm_c_define_gsubr("scene:pop", 0, 0, 0, reinterpret_cast(&fn_scene__pop)); - // Drawing - // ------- - scm_c_define_gsubr("rect", 4, 0, 0, reinterpret_cast(&fn_rect)); - scm_c_define_gsubr("color!", 4, 0, 0, - reinterpret_cast(&fn_set_color)); + // Inputs + // ------ + scm_c_define_gsubr("pressed?", 2, 0, 0, + reinterpret_cast(&fn_is_pressed)); + scm_c_define_gsubr("just-pressed?", 2, 0, 0, + reinterpret_cast(&fn_is_just_pressed)); + + scm_c_define_gsubr("mouse-x", 0, 0, 0, + reinterpret_cast(&fn_mouse_x)); + scm_c_define_gsubr("mouse-y", 0, 0, 0, + reinterpret_cast(&fn_mouse_y)); + + } /*static*/ void Script::terminate() @@ -56,27 +69,7 @@ namespace d2 return SCM_BOOL_T; } - /*static*/ SCM Script::fn_scene__push(SCM scm_function, SCM scm_ctx) - { - if (scm_is_null(scm_ctx)) - { - Script::game->push(scm_function); - } - else - { - Script::game->push(scm_function, scm_ctx); - } - - return SCM_BOOL_T; - } - - /*static*/ SCM Script::fn_scene__pop() - { - Script::game->pop(); - return SCM_BOOL_T; - } - - /*static*/ SCM Script::fn_rect(SCM scm_x, SCM scm_y, SCM scm_w, SCM scm_h) + /*static*/ SCM Script::fn_rect(SCM scm_x, SCM scm_y, SCM scm_w, SCM scm_h) { float x = scm_to_double(scm_x); float y = scm_to_double(scm_y); @@ -116,4 +109,76 @@ namespace d2 return SCM_BOOL_T; } + + /*static*/ SCM Script::fn_scene__push(SCM scm_function, SCM scm_ctx) + { + if (scm_is_null(scm_ctx)) + { + Script::game->push(scm_function); + } + else + { + Script::game->push(scm_function, scm_ctx); + } + + return SCM_BOOL_T; + } + + /*static*/ SCM Script::fn_scene__pop() + { + Script::game->pop(); + return SCM_BOOL_T; + } + + /*static*/ SCM Script::fn_is_pressed(SCM scm_device, SCM scm_keyname) + { + std::string device = + scm_to_locale_string(scm_symbol_to_string(scm_device)); + std::string keyname = scm_to_locale_string(scm_keyname); + + if (device == "key") + { + bool result = Script::game->is_key_pressed(keyname); + return scm_from_bool(result); + } + + if (device == "mouse") + { + bool result = Script::game->is_mouse_pressed(keyname); + return scm_from_bool(result); + } + + throw script_error {"Unknown device '" + device + "'."}; + } + + /*static*/ SCM Script::fn_is_just_pressed(SCM scm_device, SCM scm_keyname) + { + std::string device = + scm_to_locale_string(scm_symbol_to_string(scm_device)); + std::string keyname = scm_to_locale_string(scm_keyname); + + if (device == "key") + { + bool result = Script::game->is_key_just_pressed(keyname); + return scm_from_bool(result); + } + + if (device == "mouse") + { + bool result = Script::game->is_mouse_just_pressed(keyname); + return scm_from_bool(result); + } + + throw script_error {"Unknown device '" + device + "'."}; + } + + /*static*/ SCM Script::fn_mouse_x() + { + return scm_from_int32(Script::game->mouse_x()); + } + + /*static*/ SCM Script::fn_mouse_y() + { + return scm_from_int32(Script::game->mouse_y()); + } } diff --git a/src/Script.hpp b/src/Script.hpp index 5b34222..2f0f4ef 100644 --- a/src/Script.hpp +++ b/src/Script.hpp @@ -8,6 +8,8 @@ namespace d2 { + D2_ERROR(script_error); + struct Script { static void init(); @@ -21,6 +23,12 @@ namespace d2 static SCM fn_scene__push(SCM scm_function, SCM scm_ctx); static SCM fn_scene__pop(); + static SCM fn_is_pressed(SCM scm_device, SCM scm_keyname); + static SCM fn_is_just_pressed(SCM scm_device, SCM scm_keyname); + + static SCM fn_mouse_x(); + static SCM fn_mouse_y(); + private: static std::unique_ptr game; static glm::vec4 color;