Game control plus library with presets

Hello.
I use the game controls plus library and it works very well. But every time I start the program, the configuration window appears. Is there a way to save a preset and let the user switch between these presets without showing the configuration window, or for the program to select the preset itself and don’t show any extra windows and start the program immediately?
Maybe with the getMatchedDeviceSilent method? But i don’t know how to work with this method.

If I remember correctly :grinning: the solution is to create a config file that matches your input device. For instance if you look at the example Gcp_Tanker you will find the following statements in setup()

stick = control.filter(GCP.STICK).getMatchedDevice("tank_game");

This will look for a file called tank_game inside the sketch folder(or sketch data folder) and if found will read the file and attempt to find a matching device.

If a matching device can’t be found then it will open a window where the user can select a connected device to configure for the game.

If a device matching the config file is not found and the user does not configure another then after execution the variable stick will be null and the following lines will close the sketch.

  // Find a device that matches the configuration file
  stick = control.filter(GCP.STICK).getMatchedDevice("tank_game");
  if (stick == null) {
    println("No suitable device configured");
    System.exit(-1); // End the program NOW!
  }

An alternative is to use the getMatchedDeviceSilent method like this

stick = control.filter(GCP.STICK).getMatchedDeviceSilent("tank_game");

In this case if no device can be found that matches the config file, tank_game, the user will not be given the option to select a different device, therefore stick will equal null and the sketch closes down.

So as I said at the beginning, you need a config file for your sketch. The example Gcp_Configurator will help you create the config file. Read the comments in that sketch.

If you want more info on GCP then I suggest you visit my website where you will find 3 videos about using this library.

Hope this helps.

1 Like

A configuration file exists, but the Program always opens the window anyway. However, it is sufficient if I simply tap the device and then click on use immediately afterwards. So the file has already been adjusted correctly. And with the getMatchedDeviceSilent method, the program always stops.

Based on this information you provided I suspect that the library does not recognise the device from your config file.

I suggest you try the Gcp_Configurator example to create a new config file and compare it with the one you are using and see if there is a difference.

No, it doesn’t work. I created a new configuration file with the configurator example, but the library still doesn’t recognize my controller (Dualshock 4 from PS4).
I’m using Processing 3.5.4 on Windows 10.
And this is the configuration file:

control bindings
X	mouse x axis	3	SLIDER	X-Achse	0	1.0	0.1
Y	mouse y axis	3	SLIDER	Y-Achse	0	1.0	0.1
WS	WS movement	3	SLIDER	Z-Rotation	0	1.0	0.1
AD	AD movement	3	SLIDER	Z-Achse	0	1.0	0.1
WHEEL	mouse wheel	2	HAT	cooliehat: Mehrwegeschalter	0	1.0	0.0
LEFT	left click	1	BUTTON	Taste 1	0	0.0	0.0
RIGHT	right click	1	BUTTON	Taste 0	0	0.0	0.0
E	E	1	BUTTON	Taste 2	0	0.0	0.0
TAB	tab	1	BUTTON	Taste 9	0	0.0	0.0
ESC	escape	1	BUTTON	Taste 13	0	0.0	0.0
SPACE	space	1	BUTTON	Taste 5	0	0.0	0.0
STRG	control	1	BUTTON	Taste 4	0	0.0	0.0
SHIFT	shift	1	BUTTON	Taste 10	0	0.0	0.0
WHEELCLICK	mouse wheel click	1	BUTTON	Taste 11	0	0.0	0.0

If you need the Code:

import org.gamecontrolplus.*;
import java.awt.Robot;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;

Robot robot;

float mouseExpo = 2.5f;

PVector bufferPos = new PVector();
final float multiplier = 35;

boolean pw,pa,ps,pd;

boolean pWheelPress = false;
int pWheelChangeMillis = 0;
final int wheelRepeatTime = 250;
final int wheelRepeatDistanceTime = 50;


ControlIO control;
ControlDevice stick;

public void setup() {
  try{
    robot = new Robot();
  }catch(Exception e) {
    e.printStackTrace();
  }
  
  control = ControlIO.getInstance(this);
  stick = control.filter(GCP.STICK).getMatchedDevice("joystick");
  if(stick == null) {
    println("No suitable device configured");
    System.exit(-1);
  }
  stick.getButton("LEFT").plug(this, "leftPress", ControlIO.ON_PRESS);
  stick.getButton("LEFT").plug(this, "leftRelease", ControlIO.ON_RELEASE);
  stick.getButton("RIGHT").plug(this, "rightPress", ControlIO.ON_PRESS);
  stick.getButton("RIGHT").plug(this, "rightRelease", ControlIO.ON_RELEASE);
  /*stick.getButton("W").plug(this, "wPress", ControlIO.ON_PRESS);
  stick.getButton("W").plug(this, "wRelease", ControlIO.ON_RELEASE);
  stick.getButton("A").plug(this, "aPress", ControlIO.ON_PRESS);
  stick.getButton("A").plug(this, "aRelease", ControlIO.ON_RELEASE);
  stick.getButton("S").plug(this, "sPress", ControlIO.ON_PRESS);
  stick.getButton("S").plug(this, "sRelease", ControlIO.ON_RELEASE);
  stick.getButton("D").plug(this, "dPress", ControlIO.ON_PRESS);
  stick.getButton("D").plug(this, "dRelease", ControlIO.ON_RELEASE);*/
  stick.getButton("E").plug(this, "ePress", ControlIO.ON_PRESS);
  stick.getButton("E").plug(this, "eRelease", ControlIO.ON_RELEASE);
  stick.getButton("TAB").plug(this, "tabPress", ControlIO.ON_PRESS);
  stick.getButton("TAB").plug(this, "tabRelease", ControlIO.ON_RELEASE);
  stick.getButton("ESC").plug(this, "escPress", ControlIO.ON_PRESS);
  stick.getButton("ESC").plug(this, "escRelease", ControlIO.ON_RELEASE);
  stick.getButton("SPACE").plug(this, "spacePress", ControlIO.ON_PRESS);
  stick.getButton("SPACE").plug(this, "spaceRelease", ControlIO.ON_RELEASE);
  stick.getButton("STRG").plug(this, "strgPress", ControlIO.ON_PRESS);
  stick.getButton("STRG").plug(this, "strgRelease", ControlIO.ON_RELEASE);
  stick.getButton("SHIFT").plug(this, "shiftPress", ControlIO.ON_PRESS);
  stick.getButton("SHIFT").plug(this, "shiftRelease", ControlIO.ON_RELEASE);
  stick.getButton("WHEELCLICK").plug(this, "wheelPress", ControlIO.ON_PRESS);
  stick.getButton("WHEELCLICK").plug(this, "wheelRelease", ControlIO.ON_RELEASE);
}

public void draw() {
  ControlHat hat = stick.getHat("WHEEL");
  boolean repeatWheel = millis()-pWheelChangeMillis >= wheelRepeatTime;
  if(hat.pressed() && (!pWheelPress || repeatWheel)) {
    if(hat.left() || hat.up())
      robot.mouseWheel(-1);
    else
      robot.mouseWheel(1);
    
    pWheelPress = true;
    
    if(repeatWheel) {
      pWheelChangeMillis = millis()-wheelRepeatTime+wheelRepeatDistanceTime;
    }
  }else{
    if(!hat.pressed()) {
      pWheelPress = false;
      pWheelChangeMillis = millis();
    }
  }
  float WS = stick.getSlider("WS").getValue();
  float AD = stick.getSlider("AD").getValue();
  boolean w = WS <= -0.5, s = WS >= 0.5, a = AD <= -0.5, d = AD >= 0.5;
  if(w != pw) {
    pw = w;
    if(w)
      wPress();
    else
      wRelease();
  }
  if(a != pa) {
    pa = a;
    if(a)
      aPress();
    else
      aRelease();
  }
  if(s != ps) {
    ps = s;
    if(s)
      sPress();
    else
      sRelease();
  }
  if(d != pd) {
    pd = d;
    if(d)
      dPress();
    else
      dRelease();
  }
  
  PVector vel = new PVector(stick.getSlider("X").getValue(), stick.getSlider("Y").getValue());
  vel.setMag(pow(vel.mag(), mouseExpo));
  vel.mult(multiplier);
  
  bufferPos.add(vel.x%1, vel.y%1);
  
  java.awt.Point mousePos = java.awt.MouseInfo.getPointerInfo().getLocation();
  robot.mouseMove((int)mousePos.getX() + int(vel.x) + int(bufferPos.x), (int)mousePos.getY() + int(vel.y) + int(bufferPos.y));
  
  bufferPos = new PVector(bufferPos.x%1, bufferPos.y%1);
}

void leftPress() {
  robot.mousePress(InputEvent.BUTTON1_MASK);
}
void leftRelease() {
  robot.mouseRelease(InputEvent.BUTTON1_MASK);
}
void rightPress() {
  robot.mousePress(InputEvent.BUTTON3_MASK);
}
void rightRelease() {
  robot.mouseRelease(InputEvent.BUTTON3_MASK);
}
void wPress() {
  robot.keyPress(KeyEvent.VK_W);
}
void wRelease() {
  robot.keyRelease(KeyEvent.VK_W);
}
void aPress() {
  robot.keyPress(KeyEvent.VK_A);
}
void aRelease() {
  robot.keyRelease(KeyEvent.VK_A);
}
void sPress() {
  robot.keyPress(KeyEvent.VK_S);
}
void sRelease() {
  robot.keyRelease(KeyEvent.VK_S);
}
void dPress() {
  robot.keyPress(KeyEvent.VK_D);
}
void dRelease() {
  robot.keyRelease(KeyEvent.VK_D);
}
void ePress() {
  robot.keyPress(KeyEvent.VK_E);
}
void eRelease() {
  robot.keyRelease(KeyEvent.VK_E);
}
void tabPress() {
  robot.keyPress(KeyEvent.VK_TAB);
}
void tabRelease() {
  robot.keyRelease(KeyEvent.VK_TAB);
}
void escPress() {
  robot.keyPress(KeyEvent.VK_ESCAPE);
}
void escRelease() {
  robot.keyRelease(KeyEvent.VK_ESCAPE);
}
void spacePress() {
  robot.keyPress(KeyEvent.VK_SPACE);
}
void spaceRelease() {
  robot.keyRelease(KeyEvent.VK_SPACE);
}
void strgPress() {
  robot.keyPress(KeyEvent.VK_CONTROL);
}
void strgRelease() {
  robot.keyRelease(KeyEvent.VK_CONTROL);
}
void shiftPress() {
  robot.keyPress(KeyEvent.VK_SHIFT);
}
void shiftRelease() {
  robot.keyRelease(KeyEvent.VK_SHIFT);
}
void wheelPress() {
  robot.mousePress(MouseEvent.WHEEL);
}
void wheelRelease() {
  robot.mouseRelease(MouseEvent.WHEEL);
}

It appears that you are using a PS4 controller so try removing the filter like this
stick = control.getMatchedDevice("joystick");

If it still doesn’t recognise the device make a master copy of the config file joystick and keep it safe. Then create a new one with just the first 5 lines from the master copy and try that. If it works then try 6 lines then 7 lines and so on until it fails. See if there is any particular line causing the problem.

Be careful because each line (after the first) consists of 8 tab-separated values so easy to get them mixed with spaces. You could always use the configurator to create these intermediate files.

1 Like

Oh, now I’ve understood what the filter method does. Then it is also logical that the library filters the controller. Now it works perfectly. thanks

Is there also a possibility that the configuration window is always called up, even if a device is found, if you want to change settings?

No - the whole idea is to enable a user to configure a device if a matched device cannot be found.

What settings would you want to change?

The connections. For example when the user want to use another button to jump.

You could have several config files the user can choose from and sketch then uses the chosen file to find the matched device.

There is no easy way to change a connection once the device has been matched.

Ok, than i try this.