Add extremely basic controller support (only movement)
This commit is contained in:
parent
0886098242
commit
0b7ddd05d1
@ -163,4 +163,38 @@ EnumMap<MouseWheel> const MouseWheelNames{
|
|||||||
{MouseWheel::Down, "MouseWheelDown"}
|
{MouseWheel::Down, "MouseWheelDown"}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
EnumMap<ControllerAxis> const ControllerAxisNames{
|
||||||
|
{ControllerAxis::LeftX, "LeftX"},
|
||||||
|
{ControllerAxis::LeftY, "LeftY"},
|
||||||
|
{ControllerAxis::RightX, "RightX"},
|
||||||
|
{ControllerAxis::RightY, "RightY"},
|
||||||
|
{ControllerAxis::TriggerLeft, "TriggerLeft"},
|
||||||
|
{ControllerAxis::TriggerRight, "TriggerRight"},
|
||||||
|
};
|
||||||
|
|
||||||
|
EnumMap<ControllerButton> const ControllerButtonNames{
|
||||||
|
{ControllerButton::A, "A"},
|
||||||
|
{ControllerButton::B, "B"},
|
||||||
|
{ControllerButton::X, "X"},
|
||||||
|
{ControllerButton::Y, "Y"},
|
||||||
|
{ControllerButton::Back, "Back"},
|
||||||
|
{ControllerButton::Guide, "Guide"},
|
||||||
|
{ControllerButton::Start, "Start"},
|
||||||
|
{ControllerButton::LeftStick, "LeftStick"},
|
||||||
|
{ControllerButton::RightStick, "RightStick"},
|
||||||
|
{ControllerButton::LeftShoulder, "LeftShoulder"},
|
||||||
|
{ControllerButton::RightShoulder, "RightShoulder"},
|
||||||
|
{ControllerButton::DPadUp, "DPadUp"},
|
||||||
|
{ControllerButton::DPadDown, "DPadDown"},
|
||||||
|
{ControllerButton::DPadLeft, "DPadLeft"},
|
||||||
|
{ControllerButton::DPadRight, "DPadRight"},
|
||||||
|
{ControllerButton::Misc1, "Misc1"},
|
||||||
|
{ControllerButton::Paddle1, "Paddle1"},
|
||||||
|
{ControllerButton::Paddle2, "Paddle2"},
|
||||||
|
{ControllerButton::Paddle3, "Paddle3"},
|
||||||
|
{ControllerButton::Paddle4, "Paddle4"},
|
||||||
|
{ControllerButton::Touchpad, "Touchpad"},
|
||||||
|
{ControllerButton::Invalid, "Invalid"}
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -154,7 +154,8 @@ enum class KeyMod : uint16_t {
|
|||||||
RGui = 0x0800,
|
RGui = 0x0800,
|
||||||
Num = 0x1000,
|
Num = 0x1000,
|
||||||
Caps = 0x2000,
|
Caps = 0x2000,
|
||||||
AltGr = 0x4000
|
AltGr = 0x4000,
|
||||||
|
Scroll = 0x8000
|
||||||
};
|
};
|
||||||
extern EnumMap<KeyMod> const KeyModNames;
|
extern EnumMap<KeyMod> const KeyModNames;
|
||||||
|
|
||||||
@ -181,6 +182,43 @@ extern EnumMap<MouseWheel> const MouseWheelNames;
|
|||||||
|
|
||||||
typedef uint32_t ControllerId;
|
typedef uint32_t ControllerId;
|
||||||
|
|
||||||
|
enum class ControllerAxis : uint8_t {
|
||||||
|
LeftX,
|
||||||
|
LeftY,
|
||||||
|
RightX,
|
||||||
|
RightY,
|
||||||
|
TriggerLeft,
|
||||||
|
TriggerRight,
|
||||||
|
Invalid = 255
|
||||||
|
};
|
||||||
|
extern EnumMap<ControllerAxis> const ControllerAxisNames;
|
||||||
|
|
||||||
|
enum class ControllerButton : uint8_t {
|
||||||
|
A,
|
||||||
|
B,
|
||||||
|
X,
|
||||||
|
Y,
|
||||||
|
Back,
|
||||||
|
Guide,
|
||||||
|
Start,
|
||||||
|
LeftStick,
|
||||||
|
RightStick,
|
||||||
|
LeftShoulder,
|
||||||
|
RightShoulder,
|
||||||
|
DPadUp,
|
||||||
|
DPadDown,
|
||||||
|
DPadLeft,
|
||||||
|
DPadRight,
|
||||||
|
Misc1,
|
||||||
|
Paddle1,
|
||||||
|
Paddle2,
|
||||||
|
Paddle3,
|
||||||
|
Paddle4,
|
||||||
|
Touchpad,
|
||||||
|
Invalid = 255
|
||||||
|
};
|
||||||
|
extern EnumMap<ControllerButton> const ControllerButtonNames;
|
||||||
|
|
||||||
struct KeyDownEvent {
|
struct KeyDownEvent {
|
||||||
Key key;
|
Key key;
|
||||||
KeyMod mods;
|
KeyMod mods;
|
||||||
@ -216,18 +254,18 @@ struct MouseWheelEvent {
|
|||||||
|
|
||||||
struct ControllerAxisEvent {
|
struct ControllerAxisEvent {
|
||||||
ControllerId controller;
|
ControllerId controller;
|
||||||
unsigned controllerAxis;
|
ControllerAxis controllerAxis;
|
||||||
float controllerAxisValue;
|
float controllerAxisValue;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ControllerButtonDownEvent {
|
struct ControllerButtonDownEvent {
|
||||||
ControllerId controller;
|
ControllerId controller;
|
||||||
unsigned controllerButton;
|
ControllerButton controllerButton;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ControllerButtonUpEvent {
|
struct ControllerButtonUpEvent {
|
||||||
ControllerId controller;
|
ControllerId controller;
|
||||||
unsigned controllerButton;
|
ControllerButton controllerButton;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef Variant<
|
typedef Variant<
|
||||||
|
@ -151,45 +151,56 @@ Maybe<Key> keyFromSdlKeyCode(SDL_Keycode sym) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
KeyMod keyModsFromSdlKeyMods(uint16_t mod) {
|
KeyMod keyModsFromSdlKeyMods(uint16_t mod) {
|
||||||
KeyMod keyMod = KeyMod::NoMod;
|
return static_cast<KeyMod>(mod);
|
||||||
|
|
||||||
if (mod & KMOD_LSHIFT)
|
|
||||||
keyMod |= KeyMod::LShift;
|
|
||||||
if (mod & KMOD_RSHIFT)
|
|
||||||
keyMod |= KeyMod::RShift;
|
|
||||||
if (mod & KMOD_LCTRL)
|
|
||||||
keyMod |= KeyMod::LCtrl;
|
|
||||||
if (mod & KMOD_RCTRL)
|
|
||||||
keyMod |= KeyMod::RCtrl;
|
|
||||||
if (mod & KMOD_LALT)
|
|
||||||
keyMod |= KeyMod::LAlt;
|
|
||||||
if (mod & KMOD_RALT)
|
|
||||||
keyMod |= KeyMod::RAlt;
|
|
||||||
if (mod & KMOD_LGUI)
|
|
||||||
keyMod |= KeyMod::LGui;
|
|
||||||
if (mod & KMOD_RGUI)
|
|
||||||
keyMod |= KeyMod::RGui;
|
|
||||||
if (mod & KMOD_NUM)
|
|
||||||
keyMod |= KeyMod::Num;
|
|
||||||
if (mod & KMOD_CAPS)
|
|
||||||
keyMod |= KeyMod::Caps;
|
|
||||||
if (mod & KMOD_MODE)
|
|
||||||
keyMod |= KeyMod::AltGr;
|
|
||||||
|
|
||||||
return keyMod;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseButton mouseButtonFromSdlMouseButton(uint8_t button) {
|
MouseButton mouseButtonFromSdlMouseButton(uint8_t button) {
|
||||||
if (button == SDL_BUTTON_LEFT)
|
switch (button) {
|
||||||
return MouseButton::Left;
|
case SDL_BUTTON_LEFT: return MouseButton::Left;
|
||||||
else if (button == SDL_BUTTON_MIDDLE)
|
case SDL_BUTTON_MIDDLE: return MouseButton::Middle;
|
||||||
return MouseButton::Middle;
|
case SDL_BUTTON_RIGHT: return MouseButton::Right;
|
||||||
else if (button == SDL_BUTTON_RIGHT)
|
case SDL_BUTTON_X1: return MouseButton::FourthButton;
|
||||||
return MouseButton::Right;
|
default: return MouseButton::FifthButton;
|
||||||
else if (button == SDL_BUTTON_X1)
|
}
|
||||||
return MouseButton::FourthButton;
|
}
|
||||||
else
|
|
||||||
return MouseButton::FifthButton;
|
ControllerAxis controllerAxisFromSdlControllerAxis(uint8_t axis) {
|
||||||
|
switch (axis) {
|
||||||
|
case SDL_CONTROLLER_AXIS_LEFTX: return ControllerAxis::LeftX;
|
||||||
|
case SDL_CONTROLLER_AXIS_LEFTY: return ControllerAxis::LeftY;
|
||||||
|
case SDL_CONTROLLER_AXIS_RIGHTX: return ControllerAxis::RightX;
|
||||||
|
case SDL_CONTROLLER_AXIS_RIGHTY: return ControllerAxis::RightY;
|
||||||
|
case SDL_CONTROLLER_AXIS_TRIGGERLEFT: return ControllerAxis::TriggerLeft;
|
||||||
|
case SDL_CONTROLLER_AXIS_TRIGGERRIGHT: return ControllerAxis::TriggerRight;
|
||||||
|
default: return ControllerAxis::Invalid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ControllerButton controllerButtonFromSdlControllerButton(uint8_t button) {
|
||||||
|
switch (button) {
|
||||||
|
case SDL_CONTROLLER_BUTTON_A: return ControllerButton::A;
|
||||||
|
case SDL_CONTROLLER_BUTTON_B: return ControllerButton::B;
|
||||||
|
case SDL_CONTROLLER_BUTTON_X: return ControllerButton::X;
|
||||||
|
case SDL_CONTROLLER_BUTTON_Y: return ControllerButton::Y;
|
||||||
|
case SDL_CONTROLLER_BUTTON_BACK: return ControllerButton::Back;
|
||||||
|
case SDL_CONTROLLER_BUTTON_GUIDE: return ControllerButton::Guide;
|
||||||
|
case SDL_CONTROLLER_BUTTON_START: return ControllerButton::Start;
|
||||||
|
case SDL_CONTROLLER_BUTTON_LEFTSTICK: return ControllerButton::LeftStick;
|
||||||
|
case SDL_CONTROLLER_BUTTON_RIGHTSTICK: return ControllerButton::RightStick;
|
||||||
|
case SDL_CONTROLLER_BUTTON_LEFTSHOULDER: return ControllerButton::LeftShoulder;
|
||||||
|
case SDL_CONTROLLER_BUTTON_RIGHTSHOULDER: return ControllerButton::RightShoulder;
|
||||||
|
case SDL_CONTROLLER_BUTTON_DPAD_UP: return ControllerButton::DPadUp;
|
||||||
|
case SDL_CONTROLLER_BUTTON_DPAD_DOWN: return ControllerButton::DPadDown;
|
||||||
|
case SDL_CONTROLLER_BUTTON_DPAD_LEFT: return ControllerButton::DPadLeft;
|
||||||
|
case SDL_CONTROLLER_BUTTON_DPAD_RIGHT: return ControllerButton::DPadRight;
|
||||||
|
case SDL_CONTROLLER_BUTTON_MISC1: return ControllerButton::Misc1;
|
||||||
|
case SDL_CONTROLLER_BUTTON_PADDLE1: return ControllerButton::Paddle1;
|
||||||
|
case SDL_CONTROLLER_BUTTON_PADDLE2: return ControllerButton::Paddle2;
|
||||||
|
case SDL_CONTROLLER_BUTTON_PADDLE3: return ControllerButton::Paddle3;
|
||||||
|
case SDL_CONTROLLER_BUTTON_PADDLE4: return ControllerButton::Paddle4;
|
||||||
|
case SDL_CONTROLLER_BUTTON_TOUCHPAD: return ControllerButton::Touchpad;
|
||||||
|
default: return ControllerButton::Invalid;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SdlPlatform {
|
class SdlPlatform {
|
||||||
@ -233,9 +244,9 @@ public:
|
|||||||
if (SDL_InitSubSystem(SDL_INIT_VIDEO))
|
if (SDL_InitSubSystem(SDL_INIT_VIDEO))
|
||||||
throw ApplicationException(strf("Couldn't initialize SDL Video: {}", SDL_GetError()));
|
throw ApplicationException(strf("Couldn't initialize SDL Video: {}", SDL_GetError()));
|
||||||
|
|
||||||
Logger::info("Application: Initializing SDL Joystick");
|
Logger::info("Application: Initializing SDL Controller");
|
||||||
if (SDL_InitSubSystem(SDL_INIT_JOYSTICK))
|
if (SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER))
|
||||||
throw ApplicationException(strf("Couldn't initialize SDL Joystick: {}", SDL_GetError()));
|
throw ApplicationException(strf("Couldn't initialize SDL Controller: {}", SDL_GetError()));
|
||||||
|
|
||||||
Logger::info("Application: Initializing SDL Sound");
|
Logger::info("Application: Initializing SDL Sound");
|
||||||
if (SDL_InitSubSystem(SDL_INIT_AUDIO))
|
if (SDL_InitSubSystem(SDL_INIT_AUDIO))
|
||||||
@ -585,7 +596,8 @@ private:
|
|||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
while (SDL_PollEvent(&event)) {
|
while (SDL_PollEvent(&event)) {
|
||||||
Maybe<InputEvent> starEvent;
|
Maybe<InputEvent> starEvent;
|
||||||
if (event.type == SDL_WINDOWEVENT) {
|
switch (event.type) {
|
||||||
|
case SDL_WINDOWEVENT:
|
||||||
if (event.window.event == SDL_WINDOWEVENT_MAXIMIZED || event.window.event == SDL_WINDOWEVENT_RESTORED) {
|
if (event.window.event == SDL_WINDOWEVENT_MAXIMIZED || event.window.event == SDL_WINDOWEVENT_RESTORED) {
|
||||||
auto windowFlags = SDL_GetWindowFlags(m_sdlWindow);
|
auto windowFlags = SDL_GetWindowFlags(m_sdlWindow);
|
||||||
|
|
||||||
@ -605,40 +617,71 @@ private:
|
|||||||
m_renderer->setScreenSize(m_windowSize);
|
m_renderer->setScreenSize(m_windowSize);
|
||||||
m_application->windowChanged(m_windowMode, m_windowSize);
|
m_application->windowChanged(m_windowMode, m_windowSize);
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
} else if (event.type == SDL_KEYDOWN) {
|
case SDL_KEYDOWN:
|
||||||
if (!event.key.repeat) {
|
if (!event.key.repeat) {
|
||||||
if (auto key = keyFromSdlKeyCode(event.key.keysym.sym))
|
if (auto key = keyFromSdlKeyCode(event.key.keysym.sym))
|
||||||
starEvent.set(KeyDownEvent{*key, keyModsFromSdlKeyMods(event.key.keysym.mod)});
|
starEvent.set(KeyDownEvent{*key, keyModsFromSdlKeyMods(event.key.keysym.mod)});
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
} else if (event.type == SDL_KEYUP) {
|
case SDL_KEYUP:
|
||||||
if (auto key = keyFromSdlKeyCode(event.key.keysym.sym))
|
if (auto key = keyFromSdlKeyCode(event.key.keysym.sym))
|
||||||
starEvent.set(KeyUpEvent{*key});
|
starEvent.set(KeyUpEvent{*key});
|
||||||
|
break;
|
||||||
} else if (event.type == SDL_TEXTINPUT) {
|
case SDL_TEXTINPUT:
|
||||||
starEvent.set(TextInputEvent{String(event.text.text)});
|
starEvent.set(TextInputEvent{String(event.text.text)});
|
||||||
|
break;
|
||||||
} else if (event.type == SDL_MOUSEMOTION) {
|
case SDL_MOUSEMOTION:
|
||||||
starEvent.set(MouseMoveEvent{
|
starEvent.set(MouseMoveEvent{
|
||||||
{event.motion.xrel, -event.motion.yrel}, {event.motion.x, (int)m_windowSize[1] - event.motion.y}});
|
{event.motion.xrel, -event.motion.yrel}, {event.motion.x, (int)m_windowSize[1] - event.motion.y}});
|
||||||
|
break;
|
||||||
} else if (event.type == SDL_MOUSEBUTTONDOWN) {
|
case SDL_MOUSEBUTTONDOWN:
|
||||||
starEvent.set(MouseButtonDownEvent{mouseButtonFromSdlMouseButton(event.button.button),
|
starEvent.set(MouseButtonDownEvent{mouseButtonFromSdlMouseButton(event.button.button),
|
||||||
{event.button.x, (int)m_windowSize[1] - event.button.y}});
|
{event.button.x, (int)m_windowSize[1] - event.button.y}});
|
||||||
|
break;
|
||||||
} else if (event.type == SDL_MOUSEBUTTONUP) {
|
case SDL_MOUSEBUTTONUP:
|
||||||
starEvent.set(MouseButtonUpEvent{mouseButtonFromSdlMouseButton(event.button.button),
|
starEvent.set(MouseButtonUpEvent{mouseButtonFromSdlMouseButton(event.button.button),
|
||||||
{event.button.x, (int)m_windowSize[1] - event.button.y}});
|
{event.button.x, (int)m_windowSize[1] - event.button.y}});
|
||||||
|
break;
|
||||||
} else if (event.type == SDL_MOUSEWHEEL) {
|
case SDL_MOUSEWHEEL:
|
||||||
int x, y;
|
int x, y;
|
||||||
SDL_GetMouseState(&x, &y);
|
SDL_GetMouseState(&x, &y);
|
||||||
starEvent.set(MouseWheelEvent{event.wheel.y < 0 ? MouseWheel::Down : MouseWheel::Up, {x, (int)m_windowSize[1] - y}});
|
starEvent.set(MouseWheelEvent{event.wheel.y < 0 ? MouseWheel::Down : MouseWheel::Up, {x, (int)m_windowSize[1] - y}});
|
||||||
|
break;
|
||||||
} else if (event.type == SDL_QUIT) {
|
case SDL_CONTROLLERAXISMOTION:
|
||||||
|
starEvent.set(ControllerAxisEvent{
|
||||||
|
(ControllerId)event.caxis.which,
|
||||||
|
controllerAxisFromSdlControllerAxis(event.caxis.axis),
|
||||||
|
(float)event.caxis.value / 32768.0f
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case SDL_CONTROLLERBUTTONDOWN:
|
||||||
|
starEvent.set(ControllerButtonDownEvent{ (ControllerId)event.cbutton.which, controllerButtonFromSdlControllerButton(event.cbutton.button) });
|
||||||
|
break;
|
||||||
|
case SDL_CONTROLLERBUTTONUP:
|
||||||
|
starEvent.set(ControllerButtonUpEvent{ (ControllerId)event.cbutton.which, controllerButtonFromSdlControllerButton(event.cbutton.button) });
|
||||||
|
break;
|
||||||
|
case SDL_CONTROLLERDEVICEADDED:
|
||||||
|
{
|
||||||
|
auto insertion = m_SdlControllers.insert_or_assign(event.cdevice.which, SDLGameControllerUPtr(SDL_GameControllerOpen(event.cdevice.which), SDL_GameControllerClose));
|
||||||
|
if (SDL_GameController* controller = insertion.first->second.get())
|
||||||
|
Logger::info("Controller device '{}' added", SDL_GameControllerName(controller));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SDL_CONTROLLERDEVICEREMOVED:
|
||||||
|
{
|
||||||
|
auto find = m_SdlControllers.find(event.cdevice.which);
|
||||||
|
if (find != m_SdlControllers.end()) {
|
||||||
|
if (SDL_GameController* controller = find->second.get())
|
||||||
|
Logger::info("Controller device '{}' removed", SDL_GameControllerName(controller));
|
||||||
|
m_SdlControllers.erase(event.cdevice.which);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SDL_QUIT:
|
||||||
m_quitRequested = true;
|
m_quitRequested = true;
|
||||||
starEvent.reset();
|
starEvent.reset();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (starEvent)
|
if (starEvent)
|
||||||
@ -744,6 +787,9 @@ private:
|
|||||||
SDL_GLContext m_sdlGlContext = nullptr;
|
SDL_GLContext m_sdlGlContext = nullptr;
|
||||||
SDL_AudioDeviceID m_sdlAudioDevice = 0;
|
SDL_AudioDeviceID m_sdlAudioDevice = 0;
|
||||||
|
|
||||||
|
typedef std::unique_ptr<SDL_GameController, decltype(&SDL_GameControllerClose)> SDLGameControllerUPtr;
|
||||||
|
StableHashMap<int, SDLGameControllerUPtr> m_SdlControllers;
|
||||||
|
|
||||||
typedef std::unique_ptr<SDL_Surface, decltype(&SDL_FreeSurface)> SDLSurfaceUPtr;
|
typedef std::unique_ptr<SDL_Surface, decltype(&SDL_FreeSurface)> SDLSurfaceUPtr;
|
||||||
typedef std::unique_ptr<SDL_Cursor, decltype(&SDL_FreeCursor)> SDLCursorUPtr;
|
typedef std::unique_ptr<SDL_Cursor, decltype(&SDL_FreeCursor)> SDLCursorUPtr;
|
||||||
struct CursorEntry {
|
struct CursorEntry {
|
||||||
|
@ -273,6 +273,16 @@ void ClientApplication::processInput(InputEvent const& event) {
|
|||||||
return KeyDownEvent{keyEvent.key, keyEvent.mods & ~*modKey};
|
return KeyDownEvent{keyEvent.key, keyEvent.mods & ~*modKey};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
else if (auto cAxis = event.ptr<ControllerAxisEvent>()) {
|
||||||
|
if (cAxis->controllerAxis == ControllerAxis::LeftX)
|
||||||
|
m_controllerLeftStick[0] = cAxis->controllerAxisValue;
|
||||||
|
else if (cAxis->controllerAxis == ControllerAxis::LeftY)
|
||||||
|
m_controllerLeftStick[1] = cAxis->controllerAxisValue;
|
||||||
|
else if (cAxis->controllerAxis == ControllerAxis::RightX)
|
||||||
|
m_controllerRightStick[0] = cAxis->controllerAxisValue;
|
||||||
|
else if (cAxis->controllerAxis == ControllerAxis::RightY)
|
||||||
|
m_controllerRightStick[1] = cAxis->controllerAxisValue;
|
||||||
|
}
|
||||||
|
|
||||||
if (!m_errorScreen->accepted() && m_errorScreen->handleInputEvent(event))
|
if (!m_errorScreen->accepted() && m_errorScreen->handleInputEvent(event))
|
||||||
return;
|
return;
|
||||||
@ -755,6 +765,11 @@ void ClientApplication::updateRunning() {
|
|||||||
m_player->addEmote(HumanoidEmote::Sleep);
|
m_player->addEmote(HumanoidEmote::Sleep);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_controllerLeftStick.magnitudeSquared() > 0.001f)
|
||||||
|
m_player->setMoveVector(m_controllerLeftStick);
|
||||||
|
else
|
||||||
|
m_player->setMoveVector(Vec2F());
|
||||||
|
|
||||||
auto checkDisconnection = [this]() {
|
auto checkDisconnection = [this]() {
|
||||||
if (!m_universeClient->isConnected()) {
|
if (!m_universeClient->isConnected()) {
|
||||||
m_cinematicOverlay->stop();
|
m_cinematicOverlay->stop();
|
||||||
|
@ -105,6 +105,8 @@ private:
|
|||||||
int m_maxInterfaceScale = 3;
|
int m_maxInterfaceScale = 3;
|
||||||
Vec2F m_crossoverRes;
|
Vec2F m_crossoverRes;
|
||||||
|
|
||||||
|
Vec2F m_controllerLeftStick;
|
||||||
|
Vec2F m_controllerRightStick;
|
||||||
List<KeyDownEvent> m_heldKeyEvents;
|
List<KeyDownEvent> m_heldKeyEvents;
|
||||||
List<KeyDownEvent> m_edgeKeyEvents;
|
List<KeyDownEvent> m_edgeKeyEvents;
|
||||||
|
|
||||||
|
@ -446,6 +446,7 @@ ActorMovementController::ActorMovementController(ActorMovementParameters const&
|
|||||||
m_lastControlJump = false;
|
m_lastControlJump = false;
|
||||||
m_lastControlDown = false;
|
m_lastControlDown = false;
|
||||||
m_targetHorizontalAmbulatingVelocity = 0.0f;
|
m_targetHorizontalAmbulatingVelocity = 0.0f;
|
||||||
|
m_moveSpeedMultiplier = 1.0f;
|
||||||
|
|
||||||
resetBaseParameters(parameters);
|
resetBaseParameters(parameters);
|
||||||
}
|
}
|
||||||
@ -696,6 +697,10 @@ Maybe<pair<Vec2F, bool>> ActorMovementController::controlPathMove(Vec2F const& p
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ActorMovementController::setMoveSpeedMultiplier(float scale) {
|
||||||
|
m_moveSpeedMultiplier = scale;
|
||||||
|
}
|
||||||
|
|
||||||
void ActorMovementController::clearControls() {
|
void ActorMovementController::clearControls() {
|
||||||
m_controlRotationRate = 0.0f;
|
m_controlRotationRate = 0.0f;
|
||||||
m_controlAcceleration = Vec2F();
|
m_controlAcceleration = Vec2F();
|
||||||
@ -951,6 +956,8 @@ void ActorMovementController::tickMaster() {
|
|||||||
: *activeParameters.walkSpeed * activeModifiers.speedModifier);
|
: *activeParameters.walkSpeed * activeModifiers.speedModifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_targetHorizontalAmbulatingVelocity *= m_moveSpeedMultiplier;
|
||||||
|
|
||||||
if (m_liquidMovement.get())
|
if (m_liquidMovement.get())
|
||||||
m_targetHorizontalAmbulatingVelocity *= (1.0f - liquidImpedance);
|
m_targetHorizontalAmbulatingVelocity *= (1.0f - liquidImpedance);
|
||||||
|
|
||||||
@ -1102,7 +1109,7 @@ void ActorMovementController::doSetAnchorState(Maybe<EntityAnchorState> anchorSt
|
|||||||
if (m_entityAnchor)
|
if (m_entityAnchor)
|
||||||
setPosition(m_entityAnchor->position);
|
setPosition(m_entityAnchor->position);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PathController::PathController(World* world)
|
PathController::PathController(World* world)
|
||||||
: m_world(world), m_edgeTimer(0.0) { }
|
: m_world(world), m_edgeTimer(0.0) { }
|
||||||
|
@ -239,6 +239,9 @@ public:
|
|||||||
Maybe<pair<Vec2F, bool>> pathMove(Vec2F const& pathPosition, bool run = false, Maybe<PlatformerAStar::Parameters> const& parameters = {});
|
Maybe<pair<Vec2F, bool>> pathMove(Vec2F const& pathPosition, bool run = false, Maybe<PlatformerAStar::Parameters> const& parameters = {});
|
||||||
Maybe<pair<Vec2F, bool>> controlPathMove(Vec2F const& pathPosition, bool run = false, Maybe<PlatformerAStar::Parameters> const& parameters = {});
|
Maybe<pair<Vec2F, bool>> controlPathMove(Vec2F const& pathPosition, bool run = false, Maybe<PlatformerAStar::Parameters> const& parameters = {});
|
||||||
|
|
||||||
|
// Used for user controller input.
|
||||||
|
void setMoveSpeedMultiplier(float multiplier = 1.0f);
|
||||||
|
|
||||||
// Clears all control data.
|
// Clears all control data.
|
||||||
void clearControls();
|
void clearControls();
|
||||||
|
|
||||||
@ -248,6 +251,7 @@ public:
|
|||||||
|
|
||||||
void tickSlave();
|
void tickSlave();
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct ApproachVelocityCommand {
|
struct ApproachVelocityCommand {
|
||||||
Vec2F targetVelocity;
|
Vec2F targetVelocity;
|
||||||
@ -313,6 +317,7 @@ private:
|
|||||||
int m_fallThroughSustain;
|
int m_fallThroughSustain;
|
||||||
bool m_lastControlJump;
|
bool m_lastControlJump;
|
||||||
bool m_lastControlDown;
|
bool m_lastControlDown;
|
||||||
|
float m_moveSpeedMultiplier;
|
||||||
|
|
||||||
GameTimer m_reJumpTimer;
|
GameTimer m_reJumpTimer;
|
||||||
Maybe<GameTimer> m_jumpHoldTimer;
|
Maybe<GameTimer> m_jumpHoldTimer;
|
||||||
|
@ -669,6 +669,10 @@ void Player::special(int specialKey) {
|
|||||||
m_techController->special(specialKey);
|
m_techController->special(specialKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Player::setMoveVector(Vec2F const& vec) {
|
||||||
|
m_moveVector = vec;
|
||||||
|
}
|
||||||
|
|
||||||
void Player::moveLeft() {
|
void Player::moveLeft() {
|
||||||
m_pendingMoves.add(MoveControlType::Left);
|
m_pendingMoves.add(MoveControlType::Left);
|
||||||
}
|
}
|
||||||
@ -1543,6 +1547,24 @@ void Player::disableInterpolation() {
|
|||||||
|
|
||||||
void Player::processControls() {
|
void Player::processControls() {
|
||||||
bool run = !m_shifting && !m_statusController->statPositive("encumberance");
|
bool run = !m_shifting && !m_statusController->statPositive("encumberance");
|
||||||
|
|
||||||
|
bool useMoveVector = m_moveVector.x() != 0.0f;
|
||||||
|
if (useMoveVector) {
|
||||||
|
for (auto move : m_pendingMoves) {
|
||||||
|
if (move == MoveControlType::Left || move == MoveControlType::Right) {
|
||||||
|
useMoveVector = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (useMoveVector) {
|
||||||
|
m_pendingMoves.insert(signbit(m_moveVector.x()) ? MoveControlType::Left : MoveControlType::Right);
|
||||||
|
m_movementController->setMoveSpeedMultiplier(clamp(abs(m_moveVector.x()), 0.0f, 1.0f));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m_movementController->setMoveSpeedMultiplier(1.0f);
|
||||||
|
|
||||||
if (auto fireableMain = as<FireableItem>(m_tools->primaryHandItem())) {
|
if (auto fireableMain = as<FireableItem>(m_tools->primaryHandItem())) {
|
||||||
if (fireableMain->inUse() && fireableMain->walkWhileFiring())
|
if (fireableMain->inUse() && fireableMain->walkWhileFiring())
|
||||||
run = false;
|
run = false;
|
||||||
@ -1621,6 +1643,7 @@ void Player::processControls() {
|
|||||||
|
|
||||||
void Player::processStateChanges() {
|
void Player::processStateChanges() {
|
||||||
if (isMaster()) {
|
if (isMaster()) {
|
||||||
|
|
||||||
// Set the current player state based on what movement controller tells us
|
// Set the current player state based on what movement controller tells us
|
||||||
// we're doing and do some state transition logic
|
// we're doing and do some state transition logic
|
||||||
State oldState = m_state;
|
State oldState = m_state;
|
||||||
@ -1662,6 +1685,9 @@ void Player::processStateChanges() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_moveVector.x() != 0.0f && (m_state == State::Run || m_state == State::Walk))
|
||||||
|
m_state = abs(m_moveVector.x()) > 0.5f ? State::Run : State::Walk;
|
||||||
|
|
||||||
if (m_state == State::Jump && (oldState == State::Idle || oldState == State::Run || oldState == State::Walk || oldState == State::Crouch))
|
if (m_state == State::Jump && (oldState == State::Idle || oldState == State::Run || oldState == State::Walk || oldState == State::Crouch))
|
||||||
m_effectsAnimator->burstParticleEmitter("jump");
|
m_effectsAnimator->burstParticleEmitter("jump");
|
||||||
|
|
||||||
|
@ -132,6 +132,7 @@ public:
|
|||||||
void setShifting(bool shifting);
|
void setShifting(bool shifting);
|
||||||
void special(int specialKey);
|
void special(int specialKey);
|
||||||
|
|
||||||
|
void setMoveVector(Vec2F const& vec);
|
||||||
void moveLeft();
|
void moveLeft();
|
||||||
void moveRight();
|
void moveRight();
|
||||||
void moveUp();
|
void moveUp();
|
||||||
@ -505,6 +506,7 @@ private:
|
|||||||
Vec2F m_blinkInterval;
|
Vec2F m_blinkInterval;
|
||||||
|
|
||||||
HashSet<MoveControlType> m_pendingMoves;
|
HashSet<MoveControlType> m_pendingMoves;
|
||||||
|
Vec2F m_moveVector;
|
||||||
bool m_shifting;
|
bool m_shifting;
|
||||||
ActorMovementParameters m_zeroGMovementParameters;
|
ActorMovementParameters m_zeroGMovementParameters;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user