Skip to content

Commit 26ee1fa

Browse files
committed
implemented the option to set right trigger to be the boost button which
matches the modern boost sonic games like sonic frontiers and shadow generations. The entry in the config.toml file will be an enum with options for "drift" or "boost" under "RightTriggerAction" the benifits rather than the user using controller remapping software is this ONLY effects the day stages so the trigger will function normally when the using plays the night stages. The option especially works well in Eggmanland. The right trigger seemlessly de/activates when switching between sonics that stage
1 parent 5e8695a commit 26ee1fa

5 files changed

Lines changed: 147 additions & 0 deletions

File tree

UnleashedRecomp/hid/driver/sdl_hid.cpp

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,18 @@
1010
#define TRANSLATE_INPUT(S, X) SDL_GameControllerGetButton(controller, S) << FirstBitLow(X)
1111
#define VIBRATION_TIMEOUT_MS 5000
1212

13+
static bool IsBoostOnRightTriggerActive()
14+
{
15+
// true if sonic is werehog and right trigger preference is boost
16+
return !App::s_isWerehog && Config::RightTriggerAction == ERightTriggerAction::Boost;
17+
}
18+
19+
static uint32_t GetBoostCancelDurationMs()
20+
{
21+
int32_t fps = Config::FPS > 0 ? Config::FPS : 60;
22+
return static_cast<uint32_t>(2000 / fps);
23+
}
24+
1325
class Controller
1426
{
1527
public:
@@ -20,6 +32,13 @@ class Controller
2032
XAMINPUT_VIBRATION vibration{ 0, 0 };
2133
int index{};
2234

35+
// for when user sets Config::RightTriggerAction to ERightTriggerAction this
36+
// increases stability to allow square/X to be recognised by the game while
37+
// right trigger is being pressed down especially when the user is moving
38+
// the thumbsticks
39+
bool xWasHeldLastPoll{};
40+
uint32_t xCancelUntilTick{};
41+
2342
Controller() = default;
2443

2544
explicit Controller(int index) : Controller(SDL_GameControllerOpen(index))
@@ -99,6 +118,33 @@ class Controller
99118

100119
pad.bLeftTrigger = SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_TRIGGERLEFT) >> 7;
101120
pad.bRightTrigger = SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_TRIGGERRIGHT) >> 7;
121+
122+
123+
124+
if (IsBoostOnRightTriggerActive())
125+
{
126+
bool xHeldPhysically = SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_X) != 0;
127+
bool xRisingEdge = xHeldPhysically && !xWasHeldLastPoll;
128+
bool rtPulled = pad.bRightTrigger >= 30; // TODO: change this to a pressure preference
129+
130+
// these checks are in place to improve responsiveness of square/X while right trigger is held down
131+
if (xRisingEdge && rtPulled)
132+
xCancelUntilTick = SDL_GetTicks() + GetBoostCancelDurationMs();
133+
134+
bool inCancelWindow = SDL_TICKS_PASSED(xCancelUntilTick, SDL_GetTicks());
135+
136+
if (inCancelWindow)
137+
pad.wButtons &= ~XAMINPUT_GAMEPAD_X;
138+
else if (xHeldPhysically || rtPulled)
139+
pad.wButtons |= XAMINPUT_GAMEPAD_X;
140+
else
141+
pad.wButtons &= ~XAMINPUT_GAMEPAD_X;
142+
143+
if (rtPulled)
144+
pad.bRightTrigger = 0;
145+
146+
xWasHeldLastPoll = xHeldPhysically;
147+
}
102148
}
103149

104150
void Poll()
@@ -129,6 +175,34 @@ class Controller
129175
pad.wButtons |= TRANSLATE_INPUT(SDL_CONTROLLER_BUTTON_B, XAMINPUT_GAMEPAD_B);
130176
pad.wButtons |= TRANSLATE_INPUT(SDL_CONTROLLER_BUTTON_X, XAMINPUT_GAMEPAD_X);
131177
pad.wButtons |= TRANSLATE_INPUT(SDL_CONTROLLER_BUTTON_Y, XAMINPUT_GAMEPAD_Y);
178+
179+
// when playing day stages keep the right trigger mirrored onto square/X
180+
// so so the game knows the user is boosting. This will remove the actual
181+
// right trigger from the game so sonic wouldn't drift
182+
if (IsBoostOnRightTriggerActive())
183+
{
184+
bool xHeldPhysically = (pad.wButtons & XAMINPUT_GAMEPAD_X) != 0;
185+
bool xRisingEdge = xHeldPhysically && !xWasHeldLastPoll;
186+
uint8_t rtRaw = SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_TRIGGERRIGHT) >> 7;
187+
bool rtPulled = rtRaw >= 30; // TODO: change this to a pressure preference
188+
189+
// like in Poll() these checks are in place to improve responsiveness
190+
// of square/X while right trigger is held down
191+
if (xRisingEdge && rtPulled)
192+
xCancelUntilTick = SDL_GetTicks() + GetBoostCancelDurationMs();
193+
194+
bool inCancelWindow = SDL_TICKS_PASSED(xCancelUntilTick, SDL_GetTicks());
195+
196+
if (inCancelWindow)
197+
pad.wButtons &= ~XAMINPUT_GAMEPAD_X;
198+
else if (rtPulled)
199+
pad.wButtons |= XAMINPUT_GAMEPAD_X;
200+
201+
if (rtPulled)
202+
pad.bRightTrigger = 0;
203+
204+
xWasHeldLastPoll = xHeldPhysically;
205+
}
132206
}
133207

134208
void SetVibration(const XAMINPUT_VIBRATION& vibration)

UnleashedRecomp/locale/config_locale.cpp

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,66 @@ CONFIG_DEFINE_ENUM_LOCALE(ETimeOfDayTransition)
216216
}
217217
};
218218

219+
// Translation required
220+
// Japanese Notes: This localization should include furigana in its description.
221+
CONFIG_DEFINE_LOCALE(RightTriggerAction)
222+
{
223+
{ ELanguage::English, { "Right Trigger Action", "Choose what the right trigger does in day stages." } },
224+
{ ELanguage::Japanese, { "Right Trigger Action", "Choose what the right trigger does in day stages." } }, // Translation required
225+
{ ELanguage::German, { "Right Trigger Action", "Choose what the right trigger does in day stages." } }, // Translation required
226+
{ ELanguage::French, { "Right Trigger Action", "Choose what the right trigger does in day stages." } }, // Translation required
227+
{ ELanguage::Spanish, { "Right Trigger Action", "Choose what the right trigger does in day stages." } }, // Translation required
228+
{ ELanguage::Italian, { "Right Trigger Action", "Choose what the right trigger does in day stages." } } // Translation required
229+
};
230+
231+
// Translation required
232+
// Japanese Notes: This localization should include furigana in its description.
233+
CONFIG_DEFINE_ENUM_LOCALE(ERightTriggerAction)
234+
{
235+
{
236+
ELanguage::English,
237+
{
238+
{ ERightTriggerAction::Drift, { "DRIFT", "Default: the right trigger acts as drift, matching the original Xbox 360/PS3 controls." } },
239+
{ ERightTriggerAction::Boost, { "BOOST/H.A", "EXPERIMENTAL: The right trigger acts as boost or homing attack. Drift is still available on the left trigger and X/Square still triggers boost too." } }
240+
}
241+
},
242+
{
243+
ELanguage::Japanese,
244+
{
245+
{ ERightTriggerAction::Drift, { "DRIFT", "" } },
246+
{ ERightTriggerAction::Boost, { "BOOST", "" } }
247+
}
248+
},
249+
{
250+
ELanguage::German,
251+
{
252+
{ ERightTriggerAction::Drift, { "DRIFT", "" } },
253+
{ ERightTriggerAction::Boost, { "BOOST", "" } }
254+
}
255+
},
256+
{
257+
ELanguage::French,
258+
{
259+
{ ERightTriggerAction::Drift, { "DRIFT", "" } },
260+
{ ERightTriggerAction::Boost, { "BOOST", "" } }
261+
}
262+
},
263+
{
264+
ELanguage::Spanish,
265+
{
266+
{ ERightTriggerAction::Drift, { "DRIFT", "" } },
267+
{ ERightTriggerAction::Boost, { "BOOST", "" } }
268+
}
269+
},
270+
{
271+
ELanguage::Italian,
272+
{
273+
{ ERightTriggerAction::Drift, { "DRIFT", "" } },
274+
{ ERightTriggerAction::Boost, { "BOOST", "" } }
275+
}
276+
}
277+
};
278+
219279
// Japanese Notes: This localization should include furigana.
220280
CONFIG_DEFINE_LOCALE(ControllerIcons)
221281
{

UnleashedRecomp/user/config.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@ CONFIG_DEFINE_ENUM_TEMPLATE(ECameraRotationMode)
3030
{ "Reverse", ECameraRotationMode::Reverse },
3131
};
3232

33+
CONFIG_DEFINE_ENUM_TEMPLATE(ERightTriggerAction)
34+
{
35+
{ "Drift", ERightTriggerAction::Drift },
36+
{ "Boost", ERightTriggerAction::Boost }
37+
};
38+
3339
CONFIG_DEFINE_ENUM_TEMPLATE(EControllerIcons)
3440
{
3541
{ "Auto", EControllerIcons::Auto },

UnleashedRecomp/user/config.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,12 @@ enum class ECameraRotationMode : uint32_t
5252
Reverse
5353
};
5454

55+
enum class ERightTriggerAction : uint32_t
56+
{
57+
Drift,
58+
Boost
59+
};
60+
5561
enum class EControllerIcons : uint32_t
5662
{
5763
Auto,

UnleashedRecomp/user/config_def.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ CONFIG_DEFINE("System", bool, ShowConsole, false);
1212

1313
CONFIG_DEFINE_ENUM_LOCALISED("Input", ECameraRotationMode, HorizontalCamera, ECameraRotationMode::Normal);
1414
CONFIG_DEFINE_ENUM_LOCALISED("Input", ECameraRotationMode, VerticalCamera, ECameraRotationMode::Normal);
15+
CONFIG_DEFINE_ENUM_LOCALISED("Input", ERightTriggerAction, RightTriggerAction, ERightTriggerAction::Drift);
1516
CONFIG_DEFINE_LOCALISED("Input", bool, Vibration, true);
1617
CONFIG_DEFINE_LOCALISED("Input", bool, AllowBackgroundInput, false);
1718
CONFIG_DEFINE_ENUM_LOCALISED("Input", EControllerIcons, ControllerIcons, EControllerIcons::Auto);

0 commit comments

Comments
 (0)