1 /* ScummVM - Graphic Adventure Engine 2 * 3 * ScummVM is the legal property of its developers, whose names 4 * are too numerous to list here. Please refer to the COPYRIGHT 5 * file distributed with this source distribution. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 */ 22 23 #ifndef COMMON_HARDWARE_KEY_H 24 #define COMMON_HARDWARE_KEY_H 25 26 #include "common/scummsys.h" 27 28 #include "common/array.h" 29 #include "common/events.h" 30 #include "common/keyboard.h" 31 #include "common/str.h" 32 33 namespace Common { 34 35 typedef uint32 HardwareInputCode; 36 37 enum HardwareInputType { 38 /** Empty / invalid input type */ 39 kHardwareInputTypeInvalid, 40 /** Keyboard input that sends -up and -down events */ 41 kHardwareInputTypeKeyboard, 42 /** Mouse input that sends -up and -down events */ 43 kHardwareInputTypeMouse, 44 /** Joystick input that sends -up and -down events */ 45 kHardwareInputTypeJoystickButton, 46 /** Joystick input that sends "analog" values */ 47 kHardwareInputTypeJoystickHalfAxis, 48 /** Input that sends single events */ 49 kHardwareInputTypeCustom 50 }; 51 52 /** 53 * Describes an available hardware input 54 */ 55 struct HardwareInput { 56 /** unique id used for saving/loading to config */ 57 String id; 58 59 /** Human readable description */ 60 U32String description; 61 62 /** Type tag */ 63 HardwareInputType type; 64 65 /** 66 * A platform specific unique identifier for an input event 67 * generated when this input is triggered. 68 * This is only relevant when type == kHardwareInputTypeGeneric 69 */ 70 HardwareInputCode inputCode; 71 72 /** 73 * The KeyState that is generated by the back-end 74 * when this hardware key is pressed. 75 * This is only relevant when type == kHardwareInputTypeKeyboard 76 */ 77 KeyState key; 78 HardwareInputHardwareInput79 HardwareInput() 80 : inputCode(0), type(kHardwareInputTypeInvalid) { } 81 createCustomHardwareInput82 static HardwareInput createCustom(const String &i, HardwareInputCode ic, const U32String &desc) { 83 return createSimple(kHardwareInputTypeCustom, i, ic, desc); 84 } 85 createKeyboardHardwareInput86 static HardwareInput createKeyboard(const String &i, KeyState ky, const U32String &desc) { 87 HardwareInput hardwareInput; 88 hardwareInput.id = i; 89 hardwareInput.description = desc; 90 hardwareInput.type = kHardwareInputTypeKeyboard; 91 hardwareInput.inputCode = 0; 92 hardwareInput.key = ky; 93 return hardwareInput; 94 } 95 createJoystickButtonHardwareInput96 static HardwareInput createJoystickButton(const String &i, uint8 button, const U32String &desc) { 97 return createSimple(kHardwareInputTypeJoystickButton, i, button, desc); 98 } 99 createJoystickHalfAxisHardwareInput100 static HardwareInput createJoystickHalfAxis(const String &i, uint8 axis, bool positiveHalf, const U32String &desc) { 101 return createSimple(kHardwareInputTypeJoystickHalfAxis, i, axis * 2 + (positiveHalf ? 1 : 0), desc); 102 } 103 createMouseHardwareInput104 static HardwareInput createMouse(const String &i, uint8 button, const U32String &desc) { 105 return createSimple(kHardwareInputTypeMouse, i, button, desc); 106 } 107 108 private: createSimpleHardwareInput109 static HardwareInput createSimple(HardwareInputType type, const String &i, HardwareInputCode ic, const U32String &desc) { 110 HardwareInput hardwareInput; 111 hardwareInput.id = i; 112 hardwareInput.description = desc; 113 hardwareInput.type = type; 114 hardwareInput.inputCode = ic; 115 return hardwareInput; 116 } 117 }; 118 119 /** 120 * Entry in a static table of custom backend hardware inputs 121 */ 122 struct HardwareInputTableEntry { 123 const char *hwId; 124 HardwareInputCode code; 125 const char *desc; 126 findWithCodeHardwareInputTableEntry127 static const HardwareInputTableEntry *findWithCode(const HardwareInputTableEntry *_entries, HardwareInputCode code) { 128 for (const HardwareInputTableEntry *hw = _entries; hw->hwId; hw++) { 129 if (hw->code == code) { 130 return hw; 131 } 132 } 133 return nullptr; 134 } 135 findWithIdHardwareInputTableEntry136 static const HardwareInputTableEntry *findWithId(const HardwareInputTableEntry *_entries, const String &id) { 137 for (const HardwareInputTableEntry *hw = _entries; hw->hwId; hw++) { 138 if (id.equals(hw->hwId)) { 139 return hw; 140 } 141 } 142 return nullptr; 143 } 144 }; 145 146 /** 147 * Entry in a static table of available non-modifier keys 148 */ 149 struct KeyTableEntry { 150 const char *hwId; 151 KeyCode keycode; 152 const char *desc; 153 }; 154 155 /** 156 * Entry in a static table of available key modifiers 157 */ 158 struct ModifierTableEntry { 159 byte flag; 160 const char *id; 161 const char *desc; 162 }; 163 164 enum AxisType { 165 /** An axis that sends "analog" values from JOYAXIS_MIN to JOYAXIS_MAX. e.g. a gamepad stick axis */ 166 kAxisTypeFull, 167 /** An axis that sends "analog" values from 0 to JOYAXIS_MAX. e.g. a gamepad trigger */ 168 kAxisTypeHalf 169 }; 170 171 struct AxisTableEntry { 172 const char *hwId; 173 HardwareInputCode code; 174 AxisType type; 175 const char *desc; 176 findWithCodeAxisTableEntry177 static const AxisTableEntry *findWithCode(const AxisTableEntry *_entries, HardwareInputCode code) { 178 for (const AxisTableEntry *hw = _entries; hw->hwId; hw++) { 179 if (hw->code == code) { 180 return hw; 181 } 182 } 183 return nullptr; 184 } 185 findWithIdAxisTableEntry186 static const AxisTableEntry *findWithId(const AxisTableEntry *_entries, const String &id) { 187 for (const AxisTableEntry *hw = _entries; hw->hwId; hw++) { 188 if (id.equals(hw->hwId)) { 189 return hw; 190 } 191 } 192 return nullptr; 193 } 194 }; 195 196 197 /** 198 * Interface for querying information about a hardware input device 199 */ 200 class HardwareInputSet { 201 public: 202 virtual ~HardwareInputSet(); 203 204 /** 205 * Retrieve a hardware input description from an unique identifier 206 * 207 * In case no input was found with the specified id, an empty 208 * HardwareInput structure is return with the type set to 209 * kHardwareInputTypeInvalid. 210 */ 211 virtual HardwareInput findHardwareInput(const String &id) const = 0; 212 213 /** 214 * Retrieve a hardware input description from one of the events 215 * produced when the input is triggered. 216 * 217 * In case the specified event is not produced by this device, 218 * an empty HardwareInput structure is return with the type set to 219 * kHardwareInputTypeInvalid. 220 */ 221 virtual HardwareInput findHardwareInput(const Event &event) const = 0; 222 }; 223 224 /** 225 * A keyboard input device 226 * 227 * Describes the keys and key + modifiers combinations as HardwareInputs 228 */ 229 class KeyboardHardwareInputSet : public HardwareInputSet { 230 public: 231 KeyboardHardwareInputSet(const KeyTableEntry *keys, const ModifierTableEntry *modifiers); 232 233 // HardwareInputSet API 234 HardwareInput findHardwareInput(const String &id) const override; 235 HardwareInput findHardwareInput(const Event &event) const override; 236 237 /** Transform a keystate into a canonical form that can be used to unambiguously identify the keypress */ 238 static KeyState normalizeKeyState(const KeyState &keystate); 239 240 private: 241 const KeyTableEntry *_keys; 242 const ModifierTableEntry *_modifiers; 243 }; 244 245 /** 246 * A mouse input device 247 * 248 * Describes the mouse buttons 249 */ 250 class MouseHardwareInputSet : public HardwareInputSet { 251 public: 252 MouseHardwareInputSet(const HardwareInputTableEntry *buttonEntries); 253 254 // HardwareInputSet API 255 HardwareInput findHardwareInput(const String &id) const override; 256 HardwareInput findHardwareInput(const Event &event) const override; 257 258 private: 259 const HardwareInputTableEntry *_buttonEntries; 260 }; 261 262 /** 263 * A joystick input device 264 */ 265 class JoystickHardwareInputSet : public HardwareInputSet { 266 public: 267 JoystickHardwareInputSet(const HardwareInputTableEntry *buttonEntries, const AxisTableEntry *axisEntries); 268 269 // HardwareInputSet API 270 HardwareInput findHardwareInput(const String &id) const override; 271 HardwareInput findHardwareInput(const Event &event) const override; 272 273 private: 274 const HardwareInputTableEntry *_buttonEntries; 275 const AxisTableEntry *_axisEntries; 276 }; 277 278 /** 279 * A custom backend input device 280 * 281 * @todo This is currently unused. Perhaps it should be removed. 282 */ 283 class CustomHardwareInputSet : public HardwareInputSet { 284 public: 285 CustomHardwareInputSet(const HardwareInputTableEntry *hardwareEntries); 286 287 // HardwareInputSet API 288 HardwareInput findHardwareInput(const String &id) const override; 289 HardwareInput findHardwareInput(const Event &event) const override; 290 291 private: 292 const HardwareInputTableEntry *_hardwareEntries; 293 }; 294 295 /** 296 * A composite input device that delegates to a set of actual input devices. 297 */ 298 class CompositeHardwareInputSet : public HardwareInputSet { 299 public: 300 ~CompositeHardwareInputSet() override; 301 302 // HardwareInputSet API 303 HardwareInput findHardwareInput(const String &id) const override; 304 HardwareInput findHardwareInput(const Event &event) const override; 305 306 /** 307 * Add an input device to this composite device 308 * 309 * Takes ownership of the hardware input set 310 */ 311 void addHardwareInputSet(HardwareInputSet *hardwareInputSet); 312 313 private: 314 Array<HardwareInputSet *> _inputSets; 315 }; 316 317 /** A standard set of keyboard keys */ 318 extern const KeyTableEntry defaultKeys[]; 319 320 /** A standard set of keyboard modifiers */ 321 extern const ModifierTableEntry defaultModifiers[]; 322 323 /** A standard set of mouse buttons */ 324 extern const HardwareInputTableEntry defaultMouseButtons[]; 325 326 /** A standard set of joystick buttons based on the ScummVM event model */ 327 extern const HardwareInputTableEntry defaultJoystickButtons[]; 328 329 /** A standard set of joystick axes based on the ScummVM event model */ 330 extern const AxisTableEntry defaultJoystickAxes[]; 331 332 } // End of namespace Common 333 334 #endif // #ifndef COMMON_HARDWARE_KEY_H 335