Skip to content

Commit 62bc789

Browse files
authored
Merge pull request #3362 from florianessl/compat/Ineluki_MouseBindings
Implement undocumented mouse binding for the Ineluki patch
2 parents efc104e + c132fb4 commit 62bc789

File tree

6 files changed

+146
-4
lines changed

6 files changed

+146
-4
lines changed

src/game_ineluki.cpp

Lines changed: 73 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,40 @@ bool Game_Ineluki::Execute(StringView ini_file) {
173173
// no-op
174174
} else if (cmd.name == "registercheatevent") {
175175
cheatlist.emplace_back(Utils::LowerCase(cmd.arg), atoi(cmd.arg2.c_str()));
176+
} else if (cmd.name == "setmouseasreturn") {
177+
// This command is only found in a few uncommon versions of the patch
178+
if (!mouse_support) {
179+
return true;
180+
}
181+
std::string arg_lower = Utils::LowerCase(cmd.arg);
182+
if (arg_lower == "left") {
183+
mouse_decision_binding = MouseReturnMode::Left;
184+
} else if (arg_lower == "right") {
185+
mouse_decision_binding = MouseReturnMode::Right;
186+
} else if (arg_lower == "both") {
187+
mouse_decision_binding = MouseReturnMode::Both;
188+
} else if (arg_lower == "none") {
189+
mouse_decision_binding = MouseReturnMode::None;
190+
} else {
191+
Output::Warning("Ineluki: Invalid value for setMouseAsReturn");
192+
mouse_decision_binding = MouseReturnMode::None;
193+
}
194+
} else if (cmd.name == "setmousewheelaskeys") {
195+
// This command is only found in a few uncommon versions of the patch
196+
if (!mouse_support) {
197+
return true;
198+
}
199+
std::string arg_lower = Utils::LowerCase(cmd.arg);
200+
if (arg_lower == "updown") {
201+
mouse_wheel_binding = MouseWheelMode::UpDown;
202+
} else if (arg_lower == "leftright") {
203+
mouse_wheel_binding = MouseWheelMode::LeftRight;
204+
} else if (arg_lower == "none") {
205+
mouse_wheel_binding = MouseWheelMode::None;
206+
} else {
207+
Output::Warning("Ineluki: Invalid value for setMouseWheelAsKeys");
208+
mouse_wheel_binding = MouseWheelMode::None;
209+
}
176210
}
177211
}
178212

@@ -263,6 +297,10 @@ bool Game_Ineluki::Parse(StringView ini_file) {
263297
} else if (cmd.name == "registercheatevent") {
264298
cmd.arg = ini.Get(section, "cheat", std::string());
265299
cmd.arg2 = ini.Get(section, "value", std::string());
300+
} else if (cmd.name == "setmouseasreturn") {
301+
cmd.arg = ini.Get(section, "value", std::string());
302+
} else if (cmd.name == "setmousewheelaskeys") {
303+
cmd.arg = ini.Get(section, "value", std::string());
266304
} else {
267305
Output::Debug("Ineluki: Unknown command {}", cmd.name);
268306
valid = false;
@@ -294,10 +332,15 @@ int Game_Ineluki::GetMidiTicks() {
294332
}
295333

296334
void Game_Ineluki::Update() {
297-
if (!key_support) {
298-
return;
335+
if (key_support) {
336+
UpdateKeys();
337+
}
338+
if (mouse_support) {
339+
UpdateMouse();
299340
}
341+
}
300342

343+
void Game_Ineluki::UpdateKeys() {
301344
for (const auto& key : keylist_down) {
302345
if (Input::IsRawKeyTriggered(key.key)) {
303346
output_list.push_back(key.value);
@@ -332,6 +375,34 @@ void Game_Ineluki::Update() {
332375
}
333376
}
334377

378+
void Game_Ineluki::UpdateMouse() {
379+
#if defined(USE_MOUSE) && defined(SUPPORT_MOUSE)
380+
if (Input::IsRawKeyTriggered(Input::Keys::MOUSE_LEFT)) {
381+
if ((mouse_decision_binding == MouseReturnMode::Left || mouse_decision_binding == MouseReturnMode::Both)) {
382+
Input::SimulateButtonPress(Input::DECISION);
383+
}
384+
} else if (Input::IsRawKeyTriggered(Input::Keys::MOUSE_RIGHT)) {
385+
if ((mouse_decision_binding == MouseReturnMode::Right || mouse_decision_binding == MouseReturnMode::Both)) {
386+
Input::SimulateButtonPress(Input::DECISION);
387+
}
388+
}
389+
390+
if (Input::IsRawKeyTriggered(Input::Keys::MOUSE_SCROLLUP)) {
391+
if (mouse_wheel_binding == MouseWheelMode::UpDown) {
392+
Input::SimulateButtonPress(Input::UP);
393+
} else if (mouse_wheel_binding == MouseWheelMode::LeftRight) {
394+
Input::SimulateButtonPress(Input::LEFT);
395+
}
396+
} else if (Input::IsRawKeyTriggered(Input::Keys::MOUSE_SCROLLDOWN)) {
397+
if (mouse_wheel_binding == MouseWheelMode::UpDown) {
398+
Input::SimulateButtonPress(Input::DOWN);
399+
} else if (mouse_wheel_binding == MouseWheelMode::LeftRight) {
400+
Input::SimulateButtonPress(Input::RIGHT);
401+
}
402+
}
403+
#endif
404+
}
405+
335406
void Game_Ineluki::OnScriptFileReady(FileRequestResult* result) {
336407
auto it = std::find_if(async_scripts.begin(), async_scripts.end(), [&](const auto& a) {
337408
return a.script_name == result->file;

src/game_ineluki.h

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,11 +74,21 @@ class Game_Ineluki {
7474
int GetMidiTicks();
7575

7676
/**
77-
* Updates the key up/down list. Must be called once per update frame.
77+
* Updates the configured input patches. Must be called once per update frame.
7878
*/
7979
void Update();
8080

8181
private:
82+
/**
83+
* Updates the key up/down list.
84+
*/
85+
void UpdateKeys();
86+
87+
/**
88+
* Handles virtual key bindings for mouse buttons.
89+
*/
90+
void UpdateMouse();
91+
8292
/**
8393
* Parses and caches the script.
8494
*
@@ -123,6 +133,22 @@ class Game_Ineluki {
123133
bool mouse_support = false;
124134
int mouse_id_prefix = 0;
125135

136+
enum class MouseReturnMode {
137+
None,
138+
Left,
139+
Right,
140+
Both
141+
};
142+
143+
enum class MouseWheelMode {
144+
None,
145+
UpDown,
146+
LeftRight
147+
};
148+
149+
MouseReturnMode mouse_decision_binding = MouseReturnMode::None;
150+
MouseWheelMode mouse_wheel_binding = MouseWheelMode::None;
151+
126152
struct Mapping {
127153
Input::Keys::InputKey key;
128154
const char* name;

src/input.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,3 +408,27 @@ void Input::ResetMask() {
408408
SetMask(source->GetMask());
409409
}
410410

411+
void Input::SimulateButtonPress(Input::InputButton button) {
412+
switch (button) {
413+
case Input::UP:
414+
case Input::DOWN:
415+
case Input::LEFT:
416+
case Input::RIGHT:
417+
{
418+
// Directional movement has its own input handling
419+
// These buttons need to be simulated on a lower level,
420+
// or else those movement actions will be overwritten
421+
auto& cfg = source->GetConfig();
422+
for (auto& bm : cfg.buttons) {
423+
if (bm.first == button) {
424+
source->SimulateKeyPress(bm.second);
425+
break;
426+
}
427+
}
428+
break;
429+
}
430+
default:
431+
break;
432+
}
433+
UpdateButton(button, true);
434+
}

src/input.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,15 @@ namespace Input {
303303
*/
304304
Source* GetInputSource();
305305

306+
/**
307+
* Used to simulate a button press. This is used for
308+
* emulating the behavior of some runtime patches.
309+
* Buttons for directional movement will be delegated
310+
* to the underlying low level input source.
311+
* @param button The input button which should be registered as being 'pressed'
312+
*/
313+
void SimulateButtonPress(Input::InputButton button);
314+
306315
/** Buttons press time (in frames). */
307316
extern std::array<int, BUTTON_COUNT> press_time;
308317

src/input_source.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,10 @@ void Input::UiSource::DoUpdate(bool system_only) {
6464
}
6565

6666
if (!system_only || Input::IsSystemButton(bm.first)) {
67-
pressed_buttons[bm.first] = pressed_buttons[bm.first] || keystates[bm.second];
67+
pressed_buttons[bm.first] = pressed_buttons[bm.first] || keystates[bm.second] || keystates_virtual[bm.second];
6868
}
6969
}
70+
keystates_virtual = {};
7071

7172
Record();
7273

@@ -330,6 +331,10 @@ void Input::Source::AddRecordingData(Input::RecordingData type, StringView data)
330331
}
331332
}
332333

334+
void Input::Source::SimulateKeyPress(Input::Keys::InputKey key) {
335+
keystates_virtual[key] = true;
336+
}
337+
333338
void Input::LogSource::UpdateSystem() {
334339
// input log does not record actions outside of logical frames.
335340
}

src/input_source.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,12 @@ namespace Input {
139139
const KeyStatus& GetMask() const { return keymask; }
140140
KeyStatus& GetMask() { return keymask; }
141141

142+
/**
143+
* Emulate a key being pressed.
144+
* @param key
145+
*/
146+
void SimulateKeyPress(Input::Keys::InputKey key);
147+
142148
protected:
143149
void Record();
144150
void UpdateGamepad();
@@ -152,6 +158,7 @@ namespace Input {
152158

153159
KeyStatus keystates;
154160
KeyStatus keymask;
161+
KeyStatus keystates_virtual;
155162
Point mouse_pos;
156163
AnalogInput analog_input;
157164

0 commit comments

Comments
 (0)