diff --git a/ActiveGS_iOS/ActiveGS/Images.xcassets/keyboardBackground.imageset/3800713644_bbfa97eb60_b.jpg b/ActiveGS_iOS/ActiveGS/Images.xcassets/keyboardBackground.imageset/3800713644_bbfa97eb60_b.jpg new file mode 100644 index 0000000..5d03658 Binary files /dev/null and b/ActiveGS_iOS/ActiveGS/Images.xcassets/keyboardBackground.imageset/3800713644_bbfa97eb60_b.jpg differ diff --git a/ActiveGS_iOS/ActiveGS/Images.xcassets/keyboardBackground.imageset/Contents.json b/ActiveGS_iOS/ActiveGS/Images.xcassets/keyboardBackground.imageset/Contents.json new file mode 100644 index 0000000..ca54253 --- /dev/null +++ b/ActiveGS_iOS/ActiveGS/Images.xcassets/keyboardBackground.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "3800713644_bbfa97eb60_b.jpg", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/ActiveGS_iOS/KeyCapView.xib b/ActiveGS_iOS/KeyCapView.xib new file mode 100644 index 0000000..caf7774 --- /dev/null +++ b/ActiveGS_iOS/KeyCapView.xib @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ActiveGS_iOS/activegs.xcodeproj/project.pbxproj b/ActiveGS_iOS/activegs.xcodeproj/project.pbxproj index 089b3d0..39c56e5 100644 --- a/ActiveGS_iOS/activegs.xcodeproj/project.pbxproj +++ b/ActiveGS_iOS/activegs.xcodeproj/project.pbxproj @@ -214,7 +214,6 @@ 09FD36F31278CCEB009C31AB /* BLUE_HELMET.FTA in Resources */ = {isa = PBXBuildFile; fileRef = 09FD36F01278CCEB009C31AB /* BLUE_HELMET.FTA */; }; 09FD36F41278CCEB009C31AB /* bluehelmet_1.png in Resources */ = {isa = PBXBuildFile; fileRef = 09FD36F11278CCEB009C31AB /* bluehelmet_1.png */; }; 09FD36F51278CCEB009C31AB /* bluehelmet_2.png in Resources */ = {isa = PBXBuildFile; fileRef = 09FD36F21278CCEB009C31AB /* bluehelmet_2.png */; }; - 1D60589B0D05DD56006BFB54 /* main.mm in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.mm */; }; 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; 288765A50DF7441C002DB57D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765A40DF7441C002DB57D /* CoreGraphics.framework */; }; @@ -237,6 +236,12 @@ 7E51482F1CA6B5CE005DA0A6 /* ShastonHi640.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 7E51481C1CA6B5CE005DA0A6 /* ShastonHi640.ttf */; }; 7E5148301CA6B5CE005DA0A6 /* Spin Up Search 1.wav in Resources */ = {isa = PBXBuildFile; fileRef = 7E51481D1CA6B5CE005DA0A6 /* Spin Up Search 1.wav */; }; 7E5148311CA6B5CE005DA0A6 /* Spin Up Search 2.wav in Resources */ = {isa = PBXBuildFile; fileRef = 7E51481E1CA6B5CE005DA0A6 /* Spin Up Search 2.wav */; }; + 9222DD461CBECF2300B321B9 /* main.mm in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.mm */; }; + 924A1BAC1CB81B5800D69162 /* GameControllerKeyRemapController.m in Sources */ = {isa = PBXBuildFile; fileRef = 924A1BAA1CB81B5800D69162 /* GameControllerKeyRemapController.m */; }; + 924A1BAD1CB81B5800D69162 /* GameControllerKeyRemapController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 924A1BAB1CB81B5800D69162 /* GameControllerKeyRemapController.xib */; }; + 924A1BAF1CB9671400D69162 /* KeyCapView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 924A1BAE1CB9671400D69162 /* KeyCapView.xib */; }; + 924A1BB21CB9685700D69162 /* KeyCapView.m in Sources */ = {isa = PBXBuildFile; fileRef = 924A1BB11CB9685700D69162 /* KeyCapView.m */; }; + 924A1BB51CBA049D00D69162 /* KeyMapper.m in Sources */ = {isa = PBXBuildFile; fileRef = 924A1BB41CBA049D00D69162 /* KeyMapper.m */; }; 9250DCB31CAEEF990093CE9A /* MfiGameControllerHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 9250DCB21CAEEF990093CE9A /* MfiGameControllerHandler.m */; }; 9250DCB51CAEFD3B0093CE9A /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9250DCB41CAEFD3B0093CE9A /* GameController.framework */; }; 928410581CA8443A00DC5D93 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 928410571CA8443A00DC5D93 /* Images.xcassets */; }; @@ -576,6 +581,14 @@ 7E51481C1CA6B5CE005DA0A6 /* ShastonHi640.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = ShastonHi640.ttf; sourceTree = ""; }; 7E51481D1CA6B5CE005DA0A6 /* Spin Up Search 1.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = "Spin Up Search 1.wav"; sourceTree = ""; }; 7E51481E1CA6B5CE005DA0A6 /* Spin Up Search 2.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = "Spin Up Search 2.wav"; sourceTree = ""; }; + 924A1BA91CB81B5800D69162 /* GameControllerKeyRemapController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GameControllerKeyRemapController.h; sourceTree = ""; }; + 924A1BAA1CB81B5800D69162 /* GameControllerKeyRemapController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GameControllerKeyRemapController.m; sourceTree = ""; }; + 924A1BAB1CB81B5800D69162 /* GameControllerKeyRemapController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = GameControllerKeyRemapController.xib; sourceTree = ""; }; + 924A1BAE1CB9671400D69162 /* KeyCapView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = KeyCapView.xib; sourceTree = ""; }; + 924A1BB01CB9685700D69162 /* KeyCapView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KeyCapView.h; sourceTree = ""; }; + 924A1BB11CB9685700D69162 /* KeyCapView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KeyCapView.m; sourceTree = ""; }; + 924A1BB31CBA049D00D69162 /* KeyMapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KeyMapper.h; sourceTree = ""; }; + 924A1BB41CBA049D00D69162 /* KeyMapper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KeyMapper.m; sourceTree = ""; }; 9250DCB11CAEEF990093CE9A /* MfiGameControllerHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MfiGameControllerHandler.h; sourceTree = ""; }; 9250DCB21CAEEF990093CE9A /* MfiGameControllerHandler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MfiGameControllerHandler.m; sourceTree = ""; }; 9250DCB41CAEFD3B0093CE9A /* GameController.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GameController.framework; path = System/Library/Frameworks/GameController.framework; sourceTree = SDKROOT; }; @@ -712,6 +725,7 @@ 0916BB03129473CE001727AF /* infoViewController-ipad.xib */, 09A5CE75125D422D0018DC22 /* infoViewController.xib */, 099CD904125E6F6E008EFD6C /* detailViewController.xib */, + 924A1BAE1CB9671400D69162 /* KeyCapView.xib */, ); name = xib; sourceTree = ""; @@ -985,6 +999,13 @@ 09FA608B125A7B3E00B07F77 /* KBDController.mm */, 9250DCB11CAEEF990093CE9A /* MfiGameControllerHandler.h */, 9250DCB21CAEEF990093CE9A /* MfiGameControllerHandler.m */, + 924A1BA91CB81B5800D69162 /* GameControllerKeyRemapController.h */, + 924A1BAA1CB81B5800D69162 /* GameControllerKeyRemapController.m */, + 924A1BAB1CB81B5800D69162 /* GameControllerKeyRemapController.xib */, + 924A1BB01CB9685700D69162 /* KeyCapView.h */, + 924A1BB11CB9685700D69162 /* KeyCapView.m */, + 924A1BB31CBA049D00D69162 /* KeyMapper.h */, + 924A1BB41CBA049D00D69162 /* KeyMapper.m */, ); name = Common.iphone; path = ../Common.iphone; @@ -1211,6 +1232,7 @@ 09087F3B12244C0500C52D88 /* delta_2.png in Resources */, 09087F3C12244C0500C52D88 /* delta_3.png in Resources */, 09087F3D12244C0500C52D88 /* delta_4.png in Resources */, + 924A1BAD1CB81B5800D69162 /* GameControllerKeyRemapController.xib in Resources */, 09087F3E12244C0500C52D88 /* delta_5.png in Resources */, 09087F3F12244C0500C52D88 /* delta_6.png in Resources */, 7E5148311CA6B5CE005DA0A6 /* Spin Up Search 2.wav in Resources */, @@ -1266,6 +1288,7 @@ 09AF98051283F0DF00083D60 /* Oil_Landers.fta in Resources */, 09AF980C1283F12200083D60 /* StarWizard (2002).fta in Resources */, 09AF980D1283F12200083D60 /* starwizard_2.png in Resources */, + 924A1BAF1CB9671400D69162 /* KeyCapView.xib in Resources */, 09AF980E1283F12200083D60 /* starwizard_3.png in Resources */, 7E5148271CA6B5CE005DA0A6 /* floppy_eject.wav in Resources */, 09AF980F1283F12200083D60 /* starwizard_4.png in Resources */, @@ -1303,7 +1326,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 1D60589B0D05DD56006BFB54 /* main.mm in Sources */, + 9222DD461CBECF2300B321B9 /* main.mm in Sources */, 09BB434511D92F65005ADA46 /* ActiveDownloadMac.cpp in Sources */, 09BB434711D92F65005ADA46 /* CEmulatorCtrlMac.cpp in Sources */, 09BB43B011D92F70005ADA46 /* activeconfig.cpp in Sources */, @@ -1331,6 +1354,7 @@ 09AADC78125C560A00654DF1 /* detailViewController.mm in Sources */, 09A5CE60125D41860018DC22 /* infoViewController.mm in Sources */, 0972554713CF2232006194F9 /* activegsEmulatorController.mm in Sources */, + 924A1BB51CBA049D00D69162 /* KeyMapper.m in Sources */, 0907BCC9142F567A0051CA0A /* asynccommand.mm in Sources */, 09052B7D19053C9F00853FAE /* pngread.cpp in Sources */, 09C81A781657ACAE008539D5 /* adb.cpp in Sources */, @@ -1352,6 +1376,7 @@ 09C81A861657ACAE008539D5 /* openalasync_snddriver.cpp in Sources */, 09052B8219053C9F00853FAE /* pngtrans.cpp in Sources */, 09C81A871657ACAE008539D5 /* paddles.cpp in Sources */, + 924A1BAC1CB81B5800D69162 /* GameControllerKeyRemapController.m in Sources */, 09C81A881657ACAE008539D5 /* SaveState.cpp in Sources */, 09C81A891657ACAE008539D5 /* scc.cpp in Sources */, 09C81A8A1657ACAE008539D5 /* scc_socket_driver.cpp in Sources */, @@ -1375,6 +1400,7 @@ 09C81AA91657AD18008539D5 /* zoomEmulatorView.mm in Sources */, 09052B7F19053C9F00853FAE /* pngrtran.cpp in Sources */, 09052B7A19053C9F00853FAE /* pngget.cpp in Sources */, + 924A1BB21CB9685700D69162 /* KeyCapView.m in Sources */, 09052B7919053C9F00853FAE /* pnggccrd.cpp in Sources */, 09052B9219053C9F00853FAE /* inftrees.cpp in Sources */, 09052B8819053C9F00853FAE /* ioapi.cpp in Sources */, diff --git a/ActiveGS_iOS/infoViewController.xib b/ActiveGS_iOS/infoViewController.xib index 8f7635d..feadb2e 100644 --- a/ActiveGS_iOS/infoViewController.xib +++ b/ActiveGS_iOS/infoViewController.xib @@ -131,91 +131,13 @@ Cg - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -224,365 +146,53 @@ Cgo - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -591,46 +201,7 @@ Cgo - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -643,92 +214,14 @@ Cgo - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -736,46 +229,7 @@ Cgo - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -788,92 +242,14 @@ Cgo - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -881,46 +257,7 @@ Cgo - Are supported and they work..most of the time! Save states are specific to each program and you have 6 available slots. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + diff --git a/Common.iphone/GameControllerKeyRemapController.h b/Common.iphone/GameControllerKeyRemapController.h new file mode 100644 index 0000000..fb2f673 --- /dev/null +++ b/Common.iphone/GameControllerKeyRemapController.h @@ -0,0 +1,17 @@ +// +// GameControllerKeyRemapController.h +// activegs +// +// Created by Yoshi Sugawara on 4/8/16. +// +// + +#import +#import "KeyMapper.h" + +@interface GameControllerKeyRemapController : UIViewController + +@property (nonatomic, strong) IBOutlet UIView *keyboardContainerView; +@property (nonatomic, strong) KeyMapper *keyMapper; + +@end diff --git a/Common.iphone/GameControllerKeyRemapController.m b/Common.iphone/GameControllerKeyRemapController.m new file mode 100644 index 0000000..72367df --- /dev/null +++ b/Common.iphone/GameControllerKeyRemapController.m @@ -0,0 +1,380 @@ +// +// GameControllerKeyRemapController.m +// activegs +// +// Created by Yoshi Sugawara on 4/8/16. +// +// + +#import +#import "GameControllerKeyRemapController.h" +#import "KeyCapView.h" +#import "KeyMapper.h" + +const CGFloat NUMBER_OF_KEYS_IN_ROW = 15.0f; + +const CGFloat KEYCAP_WIDTH_PCT = 1.0f / NUMBER_OF_KEYS_IN_ROW; + +const CGFloat KEYCAP_HORIZONTAL_PADDING = 2.0f; +const CGFloat KEYCAP_VERTICAL_PADDING = 2.0f; +const CGFloat KEYCAP_HEIGHT = 40.0f; + + +// Using a C struct here for really just convenience of typing the definitions out +// This gets converted into an obj-c object later +struct KeyCap { + CGFloat widthMultiplier; + const char* key1; + int code1; + const char* key2; +}; + +struct KeyCap keyCapDefinitions[] = { + { 1.0,"caps",KEY_CAPS,0 }, + { 1.0,"option",KEY_OPTION,0 }, + { 1.0,"",KEY_APPLE,0 }, + { 1.0,"`",KEY_TILDE,0 }, + { 6.0," ",KEY_SPACE,0 }, + { 1.0,"x",KEY_DOWN_CURSOR,0 }, + { 1.0,"->",KEY_RIGHT_CURSOR,0 }, + { 1.0,"<-",KEY_LEFT_CURSOR,0 }, + { 1.0,"^",KEY_UP_CURSOR,0 }, + { 1.0,"v",KEY_DOWN_CURSOR,0 }, + { -1,0,0,0 }, + { 2.5,"shift",KEY_SHIFT,0 }, + { 1.0,"Z",KEY_Z,0 }, + { 1.0,"X",KEY_X,0 }, + { 1.0,"C",KEY_C,0 }, + { 1.0,"V",KEY_V,0 }, + { 1.0,"B",KEY_B,0 }, + { 1.0,"N",KEY_N,0 }, + { 1.0,"M",KEY_M,0 }, + { 1.0,",",KEY_COMMA,"<" }, + { 1.0,".",KEY_PERIOD,">" }, + { 1.0,"/",KEY_FSLASH,"?" }, + { 2.5,"shift",KEY_SHIFT,0 }, + { -1,0,0,0 }, + { 2.0,"control",KEY_CTRL,0 }, + { 1.0,"A",KEY_A,0 }, + { 1.0,"S",KEY_S,0 }, + { 1.0,"D",KEY_D,0 }, + { 1.0,"F",KEY_F,0 }, + { 1.0,"G",KEY_G,0 }, + { 1.0,"H",KEY_H,0 }, + { 1.0,"J",KEY_J,0 }, + { 1.0,"K",KEY_K,0 }, + { 1.0,"L",KEY_L,0 }, + { 1.0,";",KEY_SEMICOLON,":" }, + { 1.0,"'",KEY_SQUOTE,"\""}, + { 2.0,"return",KEY_RETURN,0 }, + { -1,0,0,0 }, + { 3.0,"tab",KEY_TAB,0 }, + { 1.0,"Q",KEY_Q,0 }, + { 1.0,"W",KEY_W,0 }, + { 1.0,"E",KEY_E,0 }, + { 1.0,"R",KEY_R,0 }, + { 1.0,"T",KEY_T,0 }, + { 1.0,"Y",KEY_Y,0 }, + { 1.0,"U",KEY_U,0 }, + { 1.0,"I",KEY_I,0 }, + { 1.0,"O",KEY_O,0 }, + { 1.0,"P",KEY_P,0 }, + { 1.0,"[",KEY_LEFT_BRACKET,"{" }, + { 1.0,"]",KEY_RIGHT_BRACKET,"}" }, + { -1,0,0,0 }, + { 1.0,"esc",KEY_ESC,0 }, + { 1.0,"1",KEY_1,"!" }, + { 1.0,"2",KEY_2,"@" }, + { 1.0,"3",KEY_3,"#" }, + { 1.0,"4",KEY_4,"$" }, + { 1.0,"5",KEY_5,"%" }, + { 1.0,"6",KEY_6,"^" }, + { 1.0,"7",KEY_7,"&" }, + { 1.0,"8",KEY_8,"*" }, + { 1.0,"9",KEY_9,"(" }, + { 1.0,"0",KEY_0,")" }, + { 1.0,"-",KEY_MINUS,"_" }, + { 1.0,"=",KEY_EQUALS,"+" }, + { 2.0,"delete",KEY_DELETE,0 }, + { 0,0,0,0 } +}; + +@interface GameControllerKeyRemapController () +@property (nonatomic, strong) NSMutableArray *keyCapViews; +@property (nonatomic, strong) UIAlertView *alertView; +@end + +@implementation GameControllerKeyRemapController + +- (void)viewDidLoad { + [super viewDidLoad]; + self.keyCapViews = [NSMutableArray array]; + [self constructKeyboard]; +} + +- (void)didReceiveMemoryWarning { + [super didReceiveMemoryWarning]; + // Dispose of any resources that can be recreated. +} + +// convert the above c struct array into an objective c object to make it easier to deal with (for me, personally) +-(NSArray*) objc_keyCapsDefinitions { + NSMutableArray *keyDefs = [NSMutableArray array]; + NSMutableArray *keyDefsRow = [NSMutableArray array]; + int i = 0; + while (keyCapDefinitions[i].widthMultiplier) { + struct KeyCap keyCap = keyCapDefinitions[i]; + if ( keyCap.widthMultiplier == -1.0 ) { + [keyDefs addObject:[keyDefsRow copy]]; + [keyDefsRow removeAllObjects]; + i++; + continue; + } + [keyDefsRow addObject:@[ [NSNumber numberWithFloat:keyCap.widthMultiplier], + [NSString stringWithUTF8String:keyCap.key1], + [NSNumber numberWithInt:keyCap.code1], + keyCap.key2 != 0 ? [NSString stringWithUTF8String:keyCap.key2] : @"" + ]]; + i++; + } + [keyDefs addObject:keyDefsRow]; + return [keyDefs copy]; +} + +// Construct the keyboard key views using auto layout constraints entirely +// It gets constructed from the bottom up (pinned to the bottom) +-(void) constructKeyboard { + + NSArray *keyDefinitions = [self objc_keyCapsDefinitions]; + UIView *keyboardContainer = self.keyboardContainerView; + UIView *lastVerticalView = nil; + UIView *lastHorizontalView = nil; + NSUInteger keyboardRow = 0; + + for (NSArray *keyDefsRow in keyDefinitions) { + + KeyCapView *keyCapView = nil; + + NSUInteger keyIndex = 0; + + for (NSArray *keyDef in keyDefsRow) { + keyCapView = [KeyCapView createViewWithKeyDef:keyDef]; + keyCapView.translatesAutoresizingMaskIntoConstraints = NO; + keyCapView.layer.borderWidth = 1.0f; + keyCapView.layer.borderColor = [[UIColor blackColor] CGColor]; + [keyCapView setupWithKeyMapper:self.keyMapper]; + UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onKeyTap:)]; + [keyCapView addGestureRecognizer:tap]; + [self.keyCapViews addObject:keyCapView]; + + CGFloat widthMultiplier = [[keyDef objectAtIndex:KeyCapIndexWidthMultiplier] floatValue] * KEYCAP_WIDTH_PCT; + + NSDictionary *metrics = @{@"height" : @(KEYCAP_HEIGHT), @"padding" : @(KEYCAP_HORIZONTAL_PADDING)}; + [keyboardContainer addSubview:keyCapView]; + + // vertical + if ( keyboardRow == 0 ) { + NSDictionary *bindings = NSDictionaryOfVariableBindings(keyCapView); + // pin to super view bottom + [keyboardContainer addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[keyCapView(height)]-0@750-|" options:0 metrics:metrics views:bindings]]; + } else { + NSDictionary *bindings = NSDictionaryOfVariableBindings(keyCapView,lastVerticalView); + // pin bottom to last vertical view + [keyboardContainer addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[keyCapView(height)]-4@750-[lastVerticalView]" options:0 metrics:metrics views:bindings]]; + } + + // horizontal + NSLayoutConstraint *widthConstraint = [NSLayoutConstraint constraintWithItem:keyCapView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:keyboardContainer attribute:NSLayoutAttributeWidth multiplier:widthMultiplier constant:KEYCAP_HORIZONTAL_PADDING * -1.0]; + + if ( lastHorizontalView == nil ) { + NSDictionary *bindings = NSDictionaryOfVariableBindings(keyCapView); + [keyboardContainer addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-padding@750-[keyCapView]" options:0 metrics:metrics views:bindings]]; + } else { + NSDictionary *bindings = NSDictionaryOfVariableBindings(keyCapView,lastHorizontalView); + if ( keyIndex == (int)NUMBER_OF_KEYS_IN_ROW-1 ) { + // last key in row + [keyboardContainer addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[lastHorizontalView]-padding@750-[keyCapView]-padding@750-|" options:0 metrics:metrics views:bindings]]; + } else { + [keyboardContainer addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[lastHorizontalView]-padding@750-[keyCapView]" options:0 metrics:metrics views:bindings]]; + } + } + if ( keyIndex != (int)NUMBER_OF_KEYS_IN_ROW-1 ) { + [keyboardContainer addConstraint:widthConstraint]; + } + + keyIndex++; + lastHorizontalView = keyCapView; + } + + lastVerticalView = keyCapView; + lastHorizontalView = nil; + keyboardRow++; + } +} + +- (void) refreshAllKeyCapViews { + for (KeyCapView *view in self.keyCapViews) { + [view setupWithKeyMapper:self.keyMapper]; + } +} + +- (void) onKeyTap:(UITapGestureRecognizer*)sender { + KeyCapView *view = (KeyCapView*) sender.view; + self.alertView = [[UIAlertView alloc] initWithTitle:@"Remap Key" message:[NSString stringWithFormat:@"Press a button to map the [%@] key",[view.keyDef objectAtIndex:KeyCapIndexKey]] delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:nil]; + [self.alertView show]; + [self startRemappingControlsForMfiControllerForKey:[view.keyDef objectAtIndex:KeyCapIndexCode]]; +} + +- (void) startRemappingControlsForMfiControllerForKey:(NSNumber*)keyCode { + AppleKeyboardKey keyboardKey = [keyCode intValue]; + if ( [[GCController controllers] count] == 0 ) { + NSLog(@"Could not find any mfi controllers!"); + return; + } + GCController *controller = [[GCController controllers] firstObject]; + + if ( controller.extendedGamepad ) { + controller.extendedGamepad.valueChangedHandler = ^(GCExtendedGamepad *gamepad, GCControllerElement *element) { + if ( gamepad.buttonA.pressed ) { + [self.keyMapper mapKey:keyboardKey ToControl:MFI_BUTTON_A]; + [self.alertView dismissWithClickedButtonIndex:0 animated:YES]; + return; + } + if ( gamepad.buttonB.pressed ) { + [self.keyMapper mapKey:keyboardKey ToControl:MFI_BUTTON_B]; + [self.alertView dismissWithClickedButtonIndex:0 animated:YES]; + return; + } + if ( gamepad.buttonX.pressed ) { + [self.keyMapper mapKey:keyboardKey ToControl:MFI_BUTTON_X]; + [self.alertView dismissWithClickedButtonIndex:0 animated:YES]; + return; + } + if ( gamepad.buttonY.pressed ) { + [self.keyMapper mapKey:keyboardKey ToControl:MFI_BUTTON_Y]; + [self.alertView dismissWithClickedButtonIndex:0 animated:YES]; + return; + } + if ( gamepad.leftShoulder.pressed ) { + [self.keyMapper mapKey:keyboardKey ToControl:MFI_BUTTON_LS]; + [self.alertView dismissWithClickedButtonIndex:0 animated:YES]; + return; + } + if ( gamepad.rightShoulder.pressed ) { + [self.keyMapper mapKey:keyboardKey ToControl:MFI_BUTTON_RS]; + [self.alertView dismissWithClickedButtonIndex:0 animated:YES]; + return; + } + if ( gamepad.dpad.xAxis.value > 0.0f ) { + [self.keyMapper mapKey:keyboardKey ToControl:MFI_DPAD_RIGHT]; + [self.alertView dismissWithClickedButtonIndex:0 animated:YES]; + return; + } + if ( gamepad.dpad.xAxis.value < 0.0f ) { + [self.keyMapper mapKey:keyboardKey ToControl:MFI_DPAD_LEFT]; + [self.alertView dismissWithClickedButtonIndex:0 animated:YES]; + return; + } + if ( gamepad.dpad.yAxis.value > 0.0f ) { + [self.keyMapper mapKey:keyboardKey ToControl:MFI_DPAD_UP]; + [self.alertView dismissWithClickedButtonIndex:0 animated:YES]; + return; + } + if ( gamepad.dpad.yAxis.value < 0.0f ) { + [self.keyMapper mapKey:keyboardKey ToControl:MFI_DPAD_DOWN]; + [self.alertView dismissWithClickedButtonIndex:0 animated:YES]; + return; + } + if ( gamepad.rightTrigger.pressed ) { + [self.keyMapper mapKey:keyboardKey ToControl:MFI_BUTTON_RT]; + [self.alertView dismissWithClickedButtonIndex:0 animated:YES]; + return; + } + if ( gamepad.leftTrigger.pressed ) { + [self.keyMapper mapKey:keyboardKey ToControl:MFI_BUTTON_LT]; + [self.alertView dismissWithClickedButtonIndex:0 animated:YES]; + return; + } + }; + } else { + controller.gamepad.valueChangedHandler = ^(GCGamepad *gamepad, GCControllerElement *element) { + if ( gamepad.buttonA.pressed ) { + [self.keyMapper mapKey:keyboardKey ToControl:MFI_BUTTON_A]; + [self.alertView dismissWithClickedButtonIndex:0 animated:YES]; + return; + } + if ( gamepad.buttonB.pressed ) { + [self.keyMapper mapKey:keyboardKey ToControl:MFI_BUTTON_B]; + [self.alertView dismissWithClickedButtonIndex:0 animated:YES]; + return; + } + if ( gamepad.buttonX.pressed ) { + [self.keyMapper mapKey:keyboardKey ToControl:MFI_BUTTON_X]; + [self.alertView dismissWithClickedButtonIndex:0 animated:YES]; + return; + } + if ( gamepad.buttonY.pressed ) { + [self.keyMapper mapKey:keyboardKey ToControl:MFI_BUTTON_Y]; + [self.alertView dismissWithClickedButtonIndex:0 animated:YES];; + return; + } + if ( gamepad.leftShoulder.pressed ) { + [self.keyMapper mapKey:keyboardKey ToControl:MFI_BUTTON_LS]; + [self.alertView dismissWithClickedButtonIndex:0 animated:YES]; + return; + } + if ( gamepad.rightShoulder.pressed ) { + [self.keyMapper mapKey:keyboardKey ToControl:MFI_BUTTON_RS]; + [self.alertView dismissWithClickedButtonIndex:0 animated:YES]; + return; + } + if ( gamepad.dpad.xAxis.value > 0.0f ) { + [self.keyMapper mapKey:keyboardKey ToControl:MFI_DPAD_RIGHT]; + [self.alertView dismissWithClickedButtonIndex:0 animated:YES]; + return; + } + if ( gamepad.dpad.xAxis.value < 0.0f ) { + [self.keyMapper mapKey:keyboardKey ToControl:MFI_DPAD_LEFT]; + [self.alertView dismissWithClickedButtonIndex:0 animated:YES]; + return; + } + if ( gamepad.dpad.yAxis.value > 0.0f ) { + [self.keyMapper mapKey:keyboardKey ToControl:MFI_DPAD_UP]; + [self.alertView dismissWithClickedButtonIndex:0 animated:YES]; + return; + } + if ( gamepad.dpad.yAxis.value < 0.0f ) { + [self.keyMapper mapKey:keyboardKey ToControl:MFI_DPAD_DOWN]; + [self.alertView dismissWithClickedButtonIndex:0 animated:YES]; + return; + } + }; + } +} + +-(void) stopRemappingControls { + if ( [[GCController controllers] count] == 0 ) { + return; + } + GCController *controller = [[GCController controllers] firstObject]; + if ( controller.extendedGamepad ) { + controller.extendedGamepad.valueChangedHandler = nil; + } else { + controller.gamepad.valueChangedHandler = nil; + } +} + +# +# pragma mark - UIAlertViewDelegate +# + +- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { + [self stopRemappingControls]; +} + +- (void)alertView:(UIAlertView *)alertView willDismissWithButtonIndex:(NSInteger)buttonIndex { + [self stopRemappingControls]; + [self refreshAllKeyCapViews]; +} + +@end diff --git a/Common.iphone/GameControllerKeyRemapController.xib b/Common.iphone/GameControllerKeyRemapController.xib new file mode 100644 index 0000000..b8eee8b --- /dev/null +++ b/Common.iphone/GameControllerKeyRemapController.xib @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Common.iphone/KBDController.mm b/Common.iphone/KBDController.mm index bb9be3c..3fff123 100644 --- a/Common.iphone/KBDController.mm +++ b/Common.iphone/KBDController.mm @@ -22,6 +22,7 @@ #include "../kegs/src/SaveState.h" #include "../common/activedownload.h" #import "MfiGameControllerHandler.h" +#import "GameControllerKeyRemapController.h" #ifdef ACTIVEGS_CUSTOMKEYS #include "UICustomKey.h" @@ -280,6 +281,7 @@ int isHardwareKeyboard() UISegmentedControl *saveStateSegmentedControl; } @property (nonatomic,strong) MfiGameControllerHandler *mfiControllerHandler; +@property (nonatomic,strong) KeyMapper *keyMapper; @end @implementation KBDController @@ -608,6 +610,8 @@ extern int findCode(const char* _s); if ( controller.extendedGamepad ) { controller.extendedGamepad.leftThumbstick.valueChangedHandler = appleJoystickhHandler; } + + self.keyMapper = [[KeyMapper alloc] init]; } int hardwarekeyboard= 0; @@ -964,6 +968,13 @@ extern int x_frame_rate ; [pManager setNotificationText:[NSString stringWithFormat:@"Loaded State #%@",segIndex]]; } +-(void) remapControlsButtonPressed:(id)sender { + r_sim65816.pause(); + GameControllerKeyRemapController *remapController = [[GameControllerKeyRemapController alloc] initWithNibName:@"GameControllerKeyRemapController" bundle:nil]; + remapController.keyMapper = self.keyMapper; + [self presentViewController:remapController animated:YES completion:nil]; +} + // -(void)addRuntimeControls { @@ -1063,6 +1074,20 @@ extern int x_frame_rate ; [self.runtimeControlsOptions addSubview:loadStateButton]; l+=LINEHEIGHT; + l += 2.0; + + UIButton *remapControlsButton = [UIButton buttonWithType:UIButtonTypeCustom]; + remapControlsButton.frame = CGRectMake(OPTIONMARGIN,l,OPTIONWIDTH,LINEHEIGHT); + [remapControlsButton setTitle:@"Remap Controls" forState:UIControlStateNormal]; + remapControlsButton.titleLabel.font = [UIFont systemFontOfSize:12*res]; + [remapControlsButton setTitleColor:self.view.tintColor forState:UIControlStateNormal]; + remapControlsButton.backgroundColor = [UIColor clearColor]; + remapControlsButton.layer.borderWidth = 1.0f; + remapControlsButton.layer.borderColor = [self.view.tintColor CGColor]; + [remapControlsButton addTarget:self action:@selector(remapControlsButtonPressed:) forControlEvents:UIControlEventTouchUpInside]; + [self.runtimeControlsOptions addSubview:remapControlsButton]; + + l += LINEHEIGHT; nbs++; float w = OPTIONWIDTH+OPTIONMARGIN*2; diff --git a/Common.iphone/KeyCapView.h b/Common.iphone/KeyCapView.h new file mode 100644 index 0000000..53f3527 --- /dev/null +++ b/Common.iphone/KeyCapView.h @@ -0,0 +1,22 @@ +// +// KeyCapView.h +// activegs +// +// Created by Yoshi Sugawara on 4/9/16. +// +// + +#import +#import "KeyMapper.h" + +@interface KeyCapView : UIView + +@property (nonatomic, strong) IBOutlet UILabel *keyLabel; +@property (nonatomic, strong) IBOutlet UILabel *keyLabelAlt; +@property (nonatomic, strong) IBOutlet UILabel *mappedButtonLabel; +@property (nonatomic, strong) NSArray *keyDef; + ++ (instancetype)createViewWithKeyDef:(NSArray*)keyDef; +- (void)setupWithKeyMapper:(KeyMapper*)keyMapper; + +@end diff --git a/Common.iphone/KeyCapView.m b/Common.iphone/KeyCapView.m new file mode 100644 index 0000000..12ffbdd --- /dev/null +++ b/Common.iphone/KeyCapView.m @@ -0,0 +1,40 @@ +// +// KeyCapView.m +// activegs +// +// Created by Yoshi Sugawara on 4/9/16. +// +// + +#import "KeyCapView.h" + +@implementation KeyCapView + ++ (instancetype)createViewWithKeyDef:(NSArray*)keyDef +{ + KeyCapView *keyCapView = [[[UINib nibWithNibName:@"KeyCapView" bundle:nil] instantiateWithOwner:nil options:nil] lastObject]; + + if ([keyCapView isKindOfClass:[KeyCapView class]]) { + keyCapView.keyDef = keyDef; + return keyCapView; + } else { + return nil; + } +} + +- (void)setupWithKeyMapper:(KeyMapper*)keyMapper { + if ( ![[self.keyDef objectAtIndex:KeyCapIndexShiftedKey] isEqualToString:@""] ) { + self.keyLabel.text = [self.keyDef objectAtIndex:KeyCapIndexShiftedKey]; + self.keyLabelAlt.text = [self.keyDef objectAtIndex:KeyCapIndexKey]; + } else { + self.keyLabel.text = [self.keyDef objectAtIndex:KeyCapIndexKey]; + self.keyLabelAlt.text = @""; + } + self.mappedButtonLabel.text = @""; + KeyMapMappableButton mappedButton = [keyMapper getControlForMappedKey:[[self.keyDef objectAtIndex:KeyCapIndexCode] intValue]]; + if ( mappedButton != NSNotFound ) { + self.mappedButtonLabel.text = [KeyMapper controlToDisplayName:mappedButton]; + } +} + +@end diff --git a/Common.iphone/KeyMapper.h b/Common.iphone/KeyMapper.h new file mode 100644 index 0000000..2631fc7 --- /dev/null +++ b/Common.iphone/KeyMapper.h @@ -0,0 +1,115 @@ +// +// KeyMapper.h +// activegs +// +// Created by Yoshi Sugawara on 4/9/16. +// +// + +#import + +typedef NS_ENUM(NSInteger, AppleKeyboardKey) { + KEY_CAPS = 0x39, + KEY_OPTION = 0x37, + KEY_APPLE = 0x3A, + KEY_TILDE = 0x12, + KEY_SPACE = 0x31, + KEY_RIGHT_CURSOR = 0x3C, + KEY_LEFT_CURSOR = 0x3B, + KEY_UP_CURSOR = 0x5B, + KEY_DOWN_CURSOR = 0x13, + KEY_SHIFT = 0x38, + KEY_Z = 0x06, + KEY_X = 0x07, + KEY_C = 0x08, + KEY_V = 0x09, + KEY_B = 0x0B, + KEY_N = 0x2D, + KEY_M = 0x2E, + KEY_COMMA = 0x2B, + KEY_PERIOD = 0x2F, + KEY_FSLASH = 0x2C, + KEY_CTRL = 0x36, + KEY_A = 0x00, + KEY_S = 0x01, + KEY_D = 0x02, + KEY_F = 0x03, + KEY_G = 0x05, + KEY_H = 0x04, + KEY_J = 0x26, + KEY_K = 0x28, + KEY_L = 0x25, + KEY_SEMICOLON = 0x29, + KEY_SQUOTE = 0x27, + KEY_RETURN = 0x24, + KEY_TAB = 0x30, + KEY_Q = 0x0C, + KEY_W = 0x0D, + KEY_E = 0x0E, + KEY_R = 0x0F, + KEY_T = 0x11, + KEY_Y = 0x10, + KEY_U = 0x20, + KEY_I = 0x22, + KEY_O = 0x1F, + KEY_P = 0x23, + KEY_LEFT_BRACKET = 0x21, + KEY_RIGHT_BRACKET = 0x1E, + KEY_ESC = 0x35, + KEY_1 = 0x12, + KEY_2 = 0x13, + KEY_3 = 0x14, + KEY_4 = 0x15, + KEY_5 = 0x17, + KEY_6 = 0x16, + KEY_7 = 0x1A, + KEY_8 = 0x1C, + KEY_9 = 0x19, + KEY_0 = 0x1D, + KEY_MINUS = 0x1B, + KEY_EQUALS = 0x18, + KEY_DELETE = 0x33 +}; + +typedef NS_ENUM(NSInteger, KeyMapMappableButton) { + MFI_BUTTON_X, + MFI_BUTTON_A, + MFI_BUTTON_B, + MFI_BUTTON_Y, + MFI_BUTTON_LT, + MFI_BUTTON_RT, + MFI_BUTTON_LS, + MFI_BUTTON_RS, + MFI_DPAD_UP, + MFI_DPAD_DOWN, + MFI_DPAD_LEFT, + MFI_DPAD_RIGHT, + ICADE_BUTTON_1, + ICADE_BUTTON_2, + ICADE_BUTTON_3, + ICADE_BUTTON_4, + ICADE_BUTTON_5, + ICADE_BUTTON_6, + ICADE_BUTTON_7, + ICADE_BUTTON_8, + ICADE_DPAD_UP, + ICADE_DPAD_DOWN, + ICADE_DPAD_LEFT, + ICADE_DPAD_RIGHT +}; + +typedef NS_ENUM(NSInteger, KeyCapIndex) { + KeyCapIndexWidthMultiplier = 0, + KeyCapIndexKey = 1, + KeyCapIndexCode = 2, + KeyCapIndexShiftedKey = 3 +}; + +@interface KeyMapper : NSObject + +-(void) mapKey:(AppleKeyboardKey)keyboardKey ToControl:(KeyMapMappableButton)button; +-(AppleKeyboardKey) getMappedKeyForControl:(KeyMapMappableButton)button; +-(KeyMapMappableButton) getControlForMappedKey:(AppleKeyboardKey) keyboardKey; ++(NSString*) controlToDisplayName:(KeyMapMappableButton)button; + +@end diff --git a/Common.iphone/KeyMapper.m b/Common.iphone/KeyMapper.m new file mode 100644 index 0000000..9e5a5a1 --- /dev/null +++ b/Common.iphone/KeyMapper.m @@ -0,0 +1,126 @@ +// +// KeyMapper.m +// activegs +// +// Created by Yoshi Sugawara on 4/9/16. +// +// + +#import "KeyMapper.h" + +@interface KeyMapper() +@property (nonatomic, strong) NSMutableDictionary *keyMapping; +@end + +@implementation KeyMapper + +-(instancetype) init { + if ( self = [super init] ) { + self.keyMapping = [[[NSUserDefaults standardUserDefaults] dictionaryForKey:@"keyMapping"] mutableCopy]; + if ( self.keyMapping == nil ) { + self.keyMapping = [NSMutableDictionary dictionary]; + } + } + return self; +} + +-(void) saveKeyMapping { + [[NSUserDefaults standardUserDefaults] setObject:self.keyMapping forKey:@"keyMapping"]; + [[NSUserDefaults standardUserDefaults] synchronize]; +} + +-(void) mapKey:(AppleKeyboardKey)keyboardKey ToControl:(KeyMapMappableButton)button { + NSNumber *buttonKey = [NSNumber numberWithInteger:button]; + [self.keyMapping setObject:[NSNumber numberWithInteger:keyboardKey] forKey:buttonKey]; +} + +-(AppleKeyboardKey) getMappedKeyForControl:(KeyMapMappableButton)button { + NSNumber *buttonKey = [NSNumber numberWithInteger:button]; + NSNumber *mappedKey = [self.keyMapping objectForKey:buttonKey]; + if ( mappedKey != nil ) { + return [mappedKey integerValue]; + } else { + return NSNotFound; + } +} + +-(KeyMapMappableButton) getControlForMappedKey:(AppleKeyboardKey) keyboardKey { + for (NSNumber *buttonKey in self.keyMapping) { + NSNumber *mappedKey = [self.keyMapping objectForKey:buttonKey]; + if ( mappedKey != nil && [mappedKey integerValue] == keyboardKey ) { + return [buttonKey integerValue]; + } + } + return NSNotFound; +} + ++(NSString*) controlToDisplayName:(KeyMapMappableButton)button { + switch (button) { + case MFI_BUTTON_A: + return @"A"; + break; + case MFI_BUTTON_B: + return @"B"; + break; + case MFI_BUTTON_X: + return @"X"; + break; + case MFI_BUTTON_Y: + return @"Y"; + break; + case MFI_BUTTON_LS: + return @"LS"; + break; + case MFI_BUTTON_LT: + return @"LT"; + break; + case MFI_BUTTON_RS: + return @"RS"; + break; + case MFI_BUTTON_RT: + return @"RT"; + break; + case MFI_DPAD_UP: + return @"mUP"; + break; + case MFI_DPAD_DOWN: + return @"mDOWN"; + break; + case MFI_DPAD_LEFT: + return @"mLEFT"; + break; + case MFI_DPAD_RIGHT: + return @"mRIGHT"; + break; + case ICADE_BUTTON_1: + return @"i1"; + break; + case ICADE_BUTTON_2: + return @"i2"; + break; + case ICADE_BUTTON_3: + return @"i3"; + break; + case ICADE_BUTTON_4: + return @"i4"; + break; + case ICADE_BUTTON_5: + return @"i5"; + break; + case ICADE_BUTTON_6: + return @"i6"; + break; + case ICADE_BUTTON_7: + return @"i7"; + break; + case ICADE_BUTTON_8: + return @"i8"; + break; + default: + return @"?"; + break; + } +} + + +@end diff --git a/Common.iphone/activegsAppDelegate.h b/Common.iphone/activegsAppDelegate.h index ddd6b52..68fa659 100644 --- a/Common.iphone/activegsAppDelegate.h +++ b/Common.iphone/activegsAppDelegate.h @@ -156,6 +156,8 @@ extern enum machineSpecsEnum machineSpecs; -(void)setNotificationText:(NSString*) _text; -(void)updateNotificationView:(CGRect) newRect; - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation; +- (void) showKeyRemapController; + @property(nonatomic,strong,getter=getEmulatorView) activegsEmulatorController* emulatorController; @property(nonatomic,strong,getter=getBrowserView) ACTIVEGS_LAUNCHVIEWCONTROLLER* viewController; @property(nonatomic,strong,getter=getInfoView) infoViewController* infoController; diff --git a/Common.iphone/activegsAppDelegate.mm b/Common.iphone/activegsAppDelegate.mm index 2768998..75c84ea 100644 --- a/Common.iphone/activegsAppDelegate.mm +++ b/Common.iphone/activegsAppDelegate.mm @@ -13,6 +13,7 @@ #import #include "asynccommand.h" #import +#import "GameControllerKeyRemapController.h" // Application Singleton activegsAppDelegate* pManager = nil; @@ -613,6 +614,10 @@ void x_init_persistent_path(MyString& hp) } +- (void) showKeyRemapController { + GameControllerKeyRemapController *remapController = [[GameControllerKeyRemapController alloc] initWithNibName:@"GameControllerKeyRemapController" bundle:nil]; + [self.viewController presentViewController:remapController animated:YES completion:nil]; +} - (void) screenDidConnect:(NSNotification *)notification {