From 54df41362c0a83ac44051dc64a9ed5981c9b8e5b Mon Sep 17 00:00:00 2001 From: dsc Date: Wed, 4 May 2011 19:58:51 -0700 Subject: [PATCH] Fixes the mess with sparrow. --- .gitignore | 2 +- libs/sparrow/BUILDING | 46 + libs/sparrow/CHANGELOG | 110 +++ libs/sparrow/LICENSE | 33 + libs/sparrow/README | 26 + libs/sparrow/doc/generate.sh | 33 + libs/sparrow/src/Classes/SPALSound.h | 45 + libs/sparrow/src/Classes/SPALSound.m | 94 +++ libs/sparrow/src/Classes/SPALSoundChannel.h | 46 + libs/sparrow/src/Classes/SPALSoundChannel.m | 217 +++++ libs/sparrow/src/Classes/SPAVSound.h | 46 + libs/sparrow/src/Classes/SPAVSound.m | 56 ++ libs/sparrow/src/Classes/SPAVSoundChannel.h | 43 + libs/sparrow/src/Classes/SPAVSoundChannel.m | 136 +++ libs/sparrow/src/Classes/SPAnimatable.h | 29 + libs/sparrow/src/Classes/SPAudioEngine.h | 64 ++ libs/sparrow/src/Classes/SPAudioEngine.m | 174 ++++ libs/sparrow/src/Classes/SPBitmapChar.h | 57 ++ libs/sparrow/src/Classes/SPBitmapChar.m | 55 ++ libs/sparrow/src/Classes/SPBitmapFont.h | 94 +++ libs/sparrow/src/Classes/SPBitmapFont.m | 289 +++++++ libs/sparrow/src/Classes/SPButton.h | 112 +++ libs/sparrow/src/Classes/SPButton.m | 261 ++++++ libs/sparrow/src/Classes/SPCompiledSprite.h | 61 ++ libs/sparrow/src/Classes/SPCompiledSprite.m | 436 ++++++++++ libs/sparrow/src/Classes/SPDelayedInvocation.h | 58 ++ libs/sparrow/src/Classes/SPDelayedInvocation.m | 93 +++ libs/sparrow/src/Classes/SPDisplayObject.h | 172 ++++ libs/sparrow/src/Classes/SPDisplayObject.m | 317 +++++++ .../sparrow/src/Classes/SPDisplayObjectContainer.h | 100 +++ .../sparrow/src/Classes/SPDisplayObjectContainer.m | 250 ++++++ .../sparrow/src/Classes/SPDisplayObject_Internal.h | 20 + libs/sparrow/src/Classes/SPEnterFrameEvent.h | 54 ++ libs/sparrow/src/Classes/SPEnterFrameEvent.m | 48 ++ libs/sparrow/src/Classes/SPEvent.h | 93 +++ libs/sparrow/src/Classes/SPEvent.m | 104 +++ libs/sparrow/src/Classes/SPEventDispatcher.h | 82 ++ libs/sparrow/src/Classes/SPEventDispatcher.m | 140 ++++ libs/sparrow/src/Classes/SPEvent_Internal.h | 23 + libs/sparrow/src/Classes/SPGLTexture.h | 82 ++ libs/sparrow/src/Classes/SPGLTexture.m | 183 ++++ libs/sparrow/src/Classes/SPImage.h | 72 ++ libs/sparrow/src/Classes/SPImage.m | 80 ++ libs/sparrow/src/Classes/SPJuggler.h | 88 ++ libs/sparrow/src/Classes/SPJuggler.m | 96 +++ libs/sparrow/src/Classes/SPMacros.h | 56 ++ libs/sparrow/src/Classes/SPMatrix.h | 99 +++ libs/sparrow/src/Classes/SPMatrix.m | 165 ++++ libs/sparrow/src/Classes/SPMovieClip.h | 136 +++ libs/sparrow/src/Classes/SPMovieClip.m | 274 ++++++ libs/sparrow/src/Classes/SPNSExtensions.h | 39 + libs/sparrow/src/Classes/SPNSExtensions.m | 50 ++ libs/sparrow/src/Classes/SPPoint.h | 82 ++ libs/sparrow/src/Classes/SPPoint.m | 142 ++++ libs/sparrow/src/Classes/SPPoolObject.h | 78 ++ libs/sparrow/src/Classes/SPPoolObject.m | 113 +++ libs/sparrow/src/Classes/SPQuad.h | 97 +++ libs/sparrow/src/Classes/SPQuad.m | 104 +++ libs/sparrow/src/Classes/SPRectangle.h | 77 ++ libs/sparrow/src/Classes/SPRectangle.m | 143 ++++ libs/sparrow/src/Classes/SPRenderSupport.h | 69 ++ libs/sparrow/src/Classes/SPRenderSupport.m | 125 +++ libs/sparrow/src/Classes/SPRenderTexture.h | 91 ++ libs/sparrow/src/Classes/SPRenderTexture.m | 210 +++++ libs/sparrow/src/Classes/SPRendering.m | 125 +++ libs/sparrow/src/Classes/SPSound.h | 72 ++ libs/sparrow/src/Classes/SPSound.m | 204 +++++ libs/sparrow/src/Classes/SPSoundChannel.h | 67 ++ libs/sparrow/src/Classes/SPSoundChannel.m | 91 ++ libs/sparrow/src/Classes/SPSprite.h | 48 ++ libs/sparrow/src/Classes/SPSprite.m | 22 + libs/sparrow/src/Classes/SPStage.h | 97 +++ libs/sparrow/src/Classes/SPStage.m | 234 ++++++ libs/sparrow/src/Classes/SPStage_Internal.h | 19 + libs/sparrow/src/Classes/SPSubTexture.h | 52 ++ libs/sparrow/src/Classes/SPSubTexture.m | 118 +++ libs/sparrow/src/Classes/SPTextField.h | 169 ++++ libs/sparrow/src/Classes/SPTextField.m | 329 ++++++++ libs/sparrow/src/Classes/SPTexture.h | 133 +++ libs/sparrow/src/Classes/SPTexture.m | 306 +++++++ libs/sparrow/src/Classes/SPTextureAtlas.h | 103 +++ libs/sparrow/src/Classes/SPTextureAtlas.m | 160 ++++ libs/sparrow/src/Classes/SPTouch.h | 105 +++ libs/sparrow/src/Classes/SPTouch.m | 109 +++ libs/sparrow/src/Classes/SPTouchEvent.h | 98 +++ libs/sparrow/src/Classes/SPTouchEvent.m | 92 ++ libs/sparrow/src/Classes/SPTouchProcessor.h | 52 ++ libs/sparrow/src/Classes/SPTouchProcessor.m | 121 +++ libs/sparrow/src/Classes/SPTouch_Internal.h | 28 + libs/sparrow/src/Classes/SPTransitions.h | 75 ++ libs/sparrow/src/Classes/SPTransitions.m | 171 ++++ libs/sparrow/src/Classes/SPTween.h | 124 +++ libs/sparrow/src/Classes/SPTween.m | 169 ++++ libs/sparrow/src/Classes/SPTweenedProperty.h | 62 ++ libs/sparrow/src/Classes/SPTweenedProperty.m | 110 +++ libs/sparrow/src/Classes/SPUtils.h | 27 + libs/sparrow/src/Classes/SPUtils.m | 34 + libs/sparrow/src/Classes/SPView.h | 78 ++ libs/sparrow/src/Classes/SPView.m | 314 +++++++ libs/sparrow/src/Classes/Sparrow.h | 45 + libs/sparrow/src/Sparrow.xcodeproj/project.pbxproj | 868 ++++++++++++++++++++ libs/sparrow/src/UnitTests-Info.plist | 20 + .../src/UnitTests/SPDelayedInvocationTest.m | 121 +++ .../src/UnitTests/SPDisplayObjectContainerTest.m | 416 ++++++++++ libs/sparrow/src/UnitTests/SPDisplayObjectTest.m | 256 ++++++ libs/sparrow/src/UnitTests/SPEventDispatcherTest.m | 155 ++++ libs/sparrow/src/UnitTests/SPImageTest.m | 58 ++ libs/sparrow/src/UnitTests/SPJugglerTest.m | 109 +++ libs/sparrow/src/UnitTests/SPMatrixTest.m | 164 ++++ libs/sparrow/src/UnitTests/SPMovieClipTest.m | 176 ++++ libs/sparrow/src/UnitTests/SPNSExtensionsTest.m | 38 + libs/sparrow/src/UnitTests/SPPointTest.m | 226 +++++ libs/sparrow/src/UnitTests/SPQuadTest.m | 70 ++ libs/sparrow/src/UnitTests/SPRectangleTest.m | 103 +++ libs/sparrow/src/UnitTests/SPStageTest.m | 47 ++ libs/sparrow/src/UnitTests/SPTweenTest.m | 254 ++++++ libs/sparrow/src/UnitTests/SPUtilsTest.m | 65 ++ libs/sparrow/util/atlas_generator/README | 54 ++ .../sparrow/util/atlas_generator/generate_atlas.rb | 255 ++++++ libs/sparrow/util/hiero2sparrow/README | 16 + libs/sparrow/util/hiero2sparrow/hiero2sparrow.rb | 82 ++ libs/sparrow/util/packer2sparrow/README | 11 + libs/sparrow/util/packer2sparrow/packer2sparrow.rb | 47 ++ libs/sparrow/util/texture_scaler/README | 35 + libs/sparrow/util/texture_scaler/scale_textures.rb | 96 +++ tanks/tanks.xcodeproj/project.pbxproj | 85 ++- 126 files changed, 14847 insertions(+), 13 deletions(-) create mode 100644 libs/sparrow/BUILDING create mode 100644 libs/sparrow/CHANGELOG create mode 100644 libs/sparrow/LICENSE create mode 100644 libs/sparrow/README create mode 100755 libs/sparrow/doc/generate.sh create mode 100644 libs/sparrow/src/Classes/SPALSound.h create mode 100644 libs/sparrow/src/Classes/SPALSound.m create mode 100644 libs/sparrow/src/Classes/SPALSoundChannel.h create mode 100644 libs/sparrow/src/Classes/SPALSoundChannel.m create mode 100644 libs/sparrow/src/Classes/SPAVSound.h create mode 100644 libs/sparrow/src/Classes/SPAVSound.m create mode 100644 libs/sparrow/src/Classes/SPAVSoundChannel.h create mode 100644 libs/sparrow/src/Classes/SPAVSoundChannel.m create mode 100644 libs/sparrow/src/Classes/SPAnimatable.h create mode 100644 libs/sparrow/src/Classes/SPAudioEngine.h create mode 100644 libs/sparrow/src/Classes/SPAudioEngine.m create mode 100644 libs/sparrow/src/Classes/SPBitmapChar.h create mode 100644 libs/sparrow/src/Classes/SPBitmapChar.m create mode 100644 libs/sparrow/src/Classes/SPBitmapFont.h create mode 100644 libs/sparrow/src/Classes/SPBitmapFont.m create mode 100644 libs/sparrow/src/Classes/SPButton.h create mode 100644 libs/sparrow/src/Classes/SPButton.m create mode 100644 libs/sparrow/src/Classes/SPCompiledSprite.h create mode 100644 libs/sparrow/src/Classes/SPCompiledSprite.m create mode 100644 libs/sparrow/src/Classes/SPDelayedInvocation.h create mode 100644 libs/sparrow/src/Classes/SPDelayedInvocation.m create mode 100644 libs/sparrow/src/Classes/SPDisplayObject.h create mode 100644 libs/sparrow/src/Classes/SPDisplayObject.m create mode 100644 libs/sparrow/src/Classes/SPDisplayObjectContainer.h create mode 100644 libs/sparrow/src/Classes/SPDisplayObjectContainer.m create mode 100644 libs/sparrow/src/Classes/SPDisplayObject_Internal.h create mode 100644 libs/sparrow/src/Classes/SPEnterFrameEvent.h create mode 100644 libs/sparrow/src/Classes/SPEnterFrameEvent.m create mode 100644 libs/sparrow/src/Classes/SPEvent.h create mode 100644 libs/sparrow/src/Classes/SPEvent.m create mode 100644 libs/sparrow/src/Classes/SPEventDispatcher.h create mode 100644 libs/sparrow/src/Classes/SPEventDispatcher.m create mode 100644 libs/sparrow/src/Classes/SPEvent_Internal.h create mode 100644 libs/sparrow/src/Classes/SPGLTexture.h create mode 100644 libs/sparrow/src/Classes/SPGLTexture.m create mode 100644 libs/sparrow/src/Classes/SPImage.h create mode 100644 libs/sparrow/src/Classes/SPImage.m create mode 100644 libs/sparrow/src/Classes/SPJuggler.h create mode 100644 libs/sparrow/src/Classes/SPJuggler.m create mode 100644 libs/sparrow/src/Classes/SPMacros.h create mode 100644 libs/sparrow/src/Classes/SPMatrix.h create mode 100644 libs/sparrow/src/Classes/SPMatrix.m create mode 100644 libs/sparrow/src/Classes/SPMovieClip.h create mode 100644 libs/sparrow/src/Classes/SPMovieClip.m create mode 100644 libs/sparrow/src/Classes/SPNSExtensions.h create mode 100644 libs/sparrow/src/Classes/SPNSExtensions.m create mode 100644 libs/sparrow/src/Classes/SPPoint.h create mode 100644 libs/sparrow/src/Classes/SPPoint.m create mode 100644 libs/sparrow/src/Classes/SPPoolObject.h create mode 100644 libs/sparrow/src/Classes/SPPoolObject.m create mode 100644 libs/sparrow/src/Classes/SPQuad.h create mode 100644 libs/sparrow/src/Classes/SPQuad.m create mode 100644 libs/sparrow/src/Classes/SPRectangle.h create mode 100644 libs/sparrow/src/Classes/SPRectangle.m create mode 100644 libs/sparrow/src/Classes/SPRenderSupport.h create mode 100644 libs/sparrow/src/Classes/SPRenderSupport.m create mode 100644 libs/sparrow/src/Classes/SPRenderTexture.h create mode 100644 libs/sparrow/src/Classes/SPRenderTexture.m create mode 100644 libs/sparrow/src/Classes/SPRendering.m create mode 100644 libs/sparrow/src/Classes/SPSound.h create mode 100644 libs/sparrow/src/Classes/SPSound.m create mode 100644 libs/sparrow/src/Classes/SPSoundChannel.h create mode 100644 libs/sparrow/src/Classes/SPSoundChannel.m create mode 100644 libs/sparrow/src/Classes/SPSprite.h create mode 100644 libs/sparrow/src/Classes/SPSprite.m create mode 100644 libs/sparrow/src/Classes/SPStage.h create mode 100644 libs/sparrow/src/Classes/SPStage.m create mode 100644 libs/sparrow/src/Classes/SPStage_Internal.h create mode 100644 libs/sparrow/src/Classes/SPSubTexture.h create mode 100644 libs/sparrow/src/Classes/SPSubTexture.m create mode 100644 libs/sparrow/src/Classes/SPTextField.h create mode 100644 libs/sparrow/src/Classes/SPTextField.m create mode 100644 libs/sparrow/src/Classes/SPTexture.h create mode 100644 libs/sparrow/src/Classes/SPTexture.m create mode 100644 libs/sparrow/src/Classes/SPTextureAtlas.h create mode 100644 libs/sparrow/src/Classes/SPTextureAtlas.m create mode 100644 libs/sparrow/src/Classes/SPTouch.h create mode 100644 libs/sparrow/src/Classes/SPTouch.m create mode 100644 libs/sparrow/src/Classes/SPTouchEvent.h create mode 100644 libs/sparrow/src/Classes/SPTouchEvent.m create mode 100644 libs/sparrow/src/Classes/SPTouchProcessor.h create mode 100644 libs/sparrow/src/Classes/SPTouchProcessor.m create mode 100644 libs/sparrow/src/Classes/SPTouch_Internal.h create mode 100644 libs/sparrow/src/Classes/SPTransitions.h create mode 100644 libs/sparrow/src/Classes/SPTransitions.m create mode 100644 libs/sparrow/src/Classes/SPTween.h create mode 100644 libs/sparrow/src/Classes/SPTween.m create mode 100644 libs/sparrow/src/Classes/SPTweenedProperty.h create mode 100644 libs/sparrow/src/Classes/SPTweenedProperty.m create mode 100644 libs/sparrow/src/Classes/SPUtils.h create mode 100644 libs/sparrow/src/Classes/SPUtils.m create mode 100644 libs/sparrow/src/Classes/SPView.h create mode 100644 libs/sparrow/src/Classes/SPView.m create mode 100644 libs/sparrow/src/Classes/Sparrow.h create mode 100755 libs/sparrow/src/Sparrow.xcodeproj/project.pbxproj create mode 100644 libs/sparrow/src/UnitTests-Info.plist create mode 100644 libs/sparrow/src/UnitTests/SPDelayedInvocationTest.m create mode 100644 libs/sparrow/src/UnitTests/SPDisplayObjectContainerTest.m create mode 100644 libs/sparrow/src/UnitTests/SPDisplayObjectTest.m create mode 100644 libs/sparrow/src/UnitTests/SPEventDispatcherTest.m create mode 100644 libs/sparrow/src/UnitTests/SPImageTest.m create mode 100644 libs/sparrow/src/UnitTests/SPJugglerTest.m create mode 100644 libs/sparrow/src/UnitTests/SPMatrixTest.m create mode 100644 libs/sparrow/src/UnitTests/SPMovieClipTest.m create mode 100644 libs/sparrow/src/UnitTests/SPNSExtensionsTest.m create mode 100644 libs/sparrow/src/UnitTests/SPPointTest.m create mode 100644 libs/sparrow/src/UnitTests/SPQuadTest.m create mode 100644 libs/sparrow/src/UnitTests/SPRectangleTest.m create mode 100644 libs/sparrow/src/UnitTests/SPStageTest.m create mode 100644 libs/sparrow/src/UnitTests/SPTweenTest.m create mode 100644 libs/sparrow/src/UnitTests/SPUtilsTest.m create mode 100644 libs/sparrow/util/atlas_generator/README create mode 100755 libs/sparrow/util/atlas_generator/generate_atlas.rb create mode 100644 libs/sparrow/util/hiero2sparrow/README create mode 100755 libs/sparrow/util/hiero2sparrow/hiero2sparrow.rb create mode 100644 libs/sparrow/util/packer2sparrow/README create mode 100644 libs/sparrow/util/packer2sparrow/packer2sparrow.rb create mode 100644 libs/sparrow/util/texture_scaler/README create mode 100755 libs/sparrow/util/texture_scaler/scale_textures.rb diff --git a/.gitignore b/.gitignore index edc082c..9fac711 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ # Xcode -build/* +*/build/* *.pbxuser !default.pbxuser *.mode1v3 diff --git a/libs/sparrow/BUILDING b/libs/sparrow/BUILDING new file mode 100644 index 0000000..2f3e629 --- /dev/null +++ b/libs/sparrow/BUILDING @@ -0,0 +1,46 @@ +---------------------------------------------------------------------------------------------------- +Sparrow: Tips for building an app +---------------------------------------------------------------------------------------------------- + +--- A First look at Sparrow ------------------------------------------------------------------------ + +In the folder 'samples/demo', you will find an Xcode project that shows the most basic Sparrow +features and how to use them. Just open the project in Xcode, compile and run - everything should +work out of the box. + +--- Creating a new Xcode project that uses Sparrow ------------------------------------------------- + +In the folder 'samples/scaffold', you will find an Xcode project that contains a bare-bone Sparrow +application. We recommend that you use this project as a starting point for your game. Please follow +this steps to use this Scaffold: + +Preconditions: + +Sparrow is linked to your application via Xcode project references. This has the advantage that it's +easy to update Sparrow (just download a new release and overwrite the old one in the same directory) +and that you can easily step into Sparrow source code, I case you want to do so. + +This has to be done only once: + +1. Set up a shared build output directory that will be shared by all Xcode projects. + * In the Xcode preferences, tab: "Building", set "Place Build Products in" to + "Customized location" and specify a common build directory (anywhere you want). + * Set "Place Intermediate Build Files in" to "With build products." +2. Add a "Source Tree" variable that Xcode can use to dynamically find Sparrow. + * In the Xcode preferences, tab: "Source Trees", create a new Source Tree variable. + * For Sparrow, create SPARROW_SRC and let it point to /some_valid_path/sparrow/src/ + +Creating your new project: + +1. Copy the "scaffold"-folder to the place where you want to have your game project. +2. Open "AppScaffold.xcodeproj" +3. Build and run - just to see if everything works fine. If it does not work, check if you have + created the SPARROW_SRC variable in Xcode, and if it points to the right place. +4. In Xcodes menu, click on "Project" -> "Rename ..." +5. Enter the name of your game. +6. That's it! Now you can start to develop your game with Sparrow. + +Selecting target hardware: iPhone / iPod Touch / iPad + +1. Enter the project Settings, tab: "Build" +2. Select the target of your choice for the setting "Targeted Device Family" \ No newline at end of file diff --git a/libs/sparrow/CHANGELOG b/libs/sparrow/CHANGELOG new file mode 100644 index 0000000..8aeb392 --- /dev/null +++ b/libs/sparrow/CHANGELOG @@ -0,0 +1,110 @@ +---------------------------------------------------------------------------------------------------- +Sparrow: Changelog +---------------------------------------------------------------------------------------------------- + +version 1.1 - 2011-01-12 + +- added SPRenderTexture +- added SPUtils class for easy random number generation (more to come) +- added support for looping and reversing tweens (thanks, Shilo!) +- added new transition method: 'randomize' +- added support for uncompressed PVR texture formats (565, 5551, 4444) +- added simple way to use HD textures on the iPad +- added support for creating dynamic texture atlases (add/remove regions on the fly) +- added methods to access the glyphs of SPBitmapFont directly +- added new init method to SPImage: 'initWithContentsOfImage:(UIImage *)image' +- added more factory methods to different classes +- added support for changing the fps of SPMovieClip at runtime (thanks Shilo!) +- added AppleDoc inline API documentation +- added bash script that generates API documentation +- updated SPView class to be more robust +- updated general rendering code (moved more OpenGL calls to SPRenderTexture) +- fixed bug with canceled touch events +- fixed bug that could cause a breakdown of the touch handling (thanks Kodi!) +- fixed 'isEqual' method of SPMatrix (thanks Matt!) +- fixed bug that could cut the outermost pixels of HD textures +- Special thanks to numerous forum members for bug reports, suggestions and feedback! + +version 1.0 - 2010-10-24 + +- added support for PVRTC-textures +- added new init method to SPTexture to allow simple use of Core Graphics drawings +- added new init method to SPMovieClip that uses an NSArray containing the frames +- added method 'childByName:' to SPDisplayObjectContainer +- added method 'texturesStartingWith:' to SPTextureAtlas +- added method 'scaleBy:' to SPPoint +- added method 'interpolateFromPoint:toPoint:ratio:' to SPPoint +- added property 'textBounds' to SPTextField +- added property 'name' to SPDisplayObject +- added workaround for unit test problem in Xcode 3.2.4 +- updated SPCompiledSprite-class to be public +- updated texture utilities for sharper output +- updated scaffold so that it is easier to create an iPad application +- fixed bug that classes inheriting directly from SPQuad were not rendered +- fixed that last-moment changes were not displayed when pausing stage +- fixed bug that could lead to a white flash when textures were released +- Special thanks to numerous forum members for bug reports, suggestions and feedback! + +version 0.9 - 2010-07-30 + +- !!! interface change !!! + The IDs of vertices in SPQuad and SPImage have changed. ("colorOfVertex:", "texCoordsOfVertex:") + Before: 0 = top left, 1 = top right, 2 = bottom right, 3 = bottom left + AFTER: 0 = top left, 1 = top right, 2 = bottom left, 3 = bottom right +- greatly improved rendering speed of SPTextField when used with bitmap fonts +- greatly improved performance of touch event analysis +- added Sparrow atlas generator (sparrow/util/atlas_generator) +- added Sparrow texture resizer (sparrow/util/texture_scaler) +- added support for high resolution screens (aka iPhone4's retina display) +- added support for high resolution textures ("texture@2x.png") +- added support for high resolution texture atlases ("atlas@2x.xml") +- added support for high resolution bitmap fonts ("font@2x.xml") +- added support for loading textures that are not inside the application bundle +- added support for loading sounds that are not inside the application bundle +- changed base SDK to iOS 4.0 +- added new event: SP_EVENT_TYPE_MOVIE_COMPLETED in SPMovieClip class +- added experimental feature: SPCompiledSprite +- added some missing "@private" declarations +- fixed memory access violation when object was destroyed within an enter frame event listener +- fixed bug that alpha values were only used when a texture was active +- fixed bug that SPDelayedInvocation (aka SPJuggler::delayInvocationAtTarget) did not retain + its arguments +- fixed bug that cancelled touch events would inhibit further user input +- code cleanup (especially concerning designated initializers) +- Special thanks to: Mike, Baike, Paolo, Jule and Alex_H for bug reports, suggestions and feedback! + +version 0.8 - 2010-06-05 + +- added audio classes +- added SPMovieClip class +- added new transition functions: + - easeInBack / easeOutBack / easeInOutBack / easeOutInBack + - easeInElastic / easeOutElastic / easeInOutElastic / easeOutInElastic + - easeInBounce / easeOutBounce / easeInOutBounce / easeOutInBounce +- added 'removeTweensWithTarget:'-method to juggler +- added 'removeAllChildren'-method to SPDisplayObjectContainer +- added new text-only constructor to SPTextField +- added NSXMLParserDelegate protocol statement for iPhone SDK 4+ +- added packer2sparrow utility +- added hiero2sparrow utility +- changed transition function signature (removed delta) +- changed rotation handling: angles now clamped from -180 to +180 degrees. + this should make most rotation tweens more intuitive. +- changed license text to allow easy AppStore distribution +- changed scaffold project to support audio +- changed demo project + - new design + - new scene: sound + - new scene: movie +- fixed touch issues when view size != stage size +- fixed exception that occurred when the same object was added to a container twice +- fixed flickering at application start +- fixed method signatures in SPTexture.m +- 'removeChild'-method in SPDisplayObjectContainer no longer throws an exception when the + object is not a child, but now silently ignores the failure. +- the stage property is now accessible in the REMOVED_FROM_STAGE event +- disabled unit test execution in iPhone SDK < 3 (unit tests are only supported by iPhone SDK 3+) + +version 0.7 - 2010-01-14 + +- first public version diff --git a/libs/sparrow/LICENSE b/libs/sparrow/LICENSE new file mode 100644 index 0000000..7164bd5 --- /dev/null +++ b/libs/sparrow/LICENSE @@ -0,0 +1,33 @@ +---------------------------------------------------------------------------------------------- +Sparrow: Simplified BSD License +---------------------------------------------------------------------------------------------- + +Copyright 2010 incognitek. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are +permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this list of + conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, this list + of conditions and the following disclaimer in the documentation and/or other materials + provided with the distribution. + + 3. Redistributions via the Apple App Store constitute an exception to section 2. It is + sufficient to add a copy of this license to the application's internet page (if available). + The content of the following disclaimer is still in effect. + +THIS SOFTWARE IS PROVIDED BY INCOGNITEK ``AS IS'' AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INCOGNITEK OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those of the +authors and should not be interpreted as representing official policies, either expressed +or implied, of incognitek. \ No newline at end of file diff --git a/libs/sparrow/README b/libs/sparrow/README new file mode 100644 index 0000000..9d9715c --- /dev/null +++ b/libs/sparrow/README @@ -0,0 +1,26 @@ +---------------------------------------------------------------------------------------------------- +Sparrow: an Open Source Framework for iPhone game development +---------------------------------------------------------------------------------------------------- + +--- What is Sparrow? ------------------------------------------------------------------------------- + +Sparrow is a pure Objective C library targeted on making game development as easy and hassle-free +as possible. Sparrow makes it possible to write fast OpenGL applications without having to touch +OpenGL or pure C (but easily allowing to do so, for those who wish). It uses a tried and tested +API that is easy to use and hard to misuse. + +--- Who is Sparrow for? ---------------------------------------------------------------------------- + +Obviously Sparrow is for iPhone developers, especially those involved in game development. You +will need to have a basic understanding of Objective C – but there’s no way around that on the +iPhone anyway. + +If you have already worked with Adobe™ Flash/Flex technology, you will immediately befriend with +Sparrow since it uses lots of similar concepts and naming schemes. That said, everything is +designed to be as intuitive as possible, so any Java™ or .Net™ developer will get the hang of it +quickly as well. + +--- How to start? ---------------------------------------------------------------------------------- + +* Read through the file 'BUILDING' for a quick start with Sparrow. +* Visit --> http://www.sparrow-framework.org <-- \ No newline at end of file diff --git a/libs/sparrow/doc/generate.sh b/libs/sparrow/doc/generate.sh new file mode 100755 index 0000000..c6bb5e6 --- /dev/null +++ b/libs/sparrow/doc/generate.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +# This script creates a nice API reference documentation for the Sparrow source +# and installs it in Xcode. +# +# To execute it, you need the "AppleDoc"-tool. Download it here: +# http://www.gentlebytes.com/home/appledocapp/ + +echo "Please enter the version number (like '1.0'), followed by [ENTER]:" +read version + +appledoc \ + --project-name "Sparrow Framework" \ + --project-company "Incognitek" \ + --company-id com.incognitek \ + --project-version "$version" \ + --ignore ".m" \ + --ignore "_Internal.h" \ + --keep-undocumented-objects \ + --keep-undocumented-members \ + --keep-intermediate-files \ + --docset-bundle-id "org.sparrow-framework.docset" \ + --docset-bundle-name "Sparrow Framework API Documentation" \ + --docset-atom-filename "docset.atom" \ + --docset-feed-url "http://doc.sparrow-framework.org/core/feed/%DOCSETATOMFILENAME" \ + --docset-package-url "http://doc.sparrow-framework.org/core/feed/%DOCSETPACKAGEFILENAME" \ + --install-docset \ + --publish-docset \ + --output . \ + ../src/Classes + +echo +echo "Finished." diff --git a/libs/sparrow/src/Classes/SPALSound.h b/libs/sparrow/src/Classes/SPALSound.h new file mode 100644 index 0000000..20e250c --- /dev/null +++ b/libs/sparrow/src/Classes/SPALSound.h @@ -0,0 +1,45 @@ +// +// SPALSound.h +// Sparrow +// +// Created by Daniel Sperl on 28.05.10. +// Copyright 2010 Incognitek. All rights reserved. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the Simplified BSD License. +// + +#import +#import "SPSound.h" + +/** ------------------------------------------------------------------------------------------------ + + The SPALSound class is a concrete implementation of SPSound that uses OpenAL internally. + + Don't create instances of this class manually. Use [SPSound initWithContentsOfFile:] instead. + +------------------------------------------------------------------------------------------------- */ + +@interface SPALSound : SPSound +{ + @private + uint mBufferID; + double mDuration; +} + +/// -------------------- +/// @name Initialization +/// -------------------- + +/// Initializes a sound with its known properties. +- (id)initWithData:(const void *)data size:(int)size channels:(int)channels frequency:(int)frequency + duration:(double)duration; + +/// ---------------- +/// @name Properties +/// ---------------- + +/// The OpenAL buffer ID of the sound. +@property (nonatomic, readonly) uint bufferID; + +@end diff --git a/libs/sparrow/src/Classes/SPALSound.m b/libs/sparrow/src/Classes/SPALSound.m new file mode 100644 index 0000000..801960a --- /dev/null +++ b/libs/sparrow/src/Classes/SPALSound.m @@ -0,0 +1,94 @@ +// +// SPALSound.m +// Sparrow +// +// Created by Daniel Sperl on 28.05.10. +// Copyright 2010 Incognitek. All rights reserved. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the Simplified BSD License. +// + +#import "SPALSound.h" +#import "SPALSoundChannel.h" +#import "SPAudioEngine.h" + +#import +#import + +@implementation SPALSound + +@synthesize duration = mDuration; +@synthesize bufferID = mBufferID; + +- (id)init +{ + [self release]; + return nil; +} + +- (id)initWithData:(void *)data size:(int)size channels:(int)channels frequency:(int)frequency + duration:(double)duration +{ + if (self = [super init]) + { + BOOL success = NO; + mDuration = duration; + + do + { + [SPAudioEngine start]; + + ALCcontext *const currentContext = alcGetCurrentContext(); + if (!currentContext) + { + NSLog(@"Could not get current OpenAL context"); + break; + } + + ALenum errorCode; + + alGenBuffers(1, &mBufferID); + errorCode = alGetError(); + if (errorCode != AL_NO_ERROR) + { + NSLog(@"Could not allocate OpenAL buffer (%x)", errorCode); + break; + } + + int format = (channels > 1) ? AL_FORMAT_STEREO16 : AL_FORMAT_MONO16; + + alBufferData(mBufferID, format, data, size, frequency); + errorCode = alGetError(); + if (errorCode != AL_NO_ERROR) + { + NSLog(@"Could not fill OpenAL buffer (%x)", errorCode); + break; + } + + success = YES; + } + while (NO); + + if (!success) + { + [self release]; + return nil; + } + } + return self; +} + +- (SPSoundChannel *)createChannel +{ + return [[[SPALSoundChannel alloc] initWithSound:self] autorelease]; +} + +- (void) dealloc +{ + alDeleteBuffers(1, &mBufferID); + mBufferID = 0; + [super dealloc]; +} + +@end diff --git a/libs/sparrow/src/Classes/SPALSoundChannel.h b/libs/sparrow/src/Classes/SPALSoundChannel.h new file mode 100644 index 0000000..957277c --- /dev/null +++ b/libs/sparrow/src/Classes/SPALSoundChannel.h @@ -0,0 +1,46 @@ +// +// SPALSoundChannel.h +// Sparrow +// +// Created by Daniel Sperl on 28.05.10. +// Copyright 2010 Incognitek. All rights reserved. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the Simplified BSD License. +// + +#import +#import "SPSoundChannel.h" + +@class SPALSound; + +/** ------------------------------------------------------------------------------------------------ + + The SPALSoundChannel class is a concrete implementation of SPSoundChannel that uses + OpenAL internally. + + Don't create instances of this class manually. Use [SPSound createChannel] instead. + +------------------------------------------------------------------------------------------------- */ + +@interface SPALSoundChannel : SPSoundChannel +{ + @private + SPALSound *mSound; + uint mSourceID; + float mVolume; + BOOL mLoop; + + double mStartMoment; + double mPauseMoment; + BOOL mInterrupted; +} + +/// ------------------ +/// @name Initializers +/// ------------------ + +/// Initializes a sound channel from an SPALSound object. +- (id)initWithSound:(SPALSound *)sound; + +@end diff --git a/libs/sparrow/src/Classes/SPALSoundChannel.m b/libs/sparrow/src/Classes/SPALSoundChannel.m new file mode 100644 index 0000000..2ce4410 --- /dev/null +++ b/libs/sparrow/src/Classes/SPALSoundChannel.m @@ -0,0 +1,217 @@ +// +// SPALSoundChannel.m +// Sparrow +// +// Created by Daniel Sperl on 28.05.10. +// Copyright 2010 Incognitek. All rights reserved. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the Simplified BSD License. +// + +#import "SPALSoundChannel.h" +#import "SPALSound.h" +#import "SPAudioEngine.h" +#import "SPMacros.h" + +#import // for CACurrentMediaTime +#import +#import + +// --- private interface --------------------------------------------------------------------------- + +@interface SPALSoundChannel () + +- (void)scheduleSoundCompletedEvent; +- (void)revokeSoundCompletedEvent; + +@end + +// --- class implementation ------------------------------------------------------------------------ + +@implementation SPALSoundChannel + +@synthesize volume = mVolume; +@synthesize loop = mLoop; + +- (id)init +{ + [self release]; + return nil; +} + +- (id)initWithSound:(SPALSound *)sound +{ + if (self = [super init]) + { + mSound = [sound retain]; + mVolume = 1.0f; + mLoop = NO; + mInterrupted = NO; + mStartMoment = 0.0; + mPauseMoment = 0.0; + + alGenSources(1, &mSourceID); + alSourcei(mSourceID, AL_BUFFER, sound.bufferID); + ALenum errorCode = alGetError(); + if (errorCode != AL_NO_ERROR) + { + NSLog(@"Could not create OpenAL source (%x)", errorCode); + [self release]; + return nil; + } + + NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; + [nc addObserver:self selector:@selector(onInterruptionBegan:) + name:SP_NOTIFICATION_AUDIO_INTERRUPTION_BEGAN object:nil]; + [nc addObserver:self selector:@selector(onInterruptionEnded:) + name:SP_NOTIFICATION_AUDIO_INTERRUPTION_ENDED object:nil]; + } + return self; +} + +- (void)dealloc +{ + [[NSNotificationCenter defaultCenter] removeObserver:self]; + alSourceStop(mSourceID); + alSourcei(mSourceID, AL_BUFFER, 0); + alDeleteSources(1, &mSourceID); + mSourceID = 0; + [mSound release]; + [super dealloc]; +} + +- (void)play +{ + if (!self.isPlaying) + { + double now = CACurrentMediaTime(); + + if (mPauseMoment != 0.0) // paused + { + mStartMoment += now - mPauseMoment; + mPauseMoment = 0.0; + } + else // stopped + { + mStartMoment = now; + } + + [self scheduleSoundCompletedEvent]; + alSourcePlay(mSourceID); + } +} + +- (void)pause +{ + if (self.isPlaying) + { + [self revokeSoundCompletedEvent]; + mPauseMoment = CACurrentMediaTime(); + alSourcePause(mSourceID); + } +} + +- (void)stop +{ + [self revokeSoundCompletedEvent]; + mStartMoment = mPauseMoment = 0.0; + alSourceStop(mSourceID); +} + +- (BOOL)isPlaying +{ + ALint state; + alGetSourcei(mSourceID, AL_SOURCE_STATE, &state); + return state == AL_PLAYING; +} + +- (BOOL)isPaused +{ + ALint state; + alGetSourcei(mSourceID, AL_SOURCE_STATE, &state); + return state == AL_PAUSED; +} + +- (BOOL)isStopped +{ + ALint state; + alGetSourcei(mSourceID, AL_SOURCE_STATE, &state); + return state == AL_STOPPED; +} + +- (void)setLoop:(BOOL)value +{ + if (value != mLoop) + { + mLoop = value; + alSourcei(mSourceID, AL_LOOPING, mLoop); + } +} + +- (void)setVolume:(float)value +{ + if (value != mVolume) + { + mVolume = value; + alSourcef(mSourceID, AL_GAIN, mVolume); + } +} + +- (double)duration +{ + return [mSound duration]; +} + +- (void)scheduleSoundCompletedEvent +{ + if (mStartMoment != 0.0) + { + double remainingTime = mSound.duration - (CACurrentMediaTime() - mStartMoment); + [self revokeSoundCompletedEvent]; + if (remainingTime >= 0.0) + { + [self performSelector:@selector(dispatchSoundCompletedEvent) withObject:nil + afterDelay:remainingTime]; + } + } +} + +- (void)revokeSoundCompletedEvent +{ + [NSObject cancelPreviousPerformRequestsWithTarget:self + selector:@selector(dispatchSoundCompletedEvent) object:nil]; +} + +- (void)dispatchSoundCompletedEvent +{ + if (!mLoop) + { + SPEvent *event = [[SPEvent alloc] initWithType:SP_EVENT_TYPE_SOUND_COMPLETED]; + [self dispatchEvent:event]; + [event release]; + } +} + +- (void)onInterruptionBegan:(NSNotification *)notification +{ + if (self.isPlaying) + { + [self revokeSoundCompletedEvent]; + mInterrupted = YES; + mPauseMoment = CACurrentMediaTime(); + } +} + +- (void)onInterruptionEnded:(NSNotification *)notification +{ + if (mInterrupted) + { + mStartMoment += CACurrentMediaTime() - mPauseMoment; + mPauseMoment = 0.0; + mInterrupted = NO; + [self scheduleSoundCompletedEvent]; + } +} + +@end diff --git a/libs/sparrow/src/Classes/SPAVSound.h b/libs/sparrow/src/Classes/SPAVSound.h new file mode 100644 index 0000000..ce66c0b --- /dev/null +++ b/libs/sparrow/src/Classes/SPAVSound.h @@ -0,0 +1,46 @@ +// +// SPAVSound.h +// Sparrow +// +// Created by Daniel Sperl on 29.05.10. +// Copyright 2010 Incognitek. All rights reserved. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the Simplified BSD License. +// + +#import +#import + +#import "SPSound.h" + +/** ------------------------------------------------------------------------------------------------ + + The SPAVSound class is a concrete implementation of SPSound that uses AVAudioPlayer internally. + + Don't create instances of this class manually. Use [SPSound initWithContentsOfFile:] instead. + + */ + +@interface SPAVSound : SPSound +{ + @private + NSData *mSoundData; + double mDuration; +} + +/// -------------------- +/// @name Initialization +/// -------------------- + +/// Initializes a sound with the contents of a file and the known duration. +- (id)initWithContentsOfFile:(NSString *)path duration:(double)duration; + +/// ------------- +/// @name methods +/// ------------- + +/// Creates an AVAudioPlayer object from the sound. +- (AVAudioPlayer *)createPlayer; + +@end diff --git a/libs/sparrow/src/Classes/SPAVSound.m b/libs/sparrow/src/Classes/SPAVSound.m new file mode 100644 index 0000000..5b917e7 --- /dev/null +++ b/libs/sparrow/src/Classes/SPAVSound.m @@ -0,0 +1,56 @@ +// +// SPAVSound.m +// Sparrow +// +// Created by Daniel Sperl on 29.05.10. +// Copyright 2010 Incognitek. All rights reserved. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the Simplified BSD License. +// + +#import "SPAVSound.h" +#import "SPAVSoundChannel.h" + +@implementation SPAVSound + +@synthesize duration = mDuration; + +- (id)init +{ + [self release]; + return nil; +} + +- (id)initWithContentsOfFile:(NSString *)path duration:(double)duration +{ + if (self = [super init]) + { + NSString *fullPath = [path isAbsolutePath] ? + path : [[NSBundle mainBundle] pathForResource:path ofType:nil]; + mSoundData = [[NSData alloc] initWithContentsOfMappedFile:fullPath]; + mDuration = duration; + } + return self; +} + +- (void)dealloc +{ + [mSoundData release]; + [super dealloc]; +} + +- (SPSoundChannel *)createChannel +{ + return [[[SPAVSoundChannel alloc] initWithSound:self] autorelease]; +} + +- (AVAudioPlayer *)createPlayer +{ + NSError *error = nil; + AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithData:mSoundData error:&error]; + if (error) NSLog(@"Could not create AVAudioPlayer: %@", [error description]); + return [player autorelease]; +} + +@end diff --git a/libs/sparrow/src/Classes/SPAVSoundChannel.h b/libs/sparrow/src/Classes/SPAVSoundChannel.h new file mode 100644 index 0000000..8d722ae --- /dev/null +++ b/libs/sparrow/src/Classes/SPAVSoundChannel.h @@ -0,0 +1,43 @@ +// +// SPAVSoundChannel.h +// Sparrow +// +// Created by Daniel Sperl on 29.05.10. +// Copyright 2010 Incognitek. All rights reserved. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the Simplified BSD License. +// + +#import +#import + +#import "SPSoundChannel.h" +#import "SPAVSound.h" + +/** ------------------------------------------------------------------------------------------------ + + The SPAVSoundChannel class is a concrete implementation of SPSoundChannel that uses AVAudioPlayer + internally. + + Don't create instances of this class manually. Use [SPSound createChannel] instead. + +------------------------------------------------------------------------------------------------- */ + +@interface SPAVSoundChannel : SPSoundChannel +{ + @private + SPAVSound *mSound; + AVAudioPlayer *mPlayer; + BOOL mPaused; + float mVolume; +} + +/// ------------------ +/// @name Initializers +/// ------------------ + +/// Initializes a sound channel from an SPAVSound object. +- (id)initWithSound:(SPAVSound *)sound; + +@end diff --git a/libs/sparrow/src/Classes/SPAVSoundChannel.m b/libs/sparrow/src/Classes/SPAVSoundChannel.m new file mode 100644 index 0000000..81c411c --- /dev/null +++ b/libs/sparrow/src/Classes/SPAVSoundChannel.m @@ -0,0 +1,136 @@ +// +// SPAVSoundChannel.m +// Sparrow +// +// Created by Daniel Sperl on 29.05.10. +// Copyright 2010 Incognitek. All rights reserved. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the Simplified BSD License. +// + +#import "SPAVSoundChannel.h" +#import "SPAudioEngine.h" +#import "SPMacros.h" + +@implementation SPAVSoundChannel + +- (id)init +{ + [self release]; + return nil; +} + +- (id)initWithSound:(SPAVSound *)sound +{ + if (self = [super init]) + { + mVolume = 1.0f; + mSound = [sound retain]; + mPlayer = [[sound createPlayer] retain]; + mPlayer.delegate = self; + [mPlayer prepareToPlay]; + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(onMasterVolumeChanged:) + name:SP_NOTIFICATION_MASTER_VOLUME_CHANGED object:nil]; + } + return self; +} + +- (void)dealloc +{ + [[NSNotificationCenter defaultCenter] removeObserver:self]; + [mPlayer release]; + [mSound release]; + [super dealloc]; +} + +- (void)play +{ + mPaused = NO; + [mPlayer play]; +} + +- (void)pause +{ + mPaused = YES; + [mPlayer pause]; +} + +- (void)stop +{ + mPaused = NO; + [mPlayer stop]; + mPlayer.currentTime = 0; +} + +- (BOOL)isPlaying +{ + return mPlayer.playing; +} + +- (BOOL)isPaused +{ + return mPaused && !mPlayer.playing; +} + +- (BOOL)isStopped +{ + return !mPaused && !mPlayer.playing; +} + +- (BOOL)loop +{ + return mPlayer.numberOfLoops < 0; +} + +- (void)setLoop:(BOOL)value +{ + mPlayer.numberOfLoops = value ? -1 : 0; +} + +- (float)volume +{ + return mVolume; +} + +- (void)setVolume:(float)value +{ + mVolume = value; + mPlayer.volume = value * [SPAudioEngine masterVolume]; +} + +- (double)duration +{ + return mPlayer.duration; +} + +- (void)onMasterVolumeChanged:(NSNotification *)notification +{ + self.volume = mVolume; +} + +#pragma mark AVAudioPlayerDelegate + +- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag +{ + [self dispatchEvent:[SPEvent eventWithType:SP_EVENT_TYPE_SOUND_COMPLETED]]; +} + +- (void)audioPlayerDecodeErrorDidOccur:(AVAudioPlayer *)player error:(NSError *)error +{ + NSLog(@"Error during sound decoding: %@", [error description]); +} + +- (void)audioPlayerBeginInterruption:(AVAudioPlayer *)player +{ + [player pause]; +} + +- (void)audioPlayerEndInterruption:(AVAudioPlayer *)player +{ + [player play]; +} + +@end diff --git a/libs/sparrow/src/Classes/SPAnimatable.h b/libs/sparrow/src/Classes/SPAnimatable.h new file mode 100644 index 0000000..4668d71 --- /dev/null +++ b/libs/sparrow/src/Classes/SPAnimatable.h @@ -0,0 +1,29 @@ +// +// SPAnimatable.h +// Sparrow +// +// Created by Daniel Sperl on 09.05.09. +// Copyright 2009 Incognitek. All rights reserved. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the Simplified BSD License. +// + +#import + +/** ------------------------------------------------------------------------------------------------ + + The SPAnimatable protocol describes objects that are animated depending on the passed time. + Any object that implements this protocol can be added to the SPJuggler. + +------------------------------------------------------------------------------------------------- */ + +@protocol SPAnimatable + +/// Advance the animation by a number of seconds. +- (void)advanceTime:(double)seconds; + +/// Indicates if the animation is finished. (The juggler will purge the object.) +@property (nonatomic, readonly) BOOL isComplete; + +@end diff --git a/libs/sparrow/src/Classes/SPAudioEngine.h b/libs/sparrow/src/Classes/SPAudioEngine.h new file mode 100644 index 0000000..d59fe5d --- /dev/null +++ b/libs/sparrow/src/Classes/SPAudioEngine.h @@ -0,0 +1,64 @@ +// +// SPAudioEngine.h +// Sparrow +// +// Created by Daniel Sperl on 14.11.09. +// Copyright 2009 Incognitek. All rights reserved. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the Simplified BSD License. +// + +#import + +#define SP_NOTIFICATION_MASTER_VOLUME_CHANGED @"masterVolumeChanged" +#define SP_NOTIFICATION_AUDIO_INTERRUPTION_BEGAN @"audioInterruptionBegan" +#define SP_NOTIFICATION_AUDIO_INTERRUPTION_ENDED @"audioInterruptionEnded" + +typedef enum { + SPAudioSessionCategory_AmbientSound = 'ambi', + SPAudioSessionCategory_SoloAmbientSound = 'solo', + SPAudioSessionCategory_MediaPlayback = 'medi', + SPAudioSessionCategory_RecordAudio = 'reca', + SPAudioSessionCategory_PlayAndRecord = 'plar', + SPAudioSessionCategory_AudioProcessing = 'proc' +} SPAudioSessionCategory; + +/** ------------------------------------------------------------------------------------------------ + + The SPAudioEngine prepares the system for audio playback and controls global volume. + + Before you play sounds, you should start an audio session. The type of the audio session + defines how iOS will handle audio processing and how iPod music will mix with your audio. + + * `SPAudioSessionCategory_AmbientSound:` iPod music mixes with your audio, audio silences on mute + * `SPAudioSessionCategory_SoloAmbientSound:` iPod music is silenced, audio silences on mute + * `SPAudioSessionCategory_MediaPlayback:` iPod music is silenced, audio continues on mute + * `SPAudioSessionCategory_RecordAudio:` iPod music is silenced, used for audio recording + * `SPAudioSessionCategory_PlayAndRecord:` iPod music is silenced, for simultaneous in- and output + * `SPAudioSessionCategory_AudioProcessing:` For using an audio hardware codec or signal processor + + */ + +@interface SPAudioEngine : NSObject + +/// ------------- +/// @name Methods +/// ------------- + +/// Starts an audio session with a specified category. Call this at the start of your application. ++ (void)start:(SPAudioSessionCategory)category; + +/// Starts an audio session with with the category 'SoloAmbientSound'. ++ (void)start; + +/// Stops the audio session. Call this before the application shuts down. ++ (void)stop; + +/// The master volume for all audio. Default: 1.0 ++ (float)masterVolume; + +/// Set the master volume for all audio. Range: [0.0 - 1.0] ++ (void)setMasterVolume:(float)volume; + +@end diff --git a/libs/sparrow/src/Classes/SPAudioEngine.m b/libs/sparrow/src/Classes/SPAudioEngine.m new file mode 100644 index 0000000..3f8bd06 --- /dev/null +++ b/libs/sparrow/src/Classes/SPAudioEngine.m @@ -0,0 +1,174 @@ +// +// SPAudioEngine.m +// Sparrow +// +// Created by Daniel Sperl on 14.11.09. +// Copyright 2009 Incognitek. All rights reserved. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the Simplified BSD License. +// + +#import "SPAudioEngine.h" + +#import +#import +#import + +@interface SPAudioEngine () + ++ (BOOL)initAudioSession:(SPAudioSessionCategory)category; ++ (BOOL)initOpenAL; + ++ (void)beginInterruption; ++ (void)endInterruption; + ++ (void)postNotification:(NSString *)name object:(id)object; + +@end + +@implementation SPAudioEngine + +// --- C functions --- + +void interruptionCallback (void *inUserData, UInt32 interruptionState) +{ + if (interruptionState == kAudioSessionBeginInterruption) + [SPAudioEngine beginInterruption]; + else if (interruptionState == kAudioSessionEndInterruption) + [SPAudioEngine endInterruption]; +} + +// --- static members --- + +static ALCdevice *device = NULL; +static ALCcontext *context = NULL; +static float masterVolume = 1.0f; + +// --- + +- (id)init +{ + [self release]; + [NSException raise:NSGenericException format:@"Static class - do not initialize!"]; + return nil; +} + ++ (void)start:(SPAudioSessionCategory)category +{ + if (!device) + { + if ([SPAudioEngine initAudioSession:category]) + [SPAudioEngine initOpenAL]; + } +} + ++ (void)start +{ + [SPAudioEngine start:SPAudioSessionCategory_SoloAmbientSound]; +} + ++ (void)stop +{ + alcMakeContextCurrent(NULL); + alcDestroyContext(context); + alcCloseDevice(device); + + device = NULL; + context = NULL; + + AudioSessionSetActive(NO); +} + ++ (BOOL)initAudioSession:(SPAudioSessionCategory)category +{ + static BOOL sessionInitialized = NO; + OSStatus result; + + if (!sessionInitialized) + { + result = AudioSessionInitialize(NULL, NULL, interruptionCallback, NULL); + if (result != kAudioSessionNoError) + { + NSLog(@"Could not initialize audio session: %x", result); + return NO; + } + sessionInitialized = YES; + } + + UInt32 sessionCategory = category; + AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, + sizeof(sessionCategory), &sessionCategory); + + result = AudioSessionSetActive(YES); + if (result != kAudioSessionNoError) + { + NSLog(@"Could not activate audio session: %x", result); + return NO; + } + + return YES; +} + ++ (BOOL)initOpenAL +{ + alGetError(); // reset any errors + + device = alcOpenDevice(NULL); + if (!device) + { + NSLog(@"Could not open default OpenAL device"); + return NO; + } + + context = alcCreateContext(device, 0); + if (!context) + { + NSLog(@"Could not create OpenAL context for default device"); + return NO; + } + + BOOL success = alcMakeContextCurrent(context); + if (!success) + { + NSLog(@"Could not set current OpenAL context"); + return NO; + } + + return YES; +} + ++ (void)beginInterruption +{ + [SPAudioEngine postNotification:SP_NOTIFICATION_AUDIO_INTERRUPTION_BEGAN object:nil]; + alcMakeContextCurrent(NULL); + AudioSessionSetActive(NO); +} + ++ (void)endInterruption +{ + AudioSessionSetActive(YES); + alcMakeContextCurrent(context); + alcProcessContext(context); + [SPAudioEngine postNotification:SP_NOTIFICATION_AUDIO_INTERRUPTION_ENDED object:nil]; +} + ++ (float)masterVolume +{ + return masterVolume; +} + ++ (void)setMasterVolume:(float)volume +{ + masterVolume = volume; + alListenerf(AL_GAIN, volume); + [SPAudioEngine postNotification:SP_NOTIFICATION_MASTER_VOLUME_CHANGED object:nil]; +} + ++ (void)postNotification:(NSString *)name object:(id)object +{ + [[NSNotificationCenter defaultCenter] postNotification: + [NSNotification notificationWithName:name object:object]]; +} + +@end diff --git a/libs/sparrow/src/Classes/SPBitmapChar.h b/libs/sparrow/src/Classes/SPBitmapChar.h new file mode 100644 index 0000000..07804fa --- /dev/null +++ b/libs/sparrow/src/Classes/SPBitmapChar.h @@ -0,0 +1,57 @@ +// +// SPBitmapChar.h +// Sparrow +// +// Created by Daniel Sperl on 12.10.09. +// Copyright 2009 Incognitek. All rights reserved. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the Simplified BSD License. +// + +#import +#import "SPImage.h" + +/** ------------------------------------------------------------------------------------------------ + + An SPBitmapChar is an image that contains one char of a bitmap font. Its properties contain all + the information that is needed to arrange the char in a text. + + _You don't have to use this class directly in most cases._ + +------------------------------------------------------------------------------------------------- */ + +@interface SPBitmapChar : SPImage +{ + @private + int mCharID; + float mXOffset; + float mYOffset; + float mXAdvance; +} + +/// ------------------ +/// @name Initializers +/// ------------------ + +/// Initializes a char with a texture and his properties. +- (id)initWithID:(int)charID texture:(SPTexture *)texture + xOffset:(float)xOffset yOffset:(float)yOffset xAdvance:(float)xAdvance; + +/// ---------------- +/// @name Properties +/// ---------------- + +/// The unicode ID of the char. +@property (nonatomic, readonly) int charID; + +/// The number of pixels to move the char in x direction on character arrangement. +@property (nonatomic, readonly) float xOffset; + +/// The number of pixels to move the char in y direction on character arrangement. +@property (nonatomic, readonly) float yOffset; + +/// The number of pixels the cursor has to be moved to the right for the next char. +@property (nonatomic, readonly) float xAdvance; + +@end diff --git a/libs/sparrow/src/Classes/SPBitmapChar.m b/libs/sparrow/src/Classes/SPBitmapChar.m new file mode 100644 index 0000000..e3124c2 --- /dev/null +++ b/libs/sparrow/src/Classes/SPBitmapChar.m @@ -0,0 +1,55 @@ +// +// SPBitmapChar.m +// Sparrow +// +// Created by Daniel Sperl on 12.10.09. +// Copyright 2009 Incognitek. All rights reserved. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the Simplified BSD License. +// + +#import "SPBitmapChar.h" +#import "SPTexture.h" + +@implementation SPBitmapChar + +@synthesize charID = mCharID; +@synthesize xOffset = mXOffset; +@synthesize yOffset = mYOffset; +@synthesize xAdvance = mXAdvance; + +- (id)initWithID:(int)charID texture:(SPTexture *)texture + xOffset:(float)xOffset yOffset:(float)yOffset xAdvance:(float)xAdvance; +{ + if (self = [super initWithTexture:texture]) + { + mCharID = charID; + mXOffset = xOffset; + mYOffset = yOffset; + mXAdvance = xAdvance; + } + return self; +} + +- (id)initWithTexture:(SPTexture *)texture +{ + return [self initWithID:0 texture:texture xOffset:0 yOffset:0 xAdvance:texture.width]; +} + +- (id)init +{ + [self release]; + return nil; +} + +#pragma mark NSCopying + +- (id)copyWithZone:(NSZone*)zone; +{ + return [[[self class] allocWithZone:zone] initWithID:mCharID texture:self.texture + xOffset:mXOffset yOffset:mYOffset + xAdvance:mXAdvance]; +} + +@end diff --git a/libs/sparrow/src/Classes/SPBitmapFont.h b/libs/sparrow/src/Classes/SPBitmapFont.h new file mode 100644 index 0000000..402ef57 --- /dev/null +++ b/libs/sparrow/src/Classes/SPBitmapFont.h @@ -0,0 +1,94 @@ +// +// SPBitmapFont.h +// Sparrow +// +// Created by Daniel Sperl on 12.10.09. +// Copyright 2009 Incognitek. All rights reserved. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the Simplified BSD License. +// + +#import +#import "SPBitmapChar.h" +#import "SPTextField.h" +#import "SPMacros.h" + +@class SPTexture; +@class SPDisplayObject; + +/** ------------------------------------------------------------------------------------------------ + + The SPBitmapFont class parses bitmap font files and arranges the glyphs in the form of a text. + + The class parses the XML format as it is used in the AngelCode Bitmap Font Generator. This is what + the file format looks like: + + + + + + + + + + + + + + _You don't have to use this class directly in most cases. SPTextField contains methods that + handle bitmap fonts for you._ + +------------------------------------------------------------------------------------------------- */ + +#ifdef __IPHONE_4_0 +@interface SPBitmapFont : NSObject +#else +@interface SPBitmapFont : NSObject +#endif +{ + @private + SPTexture *mFontTexture; + NSMutableDictionary *mChars; + NSString *mName; + float mSize; + float mLineHeight; +} + +/// ------------------ +/// @name Initializers +/// ------------------ + +/// Initializes a bitmap font by parsing an XML file and uses the specified texture. +- (id)initWithContentsOfFile:(NSString *)path texture:(SPTexture *)texture; + +/// Initializes a bitmap font by parsing an XML file and loads the texture that is specified there. +- (id)initWithContentsOfFile:(NSString *)path; + +/// ------------- +/// @name Methods +/// ------------- + +/// Creates a single bitmap char with a certain character ID. +- (SPBitmapChar *)charByID:(int)charID; + +/// Creates a display object that contains the given text by arranging individual chars. +- (SPDisplayObject *)createDisplayObjectWithWidth:(float)width height:(float)height + text:(NSString *)text fontSize:(float)size color:(uint)color + hAlign:(SPHAlign)hAlign vAlign:(SPVAlign)vAlign + border:(BOOL)border; + +/// ---------------- +/// @name Properties +/// ---------------- + +/// The name of the font as it was parsed from the font file. +@property (nonatomic, readonly) NSString *name; + +/// The native size of the font. +@property (nonatomic, readonly) float size; + +/// The height of one line in pixels. +@property (nonatomic, assign) float lineHeight; + +@end diff --git a/libs/sparrow/src/Classes/SPBitmapFont.m b/libs/sparrow/src/Classes/SPBitmapFont.m new file mode 100644 index 0000000..ea81f05 --- /dev/null +++ b/libs/sparrow/src/Classes/SPBitmapFont.m @@ -0,0 +1,289 @@ +// +// SPBitmapFont.m +// Sparrow +// +// Created by Daniel Sperl on 12.10.09. +// Copyright 2009 Incognitek. All rights reserved. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the Simplified BSD License. +// + +#import "SPBitmapFont.h" +#import "SPBitmapChar.h" +#import "SPTexture.h" +#import "SPRectangle.h" +#import "SPSubTexture.h" +#import "SPDisplayObject.h" +#import "SPSprite.h" +#import "SPImage.h" +#import "SPTextField.h" +#import "SPStage.h" +#import "SPNSExtensions.h" +#import "SPCompiledSprite.h" + +#define CHAR_SPACE 32 +#define CHAR_TAB 9 +#define CHAR_NEWLINE 10 + +// --- private interface --------------------------------------------------------------------------- + +@interface SPBitmapFont () + +- (void)parseFontXml:(NSString*)path; + +@end + +// --- class implementation ------------------------------------------------------------------------ + +@implementation SPBitmapFont + +@synthesize name = mName; +@synthesize lineHeight = mLineHeight; +@synthesize size = mSize; + +- (id)initWithContentsOfFile:(NSString *)path texture:(SPTexture *)texture +{ + if (self = [super init]) + { + mName = [[NSString alloc] initWithString:@"unknown"]; + mLineHeight = mSize = SP_DEFAULT_FONT_SIZE; + mFontTexture = [texture retain]; + + [self parseFontXml:path]; + } + return self; +} + +- (id)initWithContentsOfFile:(NSString *)path +{ + return [self initWithContentsOfFile:path texture:nil]; +} + +- (id)init +{ + [self release]; + return nil; +} + +- (void)parseFontXml:(NSString*)path +{ + SP_CREATE_POOL(pool); + + [mChars release]; + mChars = [[NSMutableDictionary alloc] init]; + + if (!path) return; + + float scale = [SPStage contentScaleFactor]; + NSString *fullPath = [[NSBundle mainBundle] pathForResource:path withScaleFactor:scale]; + NSURL *xmlUrl = [NSURL fileURLWithPath:fullPath]; + NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:xmlUrl]; + xmlParser.delegate = self; + BOOL success = [xmlParser parse]; + + SP_RELEASE_POOL(pool); + + if (!success) + [NSException raise:SP_EXC_FILE_INVALID + format:@"could not parse bitmap font xml %@. Error code: %d, domain: %@", + path, xmlParser.parserError.code, xmlParser.parserError.domain]; + + [xmlParser release]; +} + +- (void)parser:(NSXMLParser*)parser didStartElement:(NSString*)elementName + namespaceURI:(NSString*)namespaceURI + qualifiedName:(NSString*)qName + attributes:(NSDictionary*)attributeDict +{ + if ([elementName isEqualToString:@"char"]) + { + int charID = [[attributeDict valueForKey:@"id"] intValue]; + float scale = mFontTexture.scale; + + SPRectangle *region = [[SPRectangle alloc] init]; + region.x = [[attributeDict valueForKey:@"x"] floatValue] / scale; + region.y = [[attributeDict valueForKey:@"y"] floatValue] / scale; + region.width = [[attributeDict valueForKey:@"width"] floatValue] / scale; + region.height = [[attributeDict valueForKey:@"height"] floatValue] / scale; + SPSubTexture *texture = [[SPSubTexture alloc] initWithRegion:region ofTexture:mFontTexture]; + [region release]; + + float xOffset = [[attributeDict valueForKey:@"xoffset"] floatValue] / scale; + float yOffset = [[attributeDict valueForKey:@"yoffset"] floatValue] / scale; + float xAdvance = [[attributeDict valueForKey:@"xadvance"] floatValue] / scale; + + SPBitmapChar *bitmapChar = [[SPBitmapChar alloc] initWithID:charID texture:texture + xOffset:xOffset yOffset:yOffset + xAdvance:xAdvance]; + [texture release]; + + [mChars setObject:bitmapChar forKey:[NSNumber numberWithInt:charID]]; + [bitmapChar release]; + } + else if ([elementName isEqualToString:@"info"]) + { + [mName release]; + mName = [[attributeDict valueForKey:@"face"] copy]; + mSize = [[attributeDict valueForKey:@"size"] floatValue]; + } + else if ([elementName isEqualToString:@"common"]) + { + mLineHeight = [[attributeDict valueForKey:@"lineHeight"] floatValue]; + } + else if ([elementName isEqualToString:@"page"]) + { + int id = [[attributeDict valueForKey:@"id"] intValue]; + if (id != 0) [NSException raise:SP_EXC_FILE_INVALID + format:@"Bitmap fonts with multiple pages are not supported"]; + if (!mFontTexture) + { + NSString *filename = [attributeDict valueForKey:@"file"]; + mFontTexture = [[SPTexture alloc] initWithContentsOfFile:filename]; + + // update sizes, now that we know the scale setting + mSize /= mFontTexture.scale; + mLineHeight /= mFontTexture.scale; + } + } +} + +- (SPBitmapChar *)charByID:(int)charID +{ + SPBitmapChar *bitmapChar = (SPBitmapChar *)[mChars objectForKey:[NSNumber numberWithInt:charID]]; + return [[bitmapChar copy] autorelease]; +} + +- (SPDisplayObject *)createDisplayObjectWithWidth:(float)width height:(float)height + text:(NSString *)text fontSize:(float)size color:(uint)color + hAlign:(SPHAlign)hAlign vAlign:(SPVAlign)vAlign + border:(BOOL)border +{ + SPSprite *lineContainer = [SPSprite sprite]; + + if (size == SP_NATIVE_FONT_SIZE) size = mSize; + float scale = size / mSize; + lineContainer.scaleX = lineContainer.scaleY = scale; + float containerWidth = width / scale; + float containerHeight = height / scale; + + int lastWhiteSpace = -1; + float currentX = 0; + SPSprite *currentLine = [SPSprite sprite]; + + for (int i=0; i containerWidth) + { + // remove characters and add them again to next line + int numCharsToRemove = lastWhiteSpace == -1 ? 1 : i - lastWhiteSpace; + int removeIndex = currentLine.numChildren - numCharsToRemove; + + for (int i=0; i +#import "SPDisplayObjectContainer.h" + +@class SPTexture; +@class SPImage; +@class SPTextField; +@class SPSprite; + +#define SP_EVENT_TYPE_TRIGGERED @"triggered" + +/** ------------------------------------------------------------------------------------------------ + + An SPButton is a simple button composed of an image and, optionally, text. + + You can pass a texture for up- and downstate of the button. If you do not provide a down stage, + the button is simply scaled a little when it is touched. + + In addition, you can overlay a text on the button. To customize the text, almost the same options + as those of SPTextField are provided. In addition, you can move the text to a certain position + with the help of the `textBounds` property. + + To react on touches on a button, there is special event type: `SP_EVENT_TYPE_TRIGGERED`. Use + this event instead of normal touch events - that way, the button will behave just like standard + iOS interface buttons. + +------------------------------------------------------------------------------------------------- */ + +@interface SPButton : SPDisplayObjectContainer +{ + @private + SPTexture *mUpState; + SPTexture *mDownState; + + SPSprite *mContents; + SPImage *mBackground; + SPTextField *mTextField; + SPRectangle *mTextBounds; + + float mScaleWhenDown; + float mAlphaWhenDisabled; + BOOL mEnabled; + BOOL mIsDown; +} + +/// ------------------ +/// @name Initializers +/// ------------------ + +/// Initializes a button with textures for up- and down-state. _Designated Initializer_. +- (id)initWithUpState:(SPTexture*)upState downState:(SPTexture*)downState; + +/// Initializes a button with an up state texture and text. +- (id)initWithUpState:(SPTexture*)upState text:(NSString*)text; + +/// Initializes a button only with an up state. +- (id)initWithUpState:(SPTexture*)upState; + +/// Factory method. ++ (SPButton*)buttonWithUpState:(SPTexture*)upState downState:(SPTexture*)downState; + +/// Factory method. ++ (SPButton*)buttonWithUpState:(SPTexture*)upState text:(NSString*)text; + +/// Factory method. ++ (SPButton*)buttonWithUpState:(SPTexture*)upState; + +/// ---------------- +/// @name Properties +/// ---------------- + +/// The scale factor of the button on touch. Per default, a button with a down state texture won't scale. +@property (nonatomic, assign) float scaleWhenDown; + +/// The alpha value of the button when it is disabled. +@property (nonatomic, assign) float alphaWhenDisabled; + +/// Indicates if the button can be triggered. +@property (nonatomic, assign) BOOL enabled; + +/// The text that is displayed on the button. +@property (nonatomic, copy) NSString *text; + +/// The name of the font displayed on the button. May be a system font or a registered bitmap font. +@property (nonatomic, copy) NSString *fontName; + +/// The size of the font. +@property (nonatomic, assign) float fontSize; + +/// The color of the font. +@property (nonatomic, assign) uint fontColor; + +/// The texture that is displayed when the button is not being touched. +@property (nonatomic, retain) SPTexture *upState; + +/// The texture that is displayed while the button is touched. +@property (nonatomic, retain) SPTexture *downState; + +/// The bounds of the textfield on the button. Allows moving the text to a custom position. +@property (nonatomic, copy) SPRectangle *textBounds; + +@end diff --git a/libs/sparrow/src/Classes/SPButton.m b/libs/sparrow/src/Classes/SPButton.m new file mode 100644 index 0000000..c2cb93a --- /dev/null +++ b/libs/sparrow/src/Classes/SPButton.m @@ -0,0 +1,261 @@ +// +// SPButton.m +// Sparrow +// +// Created by Daniel Sperl on 13.07.09. +// Copyright 2009 Incognitek. All rights reserved. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the Simplified BSD License. +// + +#import "SPButton.h" +#import "SPTouchEvent.h" +#import "SPTexture.h" +#import "SPGLTexture.h" +#import "SPImage.h" +#import "SPStage.h" +#import "SPSprite.h" +#import "SPTextField.h" + +// --- private interface --------------------------------------------------------------------------- + +@interface SPButton() + +- (void)resetContents; +- (void)createTextField; + +@end + + +// --- class implementation ------------------------------------------------------------------------ + +@implementation SPButton + +@synthesize scaleWhenDown = mScaleWhenDown; +@synthesize alphaWhenDisabled = mAlphaWhenDisabled; +@synthesize enabled = mEnabled; +@synthesize upState = mUpState; +@synthesize downState = mDownState; +@synthesize textBounds = mTextBounds; + +#define MAX_DRAG_DIST 40 + +- (id)initWithUpState:(SPTexture*)upState downState:(SPTexture*)downState; +{ + if (self = [super init]) + { + mUpState = [upState retain]; + mDownState = [downState retain]; + mContents = [[SPSprite alloc] init]; + mBackground = [[SPImage alloc] initWithTexture:upState]; + mTextField = nil; + mScaleWhenDown = 1.0f; + mAlphaWhenDisabled = 0.5f; + mEnabled = YES; + mIsDown = NO; + mTextBounds = [[SPRectangle alloc] initWithX:0 y:0 width:mUpState.width height:mUpState.height]; + + [mContents addChild:mBackground]; + [self addChild:mContents]; + [self addEventListener:@selector(onTouch:) atObject:self forType:SP_EVENT_TYPE_TOUCH]; + } + return self; +} + +- (id)initWithUpState:(SPTexture*)upState text:(NSString*)text +{ + self = [self initWithUpState:upState]; + self.text = text; + return self; +} + +- (id)initWithUpState:(SPTexture*)upState; +{ + self = [self initWithUpState:upState downState:upState]; + mScaleWhenDown = 0.9f; + return self; +} + +- (id)init +{ + SPTexture *texture = [[[SPGLTexture alloc] init] autorelease]; + return [self initWithUpState:texture]; +} + +- (void)onTouch:(SPTouchEvent*)touchEvent +{ + if (!mEnabled) return; + SPTouch *touch = [[touchEvent touchesWithTarget:self] anyObject]; + + if (touch.phase == SPTouchPhaseBegan) + { + mBackground.texture = mDownState; + mContents.scaleX = mContents.scaleY = mScaleWhenDown; + mContents.x = (1.0f - mScaleWhenDown) / 2.0f * mDownState.width; + mContents.y = (1.0f - mScaleWhenDown) / 2.0f * mDownState.height; + mIsDown = YES; + } + else if (touch.phase == SPTouchPhaseMoved && mIsDown) + { + // reset button when user dragged to far away after pushing + SPRectangle *buttonRect = [self boundsInSpace:self.stage]; + if (touch.globalX < buttonRect.x - MAX_DRAG_DIST || + touch.globalY < buttonRect.y - MAX_DRAG_DIST || + touch.globalX > buttonRect.x + buttonRect.width + MAX_DRAG_DIST || + touch.globalY > buttonRect.y + buttonRect.height + MAX_DRAG_DIST) + { + [self resetContents]; + } + } + else if (touch.phase == SPTouchPhaseEnded && mIsDown) + { + [self resetContents]; + [self dispatchEvent:[SPEvent eventWithType:SP_EVENT_TYPE_TRIGGERED]]; + } + else if (touch.phase == SPTouchPhaseCancelled && mIsDown) + { + [self resetContents]; + } +} + +- (void)resetContents +{ + mIsDown = NO; + mBackground.texture = mUpState; + mContents.x = mContents.y = 0; + mContents.scaleX = mContents.scaleY = 1.0f; +} + +- (void)setEnabled:(BOOL)value +{ + mEnabled = value; + if (mEnabled) + { + mContents.alpha = 1.0f; + } + else + { + mContents.alpha = mAlphaWhenDisabled; + [self resetContents]; + } +} + +- (void)setUpState:(SPTexture*)upState +{ + if (upState != mUpState) + { + [mUpState release]; + mUpState = [upState retain]; + if (!mIsDown) mBackground.texture = upState; + } +} + +- (void)setDownState:(SPTexture*)downState +{ + if (downState != mDownState) + { + [mDownState release]; + mDownState = [downState retain]; + if (mIsDown) mBackground.texture = downState; + } +} + +- (void)createTextField +{ + if (!mTextField) + { + mTextField = [[SPTextField alloc] initWithWidth:100 height:100 text:@""]; + mTextField.vAlign = SPVAlignCenter; + mTextField.hAlign = SPHAlignCenter; + [mContents addChild:mTextField]; + } + + mTextField.width = mTextBounds.width; + mTextField.height = mTextBounds.height; + mTextField.x = mTextBounds.x; + mTextField.y = mTextBounds.y; +} + +- (NSString*)text +{ + if (mTextField) return mTextField.text; + else return @""; +} + +- (void)setText:(NSString*)value +{ + [self createTextField]; + mTextField.text = value; +} + +- (void)setTextBounds:(SPRectangle *)value +{ + mTextBounds = [value copy]; + [self createTextField]; +} + +- (NSString*)fontName +{ + if (mTextField) return mTextField.fontName; + else return SP_DEFAULT_FONT_NAME; +} + +- (void)setFontName:(NSString*)value +{ + [self createTextField]; + mTextField.fontName = value; +} + +- (float)fontSize +{ + if (mTextField) return mTextField.fontSize; + else return SP_DEFAULT_FONT_SIZE; +} + +- (void)setFontSize:(float)value +{ + [self createTextField]; + mTextField.fontSize = value; +} + +- (uint)fontColor +{ + if (mTextField) return mTextField.color; + else return SP_DEFAULT_FONT_COLOR; +} + +- (void)setFontColor:(uint)value +{ + [self createTextField]; + mTextField.color = value; +} + ++ (SPButton*)buttonWithUpState:(SPTexture*)upState downState:(SPTexture*)downState +{ + return [[[SPButton alloc] initWithUpState:upState downState:downState] autorelease]; +} + ++ (SPButton*)buttonWithUpState:(SPTexture*)upState text:(NSString*)text +{ + return [[[SPButton alloc] initWithUpState:upState text:text] autorelease]; +} + ++ (SPButton*)buttonWithUpState:(SPTexture*)upState +{ + return [[[SPButton alloc] initWithUpState:upState] autorelease]; +} + +- (void)dealloc +{ + [self removeEventListenersAtObject:self forType:SP_EVENT_TYPE_TOUCH]; + [mTextBounds release]; + [mUpState release]; + [mDownState release]; + [mBackground release]; + [mTextField release]; + [mContents release]; + [super dealloc]; +} + +@end diff --git a/libs/sparrow/src/Classes/SPCompiledSprite.h b/libs/sparrow/src/Classes/SPCompiledSprite.h new file mode 100644 index 0000000..81bcce0 --- /dev/null +++ b/libs/sparrow/src/Classes/SPCompiledSprite.h @@ -0,0 +1,61 @@ +// +// SPCompiledContainer.h +// Sparrow +// +// Created by Daniel Sperl on 15.07.10. +// Copyright 2010 Incognitek. All rights reserved. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the Simplified BSD License. +// + +#import +#import "SPSprite.h" + +/** ------------------------------------------------------------------------------------------------ + + An SPCompiledSprite allows you to optimize the rendering of static parts of your display list. + + It analyzes the tree of children attached to it and optimizes the OpenGL rendering calls in a + way that makes rendering them extremely fast. The downside is that you will no longe see any + changes in the properties of the childs (position, rotation, alpha, etc.). To update the object + after changes have happened, simply call `compile` again. + + With the exception of this peculiarity, a compiled sprite can be use just like any other sprite. + + SPCompiledSprite *sprite = [SPCompiledSprite sprite]; + [sprite addChild:object1]; + [sprite addChild:object2]; + + [sprite compile]; // this call is optional, it will be done on rendering automatically. + +------------------------------------------------------------------------------------------------- */ + +@interface SPCompiledSprite : SPSprite +{ + @private + NSArray *mTextureSwitches; + NSMutableData *mColorData; + uint *mCurrentColors; + BOOL mAlphaChanged; + + uint mIndexBuffer; + uint mVertexBuffer; + uint mColorBuffer; + uint mTexCoordBuffer; +} + +/// ------------- +/// @name Methods +/// ------------- + +/// Compiles the children of the sprite to optimize rendering. After compilation, no changes in +/// the children will show up. Call the method again to make changes visible. +/// +/// @return Returns `YES` if compilation was successful. On error, it will `NSLog` the problem. +- (BOOL)compile; + +/// Factory method. ++ (SPCompiledSprite *)sprite; + +@end \ No newline at end of file diff --git a/libs/sparrow/src/Classes/SPCompiledSprite.m b/libs/sparrow/src/Classes/SPCompiledSprite.m new file mode 100644 index 0000000..d400f74 --- /dev/null +++ b/libs/sparrow/src/Classes/SPCompiledSprite.m @@ -0,0 +1,436 @@ +// +// SPCompiledContainer.m +// Sparrow +// +// Created by Daniel Sperl on 15.07.10. +// Copyright 2010 Incognitek. All rights reserved. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the Simplified BSD License. +// + +#import "SPCompiledSprite.h" +#import "SPDisplayObjectContainer.h" +#import "SPPoint.h" +#import "SPMatrix.h" +#import "SPImage.h" +#import "SPQuad.h" +#import "SPTexture.h" +#import "SPRenderSupport.h" +#import "SPMacros.h" + +#import +#import +#import + +// --- SPQuad extension ---------------------------------------------------------------------------- + +@interface SPQuad (SPCompiledSprite_Extension) + +- (void)copyVertexCoords:(float *)vertexCoords colors:(uint *)colors textureCoords:(float *)texCoords; + +@end + +@implementation SPQuad (SPCompiledSprite_Extension) + +- (void)copyVertexCoords:(float *)vertexCoords colors:(uint *)colors textureCoords:(float *)texCoords +{ + if (vertexCoords) memcpy(vertexCoords, mVertexCoords, 8 * sizeof(float)); + if (colors) memcpy(colors, mVertexColors, 4 * sizeof(uint)); +} + +@end + +// --- SPImage extension --------------------------------------------------------------------------- + +@implementation SPImage (SPCompiledSprite_Extension) + +- (void)copyVertexCoords:(float *)vertexCoords colors:(uint *)colors textureCoords:(float *)texCoords +{ + [super copyVertexCoords:vertexCoords colors:colors textureCoords:texCoords]; + if (texCoords) memcpy(texCoords, mTexCoords, 8 * sizeof(float)); +} + +@end + +// --- private interface --------------------------------------------------------------------------- + +@interface SPCompiledSprite () + +- (BOOL)processVerticesOfObject:(SPDisplayObject *)object withMatrices:(NSMutableArray *)matrices + vertexData:(NSMutableData *)vertexData buffer:(void *)buffer; +- (BOOL)processColorsOfObject:(SPDisplayObject *)object withAlpha:(float)alpha + colorData:(NSMutableData *)colorData buffer:(void *)buffer; +- (BOOL)processTexturesOfObject:(SPDisplayObject *)object withTextures:(NSMutableArray *)textures + texCoordData:(NSMutableData *)texCoordData buffer:(void *)buffer; +- (void)updateColorData; +- (void)deleteBuffers; + +@end + +// --- class implementation ------------------------------------------------------------------------ + +@implementation SPCompiledSprite + +- (id)init +{ + return [super init]; +} + ++ (SPCompiledSprite *)sprite +{ + return [[[SPCompiledSprite alloc] init] autorelease]; +} + +- (void)dealloc +{ + free(mCurrentColors); + [mTextureSwitches release]; + [mColorData release]; + [self deleteBuffers]; + [super dealloc]; +} + +- (BOOL)compile +{ + SP_CREATE_POOL(pool); + + [self deleteBuffers]; + [mTextureSwitches release]; + [mColorData release]; + + free(mCurrentColors); + mCurrentColors = nil; + + void *scratchBuffer = malloc(MAX(8 * sizeof(float), 4 * sizeof(uint))); + + NSMutableData *vertexData = [[NSMutableData alloc] init]; + NSMutableData *colorData = [[NSMutableData alloc] init]; + NSMutableData *texCoordData = [[NSMutableData alloc] init]; + + NSMutableArray *matrices = [[NSMutableArray alloc] initWithObjects: + [SPMatrix matrixWithIdentity], nil]; + NSMutableArray *textures = [[NSMutableArray alloc] initWithObjects: + [NSNull null], [NSNumber numberWithInt:0], nil]; + + BOOL success; + + do + { + // compilation is done with an alpha of 1.0f, to get unscaled color data + float originalAlpha = self.alpha; + self.alpha = 1.0f; + + success = [self processVerticesOfObject:self withMatrices:matrices + vertexData:vertexData buffer:scratchBuffer]; + if (!success) break; + + success = [self processColorsOfObject:self withAlpha:self.alpha + colorData:colorData buffer:scratchBuffer]; + if (!success) break; + + success = [self processTexturesOfObject:self withTextures:textures + texCoordData:texCoordData buffer:scratchBuffer]; + + self.alpha = originalAlpha; + + } while (NO); + + if (success) + { + glGenBuffers(4, &mIndexBuffer); + + int numVertices = [vertexData length] / sizeof(float) / 2; + int numQuads = numVertices / 4; + int indexBufferSize = numQuads * 6; // 4 + 2 for degenerate triangles + GLushort *indices = malloc(indexBufferSize * sizeof(GLushort)); + + int pos = 0; + for (int i=0; i> 24) / 255.0f * alpha; + *newColors = [SPRenderSupport convertColor:origColor alpha:vertexAlpha premultiplyAlpha:pma]; + ++origColors; + ++newColors; + } + } + + // update buffer + glBindBuffer(GL_ARRAY_BUFFER, mColorBuffer); + glBufferSubData(GL_ARRAY_BUFFER, 0, mColorData.length, mCurrentColors); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + mAlphaChanged = NO; +} + +- (void)deleteBuffers +{ + glDeleteBuffers(4, &mIndexBuffer); + mIndexBuffer = mVertexBuffer = mColorBuffer = mTexCoordBuffer = 0; +} + +@end diff --git a/libs/sparrow/src/Classes/SPDelayedInvocation.h b/libs/sparrow/src/Classes/SPDelayedInvocation.h new file mode 100644 index 0000000..9dbea9f --- /dev/null +++ b/libs/sparrow/src/Classes/SPDelayedInvocation.h @@ -0,0 +1,58 @@ +// +// SPDelayedInvocation.h +// Sparrow +// +// Created by Daniel Sperl on 11.07.09. +// Copyright 2009 Incognitek. All rights reserved. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the Simplified BSD License. +// + +#import +#import "SPAnimatable.h" + +/** ------------------------------------------------------------------------------------------------ + + An SPDelayedInvocation is a proxy object that will forward any methods that are called on it + to a certain target - but only after a certain time has passed. + + The easiest way to delay an invocation is by calling [SPJuggler delayInvocationAtTarget:byTime:]. + This method will create a delayed invocation for you, adding it to the juggler right away. + +------------------------------------------------------------------------------------------------- */ + + +@interface SPDelayedInvocation : NSObject +{ + @private + id mTarget; + NSMutableSet *mInvocations; + double mTotalTime; + double mCurrentTime; +} + +/// ------------------ +/// @name Initializers +/// ------------------ + +/// Initializes a delayed invocation. +- (id)initWithTarget:(id)target delay:(double)time; + +/// Factory method. ++ (SPDelayedInvocation*)invocationWithTarget:(id)target delay:(double)time; + +/// ---------------- +/// @name Properties +/// ---------------- + +/// The target object to which messages will be forwarded. +@property (nonatomic, readonly) id target; + +/// The time messages will be delayed (in seconds). +@property (nonatomic, readonly) double totalTime; + +/// The time that has already passed (in seconds). +@property (nonatomic, assign) double currentTime; + +@end diff --git a/libs/sparrow/src/Classes/SPDelayedInvocation.m b/libs/sparrow/src/Classes/SPDelayedInvocation.m new file mode 100644 index 0000000..ba8e762 --- /dev/null +++ b/libs/sparrow/src/Classes/SPDelayedInvocation.m @@ -0,0 +1,93 @@ +// +// SPDelayedInvocation.m +// Sparrow +// +// Created by Daniel Sperl on 11.07.09. +// Copyright 2009 Incognitek. All rights reserved. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the Simplified BSD License. +// + +#import "SPDelayedInvocation.h" + + +@implementation SPDelayedInvocation + +@synthesize totalTime = mTotalTime; +@synthesize currentTime = mCurrentTime; +@synthesize target = mTarget; + +- (id)initWithTarget:(id)target delay:(double)time +{ + if (!target) + { + [self release]; + return nil; + } + + if (self = [super init]) + { + mTotalTime = MAX(0.0001, time); // zero is not allowed + mCurrentTime = 0; + mTarget = [target retain]; + mInvocations = [[NSMutableSet alloc] init]; + } + return self; +} + +- (id)init +{ + [self release]; + return nil; +} + +- (NSMethodSignature*)methodSignatureForSelector:(SEL)aSelector +{ + NSMethodSignature *sig = [[self class] instanceMethodSignatureForSelector:aSelector]; + if (!sig) sig = [mTarget methodSignatureForSelector:aSelector]; + return sig; +} + +- (void)forwardInvocation:(NSInvocation*)anInvocation +{ + if ([mTarget respondsToSelector:[anInvocation selector]]) + { + anInvocation.target = mTarget; + [anInvocation retainArguments]; + [mInvocations addObject:anInvocation]; + } +} + +- (void)advanceTime:(double)seconds +{ + self.currentTime = mCurrentTime + seconds; +} + +- (void)setCurrentTime:(double)currentTime +{ + double previousTime = mCurrentTime; + mCurrentTime = MIN(mTotalTime, currentTime); + + if (previousTime < mTotalTime && mCurrentTime >= mTotalTime) + [mInvocations makeObjectsPerformSelector:@selector(invoke)]; +} + +- (BOOL)isComplete +{ + return mCurrentTime >= mTotalTime; +} + ++ (SPDelayedInvocation*)invocationWithTarget:(id)target delay:(double)time +{ + return [[[SPDelayedInvocation alloc] initWithTarget:target delay:time] autorelease]; +} + +- (void)dealloc +{ + [mTarget release]; + [mInvocations release]; + [super dealloc]; +} + +@end diff --git a/libs/sparrow/src/Classes/SPDisplayObject.h b/libs/sparrow/src/Classes/SPDisplayObject.h new file mode 100644 index 0000000..2e85055 --- /dev/null +++ b/libs/sparrow/src/Classes/SPDisplayObject.h @@ -0,0 +1,172 @@ +// +// SPDisplayObject.h +// Sparrow +// +// Created by Daniel Sperl on 15.03.09. +// Copyright 2009 Incognitek. All rights reserved. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of