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
{