From f9c4ed076157c78fd131f83c5d0f3bc4c95ae13a Mon Sep 17 00:00:00 2001 From: Jack Andersen Date: Fri, 28 Aug 2015 15:30:21 -1000 Subject: [PATCH] Dolphin controller updates --- include/boo/IWindow.hpp | 6 + include/boo/inputdev/DolphinSmashAdapter.hpp | 38 +++-- lib/inputdev/DolphinSmashAdapter.cpp | 141 +++++++++++++++++-- 3 files changed, 165 insertions(+), 20 deletions(-) diff --git a/include/boo/IWindow.hpp b/include/boo/IWindow.hpp index d63c9d3..43a9684 100644 --- a/include/boo/IWindow.hpp +++ b/include/boo/IWindow.hpp @@ -35,6 +35,12 @@ public: { double delta[2]; bool isFine; /* Use system-scale fine-scroll (for scrollable-trackpads) */ + + SScrollDelta operator+(const SScrollDelta& other) + {return {{delta[0] + other.delta[0], delta[1] + other.delta[1]}, isFine || other.isFine};} + SScrollDelta& operator+=(const SScrollDelta& other) + {delta[0] += other.delta[0]; delta[1] += other.delta[1]; isFine |= other.isFine; return *this;} + void zeroOut() {delta[0] = 0.0; delta[1] = 0.0;} }; enum ESpecialKey diff --git a/include/boo/inputdev/DolphinSmashAdapter.hpp b/include/boo/inputdev/DolphinSmashAdapter.hpp index 24a618b..e68ae1d 100644 --- a/include/boo/inputdev/DolphinSmashAdapter.hpp +++ b/include/boo/inputdev/DolphinSmashAdapter.hpp @@ -32,26 +32,38 @@ enum EDolphinControllerButtons struct DolphinControllerState { - uint8_t m_leftStick[2]; - uint8_t m_rightStick[2]; - uint8_t m_analogTriggers[2]; - uint16_t m_btns; + int8_t m_leftStick[2] = {0}; + int8_t m_rightStick[2] = {0}; + uint8_t m_analogTriggers[2] = {0}; + uint16_t m_btns = 0; + void reset() + { + m_leftStick[0] = 0; + m_leftStick[1] = 0; + m_rightStick[0] = 0; + m_rightStick[1] = 0; + m_analogTriggers[0] = 0; + m_analogTriggers[1] = 0; + m_btns = 0; + } + void clamp(); }; struct IDolphinSmashAdapterCallback { virtual void controllerConnected(unsigned idx, EDolphinControllerType type) {(void)idx;(void)type;} - virtual void controllerDisconnected(unsigned idx, EDolphinControllerType type) {(void)idx;(void)type;} + virtual void controllerDisconnected(unsigned idx) {(void)idx;} virtual void controllerUpdate(unsigned idx, EDolphinControllerType type, const DolphinControllerState& state) {(void)idx;(void)type;(void)state;} }; class DolphinSmashAdapter final : public DeviceBase { - IDolphinSmashAdapterCallback* m_callback; - uint8_t m_knownControllers; - uint8_t m_rumbleRequest; - uint8_t m_rumbleState; + IDolphinSmashAdapterCallback* m_callback = nullptr; + uint8_t m_knownControllers = 0; + uint8_t m_rumbleRequest = 0; + bool m_hardStop[4] = {false}; + uint8_t m_rumbleState = 0; void deviceDisconnected(); void initialCycle(); void transferCycle(); @@ -60,10 +72,12 @@ public: DolphinSmashAdapter(DeviceToken* token); ~DolphinSmashAdapter(); - inline void setCallback(IDolphinSmashAdapterCallback* cb) + void setCallback(IDolphinSmashAdapterCallback* cb) {m_callback = cb; m_knownControllers = 0;} - inline void startRumble(unsigned idx) {if (idx >= 4) return; m_rumbleRequest |= 1<= 4) return; m_rumbleRequest &= ~(1<= 4) return; m_rumbleRequest |= 1<= 4) return; m_rumbleRequest &= ~(1<controllerDisconnected(i, type); + m_callback->controllerDisconnected(i); } if (m_knownControllers & 1<controllerUpdate(i, type, state); @@ -102,7 +98,14 @@ void DolphinSmashAdapter::transferCycle() { uint8_t rumbleMessage[5] = {0x11}; for (int i=0 ; i<4 ; ++i) - rumbleMessage[i+1] = (rumbleReq & 1<controllerDisconnected(i); + } + } +} + +/* The following code is derived from pad.c in libogc + * + * Copyright (C) 2004 - 2009 + * Michael Wiedenbauer (shagkur) + * Dave Murphy (WinterMute) + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any + * damages arising from the use of this software. + * + * Permission is granted to anyone to use this software for any + * purpose, including commercial applications, and to alter it and + * redistribute it freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you + * must not claim that you wrote the original software. If you use + * this software in a product, an acknowledgment in the product + * documentation would be appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and + * must not be misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source + * distribution. + */ + +static uint8_t pad_clampregion[8] = {30, 180, 15, 72, 40, 15, 59, 31}; + +static void pad_clampstick(int8_t& px, int8_t& py, int8_t max, int8_t xy, int8_t min) +{ + int32_t x, y, signX, signY, d; + + x = px; + y = py; + + if (x >= 0) + signX = 1; + else + { + signX = -1; + x = -x; + } + + if (y >= 0) + signY = 1; + else + { + signY = -1; + y = -y; + } + + if (x <= min) + x = 0; + else + x -= min; + + if (y <= min) + y = 0; + else + y -= min; + + if (x || y) + { + int32_t xx, yy, maxy; + + xx = x * xy; + yy = y * xy; + maxy = max * xy; + if (yy <= xx) + { + d = (x * xy + (y * (max - xy))); + if (maxy < d) + { + x *= maxy / d; + y *= maxy / d; + } + } + else + { + d = (y * xy + (x * (max - xy))); + if (maxy < d) + { + x *= maxy / d; + y *= maxy / d; + } + } + px = int8_t(x * signX); + py = int8_t(y * signY); + } + else + px = py = 0; +} + +static void pad_clamptrigger(uint8_t& trigger) +{ + uint8_t min, max; + + min = pad_clampregion[0]; + max = pad_clampregion[1]; + if (min > trigger) + trigger = 0; + else if (max < trigger) + trigger = max - min; + else + trigger -= min; +} + +void DolphinControllerState::clamp() +{ + pad_clampstick(m_leftStick[0], m_leftStick[1], pad_clampregion[3], pad_clampregion[4], pad_clampregion[2]); + pad_clampstick(m_rightStick[0], m_rightStick[1], pad_clampregion[6], pad_clampregion[7], pad_clampregion[5]); + pad_clamptrigger(m_analogTriggers[0]); + pad_clamptrigger(m_analogTriggers[1]); } }