AppEasy Core SDK
1.5.0
Cross platform mobile and desktop app and game development SDK - The easy way to make apps
|
00001 // 00002 // 00003 // AppEasy SDK - Cross Platform Multi-purpose Game and App Engine 00004 // 00005 // Developed by Matthew Hopwood of Pocketeers Limited - www.pocketeers.co.uk 00006 // 00007 // For updates, tutorials and more details check out www.appeasymobile.com 00008 // 00009 // This code is provided free of charge and without any warranty whatsoever. You must ensure that this whole notice is present in all files and derivatives, so the reader knows its origin. 00010 // If you use this SDK in your product then please ensure that you credit AppEasy's usage appropriately. Please see www.appeasymobile.com for licensing details and support 00011 // 00012 // 00013 00014 #if !defined(_CZ_INPUT_H_) 00015 #define _CZ_INPUT_H_ 00016 00017 #include "IzPlatformInput.h" 00018 #include "CzUtil.h" 00019 #include "CzTime.h" 00020 00021 /** 00022 @addtogroup Core 00023 @{ 00024 */ 00025 00026 /** 00027 @def CZ_MAX_TOUCHES 00028 00029 @brief A macro that defines maximum number of supported simultaneous touches. 00030 00031 */ 00032 00033 #define CZ_MAX_TOUCHES 10 00034 00035 /** 00036 @def CZ_INPUT 00037 00038 @brief A macro that provides global access to the intput system. 00039 00040 */ 00041 00042 #define CZ_INPUT (CzInput::getInstance()) 00043 00044 /** 00045 @enum eCzKeyCode 00046 00047 @brief Values that represent key codes. 00048 */ 00049 00050 enum eCzKeyCode 00051 { 00052 eKeyNone, 00053 eKeyEsc, 00054 eKeyTab, 00055 eKeyBackspace, 00056 eKeyEnter, 00057 eKeyLeftShift, 00058 eKeyLeftControl, 00059 eKeyReserved, 00060 eKeySpace, 00061 eKeyLeft, 00062 eKeyUp, 00063 eKeyRight, 00064 eKeyDown, 00065 eKey0, 00066 eKey1, 00067 eKey2, 00068 eKey3, 00069 eKey4, 00070 eKey5, 00071 eKey6, 00072 eKey7, 00073 eKey8, 00074 eKey9, 00075 eKeyA, 00076 eKeyB, 00077 eKeyC, 00078 eKeyD, 00079 eKeyE, 00080 eKeyF, 00081 eKeyG, 00082 eKeyH, 00083 eKeyI, 00084 eKeyJ, 00085 eKeyK, 00086 eKeyL, 00087 eKeyM, 00088 eKeyN, 00089 eKeyO, 00090 eKeyP, 00091 eKeyQ, 00092 eKeyR, 00093 eKeyS, 00094 eKeyT, 00095 eKeyU, 00096 eKeyV, 00097 eKeyW, 00098 eKeyX, 00099 eKeyY, 00100 eKeyZ, 00101 eKeyF1, 00102 eKeyF2, 00103 eKeyF3, 00104 eKeyF4, 00105 eKeyF5, 00106 eKeyF6, 00107 eKeyF7, 00108 eKeyF8, 00109 eKeyF9, 00110 eKeyF10, 00111 eKeyNumPad0, 00112 eKeyNumPad1, 00113 eKeyNumPad2, 00114 eKeyNumPad3, 00115 eKeyNumPad4, 00116 eKeyNumPad5, 00117 eKeyNumPad6, 00118 eKeyNumPad7, 00119 eKeyNumPad8, 00120 eKeyNumPad9, 00121 eKeyNumPadPlus, 00122 eKeyNumPadMinus, 00123 eKeyNumPadEnter, 00124 eKeyRSK, 00125 eKeyLSK, 00126 eKeyLS, 00127 eKeyRS, 00128 eKeyHash, 00129 eKeyStar, 00130 eKeyOk, 00131 eKeyCLR, 00132 eKeyVolUp, 00133 eKeyVolDown, 00134 eKeyCamera, 00135 eKeyMic, 00136 eKeyFn, 00137 eKeySym, 00138 eKeyAccept, 00139 eKeyEnd, 00140 eKeyHomePage, 00141 eKeyButton1, 00142 eKeyButton2, 00143 eKeyButton3, 00144 eKeyButton4, 00145 eKeyButton5, 00146 eKeyButton6, 00147 eKeyButton7, 00148 eKeyButton8, 00149 eKeyF11, 00150 eKeyF12, 00151 eKeyLeftAlt, 00152 eKeyRightControl, 00153 eKeyRightAlt, 00154 eKeyRightShift, 00155 eKeyBacktick, 00156 eKeyComma, 00157 eKeyPeriod, 00158 eKeySlash, 00159 eKeyBackSlash, 00160 eKeySemicolon, 00161 eKeyApostrophe, 00162 eKeyLeftBracket, 00163 eKeyRightBracket, 00164 eKeyEquals, 00165 eKeyMinus, 00166 eKeyCapsLock, 00167 eKeyNumPadPeriod, 00168 eKeyNumPadSlash, 00169 eKeyNumLock, 00170 eKeyInsert, 00171 eKeyHome, 00172 eKeyPageUp, 00173 eKeyPageDown, 00174 eKeyKbEnd, 00175 eKeyDelete, 00176 eKeyPause, 00177 eKeyAt, 00178 eKeyBack, 00179 eKeyMenu, 00180 eKeySearch, 00181 eKey3DMode, 00182 eKeyMyApps, 00183 eKeyAbsGameA, 00184 eKeyAbsGameB, 00185 eKeyAbsGameC, 00186 eKeyAbsGameD, 00187 eKeyAbsUp, 00188 eKeyAbsDown, 00189 eKeyAbsLeft, 00190 eKeyAbsRight, 00191 eKeyAbsOk, 00192 eKeyAbsASK, 00193 eKeyAbsBSK, 00194 }; 00195 00196 /** 00197 @struct CzTouch 00198 00199 @brief Represents a single touch. 00200 00201 */ 00202 00203 struct CzTouch 00204 { 00205 public: 00206 int x, y; ///< Touch position 00207 int px, py; ///< Previous touch position 00208 int dx, dy; ///< Delta position 00209 bool touched; ///< Touched state 00210 bool active; ///< Touch active state 00211 bool prev_active; ///< Touch active state (last frame) 00212 int id; ///< ID of touch - The system tracks multiple touches by assigning each one a unique ID 00213 00214 CzTouch() : active(false), prev_active(false), id(-1), touched(false) {} 00215 }; 00216 00217 /** 00218 @class CzInput 00219 00220 @brief This class is responsible for handling all keyboard, pointer and other input devices input. 00221 00222 <h1>Introduction</h1> 00223 00224 AppEasy provides the CzInput singleton class to manage all game input. CzInput manages the following types of input: 00225 - Single and multi-touch input 00226 - Button and key states 00227 - On screen keyboard input 00228 - Acceleromter 00229 - Compass 00230 00231 Access to input methods are provided via the CZ_INPUT macro, for example: 00232 00233 @code 00234 if (CZ_INPUT->getTouchCount() > 0) 00235 { 00236 } 00237 @endcode 00238 00239 If you are using CzApp then you do not need to worry about initialising, updating or cleaning up the input system, however if you are rolling your own solution then you will need to take care 00240 of these steps yourself, here's a quick example showing how to do this: 00241 00242 @code 00243 // Initialise the input system 00244 CzInput::Create(); 00245 CZ_INPUT->Init(); 00246 00247 // Main loop 00248 while (1) 00249 { 00250 // Update input system 00251 CZ_INPUT->Update(); 00252 } 00253 00254 // Shut down the input system 00255 CZ_INPUT->Release(); 00256 CzInput::Destroy(); 00257 @endcode 00258 00259 <h1>Checking Availability</h1> 00260 As AppEasy is designed to work across multiple platforms you should check to ensure that a particular input system is available before you use it. Here’s a quick example showing how to check 00261 that the pointer input is available: 00262 00263 @code 00264 // Check to see that the pointer is available 00265 if (CZ_INPUT->isPointerAvailable()) 00266 { 00267 // Check to see if any touches have been made 00268 int num_touches = CZ_INPUT->getTouchCount(); 00269 } 00270 @endcode 00271 00272 AppEasy provides a number of methods to check for particular input systems availability: 00273 00274 @code 00275 bool isPointerAvailable() // Returns availability of the pointer 00276 bool isKeysAvailable() // Returns availability of keys 00277 bool isOSKeyboardAvailable() // Returns availability of on screen keyboard 00278 bool isAccelerometerAvailable() // Returns availability of accelerometer 00279 bool isCompassAvailable() // Returns true if compass is available 00280 @endcode 00281 00282 <h1>Single and Multi-touch Touches</h1> 00283 CzInput supports single and multi-touch events, allowing you to check for multiple simultaneous touches. However many devices do not support multi-touch events so a method has been provided 00284 to determine multi-touch support: 00285 00286 @code 00287 bool isMultiTouch() // Returns multitouch capability 00288 @endcode 00289 00290 If you are developing a game or app that relies on multi-touch then you should implement a fall back method that will work with single touch devices. Touch modes is a good solution that can 00291 help mirror multi-touch functionality by putting the pointer into different modes, such as move, scale, rotate etc.. and allow the user to switch between them. 00292 00293 No matter if you are using single or multi-touch functionality retrieving touches is done in very much the same way. 00294 00295 <h1>Working with Touches</h1> 00296 00297 CzInput provides methods that enable you to detect and collect touch data. The usual process is to determine if any touches have been made by calling CZ_INPUT->getTouchCount() and then take 00298 a look at the touches list to see what touch events occurred. Here's an example: 00299 00300 @code 00301 // Check to make sure that the pointer is available 00302 if (CZ_INPUT->isPointerAvailable()) 00303 { 00304 // Get the total number of current touches 00305 int num_touches = CZ_INPUT->getTouchCount(); 00306 if (num_touches != 0) 00307 { 00308 // Check list of touches to see which are active 00309 for (int t = 0; t < CZ_MAX_TOUCHES; t++) 00310 { 00311 // Get the touch data 00312 CzTouch* touch = CZ_INPUT->getTouch(t); 00313 if (touch->active) 00314 { 00315 // Do something with the touch 00316 } 00317 } 00318 } 00319 } 00320 @endcode 00321 00322 Note that getTouch() returns the CzTouch struct for the touch at the specified index. CzTouch looks like this: 00323 00324 @code 00325 struct CzTouch 00326 { 00327 public: 00328 int x, y; ///< Touch position 00329 int px, py; ///< Previous touch position 00330 int dx, dy; ///< Delta position 00331 bool touched; ///< Touched state 00332 bool active; ///< Touch active state 00333 bool prev_active; ///< Touch active state (last frame) 00334 int id; ///< ID of touch - The system tracks multiple touches by assigning each one a unique ID 00335 00336 CzTouch() : active(false), prev_active(false), id(-1), touched(false) {} 00337 }; 00338 @endcode 00339 00340 If you want to track a touch to monitor its status then you should store its ID and use CzInput::getTouchByID(id) to find it again later. 00341 00342 <h1>Checking Key / Button States</h1> 00343 00344 As you expand your list of supported devices for your products you will discover that devices come in all sorts of different configurations, some will even have hard keyboards / keypads and 00345 buttons. For example, the Samsung Galaxy pro has a full QWERTY keyboard and almost all Android devices have hardware buttons for menu, home and back. 00346 00347 To query the state of a key / button (buttons are mapped to keys) you call the following methods of CzInput: 00348 00349 @code 00350 bool isKeyDown(int key) const; // Tests if a key is down 00351 bool isKeyUp(int key) const; // Tests if a key is up 00352 bool wasKeyPressed(int key) const; // Tests if a key was pressed 00353 bool wasKeyReleased(int key) const; // Tests if a key was released 00354 @endcode 00355 00356 Each method takes a platform independent eCzKeyCode as input. 00357 00358 <h1>On Screen Keyboard</h1> 00359 00360 As most devices do not have hardware keyboards an on screen keyboard is the only method of inputting text into the device. AppEasy provides access to this functionality via showOnScreenKeyboard(): 00361 00362 @code 00363 const char* showOnScreenKeyboard(const char* prompt, int flags = 0, const char* default_text = NULL); 00364 @endcode 00365 00366 Calling this method will display a modal on screen keyboard with the provided prompt text and using the supplied default text (pass NULL if you do not require default text). Flags provides a hint 00367 to the system to let it know what type of keyboard you want to display to the user (see eInputTypeHint). Passing 0 for flags will use the default keyboard. Once the on screen keyboard has been 00368 dismissed the entered text will be returned as a string. 00369 00370 <h1>Accelerometer Input</h1> 00371 00372 An accelerometer is a device usually found inside mobile phones and tablets that measures acceleration. This is great for gaming as you can use the actual angle or speed at which the user tilts 00373 their device to affect game play. For example, you could for example use the accelerometer to allow the player to navigate a ball around a maze or maybe determine how hard the player wants to 00374 hit a ball. However the accelerometer does have limitations. If the users phone is perpendicular to the floor then changes in reading may not be registered. 00375 00376 Accelerometer hardware is usually quite power hungry so in order ot use it you need to start it using: 00377 00378 @code 00379 CZ_INPUT->startAccelerometer(); 00380 @endcode 00381 00382 And when not in use you can turn it off using: 00383 00384 @code 00385 CZ_INPUT->stopAccelerometer(); 00386 @endcode 00387 00388 00389 Per frame update of the accelerometer is automatically taken care of by CzInput. 00390 00391 To read the current position of the accelerometer you call: 00392 00393 @code 00394 CzVec3 accelerometer_pos = CZ_INPUT->getAccelerometerPosition(); 00395 @endcode 00396 00397 Because the user can potentially start a game with the phone held at any angle, reading accelerometer readings are best made from a frame of reference. This is usually the initial position that 00398 the user is holding the device at when they start the game. To set the reference point for the accelerometer call: 00399 00400 @code 00401 CZ_INPUT->setAccelerometerReference(); 00402 @endcode 00403 00404 This will set the reference point for offset reads to the current position of the users phone. You may want to display a short instructions screen at this point that informs the user how to 00405 hold the phone. 00406 00407 To read the accelerometer position with respect to the reference point call: 00408 00409 @code 00410 CzVec3 accelerometer_pos = CZ_INPUT->getAccelerometerOffset(); 00411 @endcode 00412 00413 <h1>Compass Input</h1> 00414 00415 The digital compass is a device that uses the Earth's ambient magnetic field to determine the orientation of the users mobile phone or tablet. This allows you to measure the angle of the device 00416 and the direction in which its pointing. 00417 00418 Like the accelerometer hardware the compass is usually quite power hungry so in order to use it you need to start it using: 00419 00420 @code 00421 CZ_INPUT->startCompass(); 00422 @endcode 00423 00424 And when not in use you can turn it off using: 00425 00426 @code 00427 CZ_INPUT->stopCompass(); 00428 @endcode 00429 00430 Per frame update of the compass is automatically taken care of by CzInput. 00431 00432 To read the current orientation and heading of the compass you call: 00433 00434 @code 00435 CzVec3 compass_heading = CZ_INPUT->getCompassHeading(); 00436 float compass_directiom = CZ_INPUT->getCompassDirection(); 00437 @endcode 00438 00439 */ 00440 00441 class CzInput 00442 { 00443 public: 00444 00445 /** 00446 @enum eInputTypeHint 00447 00448 @brief Passed to showOnScreenKeyboard() to hint at what type of keyboard entry to show. 00449 */ 00450 enum eInputTypeHint 00451 { 00452 Hint_Text = 0, 00453 Hint_Number = 1, 00454 Hint_Password = 2, 00455 Hint_Email = 3, 00456 Hint_URL = 4 00457 }; 00458 00459 CDEFINE_SINGLETON(CzInput) 00460 00461 // Properties 00462 private: 00463 uint8* KeyCodeMapping; ///< Table that maps platform key codes to AppEasy key codes 00464 bool PointerAvailable; ///< true if a pointer is present 00465 bool KeysAvailable; ///< true if a key input is present 00466 bool OSKeyboardAvailable; ///< true if on screen keyboard is available 00467 bool AccelerometerAvailable; ///< true if accelerometer is available 00468 bool CompassAvailable; ///< true if compass is available 00469 bool IsMultiTouch; ///< true if multitouch is enabled 00470 CzTouch Touches[CZ_MAX_TOUCHES]; ///< List of potential touches 00471 CzTouch* FirstTouch; ///< First touch that was made 00472 CzIVec2 DragDelta; ///< Amount dragged 00473 CzIVec2 TouchedPos; ///< Position user touched initially 00474 bool Touched; ///< true when user is touching the screen 00475 bool Tapped; ///< true when user taps screen (cleared in next update) 00476 bool BackPressed; ///< Back key pressed state 00477 bool MenuPressed; ///< Menu key pressed state 00478 bool AccelerometerActive; ///< Active state of accelerometer 00479 bool CompassActive; ///< Active state of compass 00480 CzVec3 AccelerometerReference; ///< Accelerometer reference position 00481 CzVec3 AccelerometerPosition; ///< Current accelerometer position 00482 CzVec3 CompassHeading; ///< Current compass heading 00483 float CompassDirection; ///< Current compass direction 00484 public: 00485 // Availability query 00486 bool isPointerAvailable() const { return PointerAvailable; } ///< Returns availability of the pointer 00487 bool isKeysAvailable() const { return KeysAvailable; } ///< Returns availability of keys 00488 bool isOSKeyboardAvailable() const { return OSKeyboardAvailable; } ///< Returns availability of on screen keyboard 00489 bool isAccelerometerAvailable() const { return AccelerometerAvailable; } ///< Returns availability of accelerometer 00490 bool isCompassAvailable() const { return CompassAvailable; } ///< Returns true if compass is available 00491 bool isMultiTouch() const { return IsMultiTouch; } ///< Returns multitouch capability 00492 00493 // Pointer 00494 CzTouch* getTouchByID(int id); ///< Returns the touch identified by its id 00495 CzTouch* getTouch(int index) { if (index < 0 || index >= CZ_MAX_TOUCHES) return NULL; else return &Touches[index]; } ///< Gets a specific touch 00496 CzTouch* getFirstTouch() { return FirstTouch; } ///< Returns last touch that was made 00497 CzTouch* findTouch(int id); ///< Finds a specific touch by its id 00498 int getTouchCount() const; ///< Get number of touches this frame 00499 bool hasTapped() const { return Tapped; } ///< Returns tapped status 00500 bool isTouching(int index) const { return Touches[index].touched; } ///< Returns true if specified touch at the specified index is touching 00501 CzIVec2 getTouchedPos(int index) const { return CzIVec2(Touches[index].x, Touches[index].y); } ///< Returns the touch position of the touch at the specified index 00502 CzIVec2 getDragDelta(int index) const { return CzIVec2(Touches[index].dx, Touches[index].dy); } ///< Returns tapped status of the touch at the specified index 00503 bool isDragging(int index) const; ///< Returns true if the user has moved the touch at the specified index 00504 00505 // keys / Buttons 00506 void setKeyCodeMapping(uint8* mapping_table) { KeyCodeMapping = mapping_table; } ///< Sets the hardware to AppEasy key nappnig table 00507 bool isKeyDown(int key) const; ///< Tests if a key is down 00508 bool isKeyUp(int key) const; ///< Tests if a key is up 00509 bool wasKeyPressed(int key) const; ///< Tests if a key was pressed 00510 bool wasKeyReleased(int key) const; ///< Tests if a key was released 00511 const char* showOnScreenKeyboard(const char* prompt, int flags = 0, const char* default_text = NULL); //< Displays the on screen keyboard 00512 bool isBackPressed() { return BackPressed; } //< Returns true if the back key is pressed 00513 void resetBackPressed() { BackPressed = false; } //< Resets the back key pressed status 00514 bool isMenuPressed() { return MenuPressed; } //< Returns true if the menu key is pressed 00515 void resetMenuPressed() { MenuPressed = false; } //< Resets the home key pressed status 00516 int getLastKey() const; //< Returns the last key pressed 00517 00518 // Accelerometer 00519 bool startAccelerometer(); ///< Start accelerometer input 00520 void stopAccelerometer(); ///< Stop accelerometer input 00521 void setAccelerometerReference(); ///< Sets the current accelerometer position as a reference posisition 00522 CzVec3 getAccelerometerPosition() const { return AccelerometerPosition; } ///< Get current accelerometer position 00523 CzVec3 getAccelerometerOffset() const; ///< Get current accelerometer offset from the reference position 00524 00525 // Compass 00526 bool startCompass(); ///< Start compass input 00527 void stopCompass(); ///< Stop compass input 00528 CzVec3 getCompassHeading() const { return CompassHeading; } ///< Get current compass heading 00529 float getCompassDirection() const { return CompassDirection; } ///< Get current compass direction (0 to 360 degrees) 00530 00531 // Properties end 00532 00533 private: 00534 CzTimer TapTimer; 00535 int TouchID; 00536 00537 public: 00538 bool Init(); ///< Initialises the input system (returns true if pointer is supported) 00539 void Release(); ///< Releases data used by the input system 00540 void Update(); ///< Updates the input system, called every frame 00541 }; 00542 00543 00544 /// @} 00545 00546 00547 #endif // _CZ_INPUT_H_