Implement controller rumble support in Gamepad (#1739)
* Add SDL rumble * Fix rumble * whitespace fixins real (#2) * whitespacing real.. please! * nativecffi rumble thing fix lol * Remove trailing whitespace. * Use SDL's argument names and order. * Standardize formatting. * Make `SDLGamepad` fully static again, for simplicity. Also, consistently use `find()` instead of array access, to avoid accidentally creating entries. Also also, consistently use guard clauses instead of indenting. * Make another guard clause. * Update CFFI function signature. * Use `clamp()` instead of `if` statements. * Include required header for `std::clamp()`. * Revert "Use `clamp()` instead of `if` statements." `std::clamp()` was not available until C++17, and we'd like to continue supporting older versions. This reverts commit715a270f79. * Revert "Include required header for `std::clamp()`." This reverts commitf47aebf640. * Tidy up. * Document `Gamepad.rumble()`'s arguments. * Don't limit rumble duration. SDL apparently supports the full Uint32 range, so there's no reason for Lime to restrict it. * Fix whitespace. * Add rumble support in HTML5 (experimental). --------- Co-authored-by: Cameron Taylor <cameron.taylor.ninja@gmail.com> Co-authored-by: player-03 <player3.14@gmail.com>
This commit is contained in:
@@ -12,6 +12,7 @@ namespace lime {
|
||||
static void AddMapping (const char* content);
|
||||
static const char* GetDeviceGUID (int id);
|
||||
static const char* GetDeviceName (int id);
|
||||
static void Rumble (int id, double lowFrequencyRumble, double highFrequencyRumble, int duration);
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -1765,6 +1765,20 @@ namespace lime {
|
||||
}
|
||||
|
||||
|
||||
void lime_gamepad_rumble (int id, double lowFrequencyRumble, double highFrequencyRumble, int duration) {
|
||||
|
||||
Gamepad::Rumble (id, lowFrequencyRumble, highFrequencyRumble, duration);
|
||||
|
||||
}
|
||||
|
||||
|
||||
HL_PRIM void HL_NAME(hl_gamepad_rumble) (int id, double lowFrequencyRumble, double highFrequencyRumble, int duration) {
|
||||
|
||||
Gamepad::Rumble (id, lowFrequencyRumble, highFrequencyRumble, duration);
|
||||
|
||||
}
|
||||
|
||||
|
||||
value lime_gzip_compress (value buffer, value bytes) {
|
||||
|
||||
#ifdef LIME_ZLIB
|
||||
@@ -4062,6 +4076,7 @@ namespace lime {
|
||||
DEFINE_PRIME2v (lime_gamepad_event_manager_register);
|
||||
DEFINE_PRIME1 (lime_gamepad_get_device_guid);
|
||||
DEFINE_PRIME1 (lime_gamepad_get_device_name);
|
||||
DEFINE_PRIME4v (lime_gamepad_rumble);
|
||||
DEFINE_PRIME2 (lime_gzip_compress);
|
||||
DEFINE_PRIME2 (lime_gzip_decompress);
|
||||
DEFINE_PRIME2v (lime_haptic_vibrate);
|
||||
@@ -4255,6 +4270,7 @@ namespace lime {
|
||||
DEFINE_HL_PRIM (_VOID, hl_gamepad_event_manager_register, _FUN(_VOID, _NO_ARG) _TGAMEPAD_EVENT);
|
||||
DEFINE_HL_PRIM (_BYTES, hl_gamepad_get_device_guid, _I32);
|
||||
DEFINE_HL_PRIM (_BYTES, hl_gamepad_get_device_name, _I32);
|
||||
DEFINE_HL_PRIM (_VOID, hl_gamepad_rumble, _I32 _I32 _F64 _F64);
|
||||
DEFINE_HL_PRIM (_TBYTES, hl_gzip_compress, _TBYTES _TBYTES);
|
||||
DEFINE_HL_PRIM (_TBYTES, hl_gzip_decompress, _TBYTES _TBYTES);
|
||||
DEFINE_HL_PRIM (_VOID, hl_haptic_vibrate, _I32 _I32);
|
||||
|
||||
@@ -4,48 +4,40 @@
|
||||
namespace lime {
|
||||
|
||||
|
||||
std::map<int, SDL_GameController*> gameControllers = std::map<int, SDL_GameController*> ();
|
||||
std::map<int, int> gameControllerIDs = std::map<int, int> ();
|
||||
std::map<int, SDL_GameController*> gameControllers;
|
||||
std::map<int, int> gameControllerIDs;
|
||||
|
||||
|
||||
bool SDLGamepad::Connect (int deviceID) {
|
||||
|
||||
if (SDL_IsGameController (deviceID)) {
|
||||
if (!SDL_IsGameController (deviceID))
|
||||
return false;
|
||||
|
||||
SDL_GameController *gameController = SDL_GameControllerOpen (deviceID);
|
||||
SDL_GameController *gameController = SDL_GameControllerOpen (deviceID);
|
||||
if (gameController == nullptr)
|
||||
return false;
|
||||
|
||||
if (gameController) {
|
||||
SDL_Joystick *joystick = SDL_GameControllerGetJoystick (gameController);
|
||||
int id = SDL_JoystickInstanceID (joystick);
|
||||
|
||||
SDL_Joystick *joystick = SDL_GameControllerGetJoystick (gameController);
|
||||
int id = SDL_JoystickInstanceID (joystick);
|
||||
gameControllers[id] = gameController;
|
||||
gameControllerIDs[deviceID] = id;
|
||||
|
||||
gameControllers[id] = gameController;
|
||||
gameControllerIDs[deviceID] = id;
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool SDLGamepad::Disconnect (int id) {
|
||||
|
||||
if (gameControllers.find (id) != gameControllers.end ()) {
|
||||
auto it = gameControllers.find (id);
|
||||
if (it == gameControllers.end ())
|
||||
return false;
|
||||
|
||||
SDL_GameController *gameController = gameControllers[id];
|
||||
SDL_GameControllerClose (gameController);
|
||||
gameControllers.erase (id);
|
||||
SDL_GameControllerClose (it->second);
|
||||
gameControllers.erase (id);
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
@@ -66,26 +58,51 @@ namespace lime {
|
||||
|
||||
const char* Gamepad::GetDeviceGUID (int id) {
|
||||
|
||||
SDL_Joystick* joystick = SDL_GameControllerGetJoystick (gameControllers[id]);
|
||||
auto it = gameControllers.find (id);
|
||||
if (it == gameControllers.end ())
|
||||
return nullptr;
|
||||
|
||||
if (joystick) {
|
||||
SDL_Joystick* joystick = SDL_GameControllerGetJoystick (it->second);
|
||||
if (joystick == nullptr)
|
||||
return nullptr;
|
||||
|
||||
char* guid = new char[64];
|
||||
SDL_JoystickGetGUIDString (SDL_JoystickGetGUID (joystick), guid, 64);
|
||||
return guid;
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
char* guid = new char[64];
|
||||
SDL_JoystickGetGUIDString (SDL_JoystickGetGUID (joystick), guid, 64);
|
||||
return guid;
|
||||
|
||||
}
|
||||
|
||||
|
||||
const char* Gamepad::GetDeviceName (int id) {
|
||||
|
||||
return SDL_GameControllerName (gameControllers[id]);
|
||||
auto it = gameControllers.find (id);
|
||||
if (it == gameControllers.end ())
|
||||
return nullptr;
|
||||
|
||||
return SDL_GameControllerName (it->second);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
void Gamepad::Rumble (int id, double lowFrequencyRumble, double highFrequencyRumble, int duration) {
|
||||
|
||||
auto it = gameControllers.find (id);
|
||||
if (it == gameControllers.end ())
|
||||
return;
|
||||
|
||||
if (highFrequencyRumble < 0.0f)
|
||||
highFrequencyRumble = 0.0f;
|
||||
else if (highFrequencyRumble > 1.0f)
|
||||
highFrequencyRumble = 1.0f;
|
||||
|
||||
if (lowFrequencyRumble < 0.0f)
|
||||
lowFrequencyRumble = 0.0f;
|
||||
else if (lowFrequencyRumble > 1.0f)
|
||||
lowFrequencyRumble = 1.0f;
|
||||
|
||||
SDL_GameControllerRumble (it->second, lowFrequencyRumble * 0xFFFF, highFrequencyRumble * 0xFFFF, duration);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user