OK so I started with the 3 files in
https://github.com/scarnie/iCade-iOS/tree/master/iCadeTest/iCade
I put them under libs/iOS/iCade
Then I wrote a manager
#ifndef __iCadeManager_H__
#define __iCadeManager_H__
#include "cocos2d.h"
USING_NS_CC;
#include "iCadeMovementDelegate.h"
class iCadeManager : public CCObject {
public:
virtual ~iCadeManager();
static iCadeManager *sharediCadeManager();
virtual bool init();
void enableUsingScheduler(float dt);
void enable();
void disable();
ccKeypadKeycode remapToKey(short state);
CREATE_FUNC(iCadeManager);
};
#endif
#include "iCadeManager.h"
#import "../../../libs/ios/iCade/iCadeReaderView.h"
#import "EAGLView.h"
#import "../../../proj.ios/AppController.h"
#import "../../../proj.ios/RootViewController.h"
#import "../../../libs/cocos2dx/platform/ios/EAGLView.h"
#include "cocos2d.h"
USING_NS_CC;
static iCadeReaderView *_icrv = nil;
@interface iCadeReaderViewDelegateWrapper : NSObject {
@public
BOOL _isUpPressed;
BOOL _isDownPressed;
BOOL _isAnyButtonPressed;
struct {
BOOL moveUp = YES;
BOOL moveDown = YES;
BOOL stopMoving = YES;
BOOL fireWeapon = YES;
BOOL iCadeActive = YES;
} _delegateFlags;
}
- (void)buttonDown:(iCadeState)button;
- (void)buttonUp:(iCadeState)button;
@end
@implementation iCadeReaderViewDelegateWrapper
#pragma mark - iCadeReaderView callbacks
-(void)buttonDown:(iCadeState)button {
if (button == iCadeJoystickUp) {
// CCLOG(@"pressing up");
_isUpPressed = TRUE;
} else if (button == iCadeJoystickDown) {
// CCLOG(@"pressing down");
_isDownPressed = TRUE;
} else if (button == iCadeButtonA ||
button == iCadeButtonB ||
button == iCadeButtonC ||
button == iCadeButtonD ||
button == iCadeButtonE ||
button == iCadeButtonF ||
button == iCadeButtonG ||
button == iCadeButtonH) {
// CCLOG(@"pressing button");
_isAnyButtonPressed = TRUE;
}
if (button == iCadeJoystickUpRight) {
CCDirector::sharedDirector()->getKeypadDispatcher()->dispatchKeypadMSG(kTypeKeyDown, iCadeManager::sharediCadeManager()->remapToKey(iCadeJoystickUp));
CCDirector::sharedDirector()->getKeypadDispatcher()->dispatchKeypadMSG(kTypeKeyDown, iCadeManager::sharediCadeManager()->remapToKey(iCadeJoystickRight));
} else if (button == iCadeJoystickDownRight) {
CCDirector::sharedDirector()->getKeypadDispatcher()->dispatchKeypadMSG(kTypeKeyDown, iCadeManager::sharediCadeManager()->remapToKey(iCadeJoystickDown));
CCDirector::sharedDirector()->getKeypadDispatcher()->dispatchKeypadMSG(kTypeKeyDown, iCadeManager::sharediCadeManager()->remapToKey(iCadeJoystickRight));
} else if (button == iCadeJoystickUpLeft) {
CCDirector::sharedDirector()->getKeypadDispatcher()->dispatchKeypadMSG(kTypeKeyDown, iCadeManager::sharediCadeManager()->remapToKey(iCadeJoystickUp));
CCDirector::sharedDirector()->getKeypadDispatcher()->dispatchKeypadMSG(kTypeKeyDown, iCadeManager::sharediCadeManager()->remapToKey(iCadeJoystickLeft));
} else if (button == iCadeJoystickDownLeft) {
CCDirector::sharedDirector()->getKeypadDispatcher()->dispatchKeypadMSG(kTypeKeyDown, iCadeManager::sharediCadeManager()->remapToKey(iCadeJoystickDown));
CCDirector::sharedDirector()->getKeypadDispatcher()->dispatchKeypadMSG(kTypeKeyDown, iCadeManager::sharediCadeManager()->remapToKey(iCadeJoystickLeft));
} else {
CCDirector::sharedDirector()->getKeypadDispatcher()->dispatchKeypadMSG(kTypeKeyDown, iCadeManager::sharediCadeManager()->remapToKey(button));
}
}
-(void)buttonUp:(iCadeState)button {
if (button == iCadeJoystickUp) {
// CCLOG(@"released up");
_isUpPressed = FALSE;
} else if (button == iCadeJoystickDown) {
// CCLOG(@"released down");
_isDownPressed = FALSE;
} else if (button == iCadeButtonA ||
button == iCadeButtonB ||
button == iCadeButtonC ||
button == iCadeButtonD ||
button == iCadeButtonE ||
button == iCadeButtonF ||
button == iCadeButtonG ||
button == iCadeButtonH) {
// CCLOG(@"released button");
_isAnyButtonPressed = FALSE;
}
if (button == iCadeJoystickUpRight) {
CCDirector::sharedDirector()->getKeypadDispatcher()->dispatchKeypadMSG(kTypeKeyUp, iCadeManager::sharediCadeManager()->remapToKey(iCadeJoystickUp));
CCDirector::sharedDirector()->getKeypadDispatcher()->dispatchKeypadMSG(kTypeKeyUp, iCadeManager::sharediCadeManager()->remapToKey(iCadeJoystickRight));
} else if (button == iCadeJoystickDownRight) {
CCDirector::sharedDirector()->getKeypadDispatcher()->dispatchKeypadMSG(kTypeKeyUp, iCadeManager::sharediCadeManager()->remapToKey(iCadeJoystickDown));
CCDirector::sharedDirector()->getKeypadDispatcher()->dispatchKeypadMSG(kTypeKeyUp, iCadeManager::sharediCadeManager()->remapToKey(iCadeJoystickRight));
} else if (button == iCadeJoystickUpLeft) {
CCDirector::sharedDirector()->getKeypadDispatcher()->dispatchKeypadMSG(kTypeKeyUp, iCadeManager::sharediCadeManager()->remapToKey(iCadeJoystickUp));
CCDirector::sharedDirector()->getKeypadDispatcher()->dispatchKeypadMSG(kTypeKeyUp, iCadeManager::sharediCadeManager()->remapToKey(iCadeJoystickLeft));
} else if (button == iCadeJoystickDownLeft) {
CCDirector::sharedDirector()->getKeypadDispatcher()->dispatchKeypadMSG(kTypeKeyUp, iCadeManager::sharediCadeManager()->remapToKey(iCadeJoystickDown));
CCDirector::sharedDirector()->getKeypadDispatcher()->dispatchKeypadMSG(kTypeKeyUp, iCadeManager::sharediCadeManager()->remapToKey(iCadeJoystickLeft));
} else {
CCDirector::sharedDirector()->getKeypadDispatcher()->dispatchKeypadMSG(kTypeKeyUp, iCadeManager::sharediCadeManager()->remapToKey(button));
}
}
@end
static iCadeManager *_sharediCadeManager = NULL;
iCadeManager *iCadeManager::sharediCadeManager() {
if (_sharediCadeManager == nil) {
_sharediCadeManager = iCadeManager::create();
CC_SAFE_RETAIN(_sharediCadeManager);
}
return _sharediCadeManager;
}
bool iCadeManager::init() {
// iCade
_icrv = [[iCadeReaderView alloc] initWithFrame:CGRectZero];
_icrv.active = NO;
_icrv.delegate = [[iCadeReaderViewDelegateWrapper alloc] init];
return true;
}
iCadeManager::~iCadeManager() {
id temp = _icrv.delegate;
_icrv.delegate = nil;
[_icrv release];
_icrv = nil;
[temp release];
}
void iCadeManager::enableUsingScheduler(float dt) {
enable();
}
void iCadeManager::enable() {
EAGLView *root = [EAGLView sharedEGLView];
// if we are adding a delegate when there was none before we need removed the keyboard listeners for the eagl view
[[NSNotificationCenter defaultCenter] removeObserver:root
name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:root
name:UIKeyboardDidShowNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:root
name:UIKeyboardWillHideNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:root
name:UIKeyboardDidHideNotification object:nil];
// if (![[root subviews] containsObject:_icrv]) {
[root addSubview:_icrv];
// }
_icrv.active = YES;
}
void iCadeManager::disable() {
EAGLView *root = [EAGLView sharedEGLView];
// if we are removing the delegate then we need to get keyboard events in the eagl view
[[NSNotificationCenter defaultCenter] addObserver:root
selector:@selector(onUIKeyboardNotification:)
name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:root
selector:@selector(onUIKeyboardNotification:)
name:UIKeyboardDidShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:root
selector:@selector(onUIKeyboardNotification:)
name:UIKeyboardWillHideNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:root
selector:@selector(onUIKeyboardNotification:)
name:UIKeyboardDidHideNotification object:nil];
// if ([[root subviews] containsObject:_icrv]) {
[_icrv removeFromSuperview];
// }
_icrv.active = NO;
}
ccKeypadKeycode iCadeManager::remapToKey(short state) {
ccKeypadKeycode key = kKeycodeUNKNOWN;
switch (state) {
case iCadeJoystickUp:
key = kKeycodeDPAD_UP;
break;
case iCadeJoystickRight:
key = kKeycodeDPAD_RIGHT;
break;
case iCadeJoystickDown:
key = kKeycodeDPAD_DOWN;
break;
case iCadeJoystickLeft:
key = kKeycodeDPAD_LEFT;
break;
case iCadeButtonA:
key = kKeycodeBUTTON_A;
break;
case iCadeButtonB:
key = kKeycodeBUTTON_B;
break;
case iCadeButtonC:
key = kKeycodeBUTTON_C;
break;
case iCadeButtonD:
key = kKeycodeBUTTON_X;
break;
case iCadeButtonE:
key = kKeycodeBUTTON_Y;
break;
case iCadeButtonF:
key = kKeycodeBUTTON_Z;
break;
case iCadeButtonG:
key = kKeycodeBUTTON_SELECT;
break;
case iCadeButtonH:
key = kKeycodeBUTTON_START;
break;
case iCadeJoystickNone:
default:
break;
}
return key;
}
So now there is one thing missing, and that is where do the constants e.g. kKeycodeBUTTON_SELECT
come from. The answer is that they are an extenstion of the cocos2d-x enuration ccKeypadCode located in CCKeyPadDelegate.h
typedef enum {
kKeycodeUNKNOWN = 0,
kKeycodeSOFT_LEFT = 1,
kKeycodeSOFT_RIGHT = 2,
kKeycodeHOME = 3,
kKeycodeBACK = 4,
kKeycodeCALL = 5,
kKeycodeENDCALL = 6,
kKeycode0 = 7,
kKeycode1 = 8,
kKeycode2 = 9,
kKeycode3 = 10,
kKeycode4 = 11,
kKeycode5 = 12,
kKeycode6 = 13,
kKeycode7 = 14,
kKeycode8 = 15,
kKeycode9 = 16,
kKeycodeSTAR = 17,
kKeycodePOUND = 18,
kKeycodeDPAD_UP = 19,
kKeycodeDPAD_DOWN = 20,
kKeycodeDPAD_LEFT = 21,
kKeycodeDPAD_RIGHT = 22,
kKeycodeDPAD_CENTER = 23,
kKeycodeVOLUME_UP = 24,
kKeycodeVOLUME_DOWN = 25,
kKeycodePOWER = 26,
kKeycodeCAMERA = 27,
kKeycodeCLEAR = 28,
kKeycodeA = 29,
kKeycodeB = 30,
kKeycodeC = 31,
kKeycodeD = 32,
kKeycodeE = 33,
kKeycodeF = 34,
kKeycodeG = 35,
kKeycodeH = 36,
kKeycodeI = 37,
kKeycodeJ = 38,
kKeycodeK = 39,
kKeycodeL = 40,
kKeycodeM = 41,
kKeycodeN = 42,
kKeycodeO = 43,
kKeycodeP = 44,
kKeycodeQ = 45,
kKeycodeR = 46,
kKeycodeS = 47,
kKeycodeT = 48,
kKeycodeU = 49,
kKeycodeV = 50,
kKeycodeW = 51,
kKeycodeX = 52,
kKeycodeY = 53,
kKeycodeZ = 54,
kKeycodeCOMMA = 55,
kKeycodePERIOD = 56,
kKeycodeALT_LEFT = 57,
kKeycodeALT_RIGHT = 58,
kKeycodeSHIFT_LEFT = 59,
kKeycodeSHIFT_RIGHT = 60,
kKeycodeTAB = 61,
kKeycodeSPACE = 62,
kKeycodeSYM = 63,
kKeycodeEXPLORER = 64,
kKeycodeENVELOPE = 65,
kKeycodeENTER = 66,
kKeycodeDEL = 67,
kKeycodeGRAVE = 68,
kKeycodeMINUS = 69,
kKeycodeEQUALS = 70,
kKeycodeLEFT_BRACKET = 71,
kKeycodeRIGHT_BRACKET = 72,
kKeycodeBACKSLASH = 73,
kKeycodeSEMICOLON = 74,
kKeycodeAPOSTROPHE = 75,
kKeycodeSLASH = 76,
kKeycodeAT = 77,
kKeycodeNUM = 78,
kKeycodeHEADSETHOOK = 79,
kKeycodeFOCUS = 80,
kKeycodePLUS = 81,
kKeycodeMENU = 82,
kKeycodeNOTIFICATION = 83,
kKeycodeSEARCH = 84,
kKeycodeMEDIA_PLAY_PAUSE = 85,
kKeycodeMEDIA_STOP = 86,
kKeycodeMEDIA_NEXT = 87,
kKeycodeMEDIA_PREVIOUS = 88,
kKeycodeMEDIA_REWIND = 89,
kKeycodeMEDIA_FAST_FORWARD = 90,
kKeycodeMUTE = 91,
kKeycodePAGE_UP = 92,
kKeycodePAGE_DOWN = 93,
kKeycodePICTSYMBOLS = 94,
kKeycodeSWITCH_CHARSET = 95,
kKeycodeBUTTON_A = 96,
kKeycodeBUTTON_B = 97,
kKeycodeBUTTON_C = 98,
kKeycodeBUTTON_X = 99,
kKeycodeBUTTON_Y = 100,
kKeycodeBUTTON_Z = 101,
kKeycodeBUTTON_L1 = 102,
kKeycodeBUTTON_R1 = 103,
kKeycodeBUTTON_L2 = 104,
kKeycodeBUTTON_R2 = 105,
kKeycodeBUTTON_THUMBL = 106,
kKeycodeBUTTON_THUMBR = 107,
kKeycodeBUTTON_START = 108,
kKeycodeBUTTON_SELECT = 109,
kKeycodeBUTTON_MODE = 110,
kKeycodeESCAPE = 111,
kKeycodeFORWARD_DEL = 112,
kKeycodeCTRL_LEFT = 113,
kKeycodeCTRL_RIGHT = 114,
kKeycodeCAPS_LOCK = 115,
kKeycodeSCROLL_LOCK = 116,
kKeycodeMETA_LEFT = 117,
kKeycodeMETA_RIGHT = 118,
kKeycodeFUNCTION = 119,
kKeycodeSYSRQ = 120,
kKeycodeBREAK = 121,
kKeycodeMOVE_HOME = 122,
kKeycodeMOVE_END = 123,
kKeycodeINSERT = 124,
kKeycodeFORWARD = 125,
kKeycodeMEDIA_PLAY = 126,
kKeycodeMEDIA_PAUSE = 127,
kKeycodeMEDIA_CLOSE = 128,
kKeycodeMEDIA_EJECT = 129,
kKeycodeMEDIA_RECORD = 130,
kKeycodeF1 = 131,
kKeycodeF2 = 132,
kKeycodeF3 = 133,
kKeycodeF4 = 134,
kKeycodeF5 = 135,
kKeycodeF6 = 136,
kKeycodeF7 = 137,
kKeycodeF8 = 138,
kKeycodeF9 = 139,
kKeycodeF10 = 140,
kKeycodeF11 = 141,
kKeycodeF12 = 142,
kKeycodeNUM_LOCK = 143,
kKeycodeNUMPAD_0 = 144,
kKeycodeNUMPAD_1 = 145,
kKeycodeNUMPAD_2 = 146,
kKeycodeNUMPAD_3 = 147,
kKeycodeNUMPAD_4 = 148,
kKeycodeNUMPAD_5 = 149,
kKeycodeNUMPAD_6 = 150,
kKeycodeNUMPAD_7 = 151,
kKeycodeNUMPAD_8 = 152,
kKeycodeNUMPAD_9 = 153,
kKeycodeNUMPAD_DIVIDE = 154,
kKeycodeNUMPAD_MULTIPLY = 155,
kKeycodeNUMPAD_SUBTRACT = 156,
kKeycodeNUMPAD_ADD = 157,
kKeycodeNUMPAD_DOT = 158,
kKeycodeNUMPAD_COMMA = 159,
kKeycodeNUMPAD_ENTER = 160,
kKeycodeNUMPAD_EQUALS = 161,
kKeycodeNUMPAD_LEFT_PAREN = 162,
kKeycodeNUMPAD_RIGHT_PAREN = 163,
kKeycodeVOLUME_MUTE = 164,
kKeycodeINFO = 165,
kKeycodeCHANNEL_UP = 166,
kKeycodeCHANNEL_DOWN = 167,
kKeycodeZOOM_IN = 168,
kKeycodeZOOM_OUT = 169,
kKeycodeTV = 170,
kKeycodeWINDOW = 171,
kKeycodeGUIDE = 172,
kKeycodeDVR = 173,
kKeycodeBOOKMARK = 174,
kKeycodeCAPTIONS = 175,
kKeycodeSETTINGS = 176,
kKeycodeTV_POWER = 177,
kKeycodeTV_INPUT = 178,
kKeycodeSTB_POWER = 179,
kKeycodeSTB_INPUT = 180,
kKeycodeAVR_POWER = 181,
kKeycodeAVR_INPUT = 182,
kKeycodePROG_RED = 183,
kKeycodePROG_GREEN = 184,
kKeycodePROG_YELLOW = 185,
kKeycodePROG_BLUE = 186,
kKeycodeAPP_SWITCH = 187,
kKeycodeBUTTON_1 = 188,
kKeycodeBUTTON_2 = 189,
kKeycodeBUTTON_3 = 190,
kKeycodeBUTTON_4 = 191,
kKeycodeBUTTON_5 = 192,
kKeycodeBUTTON_6 = 193,
kKeycodeBUTTON_7 = 194,
kKeycodeBUTTON_8 = 195,
kKeycodeBUTTON_9 = 196,
kKeycodeBUTTON_10 = 197,
kKeycodeBUTTON_11 = 198,
kKeycodeBUTTON_12 = 199,
kKeycodeBUTTON_13 = 200,
kKeycodeBUTTON_14 = 201,
kKeycodeBUTTON_15 = 202,
kKeycodeBUTTON_16 = 203,
kKeycodeLANGUAGE_SWITCH = 204,
kKeycodeMANNER_MODE = 205,
kKeycode3D_MODE = 206,
kKeycodeCONTACTS = 207,
kKeycodeCALENDAR = 208,
kKeycodeMUSIC = 209,
kKeycodeCALCULATOR = 210,
kKeycodeZENKAKU_HANKAKU = 211,
kKeycodeEISU = 212,
kKeycodeMUHENKAN = 213,
kKeycodeHENKAN = 214,
kKeycodeKATAKANA_HIRAGANA = 215,
kKeycodeYEN = 216,
kKeycodeRO = 217,
kKeycodeKANA = 218,
kKeycodeASSIST = 219,
} ccKeypadKeycode;
The driver as I undertand it uses a letter to trigger the down action and another for the key up action, so as long as you don’t use these keys for something else in the app, then the android driver should be very simple. Listen to all key ups, if you get the down letter call the dispatcher and ask it to dispatch the equivalent arrow key.
Key mapping are
/*
UP ON,OFF = w,e
RT ON,OFF = d,c
DN ON,OFF = x,z
LT ON,OFF = a,q
A ON,OFF = y,t
B ON,OFF = h,r
C ON,OFF = u,f
D ON,OFF = j,n
E ON,OFF = i,m
F ON,OFF = k,p
G ON,OFF = o,g
H ON,OFF = l,v
*/
If you want to include any of this code in your game, it is released under the MIT license.
Hope that helps.