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 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.
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.
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.