Take the 2-minute tour ×
Arqade is a question and answer site for passionate videogamers on all platforms. It's 100% free, no registration required.

I just got an iCade -- it is technically for an Apple iPad, but it is basically a generic bluetooth keyboard arcade controller.

iCade pic

It's great! But once I paired it with my laptop as a bluetooth keyboard for testing, I discovered something odd that does not bode well for using the iCade with MAME. All inputs show up as two (and only two) keypresses – one key when pushed down, and another key when released. Like so:

Joystick

w, ea, qd, cx, z

Buttons

(1 red) y, t  (2 blk) u, f  (3 blk) i, m  (4 wht) o, g  

(5 red) h, r  (6 blk) j, n  (7 blk) k, p  (8 wht) l, v  

Most MAME emulators expect standard keyboard behavior. That is, when you are pressing left you hold down left the entire duration of the movement.

This isn't a big deal for the buttons -- buttons are instant activate so if I pressed y on my keyboard that is the same as, say, pressing fire in Galaxian.

But it makes the joystick a non starter since the keyboard key is not "held down" -- that is, when I use the joystick and press ← one a is sent.. ever. But when I stop holding down ← q is sent.

How can I configure MAME or other emulators to work with the iCade joystick and its peculiar keyboard interface? Is there any way to create a MAME config file that will work with the iCade?

share|improve this question
    
Ah man the Gaming blog should get a review of this! –  Ivo Flipse Jun 17 '11 at 21:41
1  
There is always : The iCade SDK can be requested by emailing icadedev@ionaudio.com Haven't done this myself tho (yet...) –  albiglan Jun 17 '11 at 21:49
    
I don't want to post this as an answer as I do not know if I am right, but I would not be suprised if MAME supports this. One known issue with USB keyboard drivers is they only allow 6 simultaneous key-presses (ps\2 did not have this limitation), you frequently run in to this when building a 4 player arcade cabinet. Using this scheme you could get around that 6, I doubt that the iCADE guys thought of this first and is likely already in MAME's codebase. –  Scott Chamberlain Jun 19 '11 at 20:20
    
@scott if it is I can find no reference to it on the entire internet. Feel free to post an answer if you can... –  Jeff Atwood Jun 26 '11 at 13:02
    
are you on windows 7? If you are not I may have a option for you. –  Scott Chamberlain Jun 26 '11 at 22:53

2 Answers 2

I looked in to the source of MAME and, unfortunately, it does not appear to be supported, it looks like the iCade guys were the first to think of it after all. I see two options:

  1. Make a patch and add this ability to the source of MAME. (I am actually put this on my list of hobby coding projects when I get around to it)

  2. Use an intermediary program to translate the key pulses into key presses.

Option 2 is the easier solution, here is my stab at it using AutoHotKey:

; This is a program to translate the iCade to normal button presses. Use with
; the MAME controller configuration posted with this file at 
; http://gaming.stackexchange.com/questions/24774/icade-bluetooth-keyboard-mappings-for-mame
; Press END to terminate script

; iCade layout, first letter is the pressed signal, the second key is the
; released signal.
;
; Joystick
;
;      w, e
;
;  a, q    d, c
;
;      x, z
;
; Buttons
;
; (1 red) y, t  (2 blk) u, f  (3 blk) i, m  (4 wht) o, g
;
; (5 red) h, r  (6 blk) j, n  (7 blk) k, p  (8 wht) l, v



; If it is not sending commands try another send mode.
; AutoHotKey and MAME have been known to be problematic on Win7.
; You may need to totally disable UAC and reboot before it will work.
;SendMode Play
;SendMode Input

end::ExitApp
#IfWinActive ahk_class MAME


w::Send {Blind}{Up downtemp}
e::Send {Blind}{Up up}
a::Send {Blind}{Left downtemp}
q::Send {Blind}{Left up}
d::Send {Blind}{Right downtemp}
c::Send {Blind}{Right up}
x::Send {Blind}{Down downtemp}
z::Send {Blind}{Down up}
y::Send {Blind}{1 downtemp} ; Red top row
t::Send {Blind}{1 up} ; Red top row
u::Send {Blind}{2 downtemp} ; Left black top row
f::Send {Blind}{2 up} ; Left black top row
i::Send {Blind}{3 downtemp} ; Right black top row
m::Send {Blind}{3 up} ; Right black top row
o::Send {Blind}{4 downtemp} ; White top row
g::Send {Blind}{4 up} ; White top row
h::Send {Blind}{5 downtemp} ; Red bottom row
r::Send {Blind}{5 up} ; Red bottom row
j::Send {Blind}{6 downtemp} ; Left black bottom row
n::Send {Blind}{6 up } ; Left black bottom row
k::Send {Blind}{7 downtemp} ; Right black bottom row
p::Send {Blind}{7 up} ; Right black bottom row
l::Send {Blind}{8 downtemp} ; White bottom row
v::Send {Blind}{8 up} ; White bottom row

here is a pre-setup config file, just drop this in your ctrlr folder with the name icade.cfg and launch MAME with the switch -ctrlr icade

<?xml version="1.0"?>
        <!-- iCade input configuration file -->
        <!-- Requires the AutoHotKey script at http://gaming.stackexchange.com/questions/24774/icade-bluetooth-keyboard-mappings-for-mame -->
<mameconfig version="10">
    <system name="default">
        <input>
            <port type="P1_JOYSTICK_UP">
                <newseq type="standard">
                    KEYCODE_UP
                </newseq>
            </port>
            <port type="P1_JOYSTICK_DOWN">
                <newseq type="standard">
                    KEYCODE_DOWN
                </newseq>
            </port>
            <port type="P1_JOYSTICK_LEFT">
                <newseq type="standard">
                    KEYCODE_LEFT
                </newseq>
            </port>
            <port type="P1_JOYSTICK_RIGHT">
                <newseq type="standard">
                    KEYCODE_RIGHT
                </newseq>
            </port>
            <port type="P1_BUTTON1">
                <newseq type="standard">
                    KEYCODE_1
                </newseq>
            </port>
            <port type="P1_BUTTON2">
                <newseq type="standard">
                    KEYCODE_2
                </newseq>
            </port>
            <port type="P1_BUTTON3">
                <newseq type="standard">
                    KEYCODE_3
                </newseq>
            </port>
            <port type="P1_BUTTON4">
                <newseq type="standard">
                    KEYCODE_5
                </newseq>
            </port>
            <port type="P1_BUTTON5">
                <newseq type="standard">
                    KEYCODE_6
                </newseq>
            </port>
            <port type="P1_BUTTON6">
                <newseq type="standard">
                    KEYCODE_7
                </newseq>
            </port>
            <port type="P1_START">
                <newseq type="standard">
                    KEYCODE_4
                </newseq>
            </port>
            <port type="START1">
                <newseq type="standard">
                    KEYCODE_4
                </newseq>
            </port>
            <port type="COIN1">
                <newseq type="standard">
                    KEYCODE_8
                </newseq>
            </port>
        </input>
    </system>
    <system name="neogeo">
        <input><port type="P1_BUTTON1">
                <newseq type="standard">
                    KEYCODE_1
                </newseq>
            </port>
            <port type="P1_BUTTON2">
                <newseq type="standard">
                    KEYCODE_2
                </newseq>
            </port>
            <port type="P1_BUTTON3">
                <newseq type="standard">
                    KEYCODE_3
                </newseq>
            </port>
            <port type="P1_BUTTON4">
                <newseq type="standard">
                    KEYCODE_4
                </newseq>
            </port>
            <port type="P1_BUTTON5">
                <newseq type="standard">
                    KEYCODE_5
                </newseq>
            </port>
            <port type="P1_BUTTON6">
                <newseq type="standard">
                    KEYCODE_6
                </newseq>
            </port>
            <port type="P1_BUTTON7">
                <newseq type="standard">
                    KEYCODE_7
                </newseq>
            </port>
            <port type="P1_BUTTON8">
                <newseq type="standard">
                    KEYCODE_8
                </newseq>
            </port>
        </input>
    </system>
</mameconfig>
share|improve this answer
    
+1 for excellent (if kinda unavoidably nasty..) workaround –  Jeff Atwood Jun 26 '11 at 23:36
    
I updated the post, if you disable UAC it may work on Windows Vista/Windows 7 as it disables some of the isolation checks (Auto hotkey uses Journaling Hooks for its "Play" mode) that are still in affect even if both apps are administrators. –  Scott Chamberlain Jun 26 '11 at 23:50
    
gaming.stackexchange.com/q/50630/23 –  badp Feb 13 '12 at 0:06

Unfortunately, this strange operation is a hack to support iOS due to limited API support for external hardware. Currently, the iOS SDK does not expose the internal UIEvents for keydown / keyup messages, so ION send two keypresses to allow developers to determine state transitions for emulators and games. Essentially a keydown/keyup when you press a button and then a second keydown/keyup when you release the button. This is not standard keyboard operation, as you have discovered.

I am willing to bet there is a combination of buttons that would change the iCade to behave like a regular keyboard, and I bid anyone good luck figuring that out! Other controllers, like the iControlPad have multiple operating modes, which is why I suspect the iCade is similar.

I created and released an MIT licensed SDK for iCade last night, but I doubt you are running this on an iPad.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.