iCade button numbering.

A few notes from my research on the iCade. There is a developer document currently linked from this page:


Here is the direct link to the current version (1.5) in PDF format:


This document covers the button layout of the original iCade/iCade Core (same layout) used by the iPad, and the iCade Jr./iCade Mobile used by the iPhone/iPod Touch models. Only with the addition of photos showing the buttons for the iCade Mobile did I begin to understand I have been wrong about how the iCade organizes its buttons. Without one to test and play with, I have just been guessing based on available documentation.

(photo from http://www.ionaudio.com/products/details/icadecore)

(photo from http://www.ionaudio.com/products/details/icadecore)

All models provide either a joystick or a 4-way touch pad. For the original iCade (and the cost reduced iCade Core, which is the same unit but without the arcade-looking enclosure), there are eight buttons, organized as two rows of four buttons each. The buttons go red, black, black and white on each row, as if to indicate the group of 2×2 black buttons in the center are different than the red and white ones on the ends. I had been assuming that the main control buttons would be the black ones in the center, similar to the USB joystick I have been experimenting with, which labels the four buttons in the center with the Playstation symbols (square, circle, triangle, smiley face, cute kitty, whatever they are).

With the additional descriptions of the iCade Mobile button layout, I see now this is not the case. I had guessed that the buttons were numbered across, as in the first row being button 1-4 and the second row being button 5-8. This is not the case. Instead, the numbering looks more like this:

1 3 5 7
2 4 6 8

I realized this when I noticed the iCade Mobile was using the four buttons on the left (1-4) for it’s buttons, with 5-8 going to the front index finger buttons. The same was true for the iCade Jr., except buttons 5-8 were located on the back of that unit.

So, the four “primary” buttons for the iCade were 1-4, with two being red and two being black, and the other four (two red, two white) were the extra buttons. This was not what I expected, and it has led me to reorganize my button mapping for the iCade converter project.

There is only one diagram in the iCade documentation that numbers the buttons. Here it is, for the iCade Mobile:

(from http://www.ionaudio.com/products/details/icade)

(from http://www.ionaudio.com/products/details/icade)

Here it seems they number the directional buttons as 1-4, then the primary buttons as 5-8 and the final four as 9, 0, E1 (enter 1) and E2 (enter 2). With that in mind, I have changed my button definitions.

My arcade joystick has the primary buttons in the center, with the extras as grey buttons to the left and right:

Playtech Pro arcade fighting stick

So my arcade joystick thinks it is like a Playstation game pad, with the center color buttons being the right hand buttons, and the grey ones on the left and the right being the four buttons under the fingertips on the front of the gamepad.

If I wanted my joystick to use the same layout as the original iCade, I would have to map my buttons differently. With the joystick now being known as buttons 1-4, the iCade numbering layout looks like this:

  1  (5) (7) (9) (E1)
  2  (6) (8) (0) (E2)

I build my iCade array in the order of the 12 buttons:

// This is just used for printing out debug info to the console.
char iCadeDesc[][USB_BTN_COUNT] =
 {"Up", "Down", "Left", "Right",
 "Btn5", "Btn6", "Btn7", "Btn8",
 "Btn9", "Btn0", "BtnE1", "BtnE2"};

So in order to map my joystick over, I created alternate defines for my buttons so they would be easier to figure out:

// We will be treating joystick as a 16-bit value.
// Extra Buttons:
#define SELECT_USB  (1< &lt;8)  // Z1:0x0100 - Select
#define L3_USB      (1<&lt;9)  // Z1:0x0200 - L3
#define R3_USB      (1<&lt;10) // Z1:0x0400 - R3
#define START_USB   (1<&lt;11) // Z1:0x0800 - Start
// Joystick:
#define UP_USB      (1<&lt;12) // Z1:0x1000 - Up
#define RIGHT_USB   (1<&lt;13) // Z1:0x2000 - Right
#define DOWN_USB    (1<&lt;14) // Z1:0x4000 - Down
#define LEFT_USB    (1<&lt;15) // Z1:0x8000 - Left
// Grey/Front Buttons:
#define BTN1_USB    (1<&lt;0)  // Z2:0x0001 - L2
#define BTN2_USB    (1<&lt;1)  // Z2:0x0002 - R2
#define BTN3_USB    (1<&lt;2)  // Z2:0x0004 - L1
#define BTN4_USB    (1<&lt;3)  // Z2:0x0008 - R1
// Primary Buttons:
#define BTN5_USB    (1<&lt;4)  // Z2:0x0010 - "Triangle"
#define BTN6_USB    (1<&lt;5)  // Z2:0x0020 - "Circle"
#define BTN7_USB    (1<&lt;6)  // Z2:0x0040 - "X"
#define BTN8_USB    (1<&lt;7)  // Z2:0x0080 - "Square"

// Redefine some buttons for Playstation type layout:
#define TRI_BTN     BTN5_USB 
#define CIR_BTN     BTN6_USB
#define X_BTN       BTN7_USB
#define SQR_BTN     BTN8_USB
#define L1_BTN      BTN3_USB
#define R1_BTN      BTN4_USB
#define L2_BTN      BTN1_USB
#define R2_BTN      BTN2_USB

The group at the end just gives me Playstation-style labels for the buttons I will be using. So, for a gamepad style controller, my mappings would be like this:

unsigned int myPins[USB_BTN_COUNT] =
  /*5*/SQR_BTN,   /*6*/X_BTN,    /*7*/TRI_BTN,   /*8*/CIR_BTN,
  /*9*/BTN5_USB,  /*0*/BTN6_USB, /*E1*/BTN7_USB, /*E2*/BTN8_USB};

…but for my arcade stick, where the Playstation buttons are in the center, I would map it like this:

unsigned int myPins[USB_BTN_COUNT] =
   /*5*/L1_BTN,  /*6*/L2_BTN,  /*7*/SQR_BTN, /*8*/X_BTN,
   /*9*/TRI_BTN, /*0*/CIR_BTN, /*E1*/R1_BTN, /*E2*/R2_BTN};

Here you can see I assign my L1 button (top left grey) to be button 5 to the iCade, L2 for button 6, and so on. This will map my layout to match the original iCade.

It looks like I am going to need a way to switch the type of joystick being used, since clearly things are different. I will work on this next.

Oh, and I plugged up my Legacy Engineering Atari 2600 USB joystick and found it did not work at all with my converter. (Original company seems to be gone, but here is another recreation.) Instead of stuffing bits in Z1 and Z2, the Atari joystick puts them in the X and Y locations. 0 meaning left, 128 meaning center, and 255 meaning right. They are basically taking a digital joystick and faking out analog positions. The single button is mapped in to Z1 as a bit. (Inside this joystick you can hack on additional buttons, and I bet they fill out other bits in Z1.)

So, I now need to deal with two types of digital layouts (gamepad style, and fighting stick style) and an analog type stick (even one being faked, like the Atari).

To be continued…

Leave a Reply