#include #include #include #import #import #import #import "FriskyApplication.h" @implementation FriskyApplication - (void)takeScreenshotAndSaveToPath: (NSString *)path { CGImageRef img = [self createApplicationDefaultPNG]; CGImageDestinationRef exportDestination = CGImageDestinationCreateWithURL(CFURLCreateWithFileSystemPath( kCFAllocatorDefault, (CFStringRef)path, kCFURLPOSIXPathStyle, false), CFSTR("public.png"), 1, NULL); CGImageDestinationAddImage(exportDestination, img, NULL); CGImageDestinationFinalize(exportDestination); } - (void)loadControlHitBoxMap { CFURLRef url; CGDataProviderRef dataProvider; CGColorSpaceRef colorSpace; CGImageRef controlHitBoxImage; colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); controlHitBoxData = (unsigned int *)malloc(320*460*4); controlHitBoxContext = CGBitmapContextCreate(controlHitBoxData, 320, 460, 8, 320 * 4, colorSpace, kCGImageAlphaPremultipliedLast); url = CFBundleCopyResourceURL(CFBundleGetMainBundle(), CFSTR("ControlHitBoxes"), CFSTR("png"), NULL); dataProvider = CGDataProviderCreateWithURL(url); controlHitBoxImage = CGImageCreateWithPNGDataProvider(dataProvider, NULL, false, kCGRenderingIntentDefault); CGContextDrawImage(controlHitBoxContext, CGRectMake(0.0f, 0.0f, 320.0f, 460.0f), controlHitBoxImage); CGImageRelease(controlHitBoxImage); CFRelease(url); CGDataProviderRelease(dataProvider); CGColorSpaceRelease(colorSpace); controlHitBoxInfo = [[NSDictionary alloc] initWithContentsOfFile: [[NSBundle mainBundle] pathForResource: @"ControlHitBoxInfo" ofType: @"plist"]]; } - (void)reloadROMArray { NSArray *files, *strs; NSEnumerator *e; NSString *filename, *prettyFilename; UIImageAndTextTableCell *tableCell; if (ROMArray) [ROMArray release]; ROMArray = [[NSMutableArray alloc] init]; files = [[NSFileManager defaultManager] directoryContentsAtPath: @"/var/root/Media/ROMs/SNES"]; if (!files) return; e = [files objectEnumerator]; while ((filename = (NSString *)[e nextObject])) { strs = [filename componentsSeparatedByString: @"."]; if ([strs count] < 2) continue; prettyFilename = [strs objectAtIndex: [strs count] - 2]; tableCell = [[UIImageAndTextTableCell alloc] init]; [tableCell setTitle: prettyFilename]; [tableCell setShowDisclosure: YES]; [ROMArray addObject: [NSDictionary dictionaryWithObjectsAndKeys: [NSString stringWithFormat: @"/var/root/Media/ROMs/SNES/%@", filename], @"Path", prettyFilename, @"PrettyFilename", tableCell, @"Cell", nil]]; } } - (int)numberOfRowsInTable: (UITable *)table { return [ROMArray count]; } - (UITableCell *)table: (UITable *)table cellForRow: (int)row column: (int)col { return [[ROMArray objectAtIndex: row] objectForKey: @"Cell"]; } - (BOOL)shouldShowDisclosureForItemAtRow: (int)row inDataSource:(id) dataSource { return YES; } - (void)userDidChooseROMWithPath: (NSString *)path { [navigationBar pushNavigationItem: [[UINavigationItem alloc] initWithTitle: @"Controls Test"]]; [navigationBar setBarStyle: 1]; [navigationBar showButtonsWithLeftTitle: nil rightTitle: @"Options" leftBack: YES]; [self setStatusBarMode: 1 orientation: 0 duration: [UITransitionView defaultDurationForTransition: 1]]; [transitionView transition: 1 toView: gameplayView]; appMode = 1; [self performSelector: @selector(takeScreenshotAndSaveToPath:) withObject: @"/tmp/Controls.png" afterDelay: 5.0]; } - (void)tableSelectionDidChange: (NSNotification *)notif { [self userDidChooseROMWithPath: [[ROMArray objectAtIndex: [loadROMTable selectedRow]] objectForKey: @"Path"]]; } - (void)performHitTestForPoint: (CGPoint)pt { NSArray *buttons; NSString *colorCode; int colorCodes[3]; int i; unsigned int rawChannel, rawColor, x, y; x = (unsigned int)rintf(pt.x); y = (unsigned int)rintf(pt.y); rawColor = controlHitBoxData[x + 320 * y]; for (i = 0; i < 3; i++) { rawChannel = (rawColor & 0xff); switch (rawChannel) { case 0x00 ... 0x5f: colorCodes[i] = 0; break; case 0x60 ... 0xbf: colorCodes[i] = 1; break; case 0xc0 ... 0xff: colorCodes[i] = 2; } rawColor >>= 8; } colorCode = [NSString stringWithFormat: @"R%dG%dB%d", colorCodes[0], colorCodes[1], colorCodes[2]]; buttons = [[controlHitBoxInfo objectForKey: x < 160 ? @"Left" : @"Right"] objectForKey: colorCode]; if (!buttons) [[navigationBar topItem] setTitle: @"No buttons"]; else [[navigationBar topItem] setTitle: [buttons description]]; [buttonState addObjectsFromArray: buttons]; } - (BOOL)handleEvent:(GSEventRef)event { BOOL result; unsigned int button, type; struct CGPoint pt; struct CGPoint pt2; NSEnumerator *e; NSNumber *buttonNumber; result = [super handleEvent: event]; if (!result) return result; type = GSEventGetType(event); switch (type) { case kGSEventTypeOneFingerDown: case kGSEventTypeAllFingersUp: case kGSEventTypeOneFingerUp: case kGSEventTypeGesture: [prevButtonState setSet: buttonState]; [buttonState removeAllObjects]; break; default: return result; } if (type != kGSEventTypeAllFingersUp) { if (!GSEventIsChordingHandEvent(event)) { pt = GSEventGetLocationInWindow(event); [self performHitTestForPoint: pt]; } else { pt = GSEventGetInnerMostPathPosition(event); pt2 = GSEventGetOuterMostPathPosition(event); [self performHitTestForPoint: pt]; [self performHitTestForPoint: pt2]; } } /* Turn off buttons that were down last frame but are not this frame. */ [deltaButtonState setSet: prevButtonState]; [deltaButtonState minusSet: buttonState]; e = [deltaButtonState objectEnumerator]; while ((buttonNumber = [e nextObject])) { button = [buttonNumber unsignedIntValue]; [buttonImageViews[button] setImage: buttonImages[button]]; [buttonImageViews[button] setNeedsDisplay]; } /* Turn on buttons that were not down last frame but are this frame. */ [deltaButtonState setSet: buttonState]; [deltaButtonState minusSet: prevButtonState]; e = [deltaButtonState objectEnumerator]; while ((buttonNumber = [e nextObject])) { button = [buttonNumber unsignedIntValue]; [buttonImageViews[button] setImage: highlightedButtonImages[button]]; [buttonImageViews[button] setNeedsDisplay]; } return result; } - (void)initControls { float controlAreaTop, controlAreaHeight; int i; buttonImages[0] = [[UIImage imageNamed: @"ButtonY.png"] retain]; buttonImages[1] = [[UIImage imageNamed: @"ButtonB.png"] retain]; buttonImages[2] = [[UIImage imageNamed: @"ButtonA.png"] retain]; buttonImages[3] = [[UIImage imageNamed: @"ButtonX.png"] retain]; buttonImages[8] = [[UIImage imageNamed: @"ButtonL.png"] retain]; buttonImages[9] = [[UIImage imageNamed: @"ButtonR.png"] retain]; buttonImages[10] = [[UIImage imageNamed: @"ButtonSelect.png"] retain]; buttonImages[11] = [[UIImage imageNamed: @"ButtonStart.png"] retain]; highlightedButtonImages[0] = [[UIImage imageNamed: @"HighlightedButtonY.png"] retain]; highlightedButtonImages[1] = [[UIImage imageNamed: @"HighlightedButtonB.png"] retain]; highlightedButtonImages[2] = [[UIImage imageNamed: @"HighlightedButtonA.png"] retain]; highlightedButtonImages[3] = [[UIImage imageNamed: @"HighlightedButtonX.png"] retain]; highlightedButtonImages[8] = [[UIImage imageNamed: @"HighlightedButtonL.png"] retain]; highlightedButtonImages[9] = [[UIImage imageNamed: @"HighlightedButtonR.png"] retain]; highlightedButtonImages[10] = [[UIImage imageNamed: @"HighlightedButtonSelect.png"] retain]; highlightedButtonImages[11] = [[UIImage imageNamed: @"HighlightedButtonStart.png"] retain]; for (i = 4; i < 8; i++) { buttonImages[i] = [[UIImage imageNamed: @"DPadButton.png"] retain]; highlightedButtonImages[i] = [[UIImage imageNamed: @"HighlightedDPadButton.png"] retain]; } controlAreaTop = 239.0f + 8.0f; controlAreaHeight = [gameplayView frame].size.height - controlAreaTop; /* YBAX */ buttonImageViews[0] = [[UIImageView alloc] initWithFrame: CGRectMake( 160.0f + 8.0f, controlAreaTop + controlAreaHeight / 2.0f - 24.0f, 48.0f, 48.0f)]; buttonImageViews[1] = [[UIImageView alloc] initWithFrame: CGRectMake( 160.0f + 8.0f + 48.0f, controlAreaTop + controlAreaHeight / 2.0f - 24.0f + 48.0f, 48.0f, 48.0f)]; buttonImageViews[2] = [[UIImageView alloc] initWithFrame: CGRectMake( 160.0f + 8.0f + 48.0f*2, controlAreaTop + controlAreaHeight / 2.0f - 24.0f, 48.0f, 48.0f)]; buttonImageViews[3] = [[UIImageView alloc] initWithFrame: CGRectMake( 160.0f + 8.0f + 48.0f, controlAreaTop + controlAreaHeight / 2.0f - 24.0f - 48.0f, 48.0f, 48.0f)]; /* D-Pad */ buttonImageViews[4] = [[UIImageView alloc] initWithFrame: CGRectMake( 16.0f, controlAreaTop + controlAreaHeight / 2.0f - 30.0f, 60.0f, 60.0f)]; buttonImageViews[5] = [[UIImageView alloc] initWithFrame: CGRectMake( 50.0f, controlAreaTop + controlAreaHeight / 2.0f - 64.0f, 60.0f, 60.0f)]; [buttonImageViews[5] setRotationBy: 90.0f]; buttonImageViews[6] = [[UIImageView alloc] initWithFrame: CGRectMake( 50.0f, controlAreaTop + controlAreaHeight / 2.0f + 4.0f, 60.0f, 60.0f)]; [buttonImageViews[6] setRotationBy: 270.0f]; buttonImageViews[7] = [[UIImageView alloc] initWithFrame: CGRectMake( 84.0f, controlAreaTop + controlAreaHeight / 2.0f - 30.0f, 60.0f, 60.0f)]; [buttonImageViews[7] setRotationBy: 180.0f]; /* L, R, Select, Start */ buttonImageViews[8] = [[UIImageView alloc] initWithFrame: CGRectMake( 168.0f, controlAreaTop + controlAreaHeight / 2.0f - 72.0f, 32.0f, 32.0f)]; buttonImageViews[9] = [[UIImageView alloc] initWithFrame: CGRectMake( 320.0f - 8.0f - 32.0f, controlAreaTop + controlAreaHeight / 2.0f - 72.0f, 32.0f, 32.0f)]; buttonImageViews[10] = [[UIImageView alloc] initWithFrame: CGRectMake( 168.0f, ceilf(controlAreaTop + controlAreaHeight / 2.0f + 40.0f), 32.0f, 32.0f)]; buttonImageViews[11] = [[UIImageView alloc] initWithFrame: CGRectMake( 320.0f - 8.0f - 32.0f, ceilf(controlAreaTop + controlAreaHeight / 2.0f + 40.0f), 32.0f, 32.0f)]; [self loadControlHitBoxMap]; for (i = 0; i < 12; i++) { [buttonImageViews[i] setImage: buttonImages[i]]; [gameplayView addSubview: buttonImageViews[i]]; } buttonState = [[NSMutableSet alloc] init]; deltaButtonState = [[NSMutableSet alloc] init]; prevButtonState = [[NSMutableSet alloc] init]; } - (void)applicationDidFinishLaunching: (id)sender { struct CGRect rect; CGColorSpaceRef colorSpace; UINavigationItem *loadROMNavigationItem; UITableColumn *loadROMTableColumn; UIView *contentView; colorSpace = CGColorSpaceCreateDeviceRGB(); appMode = 0; window = [[UIWindow alloc] initWithContentRect: [UIHardware fullScreenApplicationContentRect]]; rect.origin.x = rect.origin.y = 0.0f; rect.size = [UIHardware fullScreenApplicationContentRect].size; contentView = [[UIView alloc] initWithFrame: rect]; loadROMNavigationItem = [[UINavigationItem alloc] initWithTitle: @"Load ROM"]; [loadROMNavigationItem setBackButtonTitle: @"Load"]; rect.origin.x = rect.origin.y = 0.0f; rect.size = [UINavigationBar defaultSize]; navigationBar = [[UINavigationBar alloc] initWithFrame: rect]; [navigationBar pushNavigationItem: loadROMNavigationItem]; [navigationBar enableAnimation]; rect.origin.x = 0.0f; rect.origin.y = [UINavigationBar defaultSize].height; rect.size.width = [UIHardware mainScreenSize].width; rect.size.height = [UIHardware fullScreenApplicationContentRect].size.height - [UINavigationBar defaultSize].height; transitionView = [[UITransitionView alloc] initWithFrame: rect]; rect.origin.y = 0.0f; loadROMTable = [[UITable alloc] initWithFrame: rect]; [loadROMTable setSeparatorStyle: 1]; gameplayView = [[UIView alloc] initWithFrame: rect]; [gameplayView setOpaque: YES]; [gameplayView setBackgroundColor: CGColorCreate(colorSpace, (const float[]) { 0.0f, 0.0f, 0.0f, 1.0f })]; loadROMTableColumn = [[UITableColumn alloc] initWithTitle: @"ROM" identifier: @"romName" width: [UIHardware mainScreenSize].width]; ROMArray = nil; [self reloadROMArray]; [loadROMTable addTableColumn: loadROMTableColumn]; [loadROMTable setDataSource: self]; [loadROMTable setDelegate: self]; screenView = [[UIView alloc] initWithFrame: CGRectMake(32.0f, 8.0f, 256.0f, 239.0f)]; [screenView setOpaque: YES]; [screenView setBackgroundColor: CGColorCreate(colorSpace, (const float[]) { 1.0f, 1.0f, 1.0f, 1.0f })]; [self initControls]; [gameplayView addSubview: screenView]; [transitionView addSubview: loadROMTable]; [contentView addSubview: navigationBar]; [contentView addSubview: transitionView]; [window setContentView: contentView]; [window _setHidden: NO]; [window orderFront: self]; [window makeKey: self]; [loadROMTable reloadData]; [loadROMTable updateDisclosures]; CGColorSpaceRelease(colorSpace); } @end