GLBasic forum

Codesnippets => Inline / 3rd party => Topic started by: mrplant on 2011-Sep-10

Title: iCade Support?
Post by: mrplant on 2011-Sep-10
I have just taken delivery of the iCade arcade cabinet for the iPad.
http://www.ionaudio.com/products/details/icade

The way this bluetooth keyboard maps the keys is detailed in this document:

http://www.ionaudio.com/downloads/iCade_Dev_Resource_v1.3.pdf

There is an SDK available and a sample Objective-C program here:

https://github.com/scarnie/iCade-iOS

I can compile and get it working ok but I lack the knowledge to interface this to GLBasic - that would be awesome.. But I think with the way the example talks to the view controller/Bluetooth keyboard
there might be some problems in doing that..

just wondering if anyone out there has any views on if this would be possible?

Maybe in the future GLBasic could add support directly?

I think going forward, the iCade and the new Atari stick (http://toucharcade.com/2011/09/07/more-details-on-the-atari-arcade-joystick-peripheral-for-ipad/) are going to sell quite nicely and games that support them will do well!

steve
Title: Re: iCade Support?
Post by: Kitty Hello on 2011-Sep-14
might be worth a try. Someone should write a wrapper that writes the last key pressed with bluetooth into a variable that I can output with inkey$.
Title: Re: iCade Support?
Post by: spacefractal on 2011-Sep-14
INKEY$ would been stupid to use with iCade, because you need to checkout multiple keys, where inkey$ dont support (and also its dont support when keys is released too). Course its should output with KEY(). Also its could been some PLATFORMINFO$() to tell if a such a keyboard is installed and used.
Title: Re: iCade Support?
Post by: Kitty Hello on 2011-Sep-14
right. But I need some code to get the key up/down events before I can implement that.
Buing an iCade is not really cheap.
Title: Re: iCade Support?
Post by: MrTAToad on 2011-Sep-14
It sounds like you would need to modify the SDL key handling routine itself...
Title: Re: iCade Support?
Post by: Kitty Hello on 2011-Sep-14
No SDL used for iOS. I'll talk to Trucidare on this later.
Title: Re: iCade Support?
Post by: mrplant on 2011-Sep-15
Jeff Minter has added support to all his games - see him play here: http://www.youtube.com/watch?v=1P5bsQN5G6I

re. replies - Key() and PLATFORMINFO$ seem the way to go...

The example program in the link I gave earlier shows a joystick on screen that shows when you press the buttons etc.
It seems to be using a second view controller on top of your main one that passes events back but someone much more cleverer than me will probably find a way...
Title: Re: iCade Support?
Post by: Kitty Hello on 2011-Sep-15
I like the iCade. I will add support for it. I'll put it into GETJOYX(1), GETJOYBUTTON(1). What do you think?
I also think about enabling bluetooth keyboards, so you can use INKEY$ with them.
I saw the code and it's pretty easy to do.
Title: Re: iCade Support?
Post by: ampos on 2011-Sep-15
Quote from: Kitty Hello on 2011-Sep-15
I like the iCade. I will add support for it. I'll put it into GETJOYX(1), GETJOYBUTTON(1). What do you think?
I also think about enabling bluetooth keyboards, so you can use INKEY$ with them.
I saw the code and it's pretty easy to do.

Yes, it is the correct way to do it  :nana:
Title: Re: iCade Support?
Post by: spacefractal on 2011-Sep-15
bluetooth keyboard, its the correct way to do.

Not sure about iCade, which depend how its use the input. Ifs its s simple keyboard (etc a keyboard encoder but with few keys used) with send keys to the iPad, there is no other to do that with KEY(), elsewise JOYX(1) is the best of course.... and of course some PLATFORMINFO$ to detect it.
Title: Re: iCade Support?
Post by: Kitty Hello on 2011-Sep-15
I found no legal way to detect a connected external keyboard so far :(
Title: Re: iCade Support?
Post by: mrplant on 2011-Sep-15
No legal way to detect bluetooth keyboard?

I know the SDK doesn't allow it at present I don't think.. I have seen people ask this question on the StackOverflow forums etc.

I have an external bluetooth keyboard here and tried it with some icade enabled games but no joy..

Surely though iCade support is possible maybe mapping to Key() or something - how is the example Icade program passing the codes back legally?

I know there are a few games approved in the app store - Atari Arcade for one..

I know Jeff Minter has just added support to his games over at LLamasoft - maybe he could shed some light...

So just to clarify - How is the example program doing it and surely it would be approved ok for app store use?

Apples own take on it is its ok but they don't like game authors mentioning iCade support in their games - in the game menu It has to say select alternative input method or something to get approved.

That is why the iCade's main manufacturers site is maintaining a list of icade enabled games.

I know of at least 10 games in the app store at the moment that support the icade and its going to get better!!

GLBasic support for this would be great if possible!!

In short - my limited technical take on it is that its not possible to read the bluetooth keyboard with the official SDK but it is possible to read the iCade key values ok using the Official SDK and example program - correct?

Update: I have just tweeted the big man.... Maybe he has some example code he could share? or some advice? I know he's a busy ox though..... ;-)
Title: Re: iCade Support?
Post by: ampos on 2011-Sep-15
I have a bluetooth keyboard I can attach to my iPhone, if you want me to make some testings...
Title: Re: iCade Support?
Post by: stinky ox on 2011-Sep-15
Basically I modified scarnie's iCade reader view from his demo on github:

https://github.com/scarnie/iCade-iOS

I basically made the insertText method maintain a single bitmap of all the switch states in a single longword.  Whenever the state changes this is updated and passed out to the delegate, which makes it available to the games, which just read it as an int in an info structure.

This makes it easy to support the iCade completely transparently = you just do your normal controls, and additionally check the bitmap for any switch closures.  If there's no iCade the bitmap will be empty and you do nothing.  If there are bits there just act accordingly.

Title: Re: iCade Support?
Post by: mrplant on 2011-Sep-15
Many thanks Jeff - I know you are a busy man - look forward to your new game any day now! Goat Up!
Title: Re: iCade Support?
Post by: Gary on 2011-Sep-16
Quote from: stinky ox on 2011-Sep-15
:nw: :nw: :nw: :nw: :nw: :nw: :nw: :nw: :nw: :nw: :nw: :nw:

Kitty has competition for the title of coding god on the forum now :)

Anyone know the wereabouts of Matt Smith? :)
Title: Re: iCade Support?
Post by: Kitty Hello on 2011-Sep-16
Quote from: stinky ox on 2011-Sep-15
I basically made the insertText method maintain a single bitmap of all the switch states in a single longword.

You mean - once there has been one character "posted" to the hidden input field, a keyboard seems to be attached? Awesome!
Title: Re: iCade Support?
Post by: spacefractal on 2011-Sep-16
in my game, in Wondows and other devices with keyboard, if there is is some key pressed the pointer is gone, but if you move the mouse, the pointer is back. The last one would of course been hidden in iOS. Buts its that way I would detect touchscreen/keyboard, so its really transperancy.

Also its really stubid move Apple due, just becaues they might not like some thing like that, but its dont break anything at all. You can dedicate to support it as a alternativt or not. So here I dont understand Apple.
Title: Re: iCade Support?
Post by: mrplant on 2011-Sep-16
If anyone needs anything tested - I have available Ipad2 and iCade unit (as well as apple Bluetooth keyboard).
Title: Re: iCade Support?
Post by: Kitty Hello on 2011-Sep-16
OK, it's working.
The only drawback is: The iCade protocol uses the keys "Z" and "Y", which are SWAPPED on a German keyboard layout. Oh. My.

So you will have to switch to the US keyboard layout before playing iCade/iTouchPad games (in iCade mode).

I hope I can find the keyboard layout to fix that, soon. Otherwise, the iPadControl default "keyboard setting" might be another option to implement instead.
I'll talk to iCade people.

Update during the weekend.

The GETNUMJOYSTICKS() will return "2" once you pressed one button on the iCade. Before that it returns "1", which is the acceleration "Joystick".

The GETJOYX(1), GETJOYY(1) and GETJOYBUTTON(1, n) will return the button/dpad state. I currently implemented 4 buttons to be compatible with the iCade/Atari Arcade.

So long and thanks for all the fish.






Title: Re: iCade Support?
Post by: mrplant on 2011-Sep-16
Sounds amazing!!!

The way its been implemented is very elegant.

Will report all findings!!
Title: Re: iCade Support?
Post by: Ian Price on 2011-Sep-16
Another fantastic feather in GLBasic's already bulging cap =D
Title: Re: iCade Support?
Post by: spacefractal on 2011-Sep-16
they allready stated on homepage you need to select "US" keyboard. damn. Its a US unit, so of course they are not aware some keyboards might have keys swapped, which is a common issue in German Keyboads.

If Z and Y is both used, I do guess the values could been swapped if its in German status, or alternative simply let users remap thier buttons before use (etc its could automatic popin when some button is pressed).
Title: Re: iCade Support?
Post by: Kitty Hello on 2011-Sep-17
OK, update is live. Read the logfile for more info.

Yes, the Y/Z issue is a true pain. I hope there's a way to detect the keyboard layout.
Otherwise, I contact iCade and ask for a bugfix. I have a solution to fix it.
Title: Re: iCade Support?
Post by: spicypixel on 2011-Sep-17
This sounds interesting would you mind re-iterating how you grab the iCade information from within GLB. I'm also a little confused about the keys issue I thought this was joystick directions and joystick buttons?
Title: Re: iCade Support?
Post by: mrplant on 2011-Sep-17
>I'm also a little confused about the keys issue I thought this was joystick directions and joystick buttons?

The iCade interfaces with iOS by simulating virtual keys being pressed/released. I wasn't aware that German keyboards swapped Y and Z previous so I learnt something interesting there. I hope there is a workaround for getting around this issue.
Title: Re: iCade Support?
Post by: mrplant on 2011-Sep-17
I applied the new update then the standard joystick demo in the help file and checked I have the iCade connected ok. I ran one of Jeff's games to verify it works and it does. My keyboard is set to UK (US layout) but for some reason,
when running on the iPad it can only see the acceleration device only.
I did a bit of manual poking around reading GETJOYX(1) directly and wrote values to screen etc. but still same result. Strange..

When I force it to read the GETJOYX(1) and GETJOYY(1) and button(1) values it seems to be reading a copy of the accelerometer device again. Mind you I am reading from 1 more than the number of joysticks reported, if you
follow.. as It is not actually registering the iCade device.

Anyone else get it to work?
Title: Re: iCade Support?
Post by: Kitty Hello on 2011-Sep-17
try a text box. Does it instert characters when you press a button?
I found a way to get the z,y swap issue fixed! When you press down and then up, the "down" position is still locked. That cant be! Thus you must have a German layout  that way the first down/up movement is a bit broken, but at least it works ok then.
Title: Re: iCade Support?
Post by: mrplant on 2011-Sep-17
Hi. Thats great you have worked around the YZ/ZY issue.
You are saying to create a text box - I take it you mean something link input A$,0,0
I tried this on the iPad and had a flashing cursor but the iCade didn't put in any characters when I pressed things on it.
I also synced up my apple bluetooth keyboard and same there - but I wasn't really expecting that to work. :S
Again, I am not sure if I am testing exactly what you meant above..

I will post some screenshots later of what my test program is seeing.
Title: Re: iCade Support?
Post by: mrplant on 2011-Sep-17
This is my test code for running on the iPad - its mainly the example program provided in the HELP file except I am being naughty and forcing it to read devices that may or may not exist!

// Joy test code below:
//
// iCade Suport Notes:
//
//   - Start App, then press one button on iCade
//  - n% = GETNUMJOYSTICK() returns "2" now on iOS.
//  - GETJOYX(1), GETJOYY(1) and GETJOYBUTTON(1,n) to get status.

LOADFONT "ZXFont.png",1 // This is a 512X256 font (32x32). My screen res is 1024x768! (iPad Landscape)
SETFONT 1

CLEARSCREEN RGB(0,0,0) // Set the backbuffer background colour to Black.
SHOWSCREEN // Show it.
LOCAL a$, b$
LOCAL i%, b%,n

WHILE TRUE
   b = GETNUMJOYSTICKS()
   IF b = 0
      BigPrint ("SCANNING - PLUG IN JOYSTICK NOW.",0,22,1)
      BigPrint ("(NO JOY DEVICES DETECTED)",4,23,1)
   ENDIF

FOR i=0 TO 1 // Bad code here as I am forcing use of joystick numbers instead of reading count in GETNUMJOYSTICKS!!!! But as a test...
  BigPrint ("JOY "+i+" NAME=("+GETJOYNAME$(i)+")", 0, i*9,1 // Name of Device
  BigPrint ("X:"+GETJOYX(i) + " Y:"+GETJOYY(i)+ " Z:"+ GETJOYZ(i),0,(i*9)+1,1) // XYZ-Position
  BigPrint ("RX:"+GETJOYRX(i) + " RX:"+GETJOYRY(i)+ " RX:"+GETJOYRZ(i),0,(i*9)+2,1) // XYZ-Rotation
  a$=""
  FOR n=0 TO 5 // Only look at a few buttons
   a$=a$+"B"+n+":"+GETJOYBUTTON (i, n)+" "
  BigPrint (a$, 0, (i*9)+3,1)

  NEXT
  a$=""
     FOR n=6 TO 10 // Up to 32 Buttons
   a$=a$+"B"+n+":"+GETJOYBUTTON (i, n)+" "
  NEXT
  BigPrint (a$, 0, (i*9)+4,1)

  // DIGI-Joystick
  b$="DX:"+ GETDIGIX(i)+" DY:"+GETDIGIY(i)
  BigPrint (b$, 0, (i*9)+5,1)
NEXT
SHOWSCREEN
SLEEP (75)
WEND


///////////////////////////////////////
//   Big Print
///////////////////////////////////////


FUNCTION BigPrint: Print$, XCoord%, YCoord%, FontNum%
   // 0 means use currently set font again!
   IF FontNum%
      SETFONT FontNum% // Select Font
   ENDIF
   PRINT Print$,32*XCoord,32*YCoord,FALSE // Force fixed width!
ENDFUNCTION

This code produces an output like this on the iPad when running whilst synced with the iCade.

http://www.pictureviewerpro.com/storage/gen/test.png

And yes, that is the Sinclair ZX81 font!! A little project I have going.... :S
Title: Re: iCade Support?
Post by: mrplant on 2011-Sep-17
Taito rips off the Icade and introduces... the Invadercade..

http://toucharcade.com/2011/09/15/taito-set-to-release-its-own-arcade-cabinet-peripheral/#comments

Title: Re: iCade Support?
Post by: spicypixel on 2011-Sep-18
Quote from: mrplant on 2011-Sep-17
Taito rips off the Icade and introduces... the Invadercade..

http://toucharcade.com/2011/09/15/taito-set-to-release-its-own-arcade-cabinet-peripheral/#comments

1 button and it only supports portrait by the look of the cabinet. Ubbish :)
Title: Re: iCade Support?
Post by: mrplant on 2011-Sep-18
Couldn't agree more!
Title: Re: iCade Support?
Post by: Kitty Hello on 2011-Sep-19
please press the "trash button" before you recompile. If getnumjoysticks() returns 0, the device is not paired, or you did not press a button, yet. (1st button press "plugs the stick in").

I tested to auto-detect the keyboard layouts and I think it's pretty possible to do so:

Code (glbasic) Select

There are three main latin keyboard layouts: QWERTY, QWERTZ and AZERTY – keyboard layouts.
The QWERTZ layout switches Y - Z
The AZERTY layout switches A - Q and Z - W


// iCade events:
  WE    YT UF IM OG
AQ  DC
  XZ    HR JN KP LV

QUERTZ/AZERTY: W w/o Z (UP,   pressed w/o DOWN, released)
AZERTY:        Q w/o A (LEFT, release w/o LEFT, pressed)
               Z w/o X (DOWN, release w/o DOWN, pressed)
Title: Re: iCade Support?
Post by: mrplant on 2011-Sep-19
Amazing!!

I've been compiling test programs for ages - the key to it working was pressing the Trash Icon like you said before recompiling..

I can't figure out why this would matter - I suppose part of my compilation was using precompiled routines from a previous version?

Anyway the GREAT news to report is SUCCESS!!

Here I am paired and pressing a joystick and a button at same time..

Ohh - the important screenshot..

http://www.pictureviewerpro.com/storage/gen/icade.png (on my font - lower case letters show up as inverted colours)

Bear in mind my code is still being rather naughty so ignore the phantom 3rd device shown... Its the second one that matters of course!!

Now I will go and fix my code up.

I compiled this on iOS 4.2 and iOS 5.- (Beta 7) as I initially thought that might be the problem at my end and can report it works fine on both anyway.

Take a bow, Kitty Hello!

This is awesome!!   :good: :good: :good: :nw: :nw: :nw: :nw: :nw: :nw: :nw: :nw: :nw: :nw: :nw:
Title: Re: iCade Support?
Post by: Gary on 2011-Sep-19
could you not have a calibrate joystick option in your software? if you ask the user to move the joystick or press a button that uses Y or Z and it returns the wrong keypress then set a flag in GLB to switch to the reversed keys being looked for?

Nice to see another option being added though
Title: Re: iCade Support?
Post by: Kitty Hello on 2011-Sep-19
Nah, don't make it complicated to users. I'll up an update tonight where the keyboard layout is taken care properly (once you pressed up/down). iControlPad is an awesome addition to the iDevices.
Get one and spread the word.

Title: Re: iCade Support?
Post by: mrplant on 2011-Sep-19
I think transparent use is the way to go - it keeps Apple happy who don't want the iCade devices mentioned in your app - for fear it would confuse other users without one...

Jeff Minters new game Goat Up has the right idea - just detect the device on the fly and start using it when game in launched - with no fanfare - it just works..

The way this is being implemented in GLBasic will enable us to do the exact same thing in our apps.

This is great news.

I will pass word around as much as I am able to!!
Title: Re: iCade Support?
Post by: doimus on 2011-Sep-19
Quote from: Kitty Hello on 2011-Sep-19
iControlPad is an awesome addition to the iDevices.
Get one and spread the word.

Yeah, I bet they will earn much more money on IControlPad than on Pandora. It's the same guy(s) developing it.

That thing would rock with iPad2 and big screen TV.
It's a shame we can't have emulators on non-jailbroken devices.
Title: Re: iCade Support?
Post by: mrplant on 2011-Sep-20
As my last report back on this subject, I thought I would post some code I came up with.
It's not amazingly crafted or anything but it does the job I wanted done and may be useful to someone.

In my game - I am only interested in Up, Down, Left Or Right. The Fire Button stops the game - its a puzzle style tiled game!
You therefore may have to adapt the code below. I ignore diagonals on purpose as they would not suit my gameplay well.
This code therefore is "as is" so please adapt to your own usage. You will see it is pretty easy to do.
It is mulit-platform which is what i wanted - Windows, Mac and iOS and is well tested now.
I read digital and analogue input on the PC (Windows), analogue on the Mac and iCade input on IOS devices.
The Function JoyDevInput$() returns an empty or one character text string which can be acted upon in your game.
"" for no input. "U" for up. "D" for down. "L" for left, "R" for right and "F" for fire. Fire always gets priority, as in my game, it stops play!

I hope it is of use to someone. V2.0:

Code (glbasic) Select

///////////////////////////////////////
// Joystick Device Input Reading
///////////////////////////////////////


FUNCTION JoyDevInput$:

LOCAL Joy$="" // Used to hold the final return value.
LOCAL X#, Y#, XD#, YD# // Used to read raw joystick values.
LOCAL n% = 0 // Used to loop through buttons.
LOCAL v% = 0 // Used to keep a running count on button values.

// The following code ia multi platform and can be called anytime to check for working joystick and iCade devices.
//
// The function returns a sting which is blank for nothing pressed. It does the same if no device is found.
//
// If a device is found, it returns a one character string as follows:
//
// "U" for when Up is pressed. "D" for when Down Is pressed.
// "L" for when Left is pressed. "R" for when right is pressed and "F" for when ANY fire button being pressed.
//
// Note: This routine ignores diagonals, even though the device supports them. It also gives priority to fire buttons,
// So, if a direction plus fire is pressed - only the fire value will be returned in this case.
// The Windows code checks both analogue and digital sticks and again ignores conflicting inputs.
// This behaviour is all by design and intended.

// The following code is compiled for Windows Platform only:
?IFDEF WIN32
IF GETNUMJOYSTICKS()=0
Joy$ = "" // Return empty string if no devices found.
ELSE
// Read raw Y value from Device 0
Y = GETJOYY(0)
YD = GETDIGIY(0) // On the PC, we also look at the digital stick values as well.
IF Y = -1 OR YD = -1
Joy$ = Joy$ + "U"
ELSEIF Y = 1 OR YD = 1
Joy$ = Joy$ + "D"
ENDIF
// If we have a movement on Y and also on Digital stick Y and they are not the same movement, then ignore the input!
IF ((Y <> 0) AND (YD<>0)) AND (Y<>YD)
Joy$ = Joy$ + "LR" // This invalidates the input as the length of this string must be one for a valid input!
ENDIF
// Read raw X value from Device 0
X = GETJOYX(0)
XD = GETDIGIX(0) // On the PC, we also look at the digital stick values as well.
IF X = -1 OR XD = -1
Joy$ = Joy$ + "L"
ELSEIF X = 1 OR XD = 1
Joy$ = Joy$ + "R"
ENDIF
// If we have a movement on X and also on Digital stick X and they are not the same movement, then ignore the input!
IF ((X <> 0) AND (XD<>0)) AND (X<>XD)
Joy$ = Joy$ + "UD" // This invalidates the input as the length of this string must be one for a valid input!
ENDIF
// Read status of first 8 buttons from Device 0 and add a running total.
FOR n = 0 TO 7
v = v + GETJOYBUTTON(0,n)
NEXT
// All raw values now read - now to process final return value.
// Priority to (any) buttons first:
IF v
Joy$= "F" // Return with "F" if any buttons pressed!
ELSE
// If more than one direction pressed, return an empty string, otherwise keep value set earlier.
IF LEN(Joy$) > 1
Joy$ = ""
ENDIF
ENDIF
ENDIF
?ENDIF

// The following code is compiled for Mac OSX Platform only:
?IFDEF OSXX86
IF GETNUMJOYSTICKS()=0
Joy$ = "" // Return empty string if no devices found.
ELSE
// Read raw Y value from Device 0
Y = GETJOYY(0)
IF Y <= -1
Joy$ = Joy$ + "U"
ELSEIF Y >= 1
Joy$ = Joy$ + "D"
ENDIF
// Read raw X value from Device 0
X = GETJOYX(0)
IF X <= -1
Joy$ = Joy$ + "L"
ELSEIF X >= 1
Joy$ = Joy$ + "R"
ENDIF
// Read status of first 8 buttons from Device 0 and add a running total.
FOR n = 0 TO 7
v = v + GETJOYBUTTON(0,n)
NEXT
// All raw values now read - now to process final return value.
// Priority to (any) buttons first:
IF v
Joy$= "F" // Return with "F" if any buttons pressed!
ELSE
// If more than one direction pressed, return an empty string, otherwise keep value set earlier.
IF LEN(Joy$) > 1
Joy$ = ""
ENDIF
ENDIF
ENDIF
?ENDIF


// The following code is compiled for iOS Platform only:

?IFDEF IPHONE
IF GETNUMJOYSTICKS()<>2 // The first joystick on iOS devices is the Accelerometer.
Joy$ = "" // Return empty string if no iCade device detected.
ELSE
// Read raw Y value from Device 1 - The iCade device!
Y = GETJOYY(1)
IF Y = -1
Joy$ = Joy$ + "U"
ELSEIF Y = 1
Joy$ = Joy$ + "D"
ENDIF
// Read raw X value from Device 1
X = GETJOYX(1)
IF X = -1
Joy$ = Joy$ + "L"
ELSEIF X = 1
Joy$ = Joy$ + "R"
ENDIF
// Read status of first 8 buttons from Device 1 and add a running total.
FOR n = 0 TO 7
v = v + GETJOYBUTTON(1,n)
NEXT
// All raw values now read - now to process final return value.
// Priority to (any) buttons first:
IF v
Joy$= "F" // Return with "F" if any buttons pressed!
ELSE
// If more than one direction pressed, return an empty string, otherwise keep value set earlier.
IF LEN(Joy$) > 1
Joy$ = ""
ENDIF
ENDIF
ENDIF
?ENDIF

RETURN Joy$ // Return from function with the value detected above.

ENDFUNCTION