summaryrefslogtreecommitdiff
path: root/indra/llwindow/llgamecontrol.h
diff options
context:
space:
mode:
authorLeviathan Linden <leviathan@lindenlab.com>2023-11-16 13:53:37 -0800
committerAndrew Meadows <andrew.l.meadows@gmail.com>2024-10-03 09:01:12 -0700
commited6ecca2a45e52d9be1d91107b9643b5ecdfb8bf (patch)
tree2b9d241bf5cb0520de13ee10f729d2b58278ce33 /indra/llwindow/llgamecontrol.h
parent13221f67c465017f44ca46aeca23b0d820935825 (diff)
avatar_motion-->GameControl translation and flycam
Diffstat (limited to 'indra/llwindow/llgamecontrol.h')
-rw-r--r--indra/llwindow/llgamecontrol.h156
1 files changed, 142 insertions, 14 deletions
diff --git a/indra/llwindow/llgamecontrol.h b/indra/llwindow/llgamecontrol.h
index fe6d6f0138..50cb78a4ea 100644
--- a/indra/llwindow/llgamecontrol.h
+++ b/indra/llwindow/llgamecontrol.h
@@ -33,6 +33,36 @@
#include "llsingleton.h"
#include "stdtypes.h"
+// For reference, here are the RAW indices of the various input channels
+// of a standard XBox controller. Button (N) is numbered in parentheses,
+// whereas axisN has N+ and N- labels.
+//
+// leftpaddle rightpaddle
+// _______ _______
+// / 4+ '-. .-' 5+ \
+// leftshoulder _(9)_________'-.____ ____.-'_________(10) rightshoulder
+// / _________ \_________/ \
+// / / 1- \ (3) \
+// | | | (4) (5) (6) Y |
+// | |0- (7) 0+| _________ (2)X B(1) |
+// | | | / 3- \ A |
+// | | 1+ | | | (0) |
+// | \_________/ |2- (8) 2+| |
+// | leftstick (11) | | |
+// | (13) (14) | 3+ | |
+// | (12) \_________/ |
+// | d-pad rightstick |
+// | ____________________ |
+// | / \ |
+// | / \ |
+// | / \ |
+// \__________/ \__________/
+//
+// Note: the analog joystics provide NEGATIVE X,Y values for LEFT,FORWARD
+// whereas those directions are actually POSITIVE in SL's local right-handed
+// reference frame. This is why we implicitly negate those axes the moment
+// they are extracted from SDL, before being used anywhere. See the
+// implementation in LLGameControllerManager::onAxis().
// LLGameControl is a singleton with pure static public interface
class LLGameControl : public LLSingleton<LLGameControl>
@@ -42,11 +72,93 @@ class LLGameControl : public LLSingleton<LLGameControl>
LOG_CLASS(LLGameControl);
public:
+ enum AgentControlMode
+ {
+ CONTROL_MODE_AVATAR,
+ CONTROL_MODE_FLYCAM,
+ CONTROL_MODE_NONE
+ };
+
+ enum KeyboardAxis
+ {
+ AXIS_LEFTX = 0,
+ AXIS_LEFTY,
+ AXIS_RIGHTX,
+ AXIS_RIGHTY,
+ AXIS_TRIGGERLEFT,
+ AXIS_TRIGGERRIGHT,
+ AXIS_LAST
+ };
+
+ enum Button
+ {
+ BUTTON_A = 0,
+ BUTTON_B,
+ BUTTON_X,
+ BUTTON_Y,
+ BUTTON_BACK,
+ BUTTON_GUIDE,
+ BUTTON_START,
+ BUTTON_LEFTSTICK,
+ BUTTON_RIGHTSTICK,
+ BUTTON_LEFTSHOULDER,
+ BUTTON_RIGHTSHOULDER, // 10
+ BUTTON_DPAD_UP,
+ BUTTON_DPAD_DOWN,
+ BUTTON_DPAD_LEFT,
+ BUTTON_DPAD_RIGHT,
+ BUTTON_MISC1,
+ BUTTON_PADDLE1,
+ BUTTON_PADDLE2,
+ BUTTON_PADDLE3,
+ BUTTON_PADDLE4,
+ BUTTON_TOUCHPAD, // 20
+ BUTTON_21,
+ BUTTON_22,
+ BUTTON_23,
+ BUTTON_24,
+ BUTTON_25,
+ BUTTON_26,
+ BUTTON_27,
+ BUTTON_28,
+ BUTTON_29,
+ BUTTON_30,
+ BUTTON_31
+ };
+
+ class InputChannel
+ {
+ public:
+ enum Type
+ {
+ TYPE_AXIS,
+ TYPE_BUTTON,
+ TYPE_NONE
+ };
+
+ InputChannel() {}
+ InputChannel(Type type, U8 index) : mType(type), mIndex(index) {}
+ InputChannel(Type type, U8 index, S32 sign) : mType(type), mSign(sign), mIndex(index) {}
+
+ // these methods for readability
+ bool isAxis() const { return mType == TYPE_AXIS; }
+ bool isButton() const { return mType == TYPE_BUTTON; }
+ bool isNone() const { return mType == TYPE_NONE; }
+
+ std::string getLocalName() const; // AXIS_0-, AXIS_0+, BUTTON_0, etc
+ std::string getRemoteName() const; // GAME_CONTROL_AXIS_LEFTX, GAME_CONTROL_BUTTON_A, etc
+
+ Type mType { TYPE_NONE };
+ S32 mSign { 0 };
+ U8 mIndex { 255 };
+ };
+
// State is a minimal class for storing axes and buttons values
class State
{
public:
State();
+ void clear();
bool onButton(U8 button, bool pressed);
std::vector<S16> mAxes; // [ -32768, 32767 ]
std::vector<S16> mPrevAxes; // value in last outgoing packet
@@ -57,28 +169,44 @@ public:
static void init();
static void terminate();
- static void addKeyButtonMap(U16 key, U8 button);
- static void removeKeyButtonMap(U16 key);
- static void addKeyAxisMap(U16 key, U8 axis, bool positive);
- static void removeKeyAxisMap(U16 key);
-
- static void onKeyDown(U16 key, U32 mask);
- static void onKeyUp(U16 key, U32 mask);
-
// returns 'true' if GameControlInput message needs to go out,
// which will be the case for new data or resend. Call this right
// before deciding to put a GameControlInput packet on the wire
// or not.
- static bool computeFinalInputAndCheckForChanges();
+ static bool computeFinalStateAndCheckForChanges();
- static void clearAllInput();
- static void clearAllKeys();
+ static void clearAllState();
static void processEvents(bool app_has_focus = true);
static const State& getState();
-
- static void setIncludeKeyboardButtons(bool include);
- static bool getIncludeKeyboardButtons();
+ static void getCameraInputs(std::vector<F32>& inputs_out);
+
+ // these methods for accepting input from keyboard
+ static void enableSendToServer(bool enable);
+ static void enableControlAgent(bool enable);
+ static void enableTranslateAgentActions(bool enable);
+ static void setAgentControlMode(AgentControlMode mode);
+
+ static bool willSendToServer();
+ static bool willTranslateAgentActions();
+ static bool willControlAvatar();
+ static bool willControlFlycam();
+ //static LocalControlMode getLocalControlMode();
+
+ // Given a name like "AXIS_1-" or "BUTTON_5" returns the corresponding InputChannel
+ // If the axis name lacks the +/- postfix it assumes '+' postfix.
+ static LLGameControl::InputChannel getChannelByName(const std::string& name);
+
+ // action_name = push+, strafe-, etc
+ static LLGameControl::InputChannel getChannelByActionName(const std::string& name);
+
+ static bool updateActionMap(const std::string& action_name, LLGameControl::InputChannel channel);
+
+ // Keyboard presses produce action_flags which can be translated into State
+ // and game_control devices produce State which can be translated into action_flags.
+ // These methods help exchange such translations.
+ static U32 computeInternalActionFlags();
+ static void setExternalActionFlags(U32 action_flags);
// call this after putting a GameControlInput packet on the wire
static void updateResendPeriod();