# Game control plus library with presets

**URL:** https://discourse.processing.org/t/game-control-plus-library-with-presets/33712
**Category:** Libraries
**Created:** [November 24, 2021, 11:15am UTC](https://discourse.processing.org/t/game-control-plus-library-with-presets/33712 "2021-11-24T11:15:12Z")
**Posts on this page:** 12
**Page:** 1

<div class="post-metadata">

### Author: ![TimeLex](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/timelex/32/12869_2.png) [@TimeLex](https://discourse.processing.org/u/TimeLex)
#### Post date: [November 24, 2021, 11:15am UTC](https://discourse.processing.org/t/game-control-plus-library-with-presets/33712/1 "2021-11-24T11:15:12Z")

</div>

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.

---

<div class="post-metadata">

### Author: ![quark](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/quark/32/26_2.png) [@quark](https://discourse.processing.org/u/quark)
#### Post date: [November 24, 2021, 3:41pm UTC](https://discourse.processing.org/t/game-control-plus-library-with-presets/33712/2 "2021-11-24T15:41:20Z")

</div>

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()`

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

```auto
  // 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

```auto
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](http://www.lagers.org.uk/gamecontrol/index.html) where you will find 3 videos about using this library.

Hope this helps.

---

<div class="post-metadata">

### Author: ![TimeLex](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/timelex/32/12869_2.png) [@TimeLex](https://discourse.processing.org/u/TimeLex)
#### Post date: [November 24, 2021, 4:49pm UTC](https://discourse.processing.org/t/game-control-plus-library-with-presets/33712/3 "2021-11-24T16:49:16Z")

</div>

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.

---

<div class="post-metadata">

### Author: ![quark](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/quark/32/26_2.png) [@quark](https://discourse.processing.org/u/quark)
#### Post date: [November 24, 2021, 5:47pm UTC](https://discourse.processing.org/t/game-control-plus-library-with-presets/33712/4 "2021-11-24T17:47:23Z")

</div>

> [@TimeLex](#):
>
> 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.

---

<div class="post-metadata">

### Author: ![TimeLex](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/timelex/32/12869_2.png) [@TimeLex](https://discourse.processing.org/u/TimeLex)
#### Post date: [November 26, 2021, 8:03am UTC](https://discourse.processing.org/t/game-control-plus-library-with-presets/33712/5 "2021-11-26T08:03:41Z")

</div>

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:

```auto
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:

```auto
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);
}

```

---

<div class="post-metadata">

### Author: ![quark](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/quark/32/26_2.png) [@quark](https://discourse.processing.org/u/quark)
#### Post date: [November 26, 2021, 9:11am UTC](https://discourse.processing.org/t/game-control-plus-library-with-presets/33712/6 "2021-11-26T09:11:53Z")

</div>

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.

---

<div class="post-metadata">

### Author: ![TimeLex](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/timelex/32/12869_2.png) [@TimeLex](https://discourse.processing.org/u/TimeLex)
#### Post date: [November 26, 2021, 9:32am UTC](https://discourse.processing.org/t/game-control-plus-library-with-presets/33712/7 "2021-11-26T09:32:29Z")

</div>

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

---

<div class="post-metadata">

### Author: ![TimeLex](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/timelex/32/12869_2.png) [@TimeLex](https://discourse.processing.org/u/TimeLex)
#### Post date: [November 26, 2021, 1:28pm UTC](https://discourse.processing.org/t/game-control-plus-library-with-presets/33712/8 "2021-11-26T13:28:46Z")

</div>

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?

---

<div class="post-metadata">

### Author: ![quark](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/quark/32/26_2.png) [@quark](https://discourse.processing.org/u/quark)
#### Post date: [November 26, 2021, 1:33pm UTC](https://discourse.processing.org/t/game-control-plus-library-with-presets/33712/9 "2021-11-26T13:33:33Z")

</div>

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?

---

<div class="post-metadata">

### Author: ![TimeLex](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/timelex/32/12869_2.png) [@TimeLex](https://discourse.processing.org/u/TimeLex)
#### Post date: [November 26, 2021, 1:38pm UTC](https://discourse.processing.org/t/game-control-plus-library-with-presets/33712/10 "2021-11-26T13:38:03Z")

</div>

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

---

<div class="post-metadata">

### Author: ![quark](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/quark/32/26_2.png) [@quark](https://discourse.processing.org/u/quark)
#### Post date: [November 26, 2021, 2:18pm UTC](https://discourse.processing.org/t/game-control-plus-library-with-presets/33712/11 "2021-11-26T14:18:44Z")

</div>

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.

---

<div class="post-metadata">

### Author: ![TimeLex](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/timelex/32/12869_2.png) [@TimeLex](https://discourse.processing.org/u/TimeLex)
#### Post date: [November 26, 2021, 2:22pm UTC](https://discourse.processing.org/t/game-control-plus-library-with-presets/33712/12 "2021-11-26T14:22:07Z")

</div>

Ok, than i try this.
