nuclear@39: /* nuclear@39: Stereoscopic tunnel for iOS. nuclear@39: Copyright (C) 2011 John Tsiombikas nuclear@39: nuclear@39: This program is free software: you can redistribute it and/or modify nuclear@39: it under the terms of the GNU General Public License as published by nuclear@39: the Free Software Foundation, either version 3 of the License, or nuclear@39: (at your option) any later version. nuclear@39: nuclear@39: This program is distributed in the hope that it will be useful, nuclear@39: but WITHOUT ANY WARRANTY; without even the implied warranty of nuclear@39: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the nuclear@39: GNU General Public License for more details. nuclear@39: nuclear@39: You should have received a copy of the GNU General Public License nuclear@39: along with this program. If not, see . nuclear@39: */ nuclear@39: nuclear@39: /* XXX this file is mostly generated from Xcode and therefore sucks ass */ nuclear@39: nuclear@35: #import "EAGLView.h" nuclear@35: #import "ES2Renderer.h" nuclear@35: #import "ui.h" nuclear@0: nuclear@0: nuclear@35: static UI *optgui; nuclear@35: nuclear@0: nuclear@0: @implementation EAGLView nuclear@0: nuclear@0: @synthesize animating; nuclear@0: @dynamic animationFrameInterval; nuclear@0: nuclear@0: // You must implement this method nuclear@0: + (Class)layerClass nuclear@0: { nuclear@35: return [CAEAGLLayer class]; nuclear@0: } nuclear@0: nuclear@0: //The EAGL view is stored in the nib file. When it's unarchived it's sent -initWithCoder: nuclear@0: - (id)initWithCoder:(NSCoder*)coder nuclear@30: { nuclear@35: if ((self = [super initWithCoder:coder])) nuclear@35: { nuclear@35: // Get the layer nuclear@35: CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer; nuclear@0: nuclear@30: //self.contentScaleFactor = 2.0; nuclear@30: nuclear@35: eaglLayer.opaque = TRUE; nuclear@35: eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys: nuclear@35: [NSNumber numberWithBool:FALSE], kEAGLDrawablePropertyRetainedBacking, kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil]; nuclear@0: nuclear@35: renderer = [[ES2Renderer alloc] init]; nuclear@35: if (!renderer) { nuclear@35: [self release]; nuclear@35: return nil; nuclear@35: } nuclear@0: nuclear@35: animating = FALSE; nuclear@35: displayLinkSupported = FALSE; nuclear@35: animationFrameInterval = 1; nuclear@35: displayLink = nil; nuclear@35: animationTimer = nil; nuclear@0: nuclear@35: // A system version of 3.1 or greater is required to use CADisplayLink. The NSTimer nuclear@35: // class is used as fallback when it isn't available. nuclear@35: NSString *reqSysVer = @"3.1"; nuclear@35: NSString *currSysVer = [[UIDevice currentDevice] systemVersion]; nuclear@35: if ([currSysVer compare:reqSysVer options:NSNumericSearch] != NSOrderedAscending) nuclear@35: displayLinkSupported = TRUE; nuclear@30: nuclear@30: self.multipleTouchEnabled = 1; nuclear@0: nuclear@35: // load the options gui nuclear@35: optgui = [[UI alloc] initWithNibName:@"ui" bundle: [NSBundle mainBundle]]; nuclear@35: hide_options(); nuclear@35: [self addSubview: optgui.view]; nuclear@35: } nuclear@35: nuclear@35: return self; nuclear@0: } nuclear@0: nuclear@0: - (void)drawView:(id)sender nuclear@0: { nuclear@35: [renderer render]; nuclear@0: } nuclear@0: nuclear@0: - (void)layoutSubviews nuclear@0: { nuclear@35: [renderer resizeFromLayer:(CAEAGLLayer*)self.layer]; nuclear@35: [self drawView:nil]; nuclear@0: } nuclear@0: nuclear@0: - (NSInteger)animationFrameInterval nuclear@0: { nuclear@35: return animationFrameInterval; nuclear@0: } nuclear@0: nuclear@0: - (void)setAnimationFrameInterval:(NSInteger)frameInterval nuclear@0: { nuclear@35: // Frame interval defines how many display frames must pass between each time the nuclear@35: // display link fires. The display link will only fire 30 times a second when the nuclear@35: // frame internal is two on a display that refreshes 60 times a second. The default nuclear@35: // frame interval setting of one will fire 60 times a second when the display refreshes nuclear@35: // at 60 times a second. A frame interval setting of less than one results in undefined nuclear@35: // behavior. nuclear@35: if (frameInterval >= 1) nuclear@35: { nuclear@35: animationFrameInterval = frameInterval; nuclear@0: nuclear@35: if (animating) nuclear@35: { nuclear@35: [self stopAnimation]; nuclear@35: [self startAnimation]; nuclear@35: } nuclear@35: } nuclear@0: } nuclear@0: nuclear@0: - (void)startAnimation nuclear@0: { nuclear@35: if (!animating) nuclear@35: { nuclear@35: if (displayLinkSupported) nuclear@35: { nuclear@35: // CADisplayLink is API new to iPhone SDK 3.1. Compiling against earlier versions will result in a warning, but can be dismissed nuclear@35: // if the system version runtime check for CADisplayLink exists in -initWithCoder:. The runtime check ensures this code will nuclear@35: // not be called in system versions earlier than 3.1. nuclear@0: nuclear@35: displayLink = [NSClassFromString(@"CADisplayLink") displayLinkWithTarget:self selector:@selector(drawView:)]; nuclear@35: [displayLink setFrameInterval:animationFrameInterval]; nuclear@35: [displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; nuclear@35: } nuclear@35: else nuclear@35: animationTimer = [NSTimer scheduledTimerWithTimeInterval:(NSTimeInterval)((1.0 / 60.0) * animationFrameInterval) target:self selector:@selector(drawView:) userInfo:nil repeats:TRUE]; nuclear@0: nuclear@35: animating = TRUE; nuclear@35: } nuclear@0: } nuclear@0: nuclear@0: - (void)stopAnimation nuclear@0: { nuclear@35: if (animating) nuclear@35: { nuclear@35: if (displayLinkSupported) nuclear@35: { nuclear@35: [displayLink invalidate]; nuclear@35: displayLink = nil; nuclear@35: } nuclear@35: else nuclear@35: { nuclear@35: [animationTimer invalidate]; nuclear@35: animationTimer = nil; nuclear@35: } nuclear@0: nuclear@35: animating = FALSE; nuclear@35: } nuclear@0: } nuclear@0: nuclear@30: static int touch_active; nuclear@30: static CGPoint start_touch; nuclear@30: extern int use_bump; nuclear@30: nuclear@30: - (void) touchesBegan: (NSSet*) touches withEvent: (UIEvent*) event nuclear@30: { nuclear@30: UITouch *touch = [[touches allObjects] objectAtIndex: 0]; nuclear@30: nuclear@30: start_touch = [touch locationInView: self]; nuclear@30: touch_active = 1; nuclear@30: } nuclear@30: nuclear@30: - (void) touchesEnded: (NSSet*) touches withEvent: (UIEvent*) event nuclear@30: { nuclear@30: UITouch *touch = [[touches allObjects] objectAtIndex: 0]; nuclear@30: nuclear@30: CGPoint end_touch = [touch locationInView: self]; nuclear@30: int dx = end_touch.x - start_touch.x; nuclear@30: int dy = end_touch.y - start_touch.y; nuclear@30: nuclear@30: if(dx * dx + dy * dy < 30) { nuclear@35: show_options(); nuclear@30: } nuclear@30: } nuclear@30: nuclear@0: - (void)dealloc nuclear@0: { nuclear@35: [renderer release]; nuclear@0: nuclear@35: [super dealloc]; nuclear@0: } nuclear@0: nuclear@0: @end nuclear@35: nuclear@35: void show_options(void) nuclear@35: { nuclear@35: assert(optgui); nuclear@35: optgui.view.hidden = NO; nuclear@35: } nuclear@35: nuclear@35: void hide_options(void) nuclear@35: { nuclear@35: assert(optgui); nuclear@35: optgui.view.hidden = YES; nuclear@35: }