Initial touch button attempt

This commit is contained in:
NyakoFox 2024-03-25 10:41:06 -03:00
parent 33fcbf8de3
commit 9353c4f20c
3 changed files with 214 additions and 25 deletions

View File

@ -215,12 +215,17 @@ bool cycle_language(bool should_recompute_textboxes)
static void remove_finger(int i) 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; if (touch::all_buttons[j]->active && touch::all_buttons[j]->pressed && touch::all_buttons[j]->down)
touch::buttons[j].fingerId = -1; {
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;
} }
} }

View File

@ -1,12 +1,25 @@
#include "Touch.h" #include "Touch.h"
#include <SDL.h> #include <SDL.h>
#include <string>
#include <vector> #include <vector>
#include "ButtonGlyphs.h"
#include "Constants.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 "Graphics.h"
#include "GraphicsResources.h" #include "GraphicsResources.h"
#include "Input.h"
#include "Localization.h"
#include "KeyPoll.h" #include "KeyPoll.h"
#include "Map.h"
#include "Music.h"
#include "Screen.h" #include "Screen.h"
#include "Script.h" #include "Script.h"
#include "UtilityClass.h" #include "UtilityClass.h"
@ -15,7 +28,26 @@ namespace touch
{ {
std::vector<VVV_Finger> fingers; std::vector<VVV_Finger> fingers;
TouchButton buttons[NUM_TOUCH_BUTTONS]; TouchButton buttons[NUM_TOUCH_BUTTONS];
std::vector<TouchButton> dynamic_buttons;
std::vector<TouchButton*> all_buttons;
bool use_buttons;
int scale; 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) int get_rect(TouchButton* button, SDL_Rect* rect)
{ {
@ -45,10 +77,32 @@ namespace touch
for (int i = 0; i < NUM_TOUCH_BUTTONS; i++) for (int i = 0; i < NUM_TOUCH_BUTTONS; i++)
{ {
buttons[i].image = NULL; buttons[i].image = NULL;
buttons[i].text = "";
buttons[i].active = false; buttons[i].active = false;
buttons[i].pressed = false;
buttons[i].down = false; buttons[i].down = false;
buttons[i].fingerId = -1; 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) void refresh_buttons(void)
@ -95,6 +149,8 @@ namespace touch
buttons[i].active = false; buttons[i].active = false;
} }
use_buttons = true;
// Now, set the buttons that are active // Now, set the buttons that are active
switch (game.gamestate) 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) void render(void)
{ {
if (!key.using_touch) if (!key.using_touch)
@ -151,16 +278,7 @@ namespace touch
int scale = get_scale(); int scale = get_scale();
refresh_buttons(); refresh_buttons();
for (int i = 0; i < NUM_TOUCH_BUTTONS; i++) render_buttons(scale, true, 64, 184, 208);
{
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);
}
}
} }
void reset(void) void reset(void)
@ -180,27 +298,44 @@ namespace touch
void update_buttons(void) void update_buttons(void)
{ {
if (graphics.fademode != FADE_NONE) if (!use_buttons || graphics.fademode != FADE_NONE)
{ {
return; return;
} }
SDL_Rect stretch_rect;
graphics.get_stretch_info(&stretch_rect);
SDL_Point point; SDL_Point point;
SDL_Rect rect; 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; button->down = false;
for (int fingerId = 0; fingerId < fingers.size(); fingerId++) for (int fingerId = 0; fingerId < fingers.size(); fingerId++)
{ {
point.x = fingers[fingerId].x; if (button->ui)
point.y = fingers[fingerId].y; {
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); 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->down = true;
button->fingerId = fingers[fingerId].id; button->fingerId = fingers[fingerId].id;
fingers[fingerId].on_button = true; fingers[fingerId].on_button = true;
@ -212,7 +347,7 @@ namespace touch
bool button_tapped(TouchButtonID button) 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++) for (int i = 0; i < fingers.size(); i++)
{ {
@ -250,11 +385,16 @@ namespace touch
{ {
for (int i = 0; i < fingers.size(); i++) for (int i = 0; i < fingers.size(); i++)
{ {
if (fingers[i].on_button) if (fingers[i].on_button && use_buttons)
{ {
continue; 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 true;
} }
return false; return false;

View File

@ -3,6 +3,7 @@
#include <SDL.h> #include <SDL.h>
#include <string>
#include <vector> #include <vector>
struct VVV_Finger struct VVV_Finger
@ -27,32 +28,75 @@ enum TouchButtonID
TOUCH_BUTTON_CANCEL, TOUCH_BUTTON_CANCEL,
TOUCH_BUTTON_CONFIRM, 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 NUM_TOUCH_BUTTONS
}; };
enum TouchButtonType
{
TOUCH_BUTTON_TYPE_NONE,
TOUCH_BUTTON_TYPE_MENU,
TOUCH_BUTTON_TYPE_MAP
};
struct TouchButton struct TouchButton
{ {
int x; int x;
int y; int y;
int width; int width;
int height; int height;
bool down; bool down; // Whether the button is currently being pressed
bool active; bool pressed; // Whether the button was pressed down and not dragged onto
SDL_Texture* image; 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; SDL_FingerID fingerId;
TouchButtonType type;
}; };
namespace touch namespace touch
{ {
extern std::vector<VVV_Finger> fingers; extern std::vector<VVV_Finger> fingers;
extern TouchButton buttons[NUM_TOUCH_BUTTONS]; extern TouchButton buttons[NUM_TOUCH_BUTTONS];
extern std::vector<TouchButton> dynamic_buttons;
extern std::vector<TouchButton*> all_buttons;
extern int scale; extern int scale;
void refresh_buttons(void); void refresh_buttons(void);
void reset(void); void reset(void);
void update_buttons(void); void update_buttons(void);
void on_button_up(TouchButton* button);
void init(void); 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); void render(void);
bool button_tapped(TouchButtonID button); bool button_tapped(TouchButtonID button);