AppEasy Core SDK  1.5.0
Cross platform mobile and desktop app and game development SDK - The easy way to make apps
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Defines
CzInput.h
Go to the documentation of this file.
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_