Browse Source

Move gamepad logic from FetchMessage() to GameEventHandler()

pull/5419/head
staphen 3 years ago committed by Anders Jenbo
parent
commit
0f74370a99
  1. 176
      Source/controls/game_controls.cpp
  2. 3
      Source/controls/game_controls.h
  3. 157
      Source/diablo.cpp
  4. 68
      Source/miniwin/misc_msg.cpp
  5. 3
      Source/movie.cpp

176
Source/controls/game_controls.cpp

@ -11,8 +11,10 @@
#include "controls/plrctrls.h"
#include "controls/touch/gamepad.h"
#include "doom.h"
#include "gamemenu.h"
#include "gmenu.h"
#include "options.h"
#include "qol/stash.h"
#include "stores.h"
namespace devilution {
@ -103,36 +105,6 @@ SDL_Keycode TranslateControllerButtonToSpellbookKey(ControllerButton controllerB
}
}
} // namespace
ControllerButton TranslateTo(GamepadLayout layout, ControllerButton button)
{
if (layout != GamepadLayout::Nintendo)
return button;
switch (button) {
case ControllerButton_BUTTON_A:
return ControllerButton_BUTTON_B;
case ControllerButton_BUTTON_B:
return ControllerButton_BUTTON_A;
case ControllerButton_BUTTON_X:
return ControllerButton_BUTTON_Y;
case ControllerButton_BUTTON_Y:
return ControllerButton_BUTTON_X;
default:
return button;
}
}
bool SkipsMovie(ControllerButtonEvent ctrlEvent)
{
return IsAnyOf(ctrlEvent.button,
ControllerButton_BUTTON_A,
ControllerButton_BUTTON_B,
ControllerButton_BUTTON_START,
ControllerButton_BUTTON_BACK);
}
bool GetGameAction(const SDL_Event &event, ControllerButtonEvent ctrlEvent, GameAction *action)
{
const bool inGameMenu = InGameMenu();
@ -241,6 +213,121 @@ bool GetGameAction(const SDL_Event &event, ControllerButtonEvent ctrlEvent, Game
return false;
}
void PressControllerButton(ControllerButton button)
{
if (IsStashOpen) {
switch (button) {
case ControllerButton_BUTTON_BACK:
StartGoldWithdraw();
return;
case ControllerButton_BUTTON_LEFTSHOULDER:
Stash.PreviousPage();
return;
case ControllerButton_BUTTON_RIGHTSHOULDER:
Stash.NextPage();
return;
}
}
if (PadHotspellMenuActive) {
auto quickSpellAction = [](size_t slot) {
if (spselflag) {
SetSpeedSpell(slot);
return;
}
if (!*sgOptions.Gameplay.quickCast)
ToggleSpell(slot);
else
QuickCast(slot);
};
switch (button) {
case devilution::ControllerButton_BUTTON_A:
quickSpellAction(2);
return;
case devilution::ControllerButton_BUTTON_B:
quickSpellAction(3);
return;
case devilution::ControllerButton_BUTTON_X:
quickSpellAction(0);
return;
case devilution::ControllerButton_BUTTON_Y:
quickSpellAction(1);
return;
default:
break;
}
}
if (PadMenuNavigatorActive) {
switch (button) {
case devilution::ControllerButton_BUTTON_DPAD_UP:
PressEscKey();
LastMouseButtonAction = MouseActionType::None;
PadHotspellMenuActive = false;
PadMenuNavigatorActive = false;
gamemenu_on();
return;
case devilution::ControllerButton_BUTTON_DPAD_DOWN:
DoAutoMap();
return;
case devilution::ControllerButton_BUTTON_DPAD_LEFT:
ProcessGameAction(GameAction { GameActionType_TOGGLE_CHARACTER_INFO });
return;
case devilution::ControllerButton_BUTTON_DPAD_RIGHT:
ProcessGameAction(GameAction { GameActionType_TOGGLE_INVENTORY });
return;
case devilution::ControllerButton_BUTTON_A:
ProcessGameAction(GameAction { GameActionType_TOGGLE_SPELL_BOOK });
return;
case devilution::ControllerButton_BUTTON_B:
return;
case devilution::ControllerButton_BUTTON_X:
ProcessGameAction(GameAction { GameActionType_TOGGLE_QUEST_LOG });
return;
case devilution::ControllerButton_BUTTON_Y:
#ifdef __3DS__
sgOptions.Graphics.zoom.SetValue(!*sgOptions.Graphics.zoom);
CalcViewportGeometry();
#endif
return;
default:
break;
}
}
sgOptions.Padmapper.ButtonPressed(button);
}
} // namespace
ControllerButton TranslateTo(GamepadLayout layout, ControllerButton button)
{
if (layout != GamepadLayout::Nintendo)
return button;
switch (button) {
case ControllerButton_BUTTON_A:
return ControllerButton_BUTTON_B;
case ControllerButton_BUTTON_B:
return ControllerButton_BUTTON_A;
case ControllerButton_BUTTON_X:
return ControllerButton_BUTTON_Y;
case ControllerButton_BUTTON_Y:
return ControllerButton_BUTTON_X;
default:
return button;
}
}
bool SkipsMovie(ControllerButtonEvent ctrlEvent)
{
return IsAnyOf(ctrlEvent.button,
ControllerButton_BUTTON_A,
ControllerButton_BUTTON_B,
ControllerButton_BUTTON_START,
ControllerButton_BUTTON_BACK);
}
bool IsSimulatedMouseClickBinding(ControllerButtonEvent ctrlEvent)
{
ControllerButtonCombo leftMouseClickBinding1 = sgOptions.Padmapper.ButtonComboForAction("LeftMouseClick1");
@ -258,4 +345,33 @@ AxisDirection GetMoveDirection()
return GetLeftStickOrDpadDirection(true);
}
bool HandleControllerButtonEvent(const SDL_Event &event, GameAction &action)
{
const ControllerButtonEvent ctrlEvent = ToControllerButtonEvent(event);
bool isGamepadMotion = ProcessControllerMotion(event, ctrlEvent);
DetectInputMethod(event, ctrlEvent);
if (isGamepadMotion) {
return true;
}
if (ctrlEvent.button != ControllerButton_NONE && ctrlEvent.button == SuppressedButton) {
if (!ctrlEvent.up)
return true;
SuppressedButton = ControllerButton_NONE;
}
if (GetGameAction(event, ctrlEvent, &action)) {
ProcessGameAction(action);
return true;
} else if (ctrlEvent.button != ControllerButton_NONE) {
if (!ctrlEvent.up)
PressControllerButton(ctrlEvent.button);
else
sgOptions.Padmapper.ButtonReleased(ctrlEvent.button);
return true;
}
return false;
}
} // namespace devilution

3
Source/controls/game_controls.h

@ -62,12 +62,13 @@ struct GameAction {
ControllerButton TranslateTo(GamepadLayout layout, ControllerButton button);
bool SkipsMovie(ControllerButtonEvent ctrlEvent);
bool GetGameAction(const SDL_Event &event, ControllerButtonEvent ctrlEvent, GameAction *action);
bool IsSimulatedMouseClickBinding(ControllerButtonEvent ctrlEvent);
AxisDirection GetMoveDirection();
bool HandleControllerButtonEvent(const SDL_Event &event, GameAction &action);
extern bool PadMenuNavigatorActive;
extern bool PadHotspellMenuActive;

157
Source/diablo.cpp

@ -20,6 +20,7 @@
#endif
#include "DiabloUI/diabloui.h"
#include "controls/plrctrls.h"
#include "controls/remap_keyboard.h"
#include "diablo.h"
#include "discord/discord.h"
#include "doom.h"
@ -415,8 +416,9 @@ void RightMouseDown(bool isShiftHeld)
}
}
void ReleaseKey(int vkey)
void ReleaseKey(SDL_Keycode vkey)
{
remap_keyboard_key(&vkey);
if (sgnTimeoutCurs != CURSOR_NONE || dropGoldFlag)
return;
sgOptions.Keymapper.KeyReleased(vkey);
@ -439,6 +441,8 @@ void ClosePanels()
void PressKey(SDL_Keycode vkey, uint16_t modState)
{
remap_keyboard_key(&vkey);
if (vkey == SDLK_UNKNOWN)
return;
@ -597,93 +601,60 @@ void PressKey(SDL_Keycode vkey, uint16_t modState)
}
}
void PressControllerButton(ControllerButton button)
void HandleMouseButtonDown(Uint8 button, uint16_t modState)
{
if (IsStashOpen) {
if (sgbMouseDown == CLICK_NONE) {
switch (button) {
case ControllerButton_BUTTON_BACK:
StartGoldWithdraw();
return;
case ControllerButton_BUTTON_LEFTSHOULDER:
Stash.PreviousPage();
return;
case ControllerButton_BUTTON_RIGHTSHOULDER:
Stash.NextPage();
return;
}
}
if (PadHotspellMenuActive) {
auto quickSpellAction = [](size_t slot) {
if (spselflag) {
SetSpeedSpell(slot);
return;
}
if (!*sgOptions.Gameplay.quickCast)
ToggleSpell(slot);
else
QuickCast(slot);
};
switch (button) {
case devilution::ControllerButton_BUTTON_A:
quickSpellAction(2);
return;
case devilution::ControllerButton_BUTTON_B:
quickSpellAction(3);
return;
case devilution::ControllerButton_BUTTON_X:
quickSpellAction(0);
return;
case devilution::ControllerButton_BUTTON_Y:
quickSpellAction(1);
return;
default:
case SDL_BUTTON_LEFT:
sgbMouseDown = CLICK_LEFT;
LeftMouseDown(modState);
break;
case SDL_BUTTON_RIGHT:
sgbMouseDown = CLICK_RIGHT;
RightMouseDown((modState & KMOD_SHIFT) != 0);
break;
}
}
if (PadMenuNavigatorActive) {
switch (button) {
case devilution::ControllerButton_BUTTON_DPAD_UP:
PressEscKey();
LastMouseButtonAction = MouseActionType::None;
PadHotspellMenuActive = false;
PadMenuNavigatorActive = false;
gamemenu_on();
return;
case devilution::ControllerButton_BUTTON_DPAD_DOWN:
DoAutoMap();
return;
case devilution::ControllerButton_BUTTON_DPAD_LEFT:
ProcessGameAction(GameAction { GameActionType_TOGGLE_CHARACTER_INFO });
return;
case devilution::ControllerButton_BUTTON_DPAD_RIGHT:
ProcessGameAction(GameAction { GameActionType_TOGGLE_INVENTORY });
return;
case devilution::ControllerButton_BUTTON_A:
ProcessGameAction(GameAction { GameActionType_TOGGLE_SPELL_BOOK });
return;
case devilution::ControllerButton_BUTTON_B:
return;
case devilution::ControllerButton_BUTTON_X:
ProcessGameAction(GameAction { GameActionType_TOGGLE_QUEST_LOG });
return;
case devilution::ControllerButton_BUTTON_Y:
#ifdef __3DS__
sgOptions.Graphics.zoom.SetValue(!*sgOptions.Graphics.zoom);
CalcViewportGeometry();
#endif
return;
default:
sgOptions.Keymapper.KeyPressed(button | KeymapperMouseButtonMask);
break;
}
}
}
sgOptions.Padmapper.ButtonPressed(button);
void HandleMouseButtonUp(Uint8 button, uint16_t modState)
{
if (sgbMouseDown == CLICK_LEFT && button == SDL_BUTTON_LEFT) {
LastMouseButtonAction = MouseActionType::None;
sgbMouseDown = CLICK_NONE;
LeftMouseUp(modState);
} else if (sgbMouseDown == CLICK_RIGHT && button == SDL_BUTTON_RIGHT) {
LastMouseButtonAction = MouseActionType::None;
sgbMouseDown = CLICK_NONE;
} else {
sgOptions.Keymapper.KeyReleased(button | KeymapperMouseButtonMask);
}
}
void GameEventHandler(const SDL_Event &event, uint16_t modState)
{
GameAction action;
if (HandleControllerButtonEvent(event, action)) {
if (action.type == GameActionType_SEND_KEY) {
if ((action.send_key.vk_code & KeymapperMouseButtonMask) != 0) {
const unsigned button = action.send_key.vk_code & ~KeymapperMouseButtonMask;
if (!action.send_key.up)
HandleMouseButtonDown(static_cast<Uint8>(button), modState);
else
HandleMouseButtonUp(static_cast<Uint8>(button), modState);
} else {
if (!action.send_key.up)
PressKey(static_cast<SDL_Keycode>(action.send_key.vk_code), modState);
else
ReleaseKey(static_cast<SDL_Keycode>(action.send_key.vk_code));
}
}
return;
}
switch (event.type) {
case SDL_KEYDOWN:
PressKey(event.key.keysym.sym, modState);
@ -697,41 +668,11 @@ void GameEventHandler(const SDL_Event &event, uint16_t modState)
return;
case SDL_MOUSEBUTTONDOWN:
MousePosition = { event.button.x, event.button.y };
if (sgbMouseDown == CLICK_NONE) {
switch (event.button.button) {
case SDL_BUTTON_LEFT:
sgbMouseDown = CLICK_LEFT;
LeftMouseDown(modState);
break;
case SDL_BUTTON_RIGHT:
sgbMouseDown = CLICK_RIGHT;
RightMouseDown((modState & KMOD_SHIFT) != 0);
break;
default:
sgOptions.Keymapper.KeyPressed(event.button.button | KeymapperMouseButtonMask);
break;
}
}
HandleMouseButtonDown(event.button.button, modState);
return;
case SDL_MOUSEBUTTONUP:
MousePosition = { event.button.x, event.button.y };
if (sgbMouseDown == CLICK_LEFT && event.button.button == SDL_BUTTON_LEFT) {
LastMouseButtonAction = MouseActionType::None;
sgbMouseDown = CLICK_NONE;
LeftMouseUp(modState);
} else if (sgbMouseDown == CLICK_RIGHT && event.button.button == SDL_BUTTON_RIGHT) {
LastMouseButtonAction = MouseActionType::None;
sgbMouseDown = CLICK_NONE;
} else {
sgOptions.Keymapper.KeyReleased(event.button.button | KeymapperMouseButtonMask);
}
return;
case SDL_JOYBUTTONDOWN:
PressControllerButton(static_cast<ControllerButton>(event.jbutton.button));
return;
case SDL_JOYBUTTONUP:
sgOptions.Padmapper.ButtonReleased(static_cast<ControllerButton>(event.jbutton.button));
HandleMouseButtonUp(event.button.button, modState);
return;
default:
if (IsCustomEvent(event.type)) {

68
Source/miniwin/misc_msg.cpp

@ -8,11 +8,8 @@
#include "control.h"
#include "controls/controller.h"
#include "controls/controller_motion.h"
#include "controls/game_controls.h"
#include "controls/input.h"
#include "controls/plrctrls.h"
#include "controls/remap_keyboard.h"
#ifndef USE_SDL1
#include "controls/touch/event_handlers.h"
#endif
@ -20,15 +17,11 @@
#include "engine/demomode.h"
#include "engine/rectangle.hpp"
#include "hwcursor.hpp"
#include "inv.h"
#include "menu.h"
#include "movie.h"
#include "panels/spell_list.hpp"
#include "qol/stash.h"
#include "utils/display.h"
#include "utils/log.hpp"
#include "utils/sdl_compat.h"
#include "utils/stubs.h"
#include "utils/utf8.hpp"
#ifdef __vita__
@ -154,52 +147,20 @@ bool FetchMessage_Real(SDL_Event *event, uint16_t *modState)
}
#endif
const ControllerButtonEvent ctrlEvent = ToControllerButtonEvent(e);
bool isGamepadMotion = ProcessControllerMotion(e, ctrlEvent);
DetectInputMethod(e, ctrlEvent);
if (isGamepadMotion) {
return true;
}
if (movie_playing && SkipsMovie(ctrlEvent)) {
event->type = SDL_KEYDOWN;
return true;
}
if (ctrlEvent.button != ControllerButton_NONE) {
if (ctrlEvent.button == SuppressedButton) {
if (!ctrlEvent.up)
return true;
SuppressedButton = ControllerButton_NONE;
}
event->type = ctrlEvent.up ? SDL_JOYBUTTONUP : SDL_JOYBUTTONDOWN;
event->jbutton.button = ctrlEvent.button;
event->jbutton.state = ctrlEvent.up ? SDL_RELEASED : SDL_PRESSED;
}
GameAction action;
if (GetGameAction(e, ctrlEvent, &action)) {
if (action.type == GameActionType_SEND_KEY) {
if ((action.send_key.vk_code & KeymapperMouseButtonMask) != 0) {
const unsigned button = action.send_key.vk_code & ~KeymapperMouseButtonMask;
SetMouseButtonEvent(*event, action.send_key.up ? SDL_MOUSEBUTTONUP : SDL_MOUSEBUTTONDOWN, static_cast<uint8_t>(button), MousePosition);
} else {
event->type = action.send_key.up ? SDL_KEYUP : SDL_KEYDOWN;
event->key.state = action.send_key.up ? SDL_PRESSED : SDL_RELEASED;
event->key.keysym.sym = static_cast<SDL_Keycode>(action.send_key.vk_code);
}
} else {
ProcessGameAction(action);
}
return true;
}
if (HandleControllerAddedOrRemovedEvent(e))
return true;
switch (e.type) {
#ifndef USE_SDL1
case SDL_CONTROLLERAXISMOTION:
case SDL_CONTROLLERBUTTONDOWN:
case SDL_CONTROLLERBUTTONUP:
#endif
case SDL_JOYAXISMOTION:
case SDL_JOYBUTTONDOWN:
case SDL_JOYBUTTONUP:
*event = e;
break;
case SDL_KEYDOWN:
case SDL_KEYUP: {
#ifdef USE_SDL1
@ -215,14 +176,9 @@ bool FetchMessage_Real(SDL_Event *event, uint16_t *modState)
}
}
#endif
SDL_Keycode key = e.key.keysym.sym;
remap_keyboard_key(&key);
if (key == -1)
if (e.key.keysym.sym == -1)
return FalseAvail(e.type == SDL_KEYDOWN ? "SDL_KEYDOWN" : "SDL_KEYUP", e.key.keysym.sym);
event->type = e.type;
event->key.state = e.key.state;
event->key.keysym.sym = key;
event->key.keysym.mod = e.key.keysym.mod;
*event = e;
} break;
case SDL_MOUSEMOTION:
*event = e;

3
Source/movie.cpp

@ -41,6 +41,9 @@ void play_movie(const char *pszMovie, bool userCanClose)
uint16_t modState;
while (movie_playing) {
while (movie_playing && FetchMessage(&event, &modState)) {
ControllerButtonEvent ctrlEvent = ToControllerButtonEvent(event);
if (userCanClose && SkipsMovie(ctrlEvent))
movie_playing = false;
switch (event.type) {
case SDL_KEYDOWN:
case SDL_MOUSEBUTTONUP:

Loading…
Cancel
Save