# Xcode
-build/*
+*/build/*
*.pbxuser
!default.pbxuser
*.mode1v3
--- /dev/null
+----------------------------------------------------------------------------------------------------
+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
--- /dev/null
+----------------------------------------------------------------------------------------------------
+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
--- /dev/null
+----------------------------------------------------------------------------------------------
+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
--- /dev/null
+----------------------------------------------------------------------------------------------------
+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
--- /dev/null
+#!/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."
--- /dev/null
+//
+// 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 <Foundation/Foundation.h>
+#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
--- /dev/null
+//
+// 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 <OpenAL/al.h>
+#import <OpenAL/alc.h>
+
+@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
--- /dev/null
+//
+// 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 <Foundation/Foundation.h>
+#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
--- /dev/null
+//
+// 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 <QuartzCore/QuartzCore.h> // for CACurrentMediaTime
+#import <OpenAL/al.h>
+#import <OpenAL/alc.h>
+
+// --- 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
--- /dev/null
+//
+// 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 <Foundation/Foundation.h>
+#import <AVFoundation/AVFoundation.h>
+
+#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&nbs