[PLUGIN] AGS Controller Support (OPEN SOURCE) - v1.1

Started by Dualnames, Tue 30/04/2019 03:20:35

Previous topic - Next topic

Olleh19

#20
Hi!

I have been trying to use the Rumble feature, but i can't seem to change the values at all. Apart from raising the duration ???
Am i doing something wrong?
All i can change is the durations length but when i try to lower it. It rumbles 4ever instead. So i've deicided to use it as a neckmassage device when my neck hurts after drawing too much pixelart, kidding (laugh)
Is it a bug or am i not understanding the concept, i've tried lowering from 40 to 30 or 35 or such. Should i lower in specific values? If so please write some that you think might work.
I want "fast" short rumbles for an impact, not these 40 game loops rumbles!  (wrong)

Wished i knew what was wrong. This is the only code that works, if i change this a little either it rumbles forever. or if i raise the duration to 100 it will go for 100game loops, etc. But the other values, no

Edit: Should the gamespeed be set to 30 if i want 30 loops to work? :/ Don't want to do that, ofc.

Code: ags
if (!gamepad.IsButtonDownOnce(3))  

{
gamepad.Rumble(65636,65535,40);

}


loneroh

Hi. Plugin is not working with my Xbox One controller. Any suggestions?

Dualnames

I have an xbox controller and it works fine on my end, can you paste your code here.
Worked on Strangeland, Primordia, Hob's Barrow, The Cat Lady, Mage's Initiation, Until I Have You, Downfall, Hunie Pop, and every game in the Wadjet Eye Games catalogue (porting)

deadsuperhero

This is an amazing idea for a plugin! Quick question: is this plugin currently only available for Windows builds of AGS games, or will it also work with MacOS / Linux runtimes?

It's not the worst thing in the world if it's Windows-only at the moment, because Wine/Proton are pretty good for AGS games, but it'd be nice to support this kind of thing natively!
The fediverse needs great indie game developers! Find me there!

Dualnames

Worked on Strangeland, Primordia, Hob's Barrow, The Cat Lady, Mage's Initiation, Until I Have You, Downfall, Hunie Pop, and every game in the Wadjet Eye Games catalogue (porting)

deadsuperhero

Oops! Sorry I didn't catch that. I'll definitely check this out for some of my projects!
The fediverse needs great indie game developers! Find me there!

Volcan

I get this error:

[imgzoom]https://atariage.com/forums/gallery_ips/monthly_2022_01/large.1514247188_agsproblem.png.d7e31b9e664507f813073733376ce057.png[/imgzoom]

I use AGS 3.5.1

I have AGSController.dll and SDL2.dll.

eri0o

The SDL2.dll has to be 32 bits and placed in the same directory.

Volcan

Quote from: eri0o on Sun 16/01/2022 23:37:41
The SDL2.dll has to be 32 bits and placed in the same directory.

I don't get it since SDL2.dll is included with AGSController.dll.

Crimson Wizard

Quote from: Volcan on Mon 17/01/2022 02:31:20
I don't get it since SDL2.dll is included with AGSController.dll.

Have you copied SDL2.dll to where your game.exe is?

BTW, I could not see the picture that you posted until I copied the address into browser by hand, and answered to captcha.

deadsuperhero

Quote from: Volcan on Mon 17/01/2022 02:31:20
Quote from: eri0o on Sun 16/01/2022 23:37:41
The SDL2.dll has to be 32 bits and placed in the same directory.

I don't get it since SDL2.dll is included with AGSController.dll.

Hey, I had the same problem earlier today. If you check earlier in the thread, it turns out you need to get the 32-bits version of the DLL from the LibSDL site: https://www.libsdl.org/download-2.0.php
The fediverse needs great indie game developers! Find me there!

Volcan

Quote from: deadsuperhero on Mon 17/01/2022 03:30:49
Quote from: Volcan on Mon 17/01/2022 02:31:20
Quote from: eri0o on Sun 16/01/2022 23:37:41
The SDL2.dll has to be 32 bits and placed in the same directory.

I don't get it since SDL2.dll is included with AGSController.dll.

Hey, I had the same problem earlier today. If you check earlier in the thread, it turns out you need to get the 32-bits version of the DLL from the LibSDL site: https://www.libsdl.org/download-2.0.php

Thanks

It works.

deadsuperhero

#32
Edit: Before reading any of this, note that I am using a Playstation 5 controller, which is less common on a PC (Linux) setup. It's entirely possible that different controllers read axis values differently.

Hey, so I'm currently working on adapting this to my game, but I have a couple of stumbling blocks to figure out:

So...the first one is getting the axis to work properly. In a nutshell, I'm trying to make one of my joysticks move the mouse cursor around. I have an extremely rough implementation right now:

Code: ags

if (gamepad.GetAxis(0) < -200 && !LEFT){ // LEFT STICK LEFT
   Mouse.SetPosition(mouse.x - 1, mouse.y);
   HitNoDirection();
   LEFT=true;
   }
    else if (gamepad.GetAxis(0) > 200 && !RIGHT){ // LEFT STICK RIGHT
      Mouse.SetPosition(mouse.x + 1, mouse.y);
      HitNoDirection();
      RIGHT=true;
    }
    else if (gamepad.GetAxis(1) < -200 && !UP){ // LEFT STICK UP
      Mouse.SetPosition(mouse.x, mouse.y - 1);
      HitNoDirection();
      UP=true;
    }
    else if (gamepad.GetAxis(1) > 200 && !DOWN){ // LEFT STICK DOWN
      Mouse.SetPosition(mouse.x, mouse.y + 1);
      HitNoDirection();
      DOWN=true;
    }
    else {
      HitNoDirection();
}


Unfortunately, the cursor seems to get confused about where it's supposed to go on the screen. Up and left seem to work okay, but the game seems to get confused about down and right.


The second stumbling block is that I'm trying to treat the X button as a Left Click, and the Square button as a Right Click:

Code: ags

    if (gamepad.IsButtonDownOnce(0)) // X Button
      {
        if (gWheel.Visible == true) {
          Wait(1); // Have to have this, otherwise the first lines of dialogue get skipped?
          Mouse.Click(eMouseLeft); // Clicking on buttons
        }
        else if (gInventory.Visible == true) {
          Mouse.Click(eMouseLeftInv); // Interact with Inventory Items
        }
        else {
          Mouse.Click(eMouseLeft); // Normal default Left Click, which is normally just walking to a specific point.
        }
      }


So...the Wheel menu buttons work fine when left clicking...but! When a message comes up on the screen, this simulated left click is incapable of dismissing them. It also can't seem to skip speech.

The fediverse needs great indie game developers! Find me there!

eri0o

If you need to click, use this plugin function ClickMouse instead. Mouse.Click goes through a different click pipeline through the engine.

Crimson Wizard

#34
Quote from: deadsuperhero on Wed 19/01/2022 09:35:41
So...the Wheel menu buttons work fine when left clicking...but! When a message comes up on the screen, this simulated left click is incapable of dismissing them. It also can't seem to skip speech.

Can you clarify, where exactly do you call that code from? What do you refer to as a "message", is this a message from Display() function?

Quote from: eri0o on Wed 19/01/2022 20:43:15
If you need to click, use this plugin function ClickMouse instead. Mouse.Click goes through a different click pipeline through the engine.

I checked what the plugin does, and it calls engine->SimulateMouseClick(), which in turn calls PluginSimulateMouseClick:
https://github.com/adventuregamestudio/ags/blob/master/Engine/plugin/agsplugin.cpp#L779
The script's Mouse.Click also calls PluginSimulateMouseClick:
https://github.com/adventuregamestudio/ags/blob/master/Engine/ac/mouse.cpp#L573

These should be identical in result. What matters is what circumstances you are calling them (e.g. on which event or callback).

deadsuperhero

#35
Quote from: Crimson Wizard on Wed 19/01/2022 20:59:26
Quote from: deadsuperhero on Wed 19/01/2022 09:35:41
So...the Wheel menu buttons work fine when left clicking...but! When a message comes up on the screen, this simulated left click is incapable of dismissing them. It also can't seem to skip speech.

Can you clarify, where exactly do you call that code from? What do you refer to as a "message", is this a message from Display() function?

These should be identical in result. What matters is what circumstances you are calling them (e.g. on which event or callback).

Hey, no problem! This is what I'm currently doing for handling clicks normally:

Code: ags


  if (button == eMouseLeft) {
   if (gWheel.Visible == false) {
     Room.ProcessClick(mouse.x, mouse.y, mouse.Mode);
   }
   else {
     gWheel.Visible = false;
     gContext.Visible = false;
   }
  }




For deeper context, here's my click handler in entirety:
Code: ags

function on_mouse_click(MouseButton button)
{
  // called when a mouse button is clicked. button is either LEFT or RIGHT
  if (IsGamePaused())
  {
    // game is paused, so do nothing (i.e. don't process mouse clicks)
    if (gInventory.Visible == true) {
       if (button == eMouseLeftInv) {
              if (mouse.Mode == eModeLookat) {
                examineItem(inventory[game.inv_activated]);
               }
               else if (mouse.Mode == eModeInteract) {
                 inventory[game.inv_activated].RunInteraction(eModeInteract);
               }
               else if (mouse.Mode == eModeUseinv) {
                 inventory[game.inv_activated].RunInteraction(eModeUseinv);
               }               
               else if (mouse.Mode == eModePointer) {
                 player.ActiveInventory = inventory[game.inv_activated];
                 mouse.Mode = eModeUseinv;
                 mouse.ChangeModeHotspot(eModeUseinv, 0, 0);
               }               
      }
    }
     else if (gMemories.Visible == true) {
       if (button == eMouseLeftInv) {
         openJournal(inventory[game.inv_activated]);
       }
     }
    
  }
  else if (button == eMouseLeft)
  {
   if (gWheel.Visible == false) {
     Room.ProcessClick(mouse.x, mouse.y, mouse.Mode);
   }
   else {
     gWheel.Visible = false;
     gContext.Visible = false;
   }
  }
  else if (button == eMouseRight){
    // right-click or mouse wheel down will cycle the mouse cursor mode forwards
    setContext();
    setPointer();
 //   gWheel.SetPosition(mouse.x, mouse.y);
    gWheel.Visible = true;
  }
  else if (button == eMouseMiddle)
  {
    // middle-click makes the character walk to clicked area, regardless of cursor mode
    Room.ProcessClick(mouse.x, mouse.y, eModeWalkto);
  }
}


To clarify - skipping speech, cutscenes, and Display() messages works just fine with both the mouse and the keyboard. But, the gamepad input just seems to ignore it.
The fediverse needs great indie game developers! Find me there!

Crimson Wizard

#36
Quote from: deadsuperhero on Thu 20/01/2022 09:20:28
Quote from: Crimson Wizard on Wed 19/01/2022 20:59:26
Can you clarify, where exactly do you call that code from?

Hey, no problem! This is what I'm currently doing for handling clicks normally:

I meant, could you tell where do you call the code that you posted above, the one with Mouse.Click?

For example, are you calling it from repeatedly_execute, or repeatedly_execute_always, or other place?

Crimson Wizard

#37
Ah! :facepalm: I just realized that forgot to explain. The reason i ask is that:

1. The speech is a blocking action; repeatedly_execute does not run during blocking actions. repeatedly_execute_always does. So that matters.

2. Display() command is special in AGS, it's "super-blocking", because even repeatedly_execute_always does not run during it. That's of course a design oversight, but I think it was made so because engine uses Display() for special messages too that are supposed to completely freeze the game. Because of that, you won't be able to call Mouse.Click in script while Display is on screen.
The only solution to this I am aware of is to not use Display, but instead make your custom overlay or GUI for such messages.
What remains of course are these special messages that I mentioned. The only fix for them would be when the engine itself would handle gamepad.

OR, if plugin would also handle these events and called "SimulateClick" automatically, not forcing you to do that in script.

deadsuperhero

#38
Hey, sorry for the delay - it turns out that I was calling it from repeatedly_execute! That one was 100% my bad, moving over to repeatedly_execute_always totally fixed it.

Looks like I'll have to come up with something clever for working around the Display() issue.
The fediverse needs great indie game developers! Find me there!

deadsuperhero

#39
Hey, just digging this up again. I took a long break from doing AGS stuff, and kind of wanted to get back into making my games work with a game controller.
One area that I'm kind of stuck on involves moving the mouse with a joystick in a way that feels good.

In my current setup, the right stick on my gamepad moves the cursor around.

Code: ags

function trackAxis() {
  if (gamepad.Plugged() == true) {
    int axis0 = gamepad.GetAxis(0); // Left Stick Vertical
    int axis1 = gamepad.GetAxis(1); // Left Stick Horizontal
    int axis2 = gamepad.GetAxis(2); // Right Stick Vertical
    int axis3 = gamepad.GetAxis(3); // Right Stick Horizontal
  }
}

function checkController() {
trackAxis();
String inputName = gamepad.GetName();

  if (inputName == "PS5 Controller") {
    int axis2 = gamepad.GetAxis(2); // Right Stick Vertical
    int axis3 = gamepad.GetAxis(3); // Right Stick Horizontal
    int axisCo2 = gamepad.GetAxis(2) / 80; // 1/4th of the Room Height
    int axisCo3 = gamepad.GetAxis(3) / 50; // 1/4th of the Room Width
    
    if (axis2 < -200 && !LEFT){ // RIGHT STICK LEFT
      Mouse.SetPosition(axisCo2, axisCo3);
      HitNoDirection();
      LEFT=true;
    }
    else if (axis2 > 200 && !RIGHT){ // RIGHT STICK RIGHT
      Mouse.SetPosition(axisCo2, axisCo3);
      HitNoDirection();
      RIGHT=true;
    }
    else if (axis3 < -200 && !UP){ // RIGHT STICK UP
      Mouse.SetPosition(axisCo2, axisCo3);
      HitNoDirection();
      UP=true;
    }
    else if (axis3 > 200 && !DOWN){ // RIGHT STICK DOWN
      Mouse.SetPosition(axisCo2, axisCo3);
      HitNoDirection();
      DOWN=true;
    }
    else {
      HitNoDirection();
    }
}


For purposes of processing input, I'm calling my code from repeatedly_execute_always, so that the player can interact with the game even during speech and cutscenes. The problem is that the right stick has a Rubber Band effect, where the cursor returns to its position of origin after the stick is released. In other words...you can position the cursor around, but it always returns to a given spot.

I'm not completely sure on how to avoid this. My guess is that, because this is running in repeatedly_execute_always, the engine is constantly polling for mouse position based on joystick input, and updating it even when the axis values are zero?

I'm just trying to figure out how to get the cursor to stay put after I move it with the stick.
The fediverse needs great indie game developers! Find me there!

SMF spam blocked by CleanTalk