GML PS4 / Direct Input controllers DC when focus lost

Slyddar

Member
I'm playing around with various controllers in a game that has coop, and noticed in the documentation, specifically this

"Also note that the Direct Input interface is run in cooperative mode which means that your game only has access when it is the foreground application, which in turn will cause Direct Input controllers to be "lost" if the game uses focus and then "found" again when it comes back into focus (this can be detected in the System Event and dealt with)."​

Sidenote, some bad English in there. It was taken from https://docs2.yoyogames.com/source/_build/3_scripting/4_gml_reference/controls/gamepad input/index.html

So in my testing I have an Xbox and PS4 controller connected, and as noted above, when the game loses focus the PS4 player drops out completely. Gaining focus again the player rejoins.

I'm currently testing using this check to not remove it if the game loses focus
Code:
if !os_is_paused()
which seems ok, but if the controller is disconnected while focus is lost, this may go south without further checks on reconnection.

I'm curious if others have experienced this and have you implemented any workarounds, or even have suggestions how to handle this dropout. It's obviously quite bad if the player has items, or health, etc, as everything gets lost.
 
Last edited:

Phil Strahl

Member
You can add an "Async - System" event to your controller object, that runs a switch on the event, something like
Code:
var event = ds_map_find_value(async_load, "event_type");
switch (event)
{
   case "gamepad discovered":
   {
       // identify gamepads
       var gp_num = gamepad_get_device_count();
       for (var i = 0; i < gp_num; i++;)
       {
           //show_debug_message("Checking GamePad slot "+string(i))
           gamepad[i] = false;
           if (gamepad_is_connected(i))
           {
              gamepad[i] = true
              pad_slot = i
              pad_name = gamepad_get_description(i);
     
              switch (pad_name)
              {               
                case "Xbox 360 Controller (XInput STANDARD GAMEPAD)":
                { pad_model = GAMEPAD.xbox360; } break;
           
                case "PS3 Controller":
                case "PLAYSTATION(R)3 Controller":
                { pad_model = GAMEPAD.ps3;     } break;
               
                case "Sony DualShock 4":
                { pad_model = GAMEPAD.ps4;     } break;
               
                case "Dual Analog Pad":
                { pad_model = GAMEPAD.saitek_dual_analog; } break;
         
                default:
                  pad_model = GAMEPAD.gamepad_generic
              }
     
              gamepad_set_axis_deadzone(i, pad_deadzone)
              show_debug_message("\""+ pad_name + "\" (" + string(pad_model) + ") found at slot "+string(i))
           }
       } // end of loop through all slots
   }
   break;
   
   case "gamepad lost":
   show_debug_message("Gamepad lost.")
   break;
}
 

Slyddar

Member
Thanks for your reply, and yep, I'm already running an Async - System event with similar code. Getting the port and controller type is not the problem. Having it drop when the game loses focus is.

In their games I was hoping others could advise what they implemented when this happens. It probably only effects games where there are multiple local players, and you can join in and out, as someone testing their own game single player game with a PS4 controller might not even notice the drop, if they have it default to keyboard controls when a controller is not detected. As soon as the game gains focus, the controller will connect again. In a local muliplayer game though, that can be a little tougher to do.
 
Top