vgamepad


Namevgamepad JSON
Version 0.1.0 PyPI version JSON
download
home_pagehttps://github.com/yannbouteiller/vgamepad
SummaryVirtual XBox360 and DualShock4 gamepads in python
upload_time2023-10-14 20:29:06
maintainer
docs_urlNone
authorYann Bouteiller
requires_python
licenseMIT
keywords virtual gamepad python xbox dualshock controller emulator
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Virtual Gamepad
Virtual XBox360 and DualShock4 gamepads in python.

---

Virtual Gamepad (```vgamepad```) is a small python library that emulates XBox360 and DualShock4 gamepads on your system.
It enables controlling e.g. a video-game that requires analog input, directly from your python script.

On Windows ```vgamepad``` uses the [Virtual Gamepad Emulation](https://github.com/nefarius/ViGEmBus) C++ framework, for which it essentially provides python bindings and a user-friendly interface.

---

__Development status:__

|  Windows  |                          Linux                          |
|:---------:|:-------------------------------------------------------:|
| *Stable.* | *Experimental,*<br/>see [Linux notes](readme/linux.md). |


## Quick links
- [Installation](#installation)
- [Getting started](#getting-started)
  - [XBox360 gamepad](#xbox360-gamepad)
  - [DualShock4 gamepad](#dualshock4-gamepad)
  - [Rumble and LEDs](#rumble-and-leds)
- [Contribute](#authors)

---

## Installation

### Windows:
Open your favorite terminal (e.g. anaconda prompt) and run:
```bash
pip install vgamepad
```

This automatically runs the installer of the ViGEmBus driver.
Accept the licence agreement, click ```Install```, allow the installer to modify you PC, wait for completion and click ```Finish```.

```vgamepad``` is now installed in your active python environment.

### Linux:

Please read the [Linux section](readme/linux.md).

---

## Getting started

```vgamepad``` provides two main python classes: ```VX360Gamepad```, which emulates a XBox360 gamepad, and ```VDS4Gamepad```, which emulates a DualShock4 gamepad.

The state of a virtual gamepad (e.g. pressed buttons, joystick values...) is called a report.
To modify the report, a number of user-friendly API functions are provided by ```vgamepad```.
When the report is modified as desired, it must be sent to the computer thanks to the ```update``` API function.

### XBox360 gamepad

The following python script creates a virtual XBox360 gamepad:

```python
import vgamepad as vg

gamepad = vg.VX360Gamepad()
```

As soon as the ```VX360Gamepad``` object is created, the virtual gamepad is connected to your system via the ViGEmBus driver, and will remain connected until the object is destroyed.

Buttons can be pressed and released through ```press_button``` and ```release_button```:

```python
gamepad.press_button(button=vg.XUSB_BUTTON.XUSB_GAMEPAD_A)  # press the A button
gamepad.press_button(button=vg.XUSB_BUTTON.XUSB_GAMEPAD_DPAD_LEFT)  # press the left hat button

gamepad.update()  # send the updated state to the computer

# (...) A and left hat are pressed...

gamepad.release_button(button=vg.XUSB_BUTTON.XUSB_GAMEPAD_A)  # release the A button

gamepad.update()  # send the updated state to the computer

# (...) left hat is still pressed...
```

All available buttons are defined in ```XUSB_BUTTON```:
```python
class XUSB_BUTTON(IntFlag):
    """
    Possible XUSB report buttons.
    """
    XUSB_GAMEPAD_DPAD_UP = 0x0001
    XUSB_GAMEPAD_DPAD_DOWN = 0x0002
    XUSB_GAMEPAD_DPAD_LEFT = 0x0004
    XUSB_GAMEPAD_DPAD_RIGHT = 0x0008
    XUSB_GAMEPAD_START = 0x0010
    XUSB_GAMEPAD_BACK = 0x0020
    XUSB_GAMEPAD_LEFT_THUMB = 0x0040
    XUSB_GAMEPAD_RIGHT_THUMB = 0x0080
    XUSB_GAMEPAD_LEFT_SHOULDER = 0x0100
    XUSB_GAMEPAD_RIGHT_SHOULDER = 0x0200
    XUSB_GAMEPAD_GUIDE = 0x0400
    XUSB_GAMEPAD_A = 0x1000
    XUSB_GAMEPAD_B = 0x2000
    XUSB_GAMEPAD_X = 0x4000
    XUSB_GAMEPAD_Y = 0x8000
```

To control the triggers (1 axis each) and the joysticks (2 axis each), two options are provided by the API.

It is possible to input raw integer values directly:
```python
gamepad.left_trigger(value=100)  # value between 0 and 255
gamepad.right_trigger(value=255)  # value between 0 and 255
gamepad.left_joystick(x_value=-10000, y_value=0)  # values between -32768 and 32767
gamepad.right_joystick(x_value=-32768, y_value=15000)  # values between -32768 and 32767

gamepad.update()
```

Or to input float values:
```python
gamepad.left_trigger_float(value_float=0.5)  # value between 0.0 and 1.0
gamepad.right_trigger_float(value_float=1.0)  # value between 0.0 and 1.0
gamepad.left_joystick_float(x_value_float=-0.5, y_value_float=0.0)  # values between -1.0 and 1.0
gamepad.right_joystick_float(x_value_float=-1.0, y_value_float=0.8)  # values between -1.0 and 1.0

gamepad.update()
```

Reset to default state:
```python
gamepad.reset()

gamepad.update()
```

Full example:
```python
import vgamepad as vg
import time

gamepad = vg.VX360Gamepad()

# press a button to wake the device up
gamepad.press_button(button=vg.XUSB_BUTTON.XUSB_GAMEPAD_A)
gamepad.update()
time.sleep(0.5)
gamepad.release_button(button=vg.XUSB_BUTTON.XUSB_GAMEPAD_A)
gamepad.update()
time.sleep(0.5)

# press buttons and things
gamepad.press_button(button=vg.XUSB_BUTTON.XUSB_GAMEPAD_A)
gamepad.press_button(button=vg.XUSB_BUTTON.XUSB_GAMEPAD_LEFT_SHOULDER)
gamepad.press_button(button=vg.XUSB_BUTTON.XUSB_GAMEPAD_DPAD_DOWN)
gamepad.press_button(button=vg.XUSB_BUTTON.XUSB_GAMEPAD_DPAD_LEFT)
gamepad.left_trigger_float(value_float=0.5)
gamepad.right_trigger_float(value_float=0.5)
gamepad.left_joystick_float(x_value_float=0.0, y_value_float=0.2)
gamepad.right_joystick_float(x_value_float=-1.0, y_value_float=1.0)

gamepad.update()

time.sleep(1.0)

# release buttons and things
gamepad.release_button(button=vg.XUSB_BUTTON.XUSB_GAMEPAD_A)
gamepad.release_button(button=vg.XUSB_BUTTON.XUSB_GAMEPAD_DPAD_LEFT)
gamepad.right_trigger_float(value_float=0.0)
gamepad.right_joystick_float(x_value_float=0.0, y_value_float=0.0)

gamepad.update()

time.sleep(1.0)

# reset gamepad to default state
gamepad.reset()

gamepad.update()

time.sleep(1.0)
```

### DualShock4 gamepad

Using a virtual DS4 gamepad is similar to X360:
```python
import vgamepad as vg

gamepad = vg.VDS4Gamepad()
```

Press and release buttons:
```python
gamepad.press_button(button=vg.DS4_BUTTONS.DS4_BUTTON_TRIANGLE)
gamepad.update()

# (...)

gamepad.release_button(button=vg.DS4_BUTTONS.DS4_BUTTON_TRIANGLE)
gamepad.update()
```

Available buttons are defined in ```DS4_BUTTONS```:
```python
class DS4_BUTTONS(IntFlag):
    """
    DualShock 4 digital buttons
    """
    DS4_BUTTON_THUMB_RIGHT = 1 << 15
    DS4_BUTTON_THUMB_LEFT = 1 << 14
    DS4_BUTTON_OPTIONS = 1 << 13
    DS4_BUTTON_SHARE = 1 << 12
    DS4_BUTTON_TRIGGER_RIGHT = 1 << 11
    DS4_BUTTON_TRIGGER_LEFT = 1 << 10
    DS4_BUTTON_SHOULDER_RIGHT = 1 << 9
    DS4_BUTTON_SHOULDER_LEFT = 1 << 8
    DS4_BUTTON_TRIANGLE = 1 << 7
    DS4_BUTTON_CIRCLE = 1 << 6
    DS4_BUTTON_CROSS = 1 << 5
    DS4_BUTTON_SQUARE = 1 << 4
```

Press and release special buttons:
```python
gamepad.press_special_button(special_button=vg.DS4_SPECIAL_BUTTONS.DS4_SPECIAL_BUTTON_PS)
gamepad.update()

# (...)

gamepad.release_special_button(special_button=vg.DS4_SPECIAL_BUTTONS.DS4_SPECIAL_BUTTON_PS)
gamepad.update()
```

Special buttons are defined in ```DS4_SPECIAL_BUTTONS```:
```python
class DS4_SPECIAL_BUTTONS(IntFlag):
    """
    DualShock 4 special buttons
    """
    DS4_SPECIAL_BUTTON_PS = 1 << 0
    DS4_SPECIAL_BUTTON_TOUCHPAD = 1 << 1  # Windows only, no effect on Linux
```

Triggers and joysticks (integer values):
```python
gamepad.left_trigger(value=100)  # value between 0 and 255
gamepad.right_trigger(value=255)  # value between 0 and 255
gamepad.left_joystick(x_value=0, y_value=128)  # value between 0 and 255
gamepad.right_joystick(x_value=0, y_value=255)  # value between 0 and 255

gamepad.update()
```

Triggers and joysticks (float values):
```python
gamepad.left_trigger_float(value_float=0.5)  # value between 0.0 and 1.0
gamepad.right_trigger_float(value_float=1.0)  # value between 0.0 and 1.0
gamepad.left_joystick_float(x_value_float=-0.5, y_value_float=0.0)  # values between -1.0 and 1.0
gamepad.right_joystick_float(x_value_float=-1.0, y_value_float=0.8)  # values between -1.0 and 1.0

gamepad.update()
```

* **Note:** Since version `0.1.0`, the DS4 Y axis on joysticks is inverted compared to the X360 API (native VIGEm behavior).

Directional pad (hat):
```python
gamepad.directional_pad(direction=vg.DS4_DPAD_DIRECTIONS.DS4_BUTTON_DPAD_NORTHWEST)
gamepad.update()
```

Directions for the directional pad are defined in ```DS4_DPAD_DIRECTIONS```:
```python
class DS4_DPAD_DIRECTIONS(IntEnum):
    """
    DualShock 4 directional pad (HAT) values
    """
    DS4_BUTTON_DPAD_NONE = 0x8
    DS4_BUTTON_DPAD_NORTHWEST = 0x7
    DS4_BUTTON_DPAD_WEST = 0x6
    DS4_BUTTON_DPAD_SOUTHWEST = 0x5
    DS4_BUTTON_DPAD_SOUTH = 0x4
    DS4_BUTTON_DPAD_SOUTHEAST = 0x3
    DS4_BUTTON_DPAD_EAST = 0x2
    DS4_BUTTON_DPAD_NORTHEAST = 0x1
    DS4_BUTTON_DPAD_NORTH = 0x0
```

Reset to default state:
```python
gamepad.reset()

gamepad.update()
```

Full example:
```python
import vgamepad as vg
import time

gamepad = vg.VDS4Gamepad()

# press a button to wake the device up
gamepad.press_button(button=vg.DS4_BUTTONS.DS4_BUTTON_TRIANGLE)
gamepad.update()
time.sleep(0.5)
gamepad.release_button(button=vg.DS4_BUTTONS.DS4_BUTTON_TRIANGLE)
gamepad.update()
time.sleep(0.5)

# press buttons and things
gamepad.press_button(button=vg.DS4_BUTTONS.DS4_BUTTON_TRIANGLE)
gamepad.press_button(button=vg.DS4_BUTTONS.DS4_BUTTON_CIRCLE)
gamepad.press_button(button=vg.DS4_BUTTONS.DS4_BUTTON_THUMB_RIGHT)
gamepad.press_button(button=vg.DS4_BUTTONS.DS4_BUTTON_TRIGGER_LEFT)
gamepad.press_special_button(special_button=vg.DS4_SPECIAL_BUTTONS.DS4_SPECIAL_BUTTON_TOUCHPAD)
gamepad.left_trigger_float(value_float=0.5)
gamepad.right_trigger_float(value_float=0.5)
gamepad.left_joystick_float(x_value_float=0.0, y_value_float=0.2)
gamepad.right_joystick_float(x_value_float=-1.0, y_value_float=1.0)

gamepad.update()

time.sleep(1.0)

# release buttons and things
gamepad.release_button(button=vg.DS4_BUTTONS.DS4_BUTTON_TRIANGLE)
gamepad.right_trigger_float(value_float=0.0)
gamepad.right_joystick_float(x_value_float=0.0, y_value_float=0.0)

gamepad.update()

time.sleep(1.0)

# reset gamepad to default state
gamepad.reset()

gamepad.update()

time.sleep(1.0)
```

---

### Rumble and LEDs:

_**Note**: Rumble and LEDs are supported on Windows only (not yet ported to Linux)._

`vgamepad` enables registering custom callback functions to handle updates of the rumble motors, and of the LED ring.

Custom callback functions require 6 parameters:
```python
def my_callback(client, target, large_motor, small_motor, led_number, user_data):
    """
    Callback function triggered at each received state change

    :param client: vigem bus ID
    :param target: vigem device ID
    :param large_motor: integer in [0, 255] representing the state of the large motor
    :param small_motor: integer in [0, 255] representing the state of the small motor
    :param led_number: integer in [0, 255] representing the state of the LED ring
    :param user_data: placeholder, do not use
    """
    # Do your things here. For instance:
    print(f"Received notification for client {client}, target {target}")
    print(f"large motor: {large_motor}, small motor: {small_motor}")
    print(f"led number: {led_number}")
```

The callback function needs to be registered as follows:
```python
gamepad.register_notification(callback_function=my_callback)
```

Each time the state of the gamepad is changed (for example by a video game that sends rumbling requests), the callback function will then be called.

In our example, when state changes are received, something like the following will be printed to `stdout`:
```terminal
Received notification for client 2876897124288, target 2876931874736
large motor: 255, small motor: 255
led number: 0
Received notification for client 2876897124288, target 2876931874736
large motor: 0, small motor: 0
led number: 0
```

If not needed anymore, the callback function can be unregistered:
```python
gamepad.unregister_notification()
```

---

### Advanced users:
More API functions are available for advanced users, and it is possible to modify the report directly instead of using the API.
See [virtual_gamepad.py](https://github.com/yannbouteiller/vgamepad/blob/main/vgamepad/win/virtual_gamepad.py).

---

## Contribute
All contributions to this project are welcome.
Please submit a PR with your name and a short description of your contribution in the Contributors list.

---
## Authors
### Maintainer:
- Yann Bouteiller
### Contributors:

- JumpyzZ (rumble and LEDs)
- willRicard (Linux support)

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/yannbouteiller/vgamepad",
    "name": "vgamepad",
    "maintainer": "",
    "docs_url": null,
    "requires_python": "",
    "maintainer_email": "",
    "keywords": "virtual,gamepad,python,xbox,dualshock,controller,emulator",
    "author": "Yann Bouteiller",
    "author_email": "",
    "download_url": "https://files.pythonhosted.org/packages/8a/54/0eaddc33f84247963af078f364b37153d09fcd6cdc398f243ec3e8842c56/vgamepad-0.1.0.tar.gz",
    "platform": null,
    "description": "# Virtual Gamepad\r\nVirtual XBox360 and DualShock4 gamepads in python.\r\n\r\n---\r\n\r\nVirtual Gamepad (```vgamepad```) is a small python library that emulates XBox360 and DualShock4 gamepads on your system.\r\nIt enables controlling e.g. a video-game that requires analog input, directly from your python script.\r\n\r\nOn Windows ```vgamepad``` uses the [Virtual Gamepad Emulation](https://github.com/nefarius/ViGEmBus) C++ framework, for which it essentially provides python bindings and a user-friendly interface.\r\n\r\n---\r\n\r\n__Development status:__\r\n\r\n|  Windows  |                          Linux                          |\r\n|:---------:|:-------------------------------------------------------:|\r\n| *Stable.* | *Experimental,*<br/>see [Linux notes](readme/linux.md). |\r\n\r\n\r\n## Quick links\r\n- [Installation](#installation)\r\n- [Getting started](#getting-started)\r\n  - [XBox360 gamepad](#xbox360-gamepad)\r\n  - [DualShock4 gamepad](#dualshock4-gamepad)\r\n  - [Rumble and LEDs](#rumble-and-leds)\r\n- [Contribute](#authors)\r\n\r\n---\r\n\r\n## Installation\r\n\r\n### Windows:\r\nOpen your favorite terminal (e.g. anaconda prompt) and run:\r\n```bash\r\npip install vgamepad\r\n```\r\n\r\nThis automatically runs the installer of the ViGEmBus driver.\r\nAccept the licence agreement, click ```Install```, allow the installer to modify you PC, wait for completion and click ```Finish```.\r\n\r\n```vgamepad``` is now installed in your active python environment.\r\n\r\n### Linux:\r\n\r\nPlease read the [Linux section](readme/linux.md).\r\n\r\n---\r\n\r\n## Getting started\r\n\r\n```vgamepad``` provides two main python classes: ```VX360Gamepad```, which emulates a XBox360 gamepad, and ```VDS4Gamepad```, which emulates a DualShock4 gamepad.\r\n\r\nThe state of a virtual gamepad (e.g. pressed buttons, joystick values...) is called a report.\r\nTo modify the report, a number of user-friendly API functions are provided by ```vgamepad```.\r\nWhen the report is modified as desired, it must be sent to the computer thanks to the ```update``` API function.\r\n\r\n### XBox360 gamepad\r\n\r\nThe following python script creates a virtual XBox360 gamepad:\r\n\r\n```python\r\nimport vgamepad as vg\r\n\r\ngamepad = vg.VX360Gamepad()\r\n```\r\n\r\nAs soon as the ```VX360Gamepad``` object is created, the virtual gamepad is connected to your system via the ViGEmBus driver, and will remain connected until the object is destroyed.\r\n\r\nButtons can be pressed and released through ```press_button``` and ```release_button```:\r\n\r\n```python\r\ngamepad.press_button(button=vg.XUSB_BUTTON.XUSB_GAMEPAD_A)  # press the A button\r\ngamepad.press_button(button=vg.XUSB_BUTTON.XUSB_GAMEPAD_DPAD_LEFT)  # press the left hat button\r\n\r\ngamepad.update()  # send the updated state to the computer\r\n\r\n# (...) A and left hat are pressed...\r\n\r\ngamepad.release_button(button=vg.XUSB_BUTTON.XUSB_GAMEPAD_A)  # release the A button\r\n\r\ngamepad.update()  # send the updated state to the computer\r\n\r\n# (...) left hat is still pressed...\r\n```\r\n\r\nAll available buttons are defined in ```XUSB_BUTTON```:\r\n```python\r\nclass XUSB_BUTTON(IntFlag):\r\n    \"\"\"\r\n    Possible XUSB report buttons.\r\n    \"\"\"\r\n    XUSB_GAMEPAD_DPAD_UP = 0x0001\r\n    XUSB_GAMEPAD_DPAD_DOWN = 0x0002\r\n    XUSB_GAMEPAD_DPAD_LEFT = 0x0004\r\n    XUSB_GAMEPAD_DPAD_RIGHT = 0x0008\r\n    XUSB_GAMEPAD_START = 0x0010\r\n    XUSB_GAMEPAD_BACK = 0x0020\r\n    XUSB_GAMEPAD_LEFT_THUMB = 0x0040\r\n    XUSB_GAMEPAD_RIGHT_THUMB = 0x0080\r\n    XUSB_GAMEPAD_LEFT_SHOULDER = 0x0100\r\n    XUSB_GAMEPAD_RIGHT_SHOULDER = 0x0200\r\n    XUSB_GAMEPAD_GUIDE = 0x0400\r\n    XUSB_GAMEPAD_A = 0x1000\r\n    XUSB_GAMEPAD_B = 0x2000\r\n    XUSB_GAMEPAD_X = 0x4000\r\n    XUSB_GAMEPAD_Y = 0x8000\r\n```\r\n\r\nTo control the triggers (1 axis each) and the joysticks (2 axis each), two options are provided by the API.\r\n\r\nIt is possible to input raw integer values directly:\r\n```python\r\ngamepad.left_trigger(value=100)  # value between 0 and 255\r\ngamepad.right_trigger(value=255)  # value between 0 and 255\r\ngamepad.left_joystick(x_value=-10000, y_value=0)  # values between -32768 and 32767\r\ngamepad.right_joystick(x_value=-32768, y_value=15000)  # values between -32768 and 32767\r\n\r\ngamepad.update()\r\n```\r\n\r\nOr to input float values:\r\n```python\r\ngamepad.left_trigger_float(value_float=0.5)  # value between 0.0 and 1.0\r\ngamepad.right_trigger_float(value_float=1.0)  # value between 0.0 and 1.0\r\ngamepad.left_joystick_float(x_value_float=-0.5, y_value_float=0.0)  # values between -1.0 and 1.0\r\ngamepad.right_joystick_float(x_value_float=-1.0, y_value_float=0.8)  # values between -1.0 and 1.0\r\n\r\ngamepad.update()\r\n```\r\n\r\nReset to default state:\r\n```python\r\ngamepad.reset()\r\n\r\ngamepad.update()\r\n```\r\n\r\nFull example:\r\n```python\r\nimport vgamepad as vg\r\nimport time\r\n\r\ngamepad = vg.VX360Gamepad()\r\n\r\n# press a button to wake the device up\r\ngamepad.press_button(button=vg.XUSB_BUTTON.XUSB_GAMEPAD_A)\r\ngamepad.update()\r\ntime.sleep(0.5)\r\ngamepad.release_button(button=vg.XUSB_BUTTON.XUSB_GAMEPAD_A)\r\ngamepad.update()\r\ntime.sleep(0.5)\r\n\r\n# press buttons and things\r\ngamepad.press_button(button=vg.XUSB_BUTTON.XUSB_GAMEPAD_A)\r\ngamepad.press_button(button=vg.XUSB_BUTTON.XUSB_GAMEPAD_LEFT_SHOULDER)\r\ngamepad.press_button(button=vg.XUSB_BUTTON.XUSB_GAMEPAD_DPAD_DOWN)\r\ngamepad.press_button(button=vg.XUSB_BUTTON.XUSB_GAMEPAD_DPAD_LEFT)\r\ngamepad.left_trigger_float(value_float=0.5)\r\ngamepad.right_trigger_float(value_float=0.5)\r\ngamepad.left_joystick_float(x_value_float=0.0, y_value_float=0.2)\r\ngamepad.right_joystick_float(x_value_float=-1.0, y_value_float=1.0)\r\n\r\ngamepad.update()\r\n\r\ntime.sleep(1.0)\r\n\r\n# release buttons and things\r\ngamepad.release_button(button=vg.XUSB_BUTTON.XUSB_GAMEPAD_A)\r\ngamepad.release_button(button=vg.XUSB_BUTTON.XUSB_GAMEPAD_DPAD_LEFT)\r\ngamepad.right_trigger_float(value_float=0.0)\r\ngamepad.right_joystick_float(x_value_float=0.0, y_value_float=0.0)\r\n\r\ngamepad.update()\r\n\r\ntime.sleep(1.0)\r\n\r\n# reset gamepad to default state\r\ngamepad.reset()\r\n\r\ngamepad.update()\r\n\r\ntime.sleep(1.0)\r\n```\r\n\r\n### DualShock4 gamepad\r\n\r\nUsing a virtual DS4 gamepad is similar to X360:\r\n```python\r\nimport vgamepad as vg\r\n\r\ngamepad = vg.VDS4Gamepad()\r\n```\r\n\r\nPress and release buttons:\r\n```python\r\ngamepad.press_button(button=vg.DS4_BUTTONS.DS4_BUTTON_TRIANGLE)\r\ngamepad.update()\r\n\r\n# (...)\r\n\r\ngamepad.release_button(button=vg.DS4_BUTTONS.DS4_BUTTON_TRIANGLE)\r\ngamepad.update()\r\n```\r\n\r\nAvailable buttons are defined in ```DS4_BUTTONS```:\r\n```python\r\nclass DS4_BUTTONS(IntFlag):\r\n    \"\"\"\r\n    DualShock 4 digital buttons\r\n    \"\"\"\r\n    DS4_BUTTON_THUMB_RIGHT = 1 << 15\r\n    DS4_BUTTON_THUMB_LEFT = 1 << 14\r\n    DS4_BUTTON_OPTIONS = 1 << 13\r\n    DS4_BUTTON_SHARE = 1 << 12\r\n    DS4_BUTTON_TRIGGER_RIGHT = 1 << 11\r\n    DS4_BUTTON_TRIGGER_LEFT = 1 << 10\r\n    DS4_BUTTON_SHOULDER_RIGHT = 1 << 9\r\n    DS4_BUTTON_SHOULDER_LEFT = 1 << 8\r\n    DS4_BUTTON_TRIANGLE = 1 << 7\r\n    DS4_BUTTON_CIRCLE = 1 << 6\r\n    DS4_BUTTON_CROSS = 1 << 5\r\n    DS4_BUTTON_SQUARE = 1 << 4\r\n```\r\n\r\nPress and release special buttons:\r\n```python\r\ngamepad.press_special_button(special_button=vg.DS4_SPECIAL_BUTTONS.DS4_SPECIAL_BUTTON_PS)\r\ngamepad.update()\r\n\r\n# (...)\r\n\r\ngamepad.release_special_button(special_button=vg.DS4_SPECIAL_BUTTONS.DS4_SPECIAL_BUTTON_PS)\r\ngamepad.update()\r\n```\r\n\r\nSpecial buttons are defined in ```DS4_SPECIAL_BUTTONS```:\r\n```python\r\nclass DS4_SPECIAL_BUTTONS(IntFlag):\r\n    \"\"\"\r\n    DualShock 4 special buttons\r\n    \"\"\"\r\n    DS4_SPECIAL_BUTTON_PS = 1 << 0\r\n    DS4_SPECIAL_BUTTON_TOUCHPAD = 1 << 1  # Windows only, no effect on Linux\r\n```\r\n\r\nTriggers and joysticks (integer values):\r\n```python\r\ngamepad.left_trigger(value=100)  # value between 0 and 255\r\ngamepad.right_trigger(value=255)  # value between 0 and 255\r\ngamepad.left_joystick(x_value=0, y_value=128)  # value between 0 and 255\r\ngamepad.right_joystick(x_value=0, y_value=255)  # value between 0 and 255\r\n\r\ngamepad.update()\r\n```\r\n\r\nTriggers and joysticks (float values):\r\n```python\r\ngamepad.left_trigger_float(value_float=0.5)  # value between 0.0 and 1.0\r\ngamepad.right_trigger_float(value_float=1.0)  # value between 0.0 and 1.0\r\ngamepad.left_joystick_float(x_value_float=-0.5, y_value_float=0.0)  # values between -1.0 and 1.0\r\ngamepad.right_joystick_float(x_value_float=-1.0, y_value_float=0.8)  # values between -1.0 and 1.0\r\n\r\ngamepad.update()\r\n```\r\n\r\n* **Note:** Since version `0.1.0`, the DS4 Y axis on joysticks is inverted compared to the X360 API (native VIGEm behavior).\r\n\r\nDirectional pad (hat):\r\n```python\r\ngamepad.directional_pad(direction=vg.DS4_DPAD_DIRECTIONS.DS4_BUTTON_DPAD_NORTHWEST)\r\ngamepad.update()\r\n```\r\n\r\nDirections for the directional pad are defined in ```DS4_DPAD_DIRECTIONS```:\r\n```python\r\nclass DS4_DPAD_DIRECTIONS(IntEnum):\r\n    \"\"\"\r\n    DualShock 4 directional pad (HAT) values\r\n    \"\"\"\r\n    DS4_BUTTON_DPAD_NONE = 0x8\r\n    DS4_BUTTON_DPAD_NORTHWEST = 0x7\r\n    DS4_BUTTON_DPAD_WEST = 0x6\r\n    DS4_BUTTON_DPAD_SOUTHWEST = 0x5\r\n    DS4_BUTTON_DPAD_SOUTH = 0x4\r\n    DS4_BUTTON_DPAD_SOUTHEAST = 0x3\r\n    DS4_BUTTON_DPAD_EAST = 0x2\r\n    DS4_BUTTON_DPAD_NORTHEAST = 0x1\r\n    DS4_BUTTON_DPAD_NORTH = 0x0\r\n```\r\n\r\nReset to default state:\r\n```python\r\ngamepad.reset()\r\n\r\ngamepad.update()\r\n```\r\n\r\nFull example:\r\n```python\r\nimport vgamepad as vg\r\nimport time\r\n\r\ngamepad = vg.VDS4Gamepad()\r\n\r\n# press a button to wake the device up\r\ngamepad.press_button(button=vg.DS4_BUTTONS.DS4_BUTTON_TRIANGLE)\r\ngamepad.update()\r\ntime.sleep(0.5)\r\ngamepad.release_button(button=vg.DS4_BUTTONS.DS4_BUTTON_TRIANGLE)\r\ngamepad.update()\r\ntime.sleep(0.5)\r\n\r\n# press buttons and things\r\ngamepad.press_button(button=vg.DS4_BUTTONS.DS4_BUTTON_TRIANGLE)\r\ngamepad.press_button(button=vg.DS4_BUTTONS.DS4_BUTTON_CIRCLE)\r\ngamepad.press_button(button=vg.DS4_BUTTONS.DS4_BUTTON_THUMB_RIGHT)\r\ngamepad.press_button(button=vg.DS4_BUTTONS.DS4_BUTTON_TRIGGER_LEFT)\r\ngamepad.press_special_button(special_button=vg.DS4_SPECIAL_BUTTONS.DS4_SPECIAL_BUTTON_TOUCHPAD)\r\ngamepad.left_trigger_float(value_float=0.5)\r\ngamepad.right_trigger_float(value_float=0.5)\r\ngamepad.left_joystick_float(x_value_float=0.0, y_value_float=0.2)\r\ngamepad.right_joystick_float(x_value_float=-1.0, y_value_float=1.0)\r\n\r\ngamepad.update()\r\n\r\ntime.sleep(1.0)\r\n\r\n# release buttons and things\r\ngamepad.release_button(button=vg.DS4_BUTTONS.DS4_BUTTON_TRIANGLE)\r\ngamepad.right_trigger_float(value_float=0.0)\r\ngamepad.right_joystick_float(x_value_float=0.0, y_value_float=0.0)\r\n\r\ngamepad.update()\r\n\r\ntime.sleep(1.0)\r\n\r\n# reset gamepad to default state\r\ngamepad.reset()\r\n\r\ngamepad.update()\r\n\r\ntime.sleep(1.0)\r\n```\r\n\r\n---\r\n\r\n### Rumble and LEDs:\r\n\r\n_**Note**: Rumble and LEDs are supported on Windows only (not yet ported to Linux)._\r\n\r\n`vgamepad` enables registering custom callback functions to handle updates of the rumble motors, and of the LED ring.\r\n\r\nCustom callback functions require 6 parameters:\r\n```python\r\ndef my_callback(client, target, large_motor, small_motor, led_number, user_data):\r\n    \"\"\"\r\n    Callback function triggered at each received state change\r\n\r\n    :param client: vigem bus ID\r\n    :param target: vigem device ID\r\n    :param large_motor: integer in [0, 255] representing the state of the large motor\r\n    :param small_motor: integer in [0, 255] representing the state of the small motor\r\n    :param led_number: integer in [0, 255] representing the state of the LED ring\r\n    :param user_data: placeholder, do not use\r\n    \"\"\"\r\n    # Do your things here. For instance:\r\n    print(f\"Received notification for client {client}, target {target}\")\r\n    print(f\"large motor: {large_motor}, small motor: {small_motor}\")\r\n    print(f\"led number: {led_number}\")\r\n```\r\n\r\nThe callback function needs to be registered as follows:\r\n```python\r\ngamepad.register_notification(callback_function=my_callback)\r\n```\r\n\r\nEach time the state of the gamepad is changed (for example by a video game that sends rumbling requests), the callback function will then be called.\r\n\r\nIn our example, when state changes are received, something like the following will be printed to `stdout`:\r\n```terminal\r\nReceived notification for client 2876897124288, target 2876931874736\r\nlarge motor: 255, small motor: 255\r\nled number: 0\r\nReceived notification for client 2876897124288, target 2876931874736\r\nlarge motor: 0, small motor: 0\r\nled number: 0\r\n```\r\n\r\nIf not needed anymore, the callback function can be unregistered:\r\n```python\r\ngamepad.unregister_notification()\r\n```\r\n\r\n---\r\n\r\n### Advanced users:\r\nMore API functions are available for advanced users, and it is possible to modify the report directly instead of using the API.\r\nSee [virtual_gamepad.py](https://github.com/yannbouteiller/vgamepad/blob/main/vgamepad/win/virtual_gamepad.py).\r\n\r\n---\r\n\r\n## Contribute\r\nAll contributions to this project are welcome.\r\nPlease submit a PR with your name and a short description of your contribution in the Contributors list.\r\n\r\n---\r\n## Authors\r\n### Maintainer:\r\n- Yann Bouteiller\r\n### Contributors:\r\n\r\n- JumpyzZ (rumble and LEDs)\r\n- willRicard (Linux support)\r\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Virtual XBox360 and DualShock4 gamepads in python",
    "version": "0.1.0",
    "project_urls": {
        "Download": "https://github.com/yannbouteiller/vgamepad/archive/refs/tags/v0.1.0.tar.gz",
        "Homepage": "https://github.com/yannbouteiller/vgamepad"
    },
    "split_keywords": [
        "virtual",
        "gamepad",
        "python",
        "xbox",
        "dualshock",
        "controller",
        "emulator"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "8a540eaddc33f84247963af078f364b37153d09fcd6cdc398f243ec3e8842c56",
                "md5": "5fe31684ec529a6e5fa705b0cdecf4d5",
                "sha256": "57f6bd01aec0c172947517fb782d150ef9b285f7f4d524c317374fa5c24a89de"
            },
            "downloads": -1,
            "filename": "vgamepad-0.1.0.tar.gz",
            "has_sig": false,
            "md5_digest": "5fe31684ec529a6e5fa705b0cdecf4d5",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": null,
            "size": 1174896,
            "upload_time": "2023-10-14T20:29:06",
            "upload_time_iso_8601": "2023-10-14T20:29:06.154151Z",
            "url": "https://files.pythonhosted.org/packages/8a/54/0eaddc33f84247963af078f364b37153d09fcd6cdc398f243ec3e8842c56/vgamepad-0.1.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-10-14 20:29:06",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "yannbouteiller",
    "github_project": "vgamepad",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "vgamepad"
}
        
Elapsed time: 1.87400s