00001 /* 00002 * gamepad-map.h 00003 * 00004 * Copyright (C) 2008-2010 Thomas A. Vaughan 00005 * All rights reserved. 00006 * 00007 * 00008 * Redistribution and use in source and binary forms, with or without 00009 * modification, are permitted provided that the following conditions are met: 00010 * * Redistributions of source code must retain the above copyright 00011 * notice, this list of conditions and the following disclaimer. 00012 * * Redistributions in binary form must reproduce the above copyright 00013 * notice, this list of conditions and the following disclaimer in the 00014 * documentation and/or other materials provided with the distribution. 00015 * * Neither the name of the <organization> nor the 00016 * names of its contributors may be used to endorse or promote products 00017 * derived from this software without specific prior written permission. 00018 * 00019 * THIS SOFTWARE IS PROVIDED BY THOMAS A. VAUGHAN ''AS IS'' AND ANY 00020 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00021 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00022 * DISCLAIMED. IN NO EVENT SHALL THOMAS A. VAUGHAN BE LIABLE FOR ANY 00023 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00024 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00025 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 00026 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00027 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00028 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00029 * 00030 * 00031 * Gamepad mapping. This contains most of the important definitions used in the 00032 * API. 00033 */ 00034 00035 #ifndef GAMEPAD_GAMEPAD_MAP_H__ 00036 #define GAMEPAD_GAMEPAD_MAP_H__ 00037 00038 00039 // includes -------------------------------------------------------------------- 00040 #include "gamepad-type.h" 00041 00042 #include "source-device/source-device.h" 00043 00044 00045 namespace gamepad { 00046 00047 00048 /// \ingroup gamepadlib 00049 /*@{*/ 00050 00051 00052 /// the current position of a dpad. A dpad is a "Directional Pad", see 00053 /// http://en.wikipedia.org/wiki/D-pad 00054 enum eDpad { 00055 eDpad_Centered = 0, ///< dpad is not pressed or tilted at all 00056 eDpad_Left = 1, ///< pushed left 00057 eDpad_Right = 2, ///< pushed right 00058 eDpad_Up = 4, ///< pushed up 00059 eDpad_Down = 8, ///< pushed straight down 00060 00061 // composite values 00062 eDpad_UpLeft = eDpad_Up | eDpad_Left, 00063 eDpad_UpRight = eDpad_Up | eDpad_Right, 00064 eDpad_DownLeft = eDpad_Down | eDpad_Left, 00065 eDpad_DownRight = eDpad_Down | eDpad_Right, 00066 00067 // keep this last! 00068 eDpad_Invalid = 16 00069 }; 00070 00071 00072 00073 /// button mapping information 00074 struct button_map_t { 00075 button_map_t(void) throw() { this->clear(); } 00076 void clear(void) throw() { 00077 index = -1; 00078 } 00079 void dump(IN const char * title) const throw() { 00080 DPRINTF("%s (button map): index=%d", title, index); 00081 } 00082 bool isValid(void) const throw() { 00083 return (index >= 0); 00084 } 00085 00086 // data fields 00087 int index; ///< button or pot index 00088 }; 00089 00090 00091 00092 /// all button values OR'd together 00093 typedef uint32_t buttons_t; // TODO: deprecate? 00094 00095 00096 /// a joystick is a 2-axis stick 00097 struct joystick_t { 00098 // constructor, manipulators 00099 joystick_t(void) throw() { this->clear(); } 00100 void clear(void) throw() { 00101 x.clear(); 00102 y.clear(); 00103 } 00104 00105 // data fields 00106 pot_value_t x; ///< current x-axis potentiometer value 00107 pot_value_t y; ///< current y-axis potentiometer value 00108 }; 00109 00110 00111 /// describes joystick mapping 00112 struct joystick_map_t { 00113 joystick_map_t(void) throw() { this->clear(); } 00114 void clear(void) throw() { 00115 xIndex = yIndex = -1; 00116 } 00117 void dump(IN const char * title) const throw() { 00118 DPRINTF("%s (joystick map): xIndex=%d yIndex=%d", 00119 title, xIndex, yIndex); 00120 } 00121 bool isValid(void) const throw() { 00122 return (xIndex >= 0 && yIndex >= 0); 00123 } 00124 00125 // data fields 00126 int xIndex; ///< index of x axis potentiometer 00127 int yIndex; ///< index of y axis potentiometer 00128 }; 00129 00130 00131 /// describes a potentiometer mapping 00132 struct pot_map_t { 00133 pot_map_t(void) throw() { this->clear(); } 00134 void clear(void) throw() { 00135 index = -1; 00136 } 00137 void dump(IN const char * title) const throw() { 00138 DPRINTF("%s (potentiometer map): index=%d", 00139 title, index); 00140 } 00141 bool isValid(void) const throw() { 00142 return (index >= 0); 00143 } 00144 00145 // data fields 00146 int index; ///< index of potentiometer 00147 }; 00148 00149 00150 00151 /// a dpad_map_t describes how to map from low-level SourceDevice events (buttons 00152 /// or potentiometers) into dpad events. 00153 struct dpad_map_t { 00154 // constants 00155 enum eType { 00156 eType_Button = 1, ///< dpad uses buttons for events 00157 eType_2Pot = 2, ///< dpad uses 2 potentiometers 00158 eType_4Pot = 3, ///< dpad uses 4 potentiometers 00159 eType_Invalid = 0 00160 }; 00161 enum eIndex { 00162 eLeft = 0, 00163 eUp = 1, 00164 eRight = 2, // left and right will be same for 2 pot 00165 eDown = 3, // up and down will be same for 2 pot 00166 00167 // keep this last 00168 eBad = 255 00169 }; 00170 00171 // constructor, destructor 00172 dpad_map_t(void) throw() { this->clear(); } 00173 00174 // manipulators 00175 void clear(void) throw() { 00176 type = eType_Invalid; 00177 for (int i = 0; i < 4; ++i) { 00178 index[i] = eBad; 00179 } 00180 flipX = flipY = false; 00181 } 00182 void dump(IN const char * title) const throw() { 00183 const char * typeName = "INVALID"; 00184 if (eType_Button == type) { 00185 typeName = "Button"; 00186 } else if (eType_2Pot == type) { 00187 typeName = "Two Potentiometer"; 00188 } else if (eType_4Pot == type) { 00189 typeName = "Four Potentiometer"; 00190 } 00191 DPRINTF("%s (directional pad mapping): %s", 00192 title, typeName); 00193 DPRINTF(" indices: up=%d down=%d left=%d right=%d", 00194 index[eUp], index[eDown], 00195 index[eLeft], index[eRight]); 00196 DPRINTF(" flip axis: X=%s Y=%s", 00197 (flipX) ? "yes" : "no", (flipY) ? "yes" : "no"); 00198 } 00199 bool isValid(void) const throw() { 00200 if (eType_Button != type && 00201 eType_2Pot != type && 00202 eType_4Pot != type) 00203 return false; // not a valid type! 00204 for (int i = 0; i < 4; ++i) { 00205 if (eBad == index[i]) 00206 return false; // not a valid index 00207 } 00208 return true; 00209 } 00210 00211 // data fields 00212 eType type; 00213 byte_t index[4]; ///< button/pot indices for 4 directions 00214 bool flipX; ///< flip x-axis value? 00215 bool flipY; ///< flip y-axis value? 00216 }; 00217 00218 00219 00220 /// A gamepad::Map is the magical binding between physical inputs (button 00221 /// presses, joystick moves, wheel turns) and logical events (left top 00222 /// trigger pressed, right joystick pushed up, etc.). In practice, there is 00223 /// no agreement between manufacturers how physical and logical events are 00224 /// related. So, for instance, different manufacturers will produce 00225 /// USB adapters that represent the exact same gamepad completely 00226 /// differently. 00227 /// In short, based on the state of the world today, there is no way for a 00228 /// programmer to know what type of gamepad a player is holding, or how to 00229 /// interpret the events coming from that device. The gamepad::Map 00230 /// performs that mapping, and most of the purpose of this entire API is to 00231 /// provide easy-to-create and manage gamepad mappings so that programmers 00232 /// can work with gamepad objects and not worry about the underlying 00233 /// details. 00234 /// This particular object gamepad::Map is fairly low-level and is designed 00235 /// to be easily persisted. Users of the gamepad library will probably want 00236 /// to use the Gamepad object instead, which is intended to represent the 00237 /// physical instance of a connected gamepad. 00238 class Map { 00239 public: 00240 // virtual destructor -------------------------------------------------- 00241 virtual ~Map(void) throw(); 00242 00243 // gamepad::Map class interface methods -------------------------------- 00244 00245 /// returns the ID of this mapping. IDs should be UUIDs 00246 virtual const char * getId(void) const throw() = 0; 00247 00248 /// returns the ID of the gamepad type this mapping is for (also UUID) 00249 virtual const char * getTypeId(void) const throw() = 0; 00250 00251 /// returns the name of this mapping. This is for debugging and is not 00252 /// meant for end users. 00253 virtual const char * getName(void) const throw() = 0; 00254 00255 /// returns the list of device names for which this mapping is 00256 /// recommended. A device name is the same as what is returned 00257 /// from gamepad::SourceDevice::getPublicName(). That is, it should 00258 /// be the device name as returned directly by the hardware itself. 00259 /// This list can be empty, and there could be multiple mappings that 00260 /// claim to support the same device. This is especially true for 00261 /// source devices that support multiple gamepads. 00262 virtual const VecString& getDeviceNames(void) const throw() = 0; 00263 00264 /// given a button index for the gamepad (see gamepad::Type), how is it 00265 /// mapped to buttons or potentiometers? Returns NULL on error 00266 /// (usually because the logicalName isn't recognized). 00267 virtual const button_map_t * getButtonMapping( 00268 IN const char * logicalName) const throw() = 0; 00269 00270 /// given a joystick index for the gamepad, how is it mapped to 00271 /// potentiometers? Returns NULL on error. 00272 virtual const joystick_map_t * getJoystickMapping( 00273 IN const char * logicalName) const throw() = 0; 00274 00275 /// given an potentiometer index for the gamepad (see gamepad::Type), 00276 /// what is the corresponding potentiometer index on the source 00277 /// device? Returns NULL on error. 00278 virtual const pot_map_t * getPotMapping( 00279 IN const char * logicalName) const throw() = 0; 00280 00281 /// given a dpad index for the gamepad (see gamepad::Type), what is the 00282 /// corresponding dpad index on the source device? Returns NULL 00283 /// on error. 00284 virtual const dpad_map_t * getDpadMapping( 00285 IN const char * logicalName) const throw() = 0; 00286 }; 00287 00288 00289 00290 /// read mapping from a datahash (often a text file) 00291 smart_ptr<Map> readMap(IN const Datahash * hash); 00292 00293 00294 /// write mapping to a datahash (you can then use Datahash utility methods to 00295 /// write to a stream etc) 00296 smart_ptr<Datahash> writeMap(IN const Map * map); 00297 00298 00299 }; // gamepad namespace 00300 00301 00302 #endif // GAMEPAD_GAMEPAD_MAP_H__ 00303