Jibble

There is a new version of the forums ready for testing. Please post here if you're willing to help test! We could also use the help of coders!

Author Topic: [EXPERIMENTAL] Gamepad in AGS - v4  (Read 1114 times)

eri0o

[EXPERIMENTAL] Gamepad in AGS - v4
« on: 29 Apr 2022, 23:57 »
Experimental Editor with AGS with Gamepad support!

Download Editor Here: >>AGS-3.6.0.25-Beta5-Gamepad-v4.zip<< | Code Source | GitHub Issue

Here's just a gamepad check, running in the browser: gamepad_check web example
Here's the AGS Game Project of the above: GamepadExample-v3.zip

ok, this is going to take a long time, but hopefully we can figure out an API that is alright. The above editor adds a new struct in AGS, which is a Gamepad! A Gamepad maps different types of joysticks to the good old Xbox 360 controller.

I plan to later support manually figuring the joystick by querying every piece of it, which will be named a RawGamepad, which SDL2 names as joysticks, but if you have no idea what you are doing, Gamepad should be fine.

Gamepad Static Methods

Gamepad.GetCount
Code: Adventure Game Studio
  1. static int Gamepad.GetCount()
Get the number of connected joysticks. No joysticks should return 0!


Gamepad.Open
Code: Adventure Game Studio
  1. static Gamepad* Gamepad.Open(int index)
Attempts  to open a gamepad, returns null if it's not a valid gamepad! If a joystick is way too different from a Xbox360 this could fail too.
This is how you can connect to a Gamepad, you pass an index, which corresponds to the number of the joystick - if you actually have a Xbox360 Joystick, it's the green light.


Gamepad.GetName
Code: Adventure Game Studio
  1. static String Gamepad.GetName(int index)
If the index is a valid gamepad, get it's name!


Gamepad Instance Attributes and Methods

Gamepad.IsConnected
Code: Adventure Game Studio
  1. bool Gamepad.IsConnected()
True if gamepad is really connected.


Gamepad.IsButtonDown
Code: Adventure Game Studio
  1. bool Gamepad.IsButtonDown(eGamepad_Button button)
checks if a gamepad button is pressed, including dpad.

Possible buttons:
  • eGamepad_ButtonA
  • eGamepad_ButtonB
  • eGamepad_ButtonX
  • eGamepad_ButtonY
  • eGamepad_ButtonBack
  • eGamepad_ButtonGuide
  • eGamepad_ButtonStart
  • eGamepad_ButtonLeftStick
  • eGamepad_ButtonRightStick
  • eGamepad_ButtonLeftShoulder
  • eGamepad_ButtonRightShoulder
  • eGamepad_ButtonDpadUp
  • eGamepad_ButtonDpadDown
  • eGamepad_ButtonDpadLeft
  • eGamepad_ButtonDpadRight


Gamepad.GetAxis
Code: Adventure Game Studio
  1. float Gamepad.GetAxis(eGamepad_Axis axis, optional float deadzone)
get gamepad axis or trigger, trigger only has positive values. Values varies from -1.0 to 1.0 for axis, and 0.0 to 1.0 for triggers.

You can optionally pass an additional parameter to use as deadzone. If an axis absolute value is smaller than the value of deadzone, it will return 0.0. Default value is GAMEPAD_DEFAULT_DEADZONE, which is for now 0.125, use the name if you need a number.

Possible axis and triggers:
  • eGamepad_AxisLeftX
  • eGamepad_AxisLeftY
  • eGamepad_AxisRightX
  • eGamepad_AxisRightY
  • eGamepad_AxisTriggerLeft
  • eGamepad_AxisTriggerRight


Gamepad.Name
Code: Adventure Game Studio
  1. readonly String Gamepad.Name
gamepad name.


CHANGELOG:
  • v1: initial release
  • v2: GetAxis now returns a float
  • v3: GetAxis now has an additional dead_zone parameter. Default value is GAMEPAD_DEFAULT_DEADZONE, which is for now 0.125, use the name if you need a number.
  • v4: Using correspondent A,B,X,Y buttons can skip Speech and Display messages, as long as you Connect to the Gamepad.
« Last Edit: 15 May 2022, 01:57 by eri0o »

Re: [EXPERIMENTAL] Gamepad in AGS - v1
« Reply #1 on: 30 Apr 2022, 06:07 »
Wow!. Super useful. Nice job @eri0o
My official site: http://www.pershaland.ir/

eri0o

Re: [EXPERIMENTAL] Gamepad in AGS - v1
« Reply #2 on: 30 Apr 2022, 12:11 »
Thanks Mehrdad! I still need to figure more things, but I wanted to throw together a basic one, since with SDL2, we can roll joysticks for all platforms at the same time when support is in the engine itself. :)

Also sketching the API with users because things on the Engine are hard to change.

eri0o

Re: [EXPERIMENTAL] Gamepad in AGS - v2
« Reply #3 on: 01 May 2022, 02:37 »
Small update, just switched GetAxis to provide a float value. An example usage is added in the code of the example project as follows:

Code: Adventure Game Studio
  1. #define DEAD_ZONE 0.125
  2. float gamepad_mouse_x, gamepad_mouse_y;
  3. bool update_mouse;
  4. bool prev_button_a_pressed;
  5.  
  6. void repeatedly_execute_always()
  7. {
  8.   if(pad != null)
  9.   {
  10.     if(pad.IsButtonDown(eGamepad_ButtonA) && !prev_button_a_pressed)
  11.     {
  12.       mouse.Click(eMouseLeft);
  13.     }
  14.    
  15.     prev_button_a_pressed = pad.IsButtonDown(eGamepad_ButtonA);
  16.    
  17.     float x_lstick = pad.GetAxis(eGamepad_AxisLeftX);
  18.     float y_lstick = pad.GetAxis(eGamepad_AxisLeftY);
  19.  
  20.     if( x_lstick < -DEAD_ZONE || x_lstick > DEAD_ZONE ||
  21.         y_lstick < -DEAD_ZONE || y_lstick > DEAD_ZONE )
  22.     {
  23.       if(update_mouse) {
  24.         gamepad_mouse_x = IntToFloat(mouse.x);
  25.         gamepad_mouse_y = IntToFloat(mouse.y);
  26.         update_mouse = false;
  27.       }
  28.      
  29.       gamepad_mouse_x += 10.0 * x_lstick;
  30.       gamepad_mouse_y += 10.0 * y_lstick;
  31.      
  32.       mouse.SetPosition(FloatToInt(gamepad_mouse_x, eRoundDown) ,
  33.                         FloatToInt(gamepad_mouse_y, eRoundDown));
  34.     } else {
  35.       update_mouse = true;
  36.     }
  37.   }
  38. }

deadsuperhero

  • Card-Carrying Satanist
    • I can help with backgrounds
    • I can help with characters
    • I can help with making music
    • I can help with scripting
Re: [EXPERIMENTAL] Gamepad in AGS - v2
« Reply #4 on: 01 May 2022, 06:12 »
Oh, man! This is exactly what I need right now for my projects. Very exciting to see this, would love to get my games working on SteamDeck!
The fediverse needs great indie game developers! Find me there!

AndreasBlack

  • Max Fury that's me
Re: [EXPERIMENTAL] Gamepad in AGS - v2
« Reply #5 on: 01 May 2022, 08:00 »
Nice! Gonna give this a try later, thanks! I knew it had something to do with the deadzone being off as i wrote in the DM, but my limited coding knowledge could only get it to stay in the middle of the screen previously!

Edit: Something really strange is going on. I get this error: Failed to save room room1.crm; details below
room1.asc(21): Error (line 21): Type mismatch: cannot convert 'int' to 'float'

The project seems to randomly work. Really odd. Say if i edit the line AGS is claiming has an error.

 
Code: Adventure Game Studio
  1.     float x_lstick = pad.GetAxis(eGamepad_AxisLeftX);

Change it to say AxisLeft); leave out the X then i get an error obviously, then edit it back to the correct syntax AxisLeftX); Then still it gives me the error Line 21 again, even tho the syntax is right!

No idea what's causing this. So i can't give this a try in my main project cause i get that error no matter what in that project. Even in the example project as written above i could recreate the error line.
« Last Edit: 01 May 2022, 09:58 by AndreasBlack »

eri0o

Re: [EXPERIMENTAL] Gamepad in AGS - v2
« Reply #6 on: 01 May 2022, 11:17 »
I cannot reproduce... Are you sure you are using the new V2 version I provided above and not the previous V1 version that was available before? In V1 GetAxis was giving an integer, but now in V2 I changed to a float, because I felt it was easier to people understand the range available.

If someone else could try too, it would be great.  (roll)

Edit: I may implement an additional axis_deadzone parameter in GetAxis to simplify code for this.
« Last Edit: 01 May 2022, 11:38 by eri0o »

AndreasBlack

  • Max Fury that's me
Re: [EXPERIMENTAL] Gamepad in AGS - v2
« Reply #7 on: 01 May 2022, 12:19 »
I was blind! I didn't see you've also updated the link for the AGSbeta to a "v2". My bad! It works now! Thanks!

The mouse/controller seems stable too, fantastic!
« Last Edit: 01 May 2022, 12:23 by AndreasBlack »

eri0o

Re: [EXPERIMENTAL] Gamepad in AGS - v3
« Reply #8 on: 01 May 2022, 14:45 »
Added a deadzone parameter in GetAxis and updated the description above to explain how it works.

This allows switching the code to a slightly simpler comparison. It will also nudge in the importance of deadzone if someone wants to modify the parameter.

Code: Adventure Game Studio
  1. float gamepad_mouse_x, gamepad_mouse_y;
  2. bool update_mouse;
  3. bool prev_button_a_pressed;
  4.  
  5. void repeatedly_execute_always()
  6. {
  7.   if(pad != null)
  8.   {
  9.     if(pad.IsButtonDown(eGamepad_ButtonA) && !prev_button_a_pressed)
  10.     {
  11.       mouse.Click(eMouseLeft);
  12.     }
  13.    
  14.     prev_button_a_pressed = pad.IsButtonDown(eGamepad_ButtonA);
  15.    
  16.     float x_lstick = pad.GetAxis(eGamepad_AxisLeftX);
  17.     float y_lstick = pad.GetAxis(eGamepad_AxisLeftY);
  18.  
  19.     if( x_lstick != 0.0 || y_lstick != 0.0 )
  20.     {
  21.       if(update_mouse) {
  22.         gamepad_mouse_x = IntToFloat(mouse.x);
  23.         gamepad_mouse_y = IntToFloat(mouse.y);
  24.         update_mouse = false;
  25.       }
  26.      
  27.       gamepad_mouse_x += 8.0 * x_lstick;
  28.       gamepad_mouse_y += 8.0 * y_lstick;
  29.      
  30.       mouse.SetPosition(FloatToInt(gamepad_mouse_x, eRoundDown) ,
  31.                         FloatToInt(gamepad_mouse_y, eRoundDown));
  32.     } else {
  33.       update_mouse = true;
  34.     }
  35.   }
  36. }

Note for the web port:
  • mouse SetPosition is not allowed unless the game enters in fullscreen once (through either alt+enter or by script, but only after the player clicks on the screen once). We would need to support a fake mouse and some way to click in a specific position to circumvent this, but I am not sure how to handle this at this time. This is because a Browser protects you from evil websites that may want to hijack your mouse.
  • after the game is loaded and in focus, you need to hit one button in the joystick at least once, before the browser recognizes it for that tab and we can find it.


Edit:
 
I ninjad a new update to v3 itself, just a small adjustment to guarantee the float values from GetAxis are always sane.
« Last Edit: 01 May 2022, 16:12 by eri0o »

Crimson Wizard

  • Local Moderator
    • Lifetime Achievement Award Winner
    • Best Innovation Award Winner 2013, for spearheading the AGS 3.3.0 project
    • Crimson Wizard worked on one or more games that won an AGS Award!
    •  
    • Crimson Wizard worked on one or more games that was nominated for an AGS Award!
Re: [EXPERIMENTAL] Gamepad in AGS - v3
« Reply #9 on: 02 May 2022, 08:46 »
I see that the gamepad buttons are used as mouse click simulation, but I assume this is done temporary for a test.

Should the goal be to have gamepad buttons handled similar to keyboard key and mouse clicks, that is to have their own respective callback, like on_gamepad_press?

One optional idea is to have gamepad buttons merged with eKey codes. The benefit of that is that you may assign them to the same variables as keys, both in engine API properties, and script variables.
« Last Edit: 02 May 2022, 08:51 by Crimson Wizard »

eri0o

Re: [EXPERIMENTAL] Gamepad in AGS - v3
« Reply #10 on: 02 May 2022, 10:54 »
Quote
One optional idea is to have gamepad buttons merged with eKey codes. The benefit of that is that you may assign them to the same variables as keys, both in engine API properties, and script variables.

That is interesting, but I think I prefer to figure some dedicated way to do so, Gamepads have predefined buttons but joysticks don't. But I will keep that approach in mind as a fallback in case things don't work the way I hope.

Things like, multiple Gamepads/Joysticks, I must keep in mind and try to not clash parts that would be helpful to most and the full range of possibilities, like couch co-op.

About on_gamepad_press, I will at some point, but it's not very useful right now (can't skip text) so I will keep using repeatedly execute always at this time. I wonder if for gamepad -> mouse mapping there's something better we could do at this time, like click and holding isn't possible, because there's no way to force a button state in the mouse...

Crimson Wizard

  • Local Moderator
    • Lifetime Achievement Award Winner
    • Best Innovation Award Winner 2013, for spearheading the AGS 3.3.0 project
    • Crimson Wizard worked on one or more games that won an AGS Award!
    •  
    • Crimson Wizard worked on one or more games that was nominated for an AGS Award!
Re: [EXPERIMENTAL] Gamepad in AGS - v3
« Reply #11 on: 02 May 2022, 10:59 »
About on_gamepad_press, I will at some point, but it's not very useful right now (can't skip text) so I will keep using repeatedly execute always at this time.

Could you elaborate how is this related to skipping text?

IMO it may be useful just as the key presses in on_key_press are useful: to react to button press without having to deal with their on/off states in the rep-exec. Right now it seems in your examples you're trying to use gamepad to simulate mouse cursor and clicks. But gamepads could be used without mouse cursors as well, similar to how keyboard is used in keyboard controlled games.

My meaning in general is not to try to simulate anything with gamepad (this was the plugin's approach, because there was no other way) but instead integrate gamepad as a part of the normal engine input and script. Have events for gamepad similar to how there are events for mouse and keys.
« Last Edit: 02 May 2022, 11:05 by Crimson Wizard »

eri0o

Re: [EXPERIMENTAL] Gamepad in AGS - v3
« Reply #12 on: 02 May 2022, 11:25 »
on_ events don't happen when something is blocking. Also they are not good when you need to get something continuously, like keep the character walking.

I also think I am handling wrong the pointers in my code, I think ideally objects that represent the same index should get the same pointer - right now this is countered because you can't connect to the same joystick twice, and that is only factory function that produces gamepads. But in the engine I could theoretically pass the pointer of the pressed joystick in an on_ event so you could inspect which joystick/gamepad had the button pressed, which would be easy if the pointers were guaranteed to match. I am not sure the best approach right now to guarantee such uniqueness.

Crimson Wizard

  • Local Moderator
    • Lifetime Achievement Award Winner
    • Best Innovation Award Winner 2013, for spearheading the AGS 3.3.0 project
    • Crimson Wizard worked on one or more games that won an AGS Award!
    •  
    • Crimson Wizard worked on one or more games that was nominated for an AGS Award!
Re: [EXPERIMENTAL] Gamepad in AGS - v3
« Reply #13 on: 02 May 2022, 11:29 »
on_ events don't happen when something is blocking. Also they are not good when you need to get something continuously, like keep the character walking.

Ok, but so do events for mouse clicks and keys, and yet they exist and are useful.

Skipping text and skippable blocking actions should be done in the engine IMO. In other words, whenever there's an event for mouse or keys there should be a corresponding event for gamepad. If a mouse or keys are checked in the engine, so should gamepad be checked as well, and so on. Well, at least this is how I thought this will be done. Is your goal for the moment to use gamepad to simulate other inputs in rep-exec-always?
« Last Edit: 02 May 2022, 12:03 by Crimson Wizard »

AndreasBlack

  • Max Fury that's me
Re: [EXPERIMENTAL] Gamepad in AGS - v3
« Reply #14 on: 02 May 2022, 12:11 »
Just tried the new V3 and i'd made sure i've downloaded all the links this time  :-D In V3 i've noticed the character seems to get stuck around the first or second walk frame before walking away, sorta like running on a treadmill a millisecond (Thumbleweed template). Not sure what that is about ??? works fine otherwise, to the untrained eye, at least. Have you tried adding a view with one frame and added audio into the frame and see if it stutters all over? Say forexample the player wants a fist animation view and adds the sound in the view and pushes the button or holds down the button, does it stutter? In my mind, i don't think it should, if it does! Thanks





eri0o

Re: [EXPERIMENTAL] Gamepad in AGS - v3
« Reply #15 on: 02 May 2022, 12:22 »
Just tried the new V3 and i'd made sure i've downloaded all the links this time  :-D In V3 i've noticed the character seems to get stuck around the first or second walk frame before walking away, sorta like running on a treadmill a millisecond (Thumbleweed template). Not sure what that is about ??? works fine otherwise, to the untrained eye, at least. Have you tried adding a view with one frame and added audio into the frame and see if it stutters all over? Say forexample the player wants a fist animation view and adds the sound in the view and pushes the button or holds down the button, does it stutter? In my mind, i don't think it should, if it does! Thanks

Sorry, but I don't think I added any handling of views here, is this something in your own code? Or is it something that happens when you click for the character to walk using the button of the gamepad to press a button on the mouse?

Quote
Skipping text and skippable blocking actions should be done in the engine IMO

Yes, but I think it needs it's own functions and place to store things. One problem is one can have two joysticks or more connected, and then they can save the game and load and have zero, there are things regarding the gamepad that seem to belong more in a config file than in an save state. But these depends on how much information is meant to be stored in these.

I will write down the bits of the problems I am trying to figure out, since, I do not have been able to figure the roadmap yet, maybe some of the problems I am thinking are just in my head and may not be that relevant for now. I revised a bit the notes on the original issue in GitHub, I will try to update there with things on my mind.

I really need people to play around with this and come up with the problems, that arise. :/
« Last Edit: 02 May 2022, 12:49 by eri0o »

eri0o

Re: [EXPERIMENTAL] Gamepad in AGS - v3
« Reply #16 on: 02 May 2022, 17:10 »
I will be looking in to add in the next version a way to properly skip texts for this, but it may not be the final form we endup going, but I need something materialized to think.

eri0o

Re: [EXPERIMENTAL] Gamepad in AGS - v4
« Reply #17 on: 15 May 2022, 15:36 »
Now you can use A,B,X or Y buttons to skip Display and Speak messages. This is still in development, I am trying to figure it out the API for being able to say which button can be used and stuff like that - for now, if keyboard can skip text, the gamepad will be able to skip too.

For now, the controller has to be connect first by using the script API before it can be used as such. I updated the top post to v4 which is the release that includes this. If you downloaded the v4 yesterday, you need to download again as I just found a mistake at that.

AndreasBlack

  • Max Fury that's me
Re: [EXPERIMENTAL] Gamepad in AGS - v4
« Reply #18 on: 20 May 2022, 21:10 »
It happens when i click walk with a button on the controller, yes. Thumbleweed template with own game/sprites ofc. They never behave like that without the controller using the mouse tho. Walks normally then.
Normal walking views added with 8 frame sprites right left up down, etc. Nothing special going on, so i was a bit surprised by it tbh. But focus on solving the big picture, i should never complain anymore, not qualified. Great job so far!  (nod)
 

eri0o

Re: [EXPERIMENTAL] Gamepad in AGS - v4
« Reply #19 on: 21 May 2022, 01:09 »
@AndreasBlack, Can you try V4 that is up and see if it still happens? I previously wrongly handled button press when the button was released too, so this may have been a problem, but I fixed in the latest version.