mirror of
https://github.com/isledecomp/isle-portable.git
synced 2025-09-24 04:26:55 -04:00
Add new touch control scheme ("gamepad") (#587)
* Add new touch control scheme * Add export * Fix enum naming
This commit is contained in:
parent
7c91a14875
commit
42bac60ec5
@ -172,6 +172,7 @@ IsleApp::IsleApp()
|
|||||||
m_maxAllowedExtras = m_islandQuality <= 1 ? 10 : 20;
|
m_maxAllowedExtras = m_islandQuality <= 1 ? 10 : 20;
|
||||||
m_transitionType = MxTransitionManager::e_mosaic;
|
m_transitionType = MxTransitionManager::e_mosaic;
|
||||||
m_cursorSensitivity = 4;
|
m_cursorSensitivity = 4;
|
||||||
|
m_touchScheme = LegoInputManager::e_gamepad;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FUNCTION: ISLE 0x4011a0
|
// FUNCTION: ISLE 0x4011a0
|
||||||
@ -650,7 +651,12 @@ SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event)
|
|||||||
float y = SDL_clamp(event->tfinger.y, 0, 1) * g_targetHeight;
|
float y = SDL_clamp(event->tfinger.y, 0, 1) * g_targetHeight;
|
||||||
|
|
||||||
if (InputManager()) {
|
if (InputManager()) {
|
||||||
InputManager()->QueueEvent(c_notificationMouseMove, LegoEventNotificationParam::c_lButtonState, x, y, 0);
|
MxU8 modifier = LegoEventNotificationParam::c_lButtonState;
|
||||||
|
if (InputManager()->HandleTouchEvent(event, g_isle->GetTouchScheme())) {
|
||||||
|
modifier |= LegoEventNotificationParam::c_motionHandled;
|
||||||
|
}
|
||||||
|
|
||||||
|
InputManager()->QueueEvent(c_notificationMouseMove, modifier, x, y, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_lastMouseX = x;
|
g_lastMouseX = x;
|
||||||
@ -691,6 +697,7 @@ SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event)
|
|||||||
float y = SDL_clamp(event->tfinger.y, 0, 1) * g_targetHeight;
|
float y = SDL_clamp(event->tfinger.y, 0, 1) * g_targetHeight;
|
||||||
|
|
||||||
if (InputManager()) {
|
if (InputManager()) {
|
||||||
|
InputManager()->HandleTouchEvent(event, g_isle->GetTouchScheme());
|
||||||
InputManager()->QueueEvent(c_notificationButtonDown, LegoEventNotificationParam::c_lButtonState, x, y, 0);
|
InputManager()->QueueEvent(c_notificationButtonDown, LegoEventNotificationParam::c_lButtonState, x, y, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -738,6 +745,7 @@ SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event)
|
|||||||
float y = SDL_clamp(event->tfinger.y, 0, 1) * g_targetHeight;
|
float y = SDL_clamp(event->tfinger.y, 0, 1) * g_targetHeight;
|
||||||
|
|
||||||
if (InputManager()) {
|
if (InputManager()) {
|
||||||
|
InputManager()->HandleTouchEvent(event, g_isle->GetTouchScheme());
|
||||||
InputManager()->QueueEvent(c_notificationButtonUp, 0, x, y, 0);
|
InputManager()->QueueEvent(c_notificationButtonUp, 0, x, y, 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1033,6 +1041,7 @@ bool IsleApp::LoadConfig()
|
|||||||
iniparser_set(dict, "isle:Max LOD", buf);
|
iniparser_set(dict, "isle:Max LOD", buf);
|
||||||
iniparser_set(dict, "isle:Max Allowed Extras", SDL_itoa(m_maxAllowedExtras, buf, 10));
|
iniparser_set(dict, "isle:Max Allowed Extras", SDL_itoa(m_maxAllowedExtras, buf, 10));
|
||||||
iniparser_set(dict, "isle:Transition Type", SDL_itoa(m_transitionType, buf, 10));
|
iniparser_set(dict, "isle:Transition Type", SDL_itoa(m_transitionType, buf, 10));
|
||||||
|
iniparser_set(dict, "isle:Touch Scheme", SDL_itoa(m_touchScheme, buf, 10));
|
||||||
|
|
||||||
#ifdef EXTENSIONS
|
#ifdef EXTENSIONS
|
||||||
iniparser_set(dict, "extensions", NULL);
|
iniparser_set(dict, "extensions", NULL);
|
||||||
@ -1103,6 +1112,7 @@ bool IsleApp::LoadConfig()
|
|||||||
m_maxAllowedExtras = iniparser_getint(dict, "isle:Max Allowed Extras", m_maxAllowedExtras);
|
m_maxAllowedExtras = iniparser_getint(dict, "isle:Max Allowed Extras", m_maxAllowedExtras);
|
||||||
m_transitionType =
|
m_transitionType =
|
||||||
(MxTransitionManager::TransitionType) iniparser_getint(dict, "isle:Transition Type", m_transitionType);
|
(MxTransitionManager::TransitionType) iniparser_getint(dict, "isle:Transition Type", m_transitionType);
|
||||||
|
m_touchScheme = (LegoInputManager::TouchScheme) iniparser_getint(dict, "isle:Touch Scheme", m_touchScheme);
|
||||||
|
|
||||||
const char* deviceId = iniparser_getstring(dict, "isle:3D Device ID", NULL);
|
const char* deviceId = iniparser_getstring(dict, "isle:3D Device ID", NULL);
|
||||||
if (deviceId != NULL) {
|
if (deviceId != NULL) {
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "cursor.h"
|
#include "cursor.h"
|
||||||
#include "lego1_export.h"
|
#include "lego1_export.h"
|
||||||
|
#include "legoinputmanager.h"
|
||||||
#include "legoutils.h"
|
#include "legoutils.h"
|
||||||
#include "mxtransitionmanager.h"
|
#include "mxtransitionmanager.h"
|
||||||
#include "mxtypes.h"
|
#include "mxtypes.h"
|
||||||
@ -53,6 +54,7 @@ public:
|
|||||||
MxS32 GetDrawCursor() { return m_drawCursor; }
|
MxS32 GetDrawCursor() { return m_drawCursor; }
|
||||||
MxS32 GetGameStarted() { return m_gameStarted; }
|
MxS32 GetGameStarted() { return m_gameStarted; }
|
||||||
MxFloat GetCursorSensitivity() { return m_cursorSensitivity; }
|
MxFloat GetCursorSensitivity() { return m_cursorSensitivity; }
|
||||||
|
LegoInputManager::TouchScheme GetTouchScheme() { return m_touchScheme; }
|
||||||
|
|
||||||
void SetWindowActive(MxS32 p_windowActive) { m_windowActive = p_windowActive; }
|
void SetWindowActive(MxS32 p_windowActive) { m_windowActive = p_windowActive; }
|
||||||
void SetGameStarted(MxS32 p_gameStarted) { m_gameStarted = p_gameStarted; }
|
void SetGameStarted(MxS32 p_gameStarted) { m_gameStarted = p_gameStarted; }
|
||||||
@ -102,6 +104,7 @@ private:
|
|||||||
MxFloat m_maxLod;
|
MxFloat m_maxLod;
|
||||||
MxU32 m_maxAllowedExtras;
|
MxU32 m_maxAllowedExtras;
|
||||||
MxTransitionManager::TransitionType m_transitionType;
|
MxTransitionManager::TransitionType m_transitionType;
|
||||||
|
LegoInputManager::TouchScheme m_touchScheme;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern IsleApp* g_isle;
|
extern IsleApp* g_isle;
|
||||||
|
@ -18,6 +18,7 @@ public:
|
|||||||
c_rButtonState = 2,
|
c_rButtonState = 2,
|
||||||
c_modKey1 = 4,
|
c_modKey1 = 4,
|
||||||
c_modKey2 = 8,
|
c_modKey2 = 8,
|
||||||
|
c_motionHandled = 16,
|
||||||
};
|
};
|
||||||
|
|
||||||
// FUNCTION: LEGO1 0x10028690
|
// FUNCTION: LEGO1 0x10028690
|
||||||
|
@ -18,6 +18,8 @@
|
|||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
|
||||||
class LegoCameraController;
|
class LegoCameraController;
|
||||||
class LegoControlManager;
|
class LegoControlManager;
|
||||||
class LegoWorld;
|
class LegoWorld;
|
||||||
@ -89,6 +91,12 @@ public:
|
|||||||
c_upOrDown = c_up | c_down
|
c_upOrDown = c_up | c_down
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum TouchScheme {
|
||||||
|
e_mouse = 0,
|
||||||
|
e_arrowKeys,
|
||||||
|
e_gamepad,
|
||||||
|
};
|
||||||
|
|
||||||
LegoInputManager();
|
LegoInputManager();
|
||||||
~LegoInputManager() override;
|
~LegoInputManager() override;
|
||||||
|
|
||||||
@ -144,6 +152,7 @@ public:
|
|||||||
void GetKeyboardState();
|
void GetKeyboardState();
|
||||||
MxResult GetNavigationKeyStates(MxU32& p_keyFlags);
|
MxResult GetNavigationKeyStates(MxU32& p_keyFlags);
|
||||||
MxResult GetNavigationTouchStates(MxU32& p_keyFlags);
|
MxResult GetNavigationTouchStates(MxU32& p_keyFlags);
|
||||||
|
LEGO1_EXPORT MxBool HandleTouchEvent(SDL_Event* p_event, TouchScheme p_touchScheme);
|
||||||
|
|
||||||
// SYNTHETIC: LEGO1 0x1005b8d0
|
// SYNTHETIC: LEGO1 0x1005b8d0
|
||||||
// LegoInputManager::`scalar deleting destructor'
|
// LegoInputManager::`scalar deleting destructor'
|
||||||
@ -171,6 +180,10 @@ private:
|
|||||||
MxBool m_useJoystick; // 0x334
|
MxBool m_useJoystick; // 0x334
|
||||||
MxBool m_unk0x335; // 0x335
|
MxBool m_unk0x335; // 0x335
|
||||||
MxBool m_unk0x336; // 0x336
|
MxBool m_unk0x336; // 0x336
|
||||||
|
|
||||||
|
std::map<SDL_FingerID, SDL_FPoint> m_touchOrigins;
|
||||||
|
std::map<SDL_FingerID, MxU32> m_touchFlags;
|
||||||
|
std::map<SDL_FingerID, Uint64> m_touchLastMotion;
|
||||||
};
|
};
|
||||||
|
|
||||||
// TEMPLATE: LEGO1 0x10028850
|
// TEMPLATE: LEGO1 0x10028850
|
||||||
|
@ -41,6 +41,10 @@ MxResult LegoCameraController::Create()
|
|||||||
// FUNCTION: BETA10 0x10067852
|
// FUNCTION: BETA10 0x10067852
|
||||||
MxLong LegoCameraController::Notify(MxParam& p_param)
|
MxLong LegoCameraController::Notify(MxParam& p_param)
|
||||||
{
|
{
|
||||||
|
if (((LegoEventNotificationParam&) p_param).GetModifier() & LegoEventNotificationParam::c_motionHandled) {
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
switch (((MxNotificationParam&) p_param).GetNotification()) {
|
switch (((MxNotificationParam&) p_param).GetNotification()) {
|
||||||
case c_notificationDragEnd: {
|
case c_notificationDragEnd: {
|
||||||
if (((((LegoEventNotificationParam&) p_param).GetModifier()) & LegoEventNotificationParam::c_lButtonState) ==
|
if (((((LegoEventNotificationParam&) p_param).GetModifier()) & LegoEventNotificationParam::c_lButtonState) ==
|
||||||
|
@ -528,42 +528,91 @@ void LegoInputManager::EnableInputProcessing()
|
|||||||
|
|
||||||
MxResult LegoInputManager::GetNavigationTouchStates(MxU32& p_keyStates)
|
MxResult LegoInputManager::GetNavigationTouchStates(MxU32& p_keyStates)
|
||||||
{
|
{
|
||||||
int count;
|
for (auto& [fingerID, touchFlags] : m_touchFlags) {
|
||||||
SDL_TouchID* touchDevices = SDL_GetTouchDevices(&count);
|
p_keyStates |= touchFlags;
|
||||||
|
|
||||||
if (touchDevices) {
|
// We need to clear these as they are not meant to be persistent in e_gamepad mode.
|
||||||
auto applyFingerNavigation = [&p_keyStates](SDL_TouchID p_touchId) {
|
if (m_touchOrigins.count(fingerID) && SDL_GetTicks() - m_touchLastMotion[fingerID] > 5) {
|
||||||
int count;
|
touchFlags &= ~c_left;
|
||||||
SDL_Finger** fingers = SDL_GetTouchFingers(p_touchId, &count);
|
touchFlags &= ~c_right;
|
||||||
|
|
||||||
if (fingers) {
|
|
||||||
for (int i = 0; i < count; i++) {
|
|
||||||
if (fingers[i]->y > 3.0 / 4.0) {
|
|
||||||
if (fingers[i]->x < 1.0 / 3.0) {
|
|
||||||
p_keyStates |= c_left;
|
|
||||||
}
|
}
|
||||||
else if (fingers[i]->x > 2.0 / 3.0) {
|
|
||||||
p_keyStates |= c_right;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
p_keyStates |= c_down;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
p_keyStates |= c_up;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SDL_free(fingers);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
for (int i = 0; i < count; i++) {
|
|
||||||
applyFingerNavigation(touchDevices[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
SDL_free(touchDevices);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MxBool LegoInputManager::HandleTouchEvent(SDL_Event* p_event, TouchScheme p_touchScheme)
|
||||||
|
{
|
||||||
|
const SDL_TouchFingerEvent& event = p_event->tfinger;
|
||||||
|
|
||||||
|
switch (p_touchScheme) {
|
||||||
|
case e_mouse:
|
||||||
|
// Handled in LegoCameraController
|
||||||
|
return FALSE;
|
||||||
|
case e_arrowKeys:
|
||||||
|
switch (p_event->type) {
|
||||||
|
case SDL_EVENT_FINGER_UP:
|
||||||
|
m_touchFlags.erase(event.fingerID);
|
||||||
|
break;
|
||||||
|
case SDL_EVENT_FINGER_DOWN:
|
||||||
|
case SDL_EVENT_FINGER_MOTION:
|
||||||
|
m_touchFlags[event.fingerID] = 0;
|
||||||
|
|
||||||
|
if (event.y > 3.0 / 4.0) {
|
||||||
|
if (event.x < 1.0 / 3.0) {
|
||||||
|
m_touchFlags[event.fingerID] |= c_left;
|
||||||
|
}
|
||||||
|
else if (event.x > 2.0 / 3.0) {
|
||||||
|
m_touchFlags[event.fingerID] |= c_right;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
m_touchFlags[event.fingerID] |= c_down;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
m_touchFlags[event.fingerID] |= c_up;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case e_gamepad:
|
||||||
|
switch (p_event->type) {
|
||||||
|
case SDL_EVENT_FINGER_DOWN:
|
||||||
|
m_touchOrigins[event.fingerID] = {event.x, event.y};
|
||||||
|
break;
|
||||||
|
case SDL_EVENT_FINGER_UP:
|
||||||
|
m_touchOrigins.erase(event.fingerID);
|
||||||
|
m_touchFlags.erase(event.fingerID);
|
||||||
|
break;
|
||||||
|
case SDL_EVENT_FINGER_MOTION:
|
||||||
|
if (m_touchOrigins.count(event.fingerID)) {
|
||||||
|
m_touchFlags[event.fingerID] = 0;
|
||||||
|
m_touchLastMotion[event.fingerID] = SDL_GetTicks();
|
||||||
|
|
||||||
|
const float deltaY = event.y - m_touchOrigins[event.fingerID].y;
|
||||||
|
const float activationThreshold = 0.05f;
|
||||||
|
|
||||||
|
if (SDL_fabsf(deltaY) > activationThreshold) {
|
||||||
|
if (deltaY > 0) {
|
||||||
|
m_touchFlags[event.fingerID] |= c_down;
|
||||||
|
}
|
||||||
|
else if (deltaY < 0) {
|
||||||
|
m_touchFlags[event.fingerID] |= c_up;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const float deltaX = event.dx;
|
||||||
|
if (deltaX > 0) {
|
||||||
|
m_touchFlags[event.fingerID] |= c_right;
|
||||||
|
}
|
||||||
|
else if (deltaX < 0) {
|
||||||
|
m_touchFlags[event.fingerID] |= c_left;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user