Browse Source

Improve behavior of ToControllerButtonEvent()

pull/3841/head
staphen 4 years ago committed by Anders Jenbo
parent
commit
74a77666b9
  1. 3
      Source/DiabloUI/credits.cpp
  2. 3
      Source/DiabloUI/diabloui.cpp
  3. 3
      Source/DiabloUI/dialogs.cpp
  4. 3
      Source/DiabloUI/progress.cpp
  5. 3
      Source/DiabloUI/title.cpp
  6. 10
      Source/controls/controller.cpp
  7. 5
      Source/controls/controller.h
  8. 14
      Source/controls/devices/game_controller.cpp
  9. 7
      Source/controls/devices/game_controller.h
  10. 17
      Source/controls/input.h
  11. 3
      Source/miniwin/misc_msg.cpp

3
Source/DiabloUI/credits.cpp

@ -8,6 +8,7 @@
#include "DiabloUI/diabloui.h"
#include "DiabloUI/support_lines.h"
#include "control.h"
#include "controls/input.h"
#include "controls/menu_controls.h"
#include "engine/render/text_render.hpp"
#include "hwcursor.hpp"
@ -138,7 +139,7 @@ bool TextDialog(char const *const *text, std::size_t textLines)
do {
creditsRenderer.Render();
UiFadeIn();
while (SDL_PollEvent(&event) != 0) {
while (PollEvent(&event) != 0) {
switch (event.type) {
case SDL_KEYDOWN:
case SDL_MOUSEBUTTONDOWN:

3
Source/DiabloUI/diabloui.cpp

@ -13,6 +13,7 @@
#include "DiabloUI/dialogs.h"
#include "DiabloUI/scrollbar.h"
#include "controls/controller.h"
#include "controls/input.h"
#include "controls/menu_controls.h"
#include "discord/discord.h"
#include "dx.h"
@ -748,7 +749,7 @@ void UiClearScreen()
void UiPollAndRender(std::function<bool(SDL_Event &)> eventHandler)
{
SDL_Event event;
while (SDL_PollEvent(&event) != 0) {
while (PollEvent(&event) != 0) {
if (eventHandler && eventHandler(event))
continue;
UiFocusNavigation(&event);

3
Source/DiabloUI/dialogs.cpp

@ -6,6 +6,7 @@
#include "DiabloUI/diabloui.h"
#include "DiabloUI/errorart.h"
#include "control.h"
#include "controls/input.h"
#include "controls/menu_controls.h"
#include "dx.h"
#include "hwcursor.hpp"
@ -220,7 +221,7 @@ void DialogLoop(const std::vector<std::unique_ptr<UiItemBase>> &items, const std
SDL_Event event;
dialogEnd = false;
do {
while (SDL_PollEvent(&event) != 0) {
while (PollEvent(&event) != 0) {
switch (event.type) {
case SDL_MOUSEBUTTONDOWN:
case SDL_MOUSEBUTTONUP:

3
Source/DiabloUI/progress.cpp

@ -2,6 +2,7 @@
#include "DiabloUI/button.h"
#include "DiabloUI/diabloui.h"
#include "control.h"
#include "controls/input.h"
#include "controls/menu_controls.h"
#include "dx.h"
#include "hwcursor.hpp"
@ -78,7 +79,7 @@ bool UiProgressDialog(const char *msg, int (*fnfunc)())
DrawMouse();
RenderPresent();
while (SDL_PollEvent(&event) != 0) {
while (PollEvent(&event) != 0) {
switch (event.type) {
case SDL_MOUSEBUTTONDOWN:
case SDL_MOUSEBUTTONUP:

3
Source/DiabloUI/title.cpp

@ -1,5 +1,6 @@
#include "DiabloUI/diabloui.h"
#include "control.h"
#include "controls/input.h"
#include "controls/menu_controls.h"
#include "discord/discord.h"
#include "utils/language.h"
@ -56,7 +57,7 @@ void UiTitleDialog()
discord_manager::UpdateMenu();
while (SDL_PollEvent(&event) != 0) {
while (PollEvent(&event) != 0) {
if (GetMenuAction(event) != MenuAction_NONE) {
endMenu = true;
break;

10
Source/controls/controller.cpp

@ -8,6 +8,16 @@
namespace devilution {
void UnlockControllerState(const SDL_Event &event)
{
#ifndef USE_SDL1
GameController *const controller = GameController::Get(event);
if (controller != nullptr) {
controller->UnlockTriggerState();
}
#endif
}
ControllerButtonEvent ToControllerButtonEvent(const SDL_Event &event)
{
ControllerButtonEvent result { ControllerButton_NONE, false };

5
Source/controls/controller.h

@ -11,8 +11,9 @@ struct ControllerButtonEvent {
bool up;
};
// NOTE: Not idempotent because of how it handles axis triggers.
// Must be called exactly once per SDL input event.
// Must be called exactly once at the start of each SDL input event.
void UnlockControllerState(const SDL_Event &event);
ControllerButtonEvent ToControllerButtonEvent(const SDL_Event &event);
bool IsControllerButtonPressed(ControllerButton button);

14
Source/controls/devices/game_controller.cpp

@ -18,6 +18,12 @@ extern bool sgbControllerActive;
std::vector<GameController> GameController::controllers_;
void GameController::UnlockTriggerState()
{
trigger_left_state_ = ControllerButton_NONE;
trigger_right_state_ = ControllerButton_NONE;
}
ControllerButton GameController::ToControllerButton(const SDL_Event &event)
{
switch (event.type) {
@ -29,18 +35,18 @@ ControllerButton GameController::ToControllerButton(const SDL_Event &event)
}
if (event.caxis.value > 16384 && !trigger_left_is_down_) { // 50% pressed
trigger_left_is_down_ = true;
return ControllerButton_AXIS_TRIGGERLEFT;
trigger_left_state_ = ControllerButton_AXIS_TRIGGERLEFT;
}
return ControllerButton_NONE;
return trigger_left_state_;
case SDL_CONTROLLER_AXIS_TRIGGERRIGHT:
if (event.caxis.value < 8192) { // 25% pressed
trigger_right_is_down_ = false;
}
if (event.caxis.value > 16384 && !trigger_right_is_down_) { // 50% pressed
trigger_right_is_down_ = true;
return ControllerButton_AXIS_TRIGGERRIGHT;
trigger_right_state_ = ControllerButton_AXIS_TRIGGERRIGHT;
}
return ControllerButton_NONE;
return trigger_right_state_;
}
break;
case SDL_CONTROLLERBUTTONDOWN:

7
Source/controls/devices/game_controller.h

@ -21,8 +21,9 @@ public:
static const std::vector<GameController> &All();
static bool IsPressedOnAnyController(ControllerButton button);
// NOTE: Not idempotent.
// Must be called exactly once for each SDL input event.
// Must be called exactly once at the start of each SDL input event.
void UnlockTriggerState();
ControllerButton ToControllerButton(const SDL_Event &event);
bool IsPressed(ControllerButton button) const;
@ -34,6 +35,8 @@ private:
SDL_GameController *sdl_game_controller_ = NULL;
SDL_JoystickID instance_id_ = -1;
ControllerButton trigger_left_state_ = ControllerButton_NONE;
ControllerButton trigger_right_state_ = ControllerButton_NONE;
bool trigger_left_is_down_ = false;
bool trigger_right_is_down_ = false;
};

17
Source/controls/input.h

@ -0,0 +1,17 @@
#pragma once
#include <SDL.h>
#include "controls/controller.h"
namespace devilution {
inline int PollEvent(SDL_Event *event)
{
int result = SDL_PollEvent(event);
if (result != 0)
UnlockControllerState(*event);
return result;
}
} // namespace devilution

3
Source/miniwin/misc_msg.cpp

@ -13,6 +13,7 @@
#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"
#include "controls/touch/event_handlers.h"
@ -310,7 +311,7 @@ bool FetchMessage_Real(tagMSG *lpMsg)
}
SDL_Event e;
if (SDL_PollEvent(&e) == 0) {
if (PollEvent(&e) == 0) {
return false;
}

Loading…
Cancel
Save