Skip to content
This repository has been archived by the owner on May 13, 2024. It is now read-only.

Commit

Permalink
SDL: Implement touchscreen support
Browse files Browse the repository at this point in the history
  • Loading branch information
grorp committed Dec 16, 2023
1 parent 9b52d6f commit a06c2d6
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 0 deletions.
66 changes: 66 additions & 0 deletions source/Irrlicht/CIrrDeviceSDL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,11 @@ CIrrDeviceSDL::CIrrDeviceSDL(const SIrrlichtCreationParameters& param)
}
}

// Minetest has its own code to synthesize mouse events from touch events,
// so we prevent SDL from doing it.
SDL_SetHint(SDL_HINT_TOUCH_MOUSE_EVENTS, "0");
SDL_SetHint(SDL_HINT_MOUSE_TOUCH_EVENTS, "0");

// create keymap
createKeyMap();

Expand Down Expand Up @@ -740,6 +745,67 @@ bool CIrrDeviceSDL::run()

postEventFromUser(irrevent);
break;

case SDL_FINGERDOWN:
{
finger_ids.push_back(SDL_event.tfinger.fingerId);
size_t finger_idx = finger_ids.size() - 1;
size_t finger_count = finger_ids.size();

irrevent.EventType = irr::EET_TOUCH_INPUT_EVENT;
irrevent.TouchInput.Event = irr::ETIE_PRESSED_DOWN;
irrevent.TouchInput.ID = finger_idx;
irrevent.TouchInput.X = SDL_event.tfinger.x * Width;
irrevent.TouchInput.Y = SDL_event.tfinger.y * Height;
irrevent.TouchInput.touchedCount = finger_count;

postEventFromUser(irrevent);
}
break;

case SDL_FINGERMOTION:
{
auto iter = std::find(finger_ids.begin(), finger_ids.end(),
SDL_event.tfinger.fingerId);
size_t finger_idx = std::distance(finger_ids.begin(), iter);
size_t finger_count = finger_ids.size();
if (finger_idx == finger_count) {
// This shouldn't ever happen. Anyway, let's allocate a new ID.
finger_ids.push_back(SDL_event.tfinger.fingerId);
}

irrevent.EventType = irr::EET_TOUCH_INPUT_EVENT;
irrevent.TouchInput.Event = irr::ETIE_MOVED;
irrevent.TouchInput.ID = finger_idx;
irrevent.TouchInput.X = SDL_event.tfinger.x * Width;
irrevent.TouchInput.Y = SDL_event.tfinger.y * Height;
irrevent.TouchInput.touchedCount = finger_count;

postEventFromUser(irrevent);
}
break;

case SDL_FINGERUP:
{
auto iter = std::find(finger_ids.begin(), finger_ids.end(),
SDL_event.tfinger.fingerId);
size_t finger_idx = std::distance(finger_ids.begin(), iter);
// To match Android behavior, still count the pointer that was just released.
size_t finger_count = finger_ids.size();
if (finger_idx != finger_count) {
finger_ids.erase(finger_ids.begin() + finger_idx);
}

irrevent.EventType = irr::EET_TOUCH_INPUT_EVENT;
irrevent.TouchInput.Event = irr::ETIE_LEFT_UP;
irrevent.TouchInput.ID = finger_idx;
irrevent.TouchInput.X = SDL_event.tfinger.x * Width;
irrevent.TouchInput.Y = SDL_event.tfinger.y * Height;
irrevent.TouchInput.touchedCount = finger_count;

postEventFromUser(irrevent);
}
break;

default:
break;
Expand Down
5 changes: 5 additions & 0 deletions source/Irrlicht/CIrrDeviceSDL.h
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,11 @@ namespace irr

core::array<SKeyMap> KeyMap;
SDL_SysWMinfo Info;

// Minetest expects touch pointer IDs to be consecutive, as they are on
// Android. SDL doesn't guarantee this, so we emulate it.
// This is also used to implement the "touchedCount" field.
std::vector<SDL_FingerID> finger_ids;
};

} // end namespace irr
Expand Down

0 comments on commit a06c2d6

Please sign in to comment.