mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2026-09-10 12:27:01 -05:00
Consolidate duplicated code.
This commit is contained in:
@@ -273,12 +273,56 @@ SDL_JoystickID Gamepad::GetSDLInstanceID() const
|
||||
return SDL_GetJoystickID(m_joystick);
|
||||
}
|
||||
|
||||
class SpringEffect final : public Core::SpringEffect
|
||||
class ScopedHapticEffect
|
||||
{
|
||||
public:
|
||||
explicit SpringEffect(SDL_Haptic* haptic) : m_haptic{haptic} {}
|
||||
explicit ScopedHapticEffect(SDL_Haptic* haptic) : m_haptic{haptic} {}
|
||||
|
||||
~SpringEffect() override { SetForce(0.0, 0.0); }
|
||||
protected:
|
||||
~ScopedHapticEffect() { UpdateEffect(nullptr); }
|
||||
|
||||
void UpdateEffect(const SDL_HapticEffect* effect)
|
||||
{
|
||||
if (effect == nullptr)
|
||||
{
|
||||
if (m_effect_id != -1)
|
||||
{
|
||||
SDL_DestroyHapticEffect(m_haptic, std::exchange(m_effect_id, -1));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_effect_id == -1)
|
||||
{
|
||||
// Create and start a new effect.
|
||||
m_effect_id = SDL_CreateHapticEffect(m_haptic, effect);
|
||||
if (m_effect_id == -1)
|
||||
{
|
||||
ERROR_LOG_FMT(CONTROLLERINTERFACE, "SDL_CreateHapticEffect: {}", SDL_GetError());
|
||||
return;
|
||||
}
|
||||
|
||||
if (!SDL_RunHapticEffect(m_haptic, m_effect_id, 1))
|
||||
ERROR_LOG_FMT(CONTROLLERINTERFACE, "SDL_RunHapticEffect: {}", SDL_GetError());
|
||||
}
|
||||
else
|
||||
{
|
||||
// Update an already running effect.
|
||||
if (!SDL_UpdateHapticEffect(m_haptic, m_effect_id, effect))
|
||||
ERROR_LOG_FMT(CONTROLLERINTERFACE, "SDL_UpdateHapticEffect: {}", SDL_GetError());
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
SDL_Haptic* const m_haptic;
|
||||
int m_effect_id = -1;
|
||||
};
|
||||
|
||||
class SpringEffect final : ScopedHapticEffect, public Core::SpringEffect
|
||||
{
|
||||
public:
|
||||
using ScopedHapticEffect::ScopedHapticEffect;
|
||||
|
||||
void SetForce(double gain, double center_position) override
|
||||
{
|
||||
@@ -286,11 +330,7 @@ public:
|
||||
|
||||
if (gain == 0.0)
|
||||
{
|
||||
if (m_effect_id != -1)
|
||||
{
|
||||
SDL_DestroyHapticEffect(m_haptic, std::exchange(m_effect_id, -1));
|
||||
}
|
||||
|
||||
UpdateEffect(nullptr);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -319,38 +359,14 @@ public:
|
||||
|
||||
condition.center[0] = ControllerEmu::MapFloat<s16>(center_position, 0);
|
||||
|
||||
if (m_effect_id == -1)
|
||||
{
|
||||
// Create and start a new effect.
|
||||
m_effect_id = SDL_CreateHapticEffect(m_haptic, &effect);
|
||||
if (m_effect_id == -1)
|
||||
{
|
||||
ERROR_LOG_FMT(CONTROLLERINTERFACE, "SDL_CreateHapticEffect: {}", SDL_GetError());
|
||||
return;
|
||||
}
|
||||
|
||||
if (!SDL_RunHapticEffect(m_haptic, m_effect_id, 1))
|
||||
ERROR_LOG_FMT(CONTROLLERINTERFACE, "SDL_RunHapticEffect: {}", SDL_GetError());
|
||||
}
|
||||
else
|
||||
{
|
||||
// Update an already running effect.
|
||||
if (!SDL_UpdateHapticEffect(m_haptic, m_effect_id, &effect))
|
||||
ERROR_LOG_FMT(CONTROLLERINTERFACE, "SDL_UpdateHapticEffect: {}", SDL_GetError());
|
||||
}
|
||||
UpdateEffect(&effect);
|
||||
}
|
||||
|
||||
private:
|
||||
SDL_Haptic* const m_haptic;
|
||||
int m_effect_id = -1;
|
||||
};
|
||||
|
||||
class FrictionEffect final : public Core::FrictionEffect
|
||||
class FrictionEffect final : ScopedHapticEffect, public Core::FrictionEffect
|
||||
{
|
||||
public:
|
||||
explicit FrictionEffect(SDL_Haptic* haptic) : m_haptic{haptic} {}
|
||||
|
||||
~FrictionEffect() override { SetForce(0.0); }
|
||||
using ScopedHapticEffect::ScopedHapticEffect;
|
||||
|
||||
void SetForce(double gain) override
|
||||
{
|
||||
@@ -358,11 +374,7 @@ public:
|
||||
|
||||
if (gain == 0.0)
|
||||
{
|
||||
if (m_effect_id != -1)
|
||||
{
|
||||
SDL_DestroyHapticEffect(m_haptic, std::exchange(m_effect_id, -1));
|
||||
}
|
||||
|
||||
UpdateEffect(nullptr);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -389,30 +401,8 @@ public:
|
||||
condition.right_coeff[0] = coeff;
|
||||
condition.left_coeff[0] = coeff;
|
||||
|
||||
if (m_effect_id == -1)
|
||||
{
|
||||
// Create and start a new effect.
|
||||
m_effect_id = SDL_CreateHapticEffect(m_haptic, &effect);
|
||||
if (m_effect_id == -1)
|
||||
{
|
||||
ERROR_LOG_FMT(CONTROLLERINTERFACE, "SDL_CreateHapticEffect: {}", SDL_GetError());
|
||||
return;
|
||||
}
|
||||
|
||||
if (!SDL_RunHapticEffect(m_haptic, m_effect_id, 1))
|
||||
ERROR_LOG_FMT(CONTROLLERINTERFACE, "SDL_RunHapticEffect: {}", SDL_GetError());
|
||||
}
|
||||
else
|
||||
{
|
||||
// Update an already running effect.
|
||||
if (!SDL_UpdateHapticEffect(m_haptic, m_effect_id, &effect))
|
||||
ERROR_LOG_FMT(CONTROLLERINTERFACE, "SDL_UpdateHapticEffect: {}", SDL_GetError());
|
||||
}
|
||||
UpdateEffect(&effect);
|
||||
}
|
||||
|
||||
private:
|
||||
SDL_Haptic* const m_haptic;
|
||||
int m_effect_id = -1;
|
||||
};
|
||||
|
||||
std::unique_ptr<Core::SpringEffect> Gamepad::CreateSpringEffect()
|
||||
|
||||
@@ -729,18 +729,17 @@ bool evdevDevice::IsValid() const
|
||||
return true;
|
||||
}
|
||||
|
||||
class SpringEffect final : public Core::SpringEffect
|
||||
class ScopedForceFeedbackEffect
|
||||
{
|
||||
public:
|
||||
explicit SpringEffect(int ffb_fd) : m_ffb_fd{ffb_fd} {}
|
||||
explicit ScopedForceFeedbackEffect(int ffb_fd) : m_ffb_fd{ffb_fd} {}
|
||||
|
||||
~SpringEffect() override { SetForce(0.0, 0.0); }
|
||||
protected:
|
||||
~ScopedForceFeedbackEffect() { UpdateEffect(nullptr); }
|
||||
|
||||
void SetForce(double gain, double center_position) override
|
||||
void UpdateEffect(ff_effect* effect)
|
||||
{
|
||||
INFO_LOG_FMT(CONTROLLERINTERFACE, "SpringEffect: {:.2} {:.2}", gain, center_position);
|
||||
|
||||
if (gain == 0.0)
|
||||
if (effect == nullptr)
|
||||
{
|
||||
if (m_effect_id != -1)
|
||||
{
|
||||
@@ -756,10 +755,50 @@ public:
|
||||
return;
|
||||
}
|
||||
|
||||
ff_effect effect{
|
||||
.type = FF_SPRING,
|
||||
.id = m_effect_id,
|
||||
};
|
||||
effect->id = m_effect_id;
|
||||
|
||||
if (ioctl(m_ffb_fd, EVIOCSFF, effect) < 0)
|
||||
{
|
||||
ERROR_LOG_FMT(COMMON, "EVIOCSFF: {}", Common::LastStrerrorString());
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_effect_id == -1)
|
||||
{
|
||||
m_effect_id = effect->id;
|
||||
|
||||
const input_event play{
|
||||
.type = EV_FF,
|
||||
.code = u16(m_effect_id),
|
||||
.value = std::numeric_limits<s32>::max(),
|
||||
};
|
||||
|
||||
if (write(m_ffb_fd, &play, sizeof(play)) < 0)
|
||||
ERROR_LOG_FMT(COMMON, "EV_FF: {}", Common::LastStrerrorString());
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
const int m_ffb_fd;
|
||||
s16 m_effect_id = -1;
|
||||
};
|
||||
|
||||
class SpringEffect final : ScopedForceFeedbackEffect, public Core::SpringEffect
|
||||
{
|
||||
public:
|
||||
using ScopedForceFeedbackEffect::ScopedForceFeedbackEffect;
|
||||
|
||||
void SetForce(double gain, double center_position) override
|
||||
{
|
||||
INFO_LOG_FMT(CONTROLLERINTERFACE, "SpringEffect: {:.2} {:.2}", gain, center_position);
|
||||
|
||||
if (gain == 0.0)
|
||||
{
|
||||
UpdateEffect(nullptr);
|
||||
return;
|
||||
}
|
||||
|
||||
ff_effect effect{.type = FF_SPRING};
|
||||
|
||||
// <linux/input.h>
|
||||
// "Values above 32767 ms (0x7fff) should not be used and have unspecified results."
|
||||
@@ -778,38 +817,14 @@ public:
|
||||
|
||||
condition[0].center = ControllerEmu::MapFloat<s16>(center_position, 0);
|
||||
|
||||
if (ioctl(m_ffb_fd, EVIOCSFF, &effect) < 0)
|
||||
{
|
||||
ERROR_LOG_FMT(COMMON, "EVIOCSFF FF_SPRING: {}", Common::LastStrerrorString());
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_effect_id == -1)
|
||||
{
|
||||
m_effect_id = effect.id;
|
||||
|
||||
const input_event play{
|
||||
.type = EV_FF,
|
||||
.code = u16(m_effect_id),
|
||||
.value = std::numeric_limits<s32>::max(),
|
||||
};
|
||||
|
||||
if (write(m_ffb_fd, &play, sizeof(play)) < 0)
|
||||
ERROR_LOG_FMT(COMMON, "EV_FF: {}", Common::LastStrerrorString());
|
||||
}
|
||||
UpdateEffect(&effect);
|
||||
}
|
||||
|
||||
private:
|
||||
const int m_ffb_fd;
|
||||
s16 m_effect_id = -1;
|
||||
};
|
||||
|
||||
class FrictionEffect final : public Core::FrictionEffect
|
||||
class FrictionEffect final : ScopedForceFeedbackEffect, public Core::FrictionEffect
|
||||
{
|
||||
public:
|
||||
explicit FrictionEffect(int ffb_fd) : m_ffb_fd{ffb_fd} {}
|
||||
|
||||
~FrictionEffect() override { SetForce(0.0); }
|
||||
using ScopedForceFeedbackEffect::ScopedForceFeedbackEffect;
|
||||
|
||||
void SetForce(double gain) override
|
||||
{
|
||||
@@ -817,24 +832,11 @@ public:
|
||||
|
||||
if (gain == 0.0)
|
||||
{
|
||||
if (m_effect_id != -1)
|
||||
{
|
||||
if (ioctl(m_ffb_fd, EVIOCRMFF, m_effect_id) < 0)
|
||||
ERROR_LOG_FMT(COMMON, "EVIOCRMFF: {}", Common::LastStrerrorString());
|
||||
|
||||
// TODO: Is it correct to not remove this effect on destruction.
|
||||
// Is it enough to close the parent fd ?
|
||||
|
||||
m_effect_id = -1;
|
||||
}
|
||||
|
||||
UpdateEffect(nullptr);
|
||||
return;
|
||||
}
|
||||
|
||||
ff_effect effect{
|
||||
.type = FF_FRICTION,
|
||||
.id = m_effect_id,
|
||||
};
|
||||
ff_effect effect{.type = FF_FRICTION};
|
||||
|
||||
// <linux/input.h>
|
||||
// "Values above 32767 ms (0x7fff) should not be used and have unspecified results."
|
||||
@@ -851,30 +853,8 @@ public:
|
||||
condition[0].right_coeff = coeff;
|
||||
condition[0].left_coeff = coeff;
|
||||
|
||||
if (ioctl(m_ffb_fd, EVIOCSFF, &effect) < 0)
|
||||
{
|
||||
ERROR_LOG_FMT(COMMON, "EVIOCSFF FF_SPRING: {}", Common::LastStrerrorString());
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_effect_id == -1)
|
||||
{
|
||||
m_effect_id = effect.id;
|
||||
|
||||
const input_event play{
|
||||
.type = EV_FF,
|
||||
.code = u16(m_effect_id),
|
||||
.value = std::numeric_limits<s32>::max(),
|
||||
};
|
||||
|
||||
if (write(m_ffb_fd, &play, sizeof(play)) < 0)
|
||||
ERROR_LOG_FMT(COMMON, "EV_FF: {}", Common::LastStrerrorString());
|
||||
}
|
||||
UpdateEffect(&effect);
|
||||
}
|
||||
|
||||
private:
|
||||
const int m_ffb_fd;
|
||||
s16 m_effect_id = -1;
|
||||
};
|
||||
|
||||
std::unique_ptr<Core::SpringEffect> evdevDevice::CreateSpringEffect()
|
||||
|
||||
Reference in New Issue
Block a user