Skip to content

Commit

Permalink
Touch devices: implemented a way to quickly show/hide the cursor when…
Browse files Browse the repository at this point in the history
… switching between touch and real mouse input via the bool Mouse::use_touch_input.

For now this is only possible by working around several SDL2 issues on iOS (and possible Android) with real mouse devices.
When these are solved this needs to be visited again and this cursor feature put in #if SDL_VERSION_ATLEAST(version that fixed this).
  • Loading branch information
DominusExult committed Jul 25, 2021
1 parent bb450b5 commit bc98208
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 7 deletions.
18 changes: 17 additions & 1 deletion exult.cc
Expand Up @@ -700,6 +700,7 @@ static void Init(
init_flags |= SDL_INIT_JOYSTICK;
#endif
#ifdef __IPHONEOS__
Mouse::use_touch_input = true;
SDL_SetHint(SDL_HINT_IOS_HIDE_HOME_INDICATOR, "2");
#endif
if (SDL_Init(init_flags) < 0) {
Expand Down Expand Up @@ -1260,7 +1261,8 @@ static void Handle_event(
// We want this
Gump_manager *gump_man = gwin->get_gump_man();
Gump *gump = nullptr;


static sint64 last_finger_id = 0;
// For detecting double-clicks.
static uint32 last_b1_click = 0;
static uint32 last_b3_click = 0;
Expand Down Expand Up @@ -1371,6 +1373,18 @@ static void Handle_event(
}
break;
}
// FIXME: it is a bug in SDL2 that real mouse devices have a fingerId. A real fingerId changes on each touch
// but the erroneous real mouse fingerId stays the same for both left and right clicks. But a left click produces
// two fingerId events with the first always having the value 0.
case SDL_FINGERDOWN: {
if ((Mouse::use_touch_input == false) && (event.tfinger.fingerId != last_finger_id) && (event.tfinger.fingerId != 0)) {
Mouse::use_touch_input = true;
gwin->set_painted();
}
if (event.tfinger.fingerId != 0)
last_finger_id = event.tfinger.fingerId;
break;
}
case SDL_MOUSEBUTTONDOWN: {
SDL_SetWindowGrab(gwin->get_win()->get_screen_window(), SDL_TRUE);
if (dont_move_mode)
Expand Down Expand Up @@ -1585,6 +1599,8 @@ static void Handle_event(
case SDL_MOUSEMOTION: {
int mx ;
int my;
if ((Mouse::use_touch_input == true) && (event.motion.which != SDL_TOUCH_MOUSEID))
Mouse::use_touch_input = false;
gwin->get_win()->screen_to_game(event.motion.x, event.motion.y, gwin->get_fastmouse(), mx, my);

Mouse::mouse->move(mx, my);
Expand Down
19 changes: 19 additions & 0 deletions gumps/Gump_manager.cc
Expand Up @@ -452,12 +452,29 @@ bool Gump_manager::handle_modal_gump_event(
//int scale_factor = gwin->get_fastmouse() ? 1
// : gwin->get_win()->get_scale();
static bool rightclick;
static sint64 last_finger_id = 0;

int gx;
int gy;
Uint16 keysym_unicode = 0;

switch (event.type) {
// FIXME: it is a bug in SDL2 that real mouse devices have a fingerId. A real fingerId changes on each touch
// but the erroneous real mouse fingerId stays the same for both left and right clicks. But a left click produces
// two fingerId events with the first always having the value 0.
case SDL_FINGERDOWN: {
if ((Mouse::use_touch_input == false) && (event.tfinger.fingerId != last_finger_id) && (event.tfinger.fingerId != 0)) {
cout << "in if Finger_ID: " << last_finger_id << endl;
cout << "in if FingerID: " << event.tfinger.fingerId << endl;
Mouse::use_touch_input = true;
gwin->set_painted();
}
if (event.tfinger.fingerId != 0) {
last_finger_id = event.tfinger.fingerId;
cout << "Saved FingerID: " << last_finger_id << endl;
}
break;
}
case SDL_MOUSEBUTTONDOWN:
gwin->get_win()->screen_to_game(event.button.x, event.button.y, gwin->get_fastmouse(), gx, gy);

Expand Down Expand Up @@ -522,6 +539,8 @@ bool Gump_manager::handle_modal_gump_event(
break;
}
case SDL_MOUSEMOTION:
if ((Mouse::use_touch_input == true) && (event.motion.which != SDL_TOUCH_MOUSEID))
Mouse::use_touch_input = false;
gwin->get_win()->screen_to_game(event.motion.x, event.motion.y, gwin->get_fastmouse(), gx, gy);

Mouse::mouse->move(gx, gy);
Expand Down
14 changes: 14 additions & 0 deletions menulist.cc
Expand Up @@ -288,6 +288,7 @@ int MenuList::handle_events(Game_window *gwin, Mouse *mouse) {
gwin->show(true);
mouse->show();

static sint64 last_finger_id = 0;
bool exit_loop = false;
do {
Delay();
Expand All @@ -309,6 +310,8 @@ int MenuList::handle_events(Game_window *gwin, Mouse *mouse) {
int gx;
int gy;
if (event.type == SDL_MOUSEMOTION) {
if ((Mouse::use_touch_input == true) && (event.motion.which != SDL_TOUCH_MOUSEID))
Mouse::use_touch_input = false;
gwin->get_win()->screen_to_game(event.motion.x, event.motion.y, gwin->get_fastmouse(), gx, gy);
if (!mouse_updated) mouse->hide();
mouse_updated = true;
Expand Down Expand Up @@ -381,6 +384,17 @@ int MenuList::handle_events(Game_window *gwin, Mouse *mouse) {
}
} else if (event.type == SDL_QUIT) {
return -1;
// FIXME: it is a bug in SDL2 that real mouse devices have a fingerId. A real fingerId changes on each touch
// but the erroneous real mouse fingerId stays the same for both left and right clicks. But a left click produces
// two fingerId events with the first always having the value 0.
} else if (event.type == SDL_FINGERDOWN) {
if ((Mouse::use_touch_input == false) && (event.tfinger.fingerId != last_finger_id) && (event.tfinger.fingerId != 0)) {
Mouse::use_touch_input = true;
gwin->set_painted();
}
if (event.tfinger.fingerId != 0) {
last_finger_id = event.tfinger.fingerId;
}
}
}
if (mouse_updated) {
Expand Down
18 changes: 12 additions & 6 deletions mouse.cc
Expand Up @@ -22,6 +22,7 @@
# include <config.h>
#endif

#include <SDL.h>
#include "SDL_mouse.h"
#include "SDL_timer.h"
#include "mouse.h"
Expand All @@ -41,13 +42,18 @@
using std::max;
#endif

bool Mouse::use_touch_input = false;

static inline bool should_hide_frame(int frame) {
#ifdef __IPHONEOS__
return frame == 0 || (frame >=8 && frame <= 47);
#else
ignore_unused_variable_warning(frame);
return false;
#endif
// on touch input only we hide the cursor
if (Mouse::use_touch_input == true) {
SDL_SetHint(SDL_HINT_TOUCH_MOUSE_EVENTS, "1");
return frame == 0 || (frame >=8 && frame <= 47);
} else {
// FIXME: it is a bug in SDL2 that real mouse devices need this hint to work correctly on a touch device
SDL_SetHint(SDL_HINT_TOUCH_MOUSE_EVENTS, "0");
return false;
}
}

short Mouse::short_arrows[8] = {8, 9, 10, 11, 12, 13, 14, 15};
Expand Down
3 changes: 3 additions & 0 deletions mouse.h
Expand Up @@ -154,6 +154,9 @@ class Mouse {

// Sets hand or speed cursors
void set_speed_cursor();

// only use touch input?
static bool use_touch_input;
};

#endif

0 comments on commit bc98208

Please sign in to comment.