From 9353c4f20c5b917f5a86ac96aa01ece87019db5e Mon Sep 17 00:00:00 2001 From: NyakoFox Date: Mon, 25 Mar 2024 10:41:06 -0300 Subject: [PATCH] Initial touch button attempt --- desktop_version/src/KeyPoll.cpp | 13 ++- desktop_version/src/Touch.cpp | 176 ++++++++++++++++++++++++++++---- desktop_version/src/Touch.h | 50 ++++++++- 3 files changed, 214 insertions(+), 25 deletions(-) diff --git a/desktop_version/src/KeyPoll.cpp b/desktop_version/src/KeyPoll.cpp index 8b63bf78..bba1df8e 100644 --- a/desktop_version/src/KeyPoll.cpp +++ b/desktop_version/src/KeyPoll.cpp @@ -215,12 +215,17 @@ bool cycle_language(bool should_recompute_textboxes) static void remove_finger(int i) { - for (int j = 0; j < NUM_TOUCH_BUTTONS; j++) + for (int j = 0; j < (int)touch::all_buttons.size(); j++) { - if (touch::buttons[j].fingerId == touch::fingers[i].id) + if (touch::all_buttons[j]->fingerId == touch::fingers[i].id) { - touch::buttons[j].down = false; - touch::buttons[j].fingerId = -1; + if (touch::all_buttons[j]->active && touch::all_buttons[j]->pressed && touch::all_buttons[j]->down) + { + touch::on_button_up(touch::all_buttons[j]); + } + touch::all_buttons[j]->down = false; + touch::all_buttons[j]->pressed = false; + touch::all_buttons[j]->fingerId = -1; } } diff --git a/desktop_version/src/Touch.cpp b/desktop_version/src/Touch.cpp index 7552bdeb..a961498c 100644 --- a/desktop_version/src/Touch.cpp +++ b/desktop_version/src/Touch.cpp @@ -1,12 +1,25 @@ #include "Touch.h" #include +#include #include +#include "ButtonGlyphs.h" #include "Constants.h" +#include "CustomLevels.h" +#include "Editor.h" +#include "Entity.h" +#include "FileSystemUtils.h" +#include "Font.h" +#include "Game.h" +#include "GlitchrunnerMode.h" #include "Graphics.h" #include "GraphicsResources.h" +#include "Input.h" +#include "Localization.h" #include "KeyPoll.h" +#include "Map.h" +#include "Music.h" #include "Screen.h" #include "Script.h" #include "UtilityClass.h" @@ -15,7 +28,26 @@ namespace touch { std::vector fingers; TouchButton buttons[NUM_TOUCH_BUTTONS]; + std::vector dynamic_buttons; + std::vector all_buttons; + bool use_buttons; int scale; + bool textbox_style; + + void refresh_all_buttons(void) + { + all_buttons.clear(); + + for (int i = 0; i < NUM_TOUCH_BUTTONS; i++) + { + all_buttons.push_back(&buttons[i]); + } + + for (int i = 0; i < dynamic_buttons.size(); i++) + { + all_buttons.push_back(&dynamic_buttons[i]); + } + } int get_rect(TouchButton* button, SDL_Rect* rect) { @@ -45,10 +77,32 @@ namespace touch for (int i = 0; i < NUM_TOUCH_BUTTONS; i++) { buttons[i].image = NULL; + buttons[i].text = ""; buttons[i].active = false; + buttons[i].pressed = false; buttons[i].down = false; buttons[i].fingerId = -1; + buttons[i].core = true; + buttons[i].ui = true; + buttons[i].type = TOUCH_BUTTON_TYPE_NONE; + buttons[i].id = -1; + buttons[i].disabled = false; } + + refresh_all_buttons(); + } + + void on_button_up(TouchButton* button) + { + bool version2_2 = GlitchrunnerMode_less_than_or_equal(Glitchrunner2_2); + switch (button->type) + { + case TOUCH_BUTTON_TYPE_MENU: + case TOUCH_BUTTON_TYPE_NONE: + default: + break; + } + refresh_buttons(); } void refresh_buttons(void) @@ -95,6 +149,8 @@ namespace touch buttons[i].active = false; } + use_buttons = true; + // Now, set the buttons that are active switch (game.gamestate) @@ -141,6 +197,77 @@ namespace touch } } + void render_buttons(int scale, bool ui, int r, int g, int b) + { + for (int i = 0; i < all_buttons.size(); i++) + { + TouchButton* button = all_buttons[i]; + + if (button->active && (button->ui == ui)) + { + if (button->image != NULL) + { + graphics.draw_texture(button->image, button->x, button->y + (button->down ? 2 * scale : 0), scale, scale); + } + else + { + int use_r = button->disabled ? 127 : r; + int use_g = button->disabled ? 127 : g; + int use_b = button->disabled ? 127 : b; + + if (button->type == TOUCH_BUTTON_TYPE_MAP) + { + if (game.menupage != button->id) + { + use_r /= 2; + use_g /= 2; + use_b /= 2; + } + } + + float shadow_div = 4; + float inner_div = 1.5; + + if (textbox_style) + { + shadow_div = 6; + inner_div = 6; + } + + graphics.fill_rect(button->x + 4 * scale, button->y + 4 * scale, button->width, button->height, r / shadow_div, g / shadow_div, b / shadow_div); + + int offset = (button->down) ? 1 : 0; + + graphics.fill_rect(button->x + offset * scale, button->y + offset * scale, button->width, button->height, use_r, use_g, use_b); + graphics.fill_rect(button->x + (offset + 2) * scale, button->y + (2 + offset) * scale, button->width - 4 * scale, button->height - 4 * scale, use_r / inner_div, use_g / inner_div, use_b / inner_div); + font::print(PR_CEN | (SDL_min((scale - 1), 7) << 0), button->x + (button->width / 2) + offset * scale, button->y + (button->height / 2) + (offset - 4) * scale, button->text, 196, 196, 255 - help.glow); + } + } + } + } + + void render_buttons(void) + { + render_buttons(64, 184, 208); + } + + void render_buttons(int r, int g, int b) + { + if (!key.using_touch) + { + return; + } + + render_buttons(1, false, r, g, b); + } + + void render_buttons(int r, int g, int b, bool textbox_style) + { + touch::textbox_style = textbox_style; + render_buttons(r, g, b); + touch::textbox_style = false; + } + void render(void) { if (!key.using_touch) @@ -151,16 +278,7 @@ namespace touch int scale = get_scale(); refresh_buttons(); - for (int i = 0; i < NUM_TOUCH_BUTTONS; i++) - { - SDL_Rect rect; - get_rect(&buttons[i], &rect); - - if (buttons[i].image != NULL && buttons[i].active) - { - graphics.draw_texture(buttons[i].image, rect.x, rect.y + (buttons[i].down ? 2 * scale : 0), scale, scale); - } - } + render_buttons(scale, true, 64, 184, 208); } void reset(void) @@ -180,27 +298,44 @@ namespace touch void update_buttons(void) { - if (graphics.fademode != FADE_NONE) + if (!use_buttons || graphics.fademode != FADE_NONE) { return; } + + SDL_Rect stretch_rect; + graphics.get_stretch_info(&stretch_rect); + SDL_Point point; SDL_Rect rect; - for (int buttonId = 0; buttonId < NUM_TOUCH_BUTTONS; buttonId++) + for (int buttonId = 0; buttonId < all_buttons.size(); buttonId++) { - TouchButton* button = &buttons[buttonId]; + TouchButton* button = all_buttons[buttonId]; button->down = false; for (int fingerId = 0; fingerId < fingers.size(); fingerId++) { - point.x = fingers[fingerId].x; - point.y = fingers[fingerId].y; + if (button->ui) + { + point.x = fingers[fingerId].x; + point.y = fingers[fingerId].y; + } + else + { + point.x = (fingers[fingerId].x - stretch_rect.x) * SCREEN_WIDTH_PIXELS / stretch_rect.w; + point.y = (fingers[fingerId].y - stretch_rect.y) * SCREEN_HEIGHT_PIXELS / stretch_rect.h; + } get_rect(button, &rect); - if (SDL_PointInRect(&point, &rect) && button->active) + if (SDL_PointInRect(&point, &rect) && button->active && !button->disabled) { + if (fingers[fingerId].pressed) + { + button->pressed = true; + } + button->down = true; button->fingerId = fingers[fingerId].id; fingers[fingerId].on_button = true; @@ -212,7 +347,7 @@ namespace touch bool button_tapped(TouchButtonID button) { - if (key.using_touch && buttons[button].active && buttons[button].down) + if (use_buttons && key.using_touch && buttons[button].active && buttons[button].down && !buttons[button].disabled) { for (int i = 0; i < fingers.size(); i++) { @@ -250,11 +385,16 @@ namespace touch { for (int i = 0; i < fingers.size(); i++) { - if (fingers[i].on_button) + if (fingers[i].on_button && use_buttons) { continue; } + if (fingers[i].pressed) + { + // Consume the input, so we don't accidentally start pressing a button or anything + fingers[i].pressed = false; + } return true; } return false; diff --git a/desktop_version/src/Touch.h b/desktop_version/src/Touch.h index ce9188d2..119350b8 100644 --- a/desktop_version/src/Touch.h +++ b/desktop_version/src/Touch.h @@ -3,6 +3,7 @@ #include +#include #include struct VVV_Finger @@ -27,32 +28,75 @@ enum TouchButtonID TOUCH_BUTTON_CANCEL, TOUCH_BUTTON_CONFIRM, + /* Map */ + TOUCH_BUTTON_MAP_MAP, + TOUCH_BUTTON_MAP_CREW, + TOUCH_BUTTON_MAP_STATS, + TOUCH_BUTTON_MAP_QUIT, + + /* Map - Warp to ship */ + TOUCH_BUTTON_MAP_SHIP_WARP, + + /* Map - Quit buttons */ + TOUCH_BUTTON_MAP_QUIT_SAVE, + TOUCH_BUTTON_MAP_QUIT_SAVEEXIT, + TOUCH_BUTTON_MAP_QUIT_EXIT, + + /* Map - Back */ + TOUCH_BUTTON_MAP_BACK, + + /* Quit */ + TOUCH_BUTTON_QUIT_YES, + TOUCH_BUTTON_QUIT_NO, + NUM_TOUCH_BUTTONS }; +enum TouchButtonType +{ + TOUCH_BUTTON_TYPE_NONE, + TOUCH_BUTTON_TYPE_MENU, + TOUCH_BUTTON_TYPE_MAP +}; + struct TouchButton { int x; int y; int width; int height; - bool down; - bool active; - SDL_Texture* image; + bool down; // Whether the button is currently being pressed + bool pressed; // Whether the button was pressed down and not dragged onto + bool active; // Whether the button is currently active, i.e. visible and usable + bool core; // Whether the button is a "core" button, one which always exists (but not necessarily active) + bool ui; // Whether the button is on the UI layer or not + int id; // The ID for the button, mainly used for menu buttons + bool disabled; // Whether the button is disabled or not (gray and can't use), different from active + std::string text; // The text for the button, if it doesn't have an image + SDL_Texture* image; // The image that gets displayed on the button, can be NULL SDL_FingerID fingerId; + TouchButtonType type; }; namespace touch { extern std::vector fingers; extern TouchButton buttons[NUM_TOUCH_BUTTONS]; + extern std::vector dynamic_buttons; + extern std::vector all_buttons; extern int scale; void refresh_buttons(void); void reset(void); void update_buttons(void); + void on_button_up(TouchButton* button); + void init(void); + void render_buttons(void); + void render_buttons(int r, int g, int b); + void render_buttons(int r, int g, int b, bool textbox_style); + void render_buttons(int scale, bool ui, int r, int g, int b); void render(void); bool button_tapped(TouchButtonID button);