![CH32X035 USB HID Gamepad Library](img/title.png)

# CH32X035 USB HID Gamepad Library

A high-performance, dual-stick USB HID Gamepad library tailored for the **WCH CH32X035** RISC-V microcontroller series.

This library allows your CH32X035 to emulate a modern gaming controller. It is recognized as a generic HID Gamepad, making it compatible with Windows, Linux, Android, and Steam "Out-of-the-box".

## Features

*   **Dual Analog Sticks:** 8-bit resolution (-127 to 127) for Left and Right joysticks.
*   **Analog Triggers:** 8-bit resolution (0 to 255) for Left (L2) and Right (R2) triggers.
*   **16 Digital Buttons:** Support for a full array of buttons (0 to 15).
*   **8-Way D-Pad:** Standard Hat Switch for directional input.
*   **Hardware Synchronization:** High-speed updates using hardware interrupts for zero-lag gaming.

## API Overview

| Function | Description |
| :--- | :--- |
| `Gamepad.begin()` | Initializes the USB stack and enumerates as a Gamepad. |
| `Gamepad.setLeftStick(x, y)` | Sets Left Stick position (-127 to 127). |
| `Gamepad.setRightStick(x, y)` | Sets Right Stick position (-127 to 127). |
| `Gamepad.setTriggers(l, r)` | Sets Analog Triggers pressure (0 to 255). |
| `Gamepad.setHat(direction)` | Sets D-Pad direction (Use constants). |
| `Gamepad.press(button)` | Presses a button (0 to 15). |
| `Gamepad.release(button)` | Releases a specific button. |
| `Gamepad.releaseAll()` | Releases all buttons at once. |
| `Gamepad.sendReport()` | **Crucial:** Transmits the current state to the USB host. |

## Supported D-Pad Directions

| Constant | Direction | Constant | Direction |
| :--- | :--- | :--- | :--- |
| `DPAD_UP` | Up | `DPAD_DOWN_RIGHT` | Down-Right |
| `DPAD_DOWN` | Down | `DPAD_DOWN_LEFT` | Down-Left |
| `DPAD_LEFT` | Left | `DPAD_UP_LEFT` | Up-Left |
| `DPAD_RIGHT` | Right | `DPAD_CENTERED` | Released / Neutral |
| `DPAD_UP_RIGHT` | Up-Right | | |

## Installation

1.  Download this repository as a ZIP file.
2.  Open the Arduino IDE.
3.  Go to **Sketch** -> **Include Library** -> **Add .ZIP Library...**
4.  Select the downloaded ZIP file.
5.  Restart the IDE.

## Usage Guide

### 1. Basic Setup

Include the library and initialize it in `setup()`.

```cpp
#include <USBGamepad.h>

void setup() {
    // Initialize USB Gamepad stack
    Gamepad.begin();
    
    // Wait for host enumeration
    delay(1000);
}

void loop() {
    // Your logic here
}
```

### 2. State Batching (The `sendReport` Logic)

To ensure maximum performance and avoid jitter, the library uses a "Batching" approach. Functions like `press()` or `setLeftStick()` only update the **internal memory**. To actually send these updates to the PC, you must call `Gamepad.sendReport()`.

```cpp
void loop() {
    // 1. Map your hardware inputs to Gamepad states
    int8_t x = map(analogRead(PA0), 0, 1023, -127, 127);
    int8_t y = map(analogRead(PA1), 0, 1023, -127, 127);
    
    Gamepad.setLeftStick(x, y);
    
    if (digitalRead(PA2) == LOW) {
        Gamepad.press(0); // Press Button 0 (e.g. 'A')
    } else {
        Gamepad.release(0);
    }

    // 2. Transmit the whole state at once (once per loop is usually best)
    Gamepad.sendReport();
    
    delay(5); // Small delay to match 200Hz polling or similar
}
```

### 3. Using Analog Triggers

Triggers are 0 (fully released) to 255 (fully pressed).

```cpp
void loop() {
    // Press Left Trigger fully
    Gamepad.setTriggers(255, 0);
    Gamepad.sendReport();
    delay(1000);
    
    // Release
    Gamepad.setTriggers(0, 0);
    Gamepad.sendReport();
    delay(1000);
}
```

## Credits & Acknowledgements

This library was developed by **NoNamedCat**.

It is architecturally inspired by and built upon the **[CH32X035_USBSerial](https://github.com/jobitjoseph/CH32X035_USBSerial)** library.

Special thanks to **[jobitjoseph](https://github.com/jobitjoseph)** for his excellent work on the CH32X035 USB CDC implementation, which provided the essential foundation for the low-level USBFS initialization and endpoint management used in this project.

## License

This project is licensed under the MIT License - see the LICENSE file for details.