Browse Source

Merge branch 'next' of https://github.com/blackberry-gaming/GamePlay into next-dgough

Darryl Gough 14 years ago
parent
commit
df099cbaba

+ 7 - 2
.gitignore

@@ -1,6 +1,10 @@
 *.suo
 *.sdf
-*.opensdf
+*.opensdf
+.DS_Store*
+ehthumbs.db
+Icon?
+Thumbs.db
 /.metadata
 /169.254.0.1
 /ipch
@@ -130,4 +134,5 @@
 /gameplay/android/proguard.cfg
 /gameplay/android/local.properties
 /gameplay/android/project.properties
-/gameplay/android/obj
+/gameplay/android/obj
+

+ 16 - 12
README.md

@@ -1,18 +1,23 @@
-## GamePlay v1.1.0
+## GamePlay v1.2.0
 GamePlay is a open-source, cross-platform 3D native gaming framework making it easy to learn and write mobile and desktop games. 
 
-## Supported Platforms
-- BlackBerry PlayBook 1.0/2.0 (using BlackBerry Native SDK 1.0/2.0)
-- Apple MacOS X (using Apple XCode 4.0)
-- Microsoft Windows 7 (using Microsoft Visual Studio 2010 Pro/Express)
-	* Requires OpenAL 1.1 (http://connect.creativelabs.com/openal/Downloads/Forms/AllItems.aspx)
+## Supported Mobile Platforms
+- BlackBerry PlayBook 1/2 (using BlackBerry Native SDK 2)
+- Google Android 4 (using Google Android NDK 7)
+- Apple iOS 4/5 (using Apple XCode 4)
+
+## Supported Desktop Platforms
+- Apple MacOS X (using Apple XCode 4)
+- Microsoft Windows XP/7 (using Microsoft Visual Studio 2010)
+    * Requires [Creative OpenAL 1.1] (http://connect.creativelabs.com/openal/Downloads/Forms/AllItems.aspx)
 
 ## Roadmap for 'next' branch
-- UI Forms with Themed Overlays.
-- Improvements to Lighting.
-- Developer Guide.
-- More Samples and Tutorials.
-- Apple iOS 5 Support.
+- UI Overlays
+- Improvements to Lighting
+- More Samples and Tutorials
+
+## Licence
+The project is open sourced under the Apache 2.0 license.
 
 ## Bug Reporting and Feature Requests
 If you find a bug in a Sample, or have an enhancement request, simply file an 
@@ -27,4 +32,3 @@ PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIG
 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 
 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 
 OTHER DEALINGS IN THE SOFTWARE.
-

+ 2 - 2
gameplay.doxyfile

@@ -32,7 +32,7 @@ PROJECT_NAME           = GamePlay
 # This could be handy for archiving the generated documentation or 
 # if some version control system is used.
 
-PROJECT_NUMBER         = 1.1.0
+PROJECT_NUMBER         = 1.2.0
 
 # Using the PROJECT_BRIEF tag one can provide an optional one line description 
 # for a project that appears at the top of each page and should give viewer 
@@ -45,7 +45,7 @@ PROJECT_BRIEF          =
 # exceed 55 pixels and the maximum width should not exceed 200 pixels. 
 # Doxygen will copy the logo to the output directory.
 
-PROJECT_LOGO           = 
+PROJECT_LOGO           = C:/Code/GamePlay/gameplay-logo.png
 
 # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
 # base path where the generated documentation will be put. 

+ 2 - 0
gameplay/gameplay.vcxproj

@@ -186,11 +186,13 @@
     <None Include="src\BoundingSphere.inl" />
     <None Include="src\Curve.inl" />
     <None Include="src\Game.inl" />
+    <None Include="src\gameplay-main-ios.mm" />
     <None Include="src\gameplay-main-macos.mm" />
     <None Include="src\Image.inl" />
     <None Include="src\Matrix.inl" />
     <None Include="src\MeshBatch.inl" />
     <None Include="src\Plane.inl" />
+    <None Include="src\PlatformiOS.mm" />
     <None Include="src\PlatformMacOS.mm" />
     <None Include="src\Quaternion.inl" />
     <None Include="src\Ray.inl" />

+ 6 - 0
gameplay/gameplay.vcxproj.filters

@@ -526,6 +526,12 @@
     <None Include="src\MeshBatch.inl">
       <Filter>src</Filter>
     </None>
+    <None Include="src\gameplay-main-ios.mm">
+      <Filter>src</Filter>
+    </None>
+    <None Include="src\PlatformiOS.mm">
+      <Filter>src</Filter>
+    </None>
   </ItemGroup>
   <ItemGroup>
     <None Include="src\PhysicsFixedConstraint.inl">

+ 6 - 0
gameplay/gameplay.xcodeproj/project.pbxproj

@@ -484,6 +484,9 @@
 		5B04C5F714BFE50B00EB0071 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk/System/Library/Frameworks/QuartzCore.framework; sourceTree = DEVELOPER_DIR; };
 		5B04C5F914BFE51000EB0071 /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk/System/Library/Frameworks/OpenGLES.framework; sourceTree = DEVELOPER_DIR; };
 		5B04C5FB14BFE51600EB0071 /* OpenAL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenAL.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk/System/Library/Frameworks/OpenAL.framework; sourceTree = DEVELOPER_DIR; };
+		5B3383A214C5181E000DC4F8 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; };
+		5B3383A414C5181E000DC4F8 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; };
+		5B3383A614C5181E000DC4F8 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = Library/Frameworks/CoreGraphics.framework; sourceTree = DEVELOPER_DIR; };
 		5B43D17914C3497B008A5D9D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk/System/Library/Frameworks/CoreGraphics.framework; sourceTree = DEVELOPER_DIR; };
 		5B5ADCE214C22DF900AC6109 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = SDKs/MacOSX10.7.sdk/usr/lib/libz.dylib; sourceTree = DEVELOPER_DIR; };
 		5B5ADCE414C22E1F00AC6109 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk/usr/lib/libz.dylib; sourceTree = DEVELOPER_DIR; };
@@ -586,6 +589,9 @@
 			children = (
 				5B04C5FE14BFE52F00EB0071 /* Mac OS X */,
 				5B04C5FD14BFE52300EB0071 /* iOS */,
+				5B3383A214C5181E000DC4F8 /* UIKit.framework */,
+				5B3383A414C5181E000DC4F8 /* Foundation.framework */,
+				5B3383A614C5181E000DC4F8 /* CoreGraphics.framework */,
 			);
 			name = Frameworks;
 			sourceTree = "<group>";

+ 5 - 1
gameplay/src/Keyboard.h

@@ -182,7 +182,11 @@ public:
         KEY_LEFT_BRACE        = '{',
         KEY_BAR               = '|',
         KEY_RIGHT_BRACE       = '}',
-        KEY_TILDE             = '~'
+        KEY_TILDE             = '~',
+        KEY_EURO,
+        KEY_POUND,
+        KEY_YEN,
+        KEY_MIDDLE_DOT
     };
 
 private:

+ 22 - 2
gameplay/src/Package.cpp

@@ -94,6 +94,26 @@ bool Package::readArray(unsigned int* length, std::vector<T>* values)
     return true;
 }
 
+template <class T>
+bool Package::readArray(unsigned int* length, std::vector<T>* values, unsigned int readSize)
+{
+    assert(sizeof(T) >= readSize);
+
+    if (!read(length))
+    {
+        return false;
+    }
+    if (*length > 0 && values)
+    {
+        values->resize(*length);
+        if (fread(&(*values)[0], readSize, *length, _file) != *length)
+        {
+            return false;
+        }
+    }
+    return true;
+}
+
 std::string readString(FILE* fp)
 {
     unsigned int length;
@@ -935,7 +955,7 @@ Animation* Package::readAnimationChannel(Scene* scene, Animation* animation, con
     unsigned int interpolationCount;
 
     // read key times
-    if (!readArray(&keyTimesCount, &keyTimes))
+    if (!readArray(&keyTimesCount, &keyTimes, sizeof(unsigned int)))
     {
         LOG_ERROR_VARG("Failed to read %s for %s: %s", "keyTimes", "animation", id);
         return NULL;
@@ -963,7 +983,7 @@ Animation* Package::readAnimationChannel(Scene* scene, Animation* animation, con
     }
     
     // read interpolations
-    if (!readArray(&interpolationCount, &interpolation))
+    if (!readArray(&interpolationCount, &interpolation, sizeof(unsigned int)))
     {
         LOG_ERROR_VARG("Failed to read %s for %s: %s", "interpolation", "animation", id);
         return NULL;

+ 12 - 0
gameplay/src/Package.h

@@ -263,6 +263,18 @@ private:
     template <class T>
     bool readArray(unsigned int* length, std::vector<T>* values);
 
+    /**
+     * Reads an array of values and the array length from the current file position.
+     * 
+     * @param length A pointer to where the length of the array will be copied to.
+     * @param values A pointer to the vector to copy the values to. The vector will be resized if it is smaller than length.
+     * @param readSize The size that reads will be preformed at, size must be the same as or smaller then the sizeof(T)
+     * 
+     * @return True if successful, false if an error occurred.
+     */
+    template <class T>
+    bool readArray(unsigned int* length, std::vector<T>* values, unsigned int readSize);
+    
     /**
      * Reads 16 floats from the current file position.
      *

+ 1 - 8
gameplay/src/PlatformAndroid.cpp

@@ -39,7 +39,7 @@ ASensorEventQueue* __sensorEventQueue;
 ASensorEvent __sensorEvent;
 const ASensor* __accelerometerSensor;
 
-static int __orientationAngle;
+static int __orientationAngle = 90; // Landscape by default.
 static bool __multiTouch = false;
 bool __displayKeyboard = false;
 
@@ -452,9 +452,6 @@ static void engine_handle_cmd(struct android_app* app, int32_t cmd)
 {
     switch (cmd) 
     {
-        case APP_CMD_SAVE_STATE:
-            // TODO
-            break;
         case APP_CMD_INIT_WINDOW:
             // The window is being shown, get it ready.
             if (app->window != NULL)
@@ -529,10 +526,6 @@ Platform* Platform::create(Game* game)
 {
     Platform* platform = new Platform(game);
     
-    // TODO: Determine initial orientation angle.
-    //orientation_direction_t direction;
-    //orientation_get(&direction, &__orientationAngle);
-
     return platform;
 }
 

+ 297 - 36
gameplay/src/PlatformiOS.mm

@@ -20,36 +20,23 @@ using namespace gameplay;
 static const float ACCELEROMETER_X_FACTOR = 90.0f / WINDOW_WIDTH;
 static const float ACCELEROMETER_Y_FACTOR = 90.0f / WINDOW_HEIGHT;
 
+@class AppDelegate;
 @class View;
 
+static AppDelegate *__appDelegate = NULL;
 static View* __view = NULL;
+
 static long __timeStart;
 static long __timeAbsolute;
 static bool __vsync = WINDOW_VSYNC;
 static float __pitch;
 static float __roll;
-static int __lx;
-static int __ly;
-static bool __hasMouse = false;
-static bool __leftMouseDown = false;
-static bool __rightMouseDown = false;
-static bool __shiftDown = false;
-
 
-long getMachTimeInMilliseconds()
-{
-    static const int64_t kOneMillion = 1000 * 1000;
-    static mach_timebase_info_data_t s_timebase_info;
-    
-    if (s_timebase_info.denom == 0) 
-        (void) mach_timebase_info(&s_timebase_info);
-    
-    // mach_absolute_time() returns billionth of seconds, so divide by one million to get milliseconds
-    return (long)((mach_absolute_time() * s_timebase_info.numer) / (kOneMillion * s_timebase_info.denom));
-}
 
+long getMachTimeInMilliseconds(); 
+int getKey(unichar keyCode);
 
-@interface View : UIView 
+@interface View : UIView <UIKeyInput>
 {
     EAGLContext* context;	
     CADisplayLink* displayLink;
@@ -69,9 +56,16 @@ long getMachTimeInMilliseconds()
 - (void)startUpdating;
 - (void)stopUpdating;
 - (void)update:(id)sender;
+- (void)setSwapInterval:(NSInteger)interval;
+- (int)swapInterval;
+
+- (BOOL)showKeyboard;
+- (BOOL)dismissKeyboard;
+@end
+
+@interface View (Private)
 - (void)createFramebuffer;
 - (void)deleteFramebuffer;
-
 @end
 
 
@@ -137,11 +131,10 @@ long getMachTimeInMilliseconds()
         
         _game = Game::getInstance();
         __timeStart = getMachTimeInMilliseconds();
-        _game->run(WINDOW_WIDTH, WINDOW_HEIGHT);    // TODO: Handle based on current orientation
+        _game->run(WINDOW_WIDTH, WINDOW_HEIGHT);    // TODO: Handle based on current orientation            
     }
     return self;
 }
-
 - (void) dealloc
 {
     _game->exit();
@@ -153,6 +146,18 @@ long getMachTimeInMilliseconds()
     [super dealloc];
 }
 
+- (BOOL)canBecomeFirstResponder 
+{
+    // Override so we can control the keyboard
+    return YES;
+}
+
+- (void) layoutSubviews
+{
+    // Called on 'resize'
+    [self deleteFramebuffer];
+}
+
 - (void)createFramebuffer
 {
     // iOS Requires all content go to a rendering buffer then it is swapped into the windows rendering surface
@@ -263,19 +268,47 @@ long getMachTimeInMilliseconds()
     }
 }
 
-- (void) layoutSubviews
+- (BOOL)showKeyboard {
+    return [self becomeFirstResponder];
+}
+- (BOOL)dismissKeyboard {
+    return [self resignFirstResponder];
+}
+
+/*
+ * Virtual Keyboard Support
+ */
+- (void)insertText:(NSString *)text 
 {
-    [self deleteFramebuffer];
+    if([text length] == 0) return;
+    assert([text length] == 1);
+    unichar c = [text characterAtIndex:0];
+    int gpk = getKey(c);
+    Game::getInstance()->keyEvent(Keyboard::KEY_PRESS, gpk);    
+    Game::getInstance()->keyEvent(Keyboard::KEY_RELEASE, gpk);    
+}
+- (void)deleteBackward 
+{
+    Game::getInstance()->keyEvent(Keyboard::KEY_PRESS, Keyboard::KEY_BACKSPACE);    
+    Game::getInstance()->keyEvent(Keyboard::KEY_RELEASE, Keyboard::KEY_BACKSPACE);    
+}
+- (BOOL)hasText 
+{
+    return YES;
 }
 
+/*
+ * Touch Support
+ */
 - (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event 
 {
     unsigned int uniqueTouch = 0;
     for(UITouch *t in touches) 
     {
-        CGPoint touchLoc = [t locationInView:nil];
-        // TODO: Handle this based on orientation
-        Game::getInstance()->touchEvent(Touch::TOUCH_PRESS, touchLoc.y,  WINDOW_WIDTH - touchLoc.x, uniqueTouch);
+        CGPoint touchLoc = [t locationInView:self];
+        if(self.multipleTouchEnabled == YES) 
+            uniqueTouch = [t hash];
+        Game::getInstance()->touchEvent(Touch::TOUCH_PRESS, touchLoc.y,  touchLoc.x, uniqueTouch);
     }
 }
 
@@ -284,9 +317,10 @@ long getMachTimeInMilliseconds()
     unsigned int uniqueTouch = 0;
     for(UITouch* t in touches) 
     {
-        CGPoint touchLoc = [t locationInView:nil];
-        // TODO: Handle this based on orientation
-        Game::getInstance()->touchEvent(Touch::TOUCH_RELEASE, touchLoc.y, WINDOW_WIDTH - touchLoc.x, uniqueTouch);
+        CGPoint touchLoc = [t locationInView:self];
+        if(self.multipleTouchEnabled == YES) 
+            uniqueTouch = [t hash];
+        Game::getInstance()->touchEvent(Touch::TOUCH_RELEASE, touchLoc.y, touchLoc.x, uniqueTouch);
     }
 }
 
@@ -298,13 +332,13 @@ long getMachTimeInMilliseconds()
 
 - (void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event 
 {
-    unsigned 
-    int uniqueTouch = 0;
+    unsigned int uniqueTouch = 0;
     for(UITouch* t in touches) 
     {
-        CGPoint touchLoc = [t locationInView:nil];
-        // TODO: Handle this based on orientation
-        Game::getInstance()->touchEvent(Touch::TOUCH_MOVE, touchLoc.y,  WINDOW_WIDTH - touchLoc.x, uniqueTouch);
+        CGPoint touchLoc = [t locationInView:self];
+        if(self.multipleTouchEnabled == YES) 
+            uniqueTouch = [t hash];
+        Game::getInstance()->touchEvent(Touch::TOUCH_MOVE, touchLoc.y,  touchLoc.x, uniqueTouch);
     }
 }
 
@@ -345,7 +379,7 @@ long getMachTimeInMilliseconds()
     self.view = [[[View alloc] init] autorelease];
     if(__view == nil) 
     {
-        __view = self.view;
+        __view = (View*)self.view;
     }
 }
 
@@ -380,6 +414,7 @@ long getMachTimeInMilliseconds()
 
 - (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
 {
+    __appDelegate = self;
     [UIApplication sharedApplication].statusBarHidden = YES;
     UIAccelerometer*  accelerometer = [UIAccelerometer sharedAccelerometer];
     accelerometer.updateInterval = 1 / 40.0;    // 40Hz
@@ -438,6 +473,232 @@ long getMachTimeInMilliseconds()
 
 @end
 
+long getMachTimeInMilliseconds()
+{
+    static const int64_t kOneMillion = 1000 * 1000;
+    static mach_timebase_info_data_t s_timebase_info;
+    
+    if (s_timebase_info.denom == 0) 
+        (void) mach_timebase_info(&s_timebase_info);
+    
+    // mach_absolute_time() returns billionth of seconds, so divide by one million to get milliseconds
+    return (long)((mach_absolute_time() * s_timebase_info.numer) / (kOneMillion * s_timebase_info.denom));
+}
+
+int getKey(unichar keyCode) 
+{
+    switch(keyCode) {
+        case 0x30:
+            return Keyboard::KEY_ZERO;
+        case 0x31:
+            return Keyboard::KEY_ONE;
+        case 0x32:
+            return Keyboard::KEY_TWO;
+        case 0x33:
+            return Keyboard::KEY_THREE;
+        case 0x34:
+            return Keyboard::KEY_FOUR;
+        case 0x35:
+            return Keyboard::KEY_FIVE;
+        case 0x36:
+            return Keyboard::KEY_SIX;
+        case 0x37:
+            return Keyboard::KEY_SEVEN;
+        case 0x38:
+            return Keyboard::KEY_EIGHT;
+        case 0x39:
+            return Keyboard::KEY_NINE;
+            
+        case 0x41:
+            return Keyboard::KEY_CAPITAL_A;
+        case 0x42:
+            return Keyboard::KEY_CAPITAL_B;
+        case 0x43:
+            return Keyboard::KEY_CAPITAL_C;
+        case 0x44:
+            return Keyboard::KEY_CAPITAL_D;
+        case 0x45:
+            return Keyboard::KEY_CAPITAL_E;
+        case 0x46:
+            return Keyboard::KEY_CAPITAL_F;
+        case 0x47:
+            return Keyboard::KEY_CAPITAL_G;
+        case 0x48:
+            return Keyboard::KEY_CAPITAL_H;
+        case 0x49:
+            return Keyboard::KEY_CAPITAL_I;
+        case 0x4A:
+            return Keyboard::KEY_CAPITAL_J;
+        case 0x4B:
+            return Keyboard::KEY_CAPITAL_K;
+        case 0x4C:
+            return Keyboard::KEY_CAPITAL_L;
+        case 0x4D:
+            return Keyboard::KEY_CAPITAL_M;
+        case 0x4E:
+            return Keyboard::KEY_CAPITAL_N;
+        case 0x4F:
+            return Keyboard::KEY_CAPITAL_O;
+        case 0x50:
+            return Keyboard::KEY_CAPITAL_P;
+        case 0x51:
+            return Keyboard::KEY_CAPITAL_Q;
+        case 0x52:
+            return Keyboard::KEY_CAPITAL_R;
+        case 0x53:
+            return Keyboard::KEY_CAPITAL_S;
+        case 0x54:
+            return Keyboard::KEY_CAPITAL_T;
+        case 0x55:
+            return Keyboard::KEY_CAPITAL_U;
+        case 0x56:
+            return Keyboard::KEY_CAPITAL_V;
+        case 0x57:
+            return Keyboard::KEY_CAPITAL_W;
+        case 0x58:
+            return Keyboard::KEY_CAPITAL_X;
+        case 0x59:
+            return Keyboard::KEY_CAPITAL_Y;
+        case 0x5A:
+            return Keyboard::KEY_CAPITAL_Z;
+            
+            
+        case 0x61:
+            return Keyboard::KEY_A;
+        case 0x62:
+            return Keyboard::KEY_B;
+        case 0x63:
+            return Keyboard::KEY_C;
+        case 0x64:
+            return Keyboard::KEY_D;
+        case 0x65:
+            return Keyboard::KEY_E;
+        case 0x66:
+            return Keyboard::KEY_F;
+        case 0x67:
+            return Keyboard::KEY_G;
+        case 0x68:
+            return Keyboard::KEY_H;
+        case 0x69:
+            return Keyboard::KEY_I;
+        case 0x6A:
+            return Keyboard::KEY_J;
+        case 0x6B:
+            return Keyboard::KEY_K;
+        case 0x6C:
+            return Keyboard::KEY_L;
+        case 0x6D:
+            return Keyboard::KEY_M;
+        case 0x6E:
+            return Keyboard::KEY_N;
+        case 0x6F:
+            return Keyboard::KEY_O;
+        case 0x70:
+            return Keyboard::KEY_P;
+        case 0x71:
+            return Keyboard::KEY_Q;
+        case 0x72:
+            return Keyboard::KEY_R;
+        case 0x73:
+            return Keyboard::KEY_S;
+        case 0x74:
+            return Keyboard::KEY_T;
+        case 0x75:
+            return Keyboard::KEY_U;
+        case 0x76:
+            return Keyboard::KEY_V;
+        case 0x77:
+            return Keyboard::KEY_W;
+        case 0x78:
+            return Keyboard::KEY_X;
+        case 0x79:
+            return Keyboard::KEY_Y;
+        case 0x7A:
+            return Keyboard::KEY_Z;
+        default:
+            break;
+            
+       // Symbol Row 3
+        case 0x2E:
+            return Keyboard::KEY_PERIOD;
+        case 0x2C:
+            return Keyboard::KEY_COMMA;
+        case 0x3F:
+            return Keyboard::KEY_QUESTION;
+        case 0x21:
+            return Keyboard::KEY_EXCLAM;
+        case 0x27:
+            return Keyboard::KEY_APOSTROPHE;
+            
+        // Symbols Row 2
+        case 0x2D:
+            return Keyboard::KEY_MINUS;
+        case 0x2F:
+            return Keyboard::KEY_SLASH;
+        case 0x3A:
+            return Keyboard::KEY_COLON;
+        case 0x3B:
+            return Keyboard::KEY_SEMICOLON;
+        case 0x28:
+            return Keyboard::KEY_LEFT_PARENTHESIS;
+        case 0x29:
+            return Keyboard::KEY_RIGHT_PARENTHESIS;
+        case 0x24:
+            return Keyboard::KEY_DOLLAR;
+        case 0x26:
+            return Keyboard::KEY_AMPERSAND;
+        case 0x40:
+            return Keyboard::KEY_AT;
+        case 0x22:
+            return Keyboard::KEY_QUOTE;
+            
+        // Numeric Symbols Row 1
+        case 0x5B:
+            return Keyboard::KEY_LEFT_BRACKET;
+        case 0x5D:
+            return Keyboard::KEY_RIGHT_BRACKET;
+        case 0x7B:
+            return Keyboard::KEY_LEFT_BRACE;
+        case 0x7D:
+            return Keyboard::KEY_RIGHT_BRACE;
+        case 0x23:
+            return Keyboard::KEY_NUMBER;
+        case 0x25:
+            return Keyboard::KEY_PERCENT;
+        case 0x5E:
+            return Keyboard::KEY_CIRCUMFLEX;
+        case 0x2A:
+            return Keyboard::KEY_ASTERISK;
+        case 0x2B:
+            return Keyboard::KEY_PLUS;
+        case 0x3D:
+            return Keyboard::KEY_EQUAL;
+            
+        // Numeric Symbols Row 2
+        case 0x5F:
+            return Keyboard::KEY_UNDERSCORE;
+        case 0x5C:
+            return Keyboard::KEY_BACK_SLASH;
+        case 0x7C:
+            return Keyboard::KEY_BAR;
+        case 0x7E:
+            return Keyboard::KEY_TILDE;
+        case 0x3C:
+            return Keyboard::KEY_LESS_THAN;
+        case 0x3E:
+            return Keyboard::KEY_GREATER_THAN;
+        case 0x80:
+            return Keyboard::KEY_EURO;
+        case 0xA3:
+            return Keyboard::KEY_POUND;
+        case 0xA5:
+            return Keyboard::KEY_YEN;
+        case 0xB7:
+            return Keyboard::KEY_MIDDLE_DOT;
+    }
+    return Keyboard::KEY_NONE;
+}
+
 
 namespace gameplay
 {

+ 8 - 8
gameplay/src/SpriteBatch.cpp

@@ -14,14 +14,6 @@
     vtx.u = vu; vtx.v = vv; \
     vtx.r = vr; vtx.g = vg; vtx.b = vb; vtx.a = va
 
-// Sprite vertex structured used for batching
-struct SpriteVertex
-{
-    float x, y, z;
-    float u, v;
-    float r, g, b, a;
-};
-
 // Default sprite vertex shader
 #define SPRITE_VSH \
     "uniform mat4 u_projectionMatrix;\n" \
@@ -53,6 +45,14 @@ struct SpriteVertex
 namespace gameplay
 {
 
+// Sprite vertex structured used for batching
+struct SpriteVertex
+{
+    float x, y, z;
+    float u, v;
+    float r, g, b, a;
+};
+
 // Shared sprite effects
 static Effect* __spriteEffect = NULL;
 

+ 4 - 2
gameplay/src/gameplay-main-android.cpp

@@ -12,7 +12,8 @@ extern struct android_app* __state;
  */
 void android_main(struct android_app* state)
 {
-    // Make sure glue isn't stripped.
+    // Android specific : Dummy function that needs to be called to 
+    // ensure that the native activity works properly behind the scenes.
     app_dummy();
     
     __state = state;
@@ -24,7 +25,8 @@ void android_main(struct android_app* state)
     Game::getInstance()->exit();
     delete platform;
     
-    // We need to exit the process to cleanup global resources.
+    // Android specific : the process needs to exit to 
+    // to trigger cleanup of global resources (such as game).
     exit(0);
 }
 

+ 3 - 6
gameplay/src/gameplay-main-ios.mm

@@ -1,6 +1,3 @@
-#ifndef GAMEPLAYMAINIOS_H_
-#define GAMEPLAYMAINIOS_H_
-
 #ifdef __APPLE__
 
 #include "gameplay.h"
@@ -15,9 +12,9 @@ int main(int argc, char** argv)
     Game* game = Game::getInstance();
     assert(game != NULL);
     Platform* platform = Platform::create(game);
-    return platform->enterMessagePump();
+    int result = platform->enterMessagePump();
+	delete platform;
+    return result;
 }
 
 #endif
-
-#endif

+ 3 - 1
gameplay/src/gameplay-main-macos.mm

@@ -12,7 +12,9 @@ int main(int argc, char** argv)
     Game* game = Game::getInstance();
     assert(game != NULL);
     Platform* platform = Platform::create(game);
-    return platform->enterMessagePump();
+    int result = platform->enterMessagePump();
+	delete platform;
+    return result;
 }
 
 #endif

+ 39 - 0
gameplay/src/gameplay.dox

@@ -0,0 +1,39 @@
+/** \mainpage GamePlay - 3D Game Framework
+ *
+ * \section intro Introduction
+ *
+ * GamePlay is a cross-platform, C++, 3D gaming framework that includes a runtime library, tools,
+ * and learning content that allows developers to write games for mobile and desktop platforms
+ * without worrying about platform details.
+ *
+ * \section License
+ *
+ * The project is open sourced under the Apache 2.0 license.
+ *
+ * \section Project Features
+ *
+ * The GamePlay C++ runtime library offers a simple, well-defined, 3D gaming framework that's
+ * designed to get the most out of today's mobile and desktop platforms. Its purpose is to help you
+ * create stunning, world-class, games that harness the power and performance of the platform without
+ * being concerned about the platform details. This is accomplished through a set of C++ classes that
+ * are built on top of the OS, providing access to the hardware, graphics, and audio libraries
+ * (including EGL, OpenGL ES 2.0, and OpenAL 1.1). These classes allow you to:
+ *
+ * <b>Build your game without worrying about platform details</b>
+ * \li Drive your game with application initialization, update, and render callbacks.
+ * \li Control your game with touch screen, keyboard and accelerometer handlers.
+ * \li Manage your game with control over the device's file system.
+ *
+ * <b>Create game components with ease</b>
+ * \li Add visuals with scene, node, camera, light, mesh, texture, sprite, materials, animation, and physics classes.
+ * \li Control and position the game using the viewport, camera, and audio listener.
+ * \li Manage fundamental elements such as fonts, colors, and curves.
+ * \li Update game data with built-in math classes for vectors, matrices, rays, planes, and their associated operations.
+ *
+ * <b>Improve your game and learn</b>
+ * \li Supports TrueType fonts and the Khronos COLLADA and FBX interchange formats to import and binary encode your 3D game assets.
+ * \li Built-in materials and shaders to enhance your game's rendering.
+ * \li Both mobile and desktop platforms are supported for ease of portability.
+ * \li Documentation, tutorials, and code samples are provided.
+ *
+ */