From 7321d33aaf835d945f83cc0c24ba816007853b75 Mon Sep 17 00:00:00 2001 From: Wartortle Date: Thu, 8 Mar 2012 11:23:47 +0000 Subject: [PATCH] Added support files for Accelerometer Simulation for iPhone Simulator and Unimotion Ref: http://code.google.com/p/accelerometer-simulator/wiki/Home Ref: https://github.com/gmarik/unimotion --- .../ios/Simulation/AccelerometerSimulation.h | 59 +++++ .../ios/Simulation/AccelerometerSimulation.m | 238 ++++++++++++++++++ tests/test.ios/main.m | 3 + .../project.pbxproj.REMOVED.git-id | 2 +- 4 files changed, 301 insertions(+), 1 deletion(-) create mode 100644 cocos2dx/platform/ios/Simulation/AccelerometerSimulation.h create mode 100644 cocos2dx/platform/ios/Simulation/AccelerometerSimulation.m diff --git a/cocos2dx/platform/ios/Simulation/AccelerometerSimulation.h b/cocos2dx/platform/ios/Simulation/AccelerometerSimulation.h new file mode 100644 index 0000000000..c1758163d9 --- /dev/null +++ b/cocos2dx/platform/ios/Simulation/AccelerometerSimulation.h @@ -0,0 +1,59 @@ +/* + * AccelerometerSimulation.h + * AccelerometerGraph + * + * Created by Otto Chrons on 9/26/08. + * Copyright 2008 Seastringo Oy. All rights reserved. + * + */ +#import + +// when compiling to ARM (iPhone device), hide everything and use system defaults +// if you wish to use simulation mode even on the device, remove the #if/#endif +#if !TARGET_CPU_ARM +#import + +// this is exactly the same as UIAcceleration, but we can modify the member variables +@interface UIAccelerationSimulation: NSObject +{ + NSTimeInterval timestamp; + UIAccelerationValue x, y, z; +} +@property(nonatomic, readonly) NSTimeInterval timestamp; +@property(nonatomic, readonly) UIAccelerationValue x, y, z; + +@end + +// override UIAccelerometer behaviour +@interface UIAccelerometer (Simulation) ++ (UIAccelerometer *)sharedAccelerometer; +@end + +// our own version of the Accelerometer +@interface AccelerometerSimulation : UIAccelerometer +{ + + //CFSocketRef udpSocket; + int udpSocket; + NSThread *thread; + BOOL isExiting; + id accelDelegate; + UIAccelerationSimulation *accObject; + // Threaded notification support + NSMutableArray *notifications; + NSThread *notificationThread; + NSLock *notificationLock; + NSMachPort *notificationPort; +} + +@property(nonatomic, assign) id delegate; + +- (void) setUpThreadingSupport; +- (void) handleMachMessage:(void *) msg; +- (void) processNotification:(NSNotification *) notification; ++ (AccelerometerSimulation *)getAccelerometer; +- (AccelerometerSimulation *)initialize; + +@end + +#endif diff --git a/cocos2dx/platform/ios/Simulation/AccelerometerSimulation.m b/cocos2dx/platform/ios/Simulation/AccelerometerSimulation.m new file mode 100644 index 0000000000..f10de2598b --- /dev/null +++ b/cocos2dx/platform/ios/Simulation/AccelerometerSimulation.m @@ -0,0 +1,238 @@ +// +// AccelerometerSimulation.m +// AccelerometerGraph +// +// Created by Otto Chrons on 9/26/08. +// Copyright 2008 Seastringo Oy. All rights reserved. +// + +#import "AccelerometerSimulation.h" + +// when compiling to ARM (iPhone device), hide everything and use system defaults +// if you wish to use simulation mode even on the device, remove the #if/#endif +#if !TARGET_CPU_ARM + +#import + +#define kAccelerometerSimulationPort 10552 + +@implementation UIAccelerationSimulation + +@synthesize timestamp; +@synthesize x; +@synthesize y; +@synthesize z; + +-(UIAccelerationSimulation*)initWithTimestamp:(NSTimeInterval)aTimeStamp + X:(UIAccelerationValue)ax + Y:(UIAccelerationValue)ay + Z:(UIAccelerationValue)az +{ + timestamp = aTimeStamp; + x = ax; + y = ay; + z = az; + + return self; +} +@end + +@implementation UIAccelerometer (Simulation) + +// override the static method and return our simulated version instead ++ (UIAccelerometer *)sharedAccelerometer +{ + return [AccelerometerSimulation getAccelerometer]; +} +@end +/* + // callback that never got called with CFSocket UDP... + + void mySocketCallBack( CFSocketRef s, + CFSocketCallBackType callbackType, + CFDataRef address, + const void *data, + void *info) + { + AccelerometerSimulation *accSim = (AccelerometerSimulation*)info; + + NSLog(@"Data %s received", (char*)data); + } + */ + +// singleton +static AccelerometerSimulation *sharedAccelerometer = NULL; + +@implementation AccelerometerSimulation + +// this is straight from developer guide example for multi-threaded notifications +- (void) setUpThreadingSupport { + if ( notifications ) return; + + notifications = [[NSMutableArray alloc] init]; + notificationLock = [[NSLock alloc] init]; + notificationThread = [[NSThread currentThread] retain]; + + notificationPort = [[NSMachPort alloc] init]; + [notificationPort setDelegate:self]; + [[NSRunLoop currentRunLoop] addPort:notificationPort + forMode:(NSString *) kCFRunLoopCommonModes]; +} + +// this is straight from developer guide example + +- (void) processNotification:(NSNotification *) notification { + if( [NSThread currentThread] != notificationThread ) { + // Forward the notification to the correct thread, this is the socket thread + NSDate* date = [[NSDate alloc] init]; + [notificationLock lock]; + [notifications addObject:notification]; + [notificationLock unlock]; + [notificationPort sendBeforeDate:date + components:nil + from:nil + reserved:0]; + [date release]; + } + else { + // now we are in the main thread + // Process the notification here; + NSString *data = (NSString*)[notification object]; + + // parse the data, no error handling! + NSArray *components = [data componentsSeparatedByString:@","]; + + // create our own acceleration object + [accObject initWithTimestamp:[[components objectAtIndex:1] doubleValue] + X:[[components objectAtIndex:2] doubleValue] + Y:[[components objectAtIndex:3] doubleValue] + Z:[[components objectAtIndex:4] doubleValue]]; + [accelDelegate accelerometer:self didAccelerate:(UIAcceleration*)accObject]; + } +} + +// this is straight from developer guide example +- (void) handleMachMessage:(void *) msg { + [notificationLock lock]; + while ( [notifications count] ) { + NSNotification *notification = [[notifications objectAtIndex:0] retain]; + [notifications removeObjectAtIndex:0]; + [notificationLock unlock]; + [self processNotification:notification]; + [notification release]; + [notificationLock lock]; + }; + [notificationLock unlock]; +} + ++ (AccelerometerSimulation *)getAccelerometer +{ + if( sharedAccelerometer == NULL ) + sharedAccelerometer = [[AccelerometerSimulation alloc] initialize]; + + return sharedAccelerometer; +} + +- (void)threadLoop:(id)object +{ + char buffer[1024]; + // we never exit... + while(1) { + int count = recv( udpSocket, buffer, sizeof(buffer), 0 ); + if( count > 0 ) + { + // got data, let's pass it on + buffer[count] = 0; + NSString *str = [[NSString alloc] initWithUTF8String:buffer]; + [[NSNotificationCenter defaultCenter] postNotificationName:@"ThreadAccelNotification" object:str]; + [str release]; + } + + } +} + +// initialize our version of the accelerometer +- (AccelerometerSimulation *)initialize +{ + accObject = [UIAccelerationSimulation alloc]; + isExiting = false; + + // couldn't get the CFSocket version to work with UDP and runloop, so used Berkely sockets and a thread instead + + udpSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + struct sockaddr_in sin; + memset(&sin, 0, sizeof(sin)); + // listen on all interfaces + sin.sin_addr.s_addr = INADDR_ANY; + sin.sin_len = sizeof(struct sockaddr_in); + sin.sin_family = AF_INET; + sin.sin_port = htons(kAccelerometerSimulationPort); + + bind(udpSocket, (const struct sockaddr*)&sin, sizeof(sin)); + + // create a separate thread for receiving UDP packets + thread = [[NSThread alloc] initWithTarget:self + selector:@selector(threadLoop:) + object:nil]; + [thread start]; + + // cross-thread communication setup + [self setUpThreadingSupport]; + [[NSNotificationCenter defaultCenter] + addObserver:self + selector:@selector(processNotification:) + name:@"ThreadAccelNotification" + object:nil]; + /* + // create and initialize a socket + CFSocketContext ctx; + + ctx.info = self; + ctx.version = 0; + ctx.retain = NULL; + ctx.release = NULL; + ctx.copyDescription = NULL; + udpSocket = CFSocketCreate(NULL, PF_INET, SOCK_DGRAM, IPPROTO_UDP, kCFSocketDataCallBack | 0xF, mySocketCallBack, NULL); + + CFRunLoopSourceRef source; + CFDataRef addr; + CFSocketError theErr; + struct sockaddr_in sin; + memset(&sin, 0, sizeof(sin)); + sin.sin_addr.s_addr = INADDR_ANY; + sin.sin_len = sizeof(struct sockaddr_in); + sin.sin_family = AF_INET; + sin.sin_port = htons(10552); + addr = CFDataCreate(NULL, (unsigned char *)&sin, sizeof(sin)); + theErr = CFSocketConnectToAddress(udpSocket, addr, 0); + switch (theErr) { + case kCFSocketSuccess: + NSLog(@"UDP Logged in"); + source = CFSocketCreateRunLoopSource(NULL, udpSocket, 0); + CFRunLoopAddSource(CFRunLoopGetMain(), source, + kCFRunLoopDefaultMode); + break; + case kCFSocketError: + NSLog(@"UDP Error"); + break; + default: + NSLog(@"UDP Networking Error"); + break; + } + */ + return self; +} + +// we grab the delegate setting action +- (void)setDelegate:(id)delegate +{ + accelDelegate = delegate; +} + +- (id)delegate +{ + return accelDelegate; +} +@end + +#endif diff --git a/tests/test.ios/main.m b/tests/test.ios/main.m index bd577a036e..3c971fe0ab 100644 --- a/tests/test.ios/main.m +++ b/tests/test.ios/main.m @@ -8,6 +8,9 @@ #import +// Under iOS and the Simulator, we can use an alternate Accelerometer interface +#import "cocos2dx/platform/ios/Simulation/AccelerometerSimulation.h" + int main(int argc, char *argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; diff --git a/tests/test.ios/test.xcodeproj/project.pbxproj.REMOVED.git-id b/tests/test.ios/test.xcodeproj/project.pbxproj.REMOVED.git-id index 3558b0be19..3d9f9b6be1 100644 --- a/tests/test.ios/test.xcodeproj/project.pbxproj.REMOVED.git-id +++ b/tests/test.ios/test.xcodeproj/project.pbxproj.REMOVED.git-id @@ -1 +1 @@ -1f8f32d78bea826a70239a16e0ff68580333d9b1 \ No newline at end of file +dcf8ba0491db5fef75efe24f9e2c9fdf07364507 \ No newline at end of file