From 9cd57b731ab1c666d4a1cb725538fdc137763d12 Mon Sep 17 00:00:00 2001 From: Starla Insigna Date: Sat, 30 Jul 2011 11:19:14 -0400 Subject: Initial commit (version 0.2.1) --- libs/cocos2d/Platforms/CCGL.h | 83 +++ libs/cocos2d/Platforms/CCNS.h | 78 +++ libs/cocos2d/Platforms/Mac/CCDirectorMac.h | 103 +++ libs/cocos2d/Platforms/Mac/CCDirectorMac.m | 479 ++++++++++++++ libs/cocos2d/Platforms/Mac/CCEventDispatcher.h | 277 ++++++++ libs/cocos2d/Platforms/Mac/CCEventDispatcher.m | 645 ++++++++++++++++++ libs/cocos2d/Platforms/Mac/MacGLView.h | 89 +++ libs/cocos2d/Platforms/Mac/MacGLView.m | 242 +++++++ libs/cocos2d/Platforms/Mac/MacWindow.h | 42 ++ libs/cocos2d/Platforms/Mac/MacWindow.m | 70 ++ libs/cocos2d/Platforms/iOS/CCDirectorIOS.h | 255 +++++++ libs/cocos2d/Platforms/iOS/CCDirectorIOS.m | 735 +++++++++++++++++++++ .../Platforms/iOS/CCTouchDelegateProtocol.h | 75 +++ libs/cocos2d/Platforms/iOS/CCTouchDispatcher.h | 123 ++++ libs/cocos2d/Platforms/iOS/CCTouchDispatcher.m | 347 ++++++++++ libs/cocos2d/Platforms/iOS/CCTouchHandler.h | 93 +++ libs/cocos2d/Platforms/iOS/CCTouchHandler.m | 135 ++++ libs/cocos2d/Platforms/iOS/EAGLView.h | 155 +++++ libs/cocos2d/Platforms/iOS/EAGLView.m | 343 ++++++++++ libs/cocos2d/Platforms/iOS/ES1Renderer.h | 72 ++ libs/cocos2d/Platforms/iOS/ES1Renderer.m | 259 ++++++++ libs/cocos2d/Platforms/iOS/ESRenderer.h | 54 ++ libs/cocos2d/Platforms/iOS/glu.c | 113 ++++ libs/cocos2d/Platforms/iOS/glu.h | 29 + 24 files changed, 4896 insertions(+) create mode 100755 libs/cocos2d/Platforms/CCGL.h create mode 100755 libs/cocos2d/Platforms/CCNS.h create mode 100755 libs/cocos2d/Platforms/Mac/CCDirectorMac.h create mode 100755 libs/cocos2d/Platforms/Mac/CCDirectorMac.m create mode 100755 libs/cocos2d/Platforms/Mac/CCEventDispatcher.h create mode 100755 libs/cocos2d/Platforms/Mac/CCEventDispatcher.m create mode 100755 libs/cocos2d/Platforms/Mac/MacGLView.h create mode 100755 libs/cocos2d/Platforms/Mac/MacGLView.m create mode 100755 libs/cocos2d/Platforms/Mac/MacWindow.h create mode 100755 libs/cocos2d/Platforms/Mac/MacWindow.m create mode 100755 libs/cocos2d/Platforms/iOS/CCDirectorIOS.h create mode 100755 libs/cocos2d/Platforms/iOS/CCDirectorIOS.m create mode 100755 libs/cocos2d/Platforms/iOS/CCTouchDelegateProtocol.h create mode 100755 libs/cocos2d/Platforms/iOS/CCTouchDispatcher.h create mode 100755 libs/cocos2d/Platforms/iOS/CCTouchDispatcher.m create mode 100755 libs/cocos2d/Platforms/iOS/CCTouchHandler.h create mode 100755 libs/cocos2d/Platforms/iOS/CCTouchHandler.m create mode 100755 libs/cocos2d/Platforms/iOS/EAGLView.h create mode 100755 libs/cocos2d/Platforms/iOS/EAGLView.m create mode 100755 libs/cocos2d/Platforms/iOS/ES1Renderer.h create mode 100755 libs/cocos2d/Platforms/iOS/ES1Renderer.m create mode 100755 libs/cocos2d/Platforms/iOS/ESRenderer.h create mode 100755 libs/cocos2d/Platforms/iOS/glu.c create mode 100755 libs/cocos2d/Platforms/iOS/glu.h (limited to 'libs/cocos2d/Platforms') diff --git a/libs/cocos2d/Platforms/CCGL.h b/libs/cocos2d/Platforms/CCGL.h new file mode 100755 index 0000000..0725f89 --- /dev/null +++ b/libs/cocos2d/Platforms/CCGL.h @@ -0,0 +1,83 @@ +/* + * cocos2d for iPhone: http://www.cocos2d-iphone.org + * + * Copyright (c) 2010 Ricardo Quesada + * Copyright (c) 2011 Zynga Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// +// Common layer for OpenGL stuff +// + +#import + +#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED +#import +#import +#import +#import "iOS/glu.h" +#import "iOS/EAGLView.h" + +#elif defined(__MAC_OS_X_VERSION_MAX_ALLOWED) +#import +#import +#import // needed for NSOpenGLView +#import "Mac/MacGLView.h" +#endif + + +// iOS +#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED +#define CC_GLVIEW EAGLView +#define ccglOrtho glOrthof +#define ccglClearDepth glClearDepthf +#define ccglGenerateMipmap glGenerateMipmapOES +#define ccglGenFramebuffers glGenFramebuffersOES +#define ccglBindFramebuffer glBindFramebufferOES +#define ccglFramebufferTexture2D glFramebufferTexture2DOES +#define ccglDeleteFramebuffers glDeleteFramebuffersOES +#define ccglCheckFramebufferStatus glCheckFramebufferStatusOES +#define ccglTranslate glTranslatef + +#define CC_GL_FRAMEBUFFER GL_FRAMEBUFFER_OES +#define CC_GL_FRAMEBUFFER_BINDING GL_FRAMEBUFFER_BINDING_OES +#define CC_GL_COLOR_ATTACHMENT0 GL_COLOR_ATTACHMENT0_OES +#define CC_GL_FRAMEBUFFER_COMPLETE GL_FRAMEBUFFER_COMPLETE_OES + +// Mac +#elif defined(__MAC_OS_X_VERSION_MAX_ALLOWED) +#define CC_GLVIEW MacGLView +#define ccglOrtho glOrtho +#define ccglClearDepth glClearDepth +#define ccglGenerateMipmap glGenerateMipmap +#define ccglGenFramebuffers glGenFramebuffers +#define ccglBindFramebuffer glBindFramebuffer +#define ccglFramebufferTexture2D glFramebufferTexture2D +#define ccglDeleteFramebuffers glDeleteFramebuffers +#define ccglCheckFramebufferStatus glCheckFramebufferStatus +#define ccglTranslate glTranslated + +#define CC_GL_FRAMEBUFFER GL_FRAMEBUFFER +#define CC_GL_FRAMEBUFFER_BINDING GL_FRAMEBUFFER_BINDING +#define CC_GL_COLOR_ATTACHMENT0 GL_COLOR_ATTACHMENT0 +#define CC_GL_FRAMEBUFFER_COMPLETE GL_FRAMEBUFFER_COMPLETE + +#endif diff --git a/libs/cocos2d/Platforms/CCNS.h b/libs/cocos2d/Platforms/CCNS.h new file mode 100755 index 0000000..c595a18 --- /dev/null +++ b/libs/cocos2d/Platforms/CCNS.h @@ -0,0 +1,78 @@ +/* + * cocos2d for iPhone: http://www.cocos2d-iphone.org + * + * Copyright (c) 2010 Ricardo Quesada + * Copyright (c) 2011 Zynga Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// +// Common layer for NS (Next-Step) stuff +// + +#import + +#import // for NSObject + +#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED + +#define CCRectFromString(__r__) CGRectFromString(__r__) +#define CCPointFromString(__p__) CGPointFromString(__p__) +#define CCSizeFromString(__s__) CGSizeFromString(__s__) +#define CCNSSizeToCGSize +#define CCNSRectToCGRect +#define CCNSPointToCGPoint +#define CCTextAlignment UITextAlignment +#define CCTextAlignmentCenter UITextAlignmentCenter +#define CCTextAlignmentLeft UITextAlignmentLeft +#define CCTextAlignmentRight UITextAlignmentRight +#define CCLineBreakMode UILineBreakMode +#define CCLineBreakModeWordWrap UILineBreakModeWordWrap +#define CCLineBreakModeCharacterWrap UILineBreakModeCharacterWrap +#define CCLineBreakModeClip UILineBreakModeClip +#define CCLineBreakModeHeadTruncation UILineBreakModeHeadTruncation +#define CCLineBreakModeTailTruncation UILineBreakModeTailTruncation +#define CCLineBreakModeMiddleTruncation UILineBreakModeMiddleTruncation + + + +#elif defined(__MAC_OS_X_VERSION_MAX_ALLOWED) + +#define CCRectFromString(__r__) NSRectToCGRect( NSRectFromString(__r__) ) +#define CCPointFromString(__p__) NSPointToCGPoint( NSPointFromString(__p__) ) +#define CCSizeFromString(__s__) NSSizeToCGSize( NSSizeFromString(__s__) ) +#define CCNSSizeToCGSize NSSizeToCGSize +#define CCNSRectToCGRect NSRectToCGRect +#define CCNSPointToCGPoint NSPointToCGPoint +#define CCTextAlignment NSTextAlignment +#define CCTextAlignmentCenter NSCenterTextAlignment +#define CCTextAlignmentLeft NSLeftTextAlignment +#define CCTextAlignmentRight NSRightTextAlignment +#define CCLineBreakMode NSLineBreakMode +#define CCLineBreakModeWordWrap NSLineBreakByWordWrapping +#define CCLineBreakModeClip -1 +#define CCLineBreakModeHeadTruncation -1 +#define CCLineBreakModeTailTruncation -1 +#define CCLineBreakModeMiddleTruncation -1 + + +#endif + + diff --git a/libs/cocos2d/Platforms/Mac/CCDirectorMac.h b/libs/cocos2d/Platforms/Mac/CCDirectorMac.h new file mode 100755 index 0000000..0d623b4 --- /dev/null +++ b/libs/cocos2d/Platforms/Mac/CCDirectorMac.h @@ -0,0 +1,103 @@ +/* + * cocos2d for iPhone: http://www.cocos2d-iphone.org + * + * Copyright (c) 2010 Ricardo Quesada + * Copyright (c) 2011 Zynga Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + + +// Only compile this code on Mac. These files should not be included on your iOS project. +// But in case they are included, it won't be compiled. +#import +#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED +#elif defined(__MAC_OS_X_VERSION_MAX_ALLOWED) + +#import +#import "../../CCDirector.h" + +enum { + /// If the window is resized, it won't be autoscaled + kCCDirectorResize_NoScale, + /// If the window is resized, it will be autoscaled (default behavior) + kCCDirectorResize_AutoScale, +}; + +@interface CCDirector (MacExtension) +/** converts an NSEvent to GL coordinates */ +-(CGPoint) convertEventToGL:(NSEvent*)event; +@end + +/** Base class of Mac directors + @since v0.99.5 + */ +@interface CCDirectorMac : CCDirector +{ + BOOL isFullScreen_; + int resizeMode_; + CGPoint winOffset_; + CGSize originalWinSize_; + + NSWindow *fullScreenWindow_; + + // cache + NSWindow *windowGLView_; + NSView *superViewGLView_; + NSRect originalWinRect_; // Original size and position +} + +// whether or not the view is in fullscreen mode +@property (nonatomic, readonly) BOOL isFullScreen; + +// resize mode: with or without scaling +@property (nonatomic, readwrite) int resizeMode; + +@property (nonatomic, readwrite) CGSize originalWinSize; + +/** Sets the view in fullscreen or window mode */ +- (void) setFullScreen:(BOOL)fullscreen; + +/** Converts window size coordiantes to logical coordinates. + Useful only if resizeMode is kCCDirectorResize_Scale. + If resizeMode is kCCDirectorResize_NoScale, then no conversion will be done. +*/ +- (CGPoint) convertToLogicalCoordinates:(CGPoint)coordinates; +@end + + +/** DisplayLinkDirector is a Director that synchronizes timers with the refresh rate of the display. + * + * Features and Limitations: + * - Only available on 3.1+ + * - Scheduled timers & drawing are synchronizes with the refresh rate of the display + * - Only supports animation intervals of 1/60 1/30 & 1/15 + * + * It is the recommended Director if the SDK is 3.1 or newer + * + * @since v0.8.2 + */ +@interface CCDirectorDisplayLink : CCDirectorMac +{ + CVDisplayLinkRef displayLink; +} +@end + +#endif // __MAC_OS_X_VERSION_MAX_ALLOWED + diff --git a/libs/cocos2d/Platforms/Mac/CCDirectorMac.m b/libs/cocos2d/Platforms/Mac/CCDirectorMac.m new file mode 100755 index 0000000..477081e --- /dev/null +++ b/libs/cocos2d/Platforms/Mac/CCDirectorMac.m @@ -0,0 +1,479 @@ +/* + * cocos2d for iPhone: http://www.cocos2d-iphone.org + * + * Copyright (c) 2010 Ricardo Quesada + * Copyright (c) 2011 Zynga Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// Only compile this code on Mac. These files should not be included on your iOS project. +// But in case they are included, it won't be compiled. +#import +#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED +#elif defined(__MAC_OS_X_VERSION_MAX_ALLOWED) + +#import + +#import "CCDirectorMac.h" +#import "CCEventDispatcher.h" +#import "MacGLView.h" + +#import "../../CCNode.h" +#import "../../CCScheduler.h" +#import "../../ccMacros.h" + +#pragma mark - +#pragma mark Director Mac extensions + + +@interface CCDirector () +-(void) setNextScene; +-(void) showFPS; +-(void) calculateDeltaTime; +@end + +@implementation CCDirector (MacExtension) +-(CGPoint) convertEventToGL:(NSEvent*)event +{ + NSPoint point = [openGLView_ convertPoint:[event locationInWindow] fromView:nil]; + CGPoint p = NSPointToCGPoint(point); + + return [(CCDirectorMac*)self convertToLogicalCoordinates:p]; +} + +@end + +#pragma mark - +#pragma mark Director Mac + +@implementation CCDirectorMac + +@synthesize isFullScreen = isFullScreen_; +@synthesize originalWinSize = originalWinSize_; + +-(id) init +{ + if( (self = [super init]) ) { + isFullScreen_ = NO; + resizeMode_ = kCCDirectorResize_AutoScale; + + originalWinSize_ = CGSizeZero; + fullScreenWindow_ = nil; + windowGLView_ = nil; + winOffset_ = CGPointZero; + } + + return self; +} + +- (void) dealloc +{ + [superViewGLView_ release]; + [fullScreenWindow_ release]; + [windowGLView_ release]; + [super dealloc]; +} + +// +// setFullScreen code taken from GLFullScreen example by Apple +// +- (void) setFullScreen:(BOOL)fullscreen +{ + // Mac OS X 10.6 and later offer a simplified mechanism to create full-screen contexts +#if MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_5 + + if (isFullScreen_ == fullscreen) return; + + if( fullscreen ) { + originalWinRect_ = [openGLView_ frame]; + + // Cache normal window and superview of openGLView + if(!windowGLView_) + windowGLView_ = [[openGLView_ window] retain]; + + [superViewGLView_ release]; + superViewGLView_ = [[openGLView_ superview] retain]; + + + // Get screen size + NSRect displayRect = [[NSScreen mainScreen] frame]; + + // Create a screen-sized window on the display you want to take over + fullScreenWindow_ = [[MacWindow alloc] initWithFrame:displayRect fullscreen:YES]; + + // Remove glView from window + [openGLView_ removeFromSuperview]; + + // Set new frame + [openGLView_ setFrame:displayRect]; + + // Attach glView to fullscreen window + [fullScreenWindow_ setContentView:openGLView_]; + + // Show the fullscreen window + [fullScreenWindow_ makeKeyAndOrderFront:self]; + [fullScreenWindow_ makeMainWindow]; + + } else { + + // Remove glView from fullscreen window + [openGLView_ removeFromSuperview]; + + // Release fullscreen window + [fullScreenWindow_ release]; + fullScreenWindow_ = nil; + + // Attach glView to superview + [superViewGLView_ addSubview:openGLView_]; + + // Set new frame + [openGLView_ setFrame:originalWinRect_]; + + // Show the window + [windowGLView_ makeKeyAndOrderFront:self]; + [windowGLView_ makeMainWindow]; + } + isFullScreen_ = fullscreen; + + [openGLView_ retain]; // Retain +1 + + // re-configure glView + [self setOpenGLView:openGLView_]; + + [openGLView_ release]; // Retain -1 + + [openGLView_ setNeedsDisplay:YES]; +#else +#error Full screen is not supported for Mac OS 10.5 or older yet +#error If you don't want FullScreen support, you can safely remove these 2 lines +#endif +} + +-(void) setOpenGLView:(MacGLView *)view +{ + [super setOpenGLView:view]; + + // cache the NSWindow and NSOpenGLView created from the NIB + if( !isFullScreen_ && CGSizeEqualToSize(originalWinSize_, CGSizeZero)) + { + originalWinSize_ = winSizeInPixels_; + } +} + +-(int) resizeMode +{ + return resizeMode_; +} + +-(void) setResizeMode:(int)mode +{ + if( mode != resizeMode_ ) { + + resizeMode_ = mode; + + [self setProjection:projection_]; + [openGLView_ setNeedsDisplay: YES]; + } +} + +-(void) setProjection:(ccDirectorProjection)projection +{ + CGSize size = winSizeInPixels_; + + CGPoint offset = CGPointZero; + float widthAspect = size.width; + float heightAspect = size.height; + + + if( resizeMode_ == kCCDirectorResize_AutoScale && ! CGSizeEqualToSize(originalWinSize_, CGSizeZero ) ) { + + size = originalWinSize_; + + float aspect = originalWinSize_.width / originalWinSize_.height; + widthAspect = winSizeInPixels_.width; + heightAspect = winSizeInPixels_.width / aspect; + + if( heightAspect > winSizeInPixels_.height ) { + widthAspect = winSizeInPixels_.height * aspect; + heightAspect = winSizeInPixels_.height; + } + + winOffset_.x = (winSizeInPixels_.width - widthAspect) / 2; + winOffset_.y = (winSizeInPixels_.height - heightAspect) / 2; + + offset = winOffset_; + + } + + switch (projection) { + case kCCDirectorProjection2D: + glViewport(offset.x, offset.y, widthAspect, heightAspect); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + ccglOrtho(0, size.width, 0, size.height, -1024, 1024); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + break; + + case kCCDirectorProjection3D: + glViewport(offset.x, offset.y, widthAspect, heightAspect); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(60, (GLfloat)widthAspect/heightAspect, 0.1f, 1500.0f); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + float eyeZ = size.height * [self getZEye] / winSizeInPixels_.height; + + gluLookAt( size.width/2, size.height/2, eyeZ, + size.width/2, size.height/2, 0, + 0.0f, 1.0f, 0.0f); + break; + + case kCCDirectorProjectionCustom: + if( projectionDelegate_ ) + [projectionDelegate_ updateProjection]; + break; + + default: + CCLOG(@"cocos2d: Director: unrecognized projecgtion"); + break; + } + + projection_ = projection; +} + +// If scaling is supported, then it should always return the original size +// otherwise it should return the "real" size. +-(CGSize) winSize +{ + if( resizeMode_ == kCCDirectorResize_AutoScale ) + return originalWinSize_; + + return winSizeInPixels_; +} + +-(CGSize) winSizeInPixels +{ + return [self winSize]; +} + +- (CGPoint) convertToLogicalCoordinates:(CGPoint)coords +{ + CGPoint ret; + + if( resizeMode_ == kCCDirectorResize_NoScale ) + ret = coords; + + else { + + float x_diff = originalWinSize_.width / (winSizeInPixels_.width - winOffset_.x * 2); + float y_diff = originalWinSize_.height / (winSizeInPixels_.height - winOffset_.y * 2); + + float adjust_x = (winSizeInPixels_.width * x_diff - originalWinSize_.width ) / 2; + float adjust_y = (winSizeInPixels_.height * y_diff - originalWinSize_.height ) / 2; + + ret = CGPointMake( (x_diff * coords.x) - adjust_x, ( y_diff * coords.y ) - adjust_y ); + } + + return ret; +} +@end + + +#pragma mark - +#pragma mark DirectorDisplayLink + + +@implementation CCDirectorDisplayLink + +- (CVReturn) getFrameForTime:(const CVTimeStamp*)outputTime +{ +#if CC_DIRECTOR_MAC_USE_DISPLAY_LINK_THREAD + if( ! runningThread_ ) + runningThread_ = [NSThread currentThread]; + + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + + [self drawScene]; + [[CCEventDispatcher sharedDispatcher] dispatchQueuedEvents]; + + [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:nil]; + + [pool release]; + +#else + [self performSelector:@selector(drawScene) onThread:runningThread_ withObject:nil waitUntilDone:YES]; +#endif + + return kCVReturnSuccess; +} + +// This is the renderer output callback function +static CVReturn MyDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeStamp* now, const CVTimeStamp* outputTime, CVOptionFlags flagsIn, CVOptionFlags* flagsOut, void* displayLinkContext) +{ + CVReturn result = [(CCDirectorDisplayLink*)displayLinkContext getFrameForTime:outputTime]; + return result; +} + +- (void) startAnimation +{ +#if ! CC_DIRECTOR_MAC_USE_DISPLAY_LINK_THREAD + runningThread_ = [[NSThread alloc] initWithTarget:self selector:@selector(mainLoop) object:nil]; + [runningThread_ start]; +#endif + + gettimeofday( &lastUpdate_, NULL); + + // Create a display link capable of being used with all active displays + CVDisplayLinkCreateWithActiveCGDisplays(&displayLink); + + // Set the renderer output callback function + CVDisplayLinkSetOutputCallback(displayLink, &MyDisplayLinkCallback, self); + + // Set the display link for the current renderer + CGLContextObj cglContext = [[openGLView_ openGLContext] CGLContextObj]; + CGLPixelFormatObj cglPixelFormat = [[openGLView_ pixelFormat] CGLPixelFormatObj]; + CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext(displayLink, cglContext, cglPixelFormat); + + // Activate the display link + CVDisplayLinkStart(displayLink); +} + +- (void) stopAnimation +{ + if( displayLink ) { + CVDisplayLinkStop(displayLink); + CVDisplayLinkRelease(displayLink); + displayLink = NULL; + +#if ! CC_DIRECTOR_MAC_USE_DISPLAY_LINK_THREAD + [runningThread_ cancel]; + [runningThread_ release]; + runningThread_ = nil; +#endif + } +} + +-(void) dealloc +{ + if( displayLink ) { + CVDisplayLinkStop(displayLink); + CVDisplayLinkRelease(displayLink); + } + [super dealloc]; +} + +// +// Mac Director has its own thread +// +-(void) mainLoop +{ + while( ![[NSThread currentThread] isCancelled] ) { + // There is no autorelease pool when this method is called because it will be called from a background thread + // It's important to create one or you will leak objects + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + + [[NSRunLoop currentRunLoop] run]; + + [pool release]; + } +} + +// +// Draw the Scene +// +- (void) drawScene +{ + // We draw on a secondary thread through the display link + // When resizing the view, -reshape is called automatically on the main thread + // Add a mutex around to avoid the threads accessing the context simultaneously when resizing + CGLLockContext([[openGLView_ openGLContext] CGLContextObj]); + [[openGLView_ openGLContext] makeCurrentContext]; + + /* calculate "global" dt */ + [self calculateDeltaTime]; + + /* tick before glClear: issue #533 */ + if( ! isPaused_ ) { + [[CCScheduler sharedScheduler] tick: dt]; + } + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + /* to avoid flickr, nextScene MUST be here: after tick and before draw. + XXX: Which bug is this one. It seems that it can't be reproduced with v0.9 */ + if( nextScene_ ) + [self setNextScene]; + + glPushMatrix(); + + + // By default enable VertexArray, ColorArray, TextureCoordArray and Texture2D + CC_ENABLE_DEFAULT_GL_STATES(); + + /* draw the scene */ + [runningScene_ visit]; + + /* draw the notification node */ + [notificationNode_ visit]; + + if( displayFPS_ ) + [self showFPS]; + +#if CC_ENABLE_PROFILERS + [self showProfilers]; +#endif + + CC_DISABLE_DEFAULT_GL_STATES(); + + glPopMatrix(); + + [[openGLView_ openGLContext] flushBuffer]; + CGLUnlockContext([[openGLView_ openGLContext] CGLContextObj]); +} + +// set the event dispatcher +-(void) setOpenGLView:(MacGLView *)view +{ + if( view != openGLView_ ) { + + [super setOpenGLView:view]; + + CCEventDispatcher *eventDispatcher = [CCEventDispatcher sharedDispatcher]; + [openGLView_ setEventDelegate: eventDispatcher]; + [eventDispatcher setDispatchEvents: YES]; + + // Enable Touches. Default no. + [view setAcceptsTouchEvents:NO]; +// [view setAcceptsTouchEvents:YES]; + + + // Synchronize buffer swaps with vertical refresh rate + [[view openGLContext] makeCurrentContext]; + GLint swapInt = 1; + [[view openGLContext] setValues:&swapInt forParameter:NSOpenGLCPSwapInterval]; + } +} + +@end + +#endif // __MAC_OS_X_VERSION_MAX_ALLOWED diff --git a/libs/cocos2d/Platforms/Mac/CCEventDispatcher.h b/libs/cocos2d/Platforms/Mac/CCEventDispatcher.h new file mode 100755 index 0000000..06889e8 --- /dev/null +++ b/libs/cocos2d/Platforms/Mac/CCEventDispatcher.h @@ -0,0 +1,277 @@ +/* + * cocos2d for iPhone: http://www.cocos2d-iphone.org + * + * Copyright (c) 2010 Ricardo Quesada + * Copyright (c) 2011 Zynga Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// Only compile this code on Mac. These files should not be included on your iOS project. +// But in case they are included, it won't be compiled. +#import +#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED +#elif defined(__MAC_OS_X_VERSION_MAX_ALLOWED) + +#import + +#import "MacGLView.h" +#import "../../Support/uthash.h" // hack: uthash needs to be imported before utlist to prevent warning +#import "../../Support/utlist.h" +#import "../../ccConfig.h" + +#pragma mark - +#pragma mark CCMouseEventDelegate + +/** CCMouseEventDelegate protocol. + Implement it in your node to receive any of mouse events + */ +@protocol CCMouseEventDelegate +@optional + +// +// left +// +/** called when the "mouseDown" event is received. + Return YES to avoid propagating the event to other delegates. + */ +-(BOOL) ccMouseDown:(NSEvent*)event; + +/** called when the "mouseDragged" event is received. + Return YES to avoid propagating the event to other delegates. + */ +-(BOOL) ccMouseDragged:(NSEvent*)event; + +/** called when the "mouseMoved" event is received. + Return YES to avoid propagating the event to other delegates. + By default, "mouseMoved" is disabled. To enable it, send the "setAcceptsMouseMovedEvents:YES" message to the main window. + */ +-(BOOL) ccMouseMoved:(NSEvent*)event; + +/** called when the "mouseUp" event is received. + Return YES to avoid propagating the event to other delegates. + */ +-(BOOL) ccMouseUp:(NSEvent*)event; + + +// +// right +// + +/** called when the "rightMouseDown" event is received. + Return YES to avoid propagating the event to other delegates. + */ +-(BOOL) ccRightMouseDown:(NSEvent*)event; + +/** called when the "rightMouseDragged" event is received. + Return YES to avoid propagating the event to other delegates. + */ +-(BOOL) ccRightMouseDragged:(NSEvent*)event; + +/** called when the "rightMouseUp" event is received. + Return YES to avoid propagating the event to other delegates. + */ +-(BOOL) ccRightMouseUp:(NSEvent*)event; + +// +// other +// + +/** called when the "otherMouseDown" event is received. + Return YES to avoid propagating the event to other delegates. + */ +-(BOOL) ccOtherMouseDown:(NSEvent*)event; + +/** called when the "otherMouseDragged" event is received. + Return YES to avoid propagating the event to other delegates. + */ +-(BOOL) ccOtherMouseDragged:(NSEvent*)event; + +/** called when the "otherMouseUp" event is received. + Return YES to avoid propagating the event to other delegates. + */ +-(BOOL) ccOtherMouseUp:(NSEvent*)event; + +// +// scroll wheel +// + +/** called when the "scrollWheel" event is received. + Return YES to avoid propagating the event to other delegates. + */ +- (BOOL)ccScrollWheel:(NSEvent *)theEvent; + + +// +// enter / exit +// + +/** called when the "mouseEntered" event is received. + Return YES to avoid propagating the event to other delegates. + */ +- (void)ccMouseEntered:(NSEvent *)theEvent; + +/** called when the "mouseExited" event is received. + Return YES to avoid propagating the event to other delegates. + */ +- (void)ccMouseExited:(NSEvent *)theEvent; + +@end + +#pragma mark - +#pragma mark CCKeyboardEventDelegate + +/** CCKeyboardEventDelegate protocol. + Implement it in your node to receive any of keyboard events + */ +@protocol CCKeyboardEventDelegate +@optional +/** called when the "keyUp" event is received. + Return YES to avoid propagating the event to other delegates. + */ +-(BOOL) ccKeyUp:(NSEvent*)event; + +/** called when the "keyDown" event is received. + Return YES to avoid propagating the event to other delegates. + */ +-(BOOL) ccKeyDown:(NSEvent*)event; +/** called when the "flagsChanged" event is received. + Return YES to avoid propagating the event to other delegates. + */ +-(BOOL) ccFlagsChanged:(NSEvent*)event; +@end + +#pragma mark - +#pragma mark CCTouchEventDelegate + +/** CCTouchEventDelegate protocol. + Implement it in your node to receive any of touch events + */ +@protocol CCTouchEventDelegate +@optional +/** called when the "touchesBegan" event is received. + Return YES to avoid propagating the event to other delegates. + */ +- (BOOL)ccTouchesBeganWithEvent:(NSEvent *)event; + +/** called when the "touchesMoved" event is received. + Return YES to avoid propagating the event to other delegates. + */ +- (BOOL)ccTouchesMovedWithEvent:(NSEvent *)event; + +/** called when the "touchesEnded" event is received. + Return YES to avoid propagating the event to other delegates. + */ +- (BOOL)ccTouchesEndedWithEvent:(NSEvent *)event; + +/** called when the "touchesCancelled" event is received. + Return YES to avoid propagating the event to other delegates. + */ +- (BOOL)ccTouchesCancelledWithEvent:(NSEvent *)event; + +@end + + +#pragma mark - +#pragma mark CCEventDispatcher + +struct _listEntry; + +/** CCEventDispatcher + + This is object is responsible for dispatching the events: + - Mouse events + - Keyboard events + - Touch events + + Only available on Mac + */ +@interface CCEventDispatcher : NSObject { + + BOOL dispatchEvents_; + + struct _listEntry *keyboardDelegates_; + struct _listEntry *mouseDelegates_; + struct _listEntry *touchDelegates_; +} + +@property (nonatomic, readwrite) BOOL dispatchEvents; + + +/** CCEventDispatcher singleton */ ++(CCEventDispatcher*) sharedDispatcher; + +#pragma mark CCEventDispatcher - Mouse + +/** Adds a mouse delegate to the dispatcher's list. + Delegates with a lower priority value will be called before higher priority values. + All the events will be propgated to all the delegates, unless the one delegate returns YES. + + IMPORTANT: The delegate will be retained. + */ +-(void) addMouseDelegate:(id) delegate priority:(NSInteger)priority; + +/** removes a mouse delegate */ +-(void) removeMouseDelegate:(id) delegate; + +/** Removes all mouse delegates, releasing all the delegates */ +-(void) removeAllMouseDelegates; + +#pragma mark CCEventDispatcher - Keyboard + +/** Adds a Keyboard delegate to the dispatcher's list. + Delegates with a lower priority value will be called before higher priority values. + All the events will be propgated to all the delegates, unless the one delegate returns YES. + + IMPORTANT: The delegate will be retained. + */ +-(void) addKeyboardDelegate:(id) delegate priority:(NSInteger)priority; + +/** removes a mouse delegate */ +-(void) removeKeyboardDelegate:(id) delegate; + +/** Removes all mouse delegates, releasing all the delegates */ +-(void) removeAllKeyboardDelegates; + +#pragma mark CCEventDispatcher - Touches + +/** Adds a Touch delegate to the dispatcher's list. + Delegates with a lower priority value will be called before higher priority values. + All the events will be propgated to all the delegates, unless the one delegate returns YES. + + IMPORTANT: The delegate will be retained. + */ +- (void)addTouchDelegate:(id)delegate priority:(NSInteger)priority; + +/** Removes a touch delegate */ +- (void)removeTouchDelegate:(id) delegate; + +/** Removes all touch delegates, releasing all the delegates */ +- (void)removeAllTouchDelegates; + +#pragma mark CCEventDispatcher - Dispatch Events + +#if CC_DIRECTOR_MAC_USE_DISPLAY_LINK_THREAD +-(void) dispatchQueuedEvents; +#endif + +@end + + +#endif // __MAC_OS_X_VERSION_MAX_ALLOWED diff --git a/libs/cocos2d/Platforms/Mac/CCEventDispatcher.m b/libs/cocos2d/Platforms/Mac/CCEventDispatcher.m new file mode 100755 index 0000000..1d1740e --- /dev/null +++ b/libs/cocos2d/Platforms/Mac/CCEventDispatcher.m @@ -0,0 +1,645 @@ +/* + * cocos2d for iPhone: http://www.cocos2d-iphone.org + * + * Copyright (c) 2010 Ricardo Quesada + * Copyright (c) 2011 Zynga Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// Only compile this code on Mac. These files should not be included on your iOS project. +// But in case they are included, it won't be compiled. +#import +#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED +#elif defined(__MAC_OS_X_VERSION_MAX_ALLOWED) + +#import "CCEventDispatcher.h" +#import "../../ccConfig.h" + +static CCEventDispatcher *sharedDispatcher = nil; + +enum { + // mouse + kCCImplementsMouseDown = 1 << 0, + kCCImplementsMouseMoved = 1 << 1, + kCCImplementsMouseDragged = 1 << 2, + kCCImplementsMouseUp = 1 << 3, + kCCImplementsRightMouseDown = 1 << 4, + kCCImplementsRightMouseDragged = 1 << 5, + kCCImplementsRightMouseUp = 1 << 6, + kCCImplementsOtherMouseDown = 1 << 7, + kCCImplementsOtherMouseDragged = 1 << 8, + kCCImplementsOtherMouseUp = 1 << 9, + kCCImplementsScrollWheel = 1 << 10, + kCCImplementsMouseEntered = 1 << 11, + kCCImplementsMouseExited = 1 << 12, + + kCCImplementsTouchesBegan = 1 << 13, + kCCImplementsTouchesMoved = 1 << 14, + kCCImplementsTouchesEnded = 1 << 15, + kCCImplementsTouchesCancelled = 1 << 16, + + // keyboard + kCCImplementsKeyUp = 1 << 0, + kCCImplementsKeyDown = 1 << 1, + kCCImplementsFlagsChanged = 1 << 2, +}; + + +typedef struct _listEntry +{ + struct _listEntry *prev, *next; + id delegate; + NSInteger priority; + NSUInteger flags; +} tListEntry; + + +#if CC_DIRECTOR_MAC_USE_DISPLAY_LINK_THREAD + +#define QUEUE_EVENT_MAX 128 +struct _eventQueue { + SEL selector; + NSEvent *event; +}; + +static struct _eventQueue eventQueue[QUEUE_EVENT_MAX]; +static int eventQueueCount; + +#endif // CC_DIRECTOR_MAC_USE_DISPLAY_LINK_THREAD + + +@implementation CCEventDispatcher + +@synthesize dispatchEvents=dispatchEvents_; + + ++(CCEventDispatcher*) sharedDispatcher +{ + @synchronized(self) { + if (sharedDispatcher == nil) + sharedDispatcher = [[self alloc] init]; // assignment not done here + } + return sharedDispatcher; +} + ++(id) allocWithZone:(NSZone *)zone +{ + @synchronized(self) { + NSAssert(sharedDispatcher == nil, @"Attempted to allocate a second instance of a singleton."); + return [super allocWithZone:zone]; + } + return nil; // on subsequent allocation attempts return nil +} + +-(id) init +{ + if( (self = [super init]) ) + { + // events enabled by default + dispatchEvents_ = YES; + + // delegates + keyboardDelegates_ = NULL; + mouseDelegates_ = NULL; + touchDelegates_ = NULL; + +#if CC_DIRECTOR_MAC_USE_DISPLAY_LINK_THREAD + eventQueueCount = 0; +#endif + } + + return self; +} + +- (void) dealloc +{ + [super dealloc]; +} + +#pragma mark CCEventDispatcher - add / remove delegates + +-(void) addDelegate:(id)delegate priority:(NSInteger)priority flags:(NSUInteger)flags list:(tListEntry**)list +{ + tListEntry *listElement = malloc( sizeof(*listElement) ); + + listElement->delegate = [delegate retain]; + listElement->priority = priority; + listElement->flags = flags; + listElement->next = listElement->prev = NULL; + + // empty list ? + if( ! *list ) { + DL_APPEND( *list, listElement ); + + } else { + BOOL added = NO; + + for( tListEntry *elem = *list; elem ; elem = elem->next ) { + if( priority < elem->priority ) { + + if( elem == *list ) + DL_PREPEND(*list, listElement); + else { + listElement->next = elem; + listElement->prev = elem->prev; + + elem->prev->next = listElement; + elem->prev = listElement; + } + + added = YES; + break; + } + } + + // Not added? priority has the higher value. Append it. + if( !added ) + DL_APPEND(*list, listElement); + } +} + +-(void) removeDelegate:(id)delegate fromList:(tListEntry**)list +{ + tListEntry *entry, *tmp; + + // updates with priority < 0 + DL_FOREACH_SAFE( *list, entry, tmp ) { + if( entry->delegate == delegate ) { + DL_DELETE( *list, entry ); + [delegate release]; + free(entry); + break; + } + } +} + +-(void) removeAllDelegatesFromList:(tListEntry**)list +{ + tListEntry *entry, *tmp; + + DL_FOREACH_SAFE( *list, entry, tmp ) { + DL_DELETE( *list, entry ); + free(entry); + } +} + + +-(void) addMouseDelegate:(id) delegate priority:(NSInteger)priority +{ + NSUInteger flags = 0; + + flags |= ( [delegate respondsToSelector:@selector(ccMouseDown:)] ? kCCImplementsMouseDown : 0 ); + flags |= ( [delegate respondsToSelector:@selector(ccMouseDragged:)] ? kCCImplementsMouseDragged : 0 ); + flags |= ( [delegate respondsToSelector:@selector(ccMouseMoved:)] ? kCCImplementsMouseMoved : 0 ); + flags |= ( [delegate respondsToSelector:@selector(ccMouseUp:)] ? kCCImplementsMouseUp : 0 ); + + flags |= ( [delegate respondsToSelector:@selector(ccRightMouseDown:)] ? kCCImplementsRightMouseDown : 0 ); + flags |= ( [delegate respondsToSelector:@selector(ccRightMouseDragged:)] ? kCCImplementsRightMouseDragged : 0 ); + flags |= ( [delegate respondsToSelector:@selector(ccRightMouseUp:)] ? kCCImplementsRightMouseUp : 0 ); + + flags |= ( [delegate respondsToSelector:@selector(ccOtherMouseDown:)] ? kCCImplementsOtherMouseDown : 0 ); + flags |= ( [delegate respondsToSelector:@selector(ccOtherMouseDragged:)] ? kCCImplementsOtherMouseDragged : 0 ); + flags |= ( [delegate respondsToSelector:@selector(ccOtherMouseUp:)] ? kCCImplementsOtherMouseUp : 0 ); + + flags |= ( [delegate respondsToSelector:@selector(ccMouseEntered:)] ? kCCImplementsMouseEntered : 0 ); + flags |= ( [delegate respondsToSelector:@selector(ccMouseExited:)] ? kCCImplementsMouseExited : 0 ); + + flags |= ( [delegate respondsToSelector:@selector(ccScrollWheel:)] ? kCCImplementsScrollWheel : 0 ); + + [self addDelegate:delegate priority:priority flags:flags list:&mouseDelegates_]; +} + +-(void) removeMouseDelegate:(id) delegate +{ + [self removeDelegate:delegate fromList:&mouseDelegates_]; +} + +-(void) removeAllMouseDelegates +{ + [self removeAllDelegatesFromList:&mouseDelegates_]; +} + +-(void) addKeyboardDelegate:(id) delegate priority:(NSInteger)priority +{ + NSUInteger flags = 0; + + flags |= ( [delegate respondsToSelector:@selector(ccKeyUp:)] ? kCCImplementsKeyUp : 0 ); + flags |= ( [delegate respondsToSelector:@selector(ccKeyDown:)] ? kCCImplementsKeyDown : 0 ); + flags |= ( [delegate respondsToSelector:@selector(ccFlagsChanged:)] ? kCCImplementsFlagsChanged : 0 ); + + [self addDelegate:delegate priority:priority flags:flags list:&keyboardDelegates_]; +} + +-(void) removeKeyboardDelegate:(id) delegate +{ + [self removeDelegate:delegate fromList:&keyboardDelegates_]; +} + +-(void) removeAllKeyboardDelegates +{ + [self removeAllDelegatesFromList:&keyboardDelegates_]; +} + +-(void) addTouchDelegate:(id) delegate priority:(NSInteger)priority +{ + NSUInteger flags = 0; + + flags |= ( [delegate respondsToSelector:@selector(ccTouchesBeganWithEvent:)] ? kCCImplementsTouchesBegan : 0 ); + flags |= ( [delegate respondsToSelector:@selector(ccTouchesMovedWithEvent:)] ? kCCImplementsTouchesMoved : 0 ); + flags |= ( [delegate respondsToSelector:@selector(ccTouchesEndedWithEvent:)] ? kCCImplementsTouchesEnded : 0 ); + flags |= ( [delegate respondsToSelector:@selector(ccTouchesCancelledWithEvent:)] ? kCCImplementsTouchesCancelled : 0 ); + + [self addDelegate:delegate priority:priority flags:flags list:&touchDelegates_]; +} + +-(void) removeTouchDelegate:(id) delegate +{ + [self removeDelegate:delegate fromList:&touchDelegates_]; +} + +-(void) removeAllTouchDelegates +{ + [self removeAllDelegatesFromList:&touchDelegates_]; +} + + +#pragma mark CCEventDispatcher - Mouse events +// +// Mouse events +// + +// +// Left +// +- (void)mouseDown:(NSEvent *)event +{ + if( dispatchEvents_ ) { + tListEntry *entry, *tmp; + + DL_FOREACH_SAFE( mouseDelegates_, entry, tmp ) { + if ( entry->flags & kCCImplementsMouseDown ) { + void *swallows = [entry->delegate performSelector:@selector(ccMouseDown:) withObject:event]; + if( swallows ) + break; + } + } + } +} + +- (void)mouseMoved:(NSEvent *)event +{ + if( dispatchEvents_ ) { + tListEntry *entry, *tmp; + + DL_FOREACH_SAFE( mouseDelegates_, entry, tmp ) { + if ( entry->flags & kCCImplementsMouseMoved ) { + void *swallows = [entry->delegate performSelector:@selector(ccMouseMoved:) withObject:event]; + if( swallows ) + break; + } + } + } +} + +- (void)mouseDragged:(NSEvent *)event +{ + if( dispatchEvents_ ) { + tListEntry *entry, *tmp; + + DL_FOREACH_SAFE( mouseDelegates_, entry, tmp ) { + if ( entry->flags & kCCImplementsMouseDragged ) { + void *swallows = [entry->delegate performSelector:@selector(ccMouseDragged:) withObject:event]; + if( swallows ) + break; + } + } + } +} + +- (void)mouseUp:(NSEvent *)event +{ + if( dispatchEvents_ ) { + tListEntry *entry, *tmp; + + DL_FOREACH_SAFE( mouseDelegates_, entry, tmp ) { + if ( entry->flags & kCCImplementsMouseUp ) { + void *swallows = [entry->delegate performSelector:@selector(ccMouseUp:) withObject:event]; + if( swallows ) + break; + } + } + } +} + +// +// Mouse Right +// +- (void)rightMouseDown:(NSEvent *)event +{ + if( dispatchEvents_ ) { + tListEntry *entry, *tmp; + + DL_FOREACH_SAFE( mouseDelegates_, entry, tmp ) { + if ( entry->flags & kCCImplementsRightMouseDown ) { + void *swallows = [entry->delegate performSelector:@selector(ccRightMouseDown:) withObject:event]; + if( swallows ) + break; + } + } + } +} + +- (void)rightMouseDragged:(NSEvent *)event +{ + if( dispatchEvents_ ) { + tListEntry *entry, *tmp; + + DL_FOREACH_SAFE( mouseDelegates_, entry, tmp ) { + if ( entry->flags & kCCImplementsRightMouseDragged ) { + void *swallows = [entry->delegate performSelector:@selector(ccRightMouseDragged:) withObject:event]; + if( swallows ) + break; + } + } + } +} + +- (void)rightMouseUp:(NSEvent *)event +{ + if( dispatchEvents_ ) { + tListEntry *entry, *tmp; + + DL_FOREACH_SAFE( mouseDelegates_, entry, tmp ) { + if ( entry->flags & kCCImplementsRightMouseUp ) { + void *swallows = [entry->delegate performSelector:@selector(ccRightMouseUp:) withObject:event]; + if( swallows ) + break; + } + } + } +} + +// +// Mouse Other +// +- (void)otherMouseDown:(NSEvent *)event +{ + if( dispatchEvents_ ) { + tListEntry *entry, *tmp; + + DL_FOREACH_SAFE( mouseDelegates_, entry, tmp ) { + if ( entry->flags & kCCImplementsOtherMouseDown ) { + void *swallows = [entry->delegate performSelector:@selector(ccOtherMouseDown:) withObject:event]; + if( swallows ) + break; + } + } + } +} + +- (void)otherMouseDragged:(NSEvent *)event +{ + if( dispatchEvents_ ) { + tListEntry *entry, *tmp; + + DL_FOREACH_SAFE( mouseDelegates_, entry, tmp ) { + if ( entry->flags & kCCImplementsOtherMouseDragged ) { + void *swallows = [entry->delegate performSelector:@selector(ccOtherMouseDragged:) withObject:event]; + if( swallows ) + break; + } + } + } +} + +- (void)otherMouseUp:(NSEvent *)event +{ + if( dispatchEvents_ ) { + tListEntry *entry, *tmp; + + DL_FOREACH_SAFE( mouseDelegates_, entry, tmp ) { + if ( entry->flags & kCCImplementsOtherMouseUp ) { + void *swallows = [entry->delegate performSelector:@selector(ccOtherMouseUp:) withObject:event]; + if( swallows ) + break; + } + } + } +} + +// +// Scroll Wheel +// +- (void)scrollWheel:(NSEvent *)event +{ + if( dispatchEvents_ ) { + tListEntry *entry, *tmp; + + DL_FOREACH_SAFE( mouseDelegates_, entry, tmp ) { + if ( entry->flags & kCCImplementsScrollWheel ) { + void *swallows = [entry->delegate performSelector:@selector(ccScrollWheel:) withObject:event]; + if( swallows ) + break; + } + } + } +} + +// +// Mouse enter / exit +- (void)mouseExited:(NSEvent *)event +{ + if( dispatchEvents_ ) { + tListEntry *entry, *tmp; + + DL_FOREACH_SAFE( mouseDelegates_, entry, tmp ) { + if ( entry->flags & kCCImplementsMouseEntered ) { + void *swallows = [entry->delegate performSelector:@selector(ccMouseEntered:) withObject:event]; + if( swallows ) + break; + } + } + } +} + +- (void)mouseEntered:(NSEvent *)event +{ + if( dispatchEvents_ ) { + tListEntry *entry, *tmp; + + DL_FOREACH_SAFE( mouseDelegates_, entry, tmp ) { + if ( entry->flags & kCCImplementsMouseExited) { + void *swallows = [entry->delegate performSelector:@selector(ccMouseExited:) withObject:event]; + if( swallows ) + break; + } + } + } +} + + +#pragma mark CCEventDispatcher - Keyboard events + +// Keyboard events +- (void)keyDown:(NSEvent *)event +{ + if( dispatchEvents_ ) { + tListEntry *entry, *tmp; + + DL_FOREACH_SAFE( keyboardDelegates_, entry, tmp ) { + if ( entry->flags & kCCImplementsKeyDown ) { + void *swallows = [entry->delegate performSelector:@selector(ccKeyDown:) withObject:event]; + if( swallows ) + break; + } + } + } +} + +- (void)keyUp:(NSEvent *)event +{ + if( dispatchEvents_ ) { + tListEntry *entry, *tmp; + + DL_FOREACH_SAFE( keyboardDelegates_, entry, tmp ) { + if ( entry->flags & kCCImplementsKeyUp ) { + void *swallows = [entry->delegate performSelector:@selector(ccKeyUp:) withObject:event]; + if( swallows ) + break; + } + } + } +} + +- (void)flagsChanged:(NSEvent *)event +{ + if( dispatchEvents_ ) { + tListEntry *entry, *tmp; + + DL_FOREACH_SAFE( keyboardDelegates_, entry, tmp ) { + if ( entry->flags & kCCImplementsFlagsChanged ) { + void *swallows = [entry->delegate performSelector:@selector(ccFlagsChanged:) withObject:event]; + if( swallows ) + break; + } + } + } +} + + +#pragma mark CCEventDispatcher - Touch events + +- (void)touchesBeganWithEvent:(NSEvent *)event +{ + if( dispatchEvents_ ) { + tListEntry *entry, *tmp; + + DL_FOREACH_SAFE( touchDelegates_, entry, tmp ) { + if ( entry->flags & kCCImplementsTouchesBegan) { + void *swallows = [entry->delegate performSelector:@selector(ccTouchesBeganWithEvent:) withObject:event]; + if( swallows ) + break; + } + } + } +} + +- (void)touchesMovedWithEvent:(NSEvent *)event +{ + if( dispatchEvents_ ) { + tListEntry *entry, *tmp; + + DL_FOREACH_SAFE( touchDelegates_, entry, tmp ) { + if ( entry->flags & kCCImplementsTouchesMoved) { + void *swallows = [entry->delegate performSelector:@selector(ccTouchesMovedWithEvent:) withObject:event]; + if( swallows ) + break; + } + } + } +} + +- (void)touchesEndedWithEvent:(NSEvent *)event +{ + if( dispatchEvents_ ) { + tListEntry *entry, *tmp; + + DL_FOREACH_SAFE( touchDelegates_, entry, tmp ) { + if ( entry->flags & kCCImplementsTouchesEnded) { + void *swallows = [entry->delegate performSelector:@selector(ccTouchesEndedWithEvent:) withObject:event]; + if( swallows ) + break; + } + } + } +} + +- (void)touchesCancelledWithEvent:(NSEvent *)event +{ + if( dispatchEvents_ ) { + tListEntry *entry, *tmp; + + DL_FOREACH_SAFE( touchDelegates_, entry, tmp ) { + if ( entry->flags & kCCImplementsTouchesCancelled) { + void *swallows = [entry->delegate performSelector:@selector(ccTouchesCancelledWithEvent:) withObject:event]; + if( swallows ) + break; + } + } + } +} + + +#pragma mark CCEventDispatcher - queue events + +#if CC_DIRECTOR_MAC_USE_DISPLAY_LINK_THREAD +-(void) queueEvent:(NSEvent*)event selector:(SEL)selector +{ + NSAssert( eventQueueCount < QUEUE_EVENT_MAX, @"CCEventDispatcher: recompile. Increment QUEUE_EVENT_MAX value"); + + @synchronized (self) { + eventQueue[eventQueueCount].selector = selector; + eventQueue[eventQueueCount].event = [event copy]; + + eventQueueCount++; + } +} + +-(void) dispatchQueuedEvents +{ + @synchronized (self) { + for( int i=0; i < eventQueueCount; i++ ) { + SEL sel = eventQueue[i].selector; + NSEvent *event = eventQueue[i].event; + + [self performSelector:sel withObject:event]; + + [event release]; + } + + eventQueueCount = 0; + } +} +#endif // CC_DIRECTOR_MAC_USE_DISPLAY_LINK_THREAD + + +@end + +#endif // __MAC_OS_X_VERSION_MAX_ALLOWED diff --git a/libs/cocos2d/Platforms/Mac/MacGLView.h b/libs/cocos2d/Platforms/Mac/MacGLView.h new file mode 100755 index 0000000..8099273 --- /dev/null +++ b/libs/cocos2d/Platforms/Mac/MacGLView.h @@ -0,0 +1,89 @@ +/* + * cocos2d for iPhone: http://www.cocos2d-iphone.org + * + * Copyright (c) 2010 Ricardo Quesada + * Copyright (c) 2011 Zynga Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// Only compile this code on Mac. These files should not be included on your iOS project. +// But in case they are included, it won't be compiled. +#import +#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED +#elif defined(__MAC_OS_X_VERSION_MAX_ALLOWED) + +#import + +#import "../../ccConfig.h" + +//PROTOCOLS: + +@protocol MacEventDelegate +// Mouse +- (void)mouseDown:(NSEvent *)theEvent; +- (void)mouseUp:(NSEvent *)theEvent; +- (void)mouseMoved:(NSEvent *)theEvent; +- (void)mouseDragged:(NSEvent *)theEvent; +- (void)rightMouseDown:(NSEvent*)event; +- (void)rightMouseDragged:(NSEvent*)event; +- (void)rightMouseUp:(NSEvent*)event; +- (void)otherMouseDown:(NSEvent*)event; +- (void)otherMouseDragged:(NSEvent*)event; +- (void)otherMouseUp:(NSEvent*)event; +- (void)scrollWheel:(NSEvent *)theEvent; +- (void)mouseEntered:(NSEvent *)theEvent; +- (void)mouseExited:(NSEvent *)theEvent; + + +// Keyboard +- (void)keyDown:(NSEvent *)theEvent; +- (void)keyUp:(NSEvent *)theEvent; +- (void)flagsChanged:(NSEvent *)theEvent; + +// Touches +- (void)touchesBeganWithEvent:(NSEvent *)event; +- (void)touchesMovedWithEvent:(NSEvent *)event; +- (void)touchesEndedWithEvent:(NSEvent *)event; +- (void)touchesCancelledWithEvent:(NSEvent *)event; + +#if CC_DIRECTOR_MAC_USE_DISPLAY_LINK_THREAD +- (void)queueEvent:(NSEvent*)event selector:(SEL)selector; +#endif + +@end + +/** MacGLView + + Only available for Mac OS X + */ +@interface MacGLView : NSOpenGLView { + id eventDelegate_; +} + +@property (nonatomic, readwrite, assign) id eventDelegate; + +// initializes the MacGLView with a frame rect and an OpenGL context +- (id) initWithFrame:(NSRect)frameRect shareContext:(NSOpenGLContext*)context; + +// private ++(void) load_; +@end + +#endif // __MAC_OS_X_VERSION_MAX_ALLOWED \ No newline at end of file diff --git a/libs/cocos2d/Platforms/Mac/MacGLView.m b/libs/cocos2d/Platforms/Mac/MacGLView.m new file mode 100755 index 0000000..a041dc8 --- /dev/null +++ b/libs/cocos2d/Platforms/Mac/MacGLView.m @@ -0,0 +1,242 @@ +/* + * cocos2d for iPhone: http://www.cocos2d-iphone.org + * + * Copyright (c) 2010 Ricardo Quesada + * Copyright (c) 2011 Zynga Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +/* + * Idea of subclassing NSOpenGLView was taken from "TextureUpload" Apple's sample + */ + +// Only compile this code on Mac. These files should not be included on your iOS project. +// But in case they are included, it won't be compiled. +#import +#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED +#elif defined(__MAC_OS_X_VERSION_MAX_ALLOWED) + +#import "MacGLView.h" +#import + +#import "CCDirectorMac.h" +#import "../../ccConfig.h" + + +@implementation MacGLView + +@synthesize eventDelegate = eventDelegate_; + ++(void) load_ +{ + NSLog(@"%@ loaded", self); +} + +- (id) initWithFrame:(NSRect)frameRect +{ + self = [self initWithFrame:frameRect shareContext:nil]; + return self; +} + +- (id) initWithFrame:(NSRect)frameRect shareContext:(NSOpenGLContext*)context +{ + NSOpenGLPixelFormatAttribute attribs[] = + { + NSOpenGLPFAAccelerated, + NSOpenGLPFANoRecovery, + NSOpenGLPFADoubleBuffer, + NSOpenGLPFADepthSize, 24, + + 0 + }; + + NSOpenGLPixelFormat *pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attribs]; + + if (!pixelFormat) + NSLog(@"No OpenGL pixel format"); + + if( (self = [super initWithFrame:frameRect pixelFormat:[pixelFormat autorelease]]) ) { + + if( context ) + [self setOpenGLContext:context]; + + // Synchronize buffer swaps with vertical refresh rate + GLint swapInt = 1; + [[self openGLContext] setValues:&swapInt forParameter:NSOpenGLCPSwapInterval]; + +// GLint order = -1; +// [[self openGLContext] setValues:&order forParameter:NSOpenGLCPSurfaceOrder]; + + // event delegate + eventDelegate_ = nil; + } + + return self; +} + +- (void) reshape +{ + // We draw on a secondary thread through the display link + // When resizing the view, -reshape is called automatically on the main thread + // Add a mutex around to avoid the threads accessing the context simultaneously when resizing + CGLLockContext([[self openGLContext] CGLContextObj]); + + NSRect rect = [self bounds]; + + CCDirector *director = [CCDirector sharedDirector]; + [director reshapeProjection: NSSizeToCGSize(rect.size) ]; + + // avoid flicker + [director drawScene]; +// [self setNeedsDisplay:YES]; + + CGLUnlockContext([[self openGLContext] CGLContextObj]); +} + +- (void) dealloc +{ + + [super dealloc]; +} + +#if CC_DIRECTOR_MAC_USE_DISPLAY_LINK_THREAD +#define DISPATCH_EVENT(__event__, __selector__) [eventDelegate_ queueEvent:__event__ selector:__selector__]; +#else +#define DISPATCH_EVENT(__event__, __selector__) \ + id obj = eventDelegate_; \ + [obj performSelector:__selector__ \ + onThread:[(CCDirectorMac*)[CCDirector sharedDirector] runningThread] \ + withObject:__event__ \ + waitUntilDone:NO]; +#endif + +#pragma mark MacGLView - Mouse events +- (void)mouseDown:(NSEvent *)theEvent +{ + DISPATCH_EVENT(theEvent, _cmd); +} + +- (void)mouseMoved:(NSEvent *)theEvent +{ + DISPATCH_EVENT(theEvent, _cmd); +} + +- (void)mouseDragged:(NSEvent *)theEvent +{ + DISPATCH_EVENT(theEvent, _cmd); +} + +- (void)mouseUp:(NSEvent *)theEvent +{ + DISPATCH_EVENT(theEvent, _cmd); +} + +- (void)rightMouseDown:(NSEvent *)theEvent { + DISPATCH_EVENT(theEvent, _cmd); +} + +- (void)rightMouseDragged:(NSEvent *)theEvent { + DISPATCH_EVENT(theEvent, _cmd); +} + +- (void)rightMouseUp:(NSEvent *)theEvent { + DISPATCH_EVENT(theEvent, _cmd); +} + +- (void)otherMouseDown:(NSEvent *)theEvent { + DISPATCH_EVENT(theEvent, _cmd); +} + +- (void)otherMouseDragged:(NSEvent *)theEvent { + DISPATCH_EVENT(theEvent, _cmd); +} + +- (void)otherMouseUp:(NSEvent *)theEvent { + DISPATCH_EVENT(theEvent, _cmd); +} + +- (void)mouseEntered:(NSEvent *)theEvent { + DISPATCH_EVENT(theEvent, _cmd); +} + +- (void)mouseExited:(NSEvent *)theEvent { + DISPATCH_EVENT(theEvent, _cmd); +} + +-(void) scrollWheel:(NSEvent *)theEvent { + DISPATCH_EVENT(theEvent, _cmd); +} + +#pragma mark MacGLView - Key events + +-(BOOL) becomeFirstResponder +{ + return YES; +} + +-(BOOL) acceptsFirstResponder +{ + return YES; +} + +-(BOOL) resignFirstResponder +{ + return YES; +} + +- (void)keyDown:(NSEvent *)theEvent +{ + DISPATCH_EVENT(theEvent, _cmd); +} + +- (void)keyUp:(NSEvent *)theEvent +{ + DISPATCH_EVENT(theEvent, _cmd); +} + +- (void)flagsChanged:(NSEvent *)theEvent +{ + DISPATCH_EVENT(theEvent, _cmd); +} + +#pragma mark MacGLView - Touch events +- (void)touchesBeganWithEvent:(NSEvent *)theEvent +{ + DISPATCH_EVENT(theEvent, _cmd); +} + +- (void)touchesMovedWithEvent:(NSEvent *)theEvent +{ + DISPATCH_EVENT(theEvent, _cmd); +} + +- (void)touchesEndedWithEvent:(NSEvent *)theEvent +{ + DISPATCH_EVENT(theEvent, _cmd); +} + +- (void)touchesCancelledWithEvent:(NSEvent *)theEvent +{ + DISPATCH_EVENT(theEvent, _cmd); +} + +@end + +#endif // __MAC_OS_X_VERSION_MAX_ALLOWED diff --git a/libs/cocos2d/Platforms/Mac/MacWindow.h b/libs/cocos2d/Platforms/Mac/MacWindow.h new file mode 100755 index 0000000..716fe9b --- /dev/null +++ b/libs/cocos2d/Platforms/Mac/MacWindow.h @@ -0,0 +1,42 @@ +/* + * cocos2d for iPhone: http://www.cocos2d-iphone.org + * + * Copyright (c) 2010 Ricardo Quesada + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// Only compile this code on Mac. These files should not be included on your iOS project. +// But in case they are included, it won't be compiled. +#import +#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED +#elif defined(__MAC_OS_X_VERSION_MAX_ALLOWED) + +#import + + +@interface MacWindow : NSWindow +{ +} +- (id) initWithFrame:(NSRect)frame fullscreen:(BOOL)fullscreen; + +@end + + +#endif // __MAC_OS_X_VERSION_MAX_ALLOWED \ No newline at end of file diff --git a/libs/cocos2d/Platforms/Mac/MacWindow.m b/libs/cocos2d/Platforms/Mac/MacWindow.m new file mode 100755 index 0000000..28736a3 --- /dev/null +++ b/libs/cocos2d/Platforms/Mac/MacWindow.m @@ -0,0 +1,70 @@ +/* + * cocos2d for iPhone: http://www.cocos2d-iphone.org + * + * Copyright (c) 2010 Ricardo Quesada + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// Only compile this code on Mac. These files should not be included on your iOS project. +// But in case they are included, it won't be compiled. +#import +#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED +#elif defined(__MAC_OS_X_VERSION_MAX_ALLOWED) + +#import "MacWindow.h" + + +@implementation MacWindow + +- (id) initWithFrame:(NSRect)frame fullscreen:(BOOL)fullscreen +{ + int styleMask = fullscreen ? NSBackingStoreBuffered : ( NSTitledWindowMask | NSClosableWindowMask ); + self = [self initWithContentRect:frame + styleMask:styleMask + backing:NSBackingStoreBuffered + defer:YES]; + + if (self != nil) + { + if(fullscreen) + { + [self setLevel:NSMainMenuWindowLevel+1]; + [self setHidesOnDeactivate:YES]; + [self setHasShadow:NO]; + } + + [self setAcceptsMouseMovedEvents:NO]; + [self setOpaque:YES]; + } + return self; +} + +- (BOOL) canBecomeKeyWindow +{ + return YES; +} + +- (BOOL) canBecomeMainWindow +{ + return YES; +} +@end + +#endif // __MAC_OS_X_VERSION_MAX_ALLOWED diff --git a/libs/cocos2d/Platforms/iOS/CCDirectorIOS.h b/libs/cocos2d/Platforms/iOS/CCDirectorIOS.h new file mode 100755 index 0000000..1c264e4 --- /dev/null +++ b/libs/cocos2d/Platforms/iOS/CCDirectorIOS.h @@ -0,0 +1,255 @@ +/* + * cocos2d for iPhone: http://www.cocos2d-iphone.org + * + * Copyright (c) 2008-2010 Ricardo Quesada + * Copyright (c) 2011 Zynga Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + + +// Only compile this code on iOS. These files should NOT be included on your Mac project. +// But in case they are included, it won't be compiled. +#import +#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED + +#import "../../CCDirector.h" + +/** @typedef ccDeviceOrientation + Possible device orientations + */ +typedef enum { + /// Device oriented vertically, home button on the bottom + kCCDeviceOrientationPortrait = UIDeviceOrientationPortrait, + /// Device oriented vertically, home button on the top + kCCDeviceOrientationPortraitUpsideDown = UIDeviceOrientationPortraitUpsideDown, + /// Device oriented horizontally, home button on the right + kCCDeviceOrientationLandscapeLeft = UIDeviceOrientationLandscapeLeft, + /// Device oriented horizontally, home button on the left + kCCDeviceOrientationLandscapeRight = UIDeviceOrientationLandscapeRight, + + // Backward compatibility stuff + CCDeviceOrientationPortrait = kCCDeviceOrientationPortrait, + CCDeviceOrientationPortraitUpsideDown = kCCDeviceOrientationPortraitUpsideDown, + CCDeviceOrientationLandscapeLeft = kCCDeviceOrientationLandscapeLeft, + CCDeviceOrientationLandscapeRight = kCCDeviceOrientationLandscapeRight, +} ccDeviceOrientation; + +/** @typedef ccDirectorType + Possible Director Types. + @since v0.8.2 + */ +typedef enum { + /** Will use a Director that triggers the main loop from an NSTimer object + * + * Features and Limitations: + * - Integrates OK with UIKit objects + * - It the slowest director + * - The invertal update is customizable from 1 to 60 + */ + kCCDirectorTypeNSTimer, + + /** will use a Director that triggers the main loop from a custom main loop. + * + * Features and Limitations: + * - Faster than NSTimer Director + * - It doesn't integrate well with UIKit objecgts + * - The interval update can't be customizable + */ + kCCDirectorTypeMainLoop, + + /** Will use a Director that triggers the main loop from a thread, but the main loop will be executed on the main thread. + * + * Features and Limitations: + * - Faster than NSTimer Director + * - It doesn't integrate well with UIKit objecgts + * - The interval update can't be customizable + */ + kCCDirectorTypeThreadMainLoop, + + /** Will use a Director that synchronizes timers with the refresh rate of the display. + * + * Features and Limitations: + * - Faster than NSTimer Director + * - Only available on 3.1+ + * - Scheduled timers & drawing are synchronizes with the refresh rate of the display + * - Integrates OK with UIKit objects + * - The interval update can be 1/60, 1/30, 1/15 + */ + kCCDirectorTypeDisplayLink, + + /** Default director is the NSTimer directory */ + kCCDirectorTypeDefault = kCCDirectorTypeNSTimer, + + // backward compatibility stuff + CCDirectorTypeNSTimer = kCCDirectorTypeNSTimer, + CCDirectorTypeMainLoop = kCCDirectorTypeMainLoop, + CCDirectorTypeThreadMainLoop = kCCDirectorTypeThreadMainLoop, + CCDirectorTypeDisplayLink = kCCDirectorTypeDisplayLink, + CCDirectorTypeDefault = kCCDirectorTypeDefault, + + +} ccDirectorType; + +/** CCDirector extensions for iPhone + */ +@interface CCDirector (iOSExtension) + +// rotates the screen if an orientation differnent than Portrait is used +-(void) applyOrientation; + +/** Sets the device orientation. + If the orientation is going to be controlled by an UIViewController, then the orientation should be Portrait + */ +-(void) setDeviceOrientation:(ccDeviceOrientation)orientation; + +/** returns the device orientation */ +-(ccDeviceOrientation) deviceOrientation; + +/** The size in pixels of the surface. It could be different than the screen size. + High-res devices might have a higher surface size than the screen size. + In non High-res device the contentScale will be emulated. + + The recommend way to enable Retina Display is by using the "enableRetinaDisplay:(BOOL)enabled" method. + + @since v0.99.4 + */ +-(void) setContentScaleFactor:(CGFloat)scaleFactor; + +/** Will enable Retina Display on devices that supports it. + It will enable Retina Display on iPhone4 and iPod Touch 4. + It will return YES, if it could enabled it, otherwise it will return NO. + + This is the recommened way to enable Retina Display. + @since v0.99.5 + */ +-(BOOL) enableRetinaDisplay:(BOOL)yes; + + +/** returns the content scale factor */ +-(CGFloat) contentScaleFactor; +@end + +@interface CCDirector (iOSExtensionClassMethods) + +/** There are 4 types of Director. + - kCCDirectorTypeNSTimer (default) + - kCCDirectorTypeMainLoop + - kCCDirectorTypeThreadMainLoop + - kCCDirectorTypeDisplayLink + + Each Director has it's own benefits, limitations. + If you are using SDK 3.1 or newer it is recommed to use the DisplayLink director + + This method should be called before any other call to the director. + + It will return NO if the director type is kCCDirectorTypeDisplayLink and the running SDK is < 3.1. Otherwise it will return YES. + + @since v0.8.2 + */ ++(BOOL) setDirectorType:(ccDirectorType) directorType; +@end + +#pragma mark - +#pragma mark CCDirectorIOS + +/** CCDirectorIOS: Base class of iOS directors + @since v0.99.5 + */ +@interface CCDirectorIOS : CCDirector +{ + /* orientation */ + ccDeviceOrientation deviceOrientation_; + + /* contentScaleFactor could be simulated */ + BOOL isContentScaleSupported_; + +} +@end + +/** FastDirector is a Director that triggers the main loop as fast as possible. + * + * Features and Limitations: + * - Faster than "normal" director + * - Consumes more battery than the "normal" director + * - It has some issues while using UIKit objects + */ +@interface CCDirectorFast : CCDirectorIOS +{ + BOOL isRunning; + + NSAutoreleasePool *autoreleasePool; +} +-(void) mainLoop; +@end + +/** ThreadedFastDirector is a Director that triggers the main loop from a thread. + * + * Features and Limitations: + * - Faster than "normal" director + * - Consumes more battery than the "normal" director + * - It can be used with UIKit objects + * + * @since v0.8.2 + */ +@interface CCDirectorFastThreaded : CCDirectorIOS +{ + BOOL isRunning; +} +-(void) mainLoop; +@end + +/** DisplayLinkDirector is a Director that synchronizes timers with the refresh rate of the display. + * + * Features and Limitations: + * - Only available on 3.1+ + * - Scheduled timers & drawing are synchronizes with the refresh rate of the display + * - Only supports animation intervals of 1/60 1/30 & 1/15 + * + * It is the recommended Director if the SDK is 3.1 or newer + * + * @since v0.8.2 + */ +@interface CCDirectorDisplayLink : CCDirectorIOS +{ + id displayLink; +} +-(void) mainLoop:(id)sender; +@end + +/** TimerDirector is a Director that calls the main loop from an NSTimer object + * + * Features and Limitations: + * - Integrates OK with UIKit objects + * - It the slowest director + * - The invertal update is customizable from 1 to 60 + * + * It is the default Director. + */ +@interface CCDirectorTimer : CCDirectorIOS +{ + NSTimer *animationTimer; +} +-(void) mainLoop; +@end + +// optimization. Should only be used to read it. Never to write it. +extern CGFloat __ccContentScaleFactor; + +#endif // __IPHONE_OS_VERSION_MAX_ALLOWED diff --git a/libs/cocos2d/Platforms/iOS/CCDirectorIOS.m b/libs/cocos2d/Platforms/iOS/CCDirectorIOS.m new file mode 100755 index 0000000..c483665 --- /dev/null +++ b/libs/cocos2d/Platforms/iOS/CCDirectorIOS.m @@ -0,0 +1,735 @@ +/* + * cocos2d for iPhone: http://www.cocos2d-iphone.org + * + * Copyright (c) 2010 Ricardo Quesada + * Copyright (c) 2011 Zynga Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +// Only compile this code on iOS. These files should NOT be included on your Mac project. +// But in case they are included, it won't be compiled. +#import +#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED + +#import + +// cocos2d imports +#import "CCDirectorIOS.h" +#import "CCTouchDelegateProtocol.h" +#import "CCTouchDispatcher.h" +#import "../../CCScheduler.h" +#import "../../CCActionManager.h" +#import "../../CCTextureCache.h" +#import "../../ccMacros.h" +#import "../../CCScene.h" + +// support imports +#import "glu.h" +#import "../../Support/OpenGL_Internal.h" +#import "../../Support/CGPointExtension.h" + +#import "CCLayer.h" + +#if CC_ENABLE_PROFILERS +#import "../../Support/CCProfiling.h" +#endif + + +#pragma mark - +#pragma mark Director - global variables (optimization) + +CGFloat __ccContentScaleFactor = 1; + +#pragma mark - +#pragma mark Director iOS + +@interface CCDirector () +-(void) setNextScene; +-(void) showFPS; +-(void) calculateDeltaTime; +@end + +@implementation CCDirector (iOSExtensionClassMethods) + ++(Class) defaultDirector +{ + return [CCDirectorTimer class]; +} + ++ (BOOL) setDirectorType:(ccDirectorType)type +{ + if( type == CCDirectorTypeDisplayLink ) { + NSString *reqSysVer = @"3.1"; + NSString *currSysVer = [[UIDevice currentDevice] systemVersion]; + + if([currSysVer compare:reqSysVer options:NSNumericSearch] == NSOrderedAscending) + return NO; + } + switch (type) { + case CCDirectorTypeNSTimer: + [CCDirectorTimer sharedDirector]; + break; + case CCDirectorTypeDisplayLink: + [CCDirectorDisplayLink sharedDirector]; + break; + case CCDirectorTypeMainLoop: + [CCDirectorFast sharedDirector]; + break; + case CCDirectorTypeThreadMainLoop: + [CCDirectorFastThreaded sharedDirector]; + break; + default: + NSAssert(NO,@"Unknown director type"); + } + + return YES; +} + +@end + + + +#pragma mark - +#pragma mark CCDirectorIOS + +@interface CCDirectorIOS () +-(void) updateContentScaleFactor; + +@end + +@implementation CCDirectorIOS + +- (id) init +{ + if( (self=[super init]) ) { + + // portrait mode default + deviceOrientation_ = CCDeviceOrientationPortrait; + + __ccContentScaleFactor = 1; + isContentScaleSupported_ = NO; + + // running thread is main thread on iOS + runningThread_ = [NSThread currentThread]; + } + + return self; +} + +- (void) dealloc +{ + [super dealloc]; +} + +// +// Draw the Scene +// +- (void) drawScene +{ + /* calculate "global" dt */ + [self calculateDeltaTime]; + + /* tick before glClear: issue #533 */ + if( ! isPaused_ ) { + [[CCScheduler sharedScheduler] tick: dt]; + } + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + /* to avoid flickr, nextScene MUST be here: after tick and before draw. + XXX: Which bug is this one. It seems that it can't be reproduced with v0.9 */ + if( nextScene_ ) + [self setNextScene]; + + glPushMatrix(); + + [self applyOrientation]; + + // By default enable VertexArray, ColorArray, TextureCoordArray and Texture2D + CC_ENABLE_DEFAULT_GL_STATES(); + + /* draw the scene */ + [runningScene_ visit]; + + /* draw the notification node */ + [notificationNode_ visit]; + + if( displayFPS_ ) + [self showFPS]; + +#if CC_ENABLE_PROFILERS + [self showProfilers]; +#endif + + CC_DISABLE_DEFAULT_GL_STATES(); + + glPopMatrix(); + + [openGLView_ swapBuffers]; +} + +-(void) setProjection:(ccDirectorProjection)projection +{ + CGSize size = winSizeInPixels_; + + switch (projection) { + case kCCDirectorProjection2D: + glViewport(0, 0, size.width, size.height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + ccglOrtho(0, size.width, 0, size.height, -1024 * CC_CONTENT_SCALE_FACTOR(), 1024 * CC_CONTENT_SCALE_FACTOR()); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + break; + + case kCCDirectorProjection3D: + { + float zeye = [self getZEye]; + + glViewport(0, 0, size.width, size.height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); +// gluPerspective(60, (GLfloat)size.width/size.height, zeye-size.height/2, zeye+size.height/2 ); + gluPerspective(60, (GLfloat)size.width/size.height, 0.5f, 1500); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + gluLookAt( size.width/2, size.height/2, zeye, + size.width/2, size.height/2, 0, + 0.0f, 1.0f, 0.0f); + break; + } + + case kCCDirectorProjectionCustom: + if( projectionDelegate_ ) + [projectionDelegate_ updateProjection]; + break; + + default: + CCLOG(@"cocos2d: Director: unrecognized projecgtion"); + break; + } + + projection_ = projection; +} + +#pragma mark Director Integration with a UIKit view + +-(void) setOpenGLView:(EAGLView *)view +{ + if( view != openGLView_ ) { + + [super setOpenGLView:view]; + + // set size + winSizeInPixels_ = CGSizeMake(winSizeInPoints_.width * __ccContentScaleFactor, winSizeInPoints_.height *__ccContentScaleFactor); + + if( __ccContentScaleFactor != 1 ) + [self updateContentScaleFactor]; + + CCTouchDispatcher *touchDispatcher = [CCTouchDispatcher sharedDispatcher]; + [openGLView_ setTouchDelegate: touchDispatcher]; + [touchDispatcher setDispatchEvents: YES]; + } +} + +#pragma mark Director - Retina Display + +-(CGFloat) contentScaleFactor +{ + return __ccContentScaleFactor; +} + +-(void) setContentScaleFactor:(CGFloat)scaleFactor +{ + if( scaleFactor != __ccContentScaleFactor ) { + + __ccContentScaleFactor = scaleFactor; + winSizeInPixels_ = CGSizeMake( winSizeInPoints_.width * scaleFactor, winSizeInPoints_.height * scaleFactor ); + + if( openGLView_ ) + [self updateContentScaleFactor]; + + // update projection + [self setProjection:projection_]; + } +} + +-(void) updateContentScaleFactor +{ + // Based on code snippet from: http://developer.apple.com/iphone/prerelease/library/snippets/sp2010/sp28.html + if ([openGLView_ respondsToSelector:@selector(setContentScaleFactor:)]) + { + [openGLView_ setContentScaleFactor: __ccContentScaleFactor]; + + isContentScaleSupported_ = YES; + } + else + CCLOG(@"cocos2d: 'setContentScaleFactor:' is not supported on this device"); +} + +-(BOOL) enableRetinaDisplay:(BOOL)enabled +{ + // Already enabled ? + if( enabled && __ccContentScaleFactor == 2 ) + return YES; + + // Already disabled + if( ! enabled && __ccContentScaleFactor == 1 ) + return YES; + + // setContentScaleFactor is not supported + if (! [openGLView_ respondsToSelector:@selector(setContentScaleFactor:)]) + return NO; + + // SD device + if ([[UIScreen mainScreen] scale] == 1.0) + return NO; + + float newScale = enabled ? 2 : 1; + [self setContentScaleFactor:newScale]; + + return YES; +} + +// overriden, don't call super +-(void) reshapeProjection:(CGSize)size +{ + winSizeInPoints_ = [openGLView_ bounds].size; + winSizeInPixels_ = CGSizeMake(winSizeInPoints_.width * __ccContentScaleFactor, winSizeInPoints_.height *__ccContentScaleFactor); + + [self setProjection:projection_]; +} + +#pragma mark Director Scene Landscape + +-(CGPoint)convertToGL:(CGPoint)uiPoint +{ + CGSize s = winSizeInPoints_; + float newY = s.height - uiPoint.y; + float newX = s.width - uiPoint.x; + + CGPoint ret = CGPointZero; + switch ( deviceOrientation_) { + case CCDeviceOrientationPortrait: + ret = ccp( uiPoint.x, newY ); + break; + case CCDeviceOrientationPortraitUpsideDown: + ret = ccp(newX, uiPoint.y); + break; + case CCDeviceOrientationLandscapeLeft: + ret.x = uiPoint.y; + ret.y = uiPoint.x; + break; + case CCDeviceOrientationLandscapeRight: + ret.x = newY; + ret.y = newX; + break; + } + return ret; +} + +-(CGPoint)convertToUI:(CGPoint)glPoint +{ + CGSize winSize = winSizeInPoints_; + int oppositeX = winSize.width - glPoint.x; + int oppositeY = winSize.height - glPoint.y; + CGPoint uiPoint = CGPointZero; + switch ( deviceOrientation_) { + case CCDeviceOrientationPortrait: + uiPoint = ccp(glPoint.x, oppositeY); + break; + case CCDeviceOrientationPortraitUpsideDown: + uiPoint = ccp(oppositeX, glPoint.y); + break; + case CCDeviceOrientationLandscapeLeft: + uiPoint = ccp(glPoint.y, glPoint.x); + break; + case CCDeviceOrientationLandscapeRight: + // Can't use oppositeX/Y because x/y are flipped + uiPoint = ccp(winSize.width-glPoint.y, winSize.height-glPoint.x); + break; + } + return uiPoint; +} + +// get the current size of the glview +-(CGSize) winSize +{ + CGSize s = winSizeInPoints_; + + if( deviceOrientation_ == CCDeviceOrientationLandscapeLeft || deviceOrientation_ == CCDeviceOrientationLandscapeRight ) { + // swap x,y in landscape mode + CGSize tmp = s; + s.width = tmp.height; + s.height = tmp.width; + } + return s; +} + +-(CGSize) winSizeInPixels +{ + CGSize s = [self winSize]; + + s.width *= CC_CONTENT_SCALE_FACTOR(); + s.height *= CC_CONTENT_SCALE_FACTOR(); + + return s; +} + +-(ccDeviceOrientation) deviceOrientation +{ + return deviceOrientation_; +} + +- (void) setDeviceOrientation:(ccDeviceOrientation) orientation +{ + if( deviceOrientation_ != orientation ) { + deviceOrientation_ = orientation; + switch( deviceOrientation_) { + case CCDeviceOrientationPortrait: + [[UIApplication sharedApplication] setStatusBarOrientation: UIInterfaceOrientationPortrait animated:NO]; + break; + case CCDeviceOrientationPortraitUpsideDown: + [[UIApplication sharedApplication] setStatusBarOrientation: UIInterfaceOrientationPortraitUpsideDown animated:NO]; + break; + case CCDeviceOrientationLandscapeLeft: + [[UIApplication sharedApplication] setStatusBarOrientation: UIInterfaceOrientationLandscapeRight animated:NO]; + break; + case CCDeviceOrientationLandscapeRight: + [[UIApplication sharedApplication] setStatusBarOrientation: UIInterfaceOrientationLandscapeLeft animated:NO]; + break; + default: + NSLog(@"Director: Unknown device orientation"); + break; + } + } +} + +-(void) applyOrientation +{ + CGSize s = winSizeInPixels_; + float w = s.width / 2; + float h = s.height / 2; + + // XXX it's using hardcoded values. + // What if the the screen size changes in the future? + switch ( deviceOrientation_ ) { + case CCDeviceOrientationPortrait: + // nothing + break; + case CCDeviceOrientationPortraitUpsideDown: + // upside down + glTranslatef(w,h,0); + glRotatef(180,0,0,1); + glTranslatef(-w,-h,0); + break; + case CCDeviceOrientationLandscapeRight: + glTranslatef(w,h,0); + glRotatef(90,0,0,1); + glTranslatef(-h,-w,0); + break; + case CCDeviceOrientationLandscapeLeft: + glTranslatef(w,h,0); + glRotatef(-90,0,0,1); + glTranslatef(-h,-w,0); + break; + } +} + +-(void) end +{ + // don't release the event handlers + // They are needed in case the director is run again + [[CCTouchDispatcher sharedDispatcher] removeAllDelegates]; + + [super end]; +} + +@end + + +#pragma mark - +#pragma mark Director TimerDirector + +@implementation CCDirectorTimer +- (void)startAnimation +{ + NSAssert( animationTimer == nil, @"animationTimer must be nil. Calling startAnimation twice?"); + + if( gettimeofday( &lastUpdate_, NULL) != 0 ) { + CCLOG(@"cocos2d: Director: Error in gettimeofday"); + } + + animationTimer = [NSTimer scheduledTimerWithTimeInterval:animationInterval_ target:self selector:@selector(mainLoop) userInfo:nil repeats:YES]; + + // + // If you want to attach the opengl view into UIScrollView + // uncomment this line to prevent 'freezing'. + // It doesn't work on with the Fast Director + // + // [[NSRunLoop currentRunLoop] addTimer:animationTimer + // forMode:NSRunLoopCommonModes]; +} + +-(void) mainLoop +{ + [self drawScene]; +} + +- (void)stopAnimation +{ + [animationTimer invalidate]; + animationTimer = nil; +} + +- (void)setAnimationInterval:(NSTimeInterval)interval +{ + animationInterval_ = interval; + + if(animationTimer) { + [self stopAnimation]; + [self startAnimation]; + } +} + +-(void) dealloc +{ + [animationTimer release]; + [super dealloc]; +} +@end + + +#pragma mark - +#pragma mark Director DirectorFast + +@implementation CCDirectorFast + +- (id) init +{ + if(( self = [super init] )) { + +#if CC_DIRECTOR_DISPATCH_FAST_EVENTS + CCLOG(@"cocos2d: Fast Events enabled"); +#else + CCLOG(@"cocos2d: Fast Events disabled"); +#endif + isRunning = NO; + + // XXX: + // XXX: Don't create any autorelease object before calling "fast director" + // XXX: else it will be leaked + // XXX: + autoreleasePool = [NSAutoreleasePool new]; + } + + return self; +} + +- (void) startAnimation +{ + NSAssert( isRunning == NO, @"isRunning must be NO. Calling startAnimation twice?"); + + // XXX: + // XXX: release autorelease objects created + // XXX: between "use fast director" and "runWithScene" + // XXX: + [autoreleasePool release]; + autoreleasePool = nil; + + if ( gettimeofday( &lastUpdate_, NULL) != 0 ) { + CCLOG(@"cocos2d: Director: Error in gettimeofday"); + } + + + isRunning = YES; + + SEL selector = @selector(mainLoop); + NSMethodSignature* sig = [[[CCDirector sharedDirector] class] + instanceMethodSignatureForSelector:selector]; + NSInvocation* invocation = [NSInvocation + invocationWithMethodSignature:sig]; + [invocation setTarget:[CCDirector sharedDirector]]; + [invocation setSelector:selector]; + [invocation performSelectorOnMainThread:@selector(invokeWithTarget:) + withObject:[CCDirector sharedDirector] waitUntilDone:NO]; + +// NSInvocationOperation *loopOperation = [[[NSInvocationOperation alloc] +// initWithTarget:self selector:@selector(mainLoop) object:nil] +// autorelease]; +// +// [loopOperation performSelectorOnMainThread:@selector(start) withObject:nil +// waitUntilDone:NO]; +} + +-(void) mainLoop +{ + while (isRunning) { + + NSAutoreleasePool *loopPool = [NSAutoreleasePool new]; + +#if CC_DIRECTOR_DISPATCH_FAST_EVENTS + while( CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.004f, FALSE) == kCFRunLoopRunHandledSource); +#else + while(CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, TRUE) == kCFRunLoopRunHandledSource); +#endif + + if (isPaused_) { + usleep(250000); // Sleep for a quarter of a second (250,000 microseconds) so that the framerate is 4 fps. + } + + [self drawScene]; + +#if CC_DIRECTOR_DISPATCH_FAST_EVENTS + while( CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.004f, FALSE) == kCFRunLoopRunHandledSource); +#else + while(CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, TRUE) == kCFRunLoopRunHandledSource); +#endif + + [loopPool release]; + } +} +- (void) stopAnimation +{ + isRunning = NO; +} + +- (void)setAnimationInterval:(NSTimeInterval)interval +{ + NSLog(@"FastDirectory doesn't support setAnimationInterval, yet"); +} +@end + +#pragma mark - +#pragma mark Director DirectorThreadedFast + +@implementation CCDirectorFastThreaded + +- (id) init +{ + if(( self = [super init] )) { + isRunning = NO; + } + + return self; +} + +- (void) startAnimation +{ + NSAssert( isRunning == NO, @"isRunning must be NO. Calling startAnimation twice?"); + + if ( gettimeofday( &lastUpdate_, NULL) != 0 ) { + CCLOG(@"cocos2d: ThreadedFastDirector: Error on gettimeofday"); + } + + isRunning = YES; + + NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(mainLoop) object:nil]; + [thread start]; + [thread release]; +} + +-(void) mainLoop +{ + while( ![[NSThread currentThread] isCancelled] ) { + if( isRunning ) + [self performSelectorOnMainThread:@selector(drawScene) withObject:nil waitUntilDone:YES]; + + if (isPaused_) { + usleep(250000); // Sleep for a quarter of a second (250,000 microseconds) so that the framerate is 4 fps. + } else { +// usleep(2000); + } + } +} +- (void) stopAnimation +{ + isRunning = NO; +} + +- (void)setAnimationInterval:(NSTimeInterval)interval +{ + NSLog(@"FastDirector doesn't support setAnimationInterval, yet"); +} +@end + +#pragma mark - +#pragma mark DirectorDisplayLink + +// Allows building DisplayLinkDirector for pre-3.1 SDKS +// without getting compiler warnings. +@interface NSObject(CADisplayLink) ++ (id) displayLinkWithTarget:(id)arg1 selector:(SEL)arg2; +- (void) addToRunLoop:(id)arg1 forMode:(id)arg2; +- (void) setFrameInterval:(int)interval; +- (void) invalidate; +@end + +@implementation CCDirectorDisplayLink + +- (void)setAnimationInterval:(NSTimeInterval)interval +{ + animationInterval_ = interval; + if(displayLink){ + [self stopAnimation]; + [self startAnimation]; + } +} + +- (void) startAnimation +{ + NSAssert( displayLink == nil, @"displayLink must be nil. Calling startAnimation twice?"); + + if ( gettimeofday( &lastUpdate_, NULL) != 0 ) { + CCLOG(@"cocos2d: DisplayLinkDirector: Error on gettimeofday"); + } + + // approximate frame rate + // assumes device refreshes at 60 fps + int frameInterval = (int) floor(animationInterval_ * 60.0f); + + CCLOG(@"cocos2d: Frame interval: %d", frameInterval); + + displayLink = [NSClassFromString(@"CADisplayLink") displayLinkWithTarget:self selector:@selector(mainLoop:)]; + [displayLink setFrameInterval:frameInterval]; + [displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; +} + +-(void) mainLoop:(id)sender +{ + [self drawScene]; +} + +- (void) stopAnimation +{ + [displayLink invalidate]; + displayLink = nil; +} + +-(void) dealloc +{ + [displayLink release]; + [super dealloc]; +} +@end + +#endif // __IPHONE_OS_VERSION_MAX_ALLOWED diff --git a/libs/cocos2d/Platforms/iOS/CCTouchDelegateProtocol.h b/libs/cocos2d/Platforms/iOS/CCTouchDelegateProtocol.h new file mode 100755 index 0000000..20ba036 --- /dev/null +++ b/libs/cocos2d/Platforms/iOS/CCTouchDelegateProtocol.h @@ -0,0 +1,75 @@ +/* + * cocos2d for iPhone: http://www.cocos2d-iphone.org + * + * Copyright (c) 2009 Valentin Milea + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +// Only compile this code on iOS. These files should NOT be included on your Mac project. +// But in case they are included, it won't be compiled. +#import +#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED + +#import + +/** + CCTargetedTouchDelegate. + + Using this type of delegate results in two benefits: + 1. You don't need to deal with NSSets, the dispatcher does the job of splitting + them. You get exactly one UITouch per call. + 2. You can *claim* a UITouch by returning YES in ccTouchBegan. Updates of claimed + touches are sent only to the delegate(s) that claimed them. So if you get a move/ + ended/cancelled update you're sure it's your touch. This frees you from doing a + lot of checks when doing multi-touch. + + (The name TargetedTouchDelegate relates to updates "targeting" their specific + handler, without bothering the other handlers.) + @since v0.8 + */ +@protocol CCTargetedTouchDelegate + +/** Return YES to claim the touch. + @since v0.8 + */ +- (BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event; +@optional +// touch updates: +- (void)ccTouchMoved:(UITouch *)touch withEvent:(UIEvent *)event; +- (void)ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event; +- (void)ccTouchCancelled:(UITouch *)touch withEvent:(UIEvent *)event; +@end + +/** + CCStandardTouchDelegate. + + This type of delegate is the same one used by CocoaTouch. You will receive all the events (Began,Moved,Ended,Cancelled). + @since v0.8 +*/ +@protocol CCStandardTouchDelegate +@optional +- (void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event; +- (void)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event; +- (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event; +- (void)ccTouchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event; +@end + +#endif // __IPHONE_OS_VERSION_MAX_ALLOWED diff --git a/libs/cocos2d/Platforms/iOS/CCTouchDispatcher.h b/libs/cocos2d/Platforms/iOS/CCTouchDispatcher.h new file mode 100755 index 0000000..9931189 --- /dev/null +++ b/libs/cocos2d/Platforms/iOS/CCTouchDispatcher.h @@ -0,0 +1,123 @@ +/* + * cocos2d for iPhone: http://www.cocos2d-iphone.org + * + * Copyright (c) 2009 Valentin Milea + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +// Only compile this code on iOS. These files should NOT be included on your Mac project. +// But in case they are included, it won't be compiled. +#import +#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED + +#import "CCTouchDelegateProtocol.h" +#import "EAGLView.h" + + +typedef enum +{ + kCCTouchSelectorBeganBit = 1 << 0, + kCCTouchSelectorMovedBit = 1 << 1, + kCCTouchSelectorEndedBit = 1 << 2, + kCCTouchSelectorCancelledBit = 1 << 3, + kCCTouchSelectorAllBits = ( kCCTouchSelectorBeganBit | kCCTouchSelectorMovedBit | kCCTouchSelectorEndedBit | kCCTouchSelectorCancelledBit), +} ccTouchSelectorFlag; + + +enum { + kCCTouchBegan, + kCCTouchMoved, + kCCTouchEnded, + kCCTouchCancelled, + + kCCTouchMax, +}; + +struct ccTouchHandlerHelperData { + SEL touchesSel; + SEL touchSel; + ccTouchSelectorFlag type; +}; + +/** CCTouchDispatcher. + Singleton that handles all the touch events. + The dispatcher dispatches events to the registered TouchHandlers. + There are 2 different type of touch handlers: + - Standard Touch Handlers + - Targeted Touch Handlers + + The Standard Touch Handlers work like the CocoaTouch touch handler: a set of touches is passed to the delegate. + On the other hand, the Targeted Touch Handlers only receive 1 touch at the time, and they can "swallow" touches (avoid the propagation of the event). + + Firstly, the dispatcher sends the received touches to the targeted touches. + These touches can be swallowed by the Targeted Touch Handlers. If there are still remaining touches, then the remaining touches will be sent + to the Standard Touch Handlers. + + @since v0.8.0 + */ +@interface CCTouchDispatcher : NSObject +{ + NSMutableArray *targetedHandlers; + NSMutableArray *standardHandlers; + + BOOL locked; + BOOL toAdd; + BOOL toRemove; + NSMutableArray *handlersToAdd; + NSMutableArray *handlersToRemove; + BOOL toQuit; + + BOOL dispatchEvents; + + // 4, 1 for each type of event + struct ccTouchHandlerHelperData handlerHelperData[kCCTouchMax]; +} + +/** singleton of the CCTouchDispatcher */ ++ (CCTouchDispatcher*)sharedDispatcher; + +/** Whether or not the events are going to be dispatched. Default: YES */ +@property (nonatomic,readwrite, assign) BOOL dispatchEvents; + +/** Adds a standard touch delegate to the dispatcher's list. + See StandardTouchDelegate description. + IMPORTANT: The delegate will be retained. + */ +-(void) addStandardDelegate:(id) delegate priority:(int)priority; +/** Adds a targeted touch delegate to the dispatcher's list. + See TargetedTouchDelegate description. + IMPORTANT: The delegate will be retained. + */ +-(void) addTargetedDelegate:(id) delegate priority:(int)priority swallowsTouches:(BOOL)swallowsTouches; +/** Removes a touch delegate. + The delegate will be released + */ +-(void) removeDelegate:(id) delegate; +/** Removes all touch delegates, releasing all the delegates */ +-(void) removeAllDelegates; +/** Changes the priority of a previously added delegate. The lower the number, + the higher the priority */ +-(void) setPriority:(int) priority forDelegate:(id) delegate; + +NSComparisonResult sortByPriority(id first, id second, void *context); +@end + +#endif // __IPHONE_OS_VERSION_MAX_ALLOWED diff --git a/libs/cocos2d/Platforms/iOS/CCTouchDispatcher.m b/libs/cocos2d/Platforms/iOS/CCTouchDispatcher.m new file mode 100755 index 0000000..1553b48 --- /dev/null +++ b/libs/cocos2d/Platforms/iOS/CCTouchDispatcher.m @@ -0,0 +1,347 @@ +/* + * cocos2d for iPhone: http://www.cocos2d-iphone.org + * + * Copyright (c) 2009 Valentin Milea + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +// Only compile this code on iOS. These files should NOT be included on your Mac project. +// But in case they are included, it won't be compiled. +#import +#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED + + +#import "CCTouchDispatcher.h" +#import "CCTouchHandler.h" + +@implementation CCTouchDispatcher + +@synthesize dispatchEvents; + +static CCTouchDispatcher *sharedDispatcher = nil; + ++(CCTouchDispatcher*) sharedDispatcher +{ + @synchronized(self) { + if (sharedDispatcher == nil) + sharedDispatcher = [[self alloc] init]; // assignment not done here + } + return sharedDispatcher; +} + ++(id) allocWithZone:(NSZone *)zone +{ + @synchronized(self) { + NSAssert(sharedDispatcher == nil, @"Attempted to allocate a second instance of a singleton."); + return [super allocWithZone:zone]; + } + return nil; // on subsequent allocation attempts return nil +} + +-(id) init +{ + if((self = [super init])) { + + dispatchEvents = YES; + targetedHandlers = [[NSMutableArray alloc] initWithCapacity:8]; + standardHandlers = [[NSMutableArray alloc] initWithCapacity:4]; + + handlersToAdd = [[NSMutableArray alloc] initWithCapacity:8]; + handlersToRemove = [[NSMutableArray alloc] initWithCapacity:8]; + + toRemove = NO; + toAdd = NO; + toQuit = NO; + locked = NO; + + handlerHelperData[kCCTouchBegan] = (struct ccTouchHandlerHelperData) {@selector(ccTouchesBegan:withEvent:),@selector(ccTouchBegan:withEvent:),kCCTouchSelectorBeganBit}; + handlerHelperData[kCCTouchMoved] = (struct ccTouchHandlerHelperData) {@selector(ccTouchesMoved:withEvent:),@selector(ccTouchMoved:withEvent:),kCCTouchSelectorMovedBit}; + handlerHelperData[kCCTouchEnded] = (struct ccTouchHandlerHelperData) {@selector(ccTouchesEnded:withEvent:),@selector(ccTouchEnded:withEvent:),kCCTouchSelectorEndedBit}; + handlerHelperData[kCCTouchCancelled] = (struct ccTouchHandlerHelperData) {@selector(ccTouchesCancelled:withEvent:),@selector(ccTouchCancelled:withEvent:),kCCTouchSelectorCancelledBit}; + + } + + return self; +} + +-(void) dealloc +{ + [targetedHandlers release]; + [standardHandlers release]; + [handlersToAdd release]; + [handlersToRemove release]; + [super dealloc]; +} + +// +// handlers management +// + +#pragma mark TouchDispatcher - Add Hanlder + +-(void) forceAddHandler:(CCTouchHandler*)handler array:(NSMutableArray*)array +{ + NSUInteger i = 0; + + for( CCTouchHandler *h in array ) { + if( h.priority < handler.priority ) + i++; + + NSAssert( h.delegate != handler.delegate, @"Delegate already added to touch dispatcher."); + } + [array insertObject:handler atIndex:i]; +} + +-(void) addStandardDelegate:(id) delegate priority:(int)priority +{ + CCTouchHandler *handler = [CCStandardTouchHandler handlerWithDelegate:delegate priority:priority]; + if( ! locked ) { + [self forceAddHandler:handler array:standardHandlers]; + } else { + [handlersToAdd addObject:handler]; + toAdd = YES; + } +} + +-(void) addTargetedDelegate:(id) delegate priority:(int)priority swallowsTouches:(BOOL)swallowsTouches +{ + CCTouchHandler *handler = [CCTargetedTouchHandler handlerWithDelegate:delegate priority:priority swallowsTouches:swallowsTouches]; + if( ! locked ) { + [self forceAddHandler:handler array:targetedHandlers]; + } else { + [handlersToAdd addObject:handler]; + toAdd = YES; + } +} + +#pragma mark TouchDispatcher - removeDelegate + +-(void) forceRemoveDelegate:(id)delegate +{ + // XXX: remove it from both handlers ??? + + for( CCTouchHandler *handler in targetedHandlers ) { + if( handler.delegate == delegate ) { + [targetedHandlers removeObject:handler]; + break; + } + } + + for( CCTouchHandler *handler in standardHandlers ) { + if( handler.delegate == delegate ) { + [standardHandlers removeObject:handler]; + break; + } + } +} + +-(void) removeDelegate:(id) delegate +{ + if( delegate == nil ) + return; + + if( ! locked ) { + [self forceRemoveDelegate:delegate]; + } else { + [handlersToRemove addObject:delegate]; + toRemove = YES; + } +} + +#pragma mark TouchDispatcher - removeAllDelegates + +-(void) forceRemoveAllDelegates +{ + [standardHandlers removeAllObjects]; + [targetedHandlers removeAllObjects]; +} +-(void) removeAllDelegates +{ + if( ! locked ) + [self forceRemoveAllDelegates]; + else + toQuit = YES; +} + +#pragma mark Changing priority of added handlers + +-(CCTouchHandler*) findHandler:(id)delegate +{ + for( CCTouchHandler *handler in targetedHandlers ) { + if( handler.delegate == delegate ) { + return handler; + } + } + + for( CCTouchHandler *handler in standardHandlers ) { + if( handler.delegate == delegate ) { + return handler; + } + } + return nil; +} + +NSComparisonResult sortByPriority(id first, id second, void *context) +{ + if (((CCTouchHandler*)first).priority < ((CCTouchHandler*)second).priority) + return NSOrderedAscending; + else if (((CCTouchHandler*)first).priority > ((CCTouchHandler*)second).priority) + return NSOrderedDescending; + else + return NSOrderedSame; +} + +-(void) rearrangeHandlers:(NSMutableArray*)array +{ + [array sortUsingFunction:sortByPriority context:nil]; +} + +-(void) setPriority:(int) priority forDelegate:(id) delegate +{ + NSAssert(delegate != nil, @"Got nil touch delegate!"); + + CCTouchHandler *handler = nil; + handler = [self findHandler:delegate]; + + NSAssert(handler != nil, @"Delegate not found!"); + + handler.priority = priority; + + [self rearrangeHandlers:targetedHandlers]; + [self rearrangeHandlers:standardHandlers]; +} + +// +// dispatch events +// +-(void) touches:(NSSet*)touches withEvent:(UIEvent*)event withTouchType:(unsigned int)idx +{ + NSAssert(idx < 4, @"Invalid idx value"); + + id mutableTouches; + locked = YES; + + // optimization to prevent a mutable copy when it is not necessary + unsigned int targetedHandlersCount = [targetedHandlers count]; + unsigned int standardHandlersCount = [standardHandlers count]; + BOOL needsMutableSet = (targetedHandlersCount && standardHandlersCount); + + mutableTouches = (needsMutableSet ? [touches mutableCopy] : touches); + + struct ccTouchHandlerHelperData helper = handlerHelperData[idx]; + // + // process the target handlers 1st + // + if( targetedHandlersCount > 0 ) { + for( UITouch *touch in touches ) { + for(CCTargetedTouchHandler *handler in targetedHandlers) { + + BOOL claimed = NO; + if( idx == kCCTouchBegan ) { + claimed = [handler.delegate ccTouchBegan:touch withEvent:event]; + if( claimed ) + [handler.claimedTouches addObject:touch]; + } + + // else (moved, ended, cancelled) + else if( [handler.claimedTouches containsObject:touch] ) { + claimed = YES; + if( handler.enabledSelectors & helper.type ) + [handler.delegate performSelector:helper.touchSel withObject:touch withObject:event]; + + if( helper.type & (kCCTouchSelectorCancelledBit | kCCTouchSelectorEndedBit) ) + [handler.claimedTouches removeObject:touch]; + } + + if( claimed && handler.swallowsTouches ) { + if( needsMutableSet ) + [mutableTouches removeObject:touch]; + break; + } + } + } + } + + // + // process standard handlers 2nd + // + if( standardHandlersCount > 0 && [mutableTouches count]>0 ) { + for( CCTouchHandler *handler in standardHandlers ) { + if( handler.enabledSelectors & helper.type ) + [handler.delegate performSelector:helper.touchesSel withObject:mutableTouches withObject:event]; + } + } + if( needsMutableSet ) + [mutableTouches release]; + + // + // Optimization. To prevent a [handlers copy] which is expensive + // the add/removes/quit is done after the iterations + // + locked = NO; + if( toRemove ) { + toRemove = NO; + for( id delegate in handlersToRemove ) + [self forceRemoveDelegate:delegate]; + [handlersToRemove removeAllObjects]; + } + if( toAdd ) { + toAdd = NO; + for( CCTouchHandler *handler in handlersToAdd ) { + Class targetedClass = [CCTargetedTouchHandler class]; + if( [handler isKindOfClass:targetedClass] ) + [self forceAddHandler:handler array:targetedHandlers]; + else + [self forceAddHandler:handler array:standardHandlers]; + } + [handlersToAdd removeAllObjects]; + } + if( toQuit ) { + toQuit = NO; + [self forceRemoveAllDelegates]; + } +} + +- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event +{ + if( dispatchEvents ) + [self touches:touches withEvent:event withTouchType:kCCTouchBegan]; +} +- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event +{ + if( dispatchEvents ) + [self touches:touches withEvent:event withTouchType:kCCTouchMoved]; +} + +- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event +{ + if( dispatchEvents ) + [self touches:touches withEvent:event withTouchType:kCCTouchEnded]; +} + +- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event +{ + if( dispatchEvents ) + [self touches:touches withEvent:event withTouchType:kCCTouchCancelled]; +} +@end + +#endif // __IPHONE_OS_VERSION_MAX_ALLOWED diff --git a/libs/cocos2d/Platforms/iOS/CCTouchHandler.h b/libs/cocos2d/Platforms/iOS/CCTouchHandler.h new file mode 100755 index 0000000..31a3e36 --- /dev/null +++ b/libs/cocos2d/Platforms/iOS/CCTouchHandler.h @@ -0,0 +1,93 @@ +/* + * cocos2d for iPhone: http://www.cocos2d-iphone.org + * + * Copyright (c) 2009 Valentin Milea + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +// Only compile this code on iOS. These files should NOT be included on your Mac project. +// But in case they are included, it won't be compiled. +#import +#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED + +/* + * This file contains the delegates of the touches + * There are 2 possible delegates: + * - CCStandardTouchHandler: propagates all the events at once + * - CCTargetedTouchHandler: propagates 1 event at the time + */ + +#import "CCTouchDelegateProtocol.h" +#import "CCTouchDispatcher.h" + +/** + CCTouchHandler + Object than contains the delegate and priority of the event handler. +*/ +@interface CCTouchHandler : NSObject { + id delegate; + int priority; + ccTouchSelectorFlag enabledSelectors_; +} + +/** delegate */ +@property(nonatomic, readwrite, retain) id delegate; +/** priority */ +@property(nonatomic, readwrite) int priority; // default 0 +/** enabled selectors */ +@property(nonatomic,readwrite) ccTouchSelectorFlag enabledSelectors; + +/** allocates a TouchHandler with a delegate and a priority */ ++ (id)handlerWithDelegate:(id)aDelegate priority:(int)priority; +/** initializes a TouchHandler with a delegate and a priority */ +- (id)initWithDelegate:(id)aDelegate priority:(int)priority; +@end + +/** CCStandardTouchHandler + It forwardes each event to the delegate. + */ +@interface CCStandardTouchHandler : CCTouchHandler +{ +} +@end + +/** + CCTargetedTouchHandler + Object than contains the claimed touches and if it swallos touches. + Used internally by TouchDispatcher + */ +@interface CCTargetedTouchHandler : CCTouchHandler { + BOOL swallowsTouches; + NSMutableSet *claimedTouches; +} +/** whether or not the touches are swallowed */ +@property(nonatomic, readwrite) BOOL swallowsTouches; // default NO +/** MutableSet that contains the claimed touches */ +@property(nonatomic, readonly) NSMutableSet *claimedTouches; + +/** allocates a TargetedTouchHandler with a delegate, a priority and whether or not it swallows touches or not */ ++ (id)handlerWithDelegate:(id) aDelegate priority:(int)priority swallowsTouches:(BOOL)swallowsTouches; +/** initializes a TargetedTouchHandler with a delegate, a priority and whether or not it swallows touches or not */ +- (id)initWithDelegate:(id) aDelegate priority:(int)priority swallowsTouches:(BOOL)swallowsTouches; + +@end + +#endif // __IPHONE_OS_VERSION_MAX_ALLOWED diff --git a/libs/cocos2d/Platforms/iOS/CCTouchHandler.m b/libs/cocos2d/Platforms/iOS/CCTouchHandler.m new file mode 100755 index 0000000..a52103b --- /dev/null +++ b/libs/cocos2d/Platforms/iOS/CCTouchHandler.m @@ -0,0 +1,135 @@ +/* + * cocos2d for iPhone: http://www.cocos2d-iphone.org + * + * Copyright (c) 2009 Valentin Milea + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + + +// Only compile this code on iOS. These files should NOT be included on your Mac project. +// But in case they are included, it won't be compiled. +#import +#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED + +/* + * This file contains the delegates of the touches + * There are 2 possible delegates: + * - CCStandardTouchHandler: propagates all the events at once + * - CCTargetedTouchHandler: propagates 1 event at the time + */ + +#import "CCTouchHandler.h" +#import "../../ccMacros.h" + +#pragma mark - +#pragma mark TouchHandler +@implementation CCTouchHandler + +@synthesize delegate, priority; +@synthesize enabledSelectors=enabledSelectors_; + ++ (id)handlerWithDelegate:(id) aDelegate priority:(int)aPriority +{ + return [[[self alloc] initWithDelegate:aDelegate priority:aPriority] autorelease]; +} + +- (id)initWithDelegate:(id) aDelegate priority:(int)aPriority +{ + NSAssert(aDelegate != nil, @"Touch delegate may not be nil"); + + if ((self = [super init])) { + self.delegate = aDelegate; + priority = aPriority; + enabledSelectors_ = 0; + } + + return self; +} + +- (void)dealloc { + CCLOGINFO(@"cocos2d: deallocing %@", self); + [delegate release]; + [super dealloc]; +} +@end + +#pragma mark - +#pragma mark StandardTouchHandler +@implementation CCStandardTouchHandler +-(id) initWithDelegate:(id)del priority:(int)pri +{ + if( (self=[super initWithDelegate:del priority:pri]) ) { + if( [del respondsToSelector:@selector(ccTouchesBegan:withEvent:)] ) + enabledSelectors_ |= kCCTouchSelectorBeganBit; + if( [del respondsToSelector:@selector(ccTouchesMoved:withEvent:)] ) + enabledSelectors_ |= kCCTouchSelectorMovedBit; + if( [del respondsToSelector:@selector(ccTouchesEnded:withEvent:)] ) + enabledSelectors_ |= kCCTouchSelectorEndedBit; + if( [del respondsToSelector:@selector(ccTouchesCancelled:withEvent:)] ) + enabledSelectors_ |= kCCTouchSelectorCancelledBit; + } + return self; +} +@end + +#pragma mark - +#pragma mark TargetedTouchHandler + +@interface CCTargetedTouchHandler (private) +-(void) updateKnownTouches:(NSMutableSet *)touches withEvent:(UIEvent *)event selector:(SEL)selector unclaim:(BOOL)doUnclaim; +@end + +@implementation CCTargetedTouchHandler + +@synthesize swallowsTouches, claimedTouches; + ++ (id)handlerWithDelegate:(id)aDelegate priority:(int)priority swallowsTouches:(BOOL)swallow +{ + return [[[self alloc] initWithDelegate:aDelegate priority:priority swallowsTouches:swallow] autorelease]; +} + +- (id)initWithDelegate:(id)aDelegate priority:(int)aPriority swallowsTouches:(BOOL)swallow +{ + if ((self = [super initWithDelegate:aDelegate priority:aPriority])) { + claimedTouches = [[NSMutableSet alloc] initWithCapacity:2]; + swallowsTouches = swallow; + + if( [aDelegate respondsToSelector:@selector(ccTouchBegan:withEvent:)] ) + enabledSelectors_ |= kCCTouchSelectorBeganBit; + if( [aDelegate respondsToSelector:@selector(ccTouchMoved:withEvent:)] ) + enabledSelectors_ |= kCCTouchSelectorMovedBit; + if( [aDelegate respondsToSelector:@selector(ccTouchEnded:withEvent:)] ) + enabledSelectors_ |= kCCTouchSelectorEndedBit; + if( [aDelegate respondsToSelector:@selector(ccTouchCancelled:withEvent:)] ) + enabledSelectors_ |= kCCTouchSelectorCancelledBit; + } + + return self; +} + +- (void)dealloc { + [claimedTouches release]; + [super dealloc]; +} +@end + + +#endif // __IPHONE_OS_VERSION_MAX_ALLOWED \ No newline at end of file diff --git a/libs/cocos2d/Platforms/iOS/EAGLView.h b/libs/cocos2d/Platforms/iOS/EAGLView.h new file mode 100755 index 0000000..3b6c2f3 --- /dev/null +++ b/libs/cocos2d/Platforms/iOS/EAGLView.h @@ -0,0 +1,155 @@ +/* + +===== IMPORTANT ===== + +This is sample code demonstrating API, technology or techniques in development. +Although this sample code has been reviewed for technical accuracy, it is not +final. Apple is supplying this information to help you plan for the adoption of +the technologies and programming interfaces described herein. This information +is subject to change, and software implemented based on this sample code should +be tested with final operating system software and final documentation. Newer +versions of this sample code may be provided with future seeds of the API or +technology. For information about updates to this and other developer +documentation, view the New & Updated sidebars in subsequent documentation +seeds. + +===================== + +File: EAGLView.h +Abstract: Convenience class that wraps the CAEAGLLayer from CoreAnimation into a +UIView subclass. + +Version: 1.3 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. +("Apple") in consideration of your agreement to the following terms, and your +use, installation, modification or redistribution of this Apple software +constitutes acceptance of these terms. If you do not agree with these terms, +please do not use, install, modify or redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and subject +to these terms, Apple grants you a personal, non-exclusive license, under +Apple's copyrights in this original Apple software (the "Apple Software"), to +use, reproduce, modify and redistribute the Apple Software, with or without +modifications, in source and/or binary forms; provided that if you redistribute +the Apple Software in its entirety and without modifications, you must retain +this notice and the following text and disclaimers in all such redistributions +of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may be used +to endorse or promote products derived from the Apple Software without specific +prior written permission from Apple. Except as expressly stated in this notice, +no other rights or licenses, express or implied, are granted by Apple herein, +including but not limited to any patent rights that may be infringed by your +derivative works or by other works in which the Apple Software may be +incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO +WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED +WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN +COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR +DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF +CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF +APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2008 Apple Inc. All Rights Reserved. + +*/ + +// Only compile this code on iOS. These files should NOT be included on your Mac project. +// But in case they are included, it won't be compiled. +#import +#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED + +#import +#import +#import +#import +#import + +#import "ESRenderer.h" + +//CLASSES: + +@class EAGLView; +@class EAGLSharegroup; + +//PROTOCOLS: + +@protocol EAGLTouchDelegate +- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event; +- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event; +- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event; +- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event; +@end + +//CLASS INTERFACE: + +/** EAGLView Class. + * This class wraps the CAEAGLLayer from CoreAnimation into a convenient UIView subclass. + * The view content is basically an EAGL surface you render your OpenGL scene into. + * Note that setting the view non-opaque will only work if the EAGL surface has an alpha channel. + */ +@interface EAGLView : UIView +{ + id renderer_; + EAGLContext *context_; // weak ref + + NSString *pixelformat_; + GLuint depthFormat_; + BOOL preserveBackbuffer_; + + CGSize size_; + BOOL discardFramebufferSupported_; + id touchDelegate_; + + //fsaa addition + BOOL multisampling_; + unsigned int requestedSamples_; +} + +/** creates an initializes an EAGLView with a frame and 0-bit depth buffer, and a RGB565 color buffer. */ ++ (id) viewWithFrame:(CGRect)frame; +/** creates an initializes an EAGLView with a frame, a color buffer format, and 0-bit depth buffer. */ ++ (id) viewWithFrame:(CGRect)frame pixelFormat:(NSString*)format; +/** creates an initializes an EAGLView with a frame, a color buffer format, and a depth buffer. */ ++ (id) viewWithFrame:(CGRect)frame pixelFormat:(NSString*)format depthFormat:(GLuint)depth; +/** creates an initializes an EAGLView with a frame, a color buffer format, a depth buffer format, a sharegroup, and multisamping */ ++ (id) viewWithFrame:(CGRect)frame pixelFormat:(NSString*)format depthFormat:(GLuint)depth preserveBackbuffer:(BOOL)retained sharegroup:(EAGLSharegroup*)sharegroup multiSampling:(BOOL)multisampling numberOfSamples:(unsigned int)samples; + +/** Initializes an EAGLView with a frame and 0-bit depth buffer, and a RGB565 color buffer */ +- (id) initWithFrame:(CGRect)frame; //These also set the current context +/** Initializes an EAGLView with a frame, a color buffer format, and 0-bit depth buffer */ +- (id) initWithFrame:(CGRect)frame pixelFormat:(NSString*)format; +/** Initializes an EAGLView with a frame, a color buffer format, a depth buffer format, a sharegroup and multisampling support */ +- (id) initWithFrame:(CGRect)frame pixelFormat:(NSString*)format depthFormat:(GLuint)depth preserveBackbuffer:(BOOL)retained sharegroup:(EAGLSharegroup*)sharegroup multiSampling:(BOOL)sampling numberOfSamples:(unsigned int)nSamples; + +/** pixel format: it could be RGBA8 (32-bit) or RGB565 (16-bit) */ +@property(nonatomic,readonly) NSString* pixelFormat; +/** depth format of the render buffer: 0, 16 or 24 bits*/ +@property(nonatomic,readonly) GLuint depthFormat; + +/** returns surface size in pixels */ +@property(nonatomic,readonly) CGSize surfaceSize; + +/** OpenGL context */ +@property(nonatomic,readonly) EAGLContext *context; + +@property(nonatomic,readwrite) BOOL multiSampling; + +/** touch delegate */ +@property(nonatomic,readwrite,assign) id touchDelegate; + +/** EAGLView uses double-buffer. This method swaps the buffers */ +-(void) swapBuffers; + +- (CGPoint) convertPointFromViewToSurface:(CGPoint)point; +- (CGRect) convertRectFromViewToSurface:(CGRect)rect; +@end + +#endif // __IPHONE_OS_VERSION_MAX_ALLOWED diff --git a/libs/cocos2d/Platforms/iOS/EAGLView.m b/libs/cocos2d/Platforms/iOS/EAGLView.m new file mode 100755 index 0000000..d5ead65 --- /dev/null +++ b/libs/cocos2d/Platforms/iOS/EAGLView.m @@ -0,0 +1,343 @@ +/* + +===== IMPORTANT ===== + +This is sample code demonstrating API, technology or techniques in development. +Although this sample code has been reviewed for technical accuracy, it is not +final. Apple is supplying this information to help you plan for the adoption of +the technologies and programming interfaces described herein. This information +is subject to change, and software implemented based on this sample code should +be tested with final operating system software and final documentation. Newer +versions of this sample code may be provided with future seeds of the API or +technology. For information about updates to this and other developer +documentation, view the New & Updated sidebars in subsequent documentation +seeds. + +===================== + +File: EAGLView.m +Abstract: Convenience class that wraps the CAEAGLLayer from CoreAnimation into a +UIView subclass. + +Version: 1.3 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. +("Apple") in consideration of your agreement to the following terms, and your +use, installation, modification or redistribution of this Apple software +constitutes acceptance of these terms. If you do not agree with these terms, +please do not use, install, modify or redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and subject +to these terms, Apple grants you a personal, non-exclusive license, under +Apple's copyrights in this original Apple software (the "Apple Software"), to +use, reproduce, modify and redistribute the Apple Software, with or without +modifications, in source and/or binary forms; provided that if you redistribute +the Apple Software in its entirety and without modifications, you must retain +this notice and the following text and disclaimers in all such redistributions +of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may be used +to endorse or promote products derived from the Apple Software without specific +prior written permission from Apple. Except as expressly stated in this notice, +no other rights or licenses, express or implied, are granted by Apple herein, +including but not limited to any patent rights that may be infringed by your +derivative works or by other works in which the Apple Software may be +incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO +WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED +WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN +COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR +DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF +CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF +APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2008 Apple Inc. All Rights Reserved. + +*/ + +// Only compile this code on iOS. These files should NOT be included on your Mac project. +// But in case they are included, it won't be compiled. +#import +#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED + +#import + +#import "EAGLView.h" +#import "ES1Renderer.h" +#import "../../CCDirector.h" +#import "../../ccMacros.h" +#import "../../CCConfiguration.h" +#import "../../Support/OpenGL_Internal.h" + + +//CLASS IMPLEMENTATIONS: + +@interface EAGLView (Private) +- (BOOL) setupSurfaceWithSharegroup:(EAGLSharegroup*)sharegroup; +- (unsigned int) convertPixelFormat:(NSString*) pixelFormat; +@end + +@implementation EAGLView + +@synthesize surfaceSize=size_; +@synthesize pixelFormat=pixelformat_, depthFormat=depthFormat_; +@synthesize touchDelegate=touchDelegate_; +@synthesize context=context_; +@synthesize multiSampling=multiSampling_; + ++ (Class) layerClass +{ + return [CAEAGLLayer class]; +} + ++ (id) viewWithFrame:(CGRect)frame +{ + return [[[self alloc] initWithFrame:frame] autorelease]; +} + ++ (id) viewWithFrame:(CGRect)frame pixelFormat:(NSString*)format +{ + return [[[self alloc] initWithFrame:frame pixelFormat:format] autorelease]; +} + ++ (id) viewWithFrame:(CGRect)frame pixelFormat:(NSString*)format depthFormat:(GLuint)depth +{ + return [[[self alloc] initWithFrame:frame pixelFormat:format depthFormat:depth preserveBackbuffer:NO sharegroup:nil multiSampling:NO numberOfSamples:0] autorelease]; +} + ++ (id) viewWithFrame:(CGRect)frame pixelFormat:(NSString*)format depthFormat:(GLuint)depth preserveBackbuffer:(BOOL)retained sharegroup:(EAGLSharegroup*)sharegroup multiSampling:(BOOL)multisampling numberOfSamples:(unsigned int)samples +{ + return [[[self alloc] initWithFrame:frame pixelFormat:format depthFormat:depth preserveBackbuffer:retained sharegroup:sharegroup multiSampling:multisampling numberOfSamples:samples] autorelease]; +} + +- (id) initWithFrame:(CGRect)frame +{ + return [self initWithFrame:frame pixelFormat:kEAGLColorFormatRGB565 depthFormat:0 preserveBackbuffer:NO sharegroup:nil multiSampling:NO numberOfSamples:0]; +} + +- (id) initWithFrame:(CGRect)frame pixelFormat:(NSString*)format +{ + return [self initWithFrame:frame pixelFormat:format depthFormat:0 preserveBackbuffer:NO sharegroup:nil multiSampling:NO numberOfSamples:0]; +} + +- (id) initWithFrame:(CGRect)frame pixelFormat:(NSString*)format depthFormat:(GLuint)depth preserveBackbuffer:(BOOL)retained sharegroup:(EAGLSharegroup*)sharegroup multiSampling:(BOOL)sampling numberOfSamples:(unsigned int)nSamples +{ + if((self = [super initWithFrame:frame])) + { + pixelformat_ = format; + depthFormat_ = depth; + multiSampling_ = sampling; + requestedSamples_ = nSamples; + preserveBackbuffer_ = retained; + + if( ! [self setupSurfaceWithSharegroup:sharegroup] ) { + [self release]; + return nil; + } + } + + return self; +} + +-(id) initWithCoder:(NSCoder *)aDecoder +{ + if( (self = [super initWithCoder:aDecoder]) ) { + + CAEAGLLayer* eaglLayer = (CAEAGLLayer*)[self layer]; + + pixelformat_ = kEAGLColorFormatRGB565; + depthFormat_ = 0; // GL_DEPTH_COMPONENT24_OES; + multiSampling_= NO; + requestedSamples_ = 0; + size_ = [eaglLayer bounds].size; + + if( ! [self setupSurfaceWithSharegroup:nil] ) { + [self release]; + return nil; + } + } + + return self; +} + +-(BOOL) setupSurfaceWithSharegroup:(EAGLSharegroup*)sharegroup +{ + CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer; + + eaglLayer.opaque = YES; + eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithBool:preserveBackbuffer_], kEAGLDrawablePropertyRetainedBacking, + pixelformat_, kEAGLDrawablePropertyColorFormat, nil]; + + + renderer_ = [[ES1Renderer alloc] initWithDepthFormat:depthFormat_ + withPixelFormat:[self convertPixelFormat:pixelformat_] + withSharegroup:sharegroup + withMultiSampling:multiSampling_ + withNumberOfSamples:requestedSamples_]; + if (!renderer_) + return NO; + + context_ = [renderer_ context]; + [context_ renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:eaglLayer]; + + discardFramebufferSupported_ = [[CCConfiguration sharedConfiguration] supportsDiscardFramebuffer]; + + return YES; +} + +- (void) dealloc +{ + CCLOGINFO(@"cocos2d: deallocing %@", self); + + + [renderer_ release]; + [super dealloc]; +} + +- (void) layoutSubviews +{ + size_ = [renderer_ backingSize]; + + [renderer_ resizeFromLayer:(CAEAGLLayer*)self.layer]; + + // Issue #914 #924 + CCDirector *director = [CCDirector sharedDirector]; + [director reshapeProjection:size_]; + + // Avoid flicker. Issue #350 + [director performSelectorOnMainThread:@selector(drawScene) withObject:nil waitUntilDone:YES]; +} + +- (void) swapBuffers +{ + // IMPORTANT: + // - preconditions + // -> context_ MUST be the OpenGL context + // -> renderbuffer_ must be the the RENDER BUFFER + +#ifdef __IPHONE_4_0 + + if (multiSampling_) + { + /* Resolve from msaaFramebuffer to resolveFramebuffer */ + //glDisable(GL_SCISSOR_TEST); + glBindFramebufferOES(GL_READ_FRAMEBUFFER_APPLE, [renderer_ msaaFrameBuffer]); + glBindFramebufferOES(GL_DRAW_FRAMEBUFFER_APPLE, [renderer_ defaultFrameBuffer]); + glResolveMultisampleFramebufferAPPLE(); + } + + if( discardFramebufferSupported_) + { + if (multiSampling_) + { + if (depthFormat_) + { + GLenum attachments[] = {GL_COLOR_ATTACHMENT0_OES, GL_DEPTH_ATTACHMENT_OES}; + glDiscardFramebufferEXT(GL_READ_FRAMEBUFFER_APPLE, 2, attachments); + } + else + { + GLenum attachments[] = {GL_COLOR_ATTACHMENT0_OES}; + glDiscardFramebufferEXT(GL_READ_FRAMEBUFFER_APPLE, 1, attachments); + } + + glBindRenderbufferOES(GL_RENDERBUFFER_OES, [renderer_ colorRenderBuffer]); + + } + + // not MSAA + else if (depthFormat_ ) { + GLenum attachments[] = { GL_DEPTH_ATTACHMENT_OES}; + glDiscardFramebufferEXT(GL_FRAMEBUFFER_OES, 1, attachments); + } + } + +#endif // __IPHONE_4_0 + + if(![context_ presentRenderbuffer:GL_RENDERBUFFER_OES]) + CCLOG(@"cocos2d: Failed to swap renderbuffer in %s\n", __FUNCTION__); + +#if COCOS2D_DEBUG + CHECK_GL_ERROR(); +#endif + + // We can safely re-bind the framebuffer here, since this will be the + // 1st instruction of the new main loop + if( multiSampling_ ) + glBindFramebufferOES(GL_FRAMEBUFFER_OES, [renderer_ msaaFrameBuffer]); +} + +- (unsigned int) convertPixelFormat:(NSString*) pixelFormat +{ + // define the pixel format + GLenum pFormat; + + + if([pixelFormat isEqualToString:@"EAGLColorFormat565"]) + pFormat = GL_RGB565_OES; + else + pFormat = GL_RGBA8_OES; + + return pFormat; +} + +#pragma mark EAGLView - Point conversion + +- (CGPoint) convertPointFromViewToSurface:(CGPoint)point +{ + CGRect bounds = [self bounds]; + + return CGPointMake((point.x - bounds.origin.x) / bounds.size.width * size_.width, (point.y - bounds.origin.y) / bounds.size.height * size_.height); +} + +- (CGRect) convertRectFromViewToSurface:(CGRect)rect +{ + CGRect bounds = [self bounds]; + + return CGRectMake((rect.origin.x - bounds.origin.x) / bounds.size.width * size_.width, (rect.origin.y - bounds.origin.y) / bounds.size.height * size_.height, rect.size.width / bounds.size.width * size_.width, rect.size.height / bounds.size.height * size_.height); +} + +// Pass the touches to the superview +#pragma mark EAGLView - Touch Delegate + +- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event +{ + if(touchDelegate_) + { + [touchDelegate_ touchesBegan:touches withEvent:event]; + } +} + +- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event +{ + if(touchDelegate_) + { + [touchDelegate_ touchesMoved:touches withEvent:event]; + } +} + +- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event +{ + if(touchDelegate_) + { + [touchDelegate_ touchesEnded:touches withEvent:event]; + } +} +- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event +{ + if(touchDelegate_) + { + [touchDelegate_ touchesCancelled:touches withEvent:event]; + } +} + +@end + +#endif // __IPHONE_OS_VERSION_MAX_ALLOWED \ No newline at end of file diff --git a/libs/cocos2d/Platforms/iOS/ES1Renderer.h b/libs/cocos2d/Platforms/iOS/ES1Renderer.h new file mode 100755 index 0000000..fd946a7 --- /dev/null +++ b/libs/cocos2d/Platforms/iOS/ES1Renderer.h @@ -0,0 +1,72 @@ +/* + * cocos2d for iPhone: http://www.cocos2d-iphone.org + * + * Copyright (c) 2010 Ricardo Quesada + * Copyright (c) 2011 Zynga Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * + * File autogenerated with Xcode. Adapted for cocos2d needs. + */ + +// Only compile this code on iOS. These files should NOT be included on your Mac project. +// But in case they are included, it won't be compiled. +#import +#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED + + +#import "ESRenderer.h" + +#import +#import + +@interface ES1Renderer : NSObject +{ + // The pixel dimensions of the CAEAGLLayer + GLint backingWidth_; + GLint backingHeight_; + + unsigned int samplesToUse_; + BOOL multiSampling_; + + unsigned int depthFormat_; + unsigned int pixelFormat_; + + // The OpenGL ES names for the framebuffer and renderbuffer used to render to this view + GLuint defaultFramebuffer_; + GLuint colorRenderbuffer_; + GLuint depthBuffer_; + + + //buffers for MSAA + GLuint msaaFramebuffer_; + GLuint msaaColorbuffer_; + + EAGLContext *context_; +} + +/** EAGLContext */ +@property (nonatomic,readonly) EAGLContext* context; + +- (BOOL)resizeFromLayer:(CAEAGLLayer *)layer; + +@end + +#endif // __IPHONE_OS_VERSION_MAX_ALLOWED diff --git a/libs/cocos2d/Platforms/iOS/ES1Renderer.m b/libs/cocos2d/Platforms/iOS/ES1Renderer.m new file mode 100755 index 0000000..398d946 --- /dev/null +++ b/libs/cocos2d/Platforms/iOS/ES1Renderer.m @@ -0,0 +1,259 @@ +/* + * cocos2d for iPhone: http://www.cocos2d-iphone.org + * + * Copyright (c) 2010 Ricardo Quesada + * Copyright (c) 2011 Zynga Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * + * File autogenerated with Xcode. Adapted for cocos2d needs. + */ + +// Only compile this code on iOS. These files should NOT be included on your Mac project. +// But in case they are included, it won't be compiled. +#import +#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED + +#import "ES1Renderer.h" +#import "../../Support/OpenGL_Internal.h" +#import "../../ccMacros.h" + + +@interface ES1Renderer (private) + +- (GLenum) convertPixelFormat:(int) pixelFormat; + +@end + + +@implementation ES1Renderer + +@synthesize context=context_; + +- (id) initWithDepthFormat:(unsigned int)depthFormat withPixelFormat:(unsigned int)pixelFormat withSharegroup:(EAGLSharegroup*)sharegroup withMultiSampling:(BOOL) multiSampling withNumberOfSamples:(unsigned int) requestedSamples +{ + if ((self = [super init])) + { + if ( sharegroup == nil ) + { + context_ = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1]; + } + else + { + context_ = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1 sharegroup:sharegroup]; + } + + if (!context_ || ![EAGLContext setCurrentContext:context_]) + { + [self release]; + return nil; + } + + // Create default framebuffer object. The backing will be allocated for the current layer in -resizeFromLayer + glGenFramebuffersOES(1, &defaultFramebuffer_); + NSAssert( defaultFramebuffer_, @"Can't create default frame buffer"); + glGenRenderbuffersOES(1, &colorRenderbuffer_); + NSAssert( colorRenderbuffer_, @"Can't create default render buffer"); + + glBindFramebufferOES(GL_FRAMEBUFFER_OES, defaultFramebuffer_); + glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer_); + glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, colorRenderbuffer_); + + depthFormat_ = depthFormat; + + if( depthFormat_ ) { +// glGenRenderbuffersOES(1, &depthBuffer_); +// glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthBuffer_); +// glRenderbufferStorageOES(GL_RENDERBUFFER_OES, depthFormat_, 100, 100); +// glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthBuffer_); + + // default buffer +// glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer_); + } + + pixelFormat_ = pixelFormat; + multiSampling_ = multiSampling; + if (multiSampling_) + { + GLint maxSamplesAllowed; + glGetIntegerv(GL_MAX_SAMPLES_APPLE, &maxSamplesAllowed); + samplesToUse_ = MIN(maxSamplesAllowed,requestedSamples); + + /* Create the MSAA framebuffer (offscreen) */ + glGenFramebuffersOES(1, &msaaFramebuffer_); + glBindFramebufferOES(GL_FRAMEBUFFER_OES, msaaFramebuffer_); + + } + + CHECK_GL_ERROR(); + } + + return self; +} + +- (BOOL)resizeFromLayer:(CAEAGLLayer *)layer +{ + // Allocate color buffer backing based on the current layer size + + glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer_); + + if (![context_ renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:layer]) + { + CCLOG(@"failed to call context"); + } + + glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth_); + glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight_); + + CCLOG(@"cocos2d: surface size: %dx%d", (int)backingWidth_, (int)backingHeight_); + + if (multiSampling_) + { + + if ( msaaColorbuffer_) { + glDeleteRenderbuffersOES(1, &msaaColorbuffer_); + msaaColorbuffer_ = 0; + } + + /* Create the offscreen MSAA color buffer. + After rendering, the contents of this will be blitted into ColorRenderbuffer */ + + //msaaFrameBuffer needs to be binded + glBindFramebufferOES(GL_FRAMEBUFFER_OES, msaaFramebuffer_); + glGenRenderbuffersOES(1, &msaaColorbuffer_); + glBindRenderbufferOES(GL_RENDERBUFFER_OES, msaaColorbuffer_); + glRenderbufferStorageMultisampleAPPLE(GL_RENDERBUFFER_OES, samplesToUse_,pixelFormat_ , backingWidth_, backingHeight_); + glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, msaaColorbuffer_); + + if (glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) + { + CCLOG(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES)); + return NO; + } + } + + if (depthFormat_) + { + if( ! depthBuffer_ ) + glGenRenderbuffersOES(1, &depthBuffer_); + + glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthBuffer_); + if( multiSampling_ ) + glRenderbufferStorageMultisampleAPPLE(GL_RENDERBUFFER_OES, samplesToUse_, depthFormat_,backingWidth_, backingHeight_); + else + glRenderbufferStorageOES(GL_RENDERBUFFER_OES, depthFormat_, backingWidth_, backingHeight_); + glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthBuffer_); + + // bind color buffer + glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer_); + } + + glBindFramebufferOES(GL_FRAMEBUFFER_OES, defaultFramebuffer_); + + if (glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) + { + CCLOG(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES)); + return NO; + } + + CHECK_GL_ERROR(); + + return YES; +} + +-(CGSize) backingSize +{ + return CGSizeMake( backingWidth_, backingHeight_); +} + +- (NSString*) description +{ + return [NSString stringWithFormat:@"<%@ = %08X | size = %ix%i>", [self class], self, backingWidth_, backingHeight_]; +} + + +- (void)dealloc +{ + CCLOGINFO(@"cocos2d: deallocing %@", self); + + // Tear down GL + if(defaultFramebuffer_) + { + glDeleteFramebuffersOES(1, &defaultFramebuffer_); + defaultFramebuffer_ = 0; + } + + if(colorRenderbuffer_) + { + glDeleteRenderbuffersOES(1, &colorRenderbuffer_); + colorRenderbuffer_ = 0; + } + + if( depthBuffer_ ) + { + glDeleteRenderbuffersOES(1, &depthBuffer_); + depthBuffer_ = 0; + } + + if ( msaaColorbuffer_) + { + glDeleteRenderbuffersOES(1, &msaaColorbuffer_); + msaaColorbuffer_ = 0; + } + + if ( msaaFramebuffer_) + { + glDeleteRenderbuffersOES(1, &msaaFramebuffer_); + msaaFramebuffer_ = 0; + } + + // Tear down context + if ([EAGLContext currentContext] == context_) + [EAGLContext setCurrentContext:nil]; + + [context_ release]; + context_ = nil; + + [super dealloc]; +} + +- (unsigned int) colorRenderBuffer +{ + return colorRenderbuffer_; +} + +- (unsigned int) defaultFrameBuffer +{ + return defaultFramebuffer_; +} + +- (unsigned int) msaaFrameBuffer +{ + return msaaFramebuffer_; +} + +- (unsigned int) msaaColorBuffer +{ + return msaaColorbuffer_; +} + +@end + +#endif // __IPHONE_OS_VERSION_MAX_ALLOWED diff --git a/libs/cocos2d/Platforms/iOS/ESRenderer.h b/libs/cocos2d/Platforms/iOS/ESRenderer.h new file mode 100755 index 0000000..e612eee --- /dev/null +++ b/libs/cocos2d/Platforms/iOS/ESRenderer.h @@ -0,0 +1,54 @@ +/* + * cocos2d for iPhone: http://www.cocos2d-iphone.org + * + * Copyright (c) 2010 Ricardo Quesada + * Copyright (c) 2011 Zynga Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * + * File autogenerated with Xcode. Adapted for cocos2d needs. + */ + +// Only compile this code on iOS. These files should NOT be included on your Mac project. +// But in case they are included, it won't be compiled. +#import +#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED + +#import + +#import +#import + +@protocol ESRenderer + +- (id) initWithDepthFormat:(unsigned int)depthFormat withPixelFormat:(unsigned int)pixelFormat withSharegroup:(EAGLSharegroup*)sharegroup withMultiSampling:(BOOL) multiSampling withNumberOfSamples:(unsigned int) requestedSamples; + +- (BOOL) resizeFromLayer:(CAEAGLLayer *)layer; + +- (EAGLContext*) context; +- (CGSize) backingSize; + +- (unsigned int) colorRenderBuffer; +- (unsigned int) defaultFrameBuffer; +- (unsigned int) msaaFrameBuffer; +- (unsigned int) msaaColorBuffer; +@end + +#endif // __IPHONE_OS_VERSION_MAX_ALLOWED diff --git a/libs/cocos2d/Platforms/iOS/glu.c b/libs/cocos2d/Platforms/iOS/glu.c new file mode 100755 index 0000000..2e00d5f --- /dev/null +++ b/libs/cocos2d/Platforms/iOS/glu.c @@ -0,0 +1,113 @@ +// +// cocos2d (incomplete) GLU implementation +// +// gluLookAt and gluPerspective from: +// http://jet.ro/creations (San Angeles Observation) +// +// + +// Only compile this code on iOS. These files should NOT be included on your Mac project. +// But in case they are included, it won't be compiled. +#import +#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED + +#import +#import +#import "../../Support/OpenGL_Internal.h" +#include "glu.h" + +void gluPerspective(GLfloat fovy, GLfloat aspect, GLfloat zNear, GLfloat zFar) +{ + GLfloat xmin, xmax, ymin, ymax; + + ymax = zNear * (GLfloat)tanf(fovy * (float)M_PI / 360); + ymin = -ymax; + xmin = ymin * aspect; + xmax = ymax * aspect; + + glFrustumf(xmin, xmax, + ymin, ymax, + zNear, zFar); +} + +void gluLookAt(GLfloat eyex, GLfloat eyey, GLfloat eyez, + GLfloat centerx, GLfloat centery, GLfloat centerz, + GLfloat upx, GLfloat upy, GLfloat upz) +{ + GLfloat m[16]; + GLfloat x[3], y[3], z[3]; + GLfloat mag; + + /* Make rotation matrix */ + + /* Z vector */ + z[0] = eyex - centerx; + z[1] = eyey - centery; + z[2] = eyez - centerz; + mag = (float)sqrtf(z[0] * z[0] + z[1] * z[1] + z[2] * z[2]); + if (mag) { + z[0] /= mag; + z[1] /= mag; + z[2] /= mag; + } + + /* Y vector */ + y[0] = upx; + y[1] = upy; + y[2] = upz; + + /* X vector = Y cross Z */ + x[0] = y[1] * z[2] - y[2] * z[1]; + x[1] = -y[0] * z[2] + y[2] * z[0]; + x[2] = y[0] * z[1] - y[1] * z[0]; + + /* Recompute Y = Z cross X */ + y[0] = z[1] * x[2] - z[2] * x[1]; + y[1] = -z[0] * x[2] + z[2] * x[0]; + y[2] = z[0] * x[1] - z[1] * x[0]; + + /* cross product gives area of parallelogram, which is < 1.0 for + * non-perpendicular unit-length vectors; so normalize x, y here + */ + + mag = (float)sqrtf(x[0] * x[0] + x[1] * x[1] + x[2] * x[2]); + if (mag) { + x[0] /= mag; + x[1] /= mag; + x[2] /= mag; + } + + mag = (float)sqrtf(y[0] * y[0] + y[1] * y[1] + y[2] * y[2]); + if (mag) { + y[0] /= mag; + y[1] /= mag; + y[2] /= mag; + } + +#define M(row,col) m[col*4+row] + M(0, 0) = x[0]; + M(0, 1) = x[1]; + M(0, 2) = x[2]; + M(0, 3) = 0.0f; + M(1, 0) = y[0]; + M(1, 1) = y[1]; + M(1, 2) = y[2]; + M(1, 3) = 0.0f; + M(2, 0) = z[0]; + M(2, 1) = z[1]; + M(2, 2) = z[2]; + M(2, 3) = 0.0f; + M(3, 0) = 0.0f; + M(3, 1) = 0.0f; + M(3, 2) = 0.0f; + M(3, 3) = 1.0f; +#undef M + + glMultMatrixf(m); + + + /* Translate Eye to Origin */ + glTranslatef(-eyex, -eyey, -eyez); +} + +#endif // __IPHONE_OS_VERSION_MAX_ALLOWED diff --git a/libs/cocos2d/Platforms/iOS/glu.h b/libs/cocos2d/Platforms/iOS/glu.h new file mode 100755 index 0000000..86dcac7 --- /dev/null +++ b/libs/cocos2d/Platforms/iOS/glu.h @@ -0,0 +1,29 @@ +// +// cocos2d GLU implementation +// +// implementation of GLU functions +// +#ifndef __COCOS2D_GLU_H +#define __COCOS2D_GLU_H + +// Only compile this code on iOS. These files should NOT be included on your Mac project. +// But in case they are included, it won't be compiled. +#import +#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED + +#import + +/** + @file + cocos2d OpenGL GLU implementation + */ + +/** OpenGL gluLookAt implementation */ +void gluLookAt(float eyeX, float eyeY, float eyeZ, float lookAtX, float lookAtY, float lookAtZ, float upX, float upY, float upZ); +/** OpenGL gluPerspective implementation */ +void gluPerspective(GLfloat fovy, GLfloat aspect, GLfloat zNear, GLfloat zFar); + +#endif // __IPHONE_OS_VERSION_MAX_ALLOWED + +#endif /* __COCOS2D_GLU_H */ + -- cgit 1.4.1