Implement joystick rumble. #522

Call `rtcEnableRumble()` in the core if the rtc is enabled during ROM
loading.

On `systemCartridgeRumble(bool)` events from the core, set the state in
`wxSDLJoy` accordingly, to either rumbling or not rumbling based on the
boolean parameter.

On the `50ms` joystick poll events, use `SDL_JoystickRumble()` to enable
rumble on both the low and high frequencies at maximum for the poll time
of `50ms`, to be set or reset again on the next poll event.

Tested in Drill Dozer, rumbling is being activated. Will need testing
from users as well to see if this is implemented correctly.

Fix #522.

Signed-off-by: Rafael Kitover <rkitover@gmail.com>
This commit is contained in:
Rafael Kitover 2019-10-06 11:06:08 +00:00
parent 5b809e3ad1
commit 4bc9bb84b4
No known key found for this signature in database
GPG Key ID: 08AB596679D86240
5 changed files with 29 additions and 3 deletions

View File

@ -226,7 +226,11 @@ void GameArea::LoadGame(const wxString& name)
if (cfg->HasGroup(id)) {
cfg->SetPath(id);
rtcEnable(cfg->Read(wxT("rtcEnabled"), rtcEnabled));
bool enable_rtc = cfg->Read(wxT("rtcEnabled"), rtcEnabled);
rtcEnable(enable_rtc);
rtcEnableRumble(enable_rtc);
int fsz = cfg->Read(wxT("flashSize"), (long)0);
if (fsz != 0x10000 && fsz != 0x20000)
@ -247,6 +251,7 @@ void GameArea::LoadGame(const wxString& name)
cfg->SetPath(wxT("/"));
} else {
rtcEnable(rtcEnabled);
rtcEnableRumble(rtcEnabled);
flashSetSize(0x10000 << winFlashSize);
if (cpuSaveType < 0 || cpuSaveType > 5)
@ -269,6 +274,7 @@ void GameArea::LoadGame(const wxString& name)
// this **MUST** be called **AFTER** setting sample rate because the core calls soundInit()
soundSetThrottle(throttle);
soundFiltering = (float)gopts.gba_sound_filter / 100.0f;
CPUInit(gopts.gba_bios.mb_fn_str(), useBiosFileGBA);
if (useBiosFileGBA && !useBios) {

View File

@ -458,7 +458,10 @@ uint32_t systemGetClock()
return wxGetApp().timer.Time();
}
void systemCartridgeRumble(bool) {}
void systemCartridgeRumble(bool b)
{
wxGetApp().frame->SetJoystickRumble(b);
}
static uint8_t sensorDarkness = 0xE8; // total darkness (including daylight on rainy days)

View File

@ -121,7 +121,7 @@ void wxSDLJoy::Add(int joy)
joystate[joy].dev = SDL_JoystickOpen(joy);
if (nosticks && joystate[joy].dev) {
Start(50);
Start(poll_time_ms);
nosticks = false;
}
}
@ -238,6 +238,16 @@ void wxSDLJoy::Notify()
joystate[i].curval[nax + nhat + j] = val;
}
}
}
// do rumble only on device 0
SDL_Joystick* dev = joystate[0].dev;
if (dev) {
if (rumbling)
SDL_JoystickRumble(dev, 0xFFFF, 0xFFFF, poll_time_ms);
else
SDL_JoystickRumble(dev, 0, 0, 0);
}
}

View File

@ -56,6 +56,9 @@ public:
// 0 is returned if joy is invalid
int GetNumButtons(int joy);
// true = currently rumbling, false = turn off rumbling
void SetRumble(bool b) { rumbling = b; }
virtual ~wxSDLJoy();
protected:
@ -64,7 +67,9 @@ protected:
wxSDLJoyState* joystate;
wxEvtHandler* evthandler;
bool nosticks;
bool rumbling = false;
void Notify();
uint16_t poll_time_ms = 50;
};
enum {

View File

@ -326,6 +326,8 @@ public:
virtual bool DialogOpened() { return dialog_opened != 0; }
virtual void SetJoystickRumble(bool b) { joy.SetRumble(b); }
// required for building from xrc
DECLARE_DYNAMIC_CLASS(MainFrame);
// required for event handling