GLBasic forum

Main forum => Tutorials => Topic started by: spacefractal on 2015-Nov-13

Title: How to uses GameInput API.
Post by: spacefractal on 2015-Nov-13
Download link for GameInput API:
https://www.dropbox.com/s/1o0frsdrqzhjz57/EXTRAS.zip?dl=0

GameInput API is a replacement for Android.GameController$() code, except its runs on more platform than just Android. Here its also supports iOS, tvOS, Pandora and Windows as well.

1. A basic uses for GameInput code could been something like this:

Code: (glbasic) [Select]
LOCAL Left, Right, Up, Down

GameInput.update()
GameInput.SetPresaure(0) // Analog Presaure is supported on iOS only, include all buttons on that platform.

FOR i=1 to 2
Left=GameInput.LeftStick_Left(i)+GameInput.Left(i); IF Left>1 THEN Left=1
Right=GameInput.LeftStick_Right(i)+GameInput.Right(i); IF Right>1 THEN Right=1
Up=GameInput.LeftStick_Up(i)+GameInput.Up(i); IF Up>1 THEN Up=1
Down=GameInput.LeftStick_Down(i)+GameInput.Down(i); IF Down>1 THEN Down=1


A=GameInput.ActionButton("A", i)
B=GameInput.ActionButton("B", i)
Y=GameInput.ActionButton("Y", i)
X=GameInput.ActionButton("X", i)
NEXT

SHOWSCREEN

You can also checking other forms for buttons, like these:

1. GameInput.CenterButton() for checking the Center button on Android TV remote.
2. GameInput.Back() for checking the BACK button on the controller.
3. GameInput.isProfileChanged() can been checked, if something have been changed to the controller (required on iOS).

On Android, you can also uses PLATFORMINFO$("DEVICE") as well. Here its auto change to "KEYBOARD" or "TOUCHSCREEN", what the user have changed last time.

4. GameInput.GetButtonName$() can been used to check the name of the button, which might differ from platform to platform. Example, you can checkout a GameInput.GetButtonName$("A"), the main select button.

5. A Platform can also been checked, by using GameInput.GetDeviceName$(). This is mostly used with Android.

6. If you want do your own mapping on Android, you can also uses Android.Scancode() or KEY() commands. KEY() cannot send a float, but Android.Scancode() does. Im mapped to those command, and not JOY, simply because mapping on those GameControllers does NOT suit those commands at all, because they can been quite very different, unlike on Windows. On Android those is treated more as a keyboard.

7. GameInput also supports Remapping, which is required to been do that on Android, if you will use RIGHT STICK or ANALOGE TRIGGERS. None of those buttons follow a standard at all. Im will explain that in a a later post.

8. Open up GameControllers.gbas. Most functions is explained how to use them. helper functions should been used internal.
 
Title: Re: How to uses GameInput API.
Post by: Ian Price on 2015-Nov-13
Cheers SF  :good:  :booze:
Title: Re: How to uses GameInput API.
Post by: erico on 2015-Nov-14
Super nice SF! But to a noob like me, that is all a bit hard to understand, I could do with trying it out, like on PC which is faster.
I will try a go on the avocado.
Title: Re: How to uses GameInput API.
Post by: spacefractal on 2015-Nov-14
im can eventuelly edit, if im got corrections. No problem.
Title: Re: How to uses GameInput API.
Post by: erico on 2015-Nov-14
You are doing great man! Way way up above. :good:
Maybe smoothing it out to noobs is a task for others, donĀ“t worry about it, it is class as it is. :good:
Title: Re: How to uses GameInput API.
Post by: nabz32 on 2016-Apr-13
Hm I tried to implement GameInput into my low rez jam project,
and it seems like one button is pressed all the time, allthough I have not connected any game controler.

I tried the CostumeRemapping method,

but CostumeRemapping.ready() always returns zero for me.

This is how my costumeremapping function looks:
Code: (glbasic) [Select]
LOCAL kG% , kNr% , noKeys% , text$
kNr = 0
CostumeRemapping.reset()
CostumeRemapping.init()
IF OPENFILE( 1 , "mapping.keys" , 1 ) 
READLINE 1 , myMapping$
CLOSEFILE 1
CostumeRemapping.load( myMapping$ )
ELSE
noKeys = 1
WHILE noKeys
X_MAKE2D
IF NOT CostumeRemapping.ready()
PRINT "RELEASE", 0 , 0 , TRUE
PRINT "KEYS!" , 0 , 16 , TRUE
ELSE
PRINT "please" , 0 , 0
PRINT "press" , 0 , 16
PRINT "key to:" , 0 , 32
SELECT kNr
CASE 0 ; text$ = "up..."
CASE 1 ; text$ = "down..."
CASE 2 ; text$ = "left.."
CASE 3 ; text$ = "right.."
CASE 4 ; text$ = "shoot"
CASE 5 ; text$ = "strafe"
ENDSELECT
PRINT text$ , 0 , 48
WHILE kG = 0
kG = CostumeRemapping.check()
WEND
SELECT kNr
CASE 0 ; CostumeRemapping.set(kG) ; CostumeRemapping._UP = kG
CASE 1 ; CostumeRemapping.set(kG) ; CostumeRemapping._DOWN = kG
CASE 2 ; CostumeRemapping.set(kG) ; CostumeRemapping._LEFT = kG
CASE 3 ; CostumeRemapping.set(kG) ; CostumeRemapping._RIGHT = kG
CASE 4 ; CostumeRemapping.set(kG) ; CostumeRemapping._A = kG
CASE 5 ; CostumeRemapping.set(kG) ; CostumeRemapping._B = kG
ENDSELECT
INC kNr , 1
ENDIF
IF kNr > 4 THEN noKeys = 0
scaleUp() // Used to scale the screen up
SHOWSCREEN
WEND
OPENFILE( 1 , "mapping.keys" , 0 )
WRITELINE 1 , CostumeRemapping.Save$()
CLOSEFILE 1
ENDIF

also it is possible to map the same button to everything.
I looked a bit into the CostumeRemapping.check() function do I need to call it while waiting for CostumeRemapping.ready() so that the CostumeRemapping._TIMER increases?
Title: Re: How to uses GameInput API.
Post by: spacefractal on 2016-Apr-13
Its a quite undocumented feature im diddent 100% finish with and should have been done easier.

Here is the code im used for Karma Miwa for the remap (if not its a bugs):

Code: (glbasic) [Select]
IF CostumeRemapping._B=0 THEN GAMEREMAP$="Press JUMP RIGHT (Back/B)"
IF CostumeRemapping._X=0 THEN GAMEREMAP$="Press JUMP LEFT (X)"
IF CostumeRemapping._A=0 THEN GAMEREMAP$="Press JUMP (Select/A)"
IF CostumeRemapping._DOWN=0 THEN GAMEREMAP$="Press MOVE DOWN"
IF CostumeRemapping._UP=0 THEN GAMEREMAP$="Press MOVE UP"
IF CostumeRemapping._RIGHT=0 THEN GAMEREMAP$="Press MOVE RIGHT"
IF CostumeRemapping._LEFT=0 THEN GAMEREMAP$="Press MOVE LEFT"
IF CostumeRemapping.ready()=FALSE THEN GAMEREMAP$="DONT touch anything"
LOCAL ScanKey=CostumeRemapping.check(UpdateTicks)
IF ScanKey>1
IF CostumeRemapping._LEFT=0 AND ScanKey>0
CostumeRemapping._LEFT=ScanKey; CostumeRemapping.set(ScanKey); ScanKey=0
CostumeRemapping._B=0
ELSEIF CostumeRemapping._RIGHT=0 AND ScanKey>0
CostumeRemapping._RIGHT=ScanKey; CostumeRemapping.set(ScanKey); ScanKey=0
ELSEIF CostumeRemapping._UP=0 AND ScanKey>0
CostumeRemapping._UP=ScanKey; CostumeRemapping.set(ScanKey); ScanKey=0
ELSEIF CostumeRemapping._DOWN=0 AND ScanKey>0
CostumeRemapping._DOWN=ScanKey; CostumeRemapping.set(ScanKey); ScanKey=0
ELSEIF CostumeRemapping._A=0 AND ScanKey>0
CostumeRemapping._A=ScanKey; CostumeRemapping.set(ScanKey); ScanKey=0
ELSEIF CostumeRemapping._X=0 AND ScanKey>0
CostumeRemapping._X=ScanKey; CostumeRemapping.set(ScanKey); ScanKey=0
ELSEIF CostumeRemapping._B=0 AND ScanKey>0
CostumeRemapping._B=ScanKey; CostumeRemapping.set(ScanKey); ScanKey=0
S_Status$="Menu"
LOCAL SaveString$=CostumeRemapping.Save$()
DEPRINT("SavedKeys: "+SaveString$)
ENDIF
ENDIF
....
SHOWSCREEN

hope that give idea. Im dont use a while/wend loop at all, but doing that in full in GLB_ON_LOOP() which is the most correct way to do. If you doing in while/wend in that way, make sure to show something to the user.

Its a little bit bad coded yes and should have been something like that you did, since im checking if there is some input in the mapping directly in GameInput, rather using a function. If you want, you can expand that.
Title: Re: How to uses GameInput API.
Post by: nabz32 on 2016-Apr-13
Thx SF  :booze:

Now i got this and it works:
Code: (glbasic) [Select]
IF OPENFILE( 1 , "mapping.keys" , 1 ) 
READLINE 1 , myMapping$
CLOSEFILE 1
CostumeRemapping.load( myMapping$ )
ELSE
noKeys = 1
WHILE noKeys
wait = FALSE
X_MAKE2D
kG = CostumeRemapping.check()
IF NOT CostumeRemapping.ready() AND rdy = 0
PRINT "RELEASE", 0 , 0 , TRUE
PRINT "KEYS!" , 0 , 16 , TRUE
ELSE
rdy = 1
WHILE kG < 1
PRINT "please" , 0 , 0
PRINT "press" , 0 , 16
PRINT "key to:" , 0 , 32
SELECT kNr
CASE 0 ; text$ = "up..."
CASE 1 ; text$ = "right..."
CASE 2 ; text$ = "down.."
CASE 3 ; text$ = "left.."
CASE 4 ; text$ = "shoot"
CASE 5 ; text$ = "strafe"
ENDSELECT
PRINT text$ , 0 , 48
kG = CostumeRemapping.check()
scaleUp()
SHOWSCREEN
WEND
SELECT kNr
CASE 0 ; CostumeRemapping.set(kG) ; CostumeRemapping._DOWN = kG
CASE 1 ; CostumeRemapping.set(kG) ; CostumeRemapping._LEFT = kG
CASE 2 ; CostumeRemapping.set(kG) ; CostumeRemapping._UP = kG
CASE 3 ; CostumeRemapping.set(kG) ; CostumeRemapping._RIGHT = kG // ( yeah I switched left, right, up and down in my movement calculations  ^^ )
CASE 4 ; CostumeRemapping.set(kG) ; CostumeRemapping._A = kG
CASE 5 ; CostumeRemapping.set(kG) ; CostumeRemapping._B = kG
ENDSELECT
INC kNr , 1
ENDIF
IF kNr > 5 THEN noKeys = 0
scaleUp()
SHOWSCREEN
WEND
OPENFILE( 1 , "mapping.keys" , 0 )
WRITELINE 1 , CostumeRemapping.Save$()
CLOSEFILE 1
ENDIF
Title: Re: How to uses GameInput API.
Post by: spacefractal on 2016-Apr-13
im guess its a minor bug in the set function. Its should have set to a variable (etc CostumeRemapping._LEFT). Im guess the reason im did not do that is because games input is different from game to game.

 Im should done that easier, example something like CostumeRemapping.set(kG, "Left"), instead of CostumeRemapping.set(kG); CostumeRemapping._LEFT=kG.