Browse Source

Merge pull request #1304 from seanpaultaylor/next

Added FileSystem::displayFileDialog and implemented on Windows.
Sean Taylor 12 years ago
parent
commit
8dab93e04c

+ 6 - 1
gameplay/src/FileSystem.cpp

@@ -2,6 +2,7 @@
 #include "FileSystem.h"
 #include "Properties.h"
 #include "Stream.h"
+#include "Platform.h"
 
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -64,7 +65,6 @@ static void makepath(std::string path, int mode)
             }
         }
     }
-    
     return;
 }
 
@@ -225,6 +225,11 @@ void FileSystem::loadResourceAliases(Properties* properties)
     }
 }
 
+std::string FileSystem::displayFileDialog(size_t mode, const char* title, const char* filterDescription, const char* filterExtension)
+{
+    return Platform::displayFileDialog(mode, title, filterDescription, filterExtension);
+}
+
 const char* FileSystem::resolvePath(const char* path)
 {
     GP_ASSERT(path);

+ 248 - 225
gameplay/src/FileSystem.h

@@ -1,225 +1,248 @@
-#ifndef FILESYSTEM_H_
-#define FILESYSTEM_H_
-
-#include "Stream.h"
-#include <string>
-
-namespace gameplay
-{
-
-class Properties;
-
-/**
- * Defines a set of functions for interacting with the device filesystem.
- */
-class FileSystem
-{
-public:
-
-    /**
-     * Mode flags for opening a stream.
-     * @script{ignore}
-     */
-    enum StreamMode
-    {
-        READ = 1,
-        WRITE = 2
-    };
-
-    /**
-     * Destructor.
-     */
-    ~FileSystem();
-
-    /**
-     * Sets the path to the root of the resources folder for the game.
-     *
-     * Once set, all resource/file loading will load from the given path.
-     * The default resource path is "./".
-     * 
-     * @param path The path to the root of the resources folder.
-     */
-    static void setResourcePath(const char* path);
-
-    /**
-     * Returns the currently set resource path.
-     * 
-     * @return The currently set resource path.
-     */
-    static const char* getResourcePath();
-
-    /**
-     * Loads a properties file containing a list of filesystem aliases.
-     *
-     * The specified aliases file is a valid properties file that contains one
-     * or more namespaces with a list of filesystem aliases that will be used
-     * to establish soft links to files when reading files through this class.
-     *
-     * This can be helpful for managing loading of resources that may change
-     * from one platform to another (such as texture formats). An aliases
-     * file per-platform can be maintained and asset loading code can refer
-     * to the alias name instead of the actual hard file name.
-     *
-     * @param aliasFilePath Path to a properties file containing filesystem aliases.
-     * 
-     * @see Properties
-     */
-    static void loadResourceAliases(const char* aliasFilePath);
-
-    /**
-     * Loads a set of filesystem aliases from the given Properties object.
-     *
-     * The specified properties object contains a single namespace with a list
-     * of filesystem aliases that will be used to establish soft links to files
-     * when reading files through this class.
-     *
-     * This can be helpful for managing loading of resources that may change
-     * from one platform to another (such as texture formats). An aliases
-     * file per-platform can be maintained and asset loading code can refer
-     * to the alias name instead of the actual hard file name.
-     *
-     * @param properties Properties object containing filesystem aliases.
-     * 
-     * @see Properties
-     */
-    static void loadResourceAliases(Properties* properties);
-
-    /**
-     * Resolves a filesystem path.
-     *
-     * If the specified path is a filesystem alias, the alias will be
-     * resolved and the physical file will be returned.
-     *
-     * Note that this method does not convert a relative path to an
-     * absolute filesystem path.
-     *
-     * @param path Path to resolve.
-     * 
-     * @return The resolved file path.
-     */
-    static const char* resolvePath(const char* path);
-
-    /**
-     * Lists the files in the specified directory and adds the files to the vector. Excludes directories.
-     * 
-     * @param dirPath Directory path relative to the path set in <code>setResourcePath(const char*)</code>.
-     * @param files The vector to append the files to.
-     * 
-     * @return True if successful, false if error.
-     * 
-     * @script{ignore}
-     */
-    static bool listFiles(const char* dirPath, std::vector<std::string>& files);
-
-    /**
-     * Checks if the file at the given path exists.
-     * 
-     * @param filePath The path to the file.
-     * 
-     * @return <code>true</code> if the file exists; <code>false</code> otherwise.
-     */
-    static bool fileExists(const char* filePath);
-
-    /**
-     * Opens a byte stream for the given resource path.
-     *
-     * If <code>path</code> is a file path, the file at the specified location is opened relative to the currently set
-     * resource path.
-     *
-     * @param path The path to the resource to be opened, relative to the currently set resource path.
-     * @param mode The mode used to open the file.
-     * 
-     * @return A stream that can be used to read or write to the file depending on the mode.
-     *         Returns NULL if there was an error. (Request mode not supported).
-     * 
-     * @script{ignore}
-     */
-    static Stream* open(const char* path, size_t mode = READ);
-
-    /**
-     * Opens the specified file.
-     *
-     * The file at the specified location is opened, relative to the currently set
-     * resource path.
-     *
-     * @param filePath The path to the file to be opened, relative to the currently set resource path.
-     * @param mode The mode used to open the file, passed directly to fopen.
-     * 
-     * @return A pointer to a FILE object that can be used to identify the stream or NULL on error.
-     * 
-     * @see setResourcePath(const char*)
-     * @script{ignore}
-     */
-    static FILE* openFile(const char* filePath, const char* mode);
-
-    /**
-     * Reads the entire contents of the specified file and returns its contents.
-     *
-     * The returned character array is allocated with new[] and must therefore
-     * deleted by the caller using delete[].
-     *
-     * @param filePath The path to the file to be read.
-     * @param fileSize The size of the file in bytes (optional).
-     * 
-     * @return A newly allocated (NULL-terminated) character array containing the
-     *      contents of the file, or NULL if the file could not be read.
-     */
-    static char* readAll(const char* filePath, int* fileSize = NULL);
-
-    /**
-     * Determines if the file path is an absolute path for the current platform.
-     * 
-     * @param filePath The file path to test.
-     * 
-     * @return True if the path is an absolute path or false otherwise.
-     */
-    static bool isAbsolutePath(const char* filePath);
-
-    /**
-     * Creates a file on the file system from the specified asset (Android-specific).
-     * 
-     * @param path The path to the file.
-     */
-    static void createFileFromAsset(const char* path);
-
-    /**
-     * Returns the directory name up to and including the trailing '/'.
-     * 
-     * This is a lexical method so it does not verify that the directory exists.
-     * Back slashes will be converted to forward slashes.
-     * 
-     * - "res/image.png" will return "res/"
-     * - "image.png" will return ""
-     * - "c:\foo\bar\image.png" will return "c:/foo/bar/"
-     * 
-     * @param The file path. May be relative or absolute, forward or back slashes. May be NULL.
-     * 
-     * @return The directory name with the trailing '/'. Returns "" if path is NULL or the path does not contain a directory.
-     */
-    static std::string getDirectoryName(const char* path);
-
-    /**
-     * Returns the extension of the given file path.
-     *
-     * The extension returned includes all character after and including the last '.'
-     * in the file path. The extension is returned as all uppercase.
-     *
-     * If the path does not contain an extension, an empty string is returned.
-     * 
-     * @param path File path.
-     *
-     * @return The file extension, all uppercase, including the '.'.
-     */
-    static std::string getExtension(const char* path);
-
-private:
-
-    /**
-     * Constructor.
-     */
-    FileSystem();
-};
-
-}
-
-#endif
+#ifndef FILESYSTEM_H_
+#define FILESYSTEM_H_
+
+#include "Stream.h"
+#include <string>
+
+namespace gameplay
+{
+
+class Properties;
+
+/**
+ * Defines a set of functions for interacting with the device filesystem.
+ */
+class FileSystem
+{
+public:
+
+    /**
+     * Mode flags for opening a stream.
+     * @script{ignore}
+     */
+    enum StreamMode
+    {
+        READ = 1,
+        WRITE = 2
+    };
+
+    /**
+     * Mode flags for opening a stream.
+     * @script{ignore}
+     */
+    enum DialogMode
+    {
+        OPEN,
+        SAVE
+    };
+
+    /**
+     * Destructor.
+     */
+    ~FileSystem();
+
+    /**
+     * Sets the path to the root of the resources folder for the game.
+     *
+     * Once set, all resource/file loading will load from the given path.
+     * The default resource path is "./".
+     * 
+     * @param path The path to the root of the resources folder.
+     */
+    static void setResourcePath(const char* path);
+
+    /**
+     * Returns the currently set resource path.
+     * 
+     * @return The currently set resource path.
+     */
+    static const char* getResourcePath();
+
+    /**
+     * Loads a properties file containing a list of filesystem aliases.
+     *
+     * The specified aliases file is a valid properties file that contains one
+     * or more namespaces with a list of filesystem aliases that will be used
+     * to establish soft links to files when reading files through this class.
+     *
+     * This can be helpful for managing loading of resources that may change
+     * from one platform to another (such as texture formats). An aliases
+     * file per-platform can be maintained and asset loading code can refer
+     * to the alias name instead of the actual hard file name.
+     *
+     * @param aliasFilePath Path to a properties file containing filesystem aliases.
+     * 
+     * @see Properties
+     */
+    static void loadResourceAliases(const char* aliasFilePath);
+
+    /**
+     * Loads a set of filesystem aliases from the given Properties object.
+     *
+     * The specified properties object contains a single namespace with a list
+     * of filesystem aliases that will be used to establish soft links to files
+     * when reading files through this class.
+     *
+     * This can be helpful for managing loading of resources that may change
+     * from one platform to another (such as texture formats). An aliases
+     * file per-platform can be maintained and asset loading code can refer
+     * to the alias name instead of the actual hard file name.
+     *
+     * @param properties Properties object containing filesystem aliases.
+     * 
+     * @see Properties
+     */
+    static void loadResourceAliases(Properties* properties);
+
+    /**
+     * Displays an open or save dialog using the native platform dialog system.
+     *
+     * @param mode The mode of the dialog. (Ex. OPEN or SAVE)
+     * @param title The title of the dialog. (Ex. Select File or Save File)
+     * @param filterDescription The file filter description. (Ex. All Files or PNG Files)
+     * @param filterExtension The extension. Ex. (* or png)  Note: This prefixed with *.
+     * @return The file that is opened or saved.
+     *
+     * @script{ignore}
+     */
+    static std::string displayFileDialog(size_t mode, const char* title, const char* filterDescription, const char* filterExtension);
+
+    /**
+     * Resolves a filesystem path.
+     *
+     * If the specified path is a filesystem alias, the alias will be
+     * resolved and the physical file will be returned.
+     *
+     * Note that this method does not convert a relative path to an
+     * absolute filesystem path.
+     *
+     * @param path Path to resolve.
+     * 
+     * @return The resolved file path.
+     */
+    static const char* resolvePath(const char* path);
+
+    /**
+     * Lists the files in the specified directory and adds the files to the vector. Excludes directories.
+     * 
+     * @param dirPath Directory path relative to the path set in <code>setResourcePath(const char*)</code>.
+     * @param files The vector to append the files to.
+     * 
+     * @return True if successful, false if error.
+     * 
+     * @script{ignore}
+     */
+    static bool listFiles(const char* dirPath, std::vector<std::string>& files);
+
+    /**
+     * Checks if the file at the given path exists.
+     * 
+     * @param filePath The path to the file.
+     * 
+     * @return <code>true</code> if the file exists; <code>false</code> otherwise.
+     */
+    static bool fileExists(const char* filePath);
+
+    /**
+     * Opens a byte stream for the given resource path.
+     *
+     * If <code>path</code> is a file path, the file at the specified location is opened relative to the currently set
+     * resource path.
+     *
+     * @param path The path to the resource to be opened, relative to the currently set resource path.
+     * @param mode The mode used to open the file.
+     * 
+     * @return A stream that can be used to read or write to the file depending on the mode.
+     *         Returns NULL if there was an error. (Request mode not supported).
+     * 
+     * @script{ignore}
+     */
+    static Stream* open(const char* path, size_t mode = READ);
+
+    /**
+     * Opens the specified file.
+     *
+     * The file at the specified location is opened, relative to the currently set
+     * resource path.
+     *
+     * @param filePath The path to the file to be opened, relative to the currently set resource path.
+     * @param mode The mode used to open the file, passed directly to fopen.
+     * 
+     * @return A pointer to a FILE object that can be used to identify the stream or NULL on error.
+     * 
+     * @see setResourcePath(const char*)
+     * @script{ignore}
+     */
+    static FILE* openFile(const char* filePath, const char* mode);
+
+    /**
+     * Reads the entire contents of the specified file and returns its contents.
+     *
+     * The returned character array is allocated with new[] and must therefore
+     * deleted by the caller using delete[].
+     *
+     * @param filePath The path to the file to be read.
+     * @param fileSize The size of the file in bytes (optional).
+     * 
+     * @return A newly allocated (NULL-terminated) character array containing the
+     *      contents of the file, or NULL if the file could not be read.
+     */
+    static char* readAll(const char* filePath, int* fileSize = NULL);
+
+    /**
+     * Determines if the file path is an absolute path for the current platform.
+     * 
+     * @param filePath The file path to test.
+     * 
+     * @return True if the path is an absolute path or false otherwise.
+     */
+    static bool isAbsolutePath(const char* filePath);
+
+    /**
+     * Creates a file on the file system from the specified asset (Android-specific).
+     * 
+     * @param path The path to the file.
+     */
+    static void createFileFromAsset(const char* path);
+
+    /**
+     * Returns the directory name up to and including the trailing '/'.
+     * 
+     * This is a lexical method so it does not verify that the directory exists.
+     * Back slashes will be converted to forward slashes.
+     * 
+     * - "res/image.png" will return "res/"
+     * - "image.png" will return ""
+     * - "c:\foo\bar\image.png" will return "c:/foo/bar/"
+     * 
+     * @param The file path. May be relative or absolute, forward or back slashes. May be NULL.
+     * 
+     * @return The directory name with the trailing '/'. Returns "" if path is NULL or the path does not contain a directory.
+     */
+    static std::string getDirectoryName(const char* path);
+
+    /**
+     * Returns the extension of the given file path.
+     *
+     * The extension returned includes all character after and including the last '.'
+     * in the file path. The extension is returned as all uppercase.
+     *
+     * If the path does not contain an extension, an empty string is returned.
+     * 
+     * @param path File path.
+     *
+     * @return The file extension, all uppercase, including the '.'.
+     */
+    static std::string getExtension(const char* path);
+
+private:
+
+    /**
+     * Constructor.
+     */
+    FileSystem();
+};
+
+}
+
+#endif

+ 655 - 655
gameplay/src/Game.cpp

@@ -1,655 +1,655 @@
-#include "Base.h"
-#include "Game.h"
-#include "Platform.h"
-#include "RenderState.h"
-#include "FileSystem.h"
-#include "FrameBuffer.h"
-#include "SceneLoader.h"
-#include "ControlFactory.h"
-
-/** @script{ignore} */
-GLenum __gl_error_code = GL_NO_ERROR;
-/** @script{ignore} */
-ALenum __al_error_code = AL_NO_ERROR;
-
-namespace gameplay
-{
-
-static Game* __gameInstance = NULL;
-double Game::_pausedTimeLast = 0.0;
-double Game::_pausedTimeTotal = 0.0;
-
-Game::Game()
-    : _initialized(false), _state(UNINITIALIZED), _pausedCount(0),
-      _frameLastFPS(0), _frameCount(0), _frameRate(0), _width(0), _height(0),
-      _clearDepth(1.0f), _clearStencil(0), _properties(NULL),
-      _animationController(NULL), _audioController(NULL),
-      _physicsController(NULL), _aiController(NULL), _audioListener(NULL),
-      _timeEvents(NULL), _scriptController(NULL), _scriptListeners(NULL)
-{
-    GP_ASSERT(__gameInstance == NULL);
-    __gameInstance = this;
-    _timeEvents = new std::priority_queue<TimeEvent, std::vector<TimeEvent>, std::less<TimeEvent> >();
-}
-
-Game::~Game()
-{
-	SAFE_DELETE(_scriptController);
-
-    // Do not call any virtual functions from the destructor.
-    // Finalization is done from outside this class.
-    SAFE_DELETE(_timeEvents);
-#ifdef GP_USE_MEM_LEAK_DETECTION
-    Ref::printLeaks();
-    printMemoryLeaks();
-#endif
-}
-
-Game* Game::getInstance()
-{
-    GP_ASSERT(__gameInstance);
-    return __gameInstance;
-}
-
-double Game::getAbsoluteTime()
-{
-    return Platform::getAbsoluteTime();
-}
-
-double Game::getGameTime()
-{
-    return Platform::getAbsoluteTime() - _pausedTimeTotal;
-}
-
-void Game::setVsync(bool enable)
-{
-    Platform::setVsync(enable);
-}
-
-bool Game::isVsync()
-{
-    return Platform::isVsync();
-}
-
-int Game::run()
-{
-    if (_state != UNINITIALIZED)
-        return -1;
-
-    loadConfig();
-
-    _width = Platform::getDisplayWidth();
-    _height = Platform::getDisplayHeight();
-
-    // Start up game systems.
-    if (!startup())
-    {
-        shutdown();
-        return -2;
-    }
-
-    return 0;
-}
-
-bool Game::startup()
-{
-    if (_state != UNINITIALIZED)
-        return false;
-
-    setViewport(Rectangle(0.0f, 0.0f, (float)_width, (float)_height));
-    RenderState::initialize();
-    FrameBuffer::initialize();
-
-    _animationController = new AnimationController();
-    _animationController->initialize();
-
-    _audioController = new AudioController();
-    _audioController->initialize();
-
-    _physicsController = new PhysicsController();
-    _physicsController->initialize();
-
-    _aiController = new AIController();
-    _aiController->initialize();
-
-    _scriptController = new ScriptController();
-    _scriptController->initialize();
-
-    // Load any gamepads, ui or physical.
-    loadGamepads();
-
-    // Set the script callback functions.
-    if (_properties)
-    {
-        Properties* scripts = _properties->getNamespace("scripts", true);
-        if (scripts)
-        {
-            const char* callback;
-            while ((callback = scripts->getNextProperty()) != NULL)
-            {
-                std::string url = scripts->getString();
-                std::string file;
-                std::string id;
-                splitURL(url, &file, &id);
-
-                if (file.size() <= 0 || id.size() <= 0)
-                {
-                    GP_ERROR("Invalid %s script callback function '%s'.", callback, url.c_str());
-                }
-                else
-                {
-                    _scriptController->loadScript(file.c_str());
-                    _scriptController->registerCallback(callback, id.c_str());
-                }
-            }
-        }
-    }
-
-    _state = RUNNING;
-
-    return true;
-}
-
-void Game::shutdown()
-{
-    // Call user finalization.
-    if (_state != UNINITIALIZED)
-    {
-        GP_ASSERT(_animationController);
-        GP_ASSERT(_audioController);
-        GP_ASSERT(_physicsController);
-        GP_ASSERT(_aiController);
-
-        Platform::signalShutdown();
-
-		// Call user finalize
-        finalize();
-
-		// Shutdown scripting system first so that any objects allocated in script are released before our subsystems are released
-		_scriptController->finalizeGame();
-		if (_scriptListeners)
-		{
-			for (size_t i = 0; i < _scriptListeners->size(); i++)
-			{
-				SAFE_DELETE((*_scriptListeners)[i]);
-			}
-			SAFE_DELETE(_scriptListeners);
-		}
-		_scriptController->finalize();
-
-        unsigned int gamepadCount = Gamepad::getGamepadCount();
-        for (unsigned int i = 0; i < gamepadCount; i++)
-        {
-            Gamepad* gamepad = Gamepad::getGamepad(i, false);
-            SAFE_DELETE(gamepad);
-        }
-
-        _animationController->finalize();
-        SAFE_DELETE(_animationController);
-
-        _audioController->finalize();
-        SAFE_DELETE(_audioController);
-
-        _physicsController->finalize();
-        SAFE_DELETE(_physicsController);
-        _aiController->finalize();
-        SAFE_DELETE(_aiController);
-        
-        ControlFactory::finalize();
-
-        // Note: we do not clean up the script controller here
-        // because users can call Game::exit() from a script.
-
-        SAFE_DELETE(_audioListener);
-
-        FrameBuffer::finalize();
-        RenderState::finalize();
-
-        SAFE_DELETE(_properties);
-
-		_state = UNINITIALIZED;
-    }
-}
-
-void Game::pause()
-{
-    if (_state == RUNNING)
-    {
-        GP_ASSERT(_animationController);
-        GP_ASSERT(_audioController);
-        GP_ASSERT(_physicsController);
-        GP_ASSERT(_aiController);
-        _state = PAUSED;
-        _pausedTimeLast = Platform::getAbsoluteTime();
-        _animationController->pause();
-        _audioController->pause();
-        _physicsController->pause();
-        _aiController->pause();
-    }
-
-    ++_pausedCount;
-}
-
-void Game::resume()
-{
-    if (_state == PAUSED)
-    {
-        --_pausedCount;
-
-        if (_pausedCount == 0)
-        {
-            GP_ASSERT(_animationController);
-            GP_ASSERT(_audioController);
-            GP_ASSERT(_physicsController);
-            GP_ASSERT(_aiController);
-            _state = RUNNING;
-            _pausedTimeTotal += Platform::getAbsoluteTime() - _pausedTimeLast;
-            _animationController->resume();
-            _audioController->resume();
-            _physicsController->resume();
-            _aiController->resume();
-        }
-    }
-}
-
-void Game::exit()
-{
-    // Only perform a full/clean shutdown if FORCE_CLEAN_SHUTDOWN or
-    // GP_USE_MEM_LEAK_DETECTION is defined. Every modern OS is able to
-    // handle reclaiming process memory hundreds of times faster than it
-    // would take us to go through every pointer in the engine and release
-    // them nicely. For large games, shutdown can end up taking long time,
-    // so we'll just call ::exit(0) to force an instant shutdown.
-
-#if defined FORCE_CLEAN_SHUTDOWN || defined GP_USE_MEM_LEAK_DETECTION
-
-    // Schedule a call to shutdown rather than calling it right away.
-	// This handles the case of shutting down the script system from
-	// within a script function (which can cause errors).
-	static ShutdownListener listener;
-	schedule(0, &listener);
-
-#else
-
-    // End the process immediately without a full shutdown
-    ::exit(0);
-
-#endif
-}
-
-
-void Game::frame()
-{
-    if (!_initialized)
-    {
-        // Perform lazy first time initialization
-        initialize();
-        _scriptController->initializeGame();
-        _initialized = true;
-
-        // Fire first game resize event
-        Platform::resizeEventInternal(_width, _height);
-    }
-
-	static double lastFrameTime = Game::getGameTime();
-	double frameTime = getGameTime();
-
-    // Fire time events to scheduled TimeListeners
-    fireTimeEvents(frameTime);
-
-    if (_state == Game::RUNNING)
-    {
-        GP_ASSERT(_animationController);
-        GP_ASSERT(_audioController);
-        GP_ASSERT(_physicsController);
-        GP_ASSERT(_aiController);
-
-        // Update Time.
-        float elapsedTime = (frameTime - lastFrameTime);
-        lastFrameTime = frameTime;
-
-        // Update the scheduled and running animations.
-        _animationController->update(elapsedTime);
-
-        // Update the physics.
-        _physicsController->update(elapsedTime);
-
-        // Update AI.
-        _aiController->update(elapsedTime);
-
-        // Update gamepads.
-        Gamepad::updateInternal(elapsedTime);
-
-        // Application Update.
-        update(elapsedTime);
-
-        // Update forms.
-        Form::updateInternal(elapsedTime);
-
-        // Run script update.
-        _scriptController->update(elapsedTime);
-
-        // Audio Rendering.
-        _audioController->update(elapsedTime);
-
-        // Graphics Rendering.
-        render(elapsedTime);
-
-        // Run script render.
-        _scriptController->render(elapsedTime);
-
-        // Update FPS.
-        ++_frameCount;
-        if ((Game::getGameTime() - _frameLastFPS) >= 1000)
-        {
-            _frameRate = _frameCount;
-            _frameCount = 0;
-            _frameLastFPS = getGameTime();
-        }
-    }
-	else if (_state == Game::PAUSED)
-    {
-        // Update gamepads.
-        Gamepad::updateInternal(0);
-
-        // Application Update.
-        update(0);
-
-        // Update forms.
-        Form::updateInternal(0);
-
-        // Script update.
-        _scriptController->update(0);
-
-        // Graphics Rendering.
-        render(0);
-
-        // Script render.
-        _scriptController->render(0);
-    }
-}
-
-void Game::renderOnce(const char* function)
-{
-    _scriptController->executeFunction<void>(function, NULL);
-    Platform::swapBuffers();
-}
-
-void Game::updateOnce()
-{
-    GP_ASSERT(_animationController);
-    GP_ASSERT(_audioController);
-    GP_ASSERT(_physicsController);
-    GP_ASSERT(_aiController);
-
-    // Update Time.
-    static double lastFrameTime = getGameTime();
-    double frameTime = getGameTime();
-    float elapsedTime = (frameTime - lastFrameTime);
-    lastFrameTime = frameTime;
-
-    // Update the internal controllers.
-    _animationController->update(elapsedTime);
-    _physicsController->update(elapsedTime);
-    _aiController->update(elapsedTime);
-    _audioController->update(elapsedTime);
-    _scriptController->update(elapsedTime);
-}
-
-void Game::setViewport(const Rectangle& viewport)
-{
-    _viewport = viewport;
-    glViewport((GLuint)viewport.x, (GLuint)viewport.y, (GLuint)viewport.width, (GLuint)viewport.height);
-}
-
-void Game::clear(ClearFlags flags, const Vector4& clearColor, float clearDepth, int clearStencil)
-{
-    GLbitfield bits = 0;
-    if (flags & CLEAR_COLOR)
-    {
-        if (clearColor.x != _clearColor.x ||
-            clearColor.y != _clearColor.y ||
-            clearColor.z != _clearColor.z ||
-            clearColor.w != _clearColor.w )
-        {
-            glClearColor(clearColor.x, clearColor.y, clearColor.z, clearColor.w);
-            _clearColor.set(clearColor);
-        }
-        bits |= GL_COLOR_BUFFER_BIT;
-    }
-
-    if (flags & CLEAR_DEPTH)
-    {
-        if (clearDepth != _clearDepth)
-        {
-            glClearDepth(clearDepth);
-            _clearDepth = clearDepth;
-        }
-        bits |= GL_DEPTH_BUFFER_BIT;
-
-        // We need to explicitly call the static enableDepthWrite() method on StateBlock
-        // to ensure depth writing is enabled before clearing the depth buffer (and to
-        // update the global StateBlock render state to reflect this).
-        RenderState::StateBlock::enableDepthWrite();
-    }
-
-    if (flags & CLEAR_STENCIL)
-    {
-        if (clearStencil != _clearStencil)
-        {
-            glClearStencil(clearStencil);
-            _clearStencil = clearStencil;
-        }
-        bits |= GL_STENCIL_BUFFER_BIT;
-    }
-    glClear(bits);
-}
-
-void Game::clear(ClearFlags flags, float red, float green, float blue, float alpha, float clearDepth, int clearStencil)
-{
-    clear(flags, Vector4(red, green, blue, alpha), clearDepth, clearStencil);
-}
-
-AudioListener* Game::getAudioListener()
-{
-    if (_audioListener == NULL)
-    {
-        _audioListener = new AudioListener();
-    }
-    return _audioListener;
-}
-
-void Game::keyEvent(Keyboard::KeyEvent evt, int key)
-{
-}
-
-void Game::touchEvent(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex)
-{
-}
-
-bool Game::mouseEvent(Mouse::MouseEvent evt, int x, int y, int wheelDelta)
-{
-    return false;
-}
-
-void Game::resizeEvent(unsigned int width, unsigned int height)
-{
-}
-
-bool Game::isGestureSupported(Gesture::GestureEvent evt)
-{
-    return Platform::isGestureSupported(evt);
-}
-
-void Game::registerGesture(Gesture::GestureEvent evt)
-{
-    Platform::registerGesture(evt);
-}
-
-void Game::unregisterGesture(Gesture::GestureEvent evt)
-{
-    Platform::unregisterGesture(evt);
-}
-
-bool Game::isGestureRegistered(Gesture::GestureEvent evt)
-{
-    return Platform::isGestureRegistered(evt);
-}
-
-void Game::gestureSwipeEvent(int x, int y, int direction)
-{
-}
-
-void Game::gesturePinchEvent(int x, int y, float scale)
-{
-}
-
-void Game::gestureTapEvent(int x, int y)
-{
-}
-
-void Game::gestureLongTapEvent(int x, int y, float duration)
-{
-}
-
-void Game::gestureDragEvent(int x, int y)
-{
-}
-
-void Game::gestureDropEvent(int x, int y)
-{
-}
-
-void Game::gamepadEvent(Gamepad::GamepadEvent evt, Gamepad* gamepad)
-{
-}
-
-void Game::getArguments(int* argc, char*** argv) const
-{
-    Platform::getArguments(argc, argv);
-}
-
-void Game::schedule(float timeOffset, TimeListener* timeListener, void* cookie)
-{
-    GP_ASSERT(_timeEvents);
-    TimeEvent timeEvent(getGameTime() + timeOffset, timeListener, cookie);
-    _timeEvents->push(timeEvent);
-}
-
-void Game::schedule(float timeOffset, const char* function)
-{
-    if (!_scriptListeners)
-        _scriptListeners = new std::vector<ScriptListener*>();
-
-    ScriptListener* listener = new ScriptListener(function);
-    _scriptListeners->push_back(listener);
-    schedule(timeOffset, listener, NULL);
-}
-
-void Game::fireTimeEvents(double frameTime)
-{
-    while (_timeEvents->size() > 0)
-    {
-        const TimeEvent* timeEvent = &_timeEvents->top();
-        if (timeEvent->time > frameTime)
-        {
-            break;
-        }
-        if (timeEvent->listener)
-        {
-            timeEvent->listener->timeEvent(frameTime - timeEvent->time, timeEvent->cookie);
-        }
-        _timeEvents->pop();
-    }
-}
-
-Game::ScriptListener::ScriptListener(const char* url)
-{
-    function = Game::getInstance()->getScriptController()->loadUrl(url);
-}
-
-void Game::ScriptListener::timeEvent(long timeDiff, void* cookie)
-{
-    Game::getInstance()->getScriptController()->executeFunction<void>(function.c_str(), "l", timeDiff);
-}
-
-Game::TimeEvent::TimeEvent(double time, TimeListener* timeListener, void* cookie)
-    : time(time), listener(timeListener), cookie(cookie)
-{
-}
-
-bool Game::TimeEvent::operator<(const TimeEvent& v) const
-{
-    // The first element of std::priority_queue is the greatest.
-    return time > v.time;
-}
-
-Properties* Game::getConfig() const
-{
-    if (_properties == NULL)
-        const_cast<Game*>(this)->loadConfig();
-
-    return _properties;
-}
-
-void Game::loadConfig()
-{
-    if (_properties == NULL)
-    {
-        // Try to load custom config from file.
-        if (FileSystem::fileExists("game.config"))
-        {
-            _properties = Properties::create("game.config");
-
-            // Load filesystem aliases.
-            Properties* aliases = _properties->getNamespace("aliases", true);
-            if (aliases)
-            {
-                FileSystem::loadResourceAliases(aliases);
-            }
-        }
-        else
-        {
-            // Create an empty config
-            _properties = new Properties();
-        }
-    }
-}
-
-void Game::loadGamepads()
-{
-    // Load virtual gamepads.
-    if (_properties)
-    {
-        // Check if there are any virtual gamepads included in the .config file.
-        // If there are, create and initialize them.
-        _properties->rewind();
-        Properties* inner = _properties->getNextNamespace();
-        while (inner != NULL)
-        {
-            std::string spaceName(inner->getNamespace());
-            // This namespace was accidentally named "gamepads" originally but we'll keep this check
-            // for backwards compatibility.
-            if (spaceName == "gamepads" || spaceName == "gamepad")
-            {
-                if (inner->exists("form"))
-                {
-                    const char* gamepadFormPath = inner->getString("form");
-                    GP_ASSERT(gamepadFormPath);
-                    Gamepad* gamepad = Gamepad::add(gamepadFormPath);
-                    GP_ASSERT(gamepad);
-                }
-            }
-
-            inner = _properties->getNextNamespace();
-        }
-    }
-}
-
-void Game::ShutdownListener::timeEvent(long timeDiff, void* cookie)
-{
-	Game::getInstance()->shutdown();
-}
-
-}
-
+#include "Base.h"
+#include "Game.h"
+#include "Platform.h"
+#include "RenderState.h"
+#include "FileSystem.h"
+#include "FrameBuffer.h"
+#include "SceneLoader.h"
+#include "ControlFactory.h"
+
+/** @script{ignore} */
+GLenum __gl_error_code = GL_NO_ERROR;
+/** @script{ignore} */
+ALenum __al_error_code = AL_NO_ERROR;
+
+namespace gameplay
+{
+
+static Game* __gameInstance = NULL;
+double Game::_pausedTimeLast = 0.0;
+double Game::_pausedTimeTotal = 0.0;
+
+Game::Game()
+    : _initialized(false), _state(UNINITIALIZED), _pausedCount(0),
+      _frameLastFPS(0), _frameCount(0), _frameRate(0), _width(0), _height(0),
+      _clearDepth(1.0f), _clearStencil(0), _properties(NULL),
+      _animationController(NULL), _audioController(NULL),
+      _physicsController(NULL), _aiController(NULL), _audioListener(NULL),
+      _timeEvents(NULL), _scriptController(NULL), _scriptListeners(NULL)
+{
+    GP_ASSERT(__gameInstance == NULL);
+    __gameInstance = this;
+    _timeEvents = new std::priority_queue<TimeEvent, std::vector<TimeEvent>, std::less<TimeEvent> >();
+}
+
+Game::~Game()
+{
+	SAFE_DELETE(_scriptController);
+
+    // Do not call any virtual functions from the destructor.
+    // Finalization is done from outside this class.
+    SAFE_DELETE(_timeEvents);
+#ifdef GP_USE_MEM_LEAK_DETECTION
+    Ref::printLeaks();
+    printMemoryLeaks();
+#endif
+}
+
+Game* Game::getInstance()
+{
+    GP_ASSERT(__gameInstance);
+    return __gameInstance;
+}
+
+double Game::getAbsoluteTime()
+{
+    return Platform::getAbsoluteTime();
+}
+
+double Game::getGameTime()
+{
+    return Platform::getAbsoluteTime() - _pausedTimeTotal;
+}
+
+void Game::setVsync(bool enable)
+{
+    Platform::setVsync(enable);
+}
+
+bool Game::isVsync()
+{
+    return Platform::isVsync();
+}
+
+int Game::run()
+{
+    if (_state != UNINITIALIZED)
+        return -1;
+
+    loadConfig();
+
+    _width = Platform::getDisplayWidth();
+    _height = Platform::getDisplayHeight();
+
+    // Start up game systems.
+    if (!startup())
+    {
+        shutdown();
+        return -2;
+    }
+
+    return 0;
+}
+
+bool Game::startup()
+{
+    if (_state != UNINITIALIZED)
+        return false;
+
+    setViewport(Rectangle(0.0f, 0.0f, (float)_width, (float)_height));
+    RenderState::initialize();
+    FrameBuffer::initialize();
+
+    _animationController = new AnimationController();
+    _animationController->initialize();
+
+    _audioController = new AudioController();
+    _audioController->initialize();
+
+    _physicsController = new PhysicsController();
+    _physicsController->initialize();
+
+    _aiController = new AIController();
+    _aiController->initialize();
+
+    _scriptController = new ScriptController();
+    _scriptController->initialize();
+
+    // Load any gamepads, ui or physical.
+    loadGamepads();
+
+    // Set the script callback functions.
+    if (_properties)
+    {
+        Properties* scripts = _properties->getNamespace("scripts", true);
+        if (scripts)
+        {
+            const char* callback;
+            while ((callback = scripts->getNextProperty()) != NULL)
+            {
+                std::string url = scripts->getString();
+                std::string file;
+                std::string id;
+                splitURL(url, &file, &id);
+
+                if (file.size() <= 0 || id.size() <= 0)
+                {
+                    GP_ERROR("Invalid %s script callback function '%s'.", callback, url.c_str());
+                }
+                else
+                {
+                    _scriptController->loadScript(file.c_str());
+                    _scriptController->registerCallback(callback, id.c_str());
+                }
+            }
+        }
+    }
+
+    _state = RUNNING;
+
+    return true;
+}
+
+void Game::shutdown()
+{
+    // Call user finalization.
+    if (_state != UNINITIALIZED)
+    {
+        GP_ASSERT(_animationController);
+        GP_ASSERT(_audioController);
+        GP_ASSERT(_physicsController);
+        GP_ASSERT(_aiController);
+
+        Platform::signalShutdown();
+
+		// Call user finalize
+        finalize();
+
+		// Shutdown scripting system first so that any objects allocated in script are released before our subsystems are released
+		_scriptController->finalizeGame();
+		if (_scriptListeners)
+		{
+			for (size_t i = 0; i < _scriptListeners->size(); i++)
+			{
+				SAFE_DELETE((*_scriptListeners)[i]);
+			}
+			SAFE_DELETE(_scriptListeners);
+		}
+		_scriptController->finalize();
+
+        unsigned int gamepadCount = Gamepad::getGamepadCount();
+        for (unsigned int i = 0; i < gamepadCount; i++)
+        {
+            Gamepad* gamepad = Gamepad::getGamepad(i, false);
+            SAFE_DELETE(gamepad);
+        }
+
+        _animationController->finalize();
+        SAFE_DELETE(_animationController);
+
+        _audioController->finalize();
+        SAFE_DELETE(_audioController);
+
+        _physicsController->finalize();
+        SAFE_DELETE(_physicsController);
+        _aiController->finalize();
+        SAFE_DELETE(_aiController);
+        
+        ControlFactory::finalize();
+
+        // Note: we do not clean up the script controller here
+        // because users can call Game::exit() from a script.
+
+        SAFE_DELETE(_audioListener);
+
+        FrameBuffer::finalize();
+        RenderState::finalize();
+
+        SAFE_DELETE(_properties);
+
+		_state = UNINITIALIZED;
+    }
+}
+
+void Game::pause()
+{
+    if (_state == RUNNING)
+    {
+        GP_ASSERT(_animationController);
+        GP_ASSERT(_audioController);
+        GP_ASSERT(_physicsController);
+        GP_ASSERT(_aiController);
+        _state = PAUSED;
+        _pausedTimeLast = Platform::getAbsoluteTime();
+        _animationController->pause();
+        _audioController->pause();
+        _physicsController->pause();
+        _aiController->pause();
+    }
+
+    ++_pausedCount;
+}
+
+void Game::resume()
+{
+    if (_state == PAUSED)
+    {
+        --_pausedCount;
+
+        if (_pausedCount == 0)
+        {
+            GP_ASSERT(_animationController);
+            GP_ASSERT(_audioController);
+            GP_ASSERT(_physicsController);
+            GP_ASSERT(_aiController);
+            _state = RUNNING;
+            _pausedTimeTotal += Platform::getAbsoluteTime() - _pausedTimeLast;
+            _animationController->resume();
+            _audioController->resume();
+            _physicsController->resume();
+            _aiController->resume();
+        }
+    }
+}
+
+void Game::exit()
+{
+    // Only perform a full/clean shutdown if FORCE_CLEAN_SHUTDOWN or
+    // GP_USE_MEM_LEAK_DETECTION is defined. Every modern OS is able to
+    // handle reclaiming process memory hundreds of times faster than it
+    // would take us to go through every pointer in the engine and release
+    // them nicely. For large games, shutdown can end up taking long time,
+    // so we'll just call ::exit(0) to force an instant shutdown.
+
+#if defined FORCE_CLEAN_SHUTDOWN || defined GP_USE_MEM_LEAK_DETECTION
+
+    // Schedule a call to shutdown rather than calling it right away.
+	// This handles the case of shutting down the script system from
+	// within a script function (which can cause errors).
+	static ShutdownListener listener;
+	schedule(0, &listener);
+
+#else
+
+    // End the process immediately without a full shutdown
+    ::exit(0);
+
+#endif
+}
+
+
+void Game::frame()
+{
+    if (!_initialized)
+    {
+        // Perform lazy first time initialization
+        initialize();
+        _scriptController->initializeGame();
+        _initialized = true;
+
+        // Fire first game resize event
+        Platform::resizeEventInternal(_width, _height);
+    }
+
+	static double lastFrameTime = Game::getGameTime();
+	double frameTime = getGameTime();
+
+    // Fire time events to scheduled TimeListeners
+    fireTimeEvents(frameTime);
+
+    if (_state == Game::RUNNING)
+    {
+        GP_ASSERT(_animationController);
+        GP_ASSERT(_audioController);
+        GP_ASSERT(_physicsController);
+        GP_ASSERT(_aiController);
+
+        // Update Time.
+        float elapsedTime = (frameTime - lastFrameTime);
+        lastFrameTime = frameTime;
+
+        // Update the scheduled and running animations.
+        _animationController->update(elapsedTime);
+
+        // Update the physics.
+        _physicsController->update(elapsedTime);
+
+        // Update AI.
+        _aiController->update(elapsedTime);
+
+        // Update gamepads.
+        Gamepad::updateInternal(elapsedTime);
+
+        // Application Update.
+        update(elapsedTime);
+
+        // Update forms.
+        Form::updateInternal(elapsedTime);
+
+        // Run script update.
+        _scriptController->update(elapsedTime);
+
+        // Audio Rendering.
+        _audioController->update(elapsedTime);
+
+        // Graphics Rendering.
+        render(elapsedTime);
+
+        // Run script render.
+        _scriptController->render(elapsedTime);
+
+        // Update FPS.
+        ++_frameCount;
+        if ((Game::getGameTime() - _frameLastFPS) >= 1000)
+        {
+            _frameRate = _frameCount;
+            _frameCount = 0;
+            _frameLastFPS = getGameTime();
+        }
+    }
+	else if (_state == Game::PAUSED)
+    {
+        // Update gamepads.
+        Gamepad::updateInternal(0);
+
+        // Application Update.
+        update(0);
+
+        // Update forms.
+        Form::updateInternal(0);
+
+        // Script update.
+        _scriptController->update(0);
+
+        // Graphics Rendering.
+        render(0);
+
+        // Script render.
+        _scriptController->render(0);
+    }
+}
+
+void Game::renderOnce(const char* function)
+{
+    _scriptController->executeFunction<void>(function, NULL);
+    Platform::swapBuffers();
+}
+
+void Game::updateOnce()
+{
+    GP_ASSERT(_animationController);
+    GP_ASSERT(_audioController);
+    GP_ASSERT(_physicsController);
+    GP_ASSERT(_aiController);
+
+    // Update Time.
+    static double lastFrameTime = getGameTime();
+    double frameTime = getGameTime();
+    float elapsedTime = (frameTime - lastFrameTime);
+    lastFrameTime = frameTime;
+
+    // Update the internal controllers.
+    _animationController->update(elapsedTime);
+    _physicsController->update(elapsedTime);
+    _aiController->update(elapsedTime);
+    _audioController->update(elapsedTime);
+    _scriptController->update(elapsedTime);
+}
+
+void Game::setViewport(const Rectangle& viewport)
+{
+    _viewport = viewport;
+    glViewport((GLuint)viewport.x, (GLuint)viewport.y, (GLuint)viewport.width, (GLuint)viewport.height);
+}
+
+void Game::clear(ClearFlags flags, const Vector4& clearColor, float clearDepth, int clearStencil)
+{
+    GLbitfield bits = 0;
+    if (flags & CLEAR_COLOR)
+    {
+        if (clearColor.x != _clearColor.x ||
+            clearColor.y != _clearColor.y ||
+            clearColor.z != _clearColor.z ||
+            clearColor.w != _clearColor.w )
+        {
+            glClearColor(clearColor.x, clearColor.y, clearColor.z, clearColor.w);
+            _clearColor.set(clearColor);
+        }
+        bits |= GL_COLOR_BUFFER_BIT;
+    }
+
+    if (flags & CLEAR_DEPTH)
+    {
+        if (clearDepth != _clearDepth)
+        {
+            glClearDepth(clearDepth);
+            _clearDepth = clearDepth;
+        }
+        bits |= GL_DEPTH_BUFFER_BIT;
+
+        // We need to explicitly call the static enableDepthWrite() method on StateBlock
+        // to ensure depth writing is enabled before clearing the depth buffer (and to
+        // update the global StateBlock render state to reflect this).
+        RenderState::StateBlock::enableDepthWrite();
+    }
+
+    if (flags & CLEAR_STENCIL)
+    {
+        if (clearStencil != _clearStencil)
+        {
+            glClearStencil(clearStencil);
+            _clearStencil = clearStencil;
+        }
+        bits |= GL_STENCIL_BUFFER_BIT;
+    }
+    glClear(bits);
+}
+
+void Game::clear(ClearFlags flags, float red, float green, float blue, float alpha, float clearDepth, int clearStencil)
+{
+    clear(flags, Vector4(red, green, blue, alpha), clearDepth, clearStencil);
+}
+
+AudioListener* Game::getAudioListener()
+{
+    if (_audioListener == NULL)
+    {
+        _audioListener = new AudioListener();
+    }
+    return _audioListener;
+}
+
+void Game::keyEvent(Keyboard::KeyEvent evt, int key)
+{
+}
+
+void Game::touchEvent(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex)
+{
+}
+
+bool Game::mouseEvent(Mouse::MouseEvent evt, int x, int y, int wheelDelta)
+{
+    return false;
+}
+
+void Game::resizeEvent(unsigned int width, unsigned int height)
+{
+}
+
+bool Game::isGestureSupported(Gesture::GestureEvent evt)
+{
+    return Platform::isGestureSupported(evt);
+}
+
+void Game::registerGesture(Gesture::GestureEvent evt)
+{
+    Platform::registerGesture(evt);
+}
+
+void Game::unregisterGesture(Gesture::GestureEvent evt)
+{
+    Platform::unregisterGesture(evt);
+}
+
+bool Game::isGestureRegistered(Gesture::GestureEvent evt)
+{
+    return Platform::isGestureRegistered(evt);
+}
+
+void Game::gestureSwipeEvent(int x, int y, int direction)
+{
+}
+
+void Game::gesturePinchEvent(int x, int y, float scale)
+{
+}
+
+void Game::gestureTapEvent(int x, int y)
+{
+}
+
+void Game::gestureLongTapEvent(int x, int y, float duration)
+{
+}
+
+void Game::gestureDragEvent(int x, int y)
+{
+}
+
+void Game::gestureDropEvent(int x, int y)
+{
+}
+
+void Game::gamepadEvent(Gamepad::GamepadEvent evt, Gamepad* gamepad)
+{
+}
+
+void Game::getArguments(int* argc, char*** argv) const
+{
+    Platform::getArguments(argc, argv);
+}
+
+void Game::schedule(float timeOffset, TimeListener* timeListener, void* cookie)
+{
+    GP_ASSERT(_timeEvents);
+    TimeEvent timeEvent(getGameTime() + timeOffset, timeListener, cookie);
+    _timeEvents->push(timeEvent);
+}
+
+void Game::schedule(float timeOffset, const char* function)
+{
+    if (!_scriptListeners)
+        _scriptListeners = new std::vector<ScriptListener*>();
+
+    ScriptListener* listener = new ScriptListener(function);
+    _scriptListeners->push_back(listener);
+    schedule(timeOffset, listener, NULL);
+}
+
+void Game::fireTimeEvents(double frameTime)
+{
+    while (_timeEvents->size() > 0)
+    {
+        const TimeEvent* timeEvent = &_timeEvents->top();
+        if (timeEvent->time > frameTime)
+        {
+            break;
+        }
+        if (timeEvent->listener)
+        {
+            timeEvent->listener->timeEvent(frameTime - timeEvent->time, timeEvent->cookie);
+        }
+        _timeEvents->pop();
+    }
+}
+
+Game::ScriptListener::ScriptListener(const char* url)
+{
+    function = Game::getInstance()->getScriptController()->loadUrl(url);
+}
+
+void Game::ScriptListener::timeEvent(long timeDiff, void* cookie)
+{
+    Game::getInstance()->getScriptController()->executeFunction<void>(function.c_str(), "l", timeDiff);
+}
+
+Game::TimeEvent::TimeEvent(double time, TimeListener* timeListener, void* cookie)
+    : time(time), listener(timeListener), cookie(cookie)
+{
+}
+
+bool Game::TimeEvent::operator<(const TimeEvent& v) const
+{
+    // The first element of std::priority_queue is the greatest.
+    return time > v.time;
+}
+
+Properties* Game::getConfig() const
+{
+    if (_properties == NULL)
+        const_cast<Game*>(this)->loadConfig();
+
+    return _properties;
+}
+
+void Game::loadConfig()
+{
+    if (_properties == NULL)
+    {
+        // Try to load custom config from file.
+        if (FileSystem::fileExists("game.config"))
+        {
+            _properties = Properties::create("game.config");
+
+            // Load filesystem aliases.
+            Properties* aliases = _properties->getNamespace("aliases", true);
+            if (aliases)
+            {
+                FileSystem::loadResourceAliases(aliases);
+            }
+        }
+        else
+        {
+            // Create an empty config
+            _properties = new Properties();
+        }
+    }
+}
+
+void Game::loadGamepads()
+{
+    // Load virtual gamepads.
+    if (_properties)
+    {
+        // Check if there are any virtual gamepads included in the .config file.
+        // If there are, create and initialize them.
+        _properties->rewind();
+        Properties* inner = _properties->getNextNamespace();
+        while (inner != NULL)
+        {
+            std::string spaceName(inner->getNamespace());
+            // This namespace was accidentally named "gamepads" originally but we'll keep this check
+            // for backwards compatibility.
+            if (spaceName == "gamepads" || spaceName == "gamepad")
+            {
+                if (inner->exists("form"))
+                {
+                    const char* gamepadFormPath = inner->getString("form");
+                    GP_ASSERT(gamepadFormPath);
+                    Gamepad* gamepad = Gamepad::add(gamepadFormPath);
+                    GP_ASSERT(gamepad);
+                }
+            }
+
+            inner = _properties->getNextNamespace();
+        }
+    }
+}
+
+void Game::ShutdownListener::timeEvent(long timeDiff, void* cookie)
+{
+	Game::getInstance()->shutdown();
+}
+
+}
+

+ 774 - 774
gameplay/src/Game.h

@@ -1,774 +1,774 @@
-#ifndef GAME_H_
-#define GAME_H_
-
-#include "Keyboard.h"
-#include "Mouse.h"
-#include "Touch.h"
-#include "Gesture.h"
-#include "Gamepad.h"
-#include "AudioController.h"
-#include "AnimationController.h"
-#include "PhysicsController.h"
-#include "AIController.h"
-#include "AudioListener.h"
-#include "Rectangle.h"
-#include "Vector4.h"
-#include "TimeListener.h"
-
-namespace gameplay
-{
-
-class ScriptController;
-
-/**
- * Defines the basic game initialization, logic and platform delegates.
- */
-class Game
-{
-    friend class Platform;
-    friend class ShutdownListener;
-
-public:
-    
-    /**
-     * The game states.
-     */
-    enum State
-    {
-        UNINITIALIZED,
-        RUNNING,
-        PAUSED
-    };
-
-    /**
-     * Flags used when clearing the active frame buffer targets.
-     */
-    enum ClearFlags
-    {
-        CLEAR_COLOR = GL_COLOR_BUFFER_BIT,
-        CLEAR_DEPTH = GL_DEPTH_BUFFER_BIT,
-        CLEAR_STENCIL = GL_STENCIL_BUFFER_BIT,
-        CLEAR_COLOR_DEPTH = CLEAR_COLOR | CLEAR_DEPTH,
-        CLEAR_COLOR_STENCIL = CLEAR_COLOR | CLEAR_STENCIL,
-        CLEAR_DEPTH_STENCIL = CLEAR_DEPTH | CLEAR_STENCIL,
-        CLEAR_COLOR_DEPTH_STENCIL = CLEAR_COLOR | CLEAR_DEPTH | CLEAR_STENCIL
-    };
-
-    /**
-     * Destructor.
-     */
-    virtual ~Game();
-
-    /**
-     * Gets the single instance of the game.
-     * 
-     * @return The single instance of the game.
-     */
-    static Game* getInstance();
-
-    /**
-     * Gets whether vertical sync is enabled for the game display.
-     * 
-     * @return true if vsync is enabled; false if not.
-     */
-    static bool isVsync();
-
-    /**
-     * Sets whether vertical sync is enabled for the game display.
-     *
-     * @param enable true if vsync is enabled; false if not.
-     */
-    static void setVsync(bool enable);
-
-    /**
-     * Gets the total absolute running time (in milliseconds) since Game::run().
-     * 
-     * @return The total absolute running time (in milliseconds).
-     */
-    static double getAbsoluteTime();
-
-    /**
-     * Gets the total game time (in milliseconds). This is the total accumulated game time (unpaused).
-     *
-     * You would typically use things in your game that you want to stop when the game is paused.
-     * This includes things such as game physics and animation.
-     * 
-     * @return The total game time (in milliseconds).
-     */
-    static double getGameTime();
-
-    /**
-     * Gets the game state.
-     *
-     * @return The current game state.
-     */
-    inline State getState() const;
-
-    /**
-     * Determines if the game has been initialized.
-     *
-     * @return true if the game initialization has completed, false otherwise.
-     */
-    inline bool isInitialized() const;
-
-    /**
-     * Returns the game configuration object.
-     *
-     * This method returns a Properties object containing the contents
-     * of the game.config file.
-     *
-     * @return The game configuration Properties object.
-     */
-    Properties* getConfig() const;
-
-    /**
-     * Called to initialize the game, and begin running the game.
-     * 
-     * @return Zero for normal termination, or non-zero if an error occurred.
-     */
-    int run();
-
-    /**
-     * Pauses the game after being run.
-     */
-    void pause();
-
-    /**
-     * Resumes the game after being paused.
-     */
-    void resume();
-
-    /**
-     * Exits the game.
-     */
-    void exit();
-
-    /**
-     * Platform frame delegate.
-     *
-     * This is called every frame from the platform.
-     * This in turn calls back on the user implemented game methods: update() then render()
-     */
-    void frame();
-
-    /**
-     * Gets the current frame rate.
-     * 
-     * @return The current frame rate.
-     */
-    inline unsigned int getFrameRate() const;
-
-    /**
-     * Gets the game window width.
-     * 
-     * @return The game window width.
-     */
-    inline unsigned int getWidth() const;
-
-    /**
-     * Gets the game window height.
-     * 
-     * @return The game window height.
-     */
-    inline unsigned int getHeight() const;
-    
-    /**
-     * Gets the aspect ratio of the window. (width / height)
-     * 
-     * @return The aspect ratio of the window.
-     */
-    inline float getAspectRatio() const;
-
-    /**
-     * Gets the game current viewport.
-     *
-     * The default viewport is Rectangle(0, 0, Game::getWidth(), Game::getHeight()).
-     */
-    inline const Rectangle& getViewport() const;
-
-    /**
-     * Sets the game current viewport.
-     *
-     * The x, y, width and height of the viewport must all be positive.
-     *
-     * viewport The custom viewport to be set on the game.
-     */
-    void setViewport(const Rectangle& viewport);
-
-    /**
-     * Clears the specified resource buffers to the specified clear values. 
-     *
-     * @param flags The flags indicating which buffers to be cleared.
-     * @param clearColor The color value to clear to when the flags includes the color buffer.
-     * @param clearDepth The depth value to clear to when the flags includes the color buffer.
-     * @param clearStencil The stencil value to clear to when the flags includes the color buffer.
-     */
-    void clear(ClearFlags flags, const Vector4& clearColor, float clearDepth, int clearStencil);
-
-    /**
-     * Clears the specified resource buffers to the specified clear values. 
-     * 
-     * @param flags The flags indicating which buffers to be cleared.
-     * @param red The red channel.
-     * @param green The green channel.
-     * @param blue The blue channel.
-     * @param alpha The alpha channel.
-     * @param clearDepth The depth value to clear to when the flags includes the color buffer.
-     * @param clearStencil The stencil value to clear to when the flags includes the color buffer.
-     */
-    void clear(ClearFlags flags, float red, float green, float blue, float alpha, float clearDepth, int clearStencil);
-
-    /**
-     * Gets the audio controller for managing control of audio
-     * associated with the game.
-     *
-     * @return The audio controller for this game.
-     */
-    inline AudioController* getAudioController() const;
-
-    /**
-     * Gets the animation controller for managing control of animations
-     * associated with the game.
-     * 
-     * @return The animation controller for this game.
-     */
-    inline AnimationController* getAnimationController() const;
-
-    /**
-     * Gets the physics controller for managing control of physics
-     * associated with the game.
-     * 
-     * @return The physics controller for this game.
-     */
-    inline PhysicsController* getPhysicsController() const;
-
-    /** 
-     * Gets the AI controller for managing control of artificial
-     * intelligence associated with the game.
-     *
-     * @return The AI controller for this game.
-     */
-    inline AIController* getAIController() const;
-
-    /**
-     * Gets the script controller for managing control of Lua scripts
-     * associated with the game.
-     * 
-     * @return The script controller for this game.
-     */
-    inline ScriptController* getScriptController() const;
-
-    /**
-     * Gets the audio listener for 3D audio.
-     * 
-     * @return The audio listener for this game.
-     */
-    AudioListener* getAudioListener();
-    
-    /**
-     * Shows or hides the virtual keyboard (if supported).
-     *
-     * @param display true when virtual keyboard needs to be displayed; false otherwise.
-     */
-     inline void displayKeyboard(bool display);
-     
-    /**
-     * Keyboard callback on keyPress events.
-     *
-     * @param evt The key event that occurred.
-     * @param key If evt is KEY_PRESS or KEY_RELEASE then key is the key code from Keyboard::Key.
-     *            If evt is KEY_CHAR then key is the unicode value of the character.
-     * 
-     * @see Keyboard::KeyEvent
-     * @see Keyboard::Key
-     */
-    virtual void keyEvent(Keyboard::KeyEvent evt, int key);
-
-    /**
-     * Touch callback on touch events.
-     *
-     * @param evt The touch event that occurred.
-     * @param x The x position of the touch in pixels. Left edge is zero.
-     * @param y The y position of the touch in pixels. Top edge is zero.
-     * @param contactIndex The order of occurrence for multiple touch contacts starting at zero.
-     *
-     * @see Touch::TouchEvent
-     */
-    virtual void touchEvent(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex);
-
-    /**
-     * Mouse callback on mouse events. If the game does not consume the mouse move event or left mouse click event
-     * then it is interpreted as a touch event instead.
-     *
-     * @param evt The mouse event that occurred.
-     * @param x The x position of the mouse in pixels. Left edge is zero.
-     * @param y The y position of the mouse in pixels. Top edge is zero.
-     * @param wheelDelta The number of mouse wheel ticks. Positive is up (forward), negative is down (backward).
-     *
-     * @return True if the mouse event is consumed or false if it is not consumed.
-     *
-     * @see Mouse::MouseEvent
-     */
-    virtual bool mouseEvent(Mouse::MouseEvent evt, int x, int y, int wheelDelta);
-    
-    /**
-     * Called when the game window has been resized.
-     *
-     * This method is called once the game window is created with its initial size
-     * and then again any time the game window changes size.
-     *
-     * @param width The new game window width.
-     * @param height The new game window height.
-     */
-    virtual void resizeEvent(unsigned int width, unsigned int height);
-
-    /** 
-     * Gets whether the current platform supports mouse input.
-     *
-     * @return true if a mouse is supported, false otherwise.
-     */
-    inline bool hasMouse();
-    
-    /**
-     * Gets whether mouse input is currently captured.
-     *
-     * @return is the mouse captured.
-     */
-    inline bool isMouseCaptured();
-    
-    /**
-     * Enables or disables mouse capture.
-     *
-     * On platforms that support a mouse, when mouse capture is enabled,
-     * the platform cursor will be hidden and the mouse will be warped
-     * to the center of the screen. While mouse capture is enabled,
-     * all mouse move events will then be delivered as deltas instead
-     * of absolute positions.
-     *
-     * @param captured true to enable mouse capture mode, false to disable it.
-     */
-    inline void setMouseCaptured(bool captured);
-    
-    /**
-     * Sets the visibility of the platform cursor.
-     *
-     * @param visible true to show the platform cursor, false to hide it.
-     */
-    inline void setCursorVisible(bool visible);
-    
-    /**
-     * Determines whether the platform cursor is currently visible.
-     *
-     * @return true if the platform cursor is visible, false otherwise.
-     */
-    inline bool isCursorVisible();
-
-    /**
-     * Determines whether a specified gesture event is supported.
-     *
-     * Use Gesture::GESTURE_ANY_SUPPORTED to test if one or more gesture events are supported.
-     *
-     * @param evt The gesture event to test and see if it is supported.
-     * @return true if the gesture tested is supported; false if not supported.
-     */
-    bool isGestureSupported(Gesture::GestureEvent evt);
-
-    /**
-     * Requests the game to register and start recognizing the specified gesture event.
-     *
-     * Call with Gesture::GESTURE_ANY_SUPPORTED to recognize all supported gestures.
-     * Once a gesture is recognized the specific gesture event methods will
-     * begin to be called.
-     *
-     * Registering for:
-     *
-     * Gesture::GESTURE_SWIPE calls gestureSwipeEvent(..)
-     * Gesture::GESTURE_PINCH calls gesturePinchEvent(..)
-     * Gesture::GESTURE_TAP calls gestureTapEvent(..)
-     *
-     * @param evt The gesture event to start recognizing for
-     */
-    void registerGesture(Gesture::GestureEvent evt);
-
-    /**
-     * Requests the game to unregister for and stop recognizing the specified gesture event.
-     *
-     * Call with Gesture::GESTURE_ANY_SUPPORTED to unregister events from all supported gestures.
-     *
-     * @param evt The gesture event to start recognizing for
-     */
-    void unregisterGesture(Gesture::GestureEvent evt);
-
-    /**
-     * Determines whether a specified gesture event is registered to receive event callbacks.
-     *
-     * @return true if the specified gesture event is registered; false of not registered.
-     */
-    bool isGestureRegistered(Gesture::GestureEvent evt);
-
-    /**
-     * Gesture callback on Gesture::SWIPE events.
-     *
-     * @param x The x-coordinate of the start of the swipe.
-     * @param y The y-coordinate of the start of the swipe.
-     * @param direction The direction of the swipe
-     *
-     * @see Gesture::SWIPE_DIRECTION_UP
-     * @see Gesture::SWIPE_DIRECTION_DOWN
-     * @see Gesture::SWIPE_DIRECTION_LEFT
-     * @see Gesture::SWIPE_DIRECTION_RIGHT
-     */
-    virtual void gestureSwipeEvent(int x, int y, int direction);
-
-    /**
-     * Gesture callback on Gesture::PINCH events.
-     *
-     * @param x The centroid x-coordinate of the pinch.
-     * @param y The centroid y-coordinate of the pinch.
-     * @param scale The scale of the pinch.
-     */
-    virtual void gesturePinchEvent(int x, int y, float scale);
-
-    /**
-     * Gesture callback on Gesture::LONG_TAP events.
-     *
-     * @param x The x-coordinate of the long tap.
-     * @param y The y-coordinate of the long tap.
-     * @param duration The duration of the long tap in ms.
-     */
-    virtual void gestureLongTapEvent(int x, int y, float duration);
-
-    /**
-     * Gesture callback on Gesture::TAP events.
-     *
-     * @param x The x-coordinate of the tap.
-     * @param y The y-coordinate of the tap.
-     */
-    virtual void gestureTapEvent(int x, int y);
-
-    /**
-     * Gesture callback on Gesture::DRAG events.
-     *
-     * @param x The x-coordinate of the start of the drag event.
-     * @param y The y-coordinate of the start of the drag event.
-     */
-    virtual void gestureDragEvent(int x, int y);
-
-    /**
-     * Gesture callback on Gesture::DROP events.
-     *
-     * @param x The x-coordinate of the drop event.
-     * @param y The y-coordinate of the drop event.
-     */
-    virtual void gestureDropEvent(int x, int y);
-
-    /**
-     * Gamepad callback on gamepad events.  Override to receive Gamepad::CONNECTED_EVENT 
-     * and Gamepad::DISCONNECTED_EVENT, and store the Gamepad* in order to poll it from update().
-     *
-     * @param evt The gamepad event that occurred.
-     * @param gamepad The gamepad that generated the event.
-     */
-    virtual void gamepadEvent(Gamepad::GamepadEvent evt, Gamepad* gamepad);
-
-    /**
-     * Gets the current number of gamepads currently connected to the system.
-     *
-     * @return The number of gamepads currently connected to the system.
-     */
-    inline unsigned int getGamepadCount() const;
-
-    /**
-     * Gets the gamepad at the specified index. 
-     *
-     * The gamepad index can change when connected and disconnected so you
-     * cannot rely on this other than iterating through them all to display
-     * them or poll them.
-     * 
-     * The preferPhysical will bump over virtual gamepads if physical gamepads are
-     * connected and return the request index of the first or second physcial and then 
-     * return back to the first virtual after.
-     *
-     * @param index The index of the gamepad to retrieve.
-     * @param preferPhysical true if you prefer return a physical if exist; false if only virtual.
-     * @return The gamepad at the specified index.
-     */
-    inline Gamepad* getGamepad(unsigned int index, bool preferPhysical = true) const;
-
-    /**
-     * Sets whether multi-sampling is to be enabled/disabled. Default is disabled.
-     *
-     * @param enabled true sets multi-sampling to be enabled, false to be disabled.
-     */
-    inline void setMultiSampling(bool enabled);
-
-    /*
-     * Is multi-sampling enabled.
-     *
-     * @return true if multi-sampling is enabled.
-     */
-    inline bool isMultiSampling() const;
-
-    /**
-     * Sets multi-touch is to be enabled/disabled. Default is disabled.
-     *
-     * @param enabled true sets multi-touch is enabled, false to be disabled.
-     */
-    inline void setMultiTouch(bool enabled);
-
-    /**
-     * Is multi-touch mode enabled.
-     *
-     * @return true if multi-touch is enabled.
-     */
-    inline bool isMultiTouch() const;
-
-    /**
-     * Whether this game is allowed to exit programmatically.
-     *
-     * @return true if a programmatic exit is allowed.
-     */
-    inline bool canExit() const;
-
-    /**
-     * Whether this game has accelerometer support.
-     */
-    inline bool hasAccelerometer() const;
-
-    /**
-     * Gets the current accelerometer values for use as an indication of device
-     * orientation. Despite its name, implementations are at liberty to combine
-     * accelerometer data with data from other sensors as well, such as the gyros.
-     * This method is best used to obtain an indication of device orientation; it
-     * does not necessarily distinguish between acceleration and rotation rate.
-     *
-     * @param pitch The pitch angle returned (in degrees). Zero if hasAccelerometer() returns false.
-     * @param roll The roll angle returned (in degrees). Zero if hasAccelerometer() returns false.
-     */
-    inline void getAccelerometerValues(float* pitch, float* roll);
-
-    /**
-     * Gets sensor values (raw), if equipped, allowing a distinction between device acceleration
-     * and rotation rate. Returns zeros on platforms with no corresponding support. See also
-     * hasAccelerometer() and getAccelerometerValues().
-     *
-     * @param accelX The x-coordinate of the raw accelerometer data.
-     * @param accelY The y-coordinate of the raw accelerometer data.
-     * @param accelZ The z-coordinate of the raw accelerometer data.
-     * @param gyroX The x-coordinate of the raw gyroscope data.
-     * @param gyroY The y-coordinate of the raw gyroscope data.
-     * @param gyroZ The z-coordinate of the raw gyroscope data.
-     */
-    inline void getSensorValues(float* accelX, float* accelY, float* accelZ, float* gyroX, float* gyroY, float* gyroZ);
-
-    /**
-     * Gets the command line arguments.
-     * 
-     * @param argc The number of command line arguments.
-     * @param argv The array of command line arguments.
-     * @script{ignore}
-     */
-    void getArguments(int* argc, char*** argv) const;
-
-    /**
-     * Schedules a time event to be sent to the given TimeListener a given number of game milliseconds from now.
-     * Game time stops while the game is paused. A time offset of zero will fire the time event in the next frame.
-     * 
-     * @param timeOffset The number of game milliseconds in the future to schedule the event to be fired.
-     * @param timeListener The TimeListener that will receive the event.
-     * @param cookie The cookie data that the time event will contain.
-     * @script{ignore}
-     */
-    void schedule(float timeOffset, TimeListener* timeListener, void* cookie = 0);
-
-    /**
-     * Schedules a time event to be sent to the given TimeListener a given number of game milliseconds from now.
-     * Game time stops while the game is paused. A time offset of zero will fire the time event in the next frame.
-     * 
-     * Note: the given Lua function must take a single floating point number, which is the difference between the
-     * current game time and the target time (see TimeListener::timeEvent).
-     * 
-     * @param timeOffset The number of game milliseconds in the future to schedule the event to be fired.
-     * @param function The Lua script function that will receive the event.
-     */
-    void schedule(float timeOffset, const char* function);
-
-    /**
-     * Opens an URL in an external browser, if available.
-     *
-     * @param url URL to be opened.
-     *
-     * @return True if URL was opened successfully, false otherwise.
-     */
-    bool launchURL(const char *url) const;
-
-protected:
-
-    /**
-     * Constructor.
-     */
-    Game();
-
-    /**
-     * Initialize callback that is called just before the first frame when the game starts.
-     */
-    virtual void initialize() = 0;
-
-    /**
-     * Finalize callback that is called when the game on exits.
-     */
-    virtual void finalize() = 0;
-
-    /**
-     * Update callback for handling update routines.
-     *
-     * Called just before render, once per frame when game is running.
-     * Ideal for non-render code and game logic such as input and animation.
-     *
-     * @param elapsedTime The elapsed game time.
-     */
-    virtual void update(float elapsedTime) = 0;
-
-    /**
-     * Render callback for handling rendering routines.
-     *
-     * Called just after update, once per frame when game is running.
-     * Ideal for all rendering code.
-     *
-     * @param elapsedTime The elapsed game time.
-     */
-    virtual void render(float elapsedTime) = 0;
-
-    /**
-     * Renders a single frame once and then swaps it to the display.
-     *
-     * This is useful for rendering splash screens.
-     */
-    template <class T>
-    void renderOnce(T* instance, void (T::*method)(void*), void* cookie);
-
-    /**
-     * Renders a single frame once and then swaps it to the display.
-     * This calls the given Lua function, which should take no parameters and return nothing (void).
-     *
-     * This is useful for rendering splash screens.
-     */
-    void renderOnce(const char* function);
-
-    /**
-     * Updates the game's internal systems (audio, animation, physics) once.
-     * 
-     * Note: This does not call the user-defined Game::update() function.
-     *
-     * This is useful for rendering animated splash screens.
-     */
-    void updateOnce();
-
-private:
-
-    /**
-     * Allows time listener interaction from Lua scripts.
-     */
-    struct ScriptListener : public TimeListener
-    {
-        /**
-         * Constructor.
-         */
-        ScriptListener(const char* url);
-
-        /**
-         * @see TimeListener#timeEvent(long, void*)
-         */
-        void timeEvent(long timeDiff, void* cookie);
-
-        /** Holds the name of the Lua script function to call back. */
-        std::string function;
-    };
-
-    struct ShutdownListener : public TimeListener
-    {
-        void timeEvent(long timeDiff, void* cookie);
-    };
-
-    /**
-     * TimeEvent represents the event that is sent to TimeListeners as a result of calling Game::schedule().
-     */
-    class TimeEvent
-    {
-    public:
-
-        TimeEvent(double time, TimeListener* timeListener, void* cookie);
-        bool operator<(const TimeEvent& v) const;
-        double time;
-        TimeListener* listener;
-        void* cookie;
-    };
-
-    /**
-     * Constructor.
-     *
-     * @param copy The game to copy.
-     */
-    Game(const Game& copy);
-
-    /**
-     * Starts the game.
-     */
-    bool startup();
-
-    /**
-     * Shuts down the game.
-     */
-    void shutdown();
-
-    /**
-     * Fires the time events that were scheduled to be called.
-     * 
-     * @param frameTime The current game frame time. Used to determine which time events need to be fired.
-     */
-    void fireTimeEvents(double frameTime);
-
-    /**
-     * Loads the game configuration.
-     */
-    void loadConfig();
-
-    /**
-     * Loads the gamepads from the configuration file.
-     */
-    void loadGamepads();
-
-    bool _initialized;                          // If game has initialized yet.
-    State _state;                               // The game state.
-    unsigned int _pausedCount;                  // Number of times pause() has been called.
-    static double _pausedTimeLast;              // The last time paused.
-    static double _pausedTimeTotal;             // The total time paused.
-    double _frameLastFPS;                       // The last time the frame count was updated.
-    unsigned int _frameCount;                   // The current frame count.
-    unsigned int _frameRate;                    // The current frame rate.
-    unsigned int _width;                        // The game's display width.
-    unsigned int _height;                       // The game's display height.
-    Rectangle _viewport;                        // the games's current viewport.
-    Vector4 _clearColor;                        // The clear color value last used for clearing the color buffer.
-    float _clearDepth;                          // The clear depth value last used for clearing the depth buffer.
-    int _clearStencil;                          // The clear stencil value last used for clearing the stencil buffer.
-    Properties* _properties;                    // Game configuration properties object.
-    AnimationController* _animationController;  // Controls the scheduling and running of animations.
-    AudioController* _audioController;          // Controls audio sources that are playing in the game.
-    PhysicsController* _physicsController;      // Controls the simulation of a physics scene and entities.
-    AIController* _aiController;                // Controls AI simulation.
-    AudioListener* _audioListener;              // The audio listener in 3D space.
-    std::priority_queue<TimeEvent, std::vector<TimeEvent>, std::less<TimeEvent> >* _timeEvents;     // Contains the scheduled time events.
-    ScriptController* _scriptController;            // Controls the scripting engine.
-    std::vector<ScriptListener*>* _scriptListeners; // Lua script listeners.
-
-    // Note: Do not add STL object member variables on the stack; this will cause false memory leaks to be reported.
-
-    friend class ScreenDisplayer;
-};
-
-}
-
-#include "Game.inl"
-
-#endif
+#ifndef GAME_H_
+#define GAME_H_
+
+#include "Keyboard.h"
+#include "Mouse.h"
+#include "Touch.h"
+#include "Gesture.h"
+#include "Gamepad.h"
+#include "AudioController.h"
+#include "AnimationController.h"
+#include "PhysicsController.h"
+#include "AIController.h"
+#include "AudioListener.h"
+#include "Rectangle.h"
+#include "Vector4.h"
+#include "TimeListener.h"
+
+namespace gameplay
+{
+
+class ScriptController;
+
+/**
+ * Defines the basic game initialization, logic and platform delegates.
+ */
+class Game
+{
+    friend class Platform;
+    friend class ShutdownListener;
+
+public:
+    
+    /**
+     * The game states.
+     */
+    enum State
+    {
+        UNINITIALIZED,
+        RUNNING,
+        PAUSED
+    };
+
+    /**
+     * Flags used when clearing the active frame buffer targets.
+     */
+    enum ClearFlags
+    {
+        CLEAR_COLOR = GL_COLOR_BUFFER_BIT,
+        CLEAR_DEPTH = GL_DEPTH_BUFFER_BIT,
+        CLEAR_STENCIL = GL_STENCIL_BUFFER_BIT,
+        CLEAR_COLOR_DEPTH = CLEAR_COLOR | CLEAR_DEPTH,
+        CLEAR_COLOR_STENCIL = CLEAR_COLOR | CLEAR_STENCIL,
+        CLEAR_DEPTH_STENCIL = CLEAR_DEPTH | CLEAR_STENCIL,
+        CLEAR_COLOR_DEPTH_STENCIL = CLEAR_COLOR | CLEAR_DEPTH | CLEAR_STENCIL
+    };
+
+    /**
+     * Destructor.
+     */
+    virtual ~Game();
+
+    /**
+     * Gets the single instance of the game.
+     * 
+     * @return The single instance of the game.
+     */
+    static Game* getInstance();
+
+    /**
+     * Gets whether vertical sync is enabled for the game display.
+     * 
+     * @return true if vsync is enabled; false if not.
+     */
+    static bool isVsync();
+
+    /**
+     * Sets whether vertical sync is enabled for the game display.
+     *
+     * @param enable true if vsync is enabled; false if not.
+     */
+    static void setVsync(bool enable);
+
+    /**
+     * Gets the total absolute running time (in milliseconds) since Game::run().
+     * 
+     * @return The total absolute running time (in milliseconds).
+     */
+    static double getAbsoluteTime();
+
+    /**
+     * Gets the total game time (in milliseconds). This is the total accumulated game time (unpaused).
+     *
+     * You would typically use things in your game that you want to stop when the game is paused.
+     * This includes things such as game physics and animation.
+     * 
+     * @return The total game time (in milliseconds).
+     */
+    static double getGameTime();
+
+    /**
+     * Gets the game state.
+     *
+     * @return The current game state.
+     */
+    inline State getState() const;
+
+    /**
+     * Determines if the game has been initialized.
+     *
+     * @return true if the game initialization has completed, false otherwise.
+     */
+    inline bool isInitialized() const;
+
+    /**
+     * Returns the game configuration object.
+     *
+     * This method returns a Properties object containing the contents
+     * of the game.config file.
+     *
+     * @return The game configuration Properties object.
+     */
+    Properties* getConfig() const;
+
+    /**
+     * Called to initialize the game, and begin running the game.
+     * 
+     * @return Zero for normal termination, or non-zero if an error occurred.
+     */
+    int run();
+
+    /**
+     * Pauses the game after being run.
+     */
+    void pause();
+
+    /**
+     * Resumes the game after being paused.
+     */
+    void resume();
+
+    /**
+     * Exits the game.
+     */
+    void exit();
+
+    /**
+     * Platform frame delegate.
+     *
+     * This is called every frame from the platform.
+     * This in turn calls back on the user implemented game methods: update() then render()
+     */
+    void frame();
+
+    /**
+     * Gets the current frame rate.
+     * 
+     * @return The current frame rate.
+     */
+    inline unsigned int getFrameRate() const;
+
+    /**
+     * Gets the game window width.
+     * 
+     * @return The game window width.
+     */
+    inline unsigned int getWidth() const;
+
+    /**
+     * Gets the game window height.
+     * 
+     * @return The game window height.
+     */
+    inline unsigned int getHeight() const;
+    
+    /**
+     * Gets the aspect ratio of the window. (width / height)
+     * 
+     * @return The aspect ratio of the window.
+     */
+    inline float getAspectRatio() const;
+
+    /**
+     * Gets the game current viewport.
+     *
+     * The default viewport is Rectangle(0, 0, Game::getWidth(), Game::getHeight()).
+     */
+    inline const Rectangle& getViewport() const;
+
+    /**
+     * Sets the game current viewport.
+     *
+     * The x, y, width and height of the viewport must all be positive.
+     *
+     * viewport The custom viewport to be set on the game.
+     */
+    void setViewport(const Rectangle& viewport);
+
+    /**
+     * Clears the specified resource buffers to the specified clear values. 
+     *
+     * @param flags The flags indicating which buffers to be cleared.
+     * @param clearColor The color value to clear to when the flags includes the color buffer.
+     * @param clearDepth The depth value to clear to when the flags includes the color buffer.
+     * @param clearStencil The stencil value to clear to when the flags includes the color buffer.
+     */
+    void clear(ClearFlags flags, const Vector4& clearColor, float clearDepth, int clearStencil);
+
+    /**
+     * Clears the specified resource buffers to the specified clear values. 
+     * 
+     * @param flags The flags indicating which buffers to be cleared.
+     * @param red The red channel.
+     * @param green The green channel.
+     * @param blue The blue channel.
+     * @param alpha The alpha channel.
+     * @param clearDepth The depth value to clear to when the flags includes the color buffer.
+     * @param clearStencil The stencil value to clear to when the flags includes the color buffer.
+     */
+    void clear(ClearFlags flags, float red, float green, float blue, float alpha, float clearDepth, int clearStencil);
+
+    /**
+     * Gets the audio controller for managing control of audio
+     * associated with the game.
+     *
+     * @return The audio controller for this game.
+     */
+    inline AudioController* getAudioController() const;
+
+    /**
+     * Gets the animation controller for managing control of animations
+     * associated with the game.
+     * 
+     * @return The animation controller for this game.
+     */
+    inline AnimationController* getAnimationController() const;
+
+    /**
+     * Gets the physics controller for managing control of physics
+     * associated with the game.
+     * 
+     * @return The physics controller for this game.
+     */
+    inline PhysicsController* getPhysicsController() const;
+
+    /** 
+     * Gets the AI controller for managing control of artificial
+     * intelligence associated with the game.
+     *
+     * @return The AI controller for this game.
+     */
+    inline AIController* getAIController() const;
+
+    /**
+     * Gets the script controller for managing control of Lua scripts
+     * associated with the game.
+     * 
+     * @return The script controller for this game.
+     */
+    inline ScriptController* getScriptController() const;
+
+    /**
+     * Gets the audio listener for 3D audio.
+     * 
+     * @return The audio listener for this game.
+     */
+    AudioListener* getAudioListener();
+    
+    /**
+     * Shows or hides the virtual keyboard (if supported).
+     *
+     * @param display true when virtual keyboard needs to be displayed; false otherwise.
+     */
+     inline void displayKeyboard(bool display);
+     
+    /**
+     * Keyboard callback on keyPress events.
+     *
+     * @param evt The key event that occurred.
+     * @param key If evt is KEY_PRESS or KEY_RELEASE then key is the key code from Keyboard::Key.
+     *            If evt is KEY_CHAR then key is the unicode value of the character.
+     * 
+     * @see Keyboard::KeyEvent
+     * @see Keyboard::Key
+     */
+    virtual void keyEvent(Keyboard::KeyEvent evt, int key);
+
+    /**
+     * Touch callback on touch events.
+     *
+     * @param evt The touch event that occurred.
+     * @param x The x position of the touch in pixels. Left edge is zero.
+     * @param y The y position of the touch in pixels. Top edge is zero.
+     * @param contactIndex The order of occurrence for multiple touch contacts starting at zero.
+     *
+     * @see Touch::TouchEvent
+     */
+    virtual void touchEvent(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex);
+
+    /**
+     * Mouse callback on mouse events. If the game does not consume the mouse move event or left mouse click event
+     * then it is interpreted as a touch event instead.
+     *
+     * @param evt The mouse event that occurred.
+     * @param x The x position of the mouse in pixels. Left edge is zero.
+     * @param y The y position of the mouse in pixels. Top edge is zero.
+     * @param wheelDelta The number of mouse wheel ticks. Positive is up (forward), negative is down (backward).
+     *
+     * @return True if the mouse event is consumed or false if it is not consumed.
+     *
+     * @see Mouse::MouseEvent
+     */
+    virtual bool mouseEvent(Mouse::MouseEvent evt, int x, int y, int wheelDelta);
+    
+    /**
+     * Called when the game window has been resized.
+     *
+     * This method is called once the game window is created with its initial size
+     * and then again any time the game window changes size.
+     *
+     * @param width The new game window width.
+     * @param height The new game window height.
+     */
+    virtual void resizeEvent(unsigned int width, unsigned int height);
+
+    /** 
+     * Gets whether the current platform supports mouse input.
+     *
+     * @return true if a mouse is supported, false otherwise.
+     */
+    inline bool hasMouse();
+    
+    /**
+     * Gets whether mouse input is currently captured.
+     *
+     * @return is the mouse captured.
+     */
+    inline bool isMouseCaptured();
+    
+    /**
+     * Enables or disables mouse capture.
+     *
+     * On platforms that support a mouse, when mouse capture is enabled,
+     * the platform cursor will be hidden and the mouse will be warped
+     * to the center of the screen. While mouse capture is enabled,
+     * all mouse move events will then be delivered as deltas instead
+     * of absolute positions.
+     *
+     * @param captured true to enable mouse capture mode, false to disable it.
+     */
+    inline void setMouseCaptured(bool captured);
+    
+    /**
+     * Sets the visibility of the platform cursor.
+     *
+     * @param visible true to show the platform cursor, false to hide it.
+     */
+    inline void setCursorVisible(bool visible);
+    
+    /**
+     * Determines whether the platform cursor is currently visible.
+     *
+     * @return true if the platform cursor is visible, false otherwise.
+     */
+    inline bool isCursorVisible();
+
+    /**
+     * Determines whether a specified gesture event is supported.
+     *
+     * Use Gesture::GESTURE_ANY_SUPPORTED to test if one or more gesture events are supported.
+     *
+     * @param evt The gesture event to test and see if it is supported.
+     * @return true if the gesture tested is supported; false if not supported.
+     */
+    bool isGestureSupported(Gesture::GestureEvent evt);
+
+    /**
+     * Requests the game to register and start recognizing the specified gesture event.
+     *
+     * Call with Gesture::GESTURE_ANY_SUPPORTED to recognize all supported gestures.
+     * Once a gesture is recognized the specific gesture event methods will
+     * begin to be called.
+     *
+     * Registering for:
+     *
+     * Gesture::GESTURE_SWIPE calls gestureSwipeEvent(..)
+     * Gesture::GESTURE_PINCH calls gesturePinchEvent(..)
+     * Gesture::GESTURE_TAP calls gestureTapEvent(..)
+     *
+     * @param evt The gesture event to start recognizing for
+     */
+    void registerGesture(Gesture::GestureEvent evt);
+
+    /**
+     * Requests the game to unregister for and stop recognizing the specified gesture event.
+     *
+     * Call with Gesture::GESTURE_ANY_SUPPORTED to unregister events from all supported gestures.
+     *
+     * @param evt The gesture event to start recognizing for
+     */
+    void unregisterGesture(Gesture::GestureEvent evt);
+
+    /**
+     * Determines whether a specified gesture event is registered to receive event callbacks.
+     *
+     * @return true if the specified gesture event is registered; false of not registered.
+     */
+    bool isGestureRegistered(Gesture::GestureEvent evt);
+
+    /**
+     * Gesture callback on Gesture::SWIPE events.
+     *
+     * @param x The x-coordinate of the start of the swipe.
+     * @param y The y-coordinate of the start of the swipe.
+     * @param direction The direction of the swipe
+     *
+     * @see Gesture::SWIPE_DIRECTION_UP
+     * @see Gesture::SWIPE_DIRECTION_DOWN
+     * @see Gesture::SWIPE_DIRECTION_LEFT
+     * @see Gesture::SWIPE_DIRECTION_RIGHT
+     */
+    virtual void gestureSwipeEvent(int x, int y, int direction);
+
+    /**
+     * Gesture callback on Gesture::PINCH events.
+     *
+     * @param x The centroid x-coordinate of the pinch.
+     * @param y The centroid y-coordinate of the pinch.
+     * @param scale The scale of the pinch.
+     */
+    virtual void gesturePinchEvent(int x, int y, float scale);
+
+    /**
+     * Gesture callback on Gesture::LONG_TAP events.
+     *
+     * @param x The x-coordinate of the long tap.
+     * @param y The y-coordinate of the long tap.
+     * @param duration The duration of the long tap in ms.
+     */
+    virtual void gestureLongTapEvent(int x, int y, float duration);
+
+    /**
+     * Gesture callback on Gesture::TAP events.
+     *
+     * @param x The x-coordinate of the tap.
+     * @param y The y-coordinate of the tap.
+     */
+    virtual void gestureTapEvent(int x, int y);
+
+    /**
+     * Gesture callback on Gesture::DRAG events.
+     *
+     * @param x The x-coordinate of the start of the drag event.
+     * @param y The y-coordinate of the start of the drag event.
+     */
+    virtual void gestureDragEvent(int x, int y);
+
+    /**
+     * Gesture callback on Gesture::DROP events.
+     *
+     * @param x The x-coordinate of the drop event.
+     * @param y The y-coordinate of the drop event.
+     */
+    virtual void gestureDropEvent(int x, int y);
+
+    /**
+     * Gamepad callback on gamepad events.  Override to receive Gamepad::CONNECTED_EVENT 
+     * and Gamepad::DISCONNECTED_EVENT, and store the Gamepad* in order to poll it from update().
+     *
+     * @param evt The gamepad event that occurred.
+     * @param gamepad The gamepad that generated the event.
+     */
+    virtual void gamepadEvent(Gamepad::GamepadEvent evt, Gamepad* gamepad);
+
+    /**
+     * Gets the current number of gamepads currently connected to the system.
+     *
+     * @return The number of gamepads currently connected to the system.
+     */
+    inline unsigned int getGamepadCount() const;
+
+    /**
+     * Gets the gamepad at the specified index. 
+     *
+     * The gamepad index can change when connected and disconnected so you
+     * cannot rely on this other than iterating through them all to display
+     * them or poll them.
+     * 
+     * The preferPhysical will bump over virtual gamepads if physical gamepads are
+     * connected and return the request index of the first or second physcial and then 
+     * return back to the first virtual after.
+     *
+     * @param index The index of the gamepad to retrieve.
+     * @param preferPhysical true if you prefer return a physical if exist; false if only virtual.
+     * @return The gamepad at the specified index.
+     */
+    inline Gamepad* getGamepad(unsigned int index, bool preferPhysical = true) const;
+
+    /**
+     * Sets whether multi-sampling is to be enabled/disabled. Default is disabled.
+     *
+     * @param enabled true sets multi-sampling to be enabled, false to be disabled.
+     */
+    inline void setMultiSampling(bool enabled);
+
+    /*
+     * Is multi-sampling enabled.
+     *
+     * @return true if multi-sampling is enabled.
+     */
+    inline bool isMultiSampling() const;
+
+    /**
+     * Sets multi-touch is to be enabled/disabled. Default is disabled.
+     *
+     * @param enabled true sets multi-touch is enabled, false to be disabled.
+     */
+    inline void setMultiTouch(bool enabled);
+
+    /**
+     * Is multi-touch mode enabled.
+     *
+     * @return true if multi-touch is enabled.
+     */
+    inline bool isMultiTouch() const;
+
+    /**
+     * Whether this game is allowed to exit programmatically.
+     *
+     * @return true if a programmatic exit is allowed.
+     */
+    inline bool canExit() const;
+
+    /**
+     * Whether this game has accelerometer support.
+     */
+    inline bool hasAccelerometer() const;
+
+    /**
+     * Gets the current accelerometer values for use as an indication of device
+     * orientation. Despite its name, implementations are at liberty to combine
+     * accelerometer data with data from other sensors as well, such as the gyros.
+     * This method is best used to obtain an indication of device orientation; it
+     * does not necessarily distinguish between acceleration and rotation rate.
+     *
+     * @param pitch The pitch angle returned (in degrees). Zero if hasAccelerometer() returns false.
+     * @param roll The roll angle returned (in degrees). Zero if hasAccelerometer() returns false.
+     */
+    inline void getAccelerometerValues(float* pitch, float* roll);
+
+    /**
+     * Gets sensor values (raw), if equipped, allowing a distinction between device acceleration
+     * and rotation rate. Returns zeros on platforms with no corresponding support. See also
+     * hasAccelerometer() and getAccelerometerValues().
+     *
+     * @param accelX The x-coordinate of the raw accelerometer data.
+     * @param accelY The y-coordinate of the raw accelerometer data.
+     * @param accelZ The z-coordinate of the raw accelerometer data.
+     * @param gyroX The x-coordinate of the raw gyroscope data.
+     * @param gyroY The y-coordinate of the raw gyroscope data.
+     * @param gyroZ The z-coordinate of the raw gyroscope data.
+     */
+    inline void getSensorValues(float* accelX, float* accelY, float* accelZ, float* gyroX, float* gyroY, float* gyroZ);
+
+    /**
+     * Gets the command line arguments.
+     * 
+     * @param argc The number of command line arguments.
+     * @param argv The array of command line arguments.
+     * @script{ignore}
+     */
+    void getArguments(int* argc, char*** argv) const;
+
+    /**
+     * Schedules a time event to be sent to the given TimeListener a given number of game milliseconds from now.
+     * Game time stops while the game is paused. A time offset of zero will fire the time event in the next frame.
+     * 
+     * @param timeOffset The number of game milliseconds in the future to schedule the event to be fired.
+     * @param timeListener The TimeListener that will receive the event.
+     * @param cookie The cookie data that the time event will contain.
+     * @script{ignore}
+     */
+    void schedule(float timeOffset, TimeListener* timeListener, void* cookie = 0);
+
+    /**
+     * Schedules a time event to be sent to the given TimeListener a given number of game milliseconds from now.
+     * Game time stops while the game is paused. A time offset of zero will fire the time event in the next frame.
+     * 
+     * Note: the given Lua function must take a single floating point number, which is the difference between the
+     * current game time and the target time (see TimeListener::timeEvent).
+     * 
+     * @param timeOffset The number of game milliseconds in the future to schedule the event to be fired.
+     * @param function The Lua script function that will receive the event.
+     */
+    void schedule(float timeOffset, const char* function);
+
+    /**
+     * Opens an URL in an external browser, if available.
+     *
+     * @param url URL to be opened.
+     *
+     * @return True if URL was opened successfully, false otherwise.
+     */
+    bool launchURL(const char *url) const;
+
+protected:
+
+    /**
+     * Constructor.
+     */
+    Game();
+
+    /**
+     * Initialize callback that is called just before the first frame when the game starts.
+     */
+    virtual void initialize() = 0;
+
+    /**
+     * Finalize callback that is called when the game on exits.
+     */
+    virtual void finalize() = 0;
+
+    /**
+     * Update callback for handling update routines.
+     *
+     * Called just before render, once per frame when game is running.
+     * Ideal for non-render code and game logic such as input and animation.
+     *
+     * @param elapsedTime The elapsed game time.
+     */
+    virtual void update(float elapsedTime) = 0;
+
+    /**
+     * Render callback for handling rendering routines.
+     *
+     * Called just after update, once per frame when game is running.
+     * Ideal for all rendering code.
+     *
+     * @param elapsedTime The elapsed game time.
+     */
+    virtual void render(float elapsedTime) = 0;
+
+    /**
+     * Renders a single frame once and then swaps it to the display.
+     *
+     * This is useful for rendering splash screens.
+     */
+    template <class T>
+    void renderOnce(T* instance, void (T::*method)(void*), void* cookie);
+
+    /**
+     * Renders a single frame once and then swaps it to the display.
+     * This calls the given Lua function, which should take no parameters and return nothing (void).
+     *
+     * This is useful for rendering splash screens.
+     */
+    void renderOnce(const char* function);
+
+    /**
+     * Updates the game's internal systems (audio, animation, physics) once.
+     * 
+     * Note: This does not call the user-defined Game::update() function.
+     *
+     * This is useful for rendering animated splash screens.
+     */
+    void updateOnce();
+
+private:
+
+    /**
+     * Allows time listener interaction from Lua scripts.
+     */
+    struct ScriptListener : public TimeListener
+    {
+        /**
+         * Constructor.
+         */
+        ScriptListener(const char* url);
+
+        /**
+         * @see TimeListener#timeEvent(long, void*)
+         */
+        void timeEvent(long timeDiff, void* cookie);
+
+        /** Holds the name of the Lua script function to call back. */
+        std::string function;
+    };
+
+    struct ShutdownListener : public TimeListener
+    {
+        void timeEvent(long timeDiff, void* cookie);
+    };
+
+    /**
+     * TimeEvent represents the event that is sent to TimeListeners as a result of calling Game::schedule().
+     */
+    class TimeEvent
+    {
+    public:
+
+        TimeEvent(double time, TimeListener* timeListener, void* cookie);
+        bool operator<(const TimeEvent& v) const;
+        double time;
+        TimeListener* listener;
+        void* cookie;
+    };
+
+    /**
+     * Constructor.
+     *
+     * @param copy The game to copy.
+     */
+    Game(const Game& copy);
+
+    /**
+     * Starts the game.
+     */
+    bool startup();
+
+    /**
+     * Shuts down the game.
+     */
+    void shutdown();
+
+    /**
+     * Fires the time events that were scheduled to be called.
+     * 
+     * @param frameTime The current game frame time. Used to determine which time events need to be fired.
+     */
+    void fireTimeEvents(double frameTime);
+
+    /**
+     * Loads the game configuration.
+     */
+    void loadConfig();
+
+    /**
+     * Loads the gamepads from the configuration file.
+     */
+    void loadGamepads();
+
+    bool _initialized;                          // If game has initialized yet.
+    State _state;                               // The game state.
+    unsigned int _pausedCount;                  // Number of times pause() has been called.
+    static double _pausedTimeLast;              // The last time paused.
+    static double _pausedTimeTotal;             // The total time paused.
+    double _frameLastFPS;                       // The last time the frame count was updated.
+    unsigned int _frameCount;                   // The current frame count.
+    unsigned int _frameRate;                    // The current frame rate.
+    unsigned int _width;                        // The game's display width.
+    unsigned int _height;                       // The game's display height.
+    Rectangle _viewport;                        // the games's current viewport.
+    Vector4 _clearColor;                        // The clear color value last used for clearing the color buffer.
+    float _clearDepth;                          // The clear depth value last used for clearing the depth buffer.
+    int _clearStencil;                          // The clear stencil value last used for clearing the stencil buffer.
+    Properties* _properties;                    // Game configuration properties object.
+    AnimationController* _animationController;  // Controls the scheduling and running of animations.
+    AudioController* _audioController;          // Controls audio sources that are playing in the game.
+    PhysicsController* _physicsController;      // Controls the simulation of a physics scene and entities.
+    AIController* _aiController;                // Controls AI simulation.
+    AudioListener* _audioListener;              // The audio listener in 3D space.
+    std::priority_queue<TimeEvent, std::vector<TimeEvent>, std::less<TimeEvent> >* _timeEvents;     // Contains the scheduled time events.
+    ScriptController* _scriptController;            // Controls the scripting engine.
+    std::vector<ScriptListener*>* _scriptListeners; // Lua script listeners.
+
+    // Note: Do not add STL object member variables on the stack; this will cause false memory leaks to be reported.
+
+    friend class ScreenDisplayer;
+};
+
+}
+
+#include "Game.inl"
+
+#endif

+ 58 - 58
gameplay/src/Gesture.h

@@ -1,58 +1,58 @@
-#ifndef GESTURE_H_
-#define GESTURE_H_
-
-namespace gameplay
-{
-
-/**
- * Gesture event
- */
-class Gesture
-{
-public:
-
-    /**
-     * The gesture event type.
-     */
-    enum GestureEvent
-    {
-        GESTURE_TAP = 0,
-        GESTURE_SWIPE,
-        GESTURE_PINCH,
-        GESTURE_LONG_TAP,
-        GESTURE_DRAG,
-        GESTURE_DROP,
-        GESTURE_ANY_SUPPORTED = -1,
-    };
-
-    /**
-     * The up direction for a swipe event.
-     */
-    static const int SWIPE_DIRECTION_UP = 1 << 0;
-
-    /**
-     * The down direction for a swipe event.
-     */
-    static const int SWIPE_DIRECTION_DOWN = 1 << 1;
-
-    /**
-     * The left direction for a swipe event.
-     */
-    static const int SWIPE_DIRECTION_LEFT = 1 << 2;
-
-    /**
-     * The right direction for a swipe event.
-     */
-    static const int SWIPE_DIRECTION_RIGHT = 1 << 3;
-
-private:
-
-    /**
-     * Constructor. Used internally.
-     */
-    Gesture();
-};
-
-}
-
-#endif
+#ifndef GESTURE_H_
+#define GESTURE_H_
+
+namespace gameplay
+{
+
+/**
+ * Gesture event
+ */
+class Gesture
+{
+public:
+
+    /**
+     * The gesture event type.
+     */
+    enum GestureEvent
+    {
+        GESTURE_TAP = 0,
+        GESTURE_SWIPE,
+        GESTURE_PINCH,
+        GESTURE_LONG_TAP,
+        GESTURE_DRAG,
+        GESTURE_DROP,
+        GESTURE_ANY_SUPPORTED = -1,
+    };
+
+    /**
+     * The up direction for a swipe event.
+     */
+    static const int SWIPE_DIRECTION_UP = 1 << 0;
+
+    /**
+     * The down direction for a swipe event.
+     */
+    static const int SWIPE_DIRECTION_DOWN = 1 << 1;
+
+    /**
+     * The left direction for a swipe event.
+     */
+    static const int SWIPE_DIRECTION_LEFT = 1 << 2;
+
+    /**
+     * The right direction for a swipe event.
+     */
+    static const int SWIPE_DIRECTION_RIGHT = 1 << 3;
+
+private:
+
+    /**
+     * Constructor. Used internally.
+     */
+    Gesture();
+};
+
+}
+
+#endif

+ 122 - 122
gameplay/src/Platform.cpp

@@ -1,122 +1,122 @@
-// Implementation of base platform-agnostic platform functionality.
-#include "Base.h"
-#include "Platform.h"
-#include "Game.h"
-#include "ScriptController.h"
-#include "Form.h"
-
-namespace gameplay
-{
-
-void Platform::touchEventInternal(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex, bool actuallyMouse)
-{
-    if (actuallyMouse || !Form::touchEventInternal(evt, x, y, contactIndex))
-    {
-        Game::getInstance()->touchEvent(evt, x, y, contactIndex);
-        Game::getInstance()->getScriptController()->touchEvent(evt, x, y, contactIndex);
-    }
-}
-
-void Platform::keyEventInternal(Keyboard::KeyEvent evt, int key)
-{
-    if (!Form::keyEventInternal(evt, key))
-    {
-        Game::getInstance()->keyEvent(evt, key);
-        Game::getInstance()->getScriptController()->keyEvent(evt, key);
-    }
-}
-
-bool Platform::mouseEventInternal(Mouse::MouseEvent evt, int x, int y, int wheelDelta)
-{
-    if (Form::mouseEventInternal(evt, x, y, wheelDelta))
-    {
-        return true;
-    }
-    else if (Game::getInstance()->mouseEvent(evt, x, y, wheelDelta))
-    {
-        return true;
-    }
-    else
-    {
-        return Game::getInstance()->getScriptController()->mouseEvent(evt, x, y, wheelDelta);
-    }
-}
-
-void Platform::gestureSwipeEventInternal(int x, int y, int direction)
-{
-    // TODO: Add support to Form for gestures
-    Game::getInstance()->gestureSwipeEvent(x, y, direction);
-    Game::getInstance()->getScriptController()->gestureSwipeEvent(x, y, direction);
-}
-
-void Platform::gesturePinchEventInternal(int x, int y, float scale)
-{
-    // TODO: Add support to Form for gestures
-    Game::getInstance()->gesturePinchEvent(x, y, scale);
-    Game::getInstance()->getScriptController()->gesturePinchEvent(x, y, scale);
-}
-
-void Platform::gestureTapEventInternal(int x, int y)
-{
-    // TODO: Add support to Form for gestures
-    Game::getInstance()->gestureTapEvent(x, y);
-    Game::getInstance()->getScriptController()->gestureTapEvent(x, y);
-}
-
-void Platform::gestureLongTapEventInternal(int x, int y, float duration)
-{
-    // TODO: Add support to Form for gestures
-	Game::getInstance()->gestureLongTapEvent(x, y, duration);
-	Game::getInstance()->getScriptController()->gestureLongTapEvent(x, y, duration);
-}
-
-void Platform::gestureDragEventInternal(int x, int y)
-{
-    // TODO: Add support to Form for gestures
-	Game::getInstance()->gestureDragEvent(x, y);
-	Game::getInstance()->getScriptController()->gestureDragEvent(x, y);
-}
-
-void Platform::gestureDropEventInternal(int x, int y)
-{
-    // TODO: Add support to Form for gestures
-	Game::getInstance()->gestureDropEvent(x, y);
-	Game::getInstance()->getScriptController()->gestureDropEvent(x, y);
-}
-
-void Platform::resizeEventInternal(unsigned int width, unsigned int height)
-{
-    // Update the width and height of the game
-    Game* game = Game::getInstance();
-    if (game->_width != width || game->_height != height)
-    {
-        game->_width = width;
-        game->_height = height;
-        game->resizeEvent(width, height);
-        game->getScriptController()->resizeEvent(width, height);
-    }
-
-    Form::resizeEventInternal(width, height);
-}
-
-void Platform::gamepadEventInternal(Gamepad::GamepadEvent evt, Gamepad* gamepad, unsigned int analogIndex)
-{
-    if (!Form::gamepadEventInternal(evt, gamepad, analogIndex))
-    {
-        Game::getInstance()->gamepadEvent(evt, gamepad);
-        Game::getInstance()->getScriptController()->gamepadEvent(evt, gamepad);
-    }
-}
-
-void Platform::gamepadEventConnectedInternal(GamepadHandle handle,  unsigned int buttonCount, unsigned int joystickCount, unsigned int triggerCount,
-                                             unsigned int vendorId, unsigned int productId, const char* vendorString, const char* productString)
-{
-    Gamepad::add(handle, buttonCount, joystickCount, triggerCount, vendorId, productId, vendorString, productString);
-}
-
-void Platform::gamepadEventDisconnectedInternal(GamepadHandle handle)
-{
-    Gamepad::remove(handle);
-}
-
-}
+// Implementation of base platform-agnostic platform functionality.
+#include "Base.h"
+#include "Platform.h"
+#include "Game.h"
+#include "ScriptController.h"
+#include "Form.h"
+
+namespace gameplay
+{
+
+void Platform::touchEventInternal(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex, bool actuallyMouse)
+{
+    if (actuallyMouse || !Form::touchEventInternal(evt, x, y, contactIndex))
+    {
+        Game::getInstance()->touchEvent(evt, x, y, contactIndex);
+        Game::getInstance()->getScriptController()->touchEvent(evt, x, y, contactIndex);
+    }
+}
+
+void Platform::keyEventInternal(Keyboard::KeyEvent evt, int key)
+{
+    if (!Form::keyEventInternal(evt, key))
+    {
+        Game::getInstance()->keyEvent(evt, key);
+        Game::getInstance()->getScriptController()->keyEvent(evt, key);
+    }
+}
+
+bool Platform::mouseEventInternal(Mouse::MouseEvent evt, int x, int y, int wheelDelta)
+{
+    if (Form::mouseEventInternal(evt, x, y, wheelDelta))
+    {
+        return true;
+    }
+    else if (Game::getInstance()->mouseEvent(evt, x, y, wheelDelta))
+    {
+        return true;
+    }
+    else
+    {
+        return Game::getInstance()->getScriptController()->mouseEvent(evt, x, y, wheelDelta);
+    }
+}
+
+void Platform::gestureSwipeEventInternal(int x, int y, int direction)
+{
+    // TODO: Add support to Form for gestures
+    Game::getInstance()->gestureSwipeEvent(x, y, direction);
+    Game::getInstance()->getScriptController()->gestureSwipeEvent(x, y, direction);
+}
+
+void Platform::gesturePinchEventInternal(int x, int y, float scale)
+{
+    // TODO: Add support to Form for gestures
+    Game::getInstance()->gesturePinchEvent(x, y, scale);
+    Game::getInstance()->getScriptController()->gesturePinchEvent(x, y, scale);
+}
+
+void Platform::gestureTapEventInternal(int x, int y)
+{
+    // TODO: Add support to Form for gestures
+    Game::getInstance()->gestureTapEvent(x, y);
+    Game::getInstance()->getScriptController()->gestureTapEvent(x, y);
+}
+
+void Platform::gestureLongTapEventInternal(int x, int y, float duration)
+{
+    // TODO: Add support to Form for gestures
+	Game::getInstance()->gestureLongTapEvent(x, y, duration);
+	Game::getInstance()->getScriptController()->gestureLongTapEvent(x, y, duration);
+}
+
+void Platform::gestureDragEventInternal(int x, int y)
+{
+    // TODO: Add support to Form for gestures
+	Game::getInstance()->gestureDragEvent(x, y);
+	Game::getInstance()->getScriptController()->gestureDragEvent(x, y);
+}
+
+void Platform::gestureDropEventInternal(int x, int y)
+{
+    // TODO: Add support to Form for gestures
+	Game::getInstance()->gestureDropEvent(x, y);
+	Game::getInstance()->getScriptController()->gestureDropEvent(x, y);
+}
+
+void Platform::resizeEventInternal(unsigned int width, unsigned int height)
+{
+    // Update the width and height of the game
+    Game* game = Game::getInstance();
+    if (game->_width != width || game->_height != height)
+    {
+        game->_width = width;
+        game->_height = height;
+        game->resizeEvent(width, height);
+        game->getScriptController()->resizeEvent(width, height);
+    }
+
+    Form::resizeEventInternal(width, height);
+}
+
+void Platform::gamepadEventInternal(Gamepad::GamepadEvent evt, Gamepad* gamepad, unsigned int analogIndex)
+{
+    if (!Form::gamepadEventInternal(evt, gamepad, analogIndex))
+    {
+        Game::getInstance()->gamepadEvent(evt, gamepad);
+        Game::getInstance()->getScriptController()->gamepadEvent(evt, gamepad);
+    }
+}
+
+void Platform::gamepadEventConnectedInternal(GamepadHandle handle,  unsigned int buttonCount, unsigned int joystickCount, unsigned int triggerCount,
+                                             unsigned int vendorId, unsigned int productId, const char* vendorString, const char* productString)
+{
+    Gamepad::add(handle, buttonCount, joystickCount, triggerCount, vendorId, productId, vendorString, productString);
+}
+
+void Platform::gamepadEventDisconnectedInternal(GamepadHandle handle)
+{
+    Gamepad::remove(handle);
+}
+
+}

+ 430 - 415
gameplay/src/Platform.h

@@ -1,415 +1,430 @@
-#ifndef PLATFORM_H_
-#define PLATFORM_H_
-
-#include "Vector2.h"
-#include "Keyboard.h"
-#include "Mouse.h"
-#include "Touch.h"
-#include "Gesture.h"
-#include "Gamepad.h"
-
-namespace gameplay
-{
-
-class Game;
-
-/**
- * Defines a platform abstraction.
- *
- * This class has only a few public methods for creating a platform
- *
- */
-class Platform
-{
-public:
-
-    friend class Game;
-    friend class Gamepad;
-    friend class ScreenDisplayer;
-
-    /**
-     * Destructor.
-     */
-    ~Platform();
-
-    /**
-     * Creates a platform for the specified game which it will interact with.
-     *
-     * @param game The game to create a platform for.
-     *
-     * @return The created platform interface.
-     * @script{ignore}
-     */
-    static Platform* create(Game* game);
-
-    /**
-     * Begins processing the platform messages.
-     *
-     * This method handles all OS window messages and drives the game loop.
-     * It normally does not return until the application is closed.
-     *
-     * If a attachToWindow is passed to Platform::create the message pump will instead attach
-     * to or allow the attachToWindow to drive the game loop on the platform.
-     *
-     * @return The platform message pump return code.
-     */
-    int enterMessagePump();
-
-    /**
-     * Swaps the frame buffer on the device.
-     */
-    static void swapBuffers();
-
-private:
-
-    /**
-     * This method informs the platform that the game is shutting down
-     * and anything platform specific should be shutdown as well or halted
-     * This function is called automatically when the game shutdown function is called
-     */
-    static void signalShutdown();
-
-    /**
-     * Indicates whether a programmatic exit is allowed on this platform.
-     * Some platforms (eg. iOS) do not allow apps to exit programmatically.
-     *
-     * @return whether a programmatic exit is allowed on this platform.
-     */
-    static bool canExit();
-
-    /**
-     * Gets the display width.
-     *
-     * @return The display width.
-     */
-    static unsigned int getDisplayWidth();
-
-    /**
-     * Gets the display height.
-     *
-     * @return The display height.
-     */
-    static unsigned int getDisplayHeight();
-
-    /**
-     * Gets the absolute platform time starting from when the message pump was started.
-     *
-     * @return The absolute platform time. (in milliseconds)
-     */
-    static double getAbsoluteTime();
-
-    /**
-     * Sets the absolute platform time since the start of the message pump.
-     *
-     * @param time The time to set (in milliseconds).
-     */
-    static void setAbsoluteTime(double time);
-
-    /**
-     * Gets whether vertical sync is enabled for the game display.
-     *
-     * @return true if vsync is enabled; false if not.
-     */
-    static bool isVsync();
-
-    /**
-     * Sets whether vertical sync is enable for the game display.
-     *
-     * @param enable true if vsync is enabled; false if not.
-     */
-    static void setVsync(bool enable);
-
-    /**
-     * Sleeps synchronously for the given amount of time (in milliseconds).
-     *
-     * @param ms How long to sleep (in milliseconds).
-     */
-    static void sleep(long ms);
-
-    /**
-     * Set if multi-sampling is enabled on the platform.
-     *
-     * @param enabled true sets multi-sampling to be enabled, false to be disabled.
-     */
-    static void setMultiSampling(bool enabled);
-
-   /**
-    * Is multi-sampling mode enabled.
-    */
-    static bool isMultiSampling();
-
-    /**
-     * Set if multi-touch is enabled on the platform.
-     *
-     * Note that this method does nothing on platforms that do not
-     * support multi-touch.
-     */
-    static void setMultiTouch(bool enabled);
-
-   /**
-    * Is multi-touch mode enabled.
-    */
-    static bool isMultiTouch();
-
-    /**
-     * Whether the platform has mouse support.
-     */
-    static bool hasMouse();
-
-    /**
-     * Enables or disabled mouse capture.
-     *
-     * When mouse capture is enabled, the platform cursor is hidden
-     * and mouse event points are delivered as position deltas instead
-     * of absolute positions.
-     *
-     * This is useful for games that wish to provide uninhibited mouse
-     * movement, such as when implementing free/mouse look in an FPS
-     * game.
-     *
-     * Disabling mouse capture moves the mouse back to the center of the
-     * screen and shows the platform cursor.
-     *
-     * Note that this method does nothing on platforms that do not
-     * support a mouse.
-     *
-     * @param captured True to enable mouse capture, false to disable it.
-     */
-    static void setMouseCaptured(bool captured);
-
-    /**
-     * Determines if mouse capture is currently enabled.
-     */
-    static bool isMouseCaptured();
-
-    /**
-     * Sets the visibility of the platform cursor.
-     *
-     * On platforms that support a visible cursor, this method
-     * toggles the visibility of the cursor.
-     *
-     * @param visible true to show the platform cursor, false to hide it.
-     */
-    static void setCursorVisible(bool visible);
-
-    /**
-     * Determines whether the platform cursor is currently visible.
-     *
-     * @return true if the platform cursor is visible, false otherwise.
-     */
-    static bool isCursorVisible();
-
-    /**
-     * Whether the platform has accelerometer support.
-     */
-    static bool hasAccelerometer();
-
-    /**
-     * Gets the platform accelerometer values for use as an indication of device
-     * orientation. Despite its name, implementations are at liberty to combine
-     * accelerometer data with data from other sensors as well, such as the gyros.
-     * This method is best used to obtain an indication of device orientation; it
-     * does not necessarily distinguish between acceleration and rotation rate.
-     *
-     * @param pitch The accelerometer pitch. Zero if hasAccelerometer() returns false.
-     * @param roll The accelerometer roll. Zero if hasAccelerometer() returns false.
-     */
-    static void getAccelerometerValues(float* pitch, float* roll);
-
-    /**
-     * Gets sensor values (raw), if equipped, allowing a distinction between device acceleration
-     * and rotation rate. Returns zeros on platforms with no corresponding support. See also
-     * hasAccelerometer() and getAccelerometerValues().
-     *
-     * @param accelX The x-coordinate of the raw accelerometer data.
-     * @param accelY The y-coordinate of the raw accelerometer data.
-     * @param accelZ The z-coordinate of the raw accelerometer data.
-     * @param gyroX The x-coordinate of the raw gyroscope data.
-     * @param gyroY The y-coordinate of the raw gyroscope data.
-     * @param gyroZ The z-coordinate of the raw gyroscope data.
-     */
-    static void getSensorValues(float* accelX, float* accelY, float* accelZ, float* gyroX, float* gyroY, float* gyroZ);
-
-    /**
-     * Gets the command line arguments.
-     *
-     * @param argc The number of command line arguments.
-     * @param argv The array of command line arguments.
-     */
-    static void getArguments(int* argc, char*** argv);
-
-    /**
-     * Shows or hides the virtual keyboard (if supported).
-     *
-     * @param display true when virtual keyboard needs to be displayed and false otherwise.
-     */
-    static void displayKeyboard(bool display);
-
-    /**
-     * Tests if the specified gesture is supported on the platform.
-     *
-     * @return true if it is supported; false if not supported.
-     */
-    static bool isGestureSupported(Gesture::GestureEvent evt);
-
-    /**
-     * Registers the platform for gesture recognition for the specified gesture event.
-     *
-     * @param evt The gesture event to register to start recognizing events for.
-     */
-    static void registerGesture(Gesture::GestureEvent evt);
-
-    /**
-     * Registers the platform for gesture recognition for the specified gesture event.
-     *
-     * @param evt The gesture event to register to start recognizing events for.
-     */
-    static void unregisterGesture(Gesture::GestureEvent evt);
-
-    /**
-     * Tests if the specified gesture is registered for gesture recognition for the specified gesture event
-     *
-     * @param evt The gesture event to register to start recognizing events for.
-     */
-    static bool isGestureRegistered(Gesture::GestureEvent evt);
-
-    /**
-     * Opens an URL in an external browser, if available.
-     *
-     * @param url URL to be opened.
-     *
-     * @return True if URL was opened successfully, false otherwise.
-     */
-    static bool launchURL(const char* url);
-
-    /**
-     * Constructor.
-     */
-    Platform(Game* game);
-
-    /**
-     * Constructor.
-     */
-    Platform(const Platform& copy);
-
-public:
-
-    /**
-     * Internal method used only from static code in various platform implementation.
-     *
-     * @script{ignore}
-     */
-    static void touchEventInternal(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex, bool actuallyMouse = false);
-
-    /**
-     * Internal method used only from static code in various platform implementation.
-     *
-     * @script{ignore}
-     */
-    static void keyEventInternal(Keyboard::KeyEvent evt, int key);
-
-   /**
-     * Internal method used only from static code in various platform implementation.
-     *
-     * @script{ignore}
-     */
-    static bool mouseEventInternal(Mouse::MouseEvent evt, int x, int y, int wheelDelta);
-
-    /**
-     * Internal method used only from static code in various platform implementation.
-     *
-     * @script{ignore}
-     */
-    static void gestureSwipeEventInternal(int x, int y, int direction);
-
-    /**
-     * Internal method used only from static code in various platform implementation.
-     *
-     * @script{ignore}
-     */
-    static void gesturePinchEventInternal(int x, int y, float scale);
-
-    /**
-     * Internal method used only from static code in various platform implementation.
-     *
-     * @script{ignore}
-     */
-    static void gestureTapEventInternal(int x, int y);
-
-    /**
-     * Internal method used only from static code in various platform implementation.
-     *
-     * @script{ignore}
-     */
-	static void gestureLongTapEventInternal(int x, int y, float duration);
-
-    /**
-     * Internal method used only from static code in various platform implementation.
-     *
-     * @script{ignore}
-     */
-	static void gestureDragEventInternal(int x, int y);
-
-    /**
-     * Internal method used only from static code in various platform implementation.
-     *
-     * @script{ignore}
-     */
-	static void gestureDropEventInternal(int x, int y);
-
-    /**
-     * Internal method used only from static code in various platform implementation.
-     *
-     * @script{ignore}
-     */
-    static void resizeEventInternal(unsigned int width, unsigned int height);
-
-    /**
-     * Internal method used only from static code in various platform implementation.
-     *
-     * @script{ignore}
-     */
-    static void gamepadEventInternal(Gamepad::GamepadEvent evt, Gamepad* gamepad, unsigned int analogIndex = 0);
-
-    /**
-     * Internal method used only from static code in various platform implementation.
-     *
-     * @script{ignore}
-     */
-    static void gamepadEventConnectedInternal(GamepadHandle handle, unsigned int buttonCount, unsigned int joystickCount, unsigned int triggerCount,
-                                              unsigned int vendorId, unsigned int productId,
-                                              const char* vendorString, const char* productString);
-
-    /**
-     * Internal method used only from static code in various platform implementation.
-     *
-     * @script{ignore}
-     */
-    static void gamepadEventDisconnectedInternal(GamepadHandle handle);
-
-    /**
-     * Internal method used by Gamepad that polls the platform for the updated Gamepad
-     * states such as joysticks, buttons and trigger values.
-     *
-     * @param gamepad The gamepad to be returned with the latest polled values populated.
-     * @script{ignore}
-     */
-    static void pollGamepadState(Gamepad* gamepad);
-
-   /**
-     * Internal method used only from static code in various platform implementation.
-     *
-     * @script{ignore}
-     */
-    static void shutdownInternal();
-
-private:
-
-    Game* _game;                // The game this platform is interfacing with.
-};
-
-}
-
-#include "Game.h"
-
-#endif
+#ifndef PLATFORM_H_
+#define PLATFORM_H_
+
+#include "Vector2.h"
+#include "Keyboard.h"
+#include "Mouse.h"
+#include "Touch.h"
+#include "Gesture.h"
+#include "Gamepad.h"
+#include "FileSystem.h"
+
+namespace gameplay
+{
+
+class Game;
+
+/**
+ * Defines a platform abstraction.
+ *
+ * This class has only a few public methods for creating a platform
+ *
+ */
+class Platform
+{
+public:
+
+    friend class Game;
+    friend class Gamepad;
+    friend class ScreenDisplayer;
+    friend class FileSystem;
+
+    /**
+     * Destructor.
+     */
+    ~Platform();
+
+    /**
+     * Creates a platform for the specified game which it will interact with.
+     *
+     * @param game The game to create a platform for.
+     *
+     * @return The created platform interface.
+     * @script{ignore}
+     */
+    static Platform* create(Game* game);
+
+    /**
+     * Begins processing the platform messages.
+     *
+     * This method handles all OS window messages and drives the game loop.
+     * It normally does not return until the application is closed.
+     *
+     * If a attachToWindow is passed to Platform::create the message pump will instead attach
+     * to or allow the attachToWindow to drive the game loop on the platform.
+     *
+     * @return The platform message pump return code.
+     */
+    int enterMessagePump();
+
+    /**
+     * Swaps the frame buffer on the device.
+     */
+    static void swapBuffers();
+
+private:
+
+    /**
+     * This method informs the platform that the game is shutting down
+     * and anything platform specific should be shutdown as well or halted
+     * This function is called automatically when the game shutdown function is called
+     */
+    static void signalShutdown();
+
+    /**
+     * Indicates whether a programmatic exit is allowed on this platform.
+     * Some platforms (eg. iOS) do not allow apps to exit programmatically.
+     *
+     * @return whether a programmatic exit is allowed on this platform.
+     */
+    static bool canExit();
+
+    /**
+     * Gets the display width.
+     *
+     * @return The display width.
+     */
+    static unsigned int getDisplayWidth();
+
+    /**
+     * Gets the display height.
+     *
+     * @return The display height.
+     */
+    static unsigned int getDisplayHeight();
+
+    /**
+     * Gets the absolute platform time starting from when the message pump was started.
+     *
+     * @return The absolute platform time. (in milliseconds)
+     */
+    static double getAbsoluteTime();
+
+    /**
+     * Sets the absolute platform time since the start of the message pump.
+     *
+     * @param time The time to set (in milliseconds).
+     */
+    static void setAbsoluteTime(double time);
+
+    /**
+     * Gets whether vertical sync is enabled for the game display.
+     *
+     * @return true if vsync is enabled; false if not.
+     */
+    static bool isVsync();
+
+    /**
+     * Sets whether vertical sync is enable for the game display.
+     *
+     * @param enable true if vsync is enabled; false if not.
+     */
+    static void setVsync(bool enable);
+
+    /**
+     * Sleeps synchronously for the given amount of time (in milliseconds).
+     *
+     * @param ms How long to sleep (in milliseconds).
+     */
+    static void sleep(long ms);
+
+    /**
+     * Set if multi-sampling is enabled on the platform.
+     *
+     * @param enabled true sets multi-sampling to be enabled, false to be disabled.
+     */
+    static void setMultiSampling(bool enabled);
+
+   /**
+    * Is multi-sampling mode enabled.
+    */
+    static bool isMultiSampling();
+
+    /**
+     * Set if multi-touch is enabled on the platform.
+     *
+     * Note that this method does nothing on platforms that do not
+     * support multi-touch.
+     */
+    static void setMultiTouch(bool enabled);
+
+   /**
+    * Is multi-touch mode enabled.
+    */
+    static bool isMultiTouch();
+
+    /**
+     * Whether the platform has mouse support.
+     */
+    static bool hasMouse();
+
+    /**
+     * Enables or disabled mouse capture.
+     *
+     * When mouse capture is enabled, the platform cursor is hidden
+     * and mouse event points are delivered as position deltas instead
+     * of absolute positions.
+     *
+     * This is useful for games that wish to provide uninhibited mouse
+     * movement, such as when implementing free/mouse look in an FPS
+     * game.
+     *
+     * Disabling mouse capture moves the mouse back to the center of the
+     * screen and shows the platform cursor.
+     *
+     * Note that this method does nothing on platforms that do not
+     * support a mouse.
+     *
+     * @param captured True to enable mouse capture, false to disable it.
+     */
+    static void setMouseCaptured(bool captured);
+
+    /**
+     * Determines if mouse capture is currently enabled.
+     */
+    static bool isMouseCaptured();
+
+    /**
+     * Sets the visibility of the platform cursor.
+     *
+     * On platforms that support a visible cursor, this method
+     * toggles the visibility of the cursor.
+     *
+     * @param visible true to show the platform cursor, false to hide it.
+     */
+    static void setCursorVisible(bool visible);
+
+    /**
+     * Determines whether the platform cursor is currently visible.
+     *
+     * @return true if the platform cursor is visible, false otherwise.
+     */
+    static bool isCursorVisible();
+
+    /**
+     * Whether the platform has accelerometer support.
+     */
+    static bool hasAccelerometer();
+
+    /**
+     * Gets the platform accelerometer values for use as an indication of device
+     * orientation. Despite its name, implementations are at liberty to combine
+     * accelerometer data with data from other sensors as well, such as the gyros.
+     * This method is best used to obtain an indication of device orientation; it
+     * does not necessarily distinguish between acceleration and rotation rate.
+     *
+     * @param pitch The accelerometer pitch. Zero if hasAccelerometer() returns false.
+     * @param roll The accelerometer roll. Zero if hasAccelerometer() returns false.
+     */
+    static void getAccelerometerValues(float* pitch, float* roll);
+
+    /**
+     * Gets sensor values (raw), if equipped, allowing a distinction between device acceleration
+     * and rotation rate. Returns zeros on platforms with no corresponding support. See also
+     * hasAccelerometer() and getAccelerometerValues().
+     *
+     * @param accelX The x-coordinate of the raw accelerometer data.
+     * @param accelY The y-coordinate of the raw accelerometer data.
+     * @param accelZ The z-coordinate of the raw accelerometer data.
+     * @param gyroX The x-coordinate of the raw gyroscope data.
+     * @param gyroY The y-coordinate of the raw gyroscope data.
+     * @param gyroZ The z-coordinate of the raw gyroscope data.
+     */
+    static void getSensorValues(float* accelX, float* accelY, float* accelZ, float* gyroX, float* gyroY, float* gyroZ);
+
+    /**
+     * Gets the command line arguments.
+     *
+     * @param argc The number of command line arguments.
+     * @param argv The array of command line arguments.
+     */
+    static void getArguments(int* argc, char*** argv);
+
+    /**
+     * Shows or hides the virtual keyboard (if supported).
+     *
+     * @param display true when virtual keyboard needs to be displayed and false otherwise.
+     */
+    static void displayKeyboard(bool display);
+
+    /**
+     * Tests if the specified gesture is supported on the platform.
+     *
+     * @return true if it is supported; false if not supported.
+     */
+    static bool isGestureSupported(Gesture::GestureEvent evt);
+
+    /**
+     * Registers the platform for gesture recognition for the specified gesture event.
+     *
+     * @param evt The gesture event to register to start recognizing events for.
+     */
+    static void registerGesture(Gesture::GestureEvent evt);
+
+    /**
+     * Registers the platform for gesture recognition for the specified gesture event.
+     *
+     * @param evt The gesture event to register to start recognizing events for.
+     */
+    static void unregisterGesture(Gesture::GestureEvent evt);
+
+    /**
+     * Tests if the specified gesture is registered for gesture recognition for the specified gesture event
+     *
+     * @param evt The gesture event to register to start recognizing events for.
+     */
+    static bool isGestureRegistered(Gesture::GestureEvent evt);
+
+    /**
+     * Opens an URL in an external browser, if available.
+     *
+     * @param url URL to be opened.
+     *
+     * @return True if URL was opened successfully, false otherwise.
+     */
+    static bool launchURL(const char* url);
+
+    /**
+     * Constructor.
+     */
+    Platform(Game* game);
+
+    /**
+     * Constructor.
+     */
+    Platform(const Platform& copy);
+
+public:
+
+    /**
+     * Internal method used only from static code in various platform implementation.
+     *
+     * @script{ignore}
+     */
+    static void touchEventInternal(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex, bool actuallyMouse = false);
+
+    /**
+     * Internal method used only from static code in various platform implementation.
+     *
+     * @script{ignore}
+     */
+    static void keyEventInternal(Keyboard::KeyEvent evt, int key);
+
+   /**
+     * Internal method used only from static code in various platform implementation.
+     *
+     * @script{ignore}
+     */
+    static bool mouseEventInternal(Mouse::MouseEvent evt, int x, int y, int wheelDelta);
+
+    /**
+     * Internal method used only from static code in various platform implementation.
+     *
+     * @script{ignore}
+     */
+    static void gestureSwipeEventInternal(int x, int y, int direction);
+
+    /**
+     * Internal method used only from static code in various platform implementation.
+     *
+     * @script{ignore}
+     */
+    static void gesturePinchEventInternal(int x, int y, float scale);
+
+    /**
+     * Internal method used only from static code in various platform implementation.
+     *
+     * @script{ignore}
+     */
+    static void gestureTapEventInternal(int x, int y);
+
+    /**
+     * Internal method used only from static code in various platform implementation.
+     *
+     * @script{ignore}
+     */
+	static void gestureLongTapEventInternal(int x, int y, float duration);
+
+    /**
+     * Internal method used only from static code in various platform implementation.
+     *
+     * @script{ignore}
+     */
+	static void gestureDragEventInternal(int x, int y);
+
+    /**
+     * Internal method used only from static code in various platform implementation.
+     *
+     * @script{ignore}
+     */
+	static void gestureDropEventInternal(int x, int y);
+
+    /**
+     * Internal method used only from static code in various platform implementation.
+     *
+     * @script{ignore}
+     */
+    static void resizeEventInternal(unsigned int width, unsigned int height);
+
+    /**
+     * Internal method used only from static code in various platform implementation.
+     *
+     * @script{ignore}
+     */
+    static void gamepadEventInternal(Gamepad::GamepadEvent evt, Gamepad* gamepad, unsigned int analogIndex = 0);
+
+    /**
+     * Internal method used only from static code in various platform implementation.
+     *
+     * @script{ignore}
+     */
+    static void gamepadEventConnectedInternal(GamepadHandle handle, unsigned int buttonCount, unsigned int joystickCount, unsigned int triggerCount,
+                                              unsigned int vendorId, unsigned int productId,
+                                              const char* vendorString, const char* productString);
+
+    /**
+     * Internal method used only from static code in various platform implementation.
+     *
+     * @script{ignore}
+     */
+    static void gamepadEventDisconnectedInternal(GamepadHandle handle);
+
+    /**
+     * Internal method used by Gamepad that polls the platform for the updated Gamepad
+     * states such as joysticks, buttons and trigger values.
+     *
+     * @param gamepad The gamepad to be returned with the latest polled values populated.
+     * @script{ignore}
+     */
+    static void pollGamepadState(Gamepad* gamepad);
+
+    /**
+     * Displays an open or save dialog using the native platform dialog system.
+     *
+     * @param mode The mode of the dialog. (Ex. OPEN or SAVE)
+     * @param title The title of the dialog. (Ex. Select File or Save File)
+     *  @param filterDescription The file filter description. (Ex. All Files or PNG Files)
+     * @param filterExtension The extension. Ex. (* or png)  Note: This prefixed with *.
+     * @return The file that is opened or saved.
+     *
+     * @script{ignore}
+     */
+    static std::string displayFileDialog(size_t mode, const char* title, const char* filterDescription, const char* filterExtension);
+
+    /**
+     * Internal method used only from static code in various platform implementation.
+     *
+     * @script{ignore}
+     */
+    static void shutdownInternal();
+
+private:
+
+    Game* _game;                // The game this platform is interfacing with.
+};
+
+}
+
+#include "Game.h"
+
+#endif

+ 5 - 0
gameplay/src/PlatformAndroid.cpp

@@ -1621,6 +1621,11 @@ bool Platform::launchURL(const char *url)
     return result;
 }
 
+std::string Platform::displayFileDialog(size_t mode, const char* title, const char* filterDescription, const char* filterExtension)
+{
+    return "";
+}
+
 }
 
 #endif

+ 1660 - 1655
gameplay/src/PlatformBlackBerry.cpp

@@ -1,1655 +1,1660 @@
-#ifdef __QNX__
-
-#include "Base.h"
-#include "Platform.h"
-#include "FileSystem.h"
-#include "Game.h"
-#include "Form.h"
-#include "ScriptController.h"
-#include <unistd.h>
-#include <sys/keycodes.h>
-#include <screen/screen.h>
-#include <input/screen_helpers.h>
-#include <gestures/set.h>
-#include <gestures/swipe.h>
-#include <gestures/pinch.h>
-#include <gestures/tap.h>
-#include <bps/bps.h>
-#include <bps/event.h>
-#include <bps/screen.h>
-#include <bps/navigator.h>
-#include <bps/sensor.h>
-#include <bps/orientation.h>
-#include <bps/virtualkeyboard.h>
-
-#define TOUCH_COUNT_MAX     4
-
-using namespace std;
-
-int __argc = 0;
-char** __argv = 0;
-struct timespec __timespec;
-static double __timeStart;
-static double __timeAbsolute;
-static bool __vsync = WINDOW_VSYNC;
-static screen_context_t __screenContext;
-static screen_window_t __screenWindow;
-static screen_event_t __screenEvent;
-static int __screenWindowSize[2];
-static bool __screenFullscreen = false;
-static EGLDisplay __eglDisplay = EGL_NO_DISPLAY;
-static EGLContext __eglContext = EGL_NO_CONTEXT;
-static EGLSurface __eglSurface = EGL_NO_SURFACE;
-static EGLConfig __eglConfig = 0;
-static int __orientationAngle;
-static bool __multiTouch = false;
-static bool __multiSampling = false;
-static float __pitch;
-static float __roll;
-static float __accelRawX;
-static float __accelRawY;
-static float __accelRawZ;
-static float __gyroRawX;
-static float __gyroRawY;
-static float __gyroRawZ;
-static const char* __glExtensions;
-static struct gestures_set * __gestureSet;
-static bitset<3> __gestureEventsProcessed;
-static bool __gestureSwipeRecognized = false;
-PFNGLBINDVERTEXARRAYOESPROC glBindVertexArray = NULL;
-PFNGLDELETEVERTEXARRAYSOESPROC glDeleteVertexArrays = NULL;
-PFNGLGENVERTEXARRAYSOESPROC glGenVertexArrays = NULL;
-PFNGLISVERTEXARRAYOESPROC glIsVertexArray = NULL;
-
-namespace gameplay
-{
-
-// Gets the Keyboard::Key enumeration constant that corresponds to the given QNX key code.
-static Keyboard::Key getKey(int qnxKeycode)
-{
-    switch (qnxKeycode)
-    {
-    case KEYCODE_SYSREQ:
-        return Keyboard::KEY_SYSREQ;
-    case KEYCODE_BREAK:
-        return Keyboard::KEY_BREAK;
-    case KEYCODE_MENU:
-        return Keyboard::KEY_MENU;
-    case KEYCODE_KP_ENTER:
-        return Keyboard::KEY_KP_ENTER;
-    case KEYCODE_PAUSE:
-        return Keyboard::KEY_PAUSE;
-    case KEYCODE_SCROLL_LOCK:
-        return Keyboard::KEY_SCROLL_LOCK;
-    case KEYCODE_PRINT:
-        return Keyboard::KEY_PRINT;
-    case KEYCODE_ESCAPE:
-        return Keyboard::KEY_ESCAPE;
-    case KEYCODE_BACKSPACE:
-        return Keyboard::KEY_BACKSPACE;
-    case KEYCODE_BACK_TAB:
-        return Keyboard::KEY_BACK_TAB;
-    case KEYCODE_TAB:
-        return Keyboard::KEY_TAB;
-    case KEYCODE_RETURN:
-        return Keyboard::KEY_RETURN;
-    case KEYCODE_CAPS_LOCK:
-        return Keyboard::KEY_CAPS_LOCK;
-    case KEYCODE_LEFT_SHIFT:
-    case KEYCODE_RIGHT_SHIFT:
-        return Keyboard::KEY_SHIFT;
-    case KEYCODE_LEFT_CTRL:
-    case KEYCODE_RIGHT_CTRL:
-        return Keyboard::KEY_CTRL;
-    case KEYCODE_LEFT_ALT:
-    case KEYCODE_RIGHT_ALT:
-        return Keyboard::KEY_ALT;
-    case KEYCODE_LEFT_HYPER:
-    case KEYCODE_RIGHT_HYPER:
-        return Keyboard::KEY_HYPER;
-    case KEYCODE_INSERT:
-        return Keyboard::KEY_INSERT;
-    case KEYCODE_HOME:
-        return Keyboard::KEY_HOME;
-    case KEYCODE_PG_UP:
-        return Keyboard::KEY_PG_UP;
-    case KEYCODE_DELETE:
-        return Keyboard::KEY_DELETE;
-    case KEYCODE_END:
-        return Keyboard::KEY_END;
-    case KEYCODE_PG_DOWN:
-        return Keyboard::KEY_PG_DOWN;
-    case KEYCODE_LEFT:
-        return Keyboard::KEY_LEFT_ARROW;
-    case KEYCODE_RIGHT:
-        return Keyboard::KEY_RIGHT_ARROW;
-    case KEYCODE_UP:
-        return Keyboard::KEY_UP_ARROW;
-    case KEYCODE_DOWN:
-        return Keyboard::KEY_DOWN_ARROW;
-    case KEYCODE_NUM_LOCK:
-        return Keyboard::KEY_NUM_LOCK;
-    case KEYCODE_KP_PLUS:
-        return Keyboard::KEY_KP_PLUS;
-    case KEYCODE_KP_MINUS:
-        return Keyboard::KEY_KP_MINUS;
-    case KEYCODE_KP_MULTIPLY:
-        return Keyboard::KEY_KP_MULTIPLY;
-    case KEYCODE_KP_DIVIDE:
-        return Keyboard::KEY_KP_DIVIDE;
-    case KEYCODE_KP_HOME:
-        return Keyboard::KEY_KP_HOME;
-    case KEYCODE_KP_UP:
-        return Keyboard::KEY_KP_UP;
-    case KEYCODE_KP_PG_UP:
-        return Keyboard::KEY_KP_PG_UP;
-    case KEYCODE_KP_LEFT:
-        return Keyboard::KEY_KP_LEFT;
-    case KEYCODE_KP_FIVE:
-        return Keyboard::KEY_KP_FIVE;
-    case KEYCODE_KP_RIGHT:
-        return Keyboard::KEY_KP_RIGHT;
-    case KEYCODE_KP_END:
-        return Keyboard::KEY_KP_END;
-    case KEYCODE_KP_DOWN:
-        return Keyboard::KEY_KP_DOWN;
-    case KEYCODE_KP_PG_DOWN:
-        return Keyboard::KEY_KP_PG_DOWN;
-    case KEYCODE_KP_INSERT:
-        return Keyboard::KEY_KP_INSERT;
-    case KEYCODE_KP_DELETE:
-        return Keyboard::KEY_KP_DELETE;
-    case KEYCODE_F1:
-        return Keyboard::KEY_F1;
-    case KEYCODE_F2:
-        return Keyboard::KEY_F2;
-    case KEYCODE_F3:
-        return Keyboard::KEY_F3;
-    case KEYCODE_F4:
-        return Keyboard::KEY_F4;
-    case KEYCODE_F5:
-        return Keyboard::KEY_F5;
-    case KEYCODE_F6:
-        return Keyboard::KEY_F6;
-    case KEYCODE_F7:
-        return Keyboard::KEY_F7;
-    case KEYCODE_F8:
-        return Keyboard::KEY_F8;
-    case KEYCODE_F9:
-        return Keyboard::KEY_F9;
-    case KEYCODE_F10:
-        return Keyboard::KEY_F10;
-    case KEYCODE_F11:
-        return Keyboard::KEY_F11;
-    case KEYCODE_F12:
-        return Keyboard::KEY_F12;
-    case KEYCODE_SPACE:
-        return Keyboard::KEY_SPACE;
-    case KEYCODE_RIGHT_PAREN:
-        return Keyboard::KEY_RIGHT_PARENTHESIS;
-    case KEYCODE_ZERO:
-        return Keyboard::KEY_ZERO;
-    case KEYCODE_EXCLAM:
-        return Keyboard::KEY_EXCLAM;
-    case KEYCODE_ONE:
-        return Keyboard::KEY_ONE;
-    case KEYCODE_AT:
-        return Keyboard::KEY_AT;
-    case KEYCODE_TWO:
-        return Keyboard::KEY_TWO;
-    case KEYCODE_NUMBER:
-        return Keyboard::KEY_NUMBER;
-    case KEYCODE_THREE:
-        return Keyboard::KEY_THREE;
-    case KEYCODE_DOLLAR:
-        return Keyboard::KEY_DOLLAR;
-    case KEYCODE_FOUR:
-        return Keyboard::KEY_FOUR;
-    case KEYCODE_PERCENT:
-        return Keyboard::KEY_PERCENT;
-    case KEYCODE_FIVE:
-        return Keyboard::KEY_FIVE;
-    case KEYCODE_CIRCUMFLEX:
-        return Keyboard::KEY_CIRCUMFLEX;
-    case KEYCODE_SIX:
-        return Keyboard::KEY_SIX;
-    case KEYCODE_AMPERSAND:
-        return Keyboard::KEY_AMPERSAND;
-    case KEYCODE_SEVEN:
-        return Keyboard::KEY_SEVEN;
-    case KEYCODE_ASTERISK:
-        return Keyboard::KEY_ASTERISK;
-    case KEYCODE_EIGHT:
-        return Keyboard::KEY_EIGHT;
-    case KEYCODE_LEFT_PAREN:
-        return Keyboard::KEY_LEFT_PARENTHESIS;
-    case KEYCODE_NINE:
-        return Keyboard::KEY_NINE;
-    case KEYCODE_EQUAL:
-        return Keyboard::KEY_EQUAL;
-    case KEYCODE_PLUS:
-        return Keyboard::KEY_PLUS;
-    case KEYCODE_LESS_THAN:
-        return Keyboard::KEY_LESS_THAN;
-    case KEYCODE_COMMA:
-        return Keyboard::KEY_COMMA;
-    case KEYCODE_UNDERSCORE:
-        return Keyboard::KEY_UNDERSCORE;
-    case KEYCODE_MINUS:
-        return Keyboard::KEY_MINUS;
-    case KEYCODE_GREATER_THAN:
-        return Keyboard::KEY_GREATER_THAN;
-    case KEYCODE_PERIOD:
-        return Keyboard::KEY_PERIOD;
-    case KEYCODE_COLON:
-        return Keyboard::KEY_COLON;
-    case KEYCODE_SEMICOLON:
-        return Keyboard::KEY_SEMICOLON;
-    case KEYCODE_QUESTION:
-        return Keyboard::KEY_QUESTION;
-    case KEYCODE_SLASH:
-        return Keyboard::KEY_SLASH;
-    case KEYCODE_GRAVE:
-        return Keyboard::KEY_GRAVE;
-    case KEYCODE_TILDE:
-        return Keyboard::KEY_TILDE;
-    case KEYCODE_LEFT_BRACE:
-        return Keyboard::KEY_LEFT_BRACE;
-    case KEYCODE_LEFT_BRACKET:
-        return Keyboard::KEY_LEFT_BRACKET;
-    case KEYCODE_BAR:
-        return Keyboard::KEY_BAR;
-    case KEYCODE_BACK_SLASH:
-        return Keyboard::KEY_BACK_SLASH;
-    case KEYCODE_RIGHT_BRACE:
-        return Keyboard::KEY_RIGHT_BRACE;
-    case KEYCODE_RIGHT_BRACKET:
-        return Keyboard::KEY_RIGHT_BRACKET;
-    case KEYCODE_QUOTE:
-        return Keyboard::KEY_QUOTE;
-    case KEYCODE_APOSTROPHE:
-        return Keyboard::KEY_APOSTROPHE;
-    case 0x20AC:
-        return Keyboard::KEY_EURO;
-    case KEYCODE_POUND_SIGN:
-        return Keyboard::KEY_POUND;
-    case KEYCODE_YEN_SIGN:
-        return Keyboard::KEY_YEN;
-    case KEYCODE_MIDDLE_DOT:
-        return Keyboard::KEY_MIDDLE_DOT;
-    case KEYCODE_CAPITAL_A:
-        return Keyboard::KEY_CAPITAL_A;
-    case KEYCODE_A:
-        return Keyboard::KEY_A;
-    case KEYCODE_CAPITAL_B:
-        return Keyboard::KEY_CAPITAL_B;
-    case KEYCODE_B:
-        return Keyboard::KEY_B;
-    case KEYCODE_CAPITAL_C:
-        return Keyboard::KEY_CAPITAL_C;
-    case KEYCODE_C:
-        return Keyboard::KEY_C;
-    case KEYCODE_CAPITAL_D:
-        return Keyboard::KEY_CAPITAL_D;
-    case KEYCODE_D:
-        return Keyboard::KEY_D;
-    case KEYCODE_CAPITAL_E:
-        return Keyboard::KEY_CAPITAL_E;
-    case KEYCODE_E:
-        return Keyboard::KEY_E;
-    case KEYCODE_CAPITAL_F:
-        return Keyboard::KEY_CAPITAL_F;
-    case KEYCODE_F:
-        return Keyboard::KEY_F;
-    case KEYCODE_CAPITAL_G:
-        return Keyboard::KEY_CAPITAL_G;
-    case KEYCODE_G:
-        return Keyboard::KEY_G;
-    case KEYCODE_CAPITAL_H:
-        return Keyboard::KEY_CAPITAL_H;
-    case KEYCODE_H:
-        return Keyboard::KEY_H;
-    case KEYCODE_CAPITAL_I:
-        return Keyboard::KEY_CAPITAL_I;
-    case KEYCODE_I:
-        return Keyboard::KEY_I;
-    case KEYCODE_CAPITAL_J:
-        return Keyboard::KEY_CAPITAL_J;
-    case KEYCODE_J:
-        return Keyboard::KEY_J;
-    case KEYCODE_CAPITAL_K:
-        return Keyboard::KEY_CAPITAL_K;
-    case KEYCODE_K:
-        return Keyboard::KEY_K;
-    case KEYCODE_CAPITAL_L:
-        return Keyboard::KEY_CAPITAL_L;
-    case KEYCODE_L:
-        return Keyboard::KEY_L;
-    case KEYCODE_CAPITAL_M:
-        return Keyboard::KEY_CAPITAL_M;
-    case KEYCODE_M:
-        return Keyboard::KEY_M;
-    case KEYCODE_CAPITAL_N:
-        return Keyboard::KEY_CAPITAL_N;
-    case KEYCODE_N:
-        return Keyboard::KEY_N;
-    case KEYCODE_CAPITAL_O:
-        return Keyboard::KEY_CAPITAL_O;
-    case KEYCODE_O:
-        return Keyboard::KEY_O;
-    case KEYCODE_CAPITAL_P:
-        return Keyboard::KEY_CAPITAL_P;
-    case KEYCODE_P:
-        return Keyboard::KEY_P;
-    case KEYCODE_CAPITAL_Q:
-        return Keyboard::KEY_CAPITAL_Q;
-    case KEYCODE_Q:
-        return Keyboard::KEY_Q;
-    case KEYCODE_CAPITAL_R:
-        return Keyboard::KEY_CAPITAL_R;
-    case KEYCODE_R:
-        return Keyboard::KEY_R;
-    case KEYCODE_CAPITAL_S:
-        return Keyboard::KEY_CAPITAL_S;
-    case KEYCODE_S:
-        return Keyboard::KEY_S;
-    case KEYCODE_CAPITAL_T:
-        return Keyboard::KEY_CAPITAL_T;
-    case KEYCODE_T:
-        return Keyboard::KEY_T;
-    case KEYCODE_CAPITAL_U:
-        return Keyboard::KEY_CAPITAL_U;
-    case KEYCODE_U:
-        return Keyboard::KEY_U;
-    case KEYCODE_CAPITAL_V:
-        return Keyboard::KEY_CAPITAL_V;
-    case KEYCODE_V:
-        return Keyboard::KEY_V;
-    case KEYCODE_CAPITAL_W:
-        return Keyboard::KEY_CAPITAL_W;
-    case KEYCODE_W:
-        return Keyboard::KEY_W;
-    case KEYCODE_CAPITAL_X:
-        return Keyboard::KEY_CAPITAL_X;
-    case KEYCODE_X:
-        return Keyboard::KEY_X;
-    case KEYCODE_CAPITAL_Y:
-        return Keyboard::KEY_CAPITAL_Y;
-    case KEYCODE_Y:
-        return Keyboard::KEY_Y;
-    case KEYCODE_CAPITAL_Z:
-        return Keyboard::KEY_CAPITAL_Z;
-    case KEYCODE_Z:
-        return Keyboard::KEY_Z;
-    default:
-        return Keyboard::KEY_NONE;
-    }
-}
-
-/**
- * Returns the unicode value from the given QNX key code value.
- * Some non-printable characters also have corresponding unicode values, such as backspace.
- *
- * @param qnxKeyCode The keyboard key code.
- *
- * @return The unicode value or 0 if the keycode did not represent a unicode key.
- */
-static int getUnicode(int qnxKeyCode)
-{
-    if (qnxKeyCode >= KEYCODE_PC_KEYS && qnxKeyCode <= UNICODE_PRIVATE_USE_AREA_LAST)
-    {
-        switch (qnxKeyCode)
-        {
-        case KEYCODE_BACKSPACE:
-            return 0x0008;
-        case KEYCODE_TAB:
-            return 0x0009;
-        case KEYCODE_KP_ENTER:
-        case KEYCODE_RETURN:
-            return 0x000A;
-        case KEYCODE_ESCAPE:
-            return 0x001B;
-        // Win32 doesn't consider delete to be a key char.
-        default:
-            return 0;
-        }
-    }
-    return qnxKeyCode;
-}
-
-extern void print(const char* format, ...)
-{
-    GP_ASSERT(format);
-    va_list argptr;
-    va_start(argptr, format);
-    vfprintf(stderr, format, argptr);
-    va_end(argptr);
-}
-
-EGLenum checkErrorEGL(const char* msg)
-{
-    GP_ASSERT(msg);
-    static const char* errmsg[] =
-    {
-        "EGL function failed",
-        "EGL is not initialized, or could not be initialized, for the specified display",
-        "EGL cannot access a requested resource",
-        "EGL failed to allocate resources for the requested operation",
-        "EGL fail to access an unrecognized attribute or attribute value was passed in an attribute list",
-        "EGLConfig argument does not name a valid EGLConfig",
-        "EGLContext argument does not name a valid EGLContext",
-        "EGL current surface of the calling thread is no longer valid",
-        "EGLDisplay argument does not name a valid EGLDisplay",
-        "EGL arguments are inconsistent",
-        "EGLNativePixmapType argument does not refer to a valid native pixmap",
-        "EGLNativeWindowType argument does not refer to a valid native window",
-        "EGL one or more argument values are invalid",
-        "EGLSurface argument does not name a valid surface configured for rendering",
-        "EGL power management event has occurred",
-    };
-    EGLenum error = eglGetError();
-    fprintf(stderr, "%s: %s\n", msg, errmsg[error - EGL_SUCCESS]);
-    return error;
-}
-
-void gesture_callback(gesture_base_t* gesture, mtouch_event_t* event, void* param, int async)
-{
-    switch (gesture->type)
-    {
-    case GESTURE_SWIPE:
-        {
-            if ( __gestureEventsProcessed.test(Gesture::GESTURE_SWIPE) )
-            {
-                gesture_swipe_t* swipe = (gesture_swipe_t*)gesture;
-                if (!__gestureSwipeRecognized)
-                {
-                    Platform::gestureSwipeEventInternal(swipe->coords.x, swipe->coords.y, swipe->direction);
-                    __gestureSwipeRecognized = true;
-                }
-
-            }
-            break;
-        }
-
-    case GESTURE_PINCH:
-        {
-            if ( __gestureEventsProcessed.test(Gesture::GESTURE_PINCH) )
-            {
-                gesture_pinch_t* pinch = (gesture_pinch_t*)gesture;
-                float dist_x = (float)pinch->last_distance.x - (float)pinch->distance.x;
-                float dist_y = (float)pinch->last_distance.y - (float)pinch->distance.y;
-                float scale = sqrt( (dist_x * dist_x) + (dist_y * dist_y) );
-                Game::getInstance()->gesturePinchEvent(pinch->centroid.x, pinch->centroid.y, scale);
-            }
-            break;
-        }
-
-    case GESTURE_TAP:
-        {
-            if ( __gestureEventsProcessed.test(Gesture::GESTURE_TAP) )
-            {
-                gesture_tap_t* tap = (gesture_tap_t*)gesture;
-                Platform::gestureTapEventInternal(tap->touch_coords.x, tap->touch_coords.y);
-            }
-            break;
-        }
-
-    default:
-        break;
-
-    }
-}
-
-#ifdef GP_USE_GAMEPAD
-
-static const char* __vendorStrings[] =
-{
-    "SteelSeries",
-    "Nintendo",
-};
-
-static const char* __productStrings[] =
-{
-    "FREE",
-    "Wii Remote",
-};
-
-static const int __VIDs[] = {
-    0x1038,
-    0x057e,
-};
-
-static const int __PIDs[] = {
-    0x1412,
-    0x0306,
-};
-
-static const unsigned int __knownGamepads = 2;
-
-void queryGamepad(GamepadHandle handle, int* buttonCount, int* joystickCount, int* productId, int* vendorId, char* productString, char* vendorString)
-{
-    char id[128];
-    screen_get_device_property_iv(handle, SCREEN_PROPERTY_BUTTON_COUNT, buttonCount);
-    screen_get_device_property_cv(handle, SCREEN_PROPERTY_ID_STRING, 128, id);
-    screen_get_device_property_cv(handle, SCREEN_PROPERTY_PRODUCT, 64, productString);
-    screen_get_device_property_cv(handle, SCREEN_PROPERTY_VENDOR, 64, vendorString);
-
-    // Check for the existence of analog sticks.
-    int analogs[3];
-    if (!screen_get_device_property_iv(handle, SCREEN_PROPERTY_ANALOG0, analogs))
-    {
-    	++(*joystickCount);
-    }
-
-    if (!screen_get_device_property_iv(handle, SCREEN_PROPERTY_ANALOG1, analogs))
-    {
-    	++(*joystickCount);
-    }
-
-    // ID string format: A-BBBB-CCCC-D.D
-    // A is the device's index
-    // BBBB is the device's Vendor ID (in hexadecimal)
-    // CCCC is the device's Product ID (also in hexadecimal)
-    // D.D is the device's version number
-    char* token = strtok(id, "-");
-    token = strtok(NULL, "-");
-    if (token)
-    {
-	    *vendorId = strtol(token, NULL, 16);
-    }
-
-    token = strtok(NULL, "-");
-    if (token)
-    {
-        *productId = strtol(token, NULL, 16);
-    }
-
-    // For gamepads unknown to BB10,
-    // check VID and PID against gamepads known to gameplay.
-    if (strlen(productString) == 0 || strlen(vendorString) == 0)
-    {
-        for (unsigned int i = 0; i < __knownGamepads; ++i)
-        {
-            if (__VIDs[i] == *vendorId && __PIDs[i] == *productId)
-            {
-            	strcpy(vendorString, __vendorStrings[i]);
-                strcpy(productString, __productStrings[i]);
-            }
-        }
-    }
-}
-
-void Platform::pollGamepadState(Gamepad* gamepad)
-{
-	unsigned int buttons;
-    screen_get_device_property_iv(gamepad->_handle, SCREEN_PROPERTY_BUTTONS, (int*)&buttons);
-	gamepad->setButtons(buttons);
-
-    unsigned int i;
-    for (i = 0; i < gamepad->_joystickCount; ++i)
-    {
-        GP_ASSERT(i < 2);
-
-        int analog[3];
-        switch (i)
-        {
-        case 0:
-            screen_get_device_property_iv(gamepad->_handle, SCREEN_PROPERTY_ANALOG0, analog);
-            break;
-        case 1:
-            screen_get_device_property_iv(gamepad->_handle, SCREEN_PROPERTY_ANALOG1, analog);
-            break;
-        }
-
-        // So far we've tested two gamepads with analog sticks on BlackBerry:
-        // the SteelSeries FREE, and the iControlPad.
-        // Both return values between -128 and +127, with the y axis starting from
-        // the top at -128.
-        // 1 / 128 == 0.0078125f
-        // 1 / 127 == 0.0078740157480315f
-        float x = (float)analog[0];
-        float y = -(float)analog[1];
-        x *= (x < 0) ? 0.0078125f : 0.0078740157480315f;
-        y *= (y > 0) ? 0.0078125f : 0.0078740157480315f;
-
-		gamepad->setJoystickValue(i, x, y);
-    }
-
-    for (i = 0; i < gamepad->_triggerCount; ++i)
-    {
-        GP_ASSERT(i < 2);
-
-        int analog[3];
-        switch (i)
-        {
-        case 0:
-            screen_get_device_property_iv(gamepad->_handle, SCREEN_PROPERTY_ANALOG0, analog);
-            break;
-        case 1:
-            screen_get_device_property_iv(gamepad->_handle, SCREEN_PROPERTY_ANALOG1, analog);
-            break;
-        }
-
-        float value = (float)analog[2] * 0.0078125f;
-		gamepad->setTriggerValue(i, value);
-    }
-}
-#else
-void Platform::pollGamepadState(Gamepad* gamepad)
-{
-}
-#endif
-
-Platform::Platform(Game* game)
-    : _game(game)
-{
-}
-
-Platform::~Platform()
-{
-    if (__eglDisplay != EGL_NO_DISPLAY)
-    {
-        eglMakeCurrent(__eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
-    }
-
-    if (__eglSurface != EGL_NO_SURFACE)
-    {
-        eglDestroySurface(__eglDisplay, __eglSurface);
-        __eglSurface = EGL_NO_SURFACE;
-    }
-
-    if (__eglContext != EGL_NO_CONTEXT)
-    {
-        eglDestroyContext(__eglDisplay, __eglContext);
-        __eglContext = EGL_NO_CONTEXT;
-    }
-
-    if (__eglDisplay != EGL_NO_DISPLAY)
-    {
-        eglTerminate(__eglDisplay);
-        __eglDisplay = EGL_NO_DISPLAY;
-    }
-
-    if (__screenWindow)
-    {
-        screen_destroy_window(__screenWindow);
-        __screenWindow = NULL;
-    }
-
-    if (__screenEvent)
-    {
-        screen_destroy_event(__screenEvent);
-        __screenEvent = NULL;
-    }
-
-    if (__screenContext)
-    {
-        screen_destroy_context(__screenContext);
-        __screenContext = NULL;
-    }
-}
-
-Platform* Platform::create(Game* game)
-{
-    FileSystem::setResourcePath("./app/native/");
-    Platform* platform = new Platform(game);
-
-    // Query game config
-    int samples = 0;
-    Properties* config = Game::getInstance()->getConfig()->getNamespace("window", true);
-    if (config)
-    {
-        samples = std::max(config->getInt("samples"), 0);
-    }
-
-    __gestureSet = gestures_set_alloc();
-    swipe_gesture_alloc(NULL, gesture_callback, __gestureSet);
-    pinch_gesture_alloc(NULL, gesture_callback, __gestureSet);
-    tap_gesture_alloc(NULL, gesture_callback, __gestureSet);
-
-    bps_initialize();
-
-    // Initialize navigator and orientation
-    static const int SENSOR_RATE = 25000; // (25000 microseconds = 40 Hz)
-    sensor_set_rate(SENSOR_TYPE_AZIMUTH_PITCH_ROLL, SENSOR_RATE);
-    sensor_set_rate(SENSOR_TYPE_ACCELEROMETER, SENSOR_RATE);
-    sensor_set_rate(SENSOR_TYPE_GYROSCOPE, SENSOR_RATE);
-    sensor_set_skip_duplicates(SENSOR_TYPE_AZIMUTH_PITCH_ROLL, true);
-    sensor_set_skip_duplicates(SENSOR_TYPE_ACCELEROMETER, true);
-    sensor_set_skip_duplicates(SENSOR_TYPE_GYROSCOPE, true);
-    sensor_request_events(SENSOR_TYPE_AZIMUTH_PITCH_ROLL);
-    sensor_request_events(SENSOR_TYPE_ACCELEROMETER);
-    sensor_request_events(SENSOR_TYPE_GYROSCOPE);
-    navigator_request_events(0);
-    navigator_rotation_lock(true);
-    __orientationAngle = atoi(getenv("ORIENTATION"));
-
-    int rc = 0;
-    int screenFormat = SCREEN_FORMAT_RGBA8888;
-#ifdef __X86__
-    int screenUsage = SCREEN_USAGE_OPENGL_ES2;
-#else
-    int screenUsage = SCREEN_USAGE_DISPLAY|SCREEN_USAGE_OPENGL_ES2; // Physical device copy directly into physical display
-#endif
-    int screenSwapInterval = WINDOW_VSYNC ? 1 : 0;
-    int screenTransparency = SCREEN_TRANSPARENCY_NONE;
-
-    char *width_str = getenv("WIDTH");
-    char *height_str = getenv("HEIGHT");
-
-    // Hard-coded to (0,0).
-    int windowPosition[] =
-    {
-        0, 0
-    };
-
-    EGLint eglConfigCount;
-
-    // Hard-coded to 32-bit/OpenGL ES 2.0.
-    // NOTE: EGL_SAMPLE_BUFFERS and EGL_SAMPLES MUST remain at the beginning of the attribute list
-    // since they are expected to be at indices 0-3 in config fallback code later.
-    EGLint eglConfigAttrs[] =
-    {
-        EGL_SAMPLE_BUFFERS,     samples > 0 ? 1 : 0,
-        EGL_SAMPLES,            samples,
-        EGL_RED_SIZE,           8,
-        EGL_GREEN_SIZE,         8,
-        EGL_BLUE_SIZE,          8,
-        EGL_ALPHA_SIZE,         8,
-        EGL_DEPTH_SIZE,         24,
-        EGL_STENCIL_SIZE,       8,
-        EGL_SURFACE_TYPE,       EGL_WINDOW_BIT,
-        EGL_RENDERABLE_TYPE,    EGL_OPENGL_ES2_BIT,
-        EGL_NONE
-    };
-    __multiSampling = samples > 0;
-
-    const EGLint eglContextAttrs[] =
-    {
-        EGL_CONTEXT_CLIENT_VERSION,    2,
-        EGL_NONE
-    };
-
-    const EGLint eglSurfaceAttrs[] =
-    {
-        EGL_RENDER_BUFFER,    EGL_BACK_BUFFER,
-        EGL_NONE
-    };
-
-    // Create the screen context.
-    rc = screen_create_context(&__screenContext, 0);
-    if (rc)
-    {
-        perror("screen_create_context");
-        goto error;
-    }
-
-    // Create the screen window.
-    rc = screen_create_window(&__screenWindow, __screenContext);
-    if (rc)
-    {
-        perror("screen_create_window");
-        goto error;
-    }
-
-    // Window group
-	rc = screen_create_window_group(__screenWindow, "windowgroup");
-	if (rc)
-	{
-		perror("screen_create_window_group failed");
-		goto error;
-	}
-
-    // Set/get any window properties.
-    rc = screen_set_window_property_iv(__screenWindow, SCREEN_PROPERTY_FORMAT, &screenFormat);
-    if (rc)
-    {
-        perror("screen_set_window_property_iv(SCREEN_PROPERTY_FORMAT)");
-        goto error;
-    }
-
-    rc = screen_set_window_property_iv(__screenWindow, SCREEN_PROPERTY_USAGE, &screenUsage);
-    if (rc)
-    {
-        perror("screen_set_window_property_iv(SCREEN_PROPERTY_USAGE)");
-        goto error;
-    }
-
-    if (width_str && height_str)
-    {
-        __screenWindowSize[0] = atoi(width_str);
-        __screenWindowSize[1] = atoi(height_str);
-    }
-    else
-    {
-        screen_display_t screen_display;
-        rc = screen_get_window_property_pv(__screenWindow, SCREEN_PROPERTY_DISPLAY, (void **)&screen_display);
-        if (rc)
-        {
-            perror("screen_get_window_property_pv(SCREEN_PROPERTY_DISPLAY)");
-            goto error;
-        }
-
-        screen_display_mode_t screen_mode;
-        rc = screen_get_display_property_pv(screen_display, SCREEN_PROPERTY_MODE, (void**)&screen_mode);
-        if (rc)
-        {
-            perror("screen_get_display_property_pv(SCREEN_PROPERTY_MODE)");
-            goto error;
-        }
-
-        int size[2];
-        rc = screen_get_window_property_iv(__screenWindow, SCREEN_PROPERTY_BUFFER_SIZE, size);
-        if (rc)
-        {
-            perror("screen_get_window_property_iv(SCREEN_PROPERTY_BUFFER_SIZE)");
-            goto error;
-        }
-
-        __screenWindowSize[0] = size[0];
-        __screenWindowSize[1] = size[1];
-
-        if ((__orientationAngle == 0) || (__orientationAngle == 180))
-        {
-            if (((screen_mode.width > screen_mode.height) && (size[0] < size[1])) ||
-                ((screen_mode.width < screen_mode.height) && (size[0] > size[1])))
-            {
-                __screenWindowSize[1] = size[0];
-                __screenWindowSize[0] = size[1];
-            }
-        }
-        else if ((__orientationAngle == 90) || (__orientationAngle == 270))
-        {
-            if (((screen_mode.width > screen_mode.height) && (size[0] > size[1])) ||
-                ((screen_mode.width < screen_mode.height) && (size[0] < size[1])))
-            {
-                __screenWindowSize[1] = size[0];
-                __screenWindowSize[0] = size[1];
-            }
-        }
-        else
-        {
-            perror("Navigator returned an unexpected orientation angle.");
-            goto error;
-        }
-
-
-        rc = screen_set_window_property_iv(__screenWindow, SCREEN_PROPERTY_ROTATION, &__orientationAngle);
-        if (rc)
-        {
-            perror("screen_set_window_property_iv(SCREEN_PROPERTY_ROTATION)");
-            goto error;
-        }
-    }
-
-    rc = screen_set_window_property_iv(__screenWindow, SCREEN_PROPERTY_BUFFER_SIZE, __screenWindowSize);
-    if (rc)
-    {
-        perror("screen_set_window_property_iv(SCREEN_PROPERTY_BUFFER_SIZE)");
-        goto error;
-    }
-
-    if (windowPosition[0] != 0 || windowPosition[1] != 0)
-    {
-        rc = screen_set_window_property_iv(__screenWindow, SCREEN_PROPERTY_POSITION, windowPosition);
-        if (rc)
-        {
-            perror("screen_set_window_property_iv(SCREEN_PROPERTY_POSITION)");
-            goto error;
-        }
-    }
-
-    rc = screen_set_window_property_iv(__screenWindow, SCREEN_PROPERTY_TRANSPARENCY, &screenTransparency);
-    if (rc)
-    {
-        perror("screen_set_window_property_iv(SCREEN_PROPERTY_TRANSPARENCY)");
-        goto error;
-    }
-
-    // Double buffered.
-    rc = screen_create_window_buffers(__screenWindow, 2);
-    if (rc)
-    {
-        perror("screen_create_window_buffers");
-        goto error;
-    }
-
-    // Create screen event object.
-    rc = screen_create_event(&__screenEvent);
-    if (rc)
-    {
-        perror("screen_create_event");
-        goto error;
-    }
-
-    // Request screen events.
-    screen_request_events(__screenContext);
-
-    // Get the EGL display and initialize.
-    __eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
-    if (__eglDisplay == EGL_NO_DISPLAY)
-    {
-        perror("eglGetDisplay");
-        goto error;
-    }
-    if (eglInitialize(__eglDisplay, NULL, NULL) != EGL_TRUE)
-    {
-        perror("eglInitialize");
-        goto error;
-    }
-
-    if (eglChooseConfig(__eglDisplay, eglConfigAttrs, &__eglConfig, 1, &eglConfigCount) != EGL_TRUE || eglConfigCount == 0)
-    {
-        bool success = false;
-        while (samples)
-        {
-            // Try lowering the MSAA sample count until we find a supported config
-            GP_WARN("Failed to find a valid EGL configuration with EGL samples=%d. Trying samples=%d instead.", samples, samples/2);
-            samples /= 2;
-            eglConfigAttrs[1] = samples > 0 ? 1 : 0;
-            eglConfigAttrs[3] = samples;
-            if (eglChooseConfig(__eglDisplay, eglConfigAttrs, &__eglConfig, 1, &eglConfigCount) == EGL_TRUE && eglConfigCount > 0)
-            {
-                success = true;
-                break;
-            }
-        }
-
-        __multiSampling = samples > 0;
-
-        if (!success)
-        {
-            checkErrorEGL("eglChooseConfig");
-            goto error;
-        }
-    }
-
-    __eglContext = eglCreateContext(__eglDisplay, __eglConfig, EGL_NO_CONTEXT, eglContextAttrs);
-    if (__eglContext == EGL_NO_CONTEXT)
-    {
-        checkErrorEGL("eglCreateContext");
-        goto error;
-    }
-
-    __eglSurface = eglCreateWindowSurface(__eglDisplay, __eglConfig, __screenWindow, eglSurfaceAttrs);
-    if (__eglSurface == EGL_NO_SURFACE)
-    {
-        checkErrorEGL("eglCreateWindowSurface");
-        goto error;
-    }
-
-    if (eglMakeCurrent(__eglDisplay, __eglSurface, __eglSurface, __eglContext) != EGL_TRUE)
-    {
-        checkErrorEGL("eglMakeCurrent");
-        goto error;
-    }
-
-    // Set vsync.
-    eglSwapInterval(__eglDisplay, screenSwapInterval);
-
-    // Initialize OpenGL ES extensions.
-    __glExtensions = (const char*)glGetString(GL_EXTENSIONS);
-
-    if (strstr(__glExtensions, "GL_OES_vertex_array_object") || strstr(__glExtensions, "GL_ARB_vertex_array_object"))
-    {
-        glBindVertexArray = (PFNGLBINDVERTEXARRAYOESPROC)eglGetProcAddress("glBindVertexArrayOES");
-        glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSOESPROC)eglGetProcAddress("glDeleteVertexArraysOES");
-        glGenVertexArrays = (PFNGLGENVERTEXARRAYSOESPROC)eglGetProcAddress("glGenVertexArraysOES");
-        glIsVertexArray = (PFNGLISVERTEXARRAYOESPROC)eglGetProcAddress("glIsVertexArrayOES");
-    }
-
- #ifdef GP_USE_GAMEPAD
-
-    screen_device_t* screenDevs;
-
-    // Discover initial gamepad devices.
-    int count;
-    screen_get_context_property_iv(__screenContext, SCREEN_PROPERTY_DEVICE_COUNT, &count);
-    screenDevs = (screen_device_t*)calloc(count, sizeof(screen_device_t));
-    screen_get_context_property_pv(__screenContext, SCREEN_PROPERTY_DEVICES, (void**)screenDevs);
-
-	for (int i = 0; i < count; i++)
-    {
-	    int type;
-        screen_get_device_property_iv(screenDevs[i], SCREEN_PROPERTY_TYPE, &type);
-
-        if (type == SCREEN_EVENT_GAMEPAD || type == SCREEN_EVENT_JOYSTICK)
-        {
-            int buttonCount = 0;
-            int joystickCount = 0;
-            int productId;
-            int vendorId;
-            char productString[64];
-            char vendorString[64];
-            queryGamepad(screenDevs[i], &buttonCount, &joystickCount, &productId, &vendorId, productString, vendorString);
-            Platform::gamepadEventConnectedInternal(screenDevs[i], buttonCount, joystickCount, 0, vendorId, productId, vendorString, productString);
-        }
-	}
-	free(screenDevs);
-#endif
-
-    return platform;
-
-error:
-
-    return NULL;
-}
-
-/**
- * Convert the timespec into milliseconds.
- */
-double timespec2millis(struct timespec *a)
-{
-    GP_ASSERT(a);
-    return (1000.0 * a->tv_sec) + (0.000001 * a->tv_nsec);
-}
-
-/**
- * Fires a mouse event or a touch event on the game.
- * If the mouse event is not consumed, a touch event is fired instead.
- *
- * @param mouseEvent The mouse event to fire.
- * @param touchEvent The touch event to fire.
- * @param x The x position of the touch in pixels.
- * @param y The y position of the touch in pixels.
- */
-void mouseOrTouchEvent(Mouse::MouseEvent mouseEvent, Touch::TouchEvent touchEvent, int x, int y)
-{
-    if (!gameplay::Platform::mouseEventInternal(mouseEvent, x, y, 0))
-    {
-        Platform::touchEventInternal(touchEvent, x, y, 0, true);
-    }
-}
-
-int Platform::enterMessagePump()
-{
-    GP_ASSERT(_game);
-
-    int rc;
-    int eventType;
-    int flags;
-    int value;
-    int position[2];
-    int domain;
-    mtouch_event_t touchEvent;
-    bool suspended = false;
-
-    // Get the initial time.
-    clock_gettime(CLOCK_REALTIME, &__timespec);
-    __timeStart = timespec2millis(&__timespec);
-    __timeAbsolute = 0L;
-
-    _game->run();
-
-    // Message loop.
-    while (true)
-    {
-        bps_event_t* event = NULL;
-
-        while (true)
-        {
-            rc = bps_get_event(&event, 1);
-            GP_ASSERT(rc == BPS_SUCCESS);
-
-            if (event == NULL)
-                break;
-
-#ifdef GP_USE_SOCIAL
-            // if the social controller needs to deal with the event do that here
-            if (Game::getInstance()->getSocialController()->handleEvent(event))
-            	break;
-#endif
-
-            domain = bps_event_get_domain(event);
-
-            if (domain == screen_get_domain())
-            {
-                __screenEvent = screen_event_get_event(event);
-                screen_get_event_property_iv(__screenEvent, SCREEN_PROPERTY_TYPE, &eventType);
-                switch (eventType)
-                {
-                    case SCREEN_EVENT_MTOUCH_TOUCH:
-                    {
-                        screen_get_mtouch_event(__screenEvent, &touchEvent, 0);
-                        if (__gestureEventsProcessed.any())
-                            rc = gestures_set_process_event(__gestureSet, &touchEvent, NULL);
-
-                        if ( !rc && (__multiTouch || touchEvent.contact_id == 0) )
-                        {
-                            gameplay::Platform::touchEventInternal(Touch::TOUCH_PRESS, touchEvent.x, touchEvent.y, touchEvent.contact_id);
-                        }
-                        break;
-                    }
-
-                    case SCREEN_EVENT_MTOUCH_RELEASE:
-                    {
-                        screen_get_mtouch_event(__screenEvent, &touchEvent, 0);
-                        if (__gestureEventsProcessed.any())
-                            rc = gestures_set_process_event(__gestureSet, &touchEvent, NULL);
-
-                        if ( !rc && (__multiTouch || touchEvent.contact_id == 0) )
-                        {
-                            gameplay::Platform::touchEventInternal(Touch::TOUCH_RELEASE, touchEvent.x, touchEvent.y, touchEvent.contact_id);
-                        }
-                        if (__gestureSwipeRecognized)
-                        {
-                            __gestureSwipeRecognized = false;
-                        }
-                        break;
-                    }
-
-                    case SCREEN_EVENT_MTOUCH_MOVE:
-                    {
-                        screen_get_mtouch_event(__screenEvent, &touchEvent, 0);
-                        if (__gestureEventsProcessed.any())
-                            rc = gestures_set_process_event(__gestureSet, &touchEvent, NULL);
-
-                        if ( !rc && (__multiTouch || touchEvent.contact_id == 0) )
-                        {
-                            gameplay::Platform::touchEventInternal(Touch::TOUCH_MOVE, touchEvent.x, touchEvent.y, touchEvent.contact_id);
-                        }
-                        break;
-                    }
-
-                    case SCREEN_EVENT_POINTER:
-                    {
-                        static int mouse_pressed = 0;
-                        int buttons;
-                        int wheel;
-                        // A move event will be fired unless a button state changed.
-                        bool move = true;
-                        bool left_move = false;
-                        // This is a mouse move event, it is applicable to a device with a usb mouse or simulator.
-                        screen_get_event_property_iv(__screenEvent, SCREEN_PROPERTY_BUTTONS, &buttons);
-                        screen_get_event_property_iv(__screenEvent, SCREEN_PROPERTY_SOURCE_POSITION, position);
-                        screen_get_event_property_iv(__screenEvent, SCREEN_PROPERTY_MOUSE_WHEEL, &wheel);
-
-                        // Handle left mouse. Interpret as touch if the left mouse event is not consumed.
-                        if (buttons & SCREEN_LEFT_MOUSE_BUTTON)
-                        {
-                            if (mouse_pressed & SCREEN_LEFT_MOUSE_BUTTON)
-                            {
-                                left_move = true;
-                            }
-                            else
-                            {
-                                move = false;
-                                mouse_pressed |= SCREEN_LEFT_MOUSE_BUTTON;
-                                mouseOrTouchEvent(Mouse::MOUSE_PRESS_LEFT_BUTTON, Touch::TOUCH_PRESS, position[0], position[1]);
-                            }
-                        }
-                        else if (mouse_pressed & SCREEN_LEFT_MOUSE_BUTTON)
-                        {
-                            move = false;
-                            mouse_pressed &= ~SCREEN_LEFT_MOUSE_BUTTON;
-                            mouseOrTouchEvent(Mouse::MOUSE_RELEASE_LEFT_BUTTON, Touch::TOUCH_RELEASE, position[0], position[1]);
-                        }
-
-                        // Handle right mouse.
-                        if (buttons & SCREEN_RIGHT_MOUSE_BUTTON)
-                        {
-                            if ((mouse_pressed & SCREEN_RIGHT_MOUSE_BUTTON) == 0)
-                            {
-                                move = false;
-                                mouse_pressed |= SCREEN_RIGHT_MOUSE_BUTTON;
-                                gameplay::Platform::mouseEventInternal(Mouse::MOUSE_PRESS_RIGHT_BUTTON, position[0], position[1], 0);
-                            }
-                        }
-                        else if (mouse_pressed & SCREEN_RIGHT_MOUSE_BUTTON)
-                        {
-                            move = false;
-                            mouse_pressed &= ~SCREEN_RIGHT_MOUSE_BUTTON;
-                            gameplay::Platform::mouseEventInternal(Mouse::MOUSE_RELEASE_RIGHT_BUTTON, position[0], position[1], 0);
-                        }
-
-                        // Handle middle mouse.
-                        if (buttons & SCREEN_MIDDLE_MOUSE_BUTTON)
-                        {
-                            if ((mouse_pressed & SCREEN_MIDDLE_MOUSE_BUTTON) == 0)
-                            {
-                                move = false;
-                                mouse_pressed |= SCREEN_MIDDLE_MOUSE_BUTTON;
-                                gameplay::Platform::mouseEventInternal(Mouse::MOUSE_PRESS_MIDDLE_BUTTON, position[0], position[1], 0);
-                            }
-                        }
-                        else if (mouse_pressed & SCREEN_MIDDLE_MOUSE_BUTTON)
-                        {
-                            move = false;
-                            mouse_pressed &= ~SCREEN_MIDDLE_MOUSE_BUTTON;
-                            gameplay::Platform::mouseEventInternal(Mouse::MOUSE_RELEASE_MIDDLE_BUTTON, position[0], position[1], 0);
-                        }
-
-                        // Fire a move event if none of the buttons changed.
-                        if (left_move)
-                        {
-                            mouseOrTouchEvent(Mouse::MOUSE_MOVE, Touch::TOUCH_MOVE, position[0], position[1]);
-                        }
-                        else if (move)
-                        {
-                            gameplay::Platform::mouseEventInternal(Mouse::MOUSE_MOVE, position[0], position[1], 0);
-                        }
-
-                        // Handle mouse wheel events.
-                        if (wheel)
-                        {
-                            gameplay::Platform::mouseEventInternal(Mouse::MOUSE_WHEEL, position[0], position[1], -wheel);
-                        }
-                        break;
-                    }
-
-                    case SCREEN_EVENT_KEYBOARD:
-                    {
-                        screen_get_event_property_iv(__screenEvent, SCREEN_PROPERTY_KEY_FLAGS, &flags);
-                        screen_get_event_property_iv(__screenEvent, SCREEN_PROPERTY_KEY_SYM, &value);
-                        gameplay::Keyboard::KeyEvent evt = (flags & KEY_DOWN) ? gameplay::Keyboard::KEY_PRESS :  gameplay::Keyboard::KEY_RELEASE;
-                        // Suppress key repeats.
-                        if ((flags & KEY_REPEAT) == 0)
-                        {
-                            keyEventInternal(evt, getKey(value));
-                            if (evt == gameplay::Keyboard::KEY_PRESS && (flags & KEY_SYM_VALID))
-                            {
-                                int unicode = getUnicode(value);
-                                if (unicode)
-                                    keyEventInternal(gameplay::Keyboard::KEY_CHAR, unicode);
-                            }
-                        }
-                        break;
-                    }
-#ifdef GP_USE_GAMEPAD
-                    case SCREEN_EVENT_DEVICE:
-                    {
-                        // A device was attached or removed.
-                        screen_device_t device;
-                        int attached;
-
-                        screen_get_event_property_pv(__screenEvent, SCREEN_PROPERTY_DEVICE, (void**)&device);
-                        screen_get_event_property_iv(__screenEvent, SCREEN_PROPERTY_ATTACHED, &attached);
-
-                        if (attached)
-                        {
-                            int type;
-                            screen_get_device_property_iv(device, SCREEN_PROPERTY_TYPE, &type);
-                            if (type == SCREEN_EVENT_GAMEPAD || type == SCREEN_EVENT_JOYSTICK)
-                            {
-                                int buttonCount = 0;
-                                int joystickCount = 0;
-                                int productId;
-                                int vendorId;
-                                char productString[64];
-                                char vendorString[64];
-                                queryGamepad(device, &buttonCount, &joystickCount, &productId, &vendorId, productString, vendorString);
-                                Platform::gamepadEventConnectedInternal(device, buttonCount, joystickCount, 0, vendorId, productId, vendorString, productString);
-                            }
-                        }
-                        else
-                        {
-                            Platform::gamepadEventDisconnectedInternal(device);
-                        }
-
-                        break;
-                    }
-#endif
-                    default:
-                        break;
-                }
-            }
-            else if (domain == navigator_get_domain())
-            {
-                switch (bps_event_get_code(event))
-                {
-                case NAVIGATOR_WINDOW_STATE:
-                {
-                    navigator_window_state_t state = navigator_event_get_window_state(event);
-                    switch (state)
-                    {
-                    case NAVIGATOR_WINDOW_FULLSCREEN:
-                        if (!__screenFullscreen)
-                            __screenFullscreen = true;
-                        _game->resume();
-                        suspended = false;
-                        break;
-                    case NAVIGATOR_WINDOW_THUMBNAIL:
-                    case NAVIGATOR_WINDOW_INVISIBLE:
-                        if (__screenFullscreen && !suspended)
-                        {
-                            _game->pause();
-                            suspended = true;
-                        }
-                        break;
-                    }
-                    break;
-                }
-                case NAVIGATOR_EXIT:
-                	// Call Game::shutdown directly, instead of Game::exit.
-                	// We need to do this since exit() queues a request to shutdown for the
-                	// next frame, which will never get executed because we are suspended.
-                    _game->shutdown();
-                    break;
-                }
-            }
-            else if (domain == sensor_get_domain())
-            {
-                if (bps_event_get_code(event) == SENSOR_AZIMUTH_PITCH_ROLL_READING)
-                {
-                    float azimuth;
-                    sensor_event_get_apr(event, &azimuth, &__pitch, &__roll);
-                }
-                else if (bps_event_get_code(event) == SENSOR_ACCELEROMETER_READING)
-                {
-                    sensor_event_get_xyz(event, &__accelRawX, &__accelRawY, &__accelRawZ);
-                }
-                else if (bps_event_get_code(event) == SENSOR_GYROSCOPE_READING)
-                {
-                    sensor_event_get_xyz(event, &__gyroRawX, &__gyroRawY, &__gyroRawZ);
-                }
-            }
-        }
-
-        // If we are done, then exit.
-        if (_game->getState() == Game::UNINITIALIZED)
-            break;
-
-        if (!suspended)
-        {
-            _game->frame();
-
-            // Post the new frame to the display.
-            // Note that there are a couple cases where eglSwapBuffers could fail
-            // with an error code that requires a certain level of re-initialization:
-            //
-            // 1) EGL_BAD_NATIVE_WINDOW - Called when the surface we're currently using
-            //    is invalidated. This would require us to destroy our EGL surface,
-            //    close our OpenKODE window, and start again.
-            //
-            // 2) EGL_CONTEXT_LOST - Power management event that led to our EGL context
-            //    being lost. Requires us to re-create and re-initalize our EGL context
-            //    and all OpenGL ES state.
-            //
-            // For now, if we get these, we'll simply exit.
-            rc = eglSwapBuffers(__eglDisplay, __eglSurface);
-            if (rc != EGL_TRUE)
-            {
-                _game->shutdown();
-                perror("eglSwapBuffers");
-                break;
-            }
-        }
-    }
-
-    screen_stop_events(__screenContext);
-    bps_shutdown();
-    screen_destroy_context(__screenContext);
-
-    return 0;
-}
-    
-void Platform::signalShutdown() 
-{
-    // nothing to do  
-}
-
-bool Platform::canExit()
-{
-    return true;
-}
-
-unsigned int Platform::getDisplayWidth()
-{
-    return __screenWindowSize[0];
-}
-
-unsigned int Platform::getDisplayHeight()
-{
-    return __screenWindowSize[1];
-}
-
-double Platform::getAbsoluteTime()
-{
-    clock_gettime(CLOCK_REALTIME, &__timespec);
-    double now = timespec2millis(&__timespec);
-    __timeAbsolute = now - __timeStart;
-
-    return __timeAbsolute;
-}
-
-void Platform::setAbsoluteTime(double time)
-{
-    __timeAbsolute = time;
-}
-
-bool Platform::isVsync()
-{
-    return __vsync;
-}
-
-void Platform::setVsync(bool enable)
-{
-    eglSwapInterval(__eglDisplay, enable ? 1 : 0);
-    __vsync = enable;
-}
-
-void Platform::swapBuffers()
-{
-    if (__eglDisplay && __eglSurface)
-        eglSwapBuffers(__eglDisplay, __eglSurface);
-}
-
-void Platform::sleep(long ms)
-{
-    usleep(ms * 1000);
-}
-
-void Platform::setMultiSampling(bool enabled)
-{
-    if (enabled == __multiSampling)
-    {
-        return;
-    }
-
-    // TODO:
-    __multiSampling = enabled;
-}
-
-bool Platform::isMultiSampling()
-{
-    return __multiSampling;
-}
-
-void Platform::setMultiTouch(bool enabled)
-{
-    __multiTouch = enabled;
-}
-
-bool Platform::isMultiTouch()
-{
-    return __multiTouch;
-}
-
-bool Platform::hasAccelerometer()
-{
-    return true;
-}
-
-void Platform::getAccelerometerValues(float* pitch, float* roll)
-{
-    GP_ASSERT(pitch);
-    GP_ASSERT(roll);
-
-    switch(__orientationAngle)
-    {
-    // Landscape based device adjusting for landscape game mode
-    case 0:
-        if (pitch)
-            *pitch = __pitch;
-        if (roll)
-            *roll = -__roll;
-        break;
-    case 180:
-        if (pitch)
-            *pitch = -__pitch;
-        if (roll)
-            *roll = __roll;
-        break;
-
-    // Portrait based device adjusting for landscape game mode
-    case 90:
-        if (pitch)
-            *pitch = -__roll;
-        if (roll)
-            *roll = -__pitch;
-        break;
-
-    case  270:
-        if (pitch)
-            *pitch = __roll;
-        if (roll)
-            *roll = __pitch;
-        break;
-
-    default:
-        break;
-    }
-}
-
-void Platform::getSensorValues(float* accelX, float* accelY, float* accelZ, float* gyroX, float* gyroY, float* gyroZ)
-{
-	if (accelX)
-	{
-		*accelX = __accelRawX;
-	}
-
-	if (accelY)
-	{
-		*accelY = __accelRawY;
-	}
-
-	if (accelZ)
-	{
-		*accelZ = __accelRawZ;
-	}
-
-	if (gyroX)
-	{
-		*gyroX = __gyroRawX;
-	}
-
-	if (gyroY)
-	{
-		*gyroY = __gyroRawY;
-	}
-
-	if (gyroZ)
-	{
-		*gyroZ = __gyroRawZ;
-	}
-}
-
-void Platform::getArguments(int* argc, char*** argv)
-{
-    if (argc)
-        *argc = __argc;
-    if (argv)
-        *argv = __argv;
-}
-
-bool Platform::hasMouse()
-{
-    // not supported
-    return false;
-}
-
-void Platform::setMouseCaptured(bool captured)
-{
-    // not supported
-}
-
-bool Platform::isMouseCaptured()
-{
-    // not supported
-    return false;
-}
-
-void Platform::setCursorVisible(bool visible)
-{
-    // not supported
-}
-
-bool Platform::isCursorVisible()
-{
-    // not supported
-    return false;
-}
-
-void Platform::displayKeyboard(bool display)
-{
-    if (display)
-        virtualkeyboard_show();
-    else
-        virtualkeyboard_hide();
-}
-
-void Platform::shutdownInternal()
-{
-    Game::getInstance()->shutdown();
-}
-
-bool Platform::isGestureSupported(Gesture::GestureEvent evt)
-{
-    // All are supported no need to test the bitset
-    return true;
-}
-
-void Platform::registerGesture(Gesture::GestureEvent evt)
-{
-    switch(evt)
-    {
-    case Gesture::GESTURE_ANY_SUPPORTED:
-        __gestureEventsProcessed.set();
-        break;
-
-    case Gesture::GESTURE_SWIPE:
-    case Gesture::GESTURE_PINCH:
-    case Gesture::GESTURE_TAP:
-        __gestureEventsProcessed.set(evt);
-        break;
-
-    default:
-        break;
-    }
-}
-
-void Platform::unregisterGesture(Gesture::GestureEvent evt)
-{
-    switch(evt)
-    {
-    case Gesture::GESTURE_ANY_SUPPORTED:
-        __gestureEventsProcessed.reset();
-        break;
-
-    case Gesture::GESTURE_SWIPE:
-    case Gesture::GESTURE_PINCH:
-    case Gesture::GESTURE_TAP:
-        __gestureEventsProcessed.set(evt, 0);
-        break;
-
-    default:
-        break;
-    }
-}
-    
-bool Platform::isGestureRegistered(Gesture::GestureEvent evt)
-{
-    return __gestureEventsProcessed.test(evt);
-}
-
-bool Platform::launchURL(const char* url)
-{
-    if (url == NULL || *url == '\0')
-        return false;
-
-    return navigator_invoke(url, NULL) == BPS_SUCCESS;
-}
-
-}
-
-#endif
+#ifdef __QNX__
+
+#include "Base.h"
+#include "Platform.h"
+#include "FileSystem.h"
+#include "Game.h"
+#include "Form.h"
+#include "ScriptController.h"
+#include <unistd.h>
+#include <sys/keycodes.h>
+#include <screen/screen.h>
+#include <input/screen_helpers.h>
+#include <gestures/set.h>
+#include <gestures/swipe.h>
+#include <gestures/pinch.h>
+#include <gestures/tap.h>
+#include <bps/bps.h>
+#include <bps/event.h>
+#include <bps/screen.h>
+#include <bps/navigator.h>
+#include <bps/sensor.h>
+#include <bps/orientation.h>
+#include <bps/virtualkeyboard.h>
+
+#define TOUCH_COUNT_MAX     4
+
+using namespace std;
+
+int __argc = 0;
+char** __argv = 0;
+struct timespec __timespec;
+static double __timeStart;
+static double __timeAbsolute;
+static bool __vsync = WINDOW_VSYNC;
+static screen_context_t __screenContext;
+static screen_window_t __screenWindow;
+static screen_event_t __screenEvent;
+static int __screenWindowSize[2];
+static bool __screenFullscreen = false;
+static EGLDisplay __eglDisplay = EGL_NO_DISPLAY;
+static EGLContext __eglContext = EGL_NO_CONTEXT;
+static EGLSurface __eglSurface = EGL_NO_SURFACE;
+static EGLConfig __eglConfig = 0;
+static int __orientationAngle;
+static bool __multiTouch = false;
+static bool __multiSampling = false;
+static float __pitch;
+static float __roll;
+static float __accelRawX;
+static float __accelRawY;
+static float __accelRawZ;
+static float __gyroRawX;
+static float __gyroRawY;
+static float __gyroRawZ;
+static const char* __glExtensions;
+static struct gestures_set * __gestureSet;
+static bitset<3> __gestureEventsProcessed;
+static bool __gestureSwipeRecognized = false;
+PFNGLBINDVERTEXARRAYOESPROC glBindVertexArray = NULL;
+PFNGLDELETEVERTEXARRAYSOESPROC glDeleteVertexArrays = NULL;
+PFNGLGENVERTEXARRAYSOESPROC glGenVertexArrays = NULL;
+PFNGLISVERTEXARRAYOESPROC glIsVertexArray = NULL;
+
+namespace gameplay
+{
+
+// Gets the Keyboard::Key enumeration constant that corresponds to the given QNX key code.
+static Keyboard::Key getKey(int qnxKeycode)
+{
+    switch (qnxKeycode)
+    {
+    case KEYCODE_SYSREQ:
+        return Keyboard::KEY_SYSREQ;
+    case KEYCODE_BREAK:
+        return Keyboard::KEY_BREAK;
+    case KEYCODE_MENU:
+        return Keyboard::KEY_MENU;
+    case KEYCODE_KP_ENTER:
+        return Keyboard::KEY_KP_ENTER;
+    case KEYCODE_PAUSE:
+        return Keyboard::KEY_PAUSE;
+    case KEYCODE_SCROLL_LOCK:
+        return Keyboard::KEY_SCROLL_LOCK;
+    case KEYCODE_PRINT:
+        return Keyboard::KEY_PRINT;
+    case KEYCODE_ESCAPE:
+        return Keyboard::KEY_ESCAPE;
+    case KEYCODE_BACKSPACE:
+        return Keyboard::KEY_BACKSPACE;
+    case KEYCODE_BACK_TAB:
+        return Keyboard::KEY_BACK_TAB;
+    case KEYCODE_TAB:
+        return Keyboard::KEY_TAB;
+    case KEYCODE_RETURN:
+        return Keyboard::KEY_RETURN;
+    case KEYCODE_CAPS_LOCK:
+        return Keyboard::KEY_CAPS_LOCK;
+    case KEYCODE_LEFT_SHIFT:
+    case KEYCODE_RIGHT_SHIFT:
+        return Keyboard::KEY_SHIFT;
+    case KEYCODE_LEFT_CTRL:
+    case KEYCODE_RIGHT_CTRL:
+        return Keyboard::KEY_CTRL;
+    case KEYCODE_LEFT_ALT:
+    case KEYCODE_RIGHT_ALT:
+        return Keyboard::KEY_ALT;
+    case KEYCODE_LEFT_HYPER:
+    case KEYCODE_RIGHT_HYPER:
+        return Keyboard::KEY_HYPER;
+    case KEYCODE_INSERT:
+        return Keyboard::KEY_INSERT;
+    case KEYCODE_HOME:
+        return Keyboard::KEY_HOME;
+    case KEYCODE_PG_UP:
+        return Keyboard::KEY_PG_UP;
+    case KEYCODE_DELETE:
+        return Keyboard::KEY_DELETE;
+    case KEYCODE_END:
+        return Keyboard::KEY_END;
+    case KEYCODE_PG_DOWN:
+        return Keyboard::KEY_PG_DOWN;
+    case KEYCODE_LEFT:
+        return Keyboard::KEY_LEFT_ARROW;
+    case KEYCODE_RIGHT:
+        return Keyboard::KEY_RIGHT_ARROW;
+    case KEYCODE_UP:
+        return Keyboard::KEY_UP_ARROW;
+    case KEYCODE_DOWN:
+        return Keyboard::KEY_DOWN_ARROW;
+    case KEYCODE_NUM_LOCK:
+        return Keyboard::KEY_NUM_LOCK;
+    case KEYCODE_KP_PLUS:
+        return Keyboard::KEY_KP_PLUS;
+    case KEYCODE_KP_MINUS:
+        return Keyboard::KEY_KP_MINUS;
+    case KEYCODE_KP_MULTIPLY:
+        return Keyboard::KEY_KP_MULTIPLY;
+    case KEYCODE_KP_DIVIDE:
+        return Keyboard::KEY_KP_DIVIDE;
+    case KEYCODE_KP_HOME:
+        return Keyboard::KEY_KP_HOME;
+    case KEYCODE_KP_UP:
+        return Keyboard::KEY_KP_UP;
+    case KEYCODE_KP_PG_UP:
+        return Keyboard::KEY_KP_PG_UP;
+    case KEYCODE_KP_LEFT:
+        return Keyboard::KEY_KP_LEFT;
+    case KEYCODE_KP_FIVE:
+        return Keyboard::KEY_KP_FIVE;
+    case KEYCODE_KP_RIGHT:
+        return Keyboard::KEY_KP_RIGHT;
+    case KEYCODE_KP_END:
+        return Keyboard::KEY_KP_END;
+    case KEYCODE_KP_DOWN:
+        return Keyboard::KEY_KP_DOWN;
+    case KEYCODE_KP_PG_DOWN:
+        return Keyboard::KEY_KP_PG_DOWN;
+    case KEYCODE_KP_INSERT:
+        return Keyboard::KEY_KP_INSERT;
+    case KEYCODE_KP_DELETE:
+        return Keyboard::KEY_KP_DELETE;
+    case KEYCODE_F1:
+        return Keyboard::KEY_F1;
+    case KEYCODE_F2:
+        return Keyboard::KEY_F2;
+    case KEYCODE_F3:
+        return Keyboard::KEY_F3;
+    case KEYCODE_F4:
+        return Keyboard::KEY_F4;
+    case KEYCODE_F5:
+        return Keyboard::KEY_F5;
+    case KEYCODE_F6:
+        return Keyboard::KEY_F6;
+    case KEYCODE_F7:
+        return Keyboard::KEY_F7;
+    case KEYCODE_F8:
+        return Keyboard::KEY_F8;
+    case KEYCODE_F9:
+        return Keyboard::KEY_F9;
+    case KEYCODE_F10:
+        return Keyboard::KEY_F10;
+    case KEYCODE_F11:
+        return Keyboard::KEY_F11;
+    case KEYCODE_F12:
+        return Keyboard::KEY_F12;
+    case KEYCODE_SPACE:
+        return Keyboard::KEY_SPACE;
+    case KEYCODE_RIGHT_PAREN:
+        return Keyboard::KEY_RIGHT_PARENTHESIS;
+    case KEYCODE_ZERO:
+        return Keyboard::KEY_ZERO;
+    case KEYCODE_EXCLAM:
+        return Keyboard::KEY_EXCLAM;
+    case KEYCODE_ONE:
+        return Keyboard::KEY_ONE;
+    case KEYCODE_AT:
+        return Keyboard::KEY_AT;
+    case KEYCODE_TWO:
+        return Keyboard::KEY_TWO;
+    case KEYCODE_NUMBER:
+        return Keyboard::KEY_NUMBER;
+    case KEYCODE_THREE:
+        return Keyboard::KEY_THREE;
+    case KEYCODE_DOLLAR:
+        return Keyboard::KEY_DOLLAR;
+    case KEYCODE_FOUR:
+        return Keyboard::KEY_FOUR;
+    case KEYCODE_PERCENT:
+        return Keyboard::KEY_PERCENT;
+    case KEYCODE_FIVE:
+        return Keyboard::KEY_FIVE;
+    case KEYCODE_CIRCUMFLEX:
+        return Keyboard::KEY_CIRCUMFLEX;
+    case KEYCODE_SIX:
+        return Keyboard::KEY_SIX;
+    case KEYCODE_AMPERSAND:
+        return Keyboard::KEY_AMPERSAND;
+    case KEYCODE_SEVEN:
+        return Keyboard::KEY_SEVEN;
+    case KEYCODE_ASTERISK:
+        return Keyboard::KEY_ASTERISK;
+    case KEYCODE_EIGHT:
+        return Keyboard::KEY_EIGHT;
+    case KEYCODE_LEFT_PAREN:
+        return Keyboard::KEY_LEFT_PARENTHESIS;
+    case KEYCODE_NINE:
+        return Keyboard::KEY_NINE;
+    case KEYCODE_EQUAL:
+        return Keyboard::KEY_EQUAL;
+    case KEYCODE_PLUS:
+        return Keyboard::KEY_PLUS;
+    case KEYCODE_LESS_THAN:
+        return Keyboard::KEY_LESS_THAN;
+    case KEYCODE_COMMA:
+        return Keyboard::KEY_COMMA;
+    case KEYCODE_UNDERSCORE:
+        return Keyboard::KEY_UNDERSCORE;
+    case KEYCODE_MINUS:
+        return Keyboard::KEY_MINUS;
+    case KEYCODE_GREATER_THAN:
+        return Keyboard::KEY_GREATER_THAN;
+    case KEYCODE_PERIOD:
+        return Keyboard::KEY_PERIOD;
+    case KEYCODE_COLON:
+        return Keyboard::KEY_COLON;
+    case KEYCODE_SEMICOLON:
+        return Keyboard::KEY_SEMICOLON;
+    case KEYCODE_QUESTION:
+        return Keyboard::KEY_QUESTION;
+    case KEYCODE_SLASH:
+        return Keyboard::KEY_SLASH;
+    case KEYCODE_GRAVE:
+        return Keyboard::KEY_GRAVE;
+    case KEYCODE_TILDE:
+        return Keyboard::KEY_TILDE;
+    case KEYCODE_LEFT_BRACE:
+        return Keyboard::KEY_LEFT_BRACE;
+    case KEYCODE_LEFT_BRACKET:
+        return Keyboard::KEY_LEFT_BRACKET;
+    case KEYCODE_BAR:
+        return Keyboard::KEY_BAR;
+    case KEYCODE_BACK_SLASH:
+        return Keyboard::KEY_BACK_SLASH;
+    case KEYCODE_RIGHT_BRACE:
+        return Keyboard::KEY_RIGHT_BRACE;
+    case KEYCODE_RIGHT_BRACKET:
+        return Keyboard::KEY_RIGHT_BRACKET;
+    case KEYCODE_QUOTE:
+        return Keyboard::KEY_QUOTE;
+    case KEYCODE_APOSTROPHE:
+        return Keyboard::KEY_APOSTROPHE;
+    case 0x20AC:
+        return Keyboard::KEY_EURO;
+    case KEYCODE_POUND_SIGN:
+        return Keyboard::KEY_POUND;
+    case KEYCODE_YEN_SIGN:
+        return Keyboard::KEY_YEN;
+    case KEYCODE_MIDDLE_DOT:
+        return Keyboard::KEY_MIDDLE_DOT;
+    case KEYCODE_CAPITAL_A:
+        return Keyboard::KEY_CAPITAL_A;
+    case KEYCODE_A:
+        return Keyboard::KEY_A;
+    case KEYCODE_CAPITAL_B:
+        return Keyboard::KEY_CAPITAL_B;
+    case KEYCODE_B:
+        return Keyboard::KEY_B;
+    case KEYCODE_CAPITAL_C:
+        return Keyboard::KEY_CAPITAL_C;
+    case KEYCODE_C:
+        return Keyboard::KEY_C;
+    case KEYCODE_CAPITAL_D:
+        return Keyboard::KEY_CAPITAL_D;
+    case KEYCODE_D:
+        return Keyboard::KEY_D;
+    case KEYCODE_CAPITAL_E:
+        return Keyboard::KEY_CAPITAL_E;
+    case KEYCODE_E:
+        return Keyboard::KEY_E;
+    case KEYCODE_CAPITAL_F:
+        return Keyboard::KEY_CAPITAL_F;
+    case KEYCODE_F:
+        return Keyboard::KEY_F;
+    case KEYCODE_CAPITAL_G:
+        return Keyboard::KEY_CAPITAL_G;
+    case KEYCODE_G:
+        return Keyboard::KEY_G;
+    case KEYCODE_CAPITAL_H:
+        return Keyboard::KEY_CAPITAL_H;
+    case KEYCODE_H:
+        return Keyboard::KEY_H;
+    case KEYCODE_CAPITAL_I:
+        return Keyboard::KEY_CAPITAL_I;
+    case KEYCODE_I:
+        return Keyboard::KEY_I;
+    case KEYCODE_CAPITAL_J:
+        return Keyboard::KEY_CAPITAL_J;
+    case KEYCODE_J:
+        return Keyboard::KEY_J;
+    case KEYCODE_CAPITAL_K:
+        return Keyboard::KEY_CAPITAL_K;
+    case KEYCODE_K:
+        return Keyboard::KEY_K;
+    case KEYCODE_CAPITAL_L:
+        return Keyboard::KEY_CAPITAL_L;
+    case KEYCODE_L:
+        return Keyboard::KEY_L;
+    case KEYCODE_CAPITAL_M:
+        return Keyboard::KEY_CAPITAL_M;
+    case KEYCODE_M:
+        return Keyboard::KEY_M;
+    case KEYCODE_CAPITAL_N:
+        return Keyboard::KEY_CAPITAL_N;
+    case KEYCODE_N:
+        return Keyboard::KEY_N;
+    case KEYCODE_CAPITAL_O:
+        return Keyboard::KEY_CAPITAL_O;
+    case KEYCODE_O:
+        return Keyboard::KEY_O;
+    case KEYCODE_CAPITAL_P:
+        return Keyboard::KEY_CAPITAL_P;
+    case KEYCODE_P:
+        return Keyboard::KEY_P;
+    case KEYCODE_CAPITAL_Q:
+        return Keyboard::KEY_CAPITAL_Q;
+    case KEYCODE_Q:
+        return Keyboard::KEY_Q;
+    case KEYCODE_CAPITAL_R:
+        return Keyboard::KEY_CAPITAL_R;
+    case KEYCODE_R:
+        return Keyboard::KEY_R;
+    case KEYCODE_CAPITAL_S:
+        return Keyboard::KEY_CAPITAL_S;
+    case KEYCODE_S:
+        return Keyboard::KEY_S;
+    case KEYCODE_CAPITAL_T:
+        return Keyboard::KEY_CAPITAL_T;
+    case KEYCODE_T:
+        return Keyboard::KEY_T;
+    case KEYCODE_CAPITAL_U:
+        return Keyboard::KEY_CAPITAL_U;
+    case KEYCODE_U:
+        return Keyboard::KEY_U;
+    case KEYCODE_CAPITAL_V:
+        return Keyboard::KEY_CAPITAL_V;
+    case KEYCODE_V:
+        return Keyboard::KEY_V;
+    case KEYCODE_CAPITAL_W:
+        return Keyboard::KEY_CAPITAL_W;
+    case KEYCODE_W:
+        return Keyboard::KEY_W;
+    case KEYCODE_CAPITAL_X:
+        return Keyboard::KEY_CAPITAL_X;
+    case KEYCODE_X:
+        return Keyboard::KEY_X;
+    case KEYCODE_CAPITAL_Y:
+        return Keyboard::KEY_CAPITAL_Y;
+    case KEYCODE_Y:
+        return Keyboard::KEY_Y;
+    case KEYCODE_CAPITAL_Z:
+        return Keyboard::KEY_CAPITAL_Z;
+    case KEYCODE_Z:
+        return Keyboard::KEY_Z;
+    default:
+        return Keyboard::KEY_NONE;
+    }
+}
+
+/**
+ * Returns the unicode value from the given QNX key code value.
+ * Some non-printable characters also have corresponding unicode values, such as backspace.
+ *
+ * @param qnxKeyCode The keyboard key code.
+ *
+ * @return The unicode value or 0 if the keycode did not represent a unicode key.
+ */
+static int getUnicode(int qnxKeyCode)
+{
+    if (qnxKeyCode >= KEYCODE_PC_KEYS && qnxKeyCode <= UNICODE_PRIVATE_USE_AREA_LAST)
+    {
+        switch (qnxKeyCode)
+        {
+        case KEYCODE_BACKSPACE:
+            return 0x0008;
+        case KEYCODE_TAB:
+            return 0x0009;
+        case KEYCODE_KP_ENTER:
+        case KEYCODE_RETURN:
+            return 0x000A;
+        case KEYCODE_ESCAPE:
+            return 0x001B;
+        // Win32 doesn't consider delete to be a key char.
+        default:
+            return 0;
+        }
+    }
+    return qnxKeyCode;
+}
+
+extern void print(const char* format, ...)
+{
+    GP_ASSERT(format);
+    va_list argptr;
+    va_start(argptr, format);
+    vfprintf(stderr, format, argptr);
+    va_end(argptr);
+}
+
+EGLenum checkErrorEGL(const char* msg)
+{
+    GP_ASSERT(msg);
+    static const char* errmsg[] =
+    {
+        "EGL function failed",
+        "EGL is not initialized, or could not be initialized, for the specified display",
+        "EGL cannot access a requested resource",
+        "EGL failed to allocate resources for the requested operation",
+        "EGL fail to access an unrecognized attribute or attribute value was passed in an attribute list",
+        "EGLConfig argument does not name a valid EGLConfig",
+        "EGLContext argument does not name a valid EGLContext",
+        "EGL current surface of the calling thread is no longer valid",
+        "EGLDisplay argument does not name a valid EGLDisplay",
+        "EGL arguments are inconsistent",
+        "EGLNativePixmapType argument does not refer to a valid native pixmap",
+        "EGLNativeWindowType argument does not refer to a valid native window",
+        "EGL one or more argument values are invalid",
+        "EGLSurface argument does not name a valid surface configured for rendering",
+        "EGL power management event has occurred",
+    };
+    EGLenum error = eglGetError();
+    fprintf(stderr, "%s: %s\n", msg, errmsg[error - EGL_SUCCESS]);
+    return error;
+}
+
+void gesture_callback(gesture_base_t* gesture, mtouch_event_t* event, void* param, int async)
+{
+    switch (gesture->type)
+    {
+    case GESTURE_SWIPE:
+        {
+            if ( __gestureEventsProcessed.test(Gesture::GESTURE_SWIPE) )
+            {
+                gesture_swipe_t* swipe = (gesture_swipe_t*)gesture;
+                if (!__gestureSwipeRecognized)
+                {
+                    Platform::gestureSwipeEventInternal(swipe->coords.x, swipe->coords.y, swipe->direction);
+                    __gestureSwipeRecognized = true;
+                }
+
+            }
+            break;
+        }
+
+    case GESTURE_PINCH:
+        {
+            if ( __gestureEventsProcessed.test(Gesture::GESTURE_PINCH) )
+            {
+                gesture_pinch_t* pinch = (gesture_pinch_t*)gesture;
+                float dist_x = (float)pinch->last_distance.x - (float)pinch->distance.x;
+                float dist_y = (float)pinch->last_distance.y - (float)pinch->distance.y;
+                float scale = sqrt( (dist_x * dist_x) + (dist_y * dist_y) );
+                Game::getInstance()->gesturePinchEvent(pinch->centroid.x, pinch->centroid.y, scale);
+            }
+            break;
+        }
+
+    case GESTURE_TAP:
+        {
+            if ( __gestureEventsProcessed.test(Gesture::GESTURE_TAP) )
+            {
+                gesture_tap_t* tap = (gesture_tap_t*)gesture;
+                Platform::gestureTapEventInternal(tap->touch_coords.x, tap->touch_coords.y);
+            }
+            break;
+        }
+
+    default:
+        break;
+
+    }
+}
+
+#ifdef GP_USE_GAMEPAD
+
+static const char* __vendorStrings[] =
+{
+    "SteelSeries",
+    "Nintendo",
+};
+
+static const char* __productStrings[] =
+{
+    "FREE",
+    "Wii Remote",
+};
+
+static const int __VIDs[] = {
+    0x1038,
+    0x057e,
+};
+
+static const int __PIDs[] = {
+    0x1412,
+    0x0306,
+};
+
+static const unsigned int __knownGamepads = 2;
+
+void queryGamepad(GamepadHandle handle, int* buttonCount, int* joystickCount, int* productId, int* vendorId, char* productString, char* vendorString)
+{
+    char id[128];
+    screen_get_device_property_iv(handle, SCREEN_PROPERTY_BUTTON_COUNT, buttonCount);
+    screen_get_device_property_cv(handle, SCREEN_PROPERTY_ID_STRING, 128, id);
+    screen_get_device_property_cv(handle, SCREEN_PROPERTY_PRODUCT, 64, productString);
+    screen_get_device_property_cv(handle, SCREEN_PROPERTY_VENDOR, 64, vendorString);
+
+    // Check for the existence of analog sticks.
+    int analogs[3];
+    if (!screen_get_device_property_iv(handle, SCREEN_PROPERTY_ANALOG0, analogs))
+    {
+    	++(*joystickCount);
+    }
+
+    if (!screen_get_device_property_iv(handle, SCREEN_PROPERTY_ANALOG1, analogs))
+    {
+    	++(*joystickCount);
+    }
+
+    // ID string format: A-BBBB-CCCC-D.D
+    // A is the device's index
+    // BBBB is the device's Vendor ID (in hexadecimal)
+    // CCCC is the device's Product ID (also in hexadecimal)
+    // D.D is the device's version number
+    char* token = strtok(id, "-");
+    token = strtok(NULL, "-");
+    if (token)
+    {
+	    *vendorId = strtol(token, NULL, 16);
+    }
+
+    token = strtok(NULL, "-");
+    if (token)
+    {
+        *productId = strtol(token, NULL, 16);
+    }
+
+    // For gamepads unknown to BB10,
+    // check VID and PID against gamepads known to gameplay.
+    if (strlen(productString) == 0 || strlen(vendorString) == 0)
+    {
+        for (unsigned int i = 0; i < __knownGamepads; ++i)
+        {
+            if (__VIDs[i] == *vendorId && __PIDs[i] == *productId)
+            {
+            	strcpy(vendorString, __vendorStrings[i]);
+                strcpy(productString, __productStrings[i]);
+            }
+        }
+    }
+}
+
+void Platform::pollGamepadState(Gamepad* gamepad)
+{
+	unsigned int buttons;
+    screen_get_device_property_iv(gamepad->_handle, SCREEN_PROPERTY_BUTTONS, (int*)&buttons);
+	gamepad->setButtons(buttons);
+
+    unsigned int i;
+    for (i = 0; i < gamepad->_joystickCount; ++i)
+    {
+        GP_ASSERT(i < 2);
+
+        int analog[3];
+        switch (i)
+        {
+        case 0:
+            screen_get_device_property_iv(gamepad->_handle, SCREEN_PROPERTY_ANALOG0, analog);
+            break;
+        case 1:
+            screen_get_device_property_iv(gamepad->_handle, SCREEN_PROPERTY_ANALOG1, analog);
+            break;
+        }
+
+        // So far we've tested two gamepads with analog sticks on BlackBerry:
+        // the SteelSeries FREE, and the iControlPad.
+        // Both return values between -128 and +127, with the y axis starting from
+        // the top at -128.
+        // 1 / 128 == 0.0078125f
+        // 1 / 127 == 0.0078740157480315f
+        float x = (float)analog[0];
+        float y = -(float)analog[1];
+        x *= (x < 0) ? 0.0078125f : 0.0078740157480315f;
+        y *= (y > 0) ? 0.0078125f : 0.0078740157480315f;
+
+		gamepad->setJoystickValue(i, x, y);
+    }
+
+    for (i = 0; i < gamepad->_triggerCount; ++i)
+    {
+        GP_ASSERT(i < 2);
+
+        int analog[3];
+        switch (i)
+        {
+        case 0:
+            screen_get_device_property_iv(gamepad->_handle, SCREEN_PROPERTY_ANALOG0, analog);
+            break;
+        case 1:
+            screen_get_device_property_iv(gamepad->_handle, SCREEN_PROPERTY_ANALOG1, analog);
+            break;
+        }
+
+        float value = (float)analog[2] * 0.0078125f;
+		gamepad->setTriggerValue(i, value);
+    }
+}
+#else
+void Platform::pollGamepadState(Gamepad* gamepad)
+{
+}
+#endif
+
+Platform::Platform(Game* game)
+    : _game(game)
+{
+}
+
+Platform::~Platform()
+{
+    if (__eglDisplay != EGL_NO_DISPLAY)
+    {
+        eglMakeCurrent(__eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+    }
+
+    if (__eglSurface != EGL_NO_SURFACE)
+    {
+        eglDestroySurface(__eglDisplay, __eglSurface);
+        __eglSurface = EGL_NO_SURFACE;
+    }
+
+    if (__eglContext != EGL_NO_CONTEXT)
+    {
+        eglDestroyContext(__eglDisplay, __eglContext);
+        __eglContext = EGL_NO_CONTEXT;
+    }
+
+    if (__eglDisplay != EGL_NO_DISPLAY)
+    {
+        eglTerminate(__eglDisplay);
+        __eglDisplay = EGL_NO_DISPLAY;
+    }
+
+    if (__screenWindow)
+    {
+        screen_destroy_window(__screenWindow);
+        __screenWindow = NULL;
+    }
+
+    if (__screenEvent)
+    {
+        screen_destroy_event(__screenEvent);
+        __screenEvent = NULL;
+    }
+
+    if (__screenContext)
+    {
+        screen_destroy_context(__screenContext);
+        __screenContext = NULL;
+    }
+}
+
+Platform* Platform::create(Game* game)
+{
+    FileSystem::setResourcePath("./app/native/");
+    Platform* platform = new Platform(game);
+
+    // Query game config
+    int samples = 0;
+    Properties* config = Game::getInstance()->getConfig()->getNamespace("window", true);
+    if (config)
+    {
+        samples = std::max(config->getInt("samples"), 0);
+    }
+
+    __gestureSet = gestures_set_alloc();
+    swipe_gesture_alloc(NULL, gesture_callback, __gestureSet);
+    pinch_gesture_alloc(NULL, gesture_callback, __gestureSet);
+    tap_gesture_alloc(NULL, gesture_callback, __gestureSet);
+
+    bps_initialize();
+
+    // Initialize navigator and orientation
+    static const int SENSOR_RATE = 25000; // (25000 microseconds = 40 Hz)
+    sensor_set_rate(SENSOR_TYPE_AZIMUTH_PITCH_ROLL, SENSOR_RATE);
+    sensor_set_rate(SENSOR_TYPE_ACCELEROMETER, SENSOR_RATE);
+    sensor_set_rate(SENSOR_TYPE_GYROSCOPE, SENSOR_RATE);
+    sensor_set_skip_duplicates(SENSOR_TYPE_AZIMUTH_PITCH_ROLL, true);
+    sensor_set_skip_duplicates(SENSOR_TYPE_ACCELEROMETER, true);
+    sensor_set_skip_duplicates(SENSOR_TYPE_GYROSCOPE, true);
+    sensor_request_events(SENSOR_TYPE_AZIMUTH_PITCH_ROLL);
+    sensor_request_events(SENSOR_TYPE_ACCELEROMETER);
+    sensor_request_events(SENSOR_TYPE_GYROSCOPE);
+    navigator_request_events(0);
+    navigator_rotation_lock(true);
+    __orientationAngle = atoi(getenv("ORIENTATION"));
+
+    int rc = 0;
+    int screenFormat = SCREEN_FORMAT_RGBA8888;
+#ifdef __X86__
+    int screenUsage = SCREEN_USAGE_OPENGL_ES2;
+#else
+    int screenUsage = SCREEN_USAGE_DISPLAY|SCREEN_USAGE_OPENGL_ES2; // Physical device copy directly into physical display
+#endif
+    int screenSwapInterval = WINDOW_VSYNC ? 1 : 0;
+    int screenTransparency = SCREEN_TRANSPARENCY_NONE;
+
+    char *width_str = getenv("WIDTH");
+    char *height_str = getenv("HEIGHT");
+
+    // Hard-coded to (0,0).
+    int windowPosition[] =
+    {
+        0, 0
+    };
+
+    EGLint eglConfigCount;
+
+    // Hard-coded to 32-bit/OpenGL ES 2.0.
+    // NOTE: EGL_SAMPLE_BUFFERS and EGL_SAMPLES MUST remain at the beginning of the attribute list
+    // since they are expected to be at indices 0-3 in config fallback code later.
+    EGLint eglConfigAttrs[] =
+    {
+        EGL_SAMPLE_BUFFERS,     samples > 0 ? 1 : 0,
+        EGL_SAMPLES,            samples,
+        EGL_RED_SIZE,           8,
+        EGL_GREEN_SIZE,         8,
+        EGL_BLUE_SIZE,          8,
+        EGL_ALPHA_SIZE,         8,
+        EGL_DEPTH_SIZE,         24,
+        EGL_STENCIL_SIZE,       8,
+        EGL_SURFACE_TYPE,       EGL_WINDOW_BIT,
+        EGL_RENDERABLE_TYPE,    EGL_OPENGL_ES2_BIT,
+        EGL_NONE
+    };
+    __multiSampling = samples > 0;
+
+    const EGLint eglContextAttrs[] =
+    {
+        EGL_CONTEXT_CLIENT_VERSION,    2,
+        EGL_NONE
+    };
+
+    const EGLint eglSurfaceAttrs[] =
+    {
+        EGL_RENDER_BUFFER,    EGL_BACK_BUFFER,
+        EGL_NONE
+    };
+
+    // Create the screen context.
+    rc = screen_create_context(&__screenContext, 0);
+    if (rc)
+    {
+        perror("screen_create_context");
+        goto error;
+    }
+
+    // Create the screen window.
+    rc = screen_create_window(&__screenWindow, __screenContext);
+    if (rc)
+    {
+        perror("screen_create_window");
+        goto error;
+    }
+
+    // Window group
+	rc = screen_create_window_group(__screenWindow, "windowgroup");
+	if (rc)
+	{
+		perror("screen_create_window_group failed");
+		goto error;
+	}
+
+    // Set/get any window properties.
+    rc = screen_set_window_property_iv(__screenWindow, SCREEN_PROPERTY_FORMAT, &screenFormat);
+    if (rc)
+    {
+        perror("screen_set_window_property_iv(SCREEN_PROPERTY_FORMAT)");
+        goto error;
+    }
+
+    rc = screen_set_window_property_iv(__screenWindow, SCREEN_PROPERTY_USAGE, &screenUsage);
+    if (rc)
+    {
+        perror("screen_set_window_property_iv(SCREEN_PROPERTY_USAGE)");
+        goto error;
+    }
+
+    if (width_str && height_str)
+    {
+        __screenWindowSize[0] = atoi(width_str);
+        __screenWindowSize[1] = atoi(height_str);
+    }
+    else
+    {
+        screen_display_t screen_display;
+        rc = screen_get_window_property_pv(__screenWindow, SCREEN_PROPERTY_DISPLAY, (void **)&screen_display);
+        if (rc)
+        {
+            perror("screen_get_window_property_pv(SCREEN_PROPERTY_DISPLAY)");
+            goto error;
+        }
+
+        screen_display_mode_t screen_mode;
+        rc = screen_get_display_property_pv(screen_display, SCREEN_PROPERTY_MODE, (void**)&screen_mode);
+        if (rc)
+        {
+            perror("screen_get_display_property_pv(SCREEN_PROPERTY_MODE)");
+            goto error;
+        }
+
+        int size[2];
+        rc = screen_get_window_property_iv(__screenWindow, SCREEN_PROPERTY_BUFFER_SIZE, size);
+        if (rc)
+        {
+            perror("screen_get_window_property_iv(SCREEN_PROPERTY_BUFFER_SIZE)");
+            goto error;
+        }
+
+        __screenWindowSize[0] = size[0];
+        __screenWindowSize[1] = size[1];
+
+        if ((__orientationAngle == 0) || (__orientationAngle == 180))
+        {
+            if (((screen_mode.width > screen_mode.height) && (size[0] < size[1])) ||
+                ((screen_mode.width < screen_mode.height) && (size[0] > size[1])))
+            {
+                __screenWindowSize[1] = size[0];
+                __screenWindowSize[0] = size[1];
+            }
+        }
+        else if ((__orientationAngle == 90) || (__orientationAngle == 270))
+        {
+            if (((screen_mode.width > screen_mode.height) && (size[0] > size[1])) ||
+                ((screen_mode.width < screen_mode.height) && (size[0] < size[1])))
+            {
+                __screenWindowSize[1] = size[0];
+                __screenWindowSize[0] = size[1];
+            }
+        }
+        else
+        {
+            perror("Navigator returned an unexpected orientation angle.");
+            goto error;
+        }
+
+
+        rc = screen_set_window_property_iv(__screenWindow, SCREEN_PROPERTY_ROTATION, &__orientationAngle);
+        if (rc)
+        {
+            perror("screen_set_window_property_iv(SCREEN_PROPERTY_ROTATION)");
+            goto error;
+        }
+    }
+
+    rc = screen_set_window_property_iv(__screenWindow, SCREEN_PROPERTY_BUFFER_SIZE, __screenWindowSize);
+    if (rc)
+    {
+        perror("screen_set_window_property_iv(SCREEN_PROPERTY_BUFFER_SIZE)");
+        goto error;
+    }
+
+    if (windowPosition[0] != 0 || windowPosition[1] != 0)
+    {
+        rc = screen_set_window_property_iv(__screenWindow, SCREEN_PROPERTY_POSITION, windowPosition);
+        if (rc)
+        {
+            perror("screen_set_window_property_iv(SCREEN_PROPERTY_POSITION)");
+            goto error;
+        }
+    }
+
+    rc = screen_set_window_property_iv(__screenWindow, SCREEN_PROPERTY_TRANSPARENCY, &screenTransparency);
+    if (rc)
+    {
+        perror("screen_set_window_property_iv(SCREEN_PROPERTY_TRANSPARENCY)");
+        goto error;
+    }
+
+    // Double buffered.
+    rc = screen_create_window_buffers(__screenWindow, 2);
+    if (rc)
+    {
+        perror("screen_create_window_buffers");
+        goto error;
+    }
+
+    // Create screen event object.
+    rc = screen_create_event(&__screenEvent);
+    if (rc)
+    {
+        perror("screen_create_event");
+        goto error;
+    }
+
+    // Request screen events.
+    screen_request_events(__screenContext);
+
+    // Get the EGL display and initialize.
+    __eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+    if (__eglDisplay == EGL_NO_DISPLAY)
+    {
+        perror("eglGetDisplay");
+        goto error;
+    }
+    if (eglInitialize(__eglDisplay, NULL, NULL) != EGL_TRUE)
+    {
+        perror("eglInitialize");
+        goto error;
+    }
+
+    if (eglChooseConfig(__eglDisplay, eglConfigAttrs, &__eglConfig, 1, &eglConfigCount) != EGL_TRUE || eglConfigCount == 0)
+    {
+        bool success = false;
+        while (samples)
+        {
+            // Try lowering the MSAA sample count until we find a supported config
+            GP_WARN("Failed to find a valid EGL configuration with EGL samples=%d. Trying samples=%d instead.", samples, samples/2);
+            samples /= 2;
+            eglConfigAttrs[1] = samples > 0 ? 1 : 0;
+            eglConfigAttrs[3] = samples;
+            if (eglChooseConfig(__eglDisplay, eglConfigAttrs, &__eglConfig, 1, &eglConfigCount) == EGL_TRUE && eglConfigCount > 0)
+            {
+                success = true;
+                break;
+            }
+        }
+
+        __multiSampling = samples > 0;
+
+        if (!success)
+        {
+            checkErrorEGL("eglChooseConfig");
+            goto error;
+        }
+    }
+
+    __eglContext = eglCreateContext(__eglDisplay, __eglConfig, EGL_NO_CONTEXT, eglContextAttrs);
+    if (__eglContext == EGL_NO_CONTEXT)
+    {
+        checkErrorEGL("eglCreateContext");
+        goto error;
+    }
+
+    __eglSurface = eglCreateWindowSurface(__eglDisplay, __eglConfig, __screenWindow, eglSurfaceAttrs);
+    if (__eglSurface == EGL_NO_SURFACE)
+    {
+        checkErrorEGL("eglCreateWindowSurface");
+        goto error;
+    }
+
+    if (eglMakeCurrent(__eglDisplay, __eglSurface, __eglSurface, __eglContext) != EGL_TRUE)
+    {
+        checkErrorEGL("eglMakeCurrent");
+        goto error;
+    }
+
+    // Set vsync.
+    eglSwapInterval(__eglDisplay, screenSwapInterval);
+
+    // Initialize OpenGL ES extensions.
+    __glExtensions = (const char*)glGetString(GL_EXTENSIONS);
+
+    if (strstr(__glExtensions, "GL_OES_vertex_array_object") || strstr(__glExtensions, "GL_ARB_vertex_array_object"))
+    {
+        glBindVertexArray = (PFNGLBINDVERTEXARRAYOESPROC)eglGetProcAddress("glBindVertexArrayOES");
+        glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSOESPROC)eglGetProcAddress("glDeleteVertexArraysOES");
+        glGenVertexArrays = (PFNGLGENVERTEXARRAYSOESPROC)eglGetProcAddress("glGenVertexArraysOES");
+        glIsVertexArray = (PFNGLISVERTEXARRAYOESPROC)eglGetProcAddress("glIsVertexArrayOES");
+    }
+
+ #ifdef GP_USE_GAMEPAD
+
+    screen_device_t* screenDevs;
+
+    // Discover initial gamepad devices.
+    int count;
+    screen_get_context_property_iv(__screenContext, SCREEN_PROPERTY_DEVICE_COUNT, &count);
+    screenDevs = (screen_device_t*)calloc(count, sizeof(screen_device_t));
+    screen_get_context_property_pv(__screenContext, SCREEN_PROPERTY_DEVICES, (void**)screenDevs);
+
+	for (int i = 0; i < count; i++)
+    {
+	    int type;
+        screen_get_device_property_iv(screenDevs[i], SCREEN_PROPERTY_TYPE, &type);
+
+        if (type == SCREEN_EVENT_GAMEPAD || type == SCREEN_EVENT_JOYSTICK)
+        {
+            int buttonCount = 0;
+            int joystickCount = 0;
+            int productId;
+            int vendorId;
+            char productString[64];
+            char vendorString[64];
+            queryGamepad(screenDevs[i], &buttonCount, &joystickCount, &productId, &vendorId, productString, vendorString);
+            Platform::gamepadEventConnectedInternal(screenDevs[i], buttonCount, joystickCount, 0, vendorId, productId, vendorString, productString);
+        }
+	}
+	free(screenDevs);
+#endif
+
+    return platform;
+
+error:
+
+    return NULL;
+}
+
+/**
+ * Convert the timespec into milliseconds.
+ */
+double timespec2millis(struct timespec *a)
+{
+    GP_ASSERT(a);
+    return (1000.0 * a->tv_sec) + (0.000001 * a->tv_nsec);
+}
+
+/**
+ * Fires a mouse event or a touch event on the game.
+ * If the mouse event is not consumed, a touch event is fired instead.
+ *
+ * @param mouseEvent The mouse event to fire.
+ * @param touchEvent The touch event to fire.
+ * @param x The x position of the touch in pixels.
+ * @param y The y position of the touch in pixels.
+ */
+void mouseOrTouchEvent(Mouse::MouseEvent mouseEvent, Touch::TouchEvent touchEvent, int x, int y)
+{
+    if (!gameplay::Platform::mouseEventInternal(mouseEvent, x, y, 0))
+    {
+        Platform::touchEventInternal(touchEvent, x, y, 0, true);
+    }
+}
+
+int Platform::enterMessagePump()
+{
+    GP_ASSERT(_game);
+
+    int rc;
+    int eventType;
+    int flags;
+    int value;
+    int position[2];
+    int domain;
+    mtouch_event_t touchEvent;
+    bool suspended = false;
+
+    // Get the initial time.
+    clock_gettime(CLOCK_REALTIME, &__timespec);
+    __timeStart = timespec2millis(&__timespec);
+    __timeAbsolute = 0L;
+
+    _game->run();
+
+    // Message loop.
+    while (true)
+    {
+        bps_event_t* event = NULL;
+
+        while (true)
+        {
+            rc = bps_get_event(&event, 1);
+            GP_ASSERT(rc == BPS_SUCCESS);
+
+            if (event == NULL)
+                break;
+
+#ifdef GP_USE_SOCIAL
+            // if the social controller needs to deal with the event do that here
+            if (Game::getInstance()->getSocialController()->handleEvent(event))
+            	break;
+#endif
+
+            domain = bps_event_get_domain(event);
+
+            if (domain == screen_get_domain())
+            {
+                __screenEvent = screen_event_get_event(event);
+                screen_get_event_property_iv(__screenEvent, SCREEN_PROPERTY_TYPE, &eventType);
+                switch (eventType)
+                {
+                    case SCREEN_EVENT_MTOUCH_TOUCH:
+                    {
+                        screen_get_mtouch_event(__screenEvent, &touchEvent, 0);
+                        if (__gestureEventsProcessed.any())
+                            rc = gestures_set_process_event(__gestureSet, &touchEvent, NULL);
+
+                        if ( !rc && (__multiTouch || touchEvent.contact_id == 0) )
+                        {
+                            gameplay::Platform::touchEventInternal(Touch::TOUCH_PRESS, touchEvent.x, touchEvent.y, touchEvent.contact_id);
+                        }
+                        break;
+                    }
+
+                    case SCREEN_EVENT_MTOUCH_RELEASE:
+                    {
+                        screen_get_mtouch_event(__screenEvent, &touchEvent, 0);
+                        if (__gestureEventsProcessed.any())
+                            rc = gestures_set_process_event(__gestureSet, &touchEvent, NULL);
+
+                        if ( !rc && (__multiTouch || touchEvent.contact_id == 0) )
+                        {
+                            gameplay::Platform::touchEventInternal(Touch::TOUCH_RELEASE, touchEvent.x, touchEvent.y, touchEvent.contact_id);
+                        }
+                        if (__gestureSwipeRecognized)
+                        {
+                            __gestureSwipeRecognized = false;
+                        }
+                        break;
+                    }
+
+                    case SCREEN_EVENT_MTOUCH_MOVE:
+                    {
+                        screen_get_mtouch_event(__screenEvent, &touchEvent, 0);
+                        if (__gestureEventsProcessed.any())
+                            rc = gestures_set_process_event(__gestureSet, &touchEvent, NULL);
+
+                        if ( !rc && (__multiTouch || touchEvent.contact_id == 0) )
+                        {
+                            gameplay::Platform::touchEventInternal(Touch::TOUCH_MOVE, touchEvent.x, touchEvent.y, touchEvent.contact_id);
+                        }
+                        break;
+                    }
+
+                    case SCREEN_EVENT_POINTER:
+                    {
+                        static int mouse_pressed = 0;
+                        int buttons;
+                        int wheel;
+                        // A move event will be fired unless a button state changed.
+                        bool move = true;
+                        bool left_move = false;
+                        // This is a mouse move event, it is applicable to a device with a usb mouse or simulator.
+                        screen_get_event_property_iv(__screenEvent, SCREEN_PROPERTY_BUTTONS, &buttons);
+                        screen_get_event_property_iv(__screenEvent, SCREEN_PROPERTY_SOURCE_POSITION, position);
+                        screen_get_event_property_iv(__screenEvent, SCREEN_PROPERTY_MOUSE_WHEEL, &wheel);
+
+                        // Handle left mouse. Interpret as touch if the left mouse event is not consumed.
+                        if (buttons & SCREEN_LEFT_MOUSE_BUTTON)
+                        {
+                            if (mouse_pressed & SCREEN_LEFT_MOUSE_BUTTON)
+                            {
+                                left_move = true;
+                            }
+                            else
+                            {
+                                move = false;
+                                mouse_pressed |= SCREEN_LEFT_MOUSE_BUTTON;
+                                mouseOrTouchEvent(Mouse::MOUSE_PRESS_LEFT_BUTTON, Touch::TOUCH_PRESS, position[0], position[1]);
+                            }
+                        }
+                        else if (mouse_pressed & SCREEN_LEFT_MOUSE_BUTTON)
+                        {
+                            move = false;
+                            mouse_pressed &= ~SCREEN_LEFT_MOUSE_BUTTON;
+                            mouseOrTouchEvent(Mouse::MOUSE_RELEASE_LEFT_BUTTON, Touch::TOUCH_RELEASE, position[0], position[1]);
+                        }
+
+                        // Handle right mouse.
+                        if (buttons & SCREEN_RIGHT_MOUSE_BUTTON)
+                        {
+                            if ((mouse_pressed & SCREEN_RIGHT_MOUSE_BUTTON) == 0)
+                            {
+                                move = false;
+                                mouse_pressed |= SCREEN_RIGHT_MOUSE_BUTTON;
+                                gameplay::Platform::mouseEventInternal(Mouse::MOUSE_PRESS_RIGHT_BUTTON, position[0], position[1], 0);
+                            }
+                        }
+                        else if (mouse_pressed & SCREEN_RIGHT_MOUSE_BUTTON)
+                        {
+                            move = false;
+                            mouse_pressed &= ~SCREEN_RIGHT_MOUSE_BUTTON;
+                            gameplay::Platform::mouseEventInternal(Mouse::MOUSE_RELEASE_RIGHT_BUTTON, position[0], position[1], 0);
+                        }
+
+                        // Handle middle mouse.
+                        if (buttons & SCREEN_MIDDLE_MOUSE_BUTTON)
+                        {
+                            if ((mouse_pressed & SCREEN_MIDDLE_MOUSE_BUTTON) == 0)
+                            {
+                                move = false;
+                                mouse_pressed |= SCREEN_MIDDLE_MOUSE_BUTTON;
+                                gameplay::Platform::mouseEventInternal(Mouse::MOUSE_PRESS_MIDDLE_BUTTON, position[0], position[1], 0);
+                            }
+                        }
+                        else if (mouse_pressed & SCREEN_MIDDLE_MOUSE_BUTTON)
+                        {
+                            move = false;
+                            mouse_pressed &= ~SCREEN_MIDDLE_MOUSE_BUTTON;
+                            gameplay::Platform::mouseEventInternal(Mouse::MOUSE_RELEASE_MIDDLE_BUTTON, position[0], position[1], 0);
+                        }
+
+                        // Fire a move event if none of the buttons changed.
+                        if (left_move)
+                        {
+                            mouseOrTouchEvent(Mouse::MOUSE_MOVE, Touch::TOUCH_MOVE, position[0], position[1]);
+                        }
+                        else if (move)
+                        {
+                            gameplay::Platform::mouseEventInternal(Mouse::MOUSE_MOVE, position[0], position[1], 0);
+                        }
+
+                        // Handle mouse wheel events.
+                        if (wheel)
+                        {
+                            gameplay::Platform::mouseEventInternal(Mouse::MOUSE_WHEEL, position[0], position[1], -wheel);
+                        }
+                        break;
+                    }
+
+                    case SCREEN_EVENT_KEYBOARD:
+                    {
+                        screen_get_event_property_iv(__screenEvent, SCREEN_PROPERTY_KEY_FLAGS, &flags);
+                        screen_get_event_property_iv(__screenEvent, SCREEN_PROPERTY_KEY_SYM, &value);
+                        gameplay::Keyboard::KeyEvent evt = (flags & KEY_DOWN) ? gameplay::Keyboard::KEY_PRESS :  gameplay::Keyboard::KEY_RELEASE;
+                        // Suppress key repeats.
+                        if ((flags & KEY_REPEAT) == 0)
+                        {
+                            keyEventInternal(evt, getKey(value));
+                            if (evt == gameplay::Keyboard::KEY_PRESS && (flags & KEY_SYM_VALID))
+                            {
+                                int unicode = getUnicode(value);
+                                if (unicode)
+                                    keyEventInternal(gameplay::Keyboard::KEY_CHAR, unicode);
+                            }
+                        }
+                        break;
+                    }
+#ifdef GP_USE_GAMEPAD
+                    case SCREEN_EVENT_DEVICE:
+                    {
+                        // A device was attached or removed.
+                        screen_device_t device;
+                        int attached;
+
+                        screen_get_event_property_pv(__screenEvent, SCREEN_PROPERTY_DEVICE, (void**)&device);
+                        screen_get_event_property_iv(__screenEvent, SCREEN_PROPERTY_ATTACHED, &attached);
+
+                        if (attached)
+                        {
+                            int type;
+                            screen_get_device_property_iv(device, SCREEN_PROPERTY_TYPE, &type);
+                            if (type == SCREEN_EVENT_GAMEPAD || type == SCREEN_EVENT_JOYSTICK)
+                            {
+                                int buttonCount = 0;
+                                int joystickCount = 0;
+                                int productId;
+                                int vendorId;
+                                char productString[64];
+                                char vendorString[64];
+                                queryGamepad(device, &buttonCount, &joystickCount, &productId, &vendorId, productString, vendorString);
+                                Platform::gamepadEventConnectedInternal(device, buttonCount, joystickCount, 0, vendorId, productId, vendorString, productString);
+                            }
+                        }
+                        else
+                        {
+                            Platform::gamepadEventDisconnectedInternal(device);
+                        }
+
+                        break;
+                    }
+#endif
+                    default:
+                        break;
+                }
+            }
+            else if (domain == navigator_get_domain())
+            {
+                switch (bps_event_get_code(event))
+                {
+                case NAVIGATOR_WINDOW_STATE:
+                {
+                    navigator_window_state_t state = navigator_event_get_window_state(event);
+                    switch (state)
+                    {
+                    case NAVIGATOR_WINDOW_FULLSCREEN:
+                        if (!__screenFullscreen)
+                            __screenFullscreen = true;
+                        _game->resume();
+                        suspended = false;
+                        break;
+                    case NAVIGATOR_WINDOW_THUMBNAIL:
+                    case NAVIGATOR_WINDOW_INVISIBLE:
+                        if (__screenFullscreen && !suspended)
+                        {
+                            _game->pause();
+                            suspended = true;
+                        }
+                        break;
+                    }
+                    break;
+                }
+                case NAVIGATOR_EXIT:
+                	// Call Game::shutdown directly, instead of Game::exit.
+                	// We need to do this since exit() queues a request to shutdown for the
+                	// next frame, which will never get executed because we are suspended.
+                    _game->shutdown();
+                    break;
+                }
+            }
+            else if (domain == sensor_get_domain())
+            {
+                if (bps_event_get_code(event) == SENSOR_AZIMUTH_PITCH_ROLL_READING)
+                {
+                    float azimuth;
+                    sensor_event_get_apr(event, &azimuth, &__pitch, &__roll);
+                }
+                else if (bps_event_get_code(event) == SENSOR_ACCELEROMETER_READING)
+                {
+                    sensor_event_get_xyz(event, &__accelRawX, &__accelRawY, &__accelRawZ);
+                }
+                else if (bps_event_get_code(event) == SENSOR_GYROSCOPE_READING)
+                {
+                    sensor_event_get_xyz(event, &__gyroRawX, &__gyroRawY, &__gyroRawZ);
+                }
+            }
+        }
+
+        // If we are done, then exit.
+        if (_game->getState() == Game::UNINITIALIZED)
+            break;
+
+        if (!suspended)
+        {
+            _game->frame();
+
+            // Post the new frame to the display.
+            // Note that there are a couple cases where eglSwapBuffers could fail
+            // with an error code that requires a certain level of re-initialization:
+            //
+            // 1) EGL_BAD_NATIVE_WINDOW - Called when the surface we're currently using
+            //    is invalidated. This would require us to destroy our EGL surface,
+            //    close our OpenKODE window, and start again.
+            //
+            // 2) EGL_CONTEXT_LOST - Power management event that led to our EGL context
+            //    being lost. Requires us to re-create and re-initalize our EGL context
+            //    and all OpenGL ES state.
+            //
+            // For now, if we get these, we'll simply exit.
+            rc = eglSwapBuffers(__eglDisplay, __eglSurface);
+            if (rc != EGL_TRUE)
+            {
+                _game->shutdown();
+                perror("eglSwapBuffers");
+                break;
+            }
+        }
+    }
+
+    screen_stop_events(__screenContext);
+    bps_shutdown();
+    screen_destroy_context(__screenContext);
+
+    return 0;
+}
+    
+void Platform::signalShutdown() 
+{
+    // nothing to do  
+}
+
+bool Platform::canExit()
+{
+    return true;
+}
+
+unsigned int Platform::getDisplayWidth()
+{
+    return __screenWindowSize[0];
+}
+
+unsigned int Platform::getDisplayHeight()
+{
+    return __screenWindowSize[1];
+}
+
+double Platform::getAbsoluteTime()
+{
+    clock_gettime(CLOCK_REALTIME, &__timespec);
+    double now = timespec2millis(&__timespec);
+    __timeAbsolute = now - __timeStart;
+
+    return __timeAbsolute;
+}
+
+void Platform::setAbsoluteTime(double time)
+{
+    __timeAbsolute = time;
+}
+
+bool Platform::isVsync()
+{
+    return __vsync;
+}
+
+void Platform::setVsync(bool enable)
+{
+    eglSwapInterval(__eglDisplay, enable ? 1 : 0);
+    __vsync = enable;
+}
+
+void Platform::swapBuffers()
+{
+    if (__eglDisplay && __eglSurface)
+        eglSwapBuffers(__eglDisplay, __eglSurface);
+}
+
+void Platform::sleep(long ms)
+{
+    usleep(ms * 1000);
+}
+
+void Platform::setMultiSampling(bool enabled)
+{
+    if (enabled == __multiSampling)
+    {
+        return;
+    }
+
+    // TODO:
+    __multiSampling = enabled;
+}
+
+bool Platform::isMultiSampling()
+{
+    return __multiSampling;
+}
+
+void Platform::setMultiTouch(bool enabled)
+{
+    __multiTouch = enabled;
+}
+
+bool Platform::isMultiTouch()
+{
+    return __multiTouch;
+}
+
+bool Platform::hasAccelerometer()
+{
+    return true;
+}
+
+void Platform::getAccelerometerValues(float* pitch, float* roll)
+{
+    GP_ASSERT(pitch);
+    GP_ASSERT(roll);
+
+    switch(__orientationAngle)
+    {
+    // Landscape based device adjusting for landscape game mode
+    case 0:
+        if (pitch)
+            *pitch = __pitch;
+        if (roll)
+            *roll = -__roll;
+        break;
+    case 180:
+        if (pitch)
+            *pitch = -__pitch;
+        if (roll)
+            *roll = __roll;
+        break;
+
+    // Portrait based device adjusting for landscape game mode
+    case 90:
+        if (pitch)
+            *pitch = -__roll;
+        if (roll)
+            *roll = -__pitch;
+        break;
+
+    case  270:
+        if (pitch)
+            *pitch = __roll;
+        if (roll)
+            *roll = __pitch;
+        break;
+
+    default:
+        break;
+    }
+}
+
+void Platform::getSensorValues(float* accelX, float* accelY, float* accelZ, float* gyroX, float* gyroY, float* gyroZ)
+{
+	if (accelX)
+	{
+		*accelX = __accelRawX;
+	}
+
+	if (accelY)
+	{
+		*accelY = __accelRawY;
+	}
+
+	if (accelZ)
+	{
+		*accelZ = __accelRawZ;
+	}
+
+	if (gyroX)
+	{
+		*gyroX = __gyroRawX;
+	}
+
+	if (gyroY)
+	{
+		*gyroY = __gyroRawY;
+	}
+
+	if (gyroZ)
+	{
+		*gyroZ = __gyroRawZ;
+	}
+}
+
+void Platform::getArguments(int* argc, char*** argv)
+{
+    if (argc)
+        *argc = __argc;
+    if (argv)
+        *argv = __argv;
+}
+
+bool Platform::hasMouse()
+{
+    // not supported
+    return false;
+}
+
+void Platform::setMouseCaptured(bool captured)
+{
+    // not supported
+}
+
+bool Platform::isMouseCaptured()
+{
+    // not supported
+    return false;
+}
+
+void Platform::setCursorVisible(bool visible)
+{
+    // not supported
+}
+
+bool Platform::isCursorVisible()
+{
+    // not supported
+    return false;
+}
+
+void Platform::displayKeyboard(bool display)
+{
+    if (display)
+        virtualkeyboard_show();
+    else
+        virtualkeyboard_hide();
+}
+
+void Platform::shutdownInternal()
+{
+    Game::getInstance()->shutdown();
+}
+
+bool Platform::isGestureSupported(Gesture::GestureEvent evt)
+{
+    // All are supported no need to test the bitset
+    return true;
+}
+
+void Platform::registerGesture(Gesture::GestureEvent evt)
+{
+    switch(evt)
+    {
+    case Gesture::GESTURE_ANY_SUPPORTED:
+        __gestureEventsProcessed.set();
+        break;
+
+    case Gesture::GESTURE_SWIPE:
+    case Gesture::GESTURE_PINCH:
+    case Gesture::GESTURE_TAP:
+        __gestureEventsProcessed.set(evt);
+        break;
+
+    default:
+        break;
+    }
+}
+
+void Platform::unregisterGesture(Gesture::GestureEvent evt)
+{
+    switch(evt)
+    {
+    case Gesture::GESTURE_ANY_SUPPORTED:
+        __gestureEventsProcessed.reset();
+        break;
+
+    case Gesture::GESTURE_SWIPE:
+    case Gesture::GESTURE_PINCH:
+    case Gesture::GESTURE_TAP:
+        __gestureEventsProcessed.set(evt, 0);
+        break;
+
+    default:
+        break;
+    }
+}
+    
+bool Platform::isGestureRegistered(Gesture::GestureEvent evt)
+{
+    return __gestureEventsProcessed.test(evt);
+}
+
+bool Platform::launchURL(const char* url)
+{
+    if (url == NULL || *url == '\0')
+        return false;
+
+    return navigator_invoke(url, NULL) == BPS_SUCCESS;
+}
+
+std::string Platform::displayFileDialog(size_t mode, const char* title, const char* filterDescription, const char* filterExtension)
+{
+    return "";
+}
+
+}
+
+#endif

+ 902 - 894
gameplay/src/PlatformLinux.cpp

@@ -530,1134 +530,1142 @@ static int getUnicode(gameplay::Keyboard::Key key)
             return 0;
     }
 }
-#include <linux/joystick.h> //included here so i avoid the naming conflict between KEY_* defined in input.h and the ones defined in gameplay/Keyboard.h 
+
+// Included here to avoid the naming conflict between KEY_* defined in input.h and the ones defined in gameplay/Keyboard.h 
+#include <linux/joystick.h> 
+
 namespace gameplay
 {
-    extern void print(const char* format, ...)
-    {
-        GP_ASSERT(format);
-        va_list argptr;
-        va_start(argptr, format);
-        vfprintf(stderr, format, argptr);
-        va_end(argptr);
-    }
 
-    Platform::Platform(Game* game) : _game(game)
-    {
-    }
+extern void print(const char* format, ...)
+{
+    GP_ASSERT(format);
+    va_list argptr;
+    va_start(argptr, format);
+    vfprintf(stderr, format, argptr);
+    va_end(argptr);
+}
 
-    Platform::~Platform()
-    {
-    }
+Platform::Platform(Game* game) : _game(game)
+{
+}
 
-    Platform* Platform::create(Game* game)
-    {
+Platform::~Platform()
+{
+}
 
-        GP_ASSERT(game);
+Platform* Platform::create(Game* game)
+{
 
-        FileSystem::setResourcePath("./");
-        Platform* platform = new Platform(game);
+    GP_ASSERT(game);
 
-        // Get the display and initialize
-        __display = XOpenDisplay(NULL);
-        if (__display == NULL)
-        {
-            perror("XOpenDisplay");
-            return NULL;
-        }
+    FileSystem::setResourcePath("./");
+    Platform* platform = new Platform(game);
+
+    // Get the display and initialize
+    __display = XOpenDisplay(NULL);
+    if (__display == NULL)
+    {
+        perror("XOpenDisplay");
+        return NULL;
+    }
 
-        // Get the window configuration values
-        const char *title = NULL;
-        int __x = 0, __y = 0, __width = 1280, __height = 800, __samples = 0;
-        bool fullscreen = false;
-        if (game->getConfig())
+    // Get the window configuration values
+    const char *title = NULL;
+    int __x = 0, __y = 0, __width = 1280, __height = 800, __samples = 0;
+    bool fullscreen = false;
+    if (game->getConfig())
+    {
+        Properties* config = game->getConfig()->getNamespace("window", true);
+        if (config)
         {
-            Properties* config = game->getConfig()->getNamespace("window", true);
-            if (config)
+            // Read window title.
+            title = config->getString("title");
+
+            // Read window rect.
+            int x = config->getInt("x");
+            int y = config->getInt("y");
+            int width = config->getInt("width");
+            int height = config->getInt("height");
+            int samples = config->getInt("samples");
+            fullscreen = config->getBool("fullscreen");
+
+            if (fullscreen && width == 0 && height == 0)
             {
-                // Read window title.
-                title = config->getString("title");
-
-                // Read window rect.
-                int x = config->getInt("x");
-                int y = config->getInt("y");
-                int width = config->getInt("width");
-                int height = config->getInt("height");
-                int samples = config->getInt("samples");
-                fullscreen = config->getBool("fullscreen");
-
-                if (fullscreen && width == 0 && height == 0)
-                {
-                    // Use the screen resolution if fullscreen is true but width and height were not set in the config
-                    int screen_num = DefaultScreen(__display);
-                    width = DisplayWidth(__display, screen_num);
-                    height = DisplayHeight(__display, screen_num);
-                }
-                if (x != 0) __x = x;
-                if (y != 0) __y = y;
-                if (width != 0) __width = width;
-                if (height != 0) __height = height;
-                if (samples != 0) __samples = samples;
+                // Use the screen resolution if fullscreen is true but width and height were not set in the config
+                int screen_num = DefaultScreen(__display);
+                width = DisplayWidth(__display, screen_num);
+                height = DisplayHeight(__display, screen_num);
             }
+            if (x != 0) __x = x;
+            if (y != 0) __y = y;
+            if (width != 0) __width = width;
+            if (height != 0) __height = height;
+            if (samples != 0) __samples = samples;
         }
+    }
 
-        // GLX version
-        GLint majorGLX, minorGLX = 0;
-        glXQueryVersion(__display, &majorGLX, &minorGLX);
-        if (majorGLX == 1 && minorGLX < 2)
-        {
-            perror("GLX 1.2 or greater is required.");
-            XCloseDisplay(__display);
-            return NULL;
-        }
-        else
-        {
-            printf( "GLX version: %d.%d\n", majorGLX , minorGLX);
-        }
+    // GLX version
+    GLint majorGLX, minorGLX = 0;
+    glXQueryVersion(__display, &majorGLX, &minorGLX);
+    if (majorGLX == 1 && minorGLX < 2)
+    {
+        perror("GLX 1.2 or greater is required.");
+        XCloseDisplay(__display);
+        return NULL;
+    }
+    else
+    {
+        printf( "GLX version: %d.%d\n", majorGLX , minorGLX);
+    }
 
-        // Get the GLX Functions
-        glXCreateContextAttribsARB = (GLXContext(*)(Display* dpy, GLXFBConfig config, GLXContext share_context, Bool direct,  const int *attrib_list))glXGetProcAddressARB((GLubyte*)"glXCreateContextAttribsARB");
-        glXChooseFBConfig = (GLXFBConfig*(*)(Display *dpy, int screen, const int *attrib_list, int *nelements))glXGetProcAddressARB((GLubyte*)"glXChooseFBConfig");
-        glXGetVisualFromFBConfig = (XVisualInfo*(*)(Display *dpy, GLXFBConfig config))glXGetProcAddressARB((GLubyte*)"glXGetVisualFromFBConfig");
-        glXGetFBConfigAttrib = (int(*)(Display *dpy, GLXFBConfig config, int attribute, int *value))glXGetProcAddressARB((GLubyte*)"glXGetFBConfigAttrib");
-        glXSwapIntervalEXT = (void(*)(Display* dpy, GLXDrawable drawable, int interval))glXGetProcAddressARB((GLubyte*)"glXSwapIntervalEXT");
-        glXSwapIntervalMESA = (int(*)(unsigned int interval))glXGetProcAddressARB((GLubyte*)"glXSwapIntervalMESA");
+    // Get the GLX Functions
+    glXCreateContextAttribsARB = (GLXContext(*)(Display* dpy, GLXFBConfig config, GLXContext share_context, Bool direct,  const int *attrib_list))glXGetProcAddressARB((GLubyte*)"glXCreateContextAttribsARB");
+    glXChooseFBConfig = (GLXFBConfig*(*)(Display *dpy, int screen, const int *attrib_list, int *nelements))glXGetProcAddressARB((GLubyte*)"glXChooseFBConfig");
+    glXGetVisualFromFBConfig = (XVisualInfo*(*)(Display *dpy, GLXFBConfig config))glXGetProcAddressARB((GLubyte*)"glXGetVisualFromFBConfig");
+    glXGetFBConfigAttrib = (int(*)(Display *dpy, GLXFBConfig config, int attribute, int *value))glXGetProcAddressARB((GLubyte*)"glXGetFBConfigAttrib");
+    glXSwapIntervalEXT = (void(*)(Display* dpy, GLXDrawable drawable, int interval))glXGetProcAddressARB((GLubyte*)"glXSwapIntervalEXT");
+    glXSwapIntervalMESA = (int(*)(unsigned int interval))glXGetProcAddressARB((GLubyte*)"glXSwapIntervalMESA");
 
-        // Get the configs
-        int configAttribs[] = 
-        {
-            GLX_RENDER_TYPE,    GLX_RGBA_BIT,
-            GLX_DRAWABLE_TYPE,  GLX_WINDOW_BIT,
-            GLX_X_RENDERABLE,   True,
-            GLX_DEPTH_SIZE,     24,
-            GLX_STENCIL_SIZE,   8,
-            GLX_RED_SIZE,       8,
-            GLX_GREEN_SIZE,     8,
-            GLX_BLUE_SIZE,      8,
-            GLX_DOUBLEBUFFER,   True,
-            GLX_SAMPLE_BUFFERS, __samples > 0 ? 1 : 0,
-            GLX_SAMPLES,        __samples,
-            0
-        };
-        __multiSampling = __samples > 0;
-
-        GLXFBConfig* configs;
-        int configCount = 0;
-        configs = glXChooseFBConfig(__display, DefaultScreen(__display), configAttribs, &configCount);
-        if ( configCount == 0 || configs == 0 )
-        {
-            perror( "glXChooseFBConfig" );
-            return NULL;
-        }
+    // Get the configs
+    int configAttribs[] = 
+    {
+        GLX_RENDER_TYPE,    GLX_RGBA_BIT,
+        GLX_DRAWABLE_TYPE,  GLX_WINDOW_BIT,
+        GLX_X_RENDERABLE,   True,
+        GLX_DEPTH_SIZE,     24,
+        GLX_STENCIL_SIZE,   8,
+        GLX_RED_SIZE,       8,
+        GLX_GREEN_SIZE,     8,
+        GLX_BLUE_SIZE,      8,
+        GLX_DOUBLEBUFFER,   True,
+        GLX_SAMPLE_BUFFERS, __samples > 0 ? 1 : 0,
+        GLX_SAMPLES,        __samples,
+        0
+    };
+    __multiSampling = __samples > 0;
 
-        // Create the windows
-        XVisualInfo* visualInfo;
-        visualInfo = glXGetVisualFromFBConfig(__display, configs[0]);
-
-        XSetWindowAttributes winAttribs;
-        long eventMask;
-        eventMask = ExposureMask | VisibilityChangeMask | StructureNotifyMask |
-            KeyPressMask | KeyReleaseMask | PointerMotionMask |
-            ButtonPressMask | ButtonReleaseMask |
-            EnterWindowMask | LeaveWindowMask;
-        winAttribs.event_mask = eventMask;
-        winAttribs.border_pixel = 0;
-        winAttribs.bit_gravity = StaticGravity;
-        winAttribs.colormap = XCreateColormap(__display, RootWindow(__display, visualInfo->screen), visualInfo->visual, AllocNone);
-
-        GLint winMask;
-        winMask = CWBorderPixel | CWBitGravity | CWEventMask| CWColormap;
-
-        __window = XCreateWindow(__display, DefaultRootWindow(__display), __x, __y, __width, __height, 0,
-                visualInfo->depth, InputOutput, visualInfo->visual, winMask,
-                &winAttribs);
-
-        // Tell the window manager that it should send the delete window notification through ClientMessage
-        __atomWmDeleteWindow = XInternAtom(__display, "WM_DELETE_WINDOW", False);
-        XSetWMProtocols(__display, __window, &__atomWmDeleteWindow, 1);
-
-        XMapWindow(__display, __window);
-
-        // Send fullscreen atom message to the window; most window managers respect WM_STATE messages
-        // Note: fullscreen mode will use native desktop resolution and won't care about width/height specified
-        if (fullscreen)
-        {
-            XEvent xev;
-            Atom atomWm_state = XInternAtom(__display, "_NET_WM_STATE", False);
-            Atom atomFullscreen = XInternAtom(__display, "_NET_WM_STATE_FULLSCREEN", False);
-
-            memset(&xev, 0, sizeof(xev));
-            xev.type = ClientMessage;
-            xev.xclient.window = __window;
-            xev.xclient.message_type = atomWm_state;
-            xev.xclient.format = 32;
-            xev.xclient.data.l[0] = 1;
-            xev.xclient.data.l[1] = atomFullscreen;
-            xev.xclient.data.l[2] = 0;
-
-            XSendEvent(__display, DefaultRootWindow(__display), false, SubstructureNotifyMask | SubstructureRedirectMask, &xev);
-        }
+    GLXFBConfig* configs;
+    int configCount = 0;
+    configs = glXChooseFBConfig(__display, DefaultScreen(__display), configAttribs, &configCount);
+    if ( configCount == 0 || configs == 0 )
+    {
+        perror( "glXChooseFBConfig" );
+        return NULL;
+    }
 
-        XStoreName(__display, __window, title ? title : "");
+    // Create the windows
+    XVisualInfo* visualInfo;
+    visualInfo = glXGetVisualFromFBConfig(__display, configs[0]);
+
+    XSetWindowAttributes winAttribs;
+    long eventMask;
+    eventMask = ExposureMask | VisibilityChangeMask | StructureNotifyMask |
+        KeyPressMask | KeyReleaseMask | PointerMotionMask |
+        ButtonPressMask | ButtonReleaseMask |
+        EnterWindowMask | LeaveWindowMask;
+    winAttribs.event_mask = eventMask;
+    winAttribs.border_pixel = 0;
+    winAttribs.bit_gravity = StaticGravity;
+    winAttribs.colormap = XCreateColormap(__display, RootWindow(__display, visualInfo->screen), visualInfo->visual, AllocNone);
+
+    GLint winMask;
+    winMask = CWBorderPixel | CWBitGravity | CWEventMask| CWColormap;
+
+    __window = XCreateWindow(__display, DefaultRootWindow(__display), __x, __y, __width, __height, 0,
+            visualInfo->depth, InputOutput, visualInfo->visual, winMask,
+            &winAttribs);
+
+    // Tell the window manager that it should send the delete window notification through ClientMessage
+    __atomWmDeleteWindow = XInternAtom(__display, "WM_DELETE_WINDOW", False);
+    XSetWMProtocols(__display, __window, &__atomWmDeleteWindow, 1);
+
+    XMapWindow(__display, __window);
+
+    // Send fullscreen atom message to the window; most window managers respect WM_STATE messages
+    // Note: fullscreen mode will use native desktop resolution and won't care about width/height specified
+    if (fullscreen)
+    {
+        XEvent xev;
+        Atom atomWm_state = XInternAtom(__display, "_NET_WM_STATE", False);
+        Atom atomFullscreen = XInternAtom(__display, "_NET_WM_STATE_FULLSCREEN", False);
+
+        memset(&xev, 0, sizeof(xev));
+        xev.type = ClientMessage;
+        xev.xclient.window = __window;
+        xev.xclient.message_type = atomWm_state;
+        xev.xclient.format = 32;
+        xev.xclient.data.l[0] = 1;
+        xev.xclient.data.l[1] = atomFullscreen;
+        xev.xclient.data.l[2] = 0;
+
+        XSendEvent(__display, DefaultRootWindow(__display), false, SubstructureNotifyMask | SubstructureRedirectMask, &xev);
+    }
 
-        __context = glXCreateContext(__display, visualInfo, NULL, True);
-        if (!__context)
-        {
-            perror("glXCreateContext");
-            return NULL;
-        }
-        glXMakeCurrent(__display, __window, __context);
+    XStoreName(__display, __window, title ? title : "");
 
-        // Use OpenGL 2.x with GLEW
-        glewExperimental = GL_TRUE;
-        GLenum glewStatus = glewInit();
-        if (glewStatus != GLEW_OK)
-        {
-            perror("glewInit");
-            return NULL;
-        }
+    __context = glXCreateContext(__display, visualInfo, NULL, True);
+    if (!__context)
+    {
+        perror("glXCreateContext");
+        return NULL;
+    }
+    glXMakeCurrent(__display, __window, __context);
+
+    // Use OpenGL 2.x with GLEW
+    glewExperimental = GL_TRUE;
+    GLenum glewStatus = glewInit();
+    if (glewStatus != GLEW_OK)
+    {
+        perror("glewInit");
+        return NULL;
+    }
 
-        // GL Version
-        int versionGL[2] = {-1, -1};
-        glGetIntegerv(GL_MAJOR_VERSION, versionGL);
-        glGetIntegerv(GL_MINOR_VERSION, versionGL + 1);
-        printf("GL version: %d.%d\n", versionGL[0], versionGL[1]);
+    // GL Version
+    int versionGL[2] = {-1, -1};
+    glGetIntegerv(GL_MAJOR_VERSION, versionGL);
+    glGetIntegerv(GL_MINOR_VERSION, versionGL + 1);
+    printf("GL version: %d.%d\n", versionGL[0], versionGL[1]);
 
-        // TODO: Get this workings
-        if (glXSwapIntervalEXT)
-            glXSwapIntervalEXT(__display, __window, __vsync ? 1 : 0);
-        else if(glXSwapIntervalMESA)
-            glXSwapIntervalMESA(__vsync ? 1 : 0);
+    // TODO: Get this workings
+    if (glXSwapIntervalEXT)
+        glXSwapIntervalEXT(__display, __window, __vsync ? 1 : 0);
+    else if(glXSwapIntervalMESA)
+        glXSwapIntervalMESA(__vsync ? 1 : 0);
 
-        return platform;
-    }
+    return platform;
+}
 
-    void cleanupX11()
+void cleanupX11()
+{
+    if (__display)
     {
-        if (__display)
-        {
-            glXMakeCurrent(__display, None, NULL);
+        glXMakeCurrent(__display, None, NULL);
 
-            if (__context)
-                glXDestroyContext(__display, __context);
-            if (__window)
-                XDestroyWindow(__display, __window);
+        if (__context)
+            glXDestroyContext(__display, __context);
+        if (__window)
+            XDestroyWindow(__display, __window);
 
-            XCloseDisplay(__display);
-        }
+        XCloseDisplay(__display);
     }
+}
 
-    double timespec2millis(struct timespec *a)
-    {
-        GP_ASSERT(a);
-        return (1000.0 * a->tv_sec) + (0.000001 * a->tv_nsec);
+double timespec2millis(struct timespec *a)
+{
+    GP_ASSERT(a);
+    return (1000.0 * a->tv_sec) + (0.000001 * a->tv_nsec);
+}
+
+void updateWindowSize()
+{
+    GP_ASSERT(__display);
+    GP_ASSERT(__window);
+    XWindowAttributes windowAttrs;
+    XGetWindowAttributes(__display, __window, &windowAttrs);
+    __windowSize[0] = windowAttrs.width;
+    __windowSize[1] = windowAttrs.height;
+}
+
+
+// Will need to be dynamic, also should be handled in Gamepad class
+static const GamepadInfoEntry gamepadLookupTable[] = 
+{
+    {0x0,0x0,"GENERIC XBOX360",2,6,20,2, 
+                                            (GamepadJoystickAxisInfo[]) {
+                                                                    {0,0,GP_AXIS_IS_XAXIS,0,0,2240,NEG_TO_POS},
+                                                                    {1,0,GP_AXIS_IS_NEG,0,0,2240,NEG_TO_POS},
+                                                                    {2,1,GP_AXIS_IS_XAXIS,0,0,2240,NEG_TO_POS},
+                                                                    {3,1,GP_AXIS_IS_NEG,0,0,2240,NEG_TO_POS},
+                                                                    {4,2,GP_AXIS_IS_TRIGGER,0,0,2240,ZERO_TO_POS},
+                                                                    {5,2,GP_AXIS_IS_TRIGGER,1,0,2240,ZERO_TO_POS},
+                                                                    {-1,0,0,0,0,0,NEG_TO_POS}
+                                                                },
+                                            (long[]) {
+                                                                        -1,    
+                                                                        -1,  
+                                                                        -1,  
+                                                                        -1, 
+                                                                        -1, 
+                                                                        Gamepad::BUTTON_UP,
+                                                                        Gamepad::BUTTON_DOWN,
+                                                                        Gamepad::BUTTON_LEFT,
+                                                                        Gamepad::BUTTON_RIGHT,
+                                                                        Gamepad::BUTTON_MENU2,
+                                                                        Gamepad::BUTTON_MENU1,
+                                                                        Gamepad::BUTTON_L3,
+                                                                        Gamepad::BUTTON_R3,
+                                                                        Gamepad::BUTTON_L1,
+                                                                        Gamepad::BUTTON_R1,
+                                                                        Gamepad::BUTTON_MENU3,
+                                                                        Gamepad::BUTTON_A,
+                                                                        Gamepad::BUTTON_B,
+                                                                        Gamepad::BUTTON_X,
+                                                                        Gamepad::BUTTON_Y
+                                                                        }
+    },
+    {0x79,0x6,"DragonRise Inc. Generic USB Joystick",2,7,12,0, 
+                                            (GamepadJoystickAxisInfo[]) {
+                                                                    {0,1, GP_AXIS_IS_XAXIS,0,0,2240,NEG_TO_POS},
+                                                                    {1,1,GP_AXIS_IS_NEG,0,0,2240,NEG_TO_POS},
+                                                                    {2,0,GP_AXIS_SKIP,0,0,2240,NEG_TO_POS},
+                                                                    {3,0,GP_AXIS_IS_XAXIS,0,0,2240,NEG_TO_POS},
+                                                                    {4,0,GP_AXIS_IS_NEG,0,0,2240,NEG_TO_POS},
+                                                                    {5,2,GP_AXIS_IS_DPAD, Gamepad::BUTTON_RIGHT, Gamepad::BUTTON_LEFT,2240,NEG_TO_POS},
+                                                                    {6,2,GP_AXIS_IS_DPAD, Gamepad::BUTTON_DOWN, Gamepad::BUTTON_UP,2240,NEG_TO_POS},
+                                                                    {-1,0,0,0,0,0,NEG_TO_POS}
+                                                                },
+                                            (long[]) {
+                                                                        Gamepad::BUTTON_Y,    
+                                                                        Gamepad::BUTTON_B,  
+                                                                        Gamepad::BUTTON_A,  
+                                                                        Gamepad::BUTTON_X, 
+                                                                        Gamepad::BUTTON_L1, 
+                                                                        Gamepad::BUTTON_R1, 
+                                                                        Gamepad::BUTTON_L2,    
+                                                                        Gamepad::BUTTON_R2,   
+                                                                        Gamepad::BUTTON_MENU1,   
+                                                                        Gamepad::BUTTON_MENU2,   
+                                                                        Gamepad::BUTTON_L3,
+                                                                        Gamepad::BUTTON_R3,
+                                                                        }
+    },
+    {0x54c,0x268,"Sony Corp. Batoh Device / PlayStation 3 Controller",2,27,19,2, 
+                                            (GamepadJoystickAxisInfo[]) {
+                                                                    {0,0,GP_AXIS_IS_XAXIS,0,0,2240,NEG_TO_POS},
+                                                                    {1,0,GP_AXIS_IS_NEG,0,0,2240,NEG_TO_POS},
+                                                                    {2,1,GP_AXIS_IS_XAXIS,0,0,2240,NEG_TO_POS},
+                                                                    {3,1,GP_AXIS_IS_NEG,0,0,2240,NEG_TO_POS},
+                                                                    {12,1,GP_AXIS_IS_TRIGGER,0,0,2240,ZERO_TO_POS},
+                                                                    {13,2,GP_AXIS_IS_TRIGGER,1,0,2240,ZERO_TO_POS},
+                                                                    {-1,0,0,0,0,0,NEG_TO_POS}
+                                                                },
+                                            (long[]) {
+                                                                        Gamepad::BUTTON_MENU1,    
+                                                                        Gamepad::BUTTON_L3,  
+                                                                        Gamepad::BUTTON_R3,  
+                                                                        Gamepad::BUTTON_MENU2, 
+                                                                        Gamepad::BUTTON_UP, 
+                                                                        Gamepad::BUTTON_RIGHT, 
+                                                                        Gamepad::BUTTON_DOWN,    
+                                                                        Gamepad::BUTTON_LEFT,   
+                                                                        Gamepad::BUTTON_L2,  //Use Trigger Instead of BUTTON_L2? or both should be called
+                                                                        Gamepad::BUTTON_R2,  //Use Trigger Instead of BUTTON_R2? or both should be called                                                                        
+                                                                        Gamepad::BUTTON_L1,
+                                                                        Gamepad::BUTTON_R1,
+                                                                        Gamepad::BUTTON_Y,    
+                                                                        Gamepad::BUTTON_B,  
+                                                                        Gamepad::BUTTON_A,  
+                                                                        Gamepad::BUTTON_X, 
+                                                                        Gamepad::BUTTON_MENU3, 
+                                                                        -1,
+                                                                        -1
+                                                                        }
     }
+};
 
-    void updateWindowSize()
+bool isGamepadDevRegistered(dev_t devId)
+{
+    for(list<ConnectedGamepadDevInfo>::iterator it = __connectedGamepads.begin(); it != __connectedGamepads.end();++it)
     {
-        GP_ASSERT(__display);
-        GP_ASSERT(__window);
-        XWindowAttributes windowAttrs;
-        XGetWindowAttributes(__display, __window, &windowAttrs);
-        __windowSize[0] = windowAttrs.width;
-        __windowSize[1] = windowAttrs.height;
+        if(devId == (*it).deviceId) return true;
     }
+    return false;
+}
 
+void closeGamepad(const ConnectedGamepadDevInfo& gamepadDevInfo)
+{
+    ::close(gamepadDevInfo.fd);
+}
 
-    //Will need to be dynamic, also should be handled in Gamepad class
-    static const GamepadInfoEntry gamepadLookupTable[] = 
-    {
-        {0x0,0x0,"GENERIC XBOX360",2,6,20,2, 
-                                             (GamepadJoystickAxisInfo[]) {
-                                                                     {0,0,GP_AXIS_IS_XAXIS,0,0,2240,NEG_TO_POS},
-                                                                     {1,0,GP_AXIS_IS_NEG,0,0,2240,NEG_TO_POS},
-                                                                     {2,1,GP_AXIS_IS_XAXIS,0,0,2240,NEG_TO_POS},
-                                                                     {3,1,GP_AXIS_IS_NEG,0,0,2240,NEG_TO_POS},
-                                                                     {4,2,GP_AXIS_IS_TRIGGER,0,0,2240,ZERO_TO_POS},
-                                                                     {5,2,GP_AXIS_IS_TRIGGER,1,0,2240,ZERO_TO_POS},
-                                                                     {-1,0,0,0,0,0,NEG_TO_POS}
-                                                                 },
-                                             (long[]) {
-                                                                          -1,    
-                                                                          -1,  
-                                                                          -1,  
-                                                                          -1, 
-                                                                          -1, 
-                                                                          Gamepad::BUTTON_UP,
-                                                                          Gamepad::BUTTON_DOWN,
-                                                                          Gamepad::BUTTON_LEFT,
-                                                                          Gamepad::BUTTON_RIGHT,
-                                                                          Gamepad::BUTTON_MENU2,
-                                                                          Gamepad::BUTTON_MENU1,
-                                                                          Gamepad::BUTTON_L3,
-                                                                          Gamepad::BUTTON_R3,
-                                                                          Gamepad::BUTTON_L1,
-                                                                          Gamepad::BUTTON_R1,
-                                                                          Gamepad::BUTTON_MENU3,
-                                                                          Gamepad::BUTTON_A,
-                                                                          Gamepad::BUTTON_B,
-                                                                          Gamepad::BUTTON_X,
-                                                                          Gamepad::BUTTON_Y
-                                                                         }
-        },
-        {0x79,0x6,"DragonRise Inc. Generic USB Joystick",2,7,12,0, 
-                                             (GamepadJoystickAxisInfo[]) {
-                                                                     {0,1, GP_AXIS_IS_XAXIS,0,0,2240,NEG_TO_POS},
-                                                                     {1,1,GP_AXIS_IS_NEG,0,0,2240,NEG_TO_POS},
-                                                                     {2,0,GP_AXIS_SKIP,0,0,2240,NEG_TO_POS},
-                                                                     {3,0,GP_AXIS_IS_XAXIS,0,0,2240,NEG_TO_POS},
-                                                                     {4,0,GP_AXIS_IS_NEG,0,0,2240,NEG_TO_POS},
-                                                                     {5,2,GP_AXIS_IS_DPAD, Gamepad::BUTTON_RIGHT, Gamepad::BUTTON_LEFT,2240,NEG_TO_POS},
-                                                                     {6,2,GP_AXIS_IS_DPAD, Gamepad::BUTTON_DOWN, Gamepad::BUTTON_UP,2240,NEG_TO_POS},
-                                                                     {-1,0,0,0,0,0,NEG_TO_POS}
-                                                                 },
-                                             (long[]) {
-                                                                          Gamepad::BUTTON_Y,    
-                                                                          Gamepad::BUTTON_B,  
-                                                                          Gamepad::BUTTON_A,  
-                                                                          Gamepad::BUTTON_X, 
-                                                                          Gamepad::BUTTON_L1, 
-                                                                          Gamepad::BUTTON_R1, 
-                                                                          Gamepad::BUTTON_L2,    
-                                                                          Gamepad::BUTTON_R2,   
-                                                                          Gamepad::BUTTON_MENU1,   
-                                                                          Gamepad::BUTTON_MENU2,   
-                                                                          Gamepad::BUTTON_L3,
-                                                                          Gamepad::BUTTON_R3,
-                                                                         }
-        },
-        {0x54c,0x268,"Sony Corp. Batoh Device / PlayStation 3 Controller",2,27,19,2, 
-                                             (GamepadJoystickAxisInfo[]) {
-                                                                     {0,0,GP_AXIS_IS_XAXIS,0,0,2240,NEG_TO_POS},
-                                                                     {1,0,GP_AXIS_IS_NEG,0,0,2240,NEG_TO_POS},
-                                                                     {2,1,GP_AXIS_IS_XAXIS,0,0,2240,NEG_TO_POS},
-                                                                     {3,1,GP_AXIS_IS_NEG,0,0,2240,NEG_TO_POS},
-                                                                     {12,1,GP_AXIS_IS_TRIGGER,0,0,2240,ZERO_TO_POS},
-                                                                     {13,2,GP_AXIS_IS_TRIGGER,1,0,2240,ZERO_TO_POS},
-                                                                     {-1,0,0,0,0,0,NEG_TO_POS}
-                                                                 },
-                                             (long[]) {
-                                                                          Gamepad::BUTTON_MENU1,    
-                                                                          Gamepad::BUTTON_L3,  
-                                                                          Gamepad::BUTTON_R3,  
-                                                                          Gamepad::BUTTON_MENU2, 
-                                                                          Gamepad::BUTTON_UP, 
-                                                                          Gamepad::BUTTON_RIGHT, 
-                                                                          Gamepad::BUTTON_DOWN,    
-                                                                          Gamepad::BUTTON_LEFT,   
-                                                                          Gamepad::BUTTON_L2,  //Use Trigger Instead of BUTTON_L2? or both should be called
-                                                                          Gamepad::BUTTON_R2,  //Use Trigger Instead of BUTTON_R2? or both should be called                                                                        
-                                                                          Gamepad::BUTTON_L1,
-                                                                          Gamepad::BUTTON_R1,
-                                                                          Gamepad::BUTTON_Y,    
-                                                                          Gamepad::BUTTON_B,  
-                                                                          Gamepad::BUTTON_A,  
-                                                                          Gamepad::BUTTON_X, 
-                                                                          Gamepad::BUTTON_MENU3, 
-                                                                          -1,
-                                                                          -1
-                                                                         }
-        }
-    };
-
-    bool isGamepadDevRegistered(dev_t devId)
+void unregisterGamepad(GamepadHandle handle)
+{
+    for(list<ConnectedGamepadDevInfo>::iterator it = __connectedGamepads.begin(); it != __connectedGamepads.end();++it)
     {
-        for(list<ConnectedGamepadDevInfo>::iterator it = __connectedGamepads.begin(); it != __connectedGamepads.end();++it)
+        if(handle == (*it).fd)
         {
-            if(devId == (*it).deviceId) return true;
+            closeGamepad(*it);
+            __connectedGamepads.erase(it);
+            return;
         }
-        return false;
     }
+}
 
-    void closeGamepad(const ConnectedGamepadDevInfo& gamepadDevInfo)
+void closeAllGamepads()
+{
+    for(list<ConnectedGamepadDevInfo>::iterator it = __connectedGamepads.begin(); it != __connectedGamepads.end();++it)
     {
-        ::close(gamepadDevInfo.fd);
+        closeGamepad(*it);
+        __connectedGamepads.erase(it);
     }
+}
 
-    void unregisterGamepad(GamepadHandle handle)
+const GamepadInfoEntry& getGamepadMappedInfo(unsigned int vendorId, unsigned int productId, unsigned int numberOfAxes, unsigned int numberOfButtons)
+{
+    for(int i=0;i<sizeof(gamepadLookupTable)/sizeof(GamepadInfoEntry);i++)
     {
-        for(list<ConnectedGamepadDevInfo>::iterator it = __connectedGamepads.begin(); it != __connectedGamepads.end();++it)
+        const GamepadInfoEntry& curEntry = gamepadLookupTable[i];
+        if(curEntry.vendorId == vendorId && curEntry.productId == productId)
         {
-            if(handle == (*it).fd)
-            {
-                closeGamepad(*it);
-                __connectedGamepads.erase(it);
-                return;
-            }
+            return curEntry;
         }
     }
 
-    void closeAllGamepads()
+    for(int i=0;i<sizeof(gamepadLookupTable)/sizeof(GamepadInfoEntry);i++)
     {
-        for(list<ConnectedGamepadDevInfo>::iterator it = __connectedGamepads.begin(); it != __connectedGamepads.end();++it)
+        const GamepadInfoEntry& curEntry = gamepadLookupTable[i];
+        if(curEntry.vendorId == 0 && curEntry.productId == 0 && curEntry.numberOfAxes == numberOfAxes && curEntry.numberOfButtons == numberOfButtons)
         {
-            closeGamepad(*it);
-            __connectedGamepads.erase(it);
+            return curEntry;
         }
     }
 
-    const GamepadInfoEntry& getGamepadMappedInfo(unsigned int vendorId, unsigned int productId, unsigned int numberOfAxes, unsigned int numberOfButtons)
-    {
-        for(int i=0;i<sizeof(gamepadLookupTable)/sizeof(GamepadInfoEntry);i++)
-        {
-            const GamepadInfoEntry& curEntry = gamepadLookupTable[i];
-            if(curEntry.vendorId == vendorId && curEntry.productId == productId)
-            {
-                return curEntry;
-            }
-        }
-
-        for(int i=0;i<sizeof(gamepadLookupTable)/sizeof(GamepadInfoEntry);i++)
-        {
-            const GamepadInfoEntry& curEntry = gamepadLookupTable[i];
-            if(curEntry.vendorId == 0 && curEntry.productId == 0 && curEntry.numberOfAxes == numberOfAxes && curEntry.numberOfButtons == numberOfButtons)
-            {
-                return curEntry;
-            }
-        }
+    return gamepadLookupTable[0];
+}
 
-        return gamepadLookupTable[0];
-    }
+const GamepadInfoEntry& getGamepadMappedInfo(const GamepadHandle handle)
+{
+    GP_ASSERT(handle >= 0);
 
-    const GamepadInfoEntry& getGamepadMappedInfo(const GamepadHandle handle)
+    for(list<ConnectedGamepadDevInfo>::iterator it = __connectedGamepads.begin(); it != __connectedGamepads.end();++it)
     {
-        GP_ASSERT(handle >= 0);
-
-        for(list<ConnectedGamepadDevInfo>::iterator it = __connectedGamepads.begin(); it != __connectedGamepads.end();++it)
+        if(handle == (*it).fd)
         {
-            if(handle == (*it).fd)
-            {
-                return it->gamepadInfo;
-            }
+            return it->gamepadInfo;
         }
-        GP_WARN("Gamepad not connected but yet trying to get its data. Falling back to generic one.");
-        return gamepadLookupTable[0];
     }
+    GP_WARN("Gamepad not connected but yet trying to get its data. Falling back to generic one.");
+    return gamepadLookupTable[0];
+}
 
-    const GamepadJoystickAxisInfo* tryGetGamepadMappedAxisInfo(const GamepadInfoEntry& gpinfo, unsigned int axisNumber)
+const GamepadJoystickAxisInfo* tryGetGamepadMappedAxisInfo(const GamepadInfoEntry& gpinfo, unsigned int axisNumber)
+{
+    if(axisNumber >= 0 && axisNumber < gpinfo.numberOfAxes)
     {
-        if(axisNumber >= 0 && axisNumber < gpinfo.numberOfAxes)
+        int i = 0;
+        while(true)
         {
-            int i = 0;
-            while(true)
-            {
-                const GamepadJoystickAxisInfo* curAxisInfo = &gpinfo.axes[i++];
-                if(curAxisInfo->axisIndex == axisNumber)
-                    return curAxisInfo;
-                else if(curAxisInfo->axisIndex < 0)
-                    return NULL;
-            }
+            const GamepadJoystickAxisInfo* curAxisInfo = &gpinfo.axes[i++];
+            if(curAxisInfo->axisIndex == axisNumber)
+                return curAxisInfo;
+            else if(curAxisInfo->axisIndex < 0)
+                return NULL;
         }
-        return NULL;
     }
+    return NULL;
+}
 
-    bool tryGetGamepadMappedButton(const GamepadInfoEntry& gpinfo, unsigned long btnNumber, long& outMap)
+bool tryGetGamepadMappedButton(const GamepadInfoEntry& gpinfo, unsigned long btnNumber, long& outMap)
+{
+    if(btnNumber >= 0 && btnNumber < gpinfo.numberOfButtons )
     {
-        if(btnNumber >= 0 && btnNumber < gpinfo.numberOfButtons )
+        if(gpinfo.buttons[btnNumber] >= 0)
         {
-            if(gpinfo.buttons[btnNumber] >= 0)
-            {
-                outMap = gpinfo.buttons[btnNumber];
-                return true;
-            }
-            else
-            {
-                return false;
-            }
+            outMap = gpinfo.buttons[btnNumber];
+            return true;
+        }
+        else
+        {
+            return false;
         }
-        GP_WARN("Unmapped gamepad button: %u.",btnNumber);
-        return false;
     }
+    GP_WARN("Unmapped gamepad button: %u.",btnNumber);
+    return false;
+}
 
-    unsigned int readIntegerGamepadIdPropery(const char* sysFSIdPath, const char* propertyName)
-    {
-        unsigned int ret = 0;
-        try {
-            ifstream propStream;
-            propStream.open((string(sysFSIdPath) + propertyName).c_str(),ifstream::in);
-            propStream >> std::hex >> ret;
-            propStream.close();
-        } catch (exception e) {
-            GP_WARN("Could not read propery from SysFS for Gamepad: %s", propertyName);
-        }
-        return ret;
+unsigned int readIntegerGamepadIdPropery(const char* sysFSIdPath, const char* propertyName)
+{
+    unsigned int ret = 0;
+    try {
+        ifstream propStream;
+        propStream.open((string(sysFSIdPath) + propertyName).c_str(),ifstream::in);
+        propStream >> std::hex >> ret;
+        propStream.close();
+    } catch (exception e) {
+        GP_WARN("Could not read propery from SysFS for Gamepad: %s", propertyName);
     }
+    return ret;
+}
 
-    bool isBlackListed(unsigned int vendorId, unsigned int productId)
+bool isBlackListed(unsigned int vendorId, unsigned int productId)
+{
+    switch(vendorId)
     {
-        switch(vendorId)
-        {
-            case 0x0e0f: //virtual machine devices
-                if(productId == 0x0003) // Virtual Mouse
-                    return true;
-        }
-        return false;
+        case 0x0e0f: //virtual machine devices
+            if(productId == 0x0003) // Virtual Mouse
+                return true;
     }
+    return false;
+}
 
-    void handleConnectedGamepad(dev_t devId, const char* devPath, const char* sysFSIdPath)
-    {
-        GP_ASSERT(devPath);
+void handleConnectedGamepad(dev_t devId, const char* devPath, const char* sysFSIdPath)
+{
+    GP_ASSERT(devPath);
 
-        unsigned int vendorId =readIntegerGamepadIdPropery(sysFSIdPath,"vendor");
-        unsigned int productId =readIntegerGamepadIdPropery(sysFSIdPath,"product");
+    unsigned int vendorId =readIntegerGamepadIdPropery(sysFSIdPath,"vendor");
+    unsigned int productId =readIntegerGamepadIdPropery(sysFSIdPath,"product");
 
-        if(isBlackListed(vendorId,productId)) return;
+    if(isBlackListed(vendorId,productId)) return;
 
-        GamepadHandle handle = ::open(devPath,O_RDONLY | O_NONBLOCK);
-        if(handle < 0)
-        {
-            GP_WARN("Could not open Gamepad device.");
-            return;
-        }
+    GamepadHandle handle = ::open(devPath,O_RDONLY | O_NONBLOCK);
+    if(handle < 0)
+    {
+        GP_WARN("Could not open Gamepad device.");
+        return;
+    }
 
-        if(!(fcntl(handle, F_GETFL) != -1 || errno != EBADF))
-            return;
+    if(!(fcntl(handle, F_GETFL) != -1 || errno != EBADF))
+        return;
 
-        char axesNum, btnsNum, name[256];
-        ioctl(handle, JSIOCGNAME(256), name);
-        ioctl (handle, JSIOCGAXES, &axesNum);
-        ioctl (handle, JSIOCGBUTTONS, &btnsNum);
+    char axesNum, btnsNum, name[256];
+    ioctl(handle, JSIOCGNAME(256), name);
+    ioctl (handle, JSIOCGAXES, &axesNum);
+    ioctl (handle, JSIOCGBUTTONS, &btnsNum);
 
-        const GamepadInfoEntry& gpInfo = getGamepadMappedInfo(vendorId,productId,(unsigned int)axesNum,(unsigned int)btnsNum);
-        unsigned int numJS = gpInfo.numberOfJS;
-        unsigned int numTR = gpInfo.numberOfTriggers;
+    const GamepadInfoEntry& gpInfo = getGamepadMappedInfo(vendorId,productId,(unsigned int)axesNum,(unsigned int)btnsNum);
+    unsigned int numJS = gpInfo.numberOfJS;
+    unsigned int numTR = gpInfo.numberOfTriggers;
 
 
-        Platform::gamepadEventConnectedInternal(handle,btnsNum,numJS,numTR,vendorId,productId,"",name);
+    Platform::gamepadEventConnectedInternal(handle,btnsNum,numJS,numTR,vendorId,productId,"",name);
 
-        ConnectedGamepadDevInfo info = {devId,handle,gpInfo}; 
-        __connectedGamepads.push_back(info);
-    }
+    ConnectedGamepadDevInfo info = {devId,handle,gpInfo}; 
+    __connectedGamepads.push_back(info);
+}
 
-    static float normalizeJoystickAxis(int axisValue, int deadZone, bool zeroToOne)
-    {
-        int absAxisValue = 0;
-        if(zeroToOne)
-            absAxisValue = (axisValue + 32767) / 2.0;
-        else
-             absAxisValue = abs(axisValue);
+static float normalizeJoystickAxis(int axisValue, int deadZone, bool zeroToOne)
+{
+    int absAxisValue = 0;
+    if(zeroToOne)
+        absAxisValue = (axisValue + 32767) / 2.0;
+    else
+            absAxisValue = abs(axisValue);
 
-        if (absAxisValue < deadZone)
-        {
-            return 0.0f;
-        }
-        else
+    if (absAxisValue < deadZone)
+    {
+        return 0.0f;
+    }
+    else
+    {
+        int maxVal = 0;
+        int value = 0;
+        if(!zeroToOne)
         {
-            int maxVal = 0;
-            int value = 0;
-            if(!zeroToOne)
+            value = axisValue;
+            if (value < 0)
             {
-                value = axisValue;
-                if (value < 0)
-                {
-                    value = -1;
-                    maxVal = 32768;
-                }
-                else if (value > 0)
-                {
-                    value = 1;
-                    maxVal = 32767;
-                }
-                else
-                {
-                    return 0.0f;
-                }
+                value = -1;
+                maxVal = 32768;
             }
-            else
+            else if (value > 0)
             {
                 value = 1;
                 maxVal = 32767;
             }
-
-            float ret = value * (absAxisValue - deadZone) / (float)(maxVal - deadZone);
-            return ret;
+            else
+            {
+                return 0.0f;
+            }
+        }
+        else
+        {
+            value = 1;
+            maxVal = 32767;
         }
+
+        float ret = value * (absAxisValue - deadZone) / (float)(maxVal - deadZone);
+        return ret;
     }
+}
 
-    void enumGamepads()
-    {
-        const int maxDevs = 16;
-        const char* devPathFormat = "/dev/input/js%u";
-        const char* sysfsPathFormat = "/sys/class/input/js%u/device/id/";
-        char curDevPath[20];
+void enumGamepads()
+{
+    const int maxDevs = 16;
+    const char* devPathFormat = "/dev/input/js%u";
+    const char* sysfsPathFormat = "/sys/class/input/js%u/device/id/";
+    char curDevPath[20];
 
-        for(int i=0;i<maxDevs;i++)
+    for(int i=0;i<maxDevs;i++)
+    {
+        sprintf(curDevPath,devPathFormat,i);
+        struct stat gpstat;
+        if(::stat(curDevPath,&gpstat) == 0)
         {
-            sprintf(curDevPath,devPathFormat,i);
-            struct stat gpstat;
-            if(::stat(curDevPath,&gpstat) == 0)
+            dev_t devid = gpstat.st_rdev;
+            if(!isGamepadDevRegistered(devid))
             {
-                dev_t devid = gpstat.st_rdev;
-                if(!isGamepadDevRegistered(devid))
-                {
-                    char cursysFSPath[35];
-                    sprintf(cursysFSPath,sysfsPathFormat,i);
-                    handleConnectedGamepad(devid,curDevPath,cursysFSPath);
-                }
+                char cursysFSPath[35];
+                sprintf(cursysFSPath,sysfsPathFormat,i);
+                handleConnectedGamepad(devid,curDevPath,cursysFSPath);
             }
         }
     }
+}
 
-    void gamepadHandlingLoop()
-    {
-        enumGamepads();
-    }
+void gamepadHandlingLoop()
+{
+    enumGamepads();
+}
 
-    int Platform::enterMessagePump()
-    {
-        GP_ASSERT(_game);
+int Platform::enterMessagePump()
+{
+    GP_ASSERT(_game);
 
-        updateWindowSize();
+    updateWindowSize();
 
-        static bool shiftDown = false;
-        static bool capsOn = false;
-        static XEvent evt;
+    static bool shiftDown = false;
+    static bool capsOn = false;
+    static XEvent evt;
 
-        // Get the initial time.
-        clock_gettime(CLOCK_REALTIME, &__timespec);
-        __timeStart = timespec2millis(&__timespec);
-        __timeAbsolute = 0L;
+    // Get the initial time.
+    clock_gettime(CLOCK_REALTIME, &__timespec);
+    __timeStart = timespec2millis(&__timespec);
+    __timeAbsolute = 0L;
 
-        // Run the game.
-        _game->run();
+    // Run the game.
+    _game->run();
 
-        // Setup select for message handling (to allow non-blocking)
-        int x11_fd = ConnectionNumber(__display);
+    // Setup select for message handling (to allow non-blocking)
+    int x11_fd = ConnectionNumber(__display);
 
-        pollfd xpolls[1];
-        xpolls[0].fd = x11_fd;
-        xpolls[0].events = POLLIN|POLLPRI;
+    pollfd xpolls[1];
+    xpolls[0].fd = x11_fd;
+    xpolls[0].events = POLLIN|POLLPRI;
 
-        // Message loop.
-        while (true)
+    // Message loop.
+    while (true)
+    {
+        poll( xpolls, 1, 16 );
+        // handle all pending events in one block
+        while (XPending(__display))
         {
-            poll( xpolls, 1, 16 );
-            // handle all pending events in one block
-            while (XPending(__display))
-            {
-                XNextEvent(__display, &evt);
+            XNextEvent(__display, &evt);
 
-                switch (evt.type)
-                {
-                    case ClientMessage:
-                        {
-                            // Handle destroy window message correctly
-                            if (evt.xclient.data.l[0] == __atomWmDeleteWindow)
-                            {
-                                _game->exit();
-                            }
-                        }
-                        break;
-                    case DestroyNotify :
+            switch (evt.type)
+            {
+                case ClientMessage:
+                    {
+                        // Handle destroy window message correctly
+                        if (evt.xclient.data.l[0] == __atomWmDeleteWindow)
                         {
-                            cleanupX11();
-                            exit(0);
+                            _game->exit();
                         }
-                        break;
+                    }
+                    break;
+                case DestroyNotify :
+                    {
+                        cleanupX11();
+                        exit(0);
+                    }
+                    break;
 
-                    case Expose:
-                        {
-                            updateWindowSize();
-                        }
-                        break;
+                case Expose:
+                    {
+                        updateWindowSize();
+                    }
+                    break;
 
-                    case KeyPress:
-                        {
-                            KeySym sym = XLookupKeysym(&evt.xkey, (evt.xkey.state & shiftDown) ? 1 : 0);
+                case KeyPress:
+                    {
+                        KeySym sym = XLookupKeysym(&evt.xkey, (evt.xkey.state & shiftDown) ? 1 : 0);
 
 
-                            //TempSym needed because XConvertCase operates on two keysyms: One lower and the other upper, we are only interested in the upper case
-                            KeySym tempSym;
-                            if (capsOn && !shiftDown)
-                                XConvertCase(sym,  &tempSym, &sym);
+                        //TempSym needed because XConvertCase operates on two keysyms: One lower and the other upper, we are only interested in the upper case
+                        KeySym tempSym;
+                        if (capsOn && !shiftDown)
+                            XConvertCase(sym,  &tempSym, &sym);
 
-                            Keyboard::Key key = getKey(sym);
-                            gameplay::Platform::keyEventInternal(gameplay::Keyboard::KEY_PRESS, key);
+                        Keyboard::Key key = getKey(sym);
+                        gameplay::Platform::keyEventInternal(gameplay::Keyboard::KEY_PRESS, key);
 
-                            if (key == Keyboard::KEY_CAPS_LOCK)
-                                capsOn = !capsOn;
-                            if (key == Keyboard::KEY_SHIFT)
-                                shiftDown = true;
+                        if (key == Keyboard::KEY_CAPS_LOCK)
+                            capsOn = !capsOn;
+                        if (key == Keyboard::KEY_SHIFT)
+                            shiftDown = true;
 
-                            if (int character = getUnicode(key))
-                                gameplay::Platform::keyEventInternal(gameplay::Keyboard::KEY_CHAR, character);
+                        if (int character = getUnicode(key))
+                            gameplay::Platform::keyEventInternal(gameplay::Keyboard::KEY_CHAR, character);
 
-                        }
-                        break;
+                    }
+                    break;
 
-                    case KeyRelease:
+                case KeyRelease:
+                    {
+                        //detect and drop repeating keystrokes (no other way to do this using the event interface)
+                        XEvent next;
+                        if ( XPending(__display) )
                         {
-                            //detect and drop repeating keystrokes (no other way to do this using the event interface)
-                            XEvent next;
-                            if ( XPending(__display) )
+                            XPeekEvent(__display,&next);
+                            if ( next.type == KeyPress
+                                    && next.xkey.time == evt.xkey.time
+                                    && next.xkey.keycode == evt.xkey.keycode )
                             {
-                                XPeekEvent(__display,&next);
-                                if ( next.type == KeyPress
-                                        && next.xkey.time == evt.xkey.time
-                                        && next.xkey.keycode == evt.xkey.keycode )
-                                {
-                                    XNextEvent(__display,&next);
-                                    continue;
-                                }
+                                XNextEvent(__display,&next);
+                                continue;
                             }
+                        }
 
-                            KeySym sym = XLookupKeysym(&evt.xkey, 0);
-                            Keyboard::Key key = getKey(sym);
-                            gameplay::Platform::keyEventInternal(gameplay::Keyboard::KEY_RELEASE, key);
+                        KeySym sym = XLookupKeysym(&evt.xkey, 0);
+                        Keyboard::Key key = getKey(sym);
+                        gameplay::Platform::keyEventInternal(gameplay::Keyboard::KEY_RELEASE, key);
 
-                            if (key == Keyboard::KEY_SHIFT)
-                                shiftDown = false;
-                        }
-                        break;
+                        if (key == Keyboard::KEY_SHIFT)
+                            shiftDown = false;
+                    }
+                    break;
 
-                    case ButtonPress:
+                case ButtonPress:
+                    {
+                        gameplay::Mouse::MouseEvent mouseEvt;
+                        switch (evt.xbutton.button)
                         {
-                            gameplay::Mouse::MouseEvent mouseEvt;
-                            switch (evt.xbutton.button)
-                            {
-                                case 1:
-                                    mouseEvt = gameplay::Mouse::MOUSE_PRESS_LEFT_BUTTON;
-                                    break;
-                                case 2:
-                                    mouseEvt = gameplay::Mouse::MOUSE_PRESS_MIDDLE_BUTTON;
-                                    break;
-                                case 3:
-                                    mouseEvt = gameplay::Mouse::MOUSE_PRESS_RIGHT_BUTTON;
-                                    break;
-                                case 4:
-                                case 5:
-                                    gameplay::Platform::mouseEventInternal(gameplay::Mouse::MOUSE_WHEEL,
-                                            evt.xbutton.x, evt.xbutton.y,
-                                            evt.xbutton.button == Button4 ? 1 : -1);
-                                    break;
-                                default:
-                                    break;
-                            }
-                            if (!gameplay::Platform::mouseEventInternal(mouseEvt, evt.xbutton.x, evt.xbutton.y, 0))
-                            {
-                                gameplay::Platform::touchEventInternal(gameplay::Touch::TOUCH_PRESS, evt.xbutton.x, evt.xbutton.y, 0, true);
-                            }
+                            case 1:
+                                mouseEvt = gameplay::Mouse::MOUSE_PRESS_LEFT_BUTTON;
+                                break;
+                            case 2:
+                                mouseEvt = gameplay::Mouse::MOUSE_PRESS_MIDDLE_BUTTON;
+                                break;
+                            case 3:
+                                mouseEvt = gameplay::Mouse::MOUSE_PRESS_RIGHT_BUTTON;
+                                break;
+                            case 4:
+                            case 5:
+                                gameplay::Platform::mouseEventInternal(gameplay::Mouse::MOUSE_WHEEL,
+                                        evt.xbutton.x, evt.xbutton.y,
+                                        evt.xbutton.button == Button4 ? 1 : -1);
+                                break;
+                            default:
+                                break;
                         }
-                        break;
-
-                    case ButtonRelease:
+                        if (!gameplay::Platform::mouseEventInternal(mouseEvt, evt.xbutton.x, evt.xbutton.y, 0))
                         {
-                            gameplay::Mouse::MouseEvent mouseEvt;
-                            switch (evt.xbutton.button)
-                            {
-                                case 1:
-                                    mouseEvt = gameplay::Mouse::MOUSE_RELEASE_LEFT_BUTTON;
-                                    break;
-                                case 2:
-                                    mouseEvt = gameplay::Mouse::MOUSE_RELEASE_MIDDLE_BUTTON;
-                                    break;
-                                case 3:
-                                    mouseEvt = gameplay::Mouse::MOUSE_RELEASE_RIGHT_BUTTON;
-                                    break;
-                                default:
-                                    break;
-                            }
-                            if (!gameplay::Platform::mouseEventInternal(mouseEvt, evt.xbutton.x, evt.xbutton.y, 0))
-                            {
-                                gameplay::Platform::touchEventInternal(gameplay::Touch::TOUCH_RELEASE, evt.xbutton.x, evt.xbutton.y, 0, true);
-                            }
+                            gameplay::Platform::touchEventInternal(gameplay::Touch::TOUCH_PRESS, evt.xbutton.x, evt.xbutton.y, 0, true);
                         }
-                        break;
+                    }
+                    break;
 
-                    case MotionNotify:
+                case ButtonRelease:
+                    {
+                        gameplay::Mouse::MouseEvent mouseEvt;
+                        switch (evt.xbutton.button)
                         {
-                            int x = evt.xmotion.x;
-                            int y = evt.xmotion.y;
+                            case 1:
+                                mouseEvt = gameplay::Mouse::MOUSE_RELEASE_LEFT_BUTTON;
+                                break;
+                            case 2:
+                                mouseEvt = gameplay::Mouse::MOUSE_RELEASE_MIDDLE_BUTTON;
+                                break;
+                            case 3:
+                                mouseEvt = gameplay::Mouse::MOUSE_RELEASE_RIGHT_BUTTON;
+                                break;
+                            default:
+                                break;
+                        }
+                        if (!gameplay::Platform::mouseEventInternal(mouseEvt, evt.xbutton.x, evt.xbutton.y, 0))
+                        {
+                            gameplay::Platform::touchEventInternal(gameplay::Touch::TOUCH_RELEASE, evt.xbutton.x, evt.xbutton.y, 0, true);
+                        }
+                    }
+                    break;
+
+                case MotionNotify:
+                    {
+                        int x = evt.xmotion.x;
+                        int y = evt.xmotion.y;
 
-                            if (__mouseCaptured)
+                        if (__mouseCaptured)
+                        {
+                            if (x == __mouseCapturePointX && y == __mouseCapturePointY)
                             {
-                                if (x == __mouseCapturePointX && y == __mouseCapturePointY)
-                                {
-                                    // Discard the first MotionNotify following capture
-                                    // since it contains bogus x,y data.
-                                    break;
-                                }
+                                // Discard the first MotionNotify following capture
+                                // since it contains bogus x,y data.
+                                break;
+                            }
 
-                                // Convert to deltas
-                                x -= __mouseCapturePointX;
-                                y -= __mouseCapturePointY;
+                            // Convert to deltas
+                            x -= __mouseCapturePointX;
+                            y -= __mouseCapturePointY;
 
-                                // Warp mouse back to center of screen.
-                                XWarpPointer(__display, None, __window, 0, 0, 0, 0, __mouseCapturePointX, __mouseCapturePointY);
-                            }
+                            // Warp mouse back to center of screen.
+                            XWarpPointer(__display, None, __window, 0, 0, 0, 0, __mouseCapturePointX, __mouseCapturePointY);
+                        }
 
-                            if (!gameplay::Platform::mouseEventInternal(gameplay::Mouse::MOUSE_MOVE, x, y, 0))
+                        if (!gameplay::Platform::mouseEventInternal(gameplay::Mouse::MOUSE_MOVE, x, y, 0))
+                        {
+                            if (evt.xmotion.state & Button1Mask)
                             {
-                                if (evt.xmotion.state & Button1Mask)
-                                {
-                                    gameplay::Platform::touchEventInternal(gameplay::Touch::TOUCH_MOVE, x, y, 0, true);
-                                }
+                                gameplay::Platform::touchEventInternal(gameplay::Touch::TOUCH_MOVE, x, y, 0, true);
                             }
                         }
-                        break;
+                    }
+                    break;
 
-                    default:
-                        break;
-                }
+                default:
+                    break;
             }
+        }
 
-            gamepadHandlingLoop();
+        gamepadHandlingLoop();
 
-            if (_game)
-            {
-                // Game state will be uninitialized if game was closed through Game::exit()
-                if (_game->getState() == Game::UNINITIALIZED)
-                    break;
-
-                _game->frame();
-            }
+        if (_game)
+        {
+            // Game state will be uninitialized if game was closed through Game::exit()
+            if (_game->getState() == Game::UNINITIALIZED)
+                break;
 
-            glXSwapBuffers(__display, __window);
+            _game->frame();
         }
 
-        cleanupX11();
-
-        return 0;
+        glXSwapBuffers(__display, __window);
     }
 
-    void Platform::signalShutdown()
-    {
-    }
+    cleanupX11();
 
-    bool Platform::canExit()
-    {
-        return true;
-    }
+    return 0;
+}
 
-    unsigned int Platform::getDisplayWidth()
-    {
-        return __windowSize[0];
-    }
+void Platform::signalShutdown()
+{
+}
 
-    unsigned int Platform::getDisplayHeight()
-    {
-        return __windowSize[1];
-    }
+bool Platform::canExit()
+{
+    return true;
+}
 
-    double Platform::getAbsoluteTime()
-    {
+unsigned int Platform::getDisplayWidth()
+{
+    return __windowSize[0];
+}
+
+unsigned int Platform::getDisplayHeight()
+{
+    return __windowSize[1];
+}
 
-        clock_gettime(CLOCK_REALTIME, &__timespec);
-        double now = timespec2millis(&__timespec);
-        __timeAbsolute = now - __timeStart;
+double Platform::getAbsoluteTime()
+{
 
-        return __timeAbsolute;
-    }
+    clock_gettime(CLOCK_REALTIME, &__timespec);
+    double now = timespec2millis(&__timespec);
+    __timeAbsolute = now - __timeStart;
 
-    void Platform::setAbsoluteTime(double time)
-    {
-        __timeAbsolute = time;
-    }
+    return __timeAbsolute;
+}
 
-    bool Platform::isVsync()
-    {
-        return __vsync;
-    }
+void Platform::setAbsoluteTime(double time)
+{
+    __timeAbsolute = time;
+}
 
-    void Platform::setVsync(bool enable)
-    {
-        if (glXSwapIntervalEXT)
-            glXSwapIntervalEXT(__display, __window, __vsync ? 1 : 0);
-        else if(glXSwapIntervalMESA)
-            glXSwapIntervalMESA(__vsync ? 1 : 0);
+bool Platform::isVsync()
+{
+    return __vsync;
+}
 
-        __vsync = enable;
-    }
+void Platform::setVsync(bool enable)
+{
+    if (glXSwapIntervalEXT)
+        glXSwapIntervalEXT(__display, __window, __vsync ? 1 : 0);
+    else if(glXSwapIntervalMESA)
+        glXSwapIntervalMESA(__vsync ? 1 : 0);
 
-    void Platform::swapBuffers()
-    {
-        glXSwapBuffers(__display, __window);
-    }
+    __vsync = enable;
+}
 
-    void Platform::sleep(long ms)
-    {
-        usleep(ms * 1000);
-    }
+void Platform::swapBuffers()
+{
+    glXSwapBuffers(__display, __window);
+}
 
-    void Platform::setMultiSampling(bool enabled)
+void Platform::sleep(long ms)
+{
+    usleep(ms * 1000);
+}
+
+void Platform::setMultiSampling(bool enabled)
+{
+    if (enabled == __multiSampling)
     {
-        if (enabled == __multiSampling)
-        {
-            return;
-        }
+        return;
+    }
         
-            //todo
+        //todo
             
-            __multiSampling = enabled;
-    }
+        __multiSampling = enabled;
+}
     
-        bool Platform::isMultiSampling()
-        {
-            return __multiSampling;
-        }
+    bool Platform::isMultiSampling()
+    {
+        return __multiSampling;
+    }
+
+void Platform::setMultiTouch(bool enabled)
+{
+    // not supported
+}
+
+bool Platform::isMultiTouch()
+{
+    false;
+}
+
+bool Platform::hasAccelerometer()
+{
+    return false;
+}
+
+void Platform::getAccelerometerValues(float* pitch, float* roll)
+{
+    GP_ASSERT(pitch);
+    GP_ASSERT(roll);
+
+    *pitch = 0;
+    *roll = 0;
+}
 
-    void Platform::setMultiTouch(bool enabled)
+void Platform::getSensorValues(float* accelX, float* accelY, float* accelZ, float* gyroX, float* gyroY, float* gyroZ)
+{
+    if (accelX)
     {
-        // not supported
+        *accelX = 0;
     }
 
-    bool Platform::isMultiTouch()
+    if (accelY)
     {
-        false;
+        *accelY = 0;
     }
 
-    bool Platform::hasAccelerometer()
+    if (accelZ)
     {
-        return false;
+        *accelZ = 0;
     }
 
-    void Platform::getAccelerometerValues(float* pitch, float* roll)
+    if (gyroX)
     {
-        GP_ASSERT(pitch);
-        GP_ASSERT(roll);
+        *gyroX = 0;
+    }
 
-        *pitch = 0;
-        *roll = 0;
+    if (gyroY)
+    {
+        *gyroY = 0;
     }
 
-    void Platform::getSensorValues(float* accelX, float* accelY, float* accelZ, float* gyroX, float* gyroY, float* gyroZ)
+    if (gyroZ)
     {
-        if (accelX)
-        {
-            *accelX = 0;
-        }
+        *gyroZ = 0;
+    }
+}
 
-        if (accelY)
-        {
-            *accelY = 0;
-        }
+void Platform::getArguments(int* argc, char*** argv)
+{
+    if (argc)
+        *argc = __argc;
+    if (argv)
+        *argv = __argv;
+}
 
-        if (accelZ)
-        {
-            *accelZ = 0;
-        }
+bool Platform::hasMouse()
+{
+    return true;
+}
 
-        if (gyroX)
+void Platform::setMouseCaptured(bool captured)
+{
+    if (captured != __mouseCaptured)
+    {
+        if (captured)
         {
-            *gyroX = 0;
-        }
+            // Hide the cursor and warp it to the center of the screen
+            __mouseCapturePointX = getDisplayWidth() / 2;
+            __mouseCapturePointY = getDisplayHeight() / 2;
 
-        if (gyroY)
-        {
-            *gyroY = 0;
+            setCursorVisible(false);
+            XWarpPointer(__display, None, __window, 0, 0, 0, 0, __mouseCapturePointX, __mouseCapturePointY);
         }
-
-        if (gyroZ)
+        else
         {
-            *gyroZ = 0;
+            // Restore cursor
+            XWarpPointer(__display, None, __window, 0, 0, 0, 0, __mouseCapturePointX, __mouseCapturePointY);
+            setCursorVisible(true);
         }
-    }
 
-    void Platform::getArguments(int* argc, char*** argv)
-    {
-        if (argc)
-            *argc = __argc;
-        if (argv)
-            *argv = __argv;
+        __mouseCaptured = captured;
     }
+}
 
-    bool Platform::hasMouse()
-    {
-        return true;
-    }
+bool Platform::isMouseCaptured()
+{
+    return __mouseCaptured;
+}
 
-    void Platform::setMouseCaptured(bool captured)
+void Platform::setCursorVisible(bool visible)
+{
+    if (visible != __cursorVisible)
     {
-        if (captured != __mouseCaptured)
+        if (visible)
         {
-            if (captured)
-            {
-                // Hide the cursor and warp it to the center of the screen
-                __mouseCapturePointX = getDisplayWidth() / 2;
-                __mouseCapturePointY = getDisplayHeight() / 2;
-
-                setCursorVisible(false);
-                XWarpPointer(__display, None, __window, 0, 0, 0, 0, __mouseCapturePointX, __mouseCapturePointY);
-            }
-            else
-            {
-                // Restore cursor
-                XWarpPointer(__display, None, __window, 0, 0, 0, 0, __mouseCapturePointX, __mouseCapturePointY);
-                setCursorVisible(true);
-            }
-
-            __mouseCaptured = captured;
+            Cursor invisibleCursor;
+            Pixmap bitmapNoData;
+            XColor black;
+            static char noData[] = {0, 0, 0, 0, 0, 0, 0, 0};
+            black.red = black.green = black.blue = 0;
+            bitmapNoData = XCreateBitmapFromData(__display, __window, noData, 8, 8);
+            invisibleCursor = XCreatePixmapCursor(__display, bitmapNoData, bitmapNoData, &black, &black, 0, 0);
+
+            XDefineCursor(__display, __window, invisibleCursor);
+            XFreeCursor(__display, invisibleCursor);
+            XFreePixmap(__display, bitmapNoData);
         }
-    }
-
-    bool Platform::isMouseCaptured()
-    {
-        return __mouseCaptured;
-    }
-
-    void Platform::setCursorVisible(bool visible)
-    {
-        if (visible != __cursorVisible)
+        else
         {
-            if (visible)
-            {
-                Cursor invisibleCursor;
-                Pixmap bitmapNoData;
-                XColor black;
-                static char noData[] = {0, 0, 0, 0, 0, 0, 0, 0};
-                black.red = black.green = black.blue = 0;
-                bitmapNoData = XCreateBitmapFromData(__display, __window, noData, 8, 8);
-                invisibleCursor = XCreatePixmapCursor(__display, bitmapNoData, bitmapNoData, &black, &black, 0, 0);
-
-                XDefineCursor(__display, __window, invisibleCursor);
-                XFreeCursor(__display, invisibleCursor);
-                XFreePixmap(__display, bitmapNoData);
-            }
-            else
-            {
-                XUndefineCursor(__display, __window);
-            }
-            XFlush(__display);
-            __cursorVisible = visible;
+            XUndefineCursor(__display, __window);
         }
+        XFlush(__display);
+        __cursorVisible = visible;
     }
+}
 
-    bool Platform::isCursorVisible()
-    {
-        return __cursorVisible;
-    }
+bool Platform::isCursorVisible()
+{
+    return __cursorVisible;
+}
 
-    void Platform::displayKeyboard(bool display)
-    {
-        // not supported
-    }
+void Platform::displayKeyboard(bool display)
+{
+    // not supported
+}
 
-    void Platform::shutdownInternal()
-    {
-        closeAllGamepads();
-        Game::getInstance()->shutdown();
-    }
+void Platform::shutdownInternal()
+{
+    closeAllGamepads();
+    Game::getInstance()->shutdown();
+}
 
-    bool Platform::isGestureSupported(Gesture::GestureEvent evt)
-    {
-        return false;
-    }
+bool Platform::isGestureSupported(Gesture::GestureEvent evt)
+{
+    return false;
+}
 
-    void Platform::registerGesture(Gesture::GestureEvent evt)
-    {
-    }
+void Platform::registerGesture(Gesture::GestureEvent evt)
+{
+}
 
-    void Platform::unregisterGesture(Gesture::GestureEvent evt)
-    {
-    }
+void Platform::unregisterGesture(Gesture::GestureEvent evt)
+{
+}
 
-    bool Platform::isGestureRegistered(Gesture::GestureEvent evt)
-    {
-        return false;
-    }
+bool Platform::isGestureRegistered(Gesture::GestureEvent evt)
+{
+    return false;
+}
 
-    void Platform::pollGamepadState(Gamepad* gamepad)
-    {
-        GP_ASSERT(gamepad);
+void Platform::pollGamepadState(Gamepad* gamepad)
+{
+    GP_ASSERT(gamepad);
 
-        struct js_event jevent;
-        const GamepadInfoEntry& gpInfo = getGamepadMappedInfo(gamepad->_handle);
+    struct js_event jevent;
+    const GamepadInfoEntry& gpInfo = getGamepadMappedInfo(gamepad->_handle);
 
-        while (read(gamepad->_handle, &jevent, sizeof(struct js_event)) > 0)
+    while (read(gamepad->_handle, &jevent, sizeof(struct js_event)) > 0)
+    {
+        switch (jevent.type)
         {
-            switch (jevent.type)
-            {
-                case JS_EVENT_BUTTON:
-                case JS_EVENT_BUTTON | JS_EVENT_INIT:
+            case JS_EVENT_BUTTON:
+            case JS_EVENT_BUTTON | JS_EVENT_INIT:
+                {
+                    long curMappingIndex = -1;
+                    if(tryGetGamepadMappedButton(gpInfo, jevent.number, curMappingIndex))
                     {
-                        long curMappingIndex = -1;
-                        if(tryGetGamepadMappedButton(gpInfo, jevent.number, curMappingIndex))
-                        {
-                            unsigned int buttons = 0;
-                            if (jevent.value)
-                                buttons |= (1 << curMappingIndex);
-                            else
-                                buttons &= ~(1 << curMappingIndex);
-                            gamepad->setButtons(buttons);
-                        }
-                        break;
+                        unsigned int buttons = 0;
+                        if (jevent.value)
+                            buttons |= (1 << curMappingIndex);
+                        else
+                            buttons &= ~(1 << curMappingIndex);
+                        gamepad->setButtons(buttons);
                     }
-                case JS_EVENT_AXIS:
-                case JS_EVENT_AXIS | JS_EVENT_INIT:
+                    break;
+                }
+            case JS_EVENT_AXIS:
+            case JS_EVENT_AXIS | JS_EVENT_INIT:
+                {
+                    if(jevent.number < gpInfo.numberOfAxes)
                     {
-                        if(jevent.number < gpInfo.numberOfAxes)
+                        const GamepadJoystickAxisInfo* jsInfo = tryGetGamepadMappedAxisInfo(gpInfo,jevent.number);
+                        if(jsInfo)
                         {
-                            const GamepadJoystickAxisInfo* jsInfo = tryGetGamepadMappedAxisInfo(gpInfo,jevent.number);
-                            if(jsInfo)
+                            float val = normalizeJoystickAxis(jevent.value,jsInfo->deadZone,jsInfo->mapFunc == ZERO_TO_POS);
+                            if(!(jsInfo->flags & GP_AXIS_SKIP))
                             {
-                                float val = normalizeJoystickAxis(jevent.value,jsInfo->deadZone,jsInfo->mapFunc == ZERO_TO_POS);
-                                if(!(jsInfo->flags & GP_AXIS_SKIP))
-                                {
-                                    if((jsInfo->flags & GP_AXIS_IS_NEG))
-                                        val = -1.0f * val;
+                                if((jsInfo->flags & GP_AXIS_IS_NEG))
+                                    val = -1.0f * val;
 
-                                    bool not_js_axis = false;
-                                    if((jsInfo->flags & GP_AXIS_IS_DPAD))
-                                    {
-                                        unsigned int buttons = 0;
-                                        if(jevent.value != 0)
-                                            buttons |= (1 << (jevent.value > 0 ? jsInfo->mappedPosArg : jsInfo->mappedNegArg));
-                                        else
-                                        {
-                                            buttons &= ~(1 << jsInfo->mappedPosArg);
-                                            buttons &= ~(1 << jsInfo->mappedNegArg);
-                                        }
-                                        gamepad->setButtons(buttons);
-                                        not_js_axis = true;
-                                    }
-                                    if((jsInfo->flags & GP_AXIS_IS_TRIGGER))
+                                bool not_js_axis = false;
+                                if((jsInfo->flags & GP_AXIS_IS_DPAD))
+                                {
+                                    unsigned int buttons = 0;
+                                    if(jevent.value != 0)
+                                        buttons |= (1 << (jevent.value > 0 ? jsInfo->mappedPosArg : jsInfo->mappedNegArg));
+                                    else
                                     {
-                                        gamepad->setTriggerValue(jsInfo->mappedPosArg, val);
-                                        not_js_axis = true;
+                                        buttons &= ~(1 << jsInfo->mappedPosArg);
+                                        buttons &= ~(1 << jsInfo->mappedNegArg);
                                     }
+                                    gamepad->setButtons(buttons);
+                                    not_js_axis = true;
+                                }
+                                if((jsInfo->flags & GP_AXIS_IS_TRIGGER))
+                                {
+                                    gamepad->setTriggerValue(jsInfo->mappedPosArg, val);
+                                    not_js_axis = true;
+                                }
 
-                                    if(!not_js_axis)
-                                    {
-                                        Vector2 jsVals;
-                                        gamepad->getJoystickValues(jsInfo->joystickIndex,&jsVals);
-                                        if(jsInfo->flags & GP_AXIS_IS_XAXIS)
-                                            jsVals.x = val;
-                                        else
-                                            jsVals.y = val;
-                                        gamepad->setJoystickValue(jsInfo->joystickIndex,jsVals.x,jsVals.y);
-                                    }
+                                if(!not_js_axis)
+                                {
+                                    Vector2 jsVals;
+                                    gamepad->getJoystickValues(jsInfo->joystickIndex,&jsVals);
+                                    if(jsInfo->flags & GP_AXIS_IS_XAXIS)
+                                        jsVals.x = val;
+                                    else
+                                        jsVals.y = val;
+                                    gamepad->setJoystickValue(jsInfo->joystickIndex,jsVals.x,jsVals.y);
                                 }
                             }
                         }
                     }
-                    break;
+                }
+                break;
 
-                default: 
-                    GP_WARN("unhandled gamepad event: %x\n", jevent.type);
-            }
-        }
-        if(errno == ENODEV)
-        {
-            unregisterGamepad(gamepad->_handle);
-            gamepadEventDisconnectedInternal(gamepad->_handle);
+            default: 
+                GP_WARN("unhandled gamepad event: %x\n", jevent.type);
         }
-
     }
-
-    bool Platform::launchURL(const char* url)
+    if(errno == ENODEV)
     {
-        if (url == NULL || *url == '\0')
-            return false;
+        unregisterGamepad(gamepad->_handle);
+        gamepadEventDisconnectedInternal(gamepad->_handle);
+    }
+}
+
+bool Platform::launchURL(const char* url)
+{
+    if (url == NULL || *url == '\0')
+        return false;
 
-        int len = strlen(url);
+    int len = strlen(url);
 
-        char* cmd = new char[11 + len];
-        sprintf(cmd, "xdg-open %s", url);
-        int r = system(cmd);
-        SAFE_DELETE_ARRAY(cmd);
+    char* cmd = new char[11 + len];
+    sprintf(cmd, "xdg-open %s", url);
+    int r = system(cmd);
+    SAFE_DELETE_ARRAY(cmd);
 
-        return (r == 0);
-    }
+    return (r == 0);
+}
+
+std::string Platform::displayFileDialog(size_t mode, const char* title, const char* filterDescription, const char* filterExtension)
+{
+    return "";
+}
 
 }
 

+ 5 - 0
gameplay/src/PlatformMacOSX.mm

@@ -2324,4 +2324,9 @@ bool Platform::launchURL(const char *url)
     return (err == noErr);
 }
 
+std::string Platform::displayFileDialog(size_t mode, const char* title, const char* filterDescription, const char* filterExtension)
+{
+    return "";
+}
+
 #endif

+ 1406 - 1354
gameplay/src/PlatformWindows.cpp

@@ -1,1354 +1,1406 @@
-#ifdef WIN32
-
-#include "Base.h"
-#include "Platform.h"
-#include "FileSystem.h"
-#include "Game.h"
-#include "Form.h"
-#include "Vector2.h"
-#include "ScriptController.h"
-#include <GL/wglew.h>
-#include <windowsx.h>
-#include <shellapi.h>
-#ifdef GP_USE_GAMEPAD
-#include <XInput.h>
-#endif
-
-using gameplay::print;
-
-// Window defaults
-#define DEFAULT_RESOLUTION_X 1024
-#define DEFAULT_RESOLUTION_Y 768
-#define DEFAULT_COLOR_BUFFER_SIZE 32
-#define DEFAULT_DEPTH_BUFFER_SIZE 24
-#define DEFAULT_STENCIL_BUFFER_SIZE 8
-
-static double __timeTicksPerMillis;
-static double __timeStart;
-static double __timeAbsolute;
-static bool __vsync = WINDOW_VSYNC;
-static HINSTANCE __hinstance = 0;
-static HWND __hwnd = 0;
-static HDC __hdc = 0;
-static HGLRC __hrc = 0;
-static bool __mouseCaptured = false;
-static POINT __mouseCapturePoint = { 0, 0 };
-static bool __multiSampling = false;
-static bool __cursorVisible = true;
-static unsigned int __gamepadsConnected = 0;
-
-#ifdef GP_USE_GAMEPAD
-static const unsigned int XINPUT_BUTTON_COUNT = 14;
-static const unsigned int XINPUT_JOYSTICK_COUNT = 2;
-static const unsigned int XINPUT_TRIGGER_COUNT = 2;
-
-static XINPUT_STATE __xInputState;
-static bool __connectedXInput[4];
-
-static float normalizeXInputJoystickAxis(int axisValue, int deadZone)
-{
-    int absAxisValue = abs(axisValue);
-
-    if (absAxisValue < deadZone)
-    {
-        return 0.0f;
-    }
-    else
-    {
-        int value = axisValue;
-        int maxVal;
-        if (value < 0)
-        {
-            value = -1;
-            maxVal = 32768;
-        }
-        else if (value > 0)
-        {
-            value = 1;
-            maxVal = 32767;
-        }
-        else
-        {
-            return 0;
-        }
-
-        return value * (absAxisValue - deadZone) / (float)(maxVal - deadZone);
-    }
-}
-#endif
-
-static gameplay::Keyboard::Key getKey(WPARAM win32KeyCode, bool shiftDown)
-{
-    switch (win32KeyCode)
-    {
-    case VK_PAUSE:
-        return gameplay::Keyboard::KEY_PAUSE;
-    case VK_SCROLL:
-        return gameplay::Keyboard::KEY_SCROLL_LOCK;
-    case VK_PRINT:
-        return gameplay::Keyboard::KEY_PRINT;
-    case VK_ESCAPE:
-        return gameplay::Keyboard::KEY_ESCAPE;
-    case VK_BACK:
-    case VK_F16: // generated by CTRL + BACKSPACE
-        return gameplay::Keyboard::KEY_BACKSPACE;
-    case VK_TAB:
-        return shiftDown ? gameplay::Keyboard::KEY_BACK_TAB : gameplay::Keyboard::KEY_TAB;
-    case VK_RETURN:
-        return gameplay::Keyboard::KEY_RETURN;
-    case VK_CAPITAL:
-        return gameplay::Keyboard::KEY_CAPS_LOCK;
-    case VK_SHIFT:
-        return gameplay::Keyboard::KEY_SHIFT;
-    case VK_CONTROL:
-        return gameplay::Keyboard::KEY_CTRL;
-    case VK_MENU:
-        return gameplay::Keyboard::KEY_ALT;
-    case VK_APPS:
-        return gameplay::Keyboard::KEY_MENU;
-    case VK_LSHIFT:
-        return gameplay::Keyboard::KEY_SHIFT;
-    case VK_RSHIFT:
-        return gameplay::Keyboard::KEY_SHIFT;
-    case VK_LCONTROL:
-        return gameplay::Keyboard::KEY_CTRL;
-    case VK_RCONTROL:
-        return gameplay::Keyboard::KEY_CTRL;
-    case VK_LMENU:
-        return gameplay::Keyboard::KEY_ALT;
-    case VK_RMENU:
-        return gameplay::Keyboard::KEY_ALT;
-    case VK_LWIN:
-    case VK_RWIN:
-        return gameplay::Keyboard::KEY_HYPER;
-    case VK_BROWSER_SEARCH:
-        return gameplay::Keyboard::KEY_SEARCH;
-    case VK_INSERT:
-        return gameplay::Keyboard::KEY_INSERT;
-    case VK_HOME:
-        return gameplay::Keyboard::KEY_HOME;
-    case VK_PRIOR:
-        return gameplay::Keyboard::KEY_PG_UP;
-    case VK_DELETE:
-        return gameplay::Keyboard::KEY_DELETE;
-    case VK_END:
-        return gameplay::Keyboard::KEY_END;
-    case VK_NEXT:
-        return gameplay::Keyboard::KEY_PG_DOWN;
-    case VK_LEFT:
-        return gameplay::Keyboard::KEY_LEFT_ARROW;
-    case VK_RIGHT:
-        return gameplay::Keyboard::KEY_RIGHT_ARROW;
-    case VK_UP:
-        return gameplay::Keyboard::KEY_UP_ARROW;
-    case VK_DOWN:
-        return gameplay::Keyboard::KEY_DOWN_ARROW;
-    case VK_NUMLOCK:
-        return gameplay::Keyboard::KEY_NUM_LOCK;
-    case VK_ADD:
-        return gameplay::Keyboard::KEY_KP_PLUS;
-    case VK_SUBTRACT:
-        return gameplay::Keyboard::KEY_KP_MINUS;
-    case VK_MULTIPLY:
-        return gameplay::Keyboard::KEY_KP_MULTIPLY;
-    case VK_DIVIDE:
-        return gameplay::Keyboard::KEY_KP_DIVIDE;
-    case VK_NUMPAD7:
-        return gameplay::Keyboard::KEY_KP_HOME;
-    case VK_NUMPAD8:
-        return gameplay::Keyboard::KEY_KP_UP;
-    case VK_NUMPAD9:
-        return gameplay::Keyboard::KEY_KP_PG_UP;
-    case VK_NUMPAD4:
-        return gameplay::Keyboard::KEY_KP_LEFT;
-    case VK_NUMPAD5:
-        return gameplay::Keyboard::KEY_KP_FIVE;
-    case VK_NUMPAD6:
-        return gameplay::Keyboard::KEY_KP_RIGHT;
-    case VK_NUMPAD1:
-        return gameplay::Keyboard::KEY_KP_END;
-    case VK_NUMPAD2:
-        return gameplay::Keyboard::KEY_KP_DOWN;
-    case VK_NUMPAD3:
-        return gameplay::Keyboard::KEY_KP_PG_DOWN;
-    case VK_NUMPAD0:
-        return gameplay::Keyboard::KEY_KP_INSERT;
-    case VK_DECIMAL:
-        return gameplay::Keyboard::KEY_KP_DELETE;
-    case VK_F1:
-        return gameplay::Keyboard::KEY_F1;
-    case VK_F2:
-        return gameplay::Keyboard::KEY_F2;
-    case VK_F3:
-        return gameplay::Keyboard::KEY_F3;
-    case VK_F4:
-        return gameplay::Keyboard::KEY_F4;
-    case VK_F5:
-        return gameplay::Keyboard::KEY_F5;
-    case VK_F6:
-        return gameplay::Keyboard::KEY_F6;
-    case VK_F7:
-        return gameplay::Keyboard::KEY_F7;
-    case VK_F8:
-        return gameplay::Keyboard::KEY_F8;
-    case VK_F9:
-        return gameplay::Keyboard::KEY_F9;
-    case VK_F10:
-        return gameplay::Keyboard::KEY_F10;
-    case VK_F11:
-        return gameplay::Keyboard::KEY_F11;
-    case VK_F12:
-        return gameplay::Keyboard::KEY_F12;
-    case VK_SPACE:
-        return gameplay::Keyboard::KEY_SPACE;
-    case 0x30:
-        return shiftDown ? gameplay::Keyboard::KEY_RIGHT_PARENTHESIS : gameplay::Keyboard::KEY_ZERO;
-    case 0x31:
-        return shiftDown ? gameplay::Keyboard::KEY_EXCLAM : gameplay::Keyboard::KEY_ONE;
-    case 0x32:
-        return shiftDown ? gameplay::Keyboard::KEY_AT : gameplay::Keyboard::KEY_TWO;
-    case 0x33:
-        return shiftDown ? gameplay::Keyboard::KEY_NUMBER : gameplay::Keyboard::KEY_THREE;
-    case 0x34:
-        return shiftDown ? gameplay::Keyboard::KEY_DOLLAR : gameplay::Keyboard::KEY_FOUR;
-    case 0x35:
-        return shiftDown ? gameplay::Keyboard::KEY_PERCENT : gameplay::Keyboard::KEY_FIVE;
-    case 0x36:
-        return shiftDown ? gameplay::Keyboard::KEY_CIRCUMFLEX : gameplay::Keyboard::KEY_SIX;
-    case 0x37:
-        return shiftDown ? gameplay::Keyboard::KEY_AMPERSAND : gameplay::Keyboard::KEY_SEVEN;
-    case 0x38:
-        return shiftDown ? gameplay::Keyboard::KEY_ASTERISK : gameplay::Keyboard::KEY_EIGHT;
-    case 0x39:
-        return shiftDown ? gameplay::Keyboard::KEY_LEFT_PARENTHESIS : gameplay::Keyboard::KEY_NINE;
-    case VK_OEM_PLUS:
-        return shiftDown ? gameplay::Keyboard::KEY_EQUAL : gameplay::Keyboard::KEY_PLUS;
-    case VK_OEM_COMMA:
-        return shiftDown ? gameplay::Keyboard::KEY_LESS_THAN : gameplay::Keyboard::KEY_COMMA;
-    case VK_OEM_MINUS:
-        return shiftDown ? gameplay::Keyboard::KEY_UNDERSCORE : gameplay::Keyboard::KEY_MINUS;
-    case VK_OEM_PERIOD:
-        return shiftDown ? gameplay::Keyboard::KEY_GREATER_THAN : gameplay::Keyboard::KEY_PERIOD;
-    case VK_OEM_1:
-        return shiftDown ? gameplay::Keyboard::KEY_COLON : gameplay::Keyboard::KEY_SEMICOLON;
-    case VK_OEM_2:
-        return shiftDown ? gameplay::Keyboard::KEY_QUESTION : gameplay::Keyboard::KEY_SLASH;
-    case VK_OEM_3:
-        return shiftDown ? gameplay::Keyboard::KEY_TILDE : gameplay::Keyboard::KEY_GRAVE;
-    case VK_OEM_4:
-        return shiftDown ? gameplay::Keyboard::KEY_LEFT_BRACE : gameplay::Keyboard::KEY_LEFT_BRACKET;
-    case VK_OEM_5:
-        return shiftDown ? gameplay::Keyboard::KEY_BAR : gameplay::Keyboard::KEY_BACK_SLASH;
-    case VK_OEM_6:
-        return shiftDown ? gameplay::Keyboard::KEY_RIGHT_BRACE : gameplay::Keyboard::KEY_RIGHT_BRACKET;
-    case VK_OEM_7:
-        return shiftDown ? gameplay::Keyboard::KEY_QUOTE : gameplay::Keyboard::KEY_APOSTROPHE;
-    case 0x41:
-        return shiftDown ? gameplay::Keyboard::KEY_CAPITAL_A : gameplay::Keyboard::KEY_A;
-    case 0x42:
-        return shiftDown ? gameplay::Keyboard::KEY_CAPITAL_B : gameplay::Keyboard::KEY_B;
-    case 0x43:
-        return shiftDown ? gameplay::Keyboard::KEY_CAPITAL_C : gameplay::Keyboard::KEY_C;
-    case 0x44:
-        return shiftDown ? gameplay::Keyboard::KEY_CAPITAL_D : gameplay::Keyboard::KEY_D;
-    case 0x45:
-        return shiftDown ? gameplay::Keyboard::KEY_CAPITAL_E : gameplay::Keyboard::KEY_E;
-    case 0x46:
-        return shiftDown ? gameplay::Keyboard::KEY_CAPITAL_F : gameplay::Keyboard::KEY_F;
-    case 0x47:
-        return shiftDown ? gameplay::Keyboard::KEY_CAPITAL_G : gameplay::Keyboard::KEY_G;
-    case 0x48:
-        return shiftDown ? gameplay::Keyboard::KEY_CAPITAL_H : gameplay::Keyboard::KEY_H;
-    case 0x49:
-        return shiftDown ? gameplay::Keyboard::KEY_CAPITAL_I : gameplay::Keyboard::KEY_I;
-    case 0x4A:
-        return shiftDown ? gameplay::Keyboard::KEY_CAPITAL_J : gameplay::Keyboard::KEY_J;
-    case 0x4B:
-        return shiftDown ? gameplay::Keyboard::KEY_CAPITAL_K : gameplay::Keyboard::KEY_K;
-    case 0x4C:
-        return shiftDown ? gameplay::Keyboard::KEY_CAPITAL_L : gameplay::Keyboard::KEY_L;
-    case 0x4D:
-        return shiftDown ? gameplay::Keyboard::KEY_CAPITAL_M : gameplay::Keyboard::KEY_M;
-    case 0x4E:
-        return shiftDown ? gameplay::Keyboard::KEY_CAPITAL_N : gameplay::Keyboard::KEY_N;
-    case 0x4F:
-        return shiftDown ? gameplay::Keyboard::KEY_CAPITAL_O : gameplay::Keyboard::KEY_O;
-    case 0x50:
-        return shiftDown ? gameplay::Keyboard::KEY_CAPITAL_P : gameplay::Keyboard::KEY_P;
-    case 0x51:
-        return shiftDown ? gameplay::Keyboard::KEY_CAPITAL_Q : gameplay::Keyboard::KEY_Q;
-    case 0x52:
-        return shiftDown ? gameplay::Keyboard::KEY_CAPITAL_R : gameplay::Keyboard::KEY_R;
-    case 0x53:
-        return shiftDown ? gameplay::Keyboard::KEY_CAPITAL_S : gameplay::Keyboard::KEY_S;
-    case 0x54:
-        return shiftDown ? gameplay::Keyboard::KEY_CAPITAL_T : gameplay::Keyboard::KEY_T;
-    case 0x55:
-        return shiftDown ? gameplay::Keyboard::KEY_CAPITAL_U : gameplay::Keyboard::KEY_U;
-    case 0x56:
-        return shiftDown ? gameplay::Keyboard::KEY_CAPITAL_V : gameplay::Keyboard::KEY_V;
-    case 0x57:
-        return shiftDown ? gameplay::Keyboard::KEY_CAPITAL_W : gameplay::Keyboard::KEY_W;
-    case 0x58:
-        return shiftDown ? gameplay::Keyboard::KEY_CAPITAL_X : gameplay::Keyboard::KEY_X;
-    case 0x59:
-        return shiftDown ? gameplay::Keyboard::KEY_CAPITAL_Y : gameplay::Keyboard::KEY_Y;
-    case 0x5A:
-        return shiftDown ? gameplay::Keyboard::KEY_CAPITAL_Z : gameplay::Keyboard::KEY_Z;
-    default:
-        return gameplay::Keyboard::KEY_NONE;
-    }
-}
-
-static void UpdateCapture(LPARAM lParam)
-{
-    if ((lParam & MK_LBUTTON) || (lParam & MK_MBUTTON) || (lParam & MK_RBUTTON))
-        SetCapture(__hwnd);
-    else
-        ReleaseCapture();
-}
-
-static void WarpMouse(int clientX, int clientY)
-{
-    POINT p = { clientX, clientY };
-    ClientToScreen(__hwnd, &p);
-    SetCursorPos(p.x, p.y);
-}
-
-
-/**
- * Gets the width and height of the screen in pixels.
- */
-static void getDesktopResolution(int& width, int& height)
-{
-   RECT desktop;
-   const HWND hDesktop = GetDesktopWindow();
-   // Get the size of screen to the variable desktop
-   GetWindowRect(hDesktop, &desktop);
-   width = desktop.right;
-   height = desktop.bottom;
-}
-
-LRESULT CALLBACK __WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
-{
-    static gameplay::Game* game = gameplay::Game::getInstance();
-
-    if (!game->isInitialized() || hwnd != __hwnd)
-    {
-        // Ignore messages that are not for our game window.
-        return DefWindowProc(hwnd, msg, wParam, lParam);
-    }
-
-    static bool shiftDown = false;
-    static bool capsOn = false;
-
-    switch (msg)
-    {
-    case WM_CLOSE:
-        DestroyWindow(__hwnd);
-        return 0;
-
-    case WM_DESTROY:
-        gameplay::Platform::shutdownInternal();
-        PostQuitMessage(0);
-        return 0;
-
-    case WM_LBUTTONDOWN:
-    {
-        int x = GET_X_LPARAM(lParam);
-        int y = GET_Y_LPARAM(lParam);
-
-        UpdateCapture(wParam);
-        if (!gameplay::Platform::mouseEventInternal(gameplay::Mouse::MOUSE_PRESS_LEFT_BUTTON, x, y, 0))
-        {
-            gameplay::Platform::touchEventInternal(gameplay::Touch::TOUCH_PRESS, x, y, 0, true);
-        }
-        return 0;
-    }
-    case WM_LBUTTONUP:
-    {
-        int x = GET_X_LPARAM(lParam);
-        int y = GET_Y_LPARAM(lParam);
-
-        if (!gameplay::Platform::mouseEventInternal(gameplay::Mouse::MOUSE_RELEASE_LEFT_BUTTON, x, y, 0))
-        {
-            gameplay::Platform::touchEventInternal(gameplay::Touch::TOUCH_RELEASE, x, y, 0, true);
-        }
-        UpdateCapture(wParam);
-        return 0;
-    }
-    case WM_RBUTTONDOWN:
-        UpdateCapture(wParam);
-        gameplay::Platform::mouseEventInternal(gameplay::Mouse::MOUSE_PRESS_RIGHT_BUTTON, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), 0);
-        break;
-
-    case WM_RBUTTONUP:
-        gameplay::Platform::mouseEventInternal(gameplay::Mouse::MOUSE_RELEASE_RIGHT_BUTTON, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), 0);
-        UpdateCapture(wParam);
-        break;
-
-    case WM_MBUTTONDOWN:
-        UpdateCapture(wParam);
-        gameplay::Platform::mouseEventInternal(gameplay::Mouse::MOUSE_PRESS_MIDDLE_BUTTON, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), 0);
-        break;
-
-    case WM_MBUTTONUP:
-        gameplay::Platform::mouseEventInternal(gameplay::Mouse::MOUSE_RELEASE_MIDDLE_BUTTON, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), 0);
-        UpdateCapture(wParam);
-        break;
-
-    case WM_MOUSEMOVE:
-    {
-        int x = GET_X_LPARAM(lParam);
-        int y = GET_Y_LPARAM(lParam);
-
-        if (__mouseCaptured)
-        {
-            // If the incoming position is the mouse capture point, ignore this event
-            // since this is the event that warped the cursor back.
-            if (x == __mouseCapturePoint.x && y == __mouseCapturePoint.y)
-                break;
-
-            // Convert to deltas
-            x -= __mouseCapturePoint.x;
-            y -= __mouseCapturePoint.y;
-
-            // Warp mouse back to center of screen.
-            WarpMouse(__mouseCapturePoint.x, __mouseCapturePoint.y);
-        }
-
-        // Allow Game::mouseEvent a chance to handle (and possibly consume) the event.
-        if (!gameplay::Platform::mouseEventInternal(gameplay::Mouse::MOUSE_MOVE, x, y, 0))
-        {
-            if ((wParam & MK_LBUTTON) == MK_LBUTTON)
-            {
-                // Mouse move events should be interpreted as touch move only if left mouse is held and the game did not consume the mouse event.
-                gameplay::Platform::touchEventInternal(gameplay::Touch::TOUCH_MOVE, x, y, 0, true);
-                return 0;
-            }
-        }
-        break;
-    }
-
-    case WM_MOUSEWHEEL:
-        tagPOINT point;
-        point.x = GET_X_LPARAM(lParam);
-        point.y = GET_Y_LPARAM(lParam);
-        ScreenToClient(__hwnd, &point);
-        gameplay::Platform::mouseEventInternal(gameplay::Mouse::MOUSE_WHEEL, point.x, point.y, GET_WHEEL_DELTA_WPARAM(wParam) / 120);
-        break;
-
-    case WM_KEYDOWN:
-        if (wParam == VK_SHIFT || wParam == VK_LSHIFT || wParam == VK_RSHIFT)
-            shiftDown = true;
-
-        if (wParam == VK_CAPITAL)
-            capsOn = !capsOn;
-
-        gameplay::Platform::keyEventInternal(gameplay::Keyboard::KEY_PRESS, getKey(wParam, shiftDown ^ capsOn));
-        break;
-        
-    case WM_KEYUP:
-        if (wParam == VK_SHIFT || wParam == VK_LSHIFT || wParam == VK_RSHIFT)
-            shiftDown = false;
-
-        gameplay::Platform::keyEventInternal(gameplay::Keyboard::KEY_RELEASE, getKey(wParam, shiftDown ^ capsOn));
-        break;
-
-    case WM_CHAR:
-        gameplay::Platform::keyEventInternal(gameplay::Keyboard::KEY_CHAR, wParam);
-        break;
-
-    case WM_UNICHAR:
-        gameplay::Platform::keyEventInternal(gameplay::Keyboard::KEY_CHAR, wParam);
-        break;
-
-    case WM_SETFOCUS:
-        break;
-
-    case WM_KILLFOCUS:
-        break;
-
-    case WM_SIZE:
-        // Window was resized.
-        gameplay::Platform::resizeEventInternal((unsigned int)(short)LOWORD(lParam), (unsigned int)(short)HIWORD(lParam));
-        break;
-    }
-    
-    return DefWindowProc(hwnd, msg, wParam, lParam); 
-}
-
-
-namespace gameplay
-{
-
-struct WindowCreationParams
-{
-    RECT rect;
-    std::wstring windowName;
-    bool fullscreen;
-    bool resizable;
-    int samples;
-};
-
-extern void print(const char* format, ...)
-{
-    va_list argptr;
-    va_start(argptr, format);
-    int sz = vfprintf(stderr, format, argptr);
-    if (sz > 0)
-    {
-        char* buf = new char[sz + 1];
-        vsprintf(buf, format, argptr);
-        buf[sz] = 0;
-        OutputDebugStringA(buf);
-        SAFE_DELETE_ARRAY(buf);
-    }
-    va_end(argptr);
-}
-
-Platform::Platform(Game* game)
-    : _game(game)
-{
-}
-
-Platform::~Platform()
-{
-    if (__hwnd)
-    {
-        DestroyWindow(__hwnd);
-        __hwnd = 0;
-    }
-}
-
-bool createWindow(WindowCreationParams* params, HWND* hwnd, HDC* hdc)
-{
-    bool fullscreen = false;
-    bool resizable = false;
-    RECT rect = { CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT };
-    std::wstring windowName;
-    if (params)
-    {
-        windowName = params->windowName;
-        memcpy(&rect, &params->rect, sizeof(RECT));
-        fullscreen = params->fullscreen;
-        resizable = params->resizable;
-    }
-
-    // Set the window style.
-    DWORD style, styleEx;
-    if (fullscreen)
-    {
-        style = WS_POPUP;
-        styleEx = WS_EX_APPWINDOW;
-    }
-    else
-    {
-        if (resizable)
-            style = WS_OVERLAPPEDWINDOW;
-        else
-            style = WS_POPUP | WS_BORDER | WS_CAPTION | WS_SYSMENU;
-        styleEx = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
-    }
-    style |= WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
-
-    // Adjust the window rectangle so the client size is the requested size.
-    AdjustWindowRectEx(&rect, style, FALSE, styleEx);
-
-    // Create the native Windows window.
-    *hwnd = CreateWindowEx(styleEx, L"gameplay", windowName.c_str(), style, 0, 0, rect.right - rect.left, rect.bottom - rect.top, NULL, NULL, __hinstance, NULL);
-    if (*hwnd == NULL)
-    {
-        GP_ERROR("Failed to create window.");
-        return false;
-    }
-
-    // Get the drawing context.
-    *hdc = GetDC(*hwnd);
-    if (*hdc == NULL)
-    {
-        GP_ERROR("Failed to get device context.");
-        return false;
-    }
-
-    // Center the window
-    GetWindowRect(*hwnd, &rect);
-    const int screenX = (GetSystemMetrics(SM_CXSCREEN) - rect.right) / 2;
-    const int screenY = (GetSystemMetrics(SM_CYSCREEN) - rect.bottom) / 2;
-    SetWindowPos(*hwnd, *hwnd, screenX, screenY, -1, -1, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
-
-    return true;
-}
-
-bool initializeGL(WindowCreationParams* params)
-{
-    // Create a temporary window and context to we can initialize GLEW and get access
-    // to additional OpenGL extension functions. This is a neccessary evil since the
-    // function for querying GL extensions is a GL extension itself.
-    HWND hwnd = NULL;
-    HDC hdc = NULL;
-
-    if (params)
-    {
-        if (!createWindow(params, &hwnd, &hdc))
-            return false;
-    }
-    else
-    {
-        hwnd = __hwnd;
-        hdc = __hdc;
-    }
-
-    PIXELFORMATDESCRIPTOR pfd;
-    memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
-    pfd.nSize  = sizeof(PIXELFORMATDESCRIPTOR);
-    pfd.nVersion   = 1;
-    pfd.dwFlags    = PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW;
-    pfd.iPixelType = PFD_TYPE_RGBA;
-    pfd.cColorBits = DEFAULT_COLOR_BUFFER_SIZE;
-    pfd.cDepthBits = DEFAULT_DEPTH_BUFFER_SIZE;
-    pfd.cStencilBits = DEFAULT_STENCIL_BUFFER_SIZE;
-    pfd.iLayerType = PFD_MAIN_PLANE;
-
-    int pixelFormat = ChoosePixelFormat(hdc, &pfd);
-    if (pixelFormat == 0)
-    {
-        DestroyWindow(hwnd);
-        GP_ERROR("Failed to choose a pixel format.");
-        return false;
-    }
-
-    if (!SetPixelFormat(hdc, pixelFormat, &pfd))
-    {
-        DestroyWindow(hwnd);
-        GP_ERROR("Failed to set the pixel format.");
-        return false;
-    }
-
-    HGLRC tempContext = wglCreateContext(hdc);
-    if (!tempContext)
-    {
-        DestroyWindow(hwnd);
-        GP_ERROR("Failed to create temporary context for initialization.");
-        return false;
-    }
-    wglMakeCurrent(hdc, tempContext);
-
-    // Initialize GLEW
-    if (GLEW_OK != glewInit())
-    {
-        wglDeleteContext(tempContext);
-        DestroyWindow(hwnd);
-        GP_ERROR("Failed to initialize GLEW.");
-        return false;
-    }
-
-    if( wglChoosePixelFormatARB && wglCreateContextAttribsARB )
-    {
-    // Choose pixel format using wglChoosePixelFormatARB, which allows us to specify
-    // additional attributes such as multisampling.
-    //
-    // Note: Keep multisampling attributes at the start of the attribute lists since code below
-    // assumes they are array elements 0 through 3.
-    int attribList[] = {
-        WGL_SAMPLES_ARB, params ? params->samples : 0,
-        WGL_SAMPLE_BUFFERS_ARB, params ? (params->samples > 0 ? 1 : 0) : 0,
-        WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
-        WGL_SUPPORT_OPENGL_ARB, GL_TRUE,
-        WGL_DOUBLE_BUFFER_ARB, GL_TRUE,
-        WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB,
-        WGL_COLOR_BITS_ARB, DEFAULT_COLOR_BUFFER_SIZE,
-        WGL_DEPTH_BITS_ARB, DEFAULT_DEPTH_BUFFER_SIZE,
-        WGL_STENCIL_BITS_ARB, DEFAULT_STENCIL_BUFFER_SIZE,
-        0
-    };
-    __multiSampling = params && params->samples > 0;
-
-    UINT numFormats;
-    if ( !wglChoosePixelFormatARB(hdc, attribList, NULL, 1, &pixelFormat, &numFormats) || numFormats == 0)
-    {
-        bool valid = false;
-        if (params && params->samples > 0)
-        {
-            GP_WARN("Failed to choose pixel format with WGL_SAMPLES_ARB == %d. Attempting to fallback to lower samples setting.", params->samples);
-            while (params->samples > 0)
-            {
-                params->samples /= 2;
-                attribList[1] = params->samples;
-                attribList[3] = params->samples > 0 ? 1 : 0;
-                if (wglChoosePixelFormatARB(hdc, attribList, NULL, 1, &pixelFormat, &numFormats) && numFormats > 0)
-                {
-                    valid = true;
-                    GP_WARN("Found pixel format with WGL_SAMPLES_ARB == %d.", params->samples);
-                    break;
-                }
-            }
-
-            __multiSampling = params->samples > 0;
-        }
-
-        if (!valid)
-        {
-            wglDeleteContext(tempContext);
-            DestroyWindow(hwnd);
-            GP_ERROR("Failed to choose a pixel format.");
-            return false;
-        }
-    }
-
-    // Create new/final window if needed
-    if (params)
-    {
-        DestroyWindow(hwnd);
-        hwnd = NULL;
-        hdc = NULL;
-
-        if (!createWindow(params, &__hwnd, &__hdc))
-        {
-            wglDeleteContext(tempContext);
-            return false;
-        }
-    }
-
-    // Set final pixel format for window
-    if (!SetPixelFormat(__hdc, pixelFormat, &pfd))
-    {
-        GP_ERROR("Failed to set the pixel format: %d.", (int)GetLastError());
-        return false;
-    }
-
-    // Create our new GL context
-    int attribs[] =
-    {
-        WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
-        WGL_CONTEXT_MINOR_VERSION_ARB, 1,
-        0
-    };
-
-    if (!(__hrc = wglCreateContextAttribsARB(__hdc, 0, attribs) ) )
-    {
-        wglDeleteContext(tempContext);
-        GP_ERROR("Failed to create OpenGL context.");
-        return false;
-    }
-
-    // Delete the old/temporary context and window
-    wglDeleteContext(tempContext);
-
-    // Make the new context current
-    if (!wglMakeCurrent(__hdc, __hrc) || !__hrc)
-    {
-        GP_ERROR("Failed to make the window current.");
-        return false;
-    }
-    } else    // fallback to OpenGL 2.0 if wglChoosePixelFormatARB or wglCreateContextAttribsARB is NULL.
-    {
-        // Context is already here, just use it.
-        __hrc = tempContext;
-        __hwnd = hwnd;
-        __hdc = hdc;
-    }
-
-    // Vertical sync.
-    wglSwapIntervalEXT(__vsync ? 1 : 0);
-
-    // Some old graphics cards support EXT_framebuffer_object instead of ARB_framebuffer_object.
-    // Patch ARB_framebuffer_object functions to EXT_framebuffer_object ones since semantic is same.
-    if( !GLEW_ARB_framebuffer_object && GLEW_EXT_framebuffer_object )
-    {
-        glBindFramebuffer = glBindFramebufferEXT;
-        glBindRenderbuffer = glBindRenderbufferEXT;
-        glBlitFramebuffer = glBlitFramebufferEXT;
-        glCheckFramebufferStatus = glCheckFramebufferStatusEXT;
-        glDeleteFramebuffers = glDeleteFramebuffersEXT;
-        glDeleteRenderbuffers = glDeleteRenderbuffersEXT;
-        glFramebufferRenderbuffer = glFramebufferRenderbufferEXT;
-        glFramebufferTexture1D = glFramebufferTexture1DEXT;
-        glFramebufferTexture2D = glFramebufferTexture2DEXT;
-        glFramebufferTexture3D = glFramebufferTexture3DEXT;
-        glFramebufferTextureLayer = glFramebufferTextureLayerEXT;
-        glGenFramebuffers = glGenFramebuffersEXT;
-        glGenRenderbuffers = glGenRenderbuffersEXT;
-        glGenerateMipmap = glGenerateMipmapEXT;
-        glGetFramebufferAttachmentParameteriv = glGetFramebufferAttachmentParameterivEXT;
-        glGetRenderbufferParameteriv = glGetRenderbufferParameterivEXT;
-        glIsFramebuffer = glIsFramebufferEXT;
-        glIsRenderbuffer = glIsRenderbufferEXT;
-        glRenderbufferStorage = glRenderbufferStorageEXT;
-        glRenderbufferStorageMultisample = glRenderbufferStorageMultisampleEXT;
-    }
-
-    return true;
-}
-
-Platform* Platform::create(Game* game)
-{
-    GP_ASSERT(game);
-
-    FileSystem::setResourcePath("./");
-    Platform* platform = new Platform(game);
-
-    // Get the application module handle.
-    __hinstance = ::GetModuleHandle(NULL);
-
-    // Read window settings from config.
-    WindowCreationParams params;
-    params.fullscreen = false;
-    params.resizable = false;
-    params.rect.left = 0;
-    params.rect.top = 0;
-    params.rect.right = 0;
-    params.rect.bottom = 0;
-    params.samples = 0;
-    if (game->getConfig())
-    {
-        Properties* config = game->getConfig()->getNamespace("window", true);
-        if (config)
-        {
-            // Read window title.
-            const char* title = config->getString("title");
-            if (title)
-            {
-                int len = MultiByteToWideChar(CP_ACP, 0, title, -1, NULL, 0);
-                wchar_t* wtitle = new wchar_t[len];
-                MultiByteToWideChar(CP_ACP, 0, title, -1, wtitle, len);
-                params.windowName = wtitle;
-                SAFE_DELETE_ARRAY(wtitle);
-            }
-
-            // Read fullscreen state.
-            params.fullscreen = config->getBool("fullscreen");
-            // Read resizable state.
-            params.resizable = config->getBool("resizable");
-            // Read multisampling state.
-            params.samples = config->getInt("samples");
-
-            // Read window rect.
-            int x = config->getInt("x");
-            if (x != 0)
-                params.rect.left = x;
-            int y = config->getInt("y");
-            if (y != 0)
-                params.rect.top = y;
-            int width = config->getInt("width");
-            int height = config->getInt("height");
-
-            if (width == 0 && height == 0 && params.fullscreen)
-                getDesktopResolution(width, height);
-
-            if (width != 0)
-                params.rect.right = params.rect.left + width;
-            if (height != 0)
-                params.rect.bottom = params.rect.top + height;
-        }
-    }
-
-    // If window size was not specified, set it to a default value
-    if (params.rect.right == 0)
-        params.rect.right = params.rect.left + DEFAULT_RESOLUTION_X;
-    if (params.rect.bottom == 0)
-        params.rect.bottom = params.rect.top + DEFAULT_RESOLUTION_Y;
-    int width = params.rect.right - params.rect.left;
-    int height = params.rect.bottom - params.rect.top;
-
-    if (params.fullscreen)
-    {
-        // Enumerate all supposed display settings
-        bool modeSupported = false;
-        DWORD modeNum = 0;
-        DEVMODE devMode;
-        memset(&devMode, 0, sizeof(DEVMODE));
-        devMode.dmSize = sizeof(DEVMODE);
-        devMode.dmDriverExtra = 0;
-        while (EnumDisplaySettings(NULL, modeNum++, &devMode) != 0)
-        {
-            // Is mode supported?
-            if (devMode.dmPelsWidth == width &&
-                devMode.dmPelsHeight == height &&
-                devMode.dmBitsPerPel == DEFAULT_COLOR_BUFFER_SIZE)
-            {
-                modeSupported = true;
-                break;
-            }
-        }
-
-        // If the requested mode is not supported, fall back to a safe default
-        if (!modeSupported)
-        {
-            width = DEFAULT_RESOLUTION_X;
-            height = DEFAULT_RESOLUTION_Y;
-            params.rect.right = params.rect.left + width;
-            params.rect.bottom = params.rect.top + height;
-        }
-    }
-
-
-    // Register our window class.
-    WNDCLASSEX wc;
-    wc.cbSize = sizeof(WNDCLASSEX);
-    wc.style          = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
-    wc.lpfnWndProc    = (WNDPROC)__WndProc;
-    wc.cbClsExtra     = 0;
-    wc.cbWndExtra     = 0;
-    wc.hInstance      = __hinstance;
-    wc.hIcon          = LoadIcon(NULL, IDI_APPLICATION);
-    wc.hIconSm        = NULL;
-    wc.hCursor        = LoadCursor(NULL, IDC_ARROW);
-    wc.hbrBackground  = NULL;  // No brush - we are going to paint our own background
-    wc.lpszMenuName   = NULL;  // No default menu
-    wc.lpszClassName  = L"gameplay";
-
-    if (!::RegisterClassEx(&wc))
-    {
-        GP_ERROR("Failed to register window class.");
-        goto error;
-    }
-
-    if (params.fullscreen)
-    {
-        DEVMODE dm;
-        memset(&dm, 0, sizeof(dm));
-        dm.dmSize= sizeof(dm);
-        dm.dmPelsWidth  = width;
-        dm.dmPelsHeight = height;
-        dm.dmBitsPerPel = DEFAULT_COLOR_BUFFER_SIZE;
-        dm.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
-
-        // Try to set selected mode and get results. NOTE: CDS_FULLSCREEN gets rid of start bar.
-        if (ChangeDisplaySettings(&dm, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
-        {
-            params.fullscreen = false;
-            GP_ERROR("Failed to start game in full-screen mode with resolution %dx%d.", width, height);
-            goto error;
-        }
-    }
-
-    if (!initializeGL(&params))
-        goto error;
-
-    // Show the window.
-    ShowWindow(__hwnd, SW_SHOW);
-
-#ifdef GP_USE_GAMEPAD
-    // Initialize XInputGamepads.
-    for (DWORD i = 0; i < XUSER_MAX_COUNT; i++)
-    {
-        if (XInputGetState(i, &__xInputState) == NO_ERROR)
-        {
-            if (!__connectedXInput[i])
-            {
-                // Gamepad is connected.
-                Platform::gamepadEventConnectedInternal(i, XINPUT_BUTTON_COUNT, XINPUT_JOYSTICK_COUNT, XINPUT_TRIGGER_COUNT, 0, 0, "Microsoft", "XBox360 Controller");
-                __connectedXInput[i] = true;
-            }
-        }
-    }
-#endif
-
-    return platform;
-
-error:
-
-    exit(0);
-    return NULL;
-}
-
-int Platform::enterMessagePump()
-{
-    GP_ASSERT(_game);
-
-    // Get the initial time.
-    LARGE_INTEGER tps;
-    QueryPerformanceFrequency(&tps);
-    __timeTicksPerMillis = (double)(tps.QuadPart / 1000L);
-    LARGE_INTEGER queryTime;
-    QueryPerformanceCounter(&queryTime);
-    GP_ASSERT(__timeTicksPerMillis);
-    __timeStart = queryTime.QuadPart / __timeTicksPerMillis;
-
-    SwapBuffers(__hdc);
-
-    if (_game->getState() != Game::RUNNING)
-        _game->run();
-
-    // Enter event dispatch loop.
-    MSG msg;
-    while (true)
-    {
-        if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
-        {
-            TranslateMessage(&msg);
-            DispatchMessage(&msg);
-
-            if (msg.message == WM_QUIT)
-            {
-                gameplay::Platform::shutdownInternal();
-                return msg.wParam;
-            }
-        }
-        else
-        {
-#ifdef GP_USE_GAMEPAD
-            // Check for connected XInput gamepads.
-            for (DWORD i = 0; i < XUSER_MAX_COUNT; i++)
-            {
-                if (XInputGetState(i, &__xInputState) == NO_ERROR && !__connectedXInput[i])
-                {
-                    // Gamepad was just connected.
-                    Platform::gamepadEventConnectedInternal(i, XINPUT_BUTTON_COUNT, XINPUT_JOYSTICK_COUNT, XINPUT_TRIGGER_COUNT, 0, 0, "Microsoft", "XBox360 Controller");
-                    __connectedXInput[i] = true;
-                }
-                else if (XInputGetState(i, &__xInputState) != NO_ERROR && __connectedXInput[i])
-                {
-                    // Gamepad was just disconnected.
-                    __connectedXInput[i] = false;
-                    Platform::gamepadEventDisconnectedInternal(i);
-                }
-            }
-#endif
-            _game->frame();
-            SwapBuffers(__hdc);
-        }
-
-        // If we are done, then exit.
-        if (_game->getState() == Game::UNINITIALIZED)
-            break;
-    }
-    return 0;
-}
-
-void Platform::signalShutdown() 
-{
-    // nothing to do  
-}
-
-bool Platform::canExit()
-{
-    return true;
-}
-
-unsigned int Platform::getDisplayWidth()
-{
-    static RECT rect;
-    GetClientRect(__hwnd, &rect);
-    return rect.right;
-}
-
-unsigned int Platform::getDisplayHeight()
-{
-    static RECT rect;
-    GetClientRect(__hwnd, &rect);
-    return rect.bottom;
-}
-
-double Platform::getAbsoluteTime()
-{
-    LARGE_INTEGER queryTime;
-    QueryPerformanceCounter(&queryTime);
-    GP_ASSERT(__timeTicksPerMillis);
-    __timeAbsolute = queryTime.QuadPart / __timeTicksPerMillis;
-
-    return __timeAbsolute - __timeStart;
-}
-
-void Platform::setAbsoluteTime(double time)
-{
-    __timeAbsolute = time;
-}
-
-bool Platform::isVsync()
-{
-    return __vsync;
-}
-
-void Platform::setVsync(bool enable)
-{
-     wglSwapIntervalEXT(enable ? 1 : 0);
-    __vsync = enable;
-}
-
-void Platform::swapBuffers()
-{
-    if (__hdc)
-        SwapBuffers(__hdc);
-}
-
-void Platform::sleep(long ms)
-{
-    Sleep(ms);
-}
-
-void Platform::setMultiSampling(bool enabled)
-{
-    if (enabled == __multiSampling)
-    {
-        return;
-    }
-
-    if (enabled)
-    {
-        glEnable(GL_MULTISAMPLE);
-    }
-    else
-    {
-        glDisable(GL_MULTISAMPLE);
-    }
-
-    __multiSampling = enabled;
-}
-
-bool Platform::isMultiSampling()
-{
-    return __multiSampling;
-}
-
-void Platform::setMultiTouch(bool enabled)
-{
-    // not supported
-}
-
-bool Platform::isMultiTouch()
-{
-    return false;
-}
-
-bool Platform::hasAccelerometer()
-{
-    return false;
-}
-
-void Platform::getAccelerometerValues(float* pitch, float* roll)
-{
-    GP_ASSERT(pitch);
-    GP_ASSERT(roll);
-
-    *pitch = 0;
-    *roll = 0;
-}
-
-void Platform::getSensorValues(float* accelX, float* accelY, float* accelZ, float* gyroX, float* gyroY, float* gyroZ)
-{
-    if (accelX)
-    {
-        *accelX = 0;
-    }
-
-    if (accelY)
-    {
-        *accelY = 0;
-    }
-
-    if (accelZ)
-    {
-        *accelZ = 0;
-    }
-
-    if (gyroX)
-    {
-        *gyroX = 0;
-    }
-
-    if (gyroY)
-    {
-        *gyroY = 0;
-    }
-
-    if (gyroZ)
-    {
-        *gyroZ = 0;
-    }
-}
-
-void Platform::getArguments(int* argc, char*** argv)
-{
-    if (argc)
-        *argc = __argc;
-    if (argv)
-        *argv = __argv;
-}
-
-bool Platform::hasMouse()
-{
-    return true;
-}
-
-void Platform::setMouseCaptured(bool captured)
-{
-    if (captured != __mouseCaptured)
-    {
-        if (captured)
-        {
-            // Hide the cursor and warp it to the center of the screen
-            __mouseCapturePoint.x = getDisplayWidth() / 2;
-            __mouseCapturePoint.y = getDisplayHeight() / 2;
-
-            ShowCursor(FALSE);
-            WarpMouse(__mouseCapturePoint.x, __mouseCapturePoint.y);
-        }
-        else
-        {
-            // Restore cursor
-            WarpMouse(__mouseCapturePoint.x, __mouseCapturePoint.y);
-            ShowCursor(TRUE);
-        }
-
-        __mouseCaptured = captured;
-    }
-}
-
-bool Platform::isMouseCaptured()
-{
-    return __mouseCaptured;
-}
-
-void Platform::setCursorVisible(bool visible)
-{
-    if (visible != __cursorVisible)
-    {
-        ShowCursor(visible ? TRUE : FALSE);
-        __cursorVisible = visible;
-    }
-}
-
-bool Platform::isCursorVisible()
-{
-    return __cursorVisible;
-}
-
-void Platform::displayKeyboard(bool display)
-{
-    // Do nothing.
-}
-
-bool Platform::isGestureSupported(Gesture::GestureEvent evt)
-{
-    return false;
-}
-
-void Platform::registerGesture(Gesture::GestureEvent evt)
-{
-}
-
-void Platform::unregisterGesture(Gesture::GestureEvent evt)
-{
-}
-    
-bool Platform::isGestureRegistered(Gesture::GestureEvent evt)
-{
-    return false;
-}
-
-#ifdef GP_USE_GAMEPAD
-void Platform::pollGamepadState(Gamepad* gamepad)
-{
-    GP_ASSERT(gamepad->_handle < XUSER_MAX_COUNT);
-
-    if (XInputGetState(gamepad->_handle, &__xInputState) == NO_ERROR)
-    {
-        WORD buttons = __xInputState.Gamepad.wButtons;
-
-        // Map XInput buttons to Gamepad::ButtonMappings enum.
-        static const unsigned int xInputMapping[16] = {
-            Gamepad::BUTTON_UP,    // 0x0001
-            Gamepad::BUTTON_DOWN,  // 0x0002
-            Gamepad::BUTTON_LEFT,  // 0x0004
-            Gamepad::BUTTON_RIGHT, // 0x0008
-            Gamepad::BUTTON_MENU2, // 0x0010
-            Gamepad::BUTTON_MENU1, // 0x0020
-            Gamepad::BUTTON_L3,    // 0x0040
-            Gamepad::BUTTON_R3,    // 0x0080
-            Gamepad::BUTTON_L1,    // 0x0100
-            Gamepad::BUTTON_R1,    // 0x0200
-            0,
-            0,
-            Gamepad::BUTTON_A,     // 0x1000
-            Gamepad::BUTTON_B,     // 0x2000
-            Gamepad::BUTTON_X,     // 0x4000
-            Gamepad::BUTTON_Y      // 0x8000
-        };
-
-        const unsigned int *mapping = xInputMapping;
-        unsigned int mappedButtons;
-        for (mappedButtons = 0; buttons; buttons >>= 1, mapping++)
-        {
-            if (buttons & 1)
-            {
-                mappedButtons |= (1 << *mapping);
-            }
-        }
-        gamepad->setButtons(mappedButtons);
-
-        unsigned int i;
-        for (i = 0; i < gamepad->_joystickCount; ++i)
-        {
-            GP_ASSERT(i < 2);
-
-            float x;
-            float y;
-            switch (i)
-            {
-            case 0:
-                x = normalizeXInputJoystickAxis(__xInputState.Gamepad.sThumbLX, XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE);
-                y = normalizeXInputJoystickAxis(__xInputState.Gamepad.sThumbLY, XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE);
-                break;
-            case 1:
-                x = normalizeXInputJoystickAxis(__xInputState.Gamepad.sThumbRX, XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE);
-                y = normalizeXInputJoystickAxis(__xInputState.Gamepad.sThumbRY, XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE);
-                break;
-            }
-
-            gamepad->setJoystickValue(i, x, y);
-        }
-
-        for (i = 0; i < gamepad->_triggerCount; ++i)
-        {
-            GP_ASSERT(i < 2);
-
-            BYTE trigger;
-            switch (i)
-            {
-            case 0:
-                trigger = __xInputState.Gamepad.bLeftTrigger;
-                break;
-            case 1:
-                trigger = __xInputState.Gamepad.bRightTrigger;
-                break;
-            }
-
-            if (trigger < XINPUT_GAMEPAD_TRIGGER_THRESHOLD)
-            {
-                gamepad->setTriggerValue(i, 0.0f);
-            }
-            else
-            {
-                gamepad->setTriggerValue(i, (float)trigger / 255.0f);
-            }
-        }
-    }
-}
-#else
-void Platform::pollGamepadState(Gamepad* gamepad) { }
-#endif
-
-void Platform::shutdownInternal()
-{
-    Game::getInstance()->shutdown();
-}
-
-bool Platform::launchURL(const char* url)
-{
-    if (url == NULL || *url == '\0')
-        return false;
- 
-    // Success when result code > 32
-    int len = MultiByteToWideChar(CP_ACP, 0, url, -1, NULL, 0);
-    wchar_t* wurl = new wchar_t[len];
-    MultiByteToWideChar(CP_ACP, 0, url, -1, wurl, len);
-    int r = (int)ShellExecute(NULL, NULL, wurl, NULL, NULL, SW_SHOWNORMAL);
-    SAFE_DELETE_ARRAY(wurl);
-    return (r > 32);
-}
-
-}
-
-#endif
+#ifdef WIN32
+
+#include "Base.h"
+#include "Platform.h"
+#include "FileSystem.h"
+#include "Game.h"
+#include "Form.h"
+#include "Vector2.h"
+#include "ScriptController.h"
+#include <GL/wglew.h>
+#include <windowsx.h>
+#include <Commdlg.h>
+#include <shellapi.h>
+#ifdef GP_USE_GAMEPAD
+#include <XInput.h>
+#endif
+
+using gameplay::print;
+
+// Window defaults
+#define DEFAULT_RESOLUTION_X 1024
+#define DEFAULT_RESOLUTION_Y 768
+#define DEFAULT_COLOR_BUFFER_SIZE 32
+#define DEFAULT_DEPTH_BUFFER_SIZE 24
+#define DEFAULT_STENCIL_BUFFER_SIZE 8
+
+static double __timeTicksPerMillis;
+static double __timeStart;
+static double __timeAbsolute;
+static bool __vsync = WINDOW_VSYNC;
+static HINSTANCE __hinstance = 0;
+static HWND __hwnd = 0;
+static HDC __hdc = 0;
+static HGLRC __hrc = 0;
+static bool __mouseCaptured = false;
+static POINT __mouseCapturePoint = { 0, 0 };
+static bool __multiSampling = false;
+static bool __cursorVisible = true;
+static unsigned int __gamepadsConnected = 0;
+
+#ifdef GP_USE_GAMEPAD
+static const unsigned int XINPUT_BUTTON_COUNT = 14;
+static const unsigned int XINPUT_JOYSTICK_COUNT = 2;
+static const unsigned int XINPUT_TRIGGER_COUNT = 2;
+
+static XINPUT_STATE __xInputState;
+static bool __connectedXInput[4];
+
+static float normalizeXInputJoystickAxis(int axisValue, int deadZone)
+{
+    int absAxisValue = abs(axisValue);
+
+    if (absAxisValue < deadZone)
+    {
+        return 0.0f;
+    }
+    else
+    {
+        int value = axisValue;
+        int maxVal;
+        if (value < 0)
+        {
+            value = -1;
+            maxVal = 32768;
+        }
+        else if (value > 0)
+        {
+            value = 1;
+            maxVal = 32767;
+        }
+        else
+        {
+            return 0;
+        }
+
+        return value * (absAxisValue - deadZone) / (float)(maxVal - deadZone);
+    }
+}
+#endif
+
+static gameplay::Keyboard::Key getKey(WPARAM win32KeyCode, bool shiftDown)
+{
+    switch (win32KeyCode)
+    {
+    case VK_PAUSE:
+        return gameplay::Keyboard::KEY_PAUSE;
+    case VK_SCROLL:
+        return gameplay::Keyboard::KEY_SCROLL_LOCK;
+    case VK_PRINT:
+        return gameplay::Keyboard::KEY_PRINT;
+    case VK_ESCAPE:
+        return gameplay::Keyboard::KEY_ESCAPE;
+    case VK_BACK:
+    case VK_F16: // generated by CTRL + BACKSPACE
+        return gameplay::Keyboard::KEY_BACKSPACE;
+    case VK_TAB:
+        return shiftDown ? gameplay::Keyboard::KEY_BACK_TAB : gameplay::Keyboard::KEY_TAB;
+    case VK_RETURN:
+        return gameplay::Keyboard::KEY_RETURN;
+    case VK_CAPITAL:
+        return gameplay::Keyboard::KEY_CAPS_LOCK;
+    case VK_SHIFT:
+        return gameplay::Keyboard::KEY_SHIFT;
+    case VK_CONTROL:
+        return gameplay::Keyboard::KEY_CTRL;
+    case VK_MENU:
+        return gameplay::Keyboard::KEY_ALT;
+    case VK_APPS:
+        return gameplay::Keyboard::KEY_MENU;
+    case VK_LSHIFT:
+        return gameplay::Keyboard::KEY_SHIFT;
+    case VK_RSHIFT:
+        return gameplay::Keyboard::KEY_SHIFT;
+    case VK_LCONTROL:
+        return gameplay::Keyboard::KEY_CTRL;
+    case VK_RCONTROL:
+        return gameplay::Keyboard::KEY_CTRL;
+    case VK_LMENU:
+        return gameplay::Keyboard::KEY_ALT;
+    case VK_RMENU:
+        return gameplay::Keyboard::KEY_ALT;
+    case VK_LWIN:
+    case VK_RWIN:
+        return gameplay::Keyboard::KEY_HYPER;
+    case VK_BROWSER_SEARCH:
+        return gameplay::Keyboard::KEY_SEARCH;
+    case VK_INSERT:
+        return gameplay::Keyboard::KEY_INSERT;
+    case VK_HOME:
+        return gameplay::Keyboard::KEY_HOME;
+    case VK_PRIOR:
+        return gameplay::Keyboard::KEY_PG_UP;
+    case VK_DELETE:
+        return gameplay::Keyboard::KEY_DELETE;
+    case VK_END:
+        return gameplay::Keyboard::KEY_END;
+    case VK_NEXT:
+        return gameplay::Keyboard::KEY_PG_DOWN;
+    case VK_LEFT:
+        return gameplay::Keyboard::KEY_LEFT_ARROW;
+    case VK_RIGHT:
+        return gameplay::Keyboard::KEY_RIGHT_ARROW;
+    case VK_UP:
+        return gameplay::Keyboard::KEY_UP_ARROW;
+    case VK_DOWN:
+        return gameplay::Keyboard::KEY_DOWN_ARROW;
+    case VK_NUMLOCK:
+        return gameplay::Keyboard::KEY_NUM_LOCK;
+    case VK_ADD:
+        return gameplay::Keyboard::KEY_KP_PLUS;
+    case VK_SUBTRACT:
+        return gameplay::Keyboard::KEY_KP_MINUS;
+    case VK_MULTIPLY:
+        return gameplay::Keyboard::KEY_KP_MULTIPLY;
+    case VK_DIVIDE:
+        return gameplay::Keyboard::KEY_KP_DIVIDE;
+    case VK_NUMPAD7:
+        return gameplay::Keyboard::KEY_KP_HOME;
+    case VK_NUMPAD8:
+        return gameplay::Keyboard::KEY_KP_UP;
+    case VK_NUMPAD9:
+        return gameplay::Keyboard::KEY_KP_PG_UP;
+    case VK_NUMPAD4:
+        return gameplay::Keyboard::KEY_KP_LEFT;
+    case VK_NUMPAD5:
+        return gameplay::Keyboard::KEY_KP_FIVE;
+    case VK_NUMPAD6:
+        return gameplay::Keyboard::KEY_KP_RIGHT;
+    case VK_NUMPAD1:
+        return gameplay::Keyboard::KEY_KP_END;
+    case VK_NUMPAD2:
+        return gameplay::Keyboard::KEY_KP_DOWN;
+    case VK_NUMPAD3:
+        return gameplay::Keyboard::KEY_KP_PG_DOWN;
+    case VK_NUMPAD0:
+        return gameplay::Keyboard::KEY_KP_INSERT;
+    case VK_DECIMAL:
+        return gameplay::Keyboard::KEY_KP_DELETE;
+    case VK_F1:
+        return gameplay::Keyboard::KEY_F1;
+    case VK_F2:
+        return gameplay::Keyboard::KEY_F2;
+    case VK_F3:
+        return gameplay::Keyboard::KEY_F3;
+    case VK_F4:
+        return gameplay::Keyboard::KEY_F4;
+    case VK_F5:
+        return gameplay::Keyboard::KEY_F5;
+    case VK_F6:
+        return gameplay::Keyboard::KEY_F6;
+    case VK_F7:
+        return gameplay::Keyboard::KEY_F7;
+    case VK_F8:
+        return gameplay::Keyboard::KEY_F8;
+    case VK_F9:
+        return gameplay::Keyboard::KEY_F9;
+    case VK_F10:
+        return gameplay::Keyboard::KEY_F10;
+    case VK_F11:
+        return gameplay::Keyboard::KEY_F11;
+    case VK_F12:
+        return gameplay::Keyboard::KEY_F12;
+    case VK_SPACE:
+        return gameplay::Keyboard::KEY_SPACE;
+    case 0x30:
+        return shiftDown ? gameplay::Keyboard::KEY_RIGHT_PARENTHESIS : gameplay::Keyboard::KEY_ZERO;
+    case 0x31:
+        return shiftDown ? gameplay::Keyboard::KEY_EXCLAM : gameplay::Keyboard::KEY_ONE;
+    case 0x32:
+        return shiftDown ? gameplay::Keyboard::KEY_AT : gameplay::Keyboard::KEY_TWO;
+    case 0x33:
+        return shiftDown ? gameplay::Keyboard::KEY_NUMBER : gameplay::Keyboard::KEY_THREE;
+    case 0x34:
+        return shiftDown ? gameplay::Keyboard::KEY_DOLLAR : gameplay::Keyboard::KEY_FOUR;
+    case 0x35:
+        return shiftDown ? gameplay::Keyboard::KEY_PERCENT : gameplay::Keyboard::KEY_FIVE;
+    case 0x36:
+        return shiftDown ? gameplay::Keyboard::KEY_CIRCUMFLEX : gameplay::Keyboard::KEY_SIX;
+    case 0x37:
+        return shiftDown ? gameplay::Keyboard::KEY_AMPERSAND : gameplay::Keyboard::KEY_SEVEN;
+    case 0x38:
+        return shiftDown ? gameplay::Keyboard::KEY_ASTERISK : gameplay::Keyboard::KEY_EIGHT;
+    case 0x39:
+        return shiftDown ? gameplay::Keyboard::KEY_LEFT_PARENTHESIS : gameplay::Keyboard::KEY_NINE;
+    case VK_OEM_PLUS:
+        return shiftDown ? gameplay::Keyboard::KEY_EQUAL : gameplay::Keyboard::KEY_PLUS;
+    case VK_OEM_COMMA:
+        return shiftDown ? gameplay::Keyboard::KEY_LESS_THAN : gameplay::Keyboard::KEY_COMMA;
+    case VK_OEM_MINUS:
+        return shiftDown ? gameplay::Keyboard::KEY_UNDERSCORE : gameplay::Keyboard::KEY_MINUS;
+    case VK_OEM_PERIOD:
+        return shiftDown ? gameplay::Keyboard::KEY_GREATER_THAN : gameplay::Keyboard::KEY_PERIOD;
+    case VK_OEM_1:
+        return shiftDown ? gameplay::Keyboard::KEY_COLON : gameplay::Keyboard::KEY_SEMICOLON;
+    case VK_OEM_2:
+        return shiftDown ? gameplay::Keyboard::KEY_QUESTION : gameplay::Keyboard::KEY_SLASH;
+    case VK_OEM_3:
+        return shiftDown ? gameplay::Keyboard::KEY_TILDE : gameplay::Keyboard::KEY_GRAVE;
+    case VK_OEM_4:
+        return shiftDown ? gameplay::Keyboard::KEY_LEFT_BRACE : gameplay::Keyboard::KEY_LEFT_BRACKET;
+    case VK_OEM_5:
+        return shiftDown ? gameplay::Keyboard::KEY_BAR : gameplay::Keyboard::KEY_BACK_SLASH;
+    case VK_OEM_6:
+        return shiftDown ? gameplay::Keyboard::KEY_RIGHT_BRACE : gameplay::Keyboard::KEY_RIGHT_BRACKET;
+    case VK_OEM_7:
+        return shiftDown ? gameplay::Keyboard::KEY_QUOTE : gameplay::Keyboard::KEY_APOSTROPHE;
+    case 0x41:
+        return shiftDown ? gameplay::Keyboard::KEY_CAPITAL_A : gameplay::Keyboard::KEY_A;
+    case 0x42:
+        return shiftDown ? gameplay::Keyboard::KEY_CAPITAL_B : gameplay::Keyboard::KEY_B;
+    case 0x43:
+        return shiftDown ? gameplay::Keyboard::KEY_CAPITAL_C : gameplay::Keyboard::KEY_C;
+    case 0x44:
+        return shiftDown ? gameplay::Keyboard::KEY_CAPITAL_D : gameplay::Keyboard::KEY_D;
+    case 0x45:
+        return shiftDown ? gameplay::Keyboard::KEY_CAPITAL_E : gameplay::Keyboard::KEY_E;
+    case 0x46:
+        return shiftDown ? gameplay::Keyboard::KEY_CAPITAL_F : gameplay::Keyboard::KEY_F;
+    case 0x47:
+        return shiftDown ? gameplay::Keyboard::KEY_CAPITAL_G : gameplay::Keyboard::KEY_G;
+    case 0x48:
+        return shiftDown ? gameplay::Keyboard::KEY_CAPITAL_H : gameplay::Keyboard::KEY_H;
+    case 0x49:
+        return shiftDown ? gameplay::Keyboard::KEY_CAPITAL_I : gameplay::Keyboard::KEY_I;
+    case 0x4A:
+        return shiftDown ? gameplay::Keyboard::KEY_CAPITAL_J : gameplay::Keyboard::KEY_J;
+    case 0x4B:
+        return shiftDown ? gameplay::Keyboard::KEY_CAPITAL_K : gameplay::Keyboard::KEY_K;
+    case 0x4C:
+        return shiftDown ? gameplay::Keyboard::KEY_CAPITAL_L : gameplay::Keyboard::KEY_L;
+    case 0x4D:
+        return shiftDown ? gameplay::Keyboard::KEY_CAPITAL_M : gameplay::Keyboard::KEY_M;
+    case 0x4E:
+        return shiftDown ? gameplay::Keyboard::KEY_CAPITAL_N : gameplay::Keyboard::KEY_N;
+    case 0x4F:
+        return shiftDown ? gameplay::Keyboard::KEY_CAPITAL_O : gameplay::Keyboard::KEY_O;
+    case 0x50:
+        return shiftDown ? gameplay::Keyboard::KEY_CAPITAL_P : gameplay::Keyboard::KEY_P;
+    case 0x51:
+        return shiftDown ? gameplay::Keyboard::KEY_CAPITAL_Q : gameplay::Keyboard::KEY_Q;
+    case 0x52:
+        return shiftDown ? gameplay::Keyboard::KEY_CAPITAL_R : gameplay::Keyboard::KEY_R;
+    case 0x53:
+        return shiftDown ? gameplay::Keyboard::KEY_CAPITAL_S : gameplay::Keyboard::KEY_S;
+    case 0x54:
+        return shiftDown ? gameplay::Keyboard::KEY_CAPITAL_T : gameplay::Keyboard::KEY_T;
+    case 0x55:
+        return shiftDown ? gameplay::Keyboard::KEY_CAPITAL_U : gameplay::Keyboard::KEY_U;
+    case 0x56:
+        return shiftDown ? gameplay::Keyboard::KEY_CAPITAL_V : gameplay::Keyboard::KEY_V;
+    case 0x57:
+        return shiftDown ? gameplay::Keyboard::KEY_CAPITAL_W : gameplay::Keyboard::KEY_W;
+    case 0x58:
+        return shiftDown ? gameplay::Keyboard::KEY_CAPITAL_X : gameplay::Keyboard::KEY_X;
+    case 0x59:
+        return shiftDown ? gameplay::Keyboard::KEY_CAPITAL_Y : gameplay::Keyboard::KEY_Y;
+    case 0x5A:
+        return shiftDown ? gameplay::Keyboard::KEY_CAPITAL_Z : gameplay::Keyboard::KEY_Z;
+    default:
+        return gameplay::Keyboard::KEY_NONE;
+    }
+}
+
+static void UpdateCapture(LPARAM lParam)
+{
+    if ((lParam & MK_LBUTTON) || (lParam & MK_MBUTTON) || (lParam & MK_RBUTTON))
+        SetCapture(__hwnd);
+    else
+        ReleaseCapture();
+}
+
+static void WarpMouse(int clientX, int clientY)
+{
+    POINT p = { clientX, clientY };
+    ClientToScreen(__hwnd, &p);
+    SetCursorPos(p.x, p.y);
+}
+
+
+/**
+ * Gets the width and height of the screen in pixels.
+ */
+static void getDesktopResolution(int& width, int& height)
+{
+   RECT desktop;
+   const HWND hDesktop = GetDesktopWindow();
+   // Get the size of screen to the variable desktop
+   GetWindowRect(hDesktop, &desktop);
+   width = desktop.right;
+   height = desktop.bottom;
+}
+
+LRESULT CALLBACK __WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+    static gameplay::Game* game = gameplay::Game::getInstance();
+
+    if (!game->isInitialized() || hwnd != __hwnd)
+    {
+        // Ignore messages that are not for our game window.
+        return DefWindowProc(hwnd, msg, wParam, lParam);
+    }
+
+    static bool shiftDown = false;
+    static bool capsOn = false;
+
+    switch (msg)
+    {
+    case WM_CLOSE:
+        DestroyWindow(__hwnd);
+        return 0;
+
+    case WM_DESTROY:
+        gameplay::Platform::shutdownInternal();
+        PostQuitMessage(0);
+        return 0;
+
+    case WM_LBUTTONDOWN:
+    {
+        int x = GET_X_LPARAM(lParam);
+        int y = GET_Y_LPARAM(lParam);
+
+        UpdateCapture(wParam);
+        if (!gameplay::Platform::mouseEventInternal(gameplay::Mouse::MOUSE_PRESS_LEFT_BUTTON, x, y, 0))
+        {
+            gameplay::Platform::touchEventInternal(gameplay::Touch::TOUCH_PRESS, x, y, 0, true);
+        }
+        return 0;
+    }
+    case WM_LBUTTONUP:
+    {
+        int x = GET_X_LPARAM(lParam);
+        int y = GET_Y_LPARAM(lParam);
+
+        if (!gameplay::Platform::mouseEventInternal(gameplay::Mouse::MOUSE_RELEASE_LEFT_BUTTON, x, y, 0))
+        {
+            gameplay::Platform::touchEventInternal(gameplay::Touch::TOUCH_RELEASE, x, y, 0, true);
+        }
+        UpdateCapture(wParam);
+        return 0;
+    }
+    case WM_RBUTTONDOWN:
+        UpdateCapture(wParam);
+        gameplay::Platform::mouseEventInternal(gameplay::Mouse::MOUSE_PRESS_RIGHT_BUTTON, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), 0);
+        break;
+
+    case WM_RBUTTONUP:
+        gameplay::Platform::mouseEventInternal(gameplay::Mouse::MOUSE_RELEASE_RIGHT_BUTTON, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), 0);
+        UpdateCapture(wParam);
+        break;
+
+    case WM_MBUTTONDOWN:
+        UpdateCapture(wParam);
+        gameplay::Platform::mouseEventInternal(gameplay::Mouse::MOUSE_PRESS_MIDDLE_BUTTON, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), 0);
+        break;
+
+    case WM_MBUTTONUP:
+        gameplay::Platform::mouseEventInternal(gameplay::Mouse::MOUSE_RELEASE_MIDDLE_BUTTON, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), 0);
+        UpdateCapture(wParam);
+        break;
+
+    case WM_MOUSEMOVE:
+    {
+        int x = GET_X_LPARAM(lParam);
+        int y = GET_Y_LPARAM(lParam);
+
+        if (__mouseCaptured)
+        {
+            // If the incoming position is the mouse capture point, ignore this event
+            // since this is the event that warped the cursor back.
+            if (x == __mouseCapturePoint.x && y == __mouseCapturePoint.y)
+                break;
+
+            // Convert to deltas
+            x -= __mouseCapturePoint.x;
+            y -= __mouseCapturePoint.y;
+
+            // Warp mouse back to center of screen.
+            WarpMouse(__mouseCapturePoint.x, __mouseCapturePoint.y);
+        }
+
+        // Allow Game::mouseEvent a chance to handle (and possibly consume) the event.
+        if (!gameplay::Platform::mouseEventInternal(gameplay::Mouse::MOUSE_MOVE, x, y, 0))
+        {
+            if ((wParam & MK_LBUTTON) == MK_LBUTTON)
+            {
+                // Mouse move events should be interpreted as touch move only if left mouse is held and the game did not consume the mouse event.
+                gameplay::Platform::touchEventInternal(gameplay::Touch::TOUCH_MOVE, x, y, 0, true);
+                return 0;
+            }
+        }
+        break;
+    }
+
+    case WM_MOUSEWHEEL:
+        tagPOINT point;
+        point.x = GET_X_LPARAM(lParam);
+        point.y = GET_Y_LPARAM(lParam);
+        ScreenToClient(__hwnd, &point);
+        gameplay::Platform::mouseEventInternal(gameplay::Mouse::MOUSE_WHEEL, point.x, point.y, GET_WHEEL_DELTA_WPARAM(wParam) / 120);
+        break;
+
+    case WM_KEYDOWN:
+        if (wParam == VK_SHIFT || wParam == VK_LSHIFT || wParam == VK_RSHIFT)
+            shiftDown = true;
+
+        if (wParam == VK_CAPITAL)
+            capsOn = !capsOn;
+
+        gameplay::Platform::keyEventInternal(gameplay::Keyboard::KEY_PRESS, getKey(wParam, shiftDown ^ capsOn));
+        break;
+        
+    case WM_KEYUP:
+        if (wParam == VK_SHIFT || wParam == VK_LSHIFT || wParam == VK_RSHIFT)
+            shiftDown = false;
+
+        gameplay::Platform::keyEventInternal(gameplay::Keyboard::KEY_RELEASE, getKey(wParam, shiftDown ^ capsOn));
+        break;
+
+    case WM_CHAR:
+        gameplay::Platform::keyEventInternal(gameplay::Keyboard::KEY_CHAR, wParam);
+        break;
+
+    case WM_UNICHAR:
+        gameplay::Platform::keyEventInternal(gameplay::Keyboard::KEY_CHAR, wParam);
+        break;
+
+    case WM_SETFOCUS:
+        break;
+
+    case WM_KILLFOCUS:
+        break;
+
+    case WM_SIZE:
+        // Window was resized.
+        gameplay::Platform::resizeEventInternal((unsigned int)(short)LOWORD(lParam), (unsigned int)(short)HIWORD(lParam));
+        break;
+    }
+    
+    return DefWindowProc(hwnd, msg, wParam, lParam); 
+}
+
+
+namespace gameplay
+{
+
+struct WindowCreationParams
+{
+    RECT rect;
+    std::wstring windowName;
+    bool fullscreen;
+    bool resizable;
+    int samples;
+};
+
+extern void print(const char* format, ...)
+{
+    va_list argptr;
+    va_start(argptr, format);
+    int sz = vfprintf(stderr, format, argptr);
+    if (sz > 0)
+    {
+        char* buf = new char[sz + 1];
+        vsprintf(buf, format, argptr);
+        buf[sz] = 0;
+        OutputDebugStringA(buf);
+        SAFE_DELETE_ARRAY(buf);
+    }
+    va_end(argptr);
+}
+
+Platform::Platform(Game* game)
+    : _game(game)
+{
+}
+
+Platform::~Platform()
+{
+    if (__hwnd)
+    {
+        DestroyWindow(__hwnd);
+        __hwnd = 0;
+    }
+}
+
+bool createWindow(WindowCreationParams* params, HWND* hwnd, HDC* hdc)
+{
+    bool fullscreen = false;
+    bool resizable = false;
+    RECT rect = { CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT };
+    std::wstring windowName;
+    if (params)
+    {
+        windowName = params->windowName;
+        memcpy(&rect, &params->rect, sizeof(RECT));
+        fullscreen = params->fullscreen;
+        resizable = params->resizable;
+    }
+
+    // Set the window style.
+    DWORD style, styleEx;
+    if (fullscreen)
+    {
+        style = WS_POPUP;
+        styleEx = WS_EX_APPWINDOW;
+    }
+    else
+    {
+        if (resizable)
+            style = WS_OVERLAPPEDWINDOW;
+        else
+            style = WS_POPUP | WS_BORDER | WS_CAPTION | WS_SYSMENU;
+        styleEx = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
+    }
+    style |= WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
+
+    // Adjust the window rectangle so the client size is the requested size.
+    AdjustWindowRectEx(&rect, style, FALSE, styleEx);
+
+    // Create the native Windows window.
+    *hwnd = CreateWindowEx(styleEx, L"gameplay", windowName.c_str(), style, 0, 0, rect.right - rect.left, rect.bottom - rect.top, NULL, NULL, __hinstance, NULL);
+    if (*hwnd == NULL)
+    {
+        GP_ERROR("Failed to create window.");
+        return false;
+    }
+
+    // Get the drawing context.
+    *hdc = GetDC(*hwnd);
+    if (*hdc == NULL)
+    {
+        GP_ERROR("Failed to get device context.");
+        return false;
+    }
+
+    // Center the window
+    GetWindowRect(*hwnd, &rect);
+    const int screenX = (GetSystemMetrics(SM_CXSCREEN) - rect.right) / 2;
+    const int screenY = (GetSystemMetrics(SM_CYSCREEN) - rect.bottom) / 2;
+    SetWindowPos(*hwnd, *hwnd, screenX, screenY, -1, -1, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
+
+    return true;
+}
+
+bool initializeGL(WindowCreationParams* params)
+{
+    // Create a temporary window and context to we can initialize GLEW and get access
+    // to additional OpenGL extension functions. This is a neccessary evil since the
+    // function for querying GL extensions is a GL extension itself.
+    HWND hwnd = NULL;
+    HDC hdc = NULL;
+
+    if (params)
+    {
+        if (!createWindow(params, &hwnd, &hdc))
+            return false;
+    }
+    else
+    {
+        hwnd = __hwnd;
+        hdc = __hdc;
+    }
+
+    PIXELFORMATDESCRIPTOR pfd;
+    memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
+    pfd.nSize  = sizeof(PIXELFORMATDESCRIPTOR);
+    pfd.nVersion   = 1;
+    pfd.dwFlags    = PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW;
+    pfd.iPixelType = PFD_TYPE_RGBA;
+    pfd.cColorBits = DEFAULT_COLOR_BUFFER_SIZE;
+    pfd.cDepthBits = DEFAULT_DEPTH_BUFFER_SIZE;
+    pfd.cStencilBits = DEFAULT_STENCIL_BUFFER_SIZE;
+    pfd.iLayerType = PFD_MAIN_PLANE;
+
+    int pixelFormat = ChoosePixelFormat(hdc, &pfd);
+    if (pixelFormat == 0)
+    {
+        DestroyWindow(hwnd);
+        GP_ERROR("Failed to choose a pixel format.");
+        return false;
+    }
+
+    if (!SetPixelFormat(hdc, pixelFormat, &pfd))
+    {
+        DestroyWindow(hwnd);
+        GP_ERROR("Failed to set the pixel format.");
+        return false;
+    }
+
+    HGLRC tempContext = wglCreateContext(hdc);
+    if (!tempContext)
+    {
+        DestroyWindow(hwnd);
+        GP_ERROR("Failed to create temporary context for initialization.");
+        return false;
+    }
+    wglMakeCurrent(hdc, tempContext);
+
+    // Initialize GLEW
+    if (GLEW_OK != glewInit())
+    {
+        wglDeleteContext(tempContext);
+        DestroyWindow(hwnd);
+        GP_ERROR("Failed to initialize GLEW.");
+        return false;
+    }
+
+    if( wglChoosePixelFormatARB && wglCreateContextAttribsARB )
+    {
+    // Choose pixel format using wglChoosePixelFormatARB, which allows us to specify
+    // additional attributes such as multisampling.
+    //
+    // Note: Keep multisampling attributes at the start of the attribute lists since code below
+    // assumes they are array elements 0 through 3.
+    int attribList[] = {
+        WGL_SAMPLES_ARB, params ? params->samples : 0,
+        WGL_SAMPLE_BUFFERS_ARB, params ? (params->samples > 0 ? 1 : 0) : 0,
+        WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
+        WGL_SUPPORT_OPENGL_ARB, GL_TRUE,
+        WGL_DOUBLE_BUFFER_ARB, GL_TRUE,
+        WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB,
+        WGL_COLOR_BITS_ARB, DEFAULT_COLOR_BUFFER_SIZE,
+        WGL_DEPTH_BITS_ARB, DEFAULT_DEPTH_BUFFER_SIZE,
+        WGL_STENCIL_BITS_ARB, DEFAULT_STENCIL_BUFFER_SIZE,
+        0
+    };
+    __multiSampling = params && params->samples > 0;
+
+    UINT numFormats;
+    if ( !wglChoosePixelFormatARB(hdc, attribList, NULL, 1, &pixelFormat, &numFormats) || numFormats == 0)
+    {
+        bool valid = false;
+        if (params && params->samples > 0)
+        {
+            GP_WARN("Failed to choose pixel format with WGL_SAMPLES_ARB == %d. Attempting to fallback to lower samples setting.", params->samples);
+            while (params->samples > 0)
+            {
+                params->samples /= 2;
+                attribList[1] = params->samples;
+                attribList[3] = params->samples > 0 ? 1 : 0;
+                if (wglChoosePixelFormatARB(hdc, attribList, NULL, 1, &pixelFormat, &numFormats) && numFormats > 0)
+                {
+                    valid = true;
+                    GP_WARN("Found pixel format with WGL_SAMPLES_ARB == %d.", params->samples);
+                    break;
+                }
+            }
+
+            __multiSampling = params->samples > 0;
+        }
+
+        if (!valid)
+        {
+            wglDeleteContext(tempContext);
+            DestroyWindow(hwnd);
+            GP_ERROR("Failed to choose a pixel format.");
+            return false;
+        }
+    }
+
+    // Create new/final window if needed
+    if (params)
+    {
+        DestroyWindow(hwnd);
+        hwnd = NULL;
+        hdc = NULL;
+
+        if (!createWindow(params, &__hwnd, &__hdc))
+        {
+            wglDeleteContext(tempContext);
+            return false;
+        }
+    }
+
+    // Set final pixel format for window
+    if (!SetPixelFormat(__hdc, pixelFormat, &pfd))
+    {
+        GP_ERROR("Failed to set the pixel format: %d.", (int)GetLastError());
+        return false;
+    }
+
+    // Create our new GL context
+    int attribs[] =
+    {
+        WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
+        WGL_CONTEXT_MINOR_VERSION_ARB, 1,
+        0
+    };
+
+    if (!(__hrc = wglCreateContextAttribsARB(__hdc, 0, attribs) ) )
+    {
+        wglDeleteContext(tempContext);
+        GP_ERROR("Failed to create OpenGL context.");
+        return false;
+    }
+
+    // Delete the old/temporary context and window
+    wglDeleteContext(tempContext);
+
+    // Make the new context current
+    if (!wglMakeCurrent(__hdc, __hrc) || !__hrc)
+    {
+        GP_ERROR("Failed to make the window current.");
+        return false;
+    }
+    } else    // fallback to OpenGL 2.0 if wglChoosePixelFormatARB or wglCreateContextAttribsARB is NULL.
+    {
+        // Context is already here, just use it.
+        __hrc = tempContext;
+        __hwnd = hwnd;
+        __hdc = hdc;
+    }
+
+    // Vertical sync.
+    wglSwapIntervalEXT(__vsync ? 1 : 0);
+
+    // Some old graphics cards support EXT_framebuffer_object instead of ARB_framebuffer_object.
+    // Patch ARB_framebuffer_object functions to EXT_framebuffer_object ones since semantic is same.
+    if( !GLEW_ARB_framebuffer_object && GLEW_EXT_framebuffer_object )
+    {
+        glBindFramebuffer = glBindFramebufferEXT;
+        glBindRenderbuffer = glBindRenderbufferEXT;
+        glBlitFramebuffer = glBlitFramebufferEXT;
+        glCheckFramebufferStatus = glCheckFramebufferStatusEXT;
+        glDeleteFramebuffers = glDeleteFramebuffersEXT;
+        glDeleteRenderbuffers = glDeleteRenderbuffersEXT;
+        glFramebufferRenderbuffer = glFramebufferRenderbufferEXT;
+        glFramebufferTexture1D = glFramebufferTexture1DEXT;
+        glFramebufferTexture2D = glFramebufferTexture2DEXT;
+        glFramebufferTexture3D = glFramebufferTexture3DEXT;
+        glFramebufferTextureLayer = glFramebufferTextureLayerEXT;
+        glGenFramebuffers = glGenFramebuffersEXT;
+        glGenRenderbuffers = glGenRenderbuffersEXT;
+        glGenerateMipmap = glGenerateMipmapEXT;
+        glGetFramebufferAttachmentParameteriv = glGetFramebufferAttachmentParameterivEXT;
+        glGetRenderbufferParameteriv = glGetRenderbufferParameterivEXT;
+        glIsFramebuffer = glIsFramebufferEXT;
+        glIsRenderbuffer = glIsRenderbufferEXT;
+        glRenderbufferStorage = glRenderbufferStorageEXT;
+        glRenderbufferStorageMultisample = glRenderbufferStorageMultisampleEXT;
+    }
+
+    return true;
+}
+
+Platform* Platform::create(Game* game)
+{
+    GP_ASSERT(game);
+
+    FileSystem::setResourcePath("./");
+    Platform* platform = new Platform(game);
+
+    // Get the application module handle.
+    __hinstance = ::GetModuleHandle(NULL);
+
+    // Read window settings from config.
+    WindowCreationParams params;
+    params.fullscreen = false;
+    params.resizable = false;
+    params.rect.left = 0;
+    params.rect.top = 0;
+    params.rect.right = 0;
+    params.rect.bottom = 0;
+    params.samples = 0;
+    if (game->getConfig())
+    {
+        Properties* config = game->getConfig()->getNamespace("window", true);
+        if (config)
+        {
+            // Read window title.
+            const char* title = config->getString("title");
+            if (title)
+            {
+                int len = MultiByteToWideChar(CP_ACP, 0, title, -1, NULL, 0);
+                wchar_t* wtitle = new wchar_t[len];
+                MultiByteToWideChar(CP_ACP, 0, title, -1, wtitle, len);
+                params.windowName = wtitle;
+                SAFE_DELETE_ARRAY(wtitle);
+            }
+
+            // Read fullscreen state.
+            params.fullscreen = config->getBool("fullscreen");
+            // Read resizable state.
+            params.resizable = config->getBool("resizable");
+            // Read multisampling state.
+            params.samples = config->getInt("samples");
+
+            // Read window rect.
+            int x = config->getInt("x");
+            if (x != 0)
+                params.rect.left = x;
+            int y = config->getInt("y");
+            if (y != 0)
+                params.rect.top = y;
+            int width = config->getInt("width");
+            int height = config->getInt("height");
+
+            if (width == 0 && height == 0 && params.fullscreen)
+                getDesktopResolution(width, height);
+
+            if (width != 0)
+                params.rect.right = params.rect.left + width;
+            if (height != 0)
+                params.rect.bottom = params.rect.top + height;
+        }
+    }
+
+    // If window size was not specified, set it to a default value
+    if (params.rect.right == 0)
+        params.rect.right = params.rect.left + DEFAULT_RESOLUTION_X;
+    if (params.rect.bottom == 0)
+        params.rect.bottom = params.rect.top + DEFAULT_RESOLUTION_Y;
+    int width = params.rect.right - params.rect.left;
+    int height = params.rect.bottom - params.rect.top;
+
+    if (params.fullscreen)
+    {
+        // Enumerate all supposed display settings
+        bool modeSupported = false;
+        DWORD modeNum = 0;
+        DEVMODE devMode;
+        memset(&devMode, 0, sizeof(DEVMODE));
+        devMode.dmSize = sizeof(DEVMODE);
+        devMode.dmDriverExtra = 0;
+        while (EnumDisplaySettings(NULL, modeNum++, &devMode) != 0)
+        {
+            // Is mode supported?
+            if (devMode.dmPelsWidth == width &&
+                devMode.dmPelsHeight == height &&
+                devMode.dmBitsPerPel == DEFAULT_COLOR_BUFFER_SIZE)
+            {
+                modeSupported = true;
+                break;
+            }
+        }
+
+        // If the requested mode is not supported, fall back to a safe default
+        if (!modeSupported)
+        {
+            width = DEFAULT_RESOLUTION_X;
+            height = DEFAULT_RESOLUTION_Y;
+            params.rect.right = params.rect.left + width;
+            params.rect.bottom = params.rect.top + height;
+        }
+    }
+
+
+    // Register our window class.
+    WNDCLASSEX wc;
+    wc.cbSize = sizeof(WNDCLASSEX);
+    wc.style          = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
+    wc.lpfnWndProc    = (WNDPROC)__WndProc;
+    wc.cbClsExtra     = 0;
+    wc.cbWndExtra     = 0;
+    wc.hInstance      = __hinstance;
+    wc.hIcon          = LoadIcon(NULL, IDI_APPLICATION);
+    wc.hIconSm        = NULL;
+    wc.hCursor        = LoadCursor(NULL, IDC_ARROW);
+    wc.hbrBackground  = NULL;  // No brush - we are going to paint our own background
+    wc.lpszMenuName   = NULL;  // No default menu
+    wc.lpszClassName  = L"gameplay";
+
+    if (!::RegisterClassEx(&wc))
+    {
+        GP_ERROR("Failed to register window class.");
+        goto error;
+    }
+
+    if (params.fullscreen)
+    {
+        DEVMODE dm;
+        memset(&dm, 0, sizeof(dm));
+        dm.dmSize= sizeof(dm);
+        dm.dmPelsWidth  = width;
+        dm.dmPelsHeight = height;
+        dm.dmBitsPerPel = DEFAULT_COLOR_BUFFER_SIZE;
+        dm.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
+
+        // Try to set selected mode and get results. NOTE: CDS_FULLSCREEN gets rid of start bar.
+        if (ChangeDisplaySettings(&dm, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
+        {
+            params.fullscreen = false;
+            GP_ERROR("Failed to start game in full-screen mode with resolution %dx%d.", width, height);
+            goto error;
+        }
+    }
+
+    if (!initializeGL(&params))
+        goto error;
+
+    // Show the window.
+    ShowWindow(__hwnd, SW_SHOW);
+
+#ifdef GP_USE_GAMEPAD
+    // Initialize XInputGamepads.
+    for (DWORD i = 0; i < XUSER_MAX_COUNT; i++)
+    {
+        if (XInputGetState(i, &__xInputState) == NO_ERROR)
+        {
+            if (!__connectedXInput[i])
+            {
+                // Gamepad is connected.
+                Platform::gamepadEventConnectedInternal(i, XINPUT_BUTTON_COUNT, XINPUT_JOYSTICK_COUNT, XINPUT_TRIGGER_COUNT, 0, 0, "Microsoft", "XBox360 Controller");
+                __connectedXInput[i] = true;
+            }
+        }
+    }
+#endif
+
+    return platform;
+
+error:
+
+    exit(0);
+    return NULL;
+}
+
+int Platform::enterMessagePump()
+{
+    GP_ASSERT(_game);
+
+    // Get the initial time.
+    LARGE_INTEGER tps;
+    QueryPerformanceFrequency(&tps);
+    __timeTicksPerMillis = (double)(tps.QuadPart / 1000L);
+    LARGE_INTEGER queryTime;
+    QueryPerformanceCounter(&queryTime);
+    GP_ASSERT(__timeTicksPerMillis);
+    __timeStart = queryTime.QuadPart / __timeTicksPerMillis;
+
+    SwapBuffers(__hdc);
+
+    if (_game->getState() != Game::RUNNING)
+        _game->run();
+
+    // Enter event dispatch loop.
+    MSG msg;
+    while (true)
+    {
+        if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
+        {
+            TranslateMessage(&msg);
+            DispatchMessage(&msg);
+
+            if (msg.message == WM_QUIT)
+            {
+                gameplay::Platform::shutdownInternal();
+                return msg.wParam;
+            }
+        }
+        else
+        {
+#ifdef GP_USE_GAMEPAD
+            // Check for connected XInput gamepads.
+            for (DWORD i = 0; i < XUSER_MAX_COUNT; i++)
+            {
+                if (XInputGetState(i, &__xInputState) == NO_ERROR && !__connectedXInput[i])
+                {
+                    // Gamepad was just connected.
+                    Platform::gamepadEventConnectedInternal(i, XINPUT_BUTTON_COUNT, XINPUT_JOYSTICK_COUNT, XINPUT_TRIGGER_COUNT, 0, 0, "Microsoft", "XBox360 Controller");
+                    __connectedXInput[i] = true;
+                }
+                else if (XInputGetState(i, &__xInputState) != NO_ERROR && __connectedXInput[i])
+                {
+                    // Gamepad was just disconnected.
+                    __connectedXInput[i] = false;
+                    Platform::gamepadEventDisconnectedInternal(i);
+                }
+            }
+#endif
+            _game->frame();
+            SwapBuffers(__hdc);
+        }
+
+        // If we are done, then exit.
+        if (_game->getState() == Game::UNINITIALIZED)
+            break;
+    }
+    return 0;
+}
+
+void Platform::signalShutdown() 
+{
+    // nothing to do  
+}
+
+bool Platform::canExit()
+{
+    return true;
+}
+
+unsigned int Platform::getDisplayWidth()
+{
+    static RECT rect;
+    GetClientRect(__hwnd, &rect);
+    return rect.right;
+}
+
+unsigned int Platform::getDisplayHeight()
+{
+    static RECT rect;
+    GetClientRect(__hwnd, &rect);
+    return rect.bottom;
+}
+
+double Platform::getAbsoluteTime()
+{
+    LARGE_INTEGER queryTime;
+    QueryPerformanceCounter(&queryTime);
+    GP_ASSERT(__timeTicksPerMillis);
+    __timeAbsolute = queryTime.QuadPart / __timeTicksPerMillis;
+
+    return __timeAbsolute - __timeStart;
+}
+
+void Platform::setAbsoluteTime(double time)
+{
+    __timeAbsolute = time;
+}
+
+bool Platform::isVsync()
+{
+    return __vsync;
+}
+
+void Platform::setVsync(bool enable)
+{
+     wglSwapIntervalEXT(enable ? 1 : 0);
+    __vsync = enable;
+}
+
+void Platform::swapBuffers()
+{
+    if (__hdc)
+        SwapBuffers(__hdc);
+}
+
+void Platform::sleep(long ms)
+{
+    Sleep(ms);
+}
+
+void Platform::setMultiSampling(bool enabled)
+{
+    if (enabled == __multiSampling)
+    {
+        return;
+    }
+
+    if (enabled)
+    {
+        glEnable(GL_MULTISAMPLE);
+    }
+    else
+    {
+        glDisable(GL_MULTISAMPLE);
+    }
+
+    __multiSampling = enabled;
+}
+
+bool Platform::isMultiSampling()
+{
+    return __multiSampling;
+}
+
+void Platform::setMultiTouch(bool enabled)
+{
+    // not supported
+}
+
+bool Platform::isMultiTouch()
+{
+    return false;
+}
+
+bool Platform::hasAccelerometer()
+{
+    return false;
+}
+
+void Platform::getAccelerometerValues(float* pitch, float* roll)
+{
+    GP_ASSERT(pitch);
+    GP_ASSERT(roll);
+
+    *pitch = 0;
+    *roll = 0;
+}
+
+void Platform::getSensorValues(float* accelX, float* accelY, float* accelZ, float* gyroX, float* gyroY, float* gyroZ)
+{
+    if (accelX)
+    {
+        *accelX = 0;
+    }
+
+    if (accelY)
+    {
+        *accelY = 0;
+    }
+
+    if (accelZ)
+    {
+        *accelZ = 0;
+    }
+
+    if (gyroX)
+    {
+        *gyroX = 0;
+    }
+
+    if (gyroY)
+    {
+        *gyroY = 0;
+    }
+
+    if (gyroZ)
+    {
+        *gyroZ = 0;
+    }
+}
+
+void Platform::getArguments(int* argc, char*** argv)
+{
+    if (argc)
+        *argc = __argc;
+    if (argv)
+        *argv = __argv;
+}
+
+bool Platform::hasMouse()
+{
+    return true;
+}
+
+void Platform::setMouseCaptured(bool captured)
+{
+    if (captured != __mouseCaptured)
+    {
+        if (captured)
+        {
+            // Hide the cursor and warp it to the center of the screen
+            __mouseCapturePoint.x = getDisplayWidth() / 2;
+            __mouseCapturePoint.y = getDisplayHeight() / 2;
+
+            ShowCursor(FALSE);
+            WarpMouse(__mouseCapturePoint.x, __mouseCapturePoint.y);
+        }
+        else
+        {
+            // Restore cursor
+            WarpMouse(__mouseCapturePoint.x, __mouseCapturePoint.y);
+            ShowCursor(TRUE);
+        }
+
+        __mouseCaptured = captured;
+    }
+}
+
+bool Platform::isMouseCaptured()
+{
+    return __mouseCaptured;
+}
+
+void Platform::setCursorVisible(bool visible)
+{
+    if (visible != __cursorVisible)
+    {
+        ShowCursor(visible ? TRUE : FALSE);
+        __cursorVisible = visible;
+    }
+}
+
+bool Platform::isCursorVisible()
+{
+    return __cursorVisible;
+}
+
+void Platform::displayKeyboard(bool display)
+{
+    // Do nothing.
+}
+
+bool Platform::isGestureSupported(Gesture::GestureEvent evt)
+{
+    return false;
+}
+
+void Platform::registerGesture(Gesture::GestureEvent evt)
+{
+}
+
+void Platform::unregisterGesture(Gesture::GestureEvent evt)
+{
+}
+    
+bool Platform::isGestureRegistered(Gesture::GestureEvent evt)
+{
+    return false;
+}
+
+#ifdef GP_USE_GAMEPAD
+void Platform::pollGamepadState(Gamepad* gamepad)
+{
+    GP_ASSERT(gamepad->_handle < XUSER_MAX_COUNT);
+
+    if (XInputGetState(gamepad->_handle, &__xInputState) == NO_ERROR)
+    {
+        WORD buttons = __xInputState.Gamepad.wButtons;
+
+        // Map XInput buttons to Gamepad::ButtonMappings enum.
+        static const unsigned int xInputMapping[16] = {
+            Gamepad::BUTTON_UP,    // 0x0001
+            Gamepad::BUTTON_DOWN,  // 0x0002
+            Gamepad::BUTTON_LEFT,  // 0x0004
+            Gamepad::BUTTON_RIGHT, // 0x0008
+            Gamepad::BUTTON_MENU2, // 0x0010
+            Gamepad::BUTTON_MENU1, // 0x0020
+            Gamepad::BUTTON_L3,    // 0x0040
+            Gamepad::BUTTON_R3,    // 0x0080
+            Gamepad::BUTTON_L1,    // 0x0100
+            Gamepad::BUTTON_R1,    // 0x0200
+            0,
+            0,
+            Gamepad::BUTTON_A,     // 0x1000
+            Gamepad::BUTTON_B,     // 0x2000
+            Gamepad::BUTTON_X,     // 0x4000
+            Gamepad::BUTTON_Y      // 0x8000
+        };
+
+        const unsigned int *mapping = xInputMapping;
+        unsigned int mappedButtons;
+        for (mappedButtons = 0; buttons; buttons >>= 1, mapping++)
+        {
+            if (buttons & 1)
+            {
+                mappedButtons |= (1 << *mapping);
+            }
+        }
+        gamepad->setButtons(mappedButtons);
+
+        unsigned int i;
+        for (i = 0; i < gamepad->_joystickCount; ++i)
+        {
+            GP_ASSERT(i < 2);
+
+            float x;
+            float y;
+            switch (i)
+            {
+            case 0:
+                x = normalizeXInputJoystickAxis(__xInputState.Gamepad.sThumbLX, XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE);
+                y = normalizeXInputJoystickAxis(__xInputState.Gamepad.sThumbLY, XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE);
+                break;
+            case 1:
+                x = normalizeXInputJoystickAxis(__xInputState.Gamepad.sThumbRX, XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE);
+                y = normalizeXInputJoystickAxis(__xInputState.Gamepad.sThumbRY, XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE);
+                break;
+            }
+
+            gamepad->setJoystickValue(i, x, y);
+        }
+
+        for (i = 0; i < gamepad->_triggerCount; ++i)
+        {
+            GP_ASSERT(i < 2);
+
+            BYTE trigger;
+            switch (i)
+            {
+            case 0:
+                trigger = __xInputState.Gamepad.bLeftTrigger;
+                break;
+            case 1:
+                trigger = __xInputState.Gamepad.bRightTrigger;
+                break;
+            }
+
+            if (trigger < XINPUT_GAMEPAD_TRIGGER_THRESHOLD)
+            {
+                gamepad->setTriggerValue(i, 0.0f);
+            }
+            else
+            {
+                gamepad->setTriggerValue(i, (float)trigger / 255.0f);
+            }
+        }
+    }
+}
+#else
+void Platform::pollGamepadState(Gamepad* gamepad) { }
+#endif
+
+void Platform::shutdownInternal()
+{
+    Game::getInstance()->shutdown();
+}
+
+bool Platform::launchURL(const char* url)
+{
+    if (url == NULL || *url == '\0')
+        return false;
+ 
+    // Success when result code > 32
+    int len = MultiByteToWideChar(CP_ACP, 0, url, -1, NULL, 0);
+    wchar_t* wurl = new wchar_t[len];
+    MultiByteToWideChar(CP_ACP, 0, url, -1, wurl, len);
+    int r = (int)ShellExecute(NULL, NULL, wurl, NULL, NULL, SW_SHOWNORMAL);
+    SAFE_DELETE_ARRAY(wurl);
+    return (r > 32);
+}
+
+std::string Platform::displayFileDialog(size_t mode, const char* title, const char* filterDescription, const char* filterExtension)
+{
+    std::string filename;
+    OPENFILENAMEA ofn;
+    memset(&ofn, 0, sizeof(ofn));
+
+    char currentDir[256];
+    GetCurrentDirectoryA(256, currentDir);
+    std::string initialDir = currentDir;
+    initialDir += "\\res";
+
+    std::string desc = filterDescription;
+    desc += " (*.";
+    desc += filterExtension;
+    desc += ")";
+    std::string ext = "*.";
+    ext += filterExtension;
+    char filter[512];
+    memset(filter, 0, 512);
+    strcpy(filter, desc.c_str());
+    strcpy(filter + desc.length() + 1, ext.c_str());
+
+    char szFileName[256] = "";
+    ofn.lpstrFile = szFileName;
+    ofn.lStructSize = sizeof(ofn);
+    ofn.hwndOwner = GetForegroundWindow();
+    ofn.lpstrTitle = title;
+    ofn.lpstrFilter = filter;
+    ofn.lpstrInitialDir = initialDir.c_str();
+    ofn.nMaxFile = 256;
+    ofn.lpstrDefExt = filter;
+
+    if (mode == FileSystem::OPEN)
+    {
+        ofn.Flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST;
+        GetOpenFileNameA(&ofn);
+    }
+    else
+    {
+        ofn.Flags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT;
+        GetSaveFileNameA(&ofn);
+    }
+
+    filename = szFileName;
+        
+    // Restore current dir
+    SetCurrentDirectoryA(currentDir);
+
+    return filename;
+}
+
+}
+
+#endif

+ 6 - 1
gameplay/src/PlatformiOS.mm

@@ -1697,7 +1697,12 @@ bool Platform::launchURL(const char *url)
 
     return [[UIApplication sharedApplication] openURL:[NSURL URLWithString:[NSString stringWithUTF8String: url]]];
 }
-    
+
+std::string Platform::displayFileDialog(size_t mode, const char* title, const char* filterDescription, const char* filterExtension)
+{
+    return "";
+}
+ 
 }
 
 #endif

+ 477 - 476
gameplay/src/lua/lua_FileSystem.cpp

@@ -1,476 +1,477 @@
-#include "Base.h"
-#include "ScriptController.h"
-#include "lua_FileSystem.h"
-#include "Base.h"
-#include "FileSystem.h"
-#include "Properties.h"
-#include "Stream.h"
-
-namespace gameplay
-{
-
-void luaRegister_FileSystem()
-{
-    const luaL_Reg lua_members[] = 
-    {
-        {NULL, NULL}
-    };
-    const luaL_Reg lua_statics[] = 
-    {
-        {"createFileFromAsset", lua_FileSystem_static_createFileFromAsset},
-        {"fileExists", lua_FileSystem_static_fileExists},
-        {"getDirectoryName", lua_FileSystem_static_getDirectoryName},
-        {"getExtension", lua_FileSystem_static_getExtension},
-        {"getResourcePath", lua_FileSystem_static_getResourcePath},
-        {"isAbsolutePath", lua_FileSystem_static_isAbsolutePath},
-        {"loadResourceAliases", lua_FileSystem_static_loadResourceAliases},
-        {"readAll", lua_FileSystem_static_readAll},
-        {"resolvePath", lua_FileSystem_static_resolvePath},
-        {"setResourcePath", lua_FileSystem_static_setResourcePath},
-        {NULL, NULL}
-    };
-    std::vector<std::string> scopePath;
-
-    gameplay::ScriptUtil::registerClass("FileSystem", lua_members, NULL, lua_FileSystem__gc, lua_statics, scopePath);
-}
-
-static FileSystem* getInstance(lua_State* state)
-{
-    void* userdata = luaL_checkudata(state, 1, "FileSystem");
-    luaL_argcheck(state, userdata != NULL, 1, "'FileSystem' expected.");
-    return (FileSystem*)((gameplay::ScriptUtil::LuaObject*)userdata)->instance;
-}
-
-int lua_FileSystem__gc(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 1:
-        {
-            if ((lua_type(state, 1) == LUA_TUSERDATA))
-            {
-                void* userdata = luaL_checkudata(state, 1, "FileSystem");
-                luaL_argcheck(state, userdata != NULL, 1, "'FileSystem' expected.");
-                gameplay::ScriptUtil::LuaObject* object = (gameplay::ScriptUtil::LuaObject*)userdata;
-                if (object->owns)
-                {
-                    FileSystem* instance = (FileSystem*)object->instance;
-                    SAFE_DELETE(instance);
-                }
-                
-                return 0;
-            }
-
-            lua_pushstring(state, "lua_FileSystem__gc - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 1).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_FileSystem_static_createFileFromAsset(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 1:
-        {
-            if ((lua_type(state, 1) == LUA_TSTRING || lua_type(state, 1) == LUA_TNIL))
-            {
-                // Get parameter 1 off the stack.
-                const char* param1 = gameplay::ScriptUtil::getString(1, false);
-
-                FileSystem::createFileFromAsset(param1);
-                
-                return 0;
-            }
-
-            lua_pushstring(state, "lua_FileSystem_static_createFileFromAsset - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 1).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_FileSystem_static_fileExists(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 1:
-        {
-            if ((lua_type(state, 1) == LUA_TSTRING || lua_type(state, 1) == LUA_TNIL))
-            {
-                // Get parameter 1 off the stack.
-                const char* param1 = gameplay::ScriptUtil::getString(1, false);
-
-                bool result = FileSystem::fileExists(param1);
-
-                // Push the return value onto the stack.
-                lua_pushboolean(state, result);
-
-                return 1;
-            }
-
-            lua_pushstring(state, "lua_FileSystem_static_fileExists - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 1).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_FileSystem_static_getDirectoryName(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 1:
-        {
-            if ((lua_type(state, 1) == LUA_TSTRING || lua_type(state, 1) == LUA_TNIL))
-            {
-                // Get parameter 1 off the stack.
-                const char* param1 = gameplay::ScriptUtil::getString(1, false);
-
-                std::string result = FileSystem::getDirectoryName(param1);
-
-                // Push the return value onto the stack.
-                lua_pushstring(state, result.c_str());
-
-                return 1;
-            }
-
-            lua_pushstring(state, "lua_FileSystem_static_getDirectoryName - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 1).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_FileSystem_static_getExtension(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 1:
-        {
-            if ((lua_type(state, 1) == LUA_TSTRING || lua_type(state, 1) == LUA_TNIL))
-            {
-                // Get parameter 1 off the stack.
-                const char* param1 = gameplay::ScriptUtil::getString(1, false);
-
-                std::string result = FileSystem::getExtension(param1);
-
-                // Push the return value onto the stack.
-                lua_pushstring(state, result.c_str());
-
-                return 1;
-            }
-
-            lua_pushstring(state, "lua_FileSystem_static_getExtension - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 1).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_FileSystem_static_getResourcePath(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 0:
-        {
-            const char* result = FileSystem::getResourcePath();
-
-            // Push the return value onto the stack.
-            lua_pushstring(state, result);
-
-            return 1;
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 0).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_FileSystem_static_isAbsolutePath(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 1:
-        {
-            if ((lua_type(state, 1) == LUA_TSTRING || lua_type(state, 1) == LUA_TNIL))
-            {
-                // Get parameter 1 off the stack.
-                const char* param1 = gameplay::ScriptUtil::getString(1, false);
-
-                bool result = FileSystem::isAbsolutePath(param1);
-
-                // Push the return value onto the stack.
-                lua_pushboolean(state, result);
-
-                return 1;
-            }
-
-            lua_pushstring(state, "lua_FileSystem_static_isAbsolutePath - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 1).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_FileSystem_static_loadResourceAliases(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 1:
-        {
-            do
-            {
-                if ((lua_type(state, 1) == LUA_TSTRING || lua_type(state, 1) == LUA_TNIL))
-                {
-                    // Get parameter 1 off the stack.
-                    const char* param1 = gameplay::ScriptUtil::getString(1, false);
-
-                    FileSystem::loadResourceAliases(param1);
-                    
-                    return 0;
-                }
-            } while (0);
-
-            do
-            {
-                if ((lua_type(state, 1) == LUA_TUSERDATA || lua_type(state, 1) == LUA_TTABLE || lua_type(state, 1) == LUA_TNIL))
-                {
-                    // Get parameter 1 off the stack.
-                    bool param1Valid;
-                    gameplay::ScriptUtil::LuaArray<Properties> param1 = gameplay::ScriptUtil::getObjectPointer<Properties>(1, "Properties", false, &param1Valid);
-                    if (!param1Valid)
-                        break;
-
-                    FileSystem::loadResourceAliases(param1);
-                    
-                    return 0;
-                }
-            } while (0);
-
-            lua_pushstring(state, "lua_FileSystem_static_loadResourceAliases - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 1).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_FileSystem_static_readAll(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 1:
-        {
-            if ((lua_type(state, 1) == LUA_TSTRING || lua_type(state, 1) == LUA_TNIL))
-            {
-                // Get parameter 1 off the stack.
-                const char* param1 = gameplay::ScriptUtil::getString(1, false);
-
-                const char* result = FileSystem::readAll(param1);
-
-                // Push the return value onto the stack.
-                lua_pushstring(state, result);
-
-                return 1;
-            }
-
-            lua_pushstring(state, "lua_FileSystem_static_readAll - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        case 2:
-        {
-            if ((lua_type(state, 1) == LUA_TSTRING || lua_type(state, 1) == LUA_TNIL) &&
-                (lua_type(state, 2) == LUA_TTABLE || lua_type(state, 2) == LUA_TLIGHTUSERDATA))
-            {
-                // Get parameter 1 off the stack.
-                const char* param1 = gameplay::ScriptUtil::getString(1, false);
-
-                // Get parameter 2 off the stack.
-                gameplay::ScriptUtil::LuaArray<int> param2 = gameplay::ScriptUtil::getIntPointer(2);
-
-                const char* result = FileSystem::readAll(param1, param2);
-
-                // Push the return value onto the stack.
-                lua_pushstring(state, result);
-
-                return 1;
-            }
-
-            lua_pushstring(state, "lua_FileSystem_static_readAll - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 1 or 2).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_FileSystem_static_resolvePath(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 1:
-        {
-            if ((lua_type(state, 1) == LUA_TSTRING || lua_type(state, 1) == LUA_TNIL))
-            {
-                // Get parameter 1 off the stack.
-                const char* param1 = gameplay::ScriptUtil::getString(1, false);
-
-                const char* result = FileSystem::resolvePath(param1);
-
-                // Push the return value onto the stack.
-                lua_pushstring(state, result);
-
-                return 1;
-            }
-
-            lua_pushstring(state, "lua_FileSystem_static_resolvePath - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 1).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_FileSystem_static_setResourcePath(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 1:
-        {
-            if ((lua_type(state, 1) == LUA_TSTRING || lua_type(state, 1) == LUA_TNIL))
-            {
-                // Get parameter 1 off the stack.
-                const char* param1 = gameplay::ScriptUtil::getString(1, false);
-
-                FileSystem::setResourcePath(param1);
-                
-                return 0;
-            }
-
-            lua_pushstring(state, "lua_FileSystem_static_setResourcePath - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 1).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-}
+#include "Base.h"
+#include "ScriptController.h"
+#include "lua_FileSystem.h"
+#include "Base.h"
+#include "FileSystem.h"
+#include "Platform.h"
+#include "Properties.h"
+#include "Stream.h"
+
+namespace gameplay
+{
+
+void luaRegister_FileSystem()
+{
+    const luaL_Reg lua_members[] = 
+    {
+        {NULL, NULL}
+    };
+    const luaL_Reg lua_statics[] = 
+    {
+        {"createFileFromAsset", lua_FileSystem_static_createFileFromAsset},
+        {"fileExists", lua_FileSystem_static_fileExists},
+        {"getDirectoryName", lua_FileSystem_static_getDirectoryName},
+        {"getExtension", lua_FileSystem_static_getExtension},
+        {"getResourcePath", lua_FileSystem_static_getResourcePath},
+        {"isAbsolutePath", lua_FileSystem_static_isAbsolutePath},
+        {"loadResourceAliases", lua_FileSystem_static_loadResourceAliases},
+        {"readAll", lua_FileSystem_static_readAll},
+        {"resolvePath", lua_FileSystem_static_resolvePath},
+        {"setResourcePath", lua_FileSystem_static_setResourcePath},
+        {NULL, NULL}
+    };
+    std::vector<std::string> scopePath;
+
+    gameplay::ScriptUtil::registerClass("FileSystem", lua_members, NULL, lua_FileSystem__gc, lua_statics, scopePath);
+}
+
+static FileSystem* getInstance(lua_State* state)
+{
+    void* userdata = luaL_checkudata(state, 1, "FileSystem");
+    luaL_argcheck(state, userdata != NULL, 1, "'FileSystem' expected.");
+    return (FileSystem*)((gameplay::ScriptUtil::LuaObject*)userdata)->instance;
+}
+
+int lua_FileSystem__gc(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                void* userdata = luaL_checkudata(state, 1, "FileSystem");
+                luaL_argcheck(state, userdata != NULL, 1, "'FileSystem' expected.");
+                gameplay::ScriptUtil::LuaObject* object = (gameplay::ScriptUtil::LuaObject*)userdata;
+                if (object->owns)
+                {
+                    FileSystem* instance = (FileSystem*)object->instance;
+                    SAFE_DELETE(instance);
+                }
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_FileSystem__gc - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_FileSystem_static_createFileFromAsset(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TSTRING || lua_type(state, 1) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                const char* param1 = gameplay::ScriptUtil::getString(1, false);
+
+                FileSystem::createFileFromAsset(param1);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_FileSystem_static_createFileFromAsset - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_FileSystem_static_fileExists(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TSTRING || lua_type(state, 1) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                const char* param1 = gameplay::ScriptUtil::getString(1, false);
+
+                bool result = FileSystem::fileExists(param1);
+
+                // Push the return value onto the stack.
+                lua_pushboolean(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_FileSystem_static_fileExists - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_FileSystem_static_getDirectoryName(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TSTRING || lua_type(state, 1) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                const char* param1 = gameplay::ScriptUtil::getString(1, false);
+
+                std::string result = FileSystem::getDirectoryName(param1);
+
+                // Push the return value onto the stack.
+                lua_pushstring(state, result.c_str());
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_FileSystem_static_getDirectoryName - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_FileSystem_static_getExtension(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TSTRING || lua_type(state, 1) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                const char* param1 = gameplay::ScriptUtil::getString(1, false);
+
+                std::string result = FileSystem::getExtension(param1);
+
+                // Push the return value onto the stack.
+                lua_pushstring(state, result.c_str());
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_FileSystem_static_getExtension - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_FileSystem_static_getResourcePath(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 0:
+        {
+            const char* result = FileSystem::getResourcePath();
+
+            // Push the return value onto the stack.
+            lua_pushstring(state, result);
+
+            return 1;
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 0).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_FileSystem_static_isAbsolutePath(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TSTRING || lua_type(state, 1) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                const char* param1 = gameplay::ScriptUtil::getString(1, false);
+
+                bool result = FileSystem::isAbsolutePath(param1);
+
+                // Push the return value onto the stack.
+                lua_pushboolean(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_FileSystem_static_isAbsolutePath - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_FileSystem_static_loadResourceAliases(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            do
+            {
+                if ((lua_type(state, 1) == LUA_TSTRING || lua_type(state, 1) == LUA_TNIL))
+                {
+                    // Get parameter 1 off the stack.
+                    const char* param1 = gameplay::ScriptUtil::getString(1, false);
+
+                    FileSystem::loadResourceAliases(param1);
+                    
+                    return 0;
+                }
+            } while (0);
+
+            do
+            {
+                if ((lua_type(state, 1) == LUA_TUSERDATA || lua_type(state, 1) == LUA_TTABLE || lua_type(state, 1) == LUA_TNIL))
+                {
+                    // Get parameter 1 off the stack.
+                    bool param1Valid;
+                    gameplay::ScriptUtil::LuaArray<Properties> param1 = gameplay::ScriptUtil::getObjectPointer<Properties>(1, "Properties", false, &param1Valid);
+                    if (!param1Valid)
+                        break;
+
+                    FileSystem::loadResourceAliases(param1);
+                    
+                    return 0;
+                }
+            } while (0);
+
+            lua_pushstring(state, "lua_FileSystem_static_loadResourceAliases - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_FileSystem_static_readAll(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TSTRING || lua_type(state, 1) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                const char* param1 = gameplay::ScriptUtil::getString(1, false);
+
+                const char* result = FileSystem::readAll(param1);
+
+                // Push the return value onto the stack.
+                lua_pushstring(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_FileSystem_static_readAll - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        case 2:
+        {
+            if ((lua_type(state, 1) == LUA_TSTRING || lua_type(state, 1) == LUA_TNIL) &&
+                (lua_type(state, 2) == LUA_TTABLE || lua_type(state, 2) == LUA_TLIGHTUSERDATA))
+            {
+                // Get parameter 1 off the stack.
+                const char* param1 = gameplay::ScriptUtil::getString(1, false);
+
+                // Get parameter 2 off the stack.
+                gameplay::ScriptUtil::LuaArray<int> param2 = gameplay::ScriptUtil::getIntPointer(2);
+
+                const char* result = FileSystem::readAll(param1, param2);
+
+                // Push the return value onto the stack.
+                lua_pushstring(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_FileSystem_static_readAll - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1 or 2).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_FileSystem_static_resolvePath(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TSTRING || lua_type(state, 1) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                const char* param1 = gameplay::ScriptUtil::getString(1, false);
+
+                const char* result = FileSystem::resolvePath(param1);
+
+                // Push the return value onto the stack.
+                lua_pushstring(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_FileSystem_static_resolvePath - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_FileSystem_static_setResourcePath(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TSTRING || lua_type(state, 1) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                const char* param1 = gameplay::ScriptUtil::getString(1, false);
+
+                FileSystem::setResourcePath(param1);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_FileSystem_static_setResourcePath - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+}

+ 24 - 24
gameplay/src/lua/lua_FileSystem.h

@@ -1,24 +1,24 @@
-#ifndef LUA_FILESYSTEM_H_
-#define LUA_FILESYSTEM_H_
-
-namespace gameplay
-{
-
-// Lua bindings for FileSystem.
-int lua_FileSystem__gc(lua_State* state);
-int lua_FileSystem_static_createFileFromAsset(lua_State* state);
-int lua_FileSystem_static_fileExists(lua_State* state);
-int lua_FileSystem_static_getDirectoryName(lua_State* state);
-int lua_FileSystem_static_getExtension(lua_State* state);
-int lua_FileSystem_static_getResourcePath(lua_State* state);
-int lua_FileSystem_static_isAbsolutePath(lua_State* state);
-int lua_FileSystem_static_loadResourceAliases(lua_State* state);
-int lua_FileSystem_static_readAll(lua_State* state);
-int lua_FileSystem_static_resolvePath(lua_State* state);
-int lua_FileSystem_static_setResourcePath(lua_State* state);
-
-void luaRegister_FileSystem();
-
-}
-
-#endif
+#ifndef LUA_FILESYSTEM_H_
+#define LUA_FILESYSTEM_H_
+
+namespace gameplay
+{
+
+// Lua bindings for FileSystem.
+int lua_FileSystem__gc(lua_State* state);
+int lua_FileSystem_static_createFileFromAsset(lua_State* state);
+int lua_FileSystem_static_fileExists(lua_State* state);
+int lua_FileSystem_static_getDirectoryName(lua_State* state);
+int lua_FileSystem_static_getExtension(lua_State* state);
+int lua_FileSystem_static_getResourcePath(lua_State* state);
+int lua_FileSystem_static_isAbsolutePath(lua_State* state);
+int lua_FileSystem_static_loadResourceAliases(lua_State* state);
+int lua_FileSystem_static_readAll(lua_State* state);
+int lua_FileSystem_static_resolvePath(lua_State* state);
+int lua_FileSystem_static_setResourcePath(lua_State* state);
+
+void luaRegister_FileSystem();
+
+}
+
+#endif

+ 2507 - 2380
gameplay/src/lua/lua_Game.cpp

@@ -1,2380 +1,2507 @@
-#include "Base.h"
-#include "ScriptController.h"
-#include "lua_Game.h"
-#include "Base.h"
-#include "ControlFactory.h"
-#include "FileSystem.h"
-#include "FrameBuffer.h"
-#include "Game.h"
-#include "Platform.h"
-#include "RenderState.h"
-#include "SceneLoader.h"
-#include "lua_GameClearFlags.h"
-#include "lua_GameState.h"
-#include "lua_GamepadGamepadEvent.h"
-#include "lua_GestureGestureEvent.h"
-#include "lua_KeyboardKeyEvent.h"
-#include "lua_MouseMouseEvent.h"
-#include "lua_TouchTouchEvent.h"
-
-namespace gameplay
-{
-
-void luaRegister_Game()
-{
-    const luaL_Reg lua_members[] = 
-    {
-        {"canExit", lua_Game_canExit},
-        {"clear", lua_Game_clear},
-        {"displayKeyboard", lua_Game_displayKeyboard},
-        {"exit", lua_Game_exit},
-        {"frame", lua_Game_frame},
-        {"gamepadEvent", lua_Game_gamepadEvent},
-        {"gesturePinchEvent", lua_Game_gesturePinchEvent},
-        {"gestureSwipeEvent", lua_Game_gestureSwipeEvent},
-        {"gestureTapEvent", lua_Game_gestureTapEvent},
-        {"getAIController", lua_Game_getAIController},
-        {"getAccelerometerValues", lua_Game_getAccelerometerValues},
-        {"getAnimationController", lua_Game_getAnimationController},
-        {"getAspectRatio", lua_Game_getAspectRatio},
-        {"getAudioController", lua_Game_getAudioController},
-        {"getAudioListener", lua_Game_getAudioListener},
-        {"getConfig", lua_Game_getConfig},
-        {"getFrameRate", lua_Game_getFrameRate},
-        {"getGamepad", lua_Game_getGamepad},
-        {"getGamepadCount", lua_Game_getGamepadCount},
-        {"getHeight", lua_Game_getHeight},
-        {"getPhysicsController", lua_Game_getPhysicsController},
-        {"getScriptController", lua_Game_getScriptController},
-        {"getSensorValues", lua_Game_getSensorValues},
-        {"getState", lua_Game_getState},
-        {"getViewport", lua_Game_getViewport},
-        {"getWidth", lua_Game_getWidth},
-        {"hasAccelerometer", lua_Game_hasAccelerometer},
-        {"hasMouse", lua_Game_hasMouse},
-        {"isCursorVisible", lua_Game_isCursorVisible},
-        {"isGestureRegistered", lua_Game_isGestureRegistered},
-        {"isGestureSupported", lua_Game_isGestureSupported},
-        {"isInitialized", lua_Game_isInitialized},
-        {"isMouseCaptured", lua_Game_isMouseCaptured},
-        {"isMultiSampling", lua_Game_isMultiSampling},
-        {"isMultiTouch", lua_Game_isMultiTouch},
-        {"keyEvent", lua_Game_keyEvent},
-        {"launchURL", lua_Game_launchURL},
-        {"mouseEvent", lua_Game_mouseEvent},
-        {"pause", lua_Game_pause},
-        {"registerGesture", lua_Game_registerGesture},
-        {"resizeEvent", lua_Game_resizeEvent},
-        {"resume", lua_Game_resume},
-        {"run", lua_Game_run},
-        {"schedule", lua_Game_schedule},
-        {"setCursorVisible", lua_Game_setCursorVisible},
-        {"setMouseCaptured", lua_Game_setMouseCaptured},
-        {"setMultiSampling", lua_Game_setMultiSampling},
-        {"setMultiTouch", lua_Game_setMultiTouch},
-        {"setViewport", lua_Game_setViewport},
-        {"touchEvent", lua_Game_touchEvent},
-        {"unregisterGesture", lua_Game_unregisterGesture},
-        {NULL, NULL}
-    };
-    const luaL_Reg lua_statics[] = 
-    {
-        {"getAbsoluteTime", lua_Game_static_getAbsoluteTime},
-        {"getGameTime", lua_Game_static_getGameTime},
-        {"getInstance", lua_Game_static_getInstance},
-        {"isVsync", lua_Game_static_isVsync},
-        {"setVsync", lua_Game_static_setVsync},
-        {NULL, NULL}
-    };
-    std::vector<std::string> scopePath;
-
-    gameplay::ScriptUtil::registerClass("Game", lua_members, NULL, lua_Game__gc, lua_statics, scopePath);
-}
-
-static Game* getInstance(lua_State* state)
-{
-    void* userdata = luaL_checkudata(state, 1, "Game");
-    luaL_argcheck(state, userdata != NULL, 1, "'Game' expected.");
-    return (Game*)((gameplay::ScriptUtil::LuaObject*)userdata)->instance;
-}
-
-int lua_Game__gc(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 1:
-        {
-            if ((lua_type(state, 1) == LUA_TUSERDATA))
-            {
-                void* userdata = luaL_checkudata(state, 1, "Game");
-                luaL_argcheck(state, userdata != NULL, 1, "'Game' expected.");
-                gameplay::ScriptUtil::LuaObject* object = (gameplay::ScriptUtil::LuaObject*)userdata;
-                if (object->owns)
-                {
-                    Game* instance = (Game*)object->instance;
-                    SAFE_DELETE(instance);
-                }
-                
-                return 0;
-            }
-
-            lua_pushstring(state, "lua_Game__gc - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 1).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_Game_canExit(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 1:
-        {
-            if ((lua_type(state, 1) == LUA_TUSERDATA))
-            {
-                Game* instance = getInstance(state);
-                bool result = instance->canExit();
-
-                // Push the return value onto the stack.
-                lua_pushboolean(state, result);
-
-                return 1;
-            }
-
-            lua_pushstring(state, "lua_Game_canExit - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 1).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_Game_clear(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 5:
-        {
-            do
-            {
-                if ((lua_type(state, 1) == LUA_TUSERDATA) &&
-                    (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL) &&
-                    (lua_type(state, 3) == LUA_TUSERDATA || lua_type(state, 3) == LUA_TNIL) &&
-                    lua_type(state, 4) == LUA_TNUMBER &&
-                    lua_type(state, 5) == LUA_TNUMBER)
-                {
-                    // Get parameter 1 off the stack.
-                    Game::ClearFlags param1 = (Game::ClearFlags)lua_enumFromString_GameClearFlags(luaL_checkstring(state, 2));
-
-                    // Get parameter 2 off the stack.
-                    bool param2Valid;
-                    gameplay::ScriptUtil::LuaArray<Vector4> param2 = gameplay::ScriptUtil::getObjectPointer<Vector4>(3, "Vector4", true, &param2Valid);
-                    if (!param2Valid)
-                        break;
-
-                    // Get parameter 3 off the stack.
-                    float param3 = (float)luaL_checknumber(state, 4);
-
-                    // Get parameter 4 off the stack.
-                    int param4 = (int)luaL_checkint(state, 5);
-
-                    Game* instance = getInstance(state);
-                    instance->clear(param1, *param2, param3, param4);
-                    
-                    return 0;
-                }
-            } while (0);
-
-            lua_pushstring(state, "lua_Game_clear - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        case 8:
-        {
-            do
-            {
-                if ((lua_type(state, 1) == LUA_TUSERDATA) &&
-                    (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL) &&
-                    lua_type(state, 3) == LUA_TNUMBER &&
-                    lua_type(state, 4) == LUA_TNUMBER &&
-                    lua_type(state, 5) == LUA_TNUMBER &&
-                    lua_type(state, 6) == LUA_TNUMBER &&
-                    lua_type(state, 7) == LUA_TNUMBER &&
-                    lua_type(state, 8) == LUA_TNUMBER)
-                {
-                    // Get parameter 1 off the stack.
-                    Game::ClearFlags param1 = (Game::ClearFlags)lua_enumFromString_GameClearFlags(luaL_checkstring(state, 2));
-
-                    // Get parameter 2 off the stack.
-                    float param2 = (float)luaL_checknumber(state, 3);
-
-                    // Get parameter 3 off the stack.
-                    float param3 = (float)luaL_checknumber(state, 4);
-
-                    // Get parameter 4 off the stack.
-                    float param4 = (float)luaL_checknumber(state, 5);
-
-                    // Get parameter 5 off the stack.
-                    float param5 = (float)luaL_checknumber(state, 6);
-
-                    // Get parameter 6 off the stack.
-                    float param6 = (float)luaL_checknumber(state, 7);
-
-                    // Get parameter 7 off the stack.
-                    int param7 = (int)luaL_checkint(state, 8);
-
-                    Game* instance = getInstance(state);
-                    instance->clear(param1, param2, param3, param4, param5, param6, param7);
-                    
-                    return 0;
-                }
-            } while (0);
-
-            lua_pushstring(state, "lua_Game_clear - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 5 or 8).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_Game_displayKeyboard(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 2:
-        {
-            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
-                lua_type(state, 2) == LUA_TBOOLEAN)
-            {
-                // Get parameter 1 off the stack.
-                bool param1 = gameplay::ScriptUtil::luaCheckBool(state, 2);
-
-                Game* instance = getInstance(state);
-                instance->displayKeyboard(param1);
-                
-                return 0;
-            }
-
-            lua_pushstring(state, "lua_Game_displayKeyboard - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 2).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_Game_exit(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 1:
-        {
-            if ((lua_type(state, 1) == LUA_TUSERDATA))
-            {
-                Game* instance = getInstance(state);
-                instance->exit();
-                
-                return 0;
-            }
-
-            lua_pushstring(state, "lua_Game_exit - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 1).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_Game_frame(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 1:
-        {
-            if ((lua_type(state, 1) == LUA_TUSERDATA))
-            {
-                Game* instance = getInstance(state);
-                instance->frame();
-                
-                return 0;
-            }
-
-            lua_pushstring(state, "lua_Game_frame - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 1).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_Game_gamepadEvent(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 3:
-        {
-            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
-                (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL) &&
-                (lua_type(state, 3) == LUA_TUSERDATA || lua_type(state, 3) == LUA_TTABLE || lua_type(state, 3) == LUA_TNIL))
-            {
-                // Get parameter 1 off the stack.
-                Gamepad::GamepadEvent param1 = (Gamepad::GamepadEvent)lua_enumFromString_GamepadGamepadEvent(luaL_checkstring(state, 2));
-
-                // Get parameter 2 off the stack.
-                bool param2Valid;
-                gameplay::ScriptUtil::LuaArray<Gamepad> param2 = gameplay::ScriptUtil::getObjectPointer<Gamepad>(3, "Gamepad", false, &param2Valid);
-                if (!param2Valid)
-                {
-                    lua_pushstring(state, "Failed to convert parameter 2 to type 'Gamepad'.");
-                    lua_error(state);
-                }
-
-                Game* instance = getInstance(state);
-                instance->gamepadEvent(param1, param2);
-                
-                return 0;
-            }
-
-            lua_pushstring(state, "lua_Game_gamepadEvent - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 3).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_Game_gesturePinchEvent(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 4:
-        {
-            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
-                lua_type(state, 2) == LUA_TNUMBER &&
-                lua_type(state, 3) == LUA_TNUMBER &&
-                lua_type(state, 4) == LUA_TNUMBER)
-            {
-                // Get parameter 1 off the stack.
-                int param1 = (int)luaL_checkint(state, 2);
-
-                // Get parameter 2 off the stack.
-                int param2 = (int)luaL_checkint(state, 3);
-
-                // Get parameter 3 off the stack.
-                float param3 = (float)luaL_checknumber(state, 4);
-
-                Game* instance = getInstance(state);
-                instance->gesturePinchEvent(param1, param2, param3);
-                
-                return 0;
-            }
-
-            lua_pushstring(state, "lua_Game_gesturePinchEvent - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 4).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_Game_gestureSwipeEvent(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 4:
-        {
-            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
-                lua_type(state, 2) == LUA_TNUMBER &&
-                lua_type(state, 3) == LUA_TNUMBER &&
-                lua_type(state, 4) == LUA_TNUMBER)
-            {
-                // Get parameter 1 off the stack.
-                int param1 = (int)luaL_checkint(state, 2);
-
-                // Get parameter 2 off the stack.
-                int param2 = (int)luaL_checkint(state, 3);
-
-                // Get parameter 3 off the stack.
-                int param3 = (int)luaL_checkint(state, 4);
-
-                Game* instance = getInstance(state);
-                instance->gestureSwipeEvent(param1, param2, param3);
-                
-                return 0;
-            }
-
-            lua_pushstring(state, "lua_Game_gestureSwipeEvent - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 4).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_Game_gestureTapEvent(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 3:
-        {
-            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
-                lua_type(state, 2) == LUA_TNUMBER &&
-                lua_type(state, 3) == LUA_TNUMBER)
-            {
-                // Get parameter 1 off the stack.
-                int param1 = (int)luaL_checkint(state, 2);
-
-                // Get parameter 2 off the stack.
-                int param2 = (int)luaL_checkint(state, 3);
-
-                Game* instance = getInstance(state);
-                instance->gestureTapEvent(param1, param2);
-                
-                return 0;
-            }
-
-            lua_pushstring(state, "lua_Game_gestureTapEvent - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 3).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_Game_getAIController(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 1:
-        {
-            if ((lua_type(state, 1) == LUA_TUSERDATA))
-            {
-                Game* instance = getInstance(state);
-                void* returnPtr = (void*)instance->getAIController();
-                if (returnPtr)
-                {
-                    gameplay::ScriptUtil::LuaObject* object = (gameplay::ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(gameplay::ScriptUtil::LuaObject));
-                    object->instance = returnPtr;
-                    object->owns = false;
-                    luaL_getmetatable(state, "AIController");
-                    lua_setmetatable(state, -2);
-                }
-                else
-                {
-                    lua_pushnil(state);
-                }
-
-                return 1;
-            }
-
-            lua_pushstring(state, "lua_Game_getAIController - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 1).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_Game_getAccelerometerValues(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 3:
-        {
-            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
-                (lua_type(state, 2) == LUA_TTABLE || lua_type(state, 2) == LUA_TLIGHTUSERDATA) &&
-                (lua_type(state, 3) == LUA_TTABLE || lua_type(state, 3) == LUA_TLIGHTUSERDATA))
-            {
-                // Get parameter 1 off the stack.
-                gameplay::ScriptUtil::LuaArray<float> param1 = gameplay::ScriptUtil::getFloatPointer(2);
-
-                // Get parameter 2 off the stack.
-                gameplay::ScriptUtil::LuaArray<float> param2 = gameplay::ScriptUtil::getFloatPointer(3);
-
-                Game* instance = getInstance(state);
-                instance->getAccelerometerValues(param1, param2);
-                
-                return 0;
-            }
-
-            lua_pushstring(state, "lua_Game_getAccelerometerValues - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 3).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_Game_getAnimationController(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 1:
-        {
-            if ((lua_type(state, 1) == LUA_TUSERDATA))
-            {
-                Game* instance = getInstance(state);
-                void* returnPtr = (void*)instance->getAnimationController();
-                if (returnPtr)
-                {
-                    gameplay::ScriptUtil::LuaObject* object = (gameplay::ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(gameplay::ScriptUtil::LuaObject));
-                    object->instance = returnPtr;
-                    object->owns = false;
-                    luaL_getmetatable(state, "AnimationController");
-                    lua_setmetatable(state, -2);
-                }
-                else
-                {
-                    lua_pushnil(state);
-                }
-
-                return 1;
-            }
-
-            lua_pushstring(state, "lua_Game_getAnimationController - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 1).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_Game_getAspectRatio(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 1:
-        {
-            if ((lua_type(state, 1) == LUA_TUSERDATA))
-            {
-                Game* instance = getInstance(state);
-                float result = instance->getAspectRatio();
-
-                // Push the return value onto the stack.
-                lua_pushnumber(state, result);
-
-                return 1;
-            }
-
-            lua_pushstring(state, "lua_Game_getAspectRatio - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 1).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_Game_getAudioController(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 1:
-        {
-            if ((lua_type(state, 1) == LUA_TUSERDATA))
-            {
-                Game* instance = getInstance(state);
-                void* returnPtr = (void*)instance->getAudioController();
-                if (returnPtr)
-                {
-                    gameplay::ScriptUtil::LuaObject* object = (gameplay::ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(gameplay::ScriptUtil::LuaObject));
-                    object->instance = returnPtr;
-                    object->owns = false;
-                    luaL_getmetatable(state, "AudioController");
-                    lua_setmetatable(state, -2);
-                }
-                else
-                {
-                    lua_pushnil(state);
-                }
-
-                return 1;
-            }
-
-            lua_pushstring(state, "lua_Game_getAudioController - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 1).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_Game_getAudioListener(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 1:
-        {
-            if ((lua_type(state, 1) == LUA_TUSERDATA))
-            {
-                Game* instance = getInstance(state);
-                void* returnPtr = (void*)instance->getAudioListener();
-                if (returnPtr)
-                {
-                    gameplay::ScriptUtil::LuaObject* object = (gameplay::ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(gameplay::ScriptUtil::LuaObject));
-                    object->instance = returnPtr;
-                    object->owns = false;
-                    luaL_getmetatable(state, "AudioListener");
-                    lua_setmetatable(state, -2);
-                }
-                else
-                {
-                    lua_pushnil(state);
-                }
-
-                return 1;
-            }
-
-            lua_pushstring(state, "lua_Game_getAudioListener - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 1).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_Game_getConfig(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 1:
-        {
-            if ((lua_type(state, 1) == LUA_TUSERDATA))
-            {
-                Game* instance = getInstance(state);
-                void* returnPtr = (void*)instance->getConfig();
-                if (returnPtr)
-                {
-                    gameplay::ScriptUtil::LuaObject* object = (gameplay::ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(gameplay::ScriptUtil::LuaObject));
-                    object->instance = returnPtr;
-                    object->owns = false;
-                    luaL_getmetatable(state, "Properties");
-                    lua_setmetatable(state, -2);
-                }
-                else
-                {
-                    lua_pushnil(state);
-                }
-
-                return 1;
-            }
-
-            lua_pushstring(state, "lua_Game_getConfig - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 1).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_Game_getFrameRate(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 1:
-        {
-            if ((lua_type(state, 1) == LUA_TUSERDATA))
-            {
-                Game* instance = getInstance(state);
-                unsigned int result = instance->getFrameRate();
-
-                // Push the return value onto the stack.
-                lua_pushunsigned(state, result);
-
-                return 1;
-            }
-
-            lua_pushstring(state, "lua_Game_getFrameRate - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 1).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_Game_getGamepad(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 2:
-        {
-            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
-                lua_type(state, 2) == LUA_TNUMBER)
-            {
-                // Get parameter 1 off the stack.
-                unsigned int param1 = (unsigned int)luaL_checkunsigned(state, 2);
-
-                Game* instance = getInstance(state);
-                void* returnPtr = (void*)instance->getGamepad(param1);
-                if (returnPtr)
-                {
-                    gameplay::ScriptUtil::LuaObject* object = (gameplay::ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(gameplay::ScriptUtil::LuaObject));
-                    object->instance = returnPtr;
-                    object->owns = false;
-                    luaL_getmetatable(state, "Gamepad");
-                    lua_setmetatable(state, -2);
-                }
-                else
-                {
-                    lua_pushnil(state);
-                }
-
-                return 1;
-            }
-
-            lua_pushstring(state, "lua_Game_getGamepad - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        case 3:
-        {
-            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
-                lua_type(state, 2) == LUA_TNUMBER &&
-                lua_type(state, 3) == LUA_TBOOLEAN)
-            {
-                // Get parameter 1 off the stack.
-                unsigned int param1 = (unsigned int)luaL_checkunsigned(state, 2);
-
-                // Get parameter 2 off the stack.
-                bool param2 = gameplay::ScriptUtil::luaCheckBool(state, 3);
-
-                Game* instance = getInstance(state);
-                void* returnPtr = (void*)instance->getGamepad(param1, param2);
-                if (returnPtr)
-                {
-                    gameplay::ScriptUtil::LuaObject* object = (gameplay::ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(gameplay::ScriptUtil::LuaObject));
-                    object->instance = returnPtr;
-                    object->owns = false;
-                    luaL_getmetatable(state, "Gamepad");
-                    lua_setmetatable(state, -2);
-                }
-                else
-                {
-                    lua_pushnil(state);
-                }
-
-                return 1;
-            }
-
-            lua_pushstring(state, "lua_Game_getGamepad - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 2 or 3).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_Game_getGamepadCount(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 1:
-        {
-            if ((lua_type(state, 1) == LUA_TUSERDATA))
-            {
-                Game* instance = getInstance(state);
-                unsigned int result = instance->getGamepadCount();
-
-                // Push the return value onto the stack.
-                lua_pushunsigned(state, result);
-
-                return 1;
-            }
-
-            lua_pushstring(state, "lua_Game_getGamepadCount - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 1).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_Game_getHeight(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 1:
-        {
-            if ((lua_type(state, 1) == LUA_TUSERDATA))
-            {
-                Game* instance = getInstance(state);
-                unsigned int result = instance->getHeight();
-
-                // Push the return value onto the stack.
-                lua_pushunsigned(state, result);
-
-                return 1;
-            }
-
-            lua_pushstring(state, "lua_Game_getHeight - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 1).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_Game_getPhysicsController(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 1:
-        {
-            if ((lua_type(state, 1) == LUA_TUSERDATA))
-            {
-                Game* instance = getInstance(state);
-                void* returnPtr = (void*)instance->getPhysicsController();
-                if (returnPtr)
-                {
-                    gameplay::ScriptUtil::LuaObject* object = (gameplay::ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(gameplay::ScriptUtil::LuaObject));
-                    object->instance = returnPtr;
-                    object->owns = false;
-                    luaL_getmetatable(state, "PhysicsController");
-                    lua_setmetatable(state, -2);
-                }
-                else
-                {
-                    lua_pushnil(state);
-                }
-
-                return 1;
-            }
-
-            lua_pushstring(state, "lua_Game_getPhysicsController - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 1).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_Game_getScriptController(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 1:
-        {
-            if ((lua_type(state, 1) == LUA_TUSERDATA))
-            {
-                Game* instance = getInstance(state);
-                void* returnPtr = (void*)instance->getScriptController();
-                if (returnPtr)
-                {
-                    gameplay::ScriptUtil::LuaObject* object = (gameplay::ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(gameplay::ScriptUtil::LuaObject));
-                    object->instance = returnPtr;
-                    object->owns = false;
-                    luaL_getmetatable(state, "ScriptController");
-                    lua_setmetatable(state, -2);
-                }
-                else
-                {
-                    lua_pushnil(state);
-                }
-
-                return 1;
-            }
-
-            lua_pushstring(state, "lua_Game_getScriptController - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 1).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_Game_getSensorValues(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 7:
-        {
-            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
-                (lua_type(state, 2) == LUA_TTABLE || lua_type(state, 2) == LUA_TLIGHTUSERDATA) &&
-                (lua_type(state, 3) == LUA_TTABLE || lua_type(state, 3) == LUA_TLIGHTUSERDATA) &&
-                (lua_type(state, 4) == LUA_TTABLE || lua_type(state, 4) == LUA_TLIGHTUSERDATA) &&
-                (lua_type(state, 5) == LUA_TTABLE || lua_type(state, 5) == LUA_TLIGHTUSERDATA) &&
-                (lua_type(state, 6) == LUA_TTABLE || lua_type(state, 6) == LUA_TLIGHTUSERDATA) &&
-                (lua_type(state, 7) == LUA_TTABLE || lua_type(state, 7) == LUA_TLIGHTUSERDATA))
-            {
-                // Get parameter 1 off the stack.
-                gameplay::ScriptUtil::LuaArray<float> param1 = gameplay::ScriptUtil::getFloatPointer(2);
-
-                // Get parameter 2 off the stack.
-                gameplay::ScriptUtil::LuaArray<float> param2 = gameplay::ScriptUtil::getFloatPointer(3);
-
-                // Get parameter 3 off the stack.
-                gameplay::ScriptUtil::LuaArray<float> param3 = gameplay::ScriptUtil::getFloatPointer(4);
-
-                // Get parameter 4 off the stack.
-                gameplay::ScriptUtil::LuaArray<float> param4 = gameplay::ScriptUtil::getFloatPointer(5);
-
-                // Get parameter 5 off the stack.
-                gameplay::ScriptUtil::LuaArray<float> param5 = gameplay::ScriptUtil::getFloatPointer(6);
-
-                // Get parameter 6 off the stack.
-                gameplay::ScriptUtil::LuaArray<float> param6 = gameplay::ScriptUtil::getFloatPointer(7);
-
-                Game* instance = getInstance(state);
-                instance->getSensorValues(param1, param2, param3, param4, param5, param6);
-                
-                return 0;
-            }
-
-            lua_pushstring(state, "lua_Game_getSensorValues - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 7).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_Game_getState(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 1:
-        {
-            if ((lua_type(state, 1) == LUA_TUSERDATA))
-            {
-                Game* instance = getInstance(state);
-                Game::State result = instance->getState();
-
-                // Push the return value onto the stack.
-                lua_pushstring(state, lua_stringFromEnum_GameState(result));
-
-                return 1;
-            }
-
-            lua_pushstring(state, "lua_Game_getState - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 1).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_Game_getViewport(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 1:
-        {
-            if ((lua_type(state, 1) == LUA_TUSERDATA))
-            {
-                Game* instance = getInstance(state);
-                void* returnPtr = (void*)&(instance->getViewport());
-                if (returnPtr)
-                {
-                    gameplay::ScriptUtil::LuaObject* object = (gameplay::ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(gameplay::ScriptUtil::LuaObject));
-                    object->instance = returnPtr;
-                    object->owns = false;
-                    luaL_getmetatable(state, "Rectangle");
-                    lua_setmetatable(state, -2);
-                }
-                else
-                {
-                    lua_pushnil(state);
-                }
-
-                return 1;
-            }
-
-            lua_pushstring(state, "lua_Game_getViewport - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 1).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_Game_getWidth(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 1:
-        {
-            if ((lua_type(state, 1) == LUA_TUSERDATA))
-            {
-                Game* instance = getInstance(state);
-                unsigned int result = instance->getWidth();
-
-                // Push the return value onto the stack.
-                lua_pushunsigned(state, result);
-
-                return 1;
-            }
-
-            lua_pushstring(state, "lua_Game_getWidth - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 1).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_Game_hasAccelerometer(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 1:
-        {
-            if ((lua_type(state, 1) == LUA_TUSERDATA))
-            {
-                Game* instance = getInstance(state);
-                bool result = instance->hasAccelerometer();
-
-                // Push the return value onto the stack.
-                lua_pushboolean(state, result);
-
-                return 1;
-            }
-
-            lua_pushstring(state, "lua_Game_hasAccelerometer - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 1).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_Game_hasMouse(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 1:
-        {
-            if ((lua_type(state, 1) == LUA_TUSERDATA))
-            {
-                Game* instance = getInstance(state);
-                bool result = instance->hasMouse();
-
-                // Push the return value onto the stack.
-                lua_pushboolean(state, result);
-
-                return 1;
-            }
-
-            lua_pushstring(state, "lua_Game_hasMouse - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 1).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_Game_isCursorVisible(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 1:
-        {
-            if ((lua_type(state, 1) == LUA_TUSERDATA))
-            {
-                Game* instance = getInstance(state);
-                bool result = instance->isCursorVisible();
-
-                // Push the return value onto the stack.
-                lua_pushboolean(state, result);
-
-                return 1;
-            }
-
-            lua_pushstring(state, "lua_Game_isCursorVisible - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 1).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_Game_isGestureRegistered(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 2:
-        {
-            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
-                (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL))
-            {
-                // Get parameter 1 off the stack.
-                Gesture::GestureEvent param1 = (Gesture::GestureEvent)lua_enumFromString_GestureGestureEvent(luaL_checkstring(state, 2));
-
-                Game* instance = getInstance(state);
-                bool result = instance->isGestureRegistered(param1);
-
-                // Push the return value onto the stack.
-                lua_pushboolean(state, result);
-
-                return 1;
-            }
-
-            lua_pushstring(state, "lua_Game_isGestureRegistered - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 2).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_Game_isGestureSupported(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 2:
-        {
-            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
-                (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL))
-            {
-                // Get parameter 1 off the stack.
-                Gesture::GestureEvent param1 = (Gesture::GestureEvent)lua_enumFromString_GestureGestureEvent(luaL_checkstring(state, 2));
-
-                Game* instance = getInstance(state);
-                bool result = instance->isGestureSupported(param1);
-
-                // Push the return value onto the stack.
-                lua_pushboolean(state, result);
-
-                return 1;
-            }
-
-            lua_pushstring(state, "lua_Game_isGestureSupported - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 2).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_Game_isInitialized(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 1:
-        {
-            if ((lua_type(state, 1) == LUA_TUSERDATA))
-            {
-                Game* instance = getInstance(state);
-                bool result = instance->isInitialized();
-
-                // Push the return value onto the stack.
-                lua_pushboolean(state, result);
-
-                return 1;
-            }
-
-            lua_pushstring(state, "lua_Game_isInitialized - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 1).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_Game_isMouseCaptured(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 1:
-        {
-            if ((lua_type(state, 1) == LUA_TUSERDATA))
-            {
-                Game* instance = getInstance(state);
-                bool result = instance->isMouseCaptured();
-
-                // Push the return value onto the stack.
-                lua_pushboolean(state, result);
-
-                return 1;
-            }
-
-            lua_pushstring(state, "lua_Game_isMouseCaptured - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 1).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_Game_isMultiSampling(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 1:
-        {
-            if ((lua_type(state, 1) == LUA_TUSERDATA))
-            {
-                Game* instance = getInstance(state);
-                bool result = instance->isMultiSampling();
-
-                // Push the return value onto the stack.
-                lua_pushboolean(state, result);
-
-                return 1;
-            }
-
-            lua_pushstring(state, "lua_Game_isMultiSampling - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 1).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_Game_isMultiTouch(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 1:
-        {
-            if ((lua_type(state, 1) == LUA_TUSERDATA))
-            {
-                Game* instance = getInstance(state);
-                bool result = instance->isMultiTouch();
-
-                // Push the return value onto the stack.
-                lua_pushboolean(state, result);
-
-                return 1;
-            }
-
-            lua_pushstring(state, "lua_Game_isMultiTouch - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 1).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_Game_keyEvent(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 3:
-        {
-            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
-                (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL) &&
-                lua_type(state, 3) == LUA_TNUMBER)
-            {
-                // Get parameter 1 off the stack.
-                Keyboard::KeyEvent param1 = (Keyboard::KeyEvent)lua_enumFromString_KeyboardKeyEvent(luaL_checkstring(state, 2));
-
-                // Get parameter 2 off the stack.
-                int param2 = (int)luaL_checkint(state, 3);
-
-                Game* instance = getInstance(state);
-                instance->keyEvent(param1, param2);
-                
-                return 0;
-            }
-
-            lua_pushstring(state, "lua_Game_keyEvent - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 3).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_Game_launchURL(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 2:
-        {
-            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
-                (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL))
-            {
-                // Get parameter 1 off the stack.
-                const char* param1 = gameplay::ScriptUtil::getString(2, false);
-
-                Game* instance = getInstance(state);
-                bool result = instance->launchURL(param1);
-
-                // Push the return value onto the stack.
-                lua_pushboolean(state, result);
-
-                return 1;
-            }
-
-            lua_pushstring(state, "lua_Game_launchURL - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 2).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_Game_mouseEvent(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 5:
-        {
-            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
-                (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL) &&
-                lua_type(state, 3) == LUA_TNUMBER &&
-                lua_type(state, 4) == LUA_TNUMBER &&
-                lua_type(state, 5) == LUA_TNUMBER)
-            {
-                // Get parameter 1 off the stack.
-                Mouse::MouseEvent param1 = (Mouse::MouseEvent)lua_enumFromString_MouseMouseEvent(luaL_checkstring(state, 2));
-
-                // Get parameter 2 off the stack.
-                int param2 = (int)luaL_checkint(state, 3);
-
-                // Get parameter 3 off the stack.
-                int param3 = (int)luaL_checkint(state, 4);
-
-                // Get parameter 4 off the stack.
-                int param4 = (int)luaL_checkint(state, 5);
-
-                Game* instance = getInstance(state);
-                bool result = instance->mouseEvent(param1, param2, param3, param4);
-
-                // Push the return value onto the stack.
-                lua_pushboolean(state, result);
-
-                return 1;
-            }
-
-            lua_pushstring(state, "lua_Game_mouseEvent - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 5).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_Game_pause(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 1:
-        {
-            if ((lua_type(state, 1) == LUA_TUSERDATA))
-            {
-                Game* instance = getInstance(state);
-                instance->pause();
-                
-                return 0;
-            }
-
-            lua_pushstring(state, "lua_Game_pause - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 1).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_Game_registerGesture(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 2:
-        {
-            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
-                (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL))
-            {
-                // Get parameter 1 off the stack.
-                Gesture::GestureEvent param1 = (Gesture::GestureEvent)lua_enumFromString_GestureGestureEvent(luaL_checkstring(state, 2));
-
-                Game* instance = getInstance(state);
-                instance->registerGesture(param1);
-                
-                return 0;
-            }
-
-            lua_pushstring(state, "lua_Game_registerGesture - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 2).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_Game_resizeEvent(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 3:
-        {
-            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
-                lua_type(state, 2) == LUA_TNUMBER &&
-                lua_type(state, 3) == LUA_TNUMBER)
-            {
-                // Get parameter 1 off the stack.
-                unsigned int param1 = (unsigned int)luaL_checkunsigned(state, 2);
-
-                // Get parameter 2 off the stack.
-                unsigned int param2 = (unsigned int)luaL_checkunsigned(state, 3);
-
-                Game* instance = getInstance(state);
-                instance->resizeEvent(param1, param2);
-                
-                return 0;
-            }
-
-            lua_pushstring(state, "lua_Game_resizeEvent - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 3).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_Game_resume(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 1:
-        {
-            if ((lua_type(state, 1) == LUA_TUSERDATA))
-            {
-                Game* instance = getInstance(state);
-                instance->resume();
-                
-                return 0;
-            }
-
-            lua_pushstring(state, "lua_Game_resume - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 1).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_Game_run(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 1:
-        {
-            if ((lua_type(state, 1) == LUA_TUSERDATA))
-            {
-                Game* instance = getInstance(state);
-                int result = instance->run();
-
-                // Push the return value onto the stack.
-                lua_pushinteger(state, result);
-
-                return 1;
-            }
-
-            lua_pushstring(state, "lua_Game_run - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 1).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_Game_schedule(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 3:
-        {
-            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
-                lua_type(state, 2) == LUA_TNUMBER &&
-                (lua_type(state, 3) == LUA_TSTRING || lua_type(state, 3) == LUA_TNIL))
-            {
-                // Get parameter 1 off the stack.
-                float param1 = (float)luaL_checknumber(state, 2);
-
-                // Get parameter 2 off the stack.
-                const char* param2 = gameplay::ScriptUtil::getString(3, false);
-
-                Game* instance = getInstance(state);
-                instance->schedule(param1, param2);
-                
-                return 0;
-            }
-
-            lua_pushstring(state, "lua_Game_schedule - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 3).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_Game_setCursorVisible(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 2:
-        {
-            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
-                lua_type(state, 2) == LUA_TBOOLEAN)
-            {
-                // Get parameter 1 off the stack.
-                bool param1 = gameplay::ScriptUtil::luaCheckBool(state, 2);
-
-                Game* instance = getInstance(state);
-                instance->setCursorVisible(param1);
-                
-                return 0;
-            }
-
-            lua_pushstring(state, "lua_Game_setCursorVisible - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 2).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_Game_setMouseCaptured(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 2:
-        {
-            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
-                lua_type(state, 2) == LUA_TBOOLEAN)
-            {
-                // Get parameter 1 off the stack.
-                bool param1 = gameplay::ScriptUtil::luaCheckBool(state, 2);
-
-                Game* instance = getInstance(state);
-                instance->setMouseCaptured(param1);
-                
-                return 0;
-            }
-
-            lua_pushstring(state, "lua_Game_setMouseCaptured - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 2).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_Game_setMultiSampling(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 2:
-        {
-            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
-                lua_type(state, 2) == LUA_TBOOLEAN)
-            {
-                // Get parameter 1 off the stack.
-                bool param1 = gameplay::ScriptUtil::luaCheckBool(state, 2);
-
-                Game* instance = getInstance(state);
-                instance->setMultiSampling(param1);
-                
-                return 0;
-            }
-
-            lua_pushstring(state, "lua_Game_setMultiSampling - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 2).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_Game_setMultiTouch(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 2:
-        {
-            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
-                lua_type(state, 2) == LUA_TBOOLEAN)
-            {
-                // Get parameter 1 off the stack.
-                bool param1 = gameplay::ScriptUtil::luaCheckBool(state, 2);
-
-                Game* instance = getInstance(state);
-                instance->setMultiTouch(param1);
-                
-                return 0;
-            }
-
-            lua_pushstring(state, "lua_Game_setMultiTouch - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 2).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_Game_setViewport(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 2:
-        {
-            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
-                (lua_type(state, 2) == LUA_TUSERDATA || lua_type(state, 2) == LUA_TNIL))
-            {
-                // Get parameter 1 off the stack.
-                bool param1Valid;
-                gameplay::ScriptUtil::LuaArray<Rectangle> param1 = gameplay::ScriptUtil::getObjectPointer<Rectangle>(2, "Rectangle", true, &param1Valid);
-                if (!param1Valid)
-                {
-                    lua_pushstring(state, "Failed to convert parameter 1 to type 'Rectangle'.");
-                    lua_error(state);
-                }
-
-                Game* instance = getInstance(state);
-                instance->setViewport(*param1);
-                
-                return 0;
-            }
-
-            lua_pushstring(state, "lua_Game_setViewport - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 2).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_Game_static_getAbsoluteTime(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 0:
-        {
-            double result = Game::getAbsoluteTime();
-
-            // Push the return value onto the stack.
-            lua_pushnumber(state, result);
-
-            return 1;
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 0).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_Game_static_getGameTime(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 0:
-        {
-            double result = Game::getGameTime();
-
-            // Push the return value onto the stack.
-            lua_pushnumber(state, result);
-
-            return 1;
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 0).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_Game_static_getInstance(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 0:
-        {
-            void* returnPtr = (void*)Game::getInstance();
-            if (returnPtr)
-            {
-                gameplay::ScriptUtil::LuaObject* object = (gameplay::ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(gameplay::ScriptUtil::LuaObject));
-                object->instance = returnPtr;
-                object->owns = false;
-                luaL_getmetatable(state, "Game");
-                lua_setmetatable(state, -2);
-            }
-            else
-            {
-                lua_pushnil(state);
-            }
-
-            return 1;
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 0).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_Game_static_isVsync(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 0:
-        {
-            bool result = Game::isVsync();
-
-            // Push the return value onto the stack.
-            lua_pushboolean(state, result);
-
-            return 1;
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 0).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_Game_static_setVsync(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 1:
-        {
-            if (lua_type(state, 1) == LUA_TBOOLEAN)
-            {
-                // Get parameter 1 off the stack.
-                bool param1 = gameplay::ScriptUtil::luaCheckBool(state, 1);
-
-                Game::setVsync(param1);
-                
-                return 0;
-            }
-
-            lua_pushstring(state, "lua_Game_static_setVsync - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 1).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_Game_touchEvent(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 5:
-        {
-            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
-                (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL) &&
-                lua_type(state, 3) == LUA_TNUMBER &&
-                lua_type(state, 4) == LUA_TNUMBER &&
-                lua_type(state, 5) == LUA_TNUMBER)
-            {
-                // Get parameter 1 off the stack.
-                Touch::TouchEvent param1 = (Touch::TouchEvent)lua_enumFromString_TouchTouchEvent(luaL_checkstring(state, 2));
-
-                // Get parameter 2 off the stack.
-                int param2 = (int)luaL_checkint(state, 3);
-
-                // Get parameter 3 off the stack.
-                int param3 = (int)luaL_checkint(state, 4);
-
-                // Get parameter 4 off the stack.
-                unsigned int param4 = (unsigned int)luaL_checkunsigned(state, 5);
-
-                Game* instance = getInstance(state);
-                instance->touchEvent(param1, param2, param3, param4);
-                
-                return 0;
-            }
-
-            lua_pushstring(state, "lua_Game_touchEvent - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 5).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_Game_unregisterGesture(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 2:
-        {
-            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
-                (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL))
-            {
-                // Get parameter 1 off the stack.
-                Gesture::GestureEvent param1 = (Gesture::GestureEvent)lua_enumFromString_GestureGestureEvent(luaL_checkstring(state, 2));
-
-                Game* instance = getInstance(state);
-                instance->unregisterGesture(param1);
-                
-                return 0;
-            }
-
-            lua_pushstring(state, "lua_Game_unregisterGesture - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 2).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-}
+#include "Base.h"
+#include "ScriptController.h"
+#include "lua_Game.h"
+#include "Base.h"
+#include "ControlFactory.h"
+#include "FileSystem.h"
+#include "FrameBuffer.h"
+#include "Game.h"
+#include "Platform.h"
+#include "RenderState.h"
+#include "SceneLoader.h"
+#include "lua_GameClearFlags.h"
+#include "lua_GameState.h"
+#include "lua_GamepadGamepadEvent.h"
+#include "lua_GestureGestureEvent.h"
+#include "lua_KeyboardKeyEvent.h"
+#include "lua_MouseMouseEvent.h"
+#include "lua_TouchTouchEvent.h"
+
+namespace gameplay
+{
+
+void luaRegister_Game()
+{
+    const luaL_Reg lua_members[] = 
+    {
+        {"canExit", lua_Game_canExit},
+        {"clear", lua_Game_clear},
+        {"displayKeyboard", lua_Game_displayKeyboard},
+        {"exit", lua_Game_exit},
+        {"frame", lua_Game_frame},
+        {"gamepadEvent", lua_Game_gamepadEvent},
+        {"gestureDragEvent", lua_Game_gestureDragEvent},
+        {"gestureDropEvent", lua_Game_gestureDropEvent},
+        {"gestureLongTapEvent", lua_Game_gestureLongTapEvent},
+        {"gesturePinchEvent", lua_Game_gesturePinchEvent},
+        {"gestureSwipeEvent", lua_Game_gestureSwipeEvent},
+        {"gestureTapEvent", lua_Game_gestureTapEvent},
+        {"getAIController", lua_Game_getAIController},
+        {"getAccelerometerValues", lua_Game_getAccelerometerValues},
+        {"getAnimationController", lua_Game_getAnimationController},
+        {"getAspectRatio", lua_Game_getAspectRatio},
+        {"getAudioController", lua_Game_getAudioController},
+        {"getAudioListener", lua_Game_getAudioListener},
+        {"getConfig", lua_Game_getConfig},
+        {"getFrameRate", lua_Game_getFrameRate},
+        {"getGamepad", lua_Game_getGamepad},
+        {"getGamepadCount", lua_Game_getGamepadCount},
+        {"getHeight", lua_Game_getHeight},
+        {"getPhysicsController", lua_Game_getPhysicsController},
+        {"getScriptController", lua_Game_getScriptController},
+        {"getSensorValues", lua_Game_getSensorValues},
+        {"getState", lua_Game_getState},
+        {"getViewport", lua_Game_getViewport},
+        {"getWidth", lua_Game_getWidth},
+        {"hasAccelerometer", lua_Game_hasAccelerometer},
+        {"hasMouse", lua_Game_hasMouse},
+        {"isCursorVisible", lua_Game_isCursorVisible},
+        {"isGestureRegistered", lua_Game_isGestureRegistered},
+        {"isGestureSupported", lua_Game_isGestureSupported},
+        {"isInitialized", lua_Game_isInitialized},
+        {"isMouseCaptured", lua_Game_isMouseCaptured},
+        {"isMultiSampling", lua_Game_isMultiSampling},
+        {"isMultiTouch", lua_Game_isMultiTouch},
+        {"keyEvent", lua_Game_keyEvent},
+        {"launchURL", lua_Game_launchURL},
+        {"mouseEvent", lua_Game_mouseEvent},
+        {"pause", lua_Game_pause},
+        {"registerGesture", lua_Game_registerGesture},
+        {"resizeEvent", lua_Game_resizeEvent},
+        {"resume", lua_Game_resume},
+        {"run", lua_Game_run},
+        {"schedule", lua_Game_schedule},
+        {"setCursorVisible", lua_Game_setCursorVisible},
+        {"setMouseCaptured", lua_Game_setMouseCaptured},
+        {"setMultiSampling", lua_Game_setMultiSampling},
+        {"setMultiTouch", lua_Game_setMultiTouch},
+        {"setViewport", lua_Game_setViewport},
+        {"touchEvent", lua_Game_touchEvent},
+        {"unregisterGesture", lua_Game_unregisterGesture},
+        {NULL, NULL}
+    };
+    const luaL_Reg lua_statics[] = 
+    {
+        {"getAbsoluteTime", lua_Game_static_getAbsoluteTime},
+        {"getGameTime", lua_Game_static_getGameTime},
+        {"getInstance", lua_Game_static_getInstance},
+        {"isVsync", lua_Game_static_isVsync},
+        {"setVsync", lua_Game_static_setVsync},
+        {NULL, NULL}
+    };
+    std::vector<std::string> scopePath;
+
+    gameplay::ScriptUtil::registerClass("Game", lua_members, NULL, lua_Game__gc, lua_statics, scopePath);
+}
+
+static Game* getInstance(lua_State* state)
+{
+    void* userdata = luaL_checkudata(state, 1, "Game");
+    luaL_argcheck(state, userdata != NULL, 1, "'Game' expected.");
+    return (Game*)((gameplay::ScriptUtil::LuaObject*)userdata)->instance;
+}
+
+int lua_Game__gc(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                void* userdata = luaL_checkudata(state, 1, "Game");
+                luaL_argcheck(state, userdata != NULL, 1, "'Game' expected.");
+                gameplay::ScriptUtil::LuaObject* object = (gameplay::ScriptUtil::LuaObject*)userdata;
+                if (object->owns)
+                {
+                    Game* instance = (Game*)object->instance;
+                    SAFE_DELETE(instance);
+                }
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Game__gc - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Game_canExit(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                Game* instance = getInstance(state);
+                bool result = instance->canExit();
+
+                // Push the return value onto the stack.
+                lua_pushboolean(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Game_canExit - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Game_clear(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 5:
+        {
+            do
+            {
+                if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                    (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL) &&
+                    (lua_type(state, 3) == LUA_TUSERDATA || lua_type(state, 3) == LUA_TNIL) &&
+                    lua_type(state, 4) == LUA_TNUMBER &&
+                    lua_type(state, 5) == LUA_TNUMBER)
+                {
+                    // Get parameter 1 off the stack.
+                    Game::ClearFlags param1 = (Game::ClearFlags)lua_enumFromString_GameClearFlags(luaL_checkstring(state, 2));
+
+                    // Get parameter 2 off the stack.
+                    bool param2Valid;
+                    gameplay::ScriptUtil::LuaArray<Vector4> param2 = gameplay::ScriptUtil::getObjectPointer<Vector4>(3, "Vector4", true, &param2Valid);
+                    if (!param2Valid)
+                        break;
+
+                    // Get parameter 3 off the stack.
+                    float param3 = (float)luaL_checknumber(state, 4);
+
+                    // Get parameter 4 off the stack.
+                    int param4 = (int)luaL_checkint(state, 5);
+
+                    Game* instance = getInstance(state);
+                    instance->clear(param1, *param2, param3, param4);
+                    
+                    return 0;
+                }
+            } while (0);
+
+            lua_pushstring(state, "lua_Game_clear - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        case 8:
+        {
+            do
+            {
+                if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                    (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL) &&
+                    lua_type(state, 3) == LUA_TNUMBER &&
+                    lua_type(state, 4) == LUA_TNUMBER &&
+                    lua_type(state, 5) == LUA_TNUMBER &&
+                    lua_type(state, 6) == LUA_TNUMBER &&
+                    lua_type(state, 7) == LUA_TNUMBER &&
+                    lua_type(state, 8) == LUA_TNUMBER)
+                {
+                    // Get parameter 1 off the stack.
+                    Game::ClearFlags param1 = (Game::ClearFlags)lua_enumFromString_GameClearFlags(luaL_checkstring(state, 2));
+
+                    // Get parameter 2 off the stack.
+                    float param2 = (float)luaL_checknumber(state, 3);
+
+                    // Get parameter 3 off the stack.
+                    float param3 = (float)luaL_checknumber(state, 4);
+
+                    // Get parameter 4 off the stack.
+                    float param4 = (float)luaL_checknumber(state, 5);
+
+                    // Get parameter 5 off the stack.
+                    float param5 = (float)luaL_checknumber(state, 6);
+
+                    // Get parameter 6 off the stack.
+                    float param6 = (float)luaL_checknumber(state, 7);
+
+                    // Get parameter 7 off the stack.
+                    int param7 = (int)luaL_checkint(state, 8);
+
+                    Game* instance = getInstance(state);
+                    instance->clear(param1, param2, param3, param4, param5, param6, param7);
+                    
+                    return 0;
+                }
+            } while (0);
+
+            lua_pushstring(state, "lua_Game_clear - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 5 or 8).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Game_displayKeyboard(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 2:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TBOOLEAN)
+            {
+                // Get parameter 1 off the stack.
+                bool param1 = gameplay::ScriptUtil::luaCheckBool(state, 2);
+
+                Game* instance = getInstance(state);
+                instance->displayKeyboard(param1);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Game_displayKeyboard - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 2).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Game_exit(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                Game* instance = getInstance(state);
+                instance->exit();
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Game_exit - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Game_frame(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                Game* instance = getInstance(state);
+                instance->frame();
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Game_frame - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Game_gamepadEvent(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 3:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL) &&
+                (lua_type(state, 3) == LUA_TUSERDATA || lua_type(state, 3) == LUA_TTABLE || lua_type(state, 3) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                Gamepad::GamepadEvent param1 = (Gamepad::GamepadEvent)lua_enumFromString_GamepadGamepadEvent(luaL_checkstring(state, 2));
+
+                // Get parameter 2 off the stack.
+                bool param2Valid;
+                gameplay::ScriptUtil::LuaArray<Gamepad> param2 = gameplay::ScriptUtil::getObjectPointer<Gamepad>(3, "Gamepad", false, &param2Valid);
+                if (!param2Valid)
+                {
+                    lua_pushstring(state, "Failed to convert parameter 2 to type 'Gamepad'.");
+                    lua_error(state);
+                }
+
+                Game* instance = getInstance(state);
+                instance->gamepadEvent(param1, param2);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Game_gamepadEvent - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 3).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Game_gestureDragEvent(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 3:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TNUMBER &&
+                lua_type(state, 3) == LUA_TNUMBER)
+            {
+                // Get parameter 1 off the stack.
+                int param1 = (int)luaL_checkint(state, 2);
+
+                // Get parameter 2 off the stack.
+                int param2 = (int)luaL_checkint(state, 3);
+
+                Game* instance = getInstance(state);
+                instance->gestureDragEvent(param1, param2);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Game_gestureDragEvent - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 3).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Game_gestureDropEvent(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 3:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TNUMBER &&
+                lua_type(state, 3) == LUA_TNUMBER)
+            {
+                // Get parameter 1 off the stack.
+                int param1 = (int)luaL_checkint(state, 2);
+
+                // Get parameter 2 off the stack.
+                int param2 = (int)luaL_checkint(state, 3);
+
+                Game* instance = getInstance(state);
+                instance->gestureDropEvent(param1, param2);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Game_gestureDropEvent - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 3).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Game_gestureLongTapEvent(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 4:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TNUMBER &&
+                lua_type(state, 3) == LUA_TNUMBER &&
+                lua_type(state, 4) == LUA_TNUMBER)
+            {
+                // Get parameter 1 off the stack.
+                int param1 = (int)luaL_checkint(state, 2);
+
+                // Get parameter 2 off the stack.
+                int param2 = (int)luaL_checkint(state, 3);
+
+                // Get parameter 3 off the stack.
+                float param3 = (float)luaL_checknumber(state, 4);
+
+                Game* instance = getInstance(state);
+                instance->gestureLongTapEvent(param1, param2, param3);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Game_gestureLongTapEvent - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 4).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Game_gesturePinchEvent(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 4:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TNUMBER &&
+                lua_type(state, 3) == LUA_TNUMBER &&
+                lua_type(state, 4) == LUA_TNUMBER)
+            {
+                // Get parameter 1 off the stack.
+                int param1 = (int)luaL_checkint(state, 2);
+
+                // Get parameter 2 off the stack.
+                int param2 = (int)luaL_checkint(state, 3);
+
+                // Get parameter 3 off the stack.
+                float param3 = (float)luaL_checknumber(state, 4);
+
+                Game* instance = getInstance(state);
+                instance->gesturePinchEvent(param1, param2, param3);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Game_gesturePinchEvent - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 4).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Game_gestureSwipeEvent(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 4:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TNUMBER &&
+                lua_type(state, 3) == LUA_TNUMBER &&
+                lua_type(state, 4) == LUA_TNUMBER)
+            {
+                // Get parameter 1 off the stack.
+                int param1 = (int)luaL_checkint(state, 2);
+
+                // Get parameter 2 off the stack.
+                int param2 = (int)luaL_checkint(state, 3);
+
+                // Get parameter 3 off the stack.
+                int param3 = (int)luaL_checkint(state, 4);
+
+                Game* instance = getInstance(state);
+                instance->gestureSwipeEvent(param1, param2, param3);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Game_gestureSwipeEvent - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 4).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Game_gestureTapEvent(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 3:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TNUMBER &&
+                lua_type(state, 3) == LUA_TNUMBER)
+            {
+                // Get parameter 1 off the stack.
+                int param1 = (int)luaL_checkint(state, 2);
+
+                // Get parameter 2 off the stack.
+                int param2 = (int)luaL_checkint(state, 3);
+
+                Game* instance = getInstance(state);
+                instance->gestureTapEvent(param1, param2);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Game_gestureTapEvent - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 3).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Game_getAIController(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                Game* instance = getInstance(state);
+                void* returnPtr = (void*)instance->getAIController();
+                if (returnPtr)
+                {
+                    gameplay::ScriptUtil::LuaObject* object = (gameplay::ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(gameplay::ScriptUtil::LuaObject));
+                    object->instance = returnPtr;
+                    object->owns = false;
+                    luaL_getmetatable(state, "AIController");
+                    lua_setmetatable(state, -2);
+                }
+                else
+                {
+                    lua_pushnil(state);
+                }
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Game_getAIController - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Game_getAccelerometerValues(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 3:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                (lua_type(state, 2) == LUA_TTABLE || lua_type(state, 2) == LUA_TLIGHTUSERDATA) &&
+                (lua_type(state, 3) == LUA_TTABLE || lua_type(state, 3) == LUA_TLIGHTUSERDATA))
+            {
+                // Get parameter 1 off the stack.
+                gameplay::ScriptUtil::LuaArray<float> param1 = gameplay::ScriptUtil::getFloatPointer(2);
+
+                // Get parameter 2 off the stack.
+                gameplay::ScriptUtil::LuaArray<float> param2 = gameplay::ScriptUtil::getFloatPointer(3);
+
+                Game* instance = getInstance(state);
+                instance->getAccelerometerValues(param1, param2);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Game_getAccelerometerValues - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 3).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Game_getAnimationController(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                Game* instance = getInstance(state);
+                void* returnPtr = (void*)instance->getAnimationController();
+                if (returnPtr)
+                {
+                    gameplay::ScriptUtil::LuaObject* object = (gameplay::ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(gameplay::ScriptUtil::LuaObject));
+                    object->instance = returnPtr;
+                    object->owns = false;
+                    luaL_getmetatable(state, "AnimationController");
+                    lua_setmetatable(state, -2);
+                }
+                else
+                {
+                    lua_pushnil(state);
+                }
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Game_getAnimationController - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Game_getAspectRatio(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                Game* instance = getInstance(state);
+                float result = instance->getAspectRatio();
+
+                // Push the return value onto the stack.
+                lua_pushnumber(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Game_getAspectRatio - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Game_getAudioController(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                Game* instance = getInstance(state);
+                void* returnPtr = (void*)instance->getAudioController();
+                if (returnPtr)
+                {
+                    gameplay::ScriptUtil::LuaObject* object = (gameplay::ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(gameplay::ScriptUtil::LuaObject));
+                    object->instance = returnPtr;
+                    object->owns = false;
+                    luaL_getmetatable(state, "AudioController");
+                    lua_setmetatable(state, -2);
+                }
+                else
+                {
+                    lua_pushnil(state);
+                }
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Game_getAudioController - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Game_getAudioListener(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                Game* instance = getInstance(state);
+                void* returnPtr = (void*)instance->getAudioListener();
+                if (returnPtr)
+                {
+                    gameplay::ScriptUtil::LuaObject* object = (gameplay::ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(gameplay::ScriptUtil::LuaObject));
+                    object->instance = returnPtr;
+                    object->owns = false;
+                    luaL_getmetatable(state, "AudioListener");
+                    lua_setmetatable(state, -2);
+                }
+                else
+                {
+                    lua_pushnil(state);
+                }
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Game_getAudioListener - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Game_getConfig(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                Game* instance = getInstance(state);
+                void* returnPtr = (void*)instance->getConfig();
+                if (returnPtr)
+                {
+                    gameplay::ScriptUtil::LuaObject* object = (gameplay::ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(gameplay::ScriptUtil::LuaObject));
+                    object->instance = returnPtr;
+                    object->owns = false;
+                    luaL_getmetatable(state, "Properties");
+                    lua_setmetatable(state, -2);
+                }
+                else
+                {
+                    lua_pushnil(state);
+                }
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Game_getConfig - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Game_getFrameRate(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                Game* instance = getInstance(state);
+                unsigned int result = instance->getFrameRate();
+
+                // Push the return value onto the stack.
+                lua_pushunsigned(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Game_getFrameRate - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Game_getGamepad(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 2:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TNUMBER)
+            {
+                // Get parameter 1 off the stack.
+                unsigned int param1 = (unsigned int)luaL_checkunsigned(state, 2);
+
+                Game* instance = getInstance(state);
+                void* returnPtr = (void*)instance->getGamepad(param1);
+                if (returnPtr)
+                {
+                    gameplay::ScriptUtil::LuaObject* object = (gameplay::ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(gameplay::ScriptUtil::LuaObject));
+                    object->instance = returnPtr;
+                    object->owns = false;
+                    luaL_getmetatable(state, "Gamepad");
+                    lua_setmetatable(state, -2);
+                }
+                else
+                {
+                    lua_pushnil(state);
+                }
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Game_getGamepad - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        case 3:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TNUMBER &&
+                lua_type(state, 3) == LUA_TBOOLEAN)
+            {
+                // Get parameter 1 off the stack.
+                unsigned int param1 = (unsigned int)luaL_checkunsigned(state, 2);
+
+                // Get parameter 2 off the stack.
+                bool param2 = gameplay::ScriptUtil::luaCheckBool(state, 3);
+
+                Game* instance = getInstance(state);
+                void* returnPtr = (void*)instance->getGamepad(param1, param2);
+                if (returnPtr)
+                {
+                    gameplay::ScriptUtil::LuaObject* object = (gameplay::ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(gameplay::ScriptUtil::LuaObject));
+                    object->instance = returnPtr;
+                    object->owns = false;
+                    luaL_getmetatable(state, "Gamepad");
+                    lua_setmetatable(state, -2);
+                }
+                else
+                {
+                    lua_pushnil(state);
+                }
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Game_getGamepad - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 2 or 3).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Game_getGamepadCount(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                Game* instance = getInstance(state);
+                unsigned int result = instance->getGamepadCount();
+
+                // Push the return value onto the stack.
+                lua_pushunsigned(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Game_getGamepadCount - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Game_getHeight(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                Game* instance = getInstance(state);
+                unsigned int result = instance->getHeight();
+
+                // Push the return value onto the stack.
+                lua_pushunsigned(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Game_getHeight - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Game_getPhysicsController(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                Game* instance = getInstance(state);
+                void* returnPtr = (void*)instance->getPhysicsController();
+                if (returnPtr)
+                {
+                    gameplay::ScriptUtil::LuaObject* object = (gameplay::ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(gameplay::ScriptUtil::LuaObject));
+                    object->instance = returnPtr;
+                    object->owns = false;
+                    luaL_getmetatable(state, "PhysicsController");
+                    lua_setmetatable(state, -2);
+                }
+                else
+                {
+                    lua_pushnil(state);
+                }
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Game_getPhysicsController - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Game_getScriptController(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                Game* instance = getInstance(state);
+                void* returnPtr = (void*)instance->getScriptController();
+                if (returnPtr)
+                {
+                    gameplay::ScriptUtil::LuaObject* object = (gameplay::ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(gameplay::ScriptUtil::LuaObject));
+                    object->instance = returnPtr;
+                    object->owns = false;
+                    luaL_getmetatable(state, "ScriptController");
+                    lua_setmetatable(state, -2);
+                }
+                else
+                {
+                    lua_pushnil(state);
+                }
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Game_getScriptController - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Game_getSensorValues(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 7:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                (lua_type(state, 2) == LUA_TTABLE || lua_type(state, 2) == LUA_TLIGHTUSERDATA) &&
+                (lua_type(state, 3) == LUA_TTABLE || lua_type(state, 3) == LUA_TLIGHTUSERDATA) &&
+                (lua_type(state, 4) == LUA_TTABLE || lua_type(state, 4) == LUA_TLIGHTUSERDATA) &&
+                (lua_type(state, 5) == LUA_TTABLE || lua_type(state, 5) == LUA_TLIGHTUSERDATA) &&
+                (lua_type(state, 6) == LUA_TTABLE || lua_type(state, 6) == LUA_TLIGHTUSERDATA) &&
+                (lua_type(state, 7) == LUA_TTABLE || lua_type(state, 7) == LUA_TLIGHTUSERDATA))
+            {
+                // Get parameter 1 off the stack.
+                gameplay::ScriptUtil::LuaArray<float> param1 = gameplay::ScriptUtil::getFloatPointer(2);
+
+                // Get parameter 2 off the stack.
+                gameplay::ScriptUtil::LuaArray<float> param2 = gameplay::ScriptUtil::getFloatPointer(3);
+
+                // Get parameter 3 off the stack.
+                gameplay::ScriptUtil::LuaArray<float> param3 = gameplay::ScriptUtil::getFloatPointer(4);
+
+                // Get parameter 4 off the stack.
+                gameplay::ScriptUtil::LuaArray<float> param4 = gameplay::ScriptUtil::getFloatPointer(5);
+
+                // Get parameter 5 off the stack.
+                gameplay::ScriptUtil::LuaArray<float> param5 = gameplay::ScriptUtil::getFloatPointer(6);
+
+                // Get parameter 6 off the stack.
+                gameplay::ScriptUtil::LuaArray<float> param6 = gameplay::ScriptUtil::getFloatPointer(7);
+
+                Game* instance = getInstance(state);
+                instance->getSensorValues(param1, param2, param3, param4, param5, param6);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Game_getSensorValues - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 7).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Game_getState(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                Game* instance = getInstance(state);
+                Game::State result = instance->getState();
+
+                // Push the return value onto the stack.
+                lua_pushstring(state, lua_stringFromEnum_GameState(result));
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Game_getState - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Game_getViewport(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                Game* instance = getInstance(state);
+                void* returnPtr = (void*)&(instance->getViewport());
+                if (returnPtr)
+                {
+                    gameplay::ScriptUtil::LuaObject* object = (gameplay::ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(gameplay::ScriptUtil::LuaObject));
+                    object->instance = returnPtr;
+                    object->owns = false;
+                    luaL_getmetatable(state, "Rectangle");
+                    lua_setmetatable(state, -2);
+                }
+                else
+                {
+                    lua_pushnil(state);
+                }
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Game_getViewport - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Game_getWidth(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                Game* instance = getInstance(state);
+                unsigned int result = instance->getWidth();
+
+                // Push the return value onto the stack.
+                lua_pushunsigned(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Game_getWidth - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Game_hasAccelerometer(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                Game* instance = getInstance(state);
+                bool result = instance->hasAccelerometer();
+
+                // Push the return value onto the stack.
+                lua_pushboolean(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Game_hasAccelerometer - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Game_hasMouse(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                Game* instance = getInstance(state);
+                bool result = instance->hasMouse();
+
+                // Push the return value onto the stack.
+                lua_pushboolean(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Game_hasMouse - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Game_isCursorVisible(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                Game* instance = getInstance(state);
+                bool result = instance->isCursorVisible();
+
+                // Push the return value onto the stack.
+                lua_pushboolean(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Game_isCursorVisible - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Game_isGestureRegistered(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 2:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                Gesture::GestureEvent param1 = (Gesture::GestureEvent)lua_enumFromString_GestureGestureEvent(luaL_checkstring(state, 2));
+
+                Game* instance = getInstance(state);
+                bool result = instance->isGestureRegistered(param1);
+
+                // Push the return value onto the stack.
+                lua_pushboolean(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Game_isGestureRegistered - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 2).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Game_isGestureSupported(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 2:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                Gesture::GestureEvent param1 = (Gesture::GestureEvent)lua_enumFromString_GestureGestureEvent(luaL_checkstring(state, 2));
+
+                Game* instance = getInstance(state);
+                bool result = instance->isGestureSupported(param1);
+
+                // Push the return value onto the stack.
+                lua_pushboolean(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Game_isGestureSupported - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 2).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Game_isInitialized(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                Game* instance = getInstance(state);
+                bool result = instance->isInitialized();
+
+                // Push the return value onto the stack.
+                lua_pushboolean(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Game_isInitialized - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Game_isMouseCaptured(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                Game* instance = getInstance(state);
+                bool result = instance->isMouseCaptured();
+
+                // Push the return value onto the stack.
+                lua_pushboolean(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Game_isMouseCaptured - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Game_isMultiSampling(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                Game* instance = getInstance(state);
+                bool result = instance->isMultiSampling();
+
+                // Push the return value onto the stack.
+                lua_pushboolean(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Game_isMultiSampling - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Game_isMultiTouch(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                Game* instance = getInstance(state);
+                bool result = instance->isMultiTouch();
+
+                // Push the return value onto the stack.
+                lua_pushboolean(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Game_isMultiTouch - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Game_keyEvent(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 3:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL) &&
+                lua_type(state, 3) == LUA_TNUMBER)
+            {
+                // Get parameter 1 off the stack.
+                Keyboard::KeyEvent param1 = (Keyboard::KeyEvent)lua_enumFromString_KeyboardKeyEvent(luaL_checkstring(state, 2));
+
+                // Get parameter 2 off the stack.
+                int param2 = (int)luaL_checkint(state, 3);
+
+                Game* instance = getInstance(state);
+                instance->keyEvent(param1, param2);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Game_keyEvent - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 3).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Game_launchURL(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 2:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                const char* param1 = gameplay::ScriptUtil::getString(2, false);
+
+                Game* instance = getInstance(state);
+                bool result = instance->launchURL(param1);
+
+                // Push the return value onto the stack.
+                lua_pushboolean(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Game_launchURL - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 2).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Game_mouseEvent(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 5:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL) &&
+                lua_type(state, 3) == LUA_TNUMBER &&
+                lua_type(state, 4) == LUA_TNUMBER &&
+                lua_type(state, 5) == LUA_TNUMBER)
+            {
+                // Get parameter 1 off the stack.
+                Mouse::MouseEvent param1 = (Mouse::MouseEvent)lua_enumFromString_MouseMouseEvent(luaL_checkstring(state, 2));
+
+                // Get parameter 2 off the stack.
+                int param2 = (int)luaL_checkint(state, 3);
+
+                // Get parameter 3 off the stack.
+                int param3 = (int)luaL_checkint(state, 4);
+
+                // Get parameter 4 off the stack.
+                int param4 = (int)luaL_checkint(state, 5);
+
+                Game* instance = getInstance(state);
+                bool result = instance->mouseEvent(param1, param2, param3, param4);
+
+                // Push the return value onto the stack.
+                lua_pushboolean(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Game_mouseEvent - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 5).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Game_pause(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                Game* instance = getInstance(state);
+                instance->pause();
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Game_pause - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Game_registerGesture(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 2:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                Gesture::GestureEvent param1 = (Gesture::GestureEvent)lua_enumFromString_GestureGestureEvent(luaL_checkstring(state, 2));
+
+                Game* instance = getInstance(state);
+                instance->registerGesture(param1);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Game_registerGesture - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 2).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Game_resizeEvent(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 3:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TNUMBER &&
+                lua_type(state, 3) == LUA_TNUMBER)
+            {
+                // Get parameter 1 off the stack.
+                unsigned int param1 = (unsigned int)luaL_checkunsigned(state, 2);
+
+                // Get parameter 2 off the stack.
+                unsigned int param2 = (unsigned int)luaL_checkunsigned(state, 3);
+
+                Game* instance = getInstance(state);
+                instance->resizeEvent(param1, param2);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Game_resizeEvent - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 3).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Game_resume(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                Game* instance = getInstance(state);
+                instance->resume();
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Game_resume - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Game_run(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                Game* instance = getInstance(state);
+                int result = instance->run();
+
+                // Push the return value onto the stack.
+                lua_pushinteger(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Game_run - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Game_schedule(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 3:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TNUMBER &&
+                (lua_type(state, 3) == LUA_TSTRING || lua_type(state, 3) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                float param1 = (float)luaL_checknumber(state, 2);
+
+                // Get parameter 2 off the stack.
+                const char* param2 = gameplay::ScriptUtil::getString(3, false);
+
+                Game* instance = getInstance(state);
+                instance->schedule(param1, param2);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Game_schedule - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 3).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Game_setCursorVisible(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 2:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TBOOLEAN)
+            {
+                // Get parameter 1 off the stack.
+                bool param1 = gameplay::ScriptUtil::luaCheckBool(state, 2);
+
+                Game* instance = getInstance(state);
+                instance->setCursorVisible(param1);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Game_setCursorVisible - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 2).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Game_setMouseCaptured(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 2:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TBOOLEAN)
+            {
+                // Get parameter 1 off the stack.
+                bool param1 = gameplay::ScriptUtil::luaCheckBool(state, 2);
+
+                Game* instance = getInstance(state);
+                instance->setMouseCaptured(param1);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Game_setMouseCaptured - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 2).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Game_setMultiSampling(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 2:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TBOOLEAN)
+            {
+                // Get parameter 1 off the stack.
+                bool param1 = gameplay::ScriptUtil::luaCheckBool(state, 2);
+
+                Game* instance = getInstance(state);
+                instance->setMultiSampling(param1);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Game_setMultiSampling - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 2).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Game_setMultiTouch(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 2:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TBOOLEAN)
+            {
+                // Get parameter 1 off the stack.
+                bool param1 = gameplay::ScriptUtil::luaCheckBool(state, 2);
+
+                Game* instance = getInstance(state);
+                instance->setMultiTouch(param1);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Game_setMultiTouch - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 2).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Game_setViewport(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 2:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                (lua_type(state, 2) == LUA_TUSERDATA || lua_type(state, 2) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                bool param1Valid;
+                gameplay::ScriptUtil::LuaArray<Rectangle> param1 = gameplay::ScriptUtil::getObjectPointer<Rectangle>(2, "Rectangle", true, &param1Valid);
+                if (!param1Valid)
+                {
+                    lua_pushstring(state, "Failed to convert parameter 1 to type 'Rectangle'.");
+                    lua_error(state);
+                }
+
+                Game* instance = getInstance(state);
+                instance->setViewport(*param1);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Game_setViewport - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 2).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Game_static_getAbsoluteTime(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 0:
+        {
+            double result = Game::getAbsoluteTime();
+
+            // Push the return value onto the stack.
+            lua_pushnumber(state, result);
+
+            return 1;
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 0).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Game_static_getGameTime(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 0:
+        {
+            double result = Game::getGameTime();
+
+            // Push the return value onto the stack.
+            lua_pushnumber(state, result);
+
+            return 1;
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 0).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Game_static_getInstance(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 0:
+        {
+            void* returnPtr = (void*)Game::getInstance();
+            if (returnPtr)
+            {
+                gameplay::ScriptUtil::LuaObject* object = (gameplay::ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(gameplay::ScriptUtil::LuaObject));
+                object->instance = returnPtr;
+                object->owns = false;
+                luaL_getmetatable(state, "Game");
+                lua_setmetatable(state, -2);
+            }
+            else
+            {
+                lua_pushnil(state);
+            }
+
+            return 1;
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 0).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Game_static_isVsync(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 0:
+        {
+            bool result = Game::isVsync();
+
+            // Push the return value onto the stack.
+            lua_pushboolean(state, result);
+
+            return 1;
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 0).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Game_static_setVsync(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if (lua_type(state, 1) == LUA_TBOOLEAN)
+            {
+                // Get parameter 1 off the stack.
+                bool param1 = gameplay::ScriptUtil::luaCheckBool(state, 1);
+
+                Game::setVsync(param1);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Game_static_setVsync - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Game_touchEvent(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 5:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL) &&
+                lua_type(state, 3) == LUA_TNUMBER &&
+                lua_type(state, 4) == LUA_TNUMBER &&
+                lua_type(state, 5) == LUA_TNUMBER)
+            {
+                // Get parameter 1 off the stack.
+                Touch::TouchEvent param1 = (Touch::TouchEvent)lua_enumFromString_TouchTouchEvent(luaL_checkstring(state, 2));
+
+                // Get parameter 2 off the stack.
+                int param2 = (int)luaL_checkint(state, 3);
+
+                // Get parameter 3 off the stack.
+                int param3 = (int)luaL_checkint(state, 4);
+
+                // Get parameter 4 off the stack.
+                unsigned int param4 = (unsigned int)luaL_checkunsigned(state, 5);
+
+                Game* instance = getInstance(state);
+                instance->touchEvent(param1, param2, param3, param4);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Game_touchEvent - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 5).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Game_unregisterGesture(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 2:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                Gesture::GestureEvent param1 = (Gesture::GestureEvent)lua_enumFromString_GestureGestureEvent(luaL_checkstring(state, 2));
+
+                Game* instance = getInstance(state);
+                instance->unregisterGesture(param1);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Game_unregisterGesture - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 2).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+}

+ 73 - 70
gameplay/src/lua/lua_Game.h

@@ -1,70 +1,73 @@
-#ifndef LUA_GAME_H_
-#define LUA_GAME_H_
-
-namespace gameplay
-{
-
-// Lua bindings for Game.
-int lua_Game__gc(lua_State* state);
-int lua_Game_canExit(lua_State* state);
-int lua_Game_clear(lua_State* state);
-int lua_Game_displayKeyboard(lua_State* state);
-int lua_Game_exit(lua_State* state);
-int lua_Game_frame(lua_State* state);
-int lua_Game_gamepadEvent(lua_State* state);
-int lua_Game_gesturePinchEvent(lua_State* state);
-int lua_Game_gestureSwipeEvent(lua_State* state);
-int lua_Game_gestureTapEvent(lua_State* state);
-int lua_Game_getAIController(lua_State* state);
-int lua_Game_getAccelerometerValues(lua_State* state);
-int lua_Game_getAnimationController(lua_State* state);
-int lua_Game_getAspectRatio(lua_State* state);
-int lua_Game_getAudioController(lua_State* state);
-int lua_Game_getAudioListener(lua_State* state);
-int lua_Game_getConfig(lua_State* state);
-int lua_Game_getFrameRate(lua_State* state);
-int lua_Game_getGamepad(lua_State* state);
-int lua_Game_getGamepadCount(lua_State* state);
-int lua_Game_getHeight(lua_State* state);
-int lua_Game_getPhysicsController(lua_State* state);
-int lua_Game_getScriptController(lua_State* state);
-int lua_Game_getSensorValues(lua_State* state);
-int lua_Game_getState(lua_State* state);
-int lua_Game_getViewport(lua_State* state);
-int lua_Game_getWidth(lua_State* state);
-int lua_Game_hasAccelerometer(lua_State* state);
-int lua_Game_hasMouse(lua_State* state);
-int lua_Game_isCursorVisible(lua_State* state);
-int lua_Game_isGestureRegistered(lua_State* state);
-int lua_Game_isGestureSupported(lua_State* state);
-int lua_Game_isInitialized(lua_State* state);
-int lua_Game_isMouseCaptured(lua_State* state);
-int lua_Game_isMultiSampling(lua_State* state);
-int lua_Game_isMultiTouch(lua_State* state);
-int lua_Game_keyEvent(lua_State* state);
-int lua_Game_launchURL(lua_State* state);
-int lua_Game_mouseEvent(lua_State* state);
-int lua_Game_pause(lua_State* state);
-int lua_Game_registerGesture(lua_State* state);
-int lua_Game_resizeEvent(lua_State* state);
-int lua_Game_resume(lua_State* state);
-int lua_Game_run(lua_State* state);
-int lua_Game_schedule(lua_State* state);
-int lua_Game_setCursorVisible(lua_State* state);
-int lua_Game_setMouseCaptured(lua_State* state);
-int lua_Game_setMultiSampling(lua_State* state);
-int lua_Game_setMultiTouch(lua_State* state);
-int lua_Game_setViewport(lua_State* state);
-int lua_Game_static_getAbsoluteTime(lua_State* state);
-int lua_Game_static_getGameTime(lua_State* state);
-int lua_Game_static_getInstance(lua_State* state);
-int lua_Game_static_isVsync(lua_State* state);
-int lua_Game_static_setVsync(lua_State* state);
-int lua_Game_touchEvent(lua_State* state);
-int lua_Game_unregisterGesture(lua_State* state);
-
-void luaRegister_Game();
-
-}
-
-#endif
+#ifndef LUA_GAME_H_
+#define LUA_GAME_H_
+
+namespace gameplay
+{
+
+// Lua bindings for Game.
+int lua_Game__gc(lua_State* state);
+int lua_Game_canExit(lua_State* state);
+int lua_Game_clear(lua_State* state);
+int lua_Game_displayKeyboard(lua_State* state);
+int lua_Game_exit(lua_State* state);
+int lua_Game_frame(lua_State* state);
+int lua_Game_gamepadEvent(lua_State* state);
+int lua_Game_gestureDragEvent(lua_State* state);
+int lua_Game_gestureDropEvent(lua_State* state);
+int lua_Game_gestureLongTapEvent(lua_State* state);
+int lua_Game_gesturePinchEvent(lua_State* state);
+int lua_Game_gestureSwipeEvent(lua_State* state);
+int lua_Game_gestureTapEvent(lua_State* state);
+int lua_Game_getAIController(lua_State* state);
+int lua_Game_getAccelerometerValues(lua_State* state);
+int lua_Game_getAnimationController(lua_State* state);
+int lua_Game_getAspectRatio(lua_State* state);
+int lua_Game_getAudioController(lua_State* state);
+int lua_Game_getAudioListener(lua_State* state);
+int lua_Game_getConfig(lua_State* state);
+int lua_Game_getFrameRate(lua_State* state);
+int lua_Game_getGamepad(lua_State* state);
+int lua_Game_getGamepadCount(lua_State* state);
+int lua_Game_getHeight(lua_State* state);
+int lua_Game_getPhysicsController(lua_State* state);
+int lua_Game_getScriptController(lua_State* state);
+int lua_Game_getSensorValues(lua_State* state);
+int lua_Game_getState(lua_State* state);
+int lua_Game_getViewport(lua_State* state);
+int lua_Game_getWidth(lua_State* state);
+int lua_Game_hasAccelerometer(lua_State* state);
+int lua_Game_hasMouse(lua_State* state);
+int lua_Game_isCursorVisible(lua_State* state);
+int lua_Game_isGestureRegistered(lua_State* state);
+int lua_Game_isGestureSupported(lua_State* state);
+int lua_Game_isInitialized(lua_State* state);
+int lua_Game_isMouseCaptured(lua_State* state);
+int lua_Game_isMultiSampling(lua_State* state);
+int lua_Game_isMultiTouch(lua_State* state);
+int lua_Game_keyEvent(lua_State* state);
+int lua_Game_launchURL(lua_State* state);
+int lua_Game_mouseEvent(lua_State* state);
+int lua_Game_pause(lua_State* state);
+int lua_Game_registerGesture(lua_State* state);
+int lua_Game_resizeEvent(lua_State* state);
+int lua_Game_resume(lua_State* state);
+int lua_Game_run(lua_State* state);
+int lua_Game_schedule(lua_State* state);
+int lua_Game_setCursorVisible(lua_State* state);
+int lua_Game_setMouseCaptured(lua_State* state);
+int lua_Game_setMultiSampling(lua_State* state);
+int lua_Game_setMultiTouch(lua_State* state);
+int lua_Game_setViewport(lua_State* state);
+int lua_Game_static_getAbsoluteTime(lua_State* state);
+int lua_Game_static_getGameTime(lua_State* state);
+int lua_Game_static_getInstance(lua_State* state);
+int lua_Game_static_isVsync(lua_State* state);
+int lua_Game_static_setVsync(lua_State* state);
+int lua_Game_touchEvent(lua_State* state);
+int lua_Game_unregisterGesture(lua_State* state);
+
+void luaRegister_Game();
+
+}
+
+#endif

+ 56 - 41
gameplay/src/lua/lua_GestureGestureEvent.cpp

@@ -1,41 +1,56 @@
-#include "Base.h"
-#include "lua_GestureGestureEvent.h"
-
-namespace gameplay
-{
-
-static const char* enumStringEmpty = "";
-
-static const char* luaEnumString_GestureGestureEvent_GESTURE_TAP = "GESTURE_TAP";
-static const char* luaEnumString_GestureGestureEvent_GESTURE_SWIPE = "GESTURE_SWIPE";
-static const char* luaEnumString_GestureGestureEvent_GESTURE_PINCH = "GESTURE_PINCH";
-static const char* luaEnumString_GestureGestureEvent_GESTURE_ANY_SUPPORTED = "GESTURE_ANY_SUPPORTED";
-
-Gesture::GestureEvent lua_enumFromString_GestureGestureEvent(const char* s)
-{
-    if (strcmp(s, luaEnumString_GestureGestureEvent_GESTURE_TAP) == 0)
-        return Gesture::GESTURE_TAP;
-    if (strcmp(s, luaEnumString_GestureGestureEvent_GESTURE_SWIPE) == 0)
-        return Gesture::GESTURE_SWIPE;
-    if (strcmp(s, luaEnumString_GestureGestureEvent_GESTURE_PINCH) == 0)
-        return Gesture::GESTURE_PINCH;
-    if (strcmp(s, luaEnumString_GestureGestureEvent_GESTURE_ANY_SUPPORTED) == 0)
-        return Gesture::GESTURE_ANY_SUPPORTED;
-    return Gesture::GESTURE_TAP;
-}
-
-const char* lua_stringFromEnum_GestureGestureEvent(Gesture::GestureEvent e)
-{
-    if (e == Gesture::GESTURE_TAP)
-        return luaEnumString_GestureGestureEvent_GESTURE_TAP;
-    if (e == Gesture::GESTURE_SWIPE)
-        return luaEnumString_GestureGestureEvent_GESTURE_SWIPE;
-    if (e == Gesture::GESTURE_PINCH)
-        return luaEnumString_GestureGestureEvent_GESTURE_PINCH;
-    if (e == Gesture::GESTURE_ANY_SUPPORTED)
-        return luaEnumString_GestureGestureEvent_GESTURE_ANY_SUPPORTED;
-    return enumStringEmpty;
-}
-
-}
-
+#include "Base.h"
+#include "lua_GestureGestureEvent.h"
+
+namespace gameplay
+{
+
+static const char* enumStringEmpty = "";
+
+static const char* luaEnumString_GestureGestureEvent_GESTURE_TAP = "GESTURE_TAP";
+static const char* luaEnumString_GestureGestureEvent_GESTURE_SWIPE = "GESTURE_SWIPE";
+static const char* luaEnumString_GestureGestureEvent_GESTURE_PINCH = "GESTURE_PINCH";
+static const char* luaEnumString_GestureGestureEvent_GESTURE_LONG_TAP = "GESTURE_LONG_TAP";
+static const char* luaEnumString_GestureGestureEvent_GESTURE_DRAG = "GESTURE_DRAG";
+static const char* luaEnumString_GestureGestureEvent_GESTURE_DROP = "GESTURE_DROP";
+static const char* luaEnumString_GestureGestureEvent_GESTURE_ANY_SUPPORTED = "GESTURE_ANY_SUPPORTED";
+
+Gesture::GestureEvent lua_enumFromString_GestureGestureEvent(const char* s)
+{
+    if (strcmp(s, luaEnumString_GestureGestureEvent_GESTURE_TAP) == 0)
+        return Gesture::GESTURE_TAP;
+    if (strcmp(s, luaEnumString_GestureGestureEvent_GESTURE_SWIPE) == 0)
+        return Gesture::GESTURE_SWIPE;
+    if (strcmp(s, luaEnumString_GestureGestureEvent_GESTURE_PINCH) == 0)
+        return Gesture::GESTURE_PINCH;
+    if (strcmp(s, luaEnumString_GestureGestureEvent_GESTURE_LONG_TAP) == 0)
+        return Gesture::GESTURE_LONG_TAP;
+    if (strcmp(s, luaEnumString_GestureGestureEvent_GESTURE_DRAG) == 0)
+        return Gesture::GESTURE_DRAG;
+    if (strcmp(s, luaEnumString_GestureGestureEvent_GESTURE_DROP) == 0)
+        return Gesture::GESTURE_DROP;
+    if (strcmp(s, luaEnumString_GestureGestureEvent_GESTURE_ANY_SUPPORTED) == 0)
+        return Gesture::GESTURE_ANY_SUPPORTED;
+    return Gesture::GESTURE_TAP;
+}
+
+const char* lua_stringFromEnum_GestureGestureEvent(Gesture::GestureEvent e)
+{
+    if (e == Gesture::GESTURE_TAP)
+        return luaEnumString_GestureGestureEvent_GESTURE_TAP;
+    if (e == Gesture::GESTURE_SWIPE)
+        return luaEnumString_GestureGestureEvent_GESTURE_SWIPE;
+    if (e == Gesture::GESTURE_PINCH)
+        return luaEnumString_GestureGestureEvent_GESTURE_PINCH;
+    if (e == Gesture::GESTURE_LONG_TAP)
+        return luaEnumString_GestureGestureEvent_GESTURE_LONG_TAP;
+    if (e == Gesture::GESTURE_DRAG)
+        return luaEnumString_GestureGestureEvent_GESTURE_DRAG;
+    if (e == Gesture::GESTURE_DROP)
+        return luaEnumString_GestureGestureEvent_GESTURE_DROP;
+    if (e == Gesture::GESTURE_ANY_SUPPORTED)
+        return luaEnumString_GestureGestureEvent_GESTURE_ANY_SUPPORTED;
+    return enumStringEmpty;
+}
+
+}
+

+ 3 - 0
gameplay/src/lua/lua_Global.cpp

@@ -416,6 +416,9 @@ void luaRegister_lua_Global()
         gameplay::ScriptUtil::registerConstantString("GESTURE_TAP", "GESTURE_TAP", scopePath);
         gameplay::ScriptUtil::registerConstantString("GESTURE_SWIPE", "GESTURE_SWIPE", scopePath);
         gameplay::ScriptUtil::registerConstantString("GESTURE_PINCH", "GESTURE_PINCH", scopePath);
+        gameplay::ScriptUtil::registerConstantString("GESTURE_LONG_TAP", "GESTURE_LONG_TAP", scopePath);
+        gameplay::ScriptUtil::registerConstantString("GESTURE_DRAG", "GESTURE_DRAG", scopePath);
+        gameplay::ScriptUtil::registerConstantString("GESTURE_DROP", "GESTURE_DROP", scopePath);
         gameplay::ScriptUtil::registerConstantString("GESTURE_ANY_SUPPORTED", "GESTURE_ANY_SUPPORTED", scopePath);
     }
 

+ 64 - 64
gameplay/src/lua/lua_Global.h

@@ -1,64 +1,64 @@
-#ifndef LUA_GLOBAL_H_
-#define LUA_GLOBAL_H_
-
-#include "lua_AIMessageParameterType.h"
-#include "lua_AnimationClipListenerEventType.h"
-#include "lua_AudioSourceState.h"
-#include "lua_CameraType.h"
-#include "lua_ContainerScroll.h"
-#include "lua_ControlAlignment.h"
-#include "lua_ControlAutoSize.h"
-#include "lua_ControlListenerEventType.h"
-#include "lua_ControlState.h"
-#include "lua_CurveInterpolationType.h"
-#include "lua_DepthStencilTargetFormat.h"
-#include "lua_FontFormat.h"
-#include "lua_FontJustify.h"
-#include "lua_FontStyle.h"
-#include "lua_GameClearFlags.h"
-#include "lua_GameState.h"
-#include "lua_GamepadButtonMapping.h"
-#include "lua_GamepadGamepadEvent.h"
-#include "lua_GestureGestureEvent.h"
-#include "lua_ImageFormat.h"
-#include "lua_KeyboardKey.h"
-#include "lua_KeyboardKeyEvent.h"
-#include "lua_LayoutType.h"
-#include "lua_LightType.h"
-#include "lua_LoggerLevel.h"
-#include "lua_MeshIndexFormat.h"
-#include "lua_MeshPrimitiveType.h"
-#include "lua_MouseMouseEvent.h"
-#include "lua_NodeType.h"
-#include "lua_ParticleEmitterTextureBlending.h"
-#include "lua_PhysicsCollisionObjectCollisionListenerEventType.h"
-#include "lua_PhysicsCollisionObjectType.h"
-#include "lua_PhysicsCollisionShapeType.h"
-#include "lua_PhysicsControllerListenerEventType.h"
-#include "lua_PropertiesType.h"
-#include "lua_RenderStateAutoBinding.h"
-#include "lua_RenderStateBlend.h"
-#include "lua_RenderStateCullFaceSide.h"
-#include "lua_RenderStateDepthFunction.h"
-#include "lua_RenderStateFrontFace.h"
-#include "lua_RenderStateStencilFunction.h"
-#include "lua_RenderStateStencilOperation.h"
-#include "lua_TerrainFlags.h"
-#include "lua_TextBoxInputMode.h"
-#include "lua_TextureFilter.h"
-#include "lua_TextureFormat.h"
-#include "lua_TextureWrap.h"
-#include "lua_TouchTouchEvent.h"
-#include "lua_VertexFormatUsage.h"
-
-namespace gameplay
-{
-
-// Global enum to string conversion function (used to pass enums to Lua from C++).
-const char* lua_stringFromEnumGlobal(std::string& enumname, unsigned int value);
-
-void luaRegister_lua_Global();
-
-}
-
-#endif
+#ifndef LUA_GLOBAL_H_
+#define LUA_GLOBAL_H_
+
+#include "lua_AIMessageParameterType.h"
+#include "lua_AnimationClipListenerEventType.h"
+#include "lua_AudioSourceState.h"
+#include "lua_CameraType.h"
+#include "lua_ContainerScroll.h"
+#include "lua_ControlAlignment.h"
+#include "lua_ControlAutoSize.h"
+#include "lua_ControlListenerEventType.h"
+#include "lua_ControlState.h"
+#include "lua_CurveInterpolationType.h"
+#include "lua_DepthStencilTargetFormat.h"
+#include "lua_FontFormat.h"
+#include "lua_FontJustify.h"
+#include "lua_FontStyle.h"
+#include "lua_GameClearFlags.h"
+#include "lua_GameState.h"
+#include "lua_GamepadButtonMapping.h"
+#include "lua_GamepadGamepadEvent.h"
+#include "lua_GestureGestureEvent.h"
+#include "lua_ImageFormat.h"
+#include "lua_KeyboardKey.h"
+#include "lua_KeyboardKeyEvent.h"
+#include "lua_LayoutType.h"
+#include "lua_LightType.h"
+#include "lua_LoggerLevel.h"
+#include "lua_MeshIndexFormat.h"
+#include "lua_MeshPrimitiveType.h"
+#include "lua_MouseMouseEvent.h"
+#include "lua_NodeType.h"
+#include "lua_ParticleEmitterTextureBlending.h"
+#include "lua_PhysicsCollisionObjectCollisionListenerEventType.h"
+#include "lua_PhysicsCollisionObjectType.h"
+#include "lua_PhysicsCollisionShapeType.h"
+#include "lua_PhysicsControllerListenerEventType.h"
+#include "lua_PropertiesType.h"
+#include "lua_RenderStateAutoBinding.h"
+#include "lua_RenderStateBlend.h"
+#include "lua_RenderStateCullFaceSide.h"
+#include "lua_RenderStateDepthFunction.h"
+#include "lua_RenderStateFrontFace.h"
+#include "lua_RenderStateStencilFunction.h"
+#include "lua_RenderStateStencilOperation.h"
+#include "lua_TerrainFlags.h"
+#include "lua_TextBoxInputMode.h"
+#include "lua_TextureFilter.h"
+#include "lua_TextureFormat.h"
+#include "lua_TextureWrap.h"
+#include "lua_TouchTouchEvent.h"
+#include "lua_VertexFormatUsage.h"
+
+namespace gameplay
+{
+
+// Global enum to string conversion function (used to pass enums to Lua from C++).
+const char* lua_stringFromEnumGlobal(std::string& enumname, unsigned int value);
+
+void luaRegister_lua_Global();
+
+}
+
+#endif

+ 135 - 135
gameplay/src/lua/lua_Platform.cpp

@@ -1,135 +1,135 @@
-#include "Base.h"
-#include "ScriptController.h"
-#include "lua_Platform.h"
-#include "Base.h"
-#include "Form.h"
-#include "Game.h"
-#include "Platform.h"
-#include "ScriptController.h"
-
-namespace gameplay
-{
-
-void luaRegister_Platform()
-{
-    const luaL_Reg lua_members[] = 
-    {
-        {"enterMessagePump", lua_Platform_enterMessagePump},
-        {NULL, NULL}
-    };
-    const luaL_Reg lua_statics[] = 
-    {
-        {"swapBuffers", lua_Platform_static_swapBuffers},
-        {NULL, NULL}
-    };
-    std::vector<std::string> scopePath;
-
-    gameplay::ScriptUtil::registerClass("Platform", lua_members, NULL, lua_Platform__gc, lua_statics, scopePath);
-}
-
-static Platform* getInstance(lua_State* state)
-{
-    void* userdata = luaL_checkudata(state, 1, "Platform");
-    luaL_argcheck(state, userdata != NULL, 1, "'Platform' expected.");
-    return (Platform*)((gameplay::ScriptUtil::LuaObject*)userdata)->instance;
-}
-
-int lua_Platform__gc(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 1:
-        {
-            if ((lua_type(state, 1) == LUA_TUSERDATA))
-            {
-                void* userdata = luaL_checkudata(state, 1, "Platform");
-                luaL_argcheck(state, userdata != NULL, 1, "'Platform' expected.");
-                gameplay::ScriptUtil::LuaObject* object = (gameplay::ScriptUtil::LuaObject*)userdata;
-                if (object->owns)
-                {
-                    Platform* instance = (Platform*)object->instance;
-                    SAFE_DELETE(instance);
-                }
-                
-                return 0;
-            }
-
-            lua_pushstring(state, "lua_Platform__gc - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 1).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_Platform_enterMessagePump(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 1:
-        {
-            if ((lua_type(state, 1) == LUA_TUSERDATA))
-            {
-                Platform* instance = getInstance(state);
-                int result = instance->enterMessagePump();
-
-                // Push the return value onto the stack.
-                lua_pushinteger(state, result);
-
-                return 1;
-            }
-
-            lua_pushstring(state, "lua_Platform_enterMessagePump - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 1).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_Platform_static_swapBuffers(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 0:
-        {
-            Platform::swapBuffers();
-            
-            return 0;
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 0).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-}
+#include "Base.h"
+#include "ScriptController.h"
+#include "lua_Platform.h"
+#include "Base.h"
+#include "Form.h"
+#include "Game.h"
+#include "Platform.h"
+#include "ScriptController.h"
+
+namespace gameplay
+{
+
+void luaRegister_Platform()
+{
+    const luaL_Reg lua_members[] = 
+    {
+        {"enterMessagePump", lua_Platform_enterMessagePump},
+        {NULL, NULL}
+    };
+    const luaL_Reg lua_statics[] = 
+    {
+        {"swapBuffers", lua_Platform_static_swapBuffers},
+        {NULL, NULL}
+    };
+    std::vector<std::string> scopePath;
+
+    gameplay::ScriptUtil::registerClass("Platform", lua_members, NULL, lua_Platform__gc, lua_statics, scopePath);
+}
+
+static Platform* getInstance(lua_State* state)
+{
+    void* userdata = luaL_checkudata(state, 1, "Platform");
+    luaL_argcheck(state, userdata != NULL, 1, "'Platform' expected.");
+    return (Platform*)((gameplay::ScriptUtil::LuaObject*)userdata)->instance;
+}
+
+int lua_Platform__gc(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                void* userdata = luaL_checkudata(state, 1, "Platform");
+                luaL_argcheck(state, userdata != NULL, 1, "'Platform' expected.");
+                gameplay::ScriptUtil::LuaObject* object = (gameplay::ScriptUtil::LuaObject*)userdata;
+                if (object->owns)
+                {
+                    Platform* instance = (Platform*)object->instance;
+                    SAFE_DELETE(instance);
+                }
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Platform__gc - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Platform_enterMessagePump(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                Platform* instance = getInstance(state);
+                int result = instance->enterMessagePump();
+
+                // Push the return value onto the stack.
+                lua_pushinteger(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Platform_enterMessagePump - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Platform_static_swapBuffers(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 0:
+        {
+            Platform::swapBuffers();
+            
+            return 0;
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 0).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+}

+ 16 - 16
gameplay/src/lua/lua_Platform.h

@@ -1,16 +1,16 @@
-#ifndef LUA_PLATFORM_H_
-#define LUA_PLATFORM_H_
-
-namespace gameplay
-{
-
-// Lua bindings for Platform.
-int lua_Platform__gc(lua_State* state);
-int lua_Platform_enterMessagePump(lua_State* state);
-int lua_Platform_static_swapBuffers(lua_State* state);
-
-void luaRegister_Platform();
-
-}
-
-#endif
+#ifndef LUA_PLATFORM_H_
+#define LUA_PLATFORM_H_
+
+namespace gameplay
+{
+
+// Lua bindings for Platform.
+int lua_Platform__gc(lua_State* state);
+int lua_Platform_enterMessagePump(lua_State* state);
+int lua_Platform_static_swapBuffers(lua_State* state);
+
+void luaRegister_Platform();
+
+}
+
+#endif

+ 1194 - 1280
samples/particles/src/ParticlesGame.cpp

@@ -1,1280 +1,1194 @@
-#include "ParticlesGame.h"
-
-// Declare our game instance.
-ParticlesGame game;
-
-#define DEFAULT_PARTICLE_EMITTER "res/fire.particle"
-
-const float INPUT_SENSITIVITY = 0.05f;
-const float PANNING_SENSITIVITY = 0.01f;
-const float ROTATE_SENSITIVITY = 0.25f;
-const Vector4 BACKGROUND_COLOR = Vector4::zero();
-const float INITIAL_ZOOM = 6.0f;
-
-ParticlesGame::ParticlesGame() : _scene(NULL), _panning(false), _rotating(false), _zooming(false)
-{
-}
-
-void ParticlesGame::addGrid(unsigned int lineCount)
-{
-    float z = -1;
-
-    // There needs to be an odd number of lines
-    lineCount |= 1;
-    const unsigned int pointCount = lineCount * 4;
-    const unsigned int verticesSize = pointCount * (3 + 3);  // (3 (position(xyz) + 3 color(rgb))
-
-    std::vector<float> vertices;
-    vertices.resize(verticesSize);
-
-    const float gridLength = (float)(lineCount / 2);
-    float value = -gridLength;
-    for (unsigned int i = 0; i < verticesSize; ++i)
-    {
-        // Default line color is dark grey
-        Vector4 color(0.3f, 0.3f, 0.3f, 1.0f);
-
-        // Every 10th line is brighter grey
-        if (((int)value) % 10 == 0)
-        {
-            color.set(0.45f, 0.45f, 0.45f, 1.0f);
-        }
-
-        // The Z axis is blue
-        if (value == 0.0f)
-        {
-            color.set(0.15f, 0.15f, 0.7f, 1.0f);
-        }
-
-        // Build the lines
-        vertices[i] = value;
-        vertices[++i] = -gridLength;
-        vertices[++i] = z;
-        vertices[++i] = color.x;
-        vertices[++i] = color.y;
-        vertices[++i] = color.z;
-
-        vertices[++i] = value;
-        vertices[++i] = gridLength;
-        vertices[++i] = z;
-        vertices[++i] = color.x;
-        vertices[++i] = color.y;
-        vertices[++i] = color.z;
-
-        // The X axis is red
-        if (value == 0.0f)
-        {
-            color.set(0.7f, 0.15f, 0.15f, 1.0f);
-        }
-        vertices[++i] = -gridLength;
-        vertices[++i] = value;
-        vertices[++i] = z;
-        vertices[++i] = color.x;
-        vertices[++i] = color.y;
-        vertices[++i] = color.z;
-
-        vertices[++i] = gridLength;
-        vertices[++i] = value;
-        vertices[++i] = z;
-        vertices[++i] = color.x;
-        vertices[++i] = color.y;
-        vertices[++i] = color.z;
-
-        value += 1.0f;
-    }
-    VertexFormat::Element elements[] =
-    {
-        VertexFormat::Element(VertexFormat::POSITION, 3),
-        VertexFormat::Element(VertexFormat::COLOR, 3)
-    };
-    Mesh* mesh = Mesh::createMesh(VertexFormat(elements, 2), pointCount, false);
-    if (mesh == NULL)
-        return;
-
-    mesh->setPrimitiveType(Mesh::LINES);
-    mesh->setVertexData(&vertices[0], 0, pointCount);
-
-    Model* model = Model::create(mesh);
-    model->setMaterial("res/grid.material");
-    SAFE_RELEASE(mesh);
-
-    _scene->addNode("grid")->setModel(model);
-    model->release();
-}
-
-void ParticlesGame::initialize()
-{
-    // Display the gameplay splash screen
-    displayScreen(this, &ParticlesGame::drawSplash, NULL, 250L);
-
-    setMultiTouch(true);
-
-    // Set keyboard state.
-    _wDown = _aDown = _sDown = _dDown = false;
-    _touched = false;
-    _prevX = _prevY = 0;
-
-    // Create a scene with a camera node.
-    // The camera node is a child of a node at the same location as the particle emitter.
-    // The camera node is offset from its parent, looking straight at it.
-    // That way, when we rotate the parent node, the camera stays aimed at the particle emitter.
-    _scene = Scene::create();
-    Node* cameraNode = _scene->addNode("Camera");
-    _cameraParent = _scene->addNode("CameraParent");
-    _cameraParent->addChild(cameraNode);
-    Camera* camera = Camera::createPerspective(45.0f, (float)getWidth() / (float)getHeight(), 0.25f, 1000.0f);
-    cameraNode->setCamera(camera);
-    cameraNode->setTranslation(0.0f, 0.0f, INITIAL_ZOOM);
-    _scene->setActiveCamera(camera);
-    SAFE_RELEASE(camera);
-
-    addGrid(61);
-
-    // Create a font for drawing the framerate.
-    _font = Font::create("res/arial.gpb");
-
-    // Load the form for editing ParticleEmitters.
-    _form = Form::create("res/editor.form");
-    _form->setConsumeInputEvents(false);
-    //_form->setState(Control::FOCUS);
-
-    // Store pointers to UI controls we care about.
-    _startRed = (Slider*)_form->getControl("startRed");
-    _startGreen = (Slider*)_form->getControl("startGreen");
-    _startBlue = (Slider*)_form->getControl("startBlue");
-    _startAlpha = (Slider*)_form->getControl("startAlpha");
-    _endRed = (Slider*)_form->getControl("endRed");
-    _endGreen = (Slider*)_form->getControl("endGreen");
-    _endBlue = (Slider*)_form->getControl("endBlue");
-    _endAlpha = (Slider*)_form->getControl("endAlpha");
-    _particleProperties = (Container*)_form->getControl("particleProperties");
-    _startMin = (Slider*)_form->getControl("startMin");
-    _startMax = (Slider*)_form->getControl("startMax");
-    _endMin = (Slider*)_form->getControl("endMin");
-    _endMax = (Slider*)_form->getControl("endMax");
-    _energyMin = (Slider*)_form->getControl("energyMin");
-    _energyMax = (Slider*)_form->getControl("energyMax");
-    _emissionRate = (Slider*)_form->getControl("emissionRate");
-    _started = (CheckBox*)_form->getControl("started");
-    _reset = (Button*)_form->getControl("reset");
-    _emit = (Button*)_form->getControl("emit");
-    _zoomIn = (Button*)_form->getControl("zoomIn");
-    _zoomOut = (Button*)_form->getControl("zoomOut");
-    _save = (Button*)_form->getControl("save");
-    _load = (Button*)_form->getControl("load");
-    _burstSize = (Slider*)_form->getControl("burstSize");
-    _posVarX = (Slider*)_form->getControl("posVarX");
-    _posVarY = (Slider*)_form->getControl("posVarY");
-    _posVarZ = (Slider*)_form->getControl("posVarZ");
-    _velX = (Slider*)_form->getControl("velocityX");
-    _velY = (Slider*)_form->getControl("velocityY");
-    _velZ = (Slider*)_form->getControl("velocityZ");
-    _velVarX = (Slider*)_form->getControl("velocityVarX");
-    _velVarY = (Slider*)_form->getControl("velocityVarY");
-    _velVarZ = (Slider*)_form->getControl("velocityVarZ");
-    _accelX = (Slider*)_form->getControl("accelX");
-    _accelY = (Slider*)_form->getControl("accelY");
-    _accelZ = (Slider*)_form->getControl("accelZ");
-    _accelVarX = (Slider*)_form->getControl("accelVarX");
-    _accelVarY = (Slider*)_form->getControl("accelVarY");
-    _accelVarZ = (Slider*)_form->getControl("accelVarZ");
-    _spinSpeedMin = (Slider*)_form->getControl("spinSpeedMin");
-    _spinSpeedMax = (Slider*)_form->getControl("spinSpeedMax");
-    _axisX = (Slider*)_form->getControl("axisX");
-    _axisY = (Slider*)_form->getControl("axisY");
-    _axisZ = (Slider*)_form->getControl("axisZ");
-    _axisVarX = (Slider*)_form->getControl("axisVarX");
-    _axisVarY = (Slider*)_form->getControl("axisVarY");
-    _axisVarZ = (Slider*)_form->getControl("axisVarZ");
-    _rotationSpeedMin = (Slider*)_form->getControl("rotationSpeedMin");
-    _rotationSpeedMax = (Slider*)_form->getControl("rotationSpeedMax");
-    _vsync = (CheckBox*)_form->getControl("vsync");
-
-    // Listen for UI events.
-    _startRed->addListener(this, Listener::VALUE_CHANGED);
-    _startGreen->addListener(this, Listener::VALUE_CHANGED);
-    _startBlue->addListener(this, Listener::VALUE_CHANGED);
-    _startAlpha->addListener(this, Listener::VALUE_CHANGED);
-    _endRed->addListener(this, Listener::VALUE_CHANGED);
-    _endGreen->addListener(this, Listener::VALUE_CHANGED);
-    _endBlue->addListener(this, Listener::VALUE_CHANGED);
-    _endAlpha->addListener(this, Listener::VALUE_CHANGED);
-    _startMin->addListener(this, Listener::VALUE_CHANGED);
-    _startMax->addListener(this, Listener::VALUE_CHANGED);
-    _endMin->addListener(this, Listener::VALUE_CHANGED);
-    _endMax->addListener(this, Listener::VALUE_CHANGED);
-    _energyMin->addListener(this, Listener::VALUE_CHANGED);
-    _energyMax->addListener(this, Listener::VALUE_CHANGED);
-    _emissionRate->addListener(this, Listener::VALUE_CHANGED);
-    _started->addListener(this, Listener::VALUE_CHANGED);
-    _reset->addListener(this, Listener::CLICK);
-    _emit->addListener(this, Listener::CLICK);
-    _zoomIn->addListener(this, Listener::PRESS);
-    _zoomIn->addListener(this, Listener::RELEASE);
-    _zoomOut->addListener(this, Listener::PRESS);
-    _zoomOut->addListener(this, Listener::RELEASE);
-    _save->addListener(this, Listener::RELEASE);
-    _load->addListener(this, Listener::RELEASE);
-    _burstSize->addListener(this, Listener::VALUE_CHANGED);
-    _form->getControl("posX")->addListener(this, Listener::VALUE_CHANGED);
-    _form->getControl("posY")->addListener(this, Listener::VALUE_CHANGED);
-    _form->getControl("posZ")->addListener(this, Listener::VALUE_CHANGED);
-    _posVarX->addListener(this, Listener::VALUE_CHANGED);
-    _posVarY->addListener(this, Listener::VALUE_CHANGED);
-    _posVarZ->addListener(this, Listener::VALUE_CHANGED);
-    _velX->addListener(this, Listener::VALUE_CHANGED);
-    _velY->addListener(this, Listener::VALUE_CHANGED);
-    _velZ->addListener(this, Listener::VALUE_CHANGED);
-    _velVarX->addListener(this, Listener::VALUE_CHANGED);
-    _velVarY->addListener(this, Listener::VALUE_CHANGED);
-    _velVarZ->addListener(this, Listener::VALUE_CHANGED);
-    _accelX->addListener(this, Listener::VALUE_CHANGED);
-    _accelY->addListener(this, Listener::VALUE_CHANGED);
-    _accelZ->addListener(this, Listener::VALUE_CHANGED);
-    _accelVarX->addListener(this, Listener::VALUE_CHANGED);
-    _accelVarY->addListener(this, Listener::VALUE_CHANGED);
-    _accelVarZ->addListener(this, Listener::VALUE_CHANGED);
-    _spinSpeedMin->addListener(this, Listener::VALUE_CHANGED);
-    _spinSpeedMax->addListener(this, Listener::VALUE_CHANGED);
-    _axisX->addListener(this, Listener::VALUE_CHANGED);
-    _axisY->addListener(this, Listener::VALUE_CHANGED);
-    _axisZ->addListener(this, Listener::VALUE_CHANGED);
-    _axisVarX->addListener(this, Listener::VALUE_CHANGED);
-    _axisVarY->addListener(this, Listener::VALUE_CHANGED);
-    _axisVarZ->addListener(this, Listener::VALUE_CHANGED);
-    _rotationSpeedMin->addListener(this, Listener::VALUE_CHANGED);
-    _rotationSpeedMax->addListener(this, Listener::VALUE_CHANGED);
-    _vsync->addListener(this, Listener::VALUE_CHANGED);
-    _form->getControl("sprite")->addListener(this, Listener::CLICK);
-    _form->getControl("additive")->addListener(this, Listener::VALUE_CHANGED);
-    _form->getControl("transparent")->addListener(this, Listener::VALUE_CHANGED);
-    _form->getControl("multiply")->addListener(this, Listener::VALUE_CHANGED);
-    _form->getControl("opaque")->addListener(this, Listener::VALUE_CHANGED);
-    _form->getControl("updateFrames")->addListener(this, Listener::CLICK);
-    
-    // Hide save/load buttons for non-windows platforms until we implement picking dialogs for others
-#ifdef WIN32
-    _form->getControl("zoomIn")->setVisible(false);
-    _form->getControl("zoomOut")->setVisible(false);
-#else
-    _form->getControl("saveLoad")->setVisible(false);
-    _form->getControl("image")->setVisible(false);
-#endif
-
-    // Load preset emitters.
-    loadEmitters();
-
-    updateImageControl();
-}
-
-#ifdef WIN32
-#include <Windows.h>
-#include <Commdlg.h>
-#endif
-
-std::string ParticlesGame::openFile(const char* title, const char* filterDescription, const char* filterExtension)
-{
-#ifdef WIN32
-    OPENFILENAMEA ofn;
-    memset(&ofn, 0, sizeof(ofn));
-
-    std::string desc = filterDescription;
-    desc += " (*.";
-    desc += filterExtension;
-    desc += ")";
-    std::string ext = "*.";
-    ext += filterExtension;
-    char filter[1024];
-    memset(filter, 0, 1024);
-    strcpy(filter, desc.c_str());
-    strcpy(filter + desc.length() + 1, ext.c_str());
-
-    char szCurrentDir[256];
-    GetCurrentDirectoryA(256, szCurrentDir);
-    std::string initialDir = szCurrentDir;
-    initialDir += "\\res";
-
-    char szFileName[256] = "";
-
-    ofn.lStructSize = sizeof(ofn); // SEE NOTE BELOW
-    ofn.hwndOwner = GetForegroundWindow();
-    ofn.lpstrTitle = title;
-    ofn.lpstrFilter = filter;//"Particle Files (*.particle)\0*.particle\0";
-    ofn.lpstrFile = szFileName;
-    ofn.lpstrInitialDir = initialDir.c_str();
-    ofn.nMaxFile = 256;
-    ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
-    ofn.lpstrDefExt = "filterExtension";
-
-    GetOpenFileNameA(&ofn);
-
-    // Restore current dir
-    SetCurrentDirectoryA(szCurrentDir);
-
-    return szFileName;
-#endif
-
-    return "";
-}
-
-std::string ParticlesGame::toString(bool b)
-{
-    return b ? "true" : "false";
-}
-
-std::string ParticlesGame::toString(int i)
-{
-    char buf[1024];
-    sprintf(buf, "%d", i);
-    return buf;
-}
-
-std::string ParticlesGame::toString(unsigned int i)
-{
-    char buf[1024];
-    sprintf(buf, "%d", i);
-    return buf;
-}
-
-std::string ParticlesGame::toString(const Vector3& v)
-{
-    std::ostringstream s;
-    s << v.x << ", " << v.y << ", " << v.z;
-    return s.str();
-}
-
-std::string ParticlesGame::toString(const Vector4& v)
-{
-    std::ostringstream s;
-    s << v.x << ", " << v.y << ", " << v.z << ", " << v.w;
-    return s.str();
-}
-
-std::string ParticlesGame::toString(const Quaternion& q)
-{
-    std::ostringstream s;
-    s << q.x << ", " << q.y << ", " << q.z << ", " << q.w;
-    return s.str();
-}
-
-std::string ParticlesGame::toString(ParticleEmitter::TextureBlending blending)
-{
-    switch (blending)
-    {
-        case ParticleEmitter::BLEND_OPAQUE:
-            return "OPAQUE";
-        case ParticleEmitter::BLEND_TRANSPARENT:
-            return "TRANSPARENT";
-        case ParticleEmitter::BLEND_ADDITIVE:
-            return "ADDITIVE";
-        case ParticleEmitter::BLEND_MULTIPLIED:
-            return "MULTIPLIED";
-        default:
-            return "TRANSPARENT";
-    }
-}
-
-void ParticlesGame::saveFile()
-{
-    std::string filename;
-
-#ifdef WIN32
-    OPENFILENAMEA ofn;
-    memset(&ofn, 0, sizeof(ofn));
-
-    char szCurrentDir[256];
-    GetCurrentDirectoryA(256, szCurrentDir);
-    std::string initialDir = szCurrentDir;
-    initialDir += "\\res";
-
-    char szFileName[256] = "";
-
-    ofn.lStructSize = sizeof(ofn); // SEE NOTE BELOW
-    ofn.hwndOwner = GetForegroundWindow();
-    ofn.lpstrFilter = "Particle Files (*.particle)\0*.particle\0";
-    ofn.lpstrFile = szFileName;
-    ofn.lpstrInitialDir = initialDir.c_str();
-    ofn.nMaxFile = 256;
-    ofn.Flags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT;
-    ofn.lpstrDefExt = "particle";
-
-    GetSaveFileNameA(&ofn);
-
-    filename = szFileName;
-
-    // Restore current dir
-    SetCurrentDirectoryA(szCurrentDir);
-
-#endif
-
-    if (filename.length() == 0)
-        return;
-
-    ParticleEmitter* e = _particleEmitter;
-
-    // Extract just the particle name from the filename
-    std::string dir = FileSystem::getDirectoryName(filename.c_str());
-    std::string ext = FileSystem::getExtension(filename.c_str());
-    std::string name = filename.substr(dir.length(), filename.length() - dir.length() - ext.length());
-
-    Texture* texture = e->getTexture();
-    std::string texturePath = texture->getPath();
-    std::string textureDir = FileSystem::getDirectoryName(texturePath.c_str());
-    texturePath = texturePath.substr(textureDir.length());
-
-    // Get camera rotation as axis-angle
-    Vector3 cameraAxis;
-    float cameraAngle = MATH_RAD_TO_DEG(_cameraParent->getRotation().toAxisAngle(&cameraAxis));
-
-    // Write out a properties file
-    std::ostringstream s;
-    s << 
-        "particle " << name << "\n" <<
-        "{\n" <<
-        "    sprite\n" <<
-        "    {\n" <<
-        "        path = " << texturePath << "\n" <<
-        "        width = " << e->getSpriteWidth() << "\n" <<
-        "        height = " << e->getSpriteHeight() << "\n" <<
-        "        blending = " << toString(e->getTextureBlending()) << "\n" <<
-        "        animated = " << toString(e->isSpriteAnimated()) << "\n" <<
-        "        looped = " << toString(e->isSpriteLooped()) << "\n" <<
-        "        frameCount = " << e->getSpriteFrameCount() << "\n" <<
-        "        frameRandomOffset = " << e->getSpriteFrameRandomOffset() << "\n" <<
-        "        frameDuration = " << e->getSpriteFrameDuration() << "\n" <<
-        "    }\n" <<
-        "\n" <<
-        "    particleCountMax = " << e->getParticleCountMax() << "\n" <<
-        "    emissionRate = " << e->getEmissionRate() << "\n" <<
-        "    ellipsoid = " << toString(e->isEllipsoid()) << "\n" <<
-        "    orbitPosition = " << toString(e->getOrbitPosition()) << "\n" <<
-        "    orbitVelocity = " << toString(e->getOrbitVelocity()) << "\n" <<
-        "    orbitAcceleration = " << toString(e->getOrbitAcceleration()) << "\n" <<
-        "    sizeStartMin = " << e->getSizeStartMin() << "\n" <<
-        "    sizeStartMax = " << e->getSizeStartMax() << "\n" <<
-        "    sizeEndMin = " << e->getSizeEndMin() << "\n" <<
-        "    sizeEndMax = " << e->getSizeEndMax() << "\n" <<
-        "    energyMin = " << e->getEnergyMin() << "\n" <<
-        "    energyMax = " << e->getEnergyMax() << "\n" <<
-        "    colorStart = " << toString(e->getColorStart()) << "\n" <<
-        "    colorStartVar = " << toString(e->getColorStartVariance()) << "\n" <<
-        "    colorEnd = " << toString(e->getColorEnd()) << "\n" <<
-        "    colorEndVar = " << toString(e->getColorEndVariance()) << "\n" <<
-        "    position = " << toString(e->getPosition()) << "\n" <<
-        "    positionVar = " << toString(e->getPositionVariance()) << "\n" <<
-        "    velocity = " << toString(e->getVelocity()) << "\n" <<
-        "    velocityVar = " << toString(e->getVelocityVariance()) << "\n" <<
-        "    acceleration = " << toString(e->getAcceleration()) << "\n" <<
-        "    accelerationVar = " << toString(e->getAccelerationVariance()) << "\n" <<
-        "    rotationPerParticleSpeedMin = " << e->getRotationPerParticleSpeedMin() << "\n" <<
-        "    rotationPerParticleSpeedMax = " << e->getRotationPerParticleSpeedMax() << "\n" <<
-        "\n" <<
-        "    editor\n" <<
-        "    {\n" <<
-        "        cameraTranslation = " << toString(_cameraParent->getTranslation()) << "\n" <<
-        "        cameraZoom = " << toString(_scene->getActiveCamera()->getNode()->getTranslation()) << "\n" <<
-        "        cameraRotation = " << toString(cameraAxis) << ", " << cameraAngle << "\n" <<
-        "        sizeMax = " << _startMax->getMax() << "\n" <<
-        "        energyMax = " << _energyMax->getMax() << "\n" <<
-        "    }\n"
-        "}\n";
-
-    std::string text = s.str();
-    Stream* stream = FileSystem::open(filename.c_str(), FileSystem::WRITE);
-    stream->write(text.c_str(), 1, text.length());
-    stream->close();
-    SAFE_DELETE(stream);
-}
-
-void ParticlesGame::controlEvent(Control* control, EventType evt)
-{
-    std::string id = control->getId();
-
-    // Handle UI events.
-    ParticleEmitter* emitter = _particleEmitterNode->getParticleEmitter();
-    switch(evt)
-    {
-    case Listener::VALUE_CHANGED:
-        if (control == _startRed)
-        {
-            Vector4 startColor = emitter->getColorStart();
-            startColor.x = _startRed->getValue();
-            emitter->setColor(startColor, emitter->getColorStartVariance(), emitter->getColorEnd(), emitter->getColorEndVariance());
-        }
-        else if (control == _startGreen)
-        {
-            Vector4 startColor = emitter->getColorStart();
-            startColor.y = _startGreen->getValue();
-            emitter->setColor(startColor, emitter->getColorStartVariance(), emitter->getColorEnd(), emitter->getColorEndVariance());
-        }
-        else if (control == _startBlue)
-        {
-            Vector4 startColor = emitter->getColorStart();
-            startColor.z = _startBlue->getValue();
-            emitter->setColor(startColor, emitter->getColorStartVariance(), emitter->getColorEnd(), emitter->getColorEndVariance());
-        }
-        else if (control == _startAlpha)
-        {
-            Vector4 startColor = emitter->getColorStart();
-            startColor.w = _startAlpha->getValue();
-            emitter->setColor(startColor, emitter->getColorStartVariance(), emitter->getColorEnd(), emitter->getColorEndVariance());
-        }
-        else if (control == _endRed)
-        {
-            Vector4 endColor = emitter->getColorEnd();
-            endColor.x = _endRed->getValue();
-            emitter->setColor(emitter->getColorStart(), emitter->getColorStartVariance(), endColor, emitter->getColorEndVariance());
-        }
-        else if (control == _endGreen)
-        {
-            Vector4 endColor = emitter->getColorEnd();
-            endColor.y = _endGreen->getValue();
-            emitter->setColor(emitter->getColorStart(), emitter->getColorStartVariance(), endColor, emitter->getColorEndVariance());
-        }
-        else if (control == _endBlue)
-        {
-            Vector4 endColor = emitter->getColorEnd();
-            endColor.z = _endBlue->getValue();
-            emitter->setColor(emitter->getColorStart(), emitter->getColorStartVariance(), endColor, emitter->getColorEndVariance());
-        }
-        else if (control == _endAlpha)
-        {
-            Vector4 endColor = emitter->getColorEnd();
-            endColor.w = _endAlpha->getValue();
-            emitter->setColor(emitter->getColorStart(), emitter->getColorStartVariance(), endColor, emitter->getColorEndVariance());
-        }
-        else if (control == _startMin)
-        {
-            emitter->setSize(_startMin->getValue(), emitter->getSizeStartMax(), emitter->getSizeEndMin(), emitter->getSizeEndMax());
-        }
-        else if (control == _startMax)
-        {
-            emitter->setSize(emitter->getSizeStartMin(), _startMax->getValue(), emitter->getSizeEndMin(), emitter->getSizeEndMax());
-        }
-        else if (control == _endMin)
-        {
-            emitter->setSize(emitter->getSizeStartMin(), emitter->getSizeStartMax(), _endMin->getValue(), emitter->getSizeEndMax());
-        }
-        else if (control == _endMax)
-        {
-            emitter->setSize(emitter->getSizeStartMin(), emitter->getSizeStartMax(), emitter->getSizeEndMin(), _endMax->getValue());
-        }
-        else if (control == _energyMin)
-        {
-            emitter->setEnergy(_energyMin->getValue(), emitter->getEnergyMax());
-        }
-        else if (control == _energyMax)
-        {
-            emitter->setEnergy(emitter->getEnergyMin(), _energyMax->getValue());
-        }
-        else if (control == _emissionRate)
-        {
-            emitter->setEmissionRate(_emissionRate->getValue());
-        }
-        else if (id == "posX")
-        {
-            Vector3 pos(emitter->getPosition());
-            pos.x = ((Slider*)control)->getValue();
-            emitter->setPosition(pos, emitter->getPositionVariance());
-        }
-        else if (id == "posY")
-        {
-            Vector3 pos(emitter->getPosition());
-            pos.y = ((Slider*)control)->getValue();
-            emitter->setPosition(pos, emitter->getPositionVariance());
-        }
-        else if (id == "posZ")
-        {
-            Vector3 pos(emitter->getPosition());
-            pos.z = ((Slider*)control)->getValue();
-            emitter->setPosition(pos, emitter->getPositionVariance());
-        }
-        else if (control == _posVarX)
-        {
-            Vector3 posVar = emitter->getPositionVariance();
-            posVar.x = _posVarX->getValue();
-            emitter->setPosition(emitter->getPosition(), posVar);
-        }
-        else if (control == _posVarY)
-        {
-            Vector3 posVar = emitter->getPositionVariance();
-            posVar.y = _posVarY->getValue();
-            emitter->setPosition(emitter->getPosition(), posVar);
-        }
-        else if (control == _posVarZ)
-        {
-            Vector3 posVar = emitter->getPositionVariance();
-            posVar.z = _posVarZ->getValue();
-            emitter->setPosition(emitter->getPosition(), posVar);
-        }
-        else if (control == _velX)
-        {
-            Vector3 vel = emitter->getVelocity();
-            vel.x = _velX->getValue();
-            emitter->setVelocity(vel, emitter->getVelocityVariance());
-        }
-        else if (control == _velY)
-        {
-            Vector3 vel = emitter->getVelocity();
-            vel.y = _velY->getValue();
-            emitter->setVelocity(vel, emitter->getVelocityVariance());
-        }
-        else if (control == _velZ)
-        {
-            Vector3 vel = emitter->getVelocity();
-            vel.z = _velZ->getValue();
-            emitter->setVelocity(vel, emitter->getVelocityVariance());
-        }
-        else if (control == _velVarX)
-        {
-            Vector3 velVar = emitter->getVelocityVariance();
-            velVar.x = _velVarX->getValue();
-            emitter->setVelocity(emitter->getVelocity(), velVar);
-        }
-        else if (control == _velVarY)
-        {
-            Vector3 velVar = emitter->getVelocityVariance();
-            velVar.y = _velVarY->getValue();
-            emitter->setVelocity(emitter->getVelocity(), velVar);
-        }
-        else if (control == _velVarZ)
-        {
-            Vector3 velVar = emitter->getVelocityVariance();
-            velVar.z = _velVarZ->getValue();
-            emitter->setVelocity(emitter->getVelocity(), velVar);
-        }
-        else if (control == _accelX)
-        {
-            Vector3 accel = emitter->getAcceleration();
-            accel.x = _accelX->getValue();
-            emitter->setAcceleration(accel, emitter->getAccelerationVariance());
-        }
-        else if (control == _accelY)
-        {
-            Vector3 accel = emitter->getAcceleration();
-            accel.y = _accelY->getValue();
-            emitter->setAcceleration(accel, emitter->getAccelerationVariance());
-        }
-        else if (control == _accelZ)
-        {
-            Vector3 accel = emitter->getAcceleration();
-            accel.z = _accelZ->getValue();
-            emitter->setAcceleration(accel, emitter->getAccelerationVariance());
-        }
-        else if (control == _accelVarX)
-        {
-            Vector3 accelVar = emitter->getAccelerationVariance();
-            accelVar.x = _accelVarX->getValue();
-            emitter->setAcceleration(emitter->getAcceleration(), accelVar);
-        }
-        else if (control == _accelVarY)
-        {
-            Vector3 accelVar = emitter->getAccelerationVariance();
-            accelVar.y = _accelVarY->getValue();
-            emitter->setAcceleration(emitter->getAcceleration(), accelVar);
-        }
-        else if (control == _accelVarZ)
-        {
-            Vector3 accelVar = emitter->getAccelerationVariance();
-            accelVar.z = _accelVarZ->getValue();
-            emitter->setAcceleration(emitter->getAcceleration(), accelVar);
-        }
-        else if (control == _spinSpeedMin)
-        {
-            emitter->setRotationPerParticle(_spinSpeedMin->getValue(), emitter->getRotationPerParticleSpeedMax());
-        }
-        else if (control == _spinSpeedMax)
-        {
-            emitter->setRotationPerParticle(emitter->getRotationPerParticleSpeedMin(), _spinSpeedMax->getValue());
-        }
-        else if (control == _axisX)
-        {
-            Vector3 axis = emitter->getRotationAxis();
-            axis.x = _axisX->getValue();
-            emitter->setRotation(emitter->getRotationSpeedMin(), emitter->getRotationSpeedMax(), axis, emitter->getRotationAxisVariance());
-        }
-        else if (control == _axisY)
-        {
-            Vector3 axis = emitter->getRotationAxis();
-            axis.y = _axisY->getValue();
-            emitter->setRotation(emitter->getRotationSpeedMin(), emitter->getRotationSpeedMax(), axis, emitter->getRotationAxisVariance());
-        }
-        else if (control == _axisZ)
-        {
-            Vector3 axis = emitter->getRotationAxis();
-            axis.z = _axisZ->getValue();
-            emitter->setRotation(emitter->getRotationSpeedMin(), emitter->getRotationSpeedMax(), axis, emitter->getRotationAxisVariance());
-        }
-        else if (control == _axisVarX)
-        {
-            Vector3 axisVar = emitter->getRotationAxisVariance();
-            axisVar.x = _axisVarX->getValue();
-            emitter->setRotation(emitter->getRotationSpeedMin(), emitter->getRotationSpeedMax(), emitter->getRotationAxis(), axisVar);
-        }
-        else if (control == _axisVarY)
-        {
-            Vector3 axisVar = emitter->getRotationAxisVariance();
-            axisVar.y = _axisVarY->getValue();
-            emitter->setRotation(emitter->getRotationSpeedMin(), emitter->getRotationSpeedMax(), emitter->getRotationAxis(), axisVar);
-        }
-        else if (control == _axisVarZ)
-        {
-            Vector3 axisVar = emitter->getRotationAxisVariance();
-            axisVar.z = _axisVarZ->getValue();
-            emitter->setRotation(emitter->getRotationSpeedMin(), emitter->getRotationSpeedMax(), emitter->getRotationAxis(), axisVar);
-        }
-        else if (control == _rotationSpeedMin)
-        {
-            emitter->setRotation(_rotationSpeedMin->getValue(), emitter->getRotationSpeedMax(), emitter->getRotationAxis(), emitter->getRotationAxisVariance());
-        }
-        else if (control == _rotationSpeedMax)
-        {
-            emitter->setRotation(emitter->getRotationSpeedMin(), _rotationSpeedMax->getValue(), emitter->getRotationAxis(), emitter->getRotationAxisVariance());
-        }
-        else if (control == _burstSize)
-        {
-            char txt[25];
-            sprintf(txt, "Burst Size\n\n%.0f", _burstSize->getValue());
-            _burstSize->setText(txt);
-        }
-        else if (control == _started)
-        {
-            if (_started->isChecked())
-            {
-                emitter->start();
-            }
-            else
-            {
-                emitter->stop();
-            }
-        }
-        else if (control == _vsync)
-        {
-            Game::getInstance()->setVsync(_vsync->isChecked());
-        }
-        else if (id == "additive")
-        {
-            if (((RadioButton*)control)->isSelected())
-                emitter->setTextureBlending(ParticleEmitter::BLEND_ADDITIVE);
-        }
-        else if (id == "transparent")
-        {
-            if (((RadioButton*)control)->isSelected())
-                emitter->setTextureBlending(ParticleEmitter::BLEND_TRANSPARENT);
-        }
-        else if (id == "multiply")
-        {
-            if (((RadioButton*)control)->isSelected())
-                emitter->setTextureBlending(ParticleEmitter::BLEND_MULTIPLIED);
-        }
-        else if (id == "opaque")
-        {
-            if (((RadioButton*)control)->isSelected())
-                emitter->setTextureBlending(ParticleEmitter::BLEND_OPAQUE);
-        }
-        break;
-    case Listener::CLICK:
-        if (control == _reset)
-        {
-            // Re-load the current emitter and reset the view
-            _particleEmitter = ParticleEmitter::create(_url.c_str());
-            emitterChanged();
-        }
-        else if (control == _emit)
-        {
-            // Emit a burst of particles.
-            unsigned int burstSize = (unsigned int)_burstSize->getValue();
-            emitter->emitOnce(burstSize);
-        }
-        else if (id == "sprite")
-        {
-            updateTexture();
-        }
-        else if (id == "updateFrames")
-        {
-            updateFrames();
-        }
-        break;
-    case Listener::PRESS:
-        if (control == _zoomIn)
-        {
-            _wDown = true;
-        }
-        else if (control == _zoomOut)
-        {
-            _sDown = true;
-        }
-        break;
-    case Listener::RELEASE:
-        if (control == _zoomIn)
-        {
-            _wDown = false;
-        }
-        else if (control == _zoomOut)
-        {
-            _sDown = false;
-        }
-        else if (control == _save)
-        {
-            Game::getInstance()->pause();
-            saveFile();
-            Game::getInstance()->resume();
-        }
-        else if (control == _load)
-        {
-            Game::getInstance()->pause();
-            std::string filename = openFile("Select Particle File", "Particle Files", "particle");
-            if (filename.length() > 0)
-            {
-                _url = filename;
-                _particleEmitter = ParticleEmitter::create(_url.c_str());
-                emitterChanged();
-            }
-            Game::getInstance()->resume();
-        }
-        break;
-    }
-}
-
-void ParticlesGame::updateFrames()
-{
-    Texture* texture = _particleEmitter->getTexture();
-    TextBox* cBox = (TextBox*)_form->getControl("frameCount");
-    TextBox* wBox = (TextBox*)_form->getControl("frameWidth");
-    TextBox* hBox = (TextBox*)_form->getControl("frameHeight");
-    unsigned int fc = (unsigned int)atoi(cBox->getText());
-    unsigned int w = (unsigned int)atoi(wBox->getText());
-    unsigned int h = (unsigned int)atoi(hBox->getText());
-    if (fc > 0 && fc < 256 && fc < 1000 && w > 0 && h > 0 && w < 4096 && h < 4096)
-    {
-        if (w > _particleEmitter->getTexture()->getWidth())
-        {
-            wBox->setText(toString(texture->getWidth()).c_str());
-        }
-        if (h > texture->getHeight())
-        {
-            hBox->setText(toString(texture->getHeight()).c_str());
-        }
-
-        _particleEmitter->setSpriteFrameCoords(fc, w, h);
-    }
-}
-
-void ParticlesGame::finalize()
-{
-    SAFE_RELEASE(_scene);
-    SAFE_RELEASE(_form);
-    SAFE_RELEASE(_font);
-    SAFE_RELEASE(_particleEmitter);
-}
-
-void ParticlesGame::update(float elapsedTime)
-{
-    // Update camera movement
-    if (_wDown)
-    {
-        Vector3 v = _scene->getActiveCamera()->getNode()->getForwardVector();
-        v.normalize();
-        v.scale(INPUT_SENSITIVITY * elapsedTime);
-        _scene->getActiveCamera()->getNode()->translate(v);
-    }
-    if (_aDown)
-    {
-        Vector3 v = _scene->getActiveCamera()->getNode()->getLeftVector();
-        v.normalize();
-        v.scale(INPUT_SENSITIVITY * elapsedTime);
-        _scene->getActiveCamera()->getNode()->translate(v);
-    }
-    if (_sDown)
-    {
-        Vector3 v = _scene->getActiveCamera()->getNode()->getBackVector();
-        v.normalize();
-        v.scale(INPUT_SENSITIVITY * elapsedTime);
-        _scene->getActiveCamera()->getNode()->translate(v);
-    }
-    if (_dDown)
-    {
-        Vector3 v = _scene->getActiveCamera()->getNode()->getRightVector();
-        v.normalize();
-        v.scale(INPUT_SENSITIVITY * elapsedTime);
-        _scene->getActiveCamera()->getNode()->translate(v);
-    }
-
-    // Update particles.
-    _particleEmitterNode->getParticleEmitter()->update(elapsedTime);
-}
-
-void ParticlesGame::render(float elapsedTime)
-{
-    // Clear the color and depth buffers.
-    clear(CLEAR_COLOR_DEPTH, BACKGROUND_COLOR, 1.0f, 0);
-
-    // Visit all the nodes in the scene for drawing.
-    _scene->visit(this, &ParticlesGame::drawScene, (void*)0);
-
-    // Draw the UI.
-    _form->draw();
-
-    // Draw the framerate and number of live particles.
-    drawFrameRate(_font, Vector4(1, 1, 1, 1), 170, 40, getFrameRate());
-}
-
-bool ParticlesGame::drawScene(Node* node, void* cookie)
-{
-    if (node->getModel())
-        node->getModel()->draw();
-    if (node->getParticleEmitter())
-        node->getParticleEmitter()->draw();
-    return true;
-}
-
-bool ParticlesGame::mouseEvent(Mouse::MouseEvent evt, int x, int y, int wheelDelta)
-{
-    switch (evt)
-    {
-    case Mouse::MOUSE_PRESS_MIDDLE_BUTTON:
-        Game::getInstance()->setMouseCaptured(true);
-        _panning = true;
-        return true;
-    case Mouse::MOUSE_RELEASE_MIDDLE_BUTTON:
-        Game::getInstance()->setMouseCaptured(false);
-        _panning = false;
-        return true;
-    case Mouse::MOUSE_PRESS_LEFT_BUTTON:
-        Game::getInstance()->setMouseCaptured(true);
-        _rotating = true;
-        return true;
-    case Mouse::MOUSE_RELEASE_LEFT_BUTTON:
-        Game::getInstance()->setMouseCaptured(false);
-        _rotating = false;
-        return true;
-    case Mouse::MOUSE_PRESS_RIGHT_BUTTON:
-        Game::getInstance()->setMouseCaptured(true);
-        _zooming = true;
-        return true;
-    case Mouse::MOUSE_RELEASE_RIGHT_BUTTON:
-        Game::getInstance()->setMouseCaptured(false);
-        _zooming = false;
-        return true;
-    case Mouse::MOUSE_MOVE:
-        if (_panning)
-        {
-            Vector3 n(-(float)x * PANNING_SENSITIVITY, (float)y * PANNING_SENSITIVITY, 0);
-            _cameraParent->getMatrix().transformVector(&n);
-            _cameraParent->translate(n);
-            return true;
-        }
-        else if (_rotating)
-        {
-            _cameraParent->rotateY(-MATH_DEG_TO_RAD((float)x * ROTATE_SENSITIVITY));
-            _cameraParent->rotateX(-MATH_DEG_TO_RAD((float)y * ROTATE_SENSITIVITY));
-            return true;
-        }
-        else if (_zooming)
-        {
-            Vector3 v = _scene->getActiveCamera()->getNode()->getForwardVector();
-            v.normalize();
-            v.scale((float)(x-y) * INPUT_SENSITIVITY);
-            _scene->getActiveCamera()->getNode()->translate(v);
-            return true;
-        }
-        break;
-    }
-
-    return true;
-}
-
-void ParticlesGame::touchEvent(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex)
-{
-    // Touch events that don't hit the UI
-    // allow the camera to rotate around the particle emitter.
-    switch (evt)
-    {
-    case Touch::TOUCH_PRESS:
-        _touched = true;
-        _prevX = x;
-        _prevY = y;
-        break;
-
-    case Touch::TOUCH_RELEASE:
-        _touched = false;
-        break;
-
-    case Touch::TOUCH_MOVE:
-        {
-            if (_touched)
-            {
-                int deltaX = x - _prevX;
-                int deltaY = y - _prevY;
-                _prevX = x;
-                _prevY = y;
-
-                _cameraParent->rotateY(MATH_DEG_TO_RAD(deltaX * -0.5f));
-                _cameraParent->rotateX(MATH_DEG_TO_RAD(deltaY * -0.5f));
-            }
-        }
-        break;
-    default:
-        break;
-    };
-}
-
-void ParticlesGame::keyEvent(Keyboard::KeyEvent evt, int key)
-{
-    switch(evt)
-    {
-    case Keyboard::KEY_PRESS:
-        switch (key)
-        {
-        case Keyboard::KEY_ESCAPE:
-            exit();
-            break;
-        case Keyboard::KEY_B:
-            // Disable blending.
-            _particleEmitterNode->getParticleEmitter()->setTextureBlending(ParticleEmitter::BLEND_OPAQUE);
-            break;
-        case Keyboard::KEY_W:
-            _wDown = true;
-            break;
-        case Keyboard::KEY_A:
-            _aDown = true;
-            break;
-        case Keyboard::KEY_S:
-            _sDown = true;
-            break;
-        case Keyboard::KEY_D:
-            _dDown = true;
-            break;
-        }
-        break;
-
-    case Keyboard::KEY_RELEASE:
-        switch (key)
-        {
-        case Keyboard::KEY_W:
-            _wDown = false;
-            break;
-        case Keyboard::KEY_A:
-            _aDown = false;
-            break;
-        case Keyboard::KEY_S:
-            _sDown = false;
-            break;
-        case Keyboard::KEY_D:
-            _dDown = false;
-            break;
-        }
-        break;
-    }
-}
-
-void ParticlesGame::loadEmitters()
-{
-    // Load the default particle emitter
-    _url = DEFAULT_PARTICLE_EMITTER;
-    _particleEmitter = ParticleEmitter::create(_url.c_str());
-
-    _particleEmitterNode = _scene->addNode("Particle Emitter");
-    _particleEmitterNode->setTranslation(0.0f, 0.0f, 0.0f);
-
-    emitterChanged();
-}
-
-void ParticlesGame::emitterChanged()
-{
-    ParticleEmitter* emitter = _particleEmitter;
-
-    // Set the new emitter on the node.
-    _particleEmitterNode->setParticleEmitter(_particleEmitter);
-    _particleEmitter->release();
-
-    // Reset camera view and zoom.
-    _scene->getActiveCamera()->getNode()->setTranslation(0.0f, 0.0f, 40.0f);
-    _cameraParent->setIdentity();
-    _particleEmitterNode->setIdentity();
-
-    // Set the values of UI controls to display the new emitter's settings.
-    _startRed->setValue(emitter->getColorStart().x);
-    _startGreen->setValue(emitter->getColorStart().y);
-    _startBlue->setValue(emitter->getColorStart().z);
-    _startAlpha->setValue(emitter->getColorStart().w);    
-
-    _endRed->setValue(emitter->getColorEnd().x);
-    _endGreen->setValue(emitter->getColorEnd().y);
-    _endBlue->setValue(emitter->getColorEnd().z);
-    _endAlpha->setValue(emitter->getColorEnd().w);
-
-    _startMin->setValue(emitter->getSizeStartMin());
-    _startMax->setValue(emitter->getSizeStartMax());
-    _endMin->setValue(emitter->getSizeEndMin());
-    _endMax->setValue(emitter->getSizeEndMax());
-
-    _energyMin->setValue(emitter->getEnergyMin());
-    _energyMax->setValue(emitter->getEnergyMax());
-
-    _emissionRate->setValue(emitter->getEmissionRate());
-
-    char txt[25];
-    sprintf(txt, "Burst Size\n\n%.0f", _burstSize->getValue());
-    _burstSize->setText(txt);
-
-    const Vector3& posVar = emitter->getPositionVariance();
-    _posVarX->setValue(posVar.x);
-    _posVarY->setValue(posVar.y);
-    _posVarZ->setValue(posVar.z);
-
-    const Vector3& vel = emitter->getVelocity();
-    _velX->setValue(vel.x);    
-    _velY->setValue(vel.y);
-    _velZ->setValue(vel.z);
-
-    const Vector3& velVar = emitter->getVelocityVariance();
-    _velVarX->setValue(velVar.x);
-    _velVarY->setValue(velVar.y);
-    _velVarZ->setValue(velVar.z);
-
-    const Vector3& accel = emitter->getAcceleration();
-    _accelX->setValue(accel.x);
-    _accelY->setValue(accel.y);
-    _accelZ->setValue(accel.z);
-
-    const Vector3& accelVar = emitter->getAccelerationVariance();
-    _accelVarX->setValue(accelVar.x);
-    _accelVarY->setValue(accelVar.y);
-    _accelVarZ->setValue(accelVar.z);
-
-    _spinSpeedMin->setValue(emitter->getRotationPerParticleSpeedMin());
-    _spinSpeedMax->setValue(emitter->getRotationPerParticleSpeedMax());
-
-    const Vector3& axis = emitter->getRotationAxis();
-    _axisX->setValue(axis.x);
-    _axisY->setValue(axis.y);    
-    _axisZ->setValue(axis.z);
-
-
-    const Vector3& axisVar = emitter->getRotationAxisVariance();
-    _axisVarX->setValue(axisVar.x);
-    _axisVarY->setValue(axisVar.y);
-    _axisVarZ->setValue(axisVar.z);
-
-    _rotationSpeedMin->setValue(emitter->getRotationSpeedMin());
-    _rotationSpeedMax->setValue(emitter->getRotationSpeedMax());
-
-    // Update our image control
-    updateImageControl();
-
-    // Parse editor section of particle properties
-    Properties* p = Properties::create(_url.c_str());
-    Properties* ns = p->getNamespace("editor", true);
-    if (ns)
-    {
-        Vector3 v3;
-        if (ns->getVector3("cameraTranslation", &v3))
-        {
-            _cameraParent->setTranslation(v3);
-        }
-        if (ns->getVector3("cameraZoom", &v3))
-        {
-            _scene->getActiveCamera()->getNode()->setTranslation(v3);
-        }
-        Quaternion q;
-        if (ns->getQuaternionFromAxisAngle("cameraRotation", &q))
-        {
-            _cameraParent->setRotation(q);
-        }
-        float f;
-        if ((f = ns->getFloat("sizeMax")) != 0.0f)
-        {
-            _startMin->setMax(f);
-            _startMax->setMax(f);
-            _endMin->setMax(f);
-            _endMax->setMax(f);
-        }
-        if ((f = ns->getFloat("energyMax")) != 0.0f)
-        {
-            _energyMin->setMax(f);
-            _energyMax->setMax(f);
-        }
-    }
-    SAFE_DELETE(p);
-
-    // Start the emitter
-    emitter->start();
-}
-
-void ParticlesGame::drawSplash(void* param)
-{
-    clear(CLEAR_COLOR_DEPTH, Vector4(0, 0, 0, 1), 1.0f, 0);
-    SpriteBatch* batch = SpriteBatch::create("res/logo_powered_white.png");
-    batch->start();
-    batch->draw(this->getWidth() * 0.5f, this->getHeight() * 0.5f, 0.0f, 512.0f, 512.0f, 0.0f, 1.0f, 1.0f, 0.0f, Vector4::one(), true);
-    batch->finish();
-    SAFE_DELETE(batch);
-}
-
-void ParticlesGame::drawFrameRate(Font* font, const Vector4& color, unsigned int x, unsigned int y, unsigned int fps)
-{
-    char buffer[30];
-    sprintf(buffer, "FPS: %u\nParticles: %u", fps, _particleEmitterNode->getParticleEmitter()->getParticlesCount());
-    font->start();
-    font->drawText(buffer, x, y, color, 22);
-    font->finish();
-}
-
-void ParticlesGame::resizeEvent(unsigned int width, unsigned int height)
-{
-    setViewport(gameplay::Rectangle(width, height));
-    _form->setSize(width, height);
-    _scene->getActiveCamera()->setAspectRatio((float)getWidth() / (float)getHeight());
-}
-
-void ParticlesGame::updateTexture()
-{
-    std::string file = openFile("Select Texture", "PNG Files", "png");
-    if (file.length() > 0)
-    {
-        // Set new sprite on our emitter
-        _particleEmitter->setTexture(file.c_str(), _particleEmitter->getTextureBlending());
-
-        // Update the UI to display the new sprite
-        updateImageControl();
-    }
-}
-
-void ParticlesGame::updateImageControl()
-{
-    ((ImageControl*)_form->getControl("sprite"))->setImage(_particleEmitter->getTexture()->getPath());
-
-    // Resize the image control so keep it to scale
-    int w = _particleEmitter->getTexture()->getWidth();
-    int h = _particleEmitter->getTexture()->getHeight();
-    int max = w > h ? w : h;
-    if (max > 140)
-    {
-        float ratio = 140.0f / max;
-        w *= ratio;
-        h *= ratio;
-    }
-    ((ImageControl*)_form->getControl("sprite"))->setSize(w, h);
-    _form->getControl("image")->setHeight(h + _form->getControl("imageSettings")->getHeight() + 50);
-
-    ((TextBox*)_form->getControl("frameCount"))->setText(toString(_particleEmitter->getSpriteFrameCount()).c_str());
-    ((TextBox*)_form->getControl("frameWidth"))->setText(toString(_particleEmitter->getSpriteWidth()).c_str());
-    ((TextBox*)_form->getControl("frameHeight"))->setText(toString(_particleEmitter->getSpriteHeight()).c_str());
-
-    switch (_particleEmitter->getTextureBlending())
-    {
-    case ParticleEmitter::BLEND_ADDITIVE:
-        ((RadioButton*)_form->getControl("additive"))->setSelected(true);
-        break;
-    case ParticleEmitter::BLEND_MULTIPLIED:
-        ((RadioButton*)_form->getControl("multiply"))->setSelected(true);
-        break;
-    case ParticleEmitter::BLEND_OPAQUE:
-        ((RadioButton*)_form->getControl("opaque"))->setSelected(true);
-        break;
-    case ParticleEmitter::BLEND_TRANSPARENT:
-        ((RadioButton*)_form->getControl("transparent"))->setSelected(true);
-        break;
-    }
-}
+#include "ParticlesGame.h"
+
+// Declare our game instance.
+ParticlesGame game;
+
+#define DEFAULT_PARTICLE_EMITTER "res/fire.particle"
+
+const float INPUT_SENSITIVITY = 0.05f;
+const float PANNING_SENSITIVITY = 0.01f;
+const float ROTATE_SENSITIVITY = 0.25f;
+const Vector4 BACKGROUND_COLOR = Vector4::zero();
+const float INITIAL_ZOOM = 6.0f;
+
+ParticlesGame::ParticlesGame() : _scene(NULL), _panning(false), _rotating(false), _zooming(false)
+{
+}
+
+void ParticlesGame::addGrid(unsigned int lineCount)
+{
+    float z = -1;
+
+    // There needs to be an odd number of lines
+    lineCount |= 1;
+    const unsigned int pointCount = lineCount * 4;
+    const unsigned int verticesSize = pointCount * (3 + 3);  // (3 (position(xyz) + 3 color(rgb))
+
+    std::vector<float> vertices;
+    vertices.resize(verticesSize);
+
+    const float gridLength = (float)(lineCount / 2);
+    float value = -gridLength;
+    for (unsigned int i = 0; i < verticesSize; ++i)
+    {
+        // Default line color is dark grey
+        Vector4 color(0.3f, 0.3f, 0.3f, 1.0f);
+
+        // Every 10th line is brighter grey
+        if (((int)value) % 10 == 0)
+        {
+            color.set(0.45f, 0.45f, 0.45f, 1.0f);
+        }
+
+        // The Z axis is blue
+        if (value == 0.0f)
+        {
+            color.set(0.15f, 0.15f, 0.7f, 1.0f);
+        }
+
+        // Build the lines
+        vertices[i] = value;
+        vertices[++i] = -gridLength;
+        vertices[++i] = z;
+        vertices[++i] = color.x;
+        vertices[++i] = color.y;
+        vertices[++i] = color.z;
+
+        vertices[++i] = value;
+        vertices[++i] = gridLength;
+        vertices[++i] = z;
+        vertices[++i] = color.x;
+        vertices[++i] = color.y;
+        vertices[++i] = color.z;
+
+        // The X axis is red
+        if (value == 0.0f)
+        {
+            color.set(0.7f, 0.15f, 0.15f, 1.0f);
+        }
+        vertices[++i] = -gridLength;
+        vertices[++i] = value;
+        vertices[++i] = z;
+        vertices[++i] = color.x;
+        vertices[++i] = color.y;
+        vertices[++i] = color.z;
+
+        vertices[++i] = gridLength;
+        vertices[++i] = value;
+        vertices[++i] = z;
+        vertices[++i] = color.x;
+        vertices[++i] = color.y;
+        vertices[++i] = color.z;
+
+        value += 1.0f;
+    }
+    VertexFormat::Element elements[] =
+    {
+        VertexFormat::Element(VertexFormat::POSITION, 3),
+        VertexFormat::Element(VertexFormat::COLOR, 3)
+    };
+    Mesh* mesh = Mesh::createMesh(VertexFormat(elements, 2), pointCount, false);
+    if (mesh == NULL)
+        return;
+
+    mesh->setPrimitiveType(Mesh::LINES);
+    mesh->setVertexData(&vertices[0], 0, pointCount);
+
+    Model* model = Model::create(mesh);
+    model->setMaterial("res/grid.material");
+    SAFE_RELEASE(mesh);
+
+    _scene->addNode("grid")->setModel(model);
+    model->release();
+}
+
+void ParticlesGame::initialize()
+{
+    // Display the gameplay splash screen
+    displayScreen(this, &ParticlesGame::drawSplash, NULL, 250L);
+
+    setMultiTouch(true);
+
+    // Set keyboard state.
+    _wDown = _aDown = _sDown = _dDown = false;
+    _touched = false;
+    _prevX = _prevY = 0;
+
+    // Create a scene with a camera node.
+    // The camera node is a child of a node at the same location as the particle emitter.
+    // The camera node is offset from its parent, looking straight at it.
+    // That way, when we rotate the parent node, the camera stays aimed at the particle emitter.
+    _scene = Scene::create();
+    Node* cameraNode = _scene->addNode("Camera");
+    _cameraParent = _scene->addNode("CameraParent");
+    _cameraParent->addChild(cameraNode);
+    Camera* camera = Camera::createPerspective(45.0f, (float)getWidth() / (float)getHeight(), 0.25f, 1000.0f);
+    cameraNode->setCamera(camera);
+    cameraNode->setTranslation(0.0f, 0.0f, INITIAL_ZOOM);
+    _scene->setActiveCamera(camera);
+    SAFE_RELEASE(camera);
+
+    addGrid(61);
+
+    // Create a font for drawing the framerate.
+    _font = Font::create("res/arial.gpb");
+
+    // Load the form for editing ParticleEmitters.
+    _form = Form::create("res/editor.form");
+    _form->setConsumeInputEvents(false);
+    //_form->setState(Control::FOCUS);
+
+    // Store pointers to UI controls we care about.
+    _startRed = (Slider*)_form->getControl("startRed");
+    _startGreen = (Slider*)_form->getControl("startGreen");
+    _startBlue = (Slider*)_form->getControl("startBlue");
+    _startAlpha = (Slider*)_form->getControl("startAlpha");
+    _endRed = (Slider*)_form->getControl("endRed");
+    _endGreen = (Slider*)_form->getControl("endGreen");
+    _endBlue = (Slider*)_form->getControl("endBlue");
+    _endAlpha = (Slider*)_form->getControl("endAlpha");
+    _particleProperties = (Container*)_form->getControl("particleProperties");
+    _startMin = (Slider*)_form->getControl("startMin");
+    _startMax = (Slider*)_form->getControl("startMax");
+    _endMin = (Slider*)_form->getControl("endMin");
+    _endMax = (Slider*)_form->getControl("endMax");
+    _energyMin = (Slider*)_form->getControl("energyMin");
+    _energyMax = (Slider*)_form->getControl("energyMax");
+    _emissionRate = (Slider*)_form->getControl("emissionRate");
+    _started = (CheckBox*)_form->getControl("started");
+    _reset = (Button*)_form->getControl("reset");
+    _emit = (Button*)_form->getControl("emit");
+    _zoomIn = (Button*)_form->getControl("zoomIn");
+    _zoomOut = (Button*)_form->getControl("zoomOut");
+    _save = (Button*)_form->getControl("save");
+    _load = (Button*)_form->getControl("load");
+    _burstSize = (Slider*)_form->getControl("burstSize");
+    _posVarX = (Slider*)_form->getControl("posVarX");
+    _posVarY = (Slider*)_form->getControl("posVarY");
+    _posVarZ = (Slider*)_form->getControl("posVarZ");
+    _velX = (Slider*)_form->getControl("velocityX");
+    _velY = (Slider*)_form->getControl("velocityY");
+    _velZ = (Slider*)_form->getControl("velocityZ");
+    _velVarX = (Slider*)_form->getControl("velocityVarX");
+    _velVarY = (Slider*)_form->getControl("velocityVarY");
+    _velVarZ = (Slider*)_form->getControl("velocityVarZ");
+    _accelX = (Slider*)_form->getControl("accelX");
+    _accelY = (Slider*)_form->getControl("accelY");
+    _accelZ = (Slider*)_form->getControl("accelZ");
+    _accelVarX = (Slider*)_form->getControl("accelVarX");
+    _accelVarY = (Slider*)_form->getControl("accelVarY");
+    _accelVarZ = (Slider*)_form->getControl("accelVarZ");
+    _spinSpeedMin = (Slider*)_form->getControl("spinSpeedMin");
+    _spinSpeedMax = (Slider*)_form->getControl("spinSpeedMax");
+    _axisX = (Slider*)_form->getControl("axisX");
+    _axisY = (Slider*)_form->getControl("axisY");
+    _axisZ = (Slider*)_form->getControl("axisZ");
+    _axisVarX = (Slider*)_form->getControl("axisVarX");
+    _axisVarY = (Slider*)_form->getControl("axisVarY");
+    _axisVarZ = (Slider*)_form->getControl("axisVarZ");
+    _rotationSpeedMin = (Slider*)_form->getControl("rotationSpeedMin");
+    _rotationSpeedMax = (Slider*)_form->getControl("rotationSpeedMax");
+    _vsync = (CheckBox*)_form->getControl("vsync");
+
+    // Listen for UI events.
+    _startRed->addListener(this, Listener::VALUE_CHANGED);
+    _startGreen->addListener(this, Listener::VALUE_CHANGED);
+    _startBlue->addListener(this, Listener::VALUE_CHANGED);
+    _startAlpha->addListener(this, Listener::VALUE_CHANGED);
+    _endRed->addListener(this, Listener::VALUE_CHANGED);
+    _endGreen->addListener(this, Listener::VALUE_CHANGED);
+    _endBlue->addListener(this, Listener::VALUE_CHANGED);
+    _endAlpha->addListener(this, Listener::VALUE_CHANGED);
+    _startMin->addListener(this, Listener::VALUE_CHANGED);
+    _startMax->addListener(this, Listener::VALUE_CHANGED);
+    _endMin->addListener(this, Listener::VALUE_CHANGED);
+    _endMax->addListener(this, Listener::VALUE_CHANGED);
+    _energyMin->addListener(this, Listener::VALUE_CHANGED);
+    _energyMax->addListener(this, Listener::VALUE_CHANGED);
+    _emissionRate->addListener(this, Listener::VALUE_CHANGED);
+    _started->addListener(this, Listener::VALUE_CHANGED);
+    _reset->addListener(this, Listener::CLICK);
+    _emit->addListener(this, Listener::CLICK);
+    _zoomIn->addListener(this, Listener::PRESS);
+    _zoomIn->addListener(this, Listener::RELEASE);
+    _zoomOut->addListener(this, Listener::PRESS);
+    _zoomOut->addListener(this, Listener::RELEASE);
+    _save->addListener(this, Listener::RELEASE);
+    _load->addListener(this, Listener::RELEASE);
+    _burstSize->addListener(this, Listener::VALUE_CHANGED);
+    _form->getControl("posX")->addListener(this, Listener::VALUE_CHANGED);
+    _form->getControl("posY")->addListener(this, Listener::VALUE_CHANGED);
+    _form->getControl("posZ")->addListener(this, Listener::VALUE_CHANGED);
+    _posVarX->addListener(this, Listener::VALUE_CHANGED);
+    _posVarY->addListener(this, Listener::VALUE_CHANGED);
+    _posVarZ->addListener(this, Listener::VALUE_CHANGED);
+    _velX->addListener(this, Listener::VALUE_CHANGED);
+    _velY->addListener(this, Listener::VALUE_CHANGED);
+    _velZ->addListener(this, Listener::VALUE_CHANGED);
+    _velVarX->addListener(this, Listener::VALUE_CHANGED);
+    _velVarY->addListener(this, Listener::VALUE_CHANGED);
+    _velVarZ->addListener(this, Listener::VALUE_CHANGED);
+    _accelX->addListener(this, Listener::VALUE_CHANGED);
+    _accelY->addListener(this, Listener::VALUE_CHANGED);
+    _accelZ->addListener(this, Listener::VALUE_CHANGED);
+    _accelVarX->addListener(this, Listener::VALUE_CHANGED);
+    _accelVarY->addListener(this, Listener::VALUE_CHANGED);
+    _accelVarZ->addListener(this, Listener::VALUE_CHANGED);
+    _spinSpeedMin->addListener(this, Listener::VALUE_CHANGED);
+    _spinSpeedMax->addListener(this, Listener::VALUE_CHANGED);
+    _axisX->addListener(this, Listener::VALUE_CHANGED);
+    _axisY->addListener(this, Listener::VALUE_CHANGED);
+    _axisZ->addListener(this, Listener::VALUE_CHANGED);
+    _axisVarX->addListener(this, Listener::VALUE_CHANGED);
+    _axisVarY->addListener(this, Listener::VALUE_CHANGED);
+    _axisVarZ->addListener(this, Listener::VALUE_CHANGED);
+    _rotationSpeedMin->addListener(this, Listener::VALUE_CHANGED);
+    _rotationSpeedMax->addListener(this, Listener::VALUE_CHANGED);
+    _vsync->addListener(this, Listener::VALUE_CHANGED);
+    _form->getControl("sprite")->addListener(this, Listener::CLICK);
+    _form->getControl("additive")->addListener(this, Listener::VALUE_CHANGED);
+    _form->getControl("transparent")->addListener(this, Listener::VALUE_CHANGED);
+    _form->getControl("multiply")->addListener(this, Listener::VALUE_CHANGED);
+    _form->getControl("opaque")->addListener(this, Listener::VALUE_CHANGED);
+    _form->getControl("updateFrames")->addListener(this, Listener::CLICK);
+
+    // Load preset emitters.
+    loadEmitters();
+
+    updateImageControl();
+}
+
+
+std::string ParticlesGame::toString(bool b)
+{
+    return b ? "true" : "false";
+}
+
+std::string ParticlesGame::toString(int i)
+{
+    char buf[1024];
+    sprintf(buf, "%d", i);
+    return buf;
+}
+
+std::string ParticlesGame::toString(unsigned int i)
+{
+    char buf[1024];
+    sprintf(buf, "%d", i);
+    return buf;
+}
+
+std::string ParticlesGame::toString(const Vector3& v)
+{
+    std::ostringstream s;
+    s << v.x << ", " << v.y << ", " << v.z;
+    return s.str();
+}
+
+std::string ParticlesGame::toString(const Vector4& v)
+{
+    std::ostringstream s;
+    s << v.x << ", " << v.y << ", " << v.z << ", " << v.w;
+    return s.str();
+}
+
+std::string ParticlesGame::toString(const Quaternion& q)
+{
+    std::ostringstream s;
+    s << q.x << ", " << q.y << ", " << q.z << ", " << q.w;
+    return s.str();
+}
+
+std::string ParticlesGame::toString(ParticleEmitter::TextureBlending blending)
+{
+    switch (blending)
+    {
+        case ParticleEmitter::BLEND_OPAQUE:
+            return "OPAQUE";
+        case ParticleEmitter::BLEND_TRANSPARENT:
+            return "TRANSPARENT";
+        case ParticleEmitter::BLEND_ADDITIVE:
+            return "ADDITIVE";
+        case ParticleEmitter::BLEND_MULTIPLIED:
+            return "MULTIPLIED";
+        default:
+            return "TRANSPARENT";
+    }
+}
+
+void ParticlesGame::saveFile()
+{
+    std::string filename;
+    filename = FileSystem::displayFileDialog(FileSystem::SAVE, "Save Particle File", "Particle Files", "particle");
+
+    if (filename.length() == 0)
+        return;
+
+    ParticleEmitter* e = _particleEmitter;
+
+    // Extract just the particle name from the filename
+    std::string dir = FileSystem::getDirectoryName(filename.c_str());
+    std::string ext = FileSystem::getExtension(filename.c_str());
+    std::string name = filename.substr(dir.length(), filename.length() - dir.length() - ext.length());
+
+    Texture* texture = e->getTexture();
+    std::string texturePath = texture->getPath();
+    std::string textureDir = FileSystem::getDirectoryName(texturePath.c_str());
+    texturePath = texturePath.substr(textureDir.length());
+
+    // Get camera rotation as axis-angle
+    Vector3 cameraAxis;
+    float cameraAngle = MATH_RAD_TO_DEG(_cameraParent->getRotation().toAxisAngle(&cameraAxis));
+
+    // Write out a properties file
+    std::ostringstream s;
+    s << 
+        "particle " << name << "\n" <<
+        "{\n" <<
+        "    sprite\n" <<
+        "    {\n" <<
+        "        path = " << texturePath << "\n" <<
+        "        width = " << e->getSpriteWidth() << "\n" <<
+        "        height = " << e->getSpriteHeight() << "\n" <<
+        "        blending = " << toString(e->getTextureBlending()) << "\n" <<
+        "        animated = " << toString(e->isSpriteAnimated()) << "\n" <<
+        "        looped = " << toString(e->isSpriteLooped()) << "\n" <<
+        "        frameCount = " << e->getSpriteFrameCount() << "\n" <<
+        "        frameRandomOffset = " << e->getSpriteFrameRandomOffset() << "\n" <<
+        "        frameDuration = " << e->getSpriteFrameDuration() << "\n" <<
+        "    }\n" <<
+        "\n" <<
+        "    particleCountMax = " << e->getParticleCountMax() << "\n" <<
+        "    emissionRate = " << e->getEmissionRate() << "\n" <<
+        "    ellipsoid = " << toString(e->isEllipsoid()) << "\n" <<
+        "    orbitPosition = " << toString(e->getOrbitPosition()) << "\n" <<
+        "    orbitVelocity = " << toString(e->getOrbitVelocity()) << "\n" <<
+        "    orbitAcceleration = " << toString(e->getOrbitAcceleration()) << "\n" <<
+        "    sizeStartMin = " << e->getSizeStartMin() << "\n" <<
+        "    sizeStartMax = " << e->getSizeStartMax() << "\n" <<
+        "    sizeEndMin = " << e->getSizeEndMin() << "\n" <<
+        "    sizeEndMax = " << e->getSizeEndMax() << "\n" <<
+        "    energyMin = " << e->getEnergyMin() << "\n" <<
+        "    energyMax = " << e->getEnergyMax() << "\n" <<
+        "    colorStart = " << toString(e->getColorStart()) << "\n" <<
+        "    colorStartVar = " << toString(e->getColorStartVariance()) << "\n" <<
+        "    colorEnd = " << toString(e->getColorEnd()) << "\n" <<
+        "    colorEndVar = " << toString(e->getColorEndVariance()) << "\n" <<
+        "    position = " << toString(e->getPosition()) << "\n" <<
+        "    positionVar = " << toString(e->getPositionVariance()) << "\n" <<
+        "    velocity = " << toString(e->getVelocity()) << "\n" <<
+        "    velocityVar = " << toString(e->getVelocityVariance()) << "\n" <<
+        "    acceleration = " << toString(e->getAcceleration()) << "\n" <<
+        "    accelerationVar = " << toString(e->getAccelerationVariance()) << "\n" <<
+        "    rotationPerParticleSpeedMin = " << e->getRotationPerParticleSpeedMin() << "\n" <<
+        "    rotationPerParticleSpeedMax = " << e->getRotationPerParticleSpeedMax() << "\n" <<
+        "\n" <<
+        "    editor\n" <<
+        "    {\n" <<
+        "        cameraTranslation = " << toString(_cameraParent->getTranslation()) << "\n" <<
+        "        cameraZoom = " << toString(_scene->getActiveCamera()->getNode()->getTranslation()) << "\n" <<
+        "        cameraRotation = " << toString(cameraAxis) << ", " << cameraAngle << "\n" <<
+        "        sizeMax = " << _startMax->getMax() << "\n" <<
+        "        energyMax = " << _energyMax->getMax() << "\n" <<
+        "    }\n"
+        "}\n";
+
+    std::string text = s.str();
+    Stream* stream = FileSystem::open(filename.c_str(), FileSystem::WRITE);
+    stream->write(text.c_str(), 1, text.length());
+    stream->close();
+    SAFE_DELETE(stream);
+}
+
+void ParticlesGame::controlEvent(Control* control, EventType evt)
+{
+    std::string id = control->getId();
+
+    // Handle UI events.
+    ParticleEmitter* emitter = _particleEmitterNode->getParticleEmitter();
+    switch(evt)
+    {
+    case Listener::VALUE_CHANGED:
+        if (control == _startRed)
+        {
+            Vector4 startColor = emitter->getColorStart();
+            startColor.x = _startRed->getValue();
+            emitter->setColor(startColor, emitter->getColorStartVariance(), emitter->getColorEnd(), emitter->getColorEndVariance());
+        }
+        else if (control == _startGreen)
+        {
+            Vector4 startColor = emitter->getColorStart();
+            startColor.y = _startGreen->getValue();
+            emitter->setColor(startColor, emitter->getColorStartVariance(), emitter->getColorEnd(), emitter->getColorEndVariance());
+        }
+        else if (control == _startBlue)
+        {
+            Vector4 startColor = emitter->getColorStart();
+            startColor.z = _startBlue->getValue();
+            emitter->setColor(startColor, emitter->getColorStartVariance(), emitter->getColorEnd(), emitter->getColorEndVariance());
+        }
+        else if (control == _startAlpha)
+        {
+            Vector4 startColor = emitter->getColorStart();
+            startColor.w = _startAlpha->getValue();
+            emitter->setColor(startColor, emitter->getColorStartVariance(), emitter->getColorEnd(), emitter->getColorEndVariance());
+        }
+        else if (control == _endRed)
+        {
+            Vector4 endColor = emitter->getColorEnd();
+            endColor.x = _endRed->getValue();
+            emitter->setColor(emitter->getColorStart(), emitter->getColorStartVariance(), endColor, emitter->getColorEndVariance());
+        }
+        else if (control == _endGreen)
+        {
+            Vector4 endColor = emitter->getColorEnd();
+            endColor.y = _endGreen->getValue();
+            emitter->setColor(emitter->getColorStart(), emitter->getColorStartVariance(), endColor, emitter->getColorEndVariance());
+        }
+        else if (control == _endBlue)
+        {
+            Vector4 endColor = emitter->getColorEnd();
+            endColor.z = _endBlue->getValue();
+            emitter->setColor(emitter->getColorStart(), emitter->getColorStartVariance(), endColor, emitter->getColorEndVariance());
+        }
+        else if (control == _endAlpha)
+        {
+            Vector4 endColor = emitter->getColorEnd();
+            endColor.w = _endAlpha->getValue();
+            emitter->setColor(emitter->getColorStart(), emitter->getColorStartVariance(), endColor, emitter->getColorEndVariance());
+        }
+        else if (control == _startMin)
+        {
+            emitter->setSize(_startMin->getValue(), emitter->getSizeStartMax(), emitter->getSizeEndMin(), emitter->getSizeEndMax());
+        }
+        else if (control == _startMax)
+        {
+            emitter->setSize(emitter->getSizeStartMin(), _startMax->getValue(), emitter->getSizeEndMin(), emitter->getSizeEndMax());
+        }
+        else if (control == _endMin)
+        {
+            emitter->setSize(emitter->getSizeStartMin(), emitter->getSizeStartMax(), _endMin->getValue(), emitter->getSizeEndMax());
+        }
+        else if (control == _endMax)
+        {
+            emitter->setSize(emitter->getSizeStartMin(), emitter->getSizeStartMax(), emitter->getSizeEndMin(), _endMax->getValue());
+        }
+        else if (control == _energyMin)
+        {
+            emitter->setEnergy(_energyMin->getValue(), emitter->getEnergyMax());
+        }
+        else if (control == _energyMax)
+        {
+            emitter->setEnergy(emitter->getEnergyMin(), _energyMax->getValue());
+        }
+        else if (control == _emissionRate)
+        {
+            emitter->setEmissionRate(_emissionRate->getValue());
+        }
+        else if (id == "posX")
+        {
+            Vector3 pos(emitter->getPosition());
+            pos.x = ((Slider*)control)->getValue();
+            emitter->setPosition(pos, emitter->getPositionVariance());
+        }
+        else if (id == "posY")
+        {
+            Vector3 pos(emitter->getPosition());
+            pos.y = ((Slider*)control)->getValue();
+            emitter->setPosition(pos, emitter->getPositionVariance());
+        }
+        else if (id == "posZ")
+        {
+            Vector3 pos(emitter->getPosition());
+            pos.z = ((Slider*)control)->getValue();
+            emitter->setPosition(pos, emitter->getPositionVariance());
+        }
+        else if (control == _posVarX)
+        {
+            Vector3 posVar = emitter->getPositionVariance();
+            posVar.x = _posVarX->getValue();
+            emitter->setPosition(emitter->getPosition(), posVar);
+        }
+        else if (control == _posVarY)
+        {
+            Vector3 posVar = emitter->getPositionVariance();
+            posVar.y = _posVarY->getValue();
+            emitter->setPosition(emitter->getPosition(), posVar);
+        }
+        else if (control == _posVarZ)
+        {
+            Vector3 posVar = emitter->getPositionVariance();
+            posVar.z = _posVarZ->getValue();
+            emitter->setPosition(emitter->getPosition(), posVar);
+        }
+        else if (control == _velX)
+        {
+            Vector3 vel = emitter->getVelocity();
+            vel.x = _velX->getValue();
+            emitter->setVelocity(vel, emitter->getVelocityVariance());
+        }
+        else if (control == _velY)
+        {
+            Vector3 vel = emitter->getVelocity();
+            vel.y = _velY->getValue();
+            emitter->setVelocity(vel, emitter->getVelocityVariance());
+        }
+        else if (control == _velZ)
+        {
+            Vector3 vel = emitter->getVelocity();
+            vel.z = _velZ->getValue();
+            emitter->setVelocity(vel, emitter->getVelocityVariance());
+        }
+        else if (control == _velVarX)
+        {
+            Vector3 velVar = emitter->getVelocityVariance();
+            velVar.x = _velVarX->getValue();
+            emitter->setVelocity(emitter->getVelocity(), velVar);
+        }
+        else if (control == _velVarY)
+        {
+            Vector3 velVar = emitter->getVelocityVariance();
+            velVar.y = _velVarY->getValue();
+            emitter->setVelocity(emitter->getVelocity(), velVar);
+        }
+        else if (control == _velVarZ)
+        {
+            Vector3 velVar = emitter->getVelocityVariance();
+            velVar.z = _velVarZ->getValue();
+            emitter->setVelocity(emitter->getVelocity(), velVar);
+        }
+        else if (control == _accelX)
+        {
+            Vector3 accel = emitter->getAcceleration();
+            accel.x = _accelX->getValue();
+            emitter->setAcceleration(accel, emitter->getAccelerationVariance());
+        }
+        else if (control == _accelY)
+        {
+            Vector3 accel = emitter->getAcceleration();
+            accel.y = _accelY->getValue();
+            emitter->setAcceleration(accel, emitter->getAccelerationVariance());
+        }
+        else if (control == _accelZ)
+        {
+            Vector3 accel = emitter->getAcceleration();
+            accel.z = _accelZ->getValue();
+            emitter->setAcceleration(accel, emitter->getAccelerationVariance());
+        }
+        else if (control == _accelVarX)
+        {
+            Vector3 accelVar = emitter->getAccelerationVariance();
+            accelVar.x = _accelVarX->getValue();
+            emitter->setAcceleration(emitter->getAcceleration(), accelVar);
+        }
+        else if (control == _accelVarY)
+        {
+            Vector3 accelVar = emitter->getAccelerationVariance();
+            accelVar.y = _accelVarY->getValue();
+            emitter->setAcceleration(emitter->getAcceleration(), accelVar);
+        }
+        else if (control == _accelVarZ)
+        {
+            Vector3 accelVar = emitter->getAccelerationVariance();
+            accelVar.z = _accelVarZ->getValue();
+            emitter->setAcceleration(emitter->getAcceleration(), accelVar);
+        }
+        else if (control == _spinSpeedMin)
+        {
+            emitter->setRotationPerParticle(_spinSpeedMin->getValue(), emitter->getRotationPerParticleSpeedMax());
+        }
+        else if (control == _spinSpeedMax)
+        {
+            emitter->setRotationPerParticle(emitter->getRotationPerParticleSpeedMin(), _spinSpeedMax->getValue());
+        }
+        else if (control == _axisX)
+        {
+            Vector3 axis = emitter->getRotationAxis();
+            axis.x = _axisX->getValue();
+            emitter->setRotation(emitter->getRotationSpeedMin(), emitter->getRotationSpeedMax(), axis, emitter->getRotationAxisVariance());
+        }
+        else if (control == _axisY)
+        {
+            Vector3 axis = emitter->getRotationAxis();
+            axis.y = _axisY->getValue();
+            emitter->setRotation(emitter->getRotationSpeedMin(), emitter->getRotationSpeedMax(), axis, emitter->getRotationAxisVariance());
+        }
+        else if (control == _axisZ)
+        {
+            Vector3 axis = emitter->getRotationAxis();
+            axis.z = _axisZ->getValue();
+            emitter->setRotation(emitter->getRotationSpeedMin(), emitter->getRotationSpeedMax(), axis, emitter->getRotationAxisVariance());
+        }
+        else if (control == _axisVarX)
+        {
+            Vector3 axisVar = emitter->getRotationAxisVariance();
+            axisVar.x = _axisVarX->getValue();
+            emitter->setRotation(emitter->getRotationSpeedMin(), emitter->getRotationSpeedMax(), emitter->getRotationAxis(), axisVar);
+        }
+        else if (control == _axisVarY)
+        {
+            Vector3 axisVar = emitter->getRotationAxisVariance();
+            axisVar.y = _axisVarY->getValue();
+            emitter->setRotation(emitter->getRotationSpeedMin(), emitter->getRotationSpeedMax(), emitter->getRotationAxis(), axisVar);
+        }
+        else if (control == _axisVarZ)
+        {
+            Vector3 axisVar = emitter->getRotationAxisVariance();
+            axisVar.z = _axisVarZ->getValue();
+            emitter->setRotation(emitter->getRotationSpeedMin(), emitter->getRotationSpeedMax(), emitter->getRotationAxis(), axisVar);
+        }
+        else if (control == _rotationSpeedMin)
+        {
+            emitter->setRotation(_rotationSpeedMin->getValue(), emitter->getRotationSpeedMax(), emitter->getRotationAxis(), emitter->getRotationAxisVariance());
+        }
+        else if (control == _rotationSpeedMax)
+        {
+            emitter->setRotation(emitter->getRotationSpeedMin(), _rotationSpeedMax->getValue(), emitter->getRotationAxis(), emitter->getRotationAxisVariance());
+        }
+        else if (control == _burstSize)
+        {
+            char txt[25];
+            sprintf(txt, "Burst Size\n\n%.0f", _burstSize->getValue());
+            _burstSize->setText(txt);
+        }
+        else if (control == _started)
+        {
+            if (_started->isChecked())
+            {
+                emitter->start();
+            }
+            else
+            {
+                emitter->stop();
+            }
+        }
+        else if (control == _vsync)
+        {
+            Game::getInstance()->setVsync(_vsync->isChecked());
+        }
+        else if (id == "additive")
+        {
+            if (((RadioButton*)control)->isSelected())
+                emitter->setTextureBlending(ParticleEmitter::BLEND_ADDITIVE);
+        }
+        else if (id == "transparent")
+        {
+            if (((RadioButton*)control)->isSelected())
+                emitter->setTextureBlending(ParticleEmitter::BLEND_TRANSPARENT);
+        }
+        else if (id == "multiply")
+        {
+            if (((RadioButton*)control)->isSelected())
+                emitter->setTextureBlending(ParticleEmitter::BLEND_MULTIPLIED);
+        }
+        else if (id == "opaque")
+        {
+            if (((RadioButton*)control)->isSelected())
+                emitter->setTextureBlending(ParticleEmitter::BLEND_OPAQUE);
+        }
+        break;
+    case Listener::CLICK:
+        if (control == _reset)
+        {
+            // Re-load the current emitter and reset the view
+            _particleEmitter = ParticleEmitter::create(_url.c_str());
+            emitterChanged();
+        }
+        else if (control == _emit)
+        {
+            // Emit a burst of particles.
+            unsigned int burstSize = (unsigned int)_burstSize->getValue();
+            emitter->emitOnce(burstSize);
+        }
+        else if (id == "sprite")
+        {
+            updateTexture();
+        }
+        else if (id == "updateFrames")
+        {
+            updateFrames();
+        }
+        break;
+    case Listener::PRESS:
+        if (control == _zoomIn)
+        {
+            _wDown = true;
+        }
+        else if (control == _zoomOut)
+        {
+            _sDown = true;
+        }
+        break;
+    case Listener::RELEASE:
+        if (control == _zoomIn)
+        {
+            _wDown = false;
+        }
+        else if (control == _zoomOut)
+        {
+            _sDown = false;
+        }
+        else if (control == _save)
+        {
+            Game::getInstance()->pause();
+            saveFile();
+            Game::getInstance()->resume();
+        }
+        else if (control == _load)
+        {
+            Game::getInstance()->pause();
+            std::string filename = FileSystem::displayFileDialog(FileSystem::OPEN, "Select Particle File", "Particle Files", "particle");
+            if (filename.length() > 0)
+            {
+                _url = filename;
+                _particleEmitter = ParticleEmitter::create(_url.c_str());
+                emitterChanged();
+            }
+            Game::getInstance()->resume();
+        }
+        break;
+    }
+}
+
+void ParticlesGame::updateFrames()
+{
+    Texture* texture = _particleEmitter->getTexture();
+    TextBox* cBox = (TextBox*)_form->getControl("frameCount");
+    TextBox* wBox = (TextBox*)_form->getControl("frameWidth");
+    TextBox* hBox = (TextBox*)_form->getControl("frameHeight");
+    unsigned int fc = (unsigned int)atoi(cBox->getText());
+    unsigned int w = (unsigned int)atoi(wBox->getText());
+    unsigned int h = (unsigned int)atoi(hBox->getText());
+    if (fc > 0 && fc < 256 && fc < 1000 && w > 0 && h > 0 && w < 4096 && h < 4096)
+    {
+        if (w > _particleEmitter->getTexture()->getWidth())
+        {
+            wBox->setText(toString(texture->getWidth()).c_str());
+        }
+        if (h > texture->getHeight())
+        {
+            hBox->setText(toString(texture->getHeight()).c_str());
+        }
+
+        _particleEmitter->setSpriteFrameCoords(fc, w, h);
+    }
+}
+
+void ParticlesGame::finalize()
+{
+    SAFE_RELEASE(_scene);
+    SAFE_RELEASE(_form);
+    SAFE_RELEASE(_font);
+    SAFE_RELEASE(_particleEmitter);
+}
+
+void ParticlesGame::update(float elapsedTime)
+{
+    // Update camera movement
+    if (_wDown)
+    {
+        Vector3 v = _scene->getActiveCamera()->getNode()->getForwardVector();
+        v.normalize();
+        v.scale(INPUT_SENSITIVITY * elapsedTime);
+        _scene->getActiveCamera()->getNode()->translate(v);
+    }
+    if (_aDown)
+    {
+        Vector3 v = _scene->getActiveCamera()->getNode()->getLeftVector();
+        v.normalize();
+        v.scale(INPUT_SENSITIVITY * elapsedTime);
+        _scene->getActiveCamera()->getNode()->translate(v);
+    }
+    if (_sDown)
+    {
+        Vector3 v = _scene->getActiveCamera()->getNode()->getBackVector();
+        v.normalize();
+        v.scale(INPUT_SENSITIVITY * elapsedTime);
+        _scene->getActiveCamera()->getNode()->translate(v);
+    }
+    if (_dDown)
+    {
+        Vector3 v = _scene->getActiveCamera()->getNode()->getRightVector();
+        v.normalize();
+        v.scale(INPUT_SENSITIVITY * elapsedTime);
+        _scene->getActiveCamera()->getNode()->translate(v);
+    }
+
+    // Update particles.
+    _particleEmitterNode->getParticleEmitter()->update(elapsedTime);
+}
+
+void ParticlesGame::render(float elapsedTime)
+{
+    // Clear the color and depth buffers.
+    clear(CLEAR_COLOR_DEPTH, BACKGROUND_COLOR, 1.0f, 0);
+
+    // Visit all the nodes in the scene for drawing.
+    _scene->visit(this, &ParticlesGame::drawScene, (void*)0);
+
+    // Draw the UI.
+    _form->draw();
+
+    // Draw the framerate and number of live particles.
+    drawFrameRate(_font, Vector4(1, 1, 1, 1), 170, 40, getFrameRate());
+}
+
+bool ParticlesGame::drawScene(Node* node, void* cookie)
+{
+    if (node->getModel())
+        node->getModel()->draw();
+    if (node->getParticleEmitter())
+        node->getParticleEmitter()->draw();
+    return true;
+}
+
+bool ParticlesGame::mouseEvent(Mouse::MouseEvent evt, int x, int y, int wheelDelta)
+{
+    switch (evt)
+    {
+    case Mouse::MOUSE_PRESS_MIDDLE_BUTTON:
+        Game::getInstance()->setMouseCaptured(true);
+        _panning = true;
+        return true;
+    case Mouse::MOUSE_RELEASE_MIDDLE_BUTTON:
+        Game::getInstance()->setMouseCaptured(false);
+        _panning = false;
+        return true;
+    case Mouse::MOUSE_PRESS_LEFT_BUTTON:
+        Game::getInstance()->setMouseCaptured(true);
+        _rotating = true;
+        return true;
+    case Mouse::MOUSE_RELEASE_LEFT_BUTTON:
+        Game::getInstance()->setMouseCaptured(false);
+        _rotating = false;
+        return true;
+    case Mouse::MOUSE_PRESS_RIGHT_BUTTON:
+        Game::getInstance()->setMouseCaptured(true);
+        _zooming = true;
+        return true;
+    case Mouse::MOUSE_RELEASE_RIGHT_BUTTON:
+        Game::getInstance()->setMouseCaptured(false);
+        _zooming = false;
+        return true;
+    case Mouse::MOUSE_MOVE:
+        if (_panning)
+        {
+            Vector3 n(-(float)x * PANNING_SENSITIVITY, (float)y * PANNING_SENSITIVITY, 0);
+            _cameraParent->getMatrix().transformVector(&n);
+            _cameraParent->translate(n);
+            return true;
+        }
+        else if (_rotating)
+        {
+            _cameraParent->rotateY(-MATH_DEG_TO_RAD((float)x * ROTATE_SENSITIVITY));
+            _cameraParent->rotateX(-MATH_DEG_TO_RAD((float)y * ROTATE_SENSITIVITY));
+            return true;
+        }
+        else if (_zooming)
+        {
+            Vector3 v = _scene->getActiveCamera()->getNode()->getForwardVector();
+            v.normalize();
+            v.scale((float)(x-y) * INPUT_SENSITIVITY);
+            _scene->getActiveCamera()->getNode()->translate(v);
+            return true;
+        }
+        break;
+    }
+
+    return true;
+}
+
+void ParticlesGame::touchEvent(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex)
+{
+    // Touch events that don't hit the UI
+    // allow the camera to rotate around the particle emitter.
+    switch (evt)
+    {
+    case Touch::TOUCH_PRESS:
+        _touched = true;
+        _prevX = x;
+        _prevY = y;
+        break;
+
+    case Touch::TOUCH_RELEASE:
+        _touched = false;
+        break;
+
+    case Touch::TOUCH_MOVE:
+        {
+            if (_touched)
+            {
+                int deltaX = x - _prevX;
+                int deltaY = y - _prevY;
+                _prevX = x;
+                _prevY = y;
+
+                _cameraParent->rotateY(MATH_DEG_TO_RAD(deltaX * -0.5f));
+                _cameraParent->rotateX(MATH_DEG_TO_RAD(deltaY * -0.5f));
+            }
+        }
+        break;
+    default:
+        break;
+    };
+}
+
+void ParticlesGame::keyEvent(Keyboard::KeyEvent evt, int key)
+{
+    switch(evt)
+    {
+    case Keyboard::KEY_PRESS:
+        switch (key)
+        {
+        case Keyboard::KEY_ESCAPE:
+            exit();
+            break;
+        case Keyboard::KEY_B:
+            // Disable blending.
+            _particleEmitterNode->getParticleEmitter()->setTextureBlending(ParticleEmitter::BLEND_OPAQUE);
+            break;
+        case Keyboard::KEY_W:
+            _wDown = true;
+            break;
+        case Keyboard::KEY_A:
+            _aDown = true;
+            break;
+        case Keyboard::KEY_S:
+            _sDown = true;
+            break;
+        case Keyboard::KEY_D:
+            _dDown = true;
+            break;
+        }
+        break;
+
+    case Keyboard::KEY_RELEASE:
+        switch (key)
+        {
+        case Keyboard::KEY_W:
+            _wDown = false;
+            break;
+        case Keyboard::KEY_A:
+            _aDown = false;
+            break;
+        case Keyboard::KEY_S:
+            _sDown = false;
+            break;
+        case Keyboard::KEY_D:
+            _dDown = false;
+            break;
+        }
+        break;
+    }
+}
+
+void ParticlesGame::loadEmitters()
+{
+    // Load the default particle emitter
+    _url = DEFAULT_PARTICLE_EMITTER;
+    _particleEmitter = ParticleEmitter::create(_url.c_str());
+
+    _particleEmitterNode = _scene->addNode("Particle Emitter");
+    _particleEmitterNode->setTranslation(0.0f, 0.0f, 0.0f);
+
+    emitterChanged();
+}
+
+void ParticlesGame::emitterChanged()
+{
+    ParticleEmitter* emitter = _particleEmitter;
+
+    // Set the new emitter on the node.
+    _particleEmitterNode->setParticleEmitter(_particleEmitter);
+    _particleEmitter->release();
+
+    // Reset camera view and zoom.
+    _scene->getActiveCamera()->getNode()->setTranslation(0.0f, 0.0f, 40.0f);
+    _cameraParent->setIdentity();
+    _particleEmitterNode->setIdentity();
+
+    // Set the values of UI controls to display the new emitter's settings.
+    _startRed->setValue(emitter->getColorStart().x);
+    _startGreen->setValue(emitter->getColorStart().y);
+    _startBlue->setValue(emitter->getColorStart().z);
+    _startAlpha->setValue(emitter->getColorStart().w);    
+
+    _endRed->setValue(emitter->getColorEnd().x);
+    _endGreen->setValue(emitter->getColorEnd().y);
+    _endBlue->setValue(emitter->getColorEnd().z);
+    _endAlpha->setValue(emitter->getColorEnd().w);
+
+    _startMin->setValue(emitter->getSizeStartMin());
+    _startMax->setValue(emitter->getSizeStartMax());
+    _endMin->setValue(emitter->getSizeEndMin());
+    _endMax->setValue(emitter->getSizeEndMax());
+
+    _energyMin->setValue(emitter->getEnergyMin());
+    _energyMax->setValue(emitter->getEnergyMax());
+
+    _emissionRate->setValue(emitter->getEmissionRate());
+
+    char txt[25];
+    sprintf(txt, "Burst Size\n\n%.0f", _burstSize->getValue());
+    _burstSize->setText(txt);
+
+    const Vector3& posVar = emitter->getPositionVariance();
+    _posVarX->setValue(posVar.x);
+    _posVarY->setValue(posVar.y);
+    _posVarZ->setValue(posVar.z);
+
+    const Vector3& vel = emitter->getVelocity();
+    _velX->setValue(vel.x);    
+    _velY->setValue(vel.y);
+    _velZ->setValue(vel.z);
+
+    const Vector3& velVar = emitter->getVelocityVariance();
+    _velVarX->setValue(velVar.x);
+    _velVarY->setValue(velVar.y);
+    _velVarZ->setValue(velVar.z);
+
+    const Vector3& accel = emitter->getAcceleration();
+    _accelX->setValue(accel.x);
+    _accelY->setValue(accel.y);
+    _accelZ->setValue(accel.z);
+
+    const Vector3& accelVar = emitter->getAccelerationVariance();
+    _accelVarX->setValue(accelVar.x);
+    _accelVarY->setValue(accelVar.y);
+    _accelVarZ->setValue(accelVar.z);
+
+    _spinSpeedMin->setValue(emitter->getRotationPerParticleSpeedMin());
+    _spinSpeedMax->setValue(emitter->getRotationPerParticleSpeedMax());
+
+    const Vector3& axis = emitter->getRotationAxis();
+    _axisX->setValue(axis.x);
+    _axisY->setValue(axis.y);    
+    _axisZ->setValue(axis.z);
+
+
+    const Vector3& axisVar = emitter->getRotationAxisVariance();
+    _axisVarX->setValue(axisVar.x);
+    _axisVarY->setValue(axisVar.y);
+    _axisVarZ->setValue(axisVar.z);
+
+    _rotationSpeedMin->setValue(emitter->getRotationSpeedMin());
+    _rotationSpeedMax->setValue(emitter->getRotationSpeedMax());
+
+    // Update our image control
+    updateImageControl();
+
+    // Parse editor section of particle properties
+    Properties* p = Properties::create(_url.c_str());
+    Properties* ns = p->getNamespace("editor", true);
+    if (ns)
+    {
+        Vector3 v3;
+        if (ns->getVector3("cameraTranslation", &v3))
+        {
+            _cameraParent->setTranslation(v3);
+        }
+        if (ns->getVector3("cameraZoom", &v3))
+        {
+            _scene->getActiveCamera()->getNode()->setTranslation(v3);
+        }
+        Quaternion q;
+        if (ns->getQuaternionFromAxisAngle("cameraRotation", &q))
+        {
+            _cameraParent->setRotation(q);
+        }
+        float f;
+        if ((f = ns->getFloat("sizeMax")) != 0.0f)
+        {
+            _startMin->setMax(f);
+            _startMax->setMax(f);
+            _endMin->setMax(f);
+            _endMax->setMax(f);
+        }
+        if ((f = ns->getFloat("energyMax")) != 0.0f)
+        {
+            _energyMin->setMax(f);
+            _energyMax->setMax(f);
+        }
+    }
+    SAFE_DELETE(p);
+
+    // Start the emitter
+    emitter->start();
+}
+
+void ParticlesGame::drawSplash(void* param)
+{
+    clear(CLEAR_COLOR_DEPTH, Vector4(0, 0, 0, 1), 1.0f, 0);
+    SpriteBatch* batch = SpriteBatch::create("res/logo_powered_white.png");
+    batch->start();
+    batch->draw(this->getWidth() * 0.5f, this->getHeight() * 0.5f, 0.0f, 512.0f, 512.0f, 0.0f, 1.0f, 1.0f, 0.0f, Vector4::one(), true);
+    batch->finish();
+    SAFE_DELETE(batch);
+}
+
+void ParticlesGame::drawFrameRate(Font* font, const Vector4& color, unsigned int x, unsigned int y, unsigned int fps)
+{
+    char buffer[30];
+    sprintf(buffer, "FPS: %u\nParticles: %u", fps, _particleEmitterNode->getParticleEmitter()->getParticlesCount());
+    font->start();
+    font->drawText(buffer, x, y, color, 22);
+    font->finish();
+}
+
+void ParticlesGame::resizeEvent(unsigned int width, unsigned int height)
+{
+    setViewport(gameplay::Rectangle(width, height));
+    _form->setSize(width, height);
+    _scene->getActiveCamera()->setAspectRatio((float)getWidth() / (float)getHeight());
+}
+
+void ParticlesGame::updateTexture()
+{
+    std::string file = FileSystem::displayFileDialog(FileSystem::OPEN, "Select Texture", "PNG Files", "png");
+    if (file.length() > 0)
+    {
+        // Set new sprite on our emitter
+        _particleEmitter->setTexture(file.c_str(), _particleEmitter->getTextureBlending());
+
+        // Update the UI to display the new sprite
+        updateImageControl();
+    }
+}
+
+void ParticlesGame::updateImageControl()
+{
+    ((ImageControl*)_form->getControl("sprite"))->setImage(_particleEmitter->getTexture()->getPath());
+
+    // Resize the image control so keep it to scale
+    int w = _particleEmitter->getTexture()->getWidth();
+    int h = _particleEmitter->getTexture()->getHeight();
+    int max = w > h ? w : h;
+    if (max > 140)
+    {
+        float ratio = 140.0f / max;
+        w *= ratio;
+        h *= ratio;
+    }
+    ((ImageControl*)_form->getControl("sprite"))->setSize(w, h);
+    _form->getControl("image")->setHeight(h + _form->getControl("imageSettings")->getHeight() + 50);
+
+    ((TextBox*)_form->getControl("frameCount"))->setText(toString(_particleEmitter->getSpriteFrameCount()).c_str());
+    ((TextBox*)_form->getControl("frameWidth"))->setText(toString(_particleEmitter->getSpriteWidth()).c_str());
+    ((TextBox*)_form->getControl("frameHeight"))->setText(toString(_particleEmitter->getSpriteHeight()).c_str());
+
+    switch (_particleEmitter->getTextureBlending())
+    {
+    case ParticleEmitter::BLEND_ADDITIVE:
+        ((RadioButton*)_form->getControl("additive"))->setSelected(true);
+        break;
+    case ParticleEmitter::BLEND_MULTIPLIED:
+        ((RadioButton*)_form->getControl("multiply"))->setSelected(true);
+        break;
+    case ParticleEmitter::BLEND_OPAQUE:
+        ((RadioButton*)_form->getControl("opaque"))->setSelected(true);
+        break;
+    case ParticleEmitter::BLEND_TRANSPARENT:
+        ((RadioButton*)_form->getControl("transparent"))->setSelected(true);
+        break;
+    }
+}

+ 170 - 172
samples/particles/src/ParticlesGame.h

@@ -1,172 +1,170 @@
-#ifndef PARTICLESGAME_H_
-#define PARTICLESGAME_H_
-
-#include "gameplay.h"
-
-using namespace gameplay;
-
-/**
- * Main game class.
- */
-class ParticlesGame: public Game, Control::Listener
-{
-public:
-
-    /**
-     * Constructor.
-     */
-    ParticlesGame();
-
-    /**
-     * @see Game::touchEvent
-     */
-    void touchEvent(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex);
-
-    /**
-     * @see Game::mouseEvent
-     */
-    bool mouseEvent(Mouse::MouseEvent evt, int x, int y, int wheelDelta);
-
-    /**
-     * @see Game::keyEvent
-     */
-    void keyEvent(Keyboard::KeyEvent evt, int key);
-
-    /**
-     * @see Game::resizeEvent
-     */
-    void resizeEvent(unsigned int width, unsigned int height);
-
-    /**
-     * @see Control::controlEvent
-     */
-    void controlEvent(Control* control, EventType evt);
-
-protected:
-
-    /**
-     * @see Game::initialize
-     */
-    void initialize();
-
-    /**
-     * @see Game::finalize
-     */
-    void finalize();
-
-    /**
-     * @see Game::update
-     */
-    void update(float elapsedTime);
-
-    /**
-     * @see Game::render
-     */
-    void render(float elapsedTime);
-
-private:
-
-    bool drawScene(Node* node, void* cookie);
-
-    void drawSplash(void* param);
-
-    void loadEmitters();
-
-    void emitterChanged();
-
-    void drawFrameRate(Font* font, const Vector4& color, unsigned int x, unsigned int y, unsigned int fps);
-
-    std::string openFile(const char* title, const char* filterDescription, const char* filterExtension);
-
-    void saveFile();
-
-    void updateTexture();
-
-    void updateImageControl();
-
-    void updateFrames();
-    
-    void addGrid(unsigned int lineCount);
-    
-    std::string toString(bool b);
-    
-    std::string toString(int i);
-    
-    std::string toString(unsigned int i);
-    
-    std::string toString(const Vector3& v);
-    
-    std::string toString(const Vector4& v);
-    
-    std::string toString(const Quaternion& q);
-    
-    std::string toString(ParticleEmitter::TextureBlending blending);
-
-    Scene* _scene;
-    Node* _particleEmitterNode;
-    Node* _cameraParent;
-    Form* _form;
-    bool _wDown, _sDown, _aDown, _dDown;
-    bool _touched;
-    int _prevX, _prevY;
-    ParticleEmitter* _particleEmitter;
-    std::string _url;
-    Font* _font;
-    
-    Slider* _startRed;
-    Slider* _startGreen;
-    Slider* _startBlue;
-    Slider* _startAlpha;
-    Slider* _endRed;
-    Slider* _endGreen;
-    Slider* _endBlue;
-    Slider* _endAlpha;
-    Slider* _startMin;
-    Slider* _startMax;
-    Slider* _endMin;
-    Slider* _endMax;
-    Slider* _energyMin;
-    Slider* _energyMax;
-    Slider* _emissionRate;
-    Slider* _posVarX;
-    Slider* _posVarY;
-    Slider* _posVarZ;
-    Slider* _velX;
-    Slider* _velY;
-    Slider* _velZ;
-    Slider* _velVarX;
-    Slider* _velVarY;
-    Slider* _velVarZ;
-    Slider* _accelX;
-    Slider* _accelY;
-    Slider* _accelZ;
-    Slider* _accelVarX;
-    Slider* _accelVarY;
-    Slider* _accelVarZ;
-    Slider* _spinSpeedMin;
-    Slider* _spinSpeedMax;
-    Slider* _axisX;
-    Slider* _axisY;
-    Slider* _axisZ;
-    Slider* _axisVarX;
-    Slider* _axisVarY;
-    Slider* _axisVarZ;
-    Slider* _rotationSpeedMin;
-    Slider* _rotationSpeedMax;
-    CheckBox* _started;
-    Button* _reset;
-    Button* _emit;
-    Button* _zoomIn;
-    Button* _zoomOut;
-    Button* _save;
-    Button* _load;
-    Slider* _burstSize;
-    Container* _position;
-    Container* _particleProperties;
-    CheckBox* _vsync;
-    bool _panning;
-    bool _rotating;
-    bool _zooming;
-};
-
-#endif
+#ifndef PARTICLESGAME_H_
+#define PARTICLESGAME_H_
+
+#include "gameplay.h"
+
+using namespace gameplay;
+
+/**
+ * Main game class.
+ */
+class ParticlesGame: public Game, Control::Listener
+{
+public:
+
+    /**
+     * Constructor.
+     */
+    ParticlesGame();
+
+    /**
+     * @see Game::touchEvent
+     */
+    void touchEvent(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex);
+
+    /**
+     * @see Game::mouseEvent
+     */
+    bool mouseEvent(Mouse::MouseEvent evt, int x, int y, int wheelDelta);
+
+    /**
+     * @see Game::keyEvent
+     */
+    void keyEvent(Keyboard::KeyEvent evt, int key);
+
+    /**
+     * @see Game::resizeEvent
+     */
+    void resizeEvent(unsigned int width, unsigned int height);
+
+    /**
+     * @see Control::controlEvent
+     */
+    void controlEvent(Control* control, EventType evt);
+
+protected:
+
+    /**
+     * @see Game::initialize
+     */
+    void initialize();
+
+    /**
+     * @see Game::finalize
+     */
+    void finalize();
+
+    /**
+     * @see Game::update
+     */
+    void update(float elapsedTime);
+
+    /**
+     * @see Game::render
+     */
+    void render(float elapsedTime);
+
+private:
+
+    bool drawScene(Node* node, void* cookie);
+
+    void drawSplash(void* param);
+
+    void loadEmitters();
+
+    void emitterChanged();
+
+    void drawFrameRate(Font* font, const Vector4& color, unsigned int x, unsigned int y, unsigned int fps);
+
+    void updateTexture();
+
+    void updateImageControl();
+
+    void updateFrames();
+    
+    void addGrid(unsigned int lineCount);
+
+    void saveFile();
+    
+    std::string toString(bool b);
+    
+    std::string toString(int i);
+    
+    std::string toString(unsigned int i);
+    
+    std::string toString(const Vector3& v);
+    
+    std::string toString(const Vector4& v);
+    
+    std::string toString(const Quaternion& q);
+    
+    std::string toString(ParticleEmitter::TextureBlending blending);
+
+    Scene* _scene;
+    Node* _particleEmitterNode;
+    Node* _cameraParent;
+    Form* _form;
+    bool _wDown, _sDown, _aDown, _dDown;
+    bool _touched;
+    int _prevX, _prevY;
+    ParticleEmitter* _particleEmitter;
+    std::string _url;
+    Font* _font;
+    
+    Slider* _startRed;
+    Slider* _startGreen;
+    Slider* _startBlue;
+    Slider* _startAlpha;
+    Slider* _endRed;
+    Slider* _endGreen;
+    Slider* _endBlue;
+    Slider* _endAlpha;
+    Slider* _startMin;
+    Slider* _startMax;
+    Slider* _endMin;
+    Slider* _endMax;
+    Slider* _energyMin;
+    Slider* _energyMax;
+    Slider* _emissionRate;
+    Slider* _posVarX;
+    Slider* _posVarY;
+    Slider* _posVarZ;
+    Slider* _velX;
+    Slider* _velY;
+    Slider* _velZ;
+    Slider* _velVarX;
+    Slider* _velVarY;
+    Slider* _velVarZ;
+    Slider* _accelX;
+    Slider* _accelY;
+    Slider* _accelZ;
+    Slider* _accelVarX;
+    Slider* _accelVarY;
+    Slider* _accelVarZ;
+    Slider* _spinSpeedMin;
+    Slider* _spinSpeedMax;
+    Slider* _axisX;
+    Slider* _axisY;
+    Slider* _axisZ;
+    Slider* _axisVarX;
+    Slider* _axisVarY;
+    Slider* _axisVarZ;
+    Slider* _rotationSpeedMin;
+    Slider* _rotationSpeedMax;
+    CheckBox* _started;
+    Button* _reset;
+    Button* _emit;
+    Button* _zoomIn;
+    Button* _zoomOut;
+    Button* _save;
+    Button* _load;
+    Slider* _burstSize;
+    Container* _position;
+    Container* _particleProperties;
+    CheckBox* _vsync;
+    bool _panning;
+    bool _rotating;
+    bool _zooming;
+};
+
+#endif